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