Home | History | Annotate | Line # | Download | only in src
      1 /*
      2  * Copyright 2000 ATI Technologies Inc., Markham, Ontario,
      3  *                VA Linux Systems Inc., Fremont, California.
      4  *
      5  * All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining
      8  * a copy of this software and associated documentation files (the
      9  * "Software"), to deal in the Software without restriction, including
     10  * without limitation on the rights to use, copy, modify, merge,
     11  * publish, distribute, sublicense, and/or sell copies of the Software,
     12  * and to permit persons to whom the Software is furnished to do so,
     13  * subject to the following conditions:
     14  *
     15  * The above copyright notice and this permission notice (including the
     16  * next paragraph) shall be included in all copies or substantial
     17  * portions of the Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     20  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     22  * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
     23  * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     24  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     26  * DEALINGS IN THE SOFTWARE.
     27  */
     28 
     29 #ifdef HAVE_CONFIG_H
     30 #include "config.h"
     31 #endif
     32 
     33 /*
     34  * Authors:
     35  *   Kevin E. Martin <martin (at) xfree86.org>
     36  *   Rickard E. Faith <faith (at) valinux.com>
     37  *   Gareth Hughes <gareth (at) valinux.com>
     38  *
     39  */
     40 
     41 #include <string.h>
     42 #include <stdio.h>
     43 #include <sys/types.h>
     44 #include <sys/mman.h>
     45 
     46 				/* Driver data structures */
     47 #include "radeon.h"
     48 #include "radeon_video.h"
     49 #include "radeon_reg.h"
     50 #include "r600_reg.h"
     51 #include "radeon_macros.h"
     52 #include "radeon_drm.h"
     53 #include "radeon_dri.h"
     54 #include "radeon_version.h"
     55 
     56 
     57 				/* X and server generic header files */
     58 #include "xf86.h"
     59 #include "windowstr.h"
     60 
     61 				/* GLX/DRI/DRM definitions */
     62 #define _XF86DRI_SERVER_
     63 #include "GL/glxtokens.h"
     64 #include "sarea.h"
     65 
     66 #include "atipciids.h"
     67 
     68 static size_t radeon_drm_page_size;
     69 
     70 #define RADEON_MAX_DRAWABLES 256
     71 
     72 extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
     73 				void **configprivs);
     74 
     75 static void RADEONDRITransitionTo2d(ScreenPtr pScreen);
     76 static void RADEONDRITransitionTo3d(ScreenPtr pScreen);
     77 static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen);
     78 static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen);
     79 
     80 #ifdef DAMAGE
     81 static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, RegionPtr pReg);
     82 
     83 #if (DRIINFO_MAJOR_VERSION > 5 ||		\
     84      (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1))
     85 static void RADEONDRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num);
     86 #endif
     87 #endif
     88 
     89 /* Initialize the visual configs that are supported by the hardware.
     90  * These are combined with the visual configs that the indirect
     91  * rendering core supports, and the intersection is exported to the
     92  * client.
     93  */
     94 static Bool RADEONInitVisualConfigs(ScreenPtr pScreen)
     95 {
     96     ScrnInfoPtr          pScrn             = xf86ScreenToScrn(pScreen);
     97     RADEONInfoPtr        info              = RADEONPTR(pScrn);
     98     int                  numConfigs        = 0;
     99     __GLXvisualConfig   *pConfigs          = 0;
    100     RADEONConfigPrivPtr  pRADEONConfigs    = 0;
    101     RADEONConfigPrivPtr *pRADEONConfigPtrs = 0;
    102     int                  i, accum, stencil, db, use_db;
    103 
    104     use_db = !info->dri->noBackBuffer ? 1 : 0;
    105 
    106     switch (info->CurrentLayout.pixel_code) {
    107     case 8:  /* 8bpp mode is not support */
    108     case 15: /* FIXME */
    109     case 24: /* FIXME */
    110 	xf86DrvMsg(pScreen->myNum, X_ERROR,
    111 		   "[dri] RADEONInitVisualConfigs failed "
    112 		   "(depth %d not supported).  "
    113 		   "Disabling DRI.\n", info->CurrentLayout.pixel_code);
    114 	return FALSE;
    115 
    116 #define RADEON_USE_ACCUM   1
    117 #define RADEON_USE_STENCIL 1
    118 
    119     case 16:
    120 	numConfigs = 1;
    121 	if (RADEON_USE_ACCUM)   numConfigs *= 2;
    122 	if (RADEON_USE_STENCIL) numConfigs *= 2;
    123 	if (use_db)             numConfigs *= 2;
    124 
    125 	if (!(pConfigs
    126 	      = (__GLXvisualConfig *)calloc(sizeof(__GLXvisualConfig),
    127 					    numConfigs))) {
    128 	    return FALSE;
    129 	}
    130 	if (!(pRADEONConfigs
    131 	      = (RADEONConfigPrivPtr)calloc(sizeof(RADEONConfigPrivRec),
    132 					    numConfigs))) {
    133 	    free(pConfigs);
    134 	    return FALSE;
    135 	}
    136 	if (!(pRADEONConfigPtrs
    137 	      = (RADEONConfigPrivPtr *)calloc(sizeof(RADEONConfigPrivPtr),
    138 					      numConfigs))) {
    139 	    free(pConfigs);
    140 	    free(pRADEONConfigs);
    141 	    return FALSE;
    142 	}
    143 
    144 	i = 0;
    145 	for (db = use_db; db >= 0; db--) {
    146 	  for (accum = 0; accum <= RADEON_USE_ACCUM; accum++) {
    147 	    for (stencil = 0; stencil <= RADEON_USE_STENCIL; stencil++) {
    148 		pRADEONConfigPtrs[i] = &pRADEONConfigs[i];
    149 
    150 		pConfigs[i].vid                = (VisualID)(-1);
    151 		pConfigs[i].class              = -1;
    152 		pConfigs[i].rgba               = TRUE;
    153 		pConfigs[i].redSize            = 5;
    154 		pConfigs[i].greenSize          = 6;
    155 		pConfigs[i].blueSize           = 5;
    156 		pConfigs[i].alphaSize          = 0;
    157 		pConfigs[i].redMask            = 0x0000F800;
    158 		pConfigs[i].greenMask          = 0x000007E0;
    159 		pConfigs[i].blueMask           = 0x0000001F;
    160 		pConfigs[i].alphaMask          = 0x00000000;
    161 		if (accum) { /* Simulated in software */
    162 		    pConfigs[i].accumRedSize   = 16;
    163 		    pConfigs[i].accumGreenSize = 16;
    164 		    pConfigs[i].accumBlueSize  = 16;
    165 		    pConfigs[i].accumAlphaSize = 0;
    166 		} else {
    167 		    pConfigs[i].accumRedSize   = 0;
    168 		    pConfigs[i].accumGreenSize = 0;
    169 		    pConfigs[i].accumBlueSize  = 0;
    170 		    pConfigs[i].accumAlphaSize = 0;
    171 		}
    172 		if (db)
    173 		    pConfigs[i].doubleBuffer   = TRUE;
    174 		else
    175 		    pConfigs[i].doubleBuffer   = FALSE;
    176 		pConfigs[i].stereo             = FALSE;
    177 		pConfigs[i].bufferSize         = 16;
    178 		pConfigs[i].depthSize          = info->dri->depthBits;
    179 		if (pConfigs[i].depthSize == 24 ? (RADEON_USE_STENCIL - stencil)
    180 						: stencil) {
    181 		    pConfigs[i].stencilSize    = 8;
    182 		} else {
    183 		    pConfigs[i].stencilSize    = 0;
    184 		}
    185 		pConfigs[i].auxBuffers         = 0;
    186 		pConfigs[i].level              = 0;
    187 		if (accum ||
    188 		    (pConfigs[i].stencilSize && pConfigs[i].depthSize == 16)) {
    189 		   pConfigs[i].visualRating    = GLX_SLOW_CONFIG;
    190 		} else {
    191 		   pConfigs[i].visualRating    = GLX_NONE;
    192 		}
    193 		pConfigs[i].transparentPixel   = GLX_NONE;
    194 		pConfigs[i].transparentRed     = 0;
    195 		pConfigs[i].transparentGreen   = 0;
    196 		pConfigs[i].transparentBlue    = 0;
    197 		pConfigs[i].transparentAlpha   = 0;
    198 		pConfigs[i].transparentIndex   = 0;
    199 		i++;
    200 	    }
    201 	  }
    202 	}
    203 	break;
    204 
    205     case 32:
    206 	numConfigs = 1;
    207 	if (RADEON_USE_ACCUM)   numConfigs *= 2;
    208 	if (RADEON_USE_STENCIL) numConfigs *= 2;
    209 	if (use_db)             numConfigs *= 2;
    210 
    211 	if (!(pConfigs
    212 	      = (__GLXvisualConfig *)calloc(sizeof(__GLXvisualConfig),
    213 					    numConfigs))) {
    214 	    return FALSE;
    215 	}
    216 	if (!(pRADEONConfigs
    217 	      = (RADEONConfigPrivPtr)calloc(sizeof(RADEONConfigPrivRec),
    218 					    numConfigs))) {
    219 	    free(pConfigs);
    220 	    return FALSE;
    221 	}
    222 	if (!(pRADEONConfigPtrs
    223 	      = (RADEONConfigPrivPtr *)calloc(sizeof(RADEONConfigPrivPtr),
    224 					      numConfigs))) {
    225 	    free(pConfigs);
    226 	    free(pRADEONConfigs);
    227 	    return FALSE;
    228 	}
    229 
    230 	i = 0;
    231 	for (db = use_db; db >= 0; db--) {
    232 	  for (accum = 0; accum <= RADEON_USE_ACCUM; accum++) {
    233 	    for (stencil = 0; stencil <= RADEON_USE_STENCIL; stencil++) {
    234 		pRADEONConfigPtrs[i] = &pRADEONConfigs[i];
    235 
    236 		pConfigs[i].vid                = (VisualID)(-1);
    237 		pConfigs[i].class              = -1;
    238 		pConfigs[i].rgba               = TRUE;
    239 		pConfigs[i].redSize            = 8;
    240 		pConfigs[i].greenSize          = 8;
    241 		pConfigs[i].blueSize           = 8;
    242 		pConfigs[i].alphaSize          = 8;
    243 		pConfigs[i].redMask            = 0x00FF0000;
    244 		pConfigs[i].greenMask          = 0x0000FF00;
    245 		pConfigs[i].blueMask           = 0x000000FF;
    246 		pConfigs[i].alphaMask          = 0xFF000000;
    247 		if (accum) { /* Simulated in software */
    248 		    pConfigs[i].accumRedSize   = 16;
    249 		    pConfigs[i].accumGreenSize = 16;
    250 		    pConfigs[i].accumBlueSize  = 16;
    251 		    pConfigs[i].accumAlphaSize = 16;
    252 		} else {
    253 		    pConfigs[i].accumRedSize   = 0;
    254 		    pConfigs[i].accumGreenSize = 0;
    255 		    pConfigs[i].accumBlueSize  = 0;
    256 		    pConfigs[i].accumAlphaSize = 0;
    257 		}
    258 		if (db)
    259 		    pConfigs[i].doubleBuffer   = TRUE;
    260 		else
    261 		    pConfigs[i].doubleBuffer   = FALSE;
    262 		pConfigs[i].stereo             = FALSE;
    263 		pConfigs[i].bufferSize         = 32;
    264 		pConfigs[i].depthSize          = info->dri->depthBits;
    265 		if (pConfigs[i].depthSize == 24 ? (RADEON_USE_STENCIL - stencil)
    266 						: stencil) {
    267 		    pConfigs[i].stencilSize    = 8;
    268 		} else {
    269 		    pConfigs[i].stencilSize    = 0;
    270 		}
    271 		pConfigs[i].auxBuffers         = 0;
    272 		pConfigs[i].level              = 0;
    273 		if (accum ||
    274 		    (pConfigs[i].stencilSize && pConfigs[i].depthSize == 16)) {
    275 		   pConfigs[i].visualRating    = GLX_SLOW_CONFIG;
    276 		} else {
    277 		   pConfigs[i].visualRating    = GLX_NONE;
    278 		}
    279 		pConfigs[i].transparentPixel   = GLX_NONE;
    280 		pConfigs[i].transparentRed     = 0;
    281 		pConfigs[i].transparentGreen   = 0;
    282 		pConfigs[i].transparentBlue    = 0;
    283 		pConfigs[i].transparentAlpha   = 0;
    284 		pConfigs[i].transparentIndex   = 0;
    285 		i++;
    286 	    }
    287 	  }
    288 	}
    289 	break;
    290     }
    291 
    292     info->dri->numVisualConfigs   = numConfigs;
    293     info->dri->pVisualConfigs     = pConfigs;
    294     info->dri->pVisualConfigsPriv = pRADEONConfigs;
    295     GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pRADEONConfigPtrs);
    296     return TRUE;
    297 }
    298 
    299 /* Create the Radeon-specific context information */
    300 static Bool RADEONCreateContext(ScreenPtr pScreen, VisualPtr visual,
    301 				drm_context_t hwContext, void *pVisualConfigPriv,
    302 				DRIContextType contextStore)
    303 {
    304     return TRUE;
    305 }
    306 
    307 /* Destroy the Radeon-specific context information */
    308 static void RADEONDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
    309 				 DRIContextType contextStore)
    310 {
    311 }
    312 
    313 /* Called when the X server is woken up to allow the last client's
    314  * context to be saved and the X server's context to be loaded.  This is
    315  * not necessary for the Radeon since the client detects when it's
    316  * context is not currently loaded and then load's it itself.  Since the
    317  * registers to start and stop the CP are privileged, only the X server
    318  * can start/stop the engine.
    319  */
    320 static void RADEONEnterServer(ScreenPtr pScreen)
    321 {
    322     ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
    323     RADEONInfoPtr  info  = RADEONPTR(pScrn);
    324     drm_radeon_sarea_t *pSAREAPriv;
    325 
    326 
    327     RADEON_MARK_SYNC(info, pScrn);
    328 
    329     pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
    330     if (pSAREAPriv->ctx_owner != DRIGetContext(pScrn->pScreen)) {
    331 	info->accel_state->XInited3D = FALSE;
    332 	info->cp->needCacheFlush = (info->ChipFamily >= CHIP_FAMILY_R300);
    333     }
    334 
    335 #ifdef DAMAGE
    336     if (!info->dri->pDamage && info->dri->allowPageFlip) {
    337 	PixmapPtr pPix  = pScreen->GetScreenPixmap(pScreen);
    338 	info->dri->pDamage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
    339 					  pScreen, pPix);
    340 
    341 	if (info->dri->pDamage == NULL) {
    342 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
    343 		       "No screen damage record, page flipping disabled\n");
    344 	    info->dri->allowPageFlip = 0;
    345 	} else {
    346 	    DamageRegister(&pPix->drawable, info->dri->pDamage);
    347 
    348 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    349 		       "Damage tracking initialized for page flipping\n");
    350 	}
    351     }
    352 #endif
    353 }
    354 
    355 /* Called when the X server goes to sleep to allow the X server's
    356  * context to be saved and the last client's context to be loaded.  This
    357  * is not necessary for the Radeon since the client detects when it's
    358  * context is not currently loaded and then load's it itself.  Since the
    359  * registers to start and stop the CP are privileged, only the X server
    360  * can start/stop the engine.
    361  */
    362 static void RADEONLeaveServer(ScreenPtr pScreen)
    363 {
    364     ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
    365     RADEONInfoPtr  info  = RADEONPTR(pScrn);
    366     RING_LOCALS;
    367 
    368 #ifdef DAMAGE
    369     if (info->dri->pDamage) {
    370 	RegionPtr pDamageReg = DamageRegion(info->dri->pDamage);
    371 	int nrects = pDamageReg ? REGION_NUM_RECTS(pDamageReg) : 0;
    372 
    373 	if (nrects) {
    374 	    RADEONDRIRefreshArea(pScrn, pDamageReg);
    375 	}
    376     }
    377 #endif
    378 
    379     /* The CP is always running, but if we've generated any CP commands
    380      * we must flush them to the kernel module now.
    381      */
    382     RADEONCP_RELEASE(pScrn, info);
    383 
    384 #ifdef USE_EXA
    385     info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
    386 #endif
    387 }
    388 
    389 /* Contexts can be swapped by the X server if necessary.  This callback
    390  * is currently only used to perform any functions necessary when
    391  * entering or leaving the X server, and in the future might not be
    392  * necessary.
    393  */
    394 static void RADEONDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
    395 				 DRIContextType oldContextType,
    396 				 void *oldContext,
    397 				 DRIContextType newContextType,
    398 				 void *newContext)
    399 {
    400     if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) &&
    401 	(newContextType==DRI_2D_CONTEXT)) { /* Entering from Wakeup */
    402 	RADEONEnterServer(pScreen);
    403     }
    404 
    405     if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) &&
    406 	(newContextType==DRI_2D_CONTEXT)) { /* Exiting from Block Handler */
    407 	RADEONLeaveServer(pScreen);
    408     }
    409 }
    410 
    411 #ifdef USE_XAA
    412 
    413 /* The Radeon has depth tiling on all the time. Rely on surface regs to
    414  * translate the addresses (only works if allowColorTiling is true).
    415  */
    416 
    417 /* 16-bit depth buffer functions */
    418 #define WRITE_DEPTH16(_x, _y, d)					\
    419     *(uint16_t *)(pointer)(buf + 2*(_x + _y*info->dri->frontPitch)) = (d)
    420 
    421 #define READ_DEPTH16(d, _x, _y)						\
    422     (d) = *(uint16_t *)(pointer)(buf + 2*(_x + _y*info->dri->frontPitch))
    423 
    424 /* 32-bit depth buffer (stencil and depth simultaneously) functions */
    425 #define WRITE_DEPTHSTENCIL32(_x, _y, d)					\
    426     *(uint32_t *)(pointer)(buf + 4*(_x + _y*info->dri->frontPitch)) = (d)
    427 
    428 #define READ_DEPTHSTENCIL32(d, _x, _y)					\
    429     (d) = *(uint32_t *)(pointer)(buf + 4*(_x + _y*info->dri->frontPitch))
    430 
    431 /* Screen to screen copy of data in the depth buffer */
    432 static void RADEONScreenToScreenCopyDepth(ScrnInfoPtr pScrn,
    433 					  int xa, int ya,
    434 					  int xb, int yb,
    435 					  int w, int h)
    436 {
    437     RADEONInfoPtr  info = RADEONPTR(pScrn);
    438     unsigned char *buf  = info->FB + info->dri->depthOffset;
    439     int            xstart, xend, xdir;
    440     int            ystart, yend, ydir;
    441     int            x, y, d;
    442 
    443     if (xa < xb) xdir = -1, xstart = w-1, xend = 0;
    444     else         xdir =  1, xstart = 0,   xend = w-1;
    445 
    446     if (ya < yb) ydir = -1, ystart = h-1, yend = 0;
    447     else         ydir =  1, ystart = 0,   yend = h-1;
    448 
    449     switch (pScrn->bitsPerPixel) {
    450     case 16:
    451 	for (x = xstart; x != xend; x += xdir) {
    452 	    for (y = ystart; y != yend; y += ydir) {
    453 		READ_DEPTH16(d, xa+x, ya+y);
    454 		WRITE_DEPTH16(xb+x, yb+y, d);
    455 	    }
    456 	}
    457 	break;
    458 
    459     case 32:
    460 	for (x = xstart; x != xend; x += xdir) {
    461 	    for (y = ystart; y != yend; y += ydir) {
    462 		READ_DEPTHSTENCIL32(d, xa+x, ya+y);
    463 		WRITE_DEPTHSTENCIL32(xb+x, yb+y, d);
    464 	    }
    465 	}
    466 	break;
    467 
    468     default:
    469 	break;
    470     }
    471 }
    472 
    473 #endif /* USE_XAA */
    474 
    475 /* Initialize the state of the back and depth buffers */
    476 static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx)
    477 {
    478    /* NOOP.  There's no need for the 2d driver to be clearing buffers
    479     * for the 3d client.  It knows how to do that on its own.
    480     */
    481 }
    482 
    483 /* Copy the back and depth buffers when the X server moves a window.
    484  *
    485  * This routine is a modified form of XAADoBitBlt with the calls to
    486  * ScreenToScreenBitBlt built in. My routine has the prgnSrc as source
    487  * instead of destination. My origin is upside down so the ydir cases
    488  * are reversed.
    489  */
    490 static void RADEONDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
    491 				 RegionPtr prgnSrc, CARD32 indx)
    492 {
    493 #ifdef USE_XAA
    494     ScreenPtr      pScreen  = pParent->drawable.pScreen;
    495     ScrnInfoPtr    pScrn    = xf86ScreenToScrn(pScreen);
    496     RADEONInfoPtr  info     = RADEONPTR(pScrn);
    497 
    498     BoxPtr         pboxTmp, pboxNext, pboxBase;
    499     DDXPointPtr    pptTmp;
    500     int            xdir, ydir;
    501 
    502     int            screenwidth = pScrn->virtualX;
    503     int            screenheight = pScrn->virtualY;
    504 
    505     BoxPtr         pbox     = REGION_RECTS(prgnSrc);
    506     int            nbox     = REGION_NUM_RECTS(prgnSrc);
    507 
    508     BoxPtr         pboxNew1 = NULL;
    509     BoxPtr         pboxNew2 = NULL;
    510     DDXPointPtr    pptNew1  = NULL;
    511     DDXPointPtr    pptNew2  = NULL;
    512     DDXPointPtr    pptSrc   = &ptOldOrg;
    513 
    514     int            dx       = pParent->drawable.x - ptOldOrg.x;
    515     int            dy       = pParent->drawable.y - ptOldOrg.y;
    516 
    517     /* XXX: Fix in EXA case. */
    518     if (info->useEXA)
    519 	return;
    520 
    521     /* If the copy will overlap in Y, reverse the order */
    522     if (dy > 0) {
    523 	ydir = -1;
    524 
    525 	if (nbox > 1) {
    526 	    /* Keep ordering in each band, reverse order of bands */
    527 	    pboxNew1 = (BoxPtr)malloc(sizeof(BoxRec)*nbox);
    528 	    if (!pboxNew1) return;
    529 
    530 	    pptNew1 = (DDXPointPtr)malloc(sizeof(DDXPointRec)*nbox);
    531 	    if (!pptNew1) {
    532 		free(pboxNew1);
    533 		return;
    534 	    }
    535 
    536 	    pboxBase = pboxNext = pbox+nbox-1;
    537 
    538 	    while (pboxBase >= pbox) {
    539 		while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))
    540 		    pboxNext--;
    541 
    542 		pboxTmp = pboxNext+1;
    543 		pptTmp  = pptSrc + (pboxTmp - pbox);
    544 
    545 		while (pboxTmp <= pboxBase) {
    546 		    *pboxNew1++ = *pboxTmp++;
    547 		    *pptNew1++  = *pptTmp++;
    548 		}
    549 
    550 		pboxBase = pboxNext;
    551 	    }
    552 
    553 	    pboxNew1 -= nbox;
    554 	    pbox      = pboxNew1;
    555 	    pptNew1  -= nbox;
    556 	    pptSrc    = pptNew1;
    557 	}
    558     } else {
    559 	/* No changes required */
    560 	ydir = 1;
    561     }
    562 
    563     /* If the regions will overlap in X, reverse the order */
    564     if (dx > 0) {
    565 	xdir = -1;
    566 
    567 	if (nbox > 1) {
    568 	    /* reverse order of rects in each band */
    569 	    pboxNew2 = (BoxPtr)malloc(sizeof(BoxRec)*nbox);
    570 	    pptNew2  = (DDXPointPtr)malloc(sizeof(DDXPointRec)*nbox);
    571 
    572 	    if (!pboxNew2 || !pptNew2) {
    573 		free(pptNew2);
    574 		free(pboxNew2);
    575 		free(pptNew1);
    576 		free(pboxNew1);
    577 		return;
    578 	    }
    579 
    580 	    pboxBase = pboxNext = pbox;
    581 
    582 	    while (pboxBase < pbox+nbox) {
    583 		while ((pboxNext < pbox+nbox)
    584 		       && (pboxNext->y1 == pboxBase->y1))
    585 		    pboxNext++;
    586 
    587 		pboxTmp = pboxNext;
    588 		pptTmp  = pptSrc + (pboxTmp - pbox);
    589 
    590 		while (pboxTmp != pboxBase) {
    591 		    *pboxNew2++ = *--pboxTmp;
    592 		    *pptNew2++  = *--pptTmp;
    593 		}
    594 
    595 		pboxBase = pboxNext;
    596 	    }
    597 
    598 	    pboxNew2 -= nbox;
    599 	    pbox      = pboxNew2;
    600 	    pptNew2  -= nbox;
    601 	    pptSrc    = pptNew2;
    602 	}
    603     } else {
    604 	/* No changes are needed */
    605 	xdir = 1;
    606     }
    607 
    608     /* pretty much a hack. */
    609     info->accel_state->dst_pitch_offset = info->dri->backPitchOffset;
    610     if (info->tilingEnabled)
    611        info->accel_state->dst_pitch_offset |= RADEON_DST_TILE_MACRO;
    612 
    613     (*info->accel_state->accel->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy,
    614 							    (uint32_t)(-1), -1);
    615 
    616     for (; nbox-- ; pbox++) {
    617 	int  xa    = pbox->x1;
    618 	int  ya    = pbox->y1;
    619 	int  destx = xa + dx;
    620 	int  desty = ya + dy;
    621 	int  w     = pbox->x2 - xa + 1;
    622 	int  h     = pbox->y2 - ya + 1;
    623 
    624 	if (destx < 0)                xa -= destx, w += destx, destx = 0;
    625 	if (desty < 0)                ya -= desty, h += desty, desty = 0;
    626 	if (destx + w > screenwidth)  w = screenwidth  - destx;
    627 	if (desty + h > screenheight) h = screenheight - desty;
    628 
    629 	if (w <= 0) continue;
    630 	if (h <= 0) continue;
    631 
    632 	(*info->accel_state->accel->SubsequentScreenToScreenCopy)(pScrn,
    633 								  xa, ya,
    634 								  destx, desty,
    635 								  w, h);
    636 
    637 	if (info->dri->depthMoves) {
    638 	    RADEONScreenToScreenCopyDepth(pScrn,
    639 					  xa, ya,
    640 					  destx, desty,
    641 					  w, h);
    642 	}
    643     }
    644 
    645     info->accel_state->dst_pitch_offset = info->dri->frontPitchOffset;;
    646 
    647     free(pptNew2);
    648     free(pboxNew2);
    649     free(pptNew1);
    650     free(pboxNew1);
    651 
    652     info->accel_state->accel->NeedToSync = TRUE;
    653 #endif /* USE_XAA */
    654 }
    655 
    656 static void RADEONDRIInitGARTValues(RADEONInfoPtr info)
    657 {
    658     int            s, l;
    659 
    660     info->dri->gartOffset = 0;
    661 
    662 				/* Initialize the CP ring buffer data */
    663     info->dri->ringStart       = info->dri->gartOffset;
    664     info->dri->ringMapSize     = info->dri->ringSize*1024*1024 + radeon_drm_page_size;
    665     info->dri->ringSizeLog2QW  = RADEONMinBits(info->dri->ringSize*1024*1024/8)-1;
    666 
    667     info->dri->ringReadOffset  = info->dri->ringStart + info->dri->ringMapSize;
    668     info->dri->ringReadMapSize = radeon_drm_page_size;
    669 
    670 				/* Reserve space for vertex/indirect buffers */
    671     info->dri->bufStart        = info->dri->ringReadOffset + info->dri->ringReadMapSize;
    672     info->dri->bufMapSize      = info->dri->bufSize*1024*1024;
    673 
    674 				/* Reserve the rest for GART textures */
    675     info->dri->gartTexStart     = info->dri->bufStart + info->dri->bufMapSize;
    676     s = (info->dri->gartSize*1024*1024 - info->dri->gartTexStart);
    677     l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
    678     if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
    679     info->dri->gartTexMapSize   = (s >> l) << l;
    680     info->dri->log2GARTTexGran  = l;
    681 }
    682 
    683 /* AGP Mode Quirk List - Certain hostbridge/gfx-card combos don't work with
    684  * the standard AGPMode settings, so we detect and handle these
    685  * on a case-by-base basis with quirks.  To see if an AGPMode is valid, test
    686  * it by setting Option "AGPMode" "1" (or "2", or "4", or "8"). */
    687 typedef struct {
    688     unsigned int hostbridgeVendor;
    689     unsigned int hostbridgeDevice;
    690     unsigned int chipVendor;
    691     unsigned int chipDevice;
    692     unsigned int subsysVendor;
    693     unsigned int subsysDevice;
    694     unsigned int defaultMode;
    695 } radeon_agpmode_quirk, *radeon_agpmode_quirk_ptr;
    696 
    697 /* Keep sorted by hostbridge vendor and device */
    698 static radeon_agpmode_quirk radeon_agpmode_quirk_list[] = {
    699 
    700     /* Intel E7505 Memory Controller Hub / RV350 AR [Radeon 9600XT] Needs AGPMode 4 (deb #515326) */
    701     { PCI_VENDOR_INTEL,0x2550,  PCI_VENDOR_ATI,0x4152,  0x1458,0x4038,           4 },
    702     /* Intel 82865G/PE/P DRAM Controller/Host-Hub / Mobility 9800 Needs AGPMode 4 (deb #462590) */
    703     { PCI_VENDOR_INTEL,0x2570,  PCI_VENDOR_ATI,0x4a4e,  PCI_VENDOR_DELL,0x5106,  4 },
    704     /* Intel 82865G/PE/P DRAM Controller/Host-Hub / RV280 [Radeon 9200 SE] Needs AGPMode 4 (lp #300304) */
    705     { PCI_VENDOR_INTEL,0x2570,  PCI_VENDOR_ATI,0x5964,  0x148c,0x2073,           4 },
    706     /* Intel 82855PM host bridge / Mobility M7 LW Needs AGPMode 4 (lp: #353996) */
    707     { PCI_VENDOR_INTEL,0x3340,  PCI_VENDOR_ATI,0x4c57, PCI_VENDOR_IBM,0x0530,    4 },
    708     /* Intel 82855PM Processor to I/O Controller / Mobility M6 LY Needs AGPMode 1 (deb #467235) */
    709     { PCI_VENDOR_INTEL,0x3340,  PCI_VENDOR_ATI,0x4c59,  PCI_VENDOR_IBM,0x052f,   1 },
    710     /* Intel 82855PM host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #195051) */
    711     { PCI_VENDOR_INTEL,0x3340,  PCI_VENDOR_ATI,0x4e50,  PCI_VENDOR_IBM,0x0550,   1 },
    712     /* Intel 82855PM host bridge / FireGL Mobility T2 RV350 Needs AGPMode 2 (fdo #20647) */
    713     { PCI_VENDOR_INTEL,0x3340,  PCI_VENDOR_ATI,0x4e54,  PCI_VENDOR_IBM,0x054f,   2 },
    714     /* Intel 82855PM host bridge / Mobility M9+ / VaioPCG-V505DX Needs AGPMode 2 (fdo #17928) */
    715     { PCI_VENDOR_INTEL,0x3340,  PCI_VENDOR_ATI,0x5c61,  PCI_VENDOR_SONY,0x816b,  2 },
    716     /* Intel 82855PM Processor to I/O Controller / Mobility M9+ Needs AGPMode 8 (phoronix forum) */
    717     { PCI_VENDOR_INTEL,0x3340,  PCI_VENDOR_ATI,0x5c61,  PCI_VENDOR_SONY,0x8195,  8 },
    718     /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/
    719     { PCI_VENDOR_INTEL,0x3575,  PCI_VENDOR_ATI,0x4c59,  PCI_VENDOR_DELL,0x00e3,  2 },
    720     /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */
    721     { PCI_VENDOR_INTEL,0x3580,  PCI_VENDOR_ATI,0x4c66,  PCI_VENDOR_DELL,0x0149,  1 },
    722     /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */
    723     { PCI_VENDOR_INTEL,0x3580,  PCI_VENDOR_ATI,0x4e50,  0x1025,0x0061,           1 },
    724     /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #203007) */
    725     { PCI_VENDOR_INTEL,0x3580,  PCI_VENDOR_ATI,0x4e50,  0x1025,0x0064,           1 },
    726     /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #141551) */
    727     { PCI_VENDOR_INTEL,0x3580,  PCI_VENDOR_ATI,0x4e50,  PCI_VENDOR_ASUS,0x1942,  1 },
    728     /* Intel 82852/82855 host bridge / Mobility 9600/9700 Needs AGPMode 1 (deb #510208) */
    729     { PCI_VENDOR_INTEL,0x3580,  PCI_VENDOR_ATI,0x4e50,  0x10cf,0x127f,           1 },
    730     /* Intel 82443BX/ZX/DX Host bridge / RV280 [Radeon 9200] Needs AGPMode 1 (lp #370205) */
    731     { PCI_VENDOR_INTEL,0x7190,  PCI_VENDOR_ATI,0x5961,  0x174b,0x7c13,           1 },
    732 
    733     /* Ali Corp M1671 Super P4 Northbridge / Mobility M6 LY Needs AGPMode 1 (lp #146303)*/
    734     { 0x10b9,0x1671,           PCI_VENDOR_ATI,0x4c59,   0x103c,0x0027,           1 },
    735 
    736     /* SiS Host Bridge 655 / R420 [Radeon X800] Needs AGPMode 4 (lp #371296) */
    737     { 0x1039,0x0655,            PCI_VENDOR_ATI,0x4a4b,  PCI_VENDOR_ATI,0x4422,   4 },
    738     /* SiS Host Bridge / RV280 Needs AGPMode 4 */
    739     { 0x1039,0x0741,            PCI_VENDOR_ATI,0x5964,  0x148c,0x2073,           4 },
    740 
    741     /* ASRock K7VT4A+ AGP 8x / ATI Radeon 9250 AGP Needs AGPMode 4 (lp #133192) */
    742     { 0x1849,0x3189,            PCI_VENDOR_ATI,0x5960,  0x1787,0x5960,           4 },
    743 
    744     /* VIA K8M800 Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 4 (fdo #12544) */
    745     { PCI_VENDOR_VIA,0x0204,    PCI_VENDOR_ATI,0x5960,  0x17af,0x2020,           4 },
    746     /* VIA KT880 Host Bridge / RV350 [Radeon 9550] Needs AGPMode 4 (fdo #19981) */
    747     { PCI_VENDOR_VIA,0x0269,    PCI_VENDOR_ATI,0x4153,  PCI_VENDOR_ASUS,0x003c,  4 },
    748     /* VIA VT8363 Host Bridge / R200 QL [Radeon 8500] Needs AGPMode 2 (lp #141551) */
    749     { PCI_VENDOR_VIA,0x0305,    PCI_VENDOR_ATI,0x514c,  PCI_VENDOR_ATI,0x013a,   2 },
    750     /* VIA VT82C693A Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 2 (deb #515512) */
    751     { PCI_VENDOR_VIA,0x0691,    PCI_VENDOR_ATI,0x5960,  PCI_VENDOR_ASUS,0x004c,  2 },
    752     /* VIA VT82C693A Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 2 */
    753     { PCI_VENDOR_VIA,0x0691,    PCI_VENDOR_ATI,0x5960,  PCI_VENDOR_ASUS,0x0054,  2 },
    754     /* VIA VT8377 Host Bridge / R200 QM [Radeon 9100] Needs AGPMode 4 (deb #461144) */
    755     { PCI_VENDOR_VIA,0x3189,    PCI_VENDOR_ATI,0x514d,  0x174b,0x7149,           4 },
    756     /* VIA VT8377 Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 4 (lp #312693) */
    757     { PCI_VENDOR_VIA,0x3189,    PCI_VENDOR_ATI,0x5960,  0x1462,0x0380,           4 },
    758     /* VIA VT8377 Host Bridge / RV280 Needs AGPMode 4 (ati ML) */
    759     { PCI_VENDOR_VIA,0x3189,    PCI_VENDOR_ATI,0x5964,  0x148c,0x2073,           4 },
    760     /* VIA VT8377 Host Bridge / RV280 Needs AGPMode 4 (fdo #12544) */
    761     { PCI_VENDOR_VIA,0x3189,    PCI_VENDOR_ATI,0x5964,  PCI_VENDOR_ASUS,0xc008,  4 },
    762     /* VIA VT8377 Host Bridge / RV280 Needs AGPMode 4 (deb #545040) */
    763     { PCI_VENDOR_VIA,0x3189,    PCI_VENDOR_ATI,0x5960,  PCI_VENDOR_ASUS,0x004c,  4 },
    764 
    765     /* ATI Host Bridge / RV280 [M9+] Needs AGPMode 1 (phoronix forum) */
    766     { PCI_VENDOR_ATI,0xcbb2,    PCI_VENDOR_ATI,0x5c61,  PCI_VENDOR_SONY,0x8175,  1 },
    767 
    768     /* HP Host Bridge / R300 [FireGL X1] Needs AGPMode 2 (fdo #7770) */
    769     { PCI_VENDOR_HP,0x122e,    PCI_VENDOR_ATI,0x4e47,  PCI_VENDOR_ATI,0x0152,    2 },
    770 
    771     /* nVidia Host Bridge / R420 [X800 Pro] Needs AGPMode 4 (fdo #22726) */
    772     { 0x10de,0x00e1,           PCI_VENDOR_ATI,0x4a49,  PCI_VENDOR_ATI,0x0002,    4 },
    773 
    774     { 0, 0, 0, 0, 0, 0, 0 },
    775 };
    776 
    777 /* Set AGP transfer mode according to requests and constraints */
    778 static Bool RADEONSetAgpMode(RADEONInfoPtr info, ScreenPtr pScreen)
    779 {
    780     unsigned char *RADEONMMIO = info->MMIO;
    781     unsigned long mode   = drmAgpGetMode(info->dri->drmFD);	/* Default mode */
    782     unsigned int  vendor = drmAgpVendorId(info->dri->drmFD);
    783     unsigned int  device = drmAgpDeviceId(info->dri->drmFD);
    784 
    785     if (info->ChipFamily < CHIP_FAMILY_R600) {
    786 	/* ignore agp 3.0 mode bit from the chip as it's buggy on some cards with
    787 	   pcie-agp rialto bridge chip - use the one from bridge which must match */
    788 	uint32_t agp_status = (INREG(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode;
    789 	Bool is_v3 = (agp_status & RADEON_AGPv3_MODE);
    790 	unsigned int defaultMode;
    791 	MessageType from;
    792 
    793 	if (is_v3) {
    794 	    defaultMode = (agp_status & RADEON_AGPv3_8X_MODE) ? 8 : 4;
    795 	} else {
    796 	    if (agp_status & RADEON_AGP_4X_MODE) defaultMode = 4;
    797 	    else if (agp_status & RADEON_AGP_2X_MODE) defaultMode = 2;
    798 	    else defaultMode = 1;
    799 	}
    800 
    801 	/* Apply AGPMode Quirks */
    802 	radeon_agpmode_quirk_ptr p = radeon_agpmode_quirk_list;
    803 	while (p && p->chipDevice != 0) {
    804 	    if (vendor == p->hostbridgeVendor &&
    805 		device == p->hostbridgeDevice &&
    806 		PCI_DEV_VENDOR_ID(info->PciInfo) == p->chipVendor &&
    807 		PCI_DEV_DEVICE_ID(info->PciInfo) == p->chipDevice &&
    808 		PCI_SUB_VENDOR_ID(info->PciInfo) == p->subsysVendor &&
    809 		PCI_SUB_DEVICE_ID(info->PciInfo) == p->subsysDevice)
    810 	    {
    811 		defaultMode = p->defaultMode;
    812 	    }
    813 	    ++p;
    814 	}
    815 
    816 	from = X_DEFAULT;
    817 
    818 	if (xf86GetOptValInteger(info->Options, OPTION_AGP_MODE, &info->dri->agpMode)) {
    819 	    if ((info->dri->agpMode < (is_v3 ? 4 : 1)) ||
    820 		(info->dri->agpMode > (is_v3 ? 8 : 4)) ||
    821 		(info->dri->agpMode & (info->dri->agpMode - 1))) {
    822 		xf86DrvMsg(pScreen->myNum, X_ERROR,
    823 			   "Illegal AGP Mode: %d (valid values: %s), leaving at "
    824 			   "%dx\n", info->dri->agpMode, is_v3 ? "4, 8" : "1, 2, 4",
    825 			   defaultMode);
    826 		info->dri->agpMode = defaultMode;
    827 	    } else
    828 		from = X_CONFIG;
    829 	} else
    830 	    info->dri->agpMode = defaultMode;
    831 
    832 	xf86DrvMsg(pScreen->myNum, from, "Using AGP %dx\n", info->dri->agpMode);
    833 
    834 	mode &= ~RADEON_AGP_MODE_MASK;
    835 	if (is_v3) {
    836 	    /* only set one mode bit for AGPv3 */
    837 	    switch (info->dri->agpMode) {
    838 	    case 8:          mode |= RADEON_AGPv3_8X_MODE; break;
    839 	    case 4: default: mode |= RADEON_AGPv3_4X_MODE;
    840 	    }
    841 	    /*TODO: need to take care of other bits valid for v3 mode
    842 	     *      currently these bits are not used in all tested cards.
    843 	     */
    844 	} else {
    845 	    switch (info->dri->agpMode) {
    846 	    case 4:          mode |= RADEON_AGP_4X_MODE;
    847 	    case 2:          mode |= RADEON_AGP_2X_MODE;
    848 	    case 1: default: mode |= RADEON_AGP_1X_MODE;
    849 	    }
    850 	}
    851 
    852 	/* AGP Fast Writes.
    853 	 * TODO: take into account that certain agp modes don't support fast
    854 	 * writes at all */
    855 	mode &= ~RADEON_AGP_FW_MODE; /* Disable per default */
    856 	if (xf86ReturnOptValBool(info->Options, OPTION_AGP_FW, FALSE)) {
    857 	    xf86DrvMsg(pScreen->myNum, X_WARNING,
    858 		       "WARNING: Using the AGPFastWrite option is not recommended.\n");
    859 	    xf86Msg(X_NONE, "\tThis option does not provide much of a noticable speed"
    860 		    " boost, while it\n\twill probably hard lock your machine."
    861 		    " All bets are off!\n");
    862 
    863 	    /* Black list some host/AGP bridges. */
    864 	    if ((vendor == PCI_VENDOR_AMD) && (device == PCI_CHIP_AMD761))
    865 		xf86DrvMsg(pScreen->myNum, X_PROBED, "Ignoring AGPFastWrite option "
    866 			   "for the AMD 761 northbridge.\n");
    867 	    else {
    868 		xf86DrvMsg(pScreen->myNum, X_CONFIG, "Enabling AGP Fast Writes.\n");
    869 		mode |= RADEON_AGP_FW_MODE;
    870 	    }
    871 	} /* Don't mention this otherwise, so that people don't get funny ideas */
    872     } else
    873 	info->dri->agpMode = 8; /* doesn't matter at this point */
    874 
    875     xf86DrvMsg(pScreen->myNum, X_INFO,
    876 	       "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x 0x%04x/0x%04x]\n",
    877 	       mode, vendor, device,
    878 	       PCI_DEV_VENDOR_ID(info->PciInfo),
    879 	       PCI_DEV_DEVICE_ID(info->PciInfo),
    880 	       PCI_SUB_VENDOR_ID(info->PciInfo),
    881 	       PCI_SUB_DEVICE_ID(info->PciInfo));
    882 
    883     if (drmAgpEnable(info->dri->drmFD, mode) < 0) {
    884 	xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n");
    885 	drmAgpRelease(info->dri->drmFD);
    886 	return FALSE;
    887     }
    888 
    889     /* Workaround for some hardware bugs */
    890     if (info->ChipFamily < CHIP_FAMILY_R200)
    891 	OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000);
    892 
    893 				/* Modify the mode if the default mode
    894 				 * is not appropriate for this
    895 				 * particular combination of graphics
    896 				 * card and AGP chipset.
    897 				 */
    898 
    899     return TRUE;
    900 }
    901 
    902 /* Initialize Radeon's AGP registers */
    903 static void RADEONSetAgpBase(RADEONInfoPtr info, ScreenPtr pScreen)
    904 {
    905     ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
    906     unsigned char *RADEONMMIO = info->MMIO;
    907 
    908     if (info->ChipFamily >= CHIP_FAMILY_R600)
    909 	return;
    910 
    911     /* drm already does this, so we can probably remove this.
    912      * agp_base_2 ?
    913      */
    914     if (info->ChipFamily == CHIP_FAMILY_RV515)
    915 	OUTMC(pScrn, RV515_MC_AGP_BASE, drmAgpBase(info->dri->drmFD));
    916     else if ((info->ChipFamily >= CHIP_FAMILY_R520) &&
    917 	     (info->ChipFamily <= CHIP_FAMILY_RV570))
    918 	OUTMC(pScrn, R520_MC_AGP_BASE, drmAgpBase(info->dri->drmFD));
    919     else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
    920 	     (info->ChipFamily == CHIP_FAMILY_RS740))
    921 	OUTMC(pScrn, RS690_MC_AGP_BASE, drmAgpBase(info->dri->drmFD));
    922     else if (info->ChipFamily < CHIP_FAMILY_RV515)
    923 	OUTREG(RADEON_AGP_BASE, drmAgpBase(info->dri->drmFD));
    924 }
    925 
    926 /* Initialize the AGP state.  Request memory for use in AGP space, and
    927  * initialize the Radeon registers to point to that memory.
    928  */
    929 static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
    930 {
    931     int            ret;
    932 
    933     if (drmAgpAcquire(info->dri->drmFD) < 0) {
    934 	xf86DrvMsg(pScreen->myNum, X_WARNING, "[agp] AGP not available\n");
    935 	return FALSE;
    936     }
    937 
    938     if (!RADEONSetAgpMode(info, pScreen))
    939 	return FALSE;
    940 
    941     RADEONDRIInitGARTValues(info);
    942 
    943     if ((ret = drmAgpAlloc(info->dri->drmFD, info->dri->gartSize*1024*1024, 0, NULL,
    944 			   &info->dri->agpMemHandle)) < 0) {
    945 	xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret);
    946 	drmAgpRelease(info->dri->drmFD);
    947 	return FALSE;
    948     }
    949     xf86DrvMsg(pScreen->myNum, X_INFO,
    950 	       "[agp] %d kB allocated with handle 0x%08x\n",
    951 	       info->dri->gartSize*1024,
    952 	       (unsigned int)info->dri->agpMemHandle);
    953 
    954     if (drmAgpBind(info->dri->drmFD,
    955 		   info->dri->agpMemHandle, info->dri->gartOffset) < 0) {
    956 	xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not bind\n");
    957 	drmAgpFree(info->dri->drmFD, info->dri->agpMemHandle);
    958 	drmAgpRelease(info->dri->drmFD);
    959 	return FALSE;
    960     }
    961 
    962     if (drmAddMap(info->dri->drmFD, info->dri->ringStart, info->dri->ringMapSize,
    963 		  DRM_AGP, DRM_READ_ONLY, &info->dri->ringHandle) < 0) {
    964 	xf86DrvMsg(pScreen->myNum, X_ERROR,
    965 		   "[agp] Could not add ring mapping\n");
    966 	return FALSE;
    967     }
    968     xf86DrvMsg(pScreen->myNum, X_INFO,
    969 	       "[agp] ring handle = 0x%08x\n",
    970 	       (unsigned int)info->dri->ringHandle);
    971 
    972     if (drmMap(info->dri->drmFD, info->dri->ringHandle, info->dri->ringMapSize,
    973 	       &info->dri->ring) < 0) {
    974 	xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not map ring\n");
    975 	return FALSE;
    976     }
    977     xf86DrvMsg(pScreen->myNum, X_INFO,
    978 	       "[agp] Ring mapped at 0x%08lx\n",
    979 	       (unsigned long)info->dri->ring);
    980 
    981     if (drmAddMap(info->dri->drmFD, info->dri->ringReadOffset, info->dri->ringReadMapSize,
    982 		  DRM_AGP, DRM_READ_ONLY, &info->dri->ringReadPtrHandle) < 0) {
    983 	xf86DrvMsg(pScreen->myNum, X_ERROR,
    984 		   "[agp] Could not add ring read ptr mapping\n");
    985 	return FALSE;
    986     }
    987     xf86DrvMsg(pScreen->myNum, X_INFO,
    988  	       "[agp] ring read ptr handle = 0x%08x\n",
    989 	       (unsigned int)info->dri->ringReadPtrHandle);
    990 
    991     if (drmMap(info->dri->drmFD, info->dri->ringReadPtrHandle, info->dri->ringReadMapSize,
    992 	       &info->dri->ringReadPtr) < 0) {
    993 	xf86DrvMsg(pScreen->myNum, X_ERROR,
    994 		   "[agp] Could not map ring read ptr\n");
    995 	return FALSE;
    996     }
    997     xf86DrvMsg(pScreen->myNum, X_INFO,
    998 	       "[agp] Ring read ptr mapped at 0x%08lx\n",
    999 	       (unsigned long)info->dri->ringReadPtr);
   1000 
   1001     if (drmAddMap(info->dri->drmFD, info->dri->bufStart, info->dri->bufMapSize,
   1002 		  DRM_AGP, 0, &info->dri->bufHandle) < 0) {
   1003 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1004 		   "[agp] Could not add vertex/indirect buffers mapping\n");
   1005 	return FALSE;
   1006     }
   1007     xf86DrvMsg(pScreen->myNum, X_INFO,
   1008  	       "[agp] vertex/indirect buffers handle = 0x%08x\n",
   1009 	       (unsigned int)info->dri->bufHandle);
   1010 
   1011     if (drmMap(info->dri->drmFD, info->dri->bufHandle, info->dri->bufMapSize,
   1012 	       &info->dri->buf) < 0) {
   1013 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1014 		   "[agp] Could not map vertex/indirect buffers\n");
   1015 	return FALSE;
   1016     }
   1017     xf86DrvMsg(pScreen->myNum, X_INFO,
   1018 	       "[agp] Vertex/indirect buffers mapped at 0x%08lx\n",
   1019 	       (unsigned long)info->dri->buf);
   1020 
   1021     if (drmAddMap(info->dri->drmFD, info->dri->gartTexStart, info->dri->gartTexMapSize,
   1022 		  DRM_AGP, 0, &info->dri->gartTexHandle) < 0) {
   1023 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1024 		   "[agp] Could not add GART texture map mapping\n");
   1025 	return FALSE;
   1026     }
   1027     xf86DrvMsg(pScreen->myNum, X_INFO,
   1028  	       "[agp] GART texture map handle = 0x%08x\n",
   1029 	       (unsigned int)info->dri->gartTexHandle);
   1030 
   1031     if (drmMap(info->dri->drmFD, info->dri->gartTexHandle, info->dri->gartTexMapSize,
   1032 	       &info->dri->gartTex) < 0) {
   1033 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1034 		   "[agp] Could not map GART texture map\n");
   1035 	return FALSE;
   1036     }
   1037     xf86DrvMsg(pScreen->myNum, X_INFO,
   1038 	       "[agp] GART Texture map mapped at 0x%08lx\n",
   1039 	       (unsigned long)info->dri->gartTex);
   1040 
   1041     RADEONSetAgpBase(info, pScreen);
   1042 
   1043     return TRUE;
   1044 }
   1045 
   1046 /* Initialize the PCI GART state.  Request memory for use in PCI space,
   1047  * and initialize the Radeon registers to point to that memory.
   1048  */
   1049 static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen)
   1050 {
   1051     int  ret;
   1052     int  flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL;
   1053 
   1054     ret = drmScatterGatherAlloc(info->dri->drmFD, info->dri->gartSize*1024*1024,
   1055 				&info->dri->pciMemHandle);
   1056     if (ret < 0) {
   1057 	xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Out of memory (%d)\n", ret);
   1058 	return FALSE;
   1059     }
   1060     xf86DrvMsg(pScreen->myNum, X_INFO,
   1061 	       "[pci] %d kB allocated with handle 0x%08lx\n",
   1062 	       info->dri->gartSize*1024, info->dri->pciMemHandle);
   1063 
   1064     RADEONDRIInitGARTValues(info);
   1065 
   1066     if (drmAddMap(info->dri->drmFD, info->dri->ringStart, info->dri->ringMapSize,
   1067 		  DRM_SCATTER_GATHER, flags, &info->dri->ringHandle) < 0) {
   1068 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1069 		   "[pci] Could not add ring mapping\n");
   1070 	return FALSE;
   1071     }
   1072     xf86DrvMsg(pScreen->myNum, X_INFO,
   1073 	       "[pci] ring handle = 0x%08lx, size = 0x%08x\n", info->dri->ringHandle, info->dri->ringMapSize);
   1074 
   1075     if ((ret = drmMap(info->dri->drmFD, info->dri->ringHandle, info->dri->ringMapSize,
   1076 	       &info->dri->ring)) < 0) {
   1077 	xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map ring: ret %d\n", ret);
   1078 	return FALSE;
   1079     }
   1080     xf86DrvMsg(pScreen->myNum, X_INFO,
   1081 	       "[pci] Ring mapped at 0x%08lx\n",
   1082 	       (unsigned long)info->dri->ring);
   1083     xf86DrvMsg(pScreen->myNum, X_INFO,
   1084 	       "[pci] Ring contents 0x%08lx\n",
   1085 	       *(unsigned long *)(pointer)info->dri->ring);
   1086 
   1087     if (drmAddMap(info->dri->drmFD, info->dri->ringReadOffset, info->dri->ringReadMapSize,
   1088 		  DRM_SCATTER_GATHER, flags, &info->dri->ringReadPtrHandle) < 0) {
   1089 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1090 		   "[pci] Could not add ring read ptr mapping\n");
   1091 	return FALSE;
   1092     }
   1093     xf86DrvMsg(pScreen->myNum, X_INFO,
   1094  	       "[pci] ring read ptr handle = 0x%08lx\n",
   1095 	       info->dri->ringReadPtrHandle);
   1096 
   1097     if (drmMap(info->dri->drmFD, info->dri->ringReadPtrHandle, info->dri->ringReadMapSize,
   1098 	       &info->dri->ringReadPtr) < 0) {
   1099 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1100 		   "[pci] Could not map ring read ptr\n");
   1101 	return FALSE;
   1102     }
   1103     xf86DrvMsg(pScreen->myNum, X_INFO,
   1104 	       "[pci] Ring read ptr mapped at 0x%08lx\n",
   1105 	       (unsigned long)info->dri->ringReadPtr);
   1106     xf86DrvMsg(pScreen->myNum, X_INFO,
   1107 	       "[pci] Ring read ptr contents 0x%08lx\n",
   1108 	       *(unsigned long *)(pointer)info->dri->ringReadPtr);
   1109 
   1110     if (drmAddMap(info->dri->drmFD, info->dri->bufStart, info->dri->bufMapSize,
   1111 		  DRM_SCATTER_GATHER, 0, &info->dri->bufHandle) < 0) {
   1112 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1113 		   "[pci] Could not add vertex/indirect buffers mapping\n");
   1114 	return FALSE;
   1115     }
   1116     xf86DrvMsg(pScreen->myNum, X_INFO,
   1117  	       "[pci] vertex/indirect buffers handle = 0x%08lx\n",
   1118 	       info->dri->bufHandle);
   1119 
   1120     if (drmMap(info->dri->drmFD, info->dri->bufHandle, info->dri->bufMapSize,
   1121 	       &info->dri->buf) < 0) {
   1122 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1123 		   "[pci] Could not map vertex/indirect buffers\n");
   1124 	return FALSE;
   1125     }
   1126     xf86DrvMsg(pScreen->myNum, X_INFO,
   1127 	       "[pci] Vertex/indirect buffers mapped at 0x%08lx\n",
   1128 	       (unsigned long)info->dri->buf);
   1129     xf86DrvMsg(pScreen->myNum, X_INFO,
   1130 	       "[pci] Vertex/indirect buffers contents 0x%08lx\n",
   1131 	       *(unsigned long *)(pointer)info->dri->buf);
   1132 
   1133     if (drmAddMap(info->dri->drmFD, info->dri->gartTexStart, info->dri->gartTexMapSize,
   1134 		  DRM_SCATTER_GATHER, 0, &info->dri->gartTexHandle) < 0) {
   1135 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1136 		   "[pci] Could not add GART texture map mapping\n");
   1137 	return FALSE;
   1138     }
   1139     xf86DrvMsg(pScreen->myNum, X_INFO,
   1140  	       "[pci] GART texture map handle = 0x%08lx\n",
   1141 	       info->dri->gartTexHandle);
   1142 
   1143     if (drmMap(info->dri->drmFD, info->dri->gartTexHandle, info->dri->gartTexMapSize,
   1144 	       &info->dri->gartTex) < 0) {
   1145 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1146 		   "[pci] Could not map GART texture map\n");
   1147 	return FALSE;
   1148     }
   1149     xf86DrvMsg(pScreen->myNum, X_INFO,
   1150 	       "[pci] GART Texture map mapped at 0x%08lx\n",
   1151 	       (unsigned long)info->dri->gartTex);
   1152 
   1153     return TRUE;
   1154 }
   1155 
   1156 /* Add a map for the MMIO registers that will be accessed by any
   1157  * DRI-based clients.
   1158  */
   1159 static Bool RADEONDRIMapInit(RADEONInfoPtr info, ScreenPtr pScreen)
   1160 {
   1161 				/* Map registers */
   1162     info->dri->registerSize = info->MMIOSize;
   1163     if (drmAddMap(info->dri->drmFD, info->MMIOAddr, info->dri->registerSize,
   1164 		  DRM_REGISTERS, DRM_READ_ONLY, &info->dri->registerHandle) < 0) {
   1165 	return FALSE;
   1166     }
   1167     xf86DrvMsg(pScreen->myNum, X_INFO,
   1168 	       "[drm] register handle = 0x%08lx\n", info->dri->registerHandle);
   1169 
   1170     return TRUE;
   1171 }
   1172 
   1173 /* Initialize the kernel data structures */
   1174 static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen)
   1175 {
   1176     ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
   1177     int            cpp   = info->CurrentLayout.pixel_bytes;
   1178     drm_radeon_init_t  drmInfo;
   1179 
   1180     memset(&drmInfo, 0, sizeof(drm_radeon_init_t));
   1181     if ( info->ChipFamily >= CHIP_FAMILY_R600 )
   1182 	drmInfo.func             = RADEON_INIT_R600_CP;
   1183     else if ( info->ChipFamily >= CHIP_FAMILY_R300 )
   1184 	drmInfo.func             = RADEON_INIT_R300_CP;
   1185     else if ( info->ChipFamily >= CHIP_FAMILY_R200 )
   1186 	drmInfo.func		= RADEON_INIT_R200_CP;
   1187     else
   1188 	drmInfo.func		= RADEON_INIT_CP;
   1189 
   1190     drmInfo.sarea_priv_offset   = sizeof(XF86DRISAREARec);
   1191     drmInfo.is_pci              = (info->cardType!=CARD_AGP);
   1192     drmInfo.cp_mode             = RADEON_CSQ_PRIBM_INDBM;
   1193     drmInfo.gart_size           = info->dri->gartSize*1024*1024;
   1194     drmInfo.ring_size           = info->dri->ringSize*1024*1024;
   1195     drmInfo.usec_timeout        = info->cp->CPusecTimeout;
   1196 
   1197     drmInfo.fb_bpp              = info->CurrentLayout.pixel_code;
   1198     drmInfo.depth_bpp           = (info->dri->depthBits - 8) * 2;
   1199 
   1200     drmInfo.front_offset        = info->dri->frontOffset;
   1201     drmInfo.front_pitch         = info->dri->frontPitch * cpp;
   1202     drmInfo.back_offset         = info->dri->backOffset;
   1203     drmInfo.back_pitch          = info->dri->backPitch * cpp;
   1204     drmInfo.depth_offset        = info->dri->depthOffset;
   1205     drmInfo.depth_pitch         = info->dri->depthPitch * drmInfo.depth_bpp / 8;
   1206 
   1207     drmInfo.fb_offset           = info->dri->fbHandle;
   1208     drmInfo.mmio_offset         = info->dri->registerHandle;
   1209     drmInfo.ring_offset         = info->dri->ringHandle;
   1210     drmInfo.ring_rptr_offset    = info->dri->ringReadPtrHandle;
   1211     drmInfo.buffers_offset      = info->dri->bufHandle;
   1212     drmInfo.gart_textures_offset= info->dri->gartTexHandle;
   1213 
   1214     if (drmCommandWrite(info->dri->drmFD, DRM_RADEON_CP_INIT,
   1215 			&drmInfo, sizeof(drm_radeon_init_t)) < 0)
   1216 	return FALSE;
   1217 
   1218     /* DRM_RADEON_CP_INIT does an engine reset, which resets some engine
   1219      * registers back to their default values, so we need to restore
   1220      * those engine register here.
   1221      */
   1222     if (info->ChipFamily < CHIP_FAMILY_R600)
   1223 	RADEONEngineRestore(pScrn);
   1224 
   1225     return TRUE;
   1226 }
   1227 
   1228 static void RADEONDRIGartHeapInit(RADEONInfoPtr info, ScreenPtr pScreen)
   1229 {
   1230     drm_radeon_mem_init_heap_t drmHeap;
   1231 
   1232     /* Start up the simple memory manager for GART space */
   1233     drmHeap.region = RADEON_MEM_REGION_GART;
   1234     drmHeap.start  = 0;
   1235     drmHeap.size   = info->dri->gartTexMapSize;
   1236 
   1237     if (drmCommandWrite(info->dri->drmFD, DRM_RADEON_INIT_HEAP,
   1238 			&drmHeap, sizeof(drmHeap))) {
   1239 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1240 		   "[drm] Failed to initialize GART heap manager\n");
   1241     } else {
   1242 	xf86DrvMsg(pScreen->myNum, X_INFO,
   1243 		   "[drm] Initialized kernel GART heap manager, %d\n",
   1244 		   info->dri->gartTexMapSize);
   1245     }
   1246 }
   1247 
   1248 /* Add a map for the vertex buffers that will be accessed by any
   1249  * DRI-based clients.
   1250  */
   1251 static Bool RADEONDRIBufInit(RADEONInfoPtr info, ScreenPtr pScreen)
   1252 {
   1253 				/* Initialize vertex buffers */
   1254     info->dri->bufNumBufs = drmAddBufs(info->dri->drmFD,
   1255 				       info->dri->bufMapSize / RADEON_BUFFER_SIZE,
   1256 				       RADEON_BUFFER_SIZE,
   1257 				       (info->cardType!=CARD_AGP) ? DRM_SG_BUFFER : DRM_AGP_BUFFER,
   1258 				       info->dri->bufStart);
   1259 
   1260     if (info->dri->bufNumBufs <= 0) {
   1261 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1262 		   "[drm] Could not create vertex/indirect buffers list\n");
   1263 	return FALSE;
   1264     }
   1265     xf86DrvMsg(pScreen->myNum, X_INFO,
   1266 	       "[drm] Added %d %d byte vertex/indirect buffers\n",
   1267 	       info->dri->bufNumBufs, RADEON_BUFFER_SIZE);
   1268 
   1269     if (!(info->dri->buffers = drmMapBufs(info->dri->drmFD))) {
   1270 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1271 		   "[drm] Failed to map vertex/indirect buffers list\n");
   1272 	return FALSE;
   1273     }
   1274     xf86DrvMsg(pScreen->myNum, X_INFO,
   1275 	       "[drm] Mapped %d vertex/indirect buffers\n",
   1276 	       info->dri->buffers->count);
   1277 
   1278     return TRUE;
   1279 }
   1280 
   1281 static void RADEONDRIIrqInit(RADEONInfoPtr info, ScreenPtr pScreen)
   1282 {
   1283     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
   1284 
   1285     if (!info->dri->irq) {
   1286 	info->dri->irq = drmGetInterruptFromBusID(
   1287 	    info->dri->drmFD,
   1288 	    PCI_CFG_BUS(info->PciInfo),
   1289 	    PCI_CFG_DEV(info->PciInfo),
   1290 	    PCI_CFG_FUNC(info->PciInfo));
   1291 
   1292 	if ((drmCtlInstHandler(info->dri->drmFD, info->dri->irq)) != 0) {
   1293 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1294 		       "[drm] failure adding irq handler, "
   1295 		       "there is a device already using that irq\n"
   1296 		       "[drm] falling back to irq-free operation\n");
   1297 	    info->dri->irq = 0;
   1298 	} else {
   1299 	    if (info->ChipFamily < CHIP_FAMILY_R600) {
   1300 		unsigned char *RADEONMMIO = info->MMIO;
   1301 		info->ModeReg->gen_int_cntl = INREG( RADEON_GEN_INT_CNTL );
   1302 
   1303 		/* Let the DRM know it can safely disable the vblank interrupts */
   1304 		radeon_crtc_modeset_ioctl(XF86_CRTC_CONFIG_PTR(pScrn)->crtc[0],
   1305 					  FALSE);
   1306 		radeon_crtc_modeset_ioctl(XF86_CRTC_CONFIG_PTR(pScrn)->crtc[0],
   1307 					  TRUE);
   1308 	    }
   1309 	}
   1310     }
   1311 
   1312     if (info->dri->irq)
   1313 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1314 		   "[drm] dma control initialized, using IRQ %d\n",
   1315 		   info->dri->irq);
   1316 }
   1317 
   1318 
   1319 /* Initialize the CP state, and start the CP (if used by the X server) */
   1320 static void RADEONDRICPInit(ScrnInfoPtr pScrn)
   1321 {
   1322     RADEONInfoPtr  info = RADEONPTR(pScrn);
   1323 
   1324 				/* Turn on bus mastering */
   1325     info->BusCntl &= ~RADEON_BUS_MASTER_DIS;
   1326 
   1327 				/* Make sure the CP is on for the X server */
   1328     RADEONCP_START(pScrn, info);
   1329 #ifdef USE_XAA
   1330     if (!info->useEXA)
   1331 	info->accel_state->dst_pitch_offset = info->dri->frontPitchOffset;
   1332 #endif
   1333 }
   1334 
   1335 
   1336 /* Get the DRM version and do some basic useability checks of DRI */
   1337 Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn)
   1338 {
   1339     RADEONInfoPtr  info    = RADEONPTR(pScrn);
   1340     int            major, minor, patch, fd;
   1341     int            req_major, req_minor, req_patch;
   1342     char           *busId;
   1343 
   1344     /* Check that the GLX, DRI, and DRM modules have been loaded by testing
   1345      * for known symbols in each module.
   1346      */
   1347     if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE;
   1348     if (!xf86LoaderCheckSymbol("drmAvailable"))        return FALSE;
   1349     if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
   1350       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1351 		 "[dri] RADEONDRIGetVersion failed (libdri too old)\n"
   1352 		 "[dri] Disabling DRI.\n");
   1353       return FALSE;
   1354     }
   1355 
   1356     /* Check the DRI version */
   1357     DRIQueryVersion(&major, &minor, &patch);
   1358     if (major < DRIINFO_MAJOR_VERSION) {
   1359         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1360             "[dri] RADEONDRIGetVersion failed because of a version mismatch.\n"
   1361             "[dri] This driver was built with %d.%d.x, which is too new;\n"
   1362             "[dri] libdri reports a version of %d.%d.%d."
   1363             "[dri] A server upgrade may be needed.\n"
   1364             "[dri] Disabling DRI.\n",
   1365             DRIINFO_MAJOR_VERSION, 0,
   1366             major, minor, patch);
   1367         return FALSE;
   1368     } else if (major > DRIINFO_MAJOR_VERSION) {
   1369         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1370             "[dri] RADEONDRIGetVersion failed because of a version mismatch.\n"
   1371             "[dri] This driver was built with %d.%d.x, which is too old;\n"
   1372             "[dri] libdri reports a version of %d.%d.%d."
   1373             "[dri] This driver needs to be upgraded/rebuilt.\n"
   1374             "[dri] Disabling DRI.\n",
   1375             DRIINFO_MAJOR_VERSION, 0,
   1376             major, minor, patch);
   1377         return FALSE;
   1378     }
   1379 
   1380     /* Check the lib version */
   1381     if (xf86LoaderCheckSymbol("drmGetLibVersion"))
   1382 	info->dri->pLibDRMVersion = drmGetLibVersion(info->dri->drmFD);
   1383     if (info->dri->pLibDRMVersion == NULL) {
   1384 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1385 		   "[dri] RADEONDRIGetVersion failed because libdrm is really "
   1386 		   "way to old to even get a version number out of it.\n"
   1387 		   "[dri] Disabling DRI.\n");
   1388 	return FALSE;
   1389     }
   1390     if (info->dri->pLibDRMVersion->version_major != 1 ||
   1391 	info->dri->pLibDRMVersion->version_minor < 2) {
   1392 	    /* incompatible drm library version */
   1393 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1394 		   "[dri] RADEONDRIGetVersion failed because of a "
   1395 		   "version mismatch.\n"
   1396 		   "[dri] libdrm module version is %d.%d.%d but "
   1397 		   "version 1.2.x is needed.\n"
   1398 		   "[dri] Disabling DRI.\n",
   1399 		   info->dri->pLibDRMVersion->version_major,
   1400 		   info->dri->pLibDRMVersion->version_minor,
   1401 		   info->dri->pLibDRMVersion->version_patchlevel);
   1402 	drmFreeVersion(info->dri->pLibDRMVersion);
   1403 	info->dri->pLibDRMVersion = NULL;
   1404 	return FALSE;
   1405     }
   1406 
   1407     /* Create a bus Id */
   1408     if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
   1409 	busId = DRICreatePCIBusID(info->PciInfo);
   1410     } else {
   1411 	busId = malloc(64);
   1412 	sprintf(busId,
   1413 		"PCI:%d:%d:%d",
   1414 		PCI_DEV_BUS(info->PciInfo),
   1415 		PCI_DEV_DEV(info->PciInfo),
   1416 		PCI_DEV_FUNC(info->PciInfo));
   1417     }
   1418 
   1419     /* Low level DRM open */
   1420     fd = drmOpen(RADEON_DRIVER_NAME, busId);
   1421     free(busId);
   1422     if (fd < 0) {
   1423 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1424 		   "[dri] RADEONDRIGetVersion failed to open the DRM\n"
   1425 		   "[dri] Disabling DRI.\n");
   1426 	return FALSE;
   1427     }
   1428 
   1429     /* Get DRM version & close DRM */
   1430     info->dri->pKernelDRMVersion = drmGetVersion(fd);
   1431     drmClose(fd);
   1432     if (info->dri->pKernelDRMVersion == NULL) {
   1433 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1434 		   "[dri] RADEONDRIGetVersion failed to get the DRM version\n"
   1435 		   "[dri] Disabling DRI.\n");
   1436 	return FALSE;
   1437     }
   1438 
   1439     /* Now check if we qualify */
   1440     req_major = 1;
   1441     if (info->ChipFamily >= CHIP_FAMILY_R300) {
   1442         req_minor = 17;
   1443         req_patch = 0;
   1444     } else if (info->IsIGP) {
   1445         req_minor = 10;
   1446         req_patch = 0;
   1447     } else { /* Many problems have been reported with 1.7 in the 2.4 kernel */
   1448         req_minor = 8;
   1449         req_patch = 0;
   1450     }
   1451 
   1452     /* We don't, bummer ! */
   1453     if (info->dri->pKernelDRMVersion->version_major != req_major) {
   1454         /* Looks like we're trying to start in UMS mode on a KMS kernel.
   1455 	 * This can happen if the radeon kernel module wasn't loaded before
   1456 	 * X starts.
   1457 	 */
   1458         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1459             "[dri] RADEONDRIGetVersion failed because of a version mismatch.\n"
   1460             "[dri] This chipset requires a kernel module version of %d.%d.%d,\n"
   1461             "[dri] but the kernel reports a version of %d.%d.%d."
   1462             "[dri] Make sure your module is loaded prior to starting X, and\n"
   1463             "[dri] that this driver was built with support for KMS.\n"
   1464             "[dri] Aborting.\n",
   1465             req_major, req_minor, req_patch,
   1466             info->dri->pKernelDRMVersion->version_major,
   1467             info->dri->pKernelDRMVersion->version_minor,
   1468             info->dri->pKernelDRMVersion->version_patchlevel);
   1469         drmFreeVersion(info->dri->pKernelDRMVersion);
   1470         info->dri->pKernelDRMVersion = NULL;
   1471         return -1;
   1472     } else if (info->dri->pKernelDRMVersion->version_minor < req_minor ||
   1473         (info->dri->pKernelDRMVersion->version_minor == req_minor &&
   1474         info->dri->pKernelDRMVersion->version_patchlevel < req_patch)) {
   1475         /* Incompatible drm version */
   1476         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1477             "[dri] RADEONDRIGetVersion failed because of a version mismatch.\n"
   1478             "[dri] This chipset requires a kernel module version of %d.%d.%d,\n"
   1479             "[dri] but the kernel reports a version of %d.%d.%d."
   1480             "[dri] Try upgrading your kernel.\n"
   1481             "[dri] Disabling DRI.\n",
   1482             req_major, req_minor, req_patch,
   1483             info->dri->pKernelDRMVersion->version_major,
   1484             info->dri->pKernelDRMVersion->version_minor,
   1485             info->dri->pKernelDRMVersion->version_patchlevel);
   1486         drmFreeVersion(info->dri->pKernelDRMVersion);
   1487         info->dri->pKernelDRMVersion = NULL;
   1488         return FALSE;
   1489     }
   1490 
   1491     return TRUE;
   1492 }
   1493 
   1494 Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on)
   1495 {
   1496     RADEONInfoPtr  info    = RADEONPTR(pScrn);
   1497     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
   1498     int value = 0;
   1499 
   1500     if (!info->want_vblank_interrupts)
   1501         on = FALSE;
   1502 
   1503     if (info->directRenderingEnabled && info->dri->pKernelDRMVersion->version_minor >= 28) {
   1504         if (on) {
   1505   	    if (xf86_config->num_crtc > 1 && xf86_config->crtc[1]->enabled)
   1506 	        value = DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2;
   1507 	    else
   1508 	        value = DRM_RADEON_VBLANK_CRTC1;
   1509 	}
   1510 
   1511 	if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_VBLANK_CRTC, value)) {
   1512 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RADEON Vblank Crtc Setup Failed %d\n", value);
   1513 	    return FALSE;
   1514 	}
   1515     }
   1516     return TRUE;
   1517 }
   1518 
   1519 
   1520 /* Initialize the screen-specific data structures for the DRI and the
   1521  * Radeon.  This is the main entry point to the device-specific
   1522  * initialization code.  It calls device-independent DRI functions to
   1523  * create the DRI data structures and initialize the DRI state.
   1524  */
   1525 Bool RADEONDRIScreenInit(ScreenPtr pScreen)
   1526 {
   1527     ScrnInfoPtr    pScrn   = xf86ScreenToScrn(pScreen);
   1528     RADEONInfoPtr  info    = RADEONPTR(pScrn);
   1529     DRIInfoPtr     pDRIInfo;
   1530     RADEONDRIPtr   pRADEONDRI;
   1531 
   1532     info->dri->DRICloseScreen = NULL;
   1533 
   1534     switch (info->CurrentLayout.pixel_code) {
   1535     case 8:
   1536     case 15:
   1537     case 24:
   1538 	/* These modes are not supported (yet). */
   1539 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1540 		   "[dri] RADEONInitVisualConfigs failed "
   1541 		   "(depth %d not supported).  "
   1542 		   "Disabling DRI.\n", info->CurrentLayout.pixel_code);
   1543 	return FALSE;
   1544 
   1545 	/* Only 16 and 32 color depths are supports currently. */
   1546     case 16:
   1547     case 32:
   1548 	break;
   1549     }
   1550 
   1551     radeon_drm_page_size = getpagesize();
   1552 
   1553     /* Create the DRI data structure, and fill it in before calling the
   1554      * DRIScreenInit().
   1555      */
   1556     if (!(pDRIInfo = DRICreateInfoRec())) return FALSE;
   1557 
   1558     info->dri->pDRIInfo                       = pDRIInfo;
   1559     pDRIInfo->drmDriverName              = RADEON_DRIVER_NAME;
   1560 
   1561     if ( (info->ChipFamily >= CHIP_FAMILY_R600) )
   1562        pDRIInfo->clientDriverName        = R600_DRIVER_NAME;
   1563     else if ( (info->ChipFamily >= CHIP_FAMILY_R300) )
   1564        pDRIInfo->clientDriverName        = R300_DRIVER_NAME;
   1565     else if ( info->ChipFamily >= CHIP_FAMILY_R200 )
   1566        pDRIInfo->clientDriverName	 = R200_DRIVER_NAME;
   1567     else
   1568        pDRIInfo->clientDriverName	 = RADEON_DRIVER_NAME;
   1569 
   1570     if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
   1571 	pDRIInfo->busIdString = DRICreatePCIBusID(info->PciInfo);
   1572     } else {
   1573 	pDRIInfo->busIdString            = malloc(64);
   1574 	sprintf(pDRIInfo->busIdString,
   1575 		"PCI:%d:%d:%d",
   1576 		PCI_DEV_BUS(info->PciInfo),
   1577 		PCI_DEV_DEV(info->PciInfo),
   1578 		PCI_DEV_FUNC(info->PciInfo));
   1579     }
   1580     pDRIInfo->ddxDriverMajorVersion      = info->allowColorTiling ? 5 : 4;
   1581     pDRIInfo->ddxDriverMinorVersion      = 3;
   1582     pDRIInfo->ddxDriverPatchVersion      = 0;
   1583     pDRIInfo->frameBufferPhysicalAddress = (void *)(uintptr_t)info->LinearAddr + info->dri->frontOffset;
   1584     pDRIInfo->frameBufferSize            = info->FbMapSize - info->FbSecureSize;
   1585     pDRIInfo->frameBufferStride          = (pScrn->displayWidth *
   1586 					    info->CurrentLayout.pixel_bytes);
   1587     pDRIInfo->ddxDrawableTableEntry      = RADEON_MAX_DRAWABLES;
   1588     pDRIInfo->maxDrawableTableEntry      = (SAREA_MAX_DRAWABLES
   1589 					    < RADEON_MAX_DRAWABLES
   1590 					    ? SAREA_MAX_DRAWABLES
   1591 					    : RADEON_MAX_DRAWABLES);
   1592     /* kill DRIAdjustFrame. We adjust sarea frame info ourselves to work
   1593        correctly with pageflip + mergedfb/color tiling */
   1594     pDRIInfo->wrap.AdjustFrame = NULL;
   1595 
   1596 #ifdef NOT_DONE
   1597     /* FIXME: Need to extend DRI protocol to pass this size back to
   1598      * client for SAREA mapping that includes a device private record
   1599      */
   1600     pDRIInfo->SAREASize = ((sizeof(XF86DRISAREARec) + 0xfff)
   1601 			   & 0x1000); /* round to page */
   1602     /* + shared memory device private rec */
   1603 #else
   1604     /* For now the mapping works by using a fixed size defined
   1605      * in the SAREA header
   1606      */
   1607     if (sizeof(XF86DRISAREARec)+sizeof(drm_radeon_sarea_t) > SAREA_MAX) {
   1608 	ErrorF("Data does not fit in SAREA\n");
   1609 	return FALSE;
   1610     }
   1611     pDRIInfo->SAREASize = SAREA_MAX;
   1612 #endif
   1613 
   1614     if (!(pRADEONDRI = (RADEONDRIPtr)calloc(sizeof(RADEONDRIRec),1))) {
   1615 	DRIDestroyInfoRec(info->dri->pDRIInfo);
   1616 	info->dri->pDRIInfo = NULL;
   1617 	return FALSE;
   1618     }
   1619     pDRIInfo->devPrivate     = pRADEONDRI;
   1620     pDRIInfo->devPrivateSize = sizeof(RADEONDRIRec);
   1621     pDRIInfo->contextSize    = sizeof(RADEONDRIContextRec);
   1622 
   1623     pDRIInfo->CreateContext  = RADEONCreateContext;
   1624     pDRIInfo->DestroyContext = RADEONDestroyContext;
   1625     pDRIInfo->SwapContext    = RADEONDRISwapContext;
   1626     pDRIInfo->InitBuffers    = RADEONDRIInitBuffers;
   1627     pDRIInfo->MoveBuffers    = RADEONDRIMoveBuffers;
   1628     pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
   1629     pDRIInfo->TransitionTo2d = RADEONDRITransitionTo2d;
   1630     pDRIInfo->TransitionTo3d = RADEONDRITransitionTo3d;
   1631     pDRIInfo->TransitionSingleToMulti3D = RADEONDRITransitionSingleToMulti3d;
   1632     pDRIInfo->TransitionMultiToSingle3D = RADEONDRITransitionMultiToSingle3d;
   1633 #if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 ||	\
   1634 			(DRIINFO_MAJOR_VERSION == 5 &&	\
   1635 			 DRIINFO_MINOR_VERSION >= 1))
   1636     pDRIInfo->ClipNotify     = RADEONDRIClipNotify;
   1637 #endif
   1638 
   1639     pDRIInfo->createDummyCtx     = TRUE;
   1640     pDRIInfo->createDummyCtxPriv = FALSE;
   1641 
   1642 #ifdef USE_EXA
   1643     if (info->useEXA) {
   1644 #if DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3
   1645        int major, minor, patch;
   1646 
   1647        DRIQueryVersion(&major, &minor, &patch);
   1648 
   1649        if (minor >= 3)
   1650 #endif
   1651 #if DRIINFO_MAJOR_VERSION > 5 || \
   1652     (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3)
   1653 	  pDRIInfo->texOffsetStart = RADEONTexOffsetStart;
   1654 #endif
   1655     }
   1656 #endif
   1657 
   1658     if (!DRIScreenInit(pScreen, pDRIInfo, &info->dri->drmFD)) {
   1659 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1660 		   "[dri] DRIScreenInit failed.  Disabling DRI.\n");
   1661 	free(pDRIInfo->devPrivate);
   1662 	pDRIInfo->devPrivate = NULL;
   1663 	DRIDestroyInfoRec(pDRIInfo);
   1664 	pDRIInfo = NULL;
   1665 	return FALSE;
   1666     }
   1667 				/* Initialize AGP */
   1668     if (info->cardType==CARD_AGP && !RADEONDRIAgpInit(info, pScreen)) {
   1669 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1670 		   "[agp] AGP failed to initialize. Disabling the DRI.\n" );
   1671 	xf86DrvMsg(pScreen->myNum, X_INFO,
   1672 		   "[agp] You may want to make sure the agpgart kernel "
   1673 		   "module\nis loaded before the radeon kernel module.\n");
   1674 	RADEONDRICloseScreen(pScreen);
   1675 	return FALSE;
   1676     }
   1677 
   1678 				/* Initialize PCI */
   1679     if ((info->cardType!=CARD_AGP) && !RADEONDRIPciInit(info, pScreen)) {
   1680 	xf86DrvMsg(pScreen->myNum, X_ERROR,
   1681 		   "[pci] PCI failed to initialize. Disabling the DRI.\n" );
   1682 	RADEONDRICloseScreen(pScreen);
   1683 	return FALSE;
   1684     }
   1685 
   1686 				/* DRIScreenInit doesn't add all the
   1687 				 * common mappings.  Add additional
   1688 				 * mappings here.
   1689 				 */
   1690     if (!RADEONDRIMapInit(info, pScreen)) {
   1691 	RADEONDRICloseScreen(pScreen);
   1692 	return FALSE;
   1693     }
   1694 
   1695 				/* DRIScreenInit adds the frame buffer
   1696 				   map, but we need it as well */
   1697     {
   1698 	void *scratch_ptr;
   1699         int scratch_int;
   1700 
   1701 	DRIGetDeviceInfo(pScreen, &info->dri->fbHandle,
   1702                          &scratch_int, &scratch_int,
   1703                          &scratch_int, &scratch_int,
   1704                          &scratch_ptr);
   1705     }
   1706 
   1707 				/* FIXME: When are these mappings unmapped? */
   1708 
   1709     if (!RADEONInitVisualConfigs(pScreen)) {
   1710 	RADEONDRICloseScreen(pScreen);
   1711 	return FALSE;
   1712     }
   1713     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Visual configs initialized\n");
   1714 
   1715     return TRUE;
   1716 }
   1717 
   1718 static Bool RADEONDRIDoCloseScreen(CLOSE_SCREEN_ARGS_DECL)
   1719 {
   1720     ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
   1721     RADEONInfoPtr  info  = RADEONPTR(pScrn);
   1722 
   1723     RADEONDRICloseScreen(pScreen);
   1724 
   1725     pScreen->CloseScreen = info->dri->DRICloseScreen;
   1726     return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
   1727 }
   1728 
   1729 /* Finish initializing the device-dependent DRI state, and call
   1730  * DRIFinishScreenInit() to complete the device-independent DRI
   1731  * initialization.
   1732  */
   1733 Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen)
   1734 {
   1735     ScrnInfoPtr         pScrn = xf86ScreenToScrn(pScreen);
   1736     RADEONInfoPtr       info  = RADEONPTR(pScrn);
   1737     drm_radeon_sarea_t  *pSAREAPriv;
   1738     RADEONDRIPtr        pRADEONDRI;
   1739 
   1740     info->dri->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
   1741     /* info->dri->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */
   1742 
   1743     /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit
   1744      * because *DRIKernelInit requires that the hardware lock is held by
   1745      * the X server, and the first time the hardware lock is grabbed is
   1746      * in DRIFinishScreenInit.
   1747      */
   1748     if (!DRIFinishScreenInit(pScreen)) {
   1749 	RADEONDRICloseScreen(pScreen);
   1750 	return FALSE;
   1751     }
   1752 
   1753     /* Initialize the kernel data structures */
   1754     if (!RADEONDRIKernelInit(info, pScreen)) {
   1755 	RADEONDRICloseScreen(pScreen);
   1756 	return FALSE;
   1757     }
   1758 
   1759     /* Initialize the vertex buffers list */
   1760     if (!RADEONDRIBufInit(info, pScreen)) {
   1761 	RADEONDRICloseScreen(pScreen);
   1762 	return FALSE;
   1763     }
   1764 
   1765     /* Initialize IRQ */
   1766     RADEONDRIIrqInit(info, pScreen);
   1767 
   1768     /* Initialize kernel GART memory manager */
   1769     RADEONDRIGartHeapInit(info, pScreen);
   1770 
   1771     /* Initialize and start the CP if required */
   1772     RADEONDRICPInit(pScrn);
   1773 
   1774     /* Initialize the SAREA private data structure */
   1775     pSAREAPriv = (drm_radeon_sarea_t*)DRIGetSAREAPrivate(pScreen);
   1776     memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
   1777 
   1778     pRADEONDRI                    = (RADEONDRIPtr)info->dri->pDRIInfo->devPrivate;
   1779 
   1780     pRADEONDRI->deviceID          = info->Chipset;
   1781     pRADEONDRI->width             = pScrn->virtualX;
   1782     pRADEONDRI->height            = pScrn->virtualY;
   1783     pRADEONDRI->depth             = pScrn->depth;
   1784     pRADEONDRI->bpp               = pScrn->bitsPerPixel;
   1785 
   1786     pRADEONDRI->IsPCI             = (info->cardType!=CARD_AGP);
   1787     pRADEONDRI->AGPMode           = info->dri->agpMode;
   1788 
   1789     pRADEONDRI->frontOffset       = info->dri->frontOffset;
   1790     pRADEONDRI->frontPitch        = info->dri->frontPitch;
   1791     pRADEONDRI->backOffset        = info->dri->backOffset;
   1792     pRADEONDRI->backPitch         = info->dri->backPitch;
   1793     pRADEONDRI->depthOffset       = info->dri->depthOffset;
   1794     pRADEONDRI->depthPitch        = info->dri->depthPitch;
   1795     pRADEONDRI->textureOffset     = info->dri->textureOffset;
   1796     pRADEONDRI->textureSize       = info->dri->textureSize;
   1797     pRADEONDRI->log2TexGran       = info->dri->log2TexGran;
   1798 
   1799     pRADEONDRI->registerHandle    = info->dri->registerHandle;
   1800     pRADEONDRI->registerSize      = info->dri->registerSize;
   1801 
   1802     pRADEONDRI->statusHandle      = info->dri->ringReadPtrHandle;
   1803     pRADEONDRI->statusSize        = info->dri->ringReadMapSize;
   1804 
   1805     pRADEONDRI->gartTexHandle     = info->dri->gartTexHandle;
   1806     pRADEONDRI->gartTexMapSize    = info->dri->gartTexMapSize;
   1807     pRADEONDRI->log2GARTTexGran   = info->dri->log2GARTTexGran;
   1808     pRADEONDRI->gartTexOffset     = info->dri->gartTexStart;
   1809 
   1810     pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
   1811 
   1812     info->directRenderingInited = TRUE;
   1813 
   1814     /* Wrap CloseScreen */
   1815     info->dri->DRICloseScreen = pScreen->CloseScreen;
   1816     pScreen->CloseScreen = RADEONDRIDoCloseScreen;
   1817 
   1818     /* disable vblank at startup */
   1819     RADEONDRISetVBlankInterrupt (pScrn, FALSE);
   1820 
   1821     return TRUE;
   1822 }
   1823 
   1824 /**
   1825  * This function will attempt to get the Radeon hardware back into shape
   1826  * after a resume from disc.
   1827  *
   1828  * Charl P. Botha <http://cpbotha.net>
   1829  */
   1830 void RADEONDRIResume(ScreenPtr pScreen)
   1831 {
   1832     int _ret;
   1833     ScrnInfoPtr   pScrn   = xf86ScreenToScrn(pScreen);
   1834     RADEONInfoPtr info    = RADEONPTR(pScrn);
   1835 
   1836     if (info->dri->pKernelDRMVersion->version_minor >= 9) {
   1837 	xf86DrvMsg(pScreen->myNum, X_INFO,
   1838 		   "[RESUME] Attempting to re-init Radeon hardware.\n");
   1839     } else {
   1840 	xf86DrvMsg(pScreen->myNum, X_WARNING,
   1841 		   "[RESUME] Cannot re-init Radeon hardware, DRM too old\n"
   1842 		   "(need 1.9.0  or newer)\n");
   1843 	return;
   1844     }
   1845 
   1846     if (info->cardType==CARD_AGP) {
   1847 	if (!RADEONSetAgpMode(info, pScreen))
   1848 	    return;
   1849 
   1850 	RADEONSetAgpBase(info, pScreen);
   1851     }
   1852 
   1853     _ret = drmCommandNone(info->dri->drmFD, DRM_RADEON_CP_RESUME);
   1854     if (_ret) {
   1855 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1856 		   "%s: CP resume %d\n", __FUNCTION__, _ret);
   1857 	/* FIXME: return? */
   1858     }
   1859 
   1860     if (info->ChipFamily < CHIP_FAMILY_R600)
   1861 	RADEONEngineRestore(pScrn);
   1862 
   1863     RADEONDRICPInit(pScrn);
   1864 }
   1865 
   1866 void RADEONDRIStop(ScreenPtr pScreen)
   1867 {
   1868     ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
   1869     RADEONInfoPtr  info  = RADEONPTR(pScrn);
   1870     RING_LOCALS;
   1871 
   1872     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
   1873 		   "RADEONDRIStop\n");
   1874 
   1875     /* Stop the CP */
   1876     if (info->directRenderingInited) {
   1877 	/* If we've generated any CP commands, we must flush them to the
   1878 	 * kernel module now.
   1879 	 */
   1880 	RADEONCP_RELEASE(pScrn, info);
   1881 	RADEONCP_STOP(pScrn, info);
   1882     }
   1883     info->directRenderingInited = FALSE;
   1884 }
   1885 
   1886 /* The screen is being closed, so clean up any state and free any
   1887  * resources used by the DRI.
   1888  */
   1889 void RADEONDRICloseScreen(ScreenPtr pScreen)
   1890 {
   1891     ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
   1892     RADEONInfoPtr  info  = RADEONPTR(pScrn);
   1893     drm_radeon_init_t  drmInfo;
   1894 
   1895      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
   1896 		    "RADEONDRICloseScreen\n");
   1897 
   1898 #ifdef DAMAGE
   1899      REGION_UNINIT(pScreen, &info->dri->driRegion);
   1900 #endif
   1901 
   1902      if (info->dri->irq) {
   1903 	RADEONDRISetVBlankInterrupt (pScrn, FALSE);
   1904 	drmCtlUninstHandler(info->dri->drmFD);
   1905 	info->dri->irq = 0;
   1906 	info->ModeReg->gen_int_cntl = 0;
   1907     }
   1908 
   1909     /* De-allocate vertex buffers */
   1910     if (info->dri->buffers) {
   1911 	drmUnmapBufs(info->dri->buffers);
   1912 	info->dri->buffers = NULL;
   1913     }
   1914 
   1915     /* De-allocate all kernel resources */
   1916     memset(&drmInfo, 0, sizeof(drm_radeon_init_t));
   1917     drmInfo.func = RADEON_CLEANUP_CP;
   1918     drmCommandWrite(info->dri->drmFD, DRM_RADEON_CP_INIT,
   1919 		    &drmInfo, sizeof(drm_radeon_init_t));
   1920 
   1921     /* De-allocate all GART resources */
   1922     if (info->dri->gartTex) {
   1923 	drmUnmap(info->dri->gartTex, info->dri->gartTexMapSize);
   1924 	info->dri->gartTex = NULL;
   1925     }
   1926     if (info->dri->buf) {
   1927 	drmUnmap(info->dri->buf, info->dri->bufMapSize);
   1928 	info->dri->buf = NULL;
   1929     }
   1930     if (info->dri->ringReadPtr) {
   1931 	drmUnmap(info->dri->ringReadPtr, info->dri->ringReadMapSize);
   1932 	info->dri->ringReadPtr = NULL;
   1933     }
   1934     if (info->dri->ring) {
   1935 	drmUnmap(info->dri->ring, info->dri->ringMapSize);
   1936 	info->dri->ring = NULL;
   1937     }
   1938     if (info->dri->agpMemHandle != DRM_AGP_NO_HANDLE) {
   1939 	drmAgpUnbind(info->dri->drmFD, info->dri->agpMemHandle);
   1940 	drmAgpFree(info->dri->drmFD, info->dri->agpMemHandle);
   1941 	info->dri->agpMemHandle = DRM_AGP_NO_HANDLE;
   1942 	drmAgpRelease(info->dri->drmFD);
   1943     }
   1944     if (info->dri->pciMemHandle) {
   1945 	drmScatterGatherFree(info->dri->drmFD, info->dri->pciMemHandle);
   1946 	info->dri->pciMemHandle = 0;
   1947     }
   1948 
   1949     if (info->dri->pciGartBackup) {
   1950 	free(info->dri->pciGartBackup);
   1951 	info->dri->pciGartBackup = NULL;
   1952     }
   1953 
   1954     /* De-allocate all DRI resources */
   1955     DRICloseScreen(pScreen);
   1956 
   1957     /* De-allocate all DRI data structures */
   1958     if (info->dri->pDRIInfo) {
   1959 	if (info->dri->pDRIInfo->devPrivate) {
   1960 	    free(info->dri->pDRIInfo->devPrivate);
   1961 	    info->dri->pDRIInfo->devPrivate = NULL;
   1962 	}
   1963 	DRIDestroyInfoRec(info->dri->pDRIInfo);
   1964 	info->dri->pDRIInfo = NULL;
   1965     }
   1966     if (info->dri->pVisualConfigs) {
   1967 	free(info->dri->pVisualConfigs);
   1968 	info->dri->pVisualConfigs = NULL;
   1969     }
   1970     if (info->dri->pVisualConfigsPriv) {
   1971 	free(info->dri->pVisualConfigsPriv);
   1972 	info->dri->pVisualConfigsPriv = NULL;
   1973     }
   1974 }
   1975 
   1976 /* Use callbacks from dri.c to support pageflipping mode for a single
   1977  * 3d context without need for any specific full-screen extension.
   1978  *
   1979  * Also use these callbacks to allocate and free 3d-specific memory on
   1980  * demand.
   1981  */
   1982 
   1983 
   1984 #ifdef DAMAGE
   1985 
   1986 /* Use the damage layer to maintain a list of dirty rectangles.
   1987  * These are blitted to the back buffer to keep both buffers clean
   1988  * during page-flipping when the 3d application isn't fullscreen.
   1989  *
   1990  * An alternative to this would be to organize for all on-screen drawing
   1991  * operations to be duplicated for the two buffers.  That might be
   1992  * faster, but seems like a lot more work...
   1993  */
   1994 
   1995 
   1996 static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, RegionPtr pReg)
   1997 {
   1998     RADEONInfoPtr       info       = RADEONPTR(pScrn);
   1999     int                 i, num;
   2000     ScreenPtr           pScreen    = pScrn->pScreen;
   2001     drm_radeon_sarea_t  *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
   2002 #ifdef USE_EXA
   2003     PixmapPtr           pPix = pScreen->GetScreenPixmap(pScreen);
   2004 #endif
   2005     RegionRec region;
   2006     BoxPtr pbox;
   2007 
   2008     if (!info->directRenderingInited || !info->cp->CPStarted)
   2009 	return;
   2010 
   2011     /* Don't want to do this when no 3d is active and pages are
   2012      * right-way-round
   2013      */
   2014     if (!pSAREAPriv->pfState && pSAREAPriv->pfCurrentPage == 0)
   2015 	return;
   2016 
   2017     REGION_NULL(pScreen, &region);
   2018     REGION_SUBTRACT(pScreen, &region, pReg, &info->dri->driRegion);
   2019 
   2020     num = REGION_NUM_RECTS(&region);
   2021 
   2022     if (!num) {
   2023 	goto out;
   2024     }
   2025 
   2026     pbox = REGION_RECTS(&region);
   2027 
   2028     /* pretty much a hack. */
   2029 
   2030 #ifdef USE_EXA
   2031     if (info->useEXA) {
   2032 	uint32_t src_pitch_offset, dst_pitch_offset, datatype;
   2033 
   2034 	RADEONGetPixmapOffsetPitch(pPix, &src_pitch_offset);
   2035 	dst_pitch_offset = src_pitch_offset + (info->dri->backOffset >> 10);
   2036 	RADEONGetDatatypeBpp(pScrn->bitsPerPixel, &datatype);
   2037 	info->accel_state->xdir = info->accel_state->ydir = 1;
   2038 
   2039 	RADEONDoPrepareCopyCP(pScrn, src_pitch_offset, dst_pitch_offset, datatype,
   2040 			      GXcopy, ~0);
   2041     }
   2042 #endif
   2043 
   2044 #ifdef USE_XAA
   2045     if (!info->useEXA) {
   2046 	/* Make sure accel has been properly inited */
   2047 	if (info->accel_state->accel == NULL ||
   2048 	    info->accel_state->accel->SetupForScreenToScreenCopy == NULL)
   2049 	    goto out;
   2050 	if (info->tilingEnabled)
   2051 	    info->accel_state->dst_pitch_offset |= RADEON_DST_TILE_MACRO;
   2052 	(*info->accel_state->accel->SetupForScreenToScreenCopy)(pScrn,
   2053 								1, 1, GXcopy,
   2054 								(uint32_t)(-1), -1);
   2055     }
   2056 #endif
   2057 
   2058     for (i = 0 ; i < num ; i++, pbox++) {
   2059 	int xa = max(pbox->x1, 0), xb = min(pbox->x2, pScrn->virtualX-1);
   2060 	int ya = max(pbox->y1, 0), yb = min(pbox->y2, pScrn->virtualY-1);
   2061 
   2062 	if (xa <= xb && ya <= yb) {
   2063 #ifdef USE_EXA
   2064 	    if (info->useEXA) {
   2065 		RADEONCopyCP(pPix, xa, ya, xa, ya, xb - xa + 1, yb - ya + 1);
   2066 	    }
   2067 #endif
   2068 
   2069 #ifdef USE_XAA
   2070 	    if (!info->useEXA) {
   2071 		(*info->accel_state->accel->SubsequentScreenToScreenCopy)(pScrn, xa, ya,
   2072 									  xa + info->dri->backX,
   2073 									  ya + info->dri->backY,
   2074 									  xb - xa + 1,
   2075 									  yb - ya + 1);
   2076 	    }
   2077 #endif
   2078 	}
   2079     }
   2080 
   2081 #ifdef USE_XAA
   2082     info->accel_state->dst_pitch_offset &= ~RADEON_DST_TILE_MACRO;
   2083 #endif
   2084 
   2085 out:
   2086     REGION_NULL(pScreen, &region);
   2087     DamageEmpty(info->dri->pDamage);
   2088 }
   2089 
   2090 #endif /* DAMAGE */
   2091 
   2092 static void RADEONEnablePageFlip(ScreenPtr pScreen)
   2093 {
   2094 #ifdef DAMAGE
   2095     ScrnInfoPtr         pScrn      = xf86ScreenToScrn(pScreen);
   2096     RADEONInfoPtr       info       = RADEONPTR(pScrn);
   2097 
   2098     if (info->dri->allowPageFlip) {
   2099 	drm_radeon_sarea_t *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
   2100 	BoxRec box = { .x1 = 0, .y1 = 0, .x2 = pScrn->virtualX - 1,
   2101 		       .y2 = pScrn->virtualY - 1 };
   2102 	RegionPtr pReg = REGION_CREATE(pScreen, &box, 1);
   2103 
   2104 	pSAREAPriv->pfState = 1;
   2105 	RADEONDRIRefreshArea(pScrn, pReg);
   2106 	REGION_DESTROY(pScreen, pReg);
   2107     }
   2108 #endif
   2109 }
   2110 
   2111 static void RADEONDisablePageFlip(ScreenPtr pScreen)
   2112 {
   2113     /* Tell the clients not to pageflip.  How?
   2114      *   -- Field in sarea, plus bumping the window counters.
   2115      *   -- DRM needs to cope with Front-to-Back swapbuffers.
   2116      */
   2117     drm_radeon_sarea_t  *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
   2118 
   2119     pSAREAPriv->pfState = 0;
   2120 }
   2121 
   2122 static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen)
   2123 {
   2124     RADEONDisablePageFlip(pScreen);
   2125 }
   2126 
   2127 static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen)
   2128 {
   2129     /* Let the remaining 3d app start page flipping again */
   2130     RADEONEnablePageFlip(pScreen);
   2131 }
   2132 
   2133 static void RADEONDRITransitionTo3d(ScreenPtr pScreen)
   2134 {
   2135     ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
   2136     RADEONInfoPtr  info  = RADEONPTR(pScrn);
   2137 #ifdef USE_XAA
   2138     FBAreaPtr      fbarea;
   2139     int            width, height;
   2140 
   2141     /* EXA allocates these areas up front, so it doesn't do the following
   2142      * stuff.
   2143      */
   2144     if (!info->useEXA) {
   2145 	/* reserve offscreen area for back and depth buffers and textures */
   2146 
   2147 	/* If we still have an area for the back buffer reserved, free it
   2148 	 * first so we always start with all free offscreen memory, except
   2149 	 * maybe for Xv
   2150 	 */
   2151 	if (info->dri->backArea) {
   2152 	    xf86FreeOffscreenArea(info->dri->backArea);
   2153 	    info->dri->backArea = NULL;
   2154         }
   2155 
   2156 	xf86PurgeUnlockedOffscreenAreas(pScreen);
   2157 
   2158 	xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0);
   2159 
   2160 	/* Free Xv linear offscreen memory if necessary
   2161 	 * FIXME: This is hideous.  What about telling xv "oh btw you have no memory
   2162 	 * any more?" -- anholt
   2163 	 */
   2164 	if (height < (info->dri->depthTexLines + info->dri->backLines)) {
   2165 	    RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr;
   2166 	    xf86FreeOffscreenLinear((FBLinearPtr)portPriv->video_memory);
   2167 	    portPriv->video_memory = NULL;
   2168 	    xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0);
   2169 	}
   2170 
   2171 	/* Reserve placeholder area so the other areas will match the
   2172 	 * pre-calculated offsets
   2173 	 * FIXME: We may have other locked allocations and thus this would allocate
   2174 	 * in the wrong place.  The XV surface allocations seem likely. -- anholt
   2175 	 */
   2176 	fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
   2177 					   height
   2178 					   - info->dri->depthTexLines
   2179 					   - info->dri->backLines,
   2180 					   pScrn->displayWidth,
   2181 					   NULL, NULL, NULL);
   2182 	if (!fbarea)
   2183 	    xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve placeholder "
   2184 		       "offscreen area, you might experience screen corruption\n");
   2185 
   2186 	info->dri->backArea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
   2187 							info->dri->backLines,
   2188 							pScrn->displayWidth,
   2189 							NULL, NULL, NULL);
   2190 	if (!info->dri->backArea)
   2191 	    xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve offscreen "
   2192 		       "area for back buffer, you might experience screen "
   2193 		       "corruption\n");
   2194 
   2195 	info->dri->depthTexArea = xf86AllocateOffscreenArea(pScreen,
   2196 							    pScrn->displayWidth,
   2197 							    info->dri->depthTexLines,
   2198 							    pScrn->displayWidth,
   2199 							    NULL, NULL, NULL);
   2200 	if (!info->dri->depthTexArea)
   2201 	    xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve offscreen "
   2202 		       "area for depth buffer and textures, you might "
   2203 		       "experience screen corruption\n");
   2204 
   2205 	xf86FreeOffscreenArea(fbarea);
   2206     }
   2207 #endif /* USE_XAA */
   2208 
   2209     info->dri->have3DWindows = 1;
   2210 
   2211     RADEONChangeSurfaces(pScrn);
   2212     RADEONEnablePageFlip(pScreen);
   2213 
   2214     info->want_vblank_interrupts = TRUE;
   2215     RADEONDRISetVBlankInterrupt(pScrn, TRUE);
   2216 
   2217     if (info->cursor)
   2218 	xf86ForceHWCursor (pScreen, TRUE);
   2219 }
   2220 
   2221 static void RADEONDRITransitionTo2d(ScreenPtr pScreen)
   2222 {
   2223     ScrnInfoPtr         pScrn      = xf86ScreenToScrn(pScreen);
   2224     RADEONInfoPtr       info       = RADEONPTR(pScrn);
   2225     drm_radeon_sarea_t  *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
   2226 
   2227     /* Try flipping back to the front page if necessary */
   2228     if (pSAREAPriv->pfCurrentPage == 1)
   2229 	drmCommandNone(info->dri->drmFD, DRM_RADEON_FLIP);
   2230 
   2231     /* Shut down shadowing if we've made it back to the front page */
   2232     if (pSAREAPriv->pfCurrentPage == 0) {
   2233 	RADEONDisablePageFlip(pScreen);
   2234 #ifdef USE_XAA
   2235 	if (!info->useEXA) {
   2236 	    xf86FreeOffscreenArea(info->dri->backArea);
   2237 	    info->dri->backArea = NULL;
   2238 	}
   2239 #endif
   2240     } else {
   2241 	xf86DrvMsg(pScreen->myNum, X_WARNING,
   2242 		   "[dri] RADEONDRITransitionTo2d: "
   2243 		   "kernel failed to unflip buffers.\n");
   2244     }
   2245 
   2246 #ifdef USE_XAA
   2247     if (!info->useEXA)
   2248 	xf86FreeOffscreenArea(info->dri->depthTexArea);
   2249 #endif
   2250 
   2251     info->dri->have3DWindows = 0;
   2252 
   2253     RADEONChangeSurfaces(pScrn);
   2254 
   2255     info->want_vblank_interrupts = FALSE;
   2256     RADEONDRISetVBlankInterrupt(pScrn, FALSE);
   2257 
   2258     if (info->cursor)
   2259 	xf86ForceHWCursor (pScreen, FALSE);
   2260 }
   2261 
   2262 #if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 ||	\
   2263 			(DRIINFO_MAJOR_VERSION == 5 &&	\
   2264 			 DRIINFO_MINOR_VERSION >= 1))
   2265 static void
   2266 RADEONDRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num)
   2267 {
   2268     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
   2269     RADEONInfoPtr info = RADEONPTR(pScrn);
   2270 
   2271     REGION_UNINIT(pScreen, &info->dri->driRegion);
   2272     REGION_NULL(pScreen, &info->dri->driRegion);
   2273 
   2274     if (num > 0) {
   2275 	int i;
   2276 
   2277 	for (i = 0; i < num; i++) {
   2278 	    WindowPtr pWin = ppWin[i];
   2279 
   2280 	    if (pWin) {
   2281 		REGION_UNION(pScreen, &info->dri->driRegion, &pWin->clipList,
   2282 			     &info->dri->driRegion);
   2283 	    }
   2284 	}
   2285     }
   2286 }
   2287 #endif
   2288 
   2289 void RADEONDRIAllocatePCIGARTTable(ScreenPtr pScreen)
   2290 {
   2291     ScrnInfoPtr        pScrn   = xf86ScreenToScrn(pScreen);
   2292     RADEONInfoPtr      info    = RADEONPTR(pScrn);
   2293 
   2294     if (info->cardType != CARD_PCIE ||
   2295 	info->dri->pKernelDRMVersion->version_minor < 19)
   2296       return;
   2297 
   2298     if (info->FbSecureSize==0)
   2299       return;
   2300 
   2301     /* set the old default size of pci gart table */
   2302     if (info->dri->pKernelDRMVersion->version_minor < 26)
   2303       info->dri->pciGartSize = 32768;
   2304 
   2305     info->dri->pciGartSize = RADEONDRIGetPciAperTableSize(pScrn);
   2306 
   2307     /* allocate space to back up PCIEGART table */
   2308     info->dri->pciGartBackup = xnfcalloc(1, info->dri->pciGartSize);
   2309     if (info->dri->pciGartBackup == NULL)
   2310       return;
   2311 
   2312     info->dri->pciGartOffset = (info->FbMapSize - info->FbSecureSize);
   2313 
   2314 
   2315 }
   2316 
   2317 int RADEONDRIGetPciAperTableSize(ScrnInfoPtr pScrn)
   2318 {
   2319     RADEONInfoPtr  info   = RADEONPTR(pScrn);
   2320     int ret_size;
   2321     int num_pages;
   2322 
   2323     num_pages = (info->dri->pciAperSize * 1024 * 1024) / 4096;
   2324 
   2325     if ((info->ChipFamily >= CHIP_FAMILY_R600) ||
   2326 	(info->ChipFamily == CHIP_FAMILY_RS600))
   2327 	ret_size = num_pages * sizeof(uint64_t);
   2328     else
   2329 	ret_size = num_pages * sizeof(unsigned int);
   2330 
   2331     return ret_size;
   2332 }
   2333 
   2334 int RADEONDRISetParam(ScrnInfoPtr pScrn, unsigned int param, int64_t value)
   2335 {
   2336     drm_radeon_setparam_t  radeonsetparam;
   2337     RADEONInfoPtr  info   = RADEONPTR(pScrn);
   2338     int ret;
   2339 
   2340     memset(&radeonsetparam, 0, sizeof(drm_radeon_setparam_t));
   2341     radeonsetparam.param = param;
   2342     radeonsetparam.value = value;
   2343     ret = drmCommandWrite(info->dri->drmFD, DRM_RADEON_SETPARAM,
   2344 			  &radeonsetparam, sizeof(drm_radeon_setparam_t));
   2345     return ret;
   2346 }
   2347