smi_xaa.c revision 7104f784
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
3509885543Smrg#include "miline.h"
3609885543Smrg#include "xaalocal.h"
3709885543Smrg#include "xaarop.h"
3809885543Smrg#include "servermd.h"
3909885543Smrg
4009885543Smrgstatic void SMI_SetupForScreenToScreenCopy(ScrnInfoPtr, int, int, int,
4109885543Smrg					   unsigned int, int);
4209885543Smrgstatic void SMI_SubsequentScreenToScreenCopy(ScrnInfoPtr, int, int, int, int,
4309885543Smrg					     int, int);
4409885543Smrgstatic void SMI_SetupForSolidFill(ScrnInfoPtr, int, int, unsigned);
4509885543Smrgstatic void SMI_SubsequentSolidFillRect(ScrnInfoPtr, int, int, int, int);
4609885543Smrgstatic void SMI_SubsequentSolidHorVertLine(ScrnInfoPtr, int, int, int, int);
4709885543Smrgstatic void SMI_SetupForCPUToScreenColorExpandFill(ScrnInfoPtr, int, int, int,
4809885543Smrg						   unsigned int);
4909885543Smrgstatic void SMI_SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr, int, int, int,
5009885543Smrg						     int, int);
5109885543Smrgstatic void SMI_SetupForMono8x8PatternFill(ScrnInfoPtr, int, int, int, int, int,
5209885543Smrg					   unsigned int);
5309885543Smrgstatic void SMI_SubsequentMono8x8PatternFillRect(ScrnInfoPtr, int, int, int,
5409885543Smrg						 int, int, int);
5509885543Smrgstatic void SMI_SetupForColor8x8PatternFill(ScrnInfoPtr, int, int, int,
5609885543Smrg					    unsigned int, int);
5709885543Smrgstatic void SMI_SubsequentColor8x8PatternFillRect(ScrnInfoPtr, int, int, int,
5809885543Smrg						  int, int, int);
5909885543Smrg#if SMI_USE_IMAGE_WRITES
6009885543Smrgstatic void SMI_SetupForImageWrite(ScrnInfoPtr, int, unsigned int, int, int,
6109885543Smrg				   int);
6209885543Smrgstatic void SMI_SubsequentImageWriteRect(ScrnInfoPtr, int, int, int, int, int);
6309885543Smrg#endif
6409885543Smrg
6509885543SmrgBool
6609885543SmrgSMI_XAAInit(ScreenPtr pScreen)
6709885543Smrg{
6809885543Smrg    XAAInfoRecPtr infoPtr;
6909885543Smrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
7009885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
7109885543Smrg    /*BoxRec AvailFBArea;*/
7209885543Smrg    Bool ret;
7309885543Smrg    /*int numLines, maxLines;*/
7409885543Smrg
757104f784Smrg    ENTER();
7609885543Smrg
7709885543Smrg    pSmi->XAAInfoRec = infoPtr = XAACreateInfoRec();
787104f784Smrg    if (infoPtr == NULL)
797104f784Smrg	LEAVE(FALSE);
8009885543Smrg
8109885543Smrg    infoPtr->Flags = PIXMAP_CACHE
8209885543Smrg		   | LINEAR_FRAMEBUFFER
8309885543Smrg		   | OFFSCREEN_PIXMAPS;
8409885543Smrg
8509885543Smrg    infoPtr->Sync = SMI_AccelSync;
8609885543Smrg
877104f784Smrg    if (xf86IsEntityShared(pScrn->entityList[0]))
887104f784Smrg	infoPtr->RestoreAccelState = SMI_EngineReset;
897104f784Smrg
9009885543Smrg    /* Screen to screen copies */
9109885543Smrg    infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK
9209885543Smrg				     | ONLY_TWO_BITBLT_DIRECTIONS;
9309885543Smrg    infoPtr->SetupForScreenToScreenCopy = SMI_SetupForScreenToScreenCopy;
9409885543Smrg    infoPtr->SubsequentScreenToScreenCopy = SMI_SubsequentScreenToScreenCopy;
9509885543Smrg    if (pScrn->bitsPerPixel == 24) {
9609885543Smrg	infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY;
9709885543Smrg    }
9809885543Smrg    if ((pSmi->Chipset == SMI_LYNX3D) && (pScrn->bitsPerPixel == 8)) {
9909885543Smrg	infoPtr->ScreenToScreenCopyFlags |= GXCOPY_ONLY;
10009885543Smrg    }
10109885543Smrg
10209885543Smrg    /* Solid Fills */
10309885543Smrg    infoPtr->SolidFillFlags = NO_PLANEMASK;
10409885543Smrg    infoPtr->SetupForSolidFill = SMI_SetupForSolidFill;
10509885543Smrg    infoPtr->SubsequentSolidFillRect = SMI_SubsequentSolidFillRect;
10609885543Smrg
10709885543Smrg    /* Solid Lines */
10809885543Smrg    infoPtr->SolidLineFlags = NO_PLANEMASK;
10909885543Smrg    infoPtr->SetupForSolidLine = SMI_SetupForSolidFill;
11009885543Smrg    infoPtr->SubsequentSolidHorVertLine = SMI_SubsequentSolidHorVertLine;
11109885543Smrg
11209885543Smrg    /* Color Expansion Fills */
11309885543Smrg    infoPtr->CPUToScreenColorExpandFillFlags = ROP_NEEDS_SOURCE
11409885543Smrg					     | NO_PLANEMASK
11509885543Smrg					     | BIT_ORDER_IN_BYTE_MSBFIRST
11609885543Smrg					     | LEFT_EDGE_CLIPPING
11709885543Smrg					     | CPU_TRANSFER_PAD_DWORD
11809885543Smrg					     | SCANLINE_PAD_DWORD;
11909885543Smrg    infoPtr->ColorExpandBase = pSmi->DataPortBase;
12009885543Smrg    infoPtr->ColorExpandRange = pSmi->DataPortSize;
12109885543Smrg    infoPtr->SetupForCPUToScreenColorExpandFill =
12209885543Smrg	    SMI_SetupForCPUToScreenColorExpandFill;
12309885543Smrg    infoPtr->SubsequentCPUToScreenColorExpandFill =
12409885543Smrg	    SMI_SubsequentCPUToScreenColorExpandFill;
12509885543Smrg
12609885543Smrg    /* 8x8 Mono Pattern Fills */
12709885543Smrg    infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK
12809885543Smrg				     | HARDWARE_PATTERN_PROGRAMMED_BITS
12909885543Smrg				     | HARDWARE_PATTERN_SCREEN_ORIGIN
13009885543Smrg				     | BIT_ORDER_IN_BYTE_MSBFIRST;
13109885543Smrg    infoPtr->SetupForMono8x8PatternFill = SMI_SetupForMono8x8PatternFill;
13209885543Smrg    infoPtr->SubsequentMono8x8PatternFillRect =
13309885543Smrg	SMI_SubsequentMono8x8PatternFillRect;
13409885543Smrg
13509885543Smrg    /* 8x8 Color Pattern Fills */
13609885543Smrg    if (!SMI_LYNX3D_SERIES(pSmi->Chipset) || (pScrn->bitsPerPixel != 24)) {
13709885543Smrg	infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK
13809885543Smrg					  | HARDWARE_PATTERN_SCREEN_ORIGIN;
13909885543Smrg	infoPtr->SetupForColor8x8PatternFill =
14009885543Smrg		SMI_SetupForColor8x8PatternFill;
14109885543Smrg	infoPtr->SubsequentColor8x8PatternFillRect =
14209885543Smrg		SMI_SubsequentColor8x8PatternFillRect;
14309885543Smrg    }
14409885543Smrg
14509885543Smrg#if SMI_USE_IMAGE_WRITES
14609885543Smrg    /* Image Writes */
14709885543Smrg    infoPtr->ImageWriteFlags = ROP_NEEDS_SOURCE
14809885543Smrg			     | NO_PLANEMASK
14909885543Smrg			     | CPU_TRANSFER_PAD_DWORD
15009885543Smrg			     | SCANLINE_PAD_DWORD;
15109885543Smrg    infoPtr->ImageWriteBase = pSmi->DataPortBase;
15209885543Smrg    infoPtr->ImageWriteRange = pSmi->DataPortSize;
15309885543Smrg    infoPtr->SetupForImageWrite = SMI_SetupForImageWrite;
15409885543Smrg    infoPtr->SubsequentImageWriteRect = SMI_SubsequentImageWriteRect;
15509885543Smrg#endif
15609885543Smrg
15709885543Smrg    /* Clipping */
15809885543Smrg    infoPtr->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY
15909885543Smrg			   | HARDWARE_CLIP_MONO_8x8_FILL
16009885543Smrg			   | HARDWARE_CLIP_COLOR_8x8_FILL
16109885543Smrg			   | HARDWARE_CLIP_SOLID_FILL
16209885543Smrg			   | HARDWARE_CLIP_SOLID_LINE
16309885543Smrg			   | HARDWARE_CLIP_DASHED_LINE;
16409885543Smrg    infoPtr->SetClippingRectangle = SMI_SetClippingRectangle;
16509885543Smrg    infoPtr->DisableClipping = SMI_DisableClipping;
16609885543Smrg
16709885543Smrg    /* Pixmap Cache */
16809885543Smrg    if (pScrn->bitsPerPixel == 24) {
16909885543Smrg	infoPtr->CachePixelGranularity = 16;
17009885543Smrg    } else {
17109885543Smrg	infoPtr->CachePixelGranularity = 128 / pScrn->bitsPerPixel;
17209885543Smrg    }
17309885543Smrg
17409885543Smrg    /* Offscreen Pixmaps */
17509885543Smrg    infoPtr->maxOffPixWidth  = 4096;
17609885543Smrg    infoPtr->maxOffPixHeight = 4096;
17709885543Smrg    if (pScrn->bitsPerPixel == 24) {
17809885543Smrg	infoPtr->maxOffPixWidth = 4096 / 3;
17909885543Smrg
18009885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
18109885543Smrg	    infoPtr->maxOffPixHeight = 4096 / 3;
18209885543Smrg	}
18309885543Smrg    }
18409885543Smrg
18509885543Smrg    SMI_EngineReset(pScrn);
18609885543Smrg
18709885543Smrg    ret = XAAInit(pScreen, infoPtr);
18809885543Smrg
1897104f784Smrg    LEAVE(ret);
19009885543Smrg}
19109885543Smrg
19209885543Smrg/******************************************************************************/
19309885543Smrg/*	Screen to Screen Copies						      */
19409885543Smrg/******************************************************************************/
19509885543Smrg
19609885543Smrgstatic void
19709885543SmrgSMI_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
19809885543Smrg			       unsigned int planemask, int trans)
19909885543Smrg{
20009885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
20109885543Smrg
2027104f784Smrg    ENTER();
2037104f784Smrg    DEBUG("xdir=%d ydir=%d rop=%02X trans=%08X\n", xdir, ydir, rop, trans);
20409885543Smrg
2057104f784Smrg#if __BYTE_ORDER == __BIG_ENDIAN
2067104f784Smrg    if (pScrn->depth >= 24)
2077104f784Smrg	trans = lswapl(trans);
2087104f784Smrg#endif
20909885543Smrg    pSmi->AccelCmd = XAAGetCopyROP(rop)
21009885543Smrg		   | SMI_BITBLT
21109885543Smrg		   | SMI_START_ENGINE;
21209885543Smrg
21309885543Smrg    if ((xdir == -1) || (ydir == -1)) {
21409885543Smrg	pSmi->AccelCmd |= SMI_RIGHT_TO_LEFT;
21509885543Smrg    }
21609885543Smrg
21709885543Smrg    if (trans != -1) {
21809885543Smrg	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
2197104f784Smrg	WaitQueue();
22009885543Smrg	WRITE_DPR(pSmi, 0x20, trans);
22109885543Smrg    }
22209885543Smrg
22309885543Smrg    if (pSmi->ClipTurnedOn) {
2247104f784Smrg	WaitQueue();
22509885543Smrg	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
22609885543Smrg	pSmi->ClipTurnedOn = FALSE;
22709885543Smrg    }
22809885543Smrg
2297104f784Smrg    LEAVE();
23009885543Smrg}
23109885543Smrg
23209885543Smrgstatic void
23309885543SmrgSMI_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
23409885543Smrg				 int y2, int w, int h)
23509885543Smrg{
23609885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
23709885543Smrg
2387104f784Smrg    ENTER();
2397104f784Smrg    DEBUG("x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n", x1, y1, x2, y2, w, h);
24009885543Smrg
24109885543Smrg    if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) {
24209885543Smrg	x1 += w - 1;
24309885543Smrg	y1 += h - 1;
24409885543Smrg	x2 += w - 1;
24509885543Smrg	y2 += h - 1;
24609885543Smrg    }
24709885543Smrg
24809885543Smrg    if (pScrn->bitsPerPixel == 24) {
24909885543Smrg	x1 *= 3;
25009885543Smrg	x2 *= 3;
25109885543Smrg	w  *= 3;
25209885543Smrg
25309885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
25409885543Smrg	    y1 *= 3;
25509885543Smrg	    y2 *= 3;
25609885543Smrg	}
25709885543Smrg
25809885543Smrg	if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) {
25909885543Smrg	    x1 += 2;
26009885543Smrg	    x2 += 2;
26109885543Smrg	}
26209885543Smrg    }
26309885543Smrg
2647104f784Smrg    WaitIdle();
26509885543Smrg    WRITE_DPR(pSmi, 0x00, (x1 << 16) + (y1 & 0xFFFF));
26609885543Smrg    WRITE_DPR(pSmi, 0x04, (x2 << 16) + (y2 & 0xFFFF));
26709885543Smrg    WRITE_DPR(pSmi, 0x08, (w  << 16) + (h  & 0xFFFF));
26809885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
26909885543Smrg
2707104f784Smrg    LEAVE();
27109885543Smrg}
27209885543Smrg
27309885543Smrg/******************************************************************************/
27409885543Smrg/*   Solid Fills							      */
27509885543Smrg/******************************************************************************/
27609885543Smrg
27709885543Smrgstatic void
27809885543SmrgSMI_SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
27909885543Smrg		      unsigned int planemask)
28009885543Smrg{
28109885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
28209885543Smrg
2837104f784Smrg    ENTER();
2847104f784Smrg    DEBUG("color=%08X rop=%02X\n", color, rop);
28509885543Smrg
28609885543Smrg    pSmi->AccelCmd = XAAGetPatternROP(rop)
28709885543Smrg		   | SMI_BITBLT
28809885543Smrg		   | SMI_START_ENGINE;
28909885543Smrg
2907104f784Smrg#if __BYTE_ORDER == __BIG_ENDIAN
2917104f784Smrg    if (pScrn->depth >= 24) {
2927104f784Smrg	/* because of the BGR values are in the MSB bytes,
2937104f784Smrg	 * 'white' is not possible and -1 has a different meaning.
2947104f784Smrg	 * As a work around (assuming white is more used as
2957104f784Smrg	 * light yellow (#FFFF7F), we handle this as beining white.
2967104f784Smrg	 * Thanks to the SM501 not being able to work in MSB on PCI
2977104f784Smrg	 * on the PowerPC */
2987104f784Smrg	if (color == 0x7FFFFFFF)
2997104f784Smrg	    color = -1;
3007104f784Smrg	color = lswapl(color);
3017104f784Smrg    }
3027104f784Smrg#endif
30309885543Smrg    if (pSmi->ClipTurnedOn) {
3047104f784Smrg	WaitQueue();
30509885543Smrg	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
30609885543Smrg	pSmi->ClipTurnedOn = FALSE;
30709885543Smrg    } else {
3087104f784Smrg	WaitQueue();
30909885543Smrg    }
31009885543Smrg    WRITE_DPR(pSmi, 0x14, color);
31109885543Smrg    WRITE_DPR(pSmi, 0x34, 0xFFFFFFFF);
31209885543Smrg    WRITE_DPR(pSmi, 0x38, 0xFFFFFFFF);
31309885543Smrg
3147104f784Smrg    LEAVE();
31509885543Smrg}
31609885543Smrg
31709885543Smrgvoid
31809885543SmrgSMI_SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
31909885543Smrg{
32009885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
32109885543Smrg
3227104f784Smrg    ENTER();
3237104f784Smrg    DEBUG("x=%d y=%d w=%d h=%d\n", x, y, w, h);
32409885543Smrg
32509885543Smrg    if (pScrn->bitsPerPixel == 24) {
32609885543Smrg	x *= 3;
32709885543Smrg	w *= 3;
32809885543Smrg
32909885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
33009885543Smrg	    y *= 3;
33109885543Smrg	}
33209885543Smrg    }
33309885543Smrg
3347104f784Smrg    if (IS_MSOC(pSmi)) {
3357104f784Smrg	/* Clip to prevent negative screen coordinates */
3367104f784Smrg	if (x < 0)
3377104f784Smrg	    x = 0;
3387104f784Smrg	if (y < 0)
3397104f784Smrg	    y = 0;
3407104f784Smrg    }
3417104f784Smrg
3427104f784Smrg    WaitQueue();
34309885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
34409885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
34509885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
34609885543Smrg
3477104f784Smrg    LEAVE();
34809885543Smrg}
34909885543Smrg
35009885543Smrg/******************************************************************************/
35109885543Smrg/*   Solid Lines							      */
35209885543Smrg/******************************************************************************/
35309885543Smrg
35409885543Smrgstatic void
35509885543SmrgSMI_SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len,
35609885543Smrg							   int dir)
35709885543Smrg{
35809885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
35909885543Smrg    int w, h;
36009885543Smrg
3617104f784Smrg    ENTER();
3627104f784Smrg    DEBUG("x=%d y=%d len=%d dir=%d\n", x, y, len, dir);
36309885543Smrg
36409885543Smrg    if (dir == DEGREES_0) {
36509885543Smrg	w = len;
36609885543Smrg	h = 1;
36709885543Smrg    } else {
36809885543Smrg	w = 1;
36909885543Smrg	h = len;
37009885543Smrg    }
37109885543Smrg
37209885543Smrg    if (pScrn->bitsPerPixel == 24) {
37309885543Smrg	x *= 3;
37409885543Smrg	w *= 3;
37509885543Smrg
37609885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
37709885543Smrg	    y *= 3;
37809885543Smrg	}
37909885543Smrg    }
38009885543Smrg
3817104f784Smrg    WaitQueue();
38209885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
38309885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
38409885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
38509885543Smrg
3867104f784Smrg    LEAVE();
38709885543Smrg}
38809885543Smrg
38909885543Smrg/******************************************************************************/
39009885543Smrg/*  Color Expansion Fills						      */
39109885543Smrg/******************************************************************************/
39209885543Smrg
39309885543Smrgstatic void
39409885543SmrgSMI_SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg,
39509885543Smrg				       int rop, unsigned int planemask)
39609885543Smrg{
39709885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
39809885543Smrg
3997104f784Smrg    ENTER();
4007104f784Smrg    DEBUG("fg=%08X bg=%08X rop=%02X\n", fg, bg, rop);
4017104f784Smrg
4027104f784Smrg#if __BYTE_ORDER == __BIG_ENDIAN
4037104f784Smrg    if (pScrn->depth >= 24) {
4047104f784Smrg	/* see remark elswere */
4057104f784Smrg	if (fg == 0x7FFFFFFF)
4067104f784Smrg	    fg = -1;
4077104f784Smrg	fg = lswapl(fg);
4087104f784Smrg	bg = lswapl(bg);
4097104f784Smrg    }
4107104f784Smrg#endif
41109885543Smrg
41209885543Smrg    pSmi->AccelCmd = XAAGetCopyROP(rop)
41309885543Smrg		   | SMI_HOSTBLT_WRITE
41409885543Smrg		   | SMI_SRC_MONOCHROME
41509885543Smrg		   | SMI_START_ENGINE;
41609885543Smrg
41709885543Smrg    if (bg == -1) {
41809885543Smrg	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC;
41909885543Smrg
4207104f784Smrg	WaitQueue();
42109885543Smrg	WRITE_DPR(pSmi, 0x14, fg);
42209885543Smrg	WRITE_DPR(pSmi, 0x18, ~fg);
42309885543Smrg	WRITE_DPR(pSmi, 0x20, fg);
42409885543Smrg    } else {
4257104f784Smrg#if __BYTE_ORDER == __BIG_ENDIAN
4267104f784Smrg	if (bg == 0xFFFFFF7F)
4277104f784Smrg	    bg = -1;
4287104f784Smrg#endif
4297104f784Smrg	WaitQueue();
43009885543Smrg	WRITE_DPR(pSmi, 0x14, fg);
43109885543Smrg	WRITE_DPR(pSmi, 0x18, bg);
43209885543Smrg    }
43309885543Smrg
4347104f784Smrg    LEAVE();
43509885543Smrg}
43609885543Smrg
43709885543Smrgvoid
43809885543SmrgSMI_SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y, int w,
43909885543Smrg					 int h, int skipleft)
44009885543Smrg{
44109885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
44209885543Smrg
4437104f784Smrg    ENTER();
4447104f784Smrg    DEBUG("x=%d y=%d w=%d h=%d skipleft=%d\n", x, y, w, h, skipleft);
44509885543Smrg
44609885543Smrg    if (pScrn->bitsPerPixel == 24) {
44709885543Smrg	x        *= 3;
44809885543Smrg	w        *= 3;
44909885543Smrg	skipleft *= 3;
45009885543Smrg
45109885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
45209885543Smrg	    y *= 3;
45309885543Smrg	}
45409885543Smrg    }
45509885543Smrg
45609885543Smrg    if (skipleft) {
4577104f784Smrg	WaitQueue();
45809885543Smrg	WRITE_DPR(pSmi, 0x2C, (pSmi->ScissorsLeft & 0xFFFF0000)
45909885543Smrg			      | (x + skipleft) | 0x2000);
46009885543Smrg	pSmi->ClipTurnedOn = TRUE;
46109885543Smrg    } else {
46209885543Smrg	if (pSmi->ClipTurnedOn) {
4637104f784Smrg	    WaitQueue();
46409885543Smrg	    WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
46509885543Smrg	    pSmi->ClipTurnedOn = FALSE;
46609885543Smrg	} else {
4677104f784Smrg	    WaitQueue();
46809885543Smrg	}
46909885543Smrg    }
47009885543Smrg    WRITE_DPR(pSmi, 0x00, 0);
47109885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
47209885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
47309885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
47409885543Smrg
4757104f784Smrg    LEAVE();
47609885543Smrg}
47709885543Smrg
47809885543Smrg/******************************************************************************/
47909885543Smrg/* 8x8 Mono Pattern Fills						      */
48009885543Smrg/******************************************************************************/
48109885543Smrg
48209885543Smrgstatic void
48309885543SmrgSMI_SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, int fg,
48409885543Smrg			       int bg, int rop, unsigned int planemask)
48509885543Smrg{
48609885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
48709885543Smrg
4887104f784Smrg    ENTER();
4897104f784Smrg    DEBUG("patx=%08X paty=%08X fg=%08X bg=%08X rop=%02X\n",
4907104f784Smrg	  patx, paty, fg, bg, rop);
49109885543Smrg
4927104f784Smrg#if __BYTE_ORDER == __BIG_ENDIAN
4937104f784Smrg    if (pScrn->depth >= 24) {
4947104f784Smrg	if (fg == 0x7FFFFFFF)
4957104f784Smrg	    fg = -1;
4967104f784Smrg	fg = lswapl(fg);
4977104f784Smrg	bg = lswapl(bg);
4987104f784Smrg    }
4997104f784Smrg#endif
50009885543Smrg    pSmi->AccelCmd = XAAGetPatternROP(rop)
50109885543Smrg		   | SMI_BITBLT
50209885543Smrg		   | SMI_START_ENGINE;
50309885543Smrg
50409885543Smrg    if (pSmi->ClipTurnedOn) {
5057104f784Smrg	WaitQueue();
50609885543Smrg	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
50709885543Smrg	pSmi->ClipTurnedOn = FALSE;
50809885543Smrg    }
50909885543Smrg
51009885543Smrg    if (bg == -1) {
5117104f784Smrg	WaitQueue();
51209885543Smrg	WRITE_DPR(pSmi, 0x14, fg);
51309885543Smrg	WRITE_DPR(pSmi, 0x18, ~fg);
51409885543Smrg	WRITE_DPR(pSmi, 0x20, fg);
51509885543Smrg	WRITE_DPR(pSmi, 0x34, patx);
51609885543Smrg	WRITE_DPR(pSmi, 0x38, paty);
51709885543Smrg    } else {
5187104f784Smrg#if __BYTE_ORDER == __BIG_ENDIAN
5197104f784Smrg	if (bg == 0xFFFFFF7F)
5207104f784Smrg	    bg = -1;
5217104f784Smrg#endif
5227104f784Smrg	WaitQueue();
52309885543Smrg	WRITE_DPR(pSmi, 0x14, fg);
52409885543Smrg	WRITE_DPR(pSmi, 0x18, bg);
52509885543Smrg	WRITE_DPR(pSmi, 0x34, patx);
52609885543Smrg	WRITE_DPR(pSmi, 0x38, paty);
52709885543Smrg    }
52809885543Smrg
5297104f784Smrg    LEAVE();
53009885543Smrg}
53109885543Smrg
53209885543Smrgstatic void
53309885543SmrgSMI_SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
53409885543Smrg				     int x, int y, int w, int h)
53509885543Smrg{
53609885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
53709885543Smrg
5387104f784Smrg    ENTER();
5397104f784Smrg    DEBUG("x=%d y=%d w=%d h=%d\n", x, y, w, h);
54009885543Smrg
54109885543Smrg    if (pScrn->bitsPerPixel == 24) {
54209885543Smrg	x *= 3;
54309885543Smrg	w *= 3;
54409885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
54509885543Smrg	    y *= 3;
54609885543Smrg	}
54709885543Smrg    }
54809885543Smrg
5497104f784Smrg    WaitQueue();
55009885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
55109885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
55209885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
55309885543Smrg
5547104f784Smrg    LEAVE();
55509885543Smrg}
55609885543Smrg
55709885543Smrg/******************************************************************************/
55809885543Smrg/* 8x8 Color Pattern Fills						      */
55909885543Smrg/******************************************************************************/
56009885543Smrg
56109885543Smrgstatic void
56209885543SmrgSMI_SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, int rop,
56309885543Smrg				unsigned int planemask, int trans_color)
56409885543Smrg{
56509885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
56609885543Smrg
5677104f784Smrg    ENTER();
5687104f784Smrg    DEBUG("patx=%d paty=%d rop=%02X trans_color=%08X\n",
5697104f784Smrg	  patx, paty, rop, trans_color);
57009885543Smrg
57109885543Smrg    pSmi->AccelCmd = XAAGetPatternROP(rop)
57209885543Smrg		   | SMI_BITBLT
57309885543Smrg		   | SMI_COLOR_PATTERN
57409885543Smrg		   | SMI_START_ENGINE;
57509885543Smrg
5767104f784Smrg#if __BYTE_ORDER == __BIG_ENDIAN
5777104f784Smrg    if (pScrn->depth >= 24)
5787104f784Smrg	trans_color = lswapl(trans_color);
5797104f784Smrg#endif
58009885543Smrg    if (pScrn->bitsPerPixel <= 16) {
58109885543Smrg	/* PDR#950 */
5827104f784Smrg	CARD8* pattern = pSmi->FBBase +
5837104f784Smrg	    (patx + paty * pScrn->displayWidth) * pSmi->Bpp;
58409885543Smrg
5857104f784Smrg	WaitIdle();
58609885543Smrg	WRITE_DPR(pSmi, 0x0C, SMI_BITBLT | SMI_COLOR_PATTERN);
58709885543Smrg	memcpy(pSmi->DataPortBase, pattern, 8 * pSmi->Bpp * 8);
58809885543Smrg    } else {
58909885543Smrg	if (pScrn->bitsPerPixel == 24) {
59009885543Smrg	    patx *= 3;
59109885543Smrg
59209885543Smrg	    if (pSmi->Chipset == SMI_LYNX) {
59309885543Smrg		paty *= 3;
59409885543Smrg	    }
59509885543Smrg	}
59609885543Smrg
5977104f784Smrg	WaitQueue();
59809885543Smrg	WRITE_DPR(pSmi, 0x00, (patx << 16) | (paty & 0xFFFF));
59909885543Smrg    }
60009885543Smrg
6017104f784Smrg    WaitQueue();
6027104f784Smrg
60309885543Smrg    if (trans_color == -1) {
60409885543Smrg	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
60509885543Smrg
6067104f784Smrg	WaitQueue();
60709885543Smrg	WRITE_DPR(pSmi, 0x20, trans_color);
60809885543Smrg    }
60909885543Smrg
61009885543Smrg    if (pSmi->ClipTurnedOn) {
6117104f784Smrg	WaitQueue();
61209885543Smrg	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
61309885543Smrg	pSmi->ClipTurnedOn = FALSE;
61409885543Smrg    }
61509885543Smrg
6167104f784Smrg    LEAVE();
61709885543Smrg}
61809885543Smrg
61909885543Smrgstatic void
62009885543SmrgSMI_SubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
62109885543Smrg				      int x, int y, int w, int h)
62209885543Smrg{
62309885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
62409885543Smrg
6257104f784Smrg    ENTER();
6267104f784Smrg    DEBUG("x=%d y=%d w=%d h=%d\n", x, y, w, h);
62709885543Smrg
62809885543Smrg    if (pScrn->bitsPerPixel == 24) {
62909885543Smrg	x *= 3;
63009885543Smrg	w *= 3;
63109885543Smrg
63209885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
63309885543Smrg	    y *= 3;
63409885543Smrg	}
63509885543Smrg    }
63609885543Smrg
6377104f784Smrg    WaitQueue();
63809885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
63909885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));	/* PDR#950 */
64009885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
64109885543Smrg
6427104f784Smrg    LEAVE();
64309885543Smrg}
64409885543Smrg
64509885543Smrg#if SMI_USE_IMAGE_WRITES
64609885543Smrg/******************************************************************************/
64709885543Smrg/*  Image Writes							      */
64809885543Smrg/******************************************************************************/
64909885543Smrg
65009885543Smrgstatic void
65109885543SmrgSMI_SetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned int planemask,
65209885543Smrg		       int trans_color, int bpp, int depth)
65309885543Smrg{
65409885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
65509885543Smrg
6567104f784Smrg    ENTER();
6577104f784Smrg    DEBUG("rop=%02X trans_color=%08X bpp=%d depth=%d\n",
6587104f784Smrg	  rop, trans_color, bpp, depth);
65909885543Smrg
6607104f784Smrg#if __BYTE_ORDER == __BIG_ENDIAN
6617104f784Smrg    if (pScrn->depth >= 24)
6627104f784Smrg	trans_color = lswapl(trans_color);
6637104f784Smrg#endif
66409885543Smrg    pSmi->AccelCmd = XAAGetCopyROP(rop)
66509885543Smrg		   | SMI_HOSTBLT_WRITE
66609885543Smrg		   | SMI_START_ENGINE;
66709885543Smrg
66809885543Smrg    if (trans_color != -1) {
6697104f784Smrg#if __BYTE_ORDER == __BIG_ENDIAN
6707104f784Smrg	if (trans_color == 0xFFFFFF7F)
6717104f784Smrg	    trans_color = -1;
6727104f784Smrg#endif
67309885543Smrg	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
67409885543Smrg
6757104f784Smrg	WaitQueue();
67609885543Smrg	WRITE_DPR(pSmi, 0x20, trans_color);
67709885543Smrg    }
67809885543Smrg
6797104f784Smrg    LEAVE();
68009885543Smrg}
68109885543Smrg
68209885543Smrgstatic void
68309885543SmrgSMI_SubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
68409885543Smrg			     int skipleft)
68509885543Smrg{
68609885543Smrg    SMIPtr pSmi = SMIPTR(pScrn);
68709885543Smrg
6887104f784Smrg    ENTER();
6897104f784Smrg    DEBUG("x=%d y=%d w=%d h=%d skipleft=%d\n", x, y, w, h, skipleft);
69009885543Smrg
69109885543Smrg    if (pScrn->bitsPerPixel == 24) {
69209885543Smrg	x        *= 3;
69309885543Smrg	w        *= 3;
69409885543Smrg	skipleft *= 3;
69509885543Smrg
69609885543Smrg	if (pSmi->Chipset == SMI_LYNX) {
69709885543Smrg	    y *= 3;
69809885543Smrg	}
69909885543Smrg    }
70009885543Smrg
70109885543Smrg    if (skipleft) {
7027104f784Smrg	WaitQueue();
70309885543Smrg	WRITE_DPR(pSmi, 0x2C, (pSmi->ScissorsLeft & 0xFFFF0000) |
70409885543Smrg			      (x + skipleft) | 0x2000);
70509885543Smrg	pSmi->ClipTurnedOn = TRUE;
70609885543Smrg    } else {
70709885543Smrg	if (pSmi->ClipTurnedOn) {
7087104f784Smrg	    WaitQueue();
70909885543Smrg	    WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
71009885543Smrg	    pSmi->ClipTurnedOn = FALSE;
71109885543Smrg	} else {
7127104f784Smrg	    WaitQueue();
71309885543Smrg	}
71409885543Smrg    }
71509885543Smrg    WRITE_DPR(pSmi, 0x00, 0);
71609885543Smrg    WRITE_DPR(pSmi, 0x04, (x << 16) | (y * 0xFFFF));
71709885543Smrg    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
71809885543Smrg    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
71909885543Smrg
7207104f784Smrg    LEAVE();
72109885543Smrg}
72209885543Smrg#endif
723