aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/s3fb.c
diff options
context:
space:
mode:
authorOndrej Zary <linux@rainbow-software.org>2011-03-29 15:07:08 -0400
committerPaul Mundt <lethal@linux-sh.org>2011-03-31 00:48:58 -0400
commit94e948e6e43cd34e0e2ca496d5e90e4ff0d884f9 (patch)
treee67f3b5e4ed3166f2bb2fd16a5900df2ad65426a /drivers/video/s3fb.c
parent62e0ff1ef2d8ea0814487f73a7de431396a1e914 (diff)
s3fb: fix Virge/GX2
Fix Virge/GX2 support in s3fb: - fix IDs: 86C357 is GX2, 86C359 is GX2+, 86C356 probably does not exist - add memory size detection - drive it the same way as Trio3D/2X The original IDs most likely came from S3 website which claims that: - 356 is Virge/GX2 with ID=8A10, driver included in Windows 2K, XP - 357 is Virge/GX2+ with ID=8A11, driver included in Windows ME - 359 is Virge/GX2+ with ID=8A12, driver included in Windows ME but: - google search for 86C356 only reveals references to Trio3D (probably because of a typo - Trio3D is 86C365) - my card is clearly marked as 86C357, Virge/GX2 and has ID=8A10 - there is no driver for IDs 8A11 and 8A12 in Windows ME - there is a driver for ID 8A10 in Windows ME that says it's GX2 (357) Tested with #9 Reality 334 (86C357 Virge/GX2, ID=0x8A10). Signed-off-by: Ondrej Zary <linux@rainbow-software.org> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/video/s3fb.c')
-rw-r--r--drivers/video/s3fb.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index ddedad9cd069..c4482f2e5799 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -71,9 +71,9 @@ static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512};
71 71
72static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", "S3 Trio64V+", 72static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", "S3 Trio64V+",
73 "S3 Trio64UV+", "S3 Trio64V2/DX", "S3 Trio64V2/GX", 73 "S3 Trio64UV+", "S3 Trio64V2/DX", "S3 Trio64V2/GX",
74 "S3 Plato/PX", "S3 Aurora64VP", "S3 Virge", 74 "S3 Plato/PX", "S3 Aurora64V+", "S3 Virge",
75 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX", 75 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX",
76 "S3 Virge/GX2", "S3 Virge/GX2P", "S3 Virge/GX2P", 76 "S3 Virge/GX2", "S3 Virge/GX2+", "",
77 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X", 77 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X",
78 "S3 Trio3D"}; 78 "S3 Trio3D"};
79 79
@@ -90,9 +90,8 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
90#define CHIP_988_VIRGE_VX 0x0A 90#define CHIP_988_VIRGE_VX 0x0A
91#define CHIP_375_VIRGE_DX 0x0B 91#define CHIP_375_VIRGE_DX 0x0B
92#define CHIP_385_VIRGE_GX 0x0C 92#define CHIP_385_VIRGE_GX 0x0C
93#define CHIP_356_VIRGE_GX2 0x0D 93#define CHIP_357_VIRGE_GX2 0x0D
94#define CHIP_357_VIRGE_GX2P 0x0E 94#define CHIP_359_VIRGE_GX2P 0x0E
95#define CHIP_359_VIRGE_GX2P 0x0F
96#define CHIP_360_TRIO3D_1X 0x10 95#define CHIP_360_TRIO3D_1X 0x10
97#define CHIP_362_TRIO3D_2X 0x11 96#define CHIP_362_TRIO3D_2X 0x11
98#define CHIP_368_TRIO3D_2X 0x12 97#define CHIP_368_TRIO3D_2X 0x12
@@ -359,7 +358,9 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock)
359 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 358 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
360 359
361 /* Set S3 clock registers */ 360 /* Set S3 clock registers */
362 if (par->chip == CHIP_360_TRIO3D_1X || 361 if (par->chip == CHIP_357_VIRGE_GX2 ||
362 par->chip == CHIP_359_VIRGE_GX2P ||
363 par->chip == CHIP_360_TRIO3D_1X ||
363 par->chip == CHIP_362_TRIO3D_2X || 364 par->chip == CHIP_362_TRIO3D_2X ||
364 par->chip == CHIP_368_TRIO3D_2X) { 365 par->chip == CHIP_368_TRIO3D_2X) {
365 vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */ 366 vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */
@@ -560,7 +561,9 @@ static int s3fb_set_par(struct fb_info *info)
560 pr_debug("fb%d: offset register : %d\n", info->node, offset_value); 561 pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
561 svga_wcrt_multi(par->state.vgabase, s3_offset_regs, offset_value); 562 svga_wcrt_multi(par->state.vgabase, s3_offset_regs, offset_value);
562 563
563 if (par->chip != CHIP_360_TRIO3D_1X && 564 if (par->chip != CHIP_357_VIRGE_GX2 &&
565 par->chip != CHIP_359_VIRGE_GX2P &&
566 par->chip != CHIP_360_TRIO3D_1X &&
564 par->chip != CHIP_362_TRIO3D_2X && 567 par->chip != CHIP_362_TRIO3D_2X &&
565 par->chip != CHIP_368_TRIO3D_2X) { 568 par->chip != CHIP_368_TRIO3D_2X) {
566 vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */ 569 vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */
@@ -604,7 +607,9 @@ static int s3fb_set_par(struct fb_info *info)
604 vga_wcrt(par->state.vgabase, 0x66, 0x90); 607 vga_wcrt(par->state.vgabase, 0x66, 0x90);
605 } 608 }
606 609
607 if (par->chip == CHIP_360_TRIO3D_1X || 610 if (par->chip == CHIP_357_VIRGE_GX2 ||
611 par->chip == CHIP_359_VIRGE_GX2P ||
612 par->chip == CHIP_360_TRIO3D_1X ||
608 par->chip == CHIP_362_TRIO3D_2X || 613 par->chip == CHIP_362_TRIO3D_2X ||
609 par->chip == CHIP_368_TRIO3D_2X || 614 par->chip == CHIP_368_TRIO3D_2X ||
610 par->chip == CHIP_365_TRIO3D || 615 par->chip == CHIP_365_TRIO3D ||
@@ -617,8 +622,7 @@ static int s3fb_set_par(struct fb_info *info)
617 vga_wcrt(par->state.vgabase, 0x66, 0x81); 622 vga_wcrt(par->state.vgabase, 0x66, 0x81);
618 } 623 }
619 624
620 if (par->chip == CHIP_356_VIRGE_GX2 || 625 if (par->chip == CHIP_357_VIRGE_GX2 ||
621 par->chip == CHIP_357_VIRGE_GX2P ||
622 par->chip == CHIP_359_VIRGE_GX2P || 626 par->chip == CHIP_359_VIRGE_GX2P ||
623 par->chip == CHIP_360_TRIO3D_1X || 627 par->chip == CHIP_360_TRIO3D_1X ||
624 par->chip == CHIP_362_TRIO3D_2X || 628 par->chip == CHIP_362_TRIO3D_2X ||
@@ -674,6 +678,8 @@ static int s3fb_set_par(struct fb_info *info)
674 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 678 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
675 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); 679 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
676 if (info->var.pixclock > 20000 || 680 if (info->var.pixclock > 20000 ||
681 par->chip == CHIP_357_VIRGE_GX2 ||
682 par->chip == CHIP_359_VIRGE_GX2P ||
677 par->chip == CHIP_360_TRIO3D_1X || 683 par->chip == CHIP_360_TRIO3D_1X ||
678 par->chip == CHIP_362_TRIO3D_2X || 684 par->chip == CHIP_362_TRIO3D_2X ||
679 par->chip == CHIP_368_TRIO3D_2X) 685 par->chip == CHIP_368_TRIO3D_2X)
@@ -702,7 +708,9 @@ static int s3fb_set_par(struct fb_info *info)
702 } else { 708 } else {
703 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); 709 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
704 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0); 710 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
705 if (par->chip != CHIP_360_TRIO3D_1X && 711 if (par->chip != CHIP_357_VIRGE_GX2 &&
712 par->chip != CHIP_359_VIRGE_GX2P &&
713 par->chip != CHIP_360_TRIO3D_1X &&
706 par->chip != CHIP_362_TRIO3D_2X && 714 par->chip != CHIP_362_TRIO3D_2X &&
707 par->chip != CHIP_368_TRIO3D_2X) 715 par->chip != CHIP_368_TRIO3D_2X)
708 hmul = 2; 716 hmul = 2;
@@ -727,7 +735,9 @@ static int s3fb_set_par(struct fb_info *info)
727 } else { 735 } else {
728 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30); 736 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
729 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0); 737 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
730 if (par->chip != CHIP_360_TRIO3D_1X && 738 if (par->chip != CHIP_357_VIRGE_GX2 &&
739 par->chip != CHIP_359_VIRGE_GX2P &&
740 par->chip != CHIP_360_TRIO3D_1X &&
731 par->chip != CHIP_362_TRIO3D_2X && 741 par->chip != CHIP_362_TRIO3D_2X &&
732 par->chip != CHIP_368_TRIO3D_2X) 742 par->chip != CHIP_368_TRIO3D_2X)
733 hmul = 2; 743 hmul = 2;
@@ -1069,6 +1079,16 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1069 info->screen_size = 2 << 20; 1079 info->screen_size = 2 << 20;
1070 break; 1080 break;
1071 } 1081 }
1082 } else if (par->chip == CHIP_357_VIRGE_GX2 ||
1083 par->chip == CHIP_359_VIRGE_GX2P) {
1084 switch ((regval & 0xC0) >> 6) {
1085 case 1: /* 4MB */
1086 info->screen_size = 4 << 20;
1087 break;
1088 case 3: /* 2MB */
1089 info->screen_size = 2 << 20;
1090 break;
1091 }
1072 } else 1092 } else
1073 info->screen_size = s3_memsizes[regval >> 5] << 10; 1093 info->screen_size = s3_memsizes[regval >> 5] << 10;
1074 info->fix.smem_len = info->screen_size; 1094 info->fix.smem_len = info->screen_size;
@@ -1268,8 +1288,8 @@ static struct pci_device_id s3_devices[] __devinitdata = {
1268 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x5631), .driver_data = CHIP_325_VIRGE}, 1288 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x5631), .driver_data = CHIP_325_VIRGE},
1269 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x883D), .driver_data = CHIP_988_VIRGE_VX}, 1289 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x883D), .driver_data = CHIP_988_VIRGE_VX},
1270 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A01), .driver_data = CHIP_XXX_VIRGE_DXGX}, 1290 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A01), .driver_data = CHIP_XXX_VIRGE_DXGX},
1271 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A10), .driver_data = CHIP_356_VIRGE_GX2}, 1291 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A10), .driver_data = CHIP_357_VIRGE_GX2},
1272 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P}, 1292 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_359_VIRGE_GX2P},
1273 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P}, 1293 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P},
1274 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X}, 1294 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X},
1275 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D}, 1295 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D},