s3v_dga.c revision eb61724e
1
2/*
3Copyright (C) 1994-2000 The XFree86 Project, Inc.  All Rights Reserved.
4
5Permission is hereby granted, free of charge, to any person obtaining a copy of
6this software and associated documentation files (the "Software"), to deal in
7the Software without restriction, including without limitation the rights to
8use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9of the Software, and to permit persons to whom the Software is furnished to do
10so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in all
13copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
17NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of the XFree86 Project shall not
23be used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from the XFree86 Project.
25*/
26
27/*
28Copyright (C) 1994-2000 The XFree86 Project, Inc.  All Rights Reserved.
29
30Permission is hereby granted, free of charge, to any person obtaining a copy of
31this software and associated documentation files (the "Software"), to deal in
32the Software without restriction, including without limitation the rights to
33use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
34of the Software, and to permit persons to whom the Software is furnished to do
35so, subject to the following conditions:
36
37The above copyright notice and this permission notice shall be included in all
38copies or substantial portions of the Software.
39
40THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
42NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
43XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
44AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
45WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46
47Except as contained in this notice, the name of the XFree86 Project shall not
48be used in advertising or otherwise to promote the sale, use or other dealings
49in this Software without prior written authorization from the XFree86 Project.
50*/
51
52/*
53 * file: s3v_dga.c
54 * ported from mga
55 *
56 */
57
58#ifdef HAVE_CONFIG_H
59#include "config.h"
60#endif
61
62#include "xf86.h"
63#include "xf86_OSproc.h"
64#include "xf86Pci.h"
65#include "xf86PciInfo.h"
66#include "xaa.h"
67#include "xaalocal.h"
68#include "s3v.h"
69
70#include "dgaproc.h"
71
72
73static Bool S3V_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
74					int *, int *, int *);
75static Bool S3V_SetMode(ScrnInfoPtr, DGAModePtr);
76static int  S3V_GetViewport(ScrnInfoPtr);
77static void S3V_SetViewport(ScrnInfoPtr, int, int, int);
78static void S3V_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
79static void S3V_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
80/* dummy... */
81
82
83static
84DGAFunctionRec S3V_DGAFuncs = {
85   S3V_OpenFramebuffer,
86   NULL,
87   S3V_SetMode,
88   S3V_SetViewport,
89   S3V_GetViewport,
90   S3VAccelSync,
91   S3V_FillRect,
92   S3V_BlitRect,
93   NULL
94   /* dummy... MGA_BlitTransRect */
95};
96
97
98Bool
99S3VDGAInit(ScreenPtr pScreen)
100{
101   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
102   S3VPtr ps3v = S3VPTR(pScrn);
103   DGAModePtr modes = NULL, newmodes = NULL, currentMode;
104   DisplayModePtr pMode, firstMode;
105   int Bpp = pScrn->bitsPerPixel >> 3;
106   int num = 0;
107   Bool oneMore;
108
109   PVERB5("	S3VDGAInit\n");
110
111   pMode = firstMode = pScrn->modes;
112
113   while(pMode) {
114	/* The MGA driver wasn't designed with switching depths in
115	   mind.  Subsequently, large chunks of it will probably need
116	   to be rewritten to accommodate depth changes in DGA mode */
117
118	if(0 /*pScrn->displayWidth != pMode->HDisplay*/) {
119	    newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec));
120	    oneMore = TRUE;
121	} else {
122	    newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
123	    oneMore = FALSE;
124	}
125
126	if(!newmodes) {
127	   xfree(modes);
128	   return FALSE;
129	}
130	modes = newmodes;
131
132SECOND_PASS:
133
134	currentMode = modes + num;
135	num++;
136
137	currentMode->mode = pMode;
138	currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
139	if(!ps3v->NoAccel)
140	   currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
141	if(pMode->Flags & V_DBLSCAN)
142	   currentMode->flags |= DGA_DOUBLESCAN;
143	if(pMode->Flags & V_INTERLACE)
144	   currentMode->flags |= DGA_INTERLACED;
145	currentMode->byteOrder = pScrn->imageByteOrder;
146	currentMode->depth = pScrn->depth;
147	currentMode->bitsPerPixel = pScrn->bitsPerPixel;
148	currentMode->red_mask = pScrn->mask.red;
149	currentMode->green_mask = pScrn->mask.green;
150	currentMode->blue_mask = pScrn->mask.blue;
151	currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
152	currentMode->viewportWidth = pMode->HDisplay;
153	currentMode->viewportHeight = pMode->VDisplay;
154	/* currentMode->xViewportStep = (3 - ps3v->BppShift); */
155				/* always 1 on ViRGE ? */
156	currentMode->xViewportStep = 1;
157	currentMode->yViewportStep = 1;
158	currentMode->viewportFlags = DGA_FLIP_RETRACE;
159	/* currentMode->offset = ps3v->YDstOrg * (pScrn->bitsPerPixel / 8);
160	 * MGA, 0 for ViRGE */
161	currentMode->offset = 0;
162	/* currentMode->address = pMga->FbStart;   MGA */
163	currentMode->address = ps3v->FBBase;
164/*cep*/
165  xf86ErrorFVerb(VERBLEV,
166	"	S3VDGAInit firstone vpWid=%d, vpHgt=%d, Bpp=%d, mdbitsPP=%d\n",
167		currentMode->viewportWidth,
168		currentMode->viewportHeight,
169		Bpp,
170		currentMode->bitsPerPixel
171		 );
172
173
174	if(oneMore) { /* first one is narrow width */
175	    currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
176	    currentMode->imageWidth = pMode->HDisplay;
177	    /* currentMode->imageHeight =  pMga->FbUsableSize /
178					currentMode->bytesPerScanline;
179					MGA above */
180	    currentMode->imageHeight =  pMode->VDisplay;
181	    currentMode->pixmapWidth = currentMode->imageWidth;
182	    currentMode->pixmapHeight = currentMode->imageHeight;
183	    currentMode->maxViewportX = currentMode->imageWidth -
184					currentMode->viewportWidth;
185	    /* this might need to get clamped to some maximum */
186	    currentMode->maxViewportY = currentMode->imageHeight -
187					currentMode->viewportHeight;
188	    oneMore = FALSE;
189
190/*cep*/
191  xf86ErrorFVerb(VERBLEV,
192	"	S3VDGAInit imgHgt=%d, ram=%d, bytesPerScanl=%d\n",
193		currentMode->imageHeight,
194		ps3v->videoRambytes,
195		currentMode->bytesPerScanline );
196
197	    goto SECOND_PASS;
198	} else {
199	    currentMode->bytesPerScanline =
200			((pScrn->displayWidth * Bpp) + 3) & ~3L;
201	    currentMode->imageWidth = pScrn->displayWidth;
202	    /* currentMode->imageHeight =  pMga->FbUsableSize /
203					currentMode->bytesPerScanline;
204					*/
205	    currentMode->imageHeight =  ps3v->videoRambytes /
206	    			currentMode->bytesPerScanline;
207	    currentMode->pixmapWidth = currentMode->imageWidth;
208	    currentMode->pixmapHeight = currentMode->imageHeight;
209	    currentMode->maxViewportX = currentMode->imageWidth -
210					currentMode->viewportWidth;
211	    /* this might need to get clamped to some maximum */
212	    currentMode->maxViewportY = currentMode->imageHeight -
213					currentMode->viewportHeight;
214	}
215
216	pMode = pMode->next;
217	if(pMode == firstMode)
218	   break;
219   }
220
221   ps3v->numDGAModes = num;
222   ps3v->DGAModes = modes;
223
224   return DGAInit(pScreen, &S3V_DGAFuncs, modes, num);
225}
226
227
228static Bool
229S3V_SetMode(
230   ScrnInfoPtr pScrn,
231   DGAModePtr pMode
232){
233   static int OldDisplayWidth[MAXSCREENS];
234   int index = pScrn->pScreen->myNum;
235
236   S3VPtr ps3v = S3VPTR(pScrn);
237
238   if(!pMode) { /* restore the original mode */
239	/* put the ScreenParameters back */
240
241	pScrn->displayWidth = OldDisplayWidth[index];
242
243        S3VSwitchMode(index, pScrn->currentMode, 0);
244	ps3v->DGAactive = FALSE;
245   } else {
246	if(!ps3v->DGAactive) {  /* save the old parameters */
247	    OldDisplayWidth[index] = pScrn->displayWidth;
248
249	    ps3v->DGAactive = TRUE;
250	}
251
252	pScrn->displayWidth = pMode->bytesPerScanline /
253			      (pMode->bitsPerPixel >> 3);
254
255        S3VSwitchMode(index, pMode->mode, 0);
256   }
257
258   return TRUE;
259}
260
261
262
263static int
264S3V_GetViewport(
265  ScrnInfoPtr pScrn
266){
267    S3VPtr ps3v = S3VPTR(pScrn);
268
269    return ps3v->DGAViewportStatus;
270}
271
272static void
273S3V_SetViewport(
274   ScrnInfoPtr pScrn,
275   int x, int y,
276   int flags
277){
278   S3VPtr ps3v = S3VPTR(pScrn);
279
280   S3VAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
281   ps3v->DGAViewportStatus = 0;  /* MGAAdjustFrame loops until finished */
282}
283
284static void
285S3V_FillRect (
286   ScrnInfoPtr pScrn,
287   int x, int y, int w, int h,
288   unsigned long color
289){
290    S3VPtr ps3v = S3VPTR(pScrn);
291
292    if(ps3v->AccelInfoRec) {
293	(*ps3v->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
294	(*ps3v->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
295	SET_SYNC_FLAG(ps3v->AccelInfoRec);
296    }
297}
298
299static void
300S3V_BlitRect(
301   ScrnInfoPtr pScrn,
302   int srcx, int srcy,
303   int w, int h,
304   int dstx, int dsty
305){
306    S3VPtr ps3v = S3VPTR(pScrn);
307
308    if(ps3v->AccelInfoRec) {
309	int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
310	int ydir = (srcy < dsty) ? -1 : 1;
311
312	(*ps3v->AccelInfoRec->SetupForScreenToScreenCopy)(
313		pScrn, xdir, ydir, GXcopy, ~0, -1);
314	(*ps3v->AccelInfoRec->SubsequentScreenToScreenCopy)(
315		pScrn, srcx, srcy, dstx, dsty, w, h);
316	SET_SYNC_FLAG(ps3v->AccelInfoRec);
317    }
318}
319
320
321
322static Bool
323S3V_OpenFramebuffer(
324   ScrnInfoPtr pScrn,
325   char **name,
326   unsigned char **mem,
327   int *size,
328   int *offset,
329   int *flags
330){
331    S3VPtr ps3v = S3VPTR(pScrn);
332
333    *name = NULL; 		/* no special device */
334    *mem = (unsigned char*)(uintptr_t)PCI_REGION_BASE(ps3v->PciInfo, 0, REGION_MEM);
335    *size = ps3v->videoRambytes;
336    *offset = 0;
337    *flags = DGA_NEED_ROOT;
338
339    return TRUE;
340}
341