ag10e_accel.c revision 98bb403a
1/*
2 * Fujitsu AG-10e acceleration support
3 *
4 * Copyright (C) 2005 Michael Lorenz
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * MICHAEL LORENZ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/suncg6/cg6_accel.c $ */
24
25#include <fcntl.h>
26#include <sys/time.h>
27#include <sys/types.h>
28#include <dev/sun/fbio.h>
29#include <dev/wscons/wsconsio.h>
30
31#include "ag10e.h"
32#include "dgaproc.h"
33#include "miline.h"
34#include "xaalocal.h"	/* For replacements */
35
36static Bool AG10E_OpenFramebuffer(ScrnInfoPtr, char **,
37    unsigned char **, int *, int *, int *);
38static Bool AG10E_SetMode(ScrnInfoPtr, DGAModePtr);
39static void AG10E_SetViewport(ScrnInfoPtr, int, int, int);
40static int AG10E_GetViewport(ScrnInfoPtr);
41
42#if 0
43static void AG10E_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
44static void AG10E_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
45#endif
46
47static DGAFunctionRec AG10E_DGAFuncs = {
48	AG10E_OpenFramebuffer,
49	NULL,
50	AG10E_SetMode,
51	AG10E_SetViewport,
52	AG10E_GetViewport,
53#if 0
54	AG10ESync,
55	AG10E_FillRect,
56	AG10E_BlitRect,
57#else
58	NULL,
59	NULL,
60	NULL,
61#endif
62	NULL
63};
64
65static void SXSync(ScrnInfoPtr pScrn);
66static void SXSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop,
67						unsigned int planemask);
68static void SXSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y,
69						int w, int h);
70static void SXSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx,
71						int patterny,
72					   	int fg, int bg, int rop,
73					   	unsigned int planemask);
74static void SXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
75						int patterny, int x, int y,
76				   		int w, int h);
77static void SXSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
78						int rop, unsigned int planemask,
79				    		int transparency_color);
80static void SXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
81						int x2, int y2, int w, int h);
82static void SXSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
83						int x2,int y2);
84static void SXDisableClipping(ScrnInfoPtr pScrn);
85static void SXLoadCoord(ScrnInfoPtr pScrn, int x, int y, int w, int h,
86				int a, int d);
87static void SXSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
88				unsigned int planemask);
89static void SXSubsequentHorVertLine(ScrnInfoPtr pScrn, int x1, int y1,
90				int len, int dir);
91static void SXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
92        			int x, int y, int dmaj, int dmin, int e,
93				int len, int octant);
94static void SXPolylinesThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
95   				int mode, int npt, DDXPointPtr pPts);
96static void SXPolySegmentThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
97 				int nseg, xSegment *pSeg);
98
99#define MAX_FIFO_ENTRIES		15
100
101#define PARTPROD(a,b,c) (((a)<<6) | ((b)<<3) | (c))
102
103static int partprod500TX[] = {
104	-1,
105	PARTPROD(0,0,1), PARTPROD(0,0,2), PARTPROD(0,1,2), PARTPROD(0,0,3),
106	PARTPROD(0,1,3), PARTPROD(0,2,3), PARTPROD(1,2,3), PARTPROD(0,0,4),
107	PARTPROD(0,1,4), PARTPROD(0,2,4), PARTPROD(1,2,4), PARTPROD(0,3,4),
108	PARTPROD(1,3,4), PARTPROD(2,3,4),              -1, PARTPROD(0,0,5),
109	PARTPROD(0,1,5), PARTPROD(0,2,5), PARTPROD(1,2,5), PARTPROD(0,3,5),
110	PARTPROD(1,3,5), PARTPROD(2,3,5),              -1, PARTPROD(0,4,5),
111	PARTPROD(1,4,5), PARTPROD(2,4,5), PARTPROD(3,4,5),              -1,
112	             -1,              -1,              -1, PARTPROD(0,0,6),
113	PARTPROD(0,1,6), PARTPROD(0,2,6), PARTPROD(1,2,6), PARTPROD(0,3,6),
114	PARTPROD(1,3,6), PARTPROD(2,3,6),              -1, PARTPROD(0,4,6),
115	PARTPROD(1,4,6), PARTPROD(2,4,6),              -1, PARTPROD(3,4,6),
116	             -1,              -1,              -1, PARTPROD(0,5,6),
117	PARTPROD(1,5,6), PARTPROD(2,5,6),              -1, PARTPROD(3,5,6),
118	             -1,              -1,              -1, PARTPROD(4,5,6),
119	             -1,              -1,              -1,              -1,
120		     -1,              -1,              -1, PARTPROD(0,0,7),
121	             -1, PARTPROD(0,2,7), PARTPROD(1,2,7), PARTPROD(0,3,7),
122	PARTPROD(1,3,7), PARTPROD(2,3,7),              -1, PARTPROD(0,4,7),
123	PARTPROD(1,4,7), PARTPROD(2,4,7),              -1, PARTPROD(3,4,7),
124	             -1,              -1,              -1, PARTPROD(0,5,7),
125	PARTPROD(1,5,7), PARTPROD(2,5,7),              -1, PARTPROD(3,5,7),
126	             -1,              -1,              -1, PARTPROD(4,5,7),
127	             -1,              -1,              -1,              -1,
128		     -1,              -1,              -1, PARTPROD(0,6,7),
129	PARTPROD(1,6,7), PARTPROD(2,6,7),              -1, PARTPROD(3,6,7),
130	             -1,              -1,              -1, PARTPROD(4,6,7),
131	             -1,              -1,              -1,              -1,
132		     -1,              -1,              -1, PARTPROD(5,6,7),
133	             -1,              -1,              -1,              -1,
134		     -1,              -1,              -1,              -1,
135		     -1,              -1,              -1,              -1,
136		     -1,              -1,              -1, PARTPROD(0,7,7),
137		      0};
138
139
140static void
141SXInitializeEngine(ScrnInfoPtr pScrn)
142{
143    AG10EPtr pAG10E = GLINTPTR(pScrn);
144    /* Initialize the Accelerator Engine to defaults */
145
146    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	DitherMode);
147    GLINT_SLOW_WRITE_REG(0x400,		FilterMode);
148    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  ScissorMode);
149    GLINT_SLOW_WRITE_REG(pAG10E->pprod,	LBReadMode);
150    GLINT_SLOW_WRITE_REG(pAG10E->pprod,	FBReadMode);
151    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LBWriteMode);
152    GLINT_SLOW_WRITE_REG(UNIT_ENABLE,	FBWriteMode);
153    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	AlphaBlendMode);
154    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	ColorDDAMode);
155    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	TextureColorMode);
156    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	TextureAddressMode);
157    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  TextureReadMode);
158    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  GLINTWindow);
159    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  AlphaBlendMode);
160    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  DepthMode);
161    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  RouterMode);
162    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	FogMode);
163    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	AntialiasMode);
164    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	AlphaTestMode);
165    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	StencilMode);
166    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	AreaStippleMode);
167    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LineStippleMode);
168    GLINT_SLOW_WRITE_REG(0,		UpdateLineStippleCounters);
169    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LogicalOpMode);
170    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	DepthMode);
171    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	StatisticMode);
172    GLINT_SLOW_WRITE_REG(0xffffffff,	FBHardwareWriteMask);
173    GLINT_SLOW_WRITE_REG(0xffffffff,	FBSoftwareWriteMask);
174    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	RasterizerMode);
175    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	GLINTDepth);
176    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	FBSourceOffset);
177    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	FBPixelOffset);
178    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LBSourceOffset);
179    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	WindowOrigin);
180    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	FBWindowBase);
181    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LBWindowBase);
182    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	TextureAddressMode);
183    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	RouterMode);
184
185    pAG10E->ROP = 0xFF;
186    pAG10E->ClippingOn = FALSE;
187    pAG10E->startxsub = 0;
188    pAG10E->startxdom = 0;
189    pAG10E->starty = 0;
190    pAG10E->count = 0;
191    pAG10E->dxdom = 0;
192    pAG10E->dy = 1;
193    pAG10E->planemask = 0;
194    GLINT_SLOW_WRITE_REG(0, StartXSub);
195    GLINT_SLOW_WRITE_REG(0, StartXDom);
196    GLINT_SLOW_WRITE_REG(0, StartY);
197    GLINT_SLOW_WRITE_REG(0, GLINTCount);
198    GLINT_SLOW_WRITE_REG(0, dXDom);
199    GLINT_SLOW_WRITE_REG(0, dXSub);
200    GLINT_SLOW_WRITE_REG(1<<16, dY);
201}
202
203int
204AG10EAccelInit(ScreenPtr pScreen)
205{
206    XAAInfoRecPtr infoPtr;
207    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
208    AG10EPtr pAG10E = GLINTPTR(pScrn);
209    long memory = pAG10E->FbMapSize;
210    BoxRec AvailFBArea;
211
212    pAG10E->pprod = partprod500TX[pScrn->displayWidth >> 5];
213
214    pAG10E->AccelInfoRec = infoPtr = XAACreateInfoRec();
215    if (!infoPtr) return FALSE;
216
217    SXInitializeEngine(pScrn);
218
219    infoPtr->Flags = PIXMAP_CACHE |
220		     LINEAR_FRAMEBUFFER |
221		     OFFSCREEN_PIXMAPS;
222
223    infoPtr->Sync = SXSync;
224
225    infoPtr->SetClippingRectangle = SXSetClippingRectangle;
226    infoPtr->DisableClipping = SXDisableClipping;
227    infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL |
228			     HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
229			     HARDWARE_CLIP_SOLID_FILL;
230
231    infoPtr->SolidFillFlags = 0;
232    infoPtr->SetupForSolidFill = SXSetupForFillRectSolid;
233    infoPtr->SubsequentSolidFillRect = SXSubsequentFillRectSolid;
234
235    infoPtr->SolidLineFlags = 0;
236    infoPtr->PolySegmentThinSolidFlags = 0;
237    infoPtr->PolylinesThinSolidFlags = 0;
238    infoPtr->SetupForSolidLine = SXSetupForSolidLine;
239    infoPtr->SubsequentSolidHorVertLine = SXSubsequentHorVertLine;
240    infoPtr->SubsequentSolidBresenhamLine =
241					SXSubsequentSolidBresenhamLine;
242    infoPtr->PolySegmentThinSolid = SXPolySegmentThinSolidWrapper;
243    infoPtr->PolylinesThinSolid = SXPolylinesThinSolidWrapper;
244
245    infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY |
246				       ONLY_LEFT_TO_RIGHT_BITBLT;
247    infoPtr->SetupForScreenToScreenCopy = SXSetupForScreenToScreenCopy;
248    infoPtr->SubsequentScreenToScreenCopy = SXSubsequentScreenToScreenCopy;
249
250    infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
251				       HARDWARE_PATTERN_SCREEN_ORIGIN |
252				       HARDWARE_PATTERN_PROGRAMMED_BITS;
253    infoPtr->SetupForMono8x8PatternFill = SXSetupForMono8x8PatternFill;
254    infoPtr->SubsequentMono8x8PatternFillRect =
255					SXSubsequentMono8x8PatternFillRect;
256
257    AvailFBArea.x1 = 0;
258    AvailFBArea.y1 = 0;
259    AvailFBArea.x2 = pScrn->displayWidth;
260    AvailFBArea.y2 = pAG10E->vidmem / (pScrn->displayWidth *
261					  pScrn->bitsPerPixel / 8);
262
263    if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047;
264
265    xf86InitFBManager(pScreen, &AvailFBArea);
266
267    return (XAAInit(pScreen, infoPtr));
268}
269
270static void SXLoadCoord(
271	ScrnInfoPtr pScrn,
272	int x, int y,
273	int w, int h,
274	int a, int d
275){
276    AG10EPtr pAG10E = GLINTPTR(pScrn);
277
278    if (w != pAG10E->startxsub) {
279    	GLINT_WRITE_REG(w<<16, StartXSub);
280	pAG10E->startxsub = w;
281    }
282    if (x != pAG10E->startxdom) {
283    	GLINT_WRITE_REG(x<<16,StartXDom);
284	pAG10E->startxdom = x;
285    }
286    if (y != pAG10E->starty) {
287    	GLINT_WRITE_REG(y<<16,StartY);
288	pAG10E->starty = y;
289    }
290    if (h != pAG10E->count) {
291    	GLINT_WRITE_REG(h,GLINTCount);
292	pAG10E->count = h;
293    }
294    if (a != pAG10E->dxdom) {
295    	GLINT_WRITE_REG(a<<16,dXDom);
296	pAG10E->dxdom = a;
297    }
298    if (d != pAG10E->dy) {
299    	GLINT_WRITE_REG(d<<16,dY);
300	pAG10E->dy = d;
301    }
302}
303
304static void
305SXSync(
306	ScrnInfoPtr pScrn
307){
308    AG10EPtr pAG10E = GLINTPTR(pScrn);
309    CARD32 readValue;
310
311    CHECKCLIPPING;
312
313    while (GLINT_READ_REG(DMACount) != 0);
314    GLINT_WAIT(3);
315    GLINT_WRITE_REG(0x400, FilterMode);
316    GLINT_WRITE_REG(0, GlintSync);
317    do {
318   	while(GLINT_READ_REG(OutFIFOWords) == 0);
319	readValue = GLINT_READ_REG(OutputFIFO);
320    } while (readValue != Sync_tag);
321}
322
323static void
324SXSetupForFillRectSolid(
325	ScrnInfoPtr pScrn,
326	int color, int rop,
327	unsigned int planemask
328){
329    AG10EPtr pAG10E = GLINTPTR(pScrn);
330    pAG10E->ForeGroundColor = color;
331
332    GLINT_WAIT(6);
333    REPLICATE(color);
334    DO_PLANEMASK(planemask);
335    if (pScrn->bitsPerPixel >= 24) {
336	GLINT_WRITE_REG(pAG10E->pprod | FBRM_DstEnable, FBReadMode);
337	GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
338	GLINT_WRITE_REG(color, ConstantColor);
339	pAG10E->FrameBufferReadMode = 0;
340    } else
341    if (rop == GXcopy) {
342	GLINT_WRITE_REG(pAG10E->pprod, FBReadMode);
343	GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
344	GLINT_WRITE_REG(color, FBBlockColor);
345	pAG10E->FrameBufferReadMode = FastFillEnable;
346    } else {
347	GLINT_WRITE_REG(pAG10E->pprod | FBRM_DstEnable, FBReadMode);
348	GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
349	GLINT_WRITE_REG(color, ConstantColor);
350	pAG10E->FrameBufferReadMode = 0;
351    }
352    LOADROP(rop);
353}
354
355static void
356SXSubsequentFillRectSolid(
357	ScrnInfoPtr pScrn,
358	int x, int y,
359	int w, int h
360){
361    AG10EPtr pAG10E = GLINTPTR(pScrn);
362
363    GLINT_WAIT(8);
364    SXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
365    GLINT_WRITE_REG(PrimitiveTrapezoid | pAG10E->FrameBufferReadMode,Render);
366}
367
368static void
369SXSetClippingRectangle(
370	ScrnInfoPtr pScrn,
371	int x1, int y1,
372	int x2, int y2
373){
374    AG10EPtr pAG10E = GLINTPTR(pScrn);
375
376    GLINT_WAIT(5);
377    GLINT_WRITE_REG((y1&0xFFFF)<<16|(x1&0xFFFF), ScissorMinXY);
378    GLINT_WRITE_REG((y2&0xFFFF)<<16|(x2&0xFFFF), ScissorMaxXY);
379    GLINT_WRITE_REG(1, ScissorMode); /* Enable Scissor Mode */
380    pAG10E->ClippingOn = TRUE;
381}
382
383static void
384SXDisableClipping(
385	ScrnInfoPtr pScrn
386){
387    AG10EPtr pAG10E = GLINTPTR(pScrn);
388    CHECKCLIPPING;
389}
390
391static void
392SXSetupForScreenToScreenCopy(
393	ScrnInfoPtr pScrn,
394	int xdir, int  ydir,
395	int rop,
396	unsigned int planemask,
397	int transparency_color
398){
399    AG10EPtr pAG10E = GLINTPTR(pScrn);
400
401    pAG10E->BltScanDirection = ydir;
402
403    GLINT_WAIT(6);
404    DO_PLANEMASK(planemask);
405
406    if (rop == GXcopy) {
407	GLINT_WRITE_REG(pAG10E->pprod | FBRM_SrcEnable, FBReadMode);
408    } else {
409	GLINT_WRITE_REG(pAG10E->pprod | FBRM_SrcEnable | FBRM_DstEnable, FBReadMode);
410    }
411    LOADROP(rop);
412}
413
414static void
415SXSubsequentScreenToScreenCopy(
416	ScrnInfoPtr pScrn,
417	int x1, int y1,
418	int x2, int y2,
419	int w, int h
420){
421    AG10EPtr pAG10E = GLINTPTR(pScrn);
422    int srcaddr, dstaddr;
423
424    GLINT_WAIT(10);
425
426    srcaddr = y1 * pScrn->displayWidth + x1;
427    dstaddr = y2 * pScrn->displayWidth + x2;
428    GLINT_WRITE_REG(srcaddr - dstaddr, FBSourceOffset);
429
430    if (pAG10E->BltScanDirection != 1) {
431	y1 += h - 1;
432	y2 += h - 1;
433        SXLoadCoord(pScrn, x2, y2, x2+w, h, 0, -1);
434    } else {
435        SXLoadCoord(pScrn, x2, y2, x2+w, h, 0, 1);
436    }
437
438    GLINT_WRITE_REG(PrimitiveTrapezoid, Render);
439}
440
441static void
442SXSetupForMono8x8PatternFill(
443	ScrnInfoPtr pScrn,
444	int patternx, int patterny,
445	int fg, int bg, int rop,
446	unsigned int planemask
447){
448    AG10EPtr pAG10E = GLINTPTR(pScrn);
449
450    if (bg == -1) pAG10E->FrameBufferReadMode = -1;
451	else    pAG10E->FrameBufferReadMode = 0;
452    pAG10E->ForeGroundColor = fg;
453    pAG10E->BackGroundColor = bg;
454    REPLICATE(pAG10E->ForeGroundColor);
455    REPLICATE(pAG10E->BackGroundColor);
456
457    GLINT_WAIT(13);
458    DO_PLANEMASK(planemask);
459    GLINT_WRITE_REG((patternx & 0x000000FF),       AreaStipplePattern0);
460    GLINT_WRITE_REG((patternx & 0x0000FF00) >> 8,  AreaStipplePattern1);
461    GLINT_WRITE_REG((patternx & 0x00FF0000) >> 16, AreaStipplePattern2);
462    GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3);
463    GLINT_WRITE_REG((patterny & 0x000000FF),       AreaStipplePattern4);
464    GLINT_WRITE_REG((patterny & 0x0000FF00) >> 8,  AreaStipplePattern5);
465    GLINT_WRITE_REG((patterny & 0x00FF0000) >> 16, AreaStipplePattern6);
466    GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7);
467
468    GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
469    if (rop == GXcopy)
470    	GLINT_WRITE_REG(pAG10E->pprod, FBReadMode);
471    else
472    	GLINT_WRITE_REG(pAG10E->pprod | FBRM_DstEnable, FBReadMode);
473    LOADROP(rop);
474}
475
476static void
477SXSubsequentMono8x8PatternFillRect(
478	ScrnInfoPtr pScrn,
479	int patternx, int patterny,
480	int x, int y,
481	int w, int h
482){
483    AG10EPtr pAG10E = GLINTPTR(pScrn);
484
485    GLINT_WAIT(12);
486    SXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
487
488    if (pAG10E->FrameBufferReadMode != -1) {
489  	GLINT_WRITE_REG(pAG10E->BackGroundColor, ConstantColor);
490	GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|ASM_InvertPattern |
491					UNIT_ENABLE, AreaStippleMode);
492	GLINT_WRITE_REG(AreaStippleEnable | PrimitiveTrapezoid, Render);
493    }
494
495    GLINT_WRITE_REG(pAG10E->ForeGroundColor, ConstantColor);
496    GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|
497  						UNIT_ENABLE, AreaStippleMode);
498    GLINT_WRITE_REG(AreaStippleEnable | PrimitiveTrapezoid, Render);
499}
500
501#if 0
502static void
503SXWriteBitmap(ScrnInfoPtr pScrn,
504    int x, int y, int w, int h,
505    unsigned char *src,
506    int srcwidth,
507    int skipleft,
508    int fg, int bg,
509    int rop,
510    unsigned int planemask
511){
512    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
513    AG10EPtr pAG10E = GLINTPTR(pScrn);
514    unsigned char *srcpntr;
515    int dwords, height, mode;
516    Bool SecondPass = FALSE;
517    register int count;
518    register CARD32* pattern;
519
520    w += skipleft;
521    x -= skipleft;
522    dwords = (w + 31) >> 5;
523
524    SXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h);
525
526    GLINT_WAIT(11);
527    DO_PLANEMASK(planemask);
528    GLINT_WRITE_REG(0, RasterizerMode);
529    LOADROP(rop);
530    if (rop == GXcopy) {
531	mode = FastFillEnable;
532	GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
533	GLINT_WRITE_REG(pAG10E->pprod, FBReadMode);
534    } else {
535	mode = 0;
536	GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
537	GLINT_WRITE_REG(pAG10E->pprod | FBRM_DstEnable, FBReadMode);
538    }
539    SXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
540
541    if(bg == -1) {
542	REPLICATE(fg);
543	GLINT_WAIT(3);
544	if (rop == GXcopy) {
545	    GLINT_WRITE_REG(fg, FBBlockColor);
546	} else {
547	    GLINT_WRITE_REG(fg, PatternRamData0);
548	}
549    } else if(rop == GXcopy) {
550	REPLICATE(bg);
551	GLINT_WAIT(5);
552	if (rop == GXcopy) {
553	    GLINT_WRITE_REG(bg, FBBlockColor);
554	} else {
555	    GLINT_WRITE_REG(bg, PatternRamData0);
556	}
557	GLINT_WRITE_REG(PrimitiveTrapezoid |mode|FastFillEnable,Render);
558	REPLICATE(fg);
559	if (rop == GXcopy) {
560	    GLINT_WRITE_REG(fg, FBBlockColor);
561	} else {
562	    GLINT_WRITE_REG(fg, PatternRamData0);
563	}
564    } else {
565	SecondPass = TRUE;
566	REPLICATE(fg);
567	GLINT_WAIT(3);
568	if (rop == GXcopy) {
569	    GLINT_WRITE_REG(fg, FBBlockColor);
570	} else {
571	    GLINT_WRITE_REG(fg, PatternRamData0);
572	}
573    }
574
575SECOND_PASS:
576    GLINT_WRITE_REG(PrimitiveTrapezoid | FastFillEnable | mode | SyncOnBitMask, Render);
577
578    height = h;
579    srcpntr = src;
580    while(height--) {
581	count = dwords >> 3;
582	pattern = (CARD32*)srcpntr;
583	while(count--) {
584		GLINT_WAIT(8);
585		GLINT_WRITE_REG(*(pattern), BitMaskPattern);
586		GLINT_WRITE_REG(*(pattern+1), BitMaskPattern);
587		GLINT_WRITE_REG(*(pattern+2), BitMaskPattern);
588		GLINT_WRITE_REG(*(pattern+3), BitMaskPattern);
589		GLINT_WRITE_REG(*(pattern+4), BitMaskPattern);
590		GLINT_WRITE_REG(*(pattern+5), BitMaskPattern);
591		GLINT_WRITE_REG(*(pattern+6), BitMaskPattern);
592		GLINT_WRITE_REG(*(pattern+7), BitMaskPattern);
593		pattern+=8;
594	}
595	count = dwords & 0x07;
596	GLINT_WAIT(count);
597	while (count--)
598		GLINT_WRITE_REG(*(pattern++), BitMaskPattern);
599	srcpntr += srcwidth;
600    }
601
602    if(SecondPass) {
603	SecondPass = FALSE;
604	REPLICATE(bg);
605	GLINT_WAIT(4);
606	GLINT_WRITE_REG(InvertBitMask, RasterizerMode);
607	if (rop == GXcopy) {
608	    GLINT_WRITE_REG(bg, FBBlockColor);
609	} else {
610	    GLINT_WRITE_REG(bg, PatternRamData0);
611	}
612	goto SECOND_PASS;
613    }
614
615    GLINT_WAIT(2);
616    GLINT_WRITE_REG(0, RasterizerMode);
617    CHECKCLIPPING;
618    SET_SYNC_FLAG(infoRec);
619}
620
621static void
622SXWritePixmap(
623   ScrnInfoPtr pScrn,
624   int x, int y, int w, int h,
625   unsigned char *src,
626   int srcwidth,	/* bytes */
627   int rop,
628   unsigned int planemask,
629   int trans,
630   int bpp, int depth
631){
632    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
633    AG10EPtr pAG10E = GLINTPTR(pScrn);
634    CARD32 *srcp;
635    int count,dwords, skipleft, Bpp = bpp >> 3;
636
637    if((skipleft = (long)src & 0x03L)) {
638	skipleft /= Bpp;
639
640	x -= skipleft;
641	w += skipleft;
642
643	src = (unsigned char*)((long)src & ~0x03L);
644    }
645
646    switch(Bpp) {
647    case 1:	dwords = (w + 3) >> 2;
648		break;
649    case 2:	dwords = (w + 1) >> 1;
650		break;
651    case 4:	dwords = w;
652		break;
653    default: return;
654    }
655
656    SXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h);
657
658    GLINT_WAIT(12);
659    DO_PLANEMASK(planemask);
660    GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
661    if (rop == GXcopy) {
662        GLINT_WRITE_REG(pAG10E->pprod, FBReadMode);
663    } else {
664        GLINT_WRITE_REG(pAG10E->pprod | FBRM_DstEnable, FBReadMode);
665    }
666    LOADROP(rop);
667    SXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
668    GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render);
669
670    while(h--) {
671      count = dwords;
672      srcp = (CARD32*)src;
673      while(count >= infoRec->ColorExpandRange) {
674	GLINT_WAIT(infoRec->ColorExpandRange);
675	/* (0x0f << 4) | 0x0e is the TAG for GLINTColor */
676       	GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | (0x0F << 4) |
677				0x0E, OutputFIFO);
678	GLINT_MoveDWORDS(
679		(CARD32*)((char*)pAG10E->IOBase + OutputFIFO + 4),
680 		(CARD32*)srcp, infoRec->ColorExpandRange - 1);
681	count -= infoRec->ColorExpandRange - 1;
682	srcp += infoRec->ColorExpandRange - 1;
683      }
684      if(count) {
685	GLINT_WAIT(count);
686	/* (0x0F << 4) | 0x0E is the TAG for GLINTColor */
687       	GLINT_WRITE_REG(((count - 1) << 16) | (0x0f << 4) |
688				0x0e, OutputFIFO);
689	GLINT_MoveDWORDS(
690		(CARD32*)((char*)pAG10E->IOBase + OutputFIFO + 4),
691 		(CARD32*)srcp, count);
692      }
693      src += srcwidth;
694    }
695    CHECKCLIPPING;
696    SET_SYNC_FLAG(infoRec);
697}
698#endif
699
700static void
701SXPolylinesThinSolidWrapper(
702   DrawablePtr     pDraw,
703   GCPtr           pGC,
704   int             mode,
705   int             npt,
706   DDXPointPtr     pPts
707){
708    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
709    AG10EPtr pAG10E = GLINTPTR(infoRec->pScrn);
710    pAG10E->CurrentGC = pGC;
711    pAG10E->CurrentDrawable = pDraw;
712    if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
713    XAAPolyLines(pDraw, pGC, mode, npt, pPts);
714}
715
716static void
717SXPolySegmentThinSolidWrapper(
718   DrawablePtr     pDraw,
719   GCPtr           pGC,
720   int             nseg,
721   xSegment        *pSeg
722){
723    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
724    AG10EPtr pAG10E = GLINTPTR(infoRec->pScrn);
725    pAG10E->CurrentGC = pGC;
726    pAG10E->CurrentDrawable = pDraw;
727    if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
728    XAAPolySegment(pDraw, pGC, nseg, pSeg);
729}
730
731static void
732SXSetupForSolidLine(ScrnInfoPtr pScrn, int color,
733					 int rop, unsigned int planemask)
734{
735    AG10EPtr pAG10E = GLINTPTR(pScrn);
736
737    GLINT_WAIT(7);
738    DO_PLANEMASK(planemask);
739    GLINT_WRITE_REG(color, GLINTColor);
740    GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
741    if (rop == GXcopy) {
742  	GLINT_WRITE_REG(pAG10E->pprod, FBReadMode);
743    } else {
744  	GLINT_WRITE_REG(pAG10E->pprod | FBRM_DstEnable, FBReadMode);
745    }
746    LOADROP(rop);
747}
748
749static void
750SXSubsequentHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir)
751{
752    AG10EPtr pAG10E = GLINTPTR(pScrn);
753
754    GLINT_WAIT(9);
755    if (dir == DEGREES_0) {
756        SXLoadCoord(pScrn, x, y, 0, len, 1, 0);
757    } else {
758        SXLoadCoord(pScrn, x, y, 0, len, 0, 1);
759    }
760
761    GLINT_WRITE_REG(PrimitiveLine, Render);
762}
763
764static void
765SXSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
766        int x, int y, int dmaj, int dmin, int e, int len, int octant)
767{
768    AG10EPtr pAG10E = GLINTPTR(pScrn);
769    int dxdom, dy;
770
771    if(dmaj == dmin) {
772	GLINT_WAIT(9);
773	if(octant & YDECREASING) {
774	    dy = -1;
775	} else {
776	    dy = 1;
777	}
778
779	if(octant & XDECREASING) {
780	    dxdom = -1;
781	} else {
782	    dxdom = 1;
783	}
784
785        SXLoadCoord(pScrn, x, y, 0, len, dxdom, dy);
786	GLINT_WRITE_REG(PrimitiveLine, Render);
787	return;
788    }
789
790    fbBres(pAG10E->CurrentDrawable, pAG10E->CurrentGC, 0,
791                (octant & XDECREASING) ? -1 : 1,
792                (octant & YDECREASING) ? -1 : 1,
793                (octant & YMAJOR) ? Y_AXIS : X_AXIS,
794                x, y,  e, dmin, -dmaj, len);
795}
796
797Bool
798AG10EDGAInit(ScreenPtr pScreen)
799{
800    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
801    AG10EPtr pAG10E = GET_AG10E_FROM_SCRN(pScrn);
802    DGAModePtr mode;
803    int result;
804
805    mode = xnfcalloc(sizeof(DGAModeRec), 1);
806    if (mode == NULL) {
807        xf86Msg(X_WARNING, "%s: DGA setup failed, cannot allocate memory\n",
808            pAG10E->psdp->device);
809        return FALSE;
810    }
811
812    mode->mode = pScrn->modes;
813    mode->flags = 0 /*DGA_PIXMAP_AVAILABLE | DGA_CONCURRENT_ACCESS*/;
814#if 0
815    if(!pAG10E->NoAccel) {
816        mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
817    }
818#endif
819
820    mode->imageWidth = mode->pixmapWidth = mode->viewportWidth =
821	pScrn->virtualX;
822    mode->imageHeight = mode->pixmapHeight = mode->viewportHeight =
823	pScrn->virtualY;
824
825    mode->bytesPerScanline = mode->imageWidth;
826
827    mode->byteOrder = pScrn->imageByteOrder;
828    mode->depth = 24;
829    mode->bitsPerPixel = 32;
830    mode->red_mask = pScrn->mask.red;
831    mode->green_mask = pScrn->mask.green;
832    mode->blue_mask = pScrn->mask.blue;
833
834    mode->visualClass = TrueColor;
835    mode->address = pAG10E->fb;
836
837    result = DGAInit(pScreen, &AG10E_DGAFuncs, mode, 1);
838
839    if (result) {
840    	xf86Msg(X_INFO, "%s: DGA initialized\n",
841            pAG10E->psdp->device);
842    } else {
843     	xf86Msg(X_WARNING, "%s: DGA setup failed\n",
844            pAG10E->psdp->device);
845    }
846}
847
848static Bool
849AG10E_OpenFramebuffer(ScrnInfoPtr pScrn, char **name, unsigned char **mem,
850				int *size, int *offset, int *extra)
851{
852    AG10EPtr pAG10E = GET_AG10E_FROM_SCRN(pScrn);
853
854    *name = pAG10E->psdp->device;
855
856    *mem = 0;
857    *size = pAG10E->vidmem;
858    *offset = 0;
859    *extra = 0;
860
861    return TRUE;
862}
863
864static Bool
865AG10E_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
866{
867    /*
868     * Nothing to do, we currently only support one mode
869     * and we are always in it.
870     */
871    return TRUE;
872}
873
874static void
875AG10E_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
876{
877     /* We don't support viewports, so... */
878}
879
880static int
881AG10E_GetViewport(ScrnInfoPtr pScrn)
882{
883    /* No viewports, none pending... */
884    return 0;
885}
886
887static void
888AG10E_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned long color)
889{
890#if 0
891    Cg6SetupForSolidFill(pScrn, color, GXset, 8);
892    Cg6SubsequentSolidFillRect(pScrn, x, y, w, h);
893#endif
894}
895
896static void
897AG10E_BlitRect(ScrnInfoPtr pScrn, int srcx, int srcy,
898			 int w, int h, int dstx, int dsty)
899{
900#if 0
901    Cg6SetupForScreenToScreenCopy(pScrn, 0, 0, GXcopy, 8, 0);
902    Cg6SubsequentScreenToScreenCopy(pScrn, srcx, srcy, dstx, dsty, w, h);
903#endif
904}
905