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