aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/s3fb.c
diff options
context:
space:
mode:
authorOndrej Zary <linux@rainbow-software.org>2011-03-01 14:18:35 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-03-22 02:49:56 -0400
commitcb11c048928b519548dbfb7da149dd2521500db0 (patch)
tree201a324a4063f794aa7fd9f354dd68e5f0b5c2cf /drivers/video/s3fb.c
parent3827d10ed4278323b75bf25d09c146c050519254 (diff)
s3fb: enable DTPC
Enable Data Transfer Position Control (DTPC). This is needed at least on Virge/DX to correctly display at higher pixclocks. Signed-off-by: Ondrej Zary <linux@rainbow-software.org> Acked-by: Ondrej Zajicek <santiago@crfreenet.org> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/video/s3fb.c')
-rw-r--r--drivers/video/s3fb.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 7b8fdc6d9d55..808db19aa5de 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -126,6 +126,8 @@ static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07,
126static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x31, 4, 5}, {0x51, 0, 1}, VGA_REGSET_END}; 126static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x31, 4, 5}, {0x51, 0, 1}, VGA_REGSET_END};
127static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */ 127static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */
128 128
129static const struct vga_regset s3_dtpc_regs[] = {{0x3B, 0, 7}, {0x5D, 6, 6}, VGA_REGSET_END};
130
129static const struct svga_timing_regs s3_timing_regs = { 131static const struct svga_timing_regs s3_timing_regs = {
130 s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs, 132 s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs,
131 s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs, 133 s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs,
@@ -485,6 +487,7 @@ static int s3fb_set_par(struct fb_info *info)
485 struct s3fb_info *par = info->par; 487 struct s3fb_info *par = info->par;
486 u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes; 488 u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes;
487 u32 bpp = info->var.bits_per_pixel; 489 u32 bpp = info->var.bits_per_pixel;
490 u32 htotal, hsstart;
488 491
489 if (bpp != 0) { 492 if (bpp != 0) {
490 info->fix.ypanstep = 1; 493 info->fix.ypanstep = 1;
@@ -604,7 +607,9 @@ static int s3fb_set_par(struct fb_info *info)
604 if (par->chip == CHIP_360_TRIO3D_1X || 607 if (par->chip == CHIP_360_TRIO3D_1X ||
605 par->chip == CHIP_362_TRIO3D_2X || 608 par->chip == CHIP_362_TRIO3D_2X ||
606 par->chip == CHIP_368_TRIO3D_2X || 609 par->chip == CHIP_368_TRIO3D_2X ||
607 par->chip == CHIP_365_TRIO3D) { 610 par->chip == CHIP_365_TRIO3D ||
611 par->chip == CHIP_375_VIRGE_DX ||
612 par->chip == CHIP_385_VIRGE_GX) {
608 dbytes = info->var.xres * ((bpp+7)/8); 613 dbytes = info->var.xres * ((bpp+7)/8);
609 vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8); 614 vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8);
610 vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80); 615 vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80);
@@ -612,6 +617,16 @@ static int s3fb_set_par(struct fb_info *info)
612 vga_wcrt(par->state.vgabase, 0x66, 0x81); 617 vga_wcrt(par->state.vgabase, 0x66, 0x81);
613 } 618 }
614 619
620 if (par->chip == CHIP_356_VIRGE_GX2 ||
621 par->chip == CHIP_357_VIRGE_GX2P ||
622 par->chip == CHIP_359_VIRGE_GX2P ||
623 par->chip == CHIP_360_TRIO3D_1X ||
624 par->chip == CHIP_362_TRIO3D_2X ||
625 par->chip == CHIP_368_TRIO3D_2X)
626 vga_wcrt(par->state.vgabase, 0x34, 0x00);
627 else /* enable Data Transfer Position Control (DTPC) */
628 vga_wcrt(par->state.vgabase, 0x34, 0x10);
629
615 svga_wcrt_mask(par->state.vgabase, 0x31, 0x00, 0x40); 630 svga_wcrt_mask(par->state.vgabase, 0x31, 0x00, 0x40);
616 multiplex = 0; 631 multiplex = 0;
617 hmul = 1; 632 hmul = 1;
@@ -745,9 +760,14 @@ static int s3fb_set_par(struct fb_info *info)
745 hmul, info->node); 760 hmul, info->node);
746 761
747 /* Set interlaced mode start/end register */ 762 /* Set interlaced mode start/end register */
748 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len; 763 htotal = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
749 value = ((value * hmul) / 8) - 5; 764 htotal = ((htotal * hmul) / 8) - 5;
750 vga_wcrt(par->state.vgabase, 0x3C, (value + 1) / 2); 765 vga_wcrt(par->state.vgabase, 0x3C, (htotal + 1) / 2);
766
767 /* Set Data Transfer Position */
768 hsstart = ((info->var.xres + info->var.right_margin) * hmul) / 8;
769 value = clamp((htotal + hsstart + 1) / 2, hsstart + 4, htotal + 1);
770 svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value);
751 771
752 memset_io(info->screen_base, 0x00, screen_size); 772 memset_io(info->screen_base, 0x00, screen_size);
753 /* Device and screen back on */ 773 /* Device and screen back on */