1/*
2 * Copyright 1997-2001 by Alan Hourihane, Wigan, England.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Alan Hourihane not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  Alan Hourihane makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as is" without express or implied warranty.
13 *
14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
23 *           Dirk Hohndel, <hohndel@suse.de>
24 *           Stefan Dirsch, <sndirsch@suse.de>
25 *
26 * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
27 * Siemens Nixdorf Informationssysteme
28 *
29 * GLINT 500TX / MX accelerated options.
30 */
31
32#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif
35
36#include "xf86.h"
37#include "xf86_OSproc.h"
38
39#include "xf86Pci.h"
40
41#include "fb.h"
42
43#include "miline.h"
44
45#include "glint_regs.h"
46#include "glint.h"
47
48#ifdef HAVE_XAA_H
49#include "xaalocal.h"	/* For replacements */
50
51static void TXSync(ScrnInfoPtr pScrn);
52static void DualTXSync(ScrnInfoPtr pScrn);
53static void TXSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop,
54						unsigned int planemask);
55static void TXSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y,
56						int w, int h);
57static void TXSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx,
58						int patterny,
59					   	int fg, int bg, int rop,
60					   	unsigned int planemask);
61static void TXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
62						int patterny, int x, int y,
63				   		int w, int h);
64static void TXSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
65						int rop, unsigned int planemask,
66				    		int transparency_color);
67static void TXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
68						int x2, int y2, int w, int h);
69static void TXWriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
70    				unsigned char *src, int srcwidth,
71				int skipleft, int fg, int bg, int rop,
72    				unsigned int planemask);
73static void TXSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
74						int x2,int y2);
75static void TXDisableClipping(ScrnInfoPtr pScrn);
76static void TXWritePixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
77   				unsigned char *src, int srcwidth, int rop,
78   				unsigned int planemask, int trans,
79   				int bpp, int depth);
80static void TXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg,
81				int bg, int rop, unsigned int planemask);
82static void TXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
83				int y, int w, int h, int skipleft);
84static void TXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
85static void TXLoadCoord(ScrnInfoPtr pScrn, int x, int y, int w, int h,
86				int a, int d);
87static void TXSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
88				unsigned int planemask);
89static void TXSubsequentHorVertLine(ScrnInfoPtr pScrn, int x1, int y1,
90				int len, int dir);
91static void TXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
92        			int x, int y, int dmaj, int dmin, int e,
93				int len, int octant);
94static void TXPolylinesThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
95   				int mode, int npt, DDXPointPtr pPts);
96static void TXPolySegmentThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
97 				int nseg, xSegment *pSeg);
98
99void
100TXInitializeEngine(ScrnInfoPtr pScrn)
101{
102    GLINTPtr pGlint = GLINTPTR(pScrn);
103    /* Initialize the Accelerator Engine to defaults */
104    pGlint->rasterizerMode = UNIT_DISABLE;
105
106    if (pGlint->MultiAperture) {
107    	pGlint->rasterizerMode = RMMultiGLINT;
108
109    	/* Only write the following register to the first chip */
110    	GLINT_SLOW_WRITE_REG(1, BroadcastMask);
111    	GLINT_SLOW_WRITE_REG(0x00000001,    ScanLineOwnership);
112
113    	/* Only write the following register to the second chip */
114    	GLINT_SLOW_WRITE_REG(2, BroadcastMask);
115    	GLINT_SLOW_WRITE_REG(0x00000005,    ScanLineOwnership);
116
117    	/* Make sure the rest of the register writes go to both chip's */
118    	GLINT_SLOW_WRITE_REG(3, BroadcastMask);
119
120    	pGlint->pprod |= FBRM_ScanlineInt2;
121    }
122
123    GLINT_SLOW_WRITE_REG(pGlint->pprod, LBReadMode);
124    GLINT_SLOW_WRITE_REG(pGlint->rasterizerMode, RasterizerMode);
125    GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode);
126    GLINT_SLOW_WRITE_REG(pGlint->pprod,	FBReadMode);
127    GLINT_SLOW_WRITE_REG(0, dXSub);
128    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LBWriteMode);
129    GLINT_SLOW_WRITE_REG(UNIT_ENABLE,	FBWriteMode);
130    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	DitherMode);
131    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	AlphaBlendMode);
132    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	ColorDDAMode);
133    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	TextureColorMode);
134    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	TextureAddressMode);
135    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  TextureReadMode);
136    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  GLINTWindow);
137    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  AlphaBlendMode);
138    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  DepthMode);
139    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  RouterMode);
140    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	FogMode);
141    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	AntialiasMode);
142    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	AlphaTestMode);
143    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	StencilMode);
144    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	AreaStippleMode);
145    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LineStippleMode);
146    GLINT_SLOW_WRITE_REG(0,		UpdateLineStippleCounters);
147    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LogicalOpMode);
148    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	DepthMode);
149    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	StatisticMode);
150    GLINT_SLOW_WRITE_REG(0x400,		FilterMode);
151    GLINT_SLOW_WRITE_REG(0xffffffff,	FBHardwareWriteMask);
152    GLINT_SLOW_WRITE_REG(0xffffffff,	FBSoftwareWriteMask);
153    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	GLINTDepth);
154    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	FBSourceOffset);
155    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	FBPixelOffset);
156    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LBSourceOffset);
157    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	WindowOrigin);
158    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	FBWindowBase);
159    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LBWindowBase);
160    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	TextureAddressMode);
161    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	RouterMode);
162    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	PatternRamMode);
163
164    switch (pScrn->bitsPerPixel) {
165    	case 8:
166	    GLINT_SLOW_WRITE_REG(0x2,	PixelSize);
167	    break;
168	case 16:
169	    GLINT_SLOW_WRITE_REG(0x1,	PixelSize);
170	    break;
171	case 32:
172	    GLINT_SLOW_WRITE_REG(0x0,	PixelSize);
173	    break;
174    }
175    pGlint->ROP = 0xFF;
176    pGlint->ClippingOn = FALSE;
177    pGlint->startxsub = 0;
178    pGlint->startxdom = 0;
179    pGlint->starty = 0;
180    pGlint->count = 0;
181    pGlint->dxdom = 0;
182    pGlint->dy = 1;
183    pGlint->planemask = 0;
184    GLINT_SLOW_WRITE_REG(0, StartXSub);
185    GLINT_SLOW_WRITE_REG(0, StartXDom);
186    GLINT_SLOW_WRITE_REG(0, StartY);
187    GLINT_SLOW_WRITE_REG(0, GLINTCount);
188    GLINT_SLOW_WRITE_REG(0, dXDom);
189    GLINT_SLOW_WRITE_REG(1<<16, dY);
190}
191#endif
192
193Bool
194TXAccelInit(ScreenPtr pScreen)
195{
196#ifdef HAVE_XAA_H
197    XAAInfoRecPtr infoPtr;
198    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
199    GLINTPtr pGlint = GLINTPTR(pScrn);
200    long memory = pGlint->FbMapSize;
201    BoxRec AvailFBArea;
202
203    pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec();
204    if (!infoPtr) return FALSE;
205
206    TXInitializeEngine(pScrn);
207
208    infoPtr->Flags = PIXMAP_CACHE |
209		     LINEAR_FRAMEBUFFER |
210		     OFFSCREEN_PIXMAPS;
211
212    if (pGlint->MultiAperture)
213    	infoPtr->Sync = DualTXSync;
214    else
215    	infoPtr->Sync = TXSync;
216
217    infoPtr->SetClippingRectangle = TXSetClippingRectangle;
218    infoPtr->DisableClipping = TXDisableClipping;
219    infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL |
220			     HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
221			     HARDWARE_CLIP_SOLID_FILL;
222
223    infoPtr->SolidFillFlags = 0;
224    infoPtr->SetupForSolidFill = TXSetupForFillRectSolid;
225    infoPtr->SubsequentSolidFillRect = TXSubsequentFillRectSolid;
226
227    infoPtr->SolidLineFlags = 0;
228    infoPtr->PolySegmentThinSolidFlags = 0;
229    infoPtr->PolylinesThinSolidFlags = 0;
230    infoPtr->SetupForSolidLine = TXSetupForSolidLine;
231    infoPtr->SubsequentSolidHorVertLine = TXSubsequentHorVertLine;
232    if (!(pScrn->overlayFlags & OVERLAY_8_32_PLANAR))
233    {
234        infoPtr->SubsequentSolidBresenhamLine =
235					TXSubsequentSolidBresenhamLine;
236    }
237    infoPtr->PolySegmentThinSolid = TXPolySegmentThinSolidWrapper;
238    infoPtr->PolylinesThinSolid = TXPolylinesThinSolidWrapper;
239
240    if (!pGlint->MultiAperture) {
241    	infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY |
242					       ONLY_LEFT_TO_RIGHT_BITBLT;
243    	infoPtr->SetupForScreenToScreenCopy = TXSetupForScreenToScreenCopy;
244    	infoPtr->SubsequentScreenToScreenCopy = TXSubsequentScreenToScreenCopy;
245    }
246
247    infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
248				       HARDWARE_PATTERN_SCREEN_ORIGIN |
249				       HARDWARE_PATTERN_PROGRAMMED_BITS;
250    infoPtr->SetupForMono8x8PatternFill = TXSetupForMono8x8PatternFill;
251    infoPtr->SubsequentMono8x8PatternFillRect = TXSubsequentMono8x8PatternFillRect;
252
253    infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
254					       TRANSPARENCY_ONLY |
255					       BIT_ORDER_IN_BYTE_LSBFIRST;
256
257    infoPtr->NumScanlineColorExpandBuffers = 1;
258    pGlint->ScratchBuffer                 = malloc(((pScrn->virtualX + 62) / 32 * 4) + (pScrn->virtualX * pScrn->bitsPerPixel / 8));
259    infoPtr->ScanlineColorExpandBuffers =
260					pGlint->XAAScanlineColorExpandBuffers;
261    pGlint->XAAScanlineColorExpandBuffers[0] =
262					pGlint->IOBase + OutputFIFO + 4;
263
264    infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
265				TXSetupForScanlineCPUToScreenColorExpandFill;
266    infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
267				TXSubsequentScanlineCPUToScreenColorExpandFill;
268    infoPtr->SubsequentColorExpandScanline =
269				TXSubsequentColorExpandScanline;
270
271    infoPtr->ColorExpandRange = pGlint->FIFOSize;
272
273    infoPtr->WriteBitmap = TXWriteBitmap;
274    infoPtr->WritePixmap = TXWritePixmap;
275
276    AvailFBArea.x1 = 0;
277    AvailFBArea.y1 = 0;
278    AvailFBArea.x2 = pScrn->displayWidth;
279    if (memory > (16383*1024)) memory = 16383*1024;
280    AvailFBArea.y2 = memory / (pScrn->displayWidth *
281					  pScrn->bitsPerPixel / 8);
282
283    if (AvailFBArea.y2 > 4095) AvailFBArea.y2 = 4095;
284
285    xf86InitFBManager(pScreen, &AvailFBArea);
286
287    return (XAAInit(pScreen, infoPtr));
288#else
289    return FALSE;
290#endif
291}
292
293#ifdef HAVE_XAA_H
294static void TXLoadCoord(
295	ScrnInfoPtr pScrn,
296	int x, int y,
297	int w, int h,
298	int a, int d
299){
300    GLINTPtr pGlint = GLINTPTR(pScrn);
301
302    if (w != pGlint->startxsub) {
303    	GLINT_WRITE_REG(w<<16, StartXSub);
304	pGlint->startxsub = w;
305    }
306    if (x != pGlint->startxdom) {
307    	GLINT_WRITE_REG(x<<16,StartXDom);
308	pGlint->startxdom = x;
309    }
310    if (y != pGlint->starty) {
311    	GLINT_WRITE_REG(y<<16,StartY);
312	pGlint->starty = y;
313    }
314    if (h != pGlint->count) {
315    	GLINT_WRITE_REG(h,GLINTCount);
316	pGlint->count = h;
317    }
318    if (a != pGlint->dxdom) {
319    	GLINT_WRITE_REG(a<<16,dXDom);
320	pGlint->dxdom = a;
321    }
322    if (d != pGlint->dy) {
323    	GLINT_WRITE_REG(d<<16,dY);
324	pGlint->dy = d;
325    }
326}
327
328static void
329TXSync(
330	ScrnInfoPtr pScrn
331){
332    GLINTPtr pGlint = GLINTPTR(pScrn);
333    CARD32 readValue;
334
335    CHECKCLIPPING;
336
337    while (GLINT_READ_REG(DMACount) != 0);
338    GLINT_WAIT(2);
339    GLINT_WRITE_REG(0x400, FilterMode);
340    GLINT_WRITE_REG(0, GlintSync);
341    do {
342   	while(GLINT_READ_REG(OutFIFOWords) == 0);
343	readValue = GLINT_READ_REG(OutputFIFO);
344    } while (readValue != Sync_tag);
345}
346
347static void
348DualTXSync(
349	ScrnInfoPtr pScrn
350){
351    GLINTPtr pGlint = GLINTPTR(pScrn);
352    unsigned long readValue;
353
354    CHECKCLIPPING;
355
356    while (GLINT_READ_REG(DMACount) != 0);
357    GLINT_WAIT(3);
358
359    /* hack! this shouldn't need to be reloaded */
360    GLINT_WRITE_REG(3, BroadcastMask);
361    GLINT_WRITE_REG(0x400, FilterMode);
362    GLINT_WRITE_REG(0, GlintSync);
363
364    /* Read 1st MX until Sync Tag shows */
365    ACCESSCHIP1();
366    do {
367   	while(GLINT_READ_REG(OutFIFOWords) == 0);
368	readValue = GLINT_READ_REG(OutputFIFO);
369    } while (readValue != Sync_tag);
370
371    ACCESSCHIP2();
372    /* Read 2nd MX until Sync Tag shows */
373    do {
374   	while(GLINT_READ_REG(OutFIFOWords) == 0);
375	readValue = GLINT_READ_REG(OutputFIFO);
376    } while (readValue != Sync_tag);
377
378    ACCESSCHIP1();
379}
380
381
382static void
383TXSetupForFillRectSolid(
384	ScrnInfoPtr pScrn,
385	int color, int rop,
386	unsigned int planemask
387){
388    GLINTPtr pGlint = GLINTPTR(pScrn);
389    pGlint->ForeGroundColor = color;
390
391    GLINT_WAIT(5);
392    REPLICATE(color);
393    DO_PLANEMASK(planemask);
394    if (rop == GXcopy) {
395	GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
396	GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
397	GLINT_WRITE_REG(color, FBBlockColor);
398	pGlint->FrameBufferReadMode = FastFillEnable;
399    } else {
400	GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
401	GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
402	GLINT_WRITE_REG(color, PatternRamData0);
403	pGlint->FrameBufferReadMode = FastFillEnable | SpanOperation;
404    }
405    LOADROP(rop);
406}
407
408static void
409TXSubsequentFillRectSolid(
410	ScrnInfoPtr pScrn,
411	int x, int y,
412	int w, int h
413){
414    GLINTPtr pGlint = GLINTPTR(pScrn);
415
416    GLINT_WAIT(7);
417    TXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
418    GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode,Render);
419}
420
421static void
422TXSetClippingRectangle(
423	ScrnInfoPtr pScrn,
424	int x1, int y1,
425	int x2, int y2
426){
427    GLINTPtr pGlint = GLINTPTR(pScrn);
428
429    GLINT_WAIT(3);
430    GLINT_WRITE_REG((y1&0xFFFF)<<16|(x1&0xFFFF), ScissorMinXY);
431    GLINT_WRITE_REG((y2&0xFFFF)<<16|(x2&0xFFFF), ScissorMaxXY);
432    GLINT_WRITE_REG(1, ScissorMode); /* Enable Scissor Mode */
433    pGlint->ClippingOn = TRUE;
434}
435
436static void
437TXDisableClipping(
438	ScrnInfoPtr pScrn
439){
440    GLINTPtr pGlint = GLINTPTR(pScrn);
441    CHECKCLIPPING;
442}
443
444static void
445TXSetupForScreenToScreenCopy(
446	ScrnInfoPtr pScrn,
447	int xdir, int  ydir,
448	int rop,
449	unsigned int planemask,
450	int transparency_color
451){
452    GLINTPtr pGlint = GLINTPTR(pScrn);
453
454    pGlint->BltScanDirection = ydir;
455
456    GLINT_WAIT(5);
457    DO_PLANEMASK(planemask);
458    GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
459
460    if (rop == GXcopy) {
461	GLINT_WRITE_REG(pGlint->pprod | FBRM_SrcEnable, FBReadMode);
462    } else {
463	GLINT_WRITE_REG(pGlint->pprod | FBRM_SrcEnable | FBRM_DstEnable, FBReadMode);
464    }
465    LOADROP(rop);
466}
467
468static void
469TXSubsequentScreenToScreenCopy(
470	ScrnInfoPtr pScrn,
471	int x1, int y1,
472	int x2, int y2,
473	int w, int h
474){
475    GLINTPtr pGlint = GLINTPTR(pScrn);
476    int srcaddr, dstaddr;
477
478    GLINT_WAIT(8);
479    if (pGlint->BltScanDirection != 1) {
480	y1 += h - 1;
481	y2 += h - 1;
482        TXLoadCoord(pScrn, x2, y2, x2+w, h, 0, -1);
483    } else {
484        TXLoadCoord(pScrn, x2, y2, x2+w, h, 0, 1);
485    }
486
487    srcaddr = y1 * pScrn->displayWidth + x1;
488    dstaddr = y2 * pScrn->displayWidth + x2;
489
490    GLINT_WRITE_REG(srcaddr - dstaddr, FBSourceOffset);
491    GLINT_WRITE_REG(PrimitiveTrapezoid| FastFillEnable | SpanOperation, Render);
492}
493
494static void
495TXSetupForScanlineCPUToScreenColorExpandFill(
496	ScrnInfoPtr pScrn,
497	int fg, int bg,
498	int rop,
499	unsigned int planemask
500){
501    GLINTPtr pGlint = GLINTPTR(pScrn);
502    REPLICATE(fg);
503    REPLICATE(bg);
504    GLINT_WAIT(6);
505    DO_PLANEMASK(planemask);
506    GLINT_WRITE_REG(pGlint->rasterizerMode, RasterizerMode);
507    if (rop == GXcopy) {
508        GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
509        GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
510        pGlint->FrameBufferReadMode = FastFillEnable;
511	GLINT_WRITE_REG(fg, FBBlockColor);
512    } else {
513        GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
514        GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
515        pGlint->FrameBufferReadMode = FastFillEnable | SpanOperation;
516	GLINT_WRITE_REG(fg, PatternRamData0);
517    }
518    LOADROP(rop);
519}
520
521static void
522TXSubsequentScanlineCPUToScreenColorExpandFill(
523	ScrnInfoPtr pScrn,
524	int x, int y, int w, int h,
525	int skipleft
526){
527    GLINTPtr pGlint = GLINTPTR(pScrn);
528
529    pGlint->dwords = ((w + 31) >> 5); /* dwords per scanline */
530
531    pGlint->cpucount = h;
532
533    GLINT_WAIT(8);
534    TXLoadCoord(pScrn, x, y, (x+w), h, 0, 1);
535    GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask,
536							Render);
537#if defined(__alpha__)
538    if (0) /* force Alpha to use indirect always */
539#else
540    if ((pGlint->dwords*h) < pGlint->FIFOSize)
541#endif
542    {
543	/* Turn on direct for less than FIFOSize dword colour expansion */
544    	pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->IOBase+OutputFIFO+4;
545	pGlint->ScanlineDirect = 1;
546    	GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | 0x0D, OutputFIFO);
547    	GLINT_WAIT(pGlint->dwords*h);
548    } else {
549	/* Use indirect for anything else */
550    	pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->ScratchBuffer;
551	pGlint->ScanlineDirect   = 0;
552    }
553
554    pGlint->cpucount--;
555}
556
557static void
558TXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
559{
560    GLINTPtr pGlint = GLINTPTR(pScrn);
561    CARD32 *srcp = (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno];
562    int dwords = pGlint->dwords;
563
564    if (!pGlint->ScanlineDirect) {
565	while(dwords >= pGlint->FIFOSize) {
566	    GLINT_WAIT(pGlint->FIFOSize);
567            GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | 0x0D, OutputFIFO);
568	    GLINT_MoveDWORDS(
569			(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
570	 		(CARD32*)srcp, pGlint->FIFOSize - 1);
571	    dwords -= pGlint->FIFOSize - 1;
572	    srcp += pGlint->FIFOSize - 1;
573	}
574	if(dwords) {
575	    GLINT_WAIT(dwords + 1);
576            GLINT_WRITE_REG(((dwords - 1) << 16) | 0x0D, OutputFIFO);
577	    GLINT_MoveDWORDS(
578			(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
579	 		(CARD32*)srcp, dwords);
580	}
581    }
582}
583
584void TXSetupForMono8x8PatternFill(
585	ScrnInfoPtr pScrn,
586	int patternx, int patterny,
587	int fg, int bg, int rop,
588	unsigned int planemask
589){
590    GLINTPtr pGlint = GLINTPTR(pScrn);
591
592    if (bg == -1) pGlint->FrameBufferReadMode = -1;
593	else    pGlint->FrameBufferReadMode = 0;
594    pGlint->ForeGroundColor = fg;
595    pGlint->BackGroundColor = bg;
596    REPLICATE(pGlint->ForeGroundColor);
597    REPLICATE(pGlint->BackGroundColor);
598
599    GLINT_WAIT(13);
600    DO_PLANEMASK(planemask);
601    GLINT_WRITE_REG((patternx & 0x000000FF),       AreaStipplePattern0);
602    GLINT_WRITE_REG((patternx & 0x0000FF00) >> 8,  AreaStipplePattern1);
603    GLINT_WRITE_REG((patternx & 0x00FF0000) >> 16, AreaStipplePattern2);
604    GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3);
605    GLINT_WRITE_REG((patterny & 0x000000FF),       AreaStipplePattern4);
606    GLINT_WRITE_REG((patterny & 0x0000FF00) >> 8,  AreaStipplePattern5);
607    GLINT_WRITE_REG((patterny & 0x00FF0000) >> 16, AreaStipplePattern6);
608    GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7);
609
610    if (rop == GXcopy) {
611	GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
612	GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
613    } else {
614	GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
615	GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
616    }
617    LOADROP(rop);
618}
619
620static void
621TXSubsequentMono8x8PatternFillRect(
622	ScrnInfoPtr pScrn,
623	int patternx, int patterny,
624	int x, int y,
625	int w, int h
626){
627    GLINTPtr pGlint = GLINTPTR(pScrn);
628    int span = 0;
629
630    GLINT_WAIT(12);
631    TXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
632
633    if (pGlint->FrameBufferReadMode != -1) {
634	if (pGlint->ROP == GXcopy) {
635	  GLINT_WRITE_REG(pGlint->BackGroundColor, FBBlockColor);
636	  span = 0;
637	} else {
638  	  GLINT_WRITE_REG(pGlint->BackGroundColor, PatternRamData0);
639	  span = SpanOperation;
640	}
641	GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|ASM_InvertPattern |
642					UNIT_ENABLE, AreaStippleMode);
643	GLINT_WRITE_REG(AreaStippleEnable | span | FastFillEnable |
644						PrimitiveTrapezoid, Render);
645    }
646
647    if (pGlint->ROP == GXcopy) {
648	GLINT_WRITE_REG(pGlint->ForeGroundColor, FBBlockColor);
649	span = 0;
650    } else {
651  	GLINT_WRITE_REG(pGlint->ForeGroundColor, PatternRamData0);
652	span = SpanOperation;
653    }
654    GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|
655  						UNIT_ENABLE, AreaStippleMode);
656    GLINT_WRITE_REG(AreaStippleEnable | span | FastFillEnable |
657						PrimitiveTrapezoid, Render);
658}
659
660static void
661TXWriteBitmap(ScrnInfoPtr pScrn,
662    int x, int y, int w, int h,
663    unsigned char *src,
664    int srcwidth,
665    int skipleft,
666    int fg, int bg,
667    int rop,
668    unsigned int planemask
669){
670    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
671    GLINTPtr pGlint = GLINTPTR(pScrn);
672    unsigned char *srcpntr;
673    int dwords, height, mode;
674    Bool SecondPass = FALSE;
675    register int count;
676    register CARD32* pattern;
677
678    w += skipleft;
679    x -= skipleft;
680    dwords = (w + 31) >> 5;
681
682    TXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h);
683
684    GLINT_WAIT(11);
685    DO_PLANEMASK(planemask);
686    GLINT_WRITE_REG(pGlint->rasterizerMode, RasterizerMode);
687    LOADROP(rop);
688    if (rop == GXcopy) {
689	mode = 0;
690	GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
691	GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
692    } else {
693	mode = SpanOperation;
694	GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
695	GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
696    }
697    TXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
698
699    if(bg == -1) {
700	REPLICATE(fg);
701	GLINT_WAIT(3);
702	if (rop == GXcopy) {
703	    GLINT_WRITE_REG(fg, FBBlockColor);
704	} else {
705	    GLINT_WRITE_REG(fg, PatternRamData0);
706	}
707    } else if(rop == GXcopy) {
708	REPLICATE(bg);
709	GLINT_WAIT(5);
710	if (rop == GXcopy) {
711	    GLINT_WRITE_REG(bg, FBBlockColor);
712	} else {
713	    GLINT_WRITE_REG(bg, PatternRamData0);
714	}
715	GLINT_WRITE_REG(PrimitiveTrapezoid |mode|FastFillEnable,Render);
716	REPLICATE(fg);
717	if (rop == GXcopy) {
718	    GLINT_WRITE_REG(fg, FBBlockColor);
719	} else {
720	    GLINT_WRITE_REG(fg, PatternRamData0);
721	}
722    } else {
723	SecondPass = TRUE;
724	REPLICATE(fg);
725	GLINT_WAIT(3);
726	if (rop == GXcopy) {
727	    GLINT_WRITE_REG(fg, FBBlockColor);
728	} else {
729	    GLINT_WRITE_REG(fg, PatternRamData0);
730	}
731    }
732
733SECOND_PASS:
734    GLINT_WRITE_REG(PrimitiveTrapezoid | FastFillEnable | mode | SyncOnBitMask, Render);
735
736    height = h;
737    srcpntr = src;
738    while(height--) {
739	count = dwords >> 3;
740	pattern = (CARD32*)srcpntr;
741	while(count--) {
742		GLINT_WAIT(8);
743		GLINT_WRITE_REG(*(pattern), BitMaskPattern);
744		GLINT_WRITE_REG(*(pattern+1), BitMaskPattern);
745		GLINT_WRITE_REG(*(pattern+2), BitMaskPattern);
746		GLINT_WRITE_REG(*(pattern+3), BitMaskPattern);
747		GLINT_WRITE_REG(*(pattern+4), BitMaskPattern);
748		GLINT_WRITE_REG(*(pattern+5), BitMaskPattern);
749		GLINT_WRITE_REG(*(pattern+6), BitMaskPattern);
750		GLINT_WRITE_REG(*(pattern+7), BitMaskPattern);
751		pattern+=8;
752	}
753	count = dwords & 0x07;
754	GLINT_WAIT(count);
755	while (count--)
756		GLINT_WRITE_REG(*(pattern++), BitMaskPattern);
757	srcpntr += srcwidth;
758    }
759
760    if(SecondPass) {
761	SecondPass = FALSE;
762	REPLICATE(bg);
763	GLINT_WAIT(4);
764	GLINT_WRITE_REG(InvertBitMask | pGlint->rasterizerMode, RasterizerMode);
765	if (rop == GXcopy) {
766	    GLINT_WRITE_REG(bg, FBBlockColor);
767	} else {
768	    GLINT_WRITE_REG(bg, PatternRamData0);
769	}
770	goto SECOND_PASS;
771    }
772
773    GLINT_WAIT(2);
774    GLINT_WRITE_REG(pGlint->rasterizerMode, RasterizerMode);
775    CHECKCLIPPING;
776    SET_SYNC_FLAG(infoRec);
777}
778
779static void
780TXWritePixmap(
781   ScrnInfoPtr pScrn,
782   int x, int y, int w, int h,
783   unsigned char *src,
784   int srcwidth,	/* bytes */
785   int rop,
786   unsigned int planemask,
787   int trans,
788   int bpp, int depth
789){
790    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
791    GLINTPtr pGlint = GLINTPTR(pScrn);
792    CARD32 *srcp;
793    int count,dwords, skipleft, Bpp = bpp >> 3;
794
795    if((skipleft = (long)src & 0x03L)) {
796	skipleft /= Bpp;
797
798	x -= skipleft;
799	w += skipleft;
800
801	src = (unsigned char*)((long)src & ~0x03L);
802    }
803
804    switch(Bpp) {
805    case 1:	dwords = (w + 3) >> 2;
806		break;
807    case 2:	dwords = (w + 1) >> 1;
808		break;
809    case 4:	dwords = w;
810		break;
811    default: return;
812    }
813
814    TXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h);
815
816    GLINT_WAIT(12);
817    DO_PLANEMASK(planemask);
818    GLINT_WRITE_REG(0, PatternRamMode);
819    if (rop == GXcopy) {
820        GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
821    } else {
822        GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
823    }
824    LOADROP(rop);
825    TXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
826    GLINT_WRITE_REG(PrimitiveTrapezoid | FastFillEnable | SpanOperation |
827						SyncOnHostData, Render);
828
829    while(h--) {
830      count = dwords;
831      srcp = (CARD32*)src;
832      while(count >= infoRec->ColorExpandRange) {
833	GLINT_WAIT(infoRec->ColorExpandRange);
834	/* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
835       	GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | (0x15 << 4) |
836				0x05, OutputFIFO);
837	GLINT_MoveDWORDS(
838		(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
839 		(CARD32*)srcp, infoRec->ColorExpandRange - 1);
840	count -= infoRec->ColorExpandRange - 1;
841	srcp += infoRec->ColorExpandRange - 1;
842      }
843      if(count) {
844	GLINT_WAIT(count);
845	/* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
846       	GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
847				0x05, OutputFIFO);
848	GLINT_MoveDWORDS(
849		(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
850 		(CARD32*)srcp, count);
851      }
852      src += srcwidth;
853    }
854    CHECKCLIPPING;
855    SET_SYNC_FLAG(infoRec);
856}
857
858static void
859TXPolylinesThinSolidWrapper(
860   DrawablePtr     pDraw,
861   GCPtr           pGC,
862   int             mode,
863   int             npt,
864   DDXPointPtr     pPts
865){
866    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
867    GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
868    pGlint->CurrentGC = pGC;
869    pGlint->CurrentDrawable = pDraw;
870    if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
871    XAAPolyLines(pDraw, pGC, mode, npt, pPts);
872}
873
874static void
875TXPolySegmentThinSolidWrapper(
876   DrawablePtr     pDraw,
877   GCPtr           pGC,
878   int             nseg,
879   xSegment        *pSeg
880){
881    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
882    GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
883    pGlint->CurrentGC = pGC;
884    pGlint->CurrentDrawable = pDraw;
885    if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
886    XAAPolySegment(pDraw, pGC, nseg, pSeg);
887}
888
889static void
890TXSetupForSolidLine(ScrnInfoPtr pScrn, int color,
891					 int rop, unsigned int planemask)
892{
893    GLINTPtr pGlint = GLINTPTR(pScrn);
894
895    GLINT_WAIT(5);
896    DO_PLANEMASK(planemask);
897    GLINT_WRITE_REG(color, GLINTColor);
898    if (rop == GXcopy) {
899  	GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
900    } else {
901  	GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
902    }
903    LOADROP(rop);
904}
905
906static void
907TXSubsequentHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir)
908{
909    GLINTPtr pGlint = GLINTPTR(pScrn);
910
911    GLINT_WAIT(7);
912    if (dir == DEGREES_0) {
913        TXLoadCoord(pScrn, x, y, 0, len, 1, 0);
914    } else {
915        TXLoadCoord(pScrn, x, y, 0, len, 0, 1);
916    }
917
918    GLINT_WRITE_REG(PrimitiveLine, Render);
919}
920
921static void
922TXSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
923        int x, int y, int dmaj, int dmin, int e, int len, int octant)
924{
925    GLINTPtr pGlint = GLINTPTR(pScrn);
926    int dxdom, dy;
927
928    if(dmaj == dmin) {
929	GLINT_WAIT(7);
930	if(octant & YDECREASING) {
931	    dy = -1;
932	} else {
933	    dy = 1;
934	}
935
936	if(octant & XDECREASING) {
937	    dxdom = -1;
938	} else {
939	    dxdom = 1;
940	}
941
942        TXLoadCoord(pScrn, x, y, 0, len, dxdom, dy);
943	GLINT_WRITE_REG(PrimitiveLine, Render);
944	return;
945    }
946
947    fbBres(pGlint->CurrentDrawable, pGlint->CurrentGC, 0,
948                (octant & XDECREASING) ? -1 : 1,
949                (octant & YDECREASING) ? -1 : 1,
950                (octant & YMAJOR) ? Y_AXIS : X_AXIS,
951                x, y,  e, dmin, -dmaj, len);
952}
953#endif
954