mga_dri.c revision fe5e51b7
1fe5e51b7Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c,v 1.31tsi Exp $ */ 2fe5e51b7Smrg 3fe5e51b7Smrg/* 4fe5e51b7Smrg * Copyright 2000 VA Linux Systems Inc., Fremont, California. 5fe5e51b7Smrg * All Rights Reserved. 6fe5e51b7Smrg * 7fe5e51b7Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8fe5e51b7Smrg * copy of this software and associated documentation files (the "Software"), 9fe5e51b7Smrg * to deal in the Software without restriction, including without limitation 10fe5e51b7Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11fe5e51b7Smrg * and/or sell copies of the Software, and to permit persons to whom the 12fe5e51b7Smrg * Software is furnished to do so, subject to the following conditions: 13fe5e51b7Smrg * 14fe5e51b7Smrg * The above copyright notice and this permission notice (including the next 15fe5e51b7Smrg * paragraph) shall be included in all copies or substantial portions of the 16fe5e51b7Smrg * Software. 17fe5e51b7Smrg * 18fe5e51b7Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19fe5e51b7Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20fe5e51b7Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21fe5e51b7Smrg * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES 22fe5e51b7Smrg * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23fe5e51b7Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24fe5e51b7Smrg * OTHER DEALINGS IN THE SOFTWARE. 25fe5e51b7Smrg * 26fe5e51b7Smrg * Authors: 27fe5e51b7Smrg * Keith Whitwell <keith@tungstengraphics.com> 28fe5e51b7Smrg * Gareth Hughes <gareth@valinux.com> 29fe5e51b7Smrg */ 30fe5e51b7Smrg 31fe5e51b7Smrg#ifdef HAVE_CONFIG_H 32fe5e51b7Smrg#include "config.h" 33fe5e51b7Smrg#endif 34fe5e51b7Smrg 35fe5e51b7Smrg#include "xf86.h" 36fe5e51b7Smrg#include "xf86_OSproc.h" 37fe5e51b7Smrg#include "xf86Priv.h" 38fe5e51b7Smrg 39fe5e51b7Smrg#include "xf86PciInfo.h" 40fe5e51b7Smrg#include "xf86Pci.h" 41fe5e51b7Smrg#define PSZ 8 42fe5e51b7Smrg#include "cfb.h" 43fe5e51b7Smrg#undef PSZ 44fe5e51b7Smrg#include "cfb16.h" 45fe5e51b7Smrg#include "cfb32.h" 46fe5e51b7Smrg 47fe5e51b7Smrg#include "miline.h" 48fe5e51b7Smrg 49fe5e51b7Smrg#include <errno.h> 50fe5e51b7Smrg 51fe5e51b7Smrg#include <inttypes.h> 52fe5e51b7Smrg#include "mga_reg.h" 53fe5e51b7Smrg#include "mga.h" 54fe5e51b7Smrg#include "mga_macros.h" 55fe5e51b7Smrg#include "mga_dri.h" 56fe5e51b7Smrg#include "mga_sarea.h" 57fe5e51b7Smrg#include "mga_drm.h" 58fe5e51b7Smrg 59fe5e51b7Smrg#define _XF86DRI_SERVER_ 60fe5e51b7Smrg#include "GL/glxtokens.h" 61fe5e51b7Smrg#include "sarea.h" 62fe5e51b7Smrg 63fe5e51b7Smrg 64fe5e51b7Smrg 65fe5e51b7Smrg 66fe5e51b7Smrg 67fe5e51b7Smrg#include "GL/glxtokens.h" 68fe5e51b7Smrg 69fe5e51b7Smrg#include "mga_reg.h" 70fe5e51b7Smrg#include "mga.h" 71fe5e51b7Smrg#include "mga_macros.h" 72fe5e51b7Smrg#include "mga_dri.h" 73fe5e51b7Smrg 74fe5e51b7Smrg#define DRM_MGA_IDLE_RETRY 2048 75fe5e51b7Smrg 76fe5e51b7Smrgstatic char MGAKernelDriverName[] = "mga"; 77fe5e51b7Smrgstatic char MGAClientDriverName[] = "mga"; 78fe5e51b7Smrg 79fe5e51b7Smrg/* Initialize the visual configs that are supported by the hardware. 80fe5e51b7Smrg * These are combined with the visual configs that the indirect 81fe5e51b7Smrg * rendering core supports, and the intersection is exported to the 82fe5e51b7Smrg * client. 83fe5e51b7Smrg */ 84fe5e51b7Smrgstatic Bool MGAInitVisualConfigs( ScreenPtr pScreen ) 85fe5e51b7Smrg{ 86fe5e51b7Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 87fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 88fe5e51b7Smrg int numConfigs = 0; 89fe5e51b7Smrg __GLXvisualConfig *pConfigs = 0; 90fe5e51b7Smrg MGAConfigPrivPtr pMGAConfigs = 0; 91fe5e51b7Smrg MGAConfigPrivPtr *pMGAConfigPtrs = 0; 92fe5e51b7Smrg int i, db, depth, stencil, accum; 93fe5e51b7Smrg 94fe5e51b7Smrg switch ( pScrn->bitsPerPixel ) { 95fe5e51b7Smrg case 8: 96fe5e51b7Smrg case 24: 97fe5e51b7Smrg break; 98fe5e51b7Smrg 99fe5e51b7Smrg case 16: 100fe5e51b7Smrg numConfigs = 8; 101fe5e51b7Smrg 102fe5e51b7Smrg pConfigs = (__GLXvisualConfig*)xcalloc( sizeof(__GLXvisualConfig), 103fe5e51b7Smrg numConfigs ); 104fe5e51b7Smrg if ( !pConfigs ) { 105fe5e51b7Smrg return FALSE; 106fe5e51b7Smrg } 107fe5e51b7Smrg 108fe5e51b7Smrg pMGAConfigs = (MGAConfigPrivPtr)xcalloc( sizeof(MGAConfigPrivRec), 109fe5e51b7Smrg numConfigs ); 110fe5e51b7Smrg if ( !pMGAConfigs ) { 111fe5e51b7Smrg xfree( pConfigs ); 112fe5e51b7Smrg return FALSE; 113fe5e51b7Smrg } 114fe5e51b7Smrg 115fe5e51b7Smrg pMGAConfigPtrs = (MGAConfigPrivPtr*)xcalloc( sizeof(MGAConfigPrivPtr), 116fe5e51b7Smrg numConfigs ); 117fe5e51b7Smrg if ( !pMGAConfigPtrs ) { 118fe5e51b7Smrg xfree( pConfigs ); 119fe5e51b7Smrg xfree( pMGAConfigs ); 120fe5e51b7Smrg return FALSE; 121fe5e51b7Smrg } 122fe5e51b7Smrg 123fe5e51b7Smrg for ( i = 0 ; i < numConfigs ; i++ ) { 124fe5e51b7Smrg pMGAConfigPtrs[i] = &pMGAConfigs[i]; 125fe5e51b7Smrg } 126fe5e51b7Smrg 127fe5e51b7Smrg i = 0; 128fe5e51b7Smrg for ( accum = 0 ; accum <= 1 ; accum++ ) { 129fe5e51b7Smrg for ( stencil = 0 ; stencil <= 1 ; stencil++ ) { 130fe5e51b7Smrg for ( db = 1 ; db >= 0 ; db-- ) { 131fe5e51b7Smrg pConfigs[i].vid = -1; 132fe5e51b7Smrg pConfigs[i].class = -1; 133fe5e51b7Smrg pConfigs[i].rgba = TRUE; 134fe5e51b7Smrg pConfigs[i].redSize = 5; 135fe5e51b7Smrg pConfigs[i].greenSize = 6; 136fe5e51b7Smrg pConfigs[i].blueSize = 5; 137fe5e51b7Smrg pConfigs[i].alphaSize = 0; 138fe5e51b7Smrg pConfigs[i].redMask = 0x0000F800; 139fe5e51b7Smrg pConfigs[i].greenMask = 0x000007E0; 140fe5e51b7Smrg pConfigs[i].blueMask = 0x0000001F; 141fe5e51b7Smrg pConfigs[i].alphaMask = 0; 142fe5e51b7Smrg if ( accum ) { 143fe5e51b7Smrg pConfigs[i].accumRedSize = 16; 144fe5e51b7Smrg pConfigs[i].accumGreenSize = 16; 145fe5e51b7Smrg pConfigs[i].accumBlueSize = 16; 146fe5e51b7Smrg pConfigs[i].accumAlphaSize = 0; 147fe5e51b7Smrg } else { 148fe5e51b7Smrg pConfigs[i].accumRedSize = 0; 149fe5e51b7Smrg pConfigs[i].accumGreenSize = 0; 150fe5e51b7Smrg pConfigs[i].accumBlueSize = 0; 151fe5e51b7Smrg pConfigs[i].accumAlphaSize = 0; 152fe5e51b7Smrg } 153fe5e51b7Smrg if ( db ) { 154fe5e51b7Smrg pConfigs[i].doubleBuffer = TRUE; 155fe5e51b7Smrg } else { 156fe5e51b7Smrg pConfigs[i].doubleBuffer = FALSE; 157fe5e51b7Smrg } 158fe5e51b7Smrg pConfigs[i].stereo = FALSE; 159fe5e51b7Smrg pConfigs[i].bufferSize = 16; 160fe5e51b7Smrg pConfigs[i].depthSize = 16; 161fe5e51b7Smrg if ( stencil ) { 162fe5e51b7Smrg pConfigs[i].stencilSize = 8; 163fe5e51b7Smrg } else { 164fe5e51b7Smrg pConfigs[i].stencilSize = 0; 165fe5e51b7Smrg } 166fe5e51b7Smrg pConfigs[i].auxBuffers = 0; 167fe5e51b7Smrg pConfigs[i].level = 0; 168fe5e51b7Smrg if ( accum || stencil ) { 169fe5e51b7Smrg pConfigs[i].visualRating = GLX_SLOW_CONFIG; 170fe5e51b7Smrg } else { 171fe5e51b7Smrg pConfigs[i].visualRating = GLX_NONE; 172fe5e51b7Smrg } 173fe5e51b7Smrg pConfigs[i].transparentPixel = GLX_NONE; 174fe5e51b7Smrg pConfigs[i].transparentRed = 0; 175fe5e51b7Smrg pConfigs[i].transparentGreen = 0; 176fe5e51b7Smrg pConfigs[i].transparentBlue = 0; 177fe5e51b7Smrg pConfigs[i].transparentAlpha = 0; 178fe5e51b7Smrg pConfigs[i].transparentIndex = 0; 179fe5e51b7Smrg i++; 180fe5e51b7Smrg } 181fe5e51b7Smrg } 182fe5e51b7Smrg } 183fe5e51b7Smrg if ( i != numConfigs ) { 184fe5e51b7Smrg xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 185fe5e51b7Smrg "[drm] Incorrect initialization of visuals\n" ); 186fe5e51b7Smrg return FALSE; 187fe5e51b7Smrg } 188fe5e51b7Smrg break; 189fe5e51b7Smrg 190fe5e51b7Smrg case 32: 191fe5e51b7Smrg numConfigs = 8; 192fe5e51b7Smrg 193fe5e51b7Smrg pConfigs = (__GLXvisualConfig*)xcalloc( sizeof(__GLXvisualConfig), 194fe5e51b7Smrg numConfigs ); 195fe5e51b7Smrg if ( !pConfigs ) { 196fe5e51b7Smrg return FALSE; 197fe5e51b7Smrg } 198fe5e51b7Smrg 199fe5e51b7Smrg pMGAConfigs = (MGAConfigPrivPtr)xcalloc( sizeof(MGAConfigPrivRec), 200fe5e51b7Smrg numConfigs ); 201fe5e51b7Smrg if ( !pMGAConfigs ) { 202fe5e51b7Smrg xfree( pConfigs ); 203fe5e51b7Smrg return FALSE; 204fe5e51b7Smrg } 205fe5e51b7Smrg 206fe5e51b7Smrg pMGAConfigPtrs = (MGAConfigPrivPtr*)xcalloc( sizeof(MGAConfigPrivPtr), 207fe5e51b7Smrg numConfigs ); 208fe5e51b7Smrg if ( !pMGAConfigPtrs ) { 209fe5e51b7Smrg xfree( pConfigs ); 210fe5e51b7Smrg xfree( pMGAConfigs ); 211fe5e51b7Smrg return FALSE; 212fe5e51b7Smrg } 213fe5e51b7Smrg 214fe5e51b7Smrg for ( i = 0 ; i < numConfigs ; i++ ) { 215fe5e51b7Smrg pMGAConfigPtrs[i] = &pMGAConfigs[i]; 216fe5e51b7Smrg } 217fe5e51b7Smrg 218fe5e51b7Smrg i = 0; 219fe5e51b7Smrg for ( accum = 0 ; accum <= 1 ; accum++ ) { 220fe5e51b7Smrg for ( depth = 0 ; depth <= 1 ; depth++ ) { /* and stencil */ 221fe5e51b7Smrg for ( db = 1 ; db >= 0 ; db-- ) { 222fe5e51b7Smrg pConfigs[i].vid = -1; 223fe5e51b7Smrg pConfigs[i].class = -1; 224fe5e51b7Smrg pConfigs[i].rgba = TRUE; 225fe5e51b7Smrg pConfigs[i].redSize = 8; 226fe5e51b7Smrg pConfigs[i].greenSize = 8; 227fe5e51b7Smrg pConfigs[i].blueSize = 8; 228fe5e51b7Smrg pConfigs[i].alphaSize = 0; 229fe5e51b7Smrg pConfigs[i].redMask = 0x00FF0000; 230fe5e51b7Smrg pConfigs[i].greenMask = 0x0000FF00; 231fe5e51b7Smrg pConfigs[i].blueMask = 0x000000FF; 232fe5e51b7Smrg pConfigs[i].alphaMask = 0x0; 233fe5e51b7Smrg if ( accum ) { 234fe5e51b7Smrg pConfigs[i].accumRedSize = 16; 235fe5e51b7Smrg pConfigs[i].accumGreenSize = 16; 236fe5e51b7Smrg pConfigs[i].accumBlueSize = 16; 237fe5e51b7Smrg pConfigs[i].accumAlphaSize = 0; 238fe5e51b7Smrg } else { 239fe5e51b7Smrg pConfigs[i].accumRedSize = 0; 240fe5e51b7Smrg pConfigs[i].accumGreenSize = 0; 241fe5e51b7Smrg pConfigs[i].accumBlueSize = 0; 242fe5e51b7Smrg pConfigs[i].accumAlphaSize = 0; 243fe5e51b7Smrg } 244fe5e51b7Smrg if ( db ) { 245fe5e51b7Smrg pConfigs[i].doubleBuffer = TRUE; 246fe5e51b7Smrg } else { 247fe5e51b7Smrg pConfigs[i].doubleBuffer = FALSE; 248fe5e51b7Smrg } 249fe5e51b7Smrg pConfigs[i].stereo = FALSE; 250fe5e51b7Smrg pConfigs[i].bufferSize = 24; 251fe5e51b7Smrg if ( depth ) { 252fe5e51b7Smrg pConfigs[i].depthSize = 24; 253fe5e51b7Smrg pConfigs[i].stencilSize = 8; 254fe5e51b7Smrg } 255fe5e51b7Smrg else { 256fe5e51b7Smrg pConfigs[i].depthSize = 0; 257fe5e51b7Smrg pConfigs[i].stencilSize = 0; 258fe5e51b7Smrg } 259fe5e51b7Smrg pConfigs[i].auxBuffers = 0; 260fe5e51b7Smrg pConfigs[i].level = 0; 261fe5e51b7Smrg if ( accum ) { 262fe5e51b7Smrg pConfigs[i].visualRating = GLX_SLOW_CONFIG; 263fe5e51b7Smrg } else { 264fe5e51b7Smrg pConfigs[i].visualRating = GLX_NONE; 265fe5e51b7Smrg } 266fe5e51b7Smrg pConfigs[i].transparentPixel = GLX_NONE; 267fe5e51b7Smrg pConfigs[i].transparentRed = 0; 268fe5e51b7Smrg pConfigs[i].transparentGreen = 0; 269fe5e51b7Smrg pConfigs[i].transparentBlue = 0; 270fe5e51b7Smrg pConfigs[i].transparentAlpha = 0; 271fe5e51b7Smrg pConfigs[i].transparentIndex = 0; 272fe5e51b7Smrg i++; 273fe5e51b7Smrg } 274fe5e51b7Smrg } 275fe5e51b7Smrg } 276fe5e51b7Smrg if ( i != numConfigs ) { 277fe5e51b7Smrg xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 278fe5e51b7Smrg "[drm] Incorrect initialization of visuals\n" ); 279fe5e51b7Smrg return FALSE; 280fe5e51b7Smrg } 281fe5e51b7Smrg break; 282fe5e51b7Smrg 283fe5e51b7Smrg default: 284fe5e51b7Smrg /* Unexpected bits/pixels */ 285fe5e51b7Smrg break; 286fe5e51b7Smrg } 287fe5e51b7Smrg 288fe5e51b7Smrg pMga->numVisualConfigs = numConfigs; 289fe5e51b7Smrg pMga->pVisualConfigs = pConfigs; 290fe5e51b7Smrg pMga->pVisualConfigsPriv = pMGAConfigs; 291fe5e51b7Smrg 292fe5e51b7Smrg GlxSetVisualConfigs( numConfigs, pConfigs, (void **)pMGAConfigPtrs ); 293fe5e51b7Smrg 294fe5e51b7Smrg return TRUE; 295fe5e51b7Smrg} 296fe5e51b7Smrg 297fe5e51b7Smrgstatic Bool MGACreateContext( ScreenPtr pScreen, VisualPtr visual, 298fe5e51b7Smrg drm_context_t hwContext, void *pVisualConfigPriv, 299fe5e51b7Smrg DRIContextType contextStore ) 300fe5e51b7Smrg{ 301fe5e51b7Smrg /* Nothing yet */ 302fe5e51b7Smrg return TRUE; 303fe5e51b7Smrg} 304fe5e51b7Smrg 305fe5e51b7Smrgstatic void MGADestroyContext( ScreenPtr pScreen, drm_context_t hwContext, 306fe5e51b7Smrg DRIContextType contextStore ) 307fe5e51b7Smrg{ 308fe5e51b7Smrg /* Nothing yet */ 309fe5e51b7Smrg} 310fe5e51b7Smrg 311fe5e51b7Smrg 312fe5e51b7Smrg/* Quiescence, locking 313fe5e51b7Smrg */ 314fe5e51b7Smrg#define MGA_TIMEOUT 2048 315fe5e51b7Smrg 316fe5e51b7Smrgstatic void MGAWaitForIdleDMA( ScrnInfoPtr pScrn ) 317fe5e51b7Smrg{ 318fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 319fe5e51b7Smrg drm_lock_t lock; 320fe5e51b7Smrg int ret; 321fe5e51b7Smrg int i = 0; 322fe5e51b7Smrg 323fe5e51b7Smrg memset( &lock, 0, sizeof(drm_lock_t) ); 324fe5e51b7Smrg 325fe5e51b7Smrg for (;;) { 326fe5e51b7Smrg do { 327fe5e51b7Smrg /* first ask for quiescent and flush */ 328fe5e51b7Smrg lock.flags = DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH; 329fe5e51b7Smrg do { 330fe5e51b7Smrg ret = drmCommandWrite( pMga->drmFD, DRM_MGA_FLUSH, 331fe5e51b7Smrg &lock, sizeof( drm_lock_t ) ); 332fe5e51b7Smrg } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY ); 333fe5e51b7Smrg 334fe5e51b7Smrg /* if it's still busy just try quiescent */ 335fe5e51b7Smrg if ( ret == -EBUSY ) { 336fe5e51b7Smrg lock.flags = DRM_LOCK_QUIESCENT; 337fe5e51b7Smrg do { 338fe5e51b7Smrg ret = drmCommandWrite( pMga->drmFD, DRM_MGA_FLUSH, 339fe5e51b7Smrg &lock, sizeof( drm_lock_t ) ); 340fe5e51b7Smrg } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY ); 341fe5e51b7Smrg } 342fe5e51b7Smrg } while ( ( ret == -EBUSY ) && ( i++ < MGA_TIMEOUT ) ); 343fe5e51b7Smrg 344fe5e51b7Smrg if ( ret == 0 ) 345fe5e51b7Smrg return; 346fe5e51b7Smrg 347fe5e51b7Smrg xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 348fe5e51b7Smrg "[dri] Idle timed out, resetting engine...\n" ); 349fe5e51b7Smrg 350fe5e51b7Smrg drmCommandNone( pMga->drmFD, DRM_MGA_RESET ); 351fe5e51b7Smrg } 352fe5e51b7Smrg} 353fe5e51b7Smrg 354fe5e51b7Smrg 355fe5e51b7Smrgvoid MGAGetQuiescence( ScrnInfoPtr pScrn ) 356fe5e51b7Smrg{ 357fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 358fe5e51b7Smrg 359fe5e51b7Smrg pMga->haveQuiescense = 1; 360fe5e51b7Smrg 361fe5e51b7Smrg if ( pMga->directRenderingEnabled ) { 362fe5e51b7Smrg MGAFBLayout *pLayout = &pMga->CurrentLayout; 363fe5e51b7Smrg 364fe5e51b7Smrg MGAWaitForIdleDMA( pScrn ); 365fe5e51b7Smrg 366fe5e51b7Smrg /* FIXME what about EXA? */ 367fe5e51b7Smrg#ifdef USE_XAA 368fe5e51b7Smrg if (!pMga->Exa && pMga->AccelInfoRec) { 369fe5e51b7Smrg WAITFIFO( 11 ); 370fe5e51b7Smrg OUTREG( MGAREG_MACCESS, pMga->MAccess ); 371fe5e51b7Smrg OUTREG( MGAREG_PITCH, pLayout->displayWidth ); 372fe5e51b7Smrg 373fe5e51b7Smrg pMga->PlaneMask = ~0; 374fe5e51b7Smrg OUTREG( MGAREG_PLNWT, pMga->PlaneMask ); 375fe5e51b7Smrg 376fe5e51b7Smrg pMga->BgColor = 0; 377fe5e51b7Smrg pMga->FgColor = 0; 378fe5e51b7Smrg OUTREG( MGAREG_BCOL, pMga->BgColor ); 379fe5e51b7Smrg OUTREG( MGAREG_FCOL, pMga->FgColor ); 380fe5e51b7Smrg OUTREG( MGAREG_SRCORG, pMga->realSrcOrg ); 381fe5e51b7Smrg 382fe5e51b7Smrg pMga->SrcOrg = 0; 383fe5e51b7Smrg OUTREG( MGAREG_DSTORG, pMga->DstOrg ); 384fe5e51b7Smrg OUTREG( MGAREG_OPMODE, MGAOPM_DMA_BLIT ); 385fe5e51b7Smrg OUTREG( MGAREG_CXBNDRY, 0xFFFF0000 ); /* (maxX << 16) | minX */ 386fe5e51b7Smrg OUTREG( MGAREG_YTOP, 0x00000000 ); /* minPixelPointer */ 387fe5e51b7Smrg OUTREG( MGAREG_YBOT, 0x007FFFFF ); /* maxPixelPointer */ 388fe5e51b7Smrg 389fe5e51b7Smrg pMga->AccelFlags &= ~CLIPPER_ON; 390fe5e51b7Smrg } 391fe5e51b7Smrg#endif 392fe5e51b7Smrg } 393fe5e51b7Smrg} 394fe5e51b7Smrg 395fe5e51b7Smrgvoid MGAGetQuiescenceShared( ScrnInfoPtr pScrn ) 396fe5e51b7Smrg{ 397fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 398fe5e51b7Smrg MGAEntPtr pMGAEnt = pMga->entityPrivate; 399fe5e51b7Smrg MGAPtr pMGA2 = MGAPTR(pMGAEnt->pScrn_2); 400fe5e51b7Smrg 401fe5e51b7Smrg pMga = MGAPTR(pMGAEnt->pScrn_1); 402fe5e51b7Smrg pMga->haveQuiescense = 1; 403fe5e51b7Smrg pMGA2->haveQuiescense = 1; 404fe5e51b7Smrg 405fe5e51b7Smrg if ( pMGAEnt->directRenderingEnabled ) { 406fe5e51b7Smrg MGAWaitForIdleDMA( pMGAEnt->pScrn_1 ); 407fe5e51b7Smrg 408fe5e51b7Smrg /* FIXME what about EXA? */ 409fe5e51b7Smrg#ifdef USE_XAA 410fe5e51b7Smrg if (!pMga->Exa && pMga->AccelInfoRec) 411fe5e51b7Smrg pMga->RestoreAccelState( pScrn ); 412fe5e51b7Smrg#endif 413fe5e51b7Smrg xf86SetLastScrnFlag( pScrn->entityList[0], pScrn->scrnIndex ); 414fe5e51b7Smrg } 415fe5e51b7Smrg} 416fe5e51b7Smrg 417fe5e51b7Smrgstatic void MGASwapContext( ScreenPtr pScreen ) 418fe5e51b7Smrg{ 419fe5e51b7Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 420fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 421fe5e51b7Smrg 422fe5e51b7Smrg /* Arrange for dma_quiescence and xaa sync to be called as 423fe5e51b7Smrg * appropriate. 424fe5e51b7Smrg */ 425fe5e51b7Smrg pMga->haveQuiescense = 0; 426fe5e51b7Smrg 427fe5e51b7Smrg MGA_MARK_SYNC(pMga, pScrn); 428fe5e51b7Smrg} 429fe5e51b7Smrg 430fe5e51b7Smrgstatic void MGASwapContextShared( ScreenPtr pScreen ) 431fe5e51b7Smrg{ 432fe5e51b7Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 433fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 434fe5e51b7Smrg MGAEntPtr pMGAEnt = pMga->entityPrivate; 435fe5e51b7Smrg MGAPtr pMGA2 = MGAPTR(pMGAEnt->pScrn_2); 436fe5e51b7Smrg 437fe5e51b7Smrg pMga = MGAPTR(pMGAEnt->pScrn_1); 438fe5e51b7Smrg 439fe5e51b7Smrg pMga->haveQuiescense = pMGA2->haveQuiescense = 0; 440fe5e51b7Smrg 441fe5e51b7Smrg MGA_MARK_SYNC(pMga, pScrn); 442fe5e51b7Smrg MGA_MARK_SYNC(pMGA2, pMGAEnt->pScrn_2); 443fe5e51b7Smrg} 444fe5e51b7Smrg 445fe5e51b7Smrg/* FIXME: This comment is out of date, since we aren't overriding 446fe5e51b7Smrg * Block/Wakeuphandler anymore. 447fe5e51b7Smrg * 448fe5e51b7Smrg * 449fe5e51b7Smrg * This is really only called from validate/postvalidate as we 450fe5e51b7Smrg * override the dri lock/unlock. Want to remove validate/postvalidate 451fe5e51b7Smrg * processing, but need to remove all client-side use of drawable lock 452fe5e51b7Smrg * first (otherwise there is noone recover when a client dies holding 453fe5e51b7Smrg * the drawable lock). 454fe5e51b7Smrg * 455fe5e51b7Smrg * What does this mean? 456fe5e51b7Smrg * 457fe5e51b7Smrg * - The above code gets executed every time a 458fe5e51b7Smrg * window changes shape or the focus changes, which isn't really 459fe5e51b7Smrg * optimal. 460fe5e51b7Smrg * - The X server therefore believes it needs to do an XAA sync 461fe5e51b7Smrg * *and* a dma quiescense ioctl each time that happens. 462fe5e51b7Smrg * 463fe5e51b7Smrg * We don't wrap wakeuphandler any longer, so at least we can say that 464fe5e51b7Smrg * this doesn't happen *every time the mouse moves*... 465fe5e51b7Smrg */ 466fe5e51b7Smrgstatic void 467fe5e51b7SmrgMGADRISwapContext( ScreenPtr pScreen, DRISyncType syncType, 468fe5e51b7Smrg DRIContextType oldContextType, void *oldContext, 469fe5e51b7Smrg DRIContextType newContextType, void *newContext ) 470fe5e51b7Smrg{ 471fe5e51b7Smrg if ( syncType == DRI_3D_SYNC && 472fe5e51b7Smrg oldContextType == DRI_2D_CONTEXT && 473fe5e51b7Smrg newContextType == DRI_2D_CONTEXT ) 474fe5e51b7Smrg { 475fe5e51b7Smrg MGASwapContext( pScreen ); 476fe5e51b7Smrg } 477fe5e51b7Smrg} 478fe5e51b7Smrg 479fe5e51b7Smrgstatic void 480fe5e51b7SmrgMGADRISwapContextShared( ScreenPtr pScreen, DRISyncType syncType, 481fe5e51b7Smrg DRIContextType oldContextType, void *oldContext, 482fe5e51b7Smrg DRIContextType newContextType, void *newContext ) 483fe5e51b7Smrg{ 484fe5e51b7Smrg if ( syncType == DRI_3D_SYNC && 485fe5e51b7Smrg oldContextType == DRI_2D_CONTEXT && 486fe5e51b7Smrg newContextType == DRI_2D_CONTEXT ) 487fe5e51b7Smrg { 488fe5e51b7Smrg MGASwapContextShared( pScreen ); 489fe5e51b7Smrg } 490fe5e51b7Smrg} 491fe5e51b7Smrg 492fe5e51b7Smrgvoid MGASelectBuffer( ScrnInfoPtr pScrn, int which ) 493fe5e51b7Smrg{ 494fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 495fe5e51b7Smrg MGADRIPtr pMGADRI = (MGADRIPtr)pMga->pDRIInfo->devPrivate; 496fe5e51b7Smrg 497fe5e51b7Smrg switch ( which ) { 498fe5e51b7Smrg case MGA_BACK: 499fe5e51b7Smrg OUTREG( MGAREG_DSTORG, pMGADRI->backOffset ); 500fe5e51b7Smrg OUTREG( MGAREG_SRCORG, pMGADRI->backOffset ); 501fe5e51b7Smrg break; 502fe5e51b7Smrg case MGA_DEPTH: 503fe5e51b7Smrg OUTREG( MGAREG_DSTORG, pMGADRI->depthOffset ); 504fe5e51b7Smrg OUTREG( MGAREG_SRCORG, pMGADRI->depthOffset ); 505fe5e51b7Smrg break; 506fe5e51b7Smrg default: 507fe5e51b7Smrg case MGA_FRONT: 508fe5e51b7Smrg OUTREG( MGAREG_DSTORG, pMGADRI->frontOffset ); 509fe5e51b7Smrg OUTREG( MGAREG_SRCORG, pMGADRI->frontOffset ); 510fe5e51b7Smrg break; 511fe5e51b7Smrg } 512fe5e51b7Smrg} 513fe5e51b7Smrg 514fe5e51b7Smrgstatic unsigned int mylog2( unsigned int n ) 515fe5e51b7Smrg{ 516fe5e51b7Smrg unsigned int log2 = 1; 517fe5e51b7Smrg while ( n > 1 ) n >>= 1, log2++; 518fe5e51b7Smrg return log2; 519fe5e51b7Smrg} 520fe5e51b7Smrg 521fe5e51b7Smrg/** 522fe5e51b7Smrg * Initialize DMA and secondary texture memory 523fe5e51b7Smrg * 524fe5e51b7Smrg * \todo 525fe5e51b7Smrg * The sizes used for the primary DMA buffer and the bin size and count for 526fe5e51b7Smrg * the secondary DMA buffers should be configurable from the xorg.conf. 527fe5e51b7Smrg * 528fe5e51b7Smrg * \todo 529fe5e51b7Smrg * This routine should use \c mga_bios_values::host_interface to limit the 530fe5e51b7Smrg * AGP mode. It the card is PCI, \c MGARec::agpSize should be forced to 0. 531fe5e51b7Smrg */ 532fe5e51b7Smrgstatic Bool MGADRIBootstrapDMA(ScreenPtr pScreen) 533fe5e51b7Smrg{ 534fe5e51b7Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 535fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 536fe5e51b7Smrg MGADRIServerPrivatePtr pMGADRIServer = pMga->DRIServerInfo; 537fe5e51b7Smrg int ret; 538fe5e51b7Smrg int requested_agp_mode; 539fe5e51b7Smrg int count; 540fe5e51b7Smrg 541fe5e51b7Smrg 542fe5e51b7Smrg if(pMga->agpSize < 12)pMga->agpSize = 12; 543fe5e51b7Smrg if(pMga->agpSize > 64)pMga->agpSize = 64; /* cap */ 544fe5e51b7Smrg 545fe5e51b7Smrg 546fe5e51b7Smrg requested_agp_mode = 0; 547fe5e51b7Smrg switch ( pMga->agpMode ) { 548fe5e51b7Smrg case 4: 549fe5e51b7Smrg requested_agp_mode |= MGA_AGP_4X_MODE; 550fe5e51b7Smrg case 2: 551fe5e51b7Smrg requested_agp_mode |= MGA_AGP_2X_MODE; 552fe5e51b7Smrg case 1: 553fe5e51b7Smrg default: 554fe5e51b7Smrg requested_agp_mode |= MGA_AGP_1X_MODE; 555fe5e51b7Smrg } 556fe5e51b7Smrg 557fe5e51b7Smrg 558fe5e51b7Smrg if ( (pMGADRIServer->drm_version_minor >= 2) && !pMga->useOldDmaInit ) { 559fe5e51b7Smrg drm_mga_dma_bootstrap_t dma_bs; 560fe5e51b7Smrg 561fe5e51b7Smrg 562fe5e51b7Smrg (void) memset( & dma_bs, 0, sizeof( dma_bs ) ); 563fe5e51b7Smrg dma_bs.primary_size = 1024 * 1024; 564fe5e51b7Smrg dma_bs.secondary_bin_count = MGA_NUM_BUFFERS; 565fe5e51b7Smrg dma_bs.secondary_bin_size = MGA_BUFFER_SIZE; 566fe5e51b7Smrg dma_bs.agp_size = pMga->agpSize; 567fe5e51b7Smrg dma_bs.agp_mode = (pMga->forcePciDma) ? 0 : requested_agp_mode; 568fe5e51b7Smrg 569fe5e51b7Smrg ret = drmCommandWriteRead( pMga->drmFD, DRM_MGA_DMA_BOOTSTRAP, 570fe5e51b7Smrg & dma_bs, sizeof( dma_bs ) ); 571fe5e51b7Smrg if ( ret ) { 572fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, "[drm] Could not boot-strap DMA (%d)\n", ret ); 573fe5e51b7Smrg return FALSE; 574fe5e51b7Smrg } 575fe5e51b7Smrg 576fe5e51b7Smrg pMga->agpMode = dma_bs.agp_mode; 577fe5e51b7Smrg pMGADRIServer->agp.size = dma_bs.agp_size; 578fe5e51b7Smrg 579fe5e51b7Smrg pMGADRIServer->agpTextures.handle = dma_bs.texture_handle; 580fe5e51b7Smrg pMGADRIServer->agpTextures.size = dma_bs.texture_size; 581fe5e51b7Smrg } 582fe5e51b7Smrg else { 583fe5e51b7Smrg unsigned long mode; 584fe5e51b7Smrg unsigned int vendor, device; 585fe5e51b7Smrg int i; 586fe5e51b7Smrg 587fe5e51b7Smrg 588fe5e51b7Smrg if ( pMga->forcePciDma ) { 589fe5e51b7Smrg const char * const msg = (pMGADRIServer->drm_version_minor < 2) 590fe5e51b7Smrg ? "DRM version is too old (3.2 or later required)" 591fe5e51b7Smrg : "old DMA init path was requested"; 592fe5e51b7Smrg 593fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_WARNING, 594fe5e51b7Smrg "[agp] Cannot force PCI DMA because %s\n", msg ); 595fe5e51b7Smrg } 596fe5e51b7Smrg 597fe5e51b7Smrg if ( drmAgpAcquire( pMga->drmFD ) < 0 ) { 598fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not available\n" ); 599fe5e51b7Smrg return FALSE; 600fe5e51b7Smrg } 601fe5e51b7Smrg 602fe5e51b7Smrg mode = drmAgpGetMode( pMga->drmFD ); /* Default mode */ 603fe5e51b7Smrg vendor = drmAgpVendorId( pMga->drmFD ); 604fe5e51b7Smrg device = drmAgpDeviceId( pMga->drmFD ); 605fe5e51b7Smrg 606fe5e51b7Smrg mode = (mode & ~MGA_AGP_MODE_MASK) | requested_agp_mode; 607fe5e51b7Smrg 608fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 609fe5e51b7Smrg "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", 610fe5e51b7Smrg mode, vendor, device, 611fe5e51b7Smrg VENDOR_ID(pMga->PciInfo), 612fe5e51b7Smrg DEVICE_ID(pMga->PciInfo)); 613fe5e51b7Smrg 614fe5e51b7Smrg if ( drmAgpEnable( pMga->drmFD, mode ) < 0 ) { 615fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n" ); 616fe5e51b7Smrg drmAgpRelease( pMga->drmFD ); 617fe5e51b7Smrg return FALSE; 618fe5e51b7Smrg } 619fe5e51b7Smrg 620fe5e51b7Smrg if ( pMga->Chipset == PCI_CHIP_MGAG200 ) { 621fe5e51b7Smrg switch ( pMga->agpMode ) { 622fe5e51b7Smrg case 2: 623fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 624fe5e51b7Smrg "[drm] Enabling AGP 2x PLL encoding\n" ); 625fe5e51b7Smrg OUTREG( MGAREG_AGP_PLL, MGA_AGP2XPLL_ENABLE ); 626fe5e51b7Smrg break; 627fe5e51b7Smrg 628fe5e51b7Smrg case 1: 629fe5e51b7Smrg default: 630fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 631fe5e51b7Smrg "[drm] Disabling AGP 2x PLL encoding\n" ); 632fe5e51b7Smrg OUTREG( MGAREG_AGP_PLL, MGA_AGP2XPLL_DISABLE ); 633fe5e51b7Smrg pMga->agpMode = 1; 634fe5e51b7Smrg break; 635fe5e51b7Smrg } 636fe5e51b7Smrg } 637fe5e51b7Smrg 638fe5e51b7Smrg pMGADRIServer->agp.size = pMga->agpSize * 1024 * 1024; 639fe5e51b7Smrg 640fe5e51b7Smrg pMGADRIServer->warp.offset = 0; 641fe5e51b7Smrg pMGADRIServer->warp.size = MGA_WARP_UCODE_SIZE; 642fe5e51b7Smrg 643fe5e51b7Smrg pMGADRIServer->primary.offset = (pMGADRIServer->warp.offset + 644fe5e51b7Smrg pMGADRIServer->warp.size); 645fe5e51b7Smrg pMGADRIServer->primary.size = 1024 * 1024; 646fe5e51b7Smrg 647fe5e51b7Smrg pMGADRIServer->buffers.offset = (pMGADRIServer->primary.offset + 648fe5e51b7Smrg pMGADRIServer->primary.size); 649fe5e51b7Smrg pMGADRIServer->buffers.size = MGA_NUM_BUFFERS * MGA_BUFFER_SIZE; 650fe5e51b7Smrg 651fe5e51b7Smrg 652fe5e51b7Smrg pMGADRIServer->agpTextures.offset = (pMGADRIServer->buffers.offset + 653fe5e51b7Smrg pMGADRIServer->buffers.size); 654fe5e51b7Smrg 655fe5e51b7Smrg pMGADRIServer->agpTextures.size = (pMGADRIServer->agp.size - 656fe5e51b7Smrg pMGADRIServer->agpTextures.offset); 657fe5e51b7Smrg 658fe5e51b7Smrg ret = drmAgpAlloc( pMga->drmFD, pMGADRIServer->agp.size, 659fe5e51b7Smrg 0, NULL, &pMGADRIServer->agp.handle ); 660fe5e51b7Smrg if ( ret < 0 ) { 661fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret ); 662fe5e51b7Smrg drmAgpRelease( pMga->drmFD ); 663fe5e51b7Smrg return FALSE; 664fe5e51b7Smrg } 665fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 666fe5e51b7Smrg "[agp] %d kB allocated with handle 0x%08x\n", 667fe5e51b7Smrg pMGADRIServer->agp.size/1024, 668fe5e51b7Smrg (unsigned int) pMGADRIServer->agp.handle ); 669fe5e51b7Smrg 670fe5e51b7Smrg if ( drmAgpBind( pMga->drmFD, pMGADRIServer->agp.handle, 0 ) < 0 ) { 671fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Could not bind memory\n" ); 672fe5e51b7Smrg drmAgpFree( pMga->drmFD, pMGADRIServer->agp.handle ); 673fe5e51b7Smrg drmAgpRelease( pMga->drmFD ); 674fe5e51b7Smrg return FALSE; 675fe5e51b7Smrg } 676fe5e51b7Smrg 677fe5e51b7Smrg /* WARP microcode space 678fe5e51b7Smrg */ 679fe5e51b7Smrg if ( drmAddMap( pMga->drmFD, 680fe5e51b7Smrg pMGADRIServer->warp.offset, 681fe5e51b7Smrg pMGADRIServer->warp.size, 682fe5e51b7Smrg DRM_AGP, DRM_READ_ONLY, 683fe5e51b7Smrg &pMGADRIServer->warp.handle ) < 0 ) { 684fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 685fe5e51b7Smrg "[agp] Could not add WARP microcode mapping\n" ); 686fe5e51b7Smrg return FALSE; 687fe5e51b7Smrg } 688fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 689fe5e51b7Smrg "[agp] WARP microcode handle = 0x%08x\n", 690fe5e51b7Smrg (unsigned int) pMGADRIServer->warp.handle ); 691fe5e51b7Smrg 692fe5e51b7Smrg /* Primary DMA space 693fe5e51b7Smrg */ 694fe5e51b7Smrg if ( drmAddMap( pMga->drmFD, 695fe5e51b7Smrg pMGADRIServer->primary.offset, 696fe5e51b7Smrg pMGADRIServer->primary.size, 697fe5e51b7Smrg DRM_AGP, DRM_READ_ONLY, 698fe5e51b7Smrg &pMGADRIServer->primary.handle ) < 0 ) { 699fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 700fe5e51b7Smrg "[agp] Could not add primary DMA mapping\n" ); 701fe5e51b7Smrg return FALSE; 702fe5e51b7Smrg } 703fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 704fe5e51b7Smrg "[agp] Primary DMA handle = 0x%08x\n", 705fe5e51b7Smrg (unsigned int) pMGADRIServer->primary.handle ); 706fe5e51b7Smrg 707fe5e51b7Smrg /* DMA buffers 708fe5e51b7Smrg */ 709fe5e51b7Smrg if ( drmAddMap( pMga->drmFD, 710fe5e51b7Smrg pMGADRIServer->buffers.offset, 711fe5e51b7Smrg pMGADRIServer->buffers.size, 712fe5e51b7Smrg DRM_AGP, 0, 713fe5e51b7Smrg &pMGADRIServer->buffers.handle ) < 0 ) { 714fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 715fe5e51b7Smrg "[agp] Could not add DMA buffers mapping\n" ); 716fe5e51b7Smrg return FALSE; 717fe5e51b7Smrg } 718fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 719fe5e51b7Smrg "[agp] DMA buffers handle = 0x%08x\n", 720fe5e51b7Smrg (unsigned int) pMGADRIServer->buffers.handle ); 721fe5e51b7Smrg 722fe5e51b7Smrg count = drmAddBufs( pMga->drmFD, 723fe5e51b7Smrg MGA_NUM_BUFFERS, MGA_BUFFER_SIZE, 724fe5e51b7Smrg DRM_AGP_BUFFER, pMGADRIServer->buffers.offset ); 725fe5e51b7Smrg if ( count <= 0 ) { 726fe5e51b7Smrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, 727fe5e51b7Smrg "[drm] failure adding %d %d byte DMA buffers\n", 728fe5e51b7Smrg MGA_NUM_BUFFERS, MGA_BUFFER_SIZE ); 729fe5e51b7Smrg return FALSE; 730fe5e51b7Smrg } 731fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 732fe5e51b7Smrg "[drm] Added %d %d byte DMA buffers\n", 733fe5e51b7Smrg count, MGA_BUFFER_SIZE ); 734fe5e51b7Smrg 735fe5e51b7Smrg i = mylog2(pMGADRIServer->agpTextures.size / MGA_NR_TEX_REGIONS); 736fe5e51b7Smrg if(i < MGA_LOG_MIN_TEX_REGION_SIZE) 737fe5e51b7Smrg i = MGA_LOG_MIN_TEX_REGION_SIZE; 738fe5e51b7Smrg pMGADRIServer->agpTextures.size = (pMGADRIServer->agpTextures.size >> i) << i; 739fe5e51b7Smrg 740fe5e51b7Smrg if ( drmAddMap( pMga->drmFD, 741fe5e51b7Smrg pMGADRIServer->agpTextures.offset, 742fe5e51b7Smrg pMGADRIServer->agpTextures.size, 743fe5e51b7Smrg DRM_AGP, 0, 744fe5e51b7Smrg &pMGADRIServer->agpTextures.handle ) < 0 ) { 745fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 746fe5e51b7Smrg "[agp] Could not add agpTexture mapping\n" ); 747fe5e51b7Smrg return FALSE; 748fe5e51b7Smrg } 749fe5e51b7Smrg 750fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 751fe5e51b7Smrg "[agp] agpTexture handle = 0x%08x\n", 752fe5e51b7Smrg (unsigned int) pMGADRIServer->agpTextures.handle ); 753fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 754fe5e51b7Smrg "[agp] agpTexture size: %d kb\n", pMGADRIServer->agpTextures.size/1024 ); 755fe5e51b7Smrg 756fe5e51b7Smrg pMGADRIServer->registers.size = MGAIOMAPSIZE; 757fe5e51b7Smrg 758fe5e51b7Smrg if ( drmAddMap( pMga->drmFD, 759fe5e51b7Smrg (drm_handle_t) MGA_IO_ADDRESS(pMga), 760fe5e51b7Smrg pMGADRIServer->registers.size, 761fe5e51b7Smrg DRM_REGISTERS, DRM_READ_ONLY, 762fe5e51b7Smrg &pMGADRIServer->registers.handle ) < 0 ) { 763fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 764fe5e51b7Smrg "[drm] Could not add MMIO registers mapping\n" ); 765fe5e51b7Smrg return FALSE; 766fe5e51b7Smrg } 767fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 768fe5e51b7Smrg "[drm] Registers handle = 0x%08x\n", 769fe5e51b7Smrg (unsigned int) pMGADRIServer->registers.handle ); 770fe5e51b7Smrg 771fe5e51b7Smrg pMGADRIServer->status.size = SAREA_MAX; 772fe5e51b7Smrg 773fe5e51b7Smrg if ( drmAddMap( pMga->drmFD, 0, pMGADRIServer->status.size, 774fe5e51b7Smrg DRM_SHM, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL, 775fe5e51b7Smrg &pMGADRIServer->status.handle ) < 0 ) { 776fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 777fe5e51b7Smrg "[drm] Could not add status page mapping\n" ); 778fe5e51b7Smrg return FALSE; 779fe5e51b7Smrg } 780fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 781fe5e51b7Smrg "[drm] Status handle = 0x%08x\n", 782fe5e51b7Smrg (unsigned int) pMGADRIServer->status.handle ); 783fe5e51b7Smrg } 784fe5e51b7Smrg 785fe5e51b7Smrg return TRUE; 786fe5e51b7Smrg} 787fe5e51b7Smrg 788fe5e51b7Smrgstatic Bool MGADRIKernelInit( ScreenPtr pScreen ) 789fe5e51b7Smrg{ 790fe5e51b7Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 791fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 792fe5e51b7Smrg MGADRIServerPrivatePtr pMGADRIServer = pMga->DRIServerInfo; 793fe5e51b7Smrg drm_mga_init_t init; 794fe5e51b7Smrg int ret; 795fe5e51b7Smrg 796fe5e51b7Smrg 797fe5e51b7Smrg if (!pMga->chip_attribs->dri_capable) { 798fe5e51b7Smrg return FALSE; 799fe5e51b7Smrg } 800fe5e51b7Smrg 801fe5e51b7Smrg memset( &init, 0, sizeof(drm_mga_init_t) ); 802fe5e51b7Smrg 803fe5e51b7Smrg init.func = MGA_INIT_DMA; 804fe5e51b7Smrg init.sarea_priv_offset = sizeof(XF86DRISAREARec); 805fe5e51b7Smrg init.chipset = pMga->chip_attribs->dri_chipset; 806fe5e51b7Smrg init.sgram = !pMga->HasSDRAM; 807fe5e51b7Smrg 808fe5e51b7Smrg init.maccess = pMga->MAccess; 809fe5e51b7Smrg 810fe5e51b7Smrg init.fb_cpp = pScrn->bitsPerPixel / 8; 811fe5e51b7Smrg init.front_offset = pMGADRIServer->frontOffset; 812fe5e51b7Smrg init.front_pitch = pMGADRIServer->frontPitch / init.fb_cpp; 813fe5e51b7Smrg init.back_offset = pMGADRIServer->backOffset; 814fe5e51b7Smrg init.back_pitch = pMGADRIServer->backPitch / init.fb_cpp; 815fe5e51b7Smrg 816fe5e51b7Smrg init.depth_cpp = pScrn->bitsPerPixel / 8; 817fe5e51b7Smrg init.depth_offset = pMGADRIServer->depthOffset; 818fe5e51b7Smrg init.depth_pitch = pMGADRIServer->depthPitch / init.depth_cpp; 819fe5e51b7Smrg 820fe5e51b7Smrg init.texture_offset[0] = pMGADRIServer->textureOffset; 821fe5e51b7Smrg init.texture_size[0] = pMGADRIServer->textureSize; 822fe5e51b7Smrg 823fe5e51b7Smrg init.fb_offset = pMGADRIServer->fb.handle; 824fe5e51b7Smrg init.mmio_offset = pMGADRIServer->registers.handle; 825fe5e51b7Smrg init.status_offset = pMGADRIServer->status.handle; 826fe5e51b7Smrg 827fe5e51b7Smrg init.warp_offset = pMGADRIServer->warp.handle; 828fe5e51b7Smrg init.primary_offset = pMGADRIServer->primary.handle; 829fe5e51b7Smrg init.buffers_offset = pMGADRIServer->buffers.handle; 830fe5e51b7Smrg 831fe5e51b7Smrg init.texture_offset[1] = pMGADRIServer->agpTextures.handle; 832fe5e51b7Smrg init.texture_size[1] = pMGADRIServer->agpTextures.size; 833fe5e51b7Smrg 834fe5e51b7Smrg ret = drmCommandWrite( pMga->drmFD, DRM_MGA_INIT, &init, sizeof(drm_mga_init_t)); 835fe5e51b7Smrg if ( ret < 0 ) { 836fe5e51b7Smrg xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 837fe5e51b7Smrg "[drm] Failed to initialize DMA! (%d)\n", ret ); 838fe5e51b7Smrg return FALSE; 839fe5e51b7Smrg } 840fe5e51b7Smrg 841fe5e51b7Smrg 842fe5e51b7Smrg return TRUE; 843fe5e51b7Smrg} 844fe5e51b7Smrg 845fe5e51b7Smrg/* FIXME: This function uses the DRM to get the IRQ, but the pci_device 846fe5e51b7Smrg * FIXME: structure (PciInfo) already has that information. 847fe5e51b7Smrg */ 848fe5e51b7Smrgstatic void MGADRIIrqInit(MGAPtr pMga, ScreenPtr pScreen) 849fe5e51b7Smrg{ 850fe5e51b7Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 851fe5e51b7Smrg 852fe5e51b7Smrg if (!pMga->irq) { 853fe5e51b7Smrg pMga->irq = drmGetInterruptFromBusID(pMga->drmFD, 854fe5e51b7Smrg#ifdef XSERVER_LIBPCIACCESS 855fe5e51b7Smrg ((pMga->PciInfo->domain << 8) | 856fe5e51b7Smrg pMga->PciInfo->bus), 857fe5e51b7Smrg pMga->PciInfo->dev, 858fe5e51b7Smrg pMga->PciInfo->func 859fe5e51b7Smrg#else 860fe5e51b7Smrg ((pciConfigPtr)pMga->PciInfo->thisCard)->busnum, 861fe5e51b7Smrg ((pciConfigPtr)pMga->PciInfo->thisCard)->devnum, 862fe5e51b7Smrg ((pciConfigPtr)pMga->PciInfo->thisCard)->funcnum 863fe5e51b7Smrg#endif 864fe5e51b7Smrg ); 865fe5e51b7Smrg 866fe5e51b7Smrg if((drmCtlInstHandler(pMga->drmFD, pMga->irq)) != 0) { 867fe5e51b7Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 868fe5e51b7Smrg "[drm] failure adding irq handler, " 869fe5e51b7Smrg "there is a device already using that irq\n" 870fe5e51b7Smrg "[drm] falling back to irq-free operation\n"); 871fe5e51b7Smrg pMga->irq = 0; 872fe5e51b7Smrg } else { 873fe5e51b7Smrg pMga->reg_ien = INREG( MGAREG_IEN ); 874fe5e51b7Smrg } 875fe5e51b7Smrg } 876fe5e51b7Smrg 877fe5e51b7Smrg if (pMga->irq) 878fe5e51b7Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 879fe5e51b7Smrg "[drm] dma control initialized, using IRQ %d\n", 880fe5e51b7Smrg pMga->irq); 881fe5e51b7Smrg} 882fe5e51b7Smrg 883fe5e51b7Smrgstatic Bool MGADRIBuffersInit( ScreenPtr pScreen ) 884fe5e51b7Smrg{ 885fe5e51b7Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 886fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 887fe5e51b7Smrg MGADRIServerPrivatePtr pMGADRIServer = pMga->DRIServerInfo; 888fe5e51b7Smrg 889fe5e51b7Smrg 890fe5e51b7Smrg pMGADRIServer->drmBuffers = drmMapBufs( pMga->drmFD ); 891fe5e51b7Smrg if ( !pMGADRIServer->drmBuffers ) { 892fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 893fe5e51b7Smrg "[drm] Failed to map DMA buffers list\n" ); 894fe5e51b7Smrg return FALSE; 895fe5e51b7Smrg } 896fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 897fe5e51b7Smrg "[drm] Mapped %d DMA buffers\n", 898fe5e51b7Smrg pMGADRIServer->drmBuffers->count ); 899fe5e51b7Smrg 900fe5e51b7Smrg return TRUE; 901fe5e51b7Smrg} 902fe5e51b7Smrg 903fe5e51b7Smrg#ifdef USE_XAA 904fe5e51b7Smrgstatic void MGADRIInitBuffersXAA(WindowPtr pWin, RegionPtr prgn, 905fe5e51b7Smrg CARD32 index) 906fe5e51b7Smrg{ 907fe5e51b7Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 908fe5e51b7Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 909fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 910fe5e51b7Smrg BoxPtr pbox = REGION_RECTS(prgn); 911fe5e51b7Smrg int nbox = REGION_NUM_RECTS(prgn); 912fe5e51b7Smrg XAAInfoRecPtr xaa = pMga->AccelInfoRec; 913fe5e51b7Smrg 914fe5e51b7Smrg CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn); 915fe5e51b7Smrg 916fe5e51b7Smrg xaa->SetupForSolidFill(pScrn, 0, GXcopy, -1); 917fe5e51b7Smrg 918fe5e51b7Smrg while (nbox--) { 919fe5e51b7Smrg MGASelectBuffer(pScrn, MGA_BACK); 920fe5e51b7Smrg xaa->SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, 921fe5e51b7Smrg pbox->x2-pbox->x1, pbox->y2-pbox->y1); 922fe5e51b7Smrg MGASelectBuffer(pScrn, MGA_DEPTH); 923fe5e51b7Smrg xaa->SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, 924fe5e51b7Smrg pbox->x2-pbox->x1, pbox->y2-pbox->y1); 925fe5e51b7Smrg pbox++; 926fe5e51b7Smrg } 927fe5e51b7Smrg 928fe5e51b7Smrg MGASelectBuffer(pScrn, MGA_FRONT); 929fe5e51b7Smrg 930fe5e51b7Smrg pMga->AccelInfoRec->NeedToSync = TRUE; 931fe5e51b7Smrg} 932fe5e51b7Smrg#endif 933fe5e51b7Smrg 934fe5e51b7Smrg#ifdef USE_EXA 935fe5e51b7Smrgstatic void MGADRIInitBuffersEXA(WindowPtr pWin, RegionPtr prgn, 936fe5e51b7Smrg CARD32 index) 937fe5e51b7Smrg{ 938fe5e51b7Smrg /* FIXME */ 939fe5e51b7Smrg} 940fe5e51b7Smrg#endif 941fe5e51b7Smrg 942fe5e51b7Smrg#ifdef USE_XAA 943fe5e51b7Smrg/* 944fe5e51b7Smrg This routine is a modified form of XAADoBitBlt with the calls to 945fe5e51b7Smrg ScreenToScreenBitBlt built in. My routine has the prgnSrc as source 946fe5e51b7Smrg instead of destination. My origin is upside down so the ydir cases 947fe5e51b7Smrg are reversed. 948fe5e51b7Smrg*/ 949fe5e51b7Smrgstatic void MGADRIMoveBuffersXAA(WindowPtr pParent, DDXPointRec ptOldOrg, 950fe5e51b7Smrg RegionPtr prgnSrc, CARD32 index) 951fe5e51b7Smrg{ 952fe5e51b7Smrg ScreenPtr pScreen = pParent->drawable.pScreen; 953fe5e51b7Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 954fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 955fe5e51b7Smrg int nbox; 956fe5e51b7Smrg BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2; 957fe5e51b7Smrg DDXPointPtr pptTmp, pptNew1, pptNew2; 958fe5e51b7Smrg int xdir, ydir; 959fe5e51b7Smrg int dx, dy; 960fe5e51b7Smrg DDXPointPtr pptSrc; 961fe5e51b7Smrg int screenwidth = pScrn->virtualX; 962fe5e51b7Smrg int screenheight = pScrn->virtualY; 963fe5e51b7Smrg XAAInfoRecPtr xaa = pMga->AccelInfoRec; 964fe5e51b7Smrg 965fe5e51b7Smrg CHECK_DMA_QUIESCENT(pMga, pScrn); 966fe5e51b7Smrg 967fe5e51b7Smrg pbox = REGION_RECTS(prgnSrc); 968fe5e51b7Smrg nbox = REGION_NUM_RECTS(prgnSrc); 969fe5e51b7Smrg pboxNew1 = 0; 970fe5e51b7Smrg pptNew1 = 0; 971fe5e51b7Smrg pboxNew2 = 0; 972fe5e51b7Smrg pboxNew2 = 0; 973fe5e51b7Smrg pptSrc = &ptOldOrg; 974fe5e51b7Smrg 975fe5e51b7Smrg dx = pParent->drawable.x - ptOldOrg.x; 976fe5e51b7Smrg dy = pParent->drawable.y - ptOldOrg.y; 977fe5e51b7Smrg 978fe5e51b7Smrg /* If the copy will overlap in Y, reverse the order */ 979fe5e51b7Smrg if (dy>0) { 980fe5e51b7Smrg ydir = -1; 981fe5e51b7Smrg 982fe5e51b7Smrg if (nbox>1) { 983fe5e51b7Smrg /* Keep ordering in each band, reverse order of bands */ 984fe5e51b7Smrg pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); 985fe5e51b7Smrg if (!pboxNew1) return; 986fe5e51b7Smrg pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); 987fe5e51b7Smrg if (!pptNew1) { 988fe5e51b7Smrg DEALLOCATE_LOCAL(pboxNew1); 989fe5e51b7Smrg return; 990fe5e51b7Smrg } 991fe5e51b7Smrg pboxBase = pboxNext = pbox+nbox-1; 992fe5e51b7Smrg while (pboxBase >= pbox) { 993fe5e51b7Smrg while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1)) 994fe5e51b7Smrg pboxNext--; 995fe5e51b7Smrg pboxTmp = pboxNext+1; 996fe5e51b7Smrg pptTmp = pptSrc + (pboxTmp - pbox); 997fe5e51b7Smrg while (pboxTmp <= pboxBase) { 998fe5e51b7Smrg *pboxNew1++ = *pboxTmp++; 999fe5e51b7Smrg *pptNew1++ = *pptTmp++; 1000fe5e51b7Smrg } 1001fe5e51b7Smrg pboxBase = pboxNext; 1002fe5e51b7Smrg } 1003fe5e51b7Smrg pboxNew1 -= nbox; 1004fe5e51b7Smrg pbox = pboxNew1; 1005fe5e51b7Smrg pptNew1 -= nbox; 1006fe5e51b7Smrg pptSrc = pptNew1; 1007fe5e51b7Smrg } 1008fe5e51b7Smrg } else { 1009fe5e51b7Smrg /* No changes required */ 1010fe5e51b7Smrg ydir = 1; 1011fe5e51b7Smrg } 1012fe5e51b7Smrg 1013fe5e51b7Smrg /* If the regions will overlap in X, reverse the order */ 1014fe5e51b7Smrg if (dx>0) { 1015fe5e51b7Smrg xdir = -1; 1016fe5e51b7Smrg 1017fe5e51b7Smrg if (nbox > 1) { 1018fe5e51b7Smrg /*reverse orderof rects in each band */ 1019fe5e51b7Smrg pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); 1020fe5e51b7Smrg pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); 1021fe5e51b7Smrg if (!pboxNew2 || !pptNew2) { 1022fe5e51b7Smrg if (pptNew2) DEALLOCATE_LOCAL(pptNew2); 1023fe5e51b7Smrg if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2); 1024fe5e51b7Smrg if (pboxNew1) { 1025fe5e51b7Smrg DEALLOCATE_LOCAL(pptNew1); 1026fe5e51b7Smrg DEALLOCATE_LOCAL(pboxNew1); 1027fe5e51b7Smrg } 1028fe5e51b7Smrg return; 1029fe5e51b7Smrg } 1030fe5e51b7Smrg pboxBase = pboxNext = pbox; 1031fe5e51b7Smrg while (pboxBase < pbox+nbox) { 1032fe5e51b7Smrg while ((pboxNext < pbox+nbox) && 1033fe5e51b7Smrg (pboxNext->y1 == pboxBase->y1)) 1034fe5e51b7Smrg pboxNext++; 1035fe5e51b7Smrg pboxTmp = pboxNext; 1036fe5e51b7Smrg pptTmp = pptSrc + (pboxTmp - pbox); 1037fe5e51b7Smrg while (pboxTmp != pboxBase) { 1038fe5e51b7Smrg *pboxNew2++ = *--pboxTmp; 1039fe5e51b7Smrg *pptNew2++ = *--pptTmp; 1040fe5e51b7Smrg } 1041fe5e51b7Smrg pboxBase = pboxNext; 1042fe5e51b7Smrg } 1043fe5e51b7Smrg pboxNew2 -= nbox; 1044fe5e51b7Smrg pbox = pboxNew2; 1045fe5e51b7Smrg pptNew2 -= nbox; 1046fe5e51b7Smrg pptSrc = pptNew2; 1047fe5e51b7Smrg } 1048fe5e51b7Smrg } else { 1049fe5e51b7Smrg /* No changes are needed */ 1050fe5e51b7Smrg xdir = 1; 1051fe5e51b7Smrg } 1052fe5e51b7Smrg 1053fe5e51b7Smrg xaa->SetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1); 1054fe5e51b7Smrg for ( ; nbox-- ; pbox++) { 1055fe5e51b7Smrg int x1 = pbox->x1; 1056fe5e51b7Smrg int y1 = pbox->y1; 1057fe5e51b7Smrg int destx = x1 + dx; 1058fe5e51b7Smrg int desty = y1 + dy; 1059fe5e51b7Smrg int w = pbox->x2 - x1 + 1; 1060fe5e51b7Smrg int h = pbox->y2 - y1 + 1; 1061fe5e51b7Smrg 1062fe5e51b7Smrg if ( destx < 0 ) x1 -= destx, w += destx, destx = 0; 1063fe5e51b7Smrg if ( desty < 0 ) y1 -= desty, h += desty, desty = 0; 1064fe5e51b7Smrg if ( destx + w > screenwidth ) w = screenwidth - destx; 1065fe5e51b7Smrg if ( desty + h > screenheight ) h = screenheight - desty; 1066fe5e51b7Smrg if ( w <= 0 ) continue; 1067fe5e51b7Smrg if ( h <= 0 ) continue; 1068fe5e51b7Smrg 1069fe5e51b7Smrg MGASelectBuffer(pScrn, MGA_BACK); 1070fe5e51b7Smrg xaa->SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); 1071fe5e51b7Smrg MGASelectBuffer(pScrn, MGA_DEPTH); 1072fe5e51b7Smrg xaa->SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); 1073fe5e51b7Smrg } 1074fe5e51b7Smrg MGASelectBuffer(pScrn, MGA_FRONT); 1075fe5e51b7Smrg 1076fe5e51b7Smrg if (pboxNew2) { 1077fe5e51b7Smrg DEALLOCATE_LOCAL(pptNew2); 1078fe5e51b7Smrg DEALLOCATE_LOCAL(pboxNew2); 1079fe5e51b7Smrg } 1080fe5e51b7Smrg if (pboxNew1) { 1081fe5e51b7Smrg DEALLOCATE_LOCAL(pptNew1); 1082fe5e51b7Smrg DEALLOCATE_LOCAL(pboxNew1); 1083fe5e51b7Smrg } 1084fe5e51b7Smrg 1085fe5e51b7Smrg pMga->AccelInfoRec->NeedToSync = TRUE; 1086fe5e51b7Smrg 1087fe5e51b7Smrg} 1088fe5e51b7Smrg#endif 1089fe5e51b7Smrg 1090fe5e51b7Smrg#ifdef USE_EXA 1091fe5e51b7Smrgstatic void MGADRIMoveBuffersEXA(WindowPtr pParent, DDXPointRec ptOldOrg, 1092fe5e51b7Smrg RegionPtr prgnSrc, CARD32 index) 1093fe5e51b7Smrg{ 1094fe5e51b7Smrg /* FIXME */ 1095fe5e51b7Smrg} 1096fe5e51b7Smrg#endif 1097fe5e51b7Smrg 1098fe5e51b7SmrgBool MGADRIScreenInit( ScreenPtr pScreen ) 1099fe5e51b7Smrg{ 1100fe5e51b7Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1101fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 1102fe5e51b7Smrg DRIInfoPtr pDRIInfo; 1103fe5e51b7Smrg MGADRIPtr pMGADRI; 1104fe5e51b7Smrg MGADRIServerPrivatePtr pMGADRIServer; 1105fe5e51b7Smrg 1106fe5e51b7Smrg if (!pMga->chip_attribs->dri_capable) { 1107fe5e51b7Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] Direct rendering only supported with G200/G400/G450/G550.\n"); 1108fe5e51b7Smrg return FALSE; 1109fe5e51b7Smrg } 1110fe5e51b7Smrg 1111fe5e51b7Smrg /* Check that the GLX, DRI, and DRM modules have been loaded by testing 1112fe5e51b7Smrg * for canonical symbols in each module. 1113fe5e51b7Smrg */ 1114fe5e51b7Smrg if ( !xf86LoaderCheckSymbol( "GlxSetVisualConfigs" ) ) return FALSE; 1115fe5e51b7Smrg if ( !xf86LoaderCheckSymbol( "drmAvailable" ) ) return FALSE; 1116fe5e51b7Smrg if ( !xf86LoaderCheckSymbol( "DRIQueryVersion" ) ) { 1117fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 1118fe5e51b7Smrg "[dri] MGADRIScreenInit failed (libdri.a too old)\n" ); 1119fe5e51b7Smrg return FALSE; 1120fe5e51b7Smrg } 1121fe5e51b7Smrg 1122fe5e51b7Smrg /* Check the DRI version */ 1123fe5e51b7Smrg { 1124fe5e51b7Smrg int major, minor, patch; 1125fe5e51b7Smrg DRIQueryVersion( &major, &minor, &patch ); 1126fe5e51b7Smrg if ( major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION ) { 1127fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 1128fe5e51b7Smrg "[dri] MGADRIScreenInit failed because of a version mismatch.\n" 1129fe5e51b7Smrg "[dri] libdri version = %d.%d.%d but version %d.%d.x is needed.\n" 1130fe5e51b7Smrg "[dri] Disabling the DRI.\n", 1131fe5e51b7Smrg major, minor, patch, 1132fe5e51b7Smrg DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION ); 1133fe5e51b7Smrg return FALSE; 1134fe5e51b7Smrg } 1135fe5e51b7Smrg } 1136fe5e51b7Smrg 1137fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_INFO, 1138fe5e51b7Smrg "[drm] bpp: %d depth: %d\n", 1139fe5e51b7Smrg pScrn->bitsPerPixel, pScrn->depth ); 1140fe5e51b7Smrg 1141fe5e51b7Smrg if ( (pScrn->bitsPerPixel / 8) != 2 && 1142fe5e51b7Smrg (pScrn->bitsPerPixel / 8) != 4 ) { 1143fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 1144fe5e51b7Smrg "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" ); 1145fe5e51b7Smrg return FALSE; 1146fe5e51b7Smrg } 1147fe5e51b7Smrg 1148fe5e51b7Smrg pDRIInfo = DRICreateInfoRec(); 1149fe5e51b7Smrg if ( !pDRIInfo ) { 1150fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 1151fe5e51b7Smrg "[dri] DRICreateInfoRec() failed\n" ); 1152fe5e51b7Smrg return FALSE; 1153fe5e51b7Smrg } 1154fe5e51b7Smrg pMga->pDRIInfo = pDRIInfo; 1155fe5e51b7Smrg 1156fe5e51b7Smrg pDRIInfo->drmDriverName = MGAKernelDriverName; 1157fe5e51b7Smrg pDRIInfo->clientDriverName = MGAClientDriverName; 1158fe5e51b7Smrg if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { 1159fe5e51b7Smrg pDRIInfo->busIdString = DRICreatePCIBusID(pMga->PciInfo); 1160fe5e51b7Smrg } else { 1161fe5e51b7Smrg pDRIInfo->busIdString = xalloc(64); 1162fe5e51b7Smrg sprintf( pDRIInfo->busIdString, "PCI:%d:%d:%d", 1163fe5e51b7Smrg#ifdef XSERVER_LIBPCIACCESS 1164fe5e51b7Smrg ((pMga->PciInfo->domain << 8) | pMga->PciInfo->bus), 1165fe5e51b7Smrg pMga->PciInfo->dev, pMga->PciInfo->func 1166fe5e51b7Smrg#else 1167fe5e51b7Smrg ((pciConfigPtr)pMga->PciInfo->thisCard)->busnum, 1168fe5e51b7Smrg ((pciConfigPtr)pMga->PciInfo->thisCard)->devnum, 1169fe5e51b7Smrg ((pciConfigPtr)pMga->PciInfo->thisCard)->funcnum 1170fe5e51b7Smrg#endif 1171fe5e51b7Smrg ); 1172fe5e51b7Smrg } 1173fe5e51b7Smrg pDRIInfo->ddxDriverMajorVersion = PACKAGE_VERSION_MAJOR; 1174fe5e51b7Smrg pDRIInfo->ddxDriverMinorVersion = PACKAGE_VERSION_MINOR; 1175fe5e51b7Smrg pDRIInfo->ddxDriverPatchVersion = PACKAGE_VERSION_PATCHLEVEL; 1176fe5e51b7Smrg pDRIInfo->frameBufferPhysicalAddress = (void *) pMga->FbAddress; 1177fe5e51b7Smrg pDRIInfo->frameBufferSize = pMga->FbMapSize; 1178fe5e51b7Smrg pDRIInfo->frameBufferStride = pScrn->displayWidth*(pScrn->bitsPerPixel/8); 1179fe5e51b7Smrg pDRIInfo->ddxDrawableTableEntry = MGA_MAX_DRAWABLES; 1180fe5e51b7Smrg 1181fe5e51b7Smrg pDRIInfo->wrap.ValidateTree = NULL; 1182fe5e51b7Smrg pDRIInfo->wrap.PostValidateTree = NULL; 1183fe5e51b7Smrg 1184fe5e51b7Smrg pDRIInfo->createDummyCtx = TRUE; 1185fe5e51b7Smrg pDRIInfo->createDummyCtxPriv = FALSE; 1186fe5e51b7Smrg 1187fe5e51b7Smrg if ( SAREA_MAX_DRAWABLES < MGA_MAX_DRAWABLES ) { 1188fe5e51b7Smrg pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; 1189fe5e51b7Smrg } else { 1190fe5e51b7Smrg pDRIInfo->maxDrawableTableEntry = MGA_MAX_DRAWABLES; 1191fe5e51b7Smrg } 1192fe5e51b7Smrg 1193fe5e51b7Smrg /* For now the mapping works by using a fixed size defined 1194fe5e51b7Smrg * in the SAREA header. 1195fe5e51b7Smrg */ 1196fe5e51b7Smrg if ( sizeof(XF86DRISAREARec) + sizeof(MGASAREAPrivRec) > SAREA_MAX ) { 1197fe5e51b7Smrg xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 1198fe5e51b7Smrg "[drm] Data does not fit in SAREA\n" ); 1199fe5e51b7Smrg return FALSE; 1200fe5e51b7Smrg } 1201fe5e51b7Smrg 1202fe5e51b7Smrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, 1203fe5e51b7Smrg "[drm] Sarea %d+%d: %d\n", 1204fe5e51b7Smrg (int)sizeof(XF86DRISAREARec), (int)sizeof(MGASAREAPrivRec), 1205fe5e51b7Smrg (int)sizeof(XF86DRISAREARec) + (int)sizeof(MGASAREAPrivRec) ); 1206fe5e51b7Smrg 1207fe5e51b7Smrg pDRIInfo->SAREASize = SAREA_MAX; 1208fe5e51b7Smrg 1209fe5e51b7Smrg pMGADRI = (MGADRIPtr)xcalloc( sizeof(MGADRIRec), 1 ); 1210fe5e51b7Smrg if ( !pMGADRI ) { 1211fe5e51b7Smrg DRIDestroyInfoRec( pMga->pDRIInfo ); 1212fe5e51b7Smrg pMga->pDRIInfo = 0; 1213fe5e51b7Smrg xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 1214fe5e51b7Smrg "[drm] Failed to allocate memory for private record\n" ); 1215fe5e51b7Smrg return FALSE; 1216fe5e51b7Smrg } 1217fe5e51b7Smrg 1218fe5e51b7Smrg pMGADRIServer = (MGADRIServerPrivatePtr) 1219fe5e51b7Smrg xcalloc( sizeof(MGADRIServerPrivateRec), 1 ); 1220fe5e51b7Smrg if ( !pMGADRIServer ) { 1221fe5e51b7Smrg xfree( pMGADRI ); 1222fe5e51b7Smrg DRIDestroyInfoRec( pMga->pDRIInfo ); 1223fe5e51b7Smrg pMga->pDRIInfo = 0; 1224fe5e51b7Smrg xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 1225fe5e51b7Smrg "[drm] Failed to allocate memory for private record\n" ); 1226fe5e51b7Smrg return FALSE; 1227fe5e51b7Smrg } 1228fe5e51b7Smrg pMga->DRIServerInfo = pMGADRIServer; 1229fe5e51b7Smrg 1230fe5e51b7Smrg pDRIInfo->devPrivate = pMGADRI; 1231fe5e51b7Smrg pDRIInfo->devPrivateSize = sizeof(MGADRIRec); 1232fe5e51b7Smrg pDRIInfo->contextSize = sizeof(MGADRIContextRec); 1233fe5e51b7Smrg 1234fe5e51b7Smrg pDRIInfo->CreateContext = MGACreateContext; 1235fe5e51b7Smrg pDRIInfo->DestroyContext = MGADestroyContext; 1236fe5e51b7Smrg if ( xf86IsEntityShared( pScrn->entityList[0] ) 1237fe5e51b7Smrg && pMga->DualHeadEnabled) { 1238fe5e51b7Smrg pDRIInfo->SwapContext = MGADRISwapContextShared; 1239fe5e51b7Smrg } else { 1240fe5e51b7Smrg pDRIInfo->SwapContext = MGADRISwapContext; 1241fe5e51b7Smrg } 1242fe5e51b7Smrg 1243fe5e51b7Smrg#ifdef USE_EXA 1244fe5e51b7Smrg if (pMga->Exa) { 1245fe5e51b7Smrg pDRIInfo->InitBuffers = MGADRIInitBuffersEXA; 1246fe5e51b7Smrg pDRIInfo->MoveBuffers = MGADRIMoveBuffersEXA; 1247fe5e51b7Smrg } else { 1248fe5e51b7Smrg#endif 1249fe5e51b7Smrg#ifdef USE_XAA 1250fe5e51b7Smrg pDRIInfo->InitBuffers = MGADRIInitBuffersXAA; 1251fe5e51b7Smrg pDRIInfo->MoveBuffers = MGADRIMoveBuffersXAA; 1252fe5e51b7Smrg#endif 1253fe5e51b7Smrg#ifdef USE_EXA 1254fe5e51b7Smrg } 1255fe5e51b7Smrg#endif 1256fe5e51b7Smrg 1257fe5e51b7Smrg pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; 1258fe5e51b7Smrg 1259fe5e51b7Smrg if ( !DRIScreenInit( pScreen, pDRIInfo, &pMga->drmFD ) ) { 1260fe5e51b7Smrg xfree( pMGADRIServer ); 1261fe5e51b7Smrg pMga->DRIServerInfo = 0; 1262fe5e51b7Smrg xfree( pDRIInfo->devPrivate ); 1263fe5e51b7Smrg pDRIInfo->devPrivate = 0; 1264fe5e51b7Smrg DRIDestroyInfoRec( pMga->pDRIInfo ); 1265fe5e51b7Smrg pMga->pDRIInfo = 0; 1266fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 1267fe5e51b7Smrg "[drm] DRIScreenInit failed. Disabling DRI.\n" ); 1268fe5e51b7Smrg return FALSE; 1269fe5e51b7Smrg } 1270fe5e51b7Smrg 1271fe5e51b7Smrg /* Check the DRM versioning */ 1272fe5e51b7Smrg { 1273fe5e51b7Smrg drmVersionPtr version; 1274fe5e51b7Smrg 1275fe5e51b7Smrg /* Check the DRM lib version. 1276fe5e51b7Smrg drmGetLibVersion was not supported in version 1.0, so check for 1277fe5e51b7Smrg symbol first to avoid possible crash or hang. 1278fe5e51b7Smrg */ 1279fe5e51b7Smrg if (xf86LoaderCheckSymbol("drmGetLibVersion")) { 1280fe5e51b7Smrg version = drmGetLibVersion(pMga->drmFD); 1281fe5e51b7Smrg } 1282fe5e51b7Smrg else { 1283fe5e51b7Smrg /* drmlib version 1.0.0 didn't have the drmGetLibVersion 1284fe5e51b7Smrg entry point. Fake it by allocating a version record 1285fe5e51b7Smrg via drmGetVersion and changing it to version 1.0.0 1286fe5e51b7Smrg */ 1287fe5e51b7Smrg version = drmGetVersion(pMga->drmFD); 1288fe5e51b7Smrg version->version_major = 1; 1289fe5e51b7Smrg version->version_minor = 0; 1290fe5e51b7Smrg version->version_patchlevel = 0; 1291fe5e51b7Smrg } 1292fe5e51b7Smrg 1293fe5e51b7Smrg if (version) { 1294fe5e51b7Smrg if (version->version_major != 1 || 1295fe5e51b7Smrg version->version_minor < 1) { 1296fe5e51b7Smrg /* incompatible drm library version */ 1297fe5e51b7Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 1298fe5e51b7Smrg "[dri] MGADRIScreenInit failed because of a version mismatch.\n" 1299fe5e51b7Smrg "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n" 1300fe5e51b7Smrg "[dri] Disabling DRI.\n", 1301fe5e51b7Smrg version->version_major, 1302fe5e51b7Smrg version->version_minor, 1303fe5e51b7Smrg version->version_patchlevel); 1304fe5e51b7Smrg drmFreeVersion(version); 1305fe5e51b7Smrg MGADRICloseScreen( pScreen ); /* FIXME: ??? */ 1306fe5e51b7Smrg return FALSE; 1307fe5e51b7Smrg } 1308fe5e51b7Smrg drmFreeVersion(version); 1309fe5e51b7Smrg } 1310fe5e51b7Smrg 1311fe5e51b7Smrg /* Check the MGA DRM version */ 1312fe5e51b7Smrg version = drmGetVersion(pMga->drmFD); 1313fe5e51b7Smrg if ( version ) { 1314fe5e51b7Smrg if ( version->version_major != 3 || 1315fe5e51b7Smrg version->version_minor < 0 ) { 1316fe5e51b7Smrg /* incompatible drm version */ 1317fe5e51b7Smrg xf86DrvMsg( pScreen->myNum, X_ERROR, 1318fe5e51b7Smrg "[dri] MGADRIScreenInit failed because of a version mismatch.\n" 1319fe5e51b7Smrg "[dri] mga.o kernel module version is %d.%d.%d but version 3.0.x is needed.\n" 1320fe5e51b7Smrg "[dri] Disabling DRI.\n", 1321fe5e51b7Smrg version->version_major, 1322fe5e51b7Smrg version->version_minor, 1323fe5e51b7Smrg version->version_patchlevel ); 1324fe5e51b7Smrg drmFreeVersion( version ); 1325fe5e51b7Smrg MGADRICloseScreen( pScreen ); /* FIXME: ??? */ 1326fe5e51b7Smrg return FALSE; 1327fe5e51b7Smrg } 1328fe5e51b7Smrg pMGADRIServer->drm_version_major = version->version_major; 1329fe5e51b7Smrg pMGADRIServer->drm_version_minor = version->version_minor; 1330fe5e51b7Smrg 1331fe5e51b7Smrg drmFreeVersion( version ); 1332fe5e51b7Smrg } 1333fe5e51b7Smrg } 1334fe5e51b7Smrg 1335fe5e51b7Smrg if ( (pMga->bios.host_interface == MGA_HOST_PCI) && 1336fe5e51b7Smrg ((pMGADRIServer->drm_version_minor < 2) || pMga->useOldDmaInit) ) { 1337fe5e51b7Smrg /* PCI cards are supported if the DRM version is at least 3.2 and the 1338fe5e51b7Smrg * user has not explicitly disabled the new DMA init path (i.e., to 1339fe5e51b7Smrg * support old version of the client-side driver that don't use the 1340fe5e51b7Smrg * new features of the 3.2 DRM). 1341fe5e51b7Smrg */ 1342fe5e51b7Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1343fe5e51b7Smrg "[drm] Direct rendering on PCI cards requires DRM version 3.2 or higher\n"); 1344fe5e51b7Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1345fe5e51b7Smrg "[drm] and a recent client-side driver. Also make sure that 'OldDmaInit'\n"); 1346fe5e51b7Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1347fe5e51b7Smrg "[drm] is not selected in xorg.conf.'\n"); 1348fe5e51b7Smrg return FALSE; 1349fe5e51b7Smrg } 1350fe5e51b7Smrg 1351fe5e51b7Smrg 1352fe5e51b7Smrg if ( !MGADRIBootstrapDMA( pScreen ) ) { 1353fe5e51b7Smrg DRICloseScreen( pScreen ); 1354fe5e51b7Smrg return FALSE; 1355fe5e51b7Smrg } 1356fe5e51b7Smrg 1357fe5e51b7Smrg { 1358fe5e51b7Smrg void *scratch_ptr; 1359fe5e51b7Smrg int scratch_int; 1360fe5e51b7Smrg 1361fe5e51b7Smrg DRIGetDeviceInfo(pScreen, &pMGADRIServer->fb.handle, 1362fe5e51b7Smrg &scratch_int, &scratch_int, 1363fe5e51b7Smrg &scratch_int, &scratch_int, 1364fe5e51b7Smrg &scratch_ptr); 1365fe5e51b7Smrg } 1366fe5e51b7Smrg 1367fe5e51b7Smrg if ( !MGAInitVisualConfigs( pScreen ) ) { 1368fe5e51b7Smrg DRICloseScreen( pScreen ); 1369fe5e51b7Smrg return FALSE; 1370fe5e51b7Smrg } 1371fe5e51b7Smrg xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized\n" ); 1372fe5e51b7Smrg 1373fe5e51b7Smrg return TRUE; 1374fe5e51b7Smrg} 1375fe5e51b7Smrg 1376fe5e51b7Smrg 1377fe5e51b7SmrgBool MGADRIFinishScreenInit( ScreenPtr pScreen ) 1378fe5e51b7Smrg{ 1379fe5e51b7Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1380fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 1381fe5e51b7Smrg MGADRIServerPrivatePtr pMGADRIServer = pMga->DRIServerInfo; 1382fe5e51b7Smrg MGADRIPtr pMGADRI; 1383fe5e51b7Smrg int i; 1384fe5e51b7Smrg 1385fe5e51b7Smrg if ( !pMga->pDRIInfo ) 1386fe5e51b7Smrg return FALSE; 1387fe5e51b7Smrg 1388fe5e51b7Smrg pMGADRI = (MGADRIPtr)pMga->pDRIInfo->devPrivate; 1389fe5e51b7Smrg 1390fe5e51b7Smrg pMga->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; 1391fe5e51b7Smrg 1392fe5e51b7Smrg /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit 1393fe5e51b7Smrg * because *DRIKernelInit requires that the hardware lock is held by 1394fe5e51b7Smrg * the X server, and the first time the hardware lock is grabbed is 1395fe5e51b7Smrg * in DRIFinishScreenInit. 1396fe5e51b7Smrg */ 1397fe5e51b7Smrg if ( !DRIFinishScreenInit( pScreen ) ) { 1398fe5e51b7Smrg MGADRICloseScreen( pScreen ); 1399fe5e51b7Smrg return FALSE; 1400fe5e51b7Smrg } 1401fe5e51b7Smrg 1402fe5e51b7Smrg if ( !MGADRIKernelInit( pScreen ) ) { 1403fe5e51b7Smrg MGADRICloseScreen( pScreen ); 1404fe5e51b7Smrg return FALSE; 1405fe5e51b7Smrg } 1406fe5e51b7Smrg 1407fe5e51b7Smrg if ( !MGADRIBuffersInit( pScreen ) ) { 1408fe5e51b7Smrg MGADRICloseScreen( pScreen ); 1409fe5e51b7Smrg return FALSE; 1410fe5e51b7Smrg } 1411fe5e51b7Smrg 1412fe5e51b7Smrg MGADRIIrqInit(pMga, pScreen); 1413fe5e51b7Smrg 1414fe5e51b7Smrg pMGADRI->chipset = pMga->chip_attribs->dri_chipset; 1415fe5e51b7Smrg pMGADRI->width = pScrn->virtualX; 1416fe5e51b7Smrg pMGADRI->height = pScrn->virtualY; 1417fe5e51b7Smrg pMGADRI->cpp = pScrn->bitsPerPixel / 8; 1418fe5e51b7Smrg 1419fe5e51b7Smrg pMGADRI->agpMode = pMga->agpMode; 1420fe5e51b7Smrg 1421fe5e51b7Smrg pMGADRI->frontOffset = pMGADRIServer->frontOffset; 1422fe5e51b7Smrg pMGADRI->frontPitch = pMGADRIServer->frontPitch; 1423fe5e51b7Smrg pMGADRI->backOffset = pMGADRIServer->backOffset; 1424fe5e51b7Smrg pMGADRI->backPitch = pMGADRIServer->backPitch; 1425fe5e51b7Smrg pMGADRI->depthOffset = pMGADRIServer->depthOffset; 1426fe5e51b7Smrg pMGADRI->depthPitch = pMGADRIServer->depthPitch; 1427fe5e51b7Smrg pMGADRI->textureOffset = pMGADRIServer->textureOffset; 1428fe5e51b7Smrg pMGADRI->textureSize = pMGADRIServer->textureSize; 1429fe5e51b7Smrg 1430fe5e51b7Smrg pMGADRI->agpTextureOffset = (unsigned int)pMGADRIServer->agpTextures.handle; 1431fe5e51b7Smrg pMGADRI->agpTextureSize = (unsigned int)pMGADRIServer->agpTextures.size; 1432fe5e51b7Smrg 1433fe5e51b7Smrg pMGADRI->sarea_priv_offset = sizeof(XF86DRISAREARec); 1434fe5e51b7Smrg 1435fe5e51b7Smrg 1436fe5e51b7Smrg /* Newer versions of the client-side driver do not need these if the 1437fe5e51b7Smrg * kernel version is high enough to support interrupt based waiting. 1438fe5e51b7Smrg */ 1439fe5e51b7Smrg 1440fe5e51b7Smrg pMGADRI->registers.handle = pMGADRIServer->registers.handle; 1441fe5e51b7Smrg pMGADRI->registers.size = pMGADRIServer->registers.size; 1442fe5e51b7Smrg pMGADRI->primary.handle = pMGADRIServer->primary.handle; 1443fe5e51b7Smrg pMGADRI->primary.size = pMGADRIServer->primary.size; 1444fe5e51b7Smrg 1445fe5e51b7Smrg 1446fe5e51b7Smrg /* These are no longer used by the client-side DRI driver. They should 1447fe5e51b7Smrg * be removed in the next release (i.e., 6.9 / 7.0). 1448fe5e51b7Smrg */ 1449fe5e51b7Smrg 1450fe5e51b7Smrg pMGADRI->status.handle = pMGADRIServer->status.handle; 1451fe5e51b7Smrg pMGADRI->status.size = pMGADRIServer->status.size; 1452fe5e51b7Smrg pMGADRI->buffers.handle = pMGADRIServer->buffers.handle; 1453fe5e51b7Smrg pMGADRI->buffers.size = pMGADRIServer->buffers.size; 1454fe5e51b7Smrg 1455fe5e51b7Smrg i = mylog2( pMGADRI->textureSize / MGA_NR_TEX_REGIONS ); 1456fe5e51b7Smrg if ( i < MGA_LOG_MIN_TEX_REGION_SIZE ) 1457fe5e51b7Smrg i = MGA_LOG_MIN_TEX_REGION_SIZE; 1458fe5e51b7Smrg 1459fe5e51b7Smrg pMGADRI->logTextureGranularity = i; 1460fe5e51b7Smrg pMGADRI->textureSize = (pMGADRI->textureSize >> i) << i; /* truncate */ 1461fe5e51b7Smrg 1462fe5e51b7Smrg i = mylog2( pMGADRIServer->agpTextures.size / MGA_NR_TEX_REGIONS ); 1463fe5e51b7Smrg if ( i < MGA_LOG_MIN_TEX_REGION_SIZE ) 1464fe5e51b7Smrg i = MGA_LOG_MIN_TEX_REGION_SIZE; 1465fe5e51b7Smrg 1466fe5e51b7Smrg pMGADRI->logAgpTextureGranularity = i; 1467fe5e51b7Smrg 1468fe5e51b7Smrg return TRUE; 1469fe5e51b7Smrg} 1470fe5e51b7Smrg 1471fe5e51b7Smrg 1472fe5e51b7Smrgvoid MGADRICloseScreen( ScreenPtr pScreen ) 1473fe5e51b7Smrg{ 1474fe5e51b7Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1475fe5e51b7Smrg MGAPtr pMga = MGAPTR(pScrn); 1476fe5e51b7Smrg MGADRIServerPrivatePtr pMGADRIServer = pMga->DRIServerInfo; 1477fe5e51b7Smrg drm_mga_init_t init; 1478fe5e51b7Smrg 1479fe5e51b7Smrg if ( pMGADRIServer->drmBuffers ) { 1480fe5e51b7Smrg drmUnmapBufs( pMGADRIServer->drmBuffers ); 1481fe5e51b7Smrg pMGADRIServer->drmBuffers = NULL; 1482fe5e51b7Smrg } 1483fe5e51b7Smrg 1484fe5e51b7Smrg if (pMga->irq) { 1485fe5e51b7Smrg drmCtlUninstHandler(pMga->drmFD); 1486fe5e51b7Smrg pMga->irq = 0; 1487fe5e51b7Smrg pMga->reg_ien = 0; 1488fe5e51b7Smrg } 1489fe5e51b7Smrg 1490fe5e51b7Smrg /* Cleanup DMA */ 1491fe5e51b7Smrg memset( &init, 0, sizeof(drm_mga_init_t) ); 1492fe5e51b7Smrg init.func = MGA_CLEANUP_DMA; 1493fe5e51b7Smrg drmCommandWrite( pMga->drmFD, DRM_MGA_INIT, &init, sizeof(drm_mga_init_t) ); 1494fe5e51b7Smrg 1495fe5e51b7Smrg if ( pMGADRIServer->agp.handle != DRM_AGP_NO_HANDLE ) { 1496fe5e51b7Smrg drmAgpUnbind( pMga->drmFD, pMGADRIServer->agp.handle ); 1497fe5e51b7Smrg drmAgpFree( pMga->drmFD, pMGADRIServer->agp.handle ); 1498fe5e51b7Smrg pMGADRIServer->agp.handle = DRM_AGP_NO_HANDLE; 1499fe5e51b7Smrg drmAgpRelease( pMga->drmFD ); 1500fe5e51b7Smrg } 1501fe5e51b7Smrg 1502fe5e51b7Smrg DRICloseScreen( pScreen ); 1503fe5e51b7Smrg 1504fe5e51b7Smrg if ( pMga->pDRIInfo ) { 1505fe5e51b7Smrg if ( pMga->pDRIInfo->devPrivate ) { 1506fe5e51b7Smrg xfree( pMga->pDRIInfo->devPrivate ); 1507fe5e51b7Smrg pMga->pDRIInfo->devPrivate = 0; 1508fe5e51b7Smrg } 1509fe5e51b7Smrg DRIDestroyInfoRec( pMga->pDRIInfo ); 1510fe5e51b7Smrg pMga->pDRIInfo = 0; 1511fe5e51b7Smrg } 1512fe5e51b7Smrg if ( pMga->DRIServerInfo ) { 1513fe5e51b7Smrg xfree( pMga->DRIServerInfo ); 1514fe5e51b7Smrg pMga->DRIServerInfo = 0; 1515fe5e51b7Smrg } 1516fe5e51b7Smrg if ( pMga->pVisualConfigs ) { 1517fe5e51b7Smrg xfree( pMga->pVisualConfigs ); 1518fe5e51b7Smrg } 1519fe5e51b7Smrg if ( pMga->pVisualConfigsPriv ) { 1520fe5e51b7Smrg xfree( pMga->pVisualConfigsPriv ); 1521fe5e51b7Smrg } 1522fe5e51b7Smrg} 1523