109885543Smrg/*
209885543SmrgCopyright (C) 1994-1999 The XFree86 Project, Inc.  All Rights Reserved.
309885543SmrgCopyright (C) 2000 Silicon Motion, Inc.  All Rights Reserved.
409885543Smrg
509885543SmrgPermission is hereby granted, free of charge, to any person obtaining a copy of
609885543Smrgthis software and associated documentation files (the "Software"), to deal in
709885543Smrgthe Software without restriction, including without limitation the rights to
809885543Smrguse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
909885543Smrgof the Software, and to permit persons to whom the Software is furnished to do
1009885543Smrgso, subject to the following conditions:
1109885543Smrg
1209885543SmrgThe above copyright notice and this permission notice shall be included in all
1309885543Smrgcopies or substantial portions of the Software.
1409885543Smrg
1509885543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1609885543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
1709885543SmrgNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1809885543SmrgXFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1909885543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2009885543SmrgWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2109885543Smrg
2209885543SmrgExcept as contained in this notice, the names of the XFree86 Project and
2309885543SmrgSilicon Motion shall not be used in advertising or otherwise to promote the
2409885543Smrgsale, use or other dealings in this Software without prior written
2509885543Smrgauthorization from the XFree86 Project and silicon Motion.
2609885543Smrg*/
2709885543Smrg
2809885543Smrg#ifdef HAVE_CONFIG_H
2909885543Smrg#include "config.h"
3009885543Smrg#endif
3109885543Smrg
3209885543Smrg#include "smi.h"
337104f784Smrg#include "smi_501.h"
3409885543Smrg
35b12e5c03Smrg#ifdef HAVE_XAA_H
36b12e5c03Smrg
3709885543Smrg#include "miline.h"
3809885543Smrg#include "xaalocal.h"
3909885543Smrg#include "xaarop.h"
4009885543Smrg#include "servermd.h"
4109885543Smrg
4209885543Smrgstatic void SMI_SetupForScreenToScreenCopy(ScrnInfoPtr, int, int, int,
4309885543Smrg					   unsigned int, int);
4409885543Smrgstatic void SMI_SubsequentScreenToScreenCopy(ScrnInfoPtr, int, int, int, int,
4509885543Smrg					     int, int);
4609885543Smrgstatic void SMI_SetupForSolidFill(ScrnInfoPtr, int, int, unsigned);
4709885543Smrgstatic void SMI_SubsequentSolidFillRect(ScrnInfoPtr, int, int, int, int);
4809885543Smrgstatic void SMI_SubsequentSolidHorVertLine(ScrnInfoPtr, int, int, int, int);
4909885543Smrgstatic void SMI_SetupForCPUToScreenColorExpandFill(ScrnInfoPtr, int, int, int,
5009885543Smrg						   unsigned int);
5109885543Smrgstatic void SMI_SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr, int, int, int,
5209885543Smrg						     int, int);
5309885543Smrgstatic void SMI_SetupForMono8x8PatternFill(ScrnInfoPtr, int, int, int, int, int,
5409885543Smrg					   unsigned int);
5509885543Smrgstatic void SMI_SubsequentMono8x8PatternFillRect(ScrnInfoPtr, int, int, int,
5609885543Smrg						 int, int, int);
5709885543Smrgstatic void SMI_SetupForColor8x8PatternFill(ScrnInfoPtr, int, int, int,
5809885543Smrg					    unsigned int, int);
5909885543Smrgstatic void SMI_SubsequentColor8x8PatternFillRect(ScrnInfoPtr, int, int, int,
6009885543Smrg						  int, int, int);
6109885543Smrg#if SMI_USE_IMAGE_WRITES
6209885543Smrgstatic void SMI_SetupForImageWrite(ScrnInfoPtr, int, unsigned int, int, int,
6309885543Smrg				   int);
6409885543Smrgstatic void SMI_SubsequentImageWriteRect(ScrnInfoPtr, int, int, int, int, int);
6509885543Smrg#endif
6609885543Smrg
67b12e5c03Smrg#endif
6809885543SmrgBool
6909885543SmrgSMI_XAAInit(ScreenPtr pScreen)
7009885543Smrg{
71b12e5c03Smrg#ifdef HAVE_XAA_H
7209885543Smrg    XAAInfoRecPtr infoPtr;
73b12e5c03Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
7409885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
7509885543Smrg    /*BoxRec AvailFBArea;*/
7609885543Smrg    Bool ret;
7709885543Smrg    /*int numLines, maxLines;*/
7809885543Smrg
797104f784Smrg    ENTER();
8009885543Smrg
8109885543Smrg    pSmi->XAAInfoRec = infoPtr = XAACreateInfoRec();
827104f784Smrg    if (infoPtr == NULL)
837104f784Smrg	LEAVE(FALSE);
8409885543Smrg
8509885543Smrg    infoPtr->Flags = PIXMAP_CACHE
8609885543Smrg		   | LINEAR_FRAMEBUFFER
8709885543Smrg		   | OFFSCREEN_PIXMAPS;
8809885543Smrg
8909885543Smrg    infoPtr->Sync = SMI_AccelSync;
9009885543Smrg
917104f784Smrg    if (xf86IsEntityShared(pScrn->entityList[0]))
927104f784Smrg	infoPtr->RestoreAccelState = SMI_EngineReset;
937104f784Smrg
9409885543Smrg    /* Screen to screen copies */
9509885543Smrg    infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK
9609885543Smrg				     | ONLY_TWO_BITBLT_DIRECTIONS;
9709885543Smrg    infoPtr->SetupForScreenToScreenCopy = SMI_SetupForScreenToScreenCopy;
9809885543Smrg    infoPtr->SubsequentScreenToScreenCopy = SMI_SubsequentScreenToScreenCopy;
9909885543Smrg    if (pScrn->bitsPerPixel == 24) {
10009885543Smrg	infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY;
10109885543Smrg    }
10209885543Smrg    if ((pSmi->Chipset == SMI_LYNX3D) && (pScrn->bitsPerPixel == 8)) {
10309885543Smrg	infoPtr->ScreenToScreenCopyFlags |= GXCOPY_ONLY;
10409885543Smrg    }
10509885543Smrg
10609885543Smrg    /* Solid Fills */
10709885543Smrg    infoPtr->SolidFillFlags = NO_PLANEMASK;
10809885543Smrg    infoPtr->SetupForSolidFill = SMI_SetupForSolidFill;
10909885543Smrg    infoPtr->SubsequentSolidFillRect = SMI_SubsequentSolidFillRect;
11009885543Smrg
11109885543Smrg    /* Solid Lines */
11209885543Smrg    infoPtr->SolidLineFlags = NO_PLANEMASK;
11309885543Smrg    infoPtr->SetupForSolidLine = SMI_SetupForSolidFill;
11409885543Smrg    infoPtr->SubsequentSolidHorVertLine = SMI_SubsequentSolidHorVertLine;
11509885543Smrg
11609885543Smrg    /* Color Expansion Fills */
11709885543Smrg    infoPtr->CPUToScreenColorExpandFillFlags = ROP_NEEDS_SOURCE
11809885543Smrg					     | NO_PLANEMASK
11909885543Smrg					     | BIT_ORDER_IN_BYTE_MSBFIRST
12009885543Smrg					     | LEFT_EDGE_CLIPPING
12109885543Smrg					     | CPU_TRANSFER_PAD_DWORD
12209885543Smrg					     | SCANLINE_PAD_DWORD;
12309885543Smrg    infoPtr->ColorExpandBase = pSmi->DataPortBase;
12409885543Smrg    infoPtr->ColorExpandRange = pSmi->DataPortSize;
12509885543Smrg    infoPtr->SetupForCPUToScreenColorExpandFill =
12609885543Smrg	    SMI_SetupForCPUToScreenColorExpandFill;
12709885543Smrg    infoPtr->SubsequentCPUToScreenColorExpandFill =
12809885543Smrg	    SMI_SubsequentCPUToScreenColorExpandFill;
12909885543Smrg
13009885543Smrg    /* 8x8 Mono Pattern Fills */
13109885543Smrg    infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK
13209885543Smrg				     | HARDWARE_PATTERN_PROGRAMMED_BITS
13309885543Smrg				     | HARDWARE_PATTERN_SCREEN_ORIGIN
13409885543Smrg				     | BIT_ORDER_IN_BYTE_MSBFIRST;
13509885543Smrg    infoPtr->SetupForMono8x8PatternFill = SMI_SetupForMono8x8PatternFill;
13609885543Smrg    infoPtr->SubsequentMono8x8PatternFillRect =
13709885543Smrg	SMI_SubsequentMono8x8PatternFillRect;
13809885543Smrg
13909885543Smrg    /* 8x8 Color Pattern Fills */
14009885543Smrg    if (!SMI_LYNX3D_SERIES(pSmi->Chipset) || (pScrn->bitsPerPixel != 24)) {
14109885543Smrg	infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK
14209885543Smrg					  | HARDWARE_PATTERN_SCREEN_ORIGIN;
14309885543Smrg	infoPtr->SetupForColor8x8PatternFill =
14409885543Smrg		SMI_SetupForColor8x8PatternFill;
14509885543Smrg	infoPtr->SubsequentColor8x8PatternFillRect =
14609885543Smrg		SMI_SubsequentColor8x8PatternFillRect;
14709885543Smrg    }
14809885543Smrg
14909885543Smrg#if SMI_USE_IMAGE_WRITES
15009885543Smrg    /* Image Writes */
15109885543Smrg    infoPtr->ImageWriteFlags = ROP_NEEDS_SOURCE
15209885543Smrg			     | NO_PLANEMASK
15309885543Smrg			     | CPU_TRANSFER_PAD_DWORD
15409885543Smrg			     | SCANLINE_PAD_DWORD;
15509885543Smrg    infoPtr->ImageWriteBase = pSmi->DataPortBase;
15609885543Smrg    infoPtr->ImageWriteRange = pSmi->DataPortSize;
15709885543Smrg    infoPtr->SetupForImageWrite = SMI_SetupForImageWrite;
15809885543Smrg    infoPtr->SubsequentImageWriteRect = SMI_SubsequentImageWriteRect;
15909885543Smrg#endif
16009885543Smrg
16109885543Smrg    /* Clipping */
16209885543Smrg    infoPtr->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY
16309885543Smrg			   | HARDWARE_CLIP_MONO_8x8_FILL
16409885543Smrg			   | HARDWARE_CLIP_COLOR_8x8_FILL
16509885543Smrg			   | HARDWARE_CLIP_SOLID_FILL
16609885543Smrg			   | HARDWARE_CLIP_SOLID_LINE
16709885543Smrg			   | HARDWARE_CLIP_DASHED_LINE;
16809885543Smrg    infoPtr->SetClippingRectangle = SMI_SetClippingRectangle;
16909885543Smrg    infoPtr->DisableClipping = SMI_DisableClipping;
17009885543Smrg
17109885543Smrg    /* Pixmap Cache */
17209885543Smrg    if (pScrn->bitsPerPixel == 24) {
17309885543Smrg	infoPtr->CachePixelGranularity = 16;
17409885543Smrg    } else {
17509885543Smrg	infoPtr->CachePixelGranularity = 128 / pScrn->bitsPerPixel;
17609885543Smrg    }
17709885543Smrg
17809885543Smrg    /* Offscreen Pixmaps */
17909885543Smrg    infoPtr->maxOffPixWidth  = 4096;
18009885543Smrg    infoPtr->maxOffPixHeight = 4096;
18109885543Smrg    if (pScrn->bitsPerPixel == 24) {
18209885543Smrg	infoPtr->maxOffPixWidth = 4096 / 3;
18309885543Smrg
18409885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
18509885543Smrg	    infoPtr->maxOffPixHeight = 4096 / 3;
18609885543Smrg	}
18709885543Smrg    }
18809885543Smrg
18909885543Smrg    SMI_EngineReset(pScrn);
19009885543Smrg
19109885543Smrg    ret = XAAInit(pScreen, infoPtr);
19209885543Smrg
1937104f784Smrg    LEAVE(ret);
194b12e5c03Smrg#else
195b12e5c03Smrg    return FALSE;
196b12e5c03Smrg#endif
19709885543Smrg}
19809885543Smrg
199b12e5c03Smrg
200b12e5c03Smrg#ifdef HAVE_XAA_H
20109885543Smrg/******************************************************************************/
20209885543Smrg/*	Screen to Screen Copies						      */
20309885543Smrg/******************************************************************************/
20409885543Smrg
20509885543Smrgstatic void
20609885543SmrgSMI_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
20709885543Smrg			       unsigned int planemask, int trans)
20809885543Smrg{
20909885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
21009885543Smrg
2117104f784Smrg    ENTER();
2127104f784Smrg    DEBUG("xdir=%d ydir=%d rop=%02X trans=%08X\n", xdir, ydir, rop, trans);
21309885543Smrg
214f395c03eSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
2157104f784Smrg    if (pScrn->depth >= 24)
2167104f784Smrg	trans = lswapl(trans);
2177104f784Smrg#endif
21809885543Smrg    pSmi->AccelCmd = XAAGetCopyROP(rop)
21909885543Smrg		   | SMI_BITBLT
22009885543Smrg		   | SMI_START_ENGINE;
22109885543Smrg
22209885543Smrg    if ((xdir == -1) || (ydir == -1)) {
22309885543Smrg	pSmi->AccelCmd |= SMI_RIGHT_TO_LEFT;
22409885543Smrg    }
22509885543Smrg
22609885543Smrg    if (trans != -1) {
22709885543Smrg	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
2287104f784Smrg	WaitQueue();
22909885543Smrg	WRITE_DPR(pSmi, 0x20, trans);
23009885543Smrg    }
23109885543Smrg
23209885543Smrg    if (pSmi->ClipTurnedOn) {
2337104f784Smrg	WaitQueue();
23409885543Smrg	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
23509885543Smrg	pSmi->ClipTurnedOn = FALSE;
23609885543Smrg    }
23709885543Smrg
2387104f784Smrg    LEAVE();
23909885543Smrg}
24009885543Smrg
24109885543Smrgstatic void
24209885543SmrgSMI_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
24309885543Smrg				 int y2, int w, int h)
24409885543Smrg{
24509885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
24609885543Smrg
2477104f784Smrg    ENTER();
2487104f784Smrg    DEBUG("x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n", x1, y1, x2, y2, w, h);
24909885543Smrg
25009885543Smrg    if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) {
25109885543Smrg	x1 += w - 1;
25209885543Smrg	y1 += h - 1;
25309885543Smrg	x2 += w - 1;
25409885543Smrg	y2 += h - 1;
25509885543Smrg    }
25609885543Smrg
25709885543Smrg    if (pScrn->bitsPerPixel == 24) {
25809885543Smrg	x1 *= 3;
25909885543Smrg	x2 *= 3;
26009885543Smrg	w  *= 3;
26109885543Smrg
26209885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
26309885543Smrg	    y1 *= 3;
26409885543Smrg	    y2 *= 3;
26509885543Smrg	}
26609885543Smrg
26709885543Smrg	if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) {
26809885543Smrg	    x1 += 2;
26909885543Smrg	    x2 += 2;
27009885543Smrg	}
27109885543Smrg    }
27209885543Smrg
2737104f784Smrg    WaitIdle();
27409885543Smrg    WRITE_DPR(pSmi, 0x00, (x1 << 16) + (y1 & 0xFFFF));
27509885543Smrg    WRITE_DPR(pSmi, 0x04, (x2 << 16) + (y2 & 0xFFFF));
27609885543Smrg    WRITE_DPR(pSmi, 0x08, (w  << 16) + (h  & 0xFFFF));
27709885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
27809885543Smrg
2797104f784Smrg    LEAVE();
28009885543Smrg}
28109885543Smrg
28209885543Smrg/******************************************************************************/
28309885543Smrg/*   Solid Fills							      */
28409885543Smrg/******************************************************************************/
28509885543Smrg
28609885543Smrgstatic void
28709885543SmrgSMI_SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
28809885543Smrg		      unsigned int planemask)
28909885543Smrg{
29009885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
29109885543Smrg
2927104f784Smrg    ENTER();
2937104f784Smrg    DEBUG("color=%08X rop=%02X\n", color, rop);
29409885543Smrg
29509885543Smrg    pSmi->AccelCmd = XAAGetPatternROP(rop)
29609885543Smrg		   | SMI_BITBLT
29709885543Smrg		   | SMI_START_ENGINE;
29809885543Smrg
299f395c03eSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
3007104f784Smrg    if (pScrn->depth >= 24) {
3017104f784Smrg	/* because of the BGR values are in the MSB bytes,
3027104f784Smrg	 * 'white' is not possible and -1 has a different meaning.
3037104f784Smrg	 * As a work around (assuming white is more used as
3047104f784Smrg	 * light yellow (#FFFF7F), we handle this as beining white.
3057104f784Smrg	 * Thanks to the SM501 not being able to work in MSB on PCI
3067104f784Smrg	 * on the PowerPC */
3077104f784Smrg	if (color == 0x7FFFFFFF)
3087104f784Smrg	    color = -1;
3097104f784Smrg	color = lswapl(color);
3107104f784Smrg    }
3117104f784Smrg#endif
31209885543Smrg    if (pSmi->ClipTurnedOn) {
3137104f784Smrg	WaitQueue();
31409885543Smrg	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
31509885543Smrg	pSmi->ClipTurnedOn = FALSE;
31609885543Smrg    } else {
3177104f784Smrg	WaitQueue();
31809885543Smrg    }
31909885543Smrg    WRITE_DPR(pSmi, 0x14, color);
32009885543Smrg    WRITE_DPR(pSmi, 0x34, 0xFFFFFFFF);
32109885543Smrg    WRITE_DPR(pSmi, 0x38, 0xFFFFFFFF);
32209885543Smrg
3237104f784Smrg    LEAVE();
32409885543Smrg}
32509885543Smrg
32609885543Smrgvoid
32709885543SmrgSMI_SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
32809885543Smrg{
32909885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
33009885543Smrg
3317104f784Smrg    ENTER();
3327104f784Smrg    DEBUG("x=%d y=%d w=%d h=%d\n", x, y, w, h);
33309885543Smrg
33409885543Smrg    if (pScrn->bitsPerPixel == 24) {
33509885543Smrg	x *= 3;
33609885543Smrg	w *= 3;
33709885543Smrg
33809885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
33909885543Smrg	    y *= 3;
34009885543Smrg	}
34109885543Smrg    }
34209885543Smrg
3437104f784Smrg    if (IS_MSOC(pSmi)) {
3447104f784Smrg	/* Clip to prevent negative screen coordinates */
3457104f784Smrg	if (x < 0)
3467104f784Smrg	    x = 0;
3477104f784Smrg	if (y < 0)
3487104f784Smrg	    y = 0;
3497104f784Smrg    }
3507104f784Smrg
3517104f784Smrg    WaitQueue();
35209885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
35309885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
35409885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
35509885543Smrg
3567104f784Smrg    LEAVE();
35709885543Smrg}
35809885543Smrg
35909885543Smrg/******************************************************************************/
36009885543Smrg/*   Solid Lines							      */
36109885543Smrg/******************************************************************************/
36209885543Smrg
36309885543Smrgstatic void
36409885543SmrgSMI_SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len,
36509885543Smrg							   int dir)
36609885543Smrg{
36709885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
36809885543Smrg    int w, h;
36909885543Smrg
3707104f784Smrg    ENTER();
3717104f784Smrg    DEBUG("x=%d y=%d len=%d dir=%d\n", x, y, len, dir);
37209885543Smrg
37309885543Smrg    if (dir == DEGREES_0) {
37409885543Smrg	w = len;
37509885543Smrg	h = 1;
37609885543Smrg    } else {
37709885543Smrg	w = 1;
37809885543Smrg	h = len;
37909885543Smrg    }
38009885543Smrg
38109885543Smrg    if (pScrn->bitsPerPixel == 24) {
38209885543Smrg	x *= 3;
38309885543Smrg	w *= 3;
38409885543Smrg
38509885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
38609885543Smrg	    y *= 3;
38709885543Smrg	}
38809885543Smrg    }
38909885543Smrg
3907104f784Smrg    WaitQueue();
39109885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
39209885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
39309885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
39409885543Smrg
3957104f784Smrg    LEAVE();
39609885543Smrg}
39709885543Smrg
39809885543Smrg/******************************************************************************/
39909885543Smrg/*  Color Expansion Fills						      */
40009885543Smrg/******************************************************************************/
40109885543Smrg
40209885543Smrgstatic void
40309885543SmrgSMI_SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg,
40409885543Smrg				       int rop, unsigned int planemask)
40509885543Smrg{
40609885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
40709885543Smrg
4087104f784Smrg    ENTER();
4097104f784Smrg    DEBUG("fg=%08X bg=%08X rop=%02X\n", fg, bg, rop);
4107104f784Smrg
411f395c03eSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
4127104f784Smrg    if (pScrn->depth >= 24) {
4137104f784Smrg	/* see remark elswere */
4147104f784Smrg	if (fg == 0x7FFFFFFF)
4157104f784Smrg	    fg = -1;
4167104f784Smrg	fg = lswapl(fg);
4177104f784Smrg	bg = lswapl(bg);
4187104f784Smrg    }
4197104f784Smrg#endif
42009885543Smrg
42109885543Smrg    pSmi->AccelCmd = XAAGetCopyROP(rop)
42209885543Smrg		   | SMI_HOSTBLT_WRITE
42309885543Smrg		   | SMI_SRC_MONOCHROME
42409885543Smrg		   | SMI_START_ENGINE;
42509885543Smrg
42609885543Smrg    if (bg == -1) {
42709885543Smrg	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC;
42809885543Smrg
4297104f784Smrg	WaitQueue();
43009885543Smrg	WRITE_DPR(pSmi, 0x14, fg);
43109885543Smrg	WRITE_DPR(pSmi, 0x18, ~fg);
43209885543Smrg	WRITE_DPR(pSmi, 0x20, fg);
43309885543Smrg    } else {
434f395c03eSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
4357104f784Smrg	if (bg == 0xFFFFFF7F)
4367104f784Smrg	    bg = -1;
4377104f784Smrg#endif
4387104f784Smrg	WaitQueue();
43909885543Smrg	WRITE_DPR(pSmi, 0x14, fg);
44009885543Smrg	WRITE_DPR(pSmi, 0x18, bg);
44109885543Smrg    }
44209885543Smrg
4437104f784Smrg    LEAVE();
44409885543Smrg}
44509885543Smrg
44609885543Smrgvoid
44709885543SmrgSMI_SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y, int w,
44809885543Smrg					 int h, int skipleft)
44909885543Smrg{
45009885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
45109885543Smrg
4527104f784Smrg    ENTER();
4537104f784Smrg    DEBUG("x=%d y=%d w=%d h=%d skipleft=%d\n", x, y, w, h, skipleft);
45409885543Smrg
45509885543Smrg    if (pScrn->bitsPerPixel == 24) {
45609885543Smrg	x        *= 3;
45709885543Smrg	w        *= 3;
45809885543Smrg	skipleft *= 3;
45909885543Smrg
46009885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
46109885543Smrg	    y *= 3;
46209885543Smrg	}
46309885543Smrg    }
46409885543Smrg
46509885543Smrg    if (skipleft) {
4667104f784Smrg	WaitQueue();
46709885543Smrg	WRITE_DPR(pSmi, 0x2C, (pSmi->ScissorsLeft & 0xFFFF0000)
46809885543Smrg			      | (x + skipleft) | 0x2000);
46909885543Smrg	pSmi->ClipTurnedOn = TRUE;
47009885543Smrg    } else {
47109885543Smrg	if (pSmi->ClipTurnedOn) {
4727104f784Smrg	    WaitQueue();
47309885543Smrg	    WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
47409885543Smrg	    pSmi->ClipTurnedOn = FALSE;
47509885543Smrg	} else {
4767104f784Smrg	    WaitQueue();
47709885543Smrg	}
47809885543Smrg    }
47909885543Smrg    WRITE_DPR(pSmi, 0x00, 0);
48009885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
48109885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
48209885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
48309885543Smrg
4847104f784Smrg    LEAVE();
48509885543Smrg}
48609885543Smrg
48709885543Smrg/******************************************************************************/
48809885543Smrg/* 8x8 Mono Pattern Fills						      */
48909885543Smrg/******************************************************************************/
49009885543Smrg
49109885543Smrgstatic void
49209885543SmrgSMI_SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, int fg,
49309885543Smrg			       int bg, int rop, unsigned int planemask)
49409885543Smrg{
49509885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
49609885543Smrg
4977104f784Smrg    ENTER();
4987104f784Smrg    DEBUG("patx=%08X paty=%08X fg=%08X bg=%08X rop=%02X\n",
4997104f784Smrg	  patx, paty, fg, bg, rop);
50009885543Smrg
501f395c03eSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
5027104f784Smrg    if (pScrn->depth >= 24) {
5037104f784Smrg	if (fg == 0x7FFFFFFF)
5047104f784Smrg	    fg = -1;
5057104f784Smrg	fg = lswapl(fg);
5067104f784Smrg	bg = lswapl(bg);
5077104f784Smrg    }
5087104f784Smrg#endif
50909885543Smrg    pSmi->AccelCmd = XAAGetPatternROP(rop)
51009885543Smrg		   | SMI_BITBLT
51109885543Smrg		   | SMI_START_ENGINE;
51209885543Smrg
51309885543Smrg    if (pSmi->ClipTurnedOn) {
5147104f784Smrg	WaitQueue();
51509885543Smrg	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
51609885543Smrg	pSmi->ClipTurnedOn = FALSE;
51709885543Smrg    }
51809885543Smrg
51909885543Smrg    if (bg == -1) {
5207104f784Smrg	WaitQueue();
52109885543Smrg	WRITE_DPR(pSmi, 0x14, fg);
52209885543Smrg	WRITE_DPR(pSmi, 0x18, ~fg);
52309885543Smrg	WRITE_DPR(pSmi, 0x20, fg);
52409885543Smrg	WRITE_DPR(pSmi, 0x34, patx);
52509885543Smrg	WRITE_DPR(pSmi, 0x38, paty);
52609885543Smrg    } else {
527f395c03eSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
5287104f784Smrg	if (bg == 0xFFFFFF7F)
5297104f784Smrg	    bg = -1;
5307104f784Smrg#endif
5317104f784Smrg	WaitQueue();
53209885543Smrg	WRITE_DPR(pSmi, 0x14, fg);
53309885543Smrg	WRITE_DPR(pSmi, 0x18, bg);
53409885543Smrg	WRITE_DPR(pSmi, 0x34, patx);
53509885543Smrg	WRITE_DPR(pSmi, 0x38, paty);
53609885543Smrg    }
53709885543Smrg
5387104f784Smrg    LEAVE();
53909885543Smrg}
54009885543Smrg
54109885543Smrgstatic void
54209885543SmrgSMI_SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
54309885543Smrg				     int x, int y, int w, int h)
54409885543Smrg{
54509885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
54609885543Smrg
5477104f784Smrg    ENTER();
5487104f784Smrg    DEBUG("x=%d y=%d w=%d h=%d\n", x, y, w, h);
54909885543Smrg
55009885543Smrg    if (pScrn->bitsPerPixel == 24) {
55109885543Smrg	x *= 3;
55209885543Smrg	w *= 3;
55309885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
55409885543Smrg	    y *= 3;
55509885543Smrg	}
55609885543Smrg    }
55709885543Smrg
5587104f784Smrg    WaitQueue();
55909885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
56009885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
56109885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
56209885543Smrg
5637104f784Smrg    LEAVE();
56409885543Smrg}
56509885543Smrg
56609885543Smrg/******************************************************************************/
56709885543Smrg/* 8x8 Color Pattern Fills						      */
56809885543Smrg/******************************************************************************/
56909885543Smrg
57009885543Smrgstatic void
57109885543SmrgSMI_SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, int rop,
57209885543Smrg				unsigned int planemask, int trans_color)
57309885543Smrg{
57409885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
57509885543Smrg
5767104f784Smrg    ENTER();
5777104f784Smrg    DEBUG("patx=%d paty=%d rop=%02X trans_color=%08X\n",
5787104f784Smrg	  patx, paty, rop, trans_color);
57909885543Smrg
58009885543Smrg    pSmi->AccelCmd = XAAGetPatternROP(rop)
58109885543Smrg		   | SMI_BITBLT
58209885543Smrg		   | SMI_COLOR_PATTERN
58309885543Smrg		   | SMI_START_ENGINE;
58409885543Smrg
585f395c03eSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
5867104f784Smrg    if (pScrn->depth >= 24)
5877104f784Smrg	trans_color = lswapl(trans_color);
5887104f784Smrg#endif
58909885543Smrg    if (pScrn->bitsPerPixel <= 16) {
59009885543Smrg	/* PDR#950 */
5917104f784Smrg	CARD8* pattern = pSmi->FBBase +
5927104f784Smrg	    (patx + paty * pScrn->displayWidth) * pSmi->Bpp;
59309885543Smrg
5947104f784Smrg	WaitIdle();
59509885543Smrg	WRITE_DPR(pSmi, 0x0C, SMI_BITBLT | SMI_COLOR_PATTERN);
59609885543Smrg	memcpy(pSmi->DataPortBase, pattern, 8 * pSmi->Bpp * 8);
59709885543Smrg    } else {
59809885543Smrg	if (pScrn->bitsPerPixel == 24) {
59909885543Smrg	    patx *= 3;
60009885543Smrg
60109885543Smrg	    if (pSmi->Chipset == SMI_LYNX) {
60209885543Smrg		paty *= 3;
60309885543Smrg	    }
60409885543Smrg	}
60509885543Smrg
6067104f784Smrg	WaitQueue();
60709885543Smrg	WRITE_DPR(pSmi, 0x00, (patx << 16) | (paty & 0xFFFF));
60809885543Smrg    }
60909885543Smrg
6107104f784Smrg    WaitQueue();
6117104f784Smrg
61209885543Smrg    if (trans_color == -1) {
61309885543Smrg	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
61409885543Smrg
6157104f784Smrg	WaitQueue();
61609885543Smrg	WRITE_DPR(pSmi, 0x20, trans_color);
61709885543Smrg    }
61809885543Smrg
61909885543Smrg    if (pSmi->ClipTurnedOn) {
6207104f784Smrg	WaitQueue();
62109885543Smrg	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
62209885543Smrg	pSmi->ClipTurnedOn = FALSE;
62309885543Smrg    }
62409885543Smrg
6257104f784Smrg    LEAVE();
62609885543Smrg}
62709885543Smrg
62809885543Smrgstatic void
62909885543SmrgSMI_SubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
63009885543Smrg				      int x, int y, int w, int h)
63109885543Smrg{
63209885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
63309885543Smrg
6347104f784Smrg    ENTER();
6357104f784Smrg    DEBUG("x=%d y=%d w=%d h=%d\n", x, y, w, h);
63609885543Smrg
63709885543Smrg    if (pScrn->bitsPerPixel == 24) {
63809885543Smrg	x *= 3;
63909885543Smrg	w *= 3;
64009885543Smrg
64109885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
64209885543Smrg	    y *= 3;
64309885543Smrg	}
64409885543Smrg    }
64509885543Smrg
6467104f784Smrg    WaitQueue();
64709885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
64809885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));	/* PDR#950 */
64909885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
65009885543Smrg
6517104f784Smrg    LEAVE();
65209885543Smrg}
65309885543Smrg
65409885543Smrg#if SMI_USE_IMAGE_WRITES
65509885543Smrg/******************************************************************************/
65609885543Smrg/*  Image Writes							      */
65709885543Smrg/******************************************************************************/
65809885543Smrg
65909885543Smrgstatic void
66009885543SmrgSMI_SetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned int planemask,
66109885543Smrg		       int trans_color, int bpp, int depth)
66209885543Smrg{
66309885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
66409885543Smrg
6657104f784Smrg    ENTER();
6667104f784Smrg    DEBUG("rop=%02X trans_color=%08X bpp=%d depth=%d\n",
6677104f784Smrg	  rop, trans_color, bpp, depth);
66809885543Smrg
669f395c03eSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
6707104f784Smrg    if (pScrn->depth >= 24)
6717104f784Smrg	trans_color = lswapl(trans_color);
6727104f784Smrg#endif
67309885543Smrg    pSmi->AccelCmd = XAAGetCopyROP(rop)
67409885543Smrg		   | SMI_HOSTBLT_WRITE
67509885543Smrg		   | SMI_START_ENGINE;
67609885543Smrg
67709885543Smrg    if (trans_color != -1) {
678f395c03eSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
6797104f784Smrg	if (trans_color == 0xFFFFFF7F)
6807104f784Smrg	    trans_color = -1;
6817104f784Smrg#endif
68209885543Smrg	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
68309885543Smrg
6847104f784Smrg	WaitQueue();
68509885543Smrg	WRITE_DPR(pSmi, 0x20, trans_color);
68609885543Smrg    }
68709885543Smrg
6887104f784Smrg    LEAVE();
68909885543Smrg}
69009885543Smrg
69109885543Smrgstatic void
69209885543SmrgSMI_SubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
69309885543Smrg			     int skipleft)
69409885543Smrg{
69509885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
69609885543Smrg
6977104f784Smrg    ENTER();
6987104f784Smrg    DEBUG("x=%d y=%d w=%d h=%d skipleft=%d\n", x, y, w, h, skipleft);
69909885543Smrg
70009885543Smrg    if (pScrn->bitsPerPixel == 24) {
70109885543Smrg	x        *= 3;
70209885543Smrg	w        *= 3;
70309885543Smrg	skipleft *= 3;
70409885543Smrg
70509885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
70609885543Smrg	    y *= 3;
70709885543Smrg	}
70809885543Smrg    }
70909885543Smrg
71009885543Smrg    if (skipleft) {
7117104f784Smrg	WaitQueue();
71209885543Smrg	WRITE_DPR(pSmi, 0x2C, (pSmi->ScissorsLeft & 0xFFFF0000) |
71309885543Smrg			      (x + skipleft) | 0x2000);
71409885543Smrg	pSmi->ClipTurnedOn = TRUE;
71509885543Smrg    } else {
71609885543Smrg	if (pSmi->ClipTurnedOn) {
7177104f784Smrg	    WaitQueue();
71809885543Smrg	    WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
71909885543Smrg	    pSmi->ClipTurnedOn = FALSE;
72009885543Smrg	} else {
7217104f784Smrg	    WaitQueue();
72209885543Smrg	}
72309885543Smrg    }
72409885543Smrg    WRITE_DPR(pSmi, 0x00, 0);
72509885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y * 0xFFFF));
72609885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
72709885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
72809885543Smrg
7297104f784Smrg    LEAVE();
73009885543Smrg}
73109885543Smrg#endif
732b12e5c03Smrg#endif
733