diff options
author | Ondrej Zary <linux@rainbow-software.org> | 2011-03-01 14:18:35 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-03-22 02:49:56 -0400 |
commit | cb11c048928b519548dbfb7da149dd2521500db0 (patch) | |
tree | 201a324a4063f794aa7fd9f354dd68e5f0b5c2cf /drivers/video/s3fb.c | |
parent | 3827d10ed4278323b75bf25d09c146c050519254 (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.c | 28 |
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, | |||
126 | static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x31, 4, 5}, {0x51, 0, 1}, VGA_REGSET_END}; | 126 | static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x31, 4, 5}, {0x51, 0, 1}, VGA_REGSET_END}; |
127 | static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */ | 127 | static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */ |
128 | 128 | ||
129 | static const struct vga_regset s3_dtpc_regs[] = {{0x3B, 0, 7}, {0x5D, 6, 6}, VGA_REGSET_END}; | ||
130 | |||
129 | static const struct svga_timing_regs s3_timing_regs = { | 131 | static 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 */ |