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