aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/cirrusfb.c
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2009-03-31 18:25:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-01 11:59:27 -0400
commit6e30fc086d000d15abfe5550cc8b286335f7e132 (patch)
tree82e92def6ce4ed71634e0a14f458229bf81682c5 /drivers/video/cirrusfb.c
parent213d4bdd8cd405d9ba59ee78165b8c870f83a018 (diff)
cirrusfb: add mmio registers for Laguna chipsets
The Laguna chipsets use special registers which are available through the mmio area. The cirrusfb driver does not use memory mapped registers for the PCI cards. Add the memory mapped area for Laguna chipsets and add basic usage of the special Laguna registers after SVGALIB code. This gives readable console at 16bpp on the GD-5465 (Laguna AGP). The 8bpp and 32bpp depths are still broken. 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.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 119e49ed6218..378d60e01902 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -327,6 +327,7 @@ enum cirrusfb_dbg_reg_class {
327/* info about board */ 327/* info about board */
328struct cirrusfb_info { 328struct cirrusfb_info {
329 u8 __iomem *regbase; 329 u8 __iomem *regbase;
330 u8 __iomem *laguna_mmio;
330 enum cirrus_board btype; 331 enum cirrus_board btype;
331 unsigned char SFR; /* Shadow of special function register */ 332 unsigned char SFR; /* Shadow of special function register */
332 333
@@ -699,6 +700,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
699 int yres, vdispend, vsyncstart, vsyncend, vtotal; 700 int yres, vdispend, vsyncstart, vsyncend, vtotal;
700 long freq; 701 long freq;
701 int nom, den, div; 702 int nom, den, div;
703 unsigned int control, format, threshold;
702 704
703 dev_dbg(info->device, "Requested mode: %dx%dx%d\n", 705 dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
704 var->xres, var->yres, var->bits_per_pixel); 706 var->xres, var->yres, var->bits_per_pixel);
@@ -866,6 +868,23 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
866 cirrusfb_set_mclk_as_source(info, divMCLK); 868 cirrusfb_set_mclk_as_source(info, divMCLK);
867 } 869 }
868 } 870 }
871 if (cinfo->btype == BT_LAGUNA) {
872 long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc);
873 unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407);
874 unsigned short tile_control;
875
876 tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4);
877 fb_writew(tile_control & ~0x80, cinfo->laguna_mmio + 0x2c4);
878
879 fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc);
880 fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407);
881 control = fb_readw(cinfo->laguna_mmio + 0x402);
882 threshold = fb_readw(cinfo->laguna_mmio + 0xea);
883 control &= ~0x6800;
884 format = 0;
885 threshold &= 0xffe0;
886 threshold &= 0x3fbf;
887 }
869 if (nom) { 888 if (nom) {
870 tmp = den << 1; 889 tmp = den << 1;
871 if (div != 0) 890 if (div != 0)
@@ -1035,6 +1054,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1035 case BT_LAGUNA: 1054 case BT_LAGUNA:
1036 vga_wseq(regbase, CL_SEQR7, 1055 vga_wseq(regbase, CL_SEQR7,
1037 vga_rseq(regbase, CL_SEQR7) | 0x01); 1056 vga_rseq(regbase, CL_SEQR7) | 0x01);
1057 threshold |= 0x10;
1038 break; 1058 break;
1039 1059
1040 default: 1060 default:
@@ -1146,6 +1166,9 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1146 case BT_LAGUNA: 1166 case BT_LAGUNA:
1147 vga_wseq(regbase, CL_SEQR7, 1167 vga_wseq(regbase, CL_SEQR7,
1148 vga_rseq(regbase, CL_SEQR7) & ~0x01); 1168 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1169 control |= 0x2000;
1170 format |= 0x1400;
1171 threshold |= 0x10;
1149 break; 1172 break;
1150 1173
1151 default: 1174 default:
@@ -1220,6 +1243,9 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1220 case BT_LAGUNA: 1243 case BT_LAGUNA:
1221 vga_wseq(regbase, CL_SEQR7, 1244 vga_wseq(regbase, CL_SEQR7,
1222 vga_rseq(regbase, CL_SEQR7) & ~0x01); 1245 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1246 control |= 0x6000;
1247 format |= 0x3400;
1248 threshold |= 0x20;
1223 break; 1249 break;
1224 1250
1225 default: 1251 default:
@@ -1327,6 +1353,12 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1327 /* graphics cursor attributes: nothing special */ 1353 /* graphics cursor attributes: nothing special */
1328 vga_wseq(regbase, CL_SEQR12, 0x0); 1354 vga_wseq(regbase, CL_SEQR12, 0x0);
1329 1355
1356 if (cinfo->btype == BT_LAGUNA) {
1357 /* no tiles */
1358 fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402);
1359 fb_writew(format, cinfo->laguna_mmio + 0xc0);
1360 fb_writew(threshold, cinfo->laguna_mmio + 0xea);
1361 }
1330 /* finally, turn on everything - turn off "FullBandwidth" bit */ 1362 /* finally, turn on everything - turn off "FullBandwidth" bit */
1331 /* also, set "DotClock%2" bit where requested */ 1363 /* also, set "DotClock%2" bit where requested */
1332 tmp = 0x01; 1364 tmp = 0x01;
@@ -2000,7 +2032,10 @@ static void get_pci_addrs(const struct pci_dev *pdev,
2000static void cirrusfb_pci_unmap(struct fb_info *info) 2032static void cirrusfb_pci_unmap(struct fb_info *info)
2001{ 2033{
2002 struct pci_dev *pdev = to_pci_dev(info->device); 2034 struct pci_dev *pdev = to_pci_dev(info->device);
2035 struct cirrusfb_info *cinfo = info->par;
2003 2036
2037 if (cinfo->laguna_mmio == NULL)
2038 iounmap(cinfo->laguna_mmio);
2004 iounmap(info->screen_base); 2039 iounmap(info->screen_base);
2005#if 0 /* if system didn't claim this region, we would... */ 2040#if 0 /* if system didn't claim this region, we would... */
2006 release_mem_region(0xA0000, 65535); 2041 release_mem_region(0xA0000, 65535);
@@ -2180,6 +2215,7 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
2180 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start); 2215 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2181 /* FIXME: this forces VGA. alternatives? */ 2216 /* FIXME: this forces VGA. alternatives? */
2182 cinfo->regbase = NULL; 2217 cinfo->regbase = NULL;
2218 cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
2183 } 2219 }
2184 2220
2185 dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n", 2221 dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
@@ -2234,6 +2270,8 @@ err_release_regions:
2234#endif 2270#endif
2235 pci_release_regions(pdev); 2271 pci_release_regions(pdev);
2236err_release_fb: 2272err_release_fb:
2273 if (cinfo->laguna_mmio == NULL)
2274 iounmap(cinfo->laguna_mmio);
2237 framebuffer_release(info); 2275 framebuffer_release(info);
2238err_disable: 2276err_disable:
2239err_out: 2277err_out: