Commit 66cde97da7cbbc940cb3f3dbf9e8f0ac56431f8c

Authored by Ondrej Zary
Committed by Florian Tobias Schandinat
1 parent 396fa99e0e

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>

Showing 1 changed file with 28 additions and 2 deletions Side-by-side Diff

drivers/video/s3fb.c
... ... @@ -727,7 +727,7 @@
727 727 if (par->chip == CHIP_988_VIRGE_VX) {
728 728 vga_wcrt(par->state.vgabase, 0x50, 0x00);
729 729 vga_wcrt(par->state.vgabase, 0x67, 0x50);
730   -
  730 + msleep(10); /* screen remains blank sometimes without this */
731 731 vga_wcrt(par->state.vgabase, 0x63, (mode <= 2) ? 0x90 : 0x09);
732 732 vga_wcrt(par->state.vgabase, 0x66, 0x90);
733 733 }
... ... @@ -901,7 +901,8 @@
901 901  
902 902 /* Set Data Transfer Position */
903 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 906 svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value);
906 907  
907 908 memset_io(info->screen_base, 0x00, screen_size);
... ... @@ -1214,6 +1215,31 @@
1214 1215 break;
1215 1216 case 3: /* 2MB */
1216 1217 info->screen_size = 2 << 20;
  1218 + break;
  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;
1217 1243 break;
1218 1244 }
1219 1245 } else