cg6_accel.c revision 70ca4aa4
1/*
2 * Sun GX and Turbo GX 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 "cg6.h"
26#include "cg6_regs.h"
27#include "dgaproc.h"
28
29
30static CARD32 Cg6BlitROP[] = {
31    ROP_BLIT(GX_ROP_CLEAR,  GX_ROP_CLEAR),	/* GXclear */
32    ROP_BLIT(GX_ROP_CLEAR,  GX_ROP_NOOP),	/* GXand */
33    ROP_BLIT(GX_ROP_CLEAR,  GX_ROP_INVERT),	/* GXandReverse */
34    ROP_BLIT(GX_ROP_CLEAR,  GX_ROP_SET),	/* GXcopy */
35    ROP_BLIT(GX_ROP_NOOP,   GX_ROP_CLEAR),	/* GXandInverted */
36    ROP_BLIT(GX_ROP_NOOP,   GX_ROP_NOOP),	/* GXnoop */
37    ROP_BLIT(GX_ROP_NOOP,   GX_ROP_INVERT),	/* GXxor */
38    ROP_BLIT(GX_ROP_NOOP,   GX_ROP_SET),	/* GXor */
39    ROP_BLIT(GX_ROP_INVERT, GX_ROP_CLEAR),	/* GXnor */
40    ROP_BLIT(GX_ROP_INVERT, GX_ROP_NOOP),	/* GXequiv */
41    ROP_BLIT(GX_ROP_INVERT, GX_ROP_INVERT),	/* GXinvert */
42    ROP_BLIT(GX_ROP_INVERT, GX_ROP_SET),	/* GXorReverse */
43    ROP_BLIT(GX_ROP_SET,    GX_ROP_CLEAR),	/* GXcopyInverted */
44    ROP_BLIT(GX_ROP_SET,    GX_ROP_NOOP),	/* GXorInverted */
45    ROP_BLIT(GX_ROP_SET,    GX_ROP_INVERT),	/* GXnand */
46    ROP_BLIT(GX_ROP_SET,    GX_ROP_SET),	/* GXset */
47};
48
49static CARD32 Cg6DrawROP[] = {
50    ROP_FILL(GX_ROP_CLEAR,  GX_ROP_CLEAR),	/* GXclear */
51    ROP_FILL(GX_ROP_CLEAR,  GX_ROP_NOOP),	/* GXand */
52    ROP_FILL(GX_ROP_CLEAR,  GX_ROP_INVERT),	/* GXandReverse */
53    ROP_FILL(GX_ROP_CLEAR,  GX_ROP_SET),	/* GXcopy */
54    ROP_FILL(GX_ROP_NOOP,   GX_ROP_CLEAR),	/* GXandInverted */
55    ROP_FILL(GX_ROP_NOOP,   GX_ROP_NOOP),	/* GXnoop */
56    ROP_FILL(GX_ROP_NOOP,   GX_ROP_INVERT),	/* GXxor */
57    ROP_FILL(GX_ROP_NOOP,   GX_ROP_SET),	/* GXor */
58    ROP_FILL(GX_ROP_INVERT, GX_ROP_CLEAR),	/* GXnor */
59    ROP_FILL(GX_ROP_INVERT, GX_ROP_NOOP),	/* GXequiv */
60    ROP_FILL(GX_ROP_INVERT, GX_ROP_INVERT),	/* GXinvert */
61    ROP_FILL(GX_ROP_INVERT, GX_ROP_SET),	/* GXorReverse */
62    ROP_FILL(GX_ROP_SET,    GX_ROP_CLEAR),	/* GXcopyInverted */
63    ROP_FILL(GX_ROP_SET,    GX_ROP_NOOP),	/* GXorInverted */
64    ROP_FILL(GX_ROP_SET,    GX_ROP_INVERT),	/* GXnand */
65    ROP_FILL(GX_ROP_SET,    GX_ROP_SET),	/* GXset */
66};
67
68static CARD32 Cg6StippleROP[16]={
69    ROP_STIP(GX_ROP_CLEAR,  GX_ROP_CLEAR),	/* GXclear */
70    ROP_STIP(GX_ROP_CLEAR,  GX_ROP_NOOP),	/* GXand */
71    ROP_STIP(GX_ROP_CLEAR,  GX_ROP_INVERT),	/* GXandReverse */
72    ROP_STIP(GX_ROP_CLEAR,  GX_ROP_SET),	/* GXcopy */
73    ROP_STIP(GX_ROP_NOOP,   GX_ROP_CLEAR),	/* GXandInverted */
74    ROP_STIP(GX_ROP_NOOP,   GX_ROP_NOOP),	/* GXnoop */
75    ROP_STIP(GX_ROP_NOOP,   GX_ROP_INVERT),	/* GXxor */
76    ROP_STIP(GX_ROP_NOOP,   GX_ROP_SET),	/* GXor */
77    ROP_STIP(GX_ROP_INVERT, GX_ROP_CLEAR),	/* GXnor */
78    ROP_STIP(GX_ROP_INVERT, GX_ROP_NOOP),	/* GXequiv */
79    ROP_STIP(GX_ROP_INVERT, GX_ROP_INVERT),	/* GXinvert */
80    ROP_STIP(GX_ROP_INVERT, GX_ROP_SET),	/* GXorReverse */
81    ROP_STIP(GX_ROP_SET,    GX_ROP_CLEAR),	/* GXcopyInverted */
82    ROP_STIP(GX_ROP_SET,    GX_ROP_NOOP),	/* GXorInverted */
83    ROP_STIP(GX_ROP_SET,    GX_ROP_INVERT),	/* GXnand */
84    ROP_STIP(GX_ROP_SET,    GX_ROP_SET),	/* GXset */
85};
86
87static CARD32 Cg6OpaqueStippleROP[16]={
88    ROP_OSTP(GX_ROP_CLEAR,  GX_ROP_CLEAR),	/* GXclear */
89    ROP_OSTP(GX_ROP_CLEAR,  GX_ROP_NOOP),	/* GXand */
90    ROP_OSTP(GX_ROP_CLEAR,  GX_ROP_INVERT),	/* GXandReverse */
91    ROP_OSTP(GX_ROP_CLEAR,  GX_ROP_SET),	/* GXcopy */
92    ROP_OSTP(GX_ROP_NOOP,   GX_ROP_CLEAR),	/* GXandInverted */
93    ROP_OSTP(GX_ROP_NOOP,   GX_ROP_NOOP),	/* GXnoop */
94    ROP_OSTP(GX_ROP_NOOP,   GX_ROP_INVERT),	/* GXxor */
95    ROP_OSTP(GX_ROP_NOOP,   GX_ROP_SET),	/* GXor */
96    ROP_OSTP(GX_ROP_INVERT, GX_ROP_CLEAR),	/* GXnor */
97    ROP_OSTP(GX_ROP_INVERT, GX_ROP_NOOP),	/* GXequiv */
98    ROP_OSTP(GX_ROP_INVERT, GX_ROP_INVERT),	/* GXinvert */
99    ROP_OSTP(GX_ROP_INVERT, GX_ROP_SET),	/* GXorReverse */
100    ROP_OSTP(GX_ROP_SET,    GX_ROP_CLEAR),	/* GXcopyInverted */
101    ROP_OSTP(GX_ROP_SET,    GX_ROP_NOOP),	/* GXorInverted */
102    ROP_OSTP(GX_ROP_SET,    GX_ROP_INVERT),	/* GXnand */
103    ROP_OSTP(GX_ROP_SET,    GX_ROP_SET),	/* GXset */
104};
105
106/* DGA stuff */
107
108static Bool Cg6_OpenFramebuffer(ScrnInfoPtr pScrn, char **, unsigned char **mem,
109    int *, int *, int *);
110static Bool Cg6_SetMode(ScrnInfoPtr, DGAModePtr);
111static void Cg6_SetViewport(ScrnInfoPtr, int, int, int);
112static int Cg6_GetViewport(ScrnInfoPtr);
113static void Cg6_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
114static void Cg6_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
115
116static void Cg6Sync(ScrnInfoPtr);
117
118static DGAFunctionRec Cg6_DGAFuncs = {
119	Cg6_OpenFramebuffer,
120	NULL,
121	Cg6_SetMode,
122	Cg6_SetViewport,
123	Cg6_GetViewport,
124	Cg6Sync,
125	Cg6_FillRect,
126	Cg6_BlitRect,
127	NULL
128};
129
130
131/*
132 * wait until the engine is idle
133 * unclip since clipping also influences framebuffer accesses
134 */
135static void
136Cg6Sync(ScrnInfoPtr pScrn)
137{
138    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
139
140    while (pCg6->fbc->s & GX_INPROGRESS);
141    pCg6->fbc->clipminx = 0;
142    pCg6->fbc->clipmaxx = pCg6->width;
143    pCg6->fbc->clipminy = 0;
144    pCg6->fbc->clipmaxy = pCg6->maxheight;
145}
146
147#define runDraw(pCg6) { volatile CARD32 rubbish = pCg6->fbc->draw; }
148#define runBlit(pCg6) { volatile CARD32 rubbish = pCg6->fbc->blit; }
149
150/*
151 * XXX
152 * was GX_FULL, which apparently isn't enough on some (slower) CG6 like
153 * the one found on the SPARCstation LX mainboard
154 */
155#define waitReady(pCg6) while(pCg6->fbc->s & GX_INPROGRESS)
156
157/*
158 * restore clipping values set by the Xserver since we're messing with them in
159 * CPU-to-screen colour expansion
160 */
161
162static void
163unClip(Cg6Ptr pCg6)
164{
165    pCg6->fbc->clipminx = pCg6->clipxa;
166    pCg6->fbc->clipmaxx = pCg6->clipxe;
167}
168
169void
170Cg6InitEngine(Cg6Ptr pCg6)
171{
172    pCg6->clipxa = 0;
173    pCg6->clipxe = pCg6->width;
174    pCg6->fbc->clipminx = 0;
175    pCg6->fbc->clipmaxx = pCg6->width;
176    pCg6->fbc->clipminy = 0;
177    pCg6->fbc->clipmaxy = pCg6->maxheight;
178
179    pCg6->fbc->mode = GX_BLIT_SRC |
180		GX_MODE_COLOR8 |
181		GX_DRAW_RENDER |
182		GX_BWRITE0_ENABLE |
183		GX_BWRITE1_DISABLE |
184		GX_BREAD_0 |
185		GX_BDISP_0;
186
187    pCg6->fbc->fg = 0xff;
188    pCg6->fbc->bg = 0x00;
189
190    /* we ignore the pixel mask anyway but for completeness... */
191    pCg6->fbc->pixelm = ~0;
192
193    pCg6->fbc->s = 0;
194    pCg6->fbc->clip = 0;
195    pCg6->fbc->offx = 0;
196    pCg6->fbc->offy = 0;
197    pCg6->fbc->incx = 0;
198    pCg6->fbc->incy = 0;
199}
200
201static void
202Cg6SetupForScreenToScreenCopy(
203    ScrnInfoPtr  pScrn,
204    int          xdir,
205    int          ydir,
206    int          rop,
207    unsigned int planemask,
208    int          TransparencyColour
209)
210{
211    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
212
213    waitReady(pCg6);
214    unClip(pCg6);
215
216    pCg6->fbc->mode = GX_BLIT_SRC |
217		GX_MODE_COLOR8 |
218		GX_DRAW_RENDER |
219		GX_BWRITE0_ENABLE |
220		GX_BWRITE1_DISABLE |
221		GX_BREAD_0 |
222		GX_BDISP_0;
223
224    /* we probably don't need the following three */
225    pCg6->fbc->fg = 0xff;
226    pCg6->fbc->bg = 0x00;
227    pCg6->fbc->s = 0;
228
229    pCg6->fbc->alu = Cg6BlitROP[rop];
230    pCg6->fbc->pm = planemask;
231}
232
233static void
234Cg6SubsequentScreenToScreenCopy
235(
236    ScrnInfoPtr pScrn,
237    int         xSrc,
238    int         ySrc,
239    int         xDst,
240    int         yDst,
241    int         w,
242    int         h
243)
244{
245    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
246
247    waitReady(pCg6);
248    pCg6->fbc->x0 = xSrc;
249    pCg6->fbc->y0 = ySrc;
250    pCg6->fbc->x1 = xSrc + w - 1;
251    pCg6->fbc->y1 = ySrc + h - 1;
252    pCg6->fbc->x2 = xDst;
253    pCg6->fbc->y2 = yDst;
254    pCg6->fbc->x3 = xDst + w - 1;
255    pCg6->fbc->y3 = yDst + h - 1;
256    runBlit(pCg6);
257}
258
259static void
260Cg6SetupForSolidFill
261(
262    ScrnInfoPtr  pScrn,
263    int          colour,
264    int          rop,
265    unsigned int planemask
266)
267{
268    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
269    CARD32 c2;
270
271    waitReady(pCg6);
272    unClip(pCg6);
273
274    pCg6->fbc->mode = GX_BLIT_SRC |
275		GX_MODE_COLOR8 |
276		GX_DRAW_RENDER |
277		GX_BWRITE0_ENABLE |
278		GX_BWRITE1_DISABLE |
279		GX_BREAD_0 |
280		GX_BDISP_0;
281    pCg6->fbc->fg = colour;
282    pCg6->fbc->s = 0;
283    pCg6->fbc->alu = Cg6DrawROP[rop];
284    pCg6->fbc->pm = planemask;
285}
286
287static void
288Cg6SubsequentSolidFillRect
289(
290    ScrnInfoPtr pScrn,
291    int         x,
292    int         y,
293    int         w,
294    int         h
295)
296{
297    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
298
299    waitReady(pCg6);
300    pCg6->fbc->arecty = y;
301    pCg6->fbc->arectx = x;
302    /* use the relative coordinate registers - saves two additions */
303    pCg6->fbc->rrecty = h - 1;
304    pCg6->fbc->rrectx = w - 1;
305    runDraw(pCg6);
306}
307
308static void
309Cg6SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
310        		int fg, int bg,
311			int rop,
312			unsigned int planemask)
313{
314    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
315
316    waitReady(pCg6);
317    pCg6->fbc->mode = GX_BLIT_NOSRC | GX_MODE_COLOR1;
318
319    if(bg == -1) {
320	/* transparent */
321	pCg6->fbc->alu = Cg6StippleROP[rop] | GX_PATTERN_ONES;
322	pCg6->fbc->bg = 0xff;
323    } else {
324	/* draw background */
325	pCg6->fbc->alu = Cg6OpaqueStippleROP[rop] | GX_PATTERN_ONES;
326	pCg6->fbc->bg = bg;
327    }
328    pCg6->fbc->fg = fg;
329    pCg6->fbc->incx = 32;
330    pCg6->fbc->incy = 0;
331    pCg6->fbc->s = 0;
332    pCg6->fbc->pm = planemask;
333}
334
335static void
336Cg6SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
337			int x, int y, int w, int h,
338			int skipleft )
339{
340    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
341
342    pCg6->scan_x = x;
343    pCg6->scan_xe = x + w - 1;
344    pCg6->scan_y = y;
345
346    /*
347     * we need to clip the left and right margins of what we're going to draw or
348     * we'll end up with garbage left or right
349     */
350    pCg6->fbc->clipminx = x + skipleft;
351    pCg6->fbc->clipmaxx = x + w - 1;
352    pCg6->words_in_scanline = ((w + 31) >> 5);
353}
354
355static void
356Cg6SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
357{
358    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
359    int i;
360
361    /*
362     * the GX is WEIRD. if we tell it to draw n pixels it will fill the entire
363     * line with whatever we feed into the font register. When we write the next
364     * word it draws the entire line AGAIN. So we turn on clipping and pretend
365     * to write only 32 pixels...
366     */
367    pCg6->fbc->x0 = pCg6->scan_x;
368    pCg6->fbc->x1 = pCg6->scan_x + 31;
369    pCg6->fbc->y0 = pCg6->scan_y;
370    for (i = 0; i < pCg6->words_in_scanline; i++) {
371	pCg6->fbc->font = pCg6->scanline[i];
372    }
373    pCg6->scan_y++;
374}
375
376static void
377Cg6SetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
378    unsigned int planemask)
379{
380    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
381
382    waitReady(pCg6);
383    unClip(pCg6);
384
385    pCg6->fbc->fg = color;
386    pCg6->fbc->mode = GX_BLIT_NOSRC;
387    pCg6->fbc->s = 0;
388    pCg6->fbc->alu = Cg6DrawROP[rop];
389    pCg6->fbc->pm = planemask;
390}
391
392static void
393Cg6SubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2,
394    int y2, int flags)
395{
396    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
397
398    /*
399     * XXX we're blatantly ignoring the flags parameter which could tell us not
400     * to draw the last point. Xsun simply reads it from the framebuffer and
401     * puts it back after drawing the line but that would mean we have to wait
402     * until the line is actually drawn. On the other hand - line drawing is
403     * pretty fast so we won't lose too much speed
404     */
405    waitReady(pCg6);
406    pCg6->fbc->aliney = y1;
407    pCg6->fbc->alinex = x1;
408    pCg6->fbc->aliney = y2;
409    pCg6->fbc->alinex = x2;
410    runDraw(pCg6);
411}
412
413static void
414Cg6SetClippingRectangle(ScrnInfoPtr pScrn, int left, int top, int right,
415			 int bottom)
416{
417    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
418
419    pCg6->fbc->clipminx = pCg6->clipxa = left;
420    pCg6->fbc->clipminy = top;
421    pCg6->fbc->clipmaxx = pCg6->clipxe = right;
422    pCg6->fbc->clipmaxy = bottom;
423}
424
425static void
426Cg6DisableClipping(ScrnInfoPtr pScrn)
427{
428    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
429
430    pCg6->fbc->clipminx = pCg6->clipxa = 0;
431    pCg6->fbc->clipminy = 0;
432    pCg6->fbc->clipmaxx = pCg6->clipxe = pCg6->width;
433    pCg6->fbc->clipmaxy = pCg6->maxheight;
434}
435
436int
437CG6AccelInit(ScrnInfoPtr pScrn)
438{
439    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
440    XAAInfoRecPtr pXAAInfo = pCg6->pXAA;
441
442    pXAAInfo->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
443    pXAAInfo->maxOffPixWidth = pCg6->width;
444    pXAAInfo->maxOffPixHeight = pCg6->maxheight;
445
446    Cg6InitEngine(pCg6);
447
448    /* wait until the engine is idle and remove clipping */
449    pXAAInfo->Sync = Cg6Sync;
450
451    /* clipping */
452    pXAAInfo->SetClippingRectangle = Cg6SetClippingRectangle;
453    pXAAInfo->DisableClipping = Cg6DisableClipping;
454    pXAAInfo->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
455        HARDWARE_CLIP_SOLID_FILL |
456        /*HARDWARE_CLIP_MONO_8x8_FILL |
457        HARDWARE_CLIP_COLOR_8x8_FILL |*/
458        HARDWARE_CLIP_SOLID_LINE;
459
460    /* Screen-to-screen copy */
461    pXAAInfo->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
462    pXAAInfo->SetupForScreenToScreenCopy = Cg6SetupForScreenToScreenCopy;
463    pXAAInfo->SubsequentScreenToScreenCopy =
464        Cg6SubsequentScreenToScreenCopy;
465
466    /* Solid fills */
467    pXAAInfo->SetupForSolidFill = Cg6SetupForSolidFill;
468    pXAAInfo->SubsequentSolidFillRect = Cg6SubsequentSolidFillRect;
469
470    /* TODO: add pattern fills */
471
472    /* colour expansion */
473    pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags =
474	LEFT_EDGE_CLIPPING|SCANLINE_PAD_DWORD;
475    pXAAInfo->NumScanlineColorExpandBuffers = 1;
476    pCg6->buffers[0] = (unsigned char *)pCg6->scanline;
477    pXAAInfo->ScanlineColorExpandBuffers = pCg6->buffers;
478    pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill =
479	Cg6SetupForCPUToScreenColorExpandFill;
480    pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill =
481	Cg6SubsequentScanlineCPUToScreenColorExpandFill;
482    pXAAInfo->SubsequentColorExpandScanline =
483	Cg6SubsequentColorExpandScanline;
484
485    /* line drawing */
486    pXAAInfo->SetupForSolidLine = Cg6SetupForSolidLine;
487    pXAAInfo->SubsequentSolidTwoPointLine = Cg6SubsequentSolidTwoPointLine;
488    pXAAInfo->SolidLineFlags = BIT_ORDER_IN_BYTE_MSBFIRST;
489    /*
490     * apparently the hardware can't do dashed lines, only lines with patterns
491     * which isn't useful
492     */
493
494    /* TODO: add host-to-vram colour blits */
495
496    return 0;
497}
498
499Bool
500Cg6DGAInit(ScreenPtr pScreen)
501{
502    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
503    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
504    DGAModePtr mode;
505    int result;
506
507    mode = xnfcalloc(sizeof(DGAModeRec), 1);
508    if (mode == NULL) {
509        xf86Msg(X_WARNING, "%s: DGA setup failed, cannot allocate memory\n",
510            pCg6->psdp->device);
511        return FALSE;
512    }
513
514    mode->mode = pScrn->modes;
515    mode->flags = DGA_PIXMAP_AVAILABLE | DGA_CONCURRENT_ACCESS;
516    if(!pCg6->NoAccel) {
517        mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
518    }
519
520    mode->imageWidth = mode->pixmapWidth = mode->viewportWidth =
521	pScrn->virtualX;
522    mode->imageHeight = mode->pixmapHeight = mode->viewportHeight =
523	pScrn->virtualY;
524
525    mode->bytesPerScanline = mode->imageWidth;
526
527    mode->byteOrder = pScrn->imageByteOrder;
528    mode->depth = 8;
529    mode->bitsPerPixel = 8;
530    mode->red_mask = pScrn->mask.red;
531    mode->green_mask = pScrn->mask.green;
532    mode->blue_mask = pScrn->mask.blue;
533
534    mode->visualClass = PseudoColor;
535    mode->address = pCg6->fb;
536
537    result = DGAInit(pScreen, &Cg6_DGAFuncs, mode, 1);
538
539    if (result) {
540    	xf86Msg(X_INFO, "%s: DGA initialized\n",
541            pCg6->psdp->device);
542    } else {
543     	xf86Msg(X_WARNING, "%s: DGA setup failed\n",
544            pCg6->psdp->device);
545    }
546}
547
548static Bool
549Cg6_OpenFramebuffer(ScrnInfoPtr pScrn, char **name,
550				unsigned char **mem,
551				int *size, int *offset,
552				int *extra)
553{
554    Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn);
555
556    *name = pCg6->psdp->device;
557
558    *mem = (unsigned char*)CG6_RAM_VOFF;
559    *size = pCg6->vidmem;
560    *offset = 0;
561    *extra = 0;
562
563    return TRUE;
564}
565
566static Bool
567Cg6_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
568{
569    /*
570     * Nothing to do, we currently only support one mode
571     * and we are always in it.
572     */
573    return TRUE;
574}
575
576static void
577Cg6_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
578{
579     /* We don't support viewports, so... */
580}
581
582static int
583Cg6_GetViewport(ScrnInfoPtr pScrn)
584{
585    /* No viewports, none pending... */
586    return 0;
587}
588
589static void
590Cg6_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned long color)
591{
592
593    Cg6SetupForSolidFill(pScrn, color, GXset, 8);
594    Cg6SubsequentSolidFillRect(pScrn, x, y, w, h);
595}
596
597static void
598Cg6_BlitRect(ScrnInfoPtr pScrn, int srcx, int srcy,
599			 int w, int h, int dstx, int dsty)
600{
601
602    Cg6SetupForScreenToScreenCopy(pScrn, 0, 0, GXcopy, 8, 0);
603    Cg6SubsequentScreenToScreenCopy(pScrn, srcx, srcy, dstx, dsty, w, h);
604}
605