nv_driver.c revision 22d74663
1/* 2 * Copyright 1996-1997 David J. McKay 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 */ 22 23#include <stdio.h> 24#include <fcntl.h> 25 26#include "nv_include.h" 27 28#include "xorg-server.h" 29#include "xf86drm.h" 30#include "xf86drmMode.h" 31#include "nouveau_drm.h" 32#ifdef DRI2 33#include "dri2.h" 34#endif 35 36#include "nouveau_copy.h" 37#include "nouveau_present.h" 38#include "nouveau_sync.h" 39 40#if !HAVE_XORG_LIST 41#define xorg_list_is_empty list_is_empty 42#define xorg_list_for_each_entry list_for_each_entry 43#endif 44 45/* 46 * Forward definitions for the functions that make up the driver. 47 */ 48/* Mandatory functions */ 49static const OptionInfoRec * NVAvailableOptions(int chipid, int busid); 50static void NVIdentify(int flags); 51static Bool NVPreInit(ScrnInfoPtr pScrn, int flags); 52static Bool NVScreenInit(SCREEN_INIT_ARGS_DECL); 53static Bool NVEnterVT(VT_FUNC_ARGS_DECL); 54static void NVLeaveVT(VT_FUNC_ARGS_DECL); 55static Bool NVCloseScreen(CLOSE_SCREEN_ARGS_DECL); 56static Bool NVSaveScreen(ScreenPtr pScreen, int mode); 57static void NVCloseDRM(ScrnInfoPtr); 58 59/* Optional functions */ 60static Bool NVDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op, 61 void *data); 62static Bool NVSwitchMode(SWITCH_MODE_ARGS_DECL); 63static void NVAdjustFrame(ADJUST_FRAME_ARGS_DECL); 64static void NVFreeScreen(FREE_SCREEN_ARGS_DECL); 65 66/* Internally used functions */ 67 68static Bool NVMapMem(ScrnInfoPtr pScrn); 69static Bool NVUnmapMem(ScrnInfoPtr pScrn); 70 71#define NOUVEAU_PCI_DEVICE(_vendor_id, _device_id) \ 72 { (_vendor_id), (_device_id), PCI_MATCH_ANY, PCI_MATCH_ANY, \ 73 0x00030000, 0x00ff0000, 0 } 74 75static const struct pci_id_match nouveau_device_match[] = { 76 NOUVEAU_PCI_DEVICE(0x12d2, PCI_MATCH_ANY), 77 NOUVEAU_PCI_DEVICE(0x10de, PCI_MATCH_ANY), 78 { 0, 0, 0 }, 79}; 80 81static Bool NVPciProbe ( DriverPtr drv, 82 int entity_num, 83 struct pci_device *dev, 84 intptr_t match_data ); 85 86#ifdef XSERVER_PLATFORM_BUS 87static Bool NVPlatformProbe(DriverPtr driver, 88 int entity_num, int flags, 89 struct xf86_platform_device *dev, 90 intptr_t dev_match_data); 91#endif 92 93_X_EXPORT int NVEntityIndex = -1; 94 95static int getNVEntityIndex(void) 96{ 97 return NVEntityIndex; 98} 99 100/* 101 * This contains the functions needed by the server after loading the 102 * driver module. It must be supplied, and gets added the driver list by 103 * the Module Setup funtion in the dynamic case. In the static case a 104 * reference to this is compiled in, and this requires that the name of 105 * this DriverRec be an upper-case version of the driver name. 106 */ 107 108_X_EXPORT DriverRec NV = { 109 NV_VERSION, 110 NV_DRIVER_NAME, 111 NVIdentify, 112 NULL, 113 NVAvailableOptions, 114 NULL, 115 0, 116 NVDriverFunc, 117 nouveau_device_match, 118 NVPciProbe, 119#ifdef XSERVER_PLATFORM_BUS 120 NVPlatformProbe, 121#endif 122}; 123 124struct NvFamily 125{ 126 char *name; 127 char *chipset; 128}; 129 130static struct NvFamily NVKnownFamilies[] = 131{ 132 { "RIVA TNT", "NV04" }, 133 { "RIVA TNT2", "NV05" }, 134 { "GeForce 256", "NV10" }, 135 { "GeForce 2", "NV11, NV15" }, 136 { "GeForce 4MX", "NV17, NV18" }, 137 { "GeForce 3", "NV20" }, 138 { "GeForce 4Ti", "NV25, NV28" }, 139 { "GeForce FX", "NV3x" }, 140 { "GeForce 6", "NV4x" }, 141 { "GeForce 7", "G7x" }, 142 { "GeForce 8", "G8x" }, 143 { "GeForce 9", "G9x" }, 144 { "GeForce GTX 2xx/3xx", "GT2xx" }, 145 { "GeForce GTX 4xx/5xx", "GFxxx" }, 146 { "GeForce GTX 6xx/7xx", "GKxxx" }, 147 { "GeForce GTX 9xx", "GMxxx" }, 148 { "GeForce GTX 10xx", "GPxxx" }, 149 { NULL, NULL} 150}; 151 152static MODULESETUPPROTO(nouveauSetup); 153 154static XF86ModuleVersionInfo nouveauVersRec = 155{ 156 "nouveau", 157 MODULEVENDORSTRING, 158 MODINFOSTRING1, 159 MODINFOSTRING2, 160 XORG_VERSION_CURRENT, 161 PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, 162 ABI_CLASS_VIDEODRV, /* This is a video driver */ 163 ABI_VIDEODRV_VERSION, 164 MOD_CLASS_VIDEODRV, 165 {0,0,0,0} 166}; 167 168_X_EXPORT XF86ModuleData nouveauModuleData = { &nouveauVersRec, nouveauSetup, NULL }; 169 170static pointer 171nouveauSetup(pointer module, pointer opts, int *errmaj, int *errmin) 172{ 173 static Bool setupDone = FALSE; 174 175 /* This module should be loaded only once, but check to be sure. */ 176 177 if (!setupDone) { 178 setupDone = TRUE; 179 /* The 1 here is needed to turn off a backwards compatibility mode */ 180 /* Otherwise NVPciProbe() is not called */ 181 xf86AddDriver(&NV, module, 1); 182 183 /* 184 * The return value must be non-NULL on success even though there 185 * is no TearDownProc. 186 */ 187 return (pointer)1; 188 } else { 189 if (errmaj) *errmaj = LDR_ONCEONLY; 190 return NULL; 191 } 192} 193 194static const OptionInfoRec * 195NVAvailableOptions(int chipid, int busid) 196{ 197 return NVOptions; 198} 199 200/* Mandatory */ 201static void 202NVIdentify(int flags) 203{ 204 struct NvFamily *family; 205 size_t maxLen=0; 206 207 xf86DrvMsg(0, X_INFO, NV_NAME " driver " NV_DRIVER_DATE "\n"); 208 xf86DrvMsg(0, X_INFO, NV_NAME " driver for NVIDIA chipset families :\n"); 209 210 /* maximum length for alignment */ 211 family = NVKnownFamilies; 212 while(family->name && family->chipset) 213 { 214 maxLen = max(maxLen, strlen(family->name)); 215 family++; 216 } 217 218 /* display */ 219 family = NVKnownFamilies; 220 while(family->name && family->chipset) 221 { 222 size_t len = strlen(family->name); 223 xf86ErrorF("\t%s", family->name); 224 while(len<maxLen+1) 225 { 226 xf86ErrorF(" "); 227 len++; 228 } 229 xf86ErrorF("(%s)\n", family->chipset); 230 family++; 231 } 232} 233 234static Bool 235NVDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data) 236{ 237 xorgHWFlags *flag; 238 239 switch (op) { 240 case GET_REQUIRED_HW_INTERFACES: 241 flag = (CARD32 *)data; 242 (*flag) = 0; 243 return TRUE; 244#if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,15,99,0,0) 245 case SUPPORTS_SERVER_FDS: 246 return TRUE; 247#endif 248 default: 249 return FALSE; 250 } 251} 252 253static void 254NVInitScrn(ScrnInfoPtr pScrn, struct xf86_platform_device *platform_dev, 255 int entity_num) 256{ 257 DevUnion *pPriv; 258 NVEntPtr pNVEnt; 259 260 pScrn->driverVersion = NV_VERSION; 261 pScrn->driverName = NV_DRIVER_NAME; 262 pScrn->name = NV_NAME; 263 264 pScrn->Probe = NULL; 265 pScrn->PreInit = NVPreInit; 266 pScrn->ScreenInit = NVScreenInit; 267 pScrn->SwitchMode = NVSwitchMode; 268 pScrn->AdjustFrame = NVAdjustFrame; 269 pScrn->EnterVT = NVEnterVT; 270 pScrn->LeaveVT = NVLeaveVT; 271 pScrn->FreeScreen = NVFreeScreen; 272 273 xf86SetEntitySharable(entity_num); 274 if (NVEntityIndex == -1) 275 NVEntityIndex = xf86AllocateEntityPrivateIndex(); 276 277 pPriv = xf86GetEntityPrivate(entity_num, 278 NVEntityIndex); 279 if (!pPriv->ptr) { 280 pPriv->ptr = xnfcalloc(sizeof(NVEntRec), 1); 281 pNVEnt = pPriv->ptr; 282 pNVEnt->platform_dev = platform_dev; 283 } 284 else 285 pNVEnt = pPriv->ptr; 286 287 /* Reset settings which must not persist across server regeneration */ 288 if (pNVEnt->reinitGeneration != serverGeneration) { 289 pNVEnt->reinitGeneration = serverGeneration; 290 /* Clear mask of assigned crtc's in this generation to "none" */ 291 pNVEnt->assigned_crtcs = 0; 292 } 293 294 xf86SetEntityInstanceForScreen(pScrn, entity_num, 295 xf86GetNumEntityInstances(entity_num) - 1); 296} 297 298static struct nouveau_device * 299NVOpenNouveauDevice(struct pci_device *pci_dev, 300 struct xf86_platform_device *platform_dev, int scrnIndex, Bool probe) 301{ 302 struct nouveau_device *dev = NULL; 303 char *busid; 304 int ret, fd = -1; 305 306#ifdef ODEV_ATTRIB_PATH 307 if (platform_dev) 308 busid = NULL; 309 else 310#endif 311 { 312#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,9,99,901,0) 313 XNFasprintf(&busid, "pci:%04x:%02x:%02x.%d", 314 pci_dev->domain, pci_dev->bus, 315 pci_dev->dev, pci_dev->func); 316#else 317 busid = XNFprintf("pci:%04x:%02x:%02x.%d", 318 pci_dev->domain, pci_dev->bus, 319 pci_dev->dev, pci_dev->func); 320#endif 321 } 322 323#if defined(ODEV_ATTRIB_FD) 324 if (platform_dev) 325 fd = xf86_get_platform_device_int_attrib(platform_dev, 326 ODEV_ATTRIB_FD, -1); 327#endif 328 if (fd != -1) 329 ret = nouveau_device_wrap(fd, 0, &dev); 330#ifdef ODEV_ATTRIB_PATH 331 else if (platform_dev) { 332 const char *path; 333 334 path = xf86_get_platform_device_attrib(platform_dev, 335 ODEV_ATTRIB_PATH); 336 337 fd = open(path, O_RDWR | O_CLOEXEC); 338 ret = nouveau_device_wrap(fd, 1, &dev); 339 if (ret) 340 close(fd); 341 } 342#endif 343 else 344 ret = nouveau_device_open(busid, &dev); 345 if (ret) 346 xf86DrvMsg(scrnIndex, X_ERROR, 347 "[drm] Failed to open DRM device for %s: %d\n", 348 busid, ret); 349 350 free(busid); 351 return dev; 352} 353 354static Bool 355NVHasKMS(struct pci_device *pci_dev, struct xf86_platform_device *platform_dev) 356{ 357 struct nouveau_device *dev = NULL; 358 drmVersion *version; 359 int chipset; 360 361 dev = NVOpenNouveauDevice(pci_dev, platform_dev, -1, TRUE); 362 if (!dev) 363 return FALSE; 364 365 /* Check the version reported by the kernel module. In theory we 366 * shouldn't have to do this, as libdrm_nouveau will do its own checks. 367 * But, we're currently using the kernel patchlevel to also version 368 * the DRI interface. 369 */ 370 version = drmGetVersion(dev->fd); 371 xf86DrvMsg(-1, X_INFO, "[drm] nouveau interface version: %d.%d.%d\n", 372 version->version_major, version->version_minor, 373 version->version_patchlevel); 374 drmFree(version); 375 376 chipset = dev->chipset; 377 nouveau_device_del(&dev); 378 379 380 switch (chipset & ~0xf) { 381 case 0x00: 382 case 0x10: 383 case 0x20: 384 case 0x30: 385 case 0x40: 386 case 0x60: 387 case 0x50: 388 case 0x80: 389 case 0x90: 390 case 0xa0: 391 case 0xc0: 392 case 0xd0: 393 case 0xe0: 394 case 0xf0: 395 case 0x100: 396 case 0x110: 397 case 0x120: 398 case 0x130: 399 break; 400 default: 401 xf86DrvMsg(-1, X_ERROR, "Unknown chipset: NV%02X\n", chipset); 402 return FALSE; 403 } 404 return TRUE; 405} 406 407static Bool 408NVPciProbe(DriverPtr drv, int entity_num, struct pci_device *pci_dev, 409 intptr_t match_data) 410{ 411 PciChipsets NVChipsets[] = { 412 { pci_dev->device_id, 413 (pci_dev->vendor_id << 16) | pci_dev->device_id, NULL }, 414 { -1, -1, NULL } 415 }; 416 ScrnInfoPtr pScrn = NULL; 417 418 if (!NVHasKMS(pci_dev, NULL)) 419 return FALSE; 420 421 pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, NVChipsets, 422 NULL, NULL, NULL, NULL, NULL); 423 if (!pScrn) 424 return FALSE; 425 426 NVInitScrn(pScrn, NULL, entity_num); 427 428 return TRUE; 429} 430 431#ifdef XSERVER_PLATFORM_BUS 432static Bool 433NVPlatformProbe(DriverPtr driver, 434 int entity_num, int flags, struct xf86_platform_device *dev, intptr_t dev_match_data) 435{ 436 ScrnInfoPtr scrn = NULL; 437 uint32_t scr_flags = 0; 438 439 if (!NVHasKMS(dev->pdev, dev)) 440 return FALSE; 441 442 if (flags & PLATFORM_PROBE_GPU_SCREEN) 443 scr_flags = XF86_ALLOCATE_GPU_SCREEN; 444 445 scrn = xf86AllocateScreen(driver, scr_flags); 446 if (!scrn) 447 return FALSE; 448 449 if (xf86IsEntitySharable(entity_num)) 450 xf86SetEntityShared(entity_num); 451 xf86AddEntityToScreen(scrn, entity_num); 452 453 NVInitScrn(scrn, dev, entity_num); 454 455 return TRUE; 456} 457#endif 458 459#define MAX_CHIPS MAXSCREENS 460 461Bool 462NVSwitchMode(SWITCH_MODE_ARGS_DECL) 463{ 464 SCRN_INFO_PTR(arg); 465 466 return xf86SetSingleMode(pScrn, mode, RR_Rotate_0); 467} 468 469/* 470 * This function is used to initialize the Start Address - the first 471 * displayed location in the video memory. 472 */ 473/* Usually mandatory */ 474void 475NVAdjustFrame(ADJUST_FRAME_ARGS_DECL) 476{ 477 SCRN_INFO_PTR(arg); 478 drmmode_adjust_frame(pScrn, x, y); 479} 480 481/* 482 * This is called when VT switching back to the X server. Its job is 483 * to reinitialise the video mode. 484 */ 485 486/* Mandatory */ 487static Bool 488NVEnterVT(VT_FUNC_ARGS_DECL) 489{ 490 SCRN_INFO_PTR(arg); 491 NVPtr pNv = NVPTR(pScrn); 492#ifdef XF86_PDEV_SERVER_FD 493 NVEntPtr pNVEnt = NVEntPriv(pScrn); 494#endif 495 int ret; 496 497 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVEnterVT is called.\n"); 498 499#ifdef XF86_PDEV_SERVER_FD 500 if (!(pNVEnt->platform_dev && 501 (pNVEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))) 502#endif 503 { 504 ret = drmSetMaster(pNv->dev->fd); 505 if (ret) 506 ErrorF("Unable to get master: %s\n", strerror(errno)); 507 } 508 509 if (XF86_CRTC_CONFIG_PTR(pScrn)->num_crtc && !xf86SetDesiredModes(pScrn)) 510 return FALSE; 511 512 if (pNv->overlayAdaptor && pNv->Architecture != NV_ARCH_04) 513 NV10WriteOverlayParameters(pScrn); 514 515 return TRUE; 516} 517 518/* 519 * This is called when VT switching away from the X server. Its job is 520 * to restore the previous (text) mode. 521 */ 522 523/* Mandatory */ 524static void 525NVLeaveVT(VT_FUNC_ARGS_DECL) 526{ 527 SCRN_INFO_PTR(arg); 528 NVPtr pNv = NVPTR(pScrn); 529#ifdef XF86_PDEV_SERVER_FD 530 NVEntPtr pNVEnt = NVEntPriv(pScrn); 531#endif 532 int ret; 533 534 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVLeaveVT is called.\n"); 535 536#ifdef XF86_PDEV_SERVER_FD 537 if (pNVEnt->platform_dev && 538 (pNVEnt->platform_dev->flags & XF86_PDEV_SERVER_FD)) 539 return; 540#endif 541 542 ret = drmDropMaster(pNv->dev->fd); 543 if (ret && errno != EIO && errno != ENODEV) 544 ErrorF("Error dropping master: %i(%m)\n", -errno); 545} 546 547static void 548NVFlushCallback(CallbackListPtr *list, pointer user_data, pointer call_data) 549{ 550 ScrnInfoPtr pScrn = user_data; 551 NVPtr pNv = NVPTR(pScrn); 552 if (pScrn->vtSema && pNv->Flush) 553 pNv->Flush(pScrn); 554} 555 556#ifdef NOUVEAU_PIXMAP_SHARING 557static void 558redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty) 559{ 560 RegionRec pixregion; 561 562 PixmapRegionInit(&pixregion, dirty->slave_dst); 563 564 DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion); 565#ifdef HAS_DIRTYTRACKING_ROTATION 566 PixmapSyncDirtyHelper(dirty); 567#else 568 PixmapSyncDirtyHelper(dirty, &pixregion); 569#endif 570 571 DamageRegionProcessPending(&dirty->slave_dst->drawable); 572 RegionUninit(&pixregion); 573} 574 575static void 576nouveau_dirty_update(ScreenPtr screen) 577{ 578 RegionPtr region; 579 PixmapDirtyUpdatePtr ent; 580 581 if (xorg_list_is_empty(&screen->pixmap_dirty_list)) 582 return; 583 584 xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) { 585 region = DamageRegion(ent->damage); 586 if (RegionNotEmpty(region)) { 587 redisplay_dirty(screen, ent); 588 DamageEmpty(ent->damage); 589 } 590 } 591} 592#endif 593 594static void 595NVBlockHandler (BLOCKHANDLER_ARGS_DECL) 596{ 597 SCREEN_PTR(arg); 598 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 599 NVPtr pNv = NVPTR(pScrn); 600 601 pScreen->BlockHandler = pNv->BlockHandler; 602 (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); 603 pScreen->BlockHandler = NVBlockHandler; 604 605#ifdef NOUVEAU_PIXMAP_SHARING 606 nouveau_dirty_update(pScreen); 607#endif 608 609 NVFlushCallback(NULL, pScrn, NULL); 610 611 if (pNv->VideoTimerCallback) 612 (*pNv->VideoTimerCallback)(pScrn, currentTime.milliseconds); 613} 614 615static Bool 616NVCreateScreenResources(ScreenPtr pScreen) 617{ 618 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 619 NVPtr pNv = NVPTR(pScrn); 620 621 pScreen->CreateScreenResources = pNv->CreateScreenResources; 622 if (!(*pScreen->CreateScreenResources)(pScreen)) 623 return FALSE; 624 pScreen->CreateScreenResources = NVCreateScreenResources; 625 626 drmmode_fbcon_copy(pScreen); 627 if (!NVEnterVT(VT_FUNC_ARGS(0))) 628 return FALSE; 629 630 if (pNv->AccelMethod == EXA) { 631 PixmapPtr ppix = pScreen->GetScreenPixmap(pScreen); 632 nouveau_bo_ref(pNv->scanout, &nouveau_pixmap(ppix)->bo); 633 } 634 635 return TRUE; 636} 637 638/* 639 * This is called at the end of each server generation. It restores the 640 * original (text) mode. It should also unmap the video memory, and free 641 * any per-generation data allocated by the driver. It should finish 642 * by unwrapping and calling the saved CloseScreen function. 643 */ 644 645/* Mandatory */ 646static Bool 647NVCloseScreen(CLOSE_SCREEN_ARGS_DECL) 648{ 649 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 650 NVPtr pNv = NVPTR(pScrn); 651 652 if (XF86_CRTC_CONFIG_PTR(pScrn)->num_crtc) 653 drmmode_screen_fini(pScreen); 654 655 nouveau_present_fini(pScreen); 656 nouveau_dri2_fini(pScreen); 657 nouveau_sync_fini(pScreen); 658 nouveau_copy_fini(pScreen); 659 660 if (pScrn->vtSema) { 661 NVLeaveVT(VT_FUNC_ARGS(0)); 662 pScrn->vtSema = FALSE; 663 } 664 665 NVTakedownVideo(pScrn); 666 NVAccelCommonFini(pScrn); 667 NVUnmapMem(pScrn); 668 669 xf86_cursors_fini(pScreen); 670 671 DeleteCallback(&FlushCallback, NVFlushCallback, pScrn); 672 673 if (pNv->ShadowPtr) { 674 free(pNv->ShadowPtr); 675 pNv->ShadowPtr = NULL; 676 } 677 if (pNv->overlayAdaptor) { 678 free(pNv->overlayAdaptor); 679 pNv->overlayAdaptor = NULL; 680 } 681 if (pNv->blitAdaptor) { 682 free(pNv->blitAdaptor); 683 pNv->blitAdaptor = NULL; 684 } 685 if (pNv->textureAdaptor[0]) { 686 free(pNv->textureAdaptor[0]); 687 pNv->textureAdaptor[0] = NULL; 688 } 689 if (pNv->textureAdaptor[1]) { 690 free(pNv->textureAdaptor[1]); 691 pNv->textureAdaptor[1] = NULL; 692 } 693 if (pNv->EXADriverPtr) { 694 exaDriverFini(pScreen); 695 free(pNv->EXADriverPtr); 696 pNv->EXADriverPtr = NULL; 697 } 698 699 pScrn->vtSema = FALSE; 700 pScreen->CloseScreen = pNv->CloseScreen; 701 pScreen->BlockHandler = pNv->BlockHandler; 702 return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 703} 704 705/* Free up any persistent data structures */ 706 707/* Optional */ 708static void 709NVFreeScreen(FREE_SCREEN_ARGS_DECL) 710{ 711 /* 712 * This only gets called when a screen is being deleted. It does not 713 * get called routinely at the end of a server generation. 714 */ 715 SCRN_INFO_PTR(arg); 716 NVPtr pNv = NVPTR(pScrn); 717 718 if (!pNv) 719 return; 720 721 NVCloseDRM(pScrn); 722 723 free(pScrn->driverPrivate); 724 pScrn->driverPrivate = NULL; 725} 726 727#define NVPreInitFail(fmt, args...) do { \ 728 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%d: "fmt, __LINE__, ##args); \ 729 NVFreeScreen(FREE_SCREEN_ARGS(pScrn)); \ 730 return FALSE; \ 731} while(0) 732 733static void 734NVCloseDRM(ScrnInfoPtr pScrn) 735{ 736 NVPtr pNv = NVPTR(pScrn); 737 738 drmFree(pNv->drm_device_name); 739 nouveau_client_del(&pNv->client); 740 nouveau_device_del(&pNv->dev); 741 free(pNv->render_node); 742} 743 744static void 745nouveau_setup_capabilities(ScrnInfoPtr pScrn) 746{ 747#ifdef NOUVEAU_PIXMAP_SHARING 748 NVPtr pNv = NVPTR(pScrn); 749 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 750 uint64_t value; 751 int ret; 752 753 pScrn->capabilities = 0; 754 ret = drmGetCap(pNv->dev->fd, DRM_CAP_PRIME, &value); 755 if (ret == 0) { 756 if (value & DRM_PRIME_CAP_EXPORT) 757 pScrn->capabilities |= RR_Capability_SourceOutput; 758 if (value & DRM_PRIME_CAP_IMPORT) { 759 pScrn->capabilities |= RR_Capability_SourceOffload; 760 if (xf86_config->num_crtc) 761 pScrn->capabilities |= RR_Capability_SinkOutput; 762 } 763 } 764#endif 765} 766 767NVEntPtr NVEntPriv(ScrnInfoPtr pScrn) 768{ 769 DevUnion *pPriv; 770 NVPtr pNv = NVPTR(pScrn); 771 pPriv = xf86GetEntityPrivate(pNv->pEnt->index, 772 getNVEntityIndex()); 773 return pPriv->ptr; 774} 775 776static Bool NVOpenDRMMaster(ScrnInfoPtr pScrn) 777{ 778 NVPtr pNv = NVPTR(pScrn); 779 NVEntPtr pNVEnt = NVEntPriv(pScrn); 780 drmSetVersion sv; 781 int err; 782 int ret; 783 784 if (pNVEnt->fd) { 785 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 786 " reusing fd for second head\n"); 787 ret = nouveau_device_wrap(pNVEnt->fd, 0, &pNv->dev); 788 if (ret) { 789 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 790 "[drm] error creating device\n"); 791 return FALSE; 792 } 793 return TRUE; 794 } 795 796 pNv->dev = NVOpenNouveauDevice(pNv->PciInfo, pNVEnt->platform_dev, 797 pScrn->scrnIndex, FALSE); 798 if (!pNv->dev) 799 return FALSE; 800 801 sv.drm_di_major = 1; 802 sv.drm_di_minor = 1; 803 sv.drm_dd_major = -1; 804 sv.drm_dd_minor = -1; 805 err = drmSetInterfaceVersion(pNv->dev->fd, &sv); 806 if (err != 0) { 807 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 808 "[drm] failed to set drm interface version.\n"); 809 nouveau_device_del(&pNv->dev); 810 return FALSE; 811 } 812 pNVEnt->fd = pNv->dev->fd; 813 return TRUE; 814} 815 816static Bool 817NVPreInitDRM(ScrnInfoPtr pScrn) 818{ 819 NVPtr pNv = NVPTR(pScrn); 820 int ret; 821 822 if (!xf86LoadSubModule(pScrn, "dri2")) 823 return FALSE; 824 825 /* Load the kernel module, and open the DRM */ 826 ret = NVOpenDRMMaster(pScrn); 827 if (!ret) { 828 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 829 "[drm] error opening the drm\n"); 830 return FALSE; 831 } 832 833 ret = nouveau_client_new(pNv->dev, &pNv->client); 834 if (ret) 835 return FALSE; 836 837 pNv->drm_device_name = drmGetDeviceNameFromFd(pNv->dev->fd); 838 839 return TRUE; 840} 841 842/* Mandatory */ 843Bool 844NVPreInit(ScrnInfoPtr pScrn, int flags) 845{ 846 struct nouveau_device *dev; 847 NVPtr pNv; 848 MessageType from; 849 const char *reason, *string; 850 uint64_t v; 851 int ret; 852 int defaultDepth = 0; 853 854 if (flags & PROBE_DETECT) { 855 EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 856 857 if (!pEnt) 858 return FALSE; 859 860 free(pEnt); 861 862 return TRUE; 863 } 864 865 /* 866 * Note: This function is only called once at server startup, and 867 * not at the start of each server generation. This means that 868 * only things that are persistent across server generations can 869 * be initialised here. xf86Screens[] is (pScrn is a pointer to one 870 * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() 871 * are too, and should be used for data that must persist across 872 * server generations. 873 * 874 * Per-generation data should be allocated with 875 * AllocateScreenPrivateIndex() from the ScreenInit() function. 876 */ 877 878 /* Check the number of entities, and fail if it isn't one. */ 879 if (pScrn->numEntities != 1) 880 return FALSE; 881 882 /* Allocate the NVRec driverPrivate */ 883 if (!(pScrn->driverPrivate = xnfcalloc(1, sizeof(NVRec)))) 884 return FALSE; 885 pNv = NVPTR(pScrn); 886 887 /* Get the entity, and make sure it is PCI. */ 888 pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 889 if (pNv->pEnt->location.type != BUS_PCI 890#ifdef XSERVER_PLATFORM_BUS 891 && pNv->pEnt->location.type != BUS_PLATFORM 892#endif 893 ) 894 return FALSE; 895 896 if (xf86IsEntityShared(pScrn->entityList[0])) { 897 if(!xf86IsPrimInitDone(pScrn->entityList[0])) { 898 pNv->Primary = TRUE; 899 xf86SetPrimInitDone(pScrn->entityList[0]); 900 } else { 901 pNv->Secondary = TRUE; 902 } 903 } 904 905 /* Find the PCI info for this screen */ 906 pNv->PciInfo = xf86GetPciInfoForEntity(pNv->pEnt->index); 907 908 /* Initialise the kernel module */ 909 if (!NVPreInitDRM(pScrn)) 910 NVPreInitFail("\n"); 911 dev = pNv->dev; 912 913 pScrn->chipset = malloc(sizeof(char) * 25); 914 sprintf((char *)pScrn->chipset, "NVIDIA NV%02X", dev->chipset); 915 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Chipset: \"%s\"\n", pScrn->chipset); 916 917 switch (dev->chipset & ~0xf) { 918 case 0x00: 919 pNv->Architecture = NV_ARCH_04; 920 break; 921 case 0x10: 922 pNv->Architecture = NV_ARCH_10; 923 break; 924 case 0x20: 925 pNv->Architecture = NV_ARCH_20; 926 break; 927 case 0x30: 928 pNv->Architecture = NV_ARCH_30; 929 break; 930 case 0x40: 931 case 0x60: 932 pNv->Architecture = NV_ARCH_40; 933 break; 934 case 0x50: 935 case 0x80: 936 case 0x90: 937 case 0xa0: 938 pNv->Architecture = NV_TESLA; 939 break; 940 case 0xc0: 941 case 0xd0: 942 pNv->Architecture = NV_FERMI; 943 break; 944 case 0xe0: 945 case 0xf0: 946 case 0x100: 947 pNv->Architecture = NV_KEPLER; 948 break; 949 case 0x110: 950 case 0x120: 951 pNv->Architecture = NV_MAXWELL; 952 break; 953 case 0x130: 954 pNv->Architecture = NV_PASCAL; 955 break; 956 default: 957 return FALSE; 958 } 959 960 /* Set pScrn->monitor */ 961 pScrn->monitor = pScrn->confScreen->monitor; 962 963 /* 964 * The first thing we should figure out is the depth, bpp, etc. 965 */ 966 967 if (dev->vram_size <= 16 * 1024 * 1024) 968 defaultDepth = 16; 969 if (!xf86SetDepthBpp(pScrn, defaultDepth, 0, 0, Support32bppFb)) { 970 NVPreInitFail("\n"); 971 } else { 972 /* Check that the returned depth is one we support */ 973 switch (pScrn->depth) { 974 case 16: 975 case 24: 976 /* OK */ 977 break; 978 case 30: 979 /* OK on NV50 KMS */ 980 if (pNv->Architecture < NV_TESLA) 981 NVPreInitFail("Depth 30 supported on G80+ only\n"); 982 break; 983 case 15: /* 15 may get done one day, so leave any code for it in place */ 984 default: 985 NVPreInitFail("Given depth (%d) is not supported by this driver\n", 986 pScrn->depth); 987 } 988 } 989 xf86PrintDepthBpp(pScrn); 990 991 /* 992 * This must happen after pScrn->display has been set because 993 * xf86SetWeight references it. 994 */ 995 rgb rgbzeros = {0, 0, 0}; 996 997 if (pScrn->depth == 30) { 998 rgb rgbmask; 999 1000 rgbmask.red = 0x000003ff; 1001 rgbmask.green = 0x000ffc00; 1002 rgbmask.blue = 0x3ff00000; 1003 if (!xf86SetWeight(pScrn, rgbzeros, rgbmask)) 1004 NVPreInitFail("\n"); 1005 1006 /* xf86SetWeight() seems to think ffs(1) == 0... */ 1007 pScrn->offset.red--; 1008 pScrn->offset.green--; 1009 pScrn->offset.blue--; 1010 } else { 1011 if (!xf86SetWeight(pScrn, rgbzeros, rgbzeros)) 1012 NVPreInitFail("\n"); 1013 } 1014 1015 if (!xf86SetDefaultVisual(pScrn, -1)) 1016 NVPreInitFail("\n"); 1017 1018 /* We don't support DirectColor */ 1019 if (pScrn->defaultVisual != TrueColor) { 1020 NVPreInitFail("Given default visual (%s) is not supported at depth %d\n", 1021 xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); 1022 } 1023 1024 /* We use a programmable clock */ 1025 pScrn->progClock = TRUE; 1026 1027 /* Collect all of the relevant option flags (fill in pScrn->options) */ 1028 xf86CollectOptions(pScrn, NULL); 1029 1030 /* Process the options */ 1031 if (!(pNv->Options = malloc(sizeof(NVOptions)))) 1032 return FALSE; 1033 memcpy(pNv->Options, NVOptions, sizeof(NVOptions)); 1034 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options); 1035 1036 from = X_DEFAULT; 1037 1038 pNv->HWCursor = TRUE; 1039 /* 1040 * The preferred method is to use the "hw cursor" option as a tri-state 1041 * option, with the default set above. 1042 */ 1043 if (xf86GetOptValBool(pNv->Options, OPTION_HW_CURSOR, &pNv->HWCursor)) { 1044 from = X_CONFIG; 1045 } 1046 /* For compatibility, accept this too (as an override) */ 1047 if (xf86ReturnOptValBool(pNv->Options, OPTION_SW_CURSOR, FALSE)) { 1048 from = X_CONFIG; 1049 pNv->HWCursor = FALSE; 1050 } 1051 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 1052 pNv->HWCursor ? "HW" : "SW"); 1053 1054 string = xf86GetOptValString(pNv->Options, OPTION_ACCELMETHOD); 1055 if (string) { 1056 if (!strcmp(string, "none")) pNv->AccelMethod = NONE; 1057 else if (!strcmp(string, "exa")) pNv->AccelMethod = EXA; 1058 else { 1059 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1060 "Invalid AccelMethod specified\n"); 1061 } 1062 } 1063 1064 if (pNv->AccelMethod == UNKNOWN) { 1065 pNv->AccelMethod = EXA; 1066 } 1067 1068 if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) { 1069 pNv->AccelMethod = NONE; 1070 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 1071 } 1072 1073 if (xf86ReturnOptValBool(pNv->Options, OPTION_SHADOW_FB, FALSE)) { 1074 pNv->ShadowFB = TRUE; 1075 pNv->AccelMethod = NONE; 1076 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1077 "Using \"Shadow Framebuffer\" - acceleration disabled\n"); 1078 } 1079 1080 if (pNv->AccelMethod > NONE) { 1081#if 0 1082 if (pNv->Architecture >= NV_TESLA) 1083 pNv->wfb_enabled = xf86ReturnOptValBool( 1084 pNv->Options, OPTION_WFB, FALSE); 1085#endif 1086 1087 pNv->tiled_scanout = TRUE; 1088 } 1089 1090 pNv->ce_enabled = 1091 xf86ReturnOptValBool(pNv->Options, OPTION_ASYNC_COPY, FALSE); 1092 1093 /* Define maximum allowed level of DRI implementation to use. 1094 * We default to DRI2 on EXA for now, as DRI3 still has some 1095 * problems. 1096 */ 1097 pNv->max_dri_level = 2; 1098 from = X_DEFAULT; 1099 1100 if (xf86GetOptValInteger(pNv->Options, OPTION_DRI, 1101 &pNv->max_dri_level)) { 1102 from = X_CONFIG; 1103 if (pNv->max_dri_level < 2) 1104 pNv->max_dri_level = 2; 1105 if (pNv->max_dri_level > 3) 1106 pNv->max_dri_level = 3; 1107 } 1108 xf86DrvMsg(pScrn->scrnIndex, from, "Allowed maximum DRI level %i.\n", 1109 pNv->max_dri_level); 1110 1111 if (pNv->AccelMethod > NONE && pNv->dev->chipset >= 0x11) { 1112 from = X_DEFAULT; 1113 pNv->glx_vblank = TRUE; 1114 if (xf86GetOptValBool(pNv->Options, OPTION_GLX_VBLANK, 1115 &pNv->glx_vblank)) 1116 from = X_CONFIG; 1117 1118 xf86DrvMsg(pScrn->scrnIndex, from, "GLX sync to VBlank %s.\n", 1119 pNv->glx_vblank ? "enabled" : "disabled"); 1120 } 1121 1122#ifdef NOUVEAU_GETPARAM_HAS_PAGEFLIP 1123 reason = ": no kernel support"; 1124 from = X_DEFAULT; 1125 1126 ret = nouveau_getparam(pNv->dev, NOUVEAU_GETPARAM_HAS_PAGEFLIP, &v); 1127 if (ret == 0 && v == 1) { 1128 pNv->has_pageflip = TRUE; 1129 if (xf86GetOptValBool(pNv->Options, OPTION_PAGE_FLIP, &pNv->has_pageflip)) 1130 from = X_CONFIG; 1131 reason = ""; 1132 } 1133#else 1134 reason = ": not available at build time"; 1135#endif 1136 1137 xf86DrvMsg(pScrn->scrnIndex, from, "Page flipping %sabled%s\n", 1138 pNv->has_pageflip ? "en" : "dis", reason); 1139 1140 if(xf86GetOptValInteger(pNv->Options, OPTION_VIDEO_KEY, &(pNv->videoKey))) { 1141 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", 1142 pNv->videoKey); 1143 } else { 1144 pNv->videoKey = (1 << pScrn->offset.red) | 1145 (1 << pScrn->offset.green) | 1146 (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue); 1147 } 1148 1149 /* Limit to max 2 pending swaps - we can't handle more than triple-buffering: */ 1150 pNv->max_swap_limit = 2; 1151 1152 if(xf86GetOptValInteger(pNv->Options, OPTION_SWAP_LIMIT, &(pNv->swap_limit))) { 1153 if (pNv->swap_limit < 1) 1154 pNv->swap_limit = 1; 1155 1156 if (pNv->swap_limit > pNv->max_swap_limit) 1157 pNv->swap_limit = pNv->max_swap_limit; 1158 1159 reason = ""; 1160 from = X_CONFIG; 1161 1162 if ((DRI2INFOREC_VERSION < 6) && (pNv->swap_limit > 1)) { 1163 /* No swap limit api in server. A value > 1 requires use 1164 * of problematic hacks. 1165 */ 1166 from = X_WARNING; 1167 reason = ": Caution: Use of this swap limit > 1 violates OML_sync_control spec on this X-Server!\n"; 1168 } 1169 } else { 1170 /* Always default to double-buffering, because it avoids artifacts like 1171 * unthrottled rendering of non-fullscreen clients under desktop composition. 1172 */ 1173 pNv->swap_limit = 1; 1174 reason = ""; 1175 from = X_DEFAULT; 1176 } 1177 1178 xf86DrvMsg(pScrn->scrnIndex, from, "Swap limit set to %d [Max allowed %d]%s\n", 1179 pNv->swap_limit, pNv->max_swap_limit, reason); 1180 1181 /* Does kernel do the sync of pageflips to vblank? */ 1182 pNv->has_async_pageflip = FALSE; 1183#ifdef DRM_CAP_ASYNC_PAGE_FLIP 1184 ret = drmGetCap(pNv->dev->fd, DRM_CAP_ASYNC_PAGE_FLIP, &v); 1185 if (ret == 0 && v == 1) { 1186 pNv->has_async_pageflip = TRUE; 1187 } 1188 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Page flipping synced to vblank by %s.\n", 1189 pNv->has_async_pageflip ? "kernel" : "ddx"); 1190#endif 1191 1192 ret = drmmode_pre_init(pScrn, pNv->dev->fd, pScrn->bitsPerPixel >> 3); 1193 if (ret == FALSE) 1194 NVPreInitFail("Kernel modesetting failed to initialize\n"); 1195 1196 /* 1197 * If the driver can do gamma correction, it should call xf86SetGamma() 1198 * here. 1199 */ 1200 Gamma gammazeros = {0.0, 0.0, 0.0}; 1201 1202 if (!xf86SetGamma(pScrn, gammazeros)) 1203 NVPreInitFail("\n"); 1204 1205#ifdef NOUVEAU_PIXMAP_SHARING 1206 /* 1207 * The driver will not work as gpu screen without acceleration enabled. 1208 * To support this usecase modesetting ddx can be used instead. 1209 */ 1210 if (pNv->AccelMethod <= NONE || pNv->ShadowFB) { 1211 /* 1212 * Optimus mode requires acceleration enabled. 1213 * So if no mode is found, or the screen is created 1214 * as a gpu screen the pre init should fail. 1215 */ 1216 if (pScrn->is_gpu || !pScrn->modes) 1217 return FALSE; 1218 } 1219 1220#else 1221 /* No usable mode, no optimus config possible */ 1222 if (!pScrn->modes) 1223 return FALSE; 1224#endif 1225 1226 nouveau_setup_capabilities(pScrn); 1227 1228 if (!pScrn->modes) { 1229 pScrn->modes = xf86ModesAdd(pScrn->modes, 1230 xf86CVTMode(pScrn->display->virtualX, 1231 pScrn->display->virtualY, 1232 60, 0, 0)); 1233 } 1234 1235 /* Set the current mode to the first in the list */ 1236 pScrn->currentMode = pScrn->modes; 1237 1238 /* Print the list of modes being used */ 1239 xf86PrintModes(pScrn); 1240 1241 /* Set display resolution */ 1242 xf86SetDpi(pScrn, 0, 0); 1243 1244#if 0 1245 if (pNv->wfb_enabled) { 1246 if (xf86LoadSubModule(pScrn, "wfb") == NULL) 1247 NVPreInitFail("\n"); 1248 } 1249#endif 1250 1251 if (xf86LoadSubModule(pScrn, "fb") == NULL) 1252 NVPreInitFail("\n"); 1253 1254 /* Load shadowfb */ 1255 if (!xf86LoadSubModule(pScrn, "shadowfb")) 1256 NVPreInitFail("\n"); 1257 1258 return TRUE; 1259} 1260 1261 1262static Bool 1263NVMapMem(ScrnInfoPtr pScrn) 1264{ 1265 NVPtr pNv = NVPTR(pScrn); 1266 int ret, pitch; 1267 1268 ret = nouveau_allocate_surface(pScrn, pScrn->virtualX, pScrn->virtualY, 1269 pScrn->bitsPerPixel, 1270 NOUVEAU_CREATE_PIXMAP_SCANOUT, 1271 &pitch, &pNv->scanout); 1272 if (!ret) { 1273 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1274 "Error allocating scanout buffer: %d\n", ret); 1275 return FALSE; 1276 } 1277 1278 pScrn->displayWidth = pitch / (pScrn->bitsPerPixel / 8); 1279 return TRUE; 1280} 1281 1282/* 1283 * Unmap the framebuffer and offscreen memory. 1284 */ 1285 1286static Bool 1287NVUnmapMem(ScrnInfoPtr pScrn) 1288{ 1289 NVPtr pNv = NVPTR(pScrn); 1290 1291 drmmode_remove_fb(pScrn); 1292 1293 nouveau_bo_ref(NULL, &pNv->transfer); 1294 nouveau_bo_ref(NULL, &pNv->scanout); 1295 return TRUE; 1296} 1297 1298static void 1299NVLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 1300 LOCO * colors, VisualPtr pVisual) 1301{ 1302 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1303 int c; 1304 int i, j, index; 1305 CARD16 lut_r[256], lut_g[256], lut_b[256]; 1306 1307 for (c = 0; c < xf86_config->num_crtc; c++) { 1308 xf86CrtcPtr crtc = xf86_config->crtc[c]; 1309 1310 /* code borrowed from intel driver */ 1311 switch (pScrn->depth) { 1312 case 15: 1313 for (i = 0; i < numColors; i++) { 1314 index = indices[i]; 1315 for (j = 0; j < 8; j++) { 1316 lut_r[index * 8 + j] = colors[index].red << 8; 1317 lut_g[index * 8 + j] = colors[index].green << 8; 1318 lut_b[index * 8 + j] = colors[index].blue << 8; 1319 } 1320 } 1321 break; 1322 1323 case 16: 1324 for (i = 0; i < numColors; i++) { 1325 index = indices[i]; 1326 1327 if (i <= 31) { 1328 for (j = 0; j < 8; j++) { 1329 lut_r[index * 8 + j] = colors[index].red << 8; 1330 lut_b[index * 8 + j] = colors[index].blue << 8; 1331 } 1332 } 1333 1334 for (j = 0; j < 4; j++) { 1335 lut_g[index * 4 + j] = colors[index].green << 8; 1336 } 1337 } 1338 break; 1339 1340 default: 1341 for (i = 0; i < numColors; i++) { 1342 index = indices[i]; 1343 lut_r[index] = colors[index].red << 8; 1344 lut_g[index] = colors[index].green << 8; 1345 lut_b[index] = colors[index].blue << 8; 1346 } 1347 break; 1348 } 1349 1350 if (crtc->randr_crtc) 1351 /* Make the change through RandR */ 1352 RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); 1353 } 1354} 1355 1356/* Mandatory */ 1357 1358/* This gets called at the start of each server generation */ 1359static Bool 1360NVScreenInit(SCREEN_INIT_ARGS_DECL) 1361{ 1362 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1363 NVPtr pNv = NVPTR(pScrn); 1364 int ret; 1365 VisualPtr visual; 1366 unsigned char *FBStart; 1367 int displayWidth; 1368 1369 if (pNv->AccelMethod == EXA) { 1370 if (!NVAccelCommonInit(pScrn)) { 1371 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1372 "Error initialising acceleration. " 1373 "Falling back to NoAccel\n"); 1374 pNv->AccelMethod = NONE; 1375 pNv->ShadowFB = TRUE; 1376#if 0 1377 pNv->wfb_enabled = FALSE; 1378#endif 1379 pNv->tiled_scanout = FALSE; 1380 pScrn->displayWidth = nv_pitch_align(pNv, 1381 pScrn->virtualX, 1382 pScrn->depth); 1383 } 1384 } 1385 1386 nouveau_copy_init(pScreen); 1387 1388 /* Allocate and map memory areas we need */ 1389 if (!NVMapMem(pScrn)) 1390 return FALSE; 1391 1392 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1393 int i; 1394 1395 /* need to point to new screen on server regeneration */ 1396 for (i = 0; i < xf86_config->num_crtc; i++) 1397 xf86_config->crtc[i]->scrn = pScrn; 1398 for (i = 0; i < xf86_config->num_output; i++) 1399 xf86_config->output[i]->scrn = pScrn; 1400 1401 /* 1402 * The next step is to setup the screen's visuals, and initialise the 1403 * framebuffer code. In cases where the framebuffer's default 1404 * choices for things like visual layouts and bits per RGB are OK, 1405 * this may be as simple as calling the framebuffer's ScreenInit() 1406 * function. If not, the visuals will need to be setup before calling 1407 * a fb ScreenInit() function and fixed up after. 1408 * 1409 * For most PC hardware at depths >= 8, the defaults that fb uses 1410 * are not appropriate. In this driver, we fixup the visuals after. 1411 */ 1412 1413 /* 1414 * Reset the visual list. 1415 */ 1416 miClearVisualTypes(); 1417 1418 /* Setup the visuals we support. */ 1419 if (!miSetVisualTypes(pScrn->depth, 1420 miGetDefaultVisualMask(pScrn->depth), 1421 pScrn->rgbBits, pScrn->defaultVisual)) 1422 return FALSE; 1423 1424 if (!miSetPixmapDepths ()) 1425 return FALSE; 1426 1427 /* 1428 * Call the framebuffer layer's ScreenInit function, and fill in other 1429 * pScreen fields. 1430 */ 1431 1432 if (pNv->ShadowFB) { 1433 pNv->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * pScrn->virtualX); 1434 pNv->ShadowPtr = malloc(pNv->ShadowPitch * pScrn->virtualY); 1435 displayWidth = pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3); 1436 FBStart = pNv->ShadowPtr; 1437 } else 1438 if (pNv->AccelMethod <= NONE) { 1439 pNv->ShadowPtr = NULL; 1440 displayWidth = pScrn->displayWidth; 1441 nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR, pNv->client); 1442 FBStart = pNv->scanout->map; 1443 } else { 1444 pNv->ShadowPtr = NULL; 1445 displayWidth = pScrn->displayWidth; 1446 FBStart = NULL; 1447 } 1448 1449 switch (pScrn->bitsPerPixel) { 1450 case 16: 1451 case 32: 1452#if 0 1453 if (pNv->wfb_enabled) { 1454 ret = wfbScreenInit(pScreen, FBStart, pScrn->virtualX, 1455 pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 1456 displayWidth, pScrn->bitsPerPixel, 1457 nouveau_wfb_setup_wrap, 1458 nouveau_wfb_finish_wrap); 1459 } else { 1460#endif 1461 ret = fbScreenInit(pScreen, FBStart, pScrn->virtualX, 1462 pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 1463 displayWidth, pScrn->bitsPerPixel); 1464#if 0 1465 } 1466#endif 1467 break; 1468 default: 1469 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1470 "Internal error: invalid bpp (%d) in NVScreenInit\n", 1471 pScrn->bitsPerPixel); 1472 ret = FALSE; 1473 break; 1474 } 1475 if (!ret) 1476 return FALSE; 1477 1478 /* Fixup RGB ordering */ 1479 visual = pScreen->visuals + pScreen->numVisuals; 1480 while (--visual >= pScreen->visuals) { 1481 if ((visual->class | DynamicClass) == DirectColor) { 1482 visual->offsetRed = pScrn->offset.red; 1483 visual->offsetGreen = pScrn->offset.green; 1484 visual->offsetBlue = pScrn->offset.blue; 1485 visual->redMask = pScrn->mask.red; 1486 visual->greenMask = pScrn->mask.green; 1487 visual->blueMask = pScrn->mask.blue; 1488 } 1489 } 1490 1491#if 0 1492 if (pNv->wfb_enabled) 1493 wfbPictureInit (pScreen, 0, 0); 1494 else 1495#endif 1496 fbPictureInit (pScreen, 0, 0); 1497 1498 xf86SetBlackWhitePixels(pScreen); 1499 1500 if (nouveau_present_init(pScreen)) 1501 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1502 "Hardware support for Present enabled\n"); 1503 else 1504 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1505 "Hardware support for Present disabled\n"); 1506 1507 nouveau_sync_init(pScreen); 1508 nouveau_dri2_init(pScreen); 1509 if (pNv->AccelMethod == EXA) { 1510 if (pNv->max_dri_level >= 3 && 1511 !nouveau_dri3_screen_init(pScreen)) 1512 return FALSE; 1513 1514 if (!nouveau_exa_init(pScreen)) 1515 return FALSE; 1516 } 1517 1518 xf86SetBackingStore(pScreen); 1519 xf86SetSilkenMouse(pScreen); 1520 1521 /* 1522 * Initialize software cursor. 1523 * Must precede creation of the default colormap. 1524 */ 1525 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 1526 1527 /* 1528 * Initialize HW cursor layer. 1529 * Must follow software cursor initialization. 1530 */ 1531 if (xf86_config->num_crtc && pNv->HWCursor) { 1532 ret = drmmode_cursor_init(pScreen); 1533 if (ret != TRUE) { 1534 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1535 "Hardware cursor initialization failed\n"); 1536 pNv->HWCursor = FALSE; 1537 } 1538 } 1539 1540 if (pNv->ShadowFB) 1541 ShadowFBInit(pScreen, NVRefreshArea); 1542 1543 pScrn->fbOffset = 0; 1544 1545 NVInitVideo(pScreen); 1546 1547 /* Wrap the block handler here, if we do it after the EnterVT we 1548 * can end up in the unfortunate case where we've wrapped the 1549 * xf86RotateBlockHandler which sometimes is not expecting to 1550 * be in the wrap chain and calls a NULL pointer... 1551 */ 1552 pNv->BlockHandler = pScreen->BlockHandler; 1553 pScreen->BlockHandler = NVBlockHandler; 1554 1555 if (!AddCallback(&FlushCallback, NVFlushCallback, pScrn)) 1556 return FALSE; 1557 1558 pScrn->vtSema = TRUE; 1559 pScrn->pScreen = pScreen; 1560 1561 xf86DPMSInit(pScreen, xf86DPMSSet, 0); 1562 1563 /* Wrap the current CloseScreen function */ 1564 pScreen->SaveScreen = NVSaveScreen; 1565 pNv->CloseScreen = pScreen->CloseScreen; 1566 pScreen->CloseScreen = NVCloseScreen; 1567 pNv->CreateScreenResources = pScreen->CreateScreenResources; 1568 pScreen->CreateScreenResources = NVCreateScreenResources; 1569 1570#ifdef NOUVEAU_PIXMAP_SHARING 1571 pScreen->StartPixmapTracking = PixmapStartDirtyTracking; 1572 pScreen->StopPixmapTracking = PixmapStopDirtyTracking; 1573#endif 1574 1575 if (!xf86CrtcScreenInit(pScreen)) 1576 return FALSE; 1577 1578 /* Initialise default colourmap */ 1579 if (!miCreateDefColormap(pScreen)) 1580 return FALSE; 1581 1582 /* 1583 * Initialize colormap layer. 1584 * Must follow initialization of the default colormap. 1585 * X-Server < 1.20 mishandles > 256 slots / > 8 bpc color maps, so skip 1586 * color map setup on old servers at > 8 bpc. Gamma luts still work. 1587 */ 1588 if (xf86_config->num_crtc && (pScrn->rgbBits <= 8 || 1589 XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,20,0,0,0)) && 1590 !xf86HandleColormaps(pScreen, 1 << pScrn->rgbBits, pScrn->rgbBits, 1591 NVLoadPalette, NULL, CMAP_PALETTED_TRUECOLOR)) 1592 return FALSE; 1593 1594 /* Report any unused options (only for the first generation) */ 1595 if (serverGeneration == 1) 1596 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 1597 1598 if (xf86_config->num_crtc) 1599 drmmode_screen_init(pScreen); 1600 else 1601 pNv->glx_vblank = FALSE; 1602 return TRUE; 1603} 1604 1605static Bool 1606NVSaveScreen(ScreenPtr pScreen, int mode) 1607{ 1608 return TRUE; 1609} 1610 1611