summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c
diff options
context:
space:
mode:
authorgareth <gareth>2000-12-01 20:37:35 +0000
committergareth <gareth>2000-12-01 20:37:35 +0000
commit0fa77f7f91a09cf332fd0433c7b6e962a80cecaf (patch)
tree4957535f0a4e846af59b7a8d92a852b71ddebaab /xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c
parentd03307dd9f98036c40abf2f98dac3fde22ef2e89 (diff)
Merge with trunk (almost there!).ati-4-1-1-20001202-mergeati-4-1-1-branch
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c')
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c932
1 files changed, 932 insertions, 0 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c
new file mode 100644
index 000000000..421c020c4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c
@@ -0,0 +1,932 @@
+/* Header: //Mercury/Projects/archives/XFree86/4.0/smi_accel.c-arc 1.12 27 Nov 2000 15:46:54 Frido $ */
+
+/*
+Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
+Copyright (C) 2000 Silicon Motion, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the XFree86 Project and
+Silicon Motion shall not be used in advertising or otherwise to promote the
+sale, use or other dealings in this Software without prior written
+authorization from the XFree86 Project and silicon Motion.
+*/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c,v 1.1 2000/11/28 20:59:19 dawes Exp $ */
+
+#include "smi.h"
+
+#include "miline.h"
+#include "xaalocal.h"
+#include "xaarop.h"
+#include "servermd.h"
+
+static void SMI_EngineReset(ScrnInfoPtr);
+
+static void SMI_SetupForScreenToScreenCopy(ScrnInfoPtr, int, int, int,
+ unsigned int, int);
+static void SMI_SubsequentScreenToScreenCopy(ScrnInfoPtr, int, int, int, int,
+ int, int);
+static void SMI_SetupForSolidFill(ScrnInfoPtr, int, int, unsigned);
+static void SMI_SubsequentSolidFillRect(ScrnInfoPtr, int, int, int, int);
+static void SMI_SubsequentSolidHorVertLine(ScrnInfoPtr, int, int, int, int);
+static void SMI_SetupForCPUToScreenColorExpandFill(ScrnInfoPtr, int, int, int,
+ unsigned int);
+static void SMI_SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr, int, int, int,
+ int, int);
+static void SMI_SetupForMono8x8PatternFill(ScrnInfoPtr, int, int, int, int, int,
+ unsigned int);
+static void SMI_SubsequentMono8x8PatternFillRect(ScrnInfoPtr, int, int, int,
+ int, int, int);
+static void SMI_SetupForColor8x8PatternFill(ScrnInfoPtr, int, int, int,
+ unsigned int, int);
+static void SMI_SubsequentColor8x8PatternFillRect(ScrnInfoPtr, int, int, int,
+ int, int, int);
+#if SMI_USE_IMAGE_WRITES
+static void SMI_SetupForImageWrite(ScrnInfoPtr, int, unsigned int, int, int,
+ int);
+static void SMI_SubsequentImageWriteRect(ScrnInfoPtr, int, int, int, int, int);
+#endif
+static void SMI_SetClippingRectangle(ScrnInfoPtr, int, int, int, int);
+static void SMI_DisableClipping(ScrnInfoPtr);
+
+Bool
+SMI_AccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SMIPtr pSmi = SMIPTR(pScrn);
+ BoxRec AvailFBArea;
+ Bool ret;
+ int numLines, maxLines;
+
+ ENTER_PROC("SMI_AccelInit");
+
+ pSmi->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (infoPtr == NULL)
+ {
+ LEAVE_PROC("SMI_AccelInit");
+ return FALSE;
+ }
+
+ infoPtr->Flags = PIXMAP_CACHE
+ | LINEAR_FRAMEBUFFER
+ | OFFSCREEN_PIXMAPS;
+
+ infoPtr->Sync = SMI_AccelSync;
+
+ /* Screen to screen copies */
+ infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK
+ | ONLY_TWO_BITBLT_DIRECTIONS;
+ infoPtr->SetupForScreenToScreenCopy = SMI_SetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = SMI_SubsequentScreenToScreenCopy;
+ if (pScrn->bitsPerPixel == 24)
+ {
+ infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY;
+ }
+ if ((pSmi->Chipset == SMI_LYNX3D) && (pScrn->bitsPerPixel == 8))
+ {
+ infoPtr->ScreenToScreenCopyFlags |= GXCOPY_ONLY;
+ }
+
+ /* Solid Fills */
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = SMI_SetupForSolidFill;
+ infoPtr->SubsequentSolidFillRect = SMI_SubsequentSolidFillRect;
+
+ /* Solid Lines */
+ infoPtr->SolidLineFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidLine = SMI_SetupForSolidFill;
+ infoPtr->SubsequentSolidHorVertLine = SMI_SubsequentSolidHorVertLine;
+
+ /* Color Expansion Fills */
+ infoPtr->CPUToScreenColorExpandFillFlags = ROP_NEEDS_SOURCE
+ | NO_PLANEMASK
+ | BIT_ORDER_IN_BYTE_MSBFIRST
+ | LEFT_EDGE_CLIPPING
+ | CPU_TRANSFER_PAD_DWORD
+ | SCANLINE_PAD_DWORD;
+ infoPtr->ColorExpandBase = pSmi->DataPortBase;
+ infoPtr->ColorExpandRange = pSmi->DataPortSize;
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ SMI_SetupForCPUToScreenColorExpandFill;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ SMI_SubsequentCPUToScreenColorExpandFill;
+
+ /* 8x8 Mono Pattern Fills */
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK
+ | HARDWARE_PATTERN_PROGRAMMED_BITS
+ | HARDWARE_PATTERN_SCREEN_ORIGIN
+ | BIT_ORDER_IN_BYTE_MSBFIRST;
+ infoPtr->SetupForMono8x8PatternFill = SMI_SetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ SMI_SubsequentMono8x8PatternFillRect;
+
+ /* 8x8 Color Pattern Fills */
+ if (!SMI_LYNX3D_SERIES(pSmi->Chipset) || (pScrn->bitsPerPixel != 24))
+ {
+ infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK
+ | HARDWARE_PATTERN_SCREEN_ORIGIN;
+ infoPtr->SetupForColor8x8PatternFill =
+ SMI_SetupForColor8x8PatternFill;
+ infoPtr->SubsequentColor8x8PatternFillRect =
+ SMI_SubsequentColor8x8PatternFillRect;
+ }
+
+#if SMI_USE_IMAGE_WRITES
+ /* Image Writes */
+ infoPtr->ImageWriteFlags = ROP_NEEDS_SOURCE
+ | NO_PLANEMASK
+ | CPU_TRANSFER_PAD_DWORD
+ | SCANLINE_PAD_DWORD;
+ infoPtr->ImageWriteBase = pSmi->DataPortBase;
+ infoPtr->ImageWriteRange = pSmi->DataPortSize;
+ infoPtr->SetupForImageWrite = SMI_SetupForImageWrite;
+ infoPtr->SubsequentImageWriteRect = SMI_SubsequentImageWriteRect;
+#endif
+
+ /* Clipping */
+ infoPtr->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY
+ | HARDWARE_CLIP_MONO_8x8_FILL
+ | HARDWARE_CLIP_COLOR_8x8_FILL
+ | HARDWARE_CLIP_SOLID_FILL
+ | HARDWARE_CLIP_SOLID_LINE;
+ infoPtr->SetClippingRectangle = SMI_SetClippingRectangle;
+ infoPtr->DisableClipping = SMI_DisableClipping;
+
+ /* Pixmap Cache */
+ if (pScrn->bitsPerPixel == 24)
+ {
+ infoPtr->CachePixelGranularity = 16;
+ }
+ else
+ {
+ infoPtr->CachePixelGranularity = 128 / pScrn->bitsPerPixel;
+ }
+
+ /* Offscreen Pixmaps */
+ infoPtr->maxOffPixWidth = 4096;
+ infoPtr->maxOffPixHeight = 4096;
+ if (pScrn->bitsPerPixel == 24)
+ {
+ infoPtr->maxOffPixWidth = 4096 / 3;
+
+ if (pSmi->Chipset == SMI_LYNX)
+ {
+ infoPtr->maxOffPixHeight = 4096 / 3;
+ }
+ }
+
+ SMI_EngineReset(pScrn);
+
+ maxLines = pSmi->FBReserved / (pSmi->width * pSmi->Bpp);
+ if (pSmi->rotate)
+ {
+ numLines = maxLines;
+ }
+ else
+ {
+ #if defined(XvExtension) && SMI_USE_VIDEO
+ numLines = ((pSmi->FBReserved - pSmi->width * pSmi->Bpp * pSmi->height)
+ * 25 / 100 + pSmi->width * pSmi->Bpp - 1)
+ / (pSmi->width * pSmi->Bpp);
+ numLines += pSmi->height;
+ #else
+ numLines = maxLines;
+ #endif
+ }
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pSmi->width;
+ AvailFBArea.y2 = numLines;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "FrameBuffer Box: %d,%d - %d,%d\n",
+ AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2);
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ ret = XAAInit(pScreen, infoPtr);
+
+ LEAVE_PROC("SMI_AccelInit");
+ return(ret);
+}
+
+void
+SMI_GEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+ CARD8 tmp;
+
+ ENTER_PROC("SMI_GEReset");
+
+ if (from_timeout)
+ {
+ if (pSmi->GEResetCnt++ < 10 || xf86GetVerbosity() > 1)
+ {
+ ErrorF("\tSMI_GEReset called from %s line %d\n", file, line);
+ }
+ }
+ else
+ {
+ WaitIdleEmpty();
+ }
+
+ tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x15);
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x15, tmp | 0x30);
+
+ WaitIdleEmpty();
+
+ VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x15, tmp);
+ SMI_EngineReset(pScrn);
+
+ LEAVE_PROC("SMI_GEReset");
+}
+
+/* The sync function for the GE */
+void
+SMI_AccelSync(ScrnInfoPtr pScrn)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_AccelSync");
+
+ WaitIdleEmpty(); /* #161 */
+
+ LEAVE_PROC("SMI_AccelSync");
+}
+
+static void
+SMI_EngineReset(ScrnInfoPtr pScrn)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+ CARD32 DEDataFormat = 0;
+ int i;
+ int xyAddress[] = { 320, 400, 512, 640, 800, 1024, 1280, 1600, 2048 };
+
+ ENTER_PROC("SMI_EngineReset");
+
+ pSmi->Stride = (pSmi->width * pSmi->Bpp + 15) & ~15;
+
+ switch (pScrn->bitsPerPixel)
+ {
+ case 8:
+ DEDataFormat = 0x00000000;
+ break;
+
+ case 16:
+ pSmi->Stride >>= 1;
+ DEDataFormat = 0x00100000;
+ break;
+
+ case 24:
+ DEDataFormat = 0x00300000;
+ break;
+
+ case 32:
+ pSmi->Stride >>= 2;
+ DEDataFormat = 0x00200000;
+ break;
+ }
+ for (i = 0; i < sizeof(xyAddress) / sizeof(xyAddress[0]); i++)
+ {
+ if (pSmi->rotate)
+ {
+ if (xyAddress[i] == pSmi->height)
+ {
+ DEDataFormat |= i << 16;
+ break;
+ }
+ }
+ else
+ {
+ if (xyAddress[i] == pSmi->width)
+ {
+ DEDataFormat |= i << 16;
+ break;
+ }
+ }
+ }
+
+ WaitIdleEmpty();
+ WRITE_DPR(pSmi, 0x10, (pSmi->Stride << 16) | pSmi->Stride);
+ WRITE_DPR(pSmi, 0x1C, DEDataFormat);
+ WRITE_DPR(pSmi, 0x24, 0xFFFFFFFF);
+ WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF);
+ WRITE_DPR(pSmi, 0x3C, (pSmi->Stride << 16) | pSmi->Stride);
+ WRITE_DPR(pSmi, 0x40, 0);
+ WRITE_DPR(pSmi, 0x44, 0);
+
+ SMI_DisableClipping(pScrn);
+
+ LEAVE_PROC("SMI_EngineReset");
+}
+
+/******************************************************************************/
+/* Screen to Screen Copies */
+/******************************************************************************/
+
+static void
+SMI_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
+ unsigned int planemask, int trans)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_SetupForScreenToScreenCopy");
+ DEBUG((VERBLEV, "xdir=%d ydir=%d rop=%02X trans=%08X\n", xdir, ydir,
+ rop, trans));
+
+ pSmi->AccelCmd = XAACopyROP[rop]
+ | SMI_BITBLT
+ | SMI_START_ENGINE;
+
+ if ((xdir == -1) || (ydir == -1))
+ {
+ pSmi->AccelCmd |= SMI_RIGHT_TO_LEFT;
+ }
+
+ if (trans != -1)
+ {
+ pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
+ WaitQueue(1);
+ WRITE_DPR(pSmi, 0x20, trans);
+ }
+
+ if (pSmi->ClipTurnedOn)
+ {
+ WaitQueue(1);
+ WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
+ pSmi->ClipTurnedOn = FALSE;
+ }
+
+ LEAVE_PROC("SMI_SetupForScreenToScreenCopy");
+}
+
+static void
+SMI_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w, int h)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_SubsequentScreenToScreenCopy");
+ DEBUG((VERBLEV, "x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n", x1, y1, x2, y2, w,
+ h));
+
+ if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT)
+ {
+ x1 += w - 1;
+ y1 += h - 1;
+ x2 += w - 1;
+ y2 += h - 1;
+ }
+
+ if (pScrn->bitsPerPixel == 24)
+ {
+ x1 *= 3;
+ x2 *= 2;
+ w *= 3;
+
+ if (pSmi->Chipset == SMI_LYNX)
+ {
+ y1 *= 3;
+ y2 *= 3;
+ }
+
+ if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT)
+ {
+ x1 += 2;
+ x2 += 2;
+ }
+ }
+
+ WaitQueue(4);
+ WRITE_DPR(pSmi, 0x00, (x1 << 16) + (y1 & 0xFFFF));
+ WRITE_DPR(pSmi, 0x04, (x2 << 16) + (y2 & 0xFFFF));
+ WRITE_DPR(pSmi, 0x08, (w << 16) + (h & 0xFFFF));
+ WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
+
+ LEAVE_PROC("SMI_SubsequentScreenToScreenCopy");
+}
+
+/******************************************************************************/
+/* Solid Fills */
+/******************************************************************************/
+
+static void
+SMI_SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_SetupForSolidFill");
+ DEBUG((VERBLEV, "color=%08X rop=%02X\n", color, rop));
+
+ pSmi->AccelCmd = XAAPatternROP[rop]
+ | SMI_BITBLT
+ | SMI_START_ENGINE;
+
+ if (pSmi->ClipTurnedOn)
+ {
+ WaitQueue(4);
+ WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
+ pSmi->ClipTurnedOn = FALSE;
+ }
+ else
+ {
+ WaitQueue(3);
+ }
+ WRITE_DPR(pSmi, 0x14, color);
+ WRITE_DPR(pSmi, 0x34, 0xFFFFFFFF);
+ WRITE_DPR(pSmi, 0x38, 0xFFFFFFFF);
+
+ LEAVE_PROC("SMI_SetupForSolidFill");
+}
+
+void
+SMI_SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_SubsequentSolidFillRect");
+ DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d\n", x, y, w, h));
+
+ if (pScrn->bitsPerPixel == 24)
+ {
+ x *= 3;
+ w *= 3;
+
+ if (pSmi->Chipset == SMI_LYNX)
+ {
+ y *= 3;
+ }
+ }
+
+ WaitQueue(3);
+ WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
+ WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
+ WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
+
+ LEAVE_PROC("SMI_SubsequentSolidFillRect");
+}
+
+/******************************************************************************/
+/* Solid Lines */
+/******************************************************************************/
+
+static void
+SMI_SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len,
+ int dir)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+ int w, h;
+
+ ENTER_PROC("SMI_SubsequentSolidHorVertLine");
+ DEBUG((VERBLEV, "x=%d y=%d len=%d dir=%d\n", x, y, len, dir));
+
+ if (dir == DEGREES_0)
+ {
+ w = len;
+ h = 1;
+ }
+ else
+ {
+ w = 1;
+ h = len;
+ }
+
+ if (pScrn->bitsPerPixel == 24)
+ {
+ x *= 3;
+ w *= 3;
+
+ if (pSmi->Chipset == SMI_LYNX)
+ {
+ y *= 3;
+ }
+ }
+
+ WaitQueue(3);
+ WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
+ WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
+ WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
+
+ LEAVE_PROC("SMI_SubsequentSolidHorVertLine");
+}
+
+/******************************************************************************/
+/* Color Expansion Fills */
+/******************************************************************************/
+
+static void
+SMI_SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned int planemask)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_SetupForCPUToScreenColorExpandFill");
+ DEBUG((VERBLEV, "fg=%08X bg=%08X rop=%02X\n", fg, bg, rop));
+
+ pSmi->AccelCmd = XAACopyROP[rop]
+ | SMI_HOSTBLT_WRITE
+ | SMI_SRC_MONOCHROME
+ | SMI_START_ENGINE;
+
+ if (bg == -1)
+ {
+ pSmi->AccelCmd |= SMI_TRANSPARENT_SRC;
+
+ WaitQueue(3);
+ WRITE_DPR(pSmi, 0x14, fg);
+ WRITE_DPR(pSmi, 0x18, ~fg);
+ WRITE_DPR(pSmi, 0x20, fg);
+ }
+ else
+ {
+ WaitQueue(2);
+ WRITE_DPR(pSmi, 0x14, fg);
+ WRITE_DPR(pSmi, 0x18, bg);
+ }
+
+ LEAVE_PROC("SMI_SetupForCPUToScreenColorExpandFill");
+}
+
+void
+SMI_SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h, int skipleft)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_SubsequentCPUToScreenColorExpandFill");
+ DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d skipleft=%d\n", x, y, w, h, skipleft));
+
+ if (pScrn->bitsPerPixel == 24)
+ {
+ x *= 3;
+ w *= 3;
+ skipleft *= 3;
+
+ if (pSmi->Chipset == SMI_LYNX)
+ {
+ y *= 3;
+ }
+ }
+
+ if (skipleft)
+ {
+ WaitQueue(5);
+ WRITE_DPR(pSmi, 0x2C, (pSmi->ScissorsLeft & 0xFFFF0000)
+ | (x + skipleft) | 0x2000);
+ pSmi->ClipTurnedOn = TRUE;
+ }
+ else
+ {
+ if (pSmi->ClipTurnedOn)
+ {
+ WaitQueue(5);
+ WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
+ pSmi->ClipTurnedOn = FALSE;
+ }
+ else
+ {
+ WaitQueue(4);
+ }
+ }
+ WRITE_DPR(pSmi, 0x00, 0);
+ WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
+ WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
+ WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
+
+ LEAVE_PROC("SMI_SubsequentCPUToScreenColorExpandFill");
+}
+
+/******************************************************************************/
+/* 8x8 Mono Pattern Fills */
+/******************************************************************************/
+
+static void
+SMI_SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, int fg,
+ int bg, int rop, unsigned int planemask)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_SetupForMono8x8PatternFill");
+ DEBUG((VERBLEV, "patx=%08X paty=%08X fg=%08X bg=%08X rop=%02X\n", patx,
+ paty, fg, bg, rop));
+
+ pSmi->AccelCmd = XAAPatternROP[rop]
+ | SMI_BITBLT
+ | SMI_START_ENGINE;
+
+ if (pSmi->ClipTurnedOn)
+ {
+ WaitQueue(1);
+ WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
+ pSmi->ClipTurnedOn = FALSE;
+ }
+
+ if (bg == -1)
+ {
+ WaitQueue(5);
+ WRITE_DPR(pSmi, 0x14, fg);
+ WRITE_DPR(pSmi, 0x18, ~fg);
+ WRITE_DPR(pSmi, 0x20, fg);
+ WRITE_DPR(pSmi, 0x34, patx);
+ WRITE_DPR(pSmi, 0x38, paty);
+ }
+ else
+ {
+ WaitQueue(4);
+ WRITE_DPR(pSmi, 0x14, fg);
+ WRITE_DPR(pSmi, 0x18, bg);
+ WRITE_DPR(pSmi, 0x34, patx);
+ WRITE_DPR(pSmi, 0x38, paty);
+ }
+
+ LEAVE_PROC("SMI_SetupForMono8x8PatternFill");
+}
+
+static void
+SMI_SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
+ int x, int y, int w, int h)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_SubsequentMono8x8PatternFillRect");
+ DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d\n", x, y, w, h));
+
+ if (pScrn->bitsPerPixel == 24)
+ {
+ x *= 3;
+ w *= 3;
+ if (pSmi->Chipset == SMI_LYNX)
+ {
+ y *= 3;
+ }
+ }
+
+ WaitQueue(3);
+ WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
+ WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
+ WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
+
+ LEAVE_PROC("SMI_SubsequentMono8x8PatternFillRect");
+}
+
+/******************************************************************************/
+/* 8x8 Color Pattern Fills */
+/******************************************************************************/
+
+static void
+SMI_SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, int rop,
+ unsigned int planemask, int trans_color)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_SetupForColor8x8PatternFill");
+ DEBUG((VERBLEV, "patx=%d paty=%d rop=%02X trans_color=%08X\n", patx, paty,
+ rop, trans_color));
+
+ pSmi->AccelCmd = XAAPatternROP[rop]
+ | SMI_BITBLT
+ | SMI_COLOR_PATTERN
+ | SMI_START_ENGINE;
+
+ if (pScrn->bitsPerPixel <= 16)
+ {
+ unsigned char * pattern = pSmi->FBBase + patx * pSmi->Bpp
+ + paty * pSmi->Stride;
+
+ WaitQueue(1);
+ WRITE_DPR(pSmi, 0x0C, SMI_BITBLT | SMI_COLOR_PATTERN);
+ memcpy(pSmi->DataPortBase, pattern, 8 * pSmi->Bpp * 8);
+ }
+ else
+ {
+ if (pScrn->bitsPerPixel == 24)
+ {
+ patx *= 3;
+
+ if (pSmi->Chipset == SMI_LYNX)
+ {
+ paty *= 3;
+ }
+ }
+
+ WaitQueue(1);
+ WRITE_DPR(pSmi, 0x00, (patx << 16) | (paty & 0xFFFF));
+ }
+
+ if (trans_color == -1)
+ {
+ pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
+
+ WaitQueue(1);
+ WRITE_DPR(pSmi, 0x20, trans_color);
+ }
+
+ if (pSmi->ClipTurnedOn)
+ {
+ WaitQueue(1);
+ WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
+ pSmi->ClipTurnedOn = FALSE;
+ }
+
+ LEAVE_PROC("SMI_SetupForColor8x8PatternFill");
+}
+
+static void
+SMI_SubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
+ int x, int y, int w, int h)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_SubsequentColor8x8PatternFillRect");
+ DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d\n", x, y, w, h));
+
+ if (pScrn->bitsPerPixel == 24)
+ {
+ x *= 3;
+ w *= 3;
+
+ if (pSmi->Chipset == SMI_LYNX)
+ {
+ y *= 3;
+ }
+ }
+
+ WaitQueue(3);
+ WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
+ WRITE_DPR(pSmi, 0x08, (w << 16) | (y & 0xFFFF));
+ WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
+
+ LEAVE_PROC("SMI_SubsequentColor8x8PatternFillRect");
+}
+
+#if SMI_USE_IMAGE_WRITES
+/******************************************************************************/
+/* Image Writes */
+/******************************************************************************/
+
+static void
+SMI_SetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned int planemask,
+ int trans_color, int bpp, int depth)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_SetupForImageWrite");
+ DEBUG((VERBLEV, "rop=%02X trans_color=%08X bpp=%d depth=%d\n", rop,
+ trans_color, bpp, depth));
+
+ pSmi->AccelCmd = XAACopyROP[rop]
+ | SMI_HOSTBLT_WRITE
+ | SMI_START_ENGINE;
+
+ if (trans_color != -1)
+ {
+ pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
+
+ WaitQueue(1);
+ WRITE_DPR(pSmi, 0x20, trans_color);
+ }
+
+ LEAVE_PROC("SMI_SetupForImageWrite");
+}
+
+static void
+SMI_SubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ int skipleft)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_SubsequentImageWriteRect");
+ DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d skipleft=%d\n", x, y, w, h, skipleft));
+
+ if (pScrn->bitsPerPixel == 24)
+ {
+ x *= 3;
+ w *= 3;
+ skipleft *= 3;
+
+ if (pSmi->Chipset == SMI_LYNX)
+ {
+ y *= 3;
+ }
+ }
+
+ if (skipleft)
+ {
+ WaitQueue(5);
+ WRITE_DPR(pSmi, 0x2C, (pSmi->ScissorsLeft & 0xFFFF0000) |
+ (x + skipleft) | 0x2000);
+ pSmi->ClipTurnedOn = TRUE;
+ }
+ else
+ {
+ if (pSmi->ClipTurnedOn)
+ {
+ WaitQueue(5);
+ WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
+ pSmi->ClipTurnedOn = FALSE;
+ }
+ else
+ {
+ WaitQueue(4);
+ }
+ }
+ WRITE_DPR(pSmi, 0x00, 0);
+ WRITE_DPR(pSmi, 0x04, (x << 16) | (y * 0xFFFF));
+ WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
+ WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
+
+ LEAVE_PROC("SMI_SubsequentImageWriteRect");
+}
+#endif
+
+/******************************************************************************/
+/* Clipping */
+/******************************************************************************/
+
+static void
+SMI_SetClippingRectangle(ScrnInfoPtr pScrn, int left, int top, int right,
+ int bottom)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_SetClippingRectangle");
+ DEBUG((VERBLEV, "left=%d top=%d right=%d bottom=%d\n", left, top, right,
+ bottom));
+
+ left = max(left, 0);
+ top = max(top, 0);
+ right = min(right, pSmi->width);
+ bottom = min(bottom, pSmi->height);
+
+ if (pScrn->bitsPerPixel == 24)
+ {
+ left *= 3;
+ right *= 3;
+
+ if (pSmi->Chipset == SMI_LYNX)
+ {
+ top *= 3;
+ bottom *= 3;
+ }
+ }
+
+ pSmi->ScissorsLeft = (top << 16) | (left & 0xFFFF) | 0x2000;
+ pSmi->ScissorsRight = (bottom << 16) | (right & 0xFFFF);
+
+ pSmi->ClipTurnedOn = FALSE;
+
+ WaitQueue(2);
+ WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
+ WRITE_DPR(pSmi, 0x30, pSmi->ScissorsRight);
+
+ LEAVE_PROC("SMI_SetClippingRectangle");
+}
+
+static void
+SMI_DisableClipping(ScrnInfoPtr pScrn)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+
+ ENTER_PROC("SMI_DisableClipping");
+
+ pSmi->ScissorsLeft = 0;
+ if (pScrn->bitsPerPixel == 24)
+ {
+ if (pSmi->Chipset == SMI_LYNX)
+ {
+ pSmi->ScissorsRight = ((pSmi->height * 3) << 16)
+ | (pSmi->width * 3);
+ }
+ else
+ {
+ pSmi->ScissorsRight = (pSmi->height << 16) | (pSmi->width * 3);
+ }
+ }
+ else
+ {
+ pSmi->ScissorsRight = (pSmi->height << 16) | pSmi->width;
+ }
+
+ pSmi->ClipTurnedOn = FALSE;
+
+ WaitQueue(2);
+ WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
+ WRITE_DPR(pSmi, 0x30, pSmi->ScissorsRight);
+
+ LEAVE_PROC("SMI_DisableClipping");
+}