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