Lines Matching +full:io +full:- +full:multiplex
2 * linux/drivers/video/s3fb.c -- Frame buffer device driver for S3 Trio/Virge
4 * Copyright (c) 2006-2007 Ondrej Zajicek <santiago@crfreenet.org>
30 #include <linux/i2c-algo-bit.h>
48 /* ------------------------------------------------------------------------- */
148 /* ------------------------------------------------------------------------- */
158 MODULE_AUTHOR("(c) 2006-2007 Ondrej Zajicek <santiago@crfreenet.org>");
163 MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
165 MODULE_PARM_DESC(mode, "Default video mode ('640x480-8@60', etc) (deprecated)");
167 MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
173 /* ------------------------------------------------------------------------- */
194 if (s3fb_ddc_needs_mmio(par->chip)) in s3fb_ddc_read()
195 return readb(par->mmio + DDC_MMIO_REG); in s3fb_ddc_read()
197 return vga_rcrt(par->state.vgabase, DDC_REG); in s3fb_ddc_read()
202 if (s3fb_ddc_needs_mmio(par->chip)) in s3fb_ddc_write()
203 writeb(val, par->mmio + DDC_MMIO_REG); in s3fb_ddc_write()
205 vga_wcrt(par->state.vgabase, DDC_REG, val); in s3fb_ddc_write()
250 struct s3fb_info *par = info->par; in s3fb_setup_ddc_bus()
252 strscpy(par->ddc_adapter.name, info->fix.id, in s3fb_setup_ddc_bus()
253 sizeof(par->ddc_adapter.name)); in s3fb_setup_ddc_bus()
254 par->ddc_adapter.owner = THIS_MODULE; in s3fb_setup_ddc_bus()
255 par->ddc_adapter.class = I2C_CLASS_DDC; in s3fb_setup_ddc_bus()
256 par->ddc_adapter.algo_data = &par->ddc_algo; in s3fb_setup_ddc_bus()
257 par->ddc_adapter.dev.parent = info->device; in s3fb_setup_ddc_bus()
258 par->ddc_algo.setsda = s3fb_ddc_setsda; in s3fb_setup_ddc_bus()
259 par->ddc_algo.setscl = s3fb_ddc_setscl; in s3fb_setup_ddc_bus()
260 par->ddc_algo.getsda = s3fb_ddc_getsda; in s3fb_setup_ddc_bus()
261 par->ddc_algo.getscl = s3fb_ddc_getscl; in s3fb_setup_ddc_bus()
262 par->ddc_algo.udelay = 10; in s3fb_setup_ddc_bus()
263 par->ddc_algo.timeout = 20; in s3fb_setup_ddc_bus()
264 par->ddc_algo.data = par; in s3fb_setup_ddc_bus()
266 i2c_set_adapdata(&par->ddc_adapter, par); in s3fb_setup_ddc_bus()
270 * DDC and extension pins - switch it do DDC in s3fb_setup_ddc_bus()
272 /* vga_wseq(par->state.vgabase, 0x08, 0x06); - not needed, already unlocked */ in s3fb_setup_ddc_bus()
273 if (par->chip == CHIP_357_VIRGE_GX2 || in s3fb_setup_ddc_bus()
274 par->chip == CHIP_359_VIRGE_GX2P || in s3fb_setup_ddc_bus()
275 par->chip == CHIP_260_VIRGE_MX) in s3fb_setup_ddc_bus()
276 svga_wseq_mask(par->state.vgabase, 0x0d, 0x01, 0x03); in s3fb_setup_ddc_bus()
278 svga_wseq_mask(par->state.vgabase, 0x0d, 0x00, 0x03); in s3fb_setup_ddc_bus()
280 svga_wcrt_mask(par->state.vgabase, 0x5c, 0x03, 0x03); in s3fb_setup_ddc_bus()
282 return i2c_bit_add_bus(&par->ddc_adapter); in s3fb_setup_ddc_bus()
287 /* ------------------------------------------------------------------------- */
293 const u8 *font = map->data; in s3fb_settile_fast()
294 u8 __iomem *fb = (u8 __iomem *) info->screen_base; in s3fb_settile_fast()
297 if ((map->width != 8) || (map->height != 16) || in s3fb_settile_fast()
298 (map->depth != 1) || (map->length != 256)) { in s3fb_settile_fast()
300 map->width, map->height, map->depth, map->length); in s3fb_settile_fast()
305 for (i = 0; i < map->height; i++) { in s3fb_settile_fast()
306 for (c = 0; c < map->length; c++) { in s3fb_settile_fast()
307 fb_writeb(font[c * map->height + i], fb + c * 4); in s3fb_settile_fast()
315 struct s3fb_info *par = info->par; in s3fb_tilecursor()
317 svga_tilecursor(par->state.vgabase, info, cursor); in s3fb_tilecursor()
339 /* ------------------------------------------------------------------------- */
341 /* image data is MSB-first, fb structure is MSB-first too */
347 /* s3fb_iplan_imageblit silently assumes that almost everything is 8-pixel aligned */
350 u32 fg = expand_color(image->fg_color); in s3fb_iplan_imageblit()
351 u32 bg = expand_color(image->bg_color); in s3fb_iplan_imageblit()
358 src1 = image->data; in s3fb_iplan_imageblit()
359 dst1 = info->screen_base + (image->dy * info->fix.line_length) in s3fb_iplan_imageblit()
360 + ((image->dx / 8) * 4); in s3fb_iplan_imageblit()
362 for (y = 0; y < image->height; y++) { in s3fb_iplan_imageblit()
365 for (x = 0; x < image->width; x += 8) { in s3fb_iplan_imageblit()
370 src1 += image->width / 8; in s3fb_iplan_imageblit()
371 dst1 += info->fix.line_length; in s3fb_iplan_imageblit()
376 /* s3fb_iplan_fillrect silently assumes that almost everything is 8-pixel aligned */
379 u32 fg = expand_color(rect->color); in s3fb_iplan_fillrect()
384 dst1 = info->screen_base + (rect->dy * info->fix.line_length) in s3fb_iplan_fillrect()
385 + ((rect->dx / 8) * 4); in s3fb_iplan_fillrect()
387 for (y = 0; y < rect->height; y++) { in s3fb_iplan_fillrect()
389 for (x = 0; x < rect->width; x += 8) { in s3fb_iplan_fillrect()
392 dst1 += info->fix.line_length; in s3fb_iplan_fillrect()
397 /* image data is MSB-first, fb structure is high-nibble-in-low-byte-first */
404 /* s3fb_cfb4_imageblit silently assumes that almost everything is 8-pixel aligned */
407 u32 fg = image->fg_color * 0x11111111; in s3fb_cfb4_imageblit()
408 u32 bg = image->bg_color * 0x11111111; in s3fb_cfb4_imageblit()
415 src1 = image->data; in s3fb_cfb4_imageblit()
416 dst1 = info->screen_base + (image->dy * info->fix.line_length) in s3fb_cfb4_imageblit()
417 + ((image->dx / 8) * 4); in s3fb_cfb4_imageblit()
419 for (y = 0; y < image->height; y++) { in s3fb_cfb4_imageblit()
422 for (x = 0; x < image->width; x += 8) { in s3fb_cfb4_imageblit()
427 src1 += image->width / 8; in s3fb_cfb4_imageblit()
428 dst1 += info->fix.line_length; in s3fb_cfb4_imageblit()
434 if ((info->var.bits_per_pixel == 4) && (image->depth == 1) in s3fb_imageblit()
435 && ((image->width % 8) == 0) && ((image->dx % 8) == 0)) { in s3fb_imageblit()
436 if (info->fix.type == FB_TYPE_INTERLEAVED_PLANES) in s3fb_imageblit()
446 if ((info->var.bits_per_pixel == 4) in s3fb_fillrect()
447 && ((rect->width % 8) == 0) && ((rect->dx % 8) == 0) in s3fb_fillrect()
448 && (info->fix.type == FB_TYPE_INTERLEAVED_PLANES)) in s3fb_fillrect()
456 /* ------------------------------------------------------------------------- */
461 struct s3fb_info *par = info->par; in s3_set_pixclock()
466 rv = svga_compute_pll((par->chip == CHIP_365_TRIO3D) ? &s3_trio3d_pll : &s3_pll, in s3_set_pixclock()
467 1000000000 / pixclock, &m, &n, &r, info->node); in s3_set_pixclock()
474 regval = vga_r(par->state.vgabase, VGA_MIS_R); in s3_set_pixclock()
475 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); in s3_set_pixclock()
478 if (par->chip == CHIP_357_VIRGE_GX2 || in s3_set_pixclock()
479 par->chip == CHIP_359_VIRGE_GX2P || in s3_set_pixclock()
480 par->chip == CHIP_360_TRIO3D_1X || in s3_set_pixclock()
481 par->chip == CHIP_362_TRIO3D_2X || in s3_set_pixclock()
482 par->chip == CHIP_368_TRIO3D_2X || in s3_set_pixclock()
483 par->chip == CHIP_260_VIRGE_MX) { in s3_set_pixclock()
484 vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */ in s3_set_pixclock()
485 vga_wseq(par->state.vgabase, 0x29, r >> 2); /* remaining highest bit of r */ in s3_set_pixclock()
487 vga_wseq(par->state.vgabase, 0x12, (n - 2) | (r << 5)); in s3_set_pixclock()
488 vga_wseq(par->state.vgabase, 0x13, m - 2); in s3_set_pixclock()
492 /* Activate clock - write 0, 1, 0 to seq/15 bit 5 */ in s3_set_pixclock()
493 regval = vga_rseq (par->state.vgabase, 0x15); /* | 0x80; */ in s3_set_pixclock()
494 vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5)); in s3_set_pixclock()
495 vga_wseq(par->state.vgabase, 0x15, regval | (1<<5)); in s3_set_pixclock()
496 vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5)); in s3_set_pixclock()
504 struct s3fb_info *par = info->par; in s3fb_open()
506 mutex_lock(&(par->open_lock)); in s3fb_open()
507 if (par->ref_count == 0) { in s3fb_open()
508 void __iomem *vgabase = par->state.vgabase; in s3fb_open()
510 memset(&(par->state), 0, sizeof(struct vgastate)); in s3fb_open()
511 par->state.vgabase = vgabase; in s3fb_open()
512 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; in s3fb_open()
513 par->state.num_crtc = 0x70; in s3fb_open()
514 par->state.num_seq = 0x20; in s3fb_open()
515 save_vga(&(par->state)); in s3fb_open()
518 par->ref_count++; in s3fb_open()
519 mutex_unlock(&(par->open_lock)); in s3fb_open()
528 struct s3fb_info *par = info->par; in s3fb_release()
530 mutex_lock(&(par->open_lock)); in s3fb_release()
531 if (par->ref_count == 0) { in s3fb_release()
532 mutex_unlock(&(par->open_lock)); in s3fb_release()
533 return -EINVAL; in s3fb_release()
536 if (par->ref_count == 1) in s3fb_release()
537 restore_vga(&(par->state)); in s3fb_release()
539 par->ref_count--; in s3fb_release()
540 mutex_unlock(&(par->open_lock)); in s3fb_release()
549 struct s3fb_info *par = info->par; in s3fb_check_var()
553 if (!var->pixclock) in s3fb_check_var()
554 return -EINVAL; in s3fb_check_var()
561 if ((par->chip == CHIP_988_VIRGE_VX) ? (rv == 7) : (rv == 6)) in s3fb_check_var()
562 rv = -EINVAL; in s3fb_check_var()
570 if (var->xres > var->xres_virtual) in s3fb_check_var()
571 var->xres_virtual = var->xres; in s3fb_check_var()
573 if (var->yres > var->yres_virtual) in s3fb_check_var()
574 var->yres_virtual = var->yres; in s3fb_check_var()
577 step = s3fb_formats[rv].xresstep - 1; in s3fb_check_var()
578 var->xres_virtual = (var->xres_virtual+step) & ~step; in s3fb_check_var()
581 mem = ((var->bits_per_pixel * var->xres_virtual) >> 3) * var->yres_virtual; in s3fb_check_var()
582 if (mem > info->screen_size) { in s3fb_check_var()
584 mem >> 10, (unsigned int) (info->screen_size >> 10)); in s3fb_check_var()
585 return -EINVAL; in s3fb_check_var()
588 rv = svga_check_timings (&s3_timing_regs, var, info->node); in s3fb_check_var()
594 rv = svga_compute_pll(&s3_pll, PICOS2KHZ(var->pixclock), &m, &n, &r, in s3fb_check_var()
595 info->node); in s3fb_check_var()
608 struct s3fb_info *par = info->par; in s3fb_set_par()
609 u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes; in s3fb_set_par() local
610 u32 bpp = info->var.bits_per_pixel; in s3fb_set_par()
614 info->fix.ypanstep = 1; in s3fb_set_par()
615 info->fix.line_length = (info->var.xres_virtual * bpp) / 8; in s3fb_set_par()
617 info->flags &= ~FBINFO_MISC_TILEBLITTING; in s3fb_set_par()
618 info->tileops = NULL; in s3fb_set_par()
621 info->pixmap.blit_x = (bpp == 4) ? (1 << (8 - 1)) : (~(u32)0); in s3fb_set_par()
622 info->pixmap.blit_y = ~(u32)0; in s3fb_set_par()
624 offset_value = (info->var.xres_virtual * bpp) / 64; in s3fb_set_par()
625 screen_size = info->var.yres_virtual * info->fix.line_length; in s3fb_set_par()
627 info->fix.ypanstep = 16; in s3fb_set_par()
628 info->fix.line_length = 0; in s3fb_set_par()
630 info->flags |= FBINFO_MISC_TILEBLITTING; in s3fb_set_par()
631 info->tileops = fasttext ? &s3fb_fast_tile_ops : &s3fb_tile_ops; in s3fb_set_par()
634 info->pixmap.blit_x = 1 << (8 - 1); in s3fb_set_par()
635 info->pixmap.blit_y = 1 << (16 - 1); in s3fb_set_par()
637 offset_value = info->var.xres_virtual / 16; in s3fb_set_par()
638 screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64; in s3fb_set_par()
641 info->var.xoffset = 0; in s3fb_set_par()
642 info->var.yoffset = 0; in s3fb_set_par()
643 info->var.activate = FB_ACTIVATE_NOW; in s3fb_set_par()
646 vga_wcrt(par->state.vgabase, 0x38, 0x48); in s3fb_set_par()
647 vga_wcrt(par->state.vgabase, 0x39, 0xA5); in s3fb_set_par()
648 vga_wseq(par->state.vgabase, 0x08, 0x06); in s3fb_set_par()
649 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80); in s3fb_set_par()
652 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20); in s3fb_set_par()
653 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80); in s3fb_set_par()
656 svga_set_default_gfx_regs(par->state.vgabase); in s3fb_set_par()
657 svga_set_default_atc_regs(par->state.vgabase); in s3fb_set_par()
658 svga_set_default_seq_regs(par->state.vgabase); in s3fb_set_par()
659 svga_set_default_crt_regs(par->state.vgabase); in s3fb_set_par()
660 svga_wcrt_multi(par->state.vgabase, s3_line_compare_regs, 0xFFFFFFFF); in s3fb_set_par()
661 svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, 0); in s3fb_set_par()
664 svga_wcrt_mask(par->state.vgabase, 0x58, 0x10, 0x10); /* enable linear framebuffer */ in s3fb_set_par()
665 …svga_wcrt_mask(par->state.vgabase, 0x31, 0x08, 0x08); /* enable sequencer access to framebuffer ab… in s3fb_set_par()
667 /* svga_wcrt_mask(par->state.vgabase, 0x33, 0x08, 0x08); */ /* DDR ? */ in s3fb_set_par()
668 /* svga_wcrt_mask(par->state.vgabase, 0x43, 0x01, 0x01); */ /* DDR ? */ in s3fb_set_par()
669 svga_wcrt_mask(par->state.vgabase, 0x33, 0x00, 0x08); /* no DDR ? */ in s3fb_set_par()
670 svga_wcrt_mask(par->state.vgabase, 0x43, 0x00, 0x01); /* no DDR ? */ in s3fb_set_par()
672 svga_wcrt_mask(par->state.vgabase, 0x5D, 0x00, 0x28); /* Clear strange HSlen bits */ in s3fb_set_par()
674 /* svga_wcrt_mask(par->state.vgabase, 0x58, 0x03, 0x03); */ in s3fb_set_par()
676 /* svga_wcrt_mask(par->state.vgabase, 0x53, 0x12, 0x13); */ /* enable MMIO */ in s3fb_set_par()
677 /* svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08); */ /* enable write buffer */ in s3fb_set_par()
682 svga_wcrt_multi(par->state.vgabase, s3_offset_regs, offset_value); in s3fb_set_par()
684 if (par->chip != CHIP_357_VIRGE_GX2 && in s3fb_set_par()
685 par->chip != CHIP_359_VIRGE_GX2P && in s3fb_set_par()
686 par->chip != CHIP_360_TRIO3D_1X && in s3fb_set_par()
687 par->chip != CHIP_362_TRIO3D_2X && in s3fb_set_par()
688 par->chip != CHIP_368_TRIO3D_2X && in s3fb_set_par()
689 par->chip != CHIP_260_VIRGE_MX) { in s3fb_set_par()
690 vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */ in s3fb_set_par()
691 vga_wcrt(par->state.vgabase, 0x60, 0xff); /* N parameter */ in s3fb_set_par()
692 vga_wcrt(par->state.vgabase, 0x61, 0xff); /* L parameter */ in s3fb_set_par()
693 vga_wcrt(par->state.vgabase, 0x62, 0xff); /* L parameter */ in s3fb_set_par()
696 vga_wcrt(par->state.vgabase, 0x3A, 0x35); in s3fb_set_par()
697 svga_wattr(par->state.vgabase, 0x33, 0x00); in s3fb_set_par()
699 if (info->var.vmode & FB_VMODE_DOUBLE) in s3fb_set_par()
700 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80); in s3fb_set_par()
702 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80); in s3fb_set_par()
704 if (info->var.vmode & FB_VMODE_INTERLACED) in s3fb_set_par()
705 svga_wcrt_mask(par->state.vgabase, 0x42, 0x20, 0x20); in s3fb_set_par()
707 svga_wcrt_mask(par->state.vgabase, 0x42, 0x00, 0x20); in s3fb_set_par()
710 svga_wcrt_mask(par->state.vgabase, 0x45, 0x00, 0x01); in s3fb_set_par()
712 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0x0C); in s3fb_set_par()
714 mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix)); in s3fb_set_par()
717 if (par->chip == CHIP_375_VIRGE_DX) { in s3fb_set_par()
718 vga_wcrt(par->state.vgabase, 0x86, 0x80); in s3fb_set_par()
719 vga_wcrt(par->state.vgabase, 0x90, 0x00); in s3fb_set_par()
723 if (par->chip == CHIP_988_VIRGE_VX) { in s3fb_set_par()
724 vga_wcrt(par->state.vgabase, 0x50, 0x00); in s3fb_set_par()
725 vga_wcrt(par->state.vgabase, 0x67, 0x50); in s3fb_set_par()
727 vga_wcrt(par->state.vgabase, 0x63, (mode <= 2) ? 0x90 : 0x09); in s3fb_set_par()
728 vga_wcrt(par->state.vgabase, 0x66, 0x90); in s3fb_set_par()
731 if (par->chip == CHIP_357_VIRGE_GX2 || in s3fb_set_par()
732 par->chip == CHIP_359_VIRGE_GX2P || in s3fb_set_par()
733 par->chip == CHIP_360_TRIO3D_1X || in s3fb_set_par()
734 par->chip == CHIP_362_TRIO3D_2X || in s3fb_set_par()
735 par->chip == CHIP_368_TRIO3D_2X || in s3fb_set_par()
736 par->chip == CHIP_365_TRIO3D || in s3fb_set_par()
737 par->chip == CHIP_375_VIRGE_DX || in s3fb_set_par()
738 par->chip == CHIP_385_VIRGE_GX || in s3fb_set_par()
739 par->chip == CHIP_260_VIRGE_MX) { in s3fb_set_par()
740 dbytes = info->var.xres * ((bpp+7)/8); in s3fb_set_par()
741 vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8); in s3fb_set_par()
742 vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80); in s3fb_set_par()
744 vga_wcrt(par->state.vgabase, 0x66, 0x81); in s3fb_set_par()
747 if (par->chip == CHIP_357_VIRGE_GX2 || in s3fb_set_par()
748 par->chip == CHIP_359_VIRGE_GX2P || in s3fb_set_par()
749 par->chip == CHIP_360_TRIO3D_1X || in s3fb_set_par()
750 par->chip == CHIP_362_TRIO3D_2X || in s3fb_set_par()
751 par->chip == CHIP_368_TRIO3D_2X || in s3fb_set_par()
752 par->chip == CHIP_260_VIRGE_MX) in s3fb_set_par()
753 vga_wcrt(par->state.vgabase, 0x34, 0x00); in s3fb_set_par()
755 vga_wcrt(par->state.vgabase, 0x34, 0x10); in s3fb_set_par()
757 svga_wcrt_mask(par->state.vgabase, 0x31, 0x00, 0x40); in s3fb_set_par()
758 multiplex = 0; in s3fb_set_par()
761 /* Set mode-specific register values */ in s3fb_set_par()
765 svga_set_textmode_vga_regs(par->state.vgabase); in s3fb_set_par()
767 /* Set additional registers like in 8-bit mode */ in s3fb_set_par()
768 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); in s3fb_set_par()
769 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); in s3fb_set_par()
772 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30); in s3fb_set_par()
776 svga_wcrt_mask(par->state.vgabase, 0x31, 0x40, 0x40); in s3fb_set_par()
781 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40); in s3fb_set_par()
783 /* Set additional registers like in 8-bit mode */ in s3fb_set_par()
784 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); in s3fb_set_par()
785 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); in s3fb_set_par()
788 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30); in s3fb_set_par()
793 /* Set additional registers like in 8-bit mode */ in s3fb_set_par()
794 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); in s3fb_set_par()
795 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); in s3fb_set_par()
798 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30); in s3fb_set_par()
802 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); in s3fb_set_par()
803 if (info->var.pixclock > 20000 || in s3fb_set_par()
804 par->chip == CHIP_357_VIRGE_GX2 || in s3fb_set_par()
805 par->chip == CHIP_359_VIRGE_GX2P || in s3fb_set_par()
806 par->chip == CHIP_360_TRIO3D_1X || in s3fb_set_par()
807 par->chip == CHIP_362_TRIO3D_2X || in s3fb_set_par()
808 par->chip == CHIP_368_TRIO3D_2X || in s3fb_set_par()
809 par->chip == CHIP_260_VIRGE_MX) in s3fb_set_par()
810 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); in s3fb_set_par()
812 svga_wcrt_mask(par->state.vgabase, 0x67, 0x10, 0xF0); in s3fb_set_par()
813 multiplex = 1; in s3fb_set_par()
818 if (par->chip == CHIP_988_VIRGE_VX) { in s3fb_set_par()
819 if (info->var.pixclock > 20000) in s3fb_set_par()
820 svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0); in s3fb_set_par()
822 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0); in s3fb_set_par()
823 } else if (par->chip == CHIP_365_TRIO3D) { in s3fb_set_par()
824 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); in s3fb_set_par()
825 if (info->var.pixclock > 8695) { in s3fb_set_par()
826 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0); in s3fb_set_par()
829 svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0); in s3fb_set_par()
830 multiplex = 1; in s3fb_set_par()
833 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); in s3fb_set_par()
834 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0); in s3fb_set_par()
835 if (par->chip != CHIP_357_VIRGE_GX2 && in s3fb_set_par()
836 par->chip != CHIP_359_VIRGE_GX2P && in s3fb_set_par()
837 par->chip != CHIP_360_TRIO3D_1X && in s3fb_set_par()
838 par->chip != CHIP_362_TRIO3D_2X && in s3fb_set_par()
839 par->chip != CHIP_368_TRIO3D_2X && in s3fb_set_par()
840 par->chip != CHIP_260_VIRGE_MX) in s3fb_set_par()
846 if (par->chip == CHIP_988_VIRGE_VX) { in s3fb_set_par()
847 if (info->var.pixclock > 20000) in s3fb_set_par()
848 svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0); in s3fb_set_par()
850 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0); in s3fb_set_par()
851 } else if (par->chip == CHIP_365_TRIO3D) { in s3fb_set_par()
852 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); in s3fb_set_par()
853 if (info->var.pixclock > 8695) { in s3fb_set_par()
854 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0); in s3fb_set_par()
857 svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0); in s3fb_set_par()
858 multiplex = 1; in s3fb_set_par()
861 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); in s3fb_set_par()
862 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0); in s3fb_set_par()
863 if (par->chip != CHIP_357_VIRGE_GX2 && in s3fb_set_par()
864 par->chip != CHIP_359_VIRGE_GX2P && in s3fb_set_par()
865 par->chip != CHIP_360_TRIO3D_1X && in s3fb_set_par()
866 par->chip != CHIP_362_TRIO3D_2X && in s3fb_set_par()
867 par->chip != CHIP_368_TRIO3D_2X && in s3fb_set_par()
868 par->chip != CHIP_260_VIRGE_MX) in s3fb_set_par()
875 svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0); in s3fb_set_par()
879 svga_wcrt_mask(par->state.vgabase, 0x50, 0x30, 0x30); in s3fb_set_par()
880 svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0); in s3fb_set_par()
883 fb_err(info, "unsupported mode - bug\n"); in s3fb_set_par()
884 return -EINVAL; in s3fb_set_par()
887 if (par->chip != CHIP_988_VIRGE_VX) { in s3fb_set_par()
888 svga_wseq_mask(par->state.vgabase, 0x15, multiplex ? 0x10 : 0x00, 0x10); in s3fb_set_par()
889 svga_wseq_mask(par->state.vgabase, 0x18, multiplex ? 0x80 : 0x00, 0x80); in s3fb_set_par()
892 s3_set_pixclock(info, info->var.pixclock); in s3fb_set_par()
893 svga_set_timings(par->state.vgabase, &s3_timing_regs, &(info->var), hmul, 1, in s3fb_set_par()
894 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, in s3fb_set_par()
895 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1, in s3fb_set_par()
896 hmul, info->node); in s3fb_set_par()
899 htotal = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len; in s3fb_set_par()
900 htotal = ((htotal * hmul) / 8) - 5; in s3fb_set_par()
901 vga_wcrt(par->state.vgabase, 0x3C, (htotal + 1) / 2); in s3fb_set_par()
904 hsstart = ((info->var.xres + info->var.right_margin) * hmul) / 8; in s3fb_set_par()
907 svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value); in s3fb_set_par()
909 if (screen_size > info->screen_size) in s3fb_set_par()
910 screen_size = info->screen_size; in s3fb_set_par()
911 memset_io(info->screen_base, 0x00, screen_size); in s3fb_set_par()
913 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80); in s3fb_set_par()
914 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20); in s3fb_set_par()
924 switch (fb->var.bits_per_pixel) { in s3fb_setcolreg()
928 return -EINVAL; in s3fb_setcolreg()
930 if ((fb->var.bits_per_pixel == 4) && in s3fb_setcolreg()
931 (fb->var.nonstd == 0)) { in s3fb_setcolreg()
944 return -EINVAL; in s3fb_setcolreg()
956 if (fb->var.green.length == 5) in s3fb_setcolreg()
957 ((u32*)fb->pseudo_palette)[regno] = ((red & 0xF800) >> 1) | in s3fb_setcolreg()
959 else if (fb->var.green.length == 6) in s3fb_setcolreg()
960 ((u32*)fb->pseudo_palette)[regno] = (red & 0xF800) | in s3fb_setcolreg()
962 else return -EINVAL; in s3fb_setcolreg()
969 ((u32*)fb->pseudo_palette)[regno] = ((red & 0xFF00) << 8) | in s3fb_setcolreg()
973 return -EINVAL; in s3fb_setcolreg()
984 struct s3fb_info *par = info->par; in s3fb_blank()
989 svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06); in s3fb_blank()
990 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20); in s3fb_blank()
994 svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06); in s3fb_blank()
995 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20); in s3fb_blank()
999 svga_wcrt_mask(par->state.vgabase, 0x56, 0x02, 0x06); in s3fb_blank()
1000 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20); in s3fb_blank()
1004 svga_wcrt_mask(par->state.vgabase, 0x56, 0x04, 0x06); in s3fb_blank()
1005 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20); in s3fb_blank()
1009 svga_wcrt_mask(par->state.vgabase, 0x56, 0x06, 0x06); in s3fb_blank()
1010 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20); in s3fb_blank()
1022 struct s3fb_info *par = info->par; in s3fb_pan_display()
1026 if (info->var.bits_per_pixel == 0) { in s3fb_pan_display()
1027 offset = (var->yoffset / 16) * (info->var.xres_virtual / 2) in s3fb_pan_display()
1028 + (var->xoffset / 2); in s3fb_pan_display()
1031 offset = (var->yoffset * info->fix.line_length) + in s3fb_pan_display()
1032 (var->xoffset * info->var.bits_per_pixel / 8); in s3fb_pan_display()
1037 svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, offset); in s3fb_pan_display()
1042 /* ------------------------------------------------------------------------- */
1061 /* ------------------------------------------------------------------------- */
1065 int chip = par->chip; in s3_identification()
1068 u8 cr30 = vga_rcrt(par->state.vgabase, 0x30); in s3_identification()
1069 u8 cr2e = vga_rcrt(par->state.vgabase, 0x2e); in s3_identification()
1070 u8 cr2f = vga_rcrt(par->state.vgabase, 0x2f); in s3_identification()
1085 u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f); in s3_identification()
1094 u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f); in s3_identification()
1103 switch (vga_rcrt(par->state.vgabase, 0x2f)) { in s3_identification()
1131 dev_info(&(dev->dev), "ignoring secondary device\n"); in s3_pci_probe()
1132 return -ENODEV; in s3_pci_probe()
1140 info = framebuffer_alloc(sizeof(struct s3fb_info), &(dev->dev)); in s3_pci_probe()
1142 return -ENOMEM; in s3_pci_probe()
1144 par = info->par; in s3_pci_probe()
1145 mutex_init(&par->open_lock); in s3_pci_probe()
1147 info->flags = FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN; in s3_pci_probe()
1148 info->fbops = &s3fb_ops; in s3_pci_probe()
1153 dev_err(info->device, "cannot enable PCI device\n"); in s3_pci_probe()
1159 dev_err(info->device, "cannot reserve framebuffer region\n"); in s3_pci_probe()
1164 info->fix.smem_start = pci_resource_start(dev, 0); in s3_pci_probe()
1165 info->fix.smem_len = pci_resource_len(dev, 0); in s3_pci_probe()
1167 /* Map physical IO memory address into kernel space */ in s3_pci_probe()
1168 info->screen_base = pci_iomap_wc(dev, 0, 0); in s3_pci_probe()
1169 if (! info->screen_base) { in s3_pci_probe()
1170 rc = -ENOMEM; in s3_pci_probe()
1171 dev_err(info->device, "iomap for framebuffer failed\n"); in s3_pci_probe()
1180 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg); in s3_pci_probe()
1182 par->state.vgabase = (void __iomem *) (unsigned long) vga_res.start; in s3_pci_probe()
1185 cr38 = vga_rcrt(par->state.vgabase, 0x38); in s3_pci_probe()
1186 cr39 = vga_rcrt(par->state.vgabase, 0x39); in s3_pci_probe()
1187 vga_wseq(par->state.vgabase, 0x08, 0x06); in s3_pci_probe()
1188 vga_wcrt(par->state.vgabase, 0x38, 0x48); in s3_pci_probe()
1189 vga_wcrt(par->state.vgabase, 0x39, 0xA5); in s3_pci_probe()
1192 par->chip = id->driver_data & CHIP_MASK; in s3_pci_probe()
1193 par->rev = vga_rcrt(par->state.vgabase, 0x2f); in s3_pci_probe()
1194 if (par->chip & CHIP_UNDECIDED_FLAG) in s3_pci_probe()
1195 par->chip = s3_identification(par); in s3_pci_probe()
1199 regval = vga_rcrt(par->state.vgabase, 0x36); in s3_pci_probe()
1200 if (par->chip == CHIP_360_TRIO3D_1X || in s3_pci_probe()
1201 par->chip == CHIP_362_TRIO3D_2X || in s3_pci_probe()
1202 par->chip == CHIP_368_TRIO3D_2X || in s3_pci_probe()
1203 par->chip == CHIP_365_TRIO3D) { in s3_pci_probe()
1205 case 0: /* 8MB -- only 4MB usable for display */ in s3_pci_probe()
1206 case 1: /* 4MB with 32-bit bus */ in s3_pci_probe()
1208 info->screen_size = 4 << 20; in s3_pci_probe()
1212 info->screen_size = 2 << 20; in s3_pci_probe()
1215 } else if (par->chip == CHIP_357_VIRGE_GX2 || in s3_pci_probe()
1216 par->chip == CHIP_359_VIRGE_GX2P || in s3_pci_probe()
1217 par->chip == CHIP_260_VIRGE_MX) { in s3_pci_probe()
1220 info->screen_size = 4 << 20; in s3_pci_probe()
1223 info->screen_size = 2 << 20; in s3_pci_probe()
1226 } else if (par->chip == CHIP_988_VIRGE_VX) { in s3_pci_probe()
1229 info->screen_size = 2 << 20; in s3_pci_probe()
1232 info->screen_size = 4 << 20; in s3_pci_probe()
1235 info->screen_size = 6 << 20; in s3_pci_probe()
1238 info->screen_size = 8 << 20; in s3_pci_probe()
1241 /* off-screen memory */ in s3_pci_probe()
1242 regval = vga_rcrt(par->state.vgabase, 0x37); in s3_pci_probe()
1245 info->screen_size -= 4 << 20; in s3_pci_probe()
1248 info->screen_size -= 2 << 20; in s3_pci_probe()
1252 info->screen_size = s3_memsizes[regval >> 5] << 10; in s3_pci_probe()
1253 info->fix.smem_len = info->screen_size; in s3_pci_probe()
1256 regval = vga_rseq(par->state.vgabase, 0x10); in s3_pci_probe()
1257 par->mclk_freq = ((vga_rseq(par->state.vgabase, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2); in s3_pci_probe()
1258 par->mclk_freq = par->mclk_freq >> (regval >> 5); in s3_pci_probe()
1261 vga_wcrt(par->state.vgabase, 0x38, cr38); in s3_pci_probe()
1262 vga_wcrt(par->state.vgabase, 0x39, cr39); in s3_pci_probe()
1264 strcpy(info->fix.id, s3_names [par->chip]); in s3_pci_probe()
1265 info->fix.mmio_start = 0; in s3_pci_probe()
1266 info->fix.mmio_len = 0; in s3_pci_probe()
1267 info->fix.type = FB_TYPE_PACKED_PIXELS; in s3_pci_probe()
1268 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; in s3_pci_probe()
1269 info->fix.ypanstep = 0; in s3_pci_probe()
1270 info->fix.accel = FB_ACCEL_NONE; in s3_pci_probe()
1271 info->pseudo_palette = (void*) (par->pseudo_palette); in s3_pci_probe()
1272 info->var.bits_per_pixel = 8; in s3_pci_probe()
1276 if (s3fb_ddc_needs_mmio(par->chip)) { in s3_pci_probe()
1277 par->mmio = ioremap(info->fix.smem_start + MMIO_OFFSET, MMIO_SIZE); in s3_pci_probe()
1278 if (par->mmio) in s3_pci_probe()
1279 svga_wcrt_mask(par->state.vgabase, 0x53, 0x08, 0x08); /* enable MMIO */ in s3_pci_probe()
1281 dev_err(info->device, "unable to map MMIO at 0x%lx, disabling DDC", in s3_pci_probe()
1282 info->fix.smem_start + MMIO_OFFSET); in s3_pci_probe()
1284 if (!s3fb_ddc_needs_mmio(par->chip) || par->mmio) in s3_pci_probe()
1286 u8 *edid = fb_ddc_read(&par->ddc_adapter); in s3_pci_probe()
1287 par->ddc_registered = true; in s3_pci_probe()
1289 fb_edid_to_monspecs(edid, &info->monspecs); in s3_pci_probe()
1291 if (!info->monspecs.modedb) in s3_pci_probe()
1292 dev_err(info->device, "error getting mode database\n"); in s3_pci_probe()
1296 fb_videomode_to_modelist(info->monspecs.modedb, in s3_pci_probe()
1297 info->monspecs.modedb_len, in s3_pci_probe()
1298 &info->modelist); in s3_pci_probe()
1299 m = fb_find_best_display(&info->monspecs, &info->modelist); in s3_pci_probe()
1301 fb_videomode_to_var(&info->var, m); in s3_pci_probe()
1302 /* fill all other info->var's fields */ in s3_pci_probe()
1303 if (s3fb_check_var(&info->var, info) == 0) in s3_pci_probe()
1311 mode_option = "640x480-8@60"; in s3_pci_probe()
1315 rc = fb_find_mode(&info->var, info, mode_option, in s3_pci_probe()
1316 info->monspecs.modedb, info->monspecs.modedb_len, in s3_pci_probe()
1317 NULL, info->var.bits_per_pixel); in s3_pci_probe()
1319 rc = -EINVAL; in s3_pci_probe()
1320 dev_err(info->device, "mode %s not found\n", mode_option); in s3_pci_probe()
1321 fb_destroy_modedb(info->monspecs.modedb); in s3_pci_probe()
1322 info->monspecs.modedb = NULL; in s3_pci_probe()
1327 fb_destroy_modedb(info->monspecs.modedb); in s3_pci_probe()
1328 info->monspecs.modedb = NULL; in s3_pci_probe()
1331 info->var.yres_virtual = info->fix.smem_len * 8 / in s3_pci_probe()
1332 (info->var.bits_per_pixel * info->var.xres_virtual); in s3_pci_probe()
1333 if (info->var.yres_virtual < info->var.yres) { in s3_pci_probe()
1334 dev_err(info->device, "virtual vertical size smaller than real\n"); in s3_pci_probe()
1335 rc = -EINVAL; in s3_pci_probe()
1339 rc = fb_alloc_cmap(&info->cmap, 256, 0); in s3_pci_probe()
1341 dev_err(info->device, "cannot allocate colormap\n"); in s3_pci_probe()
1347 dev_err(info->device, "cannot register framebuffer\n"); in s3_pci_probe()
1352 info->fix.id, pci_name(dev), in s3_pci_probe()
1353 info->fix.smem_len >> 20, (par->mclk_freq + 500) / 1000); in s3_pci_probe()
1355 if (par->chip == CHIP_UNKNOWN) in s3_pci_probe()
1357 vga_rcrt(par->state.vgabase, 0x2d), in s3_pci_probe()
1358 vga_rcrt(par->state.vgabase, 0x2e), in s3_pci_probe()
1359 vga_rcrt(par->state.vgabase, 0x2f), in s3_pci_probe()
1360 vga_rcrt(par->state.vgabase, 0x30)); in s3_pci_probe()
1366 par->wc_cookie = arch_phys_wc_add(info->fix.smem_start, in s3_pci_probe()
1367 info->fix.smem_len); in s3_pci_probe()
1373 fb_dealloc_cmap(&info->cmap); in s3_pci_probe()
1377 if (par->ddc_registered) in s3_pci_probe()
1378 i2c_del_adapter(&par->ddc_adapter); in s3_pci_probe()
1379 if (par->mmio) in s3_pci_probe()
1380 iounmap(par->mmio); in s3_pci_probe()
1382 pci_iounmap(dev, info->screen_base); in s3_pci_probe()
1401 par = info->par; in s3_pci_remove()
1402 arch_phys_wc_del(par->wc_cookie); in s3_pci_remove()
1404 fb_dealloc_cmap(&info->cmap); in s3_pci_remove()
1407 if (par->ddc_registered) in s3_pci_remove()
1408 i2c_del_adapter(&par->ddc_adapter); in s3_pci_remove()
1409 if (par->mmio) in s3_pci_remove()
1410 iounmap(par->mmio); in s3_pci_remove()
1413 pci_iounmap(dev, info->screen_base); in s3_pci_remove()
1426 struct s3fb_info *par = info->par; in s3_pci_suspend()
1428 dev_info(info->device, "suspend\n"); in s3_pci_suspend()
1431 mutex_lock(&(par->open_lock)); in s3_pci_suspend()
1433 if (par->ref_count == 0) { in s3_pci_suspend()
1434 mutex_unlock(&(par->open_lock)); in s3_pci_suspend()
1441 mutex_unlock(&(par->open_lock)); in s3_pci_suspend()
1453 struct s3fb_info *par = info->par; in s3_pci_resume()
1455 dev_info(info->device, "resume\n"); in s3_pci_resume()
1458 mutex_lock(&(par->open_lock)); in s3_pci_resume()
1460 if (par->ref_count == 0) { in s3_pci_resume()
1461 mutex_unlock(&(par->open_lock)); in s3_pci_resume()
1469 mutex_unlock(&(par->open_lock)); in s3_pci_resume()
1563 return -ENODEV; in s3fb_init()
1571 /* ------------------------------------------------------------------------- */