aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/cirrusfb.c
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2009-03-31 18:25:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-01 11:59:29 -0400
commitdf3aafd57d590d6f3d95310fc3430f3a536d1e59 (patch)
treeae9a277926309e9c9378df4cb10208cd6845a5b0 /drivers/video/cirrusfb.c
parent8f19e15b8ad23e28add5760ed049be2359f39fe8 (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.c72
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
263static struct pci_device_id cirrusfb_pci_table[] = { 265static 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;