1/* 2 * DRI wrapper for 300 and 315 series 3 * 4 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria 5 * 6 * Preliminary 315/330 support by Thomas Winischhofer 7 * Portions of Mesa 4/5/6 changes by Eric Anholt 8 * 9 * Licensed under the following terms: 10 * 11 * Permission to use, copy, modify, distribute, and sell this software and its 12 * documentation for any purpose is hereby granted without fee, provided that 13 * the above copyright notice appears in all copies and that both that copyright 14 * notice and this permission notice appear in supporting documentation, and 15 * and that the name of the copyright holder not be used in advertising 16 * or publicity pertaining to distribution of the software without specific, 17 * written prior permission. The copyright holder makes no representations 18 * about the suitability of this software for any purpose. It is provided 19 * "as is" without expressed or implied warranty. 20 * 21 * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 22 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 23 * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR 24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 25 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 26 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 27 * PERFORMANCE OF THIS SOFTWARE. 28 * 29 * Previously taken and modified from tdfx_dri.c, mga_dri.c 30 * 31 * Authors: Can-Ru Yeou, SiS Inc. 32 * Alan Hourihane, Wigan, England, 33 * Thomas Winischhofer <thomas@winischhofer.net> 34 * others. 35 */ 36 37#ifdef HAVE_CONFIG_H 38#include "config.h" 39#endif 40 41#include <assert.h> 42 43#include "sis.h" 44#include "sis_regs.h" 45 46#include "fb.h" 47 48#ifndef SISHAVEDRMWRITE 49# if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) 50extern Bool drmSiSAgpInit(int driSubFD, int offset, int size); 51# else 52# include "xf86drmCompat.h" 53# endif 54#endif 55 56#ifdef XORG_VERSION_CURRENT 57#define SISHAVECREATEBUSID 58#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(6,7,99,1,0) 59#ifndef XSERVER_LIBPCIACCESS 60extern char *DRICreatePCIBusID(pciVideoPtr PciInfo); 61#endif 62#endif 63#else 64# if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,4,99,9,0) 65# undef SISHAVECREATEBUSID 66# endif 67#endif 68 69#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,0,0,0) 70#include "sis_common.h" 71#endif 72 73#ifndef DRIINFO_MAJOR_VERSION 74#define DRIINFO_MAJOR_VERSION 4 75#endif 76 77#ifndef DRIINFO_MINOR_VERSION 78#define DRIINFO_MINOR_VERSION 0 79#endif 80 81/* Idle function for 300 series */ 82#define BR(x) (0x8200 | (x) << 2) 83#define SiSIdle \ 84 while((SIS_MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; \ 85 while((SIS_MMIO_IN16(pSiS->IOBase, BR(16)+2) & 0xE000) != 0xE000){}; \ 86 SIS_MMIO_IN16(pSiS->IOBase, 0x8240); 87 88/* Idle function for 315/330/340 series and XGI */ 89#define Q_STATUS 0x85CC 90#define SiS315Idle \ 91 { \ 92 while( (SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ 93 while( (SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ 94 while( (SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ 95 while( (SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ 96 } 97 98/* The kernel's "sis" DRM module handles all chipsets */ 99static char SISKernelDriverName[] = "sis"; 100 101/* The client side DRI drivers are different: */ 102static char SISClientDriverNameSiS300[] = "sis"; /* 300, 540, 630, 730 */ 103static char SISClientDriverNameSiS315[] = "sis315"; /* All of 315/330 series */ 104static char SISClientDriverNameXGI[] = "xgi"; /* XGI V3, V5, V8 */ 105 106static Bool SISCreateContext(ScreenPtr pScreen, VisualPtr visual, 107 drm_context_t hwContext, void *pVisualConfigPriv, 108 DRIContextType contextStore); 109static void SISDestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 110 DRIContextType contextStore); 111static void SISDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 112 DRIContextType readContextType, 113 void *readContextStore, 114 DRIContextType writeContextType, 115 void *writeContextStore); 116static void SISDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); 117static void SISDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 118 RegionPtr prgnSrc, CARD32 index); 119 120Bool 121SISDRIScreenInit(ScreenPtr pScreen) 122{ 123 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 124 SISPtr pSIS = SISPTR(pScrn); 125 DRIInfoPtr pDRIInfo; 126 SISDRIPtr pSISDRI; 127#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,0,0,0) 128 drmVersionPtr version; 129#endif 130 131 pSIS->cmdQueueLenPtrBackup = NULL; 132#ifdef SIS315DRI 133 pSIS->cmdQ_SharedWritePortBackup = NULL; 134#endif 135 136 /* Check that the DRI, and DRM modules have been loaded by testing 137 * for canonical symbols in each module. 138 */ 139 if(!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; 140 if(!xf86LoaderCheckSymbol("DRIQueryVersion")) { 141 xf86DrvMsg(pScreen->myNum, X_ERROR, 142 "[dri] SISDRIScreenInit failed (libdri.a too old). Disabling the DRI.\n"); 143 return FALSE; 144 } 145 146 /* Check the DRI version */ 147 { 148 int major, minor, patch; 149 DRIQueryVersion(&major, &minor, &patch); 150 if(major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) { 151 xf86DrvMsg(pScreen->myNum, X_ERROR, 152 "[dri] SISDRIScreenInit failed because of a version mismatch.\n" 153 "\t[dri] libdri version is %d.%d.%d but version %d.%d.x is needed.\n" 154 "\t[dri] Disabling the DRI.\n", 155 major, minor, patch, DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION); 156 return FALSE; 157 } 158 } 159 160 pDRIInfo = DRICreateInfoRec(); 161 if(!pDRIInfo) return FALSE; 162 pSIS->pDRIInfo = pDRIInfo; 163 164 pDRIInfo->drmDriverName = SISKernelDriverName; 165 if(pSIS->VGAEngine == SIS_300_VGA) { 166 pDRIInfo->clientDriverName = SISClientDriverNameSiS300; 167 } else if(pSIS->ChipFlags & SiSCF_IsXGI) { 168 pDRIInfo->clientDriverName = SISClientDriverNameXGI; 169 } else { 170 pDRIInfo->clientDriverName = SISClientDriverNameSiS315; 171 } 172 173#ifdef SISHAVECREATEBUSID 174 if(xf86LoaderCheckSymbol("DRICreatePCIBusID")) { 175 pDRIInfo->busIdString = DRICreatePCIBusID(pSIS->PciInfo); 176 } else { 177#endif 178 pDRIInfo->busIdString = malloc(64); 179 sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", 180 pSIS->PciBus, pSIS->PciDevice, pSIS->PciFunc); 181#ifdef SISHAVECREATEBUSID 182 } 183#endif 184 185 /* Hack to keep old DRI working -- checked for major==1 and 186 * minor==1. 187 */ 188#ifdef SISNEWDRI 189 pDRIInfo->ddxDriverMajorVersion = SIS_MAJOR_VERSION; 190 pDRIInfo->ddxDriverMinorVersion = SIS_MINOR_VERSION; 191 pDRIInfo->ddxDriverPatchVersion = SIS_PATCHLEVEL; 192#else 193 pDRIInfo->ddxDriverMajorVersion = 0; 194 pDRIInfo->ddxDriverMinorVersion = 1; 195 pDRIInfo->ddxDriverPatchVersion = 0; 196#endif 197 198 /* Strictly for mapping the framebuffer, 199 * NOT for memory management! 200 * Note: For 315/330/340 series, the 201 * framebuffer area also contains 202 * the (non-AGP) command queue, located 203 * at the offset sarea->cmdQueueOffset 204 */ 205#if DRIINFO_MAJOR_VERSION <= 4 206 pDRIInfo->frameBufferPhysicalAddress = pSIS->realFbAddress; 207#else 208 pDRIInfo->frameBufferPhysicalAddress = (pointer)pSIS->realFbAddress; 209#endif 210 pDRIInfo->frameBufferSize = pSIS->FbMapSize; 211 212 /* scrnOffset is being calulated in sis_vga.c */ 213 pDRIInfo->frameBufferStride = pSIS->scrnOffset; 214 215 pDRIInfo->ddxDrawableTableEntry = SIS_MAX_DRAWABLES; 216 217 if(SAREA_MAX_DRAWABLES < SIS_MAX_DRAWABLES) 218 pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; 219 else 220 pDRIInfo->maxDrawableTableEntry = SIS_MAX_DRAWABLES; 221 222#ifdef NOT_DONE 223 /* FIXME need to extend DRI protocol to pass this size back to client 224 * for SAREA mapping that includes a device private record 225 */ 226 pDRIInfo->SAREASize = 227 ((sizeof(XF86DRISAREARec) + getpagesize() - 1) & getpagesize()); /* round to page */ 228 /* ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); */ /* round to page */ 229 /* + shared memory device private rec */ 230#else 231 /* For now the mapping works by using a fixed size defined 232 * in the SAREA header 233 */ 234 if(sizeof(XF86DRISAREARec) + sizeof(SISSAREAPriv) > SAREA_MAX) { 235 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 236 "[dri] Data does not fit in SAREA. Disabling the DRI.\n"); 237 return FALSE; 238 } 239 pDRIInfo->SAREASize = SAREA_MAX; 240#endif 241 242 if(!(pSISDRI = (SISDRIPtr)calloc(sizeof(SISDRIRec), 1))) { 243 DRIDestroyInfoRec(pSIS->pDRIInfo); 244 pSIS->pDRIInfo = 0; 245 return FALSE; 246 } 247 pDRIInfo->devPrivate = pSISDRI; 248 pDRIInfo->devPrivateSize = sizeof(SISDRIRec); 249 pDRIInfo->contextSize = sizeof(SISDRIContextRec); 250 251 pDRIInfo->CreateContext = SISCreateContext; 252 pDRIInfo->DestroyContext = SISDestroyContext; 253 pDRIInfo->SwapContext = SISDRISwapContext; 254 pDRIInfo->InitBuffers = SISDRIInitBuffers; 255 pDRIInfo->MoveBuffers = SISDRIMoveBuffers; 256 pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; 257 258 if(!DRIScreenInit(pScreen, pDRIInfo, &pSIS->drmSubFD)) { 259 xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] DRIScreenInit failed. Disabling the DRI.\n"); 260 free(pDRIInfo->devPrivate); 261 pDRIInfo->devPrivate = 0; 262 DRIDestroyInfoRec(pSIS->pDRIInfo); 263 pSIS->pDRIInfo = 0; 264 pSIS->drmSubFD = -1; 265 return FALSE; 266 } 267 268#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,0,0,0) 269 /* Check DRM kernel version */ 270 version = drmGetVersion(pSIS->drmSubFD); 271 if(version) { 272 if((version->version_major != 1) || 273 (version->version_minor < 0)) { 274 /* incompatible drm version */ 275 xf86DrvMsg(pScreen->myNum, X_ERROR, 276 "[dri] SISDRIScreenInit failed because of a version mismatch.\n" 277 "\t[dri] sis DRM kernel module version is %d.%d.%d but version >=1.0.x\n" 278 "\t[dri] is needed. Disabling the DRI.\n", 279 version->version_major, 280 version->version_minor, 281 version->version_patchlevel); 282 drmFreeVersion(version); 283 SISDRICloseScreen(pScreen); 284 return FALSE; 285 } 286 if(version->version_minor >= 1) { 287 /* Includes support for framebuffer memory allocation without sisfb */ 288 drm_sis_fb_t fb; 289 fb.offset = pSIS->DRIheapstart; 290 fb.size = pSIS->DRIheapend - pSIS->DRIheapstart; 291 drmCommandWrite(pSIS->drmSubFD, DRM_SIS_FB_INIT, &fb, sizeof(fb)); 292 xf86DrvMsg(pScreen->myNum, X_INFO, 293 "[dri] Video RAM memory heap: 0x%0x to 0x%0x (%dKB)\n", 294 pSIS->DRIheapstart, pSIS->DRIheapend, 295 (int)((pSIS->DRIheapend - pSIS->DRIheapstart) >> 10)); 296 } 297 drmFreeVersion(version); 298 } 299#endif 300 301 /* MMIO */ 302 pSISDRI->regs.size = SISIOMAPSIZE; 303#ifndef SISISXORG6899900 304 pSISDRI->regs.map = 0; 305#endif 306 if(drmAddMap(pSIS->drmSubFD, (drm_handle_t)pSIS->IOAddress, 307 pSISDRI->regs.size, DRM_REGISTERS, 0, 308 &pSISDRI->regs.handle) < 0) { 309 SISDRICloseScreen(pScreen); 310 return FALSE; 311 } 312 313 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] MMIO registers mapped to 0x%0x\n", 314 pSISDRI->regs.handle); 315 316 /* AGP */ 317 do { 318 319 unsigned long agpmodemask = 0; 320 321 pSIS->agpWantedSize = pSIS->agpWantedPages * AGP_PAGE_SIZE; 322 pSIS->agpSize = 0; 323 pSIS->agpCmdBufSize = 0; 324 pSISDRI->AGPCmdBufSize = 0; 325 326 if(!pSIS->IsAGPCard) 327 break; 328 329 if(drmAgpAcquire(pSIS->drmSubFD) < 0) { 330 xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Failed to acquire AGP, AGP disabled\n"); 331 break; 332 } 333 334 switch(pSIS->VGAEngine) { 335#ifdef SIS315DRI 336 case SIS_315_VGA: 337 /* Default to 1X agp mode in SIS315 */ 338 agpmodemask = ~0x00000002; 339 break; 340#endif 341 case SIS_300_VGA: 342 /* TODO: default value is 2x? */ 343 agpmodemask = ~0x0; 344 break; 345 } 346 347 if(drmAgpEnable(pSIS->drmSubFD, drmAgpGetMode(pSIS->drmSubFD) & agpmodemask) < 0) { 348 xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Failed to enable AGP, AGP disabled\n"); 349 break; 350 } 351 352 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] AGP enabled\n"); 353 354#define AGP_DEFAULT_SIZE_MB 8 355#define AGP_DEFAULT_SIZE (AGP_DEFAULT_SIZE_MB * 1024 * 1024) 356 357 if(drmAgpAlloc(pSIS->drmSubFD, pSIS->agpWantedSize, 0, NULL, &pSIS->agpHandle) < 0) { 358 359 xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Failed to allocate %dMB AGP memory\n", 360 (int)(pSIS->agpWantedSize / (1024 * 1024))); 361 362 if(pSIS->agpWantedSize > AGP_DEFAULT_SIZE) { 363 364 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Retrying with %dMB\n", AGP_DEFAULT_SIZE_MB); 365 366 pSIS->agpWantedSize = AGP_DEFAULT_SIZE; 367 368 if(drmAgpAlloc(pSIS->drmSubFD, pSIS->agpWantedSize, 0, NULL, &pSIS->agpHandle) < 0) { 369 xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Failed to allocate %dMB AGP memory, AGP disabled\n", 370 AGP_DEFAULT_SIZE_MB); 371 drmAgpRelease(pSIS->drmSubFD); 372 break; 373 } 374 375 } else { 376 377 drmAgpRelease(pSIS->drmSubFD); 378 break; 379 380 } 381 382 } 383 384 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Allocated %dMB AGP memory\n", 385 (int)(pSIS->agpWantedSize / (1024 * 1024))); 386 387 if(drmAgpBind(pSIS->drmSubFD, pSIS->agpHandle, 0) < 0) { 388 389 xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Failed to bind AGP memory\n"); 390 drmAgpFree(pSIS->drmSubFD, pSIS->agpHandle); 391 392 if(pSIS->agpWantedSize > AGP_DEFAULT_SIZE) { 393 394 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Retrying with %dMB\n", AGP_DEFAULT_SIZE_MB); 395 pSIS->agpWantedSize = AGP_DEFAULT_SIZE; 396 397 if(drmAgpAlloc(pSIS->drmSubFD, pSIS->agpWantedSize, 0, NULL, &pSIS->agpHandle) < 0) { 398 399 xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Failed to re-allocate AGP memory, AGP disabled\n"); 400 drmAgpRelease(pSIS->drmSubFD); 401 break; 402 403 } else if(drmAgpBind(pSIS->drmSubFD, pSIS->agpHandle, 0) < 0) { 404 405 xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Failed to bind AGP memory again, AGP disabled\n"); 406 drmAgpFree(pSIS->drmSubFD, pSIS->agpHandle); 407 drmAgpRelease(pSIS->drmSubFD); 408 break; 409 410 } 411 412 } else { 413 414 drmAgpRelease(pSIS->drmSubFD); 415 break; 416 417 } 418 419 } 420 421 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Bound %dMB AGP memory\n", 422 (int)(pSIS->agpWantedSize / (1024 * 1024))); 423 424 pSIS->agpSize = pSIS->agpWantedSize; 425 pSIS->agpAddr = drmAgpBase(pSIS->drmSubFD); 426 /* pSIS->agpBase = */ 427 428 pSISDRI->agp.size = pSIS->agpSize; 429 if(drmAddMap(pSIS->drmSubFD, (drm_handle_t)0, pSISDRI->agp.size, DRM_AGP, 0, &pSISDRI->agp.handle) < 0) { 430 xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Failed to map public AGP area, AGP disabled\n"); 431 drmAgpUnbind(pSIS->drmSubFD, pSIS->agpHandle); 432 drmAgpFree(pSIS->drmSubFD, pSIS->agpHandle); 433 drmAgpRelease(pSIS->drmSubFD); 434 pSIS->agpSize = pSISDRI->agp.size = 0; 435 break; 436 } 437 438 switch(pSIS->VGAEngine) { 439#ifdef SIS315DRI 440 case SIS_315_VGA: 441 pSIS->agpVtxBufSize = AGP_VTXBUF_SIZE; /* = 2MB */ 442 pSIS->agpVtxBufAddr = pSIS->agpAddr; 443 pSIS->agpVtxBufBase = pSIS->agpVtxBufAddr - pSIS->agpAddr + pSIS->agpBase; 444 pSIS->agpVtxBufFree = 0; 445 446 pSISDRI->AGPVtxBufOffset = pSIS->agpVtxBufAddr - pSIS->agpAddr; 447 pSISDRI->AGPVtxBufSize = pSIS->agpVtxBufSize; 448 449#ifndef SISHAVEDRMWRITE 450 drmSiSAgpInit(pSIS->drmSubFD, AGP_VTXBUF_SIZE, (pSIS->agpSize - AGP_VTXBUF_SIZE)); 451#else 452 { 453 drm_sis_agp_t agp; 454 455 agp.offset = AGP_VTXBUF_SIZE; 456 agp.size = pSIS->agpSize - AGP_VTXBUF_SIZE; 457 drmCommandWrite(pSIS->drmSubFD, DRM_SIS_AGP_INIT, &agp, sizeof(agp)); 458 } 459 460#endif 461 break; 462#endif 463 case SIS_300_VGA: 464 pSIS->agpCmdBufSize = AGP_CMDBUF_SIZE; 465 pSIS->agpCmdBufAddr = pSIS->agpAddr; 466 pSIS->agpCmdBufBase = pSIS->agpCmdBufAddr - pSIS->agpAddr + pSIS->agpBase; 467 pSIS->agpCmdBufFree = 0; 468 469 pSISDRI->AGPCmdBufOffset = pSIS->agpCmdBufAddr - pSIS->agpAddr; 470 pSISDRI->AGPCmdBufSize = pSIS->agpCmdBufSize; 471 472#ifndef SISHAVEDRMWRITE 473 drmSiSAgpInit(pSIS->drmSubFD, AGP_CMDBUF_SIZE, (pSIS->agpSize - AGP_CMDBUF_SIZE)); 474#else 475 { 476 drm_sis_agp_t agp; 477 478 agp.offset = AGP_CMDBUF_SIZE; 479 agp.size = pSIS->agpSize - AGP_CMDBUF_SIZE; 480 drmCommandWrite(pSIS->drmSubFD, DRM_SIS_AGP_INIT, &agp, sizeof(agp)); 481 } 482#endif 483 break; 484 } 485 } while(0); 486 487 /* Eventually grab and enable IRQ */ 488 pSIS->irqEnabled = FALSE; 489 pSIS->irq = drmGetInterruptFromBusID(pSIS->drmSubFD, 490 pSIS->PciBus, pSIS->PciDevice, pSIS->PciFunc); 491 492 if(pSIS->irq < 0) { 493 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 494 "[drm] No valid IRQ number for device %d:%d:%d (code %d)\n", 495 pSIS->PciBus, pSIS->PciDevice, pSIS->PciFunc, 496 pSIS->irq); 497 } else if((drmCtlInstHandler(pSIS->drmSubFD, pSIS->irq)) != 0) { 498 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 499 "[drm] Failed to add IRQ %d handler\n", 500 pSIS->irq); 501 } else { 502 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 503 "[drm] Successfully installed handler for IRQ %d\n", 504 pSIS->irq); 505 pSIS->irqEnabled = TRUE; 506 } 507 508 pSISDRI->irqEnabled = pSIS->irqEnabled; 509 510 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Visual configs initialized\n" ); 511 512 return TRUE; 513} 514 515Bool 516SISDRIFinishScreenInit(ScreenPtr pScreen) 517{ 518 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 519 SISPtr pSiS = SISPTR(pScrn); 520 SISDRIPtr pSISDRI; 521 522 pSiS->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; 523 /* pSiS->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */ 524 525 pSISDRI = (SISDRIPtr)pSiS->pDRIInfo->devPrivate; 526 pSISDRI->deviceID = pSiS->Chipset; 527#ifdef SIS315DRI 528 pSISDRI->deviceRev= pSiS->ChipRev; 529#endif 530 pSISDRI->width = pScrn->virtualX; 531 pSISDRI->height = pScrn->virtualY; 532 pSISDRI->mem = pScrn->videoRam * 1024; 533 pSISDRI->bytesPerPixel = (pScrn->bitsPerPixel+7) / 8; 534 535 /* TODO */ 536 pSISDRI->scrnX = pSISDRI->width; 537 pSISDRI->scrnY = pSISDRI->height; 538 539 /* Offset of the front buffer (relative from beginning 540 * of video RAM). This is usually 0, but eventually not 541 * if running on a SiS76x with LFB and UMA memory. 542 * THE DRI DRIVER DOES NOT USE THIS YET (MESA 6.2.1) 543 */ 544 pSISDRI->fbOffset = pSiS->FbBaseOffset; 545 546 /* These are unused. Offsets are set up by the DRI */ 547 pSISDRI->textureOffset = 0; 548 pSISDRI->textureSize = 0; 549 pSISDRI->backOffset = 0; 550 pSISDRI->depthOffset = 0; 551 552 /* set SAREA value */ 553 { 554 SISSAREAPriv *saPriv; 555 556 saPriv = (SISSAREAPriv *)DRIGetSAREAPrivate(pScreen); 557 558 assert(saPriv); 559 560 saPriv->CtxOwner = -1; 561 562 switch(pSiS->VGAEngine) { 563 564#ifdef SIS315DRI 565 case SIS_315_VGA: 566 saPriv->AGPVtxBufNext = 0; 567 568 saPriv->QueueLength = pSiS->cmdQueueSize; /* Total (not: current) size, in bytes! */ 569 570 /* Copy current queue position to sarea */ 571 saPriv->sharedWPoffset = *(pSiS->cmdQ_SharedWritePort); 572 /* Delegate our shared offset to current queue position */ 573 pSiS->cmdQ_SharedWritePortBackup = pSiS->cmdQ_SharedWritePort; 574 pSiS->cmdQ_SharedWritePort = &(saPriv->sharedWPoffset); 575 576 saPriv->cmdQueueOffset = pSiS->cmdQueueOffset; 577 578 /* TODO: Reset frame control */ 579 580 break; 581#endif 582 583 case SIS_300_VGA: 584 saPriv->AGPCmdBufNext = 0; 585 586 /* Delegate our shared pointer to current queue length */ 587 saPriv->QueueLength = *(pSiS->cmdQueueLenPtr); 588 pSiS->cmdQueueLenPtrBackup = pSiS->cmdQueueLenPtr; 589 pSiS->cmdQueueLenPtr = &(saPriv->QueueLength); 590 591 /* frame control */ 592 saPriv->FrameCount = 0; 593 *(CARD32 *)(pSiS->IOBase+0x8a2c) = 0; 594 SiSIdle 595 break; 596 } 597 } 598 599 return DRIFinishScreenInit(pScreen); 600} 601 602void 603SISDRICloseScreen(ScreenPtr pScreen) 604{ 605 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 606 SISPtr pSIS = SISPTR(pScrn); 607 608 switch(pSIS->VGAEngine) { 609#ifdef SIS315DRI 610 case SIS_315_VGA: 611 if(pSIS->cmdQ_SharedWritePortBackup) { 612 /* Re-instate our shared offset to current queue position */ 613 pSIS->cmdQ_SharedWritePort_2D = *(pSIS->cmdQ_SharedWritePort); 614 pSIS->cmdQ_SharedWritePort = pSIS->cmdQ_SharedWritePortBackup; 615 pSIS->cmdQ_SharedWritePortBackup = 0; 616 } 617 break; 618#endif 619 case SIS_300_VGA: 620 if(pSIS->cmdQueueLenPtrBackup) { 621 /* Re-instate our shared pointer to current queue length */ 622 pSIS->cmdQueueLenPtr = pSIS->cmdQueueLenPtrBackup; 623 *(pSIS->cmdQueueLenPtr) = 0; 624 } 625 break; 626 } 627 628 if(pSIS->irqEnabled) { 629 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Removing IRQ handler\n"); 630 drmCtlUninstHandler(pSIS->drmSubFD); 631 pSIS->irqEnabled = FALSE; 632 pSIS->irq = 0; 633 } 634 635 if(pSIS->agpSize){ 636 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Freeing AGP memory\n"); 637 drmAgpUnbind(pSIS->drmSubFD, pSIS->agpHandle); 638 drmAgpFree(pSIS->drmSubFD, pSIS->agpHandle); 639 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Releasing AGP module\n"); 640 drmAgpRelease(pSIS->drmSubFD); 641 pSIS->agpSize = 0; 642 } 643 644 DRICloseScreen(pScreen); 645 646 if(pSIS->pDRIInfo) { 647 if(pSIS->pDRIInfo->devPrivate) { 648 free(pSIS->pDRIInfo->devPrivate); 649 pSIS->pDRIInfo->devPrivate = NULL; 650 } 651 DRIDestroyInfoRec(pSIS->pDRIInfo); 652 pSIS->pDRIInfo = NULL; 653 } 654 655} 656 657/* TODO: xserver receives driver's swapping event and do something 658 * according the data initialized in this function 659 */ 660static Bool 661SISCreateContext(ScreenPtr pScreen, VisualPtr visual, 662 drm_context_t hwContext, void *pVisualConfigPriv, 663 DRIContextType contextStore) 664{ 665 return TRUE; 666} 667 668static void 669SISDestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 670 DRIContextType contextStore) 671{ 672} 673 674static void 675SISDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 676 DRIContextType oldContextType, void *oldContext, 677 DRIContextType newContextType, void *newContext) 678{ 679 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 680 SISPtr pSiS = SISPTR(pScrn); 681 682#if 0 683 if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) && 684 (newContextType==DRI_2D_CONTEXT)) { /* Entering from Wakeup */ 685 SISSwapContextPrivate(pScreen); 686 } 687 if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) && 688 (newContextType==DRI_2D_CONTEXT)) { /* Exiting from Block Handler */ 689 SISLostContext(pScreen); 690 } 691#endif 692 693 /* mEndPrimitive */ 694 /* 695 * TODO: do this only if X-Server get lock. If kernel supports delayed 696 * signal, needless to do this 697 */ 698 switch(pSiS->VGAEngine) { 699#ifdef SIS315DRI 700 case SIS_315_VGA: 701 /* ? */ 702 break; 703#endif 704 case SIS_300_VGA: 705 *((unsigned char *)pSiS->IOBase + 0x8B50) = 0xff; 706 *(CARD32 *)(pSiS->IOBase + 0x8B60) = 0xffffffff; 707 break; 708 } 709} 710 711static void 712SISDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) 713{ 714 ScreenPtr pScreen = pWin->drawable.pScreen; 715 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 716 SISPtr pSiS = SISPTR(pScrn); 717 718 switch(pSiS->VGAEngine) { 719#ifdef SIS315DRI 720 case SIS_315_VGA: 721 SiS315Idle 722 break; 723#endif 724 case SIS_300_VGA: 725 SiSIdle 726 break; 727 } 728} 729 730static void 731SISDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 732 RegionPtr prgnSrc, CARD32 index) 733{ 734 ScreenPtr pScreen = pParent->drawable.pScreen; 735 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 736 SISPtr pSiS = SISPTR(pScrn); 737 738 switch(pSiS->VGAEngine) { 739#ifdef SIS315DRI 740 case SIS_315_VGA: 741 SiS315Idle 742 break; 743#endif 744 case SIS_300_VGA: 745 SiSIdle 746 break; 747 } 748} 749 750#if 0 751void SISLostContext(ScreenPtr pScreen) 752{ 753} 754 755void SISSwapContextPrivate(ScreenPtr pScreen) 756{ 757} 758#endif 759 760 761 762