savage_dri.c revision 5788ca14
1ab47cfaaSmrg/*
2ab47cfaaSmrg * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3ab47cfaaSmrg * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4ab47cfaaSmrg *
5ab47cfaaSmrg * Permission is hereby granted, free of charge, to any person obtaining a
6ab47cfaaSmrg * copy of this software and associated documentation files (the "Software"),
7ab47cfaaSmrg * to deal in the Software without restriction, including without limitation
8ab47cfaaSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license,
9ab47cfaaSmrg * and/or sell copies of the Software, and to permit persons to whom the
10ab47cfaaSmrg * Software is furnished to do so, subject to the following conditions:
11ab47cfaaSmrg *
12ab47cfaaSmrg * The above copyright notice and this permission notice (including the
13ab47cfaaSmrg * next paragraph) shall be included in all copies or substantial portions
14ab47cfaaSmrg * of the Software.
15ab47cfaaSmrg *
16ab47cfaaSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17ab47cfaaSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18ab47cfaaSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19ab47cfaaSmrg * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20ab47cfaaSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21ab47cfaaSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22ab47cfaaSmrg * DEALINGS IN THE SOFTWARE.
23ab47cfaaSmrg */
24ab47cfaaSmrg
25ab47cfaaSmrg#ifdef HAVE_CONFIG_H
26ab47cfaaSmrg#include "config.h"
27ab47cfaaSmrg#endif
28ab47cfaaSmrg
295788ca14Smrg#ifdef SAVAGEDRI
30ab47cfaaSmrg
31ab47cfaaSmrg#include "xf86.h"
32ab47cfaaSmrg#include "xf86_OSproc.h"
33ab47cfaaSmrg
345788ca14Smrg#ifdef HAVE_XAA_H
35ab47cfaaSmrg#include "xaalocal.h"
36ab47cfaaSmrg#include "xaarop.h"
375788ca14Smrg#endif
38ab47cfaaSmrg
39ab47cfaaSmrg#include "xf86Pci.h"
40ab47cfaaSmrg#include "xf86fbman.h"
41ab47cfaaSmrg
42ab47cfaaSmrg#include "miline.h"
43ab47cfaaSmrg
44ab47cfaaSmrg
45ab47cfaaSmrg/*#include "savage_vbe.h"*/
46ab47cfaaSmrg#include "savage_regs.h"
47ab47cfaaSmrg#include "savage_driver.h"
48ab47cfaaSmrg#include "savage_bci.h"
49ab47cfaaSmrg#include "savage_streams.h"
50ab47cfaaSmrg#include "savage_common.h"
51ab47cfaaSmrg
52ab47cfaaSmrg#define _XF86DRI_SERVER_
53ab47cfaaSmrg#include "GL/glxtokens.h"
54ab47cfaaSmrg#include "sarea.h"
55ab47cfaaSmrg#include "savage_dri.h"
56ab47cfaaSmrg#include "savage_sarea.h"
57ab47cfaaSmrg
585788ca14Smrgstatic struct {
595788ca14Smrg   int bpp;
605788ca14Smrg   int redSize;
615788ca14Smrg   int greenSize;
625788ca14Smrg   int blueSize;
635788ca14Smrg   int alphaSize;
645788ca14Smrg   int redMask;
655788ca14Smrg   int greenMask;
665788ca14Smrg   int blueMask;
675788ca14Smrg   int alphaMask;
685788ca14Smrg   int depthSize;
695788ca14Smrg} SAVAGEVisuals[] = {
705788ca14Smrg   { 16, 5, 6, 5, 0, 0x0000F800, 0x000007E0, 0x0000001F, 0, 16 },
715788ca14Smrg   { 32, 8, 8, 8, 0, 0x00FF0000, 0x0000FF00, 0x000000FF, 0, 24 },
725788ca14Smrg   {  0, 0, 0, 0, 0,          0,          0,          0, 0,  0 }
735788ca14Smrg};
745788ca14Smrg
75ab47cfaaSmrgstatic char SAVAGEKernelDriverName[] = "savage";
76ab47cfaaSmrgstatic char SAVAGEClientDriverName[] = "savage";
77ab47cfaaSmrg
78ab47cfaaSmrgstatic Bool SAVAGEDRIOpenFullScreen(ScreenPtr pScreen);
79ab47cfaaSmrgstatic Bool SAVAGEDRICloseFullScreen(ScreenPtr pScreen);
80ab47cfaaSmrg/* DRI buffer management
81ab47cfaaSmrg */
82ab47cfaaSmrgvoid SAVAGEDRIInitBuffers( WindowPtr pWin, RegionPtr prgn,
83ab47cfaaSmrg				CARD32 index );
84ab47cfaaSmrgvoid SAVAGEDRIMoveBuffers( WindowPtr pParent, DDXPointRec ptOldOrg,
85ab47cfaaSmrg				RegionPtr prgnSrc, CARD32 index );
86ab47cfaaSmrg
87ab47cfaaSmrg/*        almost the same besides set src/desc to */
88ab47cfaaSmrg/*        Primary Bitmap Description              */
89ab47cfaaSmrg
90ab47cfaaSmrgstatic void
91ab47cfaaSmrgSAVAGEDRISetupForScreenToScreenCopy(
92ab47cfaaSmrg    ScrnInfoPtr pScrn, int xdir, int ydir,
93ab47cfaaSmrg    int rop, unsigned planemask, int transparency_color);
94ab47cfaaSmrg
95ab47cfaaSmrg
96ab47cfaaSmrgstatic void
97ab47cfaaSmrgSAVAGEDRISubsequentScreenToScreenCopy(
98ab47cfaaSmrg    ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
99ab47cfaaSmrg    int w, int h);
100ab47cfaaSmrg
101ab47cfaaSmrg
102ab47cfaaSmrg/* Initialize the visual configs that are supported by the hardware.
103ab47cfaaSmrg * These are combined with the visual configs that the indirect
104ab47cfaaSmrg * rendering core supports, and the intersection is exported to the
105ab47cfaaSmrg * client.
106ab47cfaaSmrg */
107ab47cfaaSmrgstatic Bool SAVAGEInitVisualConfigs( ScreenPtr pScreen )
108ab47cfaaSmrg{
1095788ca14Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
110ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
111ab47cfaaSmrg   int numConfigs = 0;
112ab47cfaaSmrg   __GLXvisualConfig *pConfigs = 0;
113ab47cfaaSmrg   SAVAGEConfigPrivPtr pSAVAGEConfigs = 0;
114ab47cfaaSmrg   SAVAGEConfigPrivPtr *pSAVAGEConfigPtrs = 0;
1155788ca14Smrg   int i, db, stencil, accum, visNum;
116ab47cfaaSmrg
117ab47cfaaSmrg   switch ( pScrn->bitsPerPixel ) {
118ab47cfaaSmrg   case 8:
119ab47cfaaSmrg   case 24:
120ab47cfaaSmrg      break;
121ab47cfaaSmrg
122ab47cfaaSmrg   case 16:
1235788ca14Smrg   case 32:
124ab47cfaaSmrg      numConfigs = 8;
125ab47cfaaSmrg
1265788ca14Smrg      pConfigs = (__GLXvisualConfig*)calloc( sizeof(__GLXvisualConfig),
127ab47cfaaSmrg						numConfigs );
128ab47cfaaSmrg      if ( !pConfigs ) {
129ab47cfaaSmrg	 return FALSE;
130ab47cfaaSmrg      }
131ab47cfaaSmrg
1325788ca14Smrg      pSAVAGEConfigs = (SAVAGEConfigPrivPtr)calloc( sizeof(SAVAGEConfigPrivRec),
133ab47cfaaSmrg						 numConfigs );
134ab47cfaaSmrg      if ( !pSAVAGEConfigs ) {
1355788ca14Smrg	 free( pConfigs );
136ab47cfaaSmrg	 return FALSE;
137ab47cfaaSmrg      }
138ab47cfaaSmrg
1395788ca14Smrg      pSAVAGEConfigPtrs = (SAVAGEConfigPrivPtr*)calloc( sizeof(SAVAGEConfigPrivPtr),
140ab47cfaaSmrg						     numConfigs );
141ab47cfaaSmrg      if ( !pSAVAGEConfigPtrs ) {
1425788ca14Smrg	 free( pConfigs );
1435788ca14Smrg	 free( pSAVAGEConfigs );
144ab47cfaaSmrg	 return FALSE;
145ab47cfaaSmrg      }
146ab47cfaaSmrg
147ab47cfaaSmrg      for ( i = 0 ; i < numConfigs ; i++ ) {
148ab47cfaaSmrg	 pSAVAGEConfigPtrs[i] = &pSAVAGEConfigs[i];
149ab47cfaaSmrg      }
150ab47cfaaSmrg
1515788ca14Smrg      for (visNum = 0; SAVAGEVisuals[visNum].bpp != 0; visNum++) {
1525788ca14Smrg         if ( SAVAGEVisuals[visNum].bpp == pScrn->bitsPerPixel )
1535788ca14Smrg            break;
154ab47cfaaSmrg      }
1555788ca14Smrg      if ( SAVAGEVisuals[visNum].bpp == 0 ) {
1565788ca14Smrg	 free( pConfigs );
1575788ca14Smrg	 free( pSAVAGEConfigs );
158ab47cfaaSmrg         return FALSE;
159ab47cfaaSmrg      }
160ab47cfaaSmrg
161ab47cfaaSmrg      i = 0;
162ab47cfaaSmrg      for ( accum = 0 ; accum <= 1 ; accum++ ) {
163ab47cfaaSmrg         for ( stencil = 0 ; stencil <= 1 ; stencil++ ) {
164ab47cfaaSmrg            for ( db = 1 ; db >= 0 ; db-- ) {
1655788ca14Smrg               pConfigs[i].vid		= -1;
1665788ca14Smrg               pConfigs[i].class	= -1;
1675788ca14Smrg               pConfigs[i].rgba		= TRUE;
1685788ca14Smrg               pConfigs[i].redSize	= SAVAGEVisuals[visNum].redSize;
1695788ca14Smrg               pConfigs[i].greenSize	= SAVAGEVisuals[visNum].greenSize;
1705788ca14Smrg               pConfigs[i].blueSize	= SAVAGEVisuals[visNum].blueSize;
1715788ca14Smrg               pConfigs[i].alphaSize	= SAVAGEVisuals[visNum].alphaSize;
1725788ca14Smrg               pConfigs[i].redMask	= SAVAGEVisuals[visNum].redMask;
1735788ca14Smrg               pConfigs[i].greenMask	= SAVAGEVisuals[visNum].greenMask;
1745788ca14Smrg               pConfigs[i].blueMask	= SAVAGEVisuals[visNum].blueMask;
1755788ca14Smrg               pConfigs[i].alphaMask	= SAVAGEVisuals[visNum].alphaMask;
1765788ca14Smrg
177ab47cfaaSmrg               if ( accum ) {
178ab47cfaaSmrg                  pConfigs[i].accumRedSize	= 16;
179ab47cfaaSmrg                  pConfigs[i].accumGreenSize	= 16;
180ab47cfaaSmrg                  pConfigs[i].accumBlueSize	= 16;
181ab47cfaaSmrg                  pConfigs[i].accumAlphaSize	= 0;
182ab47cfaaSmrg               } else {
183ab47cfaaSmrg                  pConfigs[i].accumRedSize	= 0;
184ab47cfaaSmrg                  pConfigs[i].accumGreenSize	= 0;
185ab47cfaaSmrg                  pConfigs[i].accumBlueSize	= 0;
186ab47cfaaSmrg                  pConfigs[i].accumAlphaSize	= 0;
187ab47cfaaSmrg               }
188ab47cfaaSmrg               if ( db ) {
189ab47cfaaSmrg                  pConfigs[i].doubleBuffer	= TRUE;
190ab47cfaaSmrg               } else {
191ab47cfaaSmrg                  pConfigs[i].doubleBuffer	= FALSE;
1925788ca14Smrg               }
193ab47cfaaSmrg               pConfigs[i].stereo		= FALSE;
1945788ca14Smrg               pConfigs[i].bufferSize		= pScrn->bitsPerPixel;
1955788ca14Smrg               pConfigs[i].depthSize	= SAVAGEVisuals[visNum].depthSize;
196ab47cfaaSmrg               if ( stencil ) {
1975788ca14Smrg                  pConfigs[i].stencilSize	= 8;
1985788ca14Smrg               } else {
1995788ca14Smrg                  pConfigs[i].stencilSize	= 0;
200ab47cfaaSmrg               }
2015788ca14Smrg
202ab47cfaaSmrg               pConfigs[i].auxBuffers		= 0;
203ab47cfaaSmrg               pConfigs[i].level		= 0;
2045788ca14Smrg
2055788ca14Smrg               pConfigs[i].visualRating	= GLX_NONE;
2065788ca14Smrg               if ( pScrn->bitsPerPixel == 16 ) {
2075788ca14Smrg                  if ( accum || stencil ) {
2085788ca14Smrg                     pConfigs[i].visualRating	= GLX_SLOW_CONFIG;
2095788ca14Smrg                  }
2105788ca14Smrg               } else if ( accum ) {
211ab47cfaaSmrg                  pConfigs[i].visualRating	= GLX_SLOW_VISUAL_EXT;
2125788ca14Smrg               }
213ab47cfaaSmrg               pConfigs[i].transparentPixel	= GLX_NONE;
214ab47cfaaSmrg               pConfigs[i].transparentRed	= 0;
215ab47cfaaSmrg               pConfigs[i].transparentGreen	= 0;
216ab47cfaaSmrg               pConfigs[i].transparentBlue	= 0;
217ab47cfaaSmrg               pConfigs[i].transparentAlpha	= 0;
218ab47cfaaSmrg               pConfigs[i].transparentIndex	= 0;
219ab47cfaaSmrg               i++;
220ab47cfaaSmrg            }
221ab47cfaaSmrg         }
222ab47cfaaSmrg      }
223ab47cfaaSmrg      if ( i != numConfigs ) {
224ab47cfaaSmrg         xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
225ab47cfaaSmrg		     "[drm] Incorrect initialization of visuals\n" );
226ab47cfaaSmrg         return FALSE;
227ab47cfaaSmrg      }
228ab47cfaaSmrg      break;
229ab47cfaaSmrg
230ab47cfaaSmrg   default:
231ab47cfaaSmrg      /* Unexpected bits/pixels */
232ab47cfaaSmrg      break;
233ab47cfaaSmrg   }
234ab47cfaaSmrg
235ab47cfaaSmrg   psav->numVisualConfigs = numConfigs;
236ab47cfaaSmrg   psav->pVisualConfigs = pConfigs;
237ab47cfaaSmrg   psav->pVisualConfigsPriv = pSAVAGEConfigs;
238ab47cfaaSmrg
239ab47cfaaSmrg   GlxSetVisualConfigs( numConfigs, pConfigs, (void **)pSAVAGEConfigPtrs );
240ab47cfaaSmrg
241ab47cfaaSmrg   return TRUE;
242ab47cfaaSmrg}
243ab47cfaaSmrg
244ab47cfaaSmrgstatic Bool SAVAGECreateContext( ScreenPtr pScreen, VisualPtr visual,
245ab47cfaaSmrg			      drm_context_t hwContext, void *pVisualConfigPriv,
246ab47cfaaSmrg			      DRIContextType contextStore )
247ab47cfaaSmrg{
2485788ca14Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
249ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
250ab47cfaaSmrg
251ab47cfaaSmrg    if(psav->xvmcContext)
252ab47cfaaSmrg        return FALSE;
253ab47cfaaSmrg    else
254ab47cfaaSmrg    {
255ab47cfaaSmrg        psav->DRIrunning++;
256ab47cfaaSmrg    }
257ab47cfaaSmrg
258ab47cfaaSmrg    return TRUE;
259ab47cfaaSmrg}
260ab47cfaaSmrg
261ab47cfaaSmrgstatic void SAVAGEDestroyContext( ScreenPtr pScreen, drm_context_t hwContext,
262ab47cfaaSmrg			       DRIContextType contextStore )
263ab47cfaaSmrg{
2645788ca14Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
265ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
266ab47cfaaSmrg
267ab47cfaaSmrg    psav->DRIrunning--;
268ab47cfaaSmrg}
269ab47cfaaSmrg
2705788ca14Smrgstatic void SAVAGEWakeupHandler(WAKEUPHANDLER_ARGS_DECL)
271ab47cfaaSmrg{
2725788ca14Smrg   SCREEN_PTR(arg);
2735788ca14Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
274ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
275ab47cfaaSmrg
276ab47cfaaSmrg   psav->pDRIInfo->wrap.WakeupHandler = psav->coreWakeupHandler;
2775788ca14Smrg   (*psav->pDRIInfo->wrap.WakeupHandler) (WAKEUPHANDLER_ARGS);
278ab47cfaaSmrg   psav->pDRIInfo->wrap.WakeupHandler = SAVAGEWakeupHandler;
279ab47cfaaSmrg   psav->LockHeld = 1;
280ab47cfaaSmrg   if (psav->ShadowStatus) {
281ab47cfaaSmrg      /* fetch the global shadow counter */
282ab47cfaaSmrg#if 0
283ab47cfaaSmrg      if (psav->ShadowCounter != (psav->ShadowVirtual[1023] & 0xffff))
284ab47cfaaSmrg	 xf86DrvMsg( pScrn->scrnIndex, X_INFO,
285ab47cfaaSmrg		     "[dri] WakeupHandler: shadowCounter adjusted from %04x to %04lx\n",
286ab47cfaaSmrg		     psav->ShadowCounter, psav->ShadowVirtual[1023] & 0xffff);
287ab47cfaaSmrg#endif
288ab47cfaaSmrg      psav->ShadowCounter = psav->ShadowVirtual[1023] & 0xffff;
289ab47cfaaSmrg   }
290ab47cfaaSmrg   if (psav->useEXA)
291ab47cfaaSmrg	exaMarkSync(pScreen);
2925788ca14Smrg#ifdef HAVE_XAA_H
293ab47cfaaSmrg   else
294ab47cfaaSmrg	psav->AccelInfoRec->NeedToSync = TRUE;
2955788ca14Smrg#endif
296ab47cfaaSmrg   /* FK: this flag doesn't seem to be used. */
297ab47cfaaSmrg}
298ab47cfaaSmrg
2995788ca14Smrgstatic void SAVAGEBlockHandler(BLOCKHANDLER_ARGS_DECL)
300ab47cfaaSmrg{
3015788ca14Smrg   SCREEN_PTR(arg);
3025788ca14Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
303ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
304ab47cfaaSmrg
305ab47cfaaSmrg   if (psav->ShadowStatus) {
306ab47cfaaSmrg      /* update the global shadow counter */
307ab47cfaaSmrg      CARD32 globalShadowCounter = psav->ShadowVirtual[1023];
308ab47cfaaSmrg      globalShadowCounter = (globalShadowCounter & 0xffff0000) |
309ab47cfaaSmrg	  ((CARD32)psav->ShadowCounter & 0x0000ffff);
310ab47cfaaSmrg
311ab47cfaaSmrg#if 0
312ab47cfaaSmrg      if (globalShadowCounter != psav->ShadowVirtual[1023])
313ab47cfaaSmrg	 xf86DrvMsg( pScrn->scrnIndex, X_INFO,
314ab47cfaaSmrg		     "[dri] BlockHandler: shadowCounter adjusted from %08lx to %08x\n",
315ab47cfaaSmrg		     psav->ShadowVirtual[1023], globalShadowCounter);
316ab47cfaaSmrg#endif
317ab47cfaaSmrg      psav->ShadowVirtual[1023] = globalShadowCounter;
318ab47cfaaSmrg   }
319ab47cfaaSmrg   psav->LockHeld = 0;
320ab47cfaaSmrg   psav->pDRIInfo->wrap.BlockHandler = psav->coreBlockHandler;
3215788ca14Smrg   (*psav->pDRIInfo->wrap.BlockHandler) (BLOCKHANDLER_ARGS);
322ab47cfaaSmrg   psav->pDRIInfo->wrap.BlockHandler = SAVAGEBlockHandler;
323ab47cfaaSmrg}
324ab47cfaaSmrg
3255788ca14Smrgstatic void SAVAGESelectBuffer( ScrnInfoPtr pScrn, int which )
326ab47cfaaSmrg{
327ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
328ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
329ab47cfaaSmrg
330ab47cfaaSmrg   psav->WaitIdleEmpty(psav);
331ab47cfaaSmrg
332ab47cfaaSmrg   OUTREG(0x48C18,INREG(0x48C18)&(~0x00000008));
333ab47cfaaSmrg
334ab47cfaaSmrg   switch ( which ) {
335ab47cfaaSmrg   case SAVAGE_BACK:
336ab47cfaaSmrg      OUTREG( 0x8170, pSAVAGEDRIServer->backOffset );
337ab47cfaaSmrg      OUTREG( 0x8174, pSAVAGEDRIServer->backBitmapDesc );
338ab47cfaaSmrg      break;
339ab47cfaaSmrg   case SAVAGE_DEPTH:
340ab47cfaaSmrg      OUTREG( 0x8170, pSAVAGEDRIServer->depthOffset );
341ab47cfaaSmrg      OUTREG( 0x8174, pSAVAGEDRIServer->depthBitmapDesc );
342ab47cfaaSmrg      break;
343ab47cfaaSmrg   default:
344ab47cfaaSmrg   case SAVAGE_FRONT:
345ab47cfaaSmrg      OUTREG( 0x8170, pSAVAGEDRIServer->frontOffset );
346ab47cfaaSmrg      OUTREG( 0x8174, pSAVAGEDRIServer->frontBitmapDesc );
347ab47cfaaSmrg      break;
348ab47cfaaSmrg   }
349ab47cfaaSmrg   OUTREG(0x48C18,INREG(0x48C18)|(0x00000008));
350ab47cfaaSmrg   psav->WaitIdleEmpty(psav);
351ab47cfaaSmrg
352ab47cfaaSmrg}
353ab47cfaaSmrg
354ab47cfaaSmrg
355ab47cfaaSmrgstatic unsigned int mylog2( unsigned int n )
356ab47cfaaSmrg{
357ab47cfaaSmrg   unsigned int log2 = 1;
358ab47cfaaSmrg
359ab47cfaaSmrg   n--;
360ab47cfaaSmrg   while ( n > 1 ) n >>= 1, log2++;
361ab47cfaaSmrg
362ab47cfaaSmrg   return log2;
363ab47cfaaSmrg}
364ab47cfaaSmrg
3655788ca14Smrgstatic Bool SAVAGESetAgpMode(SavagePtr psav, ScreenPtr pScreen)
366ab47cfaaSmrg{
3675788ca14Smrg   unsigned long mode = drmAgpGetMode( psav->drmFD );    /* Default mode */
3685788ca14Smrg   unsigned int vendor = drmAgpVendorId( psav->drmFD );
3695788ca14Smrg   unsigned int device = drmAgpDeviceId( psav->drmFD );
370ab47cfaaSmrg
371ab47cfaaSmrg   mode &= ~SAVAGE_AGP_MODE_MASK;
372ab47cfaaSmrg
373ab47cfaaSmrg   switch ( psav->agpMode ) {
374ab47cfaaSmrg   case 4:
375ab47cfaaSmrg      mode |= SAVAGE_AGP_4X_MODE;
376ab47cfaaSmrg   case 2:
377ab47cfaaSmrg      mode |= SAVAGE_AGP_2X_MODE;
378ab47cfaaSmrg   case 1:
379ab47cfaaSmrg   default:
380ab47cfaaSmrg      mode |= SAVAGE_AGP_1X_MODE;
381ab47cfaaSmrg   }
382ab47cfaaSmrg
383ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
384ab47cfaaSmrg	       "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
385ab47cfaaSmrg	       mode, vendor, device,
3868697ee19Smrg	       VENDOR_ID(psav->PciInfo),
3878697ee19Smrg	       DEVICE_ID(psav->PciInfo));
388ab47cfaaSmrg
389ab47cfaaSmrg   if ( drmAgpEnable( psav->drmFD, mode ) < 0 ) {
390ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n" );
391ab47cfaaSmrg      drmAgpRelease( psav->drmFD );
3925788ca14Smrg      return FALSE;
3935788ca14Smrg   }
3945788ca14Smrg
3955788ca14Smrg   return TRUE;
3965788ca14Smrg}
3975788ca14Smrg
3985788ca14Smrgstatic Bool SAVAGEDRIAgpInit(ScreenPtr pScreen)
3995788ca14Smrg{
4005788ca14Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
4015788ca14Smrg   SavagePtr psav = SAVPTR(pScrn);
4025788ca14Smrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
4035788ca14Smrg   unsigned int offset;
4045788ca14Smrg   int ret;
4055788ca14Smrg
4065788ca14Smrg   if (psav->agpSize < 2)
4075788ca14Smrg      psav->agpSize = 2; /* at least 2MB for DMA buffers */
4085788ca14Smrg
4095788ca14Smrg   pSAVAGEDRIServer->agp.size = psav->agpSize * 1024 * 1024;
4105788ca14Smrg   pSAVAGEDRIServer->agp.offset = pSAVAGEDRIServer->agp.size; /* ? */
4115788ca14Smrg
4125788ca14Smrg   if ( drmAgpAcquire( psav->drmFD ) < 0 ) {
4135788ca14Smrg      xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not available\n" );
4145788ca14Smrg      return FALSE;
4155788ca14Smrg   }
4165788ca14Smrg
4175788ca14Smrg   if (!SAVAGESetAgpMode(psav, pScreen)) {
418ab47cfaaSmrg      pSAVAGEDRIServer->agp.handle = 0; /* indicate that AGP init failed */
419ab47cfaaSmrg      return FALSE;
420ab47cfaaSmrg   }
421ab47cfaaSmrg
422ab47cfaaSmrg   ret = drmAgpAlloc( psav->drmFD, pSAVAGEDRIServer->agp.size,
423ab47cfaaSmrg		      0, NULL, &pSAVAGEDRIServer->agp.handle );
424ab47cfaaSmrg   if ( ret < 0 ) {
425ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret );
426ab47cfaaSmrg      drmAgpRelease( psav->drmFD );
427ab47cfaaSmrg      pSAVAGEDRIServer->agp.handle = 0; /* indicate that AGP init failed */
428ab47cfaaSmrg      return FALSE;
429ab47cfaaSmrg   }
430ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
431ab47cfaaSmrg	       "[agp] %d kB allocated with handle 0x%08lx\n",
4325788ca14Smrg	       pSAVAGEDRIServer->agp.size/1024,
4335788ca14Smrg	       (unsigned long)pSAVAGEDRIServer->agp.handle );
434ab47cfaaSmrg
435ab47cfaaSmrg   if ( drmAgpBind( psav->drmFD, pSAVAGEDRIServer->agp.handle, 0 ) < 0 ) {
436ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Could not bind memory\n" );
437ab47cfaaSmrg      drmAgpFree( psav->drmFD, pSAVAGEDRIServer->agp.handle );
438ab47cfaaSmrg      drmAgpRelease( psav->drmFD );
439ab47cfaaSmrg      pSAVAGEDRIServer->agp.handle = 0; /* indicate that AGP init failed */
440ab47cfaaSmrg      return FALSE;
441ab47cfaaSmrg   }
442ab47cfaaSmrg
443ab47cfaaSmrg   /* AGP initialization failures above are not fatal, we can fall
444ab47cfaaSmrg    * back to PCI mode. Failures while adding AGP mappings below are
445ab47cfaaSmrg    * fatal though. DRI must be disabled in that case.
446ab47cfaaSmrg    * pSAVAGEDRIServer->agp.handle can be used to distinguish these
447ab47cfaaSmrg    * two cases.
448ab47cfaaSmrg    */
449ab47cfaaSmrg
450ab47cfaaSmrg   /* AGP memory layout
451ab47cfaaSmrg    */
452ab47cfaaSmrg   offset = 0;
453ab47cfaaSmrg
454ab47cfaaSmrg   if ( psav->AgpDMA ) {
455ab47cfaaSmrg       if ( psav->CommandDMA ) {
456ab47cfaaSmrg	   pSAVAGEDRIServer->cmdDma.offset = offset;
457ab47cfaaSmrg	   pSAVAGEDRIServer->cmdDma.size = SAVAGE_CMDDMA_SIZE;
458ab47cfaaSmrg	   offset += pSAVAGEDRIServer->cmdDma.size;
459ab47cfaaSmrg       } else if ( psav->VertexDMA ) {
460ab47cfaaSmrg	   pSAVAGEDRIServer->buffers.offset = 0;
461ab47cfaaSmrg	   pSAVAGEDRIServer->buffers.size = SAVAGE_NUM_BUFFERS * SAVAGE_BUFFER_SIZE;
462ab47cfaaSmrg	   offset += pSAVAGEDRIServer->buffers.size;
463ab47cfaaSmrg       }
464ab47cfaaSmrg   }
465ab47cfaaSmrg
4661c79cd07Smrg   if (psav->AGPforXv) {
4671c79cd07Smrg       pSAVAGEDRIServer->agpXVideo.offset = offset;
4681c79cd07Smrg       pSAVAGEDRIServer->agpXVideo.size = 2 * 1024 * 1024; /* Max XV image is 1024x1024x16bpp */
4691c79cd07Smrg       offset += pSAVAGEDRIServer->agpXVideo.size;
4701c79cd07Smrg   } else {
4711c79cd07Smrg       pSAVAGEDRIServer->agpXVideo.offset = 0;
4721c79cd07Smrg       pSAVAGEDRIServer->agpXVideo.size = 0;
4731c79cd07Smrg   }
4741c79cd07Smrg
475ab47cfaaSmrg   pSAVAGEDRIServer->agpTextures.offset = offset;
476ab47cfaaSmrg   pSAVAGEDRIServer->agpTextures.size = (pSAVAGEDRIServer->agp.size - offset);
477ab47cfaaSmrg
478ab47cfaaSmrg   /* DMA buffers
479ab47cfaaSmrg    */
480ab47cfaaSmrg   if ( psav->AgpDMA ) {
481ab47cfaaSmrg       if ( psav->CommandDMA ) {
482ab47cfaaSmrg	   if ( drmAddMap( psav->drmFD,
483ab47cfaaSmrg			   pSAVAGEDRIServer->cmdDma.offset,
484ab47cfaaSmrg			   pSAVAGEDRIServer->cmdDma.size,
485ab47cfaaSmrg			   DRM_AGP, DRM_RESTRICTED | DRM_KERNEL,
486ab47cfaaSmrg			   &pSAVAGEDRIServer->cmdDma.handle ) < 0 ) {
487ab47cfaaSmrg	       xf86DrvMsg( pScreen->myNum, X_ERROR,
488ab47cfaaSmrg			   "[agp] Could not add command DMA mapping\n" );
489ab47cfaaSmrg	       return FALSE;
490ab47cfaaSmrg	   }
491ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_INFO,
492ab47cfaaSmrg		       "[agp] command DMA handle = 0x%08lx\n",
4935788ca14Smrg		       (unsigned long)pSAVAGEDRIServer->cmdDma.handle );
494ab47cfaaSmrg	   /* not needed in the server
495ab47cfaaSmrg	   if ( drmMap( psav->drmFD,
496ab47cfaaSmrg			pSAVAGEDRIServer->cmdDma.handle,
497ab47cfaaSmrg			pSAVAGEDRIServer->cmdDma.size,
498ab47cfaaSmrg			&pSAVAGEDRIServer->cmdDma.map ) < 0 ) {
499ab47cfaaSmrg	       xf86DrvMsg( pScreen->myNum, X_ERROR,
500ab47cfaaSmrg			   "[agp] Could not map command DMA\n" );
501ab47cfaaSmrg	       return FALSE;
502ab47cfaaSmrg	   }
503ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_INFO,
504ab47cfaaSmrg		       "[agp] command DMA mapped at 0x%08lx\n",
505ab47cfaaSmrg		       (unsigned long)pSAVAGEDRIServer->cmdDma.map );
506ab47cfaaSmrg	   */
507ab47cfaaSmrg       } else if ( psav->VertexDMA ) {
508ab47cfaaSmrg	   if ( drmAddMap( psav->drmFD,
509ab47cfaaSmrg			   pSAVAGEDRIServer->buffers.offset,
510ab47cfaaSmrg			   pSAVAGEDRIServer->buffers.size,
511ab47cfaaSmrg			   DRM_AGP, 0,
512ab47cfaaSmrg			   &pSAVAGEDRIServer->buffers.handle ) < 0 ) {
513ab47cfaaSmrg	       xf86DrvMsg( pScreen->myNum, X_ERROR,
514ab47cfaaSmrg			   "[agp] Could not add DMA buffers mapping\n" );
515ab47cfaaSmrg	       return FALSE;
516ab47cfaaSmrg	   }
517ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_INFO,
518ab47cfaaSmrg		       "[agp] DMA buffers handle = 0x%08lx\n",
5195788ca14Smrg		       (unsigned long)pSAVAGEDRIServer->buffers.handle );
520ab47cfaaSmrg	   /* not needed in the server
521ab47cfaaSmrg	   if ( drmMap( psav->drmFD,
522ab47cfaaSmrg			pSAVAGEDRIServer->buffers.handle,
523ab47cfaaSmrg			pSAVAGEDRIServer->buffers.size,
524ab47cfaaSmrg			&pSAVAGEDRIServer->buffers.map ) < 0 ) {
525ab47cfaaSmrg	       xf86DrvMsg( pScreen->myNum, X_ERROR,
526ab47cfaaSmrg			   "[agp] Could not map DMA buffers\n" );
527ab47cfaaSmrg	       return FALSE;
528ab47cfaaSmrg	   }
529ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_INFO,
530ab47cfaaSmrg		       "[agp] DMA buffers mapped at 0x%08lx\n",
531ab47cfaaSmrg		       (unsigned long)pSAVAGEDRIServer->buffers.map );
532ab47cfaaSmrg	   */
533ab47cfaaSmrg       }
534ab47cfaaSmrg   }
535ab47cfaaSmrg
5361c79cd07Smrg   /* XVideo buffer
5371c79cd07Smrg    */
5381c79cd07Smrg   if (pSAVAGEDRIServer->agpXVideo.size != 0) {
5391c79cd07Smrg       if ( drmAddMap( psav->drmFD,
5401c79cd07Smrg		   pSAVAGEDRIServer->agpXVideo.offset,
5411c79cd07Smrg		   pSAVAGEDRIServer->agpXVideo.size,
5421c79cd07Smrg		   DRM_AGP, 0,
5431c79cd07Smrg		   &pSAVAGEDRIServer->agpXVideo.handle ) < 0 ) {
5441c79cd07Smrg	    xf86DrvMsg( pScreen->myNum, X_ERROR,
5451c79cd07Smrg		  "[agp] Could not add agpXVideo, will use framebuffer upload (slower) \n" );
5461c79cd07Smrg	    pSAVAGEDRIServer->agpXVideo.size = 0;
5471c79cd07Smrg	    pSAVAGEDRIServer->agpXVideo.handle = 0;
5481c79cd07Smrg       } else {
5491c79cd07Smrg	    xf86DrvMsg( pScreen->myNum, X_INFO,
5501c79cd07Smrg	       "[agp] agpXVideo handle = 0x%08lx\n",
5515788ca14Smrg	       (unsigned long)pSAVAGEDRIServer->agpXVideo.handle );
5521c79cd07Smrg       }
5531c79cd07Smrg   }
5541c79cd07Smrg
555ab47cfaaSmrg   /* AGP textures
556ab47cfaaSmrg    */
557ab47cfaaSmrg   if ( drmAddMap( psav->drmFD,
558ab47cfaaSmrg		   pSAVAGEDRIServer->agpTextures.offset,
559ab47cfaaSmrg		   pSAVAGEDRIServer->agpTextures.size,
560ab47cfaaSmrg		   DRM_AGP, 0,
561ab47cfaaSmrg		   &pSAVAGEDRIServer->agpTextures.handle ) < 0 ) {
562ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
563ab47cfaaSmrg		  "[agp] Could not add agpTextures \n" );
564ab47cfaaSmrg      return FALSE;
565ab47cfaaSmrg   }
566ab47cfaaSmrg   /*   pSAVAGEDRIServer->agp_offset=pSAVAGEDRIServer->agpTexture.size;*/
567ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
568ab47cfaaSmrg	       "[agp] agpTextures handle = 0x%08lx\n",
5695788ca14Smrg	       (unsigned long)pSAVAGEDRIServer->agpTextures.handle );
570ab47cfaaSmrg
571ab47cfaaSmrg   /* not needed in the server
572ab47cfaaSmrg   if ( drmMap( psav->drmFD,
573ab47cfaaSmrg		pSAVAGEDRIServer->agpTextures.handle,
574ab47cfaaSmrg		pSAVAGEDRIServer->agpTextures.size,
575ab47cfaaSmrg		&pSAVAGEDRIServer->agpTextures.map ) < 0 ) {
576ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
577ab47cfaaSmrg		  "[agp] Could not map agpTextures \n" );
578ab47cfaaSmrg      return FALSE;
579ab47cfaaSmrg   }
580ab47cfaaSmrg
581ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
582ab47cfaaSmrg	       "[agp] agpTextures mapped at 0x%08lx\n",
583ab47cfaaSmrg	       (unsigned long)pSAVAGEDRIServer->agpTextures.map );
584ab47cfaaSmrg   */
585ab47cfaaSmrg
586ab47cfaaSmrg   return TRUE;
587ab47cfaaSmrg}
588ab47cfaaSmrg
589ab47cfaaSmrgstatic Bool SAVAGEDRIMapInit( ScreenPtr pScreen )
590ab47cfaaSmrg{
5915788ca14Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
592ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
593ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
594ab47cfaaSmrg
595ab47cfaaSmrg   pSAVAGEDRIServer->registers.size = SAVAGEIOMAPSIZE;
596ab47cfaaSmrg
597ab47cfaaSmrg   if ( drmAddMap( psav->drmFD,
5988697ee19Smrg		   (drm_handle_t)psav->MmioRegion.base,
599ab47cfaaSmrg		   pSAVAGEDRIServer->registers.size,
600ab47cfaaSmrg		   DRM_REGISTERS,0,
601ab47cfaaSmrg		   &pSAVAGEDRIServer->registers.handle ) < 0 ) {
602ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
603ab47cfaaSmrg		  "[drm] Could not add MMIO registers mapping\n" );
604ab47cfaaSmrg      return FALSE;
605ab47cfaaSmrg   }
606ab47cfaaSmrg
607ab47cfaaSmrg   pSAVAGEDRIServer->aperture.size = 5 * 0x01000000;
608ab47cfaaSmrg
609ab47cfaaSmrg   if ( drmAddMap( psav->drmFD,
6108697ee19Smrg		   (drm_handle_t)(psav->ApertureRegion.base),
611ab47cfaaSmrg		   pSAVAGEDRIServer->aperture.size,
612ab47cfaaSmrg		   DRM_FRAME_BUFFER,0,
613ab47cfaaSmrg		   &pSAVAGEDRIServer->aperture.handle ) < 0 ) {
614ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
615ab47cfaaSmrg		  "[drm] Could not add aperture mapping\n" );
616ab47cfaaSmrg      return FALSE;
617ab47cfaaSmrg   }
618ab47cfaaSmrg
619ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
620ab47cfaaSmrg	       "[drm] aperture handle = 0x%08lx\n",
6215788ca14Smrg	       (unsigned long)pSAVAGEDRIServer->aperture.handle );
622ab47cfaaSmrg
623ab47cfaaSmrg   /*if(drmMap(psav->drmFD,
624ab47cfaaSmrg          pSAVAGEDRIServer->registers.handle,
625ab47cfaaSmrg          pSAVAGEDRIServer->registers.size,
626ab47cfaaSmrg          &pSAVAGEDRIServer->registers.map)<0)
627ab47cfaaSmrg   {
628ab47cfaaSmrg         xf86DrvMsg( pScreen->myNum, X_ERROR,
629ab47cfaaSmrg		  "[drm] Could not map MMIO registers region to virtual\n" );
630ab47cfaaSmrg      return FALSE;
631ab47cfaaSmrg
632ab47cfaaSmrg   }*/
633ab47cfaaSmrg
634ab47cfaaSmrg   if ( !psav->AgpDMA && psav->CommandDMA ) {
635ab47cfaaSmrg       pSAVAGEDRIServer->cmdDma.size = SAVAGE_CMDDMA_SIZE;
636ab47cfaaSmrg       if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->cmdDma.size,
637ab47cfaaSmrg		       DRM_CONSISTENT, DRM_RESTRICTED | DRM_LOCKED |
638ab47cfaaSmrg		       DRM_KERNEL | DRM_WRITE_COMBINING,
639ab47cfaaSmrg		       &pSAVAGEDRIServer->cmdDma.handle ) < 0 ) {
640ab47cfaaSmrg	   psav->CommandDMA = FALSE;
641ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_WARNING,
642ab47cfaaSmrg		       "[drm] Could not add PCI command DMA mapping\n" );
643ab47cfaaSmrg       } else
644ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_INFO,
645ab47cfaaSmrg		       "[drm] PCI command DMA handle = 0x%08lx\n",
6465788ca14Smrg		       (unsigned long)pSAVAGEDRIServer->cmdDma.handle );
647ab47cfaaSmrg   }
648ab47cfaaSmrg
649ab47cfaaSmrg   /* Enable ShadowStatus by default for direct rendering. */
650ab47cfaaSmrg   if ( !psav->ShadowStatus && !psav->ForceShadowStatus ) {
651ab47cfaaSmrg       psav->ShadowStatus = TRUE;
652ab47cfaaSmrg       xf86DrvMsg( pScreen->myNum, X_INFO,
653ab47cfaaSmrg		   "[drm] Enabling ShadowStatus for DRI.\n" );
654ab47cfaaSmrg   }
655ab47cfaaSmrg
656ab47cfaaSmrg   /* If shadow status is manually or automatically enabled, use a
657ab47cfaaSmrg    * page in system memory. */
658ab47cfaaSmrg   if ( psav->ShadowStatus ) {
659ab47cfaaSmrg       pSAVAGEDRIServer->status.size = 4096; /* 1 page */
660ab47cfaaSmrg
661ab47cfaaSmrg       if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->status.size,
662ab47cfaaSmrg		       DRM_CONSISTENT, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL,
663ab47cfaaSmrg		       &pSAVAGEDRIServer->status.handle ) < 0 ) {
664ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_ERROR,
665ab47cfaaSmrg		       "[drm] Could not add status page mapping\n" );
666ab47cfaaSmrg	   return FALSE;
667ab47cfaaSmrg       }
668ab47cfaaSmrg       xf86DrvMsg( pScreen->myNum, X_INFO,
669ab47cfaaSmrg		   "[drm] Status handle = 0x%08lx\n",
6705788ca14Smrg		   (unsigned long)pSAVAGEDRIServer->status.handle );
671ab47cfaaSmrg
672ab47cfaaSmrg       if ( drmMap( psav->drmFD,
673ab47cfaaSmrg		    pSAVAGEDRIServer->status.handle,
674ab47cfaaSmrg		    pSAVAGEDRIServer->status.size,
675ab47cfaaSmrg		    &pSAVAGEDRIServer->status.map ) < 0 ) {
676ab47cfaaSmrg	   xf86DrvMsg( pScreen->myNum, X_ERROR,
677ab47cfaaSmrg		       "[drm] Could not map status page\n" );
678ab47cfaaSmrg	   return FALSE;
679ab47cfaaSmrg       }
680ab47cfaaSmrg       xf86DrvMsg( pScreen->myNum, X_INFO,
681ab47cfaaSmrg		   "[drm] Status page mapped at 0x%08lx\n",
682ab47cfaaSmrg		   (unsigned long)pSAVAGEDRIServer->status.map );
683ab47cfaaSmrg
684ab47cfaaSmrg       psav->ShadowPhysical = pSAVAGEDRIServer->status.handle;
685ab47cfaaSmrg       psav->ShadowVirtual = pSAVAGEDRIServer->status.map;
686ab47cfaaSmrg   }
687ab47cfaaSmrg
688ab47cfaaSmrg   return TRUE;
689ab47cfaaSmrg}
690ab47cfaaSmrg
691ab47cfaaSmrgstatic Bool SAVAGEDRIBuffersInit( ScreenPtr pScreen )
692ab47cfaaSmrg{
6935788ca14Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
694ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
695ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
696ab47cfaaSmrg   int count;
697ab47cfaaSmrg
698ab47cfaaSmrg   if ( !psav->VertexDMA || psav->CommandDMA ) {
699ab47cfaaSmrg       /* At this point psav->CommandDMA == TRUE means that CommandDMA
700ab47cfaaSmrg	* allocation was actually successful. */
701ab47cfaaSmrg       psav->VertexDMA = FALSE;
702ab47cfaaSmrg       return TRUE;
703ab47cfaaSmrg   }
704ab47cfaaSmrg
705ab47cfaaSmrg   if ( psav->AgpDMA ) {
706ab47cfaaSmrg       count = drmAddBufs( psav->drmFD,
707ab47cfaaSmrg			   SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE,
708ab47cfaaSmrg			   DRM_AGP_BUFFER, pSAVAGEDRIServer->buffers.offset );
709ab47cfaaSmrg   } else {
710ab47cfaaSmrg       count = drmAddBufs( psav->drmFD,
711ab47cfaaSmrg			   SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE,
712ab47cfaaSmrg			   0, 0 );
713ab47cfaaSmrg   }
714ab47cfaaSmrg   if ( count <= 0 ) {
715ab47cfaaSmrg       xf86DrvMsg( pScrn->scrnIndex, X_INFO,
716ab47cfaaSmrg		   "[drm] failure adding %d %d byte DMA buffers (%d)\n",
717ab47cfaaSmrg		   SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE, count );
718ab47cfaaSmrg       return FALSE;
719ab47cfaaSmrg   }
720ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
721ab47cfaaSmrg	       "[drm] Added %d %d byte DMA buffers\n",
722ab47cfaaSmrg	       count, SAVAGE_BUFFER_SIZE );
723ab47cfaaSmrg
724ab47cfaaSmrg   /* not needed in the server
725ab47cfaaSmrg   pSAVAGEDRIServer->drmBuffers = drmMapBufs( psav->drmFD );
726ab47cfaaSmrg   if ( !pSAVAGEDRIServer->drmBuffers ) {
727ab47cfaaSmrg	xf86DrvMsg( pScreen->myNum, X_ERROR,
728ab47cfaaSmrg		    "[drm] Failed to map DMA buffers list\n" );
729ab47cfaaSmrg	return FALSE;
730ab47cfaaSmrg    }
731ab47cfaaSmrg    xf86DrvMsg( pScreen->myNum, X_INFO,
732ab47cfaaSmrg		"[drm] Mapped %d DMA buffers\n",
733ab47cfaaSmrg		pSAVAGEDRIServer->drmBuffers->count );
734ab47cfaaSmrg   */
735ab47cfaaSmrg
736ab47cfaaSmrg    return TRUE;
737ab47cfaaSmrg}
738ab47cfaaSmrg
739ab47cfaaSmrgstatic Bool SAVAGEDRIKernelInit( ScreenPtr pScreen )
740ab47cfaaSmrg{
7415788ca14Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
742ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
743ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
744ab47cfaaSmrg   drmSAVAGEInit init;
745ab47cfaaSmrg   int ret;
746ab47cfaaSmrg
747ab47cfaaSmrg   memset( &init, 0, sizeof(drmSAVAGEInit) );
748ab47cfaaSmrg
749ab47cfaaSmrg   init.func = SAVAGE_INIT_BCI;
750ab47cfaaSmrg   init.sarea_priv_offset = sizeof(XF86DRISAREARec);
751ab47cfaaSmrg
752ab47cfaaSmrg   init.cob_size = psav->cobSize/4; /* size in 32-bit entries */
753ab47cfaaSmrg   init.bci_threshold_lo = psav->bciThresholdLo;
754ab47cfaaSmrg   init.bci_threshold_hi = psav->bciThresholdHi;
755ab47cfaaSmrg   init.dma_type = psav->AgpDMA ? SAVAGE_DMA_AGP : SAVAGE_DMA_PCI;
756ab47cfaaSmrg
757ab47cfaaSmrg   init.fb_bpp		= pScrn->bitsPerPixel;
758ab47cfaaSmrg   init.front_offset	= pSAVAGEDRIServer->frontOffset;
759ab47cfaaSmrg   init.front_pitch	= pSAVAGEDRIServer->frontPitch;
760ab47cfaaSmrg   init.back_offset	= pSAVAGEDRIServer->backOffset;
761ab47cfaaSmrg   init.back_pitch	= pSAVAGEDRIServer->backPitch;
762ab47cfaaSmrg
763ab47cfaaSmrg   init.depth_bpp	= pScrn->bitsPerPixel;
764ab47cfaaSmrg   init.depth_offset	= pSAVAGEDRIServer->depthOffset;
765ab47cfaaSmrg   init.depth_pitch	= pSAVAGEDRIServer->depthPitch;
766ab47cfaaSmrg
767ab47cfaaSmrg   init.texture_offset  = pSAVAGEDRIServer->textureOffset;
768ab47cfaaSmrg   init.texture_size    = pSAVAGEDRIServer->textureSize;
769ab47cfaaSmrg
770ab47cfaaSmrg   init.status_offset   = pSAVAGEDRIServer->status.handle;
771ab47cfaaSmrg   init.agp_textures_offset = pSAVAGEDRIServer->agpTextures.handle;
772ab47cfaaSmrg
773ab47cfaaSmrg   /* Savage4-based chips with DRM version >= 2.4 support command DMA,
774ab47cfaaSmrg    * which is preferred because it works with all vertex
775ab47cfaaSmrg    * formats. Command DMA and vertex DMA don't work at the same
776ab47cfaaSmrg    * time. */
777ab47cfaaSmrg   init.buffers_offset = 0;
778ab47cfaaSmrg   init.cmd_dma_offset = 0;
779ab47cfaaSmrg   if ( psav->CommandDMA )
780ab47cfaaSmrg       init.cmd_dma_offset = pSAVAGEDRIServer->cmdDma.handle;
781ab47cfaaSmrg   else if ( psav->VertexDMA )
782ab47cfaaSmrg       init.buffers_offset = pSAVAGEDRIServer->buffers.handle;
783ab47cfaaSmrg
784ab47cfaaSmrg   ret = drmCommandWrite( psav->drmFD, DRM_SAVAGE_BCI_INIT, &init, sizeof(init) );
785ab47cfaaSmrg   if ( ret < 0 ) {
786ab47cfaaSmrg      xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
787ab47cfaaSmrg		  "[drm] Failed to initialize BCI! (%d)\n", ret );
788ab47cfaaSmrg      return FALSE;
789ab47cfaaSmrg   }
790ab47cfaaSmrg
791ab47cfaaSmrg   return TRUE;
792ab47cfaaSmrg}
793ab47cfaaSmrg
794ab47cfaaSmrgBool SAVAGEDRIScreenInit( ScreenPtr pScreen )
795ab47cfaaSmrg{
7965788ca14Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
797ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
798ab47cfaaSmrg   DRIInfoPtr pDRIInfo;
799ab47cfaaSmrg   SAVAGEDRIPtr pSAVAGEDRI;
800ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer;
801ab47cfaaSmrg
802ab47cfaaSmrg   /* Check that the GLX, DRI, and DRM modules have been loaded by testing
803ab47cfaaSmrg    * for canonical symbols in each module.
804ab47cfaaSmrg    */
805ab47cfaaSmrg   if ( !xf86LoaderCheckSymbol( "GlxSetVisualConfigs" ) )	return FALSE;
806ab47cfaaSmrg   if ( !xf86LoaderCheckSymbol( "drmAvailable" ) )		return FALSE;
807ab47cfaaSmrg   if ( !xf86LoaderCheckSymbol( "DRIQueryVersion" ) ) {
808ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
809ab47cfaaSmrg		  "[dri] SAVAGEDRIScreenInit failed (libdri.a too old)\n" );
810ab47cfaaSmrg      return FALSE;
811ab47cfaaSmrg   }
812ab47cfaaSmrg
813ab47cfaaSmrg   /* Check the DRI version */
814ab47cfaaSmrg   {
815ab47cfaaSmrg      int major, minor, patch;
816ab47cfaaSmrg      DRIQueryVersion( &major, &minor, &patch );
817ab47cfaaSmrg      if ( major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION ) {
818ab47cfaaSmrg         xf86DrvMsg( pScreen->myNum, X_ERROR,
819ab47cfaaSmrg		     "[dri] SAVAGEDRIScreenInit failed because of a version mismatch.\n"
820ab47cfaaSmrg		     "[dri] libdri version = %d.%d.%d but version %d.%d.x is needed.\n"
821ab47cfaaSmrg		     "[dri] Disabling the DRI.\n",
822ab47cfaaSmrg		     major, minor, patch,
823ab47cfaaSmrg                     DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION );
824ab47cfaaSmrg         return FALSE;
825ab47cfaaSmrg      }
826ab47cfaaSmrg   }
827ab47cfaaSmrg
828ab47cfaaSmrg   xf86DrvMsg( pScreen->myNum, X_INFO,
829ab47cfaaSmrg	       "[drm] bpp: %d depth: %d\n",
830ab47cfaaSmrg	       pScrn->bitsPerPixel, pScrn->depth );
831ab47cfaaSmrg
832ab47cfaaSmrg   if ( (pScrn->bitsPerPixel / 8) != 2 &&
833ab47cfaaSmrg	(pScrn->bitsPerPixel / 8) != 4 ) {
834ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
835ab47cfaaSmrg		  "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" );
836ab47cfaaSmrg      return FALSE;
837ab47cfaaSmrg   }
838ab47cfaaSmrg
839ab47cfaaSmrg   pDRIInfo = DRICreateInfoRec();
840ab47cfaaSmrg   if ( !pDRIInfo ) {
841ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
842ab47cfaaSmrg		  "[dri] DRICreateInfoRec() failed\n" );
843ab47cfaaSmrg      return FALSE;
844ab47cfaaSmrg   }
845ab47cfaaSmrg   psav->pDRIInfo = pDRIInfo;
846ab47cfaaSmrg
847ab47cfaaSmrg   pDRIInfo->drmDriverName = SAVAGEKernelDriverName;
848ab47cfaaSmrg   pDRIInfo->clientDriverName = SAVAGEClientDriverName;
849ab47cfaaSmrg   if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
850ab47cfaaSmrg      pDRIInfo->busIdString = DRICreatePCIBusID(psav->PciInfo);
851ab47cfaaSmrg   } else {
8525788ca14Smrg      pDRIInfo->busIdString            = malloc(64);
853ab47cfaaSmrg      sprintf(pDRIInfo->busIdString,
854ab47cfaaSmrg              "PCI:%d:%d:%d",
855ab47cfaaSmrg              psav->PciInfo->bus,
8568697ee19Smrg#ifdef XSERVER_LIBPCIACCESS
8578697ee19Smrg              psav->PciInfo->dev,
8588697ee19Smrg#else
859ab47cfaaSmrg              psav->PciInfo->device,
8608697ee19Smrg#endif
861ab47cfaaSmrg              psav->PciInfo->func);
862ab47cfaaSmrg   }
863ab47cfaaSmrg   pDRIInfo->ddxDriverMajorVersion = SAVAGE_VERSION_MAJOR;
864ab47cfaaSmrg   pDRIInfo->ddxDriverMinorVersion = SAVAGE_VERSION_MINOR;
865ab47cfaaSmrg   pDRIInfo->ddxDriverPatchVersion = SAVAGE_PATCHLEVEL;
866ab47cfaaSmrg
8672c9fd100Smrg   pDRIInfo->frameBufferPhysicalAddress = (pointer)(uintptr_t) psav->FbRegion.base;
868ab47cfaaSmrg   pDRIInfo->frameBufferSize = psav->videoRambytes;
869ab47cfaaSmrg   pDRIInfo->frameBufferStride = pScrn->displayWidth*(pScrn->bitsPerPixel/8);
870ab47cfaaSmrg   pDRIInfo->ddxDrawableTableEntry = SAVAGE_MAX_DRAWABLES;
871ab47cfaaSmrg
872ab47cfaaSmrg   /* override default DRI block and wakeup handler */
873ab47cfaaSmrg   psav->coreBlockHandler = pDRIInfo->wrap.BlockHandler;
874ab47cfaaSmrg   pDRIInfo->wrap.BlockHandler = SAVAGEBlockHandler;
875ab47cfaaSmrg   psav->coreWakeupHandler = pDRIInfo->wrap.WakeupHandler;
876ab47cfaaSmrg   pDRIInfo->wrap.WakeupHandler = SAVAGEWakeupHandler;
877ab47cfaaSmrg
878ab47cfaaSmrg   pDRIInfo->wrap.ValidateTree = NULL;
879ab47cfaaSmrg   pDRIInfo->wrap.PostValidateTree = NULL;
880ab47cfaaSmrg
881ab47cfaaSmrg   pDRIInfo->createDummyCtx = TRUE;
882ab47cfaaSmrg   pDRIInfo->createDummyCtxPriv = FALSE;
883ab47cfaaSmrg
884ab47cfaaSmrg   if ( SAREA_MAX_DRAWABLES < SAVAGE_MAX_DRAWABLES ) {
885ab47cfaaSmrg      pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
886ab47cfaaSmrg   } else {
887ab47cfaaSmrg      pDRIInfo->maxDrawableTableEntry = SAVAGE_MAX_DRAWABLES;
888ab47cfaaSmrg   }
889ab47cfaaSmrg
890ab47cfaaSmrg   /* For now the mapping works by using a fixed size defined
891ab47cfaaSmrg    * in the SAREA header.
892ab47cfaaSmrg    */
893ab47cfaaSmrg   if ( sizeof(XF86DRISAREARec) + sizeof(SAVAGESAREAPrivRec) > SAREA_MAX ) {
894ab47cfaaSmrg      xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
895ab47cfaaSmrg		  "[drm] Data does not fit in SAREA\n" );
896ab47cfaaSmrg      return FALSE;
897ab47cfaaSmrg   }
898ab47cfaaSmrg
899ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO,
900ab47cfaaSmrg	       "[drm] Sarea %d+%d: %d\n",
901ab47cfaaSmrg	       sizeof(XF86DRISAREARec), sizeof(SAVAGESAREAPrivRec),
902ab47cfaaSmrg	       sizeof(XF86DRISAREARec) + sizeof(SAVAGESAREAPrivRec) );
903ab47cfaaSmrg
904ab47cfaaSmrg   pDRIInfo->SAREASize = SAREA_MAX;
905ab47cfaaSmrg
9065788ca14Smrg   pSAVAGEDRI = (SAVAGEDRIPtr)calloc( sizeof(SAVAGEDRIRec), 1 );
907ab47cfaaSmrg   if ( !pSAVAGEDRI ) {
908ab47cfaaSmrg      DRIDestroyInfoRec( psav->pDRIInfo );
909ab47cfaaSmrg      psav->pDRIInfo = 0;
910ab47cfaaSmrg      xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
911ab47cfaaSmrg		  "[drm] Failed to allocate memory for private record\n" );
912ab47cfaaSmrg      return FALSE;
913ab47cfaaSmrg   }
914ab47cfaaSmrg
915ab47cfaaSmrg   pSAVAGEDRIServer = (SAVAGEDRIServerPrivatePtr)
9165788ca14Smrg      calloc( sizeof(SAVAGEDRIServerPrivateRec), 1 );
917ab47cfaaSmrg   if ( !pSAVAGEDRIServer ) {
9185788ca14Smrg      free( pSAVAGEDRI );
919ab47cfaaSmrg      DRIDestroyInfoRec( psav->pDRIInfo );
920ab47cfaaSmrg      psav->pDRIInfo = 0;
921ab47cfaaSmrg      xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
922ab47cfaaSmrg		  "[drm] Failed to allocate memory for private record\n" );
923ab47cfaaSmrg      return FALSE;
924ab47cfaaSmrg   }
925ab47cfaaSmrg   psav->DRIServerInfo = pSAVAGEDRIServer;
926ab47cfaaSmrg
927ab47cfaaSmrg   pDRIInfo->devPrivate = pSAVAGEDRI;
928ab47cfaaSmrg   pDRIInfo->devPrivateSize = sizeof(SAVAGEDRIRec);
929ab47cfaaSmrg   pDRIInfo->contextSize = sizeof(SAVAGEDRIContextRec);
930ab47cfaaSmrg
931ab47cfaaSmrg   pDRIInfo->CreateContext = SAVAGECreateContext;
932ab47cfaaSmrg   pDRIInfo->DestroyContext = SAVAGEDestroyContext;
933ab47cfaaSmrg
934ab47cfaaSmrg   /* FK: SwapContext is not used with KERNEL_SWAP. */
935ab47cfaaSmrg   pDRIInfo->SwapContext = NULL;
936ab47cfaaSmrg
937ab47cfaaSmrg   pDRIInfo->InitBuffers = SAVAGEDRIInitBuffers;
938ab47cfaaSmrg   pDRIInfo->MoveBuffers = SAVAGEDRIMoveBuffers;
939ab47cfaaSmrg   pDRIInfo->OpenFullScreen = SAVAGEDRIOpenFullScreen;
940ab47cfaaSmrg   pDRIInfo->CloseFullScreen = SAVAGEDRICloseFullScreen;
941ab47cfaaSmrg   pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
942ab47cfaaSmrg
943ab47cfaaSmrg   if ( !DRIScreenInit( pScreen, pDRIInfo, &psav->drmFD ) ) {
9445788ca14Smrg      free( pSAVAGEDRIServer );
945ab47cfaaSmrg      psav->DRIServerInfo = 0;
9465788ca14Smrg      free( pDRIInfo->devPrivate );
947ab47cfaaSmrg      pDRIInfo->devPrivate = 0;
948ab47cfaaSmrg      DRIDestroyInfoRec( psav->pDRIInfo );
949ab47cfaaSmrg      psav->pDRIInfo = 0;
950ab47cfaaSmrg      xf86DrvMsg( pScreen->myNum, X_ERROR,
951ab47cfaaSmrg		  "[drm] DRIScreenInit failed.  Disabling DRI.\n" );
952ab47cfaaSmrg      return FALSE;
953ab47cfaaSmrg   }
954ab47cfaaSmrg
955ab47cfaaSmrg   /* Check the SAVAGE DRM version */
956ab47cfaaSmrg   {
957ab47cfaaSmrg      drmVersionPtr version = drmGetVersion(psav->drmFD);
958ab47cfaaSmrg      if ( version ) {
959ab47cfaaSmrg         if ( version->version_major != 2 ||
960ab47cfaaSmrg	      version->version_minor < 0 ) {
961ab47cfaaSmrg            /* incompatible drm version */
962ab47cfaaSmrg            xf86DrvMsg( pScreen->myNum, X_ERROR,
963ab47cfaaSmrg			"[dri] SAVAGEDRIScreenInit failed because of a version mismatch.\n"
964ab47cfaaSmrg			"[dri] savage.ko kernel module version is %d.%d.%d but version 2.0.x is needed.\n"
965ab47cfaaSmrg			"[dri] Disabling DRI.\n",
966ab47cfaaSmrg			version->version_major,
967ab47cfaaSmrg			version->version_minor,
968ab47cfaaSmrg			version->version_patchlevel );
969ab47cfaaSmrg            drmFreeVersion( version );
970ab47cfaaSmrg	    SAVAGEDRICloseScreen( pScreen );		/* FIXME: ??? */
971ab47cfaaSmrg            return FALSE;
972ab47cfaaSmrg         }
973ab47cfaaSmrg	 if ( psav->CommandDMA && version->version_minor < 4 ) {
974ab47cfaaSmrg	    xf86DrvMsg( pScreen->myNum, X_WARNING,
975ab47cfaaSmrg			"[drm] DRM version < 2.4.0 does not support command DMA.\n");
976ab47cfaaSmrg	    psav->CommandDMA = FALSE;
977ab47cfaaSmrg	 }
978ab47cfaaSmrg	 if ( !psav->VertexDMA && version->version_minor < 4 ) {
979ab47cfaaSmrg	    xf86DrvMsg( pScreen->myNum, X_ERROR,
980ab47cfaaSmrg			"[drm] DRM version < 2.4.0 requires vertex DMA.\n");
981ab47cfaaSmrg	    drmFreeVersion( version );
982ab47cfaaSmrg	    SAVAGEDRICloseScreen( pScreen );
983ab47cfaaSmrg	    return FALSE;
984ab47cfaaSmrg	 }
985ab47cfaaSmrg         drmFreeVersion( version );
986ab47cfaaSmrg      }
987ab47cfaaSmrg   }
988ab47cfaaSmrg
989ab47cfaaSmrg   if ( !psav->IsPCI && !SAVAGEDRIAgpInit( pScreen ) ) {
990ab47cfaaSmrg       if (pSAVAGEDRIServer->agp.handle != 0) {
991ab47cfaaSmrg	   /* AGP initialization succeeded, but adding AGP mappings failed. */
992ab47cfaaSmrg	   SAVAGEDRICloseScreen( pScreen );
993ab47cfaaSmrg	   return FALSE;
994ab47cfaaSmrg       }
995ab47cfaaSmrg       /* AGP initialization failed, fall back to PCI mode. */
996ab47cfaaSmrg       psav->IsPCI = TRUE;
997ab47cfaaSmrg       psav->AgpDMA = FALSE;
998ab47cfaaSmrg       xf86DrvMsg( pScrn->scrnIndex, X_WARNING,
999ab47cfaaSmrg		   "[agp] AGP failed to initialize -- falling back to PCI mode.\n");
1000ab47cfaaSmrg       xf86DrvMsg( pScrn->scrnIndex, X_WARNING,
1001ab47cfaaSmrg		   "[agp] Make sure you have the agpgart kernel module loaded.\n");
1002ab47cfaaSmrg   }
1003ab47cfaaSmrg
1004ab47cfaaSmrg   if ( !SAVAGEDRIMapInit( pScreen ) ) {
1005ab47cfaaSmrg      SAVAGEDRICloseScreen( pScreen );
1006ab47cfaaSmrg      return FALSE;
1007ab47cfaaSmrg   }
1008ab47cfaaSmrg
10095788ca14Smrg   /* Linux kernel DRM broken in 2.6.30 through 2.6.39 */
10105788ca14Smrg   if (pDRIInfo->hFrameBuffer == pSAVAGEDRIServer->aperture.handle)
10115788ca14Smrg       xf86DrvMsg( pScrn->scrnIndex, X_WARNING,
10125788ca14Smrg		   "[drm] Detected broken drm maps. Please upgrade to linux kernel 3.x\n");
10135788ca14Smrg
1014ab47cfaaSmrg   if ( !SAVAGEDRIBuffersInit( pScreen ) ) {
1015ab47cfaaSmrg      SAVAGEDRICloseScreen( pScreen );
1016ab47cfaaSmrg      return FALSE;
1017ab47cfaaSmrg   }
1018ab47cfaaSmrg
1019ab47cfaaSmrg   if ( !SAVAGEInitVisualConfigs( pScreen ) ) {
1020ab47cfaaSmrg      SAVAGEDRICloseScreen( pScreen );
1021ab47cfaaSmrg      return FALSE;
1022ab47cfaaSmrg   }
1023ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized\n" );
1024ab47cfaaSmrg
1025ab47cfaaSmrg   return TRUE;
1026ab47cfaaSmrg}
1027ab47cfaaSmrg
10285788ca14Smrgstatic void SAVAGEDRISetupTiledSurfaceRegs( SavagePtr psav )
10295788ca14Smrg{
10305788ca14Smrg      SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate;
10315788ca14Smrg      unsigned int value = 0;
10325788ca14Smrg
10335788ca14Smrg      OUTREG(0x850C,(INREG(0x850C) | 0x00008000)); /* AGD: I don't think this does anything on 3D/MX/IX */
10345788ca14Smrg						   /* maybe savage4 too... */
10355788ca14Smrg      /* we don't use Y range flag,so comment it */
10365788ca14Smrg      /*
10375788ca14Smrg        if(pSAVAGEDRI->width <= 1024)
10385788ca14Smrg            value |= (1<<29);
10395788ca14Smrg      */
10405788ca14Smrg      if ((psav->Chipset == S3_SAVAGE_MX) /* 3D/MX/IX seem to set up the tile stride differently */
10415788ca14Smrg	|| (psav->Chipset == S3_SAVAGE3D)) {
10425788ca14Smrg      	    if(pSAVAGEDRI->cpp == 2)
10435788ca14Smrg      	    {
10445788ca14Smrg         	value |=  ((psav->lDelta / 4) >> 5) << 24;
10455788ca14Smrg         	value |= 2<<30;
10465788ca14Smrg      	    } else {
10475788ca14Smrg         	value |=  ((psav->lDelta / 4) >> 5) << 24;
10485788ca14Smrg         	value |= 3<<30;
10495788ca14Smrg      	    }
10505788ca14Smrg
10515788ca14Smrg	    OUTREG(TILED_SURFACE_REGISTER_0, value|(pSAVAGEDRI->frontOffset) ); /* front */
10525788ca14Smrg	    OUTREG(TILED_SURFACE_REGISTER_1, value|(pSAVAGEDRI->backOffset) ); /* back  */
10535788ca14Smrg	    OUTREG(TILED_SURFACE_REGISTER_2, value|(pSAVAGEDRI->depthOffset) ); /* depth */
10545788ca14Smrg      } else {
10555788ca14Smrg	    int offset_shift = 5;
10565788ca14Smrg      	    if(pSAVAGEDRI->cpp == 2)
10575788ca14Smrg      	    {
10585788ca14Smrg         	value |=  (((pSAVAGEDRI->width + 0x3F) & 0xFFC0) >> 6) << 20;
10595788ca14Smrg         	value |= 2<<30;
10605788ca14Smrg      	    } else {
10615788ca14Smrg         	value |=  (((pSAVAGEDRI->width + 0x1F) & 0xFFE0) >> 5) << 20;
10625788ca14Smrg         	value |= 3<<30;
10635788ca14Smrg      	    }
10645788ca14Smrg	    if (psav->Chipset == S3_SUPERSAVAGE) /* supersavages have a different shift */
10655788ca14Smrg		offset_shift = 6;
10665788ca14Smrg	    OUTREG(TILED_SURFACE_REGISTER_0, value|(pSAVAGEDRI->frontOffset >> offset_shift) ); /* front */
10675788ca14Smrg	    OUTREG(TILED_SURFACE_REGISTER_1, value|(pSAVAGEDRI->backOffset >> offset_shift) ); /* back  */
10685788ca14Smrg	    OUTREG(TILED_SURFACE_REGISTER_2, value|(pSAVAGEDRI->depthOffset >> offset_shift) ); /* depth */
10695788ca14Smrg      }
10705788ca14Smrg}
1071ab47cfaaSmrg
1072ab47cfaaSmrgBool SAVAGEDRIFinishScreenInit( ScreenPtr pScreen )
1073ab47cfaaSmrg{
10745788ca14Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1075ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
1076ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
1077ab47cfaaSmrg   SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate;
1078ab47cfaaSmrg   int i;
1079ab47cfaaSmrg
1080ab47cfaaSmrg   if ( !psav->pDRIInfo )
1081ab47cfaaSmrg      return FALSE;
1082ab47cfaaSmrg
1083ab47cfaaSmrg   psav->pDRIInfo->driverSwapMethod = DRI_KERNEL_SWAP;
1084ab47cfaaSmrg
1085ab47cfaaSmrg   /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit
1086ab47cfaaSmrg    * because *DRIKernelInit requires that the hardware lock is held by
1087ab47cfaaSmrg    * the X server, and the first time the hardware lock is grabbed is
1088ab47cfaaSmrg    * in DRIFinishScreenInit.
1089ab47cfaaSmrg    */
1090ab47cfaaSmrg   if ( !DRIFinishScreenInit( pScreen ) ) {
1091ab47cfaaSmrg      SAVAGEDRICloseScreen( pScreen );
1092ab47cfaaSmrg      return FALSE;
1093ab47cfaaSmrg   }
1094ab47cfaaSmrg   psav->LockHeld = 1;
1095ab47cfaaSmrg
1096ab47cfaaSmrg   if ( !SAVAGEDRIKernelInit( pScreen ) ) {
1097ab47cfaaSmrg      SAVAGEDRICloseScreen( pScreen );
1098ab47cfaaSmrg      return FALSE;
1099ab47cfaaSmrg   }
1100ab47cfaaSmrg
1101ab47cfaaSmrg   pSAVAGEDRI->chipset          = psav->Chipset;
1102ab47cfaaSmrg   pSAVAGEDRI->width		= pScrn->virtualX;
1103ab47cfaaSmrg   pSAVAGEDRI->height		= pScrn->virtualY;
1104ab47cfaaSmrg   pSAVAGEDRI->mem		= pScrn->videoRam * 1024;
1105ab47cfaaSmrg   pSAVAGEDRI->cpp		= pScrn->bitsPerPixel / 8;
1106ab47cfaaSmrg   pSAVAGEDRI->zpp		= pSAVAGEDRI->cpp;
1107ab47cfaaSmrg
1108ab47cfaaSmrg   pSAVAGEDRI->agpMode		= psav->IsPCI ? 0 : psav->agpMode;
1109ab47cfaaSmrg
1110ab47cfaaSmrg   pSAVAGEDRI->bufferSize       = SAVAGE_BUFFER_SIZE;
1111ab47cfaaSmrg
1112ab47cfaaSmrg   pSAVAGEDRI->frontOffset		= pSAVAGEDRIServer->frontOffset;
1113ab47cfaaSmrg   pSAVAGEDRI->frontbufferSize		= pSAVAGEDRIServer->frontbufferSize;
1114ab47cfaaSmrg
1115ab47cfaaSmrg   pSAVAGEDRI->backOffset		= pSAVAGEDRIServer->backOffset;
1116ab47cfaaSmrg   pSAVAGEDRI->backbufferSize		= pSAVAGEDRIServer->backbufferSize;
1117ab47cfaaSmrg
1118ab47cfaaSmrg   pSAVAGEDRI->depthOffset		= pSAVAGEDRIServer->depthOffset;
1119ab47cfaaSmrg   pSAVAGEDRI->depthbufferSize		= pSAVAGEDRIServer->depthbufferSize;
1120ab47cfaaSmrg
1121ab47cfaaSmrg   pSAVAGEDRI->textureOffset	= pSAVAGEDRIServer->textureOffset;
1122ab47cfaaSmrg
1123ab47cfaaSmrg   i = mylog2( pSAVAGEDRIServer->textureSize / SAVAGE_NR_TEX_REGIONS );
1124ab47cfaaSmrg   if ( i < SAVAGE_LOG_MIN_TEX_REGION_SIZE )
1125ab47cfaaSmrg      i = SAVAGE_LOG_MIN_TEX_REGION_SIZE;
1126ab47cfaaSmrg
1127ab47cfaaSmrg   pSAVAGEDRI->logTextureGranularity = i;
1128ab47cfaaSmrg   pSAVAGEDRI->textureSize = (pSAVAGEDRIServer->textureSize >> i) << i; /* truncate */
1129ab47cfaaSmrg
1130ab47cfaaSmrg   pSAVAGEDRI->agpTextureHandle = pSAVAGEDRIServer->agpTextures.handle;
1131ab47cfaaSmrg
1132ab47cfaaSmrg   i = mylog2( pSAVAGEDRIServer->agpTextures.size / SAVAGE_NR_TEX_REGIONS );
1133ab47cfaaSmrg   if ( i < SAVAGE_LOG_MIN_TEX_REGION_SIZE )
1134ab47cfaaSmrg      i = SAVAGE_LOG_MIN_TEX_REGION_SIZE;
1135ab47cfaaSmrg
1136ab47cfaaSmrg   pSAVAGEDRI->logAgpTextureGranularity = i;
1137ab47cfaaSmrg   pSAVAGEDRI->agpTextureSize = (pSAVAGEDRIServer->agpTextures.size >> i) << i; /* truncate */
1138ab47cfaaSmrg
1139ab47cfaaSmrg   pSAVAGEDRI->apertureHandle	= pSAVAGEDRIServer->aperture.handle;
1140ab47cfaaSmrg   pSAVAGEDRI->apertureSize	= pSAVAGEDRIServer->aperture.size;
11418697ee19Smrg   pSAVAGEDRI->aperturePitch    = psav->ulAperturePitch;
1142ab47cfaaSmrg
1143ab47cfaaSmrg   pSAVAGEDRI->statusHandle	= pSAVAGEDRIServer->status.handle;
1144ab47cfaaSmrg   pSAVAGEDRI->statusSize	= pSAVAGEDRIServer->status.size;
1145ab47cfaaSmrg
1146ab47cfaaSmrg   pSAVAGEDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
1147ab47cfaaSmrg
1148ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]pSAVAGEDRIServer:\n" );
1149ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	reserved_map_agpstart:0x%08x\n",pSAVAGEDRIServer->reserved_map_agpstart);
1150ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	reserved_map_idx:0x%08x\n",pSAVAGEDRIServer->reserved_map_idx);
1151ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	sarea_priv_offset:0x%08x\n",pSAVAGEDRIServer->sarea_priv_offset);
1152ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	chipset:0x%08x\n",pSAVAGEDRIServer->chipset);
1153ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	sgram:0x%08x\n",pSAVAGEDRIServer->sgram);
1154ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	frontbufferSize:0x%08x\n",pSAVAGEDRIServer->frontbufferSize);
1155ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	frontOffset:0x%08x\n",pSAVAGEDRIServer->frontOffset);
1156ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	frontPitch:0x%08x\n",pSAVAGEDRIServer->frontPitch);
1157ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	backbufferSize:0x%08x\n",pSAVAGEDRIServer->backbufferSize);
1158ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	backOffset:0x%08x\n",pSAVAGEDRIServer->backOffset);
1159ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	backPitch:0x%08x\n",pSAVAGEDRIServer->backPitch);
1160ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	depthbufferSize:0x%08x\n",pSAVAGEDRIServer->depthbufferSize);
1161ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	depthOffset:0x%08x\n",pSAVAGEDRIServer->depthOffset);
1162ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	depthPitch:0x%08x\n",pSAVAGEDRIServer->depthPitch);
1163ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	textureOffset:0x%08x\n",pSAVAGEDRIServer->textureOffset);
1164ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	textureSize:0x%08x\n",pSAVAGEDRIServer->textureSize);
1165ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	textureSize:0x%08x\n",pSAVAGEDRIServer->textureSize);
1166ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	logTextureGranularity:0x%08x\n",pSAVAGEDRIServer->logTextureGranularity);
1167ab47cfaaSmrg
11685788ca14Smrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agp:handle:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agp.handle);
1169ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agp:offset:0x%08x\n",pSAVAGEDRIServer->agp.offset);
1170ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agp:size:0x%08x\n",pSAVAGEDRIServer->agp.size);
1171ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agp:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agp.map);
1172ab47cfaaSmrg
11735788ca14Smrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	registers:handle:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->registers.handle);
1174ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	registers:offset:0x%08x\n",pSAVAGEDRIServer->registers.offset);
1175ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	registers:size:0x%08x\n",pSAVAGEDRIServer->registers.size);
1176ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	registers:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->registers.map);
1177ab47cfaaSmrg
11785788ca14Smrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	status:handle:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->status.handle);
1179ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	status:offset:0x%08x\n",pSAVAGEDRIServer->status.offset);
1180ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	status:size:0x%08x\n",pSAVAGEDRIServer->status.size);
1181ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	status:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->status.map);
1182ab47cfaaSmrg
11835788ca14Smrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agpTextures:handle:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agpTextures.handle);
1184ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agpTextures:offset:0x%08x\n",pSAVAGEDRIServer->agpTextures.offset);
1185ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agpTextures:size:0x%08x\n",pSAVAGEDRIServer->agpTextures.size);
1186ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	apgTextures:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agpTextures.map);
1187ab47cfaaSmrg
1188ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	logAgpTextureGranularity:0x%08x\n",pSAVAGEDRIServer->logAgpTextureGranularity);
1189ab47cfaaSmrg
11905788ca14Smrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	cmdDma:handle:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->cmdDma.handle);
1191ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	cmdDma:offset:0x%08x\n",pSAVAGEDRIServer->cmdDma.offset);
1192ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	cmdDma:size:0x%08x\n",pSAVAGEDRIServer->cmdDma.size);
1193ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	cmdDma:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->cmdDma.map);
1194ab47cfaaSmrg
1195ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]pSAVAGEDRI:\n" );
1196ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	chipset:0x%08x\n",pSAVAGEDRI->chipset );
1197ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	width:0x%08x\n",pSAVAGEDRI->width );
1198ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	height:0x%08x\n",pSAVAGEDRI->height );
1199ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	mem:0x%08x\n",pSAVAGEDRI->mem );
1200ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	cpp:%d\n",pSAVAGEDRI->cpp );
1201ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	zpp:%d\n",pSAVAGEDRI->zpp );
1202ab47cfaaSmrg
1203ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agpMode:%d\n",pSAVAGEDRI->agpMode );
1204ab47cfaaSmrg
1205ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	bufferSize:%u\n",pSAVAGEDRI->bufferSize );
1206ab47cfaaSmrg
1207ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	frontbufferSize:0x%08x\n",pSAVAGEDRI->frontbufferSize);
1208ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	frontOffset:0x%08x\n",pSAVAGEDRI->frontOffset );
1209ab47cfaaSmrg
1210ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	backbufferSize:0x%08x\n",pSAVAGEDRI->backbufferSize);
1211ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	backOffset:0x%08x\n",pSAVAGEDRI->backOffset );
1212ab47cfaaSmrg
1213ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	depthbufferSize:0x%08x\n",pSAVAGEDRI->depthbufferSize);
1214ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	depthOffset:0x%08x\n",pSAVAGEDRI->depthOffset );
1215ab47cfaaSmrg
1216ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	textureOffset:0x%08x\n",pSAVAGEDRI->textureOffset );
1217ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	textureSize:0x%08x\n",pSAVAGEDRI->textureSize );
1218ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	logTextureGranularity:0x%08x\n",pSAVAGEDRI->logTextureGranularity );
1219ab47cfaaSmrg
12205788ca14Smrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agpTextureHandle:0x%08lx\n",(unsigned long)pSAVAGEDRI->agpTextureHandle );
1221ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	agpTextureSize:0x%08x\n",pSAVAGEDRI->agpTextureSize );
1222ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	logAgpTextureGranularity:0x%08x\n",pSAVAGEDRI->logAgpTextureGranularity );
1223ab47cfaaSmrg
12245788ca14Smrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	apertureHandle:0x%08lx\n",(unsigned long)pSAVAGEDRI->apertureHandle);
1225ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	apertureSize:0x%08x\n",pSAVAGEDRI->apertureSize);
1226ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	aperturePitch:0x%08x\n",pSAVAGEDRI->aperturePitch);
1227ab47cfaaSmrg
12285788ca14Smrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	statusHandle:0x%08lx\n",(unsigned long)pSAVAGEDRI->statusHandle);
1229ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	statusSize:0x%08x\n",pSAVAGEDRI->statusSize);
1230ab47cfaaSmrg
1231ab47cfaaSmrg   xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]	sarea_priv_offset:0x%08x\n",pSAVAGEDRI->sarea_priv_offset);
1232ab47cfaaSmrg
12335788ca14Smrg   SAVAGEDRISetupTiledSurfaceRegs( psav );
1234ab47cfaaSmrg   return TRUE;
1235ab47cfaaSmrg}
1236ab47cfaaSmrg
12375788ca14Smrgvoid SAVAGEDRIResume(ScreenPtr pScreen)
12385788ca14Smrg{
12395788ca14Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
12405788ca14Smrg   SavagePtr psav = SAVPTR(pScrn);
12415788ca14Smrg   SAVAGESAREAPrivPtr pSAREAPriv =
12425788ca14Smrg			(SAVAGESAREAPrivPtr)DRIGetSAREAPrivate(pScreen);
12435788ca14Smrg
12445788ca14Smrg   if (!psav->IsPCI) {
12455788ca14Smrg	SAVAGESetAgpMode(psav, pScreen);
12465788ca14Smrg   }
12475788ca14Smrg   SAVAGEDRISetupTiledSurfaceRegs(psav);
12485788ca14Smrg   /* Assume that 3D state was clobbered, invalidate it by
12495788ca14Smrg    * changing ctxOwner in the sarea. */
12505788ca14Smrg   pSAREAPriv->ctxOwner = DRIGetContext(pScreen);
12515788ca14Smrg}
1252ab47cfaaSmrg
1253ab47cfaaSmrgvoid SAVAGEDRICloseScreen( ScreenPtr pScreen )
1254ab47cfaaSmrg{
12555788ca14Smrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1256ab47cfaaSmrg   SavagePtr psav = SAVPTR(pScrn);
1257ab47cfaaSmrg   SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
1258ab47cfaaSmrg
1259ab47cfaaSmrg   if ( pSAVAGEDRIServer->status.map ) {
1260ab47cfaaSmrg      drmUnmap( pSAVAGEDRIServer->status.map, pSAVAGEDRIServer->status.size );
1261ab47cfaaSmrg      pSAVAGEDRIServer->status.map = NULL;
1262ab47cfaaSmrg   }
1263ab47cfaaSmrg
1264ab47cfaaSmrg   if ( pSAVAGEDRIServer->registers.map ) {
1265ab47cfaaSmrg      drmUnmap( pSAVAGEDRIServer->registers.map, pSAVAGEDRIServer->registers.size );
1266ab47cfaaSmrg      pSAVAGEDRIServer->registers.map = NULL;
1267ab47cfaaSmrg   }
1268ab47cfaaSmrg
1269ab47cfaaSmrg   if ( pSAVAGEDRIServer->aperture.map ) {
1270ab47cfaaSmrg      drmUnmap( pSAVAGEDRIServer->aperture.map, pSAVAGEDRIServer->aperture.size );
1271ab47cfaaSmrg      pSAVAGEDRIServer->aperture.map = NULL;
1272ab47cfaaSmrg   }
1273ab47cfaaSmrg
12741c79cd07Smrg   if ( pSAVAGEDRIServer->agpXVideo.map ) {
12751c79cd07Smrg      drmUnmap( pSAVAGEDRIServer->agpXVideo.map,
12761c79cd07Smrg                pSAVAGEDRIServer->agpXVideo.size );
12771c79cd07Smrg      pSAVAGEDRIServer->agpXVideo.map = NULL;
12781c79cd07Smrg   }
12791c79cd07Smrg
1280ab47cfaaSmrg   if ( pSAVAGEDRIServer->agpTextures.map ) {
1281ab47cfaaSmrg      drmUnmap( pSAVAGEDRIServer->agpTextures.map,
1282ab47cfaaSmrg                pSAVAGEDRIServer->agpTextures.size );
1283ab47cfaaSmrg      pSAVAGEDRIServer->agpTextures.map = NULL;
1284ab47cfaaSmrg   }
1285ab47cfaaSmrg
1286ab47cfaaSmrg   if (pSAVAGEDRIServer->status.handle)
1287ab47cfaaSmrg       drmRmMap(psav->drmFD,pSAVAGEDRIServer->status.handle);
1288ab47cfaaSmrg
1289ab47cfaaSmrg   if (pSAVAGEDRIServer->registers.handle)
1290ab47cfaaSmrg       drmRmMap(psav->drmFD,pSAVAGEDRIServer->registers.handle);
1291ab47cfaaSmrg
1292ab47cfaaSmrg   if (pSAVAGEDRIServer->aperture.handle)
1293ab47cfaaSmrg       drmRmMap(psav->drmFD,pSAVAGEDRIServer->registers.handle);
1294ab47cfaaSmrg
12951c79cd07Smrg   if (pSAVAGEDRIServer->agpXVideo.handle)
12961c79cd07Smrg       drmRmMap(psav->drmFD,pSAVAGEDRIServer->agpXVideo.handle);
12971c79cd07Smrg
1298ab47cfaaSmrg   if (pSAVAGEDRIServer->agpTextures.handle)
1299ab47cfaaSmrg       drmRmMap(psav->drmFD,pSAVAGEDRIServer->agpTextures.handle);
1300ab47cfaaSmrg
1301ab47cfaaSmrg   if (pSAVAGEDRIServer->cmdDma.handle)
1302ab47cfaaSmrg       drmRmMap(psav->drmFD,pSAVAGEDRIServer->cmdDma.handle);
1303ab47cfaaSmrg
1304ab47cfaaSmrg   if ( pSAVAGEDRIServer->buffers.map ) {
1305ab47cfaaSmrg      drmUnmap( pSAVAGEDRIServer->buffers.map, pSAVAGEDRIServer->buffers.size );
1306ab47cfaaSmrg      pSAVAGEDRIServer->buffers.map = NULL;
1307ab47cfaaSmrg   }
1308ab47cfaaSmrg
1309ab47cfaaSmrg   if ( pSAVAGEDRIServer->agp.handle ) {
1310ab47cfaaSmrg      drmAgpUnbind( psav->drmFD, pSAVAGEDRIServer->agp.handle );
1311ab47cfaaSmrg      drmAgpFree( psav->drmFD, pSAVAGEDRIServer->agp.handle );
1312ab47cfaaSmrg      pSAVAGEDRIServer->agp.handle = 0;
1313ab47cfaaSmrg      drmAgpRelease( psav->drmFD );
1314ab47cfaaSmrg   }
1315ab47cfaaSmrg
1316ab47cfaaSmrg   DRICloseScreen( pScreen );
1317ab47cfaaSmrg
1318ab47cfaaSmrg   /* Don't use shadow status any more. If this happens due to failed
1319ab47cfaaSmrg    * DRI initialization then SavageScreenInit will do the real
1320ab47cfaaSmrg    * cleanup and restore ShadowStatus to sane settings. */
1321ab47cfaaSmrg   psav->ShadowVirtual = NULL;
1322ab47cfaaSmrg   psav->ShadowPhysical = 0;
1323ab47cfaaSmrg
1324ab47cfaaSmrg   if(psav->reserved)
1325ab47cfaaSmrg      xf86FreeOffscreenLinear(psav->reserved);
1326ab47cfaaSmrg
1327ab47cfaaSmrg   if ( psav->pDRIInfo ) {
1328ab47cfaaSmrg      if ( psav->pDRIInfo->devPrivate ) {
13295788ca14Smrg	 free( psav->pDRIInfo->devPrivate );
1330ab47cfaaSmrg	 psav->pDRIInfo->devPrivate = 0;
1331ab47cfaaSmrg      }
1332ab47cfaaSmrg      DRIDestroyInfoRec( psav->pDRIInfo );
1333ab47cfaaSmrg      psav->pDRIInfo = 0;
1334ab47cfaaSmrg   }
1335ab47cfaaSmrg   if ( psav->DRIServerInfo ) {
13365788ca14Smrg      free( psav->DRIServerInfo );
1337ab47cfaaSmrg      psav->DRIServerInfo = 0;
1338ab47cfaaSmrg   }
1339ab47cfaaSmrg   if ( psav->pVisualConfigs ) {
13405788ca14Smrg      free( psav->pVisualConfigs );
1341ab47cfaaSmrg   }
1342ab47cfaaSmrg   if ( psav->pVisualConfigsPriv ) {
13435788ca14Smrg      free( psav->pVisualConfigsPriv );
1344ab47cfaaSmrg   }
1345ab47cfaaSmrg}
1346ab47cfaaSmrg
1347ab47cfaaSmrgvoid
1348ab47cfaaSmrgSAVAGEDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
1349ab47cfaaSmrg{
1350ab47cfaaSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
13515788ca14Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1352ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1353ab47cfaaSmrg    BoxPtr pbox = REGION_RECTS(prgn);
1354ab47cfaaSmrg    int nbox  = REGION_NUM_RECTS(prgn);
1355ab47cfaaSmrg    drmSAVAGECmdHeader cmd[2];
1356ab47cfaaSmrg    drmSAVAGECmdbuf cmdBuf;
1357ab47cfaaSmrg    int ret;
1358ab47cfaaSmrg
1359ab47cfaaSmrg    if (!psav->LockHeld) {
1360ab47cfaaSmrg	xf86DrvMsg( pScrn->scrnIndex, X_WARNING,
1361ab47cfaaSmrg		    "Not holding the lock in InitBuffers.\n");
1362ab47cfaaSmrg	return;
1363ab47cfaaSmrg    }
1364ab47cfaaSmrg
1365ab47cfaaSmrg    cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR;
1366ab47cfaaSmrg    cmd[0].clear0.flags = SAVAGE_BACK|SAVAGE_DEPTH;
1367ab47cfaaSmrg    cmd[1].clear1.mask = 0xffffffff;
1368ab47cfaaSmrg    cmd[1].clear1.value = 0;
1369ab47cfaaSmrg
1370ab47cfaaSmrg    cmdBuf.cmd_addr = cmd;
1371ab47cfaaSmrg    cmdBuf.size = 2;
1372ab47cfaaSmrg    cmdBuf.dma_idx = 0;
1373ab47cfaaSmrg    cmdBuf.discard = 0;
1374ab47cfaaSmrg    cmdBuf.vb_addr = NULL;
1375ab47cfaaSmrg    cmdBuf.vb_size = 0;
1376ab47cfaaSmrg    cmdBuf.vb_stride = 0;
1377ab47cfaaSmrg    cmdBuf.box_addr = (drm_clip_rect_t*)pbox;
1378ab47cfaaSmrg    cmdBuf.nbox = nbox;
1379ab47cfaaSmrg
1380ab47cfaaSmrg    ret = drmCommandWrite(psav->drmFD, DRM_SAVAGE_BCI_CMDBUF,
1381ab47cfaaSmrg			  &cmdBuf, sizeof(cmdBuf));
1382ab47cfaaSmrg    if (ret < 0) {
1383ab47cfaaSmrg	xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
1384ab47cfaaSmrg		    "SAVAGEDRIInitBuffers: drmCommandWrite returned %d.\n",
1385ab47cfaaSmrg		    ret);
1386ab47cfaaSmrg    }
1387ab47cfaaSmrg}
1388ab47cfaaSmrg
1389ab47cfaaSmrg/*
1390ab47cfaaSmrg  This routine is a modified form of XAADoBitBlt with the calls to
1391ab47cfaaSmrg  ScreenToScreenBitBlt built in. My routine has the prgnSrc as source
1392ab47cfaaSmrg  instead of destination. My origin is upside down so the ydir cases
1393ab47cfaaSmrg  are reversed.
1394ab47cfaaSmrg*/
1395ab47cfaaSmrg
1396ab47cfaaSmrgvoid
1397ab47cfaaSmrgSAVAGEDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
1398ab47cfaaSmrg		   RegionPtr prgnSrc, CARD32 index)
1399ab47cfaaSmrg{
1400ab47cfaaSmrg    ScreenPtr pScreen = pParent->drawable.pScreen;
14015788ca14Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1402ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1403ab47cfaaSmrg    int nbox;
1404ab47cfaaSmrg    BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
1405ab47cfaaSmrg    DDXPointPtr pptTmp, pptNew1, pptNew2;
1406ab47cfaaSmrg    int xdir, ydir;
1407ab47cfaaSmrg    int dx, dy;
1408ab47cfaaSmrg    DDXPointPtr pptSrc;
1409ab47cfaaSmrg    int screenwidth = pScrn->virtualX;
1410ab47cfaaSmrg    int screenheight = pScrn->virtualY;
1411ab47cfaaSmrg    BCI_GET_PTR;
1412ab47cfaaSmrg
1413ab47cfaaSmrg    if (!psav->LockHeld) {
1414ab47cfaaSmrg	xf86DrvMsg( pScrn->scrnIndex, X_INFO, "Not holding lock in MoveBuffers\n");
1415ab47cfaaSmrg    }
1416ab47cfaaSmrg
1417ab47cfaaSmrg    pbox = REGION_RECTS(prgnSrc);
1418ab47cfaaSmrg    nbox = REGION_NUM_RECTS(prgnSrc);
1419ab47cfaaSmrg    pboxNew1 = 0;
1420ab47cfaaSmrg    pptNew1 = 0;
1421ab47cfaaSmrg    pboxNew2 = 0;
14225788ca14Smrg    pptNew2 = 0;
1423ab47cfaaSmrg    pptSrc = &ptOldOrg;
1424ab47cfaaSmrg
1425ab47cfaaSmrg    dx = pParent->drawable.x - ptOldOrg.x;
1426ab47cfaaSmrg    dy = pParent->drawable.y - ptOldOrg.y;
1427ab47cfaaSmrg
1428ab47cfaaSmrg    /* If the copy will overlap in Y, reverse the order */
1429ab47cfaaSmrg    if (dy>0) {
1430ab47cfaaSmrg        ydir = -1;
1431ab47cfaaSmrg
1432ab47cfaaSmrg        if (nbox>1) {
1433ab47cfaaSmrg	    /* Keep ordering in each band, reverse order of bands */
14345788ca14Smrg	    pboxNew1 = malloc(sizeof(BoxRec)*nbox);
1435ab47cfaaSmrg	    if (!pboxNew1) return;
14365788ca14Smrg	    pptNew1 = malloc(sizeof(DDXPointRec)*nbox);
1437ab47cfaaSmrg	    if (!pptNew1) {
14385788ca14Smrg	        free(pboxNew1);
1439ab47cfaaSmrg	        return;
1440ab47cfaaSmrg	    }
1441ab47cfaaSmrg	    pboxBase = pboxNext = pbox+nbox-1;
1442ab47cfaaSmrg	    while (pboxBase >= pbox) {
1443ab47cfaaSmrg	        while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))
1444ab47cfaaSmrg		  pboxNext--;
1445ab47cfaaSmrg	        pboxTmp = pboxNext+1;
1446ab47cfaaSmrg	        pptTmp = pptSrc + (pboxTmp - pbox);
1447ab47cfaaSmrg	        while (pboxTmp <= pboxBase) {
1448ab47cfaaSmrg		    *pboxNew1++ = *pboxTmp++;
1449ab47cfaaSmrg		    *pptNew1++ = *pptTmp++;
1450ab47cfaaSmrg		}
1451ab47cfaaSmrg	        pboxBase = pboxNext;
1452ab47cfaaSmrg	    }
1453ab47cfaaSmrg	    pboxNew1 -= nbox;
1454ab47cfaaSmrg	    pbox = pboxNew1;
1455ab47cfaaSmrg	    pptNew1 -= nbox;
1456ab47cfaaSmrg	    pptSrc = pptNew1;
1457ab47cfaaSmrg	}
1458ab47cfaaSmrg    } else {
1459ab47cfaaSmrg        /* No changes required */
1460ab47cfaaSmrg        ydir = 1;
1461ab47cfaaSmrg    }
1462ab47cfaaSmrg
1463ab47cfaaSmrg    /* If the regions will overlap in X, reverse the order */
1464ab47cfaaSmrg    if (dx>0) {
1465ab47cfaaSmrg        xdir = -1;
1466ab47cfaaSmrg
1467ab47cfaaSmrg        if (nbox > 1) {
1468ab47cfaaSmrg	    /*reverse orderof rects in each band */
14695788ca14Smrg	    pboxNew2 = malloc(sizeof(BoxRec)*nbox);
14705788ca14Smrg	    pptNew2 = malloc(sizeof(DDXPointRec)*nbox);
1471ab47cfaaSmrg	    if (!pboxNew2 || !pptNew2) {
14725788ca14Smrg	        if (pptNew2) free(pptNew2);
14735788ca14Smrg	        if (pboxNew2) free(pboxNew2);
1474ab47cfaaSmrg	        if (pboxNew1) {
14755788ca14Smrg		    free(pptNew1);
14765788ca14Smrg		    free(pboxNew1);
1477ab47cfaaSmrg		}
1478ab47cfaaSmrg	       return;
1479ab47cfaaSmrg	    }
1480ab47cfaaSmrg	    pboxBase = pboxNext = pbox;
1481ab47cfaaSmrg	    while (pboxBase < pbox+nbox) {
1482ab47cfaaSmrg	        while ((pboxNext < pbox+nbox) &&
1483ab47cfaaSmrg		       (pboxNext->y1 == pboxBase->y1))
1484ab47cfaaSmrg		  pboxNext++;
1485ab47cfaaSmrg	        pboxTmp = pboxNext;
1486ab47cfaaSmrg	        pptTmp = pptSrc + (pboxTmp - pbox);
1487ab47cfaaSmrg	        while (pboxTmp != pboxBase) {
1488ab47cfaaSmrg		    *pboxNew2++ = *--pboxTmp;
1489ab47cfaaSmrg		    *pptNew2++ = *--pptTmp;
1490ab47cfaaSmrg		}
1491ab47cfaaSmrg	        pboxBase = pboxNext;
1492ab47cfaaSmrg	    }
1493ab47cfaaSmrg	    pboxNew2 -= nbox;
1494ab47cfaaSmrg	    pbox = pboxNew2;
1495ab47cfaaSmrg	    pptNew2 -= nbox;
1496ab47cfaaSmrg	    pptSrc = pptNew2;
1497ab47cfaaSmrg	}
1498ab47cfaaSmrg    } else {
1499ab47cfaaSmrg        /* No changes are needed */
1500ab47cfaaSmrg        xdir = 1;
1501ab47cfaaSmrg    }
1502ab47cfaaSmrg
1503ab47cfaaSmrg    BCI_SEND(0xc0030000); /* wait for 2D+3D idle */
1504ab47cfaaSmrg    SAVAGEDRISetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1);
1505ab47cfaaSmrg    for ( ; nbox-- ; pbox++)
1506ab47cfaaSmrg     {
1507ab47cfaaSmrg	 int x1 = pbox->x1;
1508ab47cfaaSmrg	 int y1 = pbox->y1;
1509ab47cfaaSmrg	 int destx = x1 + dx;
1510ab47cfaaSmrg	 int desty = y1 + dy;
1511ab47cfaaSmrg	 int w = pbox->x2 - x1 + 1;
1512ab47cfaaSmrg	 int h = pbox->y2 - y1 + 1;
1513ab47cfaaSmrg
1514ab47cfaaSmrg	 if ( destx < 0 ) x1 -= destx, w += destx, destx = 0;
1515ab47cfaaSmrg	 if ( desty < 0 ) y1 -= desty, h += desty, desty = 0;
1516ab47cfaaSmrg	 if ( destx + w > screenwidth ) w = screenwidth - destx;
1517ab47cfaaSmrg	 if ( desty + h > screenheight ) h = screenheight - desty;
1518ab47cfaaSmrg	 if ( w <= 0 ) continue;
1519ab47cfaaSmrg	 if ( h <= 0 ) continue;
1520ab47cfaaSmrg
1521ab47cfaaSmrg	 SAVAGESelectBuffer(pScrn, SAVAGE_BACK);
1522ab47cfaaSmrg	 SAVAGEDRISubsequentScreenToScreenCopy(pScrn, x1, y1,
1523ab47cfaaSmrg					       destx,desty, w, h);
1524ab47cfaaSmrg	 SAVAGESelectBuffer(pScrn, SAVAGE_DEPTH);
1525ab47cfaaSmrg	 SAVAGEDRISubsequentScreenToScreenCopy(pScrn, x1,y1,
1526ab47cfaaSmrg					       destx,desty, w, h);
1527ab47cfaaSmrg     }
1528ab47cfaaSmrg    SAVAGESelectBuffer(pScrn, SAVAGE_FRONT);
1529ab47cfaaSmrg
1530ab47cfaaSmrg    if (pboxNew2) {
15315788ca14Smrg        free(pptNew2);
15325788ca14Smrg        free(pboxNew2);
1533ab47cfaaSmrg    }
1534ab47cfaaSmrg    if (pboxNew1) {
15355788ca14Smrg        free(pptNew1);
15365788ca14Smrg        free(pboxNew1);
1537ab47cfaaSmrg    }
1538ab47cfaaSmrg
1539ab47cfaaSmrg    BCI_SEND(0xc0020000); /* wait for 2D idle */
1540ab47cfaaSmrg    if (psav->useEXA)
1541ab47cfaaSmrg	exaMarkSync(pScreen);
15425788ca14Smrg#ifdef HAVE_XAA_H
1543ab47cfaaSmrg    else
1544ab47cfaaSmrg	psav->AccelInfoRec->NeedToSync = TRUE;
15455788ca14Smrg#endif
1546ab47cfaaSmrg}
1547ab47cfaaSmrg
15481c79cd07Smrg/* Definition in savage_accel.c */
15491c79cd07Smrgint SavageGetCopyROP(int rop);
15501c79cd07Smrg
1551ab47cfaaSmrgstatic void
1552ab47cfaaSmrgSAVAGEDRISetupForScreenToScreenCopy(
1553ab47cfaaSmrg    ScrnInfoPtr pScrn,
1554ab47cfaaSmrg    int xdir,
1555ab47cfaaSmrg    int ydir,
1556ab47cfaaSmrg    int rop,
1557ab47cfaaSmrg    unsigned planemask,
1558ab47cfaaSmrg    int transparency_color)
1559ab47cfaaSmrg{
1560ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1561ab47cfaaSmrg    int cmd =0;
1562ab47cfaaSmrg
1563ab47cfaaSmrg    cmd = BCI_CMD_RECT | BCI_CMD_DEST_PBD | BCI_CMD_SRC_PBD_COLOR;
15641c79cd07Smrg    BCI_CMD_SET_ROP( cmd, SavageGetCopyROP(rop) );
1565ab47cfaaSmrg    if (transparency_color != -1)
1566ab47cfaaSmrg        cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_SRC_TRANSPARENT;
1567ab47cfaaSmrg
1568ab47cfaaSmrg    if (xdir == 1 ) cmd |= BCI_CMD_RECT_XP;
1569ab47cfaaSmrg    if (ydir == 1 ) cmd |= BCI_CMD_RECT_YP;
1570ab47cfaaSmrg
1571ab47cfaaSmrg    psav->SavedBciCmd = cmd;
1572ab47cfaaSmrg    psav->SavedBgColor = transparency_color;
1573ab47cfaaSmrg
1574ab47cfaaSmrg}
1575ab47cfaaSmrg
1576ab47cfaaSmrgstatic void
1577ab47cfaaSmrgSAVAGEDRISubsequentScreenToScreenCopy(
1578ab47cfaaSmrg    ScrnInfoPtr pScrn,
1579ab47cfaaSmrg    int x1,
1580ab47cfaaSmrg    int y1,
1581ab47cfaaSmrg    int x2,
1582ab47cfaaSmrg    int y2,
1583ab47cfaaSmrg    int w,
1584ab47cfaaSmrg    int h)
1585ab47cfaaSmrg{
1586ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1587ab47cfaaSmrg    BCI_GET_PTR;
1588ab47cfaaSmrg
1589ab47cfaaSmrg    if (!w || !h) return;
1590ab47cfaaSmrg    if (!(psav->SavedBciCmd & BCI_CMD_RECT_XP)) {
1591ab47cfaaSmrg        w --;
1592ab47cfaaSmrg        x1 += w;
1593ab47cfaaSmrg        x2 += w;
1594ab47cfaaSmrg        w ++;
1595ab47cfaaSmrg    }
1596ab47cfaaSmrg    if (!(psav->SavedBciCmd & BCI_CMD_RECT_YP)) {
1597ab47cfaaSmrg        h --;
1598ab47cfaaSmrg        y1 += h;
1599ab47cfaaSmrg        y2 += h;
1600ab47cfaaSmrg        h ++;
1601ab47cfaaSmrg    }
1602ab47cfaaSmrg
1603ab47cfaaSmrg    psav->WaitQueue(psav,6);
1604ab47cfaaSmrg    BCI_SEND(psav->SavedBciCmd);
1605ab47cfaaSmrg    if (psav->SavedBgColor != -1)
1606ab47cfaaSmrg	BCI_SEND(psav->SavedBgColor);
1607ab47cfaaSmrg    BCI_SEND(BCI_X_Y(x1, y1));
1608ab47cfaaSmrg    BCI_SEND(BCI_X_Y(x2, y2));
1609ab47cfaaSmrg    BCI_SEND(BCI_W_H(w, h));
1610ab47cfaaSmrg
1611ab47cfaaSmrg}
1612ab47cfaaSmrg
1613ab47cfaaSmrg/*
1614ab47cfaaSmrg * the FullScreen DRI code is dead, this is just left in place to show how
1615ab47cfaaSmrg * to set up pageflipping.
1616ab47cfaaSmrg */
1617ab47cfaaSmrgstatic Bool
1618ab47cfaaSmrgSAVAGEDRIOpenFullScreen(ScreenPtr pScreen)
1619ab47cfaaSmrg{
16205788ca14Smrg  ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1621ab47cfaaSmrg  vgaHWPtr hwp = VGAHWPTR(pScrn);
1622ab47cfaaSmrg  SavagePtr psav = SAVPTR(pScrn);
1623ab47cfaaSmrg  unsigned int vgaCRIndex = hwp->IOBase + 4;
1624ab47cfaaSmrg  unsigned int vgaCRReg = hwp->IOBase + 5;
1625ab47cfaaSmrg  SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate;
1626ab47cfaaSmrg  unsigned int TileStride;
1627ab47cfaaSmrg  unsigned int WidthinTiles;
1628ab47cfaaSmrg  unsigned int depth;
1629ab47cfaaSmrg
1630ab47cfaaSmrg  OUTREG(0x48C18, INREG(0x48C18) & 0xFFFFFFF7);
1631ab47cfaaSmrg  /*VGAOUT8(vgaCRIndex,0x66);
1632ab47cfaaSmrg  VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg)|0x10);*/
1633ab47cfaaSmrg  VGAOUT8(vgaCRIndex,0x69);
1634ab47cfaaSmrg  VGAOUT8(vgaCRReg, 0x80);
1635ab47cfaaSmrg
1636ab47cfaaSmrg  depth = pScrn->bitsPerPixel;
1637ab47cfaaSmrg
1638ab47cfaaSmrg  if(depth == 16)
1639ab47cfaaSmrg  {
1640ab47cfaaSmrg      WidthinTiles = (pSAVAGEDRI->width+63)>>6;
1641ab47cfaaSmrg      TileStride = (pSAVAGEDRI->width+63)&(~63);
1642ab47cfaaSmrg
1643ab47cfaaSmrg  }
1644ab47cfaaSmrg  else
1645ab47cfaaSmrg  {
1646ab47cfaaSmrg      WidthinTiles = (pSAVAGEDRI->width+31)>>5;
1647ab47cfaaSmrg      TileStride = (pSAVAGEDRI->width+31)&(~31);
1648ab47cfaaSmrg
1649ab47cfaaSmrg  }
1650ab47cfaaSmrg
1651ab47cfaaSmrg
1652ab47cfaaSmrg  /* set primary stream stride */
1653ab47cfaaSmrg  {
1654ab47cfaaSmrg      unsigned int value;
1655ab47cfaaSmrg
1656ab47cfaaSmrg      /*value = 0x80000000|(WidthinTiles<<24)|(TileStride*depth/8);*/
1657ab47cfaaSmrg      value = 0x80000000|(WidthinTiles<<24);
1658ab47cfaaSmrg      if(depth == 32)
1659ab47cfaaSmrg          value |= 0x40000000;
1660ab47cfaaSmrg
1661ab47cfaaSmrg      OUTREG(PRI_STREAM_STRIDE, value);
1662ab47cfaaSmrg
1663ab47cfaaSmrg  }
1664ab47cfaaSmrg
1665ab47cfaaSmrg  /* set global bitmap descriptor */
1666ab47cfaaSmrg  {
1667ab47cfaaSmrg      unsigned int value;
1668ab47cfaaSmrg      value = 0x10000000|
1669ab47cfaaSmrg              0x00000009|
1670ab47cfaaSmrg              0x01000000|
1671ab47cfaaSmrg              (depth<<16)  | TileStride;
1672ab47cfaaSmrg
1673ab47cfaaSmrg      OUTREG(0x816C,value);
1674ab47cfaaSmrg
1675ab47cfaaSmrg  }
1676ab47cfaaSmrg
1677ab47cfaaSmrg   OUTREG(0x48C18, INREG(0x48C18) | 0x8);
1678ab47cfaaSmrg
1679ab47cfaaSmrg  return TRUE;
1680ab47cfaaSmrg}
1681ab47cfaaSmrg
1682ab47cfaaSmrgstatic Bool
1683ab47cfaaSmrgSAVAGEDRICloseFullScreen(ScreenPtr pScreen)
1684ab47cfaaSmrg{
16855788ca14Smrg  ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1686ab47cfaaSmrg  SavagePtr psav = SAVPTR(pScrn);
1687ab47cfaaSmrg  BCI_GET_PTR;
1688ab47cfaaSmrg
1689ab47cfaaSmrg  BCI_SEND(0xC0FF0000);
1690ab47cfaaSmrg  psav->WaitIdleEmpty(psav);
1691ab47cfaaSmrg  OUTREG(0x48C18, INREG(0x48C18) & 0xFFFFFFF7);
1692ab47cfaaSmrg  /* set primary stream stride */
1693ab47cfaaSmrg  {
1694ab47cfaaSmrg      /* MM81C0 and 81C4 are used to control primary stream. */
1695ab47cfaaSmrg      OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000);
1696ab47cfaaSmrg      OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000);
1697ab47cfaaSmrg
1698ab47cfaaSmrg      /* FIFO control */
1699ab47cfaaSmrg      OUTREG32(0X81EC,0Xffffffff);
1700ab47cfaaSmrg
1701ab47cfaaSmrg      if (!psav->bTiled) {
1702ab47cfaaSmrg          OUTREG32(PRI_STREAM_STRIDE,
1703ab47cfaaSmrg                   (((psav->lDelta * 2) << 16) & 0x3FFFE000) |
1704ab47cfaaSmrg                   (psav->lDelta & 0x00001fff));
1705ab47cfaaSmrg      }
1706ab47cfaaSmrg      else if (pScrn->bitsPerPixel == 16) {
1707ab47cfaaSmrg          /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
1708ab47cfaaSmrg          OUTREG32(PRI_STREAM_STRIDE,
1709ab47cfaaSmrg                   (((psav->lDelta * 2) << 16) & 0x3FFFE000)
1710ab47cfaaSmrg                   | 0x80000000 | (psav->lDelta & 0x00001fff));
1711ab47cfaaSmrg      }
1712ab47cfaaSmrg      else if (pScrn->bitsPerPixel == 32) {
1713ab47cfaaSmrg          OUTREG32(PRI_STREAM_STRIDE,
1714ab47cfaaSmrg                   (((psav->lDelta * 2) << 16) & 0x3FFFE000)
1715ab47cfaaSmrg                   | 0xC0000000 | (psav->lDelta & 0x00001fff));
1716ab47cfaaSmrg      }
1717ab47cfaaSmrg
1718ab47cfaaSmrg
1719ab47cfaaSmrg  }
1720ab47cfaaSmrg
1721ab47cfaaSmrg  /* set global bitmap descriptor */
1722ab47cfaaSmrg      {
1723ab47cfaaSmrg          OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
1724ab47cfaaSmrg          OUTREG32(S3_GLB_BD_HIGH,psav->GlobalBD.bd2.HiPart | BCI_ENABLE | S3_LITTLE_ENDIAN | S3_BD64);
1725ab47cfaaSmrg
1726ab47cfaaSmrg      }
1727ab47cfaaSmrg
1728ab47cfaaSmrg  OUTREG(0x48C18, INREG(0x48C18) | 0x8);
1729ab47cfaaSmrg  return TRUE;
1730ab47cfaaSmrg}
1731ab47cfaaSmrg
1732ab47cfaaSmrg#endif
1733