diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2009-03-31 18:25:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-01 11:59:29 -0400 |
commit | df3aafd57d590d6f3d95310fc3430f3a536d1e59 (patch) | |
tree | ae9a277926309e9c9378df4cb10208cd6845a5b0 /drivers/video/cirrusfb.c | |
parent | 8f19e15b8ad23e28add5760ed049be2359f39fe8 (diff) |
cirrusfb: GD5434 (aka SD64) support fixed
Fix handling of the Cirrus Logic GD5434 chip. Distinguish this chip from the
GD5430. It allows detecting memory size for both models correctly.
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/cirrusfb.c')
-rw-r--r-- | drivers/video/cirrusfb.c | 72 |
1 files changed, 37 insertions, 35 deletions
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 620327436082..a364e1b0dcb7 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c | |||
@@ -145,7 +145,9 @@ static const struct cirrusfb_board_info_rec { | |||
145 | .scrn_start_bit19 = true, | 145 | .scrn_start_bit19 = true, |
146 | .sr07 = 0xF0, | 146 | .sr07 = 0xF0, |
147 | .sr07_1bpp = 0xF0, | 147 | .sr07_1bpp = 0xF0, |
148 | .sr07_1bpp_mux = 0xF6, | ||
148 | .sr07_8bpp = 0xF1, | 149 | .sr07_8bpp = 0xF1, |
150 | .sr07_8bpp_mux = 0xF7, | ||
149 | .sr1f = 0x1E | 151 | .sr1f = 0x1E |
150 | }, | 152 | }, |
151 | [BT_PICCOLO] = { | 153 | [BT_PICCOLO] = { |
@@ -262,8 +264,8 @@ static const struct cirrusfb_board_info_rec { | |||
262 | 264 | ||
263 | static struct pci_device_id cirrusfb_pci_table[] = { | 265 | static struct pci_device_id cirrusfb_pci_table[] = { |
264 | CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE), | 266 | CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE), |
265 | CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE), | 267 | CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64), |
266 | CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE), | 268 | CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64), |
267 | CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */ | 269 | CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */ |
268 | CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE), | 270 | CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE), |
269 | CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE), | 271 | CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE), |
@@ -341,6 +343,7 @@ struct cirrusfb_info { | |||
341 | unsigned char SFR; /* Shadow of special function register */ | 343 | unsigned char SFR; /* Shadow of special function register */ |
342 | 344 | ||
343 | int multiplexing; | 345 | int multiplexing; |
346 | int doubleVCLK; | ||
344 | int blank_mode; | 347 | int blank_mode; |
345 | u32 pseudo_palette[16]; | 348 | u32 pseudo_palette[16]; |
346 | 349 | ||
@@ -496,18 +499,15 @@ static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var, | |||
496 | break; | 499 | break; |
497 | } | 500 | } |
498 | } | 501 | } |
499 | #if 0 | 502 | |
500 | /* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where | 503 | /* If we have a 1MB 5434, we need to put ourselves in a mode where |
501 | * the VCLK is double the pixel clock. */ | 504 | * the VCLK is double the pixel clock. */ |
502 | switch (var->bits_per_pixel) { | 505 | cinfo->doubleVCLK = 0; |
503 | case 16: | 506 | if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ && |
504 | case 24: | 507 | var->bits_per_pixel == 16) { |
505 | if (var->xres <= 800) | 508 | cinfo->doubleVCLK = 1; |
506 | /* Xbh has this type of clock for 32-bit */ | ||
507 | freq /= 2; | ||
508 | break; | ||
509 | } | 509 | } |
510 | #endif | 510 | |
511 | return 0; | 511 | return 0; |
512 | } | 512 | } |
513 | 513 | ||
@@ -830,10 +830,13 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
830 | vga_wcrt(regbase, CL_CRT1A, tmp); | 830 | vga_wcrt(regbase, CL_CRT1A, tmp); |
831 | 831 | ||
832 | freq = PICOS2KHZ(var->pixclock); | 832 | freq = PICOS2KHZ(var->pixclock); |
833 | if (cinfo->btype == BT_ALPINE && var->bits_per_pixel == 24) | 833 | if (var->bits_per_pixel == 24) |
834 | freq *= 3; | 834 | if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) |
835 | freq *= 3; | ||
835 | if (cinfo->multiplexing) | 836 | if (cinfo->multiplexing) |
836 | freq /= 2; | 837 | freq /= 2; |
838 | if (cinfo->doubleVCLK) | ||
839 | freq *= 2; | ||
837 | 840 | ||
838 | bestclock(freq, &nom, &den, &div); | 841 | bestclock(freq, &nom, &den, &div); |
839 | 842 | ||
@@ -851,10 +854,9 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
851 | * as clock source | 854 | * as clock source |
852 | */ | 855 | */ |
853 | int divMCLK = cirrusfb_check_mclk(info, freq); | 856 | int divMCLK = cirrusfb_check_mclk(info, freq); |
854 | if (divMCLK) { | 857 | if (divMCLK) |
855 | nom = 0; | 858 | nom = 0; |
856 | cirrusfb_set_mclk_as_source(info, divMCLK); | 859 | cirrusfb_set_mclk_as_source(info, divMCLK); |
857 | } | ||
858 | } | 860 | } |
859 | if (is_laguna(cinfo)) { | 861 | if (is_laguna(cinfo)) { |
860 | long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc); | 862 | long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc); |
@@ -885,14 +887,13 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
885 | (cinfo->btype == BT_GD5480)) | 887 | (cinfo->btype == BT_GD5480)) |
886 | tmp |= 0x80; | 888 | tmp |= 0x80; |
887 | 889 | ||
888 | dev_dbg(info->device, "CL_SEQR1B: %d\n", (int) tmp); | ||
889 | /* Laguna chipset has reversed clock registers */ | 890 | /* Laguna chipset has reversed clock registers */ |
890 | if (is_laguna(cinfo)) { | 891 | if (is_laguna(cinfo)) { |
891 | vga_wseq(regbase, CL_SEQRE, tmp); | 892 | vga_wseq(regbase, CL_SEQRE, tmp); |
892 | vga_wseq(regbase, CL_SEQR1E, nom); | 893 | vga_wseq(regbase, CL_SEQR1E, nom); |
893 | } else { | 894 | } else { |
894 | vga_wseq(regbase, CL_SEQRB, nom); | 895 | vga_wseq(regbase, CL_SEQRE, nom); |
895 | vga_wseq(regbase, CL_SEQR1B, tmp); | 896 | vga_wseq(regbase, CL_SEQR1E, tmp); |
896 | } | 897 | } |
897 | } | 898 | } |
898 | 899 | ||
@@ -911,15 +912,13 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
911 | else | 912 | else |
912 | vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ | 913 | vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ |
913 | 914 | ||
914 | /* adjust horizontal/vertical sync type (low/high) */ | 915 | /* adjust horizontal/vertical sync type (low/high), use VCLK3 */ |
915 | /* enable display memory & CRTC I/O address for color mode */ | 916 | /* enable display memory & CRTC I/O address for color mode */ |
916 | tmp = 0x03; | 917 | tmp = 0x03 | 0xc; |
917 | if (var->sync & FB_SYNC_HOR_HIGH_ACT) | 918 | if (var->sync & FB_SYNC_HOR_HIGH_ACT) |
918 | tmp |= 0x40; | 919 | tmp |= 0x40; |
919 | if (var->sync & FB_SYNC_VERT_HIGH_ACT) | 920 | if (var->sync & FB_SYNC_VERT_HIGH_ACT) |
920 | tmp |= 0x80; | 921 | tmp |= 0x80; |
921 | if (is_laguna(cinfo)) | ||
922 | tmp |= 0xc; | ||
923 | WGen(cinfo, VGA_MIS_W, tmp); | 922 | WGen(cinfo, VGA_MIS_W, tmp); |
924 | 923 | ||
925 | /* text cursor on and start line */ | 924 | /* text cursor on and start line */ |
@@ -1052,9 +1051,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
1052 | vga_wseq(regbase, CL_SEQRF, 0xb8); | 1051 | vga_wseq(regbase, CL_SEQRF, 0xb8); |
1053 | #endif | 1052 | #endif |
1054 | case BT_ALPINE: | 1053 | case BT_ALPINE: |
1055 | /* We already set SRF and SR1F */ | ||
1056 | break; | ||
1057 | |||
1058 | case BT_SD64: | 1054 | case BT_SD64: |
1059 | case BT_GD5480: | 1055 | case BT_GD5480: |
1060 | case BT_LAGUNA: | 1056 | case BT_LAGUNA: |
@@ -1103,7 +1099,8 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
1103 | case BT_PICASSO4: | 1099 | case BT_PICASSO4: |
1104 | case BT_ALPINE: | 1100 | case BT_ALPINE: |
1105 | /* Extended Sequencer Mode: 256c col. mode */ | 1101 | /* Extended Sequencer Mode: 256c col. mode */ |
1106 | vga_wseq(regbase, CL_SEQR7, 0xa7); | 1102 | vga_wseq(regbase, CL_SEQR7, |
1103 | cinfo->doubleVCLK ? 0xa3 : 0xa7); | ||
1107 | break; | 1104 | break; |
1108 | 1105 | ||
1109 | case BT_GD5480: | 1106 | case BT_GD5480: |
@@ -1128,7 +1125,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) | |||
1128 | /* mode register: 256 color mode */ | 1125 | /* mode register: 256 color mode */ |
1129 | vga_wgfx(regbase, VGA_GFX_MODE, 64); | 1126 | vga_wgfx(regbase, VGA_GFX_MODE, 64); |
1130 | #ifdef CONFIG_PCI | 1127 | #ifdef CONFIG_PCI |
1131 | WHDR(cinfo, 0xc1); /* Copy Xbh */ | 1128 | WHDR(cinfo, cinfo->doubleVCLK ? 0xe1 : 0xc1); |
1132 | #elif defined(CONFIG_ZORRO) | 1129 | #elif defined(CONFIG_ZORRO) |
1133 | /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */ | 1130 | /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */ |
1134 | WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */ | 1131 | WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */ |
@@ -1529,7 +1526,9 @@ static void init_vgachip(struct fb_info *info) | |||
1529 | case BT_LAGUNAB: | 1526 | case BT_LAGUNAB: |
1530 | break; | 1527 | break; |
1531 | case BT_SD64: | 1528 | case BT_SD64: |
1529 | #ifdef CONFIG_ZORRO | ||
1532 | vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8); | 1530 | vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8); |
1531 | #endif | ||
1533 | break; | 1532 | break; |
1534 | default: | 1533 | default: |
1535 | vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f); | 1534 | vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f); |
@@ -1604,7 +1603,8 @@ static void init_vgachip(struct fb_info *info) | |||
1604 | /* Bit Mask: no mask at all */ | 1603 | /* Bit Mask: no mask at all */ |
1605 | vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff); | 1604 | vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff); |
1606 | 1605 | ||
1607 | if (cinfo->btype == BT_ALPINE || is_laguna(cinfo)) | 1606 | if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 || |
1607 | is_laguna(cinfo)) | ||
1608 | /* (5434 can't have bit 3 set for bitblt) */ | 1608 | /* (5434 can't have bit 3 set for bitblt) */ |
1609 | vga_wgfx(cinfo->regbase, CL_GRB, 0x20); | 1609 | vga_wgfx(cinfo->regbase, CL_GRB, 0x20); |
1610 | else | 1610 | else |
@@ -1809,9 +1809,11 @@ static void cirrusfb_imageblit(struct fb_info *info, | |||
1809 | 1809 | ||
1810 | if (info->state != FBINFO_STATE_RUNNING) | 1810 | if (info->state != FBINFO_STATE_RUNNING) |
1811 | return; | 1811 | return; |
1812 | /* Alpine acceleration does not work at 24bpp ?!? */ | 1812 | /* Alpine/SD64 does not work at 24bpp ??? */ |
1813 | if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1 || | 1813 | if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) |
1814 | (cinfo->btype == BT_ALPINE && op == 0xc)) | 1814 | cfb_imageblit(info, image); |
1815 | else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) && | ||
1816 | op == 0xc) | ||
1815 | cfb_imageblit(info, image); | 1817 | cfb_imageblit(info, image); |
1816 | else { | 1818 | else { |
1817 | unsigned size = ((image->width + 7) >> 3) * image->height; | 1819 | unsigned size = ((image->width + 7) >> 3) * image->height; |
@@ -1895,7 +1897,7 @@ static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info, | |||
1895 | /* If DRAM bank switching is enabled, there must be | 1897 | /* If DRAM bank switching is enabled, there must be |
1896 | * twice as much memory installed. (4MB on the 5434) | 1898 | * twice as much memory installed. (4MB on the 5434) |
1897 | */ | 1899 | */ |
1898 | if (SRF & 0x80) | 1900 | if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0) |
1899 | mem *= 2; | 1901 | mem *= 2; |
1900 | } | 1902 | } |
1901 | 1903 | ||
@@ -2553,7 +2555,7 @@ static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned ch | |||
2553 | 2555 | ||
2554 | if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || | 2556 | if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || |
2555 | cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 || | 2557 | cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 || |
2556 | is_laguna(cinfo)) { | 2558 | cinfo->btype == BT_SD64 || is_laguna(cinfo)) { |
2557 | /* but DAC data register IS, at least for Picasso II */ | 2559 | /* but DAC data register IS, at least for Picasso II */ |
2558 | if (cinfo->btype == BT_PICASSO) | 2560 | if (cinfo->btype == BT_PICASSO) |
2559 | data += 0xfff; | 2561 | data += 0xfff; |