smi_xaa.c revision f395c03e
1/*
2Copyright (C) 1994-1999 The XFree86 Project, Inc.  All Rights Reserved.
3Copyright (C) 2000 Silicon Motion, Inc.  All Rights Reserved.
4
5Permission is hereby granted, free of charge, to any person obtaining a copy of
6this software and associated documentation files (the "Software"), to deal in
7the Software without restriction, including without limitation the rights to
8use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9of the Software, and to permit persons to whom the Software is furnished to do
10so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in all
13copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
17NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the names of the XFree86 Project and
23Silicon Motion shall not be used in advertising or otherwise to promote the
24sale, use or other dealings in this Software without prior written
25authorization from the XFree86 Project and silicon Motion.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "smi.h"
33#include "smi_501.h"
34
35#ifdef HAVE_XAA_H
36
37#include "miline.h"
38#include "xaalocal.h"
39#include "xaarop.h"
40#include "servermd.h"
41
42static void SMI_SetupForScreenToScreenCopy(ScrnInfoPtr, int, int, int,
43					   unsigned int, int);
44static void SMI_SubsequentScreenToScreenCopy(ScrnInfoPtr, int, int, int, int,
45					     int, int);
46static void SMI_SetupForSolidFill(ScrnInfoPtr, int, int, unsigned);
47static void SMI_SubsequentSolidFillRect(ScrnInfoPtr, int, int, int, int);
48static void SMI_SubsequentSolidHorVertLine(ScrnInfoPtr, int, int, int, int);
49static void SMI_SetupForCPUToScreenColorExpandFill(ScrnInfoPtr, int, int, int,
50						   unsigned int);
51static void SMI_SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr, int, int, int,
52						     int, int);
53static void SMI_SetupForMono8x8PatternFill(ScrnInfoPtr, int, int, int, int, int,
54					   unsigned int);
55static void SMI_SubsequentMono8x8PatternFillRect(ScrnInfoPtr, int, int, int,
56						 int, int, int);
57static void SMI_SetupForColor8x8PatternFill(ScrnInfoPtr, int, int, int,
58					    unsigned int, int);
59static void SMI_SubsequentColor8x8PatternFillRect(ScrnInfoPtr, int, int, int,
60						  int, int, int);
61#if SMI_USE_IMAGE_WRITES
62static void SMI_SetupForImageWrite(ScrnInfoPtr, int, unsigned int, int, int,
63				   int);
64static void SMI_SubsequentImageWriteRect(ScrnInfoPtr, int, int, int, int, int);
65#endif
66
67#endif
68Bool
69SMI_XAAInit(ScreenPtr pScreen)
70{
71#ifdef HAVE_XAA_H
72    XAAInfoRecPtr infoPtr;
73    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
74    SMIPtr pSmi = SMIPTR(pScrn);
75    /*BoxRec AvailFBArea;*/
76    Bool ret;
77    /*int numLines, maxLines;*/
78
79    ENTER();
80
81    pSmi->XAAInfoRec = infoPtr = XAACreateInfoRec();
82    if (infoPtr == NULL)
83	LEAVE(FALSE);
84
85    infoPtr->Flags = PIXMAP_CACHE
86		   | LINEAR_FRAMEBUFFER
87		   | OFFSCREEN_PIXMAPS;
88
89    infoPtr->Sync = SMI_AccelSync;
90
91    if (xf86IsEntityShared(pScrn->entityList[0]))
92	infoPtr->RestoreAccelState = SMI_EngineReset;
93
94    /* Screen to screen copies */
95    infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK
96				     | ONLY_TWO_BITBLT_DIRECTIONS;
97    infoPtr->SetupForScreenToScreenCopy = SMI_SetupForScreenToScreenCopy;
98    infoPtr->SubsequentScreenToScreenCopy = SMI_SubsequentScreenToScreenCopy;
99    if (pScrn->bitsPerPixel == 24) {
100	infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY;
101    }
102    if ((pSmi->Chipset == SMI_LYNX3D) && (pScrn->bitsPerPixel == 8)) {
103	infoPtr->ScreenToScreenCopyFlags |= GXCOPY_ONLY;
104    }
105
106    /* Solid Fills */
107    infoPtr->SolidFillFlags = NO_PLANEMASK;
108    infoPtr->SetupForSolidFill = SMI_SetupForSolidFill;
109    infoPtr->SubsequentSolidFillRect = SMI_SubsequentSolidFillRect;
110
111    /* Solid Lines */
112    infoPtr->SolidLineFlags = NO_PLANEMASK;
113    infoPtr->SetupForSolidLine = SMI_SetupForSolidFill;
114    infoPtr->SubsequentSolidHorVertLine = SMI_SubsequentSolidHorVertLine;
115
116    /* Color Expansion Fills */
117    infoPtr->CPUToScreenColorExpandFillFlags = ROP_NEEDS_SOURCE
118					     | NO_PLANEMASK
119					     | BIT_ORDER_IN_BYTE_MSBFIRST
120					     | LEFT_EDGE_CLIPPING
121					     | CPU_TRANSFER_PAD_DWORD
122					     | SCANLINE_PAD_DWORD;
123    infoPtr->ColorExpandBase = pSmi->DataPortBase;
124    infoPtr->ColorExpandRange = pSmi->DataPortSize;
125    infoPtr->SetupForCPUToScreenColorExpandFill =
126	    SMI_SetupForCPUToScreenColorExpandFill;
127    infoPtr->SubsequentCPUToScreenColorExpandFill =
128	    SMI_SubsequentCPUToScreenColorExpandFill;
129
130    /* 8x8 Mono Pattern Fills */
131    infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK
132				     | HARDWARE_PATTERN_PROGRAMMED_BITS
133				     | HARDWARE_PATTERN_SCREEN_ORIGIN
134				     | BIT_ORDER_IN_BYTE_MSBFIRST;
135    infoPtr->SetupForMono8x8PatternFill = SMI_SetupForMono8x8PatternFill;
136    infoPtr->SubsequentMono8x8PatternFillRect =
137	SMI_SubsequentMono8x8PatternFillRect;
138
139    /* 8x8 Color Pattern Fills */
140    if (!SMI_LYNX3D_SERIES(pSmi->Chipset) || (pScrn->bitsPerPixel != 24)) {
141	infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK
142					  | HARDWARE_PATTERN_SCREEN_ORIGIN;
143	infoPtr->SetupForColor8x8PatternFill =
144		SMI_SetupForColor8x8PatternFill;
145	infoPtr->SubsequentColor8x8PatternFillRect =
146		SMI_SubsequentColor8x8PatternFillRect;
147    }
148
149#if SMI_USE_IMAGE_WRITES
150    /* Image Writes */
151    infoPtr->ImageWriteFlags = ROP_NEEDS_SOURCE
152			     | NO_PLANEMASK
153			     | CPU_TRANSFER_PAD_DWORD
154			     | SCANLINE_PAD_DWORD;
155    infoPtr->ImageWriteBase = pSmi->DataPortBase;
156    infoPtr->ImageWriteRange = pSmi->DataPortSize;
157    infoPtr->SetupForImageWrite = SMI_SetupForImageWrite;
158    infoPtr->SubsequentImageWriteRect = SMI_SubsequentImageWriteRect;
159#endif
160
161    /* Clipping */
162    infoPtr->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY
163			   | HARDWARE_CLIP_MONO_8x8_FILL
164			   | HARDWARE_CLIP_COLOR_8x8_FILL
165			   | HARDWARE_CLIP_SOLID_FILL
166			   | HARDWARE_CLIP_SOLID_LINE
167			   | HARDWARE_CLIP_DASHED_LINE;
168    infoPtr->SetClippingRectangle = SMI_SetClippingRectangle;
169    infoPtr->DisableClipping = SMI_DisableClipping;
170
171    /* Pixmap Cache */
172    if (pScrn->bitsPerPixel == 24) {
173	infoPtr->CachePixelGranularity = 16;
174    } else {
175	infoPtr->CachePixelGranularity = 128 / pScrn->bitsPerPixel;
176    }
177
178    /* Offscreen Pixmaps */
179    infoPtr->maxOffPixWidth  = 4096;
180    infoPtr->maxOffPixHeight = 4096;
181    if (pScrn->bitsPerPixel == 24) {
182	infoPtr->maxOffPixWidth = 4096 / 3;
183
184	if (pSmi->Chipset == SMI_LYNX) {
185	    infoPtr->maxOffPixHeight = 4096 / 3;
186	}
187    }
188
189    SMI_EngineReset(pScrn);
190
191    ret = XAAInit(pScreen, infoPtr);
192
193    LEAVE(ret);
194#else
195    return FALSE;
196#endif
197}
198
199
200#ifdef HAVE_XAA_H
201/******************************************************************************/
202/*	Screen to Screen Copies						      */
203/******************************************************************************/
204
205static void
206SMI_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
207			       unsigned int planemask, int trans)
208{
209    SMIPtr pSmi = SMIPTR(pScrn);
210
211    ENTER();
212    DEBUG("xdir=%d ydir=%d rop=%02X trans=%08X\n", xdir, ydir, rop, trans);
213
214#if X_BYTE_ORDER == X_BIG_ENDIAN
215    if (pScrn->depth >= 24)
216	trans = lswapl(trans);
217#endif
218    pSmi->AccelCmd = XAAGetCopyROP(rop)
219		   | SMI_BITBLT
220		   | SMI_START_ENGINE;
221
222    if ((xdir == -1) || (ydir == -1)) {
223	pSmi->AccelCmd |= SMI_RIGHT_TO_LEFT;
224    }
225
226    if (trans != -1) {
227	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
228	WaitQueue();
229	WRITE_DPR(pSmi, 0x20, trans);
230    }
231
232    if (pSmi->ClipTurnedOn) {
233	WaitQueue();
234	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
235	pSmi->ClipTurnedOn = FALSE;
236    }
237
238    LEAVE();
239}
240
241static void
242SMI_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
243				 int y2, int w, int h)
244{
245    SMIPtr pSmi = SMIPTR(pScrn);
246
247    ENTER();
248    DEBUG("x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n", x1, y1, x2, y2, w, h);
249
250    if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) {
251	x1 += w - 1;
252	y1 += h - 1;
253	x2 += w - 1;
254	y2 += h - 1;
255    }
256
257    if (pScrn->bitsPerPixel == 24) {
258	x1 *= 3;
259	x2 *= 3;
260	w  *= 3;
261
262	if (pSmi->Chipset == SMI_LYNX) {
263	    y1 *= 3;
264	    y2 *= 3;
265	}
266
267	if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) {
268	    x1 += 2;
269	    x2 += 2;
270	}
271    }
272
273    WaitIdle();
274    WRITE_DPR(pSmi, 0x00, (x1 << 16) + (y1 & 0xFFFF));
275    WRITE_DPR(pSmi, 0x04, (x2 << 16) + (y2 & 0xFFFF));
276    WRITE_DPR(pSmi, 0x08, (w  << 16) + (h  & 0xFFFF));
277    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
278
279    LEAVE();
280}
281
282/******************************************************************************/
283/*   Solid Fills							      */
284/******************************************************************************/
285
286static void
287SMI_SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
288		      unsigned int planemask)
289{
290    SMIPtr pSmi = SMIPTR(pScrn);
291
292    ENTER();
293    DEBUG("color=%08X rop=%02X\n", color, rop);
294
295    pSmi->AccelCmd = XAAGetPatternROP(rop)
296		   | SMI_BITBLT
297		   | SMI_START_ENGINE;
298
299#if X_BYTE_ORDER == X_BIG_ENDIAN
300    if (pScrn->depth >= 24) {
301	/* because of the BGR values are in the MSB bytes,
302	 * 'white' is not possible and -1 has a different meaning.
303	 * As a work around (assuming white is more used as
304	 * light yellow (#FFFF7F), we handle this as beining white.
305	 * Thanks to the SM501 not being able to work in MSB on PCI
306	 * on the PowerPC */
307	if (color == 0x7FFFFFFF)
308	    color = -1;
309	color = lswapl(color);
310    }
311#endif
312    if (pSmi->ClipTurnedOn) {
313	WaitQueue();
314	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
315	pSmi->ClipTurnedOn = FALSE;
316    } else {
317	WaitQueue();
318    }
319    WRITE_DPR(pSmi, 0x14, color);
320    WRITE_DPR(pSmi, 0x34, 0xFFFFFFFF);
321    WRITE_DPR(pSmi, 0x38, 0xFFFFFFFF);
322
323    LEAVE();
324}
325
326void
327SMI_SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
328{
329    SMIPtr pSmi = SMIPTR(pScrn);
330
331    ENTER();
332    DEBUG("x=%d y=%d w=%d h=%d\n", x, y, w, h);
333
334    if (pScrn->bitsPerPixel == 24) {
335	x *= 3;
336	w *= 3;
337
338	if (pSmi->Chipset == SMI_LYNX) {
339	    y *= 3;
340	}
341    }
342
343    if (IS_MSOC(pSmi)) {
344	/* Clip to prevent negative screen coordinates */
345	if (x < 0)
346	    x = 0;
347	if (y < 0)
348	    y = 0;
349    }
350
351    WaitQueue();
352    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
353    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
354    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
355
356    LEAVE();
357}
358
359/******************************************************************************/
360/*   Solid Lines							      */
361/******************************************************************************/
362
363static void
364SMI_SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len,
365							   int dir)
366{
367    SMIPtr pSmi = SMIPTR(pScrn);
368    int w, h;
369
370    ENTER();
371    DEBUG("x=%d y=%d len=%d dir=%d\n", x, y, len, dir);
372
373    if (dir == DEGREES_0) {
374	w = len;
375	h = 1;
376    } else {
377	w = 1;
378	h = len;
379    }
380
381    if (pScrn->bitsPerPixel == 24) {
382	x *= 3;
383	w *= 3;
384
385	if (pSmi->Chipset == SMI_LYNX) {
386	    y *= 3;
387	}
388    }
389
390    WaitQueue();
391    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
392    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
393    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
394
395    LEAVE();
396}
397
398/******************************************************************************/
399/*  Color Expansion Fills						      */
400/******************************************************************************/
401
402static void
403SMI_SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg,
404				       int rop, unsigned int planemask)
405{
406    SMIPtr pSmi = SMIPTR(pScrn);
407
408    ENTER();
409    DEBUG("fg=%08X bg=%08X rop=%02X\n", fg, bg, rop);
410
411#if X_BYTE_ORDER == X_BIG_ENDIAN
412    if (pScrn->depth >= 24) {
413	/* see remark elswere */
414	if (fg == 0x7FFFFFFF)
415	    fg = -1;
416	fg = lswapl(fg);
417	bg = lswapl(bg);
418    }
419#endif
420
421    pSmi->AccelCmd = XAAGetCopyROP(rop)
422		   | SMI_HOSTBLT_WRITE
423		   | SMI_SRC_MONOCHROME
424		   | SMI_START_ENGINE;
425
426    if (bg == -1) {
427	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC;
428
429	WaitQueue();
430	WRITE_DPR(pSmi, 0x14, fg);
431	WRITE_DPR(pSmi, 0x18, ~fg);
432	WRITE_DPR(pSmi, 0x20, fg);
433    } else {
434#if X_BYTE_ORDER == X_BIG_ENDIAN
435	if (bg == 0xFFFFFF7F)
436	    bg = -1;
437#endif
438	WaitQueue();
439	WRITE_DPR(pSmi, 0x14, fg);
440	WRITE_DPR(pSmi, 0x18, bg);
441    }
442
443    LEAVE();
444}
445
446void
447SMI_SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y, int w,
448					 int h, int skipleft)
449{
450    SMIPtr pSmi = SMIPTR(pScrn);
451
452    ENTER();
453    DEBUG("x=%d y=%d w=%d h=%d skipleft=%d\n", x, y, w, h, skipleft);
454
455    if (pScrn->bitsPerPixel == 24) {
456	x        *= 3;
457	w        *= 3;
458	skipleft *= 3;
459
460	if (pSmi->Chipset == SMI_LYNX) {
461	    y *= 3;
462	}
463    }
464
465    if (skipleft) {
466	WaitQueue();
467	WRITE_DPR(pSmi, 0x2C, (pSmi->ScissorsLeft & 0xFFFF0000)
468			      | (x + skipleft) | 0x2000);
469	pSmi->ClipTurnedOn = TRUE;
470    } else {
471	if (pSmi->ClipTurnedOn) {
472	    WaitQueue();
473	    WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
474	    pSmi->ClipTurnedOn = FALSE;
475	} else {
476	    WaitQueue();
477	}
478    }
479    WRITE_DPR(pSmi, 0x00, 0);
480    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
481    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
482    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
483
484    LEAVE();
485}
486
487/******************************************************************************/
488/* 8x8 Mono Pattern Fills						      */
489/******************************************************************************/
490
491static void
492SMI_SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, int fg,
493			       int bg, int rop, unsigned int planemask)
494{
495    SMIPtr pSmi = SMIPTR(pScrn);
496
497    ENTER();
498    DEBUG("patx=%08X paty=%08X fg=%08X bg=%08X rop=%02X\n",
499	  patx, paty, fg, bg, rop);
500
501#if X_BYTE_ORDER == X_BIG_ENDIAN
502    if (pScrn->depth >= 24) {
503	if (fg == 0x7FFFFFFF)
504	    fg = -1;
505	fg = lswapl(fg);
506	bg = lswapl(bg);
507    }
508#endif
509    pSmi->AccelCmd = XAAGetPatternROP(rop)
510		   | SMI_BITBLT
511		   | SMI_START_ENGINE;
512
513    if (pSmi->ClipTurnedOn) {
514	WaitQueue();
515	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
516	pSmi->ClipTurnedOn = FALSE;
517    }
518
519    if (bg == -1) {
520	WaitQueue();
521	WRITE_DPR(pSmi, 0x14, fg);
522	WRITE_DPR(pSmi, 0x18, ~fg);
523	WRITE_DPR(pSmi, 0x20, fg);
524	WRITE_DPR(pSmi, 0x34, patx);
525	WRITE_DPR(pSmi, 0x38, paty);
526    } else {
527#if X_BYTE_ORDER == X_BIG_ENDIAN
528	if (bg == 0xFFFFFF7F)
529	    bg = -1;
530#endif
531	WaitQueue();
532	WRITE_DPR(pSmi, 0x14, fg);
533	WRITE_DPR(pSmi, 0x18, bg);
534	WRITE_DPR(pSmi, 0x34, patx);
535	WRITE_DPR(pSmi, 0x38, paty);
536    }
537
538    LEAVE();
539}
540
541static void
542SMI_SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
543				     int x, int y, int w, int h)
544{
545    SMIPtr pSmi = SMIPTR(pScrn);
546
547    ENTER();
548    DEBUG("x=%d y=%d w=%d h=%d\n", x, y, w, h);
549
550    if (pScrn->bitsPerPixel == 24) {
551	x *= 3;
552	w *= 3;
553	if (pSmi->Chipset == SMI_LYNX) {
554	    y *= 3;
555	}
556    }
557
558    WaitQueue();
559    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
560    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
561    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
562
563    LEAVE();
564}
565
566/******************************************************************************/
567/* 8x8 Color Pattern Fills						      */
568/******************************************************************************/
569
570static void
571SMI_SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, int rop,
572				unsigned int planemask, int trans_color)
573{
574    SMIPtr pSmi = SMIPTR(pScrn);
575
576    ENTER();
577    DEBUG("patx=%d paty=%d rop=%02X trans_color=%08X\n",
578	  patx, paty, rop, trans_color);
579
580    pSmi->AccelCmd = XAAGetPatternROP(rop)
581		   | SMI_BITBLT
582		   | SMI_COLOR_PATTERN
583		   | SMI_START_ENGINE;
584
585#if X_BYTE_ORDER == X_BIG_ENDIAN
586    if (pScrn->depth >= 24)
587	trans_color = lswapl(trans_color);
588#endif
589    if (pScrn->bitsPerPixel <= 16) {
590	/* PDR#950 */
591	CARD8* pattern = pSmi->FBBase +
592	    (patx + paty * pScrn->displayWidth) * pSmi->Bpp;
593
594	WaitIdle();
595	WRITE_DPR(pSmi, 0x0C, SMI_BITBLT | SMI_COLOR_PATTERN);
596	memcpy(pSmi->DataPortBase, pattern, 8 * pSmi->Bpp * 8);
597    } else {
598	if (pScrn->bitsPerPixel == 24) {
599	    patx *= 3;
600
601	    if (pSmi->Chipset == SMI_LYNX) {
602		paty *= 3;
603	    }
604	}
605
606	WaitQueue();
607	WRITE_DPR(pSmi, 0x00, (patx << 16) | (paty & 0xFFFF));
608    }
609
610    WaitQueue();
611
612    if (trans_color == -1) {
613	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
614
615	WaitQueue();
616	WRITE_DPR(pSmi, 0x20, trans_color);
617    }
618
619    if (pSmi->ClipTurnedOn) {
620	WaitQueue();
621	WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
622	pSmi->ClipTurnedOn = FALSE;
623    }
624
625    LEAVE();
626}
627
628static void
629SMI_SubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
630				      int x, int y, int w, int h)
631{
632    SMIPtr pSmi = SMIPTR(pScrn);
633
634    ENTER();
635    DEBUG("x=%d y=%d w=%d h=%d\n", x, y, w, h);
636
637    if (pScrn->bitsPerPixel == 24) {
638	x *= 3;
639	w *= 3;
640
641	if (pSmi->Chipset == SMI_LYNX) {
642	    y *= 3;
643	}
644    }
645
646    WaitQueue();
647    WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF));
648    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));	/* PDR#950 */
649    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
650
651    LEAVE();
652}
653
654#if SMI_USE_IMAGE_WRITES
655/******************************************************************************/
656/*  Image Writes							      */
657/******************************************************************************/
658
659static void
660SMI_SetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned int planemask,
661		       int trans_color, int bpp, int depth)
662{
663    SMIPtr pSmi = SMIPTR(pScrn);
664
665    ENTER();
666    DEBUG("rop=%02X trans_color=%08X bpp=%d depth=%d\n",
667	  rop, trans_color, bpp, depth);
668
669#if X_BYTE_ORDER == X_BIG_ENDIAN
670    if (pScrn->depth >= 24)
671	trans_color = lswapl(trans_color);
672#endif
673    pSmi->AccelCmd = XAAGetCopyROP(rop)
674		   | SMI_HOSTBLT_WRITE
675		   | SMI_START_ENGINE;
676
677    if (trans_color != -1) {
678#if X_BYTE_ORDER == X_BIG_ENDIAN
679	if (trans_color == 0xFFFFFF7F)
680	    trans_color = -1;
681#endif
682	pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL;
683
684	WaitQueue();
685	WRITE_DPR(pSmi, 0x20, trans_color);
686    }
687
688    LEAVE();
689}
690
691static void
692SMI_SubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
693			     int skipleft)
694{
695    SMIPtr pSmi = SMIPTR(pScrn);
696
697    ENTER();
698    DEBUG("x=%d y=%d w=%d h=%d skipleft=%d\n", x, y, w, h, skipleft);
699
700    if (pScrn->bitsPerPixel == 24) {
701	x        *= 3;
702	w        *= 3;
703	skipleft *= 3;
704
705	if (pSmi->Chipset == SMI_LYNX) {
706	    y *= 3;
707	}
708    }
709
710    if (skipleft) {
711	WaitQueue();
712	WRITE_DPR(pSmi, 0x2C, (pSmi->ScissorsLeft & 0xFFFF0000) |
713			      (x + skipleft) | 0x2000);
714	pSmi->ClipTurnedOn = TRUE;
715    } else {
716	if (pSmi->ClipTurnedOn) {
717	    WaitQueue();
718	    WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
719	    pSmi->ClipTurnedOn = FALSE;
720	} else {
721	    WaitQueue();
722	}
723    }
724    WRITE_DPR(pSmi, 0x00, 0);
725    WRITE_DPR(pSmi, 0x04, (x << 16) | (y * 0xFFFF));
726    WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
727    WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd);
728
729    LEAVE();
730}
731#endif
732#endif
733