1/* modified from tdfx_dri.c, mga_dri.c */ 2 3/* 4 * DRI wrapper for 300 and 315 series 5 * 6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 7 * 8 * Preliminary 315/330 support by Thomas Winischhofer 9 * Portions of Mesa 4/5 changes by Eric Anholt 10 * 11 * Licensed under the following terms: 12 * 13 * Permission to use, copy, modify, distribute, and sell this software and its 14 * documentation for any purpose is hereby granted without fee, provided that 15 * the above copyright notice appears in all copies and that both that copyright 16 * notice and this permission notice appear in supporting documentation, and 17 * and that the name of the copyright holder not be used in advertising 18 * or publicity pertaining to distribution of the software without specific, 19 * written prior permission. The copyright holder makes no representations 20 * about the suitability of this software for any purpose. It is provided 21 * "as is" without expressed or implied warranty. 22 * 23 * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 24 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 25 * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR 26 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 27 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 28 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 29 * PERFORMANCE OF THIS SOFTWARE. 30 * 31 * Previously taken and modified from tdfx_dri.c, mga_dri.c 32 * 33 * Authors: Can-Ru Yeou, SiS Inc. 34 * Alan Hourihane, Wigan, England, 35 * Thomas Winischhofer <thomas@winischhofer.net> 36 * others. 37 */ 38#ifdef HAVE_CONFIG_H 39#include "config.h" 40#endif 41 42/* Jong 09/27/2007; added for PACKAGE_VERSION_MAJOR,... */ 43#define PACKAGE_VERSION_MAJOR 1 44#define PACKAGE_VERSION_MINOR 1 45#define PACKAGE_VERSION_PATCHLEVEL 0 46 47#include "xf86.h" 48#include "xf86_OSproc.h" 49#include "xf86Priv.h" 50 51#include "xf86PciInfo.h" 52#include "xf86Pci.h" 53#include "fb.h" 54#define PSZ 8 55/* #include "cfb.h" */ 56#undef PSZ 57/* #include "cfb16.h" */ 58/* #include "cfb32.h" */ 59 60#include "miline.h" 61 62#include "GL/glxtokens.h" 63 64#include "xgi.h" 65#include "xgi_dri.h" 66 67#include "xgi_accel.h" 68#include "xgi_common.h" 69#include "drm.h" 70 71extern void GlxSetVisualConfigs( 72 int nconfigs, 73 __GLXvisualConfig *configs, 74 void **configprivs 75); 76 77#define PCIE_BUS_TYPE 2 78#define AGP_BUS_TYPE 1 79#define PCI_BUS_TYPE 0 80 81#define AGP_PAGE_SIZE 4096 /* Texture memory 8M */ 82/*#define AGP_PAGE_SIZE 5120*/ /* Texture memory 10M */ 83#define AGP_PAGES 2048 84#define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES) 85#define AGP_VTXBUF_PAGES 512 86#define AGP_VTXBUF_SIZE (AGP_PAGE_SIZE * AGP_VTXBUF_PAGES) 87 88/** 89 * Base name of kernel DRM driver. 90 * 91 * Support for XG40 chips is included in the SiS DRM because the DMA and 92 * interrupt handling for the chips is identical. 93 */ 94static const char XGIKernelDriverName[] = "sis"; 95 96static const char XGIClientDriverName[] = "xgi"; 97 98static Bool XGIInitVisualConfigs(ScreenPtr pScreen); 99static Bool XGICreateContext(ScreenPtr pScreen, VisualPtr visual, 100 drm_context_t hwContext, void *pVisualConfigPriv, 101 DRIContextType contextStore); 102static void XGIDestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 103 DRIContextType contextStore); 104static void XGIDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 105 DRIContextType readContextType, 106 void *readContextStore, 107 DRIContextType writeContextType, 108 void *writeContextStore); 109static void XGIDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); 110static void XGIDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 111 RegionPtr prgnSrc, CARD32 index); 112 113void xgiLostContext(ScreenPtr pScreen); 114 115ULONG IsXGIAGPCard(ScreenPtr pScreen); 116ULONG CheckAGPSlot(ScreenPtr pScreen, ULONG uNextLink); 117 118static Bool 119XGIInitVisualConfigs(ScreenPtr pScreen) 120{ 121 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 122 XGIPtr pXGI = XGIPTR(pScrn); 123 int numConfigs = 0; 124 __GLXvisualConfig *pConfigs = 0; 125 XGIConfigPrivPtr pXGIConfigs = 0; 126 XGIConfigPrivPtr *pXGIConfigPtrs = 0; 127 int i, db, z_stencil, accum; 128 Bool useZ16 = FALSE; 129 130 if(getenv("XGI_FORCE_Z16")){ 131 useZ16 = TRUE; 132 } 133 134 switch (pScrn->bitsPerPixel) { 135 case 8: 136 case 24: 137 break; 138 case 16: 139 case 32: 140 numConfigs = (useZ16)?8:16; 141 142 if (!(pConfigs = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig), 143 numConfigs))) { 144 return FALSE; 145 } 146 if (!(pXGIConfigs = (XGIConfigPrivPtr)xnfcalloc(sizeof(XGIConfigPrivRec), 147 numConfigs))) { 148 xfree(pConfigs); 149 return FALSE; 150 } 151 if (!(pXGIConfigPtrs = (XGIConfigPrivPtr*)xnfcalloc(sizeof(XGIConfigPrivPtr), 152 numConfigs))) { 153 xfree(pConfigs); 154 xfree(pXGIConfigs); 155 return FALSE; 156 } 157 for (i=0; i<numConfigs; i++) 158 pXGIConfigPtrs[i] = &pXGIConfigs[i]; 159 160 i = 0; 161 for (accum = 0; accum <= 1; accum++) { 162 for (z_stencil=0; z_stencil<(useZ16?2:4); z_stencil++) { 163 for (db = 0; db <= 1; db++) { 164 pConfigs[i].vid = -1; 165 pConfigs[i].class = -1; 166 pConfigs[i].rgba = TRUE; 167 pConfigs[i].redSize = -1; 168 pConfigs[i].greenSize = -1; 169 pConfigs[i].blueSize = -1; 170 pConfigs[i].redMask = -1; 171 pConfigs[i].greenMask = -1; 172 pConfigs[i].blueMask = -1; 173 pConfigs[i].alphaMask = 0; 174 if (accum) { 175 pConfigs[i].accumRedSize = 16; 176 pConfigs[i].accumGreenSize = 16; 177 pConfigs[i].accumBlueSize = 16; 178 pConfigs[i].accumAlphaSize = 16; 179 } else { 180 pConfigs[i].accumRedSize = 0; 181 pConfigs[i].accumGreenSize = 0; 182 pConfigs[i].accumBlueSize = 0; 183 pConfigs[i].accumAlphaSize = 0; 184 } 185 if (db) 186 pConfigs[i].doubleBuffer = TRUE; 187 else 188 pConfigs[i].doubleBuffer = FALSE; 189 pConfigs[i].stereo = FALSE; 190 pConfigs[i].bufferSize = -1; 191 switch (z_stencil){ 192 case 0: 193 pConfigs[i].depthSize = 0; 194 pConfigs[i].stencilSize = 0; 195 break; 196 case 1: 197 pConfigs[i].depthSize = 16; 198 pConfigs[i].stencilSize = 0; 199 break; 200 case 2: 201 pConfigs[i].depthSize = 32; 202 pConfigs[i].stencilSize = 0; 203 break; 204 case 3: 205 pConfigs[i].depthSize = 24; 206 pConfigs[i].stencilSize = 8; 207 break; 208 } 209 pConfigs[i].auxBuffers = 0; 210 pConfigs[i].level = 0; 211 pConfigs[i].visualRating = GLX_NONE_EXT; 212 pConfigs[i].transparentPixel = 0; 213 pConfigs[i].transparentRed = 0; 214 pConfigs[i].transparentGreen = 0; 215 pConfigs[i].transparentBlue = 0; 216 pConfigs[i].transparentAlpha = 0; 217 pConfigs[i].transparentIndex = 0; 218 i++; 219 } 220 } 221 } 222 if (i != numConfigs) { 223 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 224 "[drm] Incorrect initialization of visuals\n"); 225 return FALSE; 226 } 227 break; 228 } 229 230 pXGI->numVisualConfigs = numConfigs; 231 pXGI->pVisualConfigs = pConfigs; 232 pXGI->pVisualConfigsPriv = pXGIConfigs; 233 GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pXGIConfigPtrs); 234 235 return TRUE; 236} 237 238Bool XGIDRIScreenInit(ScreenPtr pScreen) 239{ 240#ifndef linux 241 return FALSE; 242#else /* linux */ 243 244 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 245 XGIPtr pXGI = XGIPTR(pScrn); 246 DRIInfoPtr pDRIInfo; 247 XGIDRIPtr pXGIDRI; 248 drm_xgi_fb_t fb; 249 int major, minor, patch; 250 drmVersionPtr drm_ver; 251 252 253 /* Check that the GLX, DRI, and DRM modules have been loaded by testing 254 * for canonical symbols in each module. */ 255 if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE; 256 if (!xf86LoaderCheckSymbol("DRIScreenInit")) return FALSE; 257 if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; 258 if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { 259 xf86DrvMsg(pScreen->myNum, X_ERROR, 260 "XGIDRIScreenInit failed (libdri.a too old)\n"); 261 return FALSE; 262 } 263 264 /* Make sure the server's DRI extension version matches the version the 265 * driver was built against. 266 */ 267 DRIQueryVersion(&major, &minor, &patch); 268 if ((major != DRIINFO_MAJOR_VERSION) || (minor < DRIINFO_MINOR_VERSION)) { 269 xf86DrvMsg(pScreen->myNum, X_ERROR, 270 "[drm] XGIDRIScreenInit failed (DRI version = %d.%d.%d, " 271 "expected %d.%d.x). Disabling DRI.\n", 272 major, minor, patch, 273 DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION); 274 return FALSE; 275 } 276 277 pDRIInfo = DRICreateInfoRec(); 278 if (!pDRIInfo) { 279 return FALSE; 280 } 281 282 pXGI->pDRIInfo = pDRIInfo; 283 pDRIInfo->drmDriverName = XGIKernelDriverName; 284 pDRIInfo->clientDriverName = XGIClientDriverName; 285 pDRIInfo->busIdString = DRICreatePCIBusID(pXGI->PciInfo); 286 pDRIInfo->ddxDriverMajorVersion = PACKAGE_VERSION_MAJOR; 287 pDRIInfo->ddxDriverMinorVersion = PACKAGE_VERSION_MINOR; 288 pDRIInfo->ddxDriverPatchVersion = PACKAGE_VERSION_PATCHLEVEL; 289 pDRIInfo->frameBufferPhysicalAddress = pXGI->FbAddress; 290 pDRIInfo->frameBufferSize = pXGI->FbMapSize; 291 292 /* ?? */ 293 pDRIInfo->frameBufferStride = pXGI->scrnOffset; 294 pDRIInfo->ddxDrawableTableEntry = XGI_MAX_DRAWABLES; 295 296 if (SAREA_MAX_DRAWABLES < XGI_MAX_DRAWABLES) 297 pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; 298 else 299 pDRIInfo->maxDrawableTableEntry = XGI_MAX_DRAWABLES; 300 301#ifdef NOT_DONE 302 /* FIXME need to extend DRI protocol to pass this size back to client 303 * for SAREA mapping that includes a device private record 304 */ 305 pDRIInfo->SAREASize = 306 ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */ 307 /* + shared memory device private rec */ 308#else 309 /* For now the mapping works by using a fixed size defined 310 * in the SAREA header 311 */ 312 if (sizeof(XF86DRISAREARec)+sizeof(XGISAREAPriv)>SAREA_MAX) { 313/* ErrorF("Data does not fit in SAREA\n"); */ 314 return FALSE; 315 } 316 pDRIInfo->SAREASize = SAREA_MAX; 317#endif 318 319 if (!(pXGIDRI = (XGIDRIPtr)xnfcalloc(sizeof(XGIDRIRec),1))) { 320 DRIDestroyInfoRec(pXGI->pDRIInfo); 321 pXGI->pDRIInfo=0; 322 return FALSE; 323 } 324 pDRIInfo->devPrivate = pXGIDRI; 325 pDRIInfo->devPrivateSize = sizeof(XGIDRIRec); 326 pDRIInfo->contextSize = sizeof(XGIDRIContextRec); 327 328 pDRIInfo->CreateContext = XGICreateContext; 329 pDRIInfo->DestroyContext = XGIDestroyContext; 330 pDRIInfo->SwapContext = XGIDRISwapContext; 331 pDRIInfo->InitBuffers = XGIDRIInitBuffers; 332 pDRIInfo->MoveBuffers = XGIDRIMoveBuffers; 333 pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; 334 335 if (!DRIScreenInit(pScreen, pDRIInfo, &pXGI->drmSubFD)) { 336 xfree(pDRIInfo->devPrivate); 337 pDRIInfo->devPrivate=0; 338 DRIDestroyInfoRec(pXGI->pDRIInfo); 339 pXGI->pDRIInfo=0; 340 pXGI->drmSubFD = -1; 341 return FALSE; 342 } 343 344 drm_ver = drmGetVersion(pXGI->drmSubFD); 345 if (drm_ver != NULL) { 346 major = drm_ver->version_major; 347 minor = drm_ver->version_minor; 348 patch = drm_ver->version_patchlevel; 349 350 drmFreeVersion(drm_ver); 351 drm_ver = NULL; 352 } 353 else { 354 major = 0; 355 minor = 0; 356 patch = 0; 357 } 358 359 if ((major != 1) || (minor < 3)) { 360 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 361 "[drm] Incorrect kernel module version. Expected 1.3.x, got %d.%d.%d\n", 362 major, minor, patch); 363 364 XGIDRICloseScreen(pScreen); 365 return FALSE; 366 } 367 else { 368 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 369 "[drm] Kernel module version is %d.%d.%d\n", 370 major, minor, patch); 371 } 372 373 pXGIDRI->regs.size = XGIIOMAPSIZE; 374 pXGIDRI->regs.map = 0; 375 if (drmAddMap(pXGI->drmSubFD, (drm_handle_t)pXGI->IOAddress, 376 pXGIDRI->regs.size, DRM_REGISTERS, 0, 377 &pXGIDRI->regs.handle)<0) 378 { 379 XGIDRICloseScreen(pScreen); 380 return FALSE; 381 } 382 383 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08lx\n", 384 (unsigned long) pXGIDRI->regs.handle); 385 386 /* Initialize the framebuffer memory manager. 387 */ 388 fb.offset = pXGI->DRIheapstart; 389 fb.size = pXGI->DRIheapend - pXGI->DRIheapstart; 390 drmCommandWrite(pXGI->drmSubFD, DRM_XGI_FB_INIT, &fb, sizeof(fb)); 391 xf86DrvMsg(pScreen->myNum, X_INFO, 392 "[dri] Video RAM memory heap: 0x%0x to 0x%0x (%dKB)\n", 393 pXGI->DRIheapstart, pXGI->DRIheapend, 394 (int)((pXGI->DRIheapend - pXGI->DRIheapstart) >> 10)); 395 396 397 /* AGP */ 398 do{ 399 pXGI->agpSize = 0; 400 pXGI->agpVtxBufSize = 0; 401 pXGIDRI->AGPVtxBufSize = 0; 402 403 /* jill note: IF not AGP, diable AGP memory allocate */ 404 if (AGP_BUS_TYPE != IsXGIAGPCard(pScreen)) 405 break; 406 407 if (drmAgpAcquire(pXGI->drmSubFD) < 0) { 408 xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed\n"); 409 break; 410 } 411 412 pXGI->agpSize = drmAgpSize(pXGI->drmSubFD); 413 if(pXGI->agpSize==0) 414 { 415 xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpSize =0\n"); 416 break; 417 } 418 419 /* TODO: default value is 2x? */ 420/* if (drmAgpEnable(pXGI->drmSubFD, drmAgpGetMode(pXGI->drmSubFD)&~0x0) < 0) { 421*/ 422 /* Default to 1X agp mode */ 423 if (drmAgpEnable(pXGI->drmSubFD, drmAgpGetMode(pXGI->drmSubFD)&~0x00000002) < 0) { 424 xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpEnable failed\n"); 425 break; 426 } 427/* ErrorF("[drm] drmAgpEnabled succeeded\n"); */ 428 429 if (drmAgpAlloc(pXGI->drmSubFD, pXGI->agpSize, 0, NULL, &pXGI->agpHandle) < 0) { 430 xf86DrvMsg(pScreen->myNum, X_ERROR, 431 "[drm] drmAgpAlloc failed\n"); 432 pXGI->agpSize = 0; 433 drmAgpRelease(pXGI->drmSubFD); 434 break; 435 } 436 437 /* Bind agp-gart table */ 438 /* fill the phys addr. into gart table */ 439 /*********************************************/ 440 if (drmAgpBind(pXGI->drmSubFD, pXGI->agpHandle, 0) < 0) { 441 xf86DrvMsg(pScreen->myNum, X_ERROR, 442 "[drm] drmAgpBind failed\n"); 443 drmAgpFree(pXGI->drmSubFD, pXGI->agpHandle); 444 drmAgpRelease(pXGI->drmSubFD); 445 446 break; 447 } 448 449/* pXGI->agpSize = AGP_SIZE; */ 450 pXGI->agpAddr = drmAgpBase(pXGI->drmSubFD); 451 /* pXGI->agpBase = */ /* Xserver connot access VtxBuf, bc. not mem-map */ 452 453 /* any client can access this VtxBuf AGP area */ 454 /* by mem-map pXGIDRI->agp.handle */ 455 /**********************************************/ 456 pXGIDRI->agp.size = pXGI->agpSize; 457 if (drmAddMap(pXGI->drmSubFD, (drm_handle_t)0, 458 pXGIDRI->agp.size, DRM_AGP, 0, 459 &pXGIDRI->agp.handle) < 0) { 460 xf86DrvMsg(pScreen->myNum, X_ERROR, 461 "[drm] Failed to map public agp area\n"); 462 pXGIDRI->agp.size = 0; 463 break; 464 } 465 466#if 1 /* chiawen : remove this to 3d driver */ 467 pXGI->agpVtxBufSize = AGP_VTXBUF_SIZE; /* 2MB */ 468 pXGI->agpVtxBufAddr = pXGI->agpAddr; 469 pXGI->agpVtxBufBase = pXGI->agpVtxBufAddr - pXGI->agpAddr + 470 pXGI->agpBase; 471 pXGI->agpVtxBufFree = 0; 472 473 pXGIDRI->AGPVtxBufOffset = pXGI->agpVtxBufAddr - pXGI->agpAddr; 474 pXGIDRI->AGPVtxBufSize = pXGI->agpVtxBufSize; 475 476 /* this AGP area is used for texture */ 477 /* is managed by drm */ 478 /*************************************/ 479 { 480 drm_xgi_agp_t agp; 481 482 agp.offset = 0; /* AGP_VTXBUF_SIZE; */ 483 agp.size = pXGI->agpSize; /* AGP_SIZE - AGP_VTXBUF_SIZE; */ 484#ifdef DRM_IOCTL_XGI_AGP_INIT 485 ioctl(pXGI->drmSubFD, DRM_IOCTL_XGI_AGP_INIT, &agp); 486#endif 487#endif 488 } 489 } 490 while(0); 491 492 /* enable IRQ */ 493 pXGI->irq = drmGetInterruptFromBusID(pXGI->drmSubFD, 494#ifdef XSERVER_LIBPCIACCESS 495 ((pXGI->PciInfo->domain << 8) 496 | pXGI->PciInfo->bus), 497 pXGI->PciInfo->dev, 498 pXGI->PciInfo->func 499#else 500 ((pciConfigPtr)pXGI->PciInfo->thisCard)->busnum, 501 ((pciConfigPtr)pXGI->PciInfo->thisCard)->devnum, 502 ((pciConfigPtr)pXGI->PciInfo->thisCard)->funcnum 503#endif 504 ); 505 506 if((drmCtlInstHandler(pXGI->drmSubFD, pXGI->irq)) != 0) 507 { 508 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 509 "[drm] failure adding irq %d handler, stereo disabled\n", 510 pXGI->irq); 511 pXGI->irqEnabled = FALSE; 512 } 513 else 514 { 515 pXGI->irqEnabled = TRUE; 516 } 517 518 pXGIDRI->irqEnabled = pXGI->irqEnabled; 519 520 if (!(XGIInitVisualConfigs(pScreen))) { 521 XGIDRICloseScreen(pScreen); 522 return FALSE; 523 } 524 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "visual configs initialized\n" ); 525 526 return TRUE; 527#endif /* linux */ 528} 529 530void 531XGIDRICloseScreen(ScreenPtr pScreen) 532{ 533 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 534 XGIPtr pXGI = XGIPTR(pScrn); 535 536 DRICloseScreen(pScreen); 537 538 if (pXGI->pDRIInfo) { 539 if (pXGI->pDRIInfo->devPrivate) { 540 xfree(pXGI->pDRIInfo->devPrivate); 541 pXGI->pDRIInfo->devPrivate=0; 542 } 543 DRIDestroyInfoRec(pXGI->pDRIInfo); 544 pXGI->pDRIInfo=0; 545 } 546 if (pXGI->pVisualConfigs) xfree(pXGI->pVisualConfigs); 547 if (pXGI->pVisualConfigsPriv) xfree(pXGI->pVisualConfigsPriv); 548 549 if(pXGI->agpSize){ 550/* ErrorF("Freeing agp memory\n"); */ 551 drmAgpFree(pXGI->drmSubFD, pXGI->agpHandle); 552/* ErrorF("releasing agp module\n"); */ 553 drmAgpRelease(pXGI->drmSubFD); 554 } 555} 556 557/* TODO: xserver receives driver's swapping event and do something 558 * according the data initialized in this function 559 */ 560static Bool 561XGICreateContext(ScreenPtr pScreen, VisualPtr visual, 562 drm_context_t hwContext, void *pVisualConfigPriv, 563 DRIContextType contextStore) 564{ 565 return TRUE; 566} 567 568static void 569XGIDestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 570 DRIContextType contextStore) 571{ 572} 573 574Bool 575XGIDRIFinishScreenInit(ScreenPtr pScreen) 576{ 577 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 578 XGIPtr pXGI = XGIPTR(pScrn); 579/* XGIPtr pXGI = XGIPTR(pScrn); */ 580 XGIDRIPtr pXGIDRI; 581 582 /*pXGI->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;*/ 583 pXGI->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; 584 585 pXGIDRI=(XGIDRIPtr)pXGI->pDRIInfo->devPrivate; 586 pXGIDRI->deviceID=pXGI->Chipset; 587 pXGIDRI->revisionID=pXGI->ChipRev; 588 pXGIDRI->width=pScrn->virtualX; 589 pXGIDRI->height=pScrn->virtualY; 590 pXGIDRI->mem=pScrn->videoRam*1024; 591 pXGIDRI->bytesPerPixel= (pScrn->bitsPerPixel+7) / 8; 592 /* TODO */ 593 pXGIDRI->scrnX=pXGIDRI->width; 594 pXGIDRI->scrnY=pXGIDRI->height; 595 596/* 597 pXGIDRI->textureOffset=pXGI->texOffset; 598 pXGIDRI->textureSize=pXGI->texSize; 599 pXGIDRI->fbOffset=pXGI->fbOffset; 600 pXGIDRI->backOffset=pXGI->backOffset; 601 pXGIDRI->depthOffset=pXGI->depthOffset; 602*/ 603 604 /* set SAREA value */ 605 { 606 XGISAREAPriv *saPriv; 607 608 saPriv=(XGISAREAPriv*)DRIGetSAREAPrivate(pScreen); 609 assert(saPriv); 610 611 saPriv->CtxOwner = -1; 612 saPriv->QueueLength = 0; 613 pXGI->cmdQueueLenPtr = &(saPriv->QueueLength); 614 saPriv->AGPVtxBufNext = 0; 615 616 617 saPriv->shareWPoffset = pXGI->cmdQueue_shareWP_only2D; 618 pXGI->pCQ_shareWritePort = &(saPriv->shareWPoffset); 619 620 621 622 Volari_Idle(pXGI); 623 } 624 625 return DRIFinishScreenInit(pScreen); 626} 627 628static void 629XGIDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 630 DRIContextType oldContextType, void *oldContext, 631 DRIContextType newContextType, void *newContext) 632{ 633 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 634 XGIPtr pXGI = XGIPTR(pScrn); 635 636 /* mEndPrimitive */ 637 /* 638 * TODO: do this only if X-Server get lock. If kernel supports delayed 639 * signal, needless to do this 640 */ 641 /* 642 *(pXGI->IOBase + 0X8B50) = 0xff; 643 *(unsigned int *)(pXGI->IOBase + 0x8B60) = -1; 644 */ 645 646 Volari_Idle(pXGI); 647} 648 649static void 650XGIDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) 651{ 652 ScreenPtr pScreen = pWin->drawable.pScreen; 653 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 654 XGIPtr pXGI = XGIPTR(pScrn); 655 656 Volari_Idle(pXGI); 657} 658 659static void 660XGIDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 661 RegionPtr prgnSrc, CARD32 index) 662{ 663 ScreenPtr pScreen = pParent->drawable.pScreen; 664 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 665 XGIPtr pXGI = XGIPTR(pScrn); 666 667 Volari_Idle(pXGI); 668} 669 670#ifndef XSERVER_LIBPCIACCESS 671/** 672 * Use this function to check AGP slot 673 */ 674ULONG CheckAGPSlot(ScreenPtr pScreen, ULONG uNextLink) 675{ 676 ULONG uBuffer = 0, uLink = 0, uValue = 0 ; 677 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 678 XGIPtr pXGI = XGIPTR(pScrn); 679 680 uBuffer = pciReadLong(pXGI->PciTag, uNextLink); 681 uLink = (uBuffer & 0xff00) >> 8; 682 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s]uBuffer=0x%lx uNextLink=0x%lx, uLink=0x%lx\n", __FUNCTION__, uBuffer, uNextLink, uLink); 683 684 if ((uBuffer & 0xff) != 0x02) 685 { 686 if(uLink) 687 uValue = CheckAGPSlot(pScreen, uLink); 688 else 689 uValue = PCI_BUS_TYPE; 690 } 691 else 692 uValue = AGP_BUS_TYPE; 693 694 return uValue; 695} 696#endif 697 698/** 699 * Use this function to check if the current card is AGP or PCI. 700 */ 701ULONG IsXGIAGPCard(ScreenPtr pScreen) 702{ 703 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 704 XGIPtr pXGI = XGIPTR(pScrn); 705 706 707#ifdef XSERVER_LIBPCIACCESS 708 const struct pci_agp_info *agp_info = 709 pci_device_get_agp_info(pXGI->PciInfo); 710 711 return (agp_info == NULL) ? PCI_BUS_TYPE : AGP_BUS_TYPE; 712#else 713 ULONG u34h = pciReadLong(pXGI->PciTag,0x34); 714 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s] u34h=0x%lx\n", __FUNCTION__, u34h); 715 716 /* This value is read only and the default value should be 0x40; 717 * I have no idea why I should do this */ 718 ULONG uLink = u34h & 0xff; 719 720 if (0 == uLink) 721 { 722 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s] No Next ID, This is a PCI card\n", __FUNCTION__); 723 return PCI_BUS_TYPE; 724 } 725 726 ULONG uType = 0; 727 uType = CheckAGPSlot(pScreen, uLink); 728 729 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s] This Card Type is %ld \n", __FUNCTION__, uType); 730 731 if (uType == PCI_BUS_TYPE) 732 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s] This Card Type is PCI\n", __FUNCTION__); 733 if (uType == AGP_BUS_TYPE) 734 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s] This Card Type is AGP\n", __FUNCTION__); 735 if (uType == PCIE_BUS_TYPE) 736 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s] This Card Type is PCIExpress\n", __FUNCTION__); 737 738 return uType; 739#endif 740} 741