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