diff options
author | Ondrej Zary <linux@rainbow-software.org> | 2011-03-29 15:07:08 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-03-31 00:48:58 -0400 |
commit | 94e948e6e43cd34e0e2ca496d5e90e4ff0d884f9 (patch) | |
tree | e67f3b5e4ed3166f2bb2fd16a5900df2ad65426a /drivers/video/s3fb.c | |
parent | 62e0ff1ef2d8ea0814487f73a7de431396a1e914 (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.c | 48 |
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 | ||
72 | static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", "S3 Trio64V+", | 72 | static 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}, |