#include <sys/io.h>
#ifdef HAVE_CONFIG_H
#include <kdrive-config.h>
#endif
#include "sis.h"
#include "sis_reg.h"
#if 0
#define SIS_FALLBACK(x) \
do { \
ErrorF x; \
return FALSE; \
} while (0)
#else
#define SIS_FALLBACK(x) return FALSE
#endif
CARD8 SiSSolidRop[16] = {
0x00,
0xa0,
0x50,
0xf0,
0x0a,
0xaa,
0x5a,
0xfa,
0x05,
0xa5,
0x55,
0xf5,
0x0f,
0xaf,
0x5f,
0xff,
};
CARD8 SiSBltRop[16] = {
0x00,
0x88,
0x44,
0xcc,
0x22,
0xaa,
0x66,
0xee,
0x11,
0x99,
0x55,
0xdd,
0x33,
0xbb,
0x77,
0xff,
};
int copydx, copydy;
int fifo_size;
SiSScreenInfo *accel_siss;
char *mmio;
CARD32 sis_color = 0;
CARD32 blitCmd;
static void
SiSWaitAvailMMIO(int n)
{
while (fifo_size < n) {
fifo_size = MMIO_IN32(mmio, REG_CommandQueue) & MASK_QueueLen;
}
fifo_size -= n;
}
static void
SiSWaitIdle(void)
{
CARD32 engineState;
do {
engineState = MMIO_IN32(mmio, REG_CommandQueue);
} while ((engineState & SiS_EngIdle) != SiS_EngIdle);
}
static Bool
SiSPrepareSolid(PixmapPtr pPixmap, int alu, Pixel pm, Pixel fg)
{
KdScreenPriv(pPixmap->drawable.pScreen);
SiSScreenInfo(pScreenPriv);
SiSCardInfo(pScreenPriv);
if (pPixmap->drawable.bitsPerPixel !=
pScreenPriv->screen->fb[0].bitsPerPixel)
return FALSE;
if ((pm & 0x00ffffff) != 0x00ffffff)
SIS_FALLBACK(("Unsupported planemask 0x%x\n", pm));
accel_siss = siss;
mmio = sisc->reg_base;
SiSWaitAvailMMIO(4);
MMIO_OUT32(mmio, REG_BLT_PATFG, fg);
MMIO_OUT32(mmio, REG_BLT_DSTRECT, (-1 << 16) | pPixmap->devKind);
MMIO_OUT32(mmio, REG_BLT_SRCPITCH, siss->depthSet);
MMIO_OUT32(mmio, REG_BLT_DSTBASE, ((CARD8 *)pPixmap->devPrivate.ptr -
pScreenPriv->screen->memory_base));
blitCmd = BLT_CMD_BITBLT | BLT_PAT_FG | BLT_X_INC | BLT_Y_INC |
BLT_NOCLIP | (SiSSolidRop[alu] << 8);
return TRUE;
}
static void
SiSSolid(int x1, int y1, int x2, int y2)
{
SiSWaitAvailMMIO(3);
MMIO_OUT32(mmio, REG_BLT_DSTXY, (x1 << 16) | y1);
MMIO_OUT32(mmio, REG_BLT_H_W, ((y2 - y1) << 16) | (x2 - x1));
MMIO_OUT32(mmio, REG_BLT_CMD, blitCmd);
}
static void
SiSDoneSolid(void)
{
}
static Bool
SiSPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu,
Pixel pm)
{
KdScreenPriv(pDst->drawable.pScreen);
SiSScreenInfo(pScreenPriv);
SiSCardInfo(pScreenPriv);
if (pDst->drawable.bitsPerPixel !=
pScreenPriv->screen->fb[0].bitsPerPixel)
return FALSE;
if ((pm & 0x00ffffff) != 0x00ffffff)
SIS_FALLBACK(("Unsupported pixel mask 0x%x\n", pm));
accel_siss = siss;
mmio = sisc->reg_base;
SiSWaitAvailMMIO(4);
MMIO_OUT32(mmio, REG_BLT_SRCPITCH, siss->depthSet | pSrc->devKind);
MMIO_OUT32(mmio, REG_BLT_DSTRECT, (-1 << 16) | pDst->devKind);
MMIO_OUT32(mmio, REG_BLT_SRCBASE, ((CARD8 *)pSrc->devPrivate.ptr -
pScreenPriv->screen->memory_base));
MMIO_OUT32(mmio, REG_BLT_DSTBASE, ((CARD8 *)pDst->devPrivate.ptr -
pScreenPriv->screen->memory_base));
blitCmd = BLT_CMD_BITBLT | BLT_PAT_FG | BLT_NOCLIP |
(SiSBltRop[alu] << 8);
if (pSrc != pDst || dx >= 0)
blitCmd |= BLT_X_INC;
if (pSrc != pDst || dy >= 0)
blitCmd |= BLT_Y_INC;
return TRUE;
}
static void
SiSCopy(int srcX, int srcY, int dstX, int dstY, int w, int h)
{
if (!(blitCmd & BLT_X_INC)) {
srcX += w - 1;
dstX += w - 1;
}
if (!(blitCmd & BLT_Y_INC)) {
srcY += h - 1;
dstY += h - 1;
}
SiSWaitAvailMMIO(4);
MMIO_OUT32(mmio, REG_BLT_H_W, (h << 16) | w);
MMIO_OUT32(mmio, REG_BLT_SRCXY, (srcX << 16) | srcY);
MMIO_OUT32(mmio, REG_BLT_DSTXY, (dstX << 16) | dstY);
MMIO_OUT32(mmio, REG_BLT_CMD, blitCmd);
}
static void
SiSDoneCopy(void)
{
}
KaaScreenInfoRec SiSKaa = {
SiSPrepareSolid,
SiSSolid,
SiSDoneSolid,
SiSPrepareCopy,
SiSCopy,
SiSDoneCopy,
KAA_OFFSCREEN_PIXMAPS,
8,
8
};
#define USE_TURBOQUEUE 0
Bool
SiSDrawInit(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
SiSScreenInfo(pScreenPriv);
CARD8 tmp;
#if USE_TURBOQUEUE
int tqsize;
#endif
switch (pScreenPriv->screen->fb[0].depth)
{
case 8:
siss->depthSet = 0x00000000;
break;
case 15:
siss->depthSet = 0x40000000;
break;
case 16:
siss->depthSet = 0x80000000;
break;
case 24:
if (pScreenPriv->screen->fb[0].bitsPerPixel == 32) {
siss->depthSet = 0xc0000000;
break;
}
default:
ErrorF("Unsupported depth/bpp %d/%d\n",
pScreenPriv->screen->fb[0].depth,
pScreenPriv->screen->fb[0].bitsPerPixel);
return FALSE;
}
outb(0x05, 0x3c4);
outb(0x86, 0x3c5);
outb(0x20, 0x3c4);
outb(0xA1, 0x3c5);
outb(0x1e, 0x3c4);
tmp = inb(0x3c5);
outb(tmp | 0x42 | 0x18, 0x3c5);
#if USE_TURBOQUEUE
tqsize = (pScreenPriv->screen->memory_size / 1024) / 64 - 8;
outb(0x26, 0x3c4);
outb(tqsize & 0xff, 0x3c5);
outb(0x27, 0x3c4);
tmp = inb(0x3c5);
outb(((tqsize >> 8) & 0x03) | (tmp & 0x0c) | 0xF0, 0x3c5);
#endif
ErrorF("Screen: %d/%d depth/bpp\n", pScreenPriv->screen->fb[0].depth,
pScreenPriv->screen->fb[0].bitsPerPixel);
if (!kaaDrawInit(pScreen, &SiSKaa))
return FALSE;
return TRUE;
}
void
SiSDrawEnable(ScreenPtr pScreen)
{
KdMarkSync(pScreen);
}
void
SiSDrawDisable(ScreenPtr pScreen)
{
}
void
SiSDrawFini(ScreenPtr pScreen)
{
kaaDrawFini (pScreen);
}
void
SiSDrawSync(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
SiSScreenInfo(pScreenPriv);
SiSCardInfo(pScreenPriv);
accel_siss = siss;
mmio = sisc->reg_base;
SiSWaitIdle();
}