diff options
-rw-r--r-- | drivers/video/s3fb.c | 30 |
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; |