324 lines
8.2 KiB
C
324 lines
8.2 KiB
C
|
/*
|
|||
|
* $Id$
|
|||
|
*
|
|||
|
* Copyright <EFBFBD> 2003 Eric Anholt
|
|||
|
*
|
|||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|||
|
* documentation for any purpose is hereby granted without fee, provided that
|
|||
|
* the above copyright notice appear in all copies and that both that
|
|||
|
* copyright notice and this permission notice appear in supporting
|
|||
|
* documentation, and that the name of Eric Anholt not be used in
|
|||
|
* advertising or publicity pertaining to distribution of the software without
|
|||
|
* specific, written prior permission. Eric Anholt makes no
|
|||
|
* representations about the suitability of this software for any purpose. It
|
|||
|
* is provided "as is" without express or implied warranty.
|
|||
|
*
|
|||
|
* ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|||
|
* EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|||
|
* PERFORMANCE OF THIS SOFTWARE.
|
|||
|
*/
|
|||
|
/* $Header$ */
|
|||
|
|
|||
|
#include <sys/io.h>
|
|||
|
|
|||
|
#ifdef HAVE_CONFIG_H
|
|||
|
#include <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] = {
|
|||
|
/* GXclear */ 0x00, /* 0 */
|
|||
|
/* GXand */ 0xa0, /* src AND dst */
|
|||
|
/* GXandReverse */ 0x50, /* src AND NOT dst */
|
|||
|
/* GXcopy */ 0xf0, /* src */
|
|||
|
/* GXandInverted*/ 0x0a, /* NOT src AND dst */
|
|||
|
/* GXnoop */ 0xaa, /* dst */
|
|||
|
/* GXxor */ 0x5a, /* src XOR dst */
|
|||
|
/* GXor */ 0xfa, /* src OR dst */
|
|||
|
/* GXnor */ 0x05, /* NOT src AND NOT dst */
|
|||
|
/* GXequiv */ 0xa5, /* NOT src XOR dst */
|
|||
|
/* GXinvert */ 0x55, /* NOT dst */
|
|||
|
/* GXorReverse */ 0xf5, /* src OR NOT dst */
|
|||
|
/* GXcopyInverted*/ 0x0f, /* NOT src */
|
|||
|
/* GXorInverted */ 0xaf, /* NOT src OR dst */
|
|||
|
/* GXnand */ 0x5f, /* NOT src OR NOT dst */
|
|||
|
/* GXset */ 0xff, /* 1 */
|
|||
|
};
|
|||
|
|
|||
|
CARD8 SiSBltRop[16] = {
|
|||
|
/* GXclear */ 0x00, /* 0 */
|
|||
|
/* GXand */ 0x88, /* src AND dst */
|
|||
|
/* GXandReverse */ 0x44, /* src AND NOT dst */
|
|||
|
/* GXcopy */ 0xcc, /* src */
|
|||
|
/* GXandInverted*/ 0x22, /* NOT src AND dst */
|
|||
|
/* GXnoop */ 0xaa, /* dst */
|
|||
|
/* GXxor */ 0x66, /* src XOR dst */
|
|||
|
/* GXor */ 0xee, /* src OR dst */
|
|||
|
/* GXnor */ 0x11, /* NOT src AND NOT dst */
|
|||
|
/* GXequiv */ 0x99, /* NOT src XOR dst */
|
|||
|
/* GXinvert */ 0x55, /* NOT dst */
|
|||
|
/* GXorReverse */ 0xdd, /* src OR NOT dst */
|
|||
|
/* GXcopyInverted*/ 0x33, /* NOT src */
|
|||
|
/* GXorInverted */ 0xbb, /* NOT src OR dst */
|
|||
|
/* GXnand */ 0x77, /* NOT src OR NOT dst */
|
|||
|
/* GXset */ 0xff, /* 1 */
|
|||
|
};
|
|||
|
|
|||
|
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);
|
|||
|
|
|||
|
/* No acceleration for other formats (yet) */
|
|||
|
if (pPixmap->drawable.bitsPerPixel !=
|
|||
|
pScreenPriv->screen->fb[0].bitsPerPixel)
|
|||
|
return FALSE;
|
|||
|
|
|||
|
if ((pm & 0x00ffffff) != 0x00ffffff) /* XXX */
|
|||
|
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);
|
|||
|
|
|||
|
/* No acceleration for other formats (yet) */
|
|||
|
if (pDst->drawable.bitsPerPixel !=
|
|||
|
pScreenPriv->screen->fb[0].bitsPerPixel)
|
|||
|
return FALSE;
|
|||
|
|
|||
|
if ((pm & 0x00ffffff) != 0x00ffffff) /* XXX */
|
|||
|
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;
|
|||
|
}
|
|||
|
/* FALLTHROUGH*/
|
|||
|
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); /* unlock registers */
|
|||
|
|
|||
|
outb(0x20, 0x3c4);
|
|||
|
outb(0xA1, 0x3c5); /* enable pci linear addressing, MMIO, PCI_IO */
|
|||
|
|
|||
|
outb(0x1e, 0x3c4);
|
|||
|
tmp = inb(0x3c5);
|
|||
|
outb(tmp | 0x42 | 0x18, 0x3c5); /* Enable 2d and 3d */
|
|||
|
|
|||
|
#if USE_TURBOQUEUE
|
|||
|
tqsize = (pScreenPriv->screen->memory_size / 1024) / 64 - 8;
|
|||
|
/* Enable TQ */
|
|||
|
outb(0x26, 0x3c4);
|
|||
|
outb(tqsize & 0xff, 0x3c5);
|
|||
|
outb(0x27, 0x3c4);
|
|||
|
tmp = inb(0x3c5);
|
|||
|
outb(((tqsize >> 8) & 0x03) | (tmp & 0x0c) | 0xF0, 0x3c5);
|
|||
|
|
|||
|
/* XXX: Adjust offscreen size to avoid TQ area (last 512k) */
|
|||
|
#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();
|
|||
|
}
|