Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[sfrench/cifs-2.6.git] / drivers / video / s3fb.c
index 946a949f4c7d44cba635432f92c7591a54b773ab..2c80246b18b88eee0b22a90c8fbc5581c02aad96 100644 (file)
@@ -727,7 +727,7 @@ static int s3fb_set_par(struct fb_info *info)
        if (par->chip == CHIP_988_VIRGE_VX) {
                vga_wcrt(par->state.vgabase, 0x50, 0x00);
                vga_wcrt(par->state.vgabase, 0x67, 0x50);
-
+               msleep(10); /* screen remains blank sometimes without this */
                vga_wcrt(par->state.vgabase, 0x63, (mode <= 2) ? 0x90 : 0x09);
                vga_wcrt(par->state.vgabase, 0x66, 0x90);
        }
@@ -901,7 +901,8 @@ static int s3fb_set_par(struct fb_info *info)
 
        /* Set Data Transfer Position */
        hsstart = ((info->var.xres + info->var.right_margin) * hmul) / 8;
-       value = clamp((htotal + hsstart + 1) / 2, hsstart + 4, htotal + 1);
+       /* + 2 is needed for Virge/VX, does no harm on other cards */
+       value = clamp((htotal + hsstart + 1) / 2 + 2, hsstart + 4, htotal + 1);
        svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value);
 
        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
                        info->screen_size = 2 << 20;
                        break;
                }
+       } else if (par->chip == CHIP_988_VIRGE_VX) {
+               switch ((regval & 0x60) >> 5) {
+               case 0: /* 2MB */
+                       info->screen_size = 2 << 20;
+                       break;
+               case 1: /* 4MB */
+                       info->screen_size = 4 << 20;
+                       break;
+               case 2: /* 6MB */
+                       info->screen_size = 6 << 20;
+                       break;
+               case 3: /* 8MB */
+                       info->screen_size = 8 << 20;
+                       break;
+               }
+               /* off-screen memory */
+               regval = vga_rcrt(par->state.vgabase, 0x37);
+               switch ((regval & 0x60) >> 5) {
+               case 1: /* 4MB */
+                       info->screen_size -= 4 << 20;
+                       break;
+               case 2: /* 2MB */
+                       info->screen_size -= 2 << 20;
+                       break;
+               }
        } else
                info->screen_size = s3_memsizes[regval >> 5] << 10;
        info->fix.smem_len = info->screen_size;