neo_2200.c revision c3c9db83
1/********************************************************************
2Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas.
3
4                        All Rights Reserved
5
6Permission to use, copy, modify, distribute, and sell this software and
7its documentation for any purpose is hereby granted without fee,
8provided that the above copyright notice appear in all copies and that
9both that copyright notice and this permission notice appear in
10supporting documentation, and that the name of Precision Insight not be
11used in advertising or publicity pertaining to distribution of the
12software without specific, written prior permission.  Precision Insight
13and its suppliers make no representations about the suitability of this
14software for any purpose.  It is provided "as is" without express or
15implied warranty.
16
17PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
20SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
21RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
22CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24**********************************************************************/
25/*
26 * The original Precision Insight driver for
27 * XFree86 v.3.3 has been sponsored by Red Hat.
28 *
29 * Authors:
30 *   Jens Owen (jens@tungstengraphics.com)
31 *   Kevin E. Martin (kevin@precisioninsight.com)
32 *
33 * Port to Xfree86 v.4.0
34 *   1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE)
35 */
36
37#ifdef HAVE_CONFIG_H
38#include "config.h"
39#endif
40
41#include "xf86.h"
42#include "xf86_OSproc.h"
43#include "compiler.h"
44
45/* Drivers that use XAA need this */
46#include "xf86fbman.h"
47
48#include "miline.h"
49
50#include "neo.h"
51#include "neo_reg.h"
52#include "neo_macros.h"
53
54static void Neo2200Sync(ScrnInfoPtr pScrn);
55static void Neo2200SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
56					      int ydir, int rop,
57					      unsigned int planemask,
58					      int trans_color);
59#ifdef NOT_BROKEN
60static void Neo2200SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX,
61						int srcY, int dstX, int dstY,
62						int w, int h);
63#else
64static void Neo2200SubsequentScreenToScreenCopyBroken(ScrnInfoPtr pScrn, int srcX,
65						int srcY, int dstX, int dstY,
66						int w, int h);
67#endif
68static void Neo2200SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
69				  unsigned int planemask);
70static void Neo2200SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
71					   int w, int h);
72static void Neo2200SetupForScanlineCPUToScreenColorExpandFill(
73                                                      ScrnInfoPtr pScrn,
74						      int fg, int bg,
75						      int rop,
76						unsigned int planemask);
77static void Neo2200SubsequentScanlineCPUToScreenColorExpandFill(
78                                                        ScrnInfoPtr pScrn,
79							int x, int y,
80							int w, int h,
81							int skipleft);
82static void Neo2200SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
83#if 0
84static void Neo2200SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
85					       int patternx,
86					       int patterny,
87					       int bg,
88					       int fg,
89					       int rop,
90					       unsigned int planemask);
91static void Neo2200SubsequentMono8x8PatternFill(ScrnInfoPtr pScrn,
92						 int patternx,
93						 int patterny,
94						 int x, int y,
95						 int w, int h);
96#endif
97
98
99static unsigned int neo2200Rop[16] = {
100    0x000000,    /* 0x0000 - GXclear         */
101    0x080000,    /* 0x1000 - GXand           */
102    0x040000,    /* 0x0100 - GXandReverse    */
103    0x0c0000,    /* 0x1100 - GXcopy          */
104    0x020000,    /* 0x0010 - GXandInvert     */
105    0x0a0000,    /* 0x1010 - GXnoop          */
106    0x060000,    /* 0x0110 - GXxor           */
107    0x0e0000,    /* 0x1110 - GXor            */
108    0x010000,    /* 0x0001 - GXnor           */
109    0x090000,    /* 0x1001 - GXequiv         */
110    0x050000,    /* 0x0101 - GXinvert        */
111    0x0d0000,    /* 0x1101 - GXorReverse     */
112    0x030000,    /* 0x0011 - GXcopyInvert    */
113    0x0b0000,    /* 0x1011 - GXorInverted    */
114    0x070000,    /* 0x0111 - GXnand          */
115    0x0f0000     /* 0x1111 - GXset           */
116};
117
118Bool
119Neo2200AccelInit(ScreenPtr pScreen)
120{
121    XAAInfoRecPtr infoPtr;
122    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
123    NEOPtr nPtr = NEOPTR(pScrn);
124    NEOACLPtr nAcl = NEOACLPTR(pScrn);
125
126    nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
127    if(!infoPtr) return FALSE;
128
129    /*
130     * Set up the main acceleration flags.
131     */
132    infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
133    if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE;
134#if 0
135    infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
136#endif
137    /* sync */
138    infoPtr->Sync = Neo2200Sync;
139
140    /* screen to screen copy */
141    infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | NO_PLANEMASK);
142    infoPtr->SetupForScreenToScreenCopy =
143	Neo2200SetupForScreenToScreenCopy;
144    infoPtr->SubsequentScreenToScreenCopy
145#ifdef NOT_BROKEN
146	= Neo2200SubsequentScreenToScreenCopy;
147#else
148	= Neo2200SubsequentScreenToScreenCopyBroken;
149#endif
150
151    /* solid filled rectangles */
152    infoPtr->SolidFillFlags = NO_PLANEMASK;
153    infoPtr->SetupForSolidFill =
154	Neo2200SetupForSolidFillRect;
155    infoPtr->SubsequentSolidFillRect =
156	Neo2200SubsequentSolidFillRect;
157
158    /* cpu to screen color expansion */
159    /*
160     * We do CPUToScreenColorExpand (ab)using the Scanline functions:
161     * the neo chipsets need byte padding however we can only do dword
162     * padding. Fortunately the graphics engine doesn't choke if we
163     * transfer up to 3 bytes more than it wants.
164     */
165
166    if (!nPtr->strangeLockups) {
167
168	infoPtr->ScanlineCPUToScreenColorExpandFillFlags = ( NO_PLANEMASK |
169#ifdef NEO_DO_CLIPPING
170						LEFT_EDGE_CLIPPING |
171#endif
172						SCANLINE_PAD_DWORD |
173						CPU_TRANSFER_PAD_DWORD |
174						BIT_ORDER_IN_BYTE_MSBFIRST );
175	infoPtr->ScanlineColorExpandBuffers =
176	    (unsigned char **)xnfalloc(sizeof(char*));
177	infoPtr->ScanlineColorExpandBuffers[0] =
178	    (unsigned char *)(nPtr->NeoMMIOBase + 0x100000);
179	infoPtr->NumScanlineColorExpandBuffers = 1;
180	infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
181	    Neo2200SetupForScanlineCPUToScreenColorExpandFill;
182	infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
183	    Neo2200SubsequentScanlineCPUToScreenColorExpandFill;
184	infoPtr->SubsequentColorExpandScanline =
185	    Neo2200SubsequentColorExpandScanline;
186    }
187
188#if 0
189    /* 8x8 pattern fills */
190    infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK
191	| HARDWARE_PATTERN_PROGRAMMED_ORIGIN
192	|BIT_ORDER_IN_BYTE_MSBFIRST;
193
194    infoPtr->SetupForMono8x8PatternFill =
195	Neo2200SetupForMono8x8PatternFill;
196    infoPtr->SubsequentMono8x8PatternFillRect =
197	Neo2200SubsequentMono8x8PatternFill;
198#endif
199
200    /*
201     * Setup some global variables
202     */
203
204    /* Initialize for 8bpp or 15/16bpp support accelerated */
205    switch (pScrn->bitsPerPixel) {
206    case 8:
207	nAcl->BltModeFlags = NEO_MODE1_DEPTH8;
208        nAcl->PixelWidth = 1;
209	break;
210    case 15:
211    case 16:
212	nAcl->BltModeFlags = NEO_MODE1_DEPTH16;
213        nAcl->PixelWidth = 2;
214	break;
215    case 24:
216	if (nPtr->noAccelSet || nPtr->NeoChipset == NM2230
217	    || nPtr->NeoChipset == NM2360
218	    || nPtr->NeoChipset == NM2380) {
219	    nAcl->BltModeFlags = NEO_MODE1_DEPTH24;
220            nAcl->PixelWidth = 3;
221	} else
222	    return FALSE;
223	break;
224    default:
225	return FALSE;
226    }
227    nAcl->Pitch = pScrn->displayWidth * nAcl->PixelWidth;
228
229    /* Initialize for widths */
230    switch (pScrn->displayWidth) {
231    case 320:
232	nAcl->BltModeFlags |= NEO_MODE1_X_320;
233	break;
234    case 640:
235	nAcl->BltModeFlags |= NEO_MODE1_X_640;
236	break;
237    case 800:
238	nAcl->BltModeFlags |= NEO_MODE1_X_800;
239	break;
240    case 1024:
241	nAcl->BltModeFlags |= NEO_MODE1_X_1024;
242	break;
243    case 1152:
244	nAcl->BltModeFlags |= NEO_MODE1_X_1152;
245	break;
246    case 1280:
247	nAcl->BltModeFlags |= NEO_MODE1_X_1280;
248	break;
249    case 1600:
250	nAcl->BltModeFlags |= NEO_MODE1_X_1600;
251	break;
252    default:
253	return FALSE;
254    }
255
256    return(XAAInit(pScreen, infoPtr));
257}
258
259static void
260Neo2200Sync(ScrnInfoPtr pScrn)
261{
262    NEOPtr nPtr = NEOPTR(pScrn);
263
264    WAIT_ENGINE_IDLE();
265}
266
267static void
268Neo2200SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
269				  int rop,
270				  unsigned int planemask,
271				  int trans_color)
272{
273    NEOPtr nPtr = NEOPTR(pScrn);
274    NEOACLPtr nAcl = NEOACLPTR(pScrn);
275
276    nAcl->tmpBltCntlFlags = (NEO_BC3_SKIP_MAPPING | neo2200Rop[rop]);
277    /* set blt control */
278    WAIT_ENGINE_IDLE();
279    /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/
280    OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16);
281    OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags);
282    OUTREG(NEOREG_PITCH, (nAcl->Pitch<<16)
283	   | (nAcl->Pitch & 0xffff));
284}
285
286#ifdef NOT_BROKEN
287static void
288Neo2200SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
289				    int srcX, int srcY,
290				    int dstX, int dstY,
291				    int w, int h)
292{
293    NEOPtr nPtr = NEOPTR(pScrn);
294    NEOACLPtr nAcl = NEOACLPTR(pScrn);
295
296    if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) {
297	/* start with upper left corner */
298	WAIT_ENGINE_IDLE();
299#if 0
300	OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags);
301#endif
302	OUTREG(NEOREG_SRCSTARTOFF,
303            (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth));
304	OUTREG(NEOREG_DSTSTARTOFF,
305            (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth));
306	OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
307    }
308    else {
309	/* start with lower right corner */
310	WAIT_ENGINE_IDLE();
311#if 0
312	OUTREG(NEOREG_BLTCNTL, (nAcl->tmpBltCntlFlags
313				| NEO_BC0_X_DEC
314				| NEO_BC0_DST_Y_DEC
315				| NEO_BC0_SRC_Y_DEC));
316#endif
317	OUTREG(NEOREG_SRCSTARTOFF,
318            ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1)
319						 * nAcl->PixelWidth));
320	OUTREG(NEOREG_DSTSTARTOFF,
321            ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1)
322						 * nAcl->PixelWidth));
323	OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
324    }
325}
326
327#else /* NOT_BROKEN */
328
329static void
330Neo2200SubsequentScreenToScreenCopyBroken(ScrnInfoPtr pScrn,
331					  int srcX, int srcY,
332					  int dstX, int dstY,
333					  int w, int h)
334{
335    NEOPtr nPtr = NEOPTR(pScrn);
336    NEOACLPtr nAcl = NEOACLPTR(pScrn);
337
338    if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) {
339	if ((((dstX < 64) && ((srcX + w + 64) >= pScrn->displayWidth)) ||
340	    ((dstX == 0) && (w > (pScrn->displayWidth - 64)))) && (w > 64)) {
341
342#define COPY_64 \
343	    OUTREG(NEOREG_SRCSTARTOFF,\
344		   (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth));\
345	    OUTREG(NEOREG_DSTSTARTOFF,\
346		   (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth));\
347	    OUTREG(NEOREG_XYEXT, (h<<16) | (64));
348#define COPY_W \
349	    OUTREG(NEOREG_SRCSTARTOFF,\
350		   (srcY * nAcl->Pitch) + (srcX1 * nAcl->PixelWidth));\
351	    OUTREG(NEOREG_DSTSTARTOFF,\
352		   (dstY * nAcl->Pitch) + (dstX1 * nAcl->PixelWidth));\
353	    OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
354
355	    int srcX1 = srcX + 64;
356	    int dstX1 = dstX + 64;
357	    w -= 64;
358	    /* start with upper left corner */
359	    WAIT_ENGINE_IDLE();
360	    OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags);
361	    if (srcX < dstX) {
362		COPY_W;
363	        WAIT_ENGINE_IDLE();
364	        COPY_64;
365	    } else {
366		COPY_64;
367	        WAIT_ENGINE_IDLE();
368		COPY_W;
369	    }
370#undef COPY_W
371#undef COPY_64
372	} else {
373	    /* start with upper left corner */
374	    WAIT_ENGINE_IDLE();
375	    OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags);
376	    OUTREG(NEOREG_SRCSTARTOFF,
377		   (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth));
378	    OUTREG(NEOREG_DSTSTARTOFF,
379		   (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth));
380	    OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
381	}
382    } else {
383	if (((((dstX + w) > (pScrn->displayWidth - 64)) && (srcX == 0))
384	    || (((dstX + w + 64) >= pScrn->displayWidth)
385		&& (w > (pScrn->displayWidth - 64)))) && (w > 64)) {
386#define COPY_64 \
387	    OUTREG(NEOREG_SRCSTARTOFF, \
388		   ((srcY+h-1) * nAcl->Pitch) + ((srcX1+64-1)  \
389						 * nAcl->PixelWidth)); \
390	    OUTREG(NEOREG_DSTSTARTOFF, \
391		   ((dstY+h-1) * nAcl->Pitch) + ((dstX1+64-1) \
392						 * nAcl->PixelWidth)); \
393	    OUTREG(NEOREG_XYEXT, (h<<16) | (64 & 0xffff));
394#define COPY_W \
395	    OUTREG(NEOREG_SRCSTARTOFF, \
396		   ((srcY+h-1) * nAcl->Pitch) + ((srcX + w -1)  \
397						 * nAcl->PixelWidth)); \
398	    OUTREG(NEOREG_DSTSTARTOFF, \
399		   ((dstY+h-1) * nAcl->Pitch) + ((dstX + w -1) \
400						 * nAcl->PixelWidth)); \
401	    OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
402
403	    int srcX1, dstX1;
404
405	    w -= 64;
406	    srcX1 = srcX + w;
407	    dstX1 = dstX + w;
408	    /* start with lower right corner */
409	    WAIT_ENGINE_IDLE();
410	    OUTREG(NEOREG_BLTCNTL, (nAcl->tmpBltCntlFlags
411				    | NEO_BC0_X_DEC
412				    | NEO_BC0_DST_Y_DEC
413				    | NEO_BC0_SRC_Y_DEC));
414	    if (srcX < dstX) {
415	      COPY_64;
416	      WAIT_ENGINE_IDLE();
417	      COPY_W;
418	    } else {
419	      COPY_W;
420	      WAIT_ENGINE_IDLE();
421	      COPY_64;
422	    }
423#undef COPY_W
424#undef COPY_64
425	} else {
426	    /* start with lower right corner */
427	    WAIT_ENGINE_IDLE();
428	    OUTREG(NEOREG_BLTCNTL, (nAcl->tmpBltCntlFlags
429				    | NEO_BC0_X_DEC
430				    | NEO_BC0_DST_Y_DEC
431				    | NEO_BC0_SRC_Y_DEC));
432	    OUTREG(NEOREG_SRCSTARTOFF,
433		   ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1)
434						 * nAcl->PixelWidth));
435	    OUTREG(NEOREG_DSTSTARTOFF,
436		   ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1)
437						 * nAcl->PixelWidth));
438	    OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
439	}
440    }
441}
442
443#endif /* NOT_BROKEN */
444
445static void
446Neo2200SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
447			     unsigned int planemask)
448{
449    NEOPtr nPtr = NEOPTR(pScrn);
450    NEOACLPtr nAcl = NEOACLPTR(pScrn);
451
452    WAIT_ENGINE_IDLE();
453
454    /* set blt control */
455    /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/
456    OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16);
457    OUTREG(NEOREG_BLTCNTL, NEO_BC0_SRC_IS_FG    |
458                           NEO_BC3_SKIP_MAPPING |
459                           NEO_BC3_DST_XY_ADDR  |
460                           NEO_BC3_SRC_XY_ADDR  | neo2200Rop[rop]);
461
462    /* set foreground color */
463    OUTREG(NEOREG_FGCOLOR, color);
464}
465
466
467static void
468Neo2200SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
469{
470    NEOPtr nPtr = NEOPTR(pScrn);
471
472    WAIT_ENGINE_IDLE();
473    OUTREG(NEOREG_DSTSTARTOFF, (y <<16) | (x & 0xffff));
474    OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
475}
476
477static void
478Neo2200SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
479 				      int fg, int bg,
480				      int rop,
481				      unsigned int planemask)
482{
483    NEOPtr nPtr = NEOPTR(pScrn);
484    NEOACLPtr nAcl = NEOACLPTR(pScrn);
485
486    if (bg == -1) {
487	/* transparent setup */
488	nAcl->tmpBltCntlFlags = ( NEO_BC0_SYS_TO_VID   |
489					 NEO_BC0_SRC_MONO     |
490					 NEO_BC0_SRC_TRANS    |
491					 NEO_BC3_SKIP_MAPPING |
492					 NEO_BC3_DST_XY_ADDR  |
493#ifdef NEO_DO_CLIPPING
494				         NEO_BC3_CLIP_ON      |
495#endif
496				         neo2200Rop[rop]);
497
498	WAIT_ENGINE_IDLE();
499	/*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/
500	OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16);
501	OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags);
502	OUTREG(NEOREG_FGCOLOR, fg);
503    }
504    else {
505	/* opaque setup */
506        nAcl->tmpBltCntlFlags = ( NEO_BC0_SYS_TO_VID   |
507					 NEO_BC0_SRC_MONO     |
508					 NEO_BC3_SKIP_MAPPING |
509					 NEO_BC3_DST_XY_ADDR  |
510#ifdef NEO_DO_CLIPPING
511 				         NEO_BC3_CLIP_ON      |
512#endif
513					 neo2200Rop[rop]);
514
515	WAIT_ENGINE_IDLE();
516	/*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/
517	OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16);
518	OUTREG(NEOREG_FGCOLOR, fg);
519	OUTREG(NEOREG_BGCOLOR, bg);
520    }
521}
522
523
524static void
525Neo2200SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
526					int x, int y,
527					int w, int h,
528					int skipleft)
529{
530    NEOPtr nPtr = NEOPTR(pScrn);
531    NEOACLPtr nAcl = NEOACLPTR(pScrn);
532
533#ifdef NEO_DO_CLIPPING
534        w = (w + 31) & ~31;
535#else
536    nAcl->CPUToScreenColorExpandFill_x = x;
537    nAcl->CPUToScreenColorExpandFill_y = y;
538    nAcl->CPUToScreenColorExpandFill_w = w;
539    nAcl->CPUToScreenColorExpandFill_h = h;
540    nAcl->CPUToScreenColorExpandFill_skipleft = skipleft;
541#endif
542    OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags
543	   | ((skipleft << 2) & 0x1C));
544#ifdef NEO_DO_CLIPPING
545    OUTREG(NEOREG_CLIPLT, (y << 16) | (x + skipleft));
546    OUTREG(NEOREG_CLIPRB, ((y + h) << 16) | (x + w));
547#endif
548    OUTREG(NEOREG_SRCSTARTOFF, 0);
549    OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff));
550#ifdef NEO_DO_CLIPPING
551    OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
552#else
553    OUTREG(NEOREG_XYEXT, (1<<16) | (w & 0xffff));
554#endif
555}
556
557static void
558Neo2200SubsequentColorExpandScanline(ScrnInfoPtr pScrn,	int bufno)
559{
560    NEOPtr nPtr = NEOPTR(pScrn);
561    NEOACLPtr nAcl = NEOACLPTR(pScrn);
562
563#ifdef NEO_DO_CLIPPING
564    /* Should I be waiting for fifo slots to prevent retries ?
565       How do I do that on this engine ? */
566#else
567    if (!(--nAcl->CPUToScreenColorExpandFill_h))
568	return;
569
570    WAIT_ENGINE_IDLE();
571    OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags
572	   | ((nAcl->CPUToScreenColorExpandFill_skipleft << 2) & 0x1C));
573    OUTREG(NEOREG_SRCSTARTOFF, 0);
574    OUTREG(NEOREG_DSTSTARTOFF, ((++nAcl->CPUToScreenColorExpandFill_y)<<16)
575	   | (nAcl->CPUToScreenColorExpandFill_x & 0xffff));
576    OUTREG(NEOREG_XYEXT, (1<<16)
577	   | (nAcl->CPUToScreenColorExpandFill_w & 0xffff));
578#endif
579}
580
581#if 0
582static void
583Neo2200SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
584				     int patternx,
585				     int patterny,
586				     int fg, int bg,
587				     int rop, unsigned int planemask)
588{
589    NEOPtr nPtr = NEOPTR(pScrn);
590    NEOACLPtr nAcl = NEOACLPTR(pScrn);
591
592    if (bg == -1) {
593	/* transparent setup */
594	nAcl->tmpBltCntlFlags = ( NEO_BC0_SRC_MONO     |
595					 NEO_BC0_FILL_PAT     |
596					 NEO_BC0_SRC_TRANS    |
597					 NEO_BC3_SKIP_MAPPING |
598					 NEO_BC3_DST_XY_ADDR  |
599					 neo2200Rop[rop]);
600
601	WAIT_ENGINE_IDLE();
602	/*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/
603	OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16);
604	OUTREG(NEOREG_FGCOLOR, fg);
605	OUTREG(NEOREG_SRCSTARTOFF,
606	    (patterny * pScrn->displayWidth * pScrn->bitsPerPixel
607	     + patternx) >> 3);
608    }
609    else {
610	/* opaque setup */
611	nAcl->tmpBltCntlFlags = ( NEO_BC0_SRC_MONO     |
612					 NEO_BC0_FILL_PAT     |
613					 NEO_BC3_SKIP_MAPPING |
614					 NEO_BC3_DST_XY_ADDR  |
615					 neo2200Rop[rop]);
616
617	WAIT_ENGINE_IDLE();
618	/*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/
619	OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16);
620	OUTREG(NEOREG_FGCOLOR, fg);
621	OUTREG(NEOREG_BGCOLOR, bg);
622	OUTREG(NEOREG_SRCSTARTOFF,
623	    (patterny * pScrn->displayWidth * pScrn->bitsPerPixel
624	     + patternx) >> 3);
625    }
626}
627
628
629static void
630Neo2200SubsequentMono8x8PatternFill(ScrnInfoPtr pScrn,
631				    int patternx,
632				    int patterny,
633				    int x, int y,
634				    int w, int h)
635{
636    NEOPtr nPtr = NEOPTR(pScrn);
637    NEOACLPtr nAcl = NEOACLPTR(pScrn);
638
639    patterny &= 0x7;
640
641    WAIT_ENGINE_IDLE();
642    OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags |
643	   (patterny << 20)       |
644	   ((patternx << 10) & 0x1C00));
645    OUTREG(NEOREG_SRCBITOFF, patternx);
646    OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff));
647    OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
648}
649#endif
650