aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/kdrive/sis300/sis_draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/kdrive/sis300/sis_draw.c')
-rw-r--r--xorg-server/hw/kdrive/sis300/sis_draw.c320
1 files changed, 320 insertions, 0 deletions
diff --git a/xorg-server/hw/kdrive/sis300/sis_draw.c b/xorg-server/hw/kdrive/sis300/sis_draw.c
new file mode 100644
index 000000000..bbc905e1d
--- /dev/null
+++ b/xorg-server/hw/kdrive/sis300/sis_draw.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright © 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.
+ */
+
+#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] = {
+ /* 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();
+}