aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/s3fb.c
diff options
context:
space:
mode:
authorOndrej Zary <linux@rainbow-software.org>2011-12-19 17:39:47 -0500
committerFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-12-20 21:25:21 -0500
commit66cde97da7cbbc940cb3f3dbf9e8f0ac56431f8c (patch)
tree7d9ffe066cebc2724b95c585f26d19f62c4248a9 /drivers/video/s3fb.c
parent396fa99e0e58198f400110f2b6432b5b6522476b (diff)
s3fb: fix Virge/VX
Add memory size detection for Virge/VX and small delay in mode setting (same as in X.org driver) to fix blank screen problem. Also adjust DTPC position to fix garbled screen in some modes (tested that this adjustment does not break other cards - at least Trio32, Trio64V+, Trio64V2/DX, Virge, Virge/DX). Tested on ELSA Winner 2000AVI/3D. Signed-off-by: Ondrej Zary <linux@rainbow-software.org> Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Diffstat (limited to 'drivers/video/s3fb.c')
-rw-r--r--drivers/video/s3fb.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 946a949f4c7d..2c80246b18b8 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -727,7 +727,7 @@ static int s3fb_set_par(struct fb_info *info)
727 if (par->chip == CHIP_988_VIRGE_VX) { 727 if (par->chip == CHIP_988_VIRGE_VX) {
728 vga_wcrt(par->state.vgabase, 0x50, 0x00); 728 vga_wcrt(par->state.vgabase, 0x50, 0x00);
729 vga_wcrt(par->state.vgabase, 0x67, 0x50); 729 vga_wcrt(par->state.vgabase, 0x67, 0x50);
730 730 msleep(10); /* screen remains blank sometimes without this */
731 vga_wcrt(par->state.vgabase, 0x63, (mode <= 2) ? 0x90 : 0x09); 731 vga_wcrt(par->state.vgabase, 0x63, (mode <= 2) ? 0x90 : 0x09);
732 vga_wcrt(par->state.vgabase, 0x66, 0x90); 732 vga_wcrt(par->state.vgabase, 0x66, 0x90);
733 } 733 }
@@ -901,7 +901,8 @@ static int s3fb_set_par(struct fb_info *info)
901 901
902 /* Set Data Transfer Position */ 902 /* Set Data Transfer Position */
903 hsstart = ((info->var.xres + info->var.right_margin) * hmul) / 8; 903 hsstart = ((info->var.xres + info->var.right_margin) * hmul) / 8;
904 value = clamp((htotal + hsstart + 1) / 2, hsstart + 4, htotal + 1); 904 /* + 2 is needed for Virge/VX, does no harm on other cards */
905 value = clamp((htotal + hsstart + 1) / 2 + 2, hsstart + 4, htotal + 1);
905 svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value); 906 svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value);
906 907
907 memset_io(info->screen_base, 0x00, screen_size); 908 memset_io(info->screen_base, 0x00, screen_size);
@@ -1216,6 +1217,31 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1216 info->screen_size = 2 << 20; 1217 info->screen_size = 2 << 20;
1217 break; 1218 break;
1218 } 1219 }
1220 } else if (par->chip == CHIP_988_VIRGE_VX) {
1221 switch ((regval & 0x60) >> 5) {
1222 case 0: /* 2MB */
1223 info->screen_size = 2 << 20;
1224 break;
1225 case 1: /* 4MB */
1226 info->screen_size = 4 << 20;
1227 break;
1228 case 2: /* 6MB */
1229 info->screen_size = 6 << 20;
1230 break;
1231 case 3: /* 8MB */
1232 info->screen_size = 8 << 20;
1233 break;
1234 }
1235 /* off-screen memory */
1236 regval = vga_rcrt(par->state.vgabase, 0x37);
1237 switch ((regval & 0x60) >> 5) {
1238 case 1: /* 4MB */
1239 info->screen_size -= 4 << 20;
1240 break;
1241 case 2: /* 2MB */
1242 info->screen_size -= 2 << 20;
1243 break;
1244 }
1219 } else 1245 } else
1220 info->screen_size = s3_memsizes[regval >> 5] << 10; 1246 info->screen_size = s3_memsizes[regval >> 5] << 10;
1221 info->fix.smem_len = info->screen_size; 1247 info->fix.smem_len = info->screen_size;