1fc5a983dSmrg#ifdef HAVE_CONFIG_H
2fc5a983dSmrg#include "config.h"
3fc5a983dSmrg#endif
4fc5a983dSmrg
5fc5a983dSmrg#include "nv_local.h"
6fc5a983dSmrg#include "nv_include.h"
7fc5a983dSmrg#include "nv_type.h"
8fc5a983dSmrg#include "nv_proto.h"
9bd304fc0Smrg#ifdef HAVE_XAA_H
10fc5a983dSmrg#include "xaalocal.h"
11bd304fc0Smrg#endif
12fc5a983dSmrg#include "dgaproc.h"
13fc5a983dSmrg
14fc5a983dSmrg
15fc5a983dSmrgstatic Bool NV_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
16fc5a983dSmrg					int *, int *, int *);
17fc5a983dSmrgstatic Bool NV_SetMode(ScrnInfoPtr, DGAModePtr);
18fc5a983dSmrgstatic int  NV_GetViewport(ScrnInfoPtr);
19fc5a983dSmrgstatic void NV_SetViewport(ScrnInfoPtr, int, int, int);
20bd304fc0Smrg#ifdef HAVE_XAA_H
21fc5a983dSmrgstatic void NV_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
22fc5a983dSmrgstatic void NV_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
23fc5a983dSmrgstatic void NV_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
24fc5a983dSmrg					unsigned long);
25bd304fc0Smrg#endif
26fc5a983dSmrg
27fc5a983dSmrgstatic
28fc5a983dSmrgDGAFunctionRec NV_DGAFuncs = {
29fc5a983dSmrg   NV_OpenFramebuffer,
30fc5a983dSmrg   NULL,
31fc5a983dSmrg   NV_SetMode,
32fc5a983dSmrg   NV_SetViewport,
33fc5a983dSmrg   NV_GetViewport,
34fc5a983dSmrg   NVSync,
35bd304fc0Smrg#ifdef HAVE_XAA_H
36fc5a983dSmrg   NV_FillRect,
37fc5a983dSmrg   NV_BlitRect,
38fc5a983dSmrg   NV_BlitTransRect
39bd304fc0Smrg#else
40bd304fc0Smrg   NULL, NULL, NULL
41bd304fc0Smrg#endif
42fc5a983dSmrg};
43fc5a983dSmrg
44fc5a983dSmrg
45fc5a983dSmrg
46fc5a983dSmrgstatic DGAModePtr
47fc5a983dSmrgNVSetupDGAMode(
48fc5a983dSmrg   ScrnInfoPtr pScrn,
49fc5a983dSmrg   DGAModePtr modes,
50fc5a983dSmrg   int *num,
51fc5a983dSmrg   int bitsPerPixel,
52fc5a983dSmrg   int depth,
53fc5a983dSmrg   Bool pixmap,
54fc5a983dSmrg   int secondPitch,
55fc5a983dSmrg   unsigned long red,
56fc5a983dSmrg   unsigned long green,
57fc5a983dSmrg   unsigned long blue,
58fc5a983dSmrg   short visualClass
59fc5a983dSmrg){
60fc5a983dSmrg   DisplayModePtr firstMode, pMode;
61fc5a983dSmrg   NVPtr pNv = NVPTR(pScrn);
62fc5a983dSmrg   DGAModePtr mode, newmodes;
63fc5a983dSmrg   int size, pitch, Bpp = bitsPerPixel >> 3;
64fc5a983dSmrg
65fc5a983dSmrgSECOND_PASS:
66fc5a983dSmrg
67fc5a983dSmrg   pMode = firstMode = pScrn->modes;
68fc5a983dSmrg
69fc5a983dSmrg   while(1) {
70fc5a983dSmrg
71fc5a983dSmrg	pitch = (pMode->HDisplay + 31) & ~31;
72fc5a983dSmrg	size = pitch * Bpp * pMode->VDisplay;
73fc5a983dSmrg
74fc5a983dSmrg	if((!secondPitch || (pitch != secondPitch)) &&
75fc5a983dSmrg		(size <= pNv->ScratchBufferStart)) {
76fc5a983dSmrg
77fc5a983dSmrg	    if(secondPitch)
78fc5a983dSmrg		pitch = secondPitch;
79fc5a983dSmrg
806086d97eSmrg	    if(!(newmodes = realloc(modes, (*num + 1) * sizeof(DGAModeRec))))
81fc5a983dSmrg		break;
82fc5a983dSmrg
83fc5a983dSmrg	    modes = newmodes;
84fc5a983dSmrg	    mode = modes + *num;
85fc5a983dSmrg
86fc5a983dSmrg	    mode->mode = pMode;
87fc5a983dSmrg	    mode->flags = DGA_CONCURRENT_ACCESS;
88fc5a983dSmrg
89fc5a983dSmrg	    if(pixmap)
90fc5a983dSmrg		mode->flags |= DGA_PIXMAP_AVAILABLE;
91bd304fc0Smrg#ifdef HAVE_XAA_H
92fc5a983dSmrg	    if(!pNv->NoAccel)
93fc5a983dSmrg		mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
94bd304fc0Smrg#endif
95fc5a983dSmrg	    if(pMode->Flags & V_DBLSCAN)
96fc5a983dSmrg		mode->flags |= DGA_DOUBLESCAN;
97fc5a983dSmrg	    if(pMode->Flags & V_INTERLACE)
98fc5a983dSmrg		mode->flags |= DGA_INTERLACED;
99fc5a983dSmrg	    mode->byteOrder = pScrn->imageByteOrder;
100fc5a983dSmrg	    mode->depth = depth;
101fc5a983dSmrg	    mode->bitsPerPixel = bitsPerPixel;
102fc5a983dSmrg	    mode->red_mask = red;
103fc5a983dSmrg	    mode->green_mask = green;
104fc5a983dSmrg	    mode->blue_mask = blue;
105fc5a983dSmrg	    mode->visualClass = visualClass;
106fc5a983dSmrg	    mode->viewportWidth = pMode->HDisplay;
107fc5a983dSmrg	    mode->viewportHeight = pMode->VDisplay;
108fc5a983dSmrg	    mode->xViewportStep = 4 / Bpp;
109fc5a983dSmrg	    mode->yViewportStep = 1;
110fc5a983dSmrg	    mode->viewportFlags = DGA_FLIP_RETRACE;
111fc5a983dSmrg	    mode->offset = 0;
112fc5a983dSmrg	    mode->address = pNv->FbStart;
113fc5a983dSmrg	    mode->bytesPerScanline = pitch * Bpp;
114fc5a983dSmrg	    mode->imageWidth = pitch;
115fc5a983dSmrg	    mode->imageHeight =  pNv->ScratchBufferStart /
116fc5a983dSmrg                                 mode->bytesPerScanline;
117fc5a983dSmrg	    mode->pixmapWidth = mode->imageWidth;
118fc5a983dSmrg	    mode->pixmapHeight = mode->imageHeight;
119fc5a983dSmrg	    mode->maxViewportX = mode->imageWidth - mode->viewportWidth;
120fc5a983dSmrg	    mode->maxViewportY = mode->imageHeight - mode->viewportHeight;
121fc5a983dSmrg	    (*num)++;
122fc5a983dSmrg	}
123fc5a983dSmrg
124fc5a983dSmrg	pMode = pMode->next;
125fc5a983dSmrg	if(pMode == firstMode)
126fc5a983dSmrg	   break;
127fc5a983dSmrg    }
128fc5a983dSmrg
129fc5a983dSmrg    if(secondPitch) {
130fc5a983dSmrg	secondPitch = 0;
131fc5a983dSmrg	goto SECOND_PASS;
132fc5a983dSmrg    }
133fc5a983dSmrg
134fc5a983dSmrg    return modes;
135fc5a983dSmrg}
136fc5a983dSmrg
137fc5a983dSmrg
138fc5a983dSmrgBool
139fc5a983dSmrgNVDGAInit(ScreenPtr pScreen)
140fc5a983dSmrg{
141bd304fc0Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
142fc5a983dSmrg   NVPtr pNv = NVPTR(pScrn);
143fc5a983dSmrg   DGAModePtr modes = NULL;
144fc5a983dSmrg   int num = 0;
145fc5a983dSmrg
146fc5a983dSmrg   /* 8 */
147fc5a983dSmrg   modes = NVSetupDGAMode (pScrn, modes, &num, 8, 8,
148fc5a983dSmrg		(pScrn->bitsPerPixel == 8),
149fc5a983dSmrg		(pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth,
150fc5a983dSmrg		0, 0, 0, PseudoColor);
151fc5a983dSmrg
152fc5a983dSmrg   /* 15 */
153fc5a983dSmrg   modes = NVSetupDGAMode (pScrn, modes, &num, 16, 15,
154fc5a983dSmrg		(pScrn->bitsPerPixel == 16),
155fc5a983dSmrg		(pScrn->depth != 15) ? 0 : pScrn->displayWidth,
156fc5a983dSmrg		0x7c00, 0x03e0, 0x001f, TrueColor);
157fc5a983dSmrg
158fc5a983dSmrg   /* 16 */
159fc5a983dSmrg   modes = NVSetupDGAMode (pScrn, modes, &num, 16, 16,
160fc5a983dSmrg		(pScrn->bitsPerPixel == 16),
161fc5a983dSmrg		(pScrn->depth != 16) ? 0 : pScrn->displayWidth,
162fc5a983dSmrg		0xf800, 0x07e0, 0x001f, TrueColor);
163fc5a983dSmrg
164fc5a983dSmrg   /* 32 */
165fc5a983dSmrg   modes = NVSetupDGAMode (pScrn, modes, &num, 32, 24,
166fc5a983dSmrg		(pScrn->bitsPerPixel == 32),
167fc5a983dSmrg		(pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
168fc5a983dSmrg		0xff0000, 0x00ff00, 0x0000ff, TrueColor);
169fc5a983dSmrg
170fc5a983dSmrg   pNv->numDGAModes = num;
171fc5a983dSmrg   pNv->DGAModes = modes;
172fc5a983dSmrg
173fc5a983dSmrg   return DGAInit(pScreen, &NV_DGAFuncs, modes, num);
174fc5a983dSmrg}
175fc5a983dSmrg
176fc5a983dSmrg
177fc5a983dSmrgstatic int
178fc5a983dSmrgBitsSet(unsigned long data)
179fc5a983dSmrg{
180fc5a983dSmrg   unsigned long mask;
181fc5a983dSmrg   int set = 0;
182fc5a983dSmrg
183fc5a983dSmrg   for(mask = 1; mask; mask <<= 1)
184fc5a983dSmrg        if(mask & data) set++;
185fc5a983dSmrg
186fc5a983dSmrg   return set;
187fc5a983dSmrg}
188fc5a983dSmrg
189fc5a983dSmrgstatic Bool
190fc5a983dSmrgNV_SetMode(
191fc5a983dSmrg   ScrnInfoPtr pScrn,
192fc5a983dSmrg   DGAModePtr pMode
193fc5a983dSmrg){
194fc5a983dSmrg   static NVFBLayout SavedLayouts[MAXSCREENS];
195fc5a983dSmrg   int index = pScrn->pScreen->myNum;
196fc5a983dSmrg
197fc5a983dSmrg   NVPtr pNv = NVPTR(pScrn);
198fc5a983dSmrg
199fc5a983dSmrg   if(!pMode) { /* restore the original mode */
200fc5a983dSmrg      if(pNv->DGAactive)
201fc5a983dSmrg        memcpy(&pNv->CurrentLayout, &SavedLayouts[index], sizeof(NVFBLayout));
202fc5a983dSmrg
203fc5a983dSmrg      pScrn->currentMode = pNv->CurrentLayout.mode;
204bd304fc0Smrg      NVSwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode));
205bd304fc0Smrg      NVAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
206fc5a983dSmrg      pNv->DGAactive = FALSE;
207fc5a983dSmrg   } else {
208fc5a983dSmrg      if(!pNv->DGAactive) {  /* save the old parameters */
209fc5a983dSmrg	memcpy(&SavedLayouts[index], &pNv->CurrentLayout, sizeof(NVFBLayout));
210fc5a983dSmrg	pNv->DGAactive = TRUE;
211fc5a983dSmrg      }
212fc5a983dSmrg
213fc5a983dSmrg      /* update CurrentLayout */
214fc5a983dSmrg      pNv->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel;
215fc5a983dSmrg      pNv->CurrentLayout.depth = pMode->depth;
216fc5a983dSmrg      pNv->CurrentLayout.displayWidth = pMode->bytesPerScanline /
217fc5a983dSmrg                              (pMode->bitsPerPixel >> 3);
218fc5a983dSmrg      pNv->CurrentLayout.weight.red = BitsSet(pMode->red_mask);
219fc5a983dSmrg      pNv->CurrentLayout.weight.green = BitsSet(pMode->green_mask);
220fc5a983dSmrg      pNv->CurrentLayout.weight.blue = BitsSet(pMode->blue_mask);
221fc5a983dSmrg      /* NVModeInit() will set the mode field */
222bd304fc0Smrg      NVSwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode));
223fc5a983dSmrg   }
224fc5a983dSmrg
225fc5a983dSmrg   return TRUE;
226fc5a983dSmrg}
227fc5a983dSmrg
228fc5a983dSmrg
229fc5a983dSmrg
230fc5a983dSmrgstatic int
231fc5a983dSmrgNV_GetViewport(
232fc5a983dSmrg  ScrnInfoPtr pScrn
233fc5a983dSmrg){
234fc5a983dSmrg    NVPtr pNv = NVPTR(pScrn);
235fc5a983dSmrg
236fc5a983dSmrg    return pNv->DGAViewportStatus;
237fc5a983dSmrg}
238fc5a983dSmrg
239fc5a983dSmrgstatic void
240fc5a983dSmrgNV_SetViewport(
241fc5a983dSmrg   ScrnInfoPtr pScrn,
242fc5a983dSmrg   int x, int y,
243fc5a983dSmrg   int flags
244fc5a983dSmrg){
245fc5a983dSmrg   NVPtr pNv = NVPTR(pScrn);
246fc5a983dSmrg
247bd304fc0Smrg   NVAdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y));
248fc5a983dSmrg
249fc5a983dSmrg   while(VGA_RD08(pNv->PCIO, 0x3da) & 0x08);
250fc5a983dSmrg   while(!(VGA_RD08(pNv->PCIO, 0x3da) & 0x08));
251fc5a983dSmrg
252fc5a983dSmrg   pNv->DGAViewportStatus = 0;
253fc5a983dSmrg}
254fc5a983dSmrg
255bd304fc0Smrg#ifdef HAVE_XAA_H
256fc5a983dSmrgstatic void
257fc5a983dSmrgNV_FillRect (
258fc5a983dSmrg   ScrnInfoPtr pScrn,
259fc5a983dSmrg   int x, int y, int w, int h,
260fc5a983dSmrg   unsigned long color
261fc5a983dSmrg){
262fc5a983dSmrg    NVPtr pNv = NVPTR(pScrn);
263fc5a983dSmrg
264fc5a983dSmrg    if(!pNv->AccelInfoRec) return;
265fc5a983dSmrg
266fc5a983dSmrg    (*pNv->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
267fc5a983dSmrg    (*pNv->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
268fc5a983dSmrg
269fc5a983dSmrg    SET_SYNC_FLAG(pNv->AccelInfoRec);
270fc5a983dSmrg}
271fc5a983dSmrg
272fc5a983dSmrgstatic void
273fc5a983dSmrgNV_BlitRect(
274fc5a983dSmrg   ScrnInfoPtr pScrn,
275fc5a983dSmrg   int srcx, int srcy,
276fc5a983dSmrg   int w, int h,
277fc5a983dSmrg   int dstx, int dsty
278fc5a983dSmrg){
279fc5a983dSmrg    NVPtr pNv = NVPTR(pScrn);
280fc5a983dSmrg    int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
281fc5a983dSmrg    int ydir = (srcy < dsty) ? -1 : 1;
282fc5a983dSmrg
283fc5a983dSmrg    if(!pNv->AccelInfoRec) return;
284fc5a983dSmrg
285fc5a983dSmrg    (*pNv->AccelInfoRec->SetupForScreenToScreenCopy)(
286fc5a983dSmrg		pScrn, xdir, ydir, GXcopy, ~0, -1);
287fc5a983dSmrg
288fc5a983dSmrg    (*pNv->AccelInfoRec->SubsequentScreenToScreenCopy)(
289fc5a983dSmrg		pScrn, srcx, srcy, dstx, dsty, w, h);
290fc5a983dSmrg
291fc5a983dSmrg    SET_SYNC_FLAG(pNv->AccelInfoRec);
292fc5a983dSmrg}
293fc5a983dSmrg
294fc5a983dSmrg
295fc5a983dSmrgstatic void
296fc5a983dSmrgNV_BlitTransRect(
297fc5a983dSmrg   ScrnInfoPtr pScrn,
298fc5a983dSmrg   int srcx, int srcy,
299fc5a983dSmrg   int w, int h,
300fc5a983dSmrg   int dstx, int dsty,
301fc5a983dSmrg   unsigned long color
302fc5a983dSmrg){
303fc5a983dSmrg   /* not implemented */
304fc5a983dSmrg}
305bd304fc0Smrg#endif
306fc5a983dSmrg
307fc5a983dSmrgstatic Bool
308fc5a983dSmrgNV_OpenFramebuffer(
309fc5a983dSmrg   ScrnInfoPtr pScrn,
310fc5a983dSmrg   char **name,
311fc5a983dSmrg   unsigned char **mem,
312fc5a983dSmrg   int *size,
313fc5a983dSmrg   int *offset,
314fc5a983dSmrg   int *flags
315fc5a983dSmrg){
316fc5a983dSmrg    NVPtr pNv = NVPTR(pScrn);
317fc5a983dSmrg
318fc5a983dSmrg    *name = NULL; 		/* no special device */
319fc5a983dSmrg    *mem = (unsigned char*)pNv->FbAddress;
320fc5a983dSmrg    *size = pNv->FbMapSize;
321fc5a983dSmrg    *offset = 0;
322fc5a983dSmrg    *flags = DGA_NEED_ROOT;
323fc5a983dSmrg
324fc5a983dSmrg    return TRUE;
325fc5a983dSmrg}
326