summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2009-03-31 15:25:05 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-01 08:59:27 -0700
commit6e30fc086d000d15abfe5550cc8b286335f7e132 (patch)
tree82e92def6ce4ed71634e0a14f458229bf81682c5 /drivers
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')
-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 119e49ed621..378d60e0190 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -327,6 +327,7 @@ enum cirrusfb_dbg_reg_class {
/* info about board */
struct cirrusfb_info {
u8 __iomem *regbase;
+ u8 __iomem *laguna_mmio;
enum cirrus_board btype;
unsigned char SFR; /* Shadow of special function register */
@@ -699,6 +700,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
int yres, vdispend, vsyncstart, vsyncend, vtotal;
long freq;
int nom, den, div;
+ unsigned int control, format, threshold;
dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
var->xres, var->yres, var->bits_per_pixel);
@@ -866,6 +868,23 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
cirrusfb_set_mclk_as_source(info, divMCLK);
}
}
+ if (cinfo->btype == BT_LAGUNA) {
+ long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc);
+ unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407);
+ unsigned short tile_control;
+
+ tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4);
+ fb_writew(tile_control & ~0x80, cinfo->laguna_mmio + 0x2c4);
+
+ fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc);
+ fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407);
+ control = fb_readw(cinfo->laguna_mmio + 0x402);
+ threshold = fb_readw(cinfo->laguna_mmio + 0xea);
+ control &= ~0x6800;
+ format = 0;
+ threshold &= 0xffe0;
+ threshold &= 0x3fbf;
+ }
if (nom) {
tmp = den << 1;
if (div != 0)
@@ -1035,6 +1054,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
case BT_LAGUNA:
vga_wseq(regbase, CL_SEQR7,
vga_rseq(regbase, CL_SEQR7) | 0x01);
+ threshold |= 0x10;
break;
default:
@@ -1146,6 +1166,9 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
case BT_LAGUNA:
vga_wseq(regbase, CL_SEQR7,
vga_rseq(regbase, CL_SEQR7) & ~0x01);
+ control |= 0x2000;
+ format |= 0x1400;
+ threshold |= 0x10;
break;
default:
@@ -1220,6 +1243,9 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
case BT_LAGUNA:
vga_wseq(regbase, CL_SEQR7,
vga_rseq(regbase, CL_SEQR7) & ~0x01);
+ control |= 0x6000;
+ format |= 0x3400;
+ threshold |= 0x20;
break;
default:
@@ -1327,6 +1353,12 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
/* graphics cursor attributes: nothing special */
vga_wseq(regbase, CL_SEQR12, 0x0);
+ if (cinfo->btype == BT_LAGUNA) {
+ /* no tiles */
+ fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402);
+ fb_writew(format, cinfo->laguna_mmio + 0xc0);
+ fb_writew(threshold, cinfo->laguna_mmio + 0xea);
+ }
/* finally, turn on everything - turn off "FullBandwidth" bit */
/* also, set "DotClock%2" bit where requested */
tmp = 0x01;
@@ -2000,7 +2032,10 @@ static void get_pci_addrs(const struct pci_dev *pdev,
static void cirrusfb_pci_unmap(struct fb_info *info)
{
struct pci_dev *pdev = to_pci_dev(info->device);
+ struct cirrusfb_info *cinfo = info->par;
+ if (cinfo->laguna_mmio == NULL)
+ iounmap(cinfo->laguna_mmio);
iounmap(info->screen_base);
#if 0 /* if system didn't claim this region, we would... */
release_mem_region(0xA0000, 65535);
@@ -2180,6 +2215,7 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
/* FIXME: this forces VGA. alternatives? */
cinfo->regbase = NULL;
+ cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
}
dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
@@ -2234,6 +2270,8 @@ err_release_regions:
#endif
pci_release_regions(pdev);
err_release_fb:
+ if (cinfo->laguna_mmio == NULL)
+ iounmap(cinfo->laguna_mmio);
framebuffer_release(info);
err_disable:
err_out: