linux-mips
[Top] [All Lists]

[PATCH] Impact video driver for SGI Indigo2

To: linux-mips@linux-mips.org, ralf@linux-mips.org
Subject: [PATCH] Impact video driver for SGI Indigo2
From: peter fuerst <post@pfrst.de>
Date: Sun, 11 Sep 2011 13:14:31 +0200 (CEST)
Cc: attilio.fiandrotti@gmail.com
Reply-to: post@pfrst.de
Sender: linux-mips-bounce@linux-mips.org


Here's an attempt to bloat the linux source a bit more ;-)

This patch brings, yet missing, parts that make a Linux-driven Indigo2
Impact (IP28 and most probably IP22-Impact) an usable desktop-machine
"out of the box".
The driver provides the framebuffer console and an interface for the
Xserver (mmap'ing a DMA-pool to the shadow framebuffer and doing the
necessary cacheflush).
Meanwhile only a few files are affected and obviously no side-effects
to other parts of the kernel are to be expected.

BTW: it would be appreciated, if someone could verify, that this driver
also works for IP22 Impact.


Signed-off-by: peter fuerst <post@pfrst.de>

---

1) Preparation

 drivers/video/Kconfig            |    6 ++++++
 drivers/video/Makefile           |    1 +
 drivers/video/logo/Kconfig       |    2 +-
 arch/mips/sgi-ip22/ip22-setup.c  |   37 +++++++++++++++++++++++++++++++++++++
 arch/mips/configs/ip28_defconfig |    1 +
 5 files changed, 46 insertions(+), 1 deletions(-)


diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 549b960..43dbc9f 100644
--- a/drivers/video/Kconfig     Thu Jan  1 00:00:00 1970
+++ b/drivers/video/Kconfig     Thu Mar 10 23:37:58 2011
@@ -2383,6 +2383,12 @@ config FB_PUV3_UNIGFX
          Choose this option if you want to use the Unigfx device as a
          framebuffer device. Without the support of PCI & AGP.

+config FB_IMPACT
+       tristate "SGI Indigo2 Impact graphics support"
+       depends on FB && (SGI_IP22 || SGI_IP28 || SGI_IP30)
+       help
+         SGI Indigo2 Impact (SI/HI/MI) graphics card support.
+
 source "drivers/video/omap/Kconfig"
 source "drivers/video/omap2/Kconfig"



diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 8b83129..278c8fa 100644
--- a/drivers/video/Makefile    Thu Jan  1 00:00:00 1970
+++ b/drivers/video/Makefile    Thu Mar 10 23:44:40 2011
@@ -141,6 +141,7 @@ obj-$(CONFIG_FB_MSM)              += msm/
 obj-$(CONFIG_FB_NUC900)           += nuc900fb.o
 obj-$(CONFIG_FB_JZ4740)                  += jz4740_fb.o
 obj-$(CONFIG_FB_PUV3_UNIGFX)      += fb-puv3.o
+obj-$(CONFIG_FB_IMPACT)                  += impact.o

 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_UVESA)            += uvesafb.o


diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index 39ac49e..3ac6da4 100644
--- a/drivers/video/logo/Kconfig        Thu Jan  1 00:00:00 1970
+++ b/drivers/video/logo/Kconfig        Fri May  8 00:51:01 2009
@@ -54,7 +54,7 @@ config LOGO_PARISC_CLUT224

 config LOGO_SGI_CLUT224
        bool "224-color SGI Linux logo"
-       depends on SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS
+       depends on SGI_IP22 || SGI_IP27 || SGI_IP28 || SGI_IP30 || SGI_IP32 || 
X86_VISWS
        default y

 config LOGO_SUN_CLUT224


diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c
index 5e66213..085b612 100644
--- a/arch/mips/sgi-ip22/ip22-setup.c   Thu Jan  1 00:00:00 1970
+++ b/arch/mips/sgi-ip22/ip22-setup.c   Fri May  8 01:05:13 2009
@@ -96,4 +96,41 @@ void __init plat_mem_setup(void)
                }
        }
 #endif
+#if defined(CONFIG_FB_IMPACT)
+       {
+               extern void setup_impact_earlycons(void);
+               /*
+                * Get graphics info before it is overwritten...
+                * E.g. @ 9000000020f02f78: ffffffff9fc6d770,900000001f000000
+                */
+#ifdef CONFIG_ARC64
+               ULONG * (*__vec)(void) = (typeof(__vec))
+                       ((ULONG*)PROMBLOCK->pvector)[8];
+               ULONG *gfxinfo = (*__vec)();
+#else
+               /* supposed to work on both 32/64-bit kernels. */
+               int (*__vec)(void) = (typeof(__vec))
+                       (long) ((int*)PROMBLOCK->pvector)[8];
+               int *gfxinfo = (typeof(gfxinfo)) (*__vec)();
+#endif
+               /* See note on __pa() in impact.c */
+               sgi_gfxaddr = __pa((void*)gfxinfo[1]);
+               if (sgi_gfxaddr < 0x1f000000 || 0x1fa00000 <= sgi_gfxaddr)
+                       sgi_gfxaddr = 0;
+               /*
+                * Early params are not yet avaialble, so this setting
+                * must be done in the ARCS environment.
+                */
+               ctype = ArcGetEnvironmentVariable("OSLoadOptions");
+               if (!ctype || !strstr(ctype, "impact=noearly"))
+#ifndef CONFIG_EARLY_PRINTK
+               if (ctype && strstr(ctype, "impact=early"))
+#endif
+                       setup_impact_earlycons();
+
+               printk(KERN_DEBUG "ARCS gfx info @ %p: %p,%p\n",
+                               gfxinfo, (void*)gfxinfo[0], (void*)gfxinfo[1]);
+               printk(KERN_INFO "SGI graphics system @ 0x%08lx\n", 
sgi_gfxaddr);
+       }
+#endif
 }


diff --git a/arch/mips/configs/ip28_defconfig b/arch/mips/configs/ip28_defconfig
index 4dbf626..b316c86 100644
--- a/arch/mips/configs/ip28_defconfig
+++ b/arch/mips/configs/ip28_defconfig
@@ -78,3 +78,4 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_HW is not set
 # CONFIG_CRC32 is not set
+CONFIG_FB_IMPACT=y


2) The driver

 drivers/video/impact.c | 1154 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/video/impact.h |  210 +++++++++
 2 files changed, 1364 insertions(+), 0 deletions(-)


diff --git a/drivers/video/impact.c b/drivers/video/impact.c
new file mode 100644
index 0000000..5ffc948
--- /dev/null   Wed Dec  8 00:46:04 2004
+++ b/drivers/video/impact.c    Mon Jul 25 00:06:58 2011
@@ -0,0 +1,1154 @@
+/*
+ * linux/drivers/video/impactsr.c -- SGI Octane MardiGras (IMPACTSR) graphics
+ * linux/drivers/video/impact.c   -- SGI Indigo2 MardiGras (IMPACT) graphics
+ *
+ *  Copyright (c) 2004-2006 by Stanislaw Skowronek     (skylark@linux-mips.org)
+ *  Adapted to Indigo2 by pf, 2005,2006,2009,2011      (post@pfrst.de)
+ *
+ *  Based on linux/drivers/video/skeletonfb.c
+ *
+ *  This driver, as most of the IP30 (SGI Octane) port, is a result of massive
+ *  amounts of reverse engineering and trial-and-error. If anyone is interested
+ *  in helping with it, please contact me: <skylark@linux-mips.org>.
+ *
+ *  The basic functions of this driver are filling and blitting rectangles.
+ *  To achieve the latter, two DMA operations are used on Impact. It is unclear
+ *  to me, why is it so, but even Xsgi (the IRIX X11 server) does it this way.
+ *  It seems that fb->fb operations are not operational on these cards.
+ *
+ *  For this purpose, a kernel DMA pool is allocated (pool number 0). This pool
+ *  is (by default) 64kB in size. An ioctl could be used to set the value at
+ *  run-time. Applications can use this pool, however proper locking has to be
+ *  guaranteed. Kernel should be locked out from this pool by an ioctl.
+ *
+ *  The IMPACTSR is quite well worked-out currently, except for the Geometry
+ *  Engines (GE11). Any information about use of those devices would be very
+ *  useful. It would enable a Linux OpenGL driver, as most of OpenGL calls are
+ *  supported directly by the hardware. So far, I can't initialize the GE11.
+ *  Verification of microcode crashes the graphics.
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/font.h>
+#include <linux/platform_device.h>
+#include <linux/console.h>
+#include <linux/version.h>
+
+#ifndef CONFIG_64BIT
+#error (S)he, who can afford Impact-graphics, shall afford a 64bit-kernel also!
+#endif
+#ifdef CONFIG_SGI_IP30
+# include <asm/mach-ip30/xtalk.h>
+# define IPNR 30
+#else
+# if defined(CONFIG_SGI_IP22)
+#  define IPNR 22
+# elif defined(CONFIG_SGI_IP26)
+#  define IPNR 26
+# else
+#  define IPNR 28
+# endif
+#endif
+#define isSR (IPNR > 28)    /* avoid nasty #if... where possible. */
+#include <video/impact.h>
+
+/* Some fixed register values. */
+
+#if isSR       /* ImpactSR (HQ4) registers */
+#define VAL_CFIFO_HW   0x47
+#define VAL_CFIFO_LW   0x14
+#define VAL_CFIFO_DELAY        0x64
+#define VAL_DFIFO_HW   0x40
+#define VAL_DFIFO_LW   0x10
+#define VAL_DFIFO_DELAY        0
+#define MSK_CFIFO_CNT  0xff
+#define USEPOOLS       5
+#else  /* Impact (HQ3) registers */
+#define VAL_CFIFO_HW   0x20 /* 0x18 ? */
+#define VAL_CFIFO_LW   0x14
+#define VAL_CFIFO_DELAY        0x64
+#define VAL_DFIFO_HW   0x28
+#define VAL_DFIFO_LW   0x14
+#define VAL_DFIFO_DELAY        0xfff
+#define MSK_CFIFO_CNT  0x7f
+#define USEPOOLS       4
+#endif
+#define POOLS  5
+
+#define IMPACT_KPOOL_SIZE      65536
+
+struct impact_par {
+       /* physical mmio base in HEART XTalk space */
+       unsigned long mmio_base;
+       /* virtual mmio base in kernel space */
+       unsigned long mmio_virt;
+       struct {
+               /* DMA pool management, txtbl[0..num-1] passed to card */
+               unsigned int *txtbl;  /* txtbl[i] = pgidx(phys[i]) */
+               unsigned int txnum;   /* valid: txtbl[0..txnum-1] */
+               unsigned int txmax;   /* alloc: txtbl[0..txmax-1] */
+               unsigned long txphys; /* txphys = dma_addr(txtbl) */
+               /* kernel DMA pools, the actual DMA-buffers */
+               void*         *virt;  /* virt[0..txnum-1]: dma-page-addresses */
+               unsigned long *phys;  /* phys[i] = dma_addr(virt[i]) */
+               unsigned int size;
+               unsigned long uaddr;  /* DMA-buffer's userland-address */
+       } pools[POOLS];
+       /* board config */
+       unsigned int num_ge, num_rss;
+       /* locks to prevent simultaneous user and kernel access */
+       int open_flag;
+       int mmap_flag;
+       spinlock_t lock;
+       unsigned xoffset; /* fb_var_screeninfo.[xy]offset, are ... */
+       unsigned yoffset; /* ...used inconsistently (at the best). */
+};
+
+static struct fb_fix_screeninfo impact_fix = {
+       .id =           "ImpactSR 0RSS",
+       .smem_start =   0,
+       .smem_len =     0,
+       .type =         FB_TYPE_PACKED_PIXELS,
+       .visual =       FB_VISUAL_TRUECOLOR,
+       .xpanstep =     0,
+       .ypanstep =     0,
+       .ywrapstep =    0,
+       .line_length =  0,
+       .accel =        FB_ACCEL_NONE,
+};
+
+static struct fb_var_screeninfo impact_var = {
+       .xres =         960,
+       .yres =         960,
+       .xres_virtual = 1280,
+       .yres_virtual = 1024,
+       .bits_per_pixel = 24,
+       .red =          { .offset = 0,  .length = 8 },
+       .green =        { .offset = 8,  .length = 8 },
+       .blue =         { .offset = 16, .length = 8 },
+       .transp =       { .offset = 24, .length = 8 },
+};
+
+static struct fb_info info;
+
+static unsigned int pseudo_palette[256];
+
+static struct impact_par current_par;
+
+/* --------------------- Gory Details --------------------- */
+#define PAR(p)  (*((struct impact_par *)(p)->par))
+#define MMIO(p) (PAR(p).mmio_virt)
+
+static void impact_wait_cfifo(unsigned long mmio, int nslots)
+{
+       while ((IMPACT_FIFOSTATUS(mmio) & MSK_CFIFO_CNT) > 
(IMPACT_CFIFO_MAX-nslots));
+}
+static void impact_wait_cfifo_empty(unsigned long mmio)
+{
+       while (IMPACT_FIFOSTATUS(mmio) & MSK_CFIFO_CNT);
+}
+static void impact_wait_bfifo(unsigned long mmio, int nslots)
+{
+       while ((IMPACT_GIOSTATUS(mmio) & 0x1f) > (IMPACT_BFIFO_MAX-nslots));
+}
+static void impact_wait_bfifo_empty(unsigned long mmio)
+{
+       while (IMPACT_GIOSTATUS(mmio) & 0x1f);
+}
+static void impact_wait_dma(unsigned long mmio)
+{
+       while (IMPACT_DMABUSY(mmio) & 0x1f);
+       while (!(IMPACT_STATUS(mmio) & 1));
+       while (!(IMPACT_STATUS(mmio) & 2));
+       while (!(IMPACT_RESTATUS(mmio) & 0x100));
+}
+static void impact_wait_dmaready(unsigned long mmio)
+{
+       IMPACT_CFIFOW(mmio) = 0x000e0100;
+       while (IMPACT_DMABUSY(mmio) & 0x1eff);
+       while (!(IMPACT_STATUS(mmio) & 2));
+}
+#define impact_wait_rss_idle impact_wait_dmaready
+
+static void impact_inithq(unsigned long mmio)
+{
+       /* Not really needed, the friendly PROM did this already for us... */
+       /* CFIFO parameters */
+       IMPACT_CFIFO_HW(mmio) = VAL_CFIFO_HW;
+       IMPACT_CFIFO_LW(mmio) = VAL_CFIFO_LW;
+       IMPACT_CFIFO_DELAY(mmio) = VAL_CFIFO_DELAY;
+       /* DFIFO parameters */
+       IMPACT_DFIFO_HW(mmio) = VAL_DFIFO_HW;
+       IMPACT_DFIFO_LW(mmio) = VAL_DFIFO_LW;
+       IMPACT_DFIFO_DELAY(mmio) = VAL_DFIFO_DELAY;
+}
+
+static void impact_initrss(unsigned long mmio)
+{
+       volatile typeof(IMPACT_CFIFO(0)) *cfifo = &IMPACT_CFIFO(mmio);
+       /* transfer mask registers */
+       *cfifo = IMPACT_CMD_COLORMASKLSBSA(0xffffff);
+       *cfifo = IMPACT_CMD_COLORMASKLSBSB(0xffffff);
+       *cfifo = IMPACT_CMD_COLORMASKMSBS(0);
+       *cfifo = IMPACT_CMD_XFRMASKLO(0xffffff);
+       *cfifo = IMPACT_CMD_XFRMASKHI(0xffffff);
+       /* use the main plane */
+       *cfifo = IMPACT_CMD_DRBPOINTERS(0xc8240);
+       /* set the RE into vertical flip mode */
+       *cfifo = IMPACT_CMD_CONFIG(0xcac);
+       *cfifo = IMPACT_CMD_XYWIN(0, 0x3ff);
+}
+
+static void impact_initxmap(unsigned long mmio)
+{
+       /* set XMAP into 24-bpp mode */
+       IMPACT_XMAP_PP1SELECT(mmio) = 0x01;
+       IMPACT_XMAP_INDEX(mmio) = 0x00;
+       IMPACT_XMAP_MAIN_MODE(mmio) = 0x07a4;
+}
+
+static void impact_initvc3(unsigned long mmio)
+{
+       /* cursor-b-gone (disable DISPLAY bit) */
+       IMPACT_VC3_INDEXDATA(mmio) = 0x1d000100;
+}
+
+static void impact_detachtxtbl(unsigned long mmio, unsigned long pool)
+{
+       volatile typeof(IMPACT_CFIFOP(0)) *cfifop = &IMPACT_CFIFOP(mmio);
+       /* clear DMA pool */
+       impact_wait_cfifo_empty(mmio);
+       impact_wait_dma(mmio);
+       IMPACT_CFIFOPW1(mmio) = IMPACT_CMD_HQ_TXBASE(pool);
+       *cfifop = 9;
+       *cfifop = IMPACT_CMD_HQ_TXMAX(pool, 0);
+       *cfifop = IMPACT_CMD_HQ_PGBITS(pool, 0);
+       if (isSR)
+               *cfifop = IMPACT_CMD_HQ_484B(pool, 0x00080000);
+       impact_wait_cfifo_empty(mmio);
+       impact_wait_dmaready(mmio);
+}
+
+static void impact_initdma(struct fb_info *p)
+{
+       volatile typeof(IMPACT_CFIFOPW(0)) *cfifopw = &IMPACT_CFIFOPW(MMIO(p));
+       volatile typeof(IMPACT_CFIFOP(0)) *cfifop = &IMPACT_CFIFOP(MMIO(p));
+       int pool;
+       /* clear DMA pools */
+       for (pool = 0; pool < POOLS; pool++) {
+               impact_detachtxtbl(MMIO(p), pool);
+               PAR(p).pools[pool].txmax = 0;
+               PAR(p).pools[pool].txnum = 0;
+       }
+       /* set DMA parameters */
+       impact_wait_cfifo_empty(MMIO(p));
+       *cfifop = IMPACT_CMD_HQ_PGSIZE(0);
+       *cfifop = IMPACT_CMD_HQ_STACKPTR(0);
+       if (isSR)
+               *cfifop = IMPACT_CMD_HQ_484A(0, 0x00180000);
+       *cfifopw = 0x000e0100;
+       *cfifopw = 0x000e0100;
+       *cfifopw = 0x000e0100;
+       *cfifopw = 0x000e0100;
+       *cfifopw = 0x000e0100;
+       if (isSR) {
+               IMPACT_REG32(MMIO(p), 0x40918) = 0x00680000;
+               IMPACT_REG32(MMIO(p), 0x40920) = 0x80280000;
+               IMPACT_REG32(MMIO(p), 0x40928) = 0x00000000;
+       }
+}
+
+static void impact_alloctxtbl(struct fb_info *p, int pool, int pages)
+{
+       /* realloc array of pool's page-indices to be passed to the card. */
+       dma_addr_t dma_handle;
+       int alloc_count;
+       if (pages > PAR(p).pools[pool].txmax) { /* grow the pool - unlikely but 
supported */
+               alloc_count = pages;
+               if (alloc_count < 1024)
+                       alloc_count = 1024;
+               if (PAR(p).pools[pool].txmax)
+                       dma_free_noncoherent(NULL, PAR(p).pools[pool].txmax*4,
+                               PAR(p).pools[pool].txtbl, 
PAR(p).pools[pool].txphys);
+               PAR(p).pools[pool].txtbl =
+                       dma_alloc_noncoherent(NULL, alloc_count*4, &dma_handle, 
GFP_KERNEL);
+               PAR(p).pools[pool].txphys = dma_handle;
+               PAR(p).pools[pool].txmax = alloc_count;
+       }
+       PAR(p).pools[pool].txnum = pages;
+}
+
+static void impact_writetxtbl(struct fb_info *p, int pool)
+{
+       volatile typeof(IMPACT_CFIFOPW(0)) *cfifopw = &IMPACT_CFIFOPW(MMIO(p));
+       volatile typeof(IMPACT_CFIFOP(0)) *cfifop = &IMPACT_CFIFOP(MMIO(p));
+       impact_wait_cfifo_empty(MMIO(p));
+       impact_wait_dma(MMIO(p));
+       /* inform the card about a new DMA pool */
+       IMPACT_CFIFOPW1(MMIO(p)) = IMPACT_CMD_HQ_TXBASE(pool);
+       *cfifop = PAR(p).pools[pool].txphys;
+       *cfifop = IMPACT_CMD_HQ_TXMAX(pool, PAR(p).pools[pool].txnum);
+       *cfifop = IMPACT_CMD_HQ_PGBITS(pool, 0x0a);
+       if (isSR)
+               *cfifop = IMPACT_CMD_HQ_484B(pool, 0x00180000);
+       *cfifopw = 0x000e0100;
+       *cfifopw = 0x000e0100;
+       *cfifopw = 0x000e0100;
+       *cfifopw = 0x000e0100;
+       *cfifopw = 0x000e0100;
+       impact_wait_cfifo_empty(MMIO(p));
+       impact_wait_dmaready(MMIO(p));
+}
+
+static void
+impact_settxtbl(struct fb_info *p, int pool, unsigned *txtbl, int txmax)
+{
+       impact_alloctxtbl(p, pool, txmax);
+       memcpy(PAR(p).pools[pool].txtbl, txtbl, txmax*4);
+       dma_cache_wback_inv((unsigned long)PAR(p).pools[pool].txtbl, txmax*4);
+       impact_writetxtbl(p, pool);
+}
+
+/*
+ * Screw the vaddress, or this damned virt_to_page() will blow up the
+ * driver for DMA_NONCOHERENT (i.e. on any Indigo2).
+ * (For 64Bit, though not for 32Bit, __pa() now does the right thing,
+ * and with a bit of luck there will be no regression...)
+ */
+static inline struct page *dma_virt_to_page(void *virt)
+{
+       return virt_to_page(phys_to_virt(__pa(virt)));
+}
+
+static void
+impact_resizekpool(struct fb_info *p, int pool, int size, int growonly)
+{
+       int pages;
+       int i;
+       dma_addr_t dma_handle;
+       if (growonly && PAR(p).pools[pool].size >= size)
+               return;
+       if (size < 8192)     /* single line smallcopy (1280*4) *must* work */
+               size = 8192;
+       pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       /* before manipulating the tbl, make it unknown to the card! */
+       impact_detachtxtbl(MMIO(p), pool);
+       if (PAR(p).pools[pool].size > 0) {
+               for (i = 0; i < PAR(p).pools[pool].txnum; i++) {
+                       
ClearPageReserved(dma_virt_to_page(PAR(p).pools[pool].virt[i]));
+                       dma_free_coherent(NULL, PAGE_SIZE, 
PAR(p).pools[pool].virt[i],
+                                       PAR(p).pools[pool].phys[i]);
+               }
+               vfree(PAR(p).pools[pool].phys);
+               vfree(PAR(p).pools[pool].virt);
+       }
+       impact_alloctxtbl(p, pool, pages);
+       PAR(p).pools[pool].virt = vmalloc(pages*sizeof(unsigned long));
+       PAR(p).pools[pool].phys = vmalloc(pages*sizeof(unsigned long));
+       for (i = 0; i < PAR(p).pools[pool].txnum; i++) {
+               PAR(p).pools[pool].virt[i] =
+                       dma_alloc_coherent(NULL, PAGE_SIZE, &dma_handle, 
GFP_KERNEL);
+               SetPageReserved(dma_virt_to_page(PAR(p).pools[pool].virt[i]));
+               PAR(p).pools[pool].phys[i] = dma_handle;
+               PAR(p).pools[pool].txtbl[i] = dma_handle >> PAGE_SHIFT;
+       }
+       i = sizeof(*PAR(p).pools[pool].txtbl) * PAR(p).pools[pool].txnum;
+       dma_cache_wback_inv((unsigned long)PAR(p).pools[pool].txtbl, i);
+       impact_writetxtbl(p, pool); /* finally attach the tbl to the card. */
+       PAR(p).pools[pool].size = pages * PAGE_SIZE;
+}
+
+static void
+impact_rect(unsigned long mmio, int x, int y, int w, int h, unsigned c, int lo)
+{
+       volatile typeof(IMPACT_CFIFO(0)) *cfifo = &IMPACT_CFIFO(mmio);
+       unsigned mode = lo != IMPACT_LO_COPY ? 0x6304:0x6300;
+       impact_wait_cfifo_empty(mmio);
+       impact_wait_rss_idle(mmio);
+       *cfifo = IMPACT_CMD_PP1FILLMODE(mode, lo);
+       *cfifo = IMPACT_CMD_FILLMODE(0);
+       *cfifo = IMPACT_CMD_PACKEDCOLOR(c);
+       *cfifo = IMPACT_CMD_BLOCKXYSTARTI(x, y);
+       *cfifo = IMPACT_CMD_BLOCKXYENDI(x+w-1, y+h-1);
+       *cfifo = IMPACT_CMD_IR_ALIAS(0x18);
+}
+
+static void
+impact_framerect(unsigned long mmio, int x, int y, int w, int h,
+       int bx, int by, unsigned c)
+{
+       impact_rect(mmio, x, y, w, by, c, IMPACT_LO_COPY);
+       impact_rect(mmio, x, y+h-by, w, by, c, IMPACT_LO_COPY);
+       impact_rect(mmio, x, y, bx, h, c, IMPACT_LO_COPY);
+       impact_rect(mmio, x+w-bx, y, bx, h, c, IMPACT_LO_COPY);
+}
+
+static unsigned long dcntr;
+static void impact_debug(struct fb_info *p, int v)
+{
+       int i;
+       IMPACT_CFIFO(MMIO(p)) = IMPACT_CMD_PIXCMD(3);
+       IMPACT_CFIFO(MMIO(p)) = IMPACT_CMD_HQ_PIXELFORMAT(0xe00);
+       switch(v) {
+       case 0:
+               for (i = 0; i < 64; i++)
+                       impact_rect(MMIO(p), 4*(i&7), 28-4*(i>>3), 4, 4,
+                               dcntr & (1L<<i) ? 0xa080ff:0x100030, 
IMPACT_LO_COPY);
+               break;
+       case 1:
+               dcntr++;
+               for (i = 0; i < 64; i++)
+                       impact_rect(MMIO(p), 4*(i&7), 28-4*(i>>3), 4, 4,
+                               dcntr & (1L<<i) ? 0xff80a0:0x300010, 
IMPACT_LO_COPY);
+               break;
+       case 2:
+               for (i = 0; i < 64; i++)
+                       impact_rect(MMIO(p), 4*(i&7), 28-4*(i>>3), 4, 4,
+                               dcntr & (1L<<i) ? 0xa0ff80:0x103000, 
IMPACT_LO_COPY);
+       }
+}
+
+static void impact_smallcopy(struct fb_info *p, unsigned sx, unsigned sy,
+                               unsigned dx, unsigned dy, unsigned w, unsigned 
h)
+{
+       volatile typeof(IMPACT_CFIFO(0)) *cfifo = &IMPACT_CFIFO(MMIO(p));
+       if (w < 1 || h < 1)
+               return;
+       w = (w+1) & ~1;
+       impact_wait_cfifo_empty(MMIO(p));
+       /* setup and perform DMA from RE to HOST */
+       impact_wait_dma(MMIO(p));
+       if (PAR(p).num_rss == 2 && (sy & 1))
+               *cfifo = IMPACT_CMD_CONFIG(0xca5);
+       else /* Beware, only I2 MaxImpact has 2 REs, SI, HI will hang ! */
+               *cfifo = IMPACT_CMD_CONFIG(0xca4);
+       *cfifo = IMPACT_CMD_PIXCMD(2);
+       *cfifo = IMPACT_CMD_PP1FILLMODE(0x2200, IMPACT_LO_COPY);
+       *cfifo = IMPACT_CMD_COLORMASKLSBSA(0xffffff);
+       *cfifo = IMPACT_CMD_COLORMASKLSBSB(0xffffff);
+       *cfifo = IMPACT_CMD_COLORMASKMSBS(0);
+       *cfifo = IMPACT_CMD_DRBPOINTERS(0xc8240);
+       *cfifo = IMPACT_CMD_BLOCKXYSTARTI(sx, sy+h-1);
+       *cfifo = IMPACT_CMD_BLOCKXYENDI(sx+w-1, sy);
+       *cfifo = IMPACT_CMD_XFRMASKLO(0xffffff);
+       *cfifo = IMPACT_CMD_XFRMASKHI(0xffffff);
+       *cfifo = IMPACT_CMD_XFRSIZE(w, h);
+       *cfifo = IMPACT_CMD_XFRCOUNTERS(w, h);
+       *cfifo = IMPACT_CMD_XFRMODE(0x00080);
+       *cfifo = IMPACT_CMD_FILLMODE(0x01000000);
+       *cfifo = IMPACT_CMD_HQ_PIXELFORMAT(0x200);
+       *cfifo = IMPACT_CMD_HQ_SCANWIDTH(w << 2);
+       *cfifo = IMPACT_CMD_HQ_DMATYPE(0x0a);
+       *cfifo = IMPACT_CMD_HQ_PG_LIST_0(0x80000000);
+       *cfifo = IMPACT_CMD_HQ_PG_WIDTH(w << 2);
+       *cfifo = IMPACT_CMD_HQ_PG_OFFSET(0);
+       *cfifo = IMPACT_CMD_HQ_PG_STARTADDR(0);
+       *cfifo = IMPACT_CMD_HQ_PG_LINECNT(h);
+       *cfifo = IMPACT_CMD_HQ_PG_WIDTHA(w << 2);
+       *cfifo = IMPACT_CMD_XFRCONTROL(8);
+       *cfifo = IMPACT_CMD_GLINE_XSTARTF(1);
+       *cfifo = IMPACT_CMD_IR_ALIAS(0x18);
+       *cfifo = IMPACT_CMD_HQ_DMACTRL_0(8);
+       *cfifo = IMPACT_CMD_XFRCONTROL(9);
+       impact_wait_dmaready(MMIO(p));
+       *cfifo = IMPACT_CMD_GLINE_XSTARTF(0);
+       *cfifo = IMPACT_CMD_RE_TOGGLECNTX(0);
+       *cfifo = IMPACT_CMD_XFRCOUNTERS(0, 0);
+       /* setup and perform DMA from HOST to RE */
+       impact_wait_dma(MMIO(p));
+       *cfifo = IMPACT_CMD_CONFIG(0xca4);
+       *cfifo = IMPACT_CMD_PP1FILLMODE(0x6200, IMPACT_LO_COPY);
+       *cfifo = IMPACT_CMD_BLOCKXYSTARTI(dx, dy+h-1);
+       *cfifo = IMPACT_CMD_BLOCKXYENDI(dx+w-1, dy);
+       *cfifo = IMPACT_CMD_FILLMODE(0x01400000);
+       *cfifo = IMPACT_CMD_XFRMODE(0x00080);
+       *cfifo = IMPACT_CMD_HQ_PIXELFORMAT(0x600);
+       *cfifo = IMPACT_CMD_HQ_SCANWIDTH(w << 2);
+       *cfifo = IMPACT_CMD_HQ_DMATYPE(0x0c);
+       *cfifo = IMPACT_CMD_PIXCMD(3);
+       *cfifo = IMPACT_CMD_XFRSIZE(w, h);
+       *cfifo = IMPACT_CMD_XFRCOUNTERS(w, h);
+       *cfifo = IMPACT_CMD_GLINE_XSTARTF(1);
+       *cfifo = IMPACT_CMD_IR_ALIAS(0x18);
+       *cfifo = IMPACT_CMD_XFRCONTROL(1);
+       *cfifo = IMPACT_CMD_HQ_PG_LIST_0(0x80000000);
+       *cfifo = IMPACT_CMD_HQ_PG_OFFSET(0);
+       *cfifo = IMPACT_CMD_HQ_PG_STARTADDR(0);
+       *cfifo = IMPACT_CMD_HQ_PG_LINECNT(h);
+       *cfifo = IMPACT_CMD_HQ_PG_WIDTHA(w << 2);
+       *cfifo = IMPACT_CMD_HQ_DMACTRL_0(0);
+       IMPACT_CFIFOW1(MMIO(p)) = 0x000e0400;
+       impact_wait_dma(MMIO(p));
+       *cfifo = IMPACT_CMD_GLINE_XSTARTF(0);
+       *cfifo = IMPACT_CMD_RE_TOGGLECNTX(0);
+       *cfifo = IMPACT_CMD_XFRCOUNTERS(0, 0);
+}
+
+static unsigned impact_getpalreg(struct fb_info *p, unsigned i)
+{
+       return ((unsigned *)p->pseudo_palette)[i];
+}
+
+/* ------------ Accelerated Functions --------------------- */
+
+static void impact_fillrect(struct fb_info *p, const struct fb_fillrect 
*region)
+{
+       unsigned long flags;
+       unsigned x = region->dx+PAR(p).xoffset;
+       unsigned y = region->dy+PAR(p).yoffset;
+       spin_lock_irqsave(&PAR(p).lock, flags);
+       if (!PAR(p).open_flag)
+               switch(region->rop) {
+               case ROP_XOR:
+                       impact_rect(MMIO(p), x, y, region->width, 
region->height,
+                               impact_getpalreg(p, region->color), 
IMPACT_LO_XOR);
+                       break;
+               case ROP_COPY:
+               default:
+                       impact_rect(MMIO(p), x, y, region->width, 
region->height,
+                               impact_getpalreg(p, region->color), 
IMPACT_LO_COPY);
+                       break;
+               }
+       spin_unlock_irqrestore(&PAR(p).lock, flags);
+}
+
+static void impact_copyarea(struct fb_info *p, const struct fb_copyarea *area)
+{
+       volatile typeof(IMPACT_CFIFO(0)) *cfifo = &IMPACT_CFIFO(MMIO(p));
+       unsigned sx, sy, dx, dy, w, h;
+       unsigned th, ah;
+       unsigned long flags;
+       w = area->width;
+       h = area->height;
+       if (w < 1 || h < 1)
+               return;
+       spin_lock_irqsave(&PAR(p).lock, flags);
+       if (PAR(p).open_flag) {
+               spin_unlock_irqrestore(&PAR(p).lock, flags);
+               return;
+       }
+       sx = area->sx + PAR(p).xoffset;
+       sy = 0x3ff - (area->sy + h - 1 + PAR(p).yoffset);
+       dx = area->dx + PAR(p).xoffset;
+       dy = 0x3ff - (area->dy + h - 1 + PAR(p).yoffset);
+       th = PAR(p).pools[0].size / (w*4);
+       *cfifo = IMPACT_CMD_XYWIN(0, 0);
+       if (dy > sy) {
+               dy += h;
+               sy += h;
+               while (h > 0) {
+                       ah = th > h ? h:th;
+                       impact_smallcopy(p, sx, sy-ah, dx, dy-ah, w, ah);
+                       dy -= ah;
+                       sy -= ah;
+                       h -= ah;
+               }
+       } else {
+               while (h > 0) {
+                       ah = th > h ? h:th;
+                       impact_smallcopy(p, sx, sy, dx, dy, w, ah);
+                       dy += ah;
+                       sy += ah;
+                       h -= ah;
+               }
+       }
+       *cfifo = IMPACT_CMD_PIXCMD(0);
+       *cfifo = IMPACT_CMD_HQ_PIXELFORMAT(0xe00);
+       *cfifo = IMPACT_CMD_CONFIG(0xcac);
+       *cfifo = IMPACT_CMD_XYWIN(0, 0x3ff);
+       spin_unlock_irqrestore(&PAR(p).lock, flags);
+}
+
+/* 8-bpp blits are done as PIO draw operation; the pixels are unpacked into
+   32-bpp values from the current palette in software */
+static void
+impact_imageblit_8bpp(struct fb_info *p, const struct fb_image *image)
+{
+       volatile typeof(IMPACT_CFIFO(0)) *cfifo = &IMPACT_CFIFO(MMIO(p));
+       int i, u, v;
+       const unsigned char *dp;
+       unsigned pix;
+       unsigned pal[256];
+       unsigned x = image->dx + PAR(p).xoffset;
+       unsigned y = image->dy + PAR(p).yoffset;
+       /* setup PIO to RE */
+       impact_wait_cfifo_empty(MMIO(p));
+       impact_wait_rss_idle(MMIO(p));
+       *cfifo = IMPACT_CMD_PP1FILLMODE(0x6300, IMPACT_LO_COPY);
+       *cfifo = IMPACT_CMD_BLOCKXYSTARTI(x, y);
+       *cfifo = IMPACT_CMD_BLOCKXYENDI(x+image->width-1, y+image->height-1);
+       *cfifo = IMPACT_CMD_FILLMODE(0x00c00000);
+       *cfifo = IMPACT_CMD_XFRMODE(0x00080);
+       *cfifo = IMPACT_CMD_XFRSIZE(image->width, image->height);
+       *cfifo = IMPACT_CMD_XFRCOUNTERS(image->width, image->height);
+       *cfifo = IMPACT_CMD_GLINE_XSTARTF(1);
+       *cfifo = IMPACT_CMD_IR_ALIAS(0x18);
+       /* another workaround.. 33 writes to alpha... hmm... */
+       for (i = 0; i < 33; i++)
+               *cfifo = IMPACT_CMD_ALPHA(0);
+       *cfifo = IMPACT_CMD_XFRCONTROL(2);
+       /* pairs of pixels are sent in two writes to the RE */
+       i = 0;
+       dp = image->data;
+       for (v = 0; v < 256; v++)
+               pal[v] = impact_getpalreg(p, v);
+       for (v = 0; v < image->height; v++) {
+               for (u = 0; u < image->width; u++) {
+                       pix = pal[*(dp++)];
+                       if (i)
+                               *cfifo = IMPACT_CMD_CHAR_L(pix);
+                       else
+                               *cfifo = IMPACT_CMD_CHAR_H(pix);
+                       i ^= 1;
+               }
+       }
+       if (i)
+               *cfifo = IMPACT_CMD_CHAR_L(0);
+       *cfifo = IMPACT_CMD_GLINE_XSTARTF(0);
+       *cfifo = IMPACT_CMD_RE_TOGGLECNTX(0);
+       *cfifo = IMPACT_CMD_XFRCOUNTERS(0, 0);
+}
+
+/* 1-bpp blits are done as character drawing; the bitmaps are drawn as 8-bit 
wide
+   strips; technically, Impact supports 16-pixel wide characters, but Linux 
bitmap
+   alignment is 8 bits and most draws are 8 pixels wide (font width), anyway */
+static void
+impact_imageblit_1bpp(struct fb_info *p, const struct fb_image *image)
+{
+       volatile typeof(IMPACT_CFIFO(0)) *cfifo = &IMPACT_CFIFO(MMIO(p));
+       int x, y, w, h, b;
+       int u, v, a;
+       const unsigned char *d;
+       impact_wait_cfifo_empty(MMIO(p));
+       impact_wait_rss_idle(MMIO(p));
+       *cfifo = IMPACT_CMD_PP1FILLMODE(0x6300, IMPACT_LO_COPY);
+       *cfifo = IMPACT_CMD_FILLMODE(0x400018);
+       a = impact_getpalreg(p, image->fg_color);
+       *cfifo = IMPACT_CMD_PACKEDCOLOR(a);
+       a = impact_getpalreg(p, image->bg_color);
+       /* Hmm, only the lower 4 bits are taken from red and blue. */
+       if (!isSR) a = (a>>4) & 0x0f000f | a & 0x00ff00;
+       *cfifo = IMPACT_CMD_BKGRD_RG(a & 0xffff);
+       *cfifo = IMPACT_CMD_BKGRD_BA((a & 0xff0000) >> 16);
+       x = image->dx + PAR(p).xoffset;
+       y = image->dy + PAR(p).yoffset;
+       w = image->width;
+       h = image->height;
+       b = (w+7) / 8;
+       for (u = 0; u < b; u++) {
+               impact_wait_cfifo_empty(MMIO(p));
+               a = (w<8) ? w:8;
+               d = image->data+u;
+               *cfifo = IMPACT_CMD_BLOCKXYSTARTI(x, y);
+               *cfifo = IMPACT_CMD_BLOCKXYENDI(x+a-1, y+h-1);
+               *cfifo = IMPACT_CMD_IR_ALIAS(0x18);
+               for (v = 0; v < h; v++) {
+                       *cfifo = IMPACT_CMD_CHAR(*d << 24);
+                       d += b;
+               }
+               w -= a;
+               x += a;
+       }
+}
+
+static void impact_imageblit(struct fb_info *p, const struct fb_image *image)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&PAR(p).lock, flags);
+       if (!PAR(p).open_flag)
+               switch(image->depth) {
+               case 1:
+                       impact_imageblit_1bpp(p, image);
+                       break;
+               case 8:
+                       impact_imageblit_8bpp(p, image);
+                       break;
+               }
+       spin_unlock_irqrestore(&PAR(p).lock, flags);
+}
+
+static int impact_sync(struct fb_info *info)
+{
+       return 0;
+}
+
+static int impact_blank(int blank_mode, struct fb_info *info)
+{
+       /* TODO */
+       return 0;
+}
+
+static int impact_setcolreg(unsigned regno, unsigned red, unsigned green,
+                       unsigned blue, unsigned transp, struct fb_info *info)
+{
+       if (regno > 255)
+               return 1;
+       ((unsigned *)info->pseudo_palette)[regno] =
+               (red >> 8) | (green & 0xff00) | ((blue << 8) & 0xff0000);
+       return 0;
+}
+
+/* ------------------- Framebuffer Access -------------------- */
+
+static ssize_t
+impact_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+{
+       return -EINVAL;
+}
+
+static ssize_t
+impact_write(struct file *file, const char __user *buf, size_t count, loff_t 
*ppos)
+{
+       return -EINVAL;
+}
+
+/* --------------------- Userland Access --------------------- */
+
+static int
+impact_cacheflush(struct fb_info *p, int pool, const struct impact_cf_args 
*arg)
+{
+       unsigned short w = arg->box.ws_xpixel << 2;
+       unsigned short h = arg->box.ws_ypixel;
+
+       if (w && h)
+       {       unsigned long a = arg->bpitch*arg->box.ws_row + (arg->box.ws_col 
<< 2);
+               unsigned long b = arg->base + PAR(p).pools[pool].size - w;
+
+               for (a += arg->base; h; h--, a += arg->bpitch)
+               {       if (!access_ok(VERIFY_WRITE, (void __user*)a, w))
+                               return -EFAULT;
+                       if (b <= a)
+                               return -EINVAL;
+                       (*_dma_cache_wback_inv)(a, w);
+               }
+       }
+       return 0;
+}
+
+static int
+impact_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+{
+       if (!isSR && IPNR != 22 && TCFLSH == cmd) {
+               static struct impact_cf_args cfpar;
+               int i;
+
+               if ( copy_from_user(&cfpar,(void __user*)arg,sizeof(cfpar)) )
+                       return -EFAULT;
+
+               if (!cfpar.base)
+                       return -EINVAL;
+
+               for (i = 0; i < POOLS; i++)
+                       if (cfpar.base == PAR(info).pools[i].uaddr) {
+                               int r = impact_cacheflush(info, i, &cfpar);
+                               /* Might be munmapped behind our back. */
+                               if (-EFAULT == r) {
+                                       printk(KERN_INFO "impact_ioctl: shut down 
user"
+                                               " cache-flush for DMA-pool %d 
(%p)\n",
+                                               i, cfpar.base);
+                                       PAR(info).pools[i].uaddr = 0;
+                               }
+                               return r;
+                       }
+       }
+       return -EINVAL;
+}
+
+static int impact_mmap(struct fb_info *p, struct vm_area_struct *vma)
+{
+       unsigned pool, i, n;
+       unsigned long size = vma->vm_end - vma->vm_start;
+       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+       unsigned long start;
+
+       switch(offset) {
+       case 0x0000000: /* map Impact-registers */
+               if (size > (isSR ? 0x200000:0x400000))
+                       return -EINVAL;
+               if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+                       return -EINVAL;
+               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+               vma->vm_flags |= VM_IO;
+               if (remap_pfn_range(vma, vma->vm_start, 
(MMIO(p)+offset)>>PAGE_SHIFT,
+                               size, vma->vm_page_prot))
+                       return -EAGAIN;
+               PAR(p).mmap_flag = 1;
+               break;
+       case 0x1000000: /* map e.g. shadow-frame-buffer */
+       case 0x2000000:
+       case 0x3000000:
+       case 0x8000000:
+       case 0x9000000:
+       case 0xa000000:
+       case 0xb000000:
+               if (size > (isSR ? 0x1000000:0xc00000))
+                       return -EINVAL;
+               pool = (offset >> 24) & 3; /* growonly = (offset>>24) & 8 */
+               n = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+               if (n*PAGE_SIZE != PAR(p).pools[pool].size)
+                       impact_resizekpool(p, pool, size, offset & 0x8000000);
+               if (22 == IPNR) /* IP22 memory may be written uncached */
+                       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+               for (start = vma->vm_start, i = 0; i < n; i++) {
+                       if (remap_pfn_range(vma, start,
+                                       PAR(p).pools[pool].phys[i] >> 
PAGE_SHIFT,
+                                       PAGE_SIZE, vma->vm_page_prot)) {
+                               PAR(p).pools[pool].uaddr = 0;
+                               return -EAGAIN;
+                       }
+                       start += PAGE_SIZE;
+               }
+               PAR(p).pools[pool].uaddr = vma->vm_start;
+               PAR(p).mmap_flag = 1;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int impact_open(struct fb_info *p, int user)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&PAR(p).lock, flags);
+       if (user)
+               PAR(p).open_flag++;
+       spin_unlock_irqrestore(&PAR(p).lock, flags);
+       return 0;
+}
+
+static int impact_release(struct fb_info *p, int user)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&PAR(p).lock, flags);
+       if (user && PAR(p).open_flag)
+               PAR(p).open_flag--;
+       spin_unlock_irqrestore(&PAR(p).lock, flags);
+       return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+    /*
+     *  Frame buffer operations
+     */
+
+static struct fb_ops impact_ops = {
+       .owner          = THIS_MODULE,
+       .fb_read        = impact_read,
+       .fb_write       = impact_write,
+       .fb_blank       = impact_blank,
+       .fb_fillrect    = impact_fillrect,
+       .fb_copyarea    = impact_copyarea,
+       .fb_imageblit   = impact_imageblit,
+       .fb_sync        = impact_sync,
+       .fb_ioctl       = impact_ioctl,
+       .fb_setcolreg   = impact_setcolreg,
+       .fb_mmap        = impact_mmap,
+       .fb_open        = impact_open,
+       .fb_release     = impact_release,
+};
+
+/* ------------------------------------------------------------------------- */
+
+    /*
+     *  Private early console
+     */
+
+#define MMIO_FIXED     (isSR ? 0x900000001c000000LL:0x900000001f000000LL)
+
+static inline void impact_earlyrect(int x, int y, int w, int h, unsigned c)
+{
+       impact_rect(MMIO_FIXED, x, y, w, h, c, IMPACT_LO_COPY);
+}
+
+static void
+impact_paintchar(int x, int y, unsigned char *b, unsigned c, unsigned a)
+{
+       volatile typeof(IMPACT_CFIFO(0)) *cfifo = &IMPACT_CFIFO(MMIO_FIXED);
+       int v;
+       /* Hmm, only the lower 4 bits are taken from red and blue. */
+       if (!isSR) a = (a>>4) & 0x0f000f | a & 0x00ff00;
+       impact_wait_cfifo_empty(MMIO_FIXED);
+       *cfifo = IMPACT_CMD_PP1FILLMODE(0x6300, IMPACT_LO_COPY);
+       *cfifo = IMPACT_CMD_FILLMODE(0x400018);
+       *cfifo = IMPACT_CMD_PACKEDCOLOR(c);
+       *cfifo = IMPACT_CMD_BKGRD_RG(a & 0xffff);
+       *cfifo = IMPACT_CMD_BKGRD_BA((a & 0xff0000) >> 16);
+       *cfifo = IMPACT_CMD_BLOCKXYSTARTI(x, y);
+       *cfifo = IMPACT_CMD_BLOCKXYENDI(x+7, y+15);
+       *cfifo = IMPACT_CMD_IR_ALIAS(0x18);
+       for (v = 0; v < 16; v++)
+               *cfifo = IMPACT_CMD_CHAR(*b++ << 24);
+}
+static void impact_earlyhwinit(void)
+{
+       impact_inithq(MMIO_FIXED);
+       impact_initrss(MMIO_FIXED);
+       impact_initxmap(MMIO_FIXED);
+       impact_initvc3(MMIO_FIXED);
+}
+
+static inline unsigned char *p8x16(unsigned char c)
+{
+       return ((unsigned char(*)[16])font_vga_8x16.data)[c];
+}
+
+static void impact_earlywrite(struct console*, const char*, unsigned);
+enum {
+       LightBlue = (230<<16)|(216<<8)|173,
+       DarkViolet2 = (105<<16)|74, LightGoldenrod = (130<<16)|(221<<8)|238,
+};
+#define EARLYBG 0x3f3f3f
+
+static struct {
+       int posx, posy;
+       spinlock_t lock;
+       struct console console;
+}
+early = {
+       .posx = -1,
+       .lock = __SPIN_LOCK_UNLOCKED(early.lock),
+       .console = {
+               .name = "earlyimpact",
+               .write = impact_earlywrite,
+               /*
+                * Omit CON_BOOT, so 'early' shall persist until fbcon takes 
over!
+                * Add CON_CONSDEV to detach a possibly active arc boot-console.
+                */
+               .flags = CON_CONSDEV | CON_PRINTBUFFER,
+               .index = -1,
+       },
+};
+
+void impact_earlychar(unsigned char c)
+{
+       if (early.posx != -1) {
+               unsigned long flags;
+               spin_lock_irqsave(&early.lock, flags);
+               if (c == '\n') {
+                       early.posy += 16;
+                       if (early.posy >= 800)
+                               early.posy = 0;
+                       early.posx = 0;
+                       goto out;
+               }
+               if (early.posx == 0) {
+                       impact_earlyrect(240, 112+early.posy, 800, 16, EARLYBG);
+                       if (early.posy+16*2 < 800)
+                               impact_earlyrect(240, 112+16+early.posy, 800, 
16, EARLYBG);
+               }
+               impact_paintchar(240+early.posx, 112+early.posy, p8x16(c), 
0xffffff, EARLYBG);
+               early.posx += 8;
+               if (early.posx >= 800) {
+                       early.posx = 0;
+                       early.posy += 16;
+                       if (early.posy >= 800)
+                               early.posy = 0;
+               }
+out:
+               spin_unlock_irqrestore(&early.lock, flags);
+       }
+}
+void impact_earlystring(char *s)
+{
+       while (*s)
+               impact_earlychar(*s++);
+}
+static void impact_earlywrite(struct console *con, const char *s, unsigned n)
+{
+       while (n-- && *s)
+               impact_earlychar(*s++);
+}
+void __init impact_earlyinit(void)
+{
+       static int up;
+       if (!up) {
+               impact_earlyhwinit();
+               impact_framerect(MMIO_FIXED, 0, 0, 1280, 1024, 240, 112, 
LightBlue);
+               impact_framerect(MMIO_FIXED, 240-4, 112-4, 800+8, 800+8, 4, 4, 
LightGoldenrod);
+               impact_earlyrect(240, 112, 800, 800, EARLYBG);
+               early.posx = 0;
+               early.posy = 0;
+               impact_earlystring("ImpactSR early console ready.\n");
+               up++;
+       }
+}
+void __init setup_impact_earlycons(void)
+{
+       static int up;
+       if (!up) {
+               impact_earlyinit();
+               register_console(&early.console);
+               up++;
+       }
+}
+
+/* ------------------------------------------------------------------------- */
+
+    /*
+     *  Initialization
+     */
+
+static inline unsigned long gfxphysaddr(void)
+{
+#if isSR
+       /* first card in Octane? */
+       int xwid = ip30_xtalk_find(IMPACT_XTALK_MFGR, IMPACT_XTALK_PART,
+                                       IP30_XTALK_NUM_WID);
+       return xwid == -1 ? 0:ip30_xtalk_swin(xwid);
+#else
+       extern unsigned long sgi_gfxaddr;       /* provided by ARCS */
+       return sgi_gfxaddr;
+#endif
+}
+
+static void __init impact_hwinit(struct fb_info *info)
+{
+       early.posx = -1;
+       /* initialize hardware */
+       impact_inithq(MMIO(info));
+       impact_initvc3(MMIO(info));
+       impact_initrss(MMIO(info));
+       impact_initxmap(MMIO(info));
+       impact_initdma(info);
+}
+
+static int __init impact_devinit(void)
+{
+       int i, x, y;
+       current_par.open_flag = 0;
+       current_par.mmap_flag = 0;
+       current_par.lock = __SPIN_LOCK_UNLOCKED(current_par.lock);
+
+       current_par.mmio_base = gfxphysaddr();
+       if (!current_par.mmio_base) {
+               printk(KERN_INFO "impact_devinit: !gfxaddr\n");
+               return -EINVAL;
+       }
+       current_par.mmio_virt = (unsigned long)
+               ioremap(current_par.mmio_base, 0x200000);
+       impact_fix.mmio_start = current_par.mmio_base;
+       impact_fix.mmio_len = 0x200000;
+
+       /* get board config */
+       current_par.num_ge = IMPACT_BDVERS1(current_par.mmio_virt) & 3;
+       if (!isSR) {
+               /* To do: desirably remove "... = 1; ". BDVERS1 fits on
+                * Solid-Impact, but couldn't check High-/Max- yet.
+                */
+               current_par.num_ge = 1;
+               /* Caveat: XImpact depends on the 'S' in id[6] to distinguish
+                * between ImpactSR and Impact by examining /proc/fb!
+                */
+               impact_fix.id[6] = '2';
+               impact_fix.id[7] = '0' + IPNR - 20;
+       }
+       current_par.num_rss = current_par.num_ge;
+       impact_fix.id[9] = '0' + current_par.num_rss;
+
+       info.flags = FBINFO_FLAG_DEFAULT;
+       info.screen_base = NULL;
+       info.fbops = &impact_ops;
+       info.fix = impact_fix;
+       info.var = impact_var;
+       info.par = &current_par;
+       info.pseudo_palette = pseudo_palette;
+
+       /* Can't wait any longer to switch off the early stuff */
+       unregister_console(&early.console);
+
+       impact_hwinit(&info);
+       /* initialize buffers */
+       impact_resizekpool(&info, 0, 65536, 0);
+       for (i = 1; i < USEPOOLS; ++i)
+               impact_resizekpool(&info, i, 8192, 0);
+
+       /* This has to been done !!! */
+       fb_alloc_cmap(&info.cmap, 256, 0);
+
+       if (register_framebuffer(&info) < 0) {
+               fb_dealloc_cmap(&info.cmap);
+               return -EINVAL;
+       }
+       x = (1280 - impact_var.xres) / 2;
+       y = (1024 - impact_var.yres) / 2;
+
+       /* Now we can take care of the nice-to-have stuff :-) */
+       impact_framerect(MMIO(&info), 0, 0, 1280, 1024, x, y, DarkViolet2);
+       impact_framerect(MMIO(&info), x-4, y-4, impact_var.xres+8,
+               impact_var.yres+8, 4, 4, LightGoldenrod);
+
+#if defined(CONFIG_LOGO)
+       if (fb_prepare_logo(&info, 0)) {
+               fb_set_cmap(&info.cmap, &info);
+               fb_show_logo(&info, 0);
+       }
+#endif
+       current_par.xoffset = x;
+       current_par.yoffset = y;
+
+       printk(KERN_INFO "fb%d: %s frame buffer device\n", info.node, 
info.fix.id);
+       return 0;
+}
+
+static int __init impact_probe(struct device *dev)
+{
+       return impact_devinit();
+}
+
+static struct platform_driver impact_driver = {
+       .driver = {
+               .name = (isSR ? "impactsr":"impact"),
+               .bus = &platform_bus_type,
+               .probe = impact_probe,
+               /* add remove someday */
+       },
+};
+
+static struct platform_device impact_device = {
+       .name = (isSR ? "impactsr":"impact"),
+};
+
+static int __init impact_init(void)
+{
+       int ret = driver_register(&impact_driver.driver);
+       if (!ret) {
+               ret = platform_device_register(&impact_device);
+               if (ret)
+                       driver_unregister(&impact_driver.driver);
+       }
+       return ret;
+}
+
+static void __exit impact_exit(void)
+{
+        driver_unregister(&impact_driver.driver);
+}
+
+module_init(impact_init);
+module_exit(impact_exit);
+
+MODULE_AUTHOR("Stanislaw Skowronek <skylark@linux-mips.org>, "\
+       "Indigo2-adaption: pf <post@pfrst.de>");
+MODULE_DESCRIPTION("SGI Octane ImpactSR HQ4, Indigo2 Impact HQ3 Video Driver");
+MODULE_VERSION("R28/R1.7");
+MODULE_LICENSE("GPL");


diff --git a/include/video/impact.h b/include/video/impact.h
new file mode 100644
index 0000000..e4b013c
--- /dev/null   Wed Dec  8 00:46:04 2004
+++ b/include/video/impact.h    Mon Jul 25 00:06:58 2011
@@ -0,0 +1,210 @@
+/*
+ *  linux/drivers/video/impactsr.h -- SGI Octane MardiGras (IMPACTSR) graphics
+ *  linux/include/video/impact.h   -- SGI Indigo2 MardiGras (IMPACT) graphics
+ *
+ *  Copyright (c) 2004-2006 by Stanislaw Skowronek     (skylark@linux-mips.org)
+ *  Adapted to Indigo2 by pf, 2005,2006,2009   (post@pfrst.de)
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#ifndef IMPACT_H
+#define IMPACT_H
+
+/* Convenient access macros */
+#define IMPACT_REG64(vma,off)  (*(volatile unsigned long long *)((vma)+(off)))
+#define IMPACT_REG32(vma,off)  (*(volatile unsigned int *)((vma)+(off)))
+#define IMPACT_REG16(vma,off)  (*(volatile unsigned short *)((vma)+(off)))
+#define IMPACT_REG8(vma,off)   (*(volatile unsigned char *)((vma)+(off)))
+
+#if defined(CONFIG_SGI_IP30)   /* Octane: Impact for "SpeedRacer"    */
+
+/* Xtalk */
+#define IMPACTSR_XTALK_MFGR            0x2aa
+#define IMPACTSR_XTALK_PART            0xc003
+
+/* ImpactSR (HQ4) register offsets */
+#define IMPACT_CFIFO(vma)              IMPACT_REG64(vma,0x20400)
+#define IMPACT_CFIFOW(vma)             IMPACT_REG32(vma,0x20400)
+#define IMPACT_CFIFOW1                 IMPACT_CFIFOW /* ? ? ? */
+#define IMPACT_CFIFOP(vma)             IMPACT_REG64(vma,0x130400)
+#define IMPACT_CFIFOPW(vma)            IMPACT_REG32(vma,0x130400)
+#define IMPACT_CFIFOPW1                        IMPACT_CFIFOPW /* ? ? ? */
+
+#define IMPACT_STATUS(vma)             IMPACT_REG32(vma,0x20000)
+#define IMPACT_FIFOSTATUS(vma) IMPACT_REG32(vma,0x20008)
+#define IMPACT_GIOSTATUS(vma)          IMPACT_REG32(vma,0x20100)
+#define IMPACT_DMABUSY(vma)            IMPACT_REG32(vma,0x20200)
+
+#define IMPACT_CFIFO_HW(vma)           IMPACT_REG32(vma,0x40000)
+#define IMPACT_CFIFO_LW(vma)           IMPACT_REG32(vma,0x40008)
+#define IMPACT_CFIFO_DELAY(vma)        IMPACT_REG32(vma,0x40010)
+#define IMPACT_DFIFO_HW(vma)           IMPACT_REG32(vma,0x40020)
+#define IMPACT_DFIFO_LW(vma)           IMPACT_REG32(vma,0x40028)
+#define IMPACT_DFIFO_DELAY(vma)        IMPACT_REG32(vma,0x40030)
+
+#define IMPACT_XMAP_OFF(off)   (0x71c00+(off))
+#define IMPACT_VC3_OFF(off)    (0x72000+(off))
+#define IMPACT_RSS_OFF(off)    (0x2c000+(off))
+
+#else /* Indigo2: IP28, IP26, IP22: Impact graphics    */
+
+/* Impact (HQ3) register offsets */
+#define IMPACT_CFIFO(vma)              IMPACT_REG64(vma,0x70080)
+#define IMPACT_CFIFOW(vma)             IMPACT_REG32(vma,0x70080)
+#define IMPACT_CFIFOW1(vma)            IMPACT_REG32(vma,0x70084)
+#define IMPACT_CFIFOP(vma)             IMPACT_REG64(vma,0x50080)
+#define IMPACT_CFIFOPW(vma)            IMPACT_REG32(vma,0x50080)
+#define IMPACT_CFIFOPW1(vma)           IMPACT_REG32(vma,0x50084)
+
+#define IMPACT_STATUS(vma)             IMPACT_REG32(vma,0x70000)
+#define IMPACT_FIFOSTATUS(vma) IMPACT_REG32(vma,0x70004)
+#define IMPACT_GIOSTATUS(vma)          IMPACT_REG32(vma,0x70100)
+#define IMPACT_DMABUSY(vma)            IMPACT_REG32(vma,0x70104)
+
+#define IMPACT_CFIFO_HW(vma)           IMPACT_REG32(vma,0x50020)
+#define IMPACT_CFIFO_LW(vma)           IMPACT_REG32(vma,0x50024)
+#define IMPACT_CFIFO_DELAY(vma)        IMPACT_REG32(vma,0x50028)
+#define IMPACT_DFIFO_HW(vma)           IMPACT_REG32(vma,0x5002c)
+#define IMPACT_DFIFO_LW(vma)           IMPACT_REG32(vma,0x50030)
+#define IMPACT_DFIFO_DELAY(vma)        IMPACT_REG32(vma,0x50034)
+
+#define IMPACT_XMAP_OFF(off)   (0x61c00+(off))
+#define IMPACT_VC3_OFF(off)    (0x62000+(off))
+#define IMPACT_RSS_OFF(off)    (0x7c000+(off))
+
+#endif
+
+#define IMPACT_RESTATUS(vma)           IMPACT_REG32(vma,IMPACT_RSS_OFF(0x578))
+
+#define IMPACT_XMAP_PP1SELECT(vma)     IMPACT_REG8(vma,IMPACT_XMAP_OFF(0x008))
+#define IMPACT_XMAP_INDEX(vma) IMPACT_REG8(vma,IMPACT_XMAP_OFF(0x088))
+#define IMPACT_XMAP_CONFIG(vma)        IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x100))
+#define IMPACT_XMAP_CONFIGB(vma)       IMPACT_REG8(vma,IMPACT_XMAP_OFF(0x108))
+#define IMPACT_XMAP_BUF_SELECT(vma)    IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x180))
+#define IMPACT_XMAP_MAIN_MODE(vma)     IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x200))
+#define IMPACT_XMAP_OVERLAY_MODE(vma)  IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x280))
+#define IMPACT_XMAP_DIB(vma)           IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x300))
+#define IMPACT_XMAP_DIB_DW(vma)        IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x340))
+#define IMPACT_XMAP_RE_RAC(vma)        IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x380))
+
+#define IMPACT_VC3_INDEX(vma)          IMPACT_REG8(vma,IMPACT_VC3_OFF(0x008))
+#define IMPACT_VC3_INDEXDATA(vma)      IMPACT_REG32(vma,IMPACT_VC3_OFF(0x038))
+#define IMPACT_VC3_DATA(vma)           IMPACT_REG16(vma,IMPACT_VC3_OFF(0x0b0))
+#define IMPACT_VC3_RAM(vma)            IMPACT_REG16(vma,IMPACT_VC3_OFF(0x190))
+
+#define IMPACT_BDVERS0(vma)            IMPACT_REG8(vma,IMPACT_VC3_OFF(0x408))
+#define IMPACT_BDVERS1(vma)            IMPACT_REG8(vma,IMPACT_VC3_OFF(0x488))
+
+/* FIFO status */
+#if defined(CONFIG_SGI_IP30)
+#define IMPACT_CFIFO_MAX               128
+#else
+#define IMPACT_CFIFO_MAX               64
+#endif
+#define IMPACT_BFIFO_MAX               16
+
+/* Commands for CFIFO */
+static __inline__
+unsigned long long ImpactCmdCFifo64( unsigned cmd, unsigned reg, unsigned val )
+{
+       return (unsigned long long)(cmd | reg<<8) << 32 | val;
+}
+static __inline__
+unsigned long long ImpactCmdWriteRSS( unsigned reg, unsigned val )
+{
+       return (0x00180004LL | reg<<8) << 32 | val;
+}
+static __inline__
+unsigned long long ImpactCmdExecRSS( unsigned reg, unsigned val )
+{
+       return (0x001c0004LL | reg<<8) << 32 | val;
+}
+
+#define IMPACT_CMD_GLINE_XSTARTF(v)    ImpactCmdWriteRSS(0x00c,v)
+#define IMPACT_CMD_IR_ALIAS(v)         ImpactCmdExecRSS(0x045,v)
+#define IMPACT_CMD_BLOCKXYSTARTI(x,y)  ImpactCmdWriteRSS(0x046,((x)<<16)|(y))
+#define IMPACT_CMD_BLOCKXYENDI(x,y)    ImpactCmdWriteRSS(0x047,((x)<<16)|(y))
+#define IMPACT_CMD_PACKEDCOLOR(v)      ImpactCmdWriteRSS(0x05b,v)
+#define IMPACT_CMD_RED(v)              ImpactCmdWriteRSS(0x05c,v)
+#define IMPACT_CMD_ALPHA(v)            ImpactCmdWriteRSS(0x05f,v)
+#define IMPACT_CMD_CHAR(v)             ImpactCmdExecRSS(0x070,v)
+#define IMPACT_CMD_CHAR_H(v)           ImpactCmdWriteRSS(0x070,v)
+#define IMPACT_CMD_CHAR_L(v)           ImpactCmdExecRSS(0x071,v)
+#define IMPACT_CMD_XFRCONTROL(v)       ImpactCmdWriteRSS(0x102,v)
+#define IMPACT_CMD_FILLMODE(v)         ImpactCmdWriteRSS(0x110,v)
+#define IMPACT_CMD_CONFIG(v)           ImpactCmdWriteRSS(0x112,v)
+#define IMPACT_CMD_XYWIN(x,y)          ImpactCmdWriteRSS(0x115,((y)<<16)|(x))
+#define IMPACT_CMD_BKGRD_RG(v)         ImpactCmdWriteRSS(0x140,((v)<<8))
+#define IMPACT_CMD_BKGRD_BA(v)         ImpactCmdWriteRSS(0x141,((v)<<8))
+#define IMPACT_CMD_WINMODE(v)          ImpactCmdWriteRSS(0x14f,v)
+#define IMPACT_CMD_XFRSIZE(x,y)                
ImpactCmdWriteRSS(0x153,((y)<<16)|(x))
+#define IMPACT_CMD_XFRMASKLO(v)                ImpactCmdWriteRSS(0x156,v)
+#define IMPACT_CMD_XFRMASKHI(v)                ImpactCmdWriteRSS(0x157,v)
+#define IMPACT_CMD_XFRCOUNTERS(x,y)    ImpactCmdWriteRSS(0x158,((y)<<16)|(x))
+#define IMPACT_CMD_XFRMODE(v)          ImpactCmdWriteRSS(0x159,v)
+#define IMPACT_CMD_RE_TOGGLECNTX(v)    ImpactCmdWriteRSS(0x15f,v)
+#define IMPACT_CMD_PIXCMD(v)           ImpactCmdWriteRSS(0x160,v)
+#define IMPACT_CMD_PP1FILLMODE(m,o)    ImpactCmdWriteRSS(0x161,(m)|(o<<26))
+#define IMPACT_CMD_COLORMASKMSBS(v)    ImpactCmdWriteRSS(0x162,v)
+#define IMPACT_CMD_COLORMASKLSBSA(v)   ImpactCmdWriteRSS(0x163,v)
+#define IMPACT_CMD_COLORMASKLSBSB(v)   ImpactCmdWriteRSS(0x164,v)
+#define IMPACT_CMD_BLENDFACTOR(v)      ImpactCmdWriteRSS(0x165,v)
+#define IMPACT_CMD_DRBPOINTERS(v)      ImpactCmdWriteRSS(0x16d,v)
+
+#define IMPACT_CMD_HQ_PIXELFORMAT(v)   ImpactCmdCFifo64(0x000c0004,0,v)
+#define IMPACT_CMD_HQ_SCANWIDTH(v)     ImpactCmdCFifo64(0x000a0204,0,v)
+#define IMPACT_CMD_HQ_DMATYPE(v)       ImpactCmdCFifo64(0x000a0604,0,v)
+#define IMPACT_CMD_HQ_PG_LIST_0(v)     ImpactCmdCFifo64(0x00080004,0,v)
+#define IMPACT_CMD_HQ_PG_WIDTH(v)      ImpactCmdCFifo64(0x00080404,0,v)
+#define IMPACT_CMD_HQ_PG_OFFSET(v)     ImpactCmdCFifo64(0x00080504,0,v)
+#define IMPACT_CMD_HQ_PG_STARTADDR(v)  ImpactCmdCFifo64(0x00080604,0,v)
+#define IMPACT_CMD_HQ_PG_LINECNT(v)    ImpactCmdCFifo64(0x00080704,0,v)
+#define IMPACT_CMD_HQ_PG_WIDTHA(v)     ImpactCmdCFifo64(0x00080804,0,v)
+#define IMPACT_CMD_HQ_DMACTRL_0(v)     (0x00080b04000000b1LL|(v)&8)
+#define IMPACT_CMD_HQ_TXBASE(p)                (0x00482008|((p)<<9))
+#define IMPACT_CMD_HQ_TXMAX(p,v)       ImpactCmdCFifo64(0x00483004,p,v)
+#define IMPACT_CMD_HQ_PGBITS(p,v)      ImpactCmdCFifo64(0x00482b04,p,v)
+#define IMPACT_CMD_HQ_PGSIZE(v)                ImpactCmdCFifo64(0x00482a04,0,v)
+#define IMPACT_CMD_HQ_STACKPTR(v)      ImpactCmdCFifo64(0x00483a04,0,v)
+#define IMPACT_CMD_HQ_484A(p,v)                ImpactCmdCFifo64(0x00484a04,p,v)
+#define IMPACT_CMD_HQ_484B(p,v)                ImpactCmdCFifo64(0x00484b04,p,v)
+
+/* Logic operations for the PP1 (SI=source invert, DI=dest invert, RI=result 
invert) */
+#define IMPACT_LO_CLEAR        0
+#define IMPACT_LO_AND          1
+#define IMPACT_LO_DIAND        2
+#define IMPACT_LO_COPY 3
+#define IMPACT_LO_SIAND        4
+#define IMPACT_LO_NOP          5
+#define IMPACT_LO_XOR          6
+#define IMPACT_LO_OR           7
+#define IMPACT_LO_RIOR 8
+#define IMPACT_LO_RIXOR        9
+#define IMPACT_LO_RINOP        10
+#define IMPACT_LO_DIOR 11
+#define IMPACT_LO_RICOPY       12
+#define IMPACT_LO_SIOR 13
+#define IMPACT_LO_RIAND        14
+#define IMPACT_LO_SET          15
+
+/* Blending factors */
+#define IMPACT_BLEND_ALPHA     0x0704c900
+
+#ifdef  __KERNEL__
+extern void impact_earlychar(unsigned char c);
+extern void impact_earlystring(char *s);
+extern void impact_earlyinit(void);
+extern void setup_impact_earlycons(void);
+#endif
+
+struct impact_cf_args
+{
+       struct winsize box;     /* termios.h */
+       unsigned long long base;
+       unsigned bpitch;
+};
+
+#endif /* IMPACT_H */

<Prev in Thread] Current Thread [Next in Thread>