ct_dga.c revision a1d73b4b
1c06b6b69Smrg
2c06b6b69Smrg#ifdef HAVE_CONFIG_H
3c06b6b69Smrg#include "config.h"
4c06b6b69Smrg#endif
5c06b6b69Smrg
6c06b6b69Smrg#include "xf86.h"
7c06b6b69Smrg#include "xf86_OSproc.h"
8c06b6b69Smrg#include "xf86Pci.h"
9c06b6b69Smrg#include "ct_driver.h"
10c06b6b69Smrg#include "dgaproc.h"
11c06b6b69Smrg
12c06b6b69Smrg
13c06b6b69Smrgstatic Bool CHIPS_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
14c06b6b69Smrg					int *, int *, int *);
15c06b6b69Smrgstatic Bool CHIPS_SetMode(ScrnInfoPtr, DGAModePtr);
16c06b6b69Smrgstatic int  CHIPS_GetViewport(ScrnInfoPtr);
17c06b6b69Smrgstatic void CHIPS_SetViewport(ScrnInfoPtr, int, int, int);
18a1d73b4bSmrg#ifdef HAVE_XAA_H
19c06b6b69Smrgstatic void CHIPS_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
20c06b6b69Smrgstatic void CHIPS_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
21c06b6b69Smrg#if 0
22c06b6b69Smrgstatic void CHIPS_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
23c06b6b69Smrg					unsigned long);
24c06b6b69Smrg#endif
25a1d73b4bSmrg#endif
26c06b6b69Smrg
27c06b6b69Smrgstatic
28c06b6b69SmrgDGAFunctionRec CHIPS_DGAFuncs = {
29c06b6b69Smrg   CHIPS_OpenFramebuffer,
30c06b6b69Smrg   NULL,
31c06b6b69Smrg   CHIPS_SetMode,
32c06b6b69Smrg   CHIPS_SetViewport,
33c06b6b69Smrg   CHIPS_GetViewport,
34a1d73b4bSmrg#ifdef HAVE_XAA_H
35c06b6b69Smrg   CHIPSSync,
36c06b6b69Smrg   CHIPS_FillRect,
37c06b6b69Smrg   CHIPS_BlitRect,
38c06b6b69Smrg#if 0
39c06b6b69Smrg   CHIPS_BlitTransRect
40c06b6b69Smrg#else
41c06b6b69Smrg   NULL
42c06b6b69Smrg#endif
43a1d73b4bSmrg#else
44a1d73b4bSmrg   NULL, NULL, NULL, NULL
45a1d73b4bSmrg#endif
46c06b6b69Smrg};
47c06b6b69Smrg
48c06b6b69Smrgstatic
49c06b6b69SmrgDGAFunctionRec CHIPS_MMIODGAFuncs = {
50c06b6b69Smrg   CHIPS_OpenFramebuffer,
51c06b6b69Smrg   NULL,
52c06b6b69Smrg   CHIPS_SetMode,
53c06b6b69Smrg   CHIPS_SetViewport,
54c06b6b69Smrg   CHIPS_GetViewport,
55a1d73b4bSmrg#ifdef HAVE_XAA_H
56c06b6b69Smrg   CHIPSMMIOSync,
57c06b6b69Smrg   CHIPS_FillRect,
58c06b6b69Smrg   CHIPS_BlitRect,
59c06b6b69Smrg#if 0
60c06b6b69Smrg   CHIPS_BlitTransRect
61c06b6b69Smrg#else
62c06b6b69Smrg   NULL
63c06b6b69Smrg#endif
64a1d73b4bSmrg#else
65a1d73b4bSmrg   NULL, NULL, NULL, NULL
66a1d73b4bSmrg#endif
67c06b6b69Smrg};
68c06b6b69Smrg
69c06b6b69Smrgstatic
70c06b6b69SmrgDGAFunctionRec CHIPS_HiQVDGAFuncs = {
71c06b6b69Smrg   CHIPS_OpenFramebuffer,
72c06b6b69Smrg   NULL,
73c06b6b69Smrg   CHIPS_SetMode,
74c06b6b69Smrg   CHIPS_SetViewport,
75c06b6b69Smrg   CHIPS_GetViewport,
76a1d73b4bSmrg#ifdef HAVE_XAA_H
77c06b6b69Smrg   CHIPSHiQVSync,
78c06b6b69Smrg   CHIPS_FillRect,
79c06b6b69Smrg   CHIPS_BlitRect,
80c06b6b69Smrg#if 0
81c06b6b69Smrg   CHIPS_BlitTransRect
82c06b6b69Smrg#else
83c06b6b69Smrg   NULL
84c06b6b69Smrg#endif
85a1d73b4bSmrg#else
86a1d73b4bSmrg   NULL, NULL, NULL, NULL
87a1d73b4bSmrg#endif
88c06b6b69Smrg};
89c06b6b69Smrg
90c06b6b69Smrg
91c06b6b69SmrgBool
92c06b6b69SmrgCHIPSDGAInit(ScreenPtr pScreen)
93c06b6b69Smrg{
94a1d73b4bSmrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
95c06b6b69Smrg   CHIPSPtr cPtr = CHIPSPTR(pScrn);
96c06b6b69Smrg   DGAModePtr modes = NULL, newmodes = NULL, currentMode;
97c06b6b69Smrg   DisplayModePtr pMode, firstMode;
98c06b6b69Smrg   int Bpp = pScrn->bitsPerPixel >> 3;
99c06b6b69Smrg   int num = 0;
100c06b6b69Smrg   Bool oneMore;
101c06b6b69Smrg   int imlines =  (pScrn->videoRam * 1024) /
102c06b6b69Smrg      (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
103c06b6b69Smrg
104c06b6b69Smrg   pMode = firstMode = pScrn->modes;
105c06b6b69Smrg
106c06b6b69Smrg   while(pMode) {
107c06b6b69Smrg
108c06b6b69Smrg	if(0 /*pScrn->displayWidth != pMode->HDisplay*/) {
1093699b6c4Smrg	    newmodes = realloc(modes, (num + 2) * sizeof(DGAModeRec));
110c06b6b69Smrg	    oneMore = TRUE;
111c06b6b69Smrg	} else {
1123699b6c4Smrg	    newmodes = realloc(modes, (num + 1) * sizeof(DGAModeRec));
113c06b6b69Smrg	    oneMore = FALSE;
114c06b6b69Smrg	}
115c06b6b69Smrg
116c06b6b69Smrg	if(!newmodes) {
1173699b6c4Smrg	   free(modes);
118c06b6b69Smrg	   return FALSE;
119c06b6b69Smrg	}
120c06b6b69Smrg	modes = newmodes;
121c06b6b69Smrg
122c06b6b69SmrgSECOND_PASS:
123c06b6b69Smrg
124c06b6b69Smrg	currentMode = modes + num;
125c06b6b69Smrg	num++;
126c06b6b69Smrg
127c06b6b69Smrg	currentMode->mode = pMode;
128c06b6b69Smrg	currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
129a1d73b4bSmrg#ifdef HAVE_XAA_H
130c06b6b69Smrg	if(cPtr->Flags & ChipsAccelSupport)
131c06b6b69Smrg	   currentMode->flags |= (cPtr->Flags & ChipsAccelSupport)
132c06b6b69Smrg	     ? (DGA_FILL_RECT | DGA_BLIT_RECT) : 0;
133a1d73b4bSmrg#endif
134c06b6b69Smrg	if(pMode->Flags & V_DBLSCAN)
135c06b6b69Smrg	   currentMode->flags |= DGA_DOUBLESCAN;
136c06b6b69Smrg	if(pMode->Flags & V_INTERLACE)
137c06b6b69Smrg	   currentMode->flags |= DGA_INTERLACED;
138c06b6b69Smrg	currentMode->byteOrder = pScrn->imageByteOrder;
139c06b6b69Smrg	currentMode->depth = pScrn->depth;
140c06b6b69Smrg	currentMode->bitsPerPixel = pScrn->bitsPerPixel;
141c06b6b69Smrg	currentMode->red_mask = pScrn->mask.red;
142c06b6b69Smrg	currentMode->green_mask = pScrn->mask.green;
143c06b6b69Smrg	currentMode->blue_mask = pScrn->mask.blue;
144c06b6b69Smrg	currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
145c06b6b69Smrg	currentMode->viewportWidth = pMode->HDisplay;
146c06b6b69Smrg	currentMode->viewportHeight = pMode->VDisplay;
147c06b6b69Smrg	currentMode->xViewportStep = 1;
148c06b6b69Smrg	currentMode->yViewportStep = 1;
149c06b6b69Smrg 	currentMode->viewportFlags = DGA_FLIP_RETRACE | DGA_FLIP_IMMEDIATE;
150c06b6b69Smrg	currentMode->offset = 0;
151c06b6b69Smrg	currentMode->address = cPtr->FbBase;
152c06b6b69Smrg
153c06b6b69Smrg	if(oneMore) { /* first one is narrow width */
154c06b6b69Smrg	    currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
155c06b6b69Smrg	    currentMode->imageWidth = pMode->HDisplay;
156c06b6b69Smrg	    currentMode->imageHeight =  imlines;
157c06b6b69Smrg	    currentMode->pixmapWidth = currentMode->imageWidth;
158c06b6b69Smrg	    currentMode->pixmapHeight = currentMode->imageHeight;
159c06b6b69Smrg	    currentMode->maxViewportX = currentMode->imageWidth -
160c06b6b69Smrg					currentMode->viewportWidth;
161c06b6b69Smrg	    /* this might need to get clamped to some maximum */
162c06b6b69Smrg	    currentMode->maxViewportY = currentMode->imageHeight -
163c06b6b69Smrg					currentMode->viewportHeight;
164c06b6b69Smrg	    oneMore = FALSE;
165c06b6b69Smrg	    goto SECOND_PASS;
166c06b6b69Smrg	} else {
167c06b6b69Smrg	    currentMode->bytesPerScanline =
168c06b6b69Smrg			((pScrn->displayWidth * Bpp) + 3) & ~3L;
169c06b6b69Smrg	    currentMode->imageWidth = pScrn->displayWidth;
170c06b6b69Smrg	    currentMode->imageHeight =  imlines;
171c06b6b69Smrg	    currentMode->pixmapWidth = currentMode->imageWidth;
172c06b6b69Smrg	    currentMode->pixmapHeight = currentMode->imageHeight;
173c06b6b69Smrg	    currentMode->maxViewportX = currentMode->imageWidth -
174c06b6b69Smrg					currentMode->viewportWidth;
175c06b6b69Smrg	    /* this might need to get clamped to some maximum */
176c06b6b69Smrg	    currentMode->maxViewportY = currentMode->imageHeight -
177c06b6b69Smrg					currentMode->viewportHeight;
178c06b6b69Smrg	}
179c06b6b69Smrg
180c06b6b69Smrg	pMode = pMode->next;
181c06b6b69Smrg	if(pMode == firstMode)
182c06b6b69Smrg	   break;
183c06b6b69Smrg   }
184c06b6b69Smrg
185c06b6b69Smrg   cPtr->numDGAModes = num;
186c06b6b69Smrg   cPtr->DGAModes = modes;
187c06b6b69Smrg
188c06b6b69Smrg   if (IS_HiQV(cPtr)) {
189c06b6b69Smrg	return DGAInit(pScreen, &CHIPS_HiQVDGAFuncs, modes, num);
190c06b6b69Smrg   } else {
191c06b6b69Smrg	if(!cPtr->UseMMIO) {
192c06b6b69Smrg	    return DGAInit(pScreen, &CHIPS_DGAFuncs, modes, num);
193c06b6b69Smrg	} else {
194c06b6b69Smrg	    return DGAInit(pScreen, &CHIPS_MMIODGAFuncs, modes, num);
195c06b6b69Smrg	}
196c06b6b69Smrg   }
197c06b6b69Smrg}
198c06b6b69Smrg
199c06b6b69Smrg
200c06b6b69Smrgstatic Bool
201c06b6b69SmrgCHIPS_SetMode(
202c06b6b69Smrg   ScrnInfoPtr pScrn,
203c06b6b69Smrg   DGAModePtr pMode
204c06b6b69Smrg){
205c06b6b69Smrg   static int OldDisplayWidth[MAXSCREENS];
206c06b6b69Smrg   int index = pScrn->pScreen->myNum;
207c06b6b69Smrg
208c06b6b69Smrg   CHIPSPtr cPtr = CHIPSPTR(pScrn);
209c06b6b69Smrg
210c06b6b69Smrg   if (!pMode) { /* restore the original mode */
211c06b6b69Smrg	/* put the ScreenParameters back */
212c06b6b69Smrg       if (cPtr->DGAactive) {
213c06b6b69Smrg           pScrn->displayWidth = OldDisplayWidth[index];
214a1d73b4bSmrg	   pScrn->EnterVT(VT_FUNC_ARGS);
215c06b6b69Smrg
216c06b6b69Smrg	   cPtr->DGAactive = FALSE;
217c06b6b69Smrg       }
218c06b6b69Smrg   } else {
219c06b6b69Smrg	if(!cPtr->DGAactive) {  /* save the old parameters */
220c06b6b69Smrg	    OldDisplayWidth[index] = pScrn->displayWidth;
221a1d73b4bSmrg	    pScrn->LeaveVT(VT_FUNC_ARGS);
222c06b6b69Smrg	    cPtr->DGAactive = TRUE;
223c06b6b69Smrg	}
224c06b6b69Smrg
225c06b6b69Smrg	pScrn->displayWidth = pMode->bytesPerScanline /
226c06b6b69Smrg			      (pMode->bitsPerPixel >> 3);
227c06b6b69Smrg
228a1d73b4bSmrg        CHIPSSwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode));
229c06b6b69Smrg   }
230c06b6b69Smrg
231c06b6b69Smrg   return TRUE;
232c06b6b69Smrg}
233c06b6b69Smrg
234c06b6b69Smrg
235c06b6b69Smrg
236c06b6b69Smrgstatic int
237c06b6b69SmrgCHIPS_GetViewport(
238c06b6b69Smrg  ScrnInfoPtr pScrn
239c06b6b69Smrg){
240c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
241c06b6b69Smrg
242c06b6b69Smrg    return cPtr->DGAViewportStatus;
243c06b6b69Smrg}
244c06b6b69Smrg
245c06b6b69Smrgstatic void
246c06b6b69SmrgCHIPS_SetViewport(
247c06b6b69Smrg   ScrnInfoPtr pScrn,
248c06b6b69Smrg   int x, int y,
249c06b6b69Smrg   int flags
250c06b6b69Smrg   ){
251c06b6b69Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
252c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
253c06b6b69Smrg
254c06b6b69Smrg    if (flags & DGA_FLIP_RETRACE) {
2553699b6c4Smrg	while ((hwp->readST01(hwp)) & 0x08){};
2563699b6c4Smrg	while (!((hwp->readST01(hwp)) & 0x08)){};
257c06b6b69Smrg    }
258c06b6b69Smrg
259a1d73b4bSmrg    CHIPSAdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y));
260c06b6b69Smrg    cPtr->DGAViewportStatus = 0;  /* CHIPSAdjustFrame loops until finished */
261c06b6b69Smrg}
262c06b6b69Smrg
263a1d73b4bSmrg#ifdef HAVE_XAA_H
264c06b6b69Smrgstatic void
265c06b6b69SmrgCHIPS_FillRect (
266c06b6b69Smrg   ScrnInfoPtr pScrn,
267c06b6b69Smrg   int x, int y, int w, int h,
268c06b6b69Smrg   unsigned long color
269c06b6b69Smrg){
270c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
271c06b6b69Smrg
272c06b6b69Smrg    if(cPtr->AccelInfoRec) {
273c06b6b69Smrg	(*cPtr->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
274c06b6b69Smrg	(*cPtr->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
275c06b6b69Smrg	SET_SYNC_FLAG(cPtr->AccelInfoRec);
276c06b6b69Smrg    }
277c06b6b69Smrg}
278c06b6b69Smrg
279c06b6b69Smrgstatic void
280c06b6b69SmrgCHIPS_BlitRect(
281c06b6b69Smrg   ScrnInfoPtr pScrn,
282c06b6b69Smrg   int srcx, int srcy,
283c06b6b69Smrg   int w, int h,
284c06b6b69Smrg   int dstx, int dsty
285c06b6b69Smrg){
286c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
287c06b6b69Smrg
288c06b6b69Smrg    if(cPtr->AccelInfoRec) {
289c06b6b69Smrg	int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
290c06b6b69Smrg	int ydir = (srcy < dsty) ? -1 : 1;
291c06b6b69Smrg
292c06b6b69Smrg	(*cPtr->AccelInfoRec->SetupForScreenToScreenCopy)(
293c06b6b69Smrg		pScrn, xdir, ydir, GXcopy, ~0, -1);
294c06b6b69Smrg	(*cPtr->AccelInfoRec->SubsequentScreenToScreenCopy)(
295c06b6b69Smrg		pScrn, srcx, srcy, dstx, dsty, w, h);
296c06b6b69Smrg	SET_SYNC_FLAG(cPtr->AccelInfoRec);
297c06b6b69Smrg    }
298c06b6b69Smrg}
299c06b6b69Smrg
300c06b6b69Smrg#if 0
301c06b6b69Smrgstatic void
302c06b6b69SmrgCHIPS_BlitTransRect(
303c06b6b69Smrg   ScrnInfoPtr pScrn,
304c06b6b69Smrg   int srcx, int srcy,
305c06b6b69Smrg   int w, int h,
306c06b6b69Smrg   int dstx, int dsty,
307c06b6b69Smrg   unsigned long color
308c06b6b69Smrg){
309c06b6b69Smrg  /* this one should be separate since the XAA function would
310c06b6b69Smrg     prohibit usage of ~0 as the key */
311c06b6b69Smrg}
312c06b6b69Smrg#endif
313a1d73b4bSmrg#endif
314c06b6b69Smrgstatic Bool
315c06b6b69SmrgCHIPS_OpenFramebuffer(
316c06b6b69Smrg   ScrnInfoPtr pScrn,
317c06b6b69Smrg   char **name,
318c06b6b69Smrg   unsigned char **mem,
319c06b6b69Smrg   int *size,
320c06b6b69Smrg   int *offset,
321c06b6b69Smrg   int *flags
322c06b6b69Smrg){
323c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
324c06b6b69Smrg
325c06b6b69Smrg    *name = NULL; 		/* no special device */
326c06b6b69Smrg    *mem = (unsigned char*)cPtr->FbAddress;
327c06b6b69Smrg    *size = cPtr->FbMapSize;
328c06b6b69Smrg    *offset = 0;
329c06b6b69Smrg    *flags = DGA_NEED_ROOT;
330c06b6b69Smrg
331c06b6b69Smrg    return TRUE;
332c06b6b69Smrg}
333