This patch provides some enhancements for XImpact:

- Check for available cache-flush methods, and use the kernel-driver's
  cache-flush ioctl if possible. (This method is likely to be the only one
  available, when the Impact kernel-driver is finally incorporated into the
  Linux-kernel! Besides, it performs slightly better than lib-cacheflush
  for a majority of window-sizes.)
  If none is available, fall back to PIO-mode automatically.

- Recognize Impact/R4k (with the help of an up to date kernel-driver) and
  handle it appropriately. (Though this could not be tested yet)

- The borders, where to switch between PIO and DMA or between DMA-Methods
  are more accurate now.


Signed-off-by: peter fuerst <[email protected]>

---

 src/impact.h        |    8 ++-
 src/impact_driver.c |   38 ++++++++++-----
 src/impact_regs.h   |   18 +++++--
 src/impact_shadow.c |  134 ++++++++++++++++++++++++++++++++++++++++-----------
 4 files changed, 150 insertions(+), 48 deletions(-)


diff --git a/src/impact.h b/src/impact.h
index 31f69c6..ce6b148 100644
--- a/xorg/driver/xf86-video-impact/src/impact.h        Thu Oct 28 07:32:19 
2010 -0400
+++ b/xorg/driver/xf86-video-impact/src/impact.h        Thu Jul 21 03:39:43 2011
@@ -50,7 +50,9 @@

 typedef struct {
        unsigned busID;
-       unsigned isSR;
+       unsigned IPnr;
+#      define IMPACTSR_IP(i) ((i) > 28)
+#      define IMPACTSR(p) IMPACTSR_IP((p)->IPnr)
        int devFD;
        int bitplanes;

@@ -139,7 +141,9 @@ void ImpactBackupPalette(ScrnInfoPtr);
 int ImpactDepth24Flags(void);
 void ImpactI2RefreshArea8(ScrnInfoPtr, int num, BoxPtr pbox);
 void ImpactSRRefreshArea8(ScrnInfoPtr, int num, BoxPtr pbox);
-void ImpactI2RefreshArea32(ScrnInfoPtr, int num, BoxPtr pbox);
+void ImpactIP28RefreshArea32(ScrnInfoPtr, int num, BoxPtr pbox);
+void ImpactIP22RefreshArea32(ScrnInfoPtr, int num, BoxPtr pbox);
 void ImpactSRRefreshArea32(ScrnInfoPtr, int num, BoxPtr pbox);
+void ImpactI2FindCflushmode(ImpactPtr);

 #endif /* __IMPACT_H__ */


diff --git a/src/impact_driver.c b/src/impact_driver.c
index 924db4a..cb16b4a 100644
--- a/xorg/driver/xf86-video-impact/src/impact_driver.c Thu Oct 28 07:32:19 
2010 -0400
+++ b/xorg/driver/xf86-video-impact/src/impact_driver.c Sun Jul 24 21:37:47 2011
@@ -80,7 +80,7 @@

 struct probed_id {
        unsigned char id;
-       unsigned char sr;
+       unsigned char ip;
 };


@@ -251,7 +251,7 @@ ImpactProbe(DriverPtr drv, int flags)
                                        int entity;
                                        ScrnInfoPtr pScrn = 0;
                                        entity = xf86ClaimNoSlot(drv, 0, dev, 
TRUE);
-                                       if (probedIDs[j].sr) {
+                                       if (IMPACTSR_IP(probedIDs[j].ip)) {
                                                base = (IMPACTSR_BASE_ADDR0 + 
busID * IMPACTSR_BASE_OFFSET);
                                                RANGE(range[0], base,
                                                        base + 
sizeof(ImpactSRRegs), ResExcMemBlock);
@@ -271,7 +271,7 @@ ImpactProbe(DriverPtr drv, int flags)
                                        pScrn->EnterVT = ImpactEnterVT;
                                        pScrn->LeaveVT = ImpactLeaveVT;
                                        pScrn->driverPrivate =
-                                               (void*)(busID | 
(long)probedIDs[j].sr<<16);
+                                               (void*)(busID | 
(long)probedIDs[j].ip<<16);
                                        foundScreen = TRUE;
                                        break;
                                }
@@ -357,10 +357,10 @@ ImpactPreInit(ScrnInfoPtr pScrn, int flags)
        /* ...and initialize it. */
        pImpact = IMPACTPTR(pScrn);
        pImpact->busID = busID & 0xffff;
-       pImpact->isSR  = busID >> 16;
+       pImpact->IPnr  = busID >> 16;
        pImpact->FlushBoxCache = 0;

-       if (pImpact->isSR) {
+       if (IMPACTSR(pImpact)) {
                pImpact->WaitCfifoEmpty = &ImpactSRWaitCfifoEmpty;
                pImpact->WaitDMAOver = &ImpactSRWaitDMAOver;
                pImpact->WaitDMAReady = &ImpactSRWaitDMAReady;
@@ -381,7 +381,10 @@ ImpactPreInit(ScrnInfoPtr pScrn, int flags)
                pImpact->XmapGetModeRegister = &ImpactI2XmapGetModeRegister;
                pImpact->XmapSetModeRegister = &ImpactI2XmapSetModeRegister;
                pImpact->RefreshArea8  = &ImpactI2RefreshArea8;
-               pImpact->RefreshArea32 = &ImpactI2RefreshArea32;
+               if (22 == pImpact->IPnr)
+                       pImpact->RefreshArea32 = &ImpactIP22RefreshArea32;
+               else
+                       pImpact->RefreshArea32 = &ImpactIP28RefreshArea32;
                pImpact->base_addr0 = IMPACTI2_BASE_ADDR0;
                pImpact->base_offset = IMPACTI2_BASE_OFFSET;
        }
@@ -603,6 +606,9 @@ ImpactScreenInit(int index, ScreenPtr pScreen, int argc, 
char **argv)
        if (1 == serverGeneration)
                xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);

+       if (!IMPACTSR(pImpact))
+               ImpactI2FindCflushmode(pImpact);
+
        return TRUE;

 out_freerec:
@@ -731,7 +737,7 @@ ImpactHWProbe(struct probed_id probedIDs[], int lim)
        FILE* fb;
        int hasImpact = 0;

-       probedIDs[0].sr = probedIDs[0].id = 0;
+       probedIDs[0].ip = probedIDs[0].id = 0;
        if (IMPACT_MAX_BOARDS < lim)
                lim = IMPACT_MAX_BOARDS;

@@ -741,9 +747,17 @@ ImpactHWProbe(struct probed_id probedIDs[], int lim)
                        char *s;
                        unsigned i = strtoul(line,&s,10);
                        if ( !strncmp(s," Impact",7) ) {
-                               probedIDs[hasImpact].sr = ('S' == s[7]);
-                               probedIDs[hasImpact].id = i;
-                               hasImpact++;
+                               switch (s[7]) {
+                                       case '2':
+                                               probedIDs[hasImpact].ip = 22 + 
s[8] - '2';
+                                               break;
+                                       case 'S':
+                                               probedIDs[hasImpact].ip = 30;
+                                               break;
+                                       default:
+                                               probedIDs[hasImpact].ip = 28;
+                               }
+                               probedIDs[hasImpact++].id = i;
                        }
                }
                fclose(fb);
@@ -797,7 +811,7 @@ ImpactMapRegs(ScrnInfoPtr pScrn)
                ErrorF("ImpactMapRegs: failed to open /dev/fb%d (%s)\n",
                        pImpact->busID , strerror(errno));
        else {
-               size_t size = pImpact->isSR ? 0x200000:sizeof(ImpactI2Regs);
+               size_t size = IMPACTSR(pImpact) ? 0x200000:sizeof(ImpactI2Regs);
                pImpact->pImpactRegs =
                        mmap((void*)0, size, PROT_READ|PROT_WRITE,
                                MAP_SHARED, pImpact->devFD, 0);
@@ -839,7 +853,7 @@ static void
 ImpactUnmapRegs(ScrnInfoPtr pScrn)
 {
        ImpactPtr pImpact = IMPACTPTR(pScrn);
-       size_t size = pImpact->isSR ? 0x200000:sizeof(ImpactI2Regs);
+       size_t size = IMPACTSR(pImpact) ? 0x200000:sizeof(ImpactI2Regs);

        if (pImpact->pImpactRegs)
                munmap( pImpact->pImpactRegs, size );


diff --git a/src/impact_regs.h b/src/impact_regs.h
index e29b941..f6b16c9 100644
--- a/xorg/driver/xf86-video-impact/src/impact_regs.h   Thu Oct 28 07:32:19 
2010 -0400
+++ b/xorg/driver/xf86-video-impact/src/impact_regs.h   Wed Jul 27 21:51:20 2011
@@ -147,11 +147,19 @@ ImpactFifoCmd64( mgicfifo_t *fifo, unsigned cmd, unsigned 
reg, unsigned val )
 }

 static __inline__ void
-ImpactFifoCmd32( mgicfifo_t *fifo, unsigned cmd, unsigned reg )
+ImpactFifoCmd32hi( mgicfifo_t *fifo, unsigned cmd, unsigned reg )
+{
+       fifo->w = cmd | reg<<8;
+}
+
+static __inline__ void
+ImpactFifoCmd32lo( mgicfifo_t *fifo, unsigned cmd, unsigned reg )
 {
        (&fifo->w)[1] = cmd | reg<<8;
 }

+#define ImpactFifoCmd32 ImpactFifoCmd32hi
+
 #define ImpactCmdWriteRss( fifo, reg, val )\
        ImpactFifoCmd64( fifo, 0x00180004, reg, val )
 #define ImpactCmdExecRss( fifo, reg, val )\
@@ -193,13 +201,11 @@ ImpactFifoCmd32( mgicfifo_t *fifo, unsigned cmd, unsigned 
reg )
 #define impact_cmd_hq_pg_startaddr(f,v)        
ImpactFifoCmd64(f,0x00080604,0,v)
 #define impact_cmd_hq_pg_linecnt(f,v)  ImpactFifoCmd64(f,0x00080704,0,v)
 #define impact_cmd_hq_pg_widtha(f,v)   ImpactFifoCmd64(f,0x00080804,0,v)
-#if 0
+
 #define impact_cmd_hq_dmactrl_1(f)     ImpactFifoCmd32(f,0x00080b04,0)
-#define impact_cmd_hq_dmactrl_2(f)     
ImpactFifoCmd64(f,0x000000b7,0,0x000e0400)
-#else
+#define impact_cmd_hq_dmactrl_2(f,p)   
ImpactFifoCmd64(f,((p)<<1)|0x000000b1,0,0x000e0400)
 #define impact_cmd_hq_dmactrl_a(f,p)   
ImpactFifoCmd64(f,0x00080b04,0,((p)<<1)|0x000000b1)
-#define impact_cmd_hq_dmactrl_b(f)     ImpactFifoCmd32(f,0x000e0400,0)
-#endif
+#define impact_cmd_hq_dmactrl_b(f)     ImpactFifoCmd32lo(f,0x000e0400,0)

 /* Now the Indexed registers of the VC2. */
 #define VC2_IREG_CONFIG    0x1f        /* this is wrong (0x20) in 
newport_regs.h */


diff --git a/src/impact_shadow.c b/src/impact_shadow.c
index fffd507..6bc711e 100644
--- a/xorg/driver/xf86-video-impact/src/impact_shadow.c Thu Oct 28 07:32:19 
2010 -0400
+++ b/xorg/driver/xf86-video-impact/src/impact_shadow.c Wed Jul 27 21:59:04 2011
@@ -168,30 +168,81 @@ ImpactSRRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr 
pbox)
  * 32-bit blits are done as DMA operations, which is FAST on SGI machines
  */

+static void (*ImpactCflushBox)(int, char*, BoxPtr, unsigned);
+
 static void
-ImpactCflushBoxPixlines(int fd, char *base, BoxPtr box, unsigned bpitch)
+ImpactCflushLib(int fd, char *base, BoxPtr box, unsigned bpitch)
 {
-       int w = (box->x2 - box->x1) << 2;
+       int w = box->x2 - box->x1;
        int h = box->y2 - box->y1;
        int i;

        base += bpitch*box->y1 + 4*box->x1;
-
-       /* One syscall for each pixel-line. */
-       for (i = 0; i < h; i++, base += bpitch)
-               cacheflush(base, w, DCACHE);
+       /*
+        * This border was found to be suitable on IP28,
+        * it may or may not fit IP26's conditions.
+        */
+       if (w > 865 || 4*w > 5440 - 11*h && 10*w > 8180 - 14*h)
+               /* Whole enclosing mem, although may be mostly unconcerned. */
+               cacheflush(base, (h-1)*bpitch + (w << 2), DCACHE);
+       else
+               /* One syscall for each pixel-line. */
+               for (w <<= 2, i = 0; i < h; i++, base += bpitch)
+                       cacheflush(base, w, DCACHE);
 }

 static void
-ImpactCflushBoxEnclosure(int fd, char *base, BoxPtr box, unsigned bpitch)
+ImpactCflushDrv(int fd, char *base, BoxPtr box, unsigned bpitch)
 {
-       int w = (box->x2 - box->x1) << 2;
-       int h = box->y2 - box->y1;
-
-       base += bpitch*box->y1 + 4*box->x1;
+       struct
+       {       struct winsize box;
+               unsigned long long base;
+               unsigned bpitch;
+       } par;
+
+       /* One cacheflush for each pixel-line by a single syscall. */
+       par.box.ws_col = box->x1;
+       par.box.ws_row = box->y1;
+       par.box.ws_xpixel = box->x2 - box->x1;
+       par.box.ws_ypixel = box->y2 - box->y1;
+       par.base = (unsigned long long) base;
+       par.bpitch = bpitch;
+       ioctl(fd, TCFLSH, &par);
+}

-       /* Whole enclosing mem, although may be mostly unconcerned. */
-       cacheflush(base, (h-1)*bpitch + w, DCACHE);
+void
+ImpactI2FindCflushmode(ImpactPtr pImpact)
+{
+       if (pImpact->IPnr != 22) {
+               struct
+               {       struct winsize box;
+                       unsigned long long base;
+                       unsigned bpitch;
+               } par;
+
+               par.box.ws_col = par.box.ws_row = 0;
+               par.box.ws_xpixel = par.box.ws_ypixel = 1;
+               par.base = (unsigned long long) pImpact->ShadowPtr;
+               par.bpitch = pImpact->ShadowPitch;
+               /*
+                * Does the Impact kernel-driver provide the special cache
+                * flush ioctl? If available, use it.
+                */
+               if (!ioctl(pImpact->devFD, TCFLSH, &par)) {
+                       ErrorF("Using kernel driver's cache-flush-ioctl.\n");
+                       ImpactCflushBox = ImpactCflushDrv;
+               /*
+                * Only the extended sys_cacheflush() would check its 3rd
+                * parameter and return non-zero here. The "standard" version
+                * simply assumes ICACHE, returning 0.
+                */
+               } else if (cacheflush(pImpact->ShadowPtr, 4, -1)) {
+                       ErrorF("Using cacheflush() system call from libc.\n");
+                       ImpactCflushBox = ImpactCflushLib;
+               } else
+                       ErrorF("No cache-flush method available, "
+                               "falling back to PIO mode.\n");
+       }
 }


@@ -235,9 +286,13 @@ ImpactRefreshBoxDMA(int isSR, mgicfifo_t *cfifo, BoxPtr 
box, unsigned bpitch)
        impact_cmd_hq_pg_startaddr(cfifo, bpitch*box->y1+(box->x1<<2));
        impact_cmd_hq_pg_linecnt(cfifo, h);
        impact_cmd_hq_pg_widtha(cfifo, w<<2);
-       impact_cmd_hq_dmactrl_a(cfifo,3);
-       impact_cmd_hq_dmactrl_b(cfifo);
-
+       if (isSR) { /* but both (should) do the same  :) */
+               impact_cmd_hq_dmactrl_1(cfifo);
+               impact_cmd_hq_dmactrl_2(cfifo,3);
+       } else {
+               impact_cmd_hq_dmactrl_a(cfifo,3);
+               impact_cmd_hq_dmactrl_b(cfifo);
+       }
        return 1;
 }

@@ -257,7 +312,7 @@ ImpactRefreshArea32DMA(ImpactPtr pImpact, int num, BoxPtr 
pbox)
 {
        ImpactRegsPtr pImpactRegs = pImpact->pImpactRegs;
        mgicfifo_t *cfifo =
-               pImpact->isSR ? &pImpactRegs->sr.cfifo:&pImpactRegs->i2.cfifo;
+               IMPACTSR(pImpact) ? 
&pImpactRegs->sr.cfifo:&pImpactRegs->i2.cfifo;
        unsigned bpitch = pImpact->ShadowPitch;

        for (; num-- > 0; pbox++) {
@@ -273,7 +328,7 @@ ImpactRefreshArea32DMA(ImpactPtr pImpact, int num, BoxPtr 
pbox)
                                                &sanebox, bpitch);

                (*pImpact->WaitDMAOver)(pImpactRegs);
-               ImpactRefreshBoxDMA(pImpact->isSR, cfifo, &sanebox, bpitch);
+               ImpactRefreshBoxDMA(IMPACTSR(pImpact), cfifo, &sanebox, bpitch);
                (*pImpact->WaitDMAOver)(pImpactRegs);
                ImpactPostRefreshBoxDMA(cfifo);
        }
@@ -290,7 +345,7 @@ ImpactRefreshArea32PIO(ImpactPtr pImpact, int num, BoxPtr 
pbox)
 {
        ImpactRegsPtr pImpactRegs = pImpact->pImpactRegs;
        mgicfifo_t *cfifo =
-               pImpact->isSR ? &pImpactRegs->sr.cfifo:&pImpactRegs->i2.cfifo;
+               IMPACTSR(pImpact) ? 
&pImpactRegs->sr.cfifo:&pImpactRegs->i2.cfifo;
        unsigned bpitch = pImpact->ShadowPitch;

        for (; num--; pbox++) {
@@ -324,27 +379,50 @@ ImpactRefreshArea32PIO(ImpactPtr pImpact, int num, BoxPtr 
pbox)
 }


+/*
+ * IP28 and IP26 need the same DMA-refresh strategy.
+ */
 void
-ImpactI2RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+ImpactIP28RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
 {
        ImpactPtr pImpact = IMPACTPTR(pScrn);
+       pImpact->FlushBoxCache = ImpactCflushBox;

        for (; num--; pbox++) {
                int w = pbox->x2 - pbox->x1;
                int h = pbox->y2 - pbox->y1;
-
-               if (w < 16 || w < 24 && h < 16 || w < 40 && h < 4)
+               int pio = !pImpact->FlushBoxCache;
+               /*
+                * This border was found to be suitable on IP28,
+                * it may or may not fit IP22's or IP26's conditions.
+                */
+               if (w < 10)
+                       pio = 1;
+               else if (w < 17) {
+                       static char lim[] = {52,23,14,11,9,8,7};
+                       if (h < lim[w-10]) pio = 1;
+               } else if (/* w < 56 && */ h < 7) {
+                       static char lim[] = {0,56,34,26,21,19,17};
+                       if (w < lim[h]) pio = 1;
+               }
+               if (pio)
                        ImpactRefreshArea32PIO(pImpact, 1, pbox);
-               else {
-                       if (h < 580)
-                               pImpact->FlushBoxCache = 
ImpactCflushBoxPixlines;
-                       else
-                               pImpact->FlushBoxCache = 
ImpactCflushBoxEnclosure;
+               else
                        ImpactRefreshArea32DMA(pImpact, 1, pbox);
-               }
        }
 }

+/*
+ * 1) On IP22 uncached writes are available, so cache-flush is not needed.
+ * 2) Where to switch between PIO and DMA could (yet) be checked on IP28 only.
+ * So solely plain DMA is used for now.
+ */
+void
+ImpactIP22RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+       ImpactRefreshArea32DMA(IMPACTPTR(pScrn), num, pbox);
+}
+
 void
 ImpactSRRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
 {

*** eof ***
_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to