Commit 6e30fc08 authored by Krzysztof Helt's avatar Krzysztof Helt Committed by Linus Torvalds

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: default avatarKrzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 213d4bdd
...@@ -327,6 +327,7 @@ enum cirrusfb_dbg_reg_class { ...@@ -327,6 +327,7 @@ enum cirrusfb_dbg_reg_class {
/* info about board */ /* info about board */
struct cirrusfb_info { struct cirrusfb_info {
u8 __iomem *regbase; u8 __iomem *regbase;
u8 __iomem *laguna_mmio;
enum cirrus_board btype; enum cirrus_board btype;
unsigned char SFR; /* Shadow of special function register */ unsigned char SFR; /* Shadow of special function register */
...@@ -699,6 +700,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) ...@@ -699,6 +700,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
int yres, vdispend, vsyncstart, vsyncend, vtotal; int yres, vdispend, vsyncstart, vsyncend, vtotal;
long freq; long freq;
int nom, den, div; int nom, den, div;
unsigned int control, format, threshold;
dev_dbg(info->device, "Requested mode: %dx%dx%d\n", dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
var->xres, var->yres, var->bits_per_pixel); var->xres, var->yres, var->bits_per_pixel);
...@@ -866,6 +868,23 @@ static int cirrusfb_set_par_foo(struct fb_info *info) ...@@ -866,6 +868,23 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
cirrusfb_set_mclk_as_source(info, divMCLK); 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) { if (nom) {
tmp = den << 1; tmp = den << 1;
if (div != 0) if (div != 0)
...@@ -1035,6 +1054,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) ...@@ -1035,6 +1054,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
case BT_LAGUNA: case BT_LAGUNA:
vga_wseq(regbase, CL_SEQR7, vga_wseq(regbase, CL_SEQR7,
vga_rseq(regbase, CL_SEQR7) | 0x01); vga_rseq(regbase, CL_SEQR7) | 0x01);
threshold |= 0x10;
break; break;
default: default:
...@@ -1146,6 +1166,9 @@ static int cirrusfb_set_par_foo(struct fb_info *info) ...@@ -1146,6 +1166,9 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
case BT_LAGUNA: case BT_LAGUNA:
vga_wseq(regbase, CL_SEQR7, vga_wseq(regbase, CL_SEQR7,
vga_rseq(regbase, CL_SEQR7) & ~0x01); vga_rseq(regbase, CL_SEQR7) & ~0x01);
control |= 0x2000;
format |= 0x1400;
threshold |= 0x10;
break; break;
default: default:
...@@ -1220,6 +1243,9 @@ static int cirrusfb_set_par_foo(struct fb_info *info) ...@@ -1220,6 +1243,9 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
case BT_LAGUNA: case BT_LAGUNA:
vga_wseq(regbase, CL_SEQR7, vga_wseq(regbase, CL_SEQR7,
vga_rseq(regbase, CL_SEQR7) & ~0x01); vga_rseq(regbase, CL_SEQR7) & ~0x01);
control |= 0x6000;
format |= 0x3400;
threshold |= 0x20;
break; break;
default: default:
...@@ -1327,6 +1353,12 @@ static int cirrusfb_set_par_foo(struct fb_info *info) ...@@ -1327,6 +1353,12 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
/* graphics cursor attributes: nothing special */ /* graphics cursor attributes: nothing special */
vga_wseq(regbase, CL_SEQR12, 0x0); 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 */ /* finally, turn on everything - turn off "FullBandwidth" bit */
/* also, set "DotClock%2" bit where requested */ /* also, set "DotClock%2" bit where requested */
tmp = 0x01; tmp = 0x01;
...@@ -2000,7 +2032,10 @@ static void get_pci_addrs(const struct pci_dev *pdev, ...@@ -2000,7 +2032,10 @@ static void get_pci_addrs(const struct pci_dev *pdev,
static void cirrusfb_pci_unmap(struct fb_info *info) static void cirrusfb_pci_unmap(struct fb_info *info)
{ {
struct pci_dev *pdev = to_pci_dev(info->device); 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); iounmap(info->screen_base);
#if 0 /* if system didn't claim this region, we would... */ #if 0 /* if system didn't claim this region, we would... */
release_mem_region(0xA0000, 65535); release_mem_region(0xA0000, 65535);
...@@ -2180,6 +2215,7 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, ...@@ -2180,6 +2215,7 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start); get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
/* FIXME: this forces VGA. alternatives? */ /* FIXME: this forces VGA. alternatives? */
cinfo->regbase = NULL; 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", dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
...@@ -2234,6 +2270,8 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, ...@@ -2234,6 +2270,8 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
#endif #endif
pci_release_regions(pdev); pci_release_regions(pdev);
err_release_fb: err_release_fb:
if (cinfo->laguna_mmio == NULL)
iounmap(cinfo->laguna_mmio);
framebuffer_release(info); framebuffer_release(info);
err_disable: err_disable:
err_out: err_out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment