radeon_kms.c revision ad43ddac
1/* 2 * Copyright © 2009 Red Hat, Inc. 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 (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Dave Airlie <airlied@redhat.com> 25 * 26 */ 27#ifdef HAVE_CONFIG_H 28#include "config.h" 29#endif 30 31#include <errno.h> 32#include <sys/ioctl.h> 33/* Driver data structures */ 34#include "radeon.h" 35#include "radeon_reg.h" 36#include "radeon_probe.h" 37#include "micmap.h" 38 39#include "shadow.h" 40 41#include "atipciids.h" 42 43 44#ifdef XF86DRM_MODE 45 46#include "radeon_chipset_gen.h" 47#include "radeon_chipinfo_gen.h" 48 49#define CURSOR_WIDTH 64 50#define CURSOR_HEIGHT 64 51 52#include "radeon_bo_gem.h" 53#include "radeon_cs_gem.h" 54#include "radeon_vbo.h" 55 56static Bool radeon_setup_kernel_mem(ScreenPtr pScreen); 57 58const OptionInfoRec RADEONOptions_KMS[] = { 59 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 60 { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 61 { OPTION_PAGE_FLIP, "EnablePageFlip", OPTV_BOOLEAN, {0}, FALSE }, 62 { OPTION_ACCEL_DFS, "AccelDFS", OPTV_BOOLEAN, {0}, FALSE }, 63 { OPTION_IGNORE_EDID, "IgnoreEDID", OPTV_BOOLEAN, {0}, FALSE }, 64 { OPTION_COLOR_TILING, "ColorTiling", OPTV_BOOLEAN, {0}, FALSE }, 65 { OPTION_RENDER_ACCEL, "RenderAccel", OPTV_BOOLEAN, {0}, FALSE }, 66 { OPTION_SUBPIXEL_ORDER, "SubPixelOrder", OPTV_ANYSTR, {0}, FALSE }, 67 { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, 68 { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE }, 69 { OPTION_TVSTD, "TVStandard", OPTV_STRING, {0}, FALSE }, 70 { OPTION_EXA_VSYNC, "EXAVSync", OPTV_BOOLEAN, {0}, FALSE }, 71 { OPTION_EXA_PIXMAPS, "EXAPixmaps", OPTV_BOOLEAN, {0}, FALSE }, 72 { OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE }, 73 { -1, NULL, OPTV_NONE, {0}, FALSE } 74}; 75 76void radeon_cs_flush_indirect(ScrnInfoPtr pScrn) 77{ 78 RADEONInfoPtr info = RADEONPTR(pScrn); 79 struct radeon_accel_state *accel_state = info->accel_state; 80 int ret; 81 82 if (!info->cs->cdw) 83 return; 84 85 if (info->accel_state->vb_ptr) 86 info->accel_state->vb_ptr = NULL; 87 88 /* release the current VBO so we don't block on mapping it later */ 89 if (info->accel_state->vb_offset && info->accel_state->vb_bo) { 90 radeon_vbo_put(pScrn); 91 info->accel_state->vb_start_op = -1; 92 } 93 94 radeon_cs_emit(info->cs); 95 radeon_cs_erase(info->cs); 96 97 if (accel_state->use_vbos) 98 radeon_vbo_flush_bos(pScrn); 99 100 ret = radeon_cs_space_check_with_bo(info->cs, 101 accel_state->vb_bo, 102 RADEON_GEM_DOMAIN_GTT, 0); 103 if (ret) 104 ErrorF("space check failed in flush\n"); 105 106 if (info->reemit_current2d && info->state_2d.op) 107 info->reemit_current2d(pScrn, info->state_2d.op); 108 109 if (info->dri2.enabled) { 110 info->accel_state->XInited3D = FALSE; 111 info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; 112 } 113 114} 115 116void radeon_ddx_cs_start(ScrnInfoPtr pScrn, 117 int n, const char *file, 118 const char *func, int line) 119{ 120 RADEONInfoPtr info = RADEONPTR(pScrn); 121 122 if (info->cs->cdw + n > info->cs->ndw) { 123 radeon_cs_flush_indirect(pScrn); 124 125 } 126 radeon_cs_begin(info->cs, n, file, func, line); 127} 128 129 130extern _X_EXPORT int gRADEONEntityIndex; 131 132static int getRADEONEntityIndex(void) 133{ 134 return gRADEONEntityIndex; 135} 136 137static void * 138radeonShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode, 139 CARD32 *size, void *closure) 140{ 141 ScrnInfoPtr pScrn = xf86Screens[screen->myNum]; 142 RADEONInfoPtr info = RADEONPTR(pScrn); 143 int stride; 144 145 stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8; 146 *size = stride; 147 148 return ((uint8_t *)info->front_bo->ptr + row * stride + offset); 149} 150 151static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) 152{ 153 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 154 RADEONInfoPtr info = RADEONPTR(pScrn); 155 PixmapPtr pixmap; 156 157 pScreen->CreateScreenResources = info->CreateScreenResources; 158 if (!(*pScreen->CreateScreenResources)(pScreen)) 159 return FALSE; 160 pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS; 161 162 if (info->r600_shadow_fb) { 163 pixmap = pScreen->GetScreenPixmap(pScreen); 164 165 if (!shadowAdd(pScreen, pixmap, shadowUpdatePackedWeak(), 166 radeonShadowWindow, 0, NULL)) 167 return FALSE; 168 } 169 170 if (info->dri2.enabled) { 171 if (info->front_bo) { 172 PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); 173 radeon_set_pixmap_bo(pPix, info->front_bo); 174 } 175 } 176 return TRUE; 177} 178 179static void RADEONBlockHandler_KMS(int i, pointer blockData, 180 pointer pTimeout, pointer pReadmask) 181{ 182 ScreenPtr pScreen = screenInfo.screens[i]; 183 ScrnInfoPtr pScrn = xf86Screens[i]; 184 RADEONInfoPtr info = RADEONPTR(pScrn); 185 186 pScreen->BlockHandler = info->BlockHandler; 187 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 188 pScreen->BlockHandler = RADEONBlockHandler_KMS; 189 190 if (info->VideoTimerCallback) 191 (*info->VideoTimerCallback)(pScrn, currentTime.milliseconds); 192 193 radeon_cs_flush_indirect(pScrn); 194} 195 196static Bool RADEONIsAccelWorking(ScrnInfoPtr pScrn) 197{ 198 RADEONInfoPtr info = RADEONPTR(pScrn); 199 struct drm_radeon_info ginfo; 200 int r; 201 uint32_t tmp; 202 203 memset(&ginfo, 0, sizeof(ginfo)); 204 ginfo.request = 0x3; 205 ginfo.value = (uintptr_t)&tmp; 206 r = drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_INFO, &ginfo, sizeof(ginfo)); 207 if (r) { 208 /* If kernel is too old before 2.6.32 than assume accel is working */ 209 if (r == -EINVAL) { 210 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Kernel too old missing accel " 211 "information, assuming accel is working\n"); 212 return TRUE; 213 } 214 return FALSE; 215 } 216 if (tmp) 217 return TRUE; 218 return FALSE; 219} 220 221static Bool RADEONPreInitAccel_KMS(ScrnInfoPtr pScrn) 222{ 223 RADEONInfoPtr info = RADEONPTR(pScrn); 224 225 if (!(info->accel_state = xcalloc(1, sizeof(struct radeon_accel_state)))) { 226 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to allocate accel_state rec!\n"); 227 return FALSE; 228 } 229 230 if (xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE) || 231 (!RADEONIsAccelWorking(pScrn))) { 232 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 233 "GPU accel disabled or not working, using shadowfb for KMS\n"); 234 info->r600_shadow_fb = TRUE; 235 if (!xf86LoadSubModule(pScrn, "shadow")) 236 info->r600_shadow_fb = FALSE; 237 return TRUE; 238 } 239 240 if ((info->ChipFamily == CHIP_FAMILY_RS100) || 241 (info->ChipFamily == CHIP_FAMILY_RS200) || 242 (info->ChipFamily == CHIP_FAMILY_RS300) || 243 (info->ChipFamily == CHIP_FAMILY_RS400) || 244 (info->ChipFamily == CHIP_FAMILY_RS480) || 245 (info->ChipFamily == CHIP_FAMILY_RS600) || 246 (info->ChipFamily == CHIP_FAMILY_RS690) || 247 (info->ChipFamily == CHIP_FAMILY_RS740)) 248 info->accel_state->has_tcl = FALSE; 249 else { 250 info->accel_state->has_tcl = TRUE; 251 } 252 253 info->useEXA = TRUE; 254 255 if (info->useEXA) { 256 int errmaj = 0, errmin = 0; 257 info->exaReq.majorversion = EXA_VERSION_MAJOR; 258 info->exaReq.minorversion = EXA_VERSION_MINOR; 259 if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, 260 &info->exaReq, &errmaj, &errmin)) { 261 LoaderErrorMsg(NULL, "exa", errmaj, errmin); 262 return FALSE; 263 } 264 } 265 266 return TRUE; 267} 268 269static Bool RADEONPreInitChipType_KMS(ScrnInfoPtr pScrn) 270{ 271 RADEONInfoPtr info = RADEONPTR(pScrn); 272 uint32_t cmd_stat; 273 int i; 274 275 info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo); 276 pScrn->chipset = (char *)xf86TokenToString(RADEONChipsets, info->Chipset); 277 if (!pScrn->chipset) { 278 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 279 "ChipID 0x%04x is not recognized\n", info->Chipset); 280 return FALSE; 281 } 282 283 if (info->Chipset < 0) { 284 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 285 "Chipset \"%s\" is not recognized\n", pScrn->chipset); 286 return FALSE; 287 } 288 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 289 "Chipset: \"%s\" (ChipID = 0x%04x)\n", 290 pScrn->chipset, 291 info->Chipset); 292 293 for (i = 0; i < sizeof(RADEONCards) / sizeof(RADEONCardInfo); i++) { 294 if (info->Chipset == RADEONCards[i].pci_device_id) { 295 RADEONCardInfo *card = &RADEONCards[i]; 296 info->ChipFamily = card->chip_family; 297 info->IsMobility = card->mobility; 298 info->IsIGP = card->igp; 299 break; 300 } 301 } 302 303 info->cardType = CARD_PCI; 304 305 PCI_READ_LONG(info->PciInfo, &cmd_stat, PCI_CMD_STAT_REG); 306 if (cmd_stat & RADEON_CAP_LIST) { 307 uint32_t cap_ptr, cap_id; 308 309 PCI_READ_LONG(info->PciInfo, &cap_ptr, RADEON_CAPABILITIES_PTR_PCI_CONFIG); 310 cap_ptr &= RADEON_CAP_PTR_MASK; 311 312 while(cap_ptr != RADEON_CAP_ID_NULL) { 313 PCI_READ_LONG(info->PciInfo, &cap_id, cap_ptr); 314 if ((cap_id & 0xff)== RADEON_CAP_ID_AGP) { 315 info->cardType = CARD_AGP; 316 break; 317 } 318 if ((cap_id & 0xff)== RADEON_CAP_ID_EXP) { 319 info->cardType = CARD_PCIE; 320 break; 321 } 322 cap_ptr = (cap_id >> 8) & RADEON_CAP_PTR_MASK; 323 } 324 } 325 326 327 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s card detected\n", 328 (info->cardType==CARD_PCI) ? "PCI" : 329 (info->cardType==CARD_PCIE) ? "PCIE" : "AGP"); 330 331 /* treat PCIE IGP cards as PCI */ 332 if (info->cardType == CARD_PCIE && info->IsIGP) 333 info->cardType = CARD_PCI; 334 335 if ((info->ChipFamily >= CHIP_FAMILY_R600) && info->IsIGP) 336 info->cardType = CARD_PCIE; 337 338 /* not sure about gart table requirements */ 339 if ((info->ChipFamily == CHIP_FAMILY_RS600) && info->IsIGP) 340 info->cardType = CARD_PCIE; 341 342#ifdef RENDER 343 info->RenderAccel = xf86ReturnOptValBool(info->Options, OPTION_RENDER_ACCEL, 344 info->Chipset != PCI_CHIP_RN50_515E && 345 info->Chipset != PCI_CHIP_RN50_5969); 346#endif 347 return TRUE; 348} 349 350static Bool radeon_alloc_dri(ScrnInfoPtr pScrn) 351{ 352 RADEONInfoPtr info = RADEONPTR(pScrn); 353 if (!(info->dri = xcalloc(1, sizeof(struct radeon_dri)))) { 354 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate dri rec!\n"); 355 return FALSE; 356 } 357 358 if (!(info->cp = xcalloc(1, sizeof(struct radeon_cp)))) { 359 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate cp rec!\n"); 360 return FALSE; 361 } 362 return TRUE; 363} 364 365static Bool radeon_open_drm_master(ScrnInfoPtr pScrn) 366{ 367 RADEONInfoPtr info = RADEONPTR(pScrn); 368 RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 369 struct pci_device *dev = info->PciInfo; 370 char *busid; 371 drmSetVersion sv; 372 int err; 373 374 if (pRADEONEnt->fd) { 375 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 376 " reusing fd for second head\n"); 377 378 info->dri2.drm_fd = pRADEONEnt->fd; 379 goto out; 380 } 381 382 busid = XNFprintf("pci:%04x:%02x:%02x.%d", 383 dev->domain, dev->bus, dev->dev, dev->func); 384 385 info->dri2.drm_fd = drmOpen("radeon", busid); 386 if (info->dri2.drm_fd == -1) { 387 388 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 389 "[drm] Failed to open DRM device for %s: %s\n", 390 busid, strerror(errno)); 391 xfree(busid); 392 return FALSE; 393 } 394 xfree(busid); 395 396 /* Check that what we opened was a master or a master-capable FD, 397 * by setting the version of the interface we'll use to talk to it. 398 * (see DRIOpenDRMMaster() in DRI1) 399 */ 400 sv.drm_di_major = 1; 401 sv.drm_di_minor = 1; 402 sv.drm_dd_major = -1; 403 sv.drm_dd_minor = -1; 404 err = drmSetInterfaceVersion(info->dri2.drm_fd, &sv); 405 if (err != 0) { 406 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 407 "[drm] failed to set drm interface version.\n"); 408 drmClose(info->dri2.drm_fd); 409 info->dri2.drm_fd = -1; 410 411 return FALSE; 412 } 413 414 pRADEONEnt->fd = info->dri2.drm_fd; 415 out: 416 info->drmmode.fd = info->dri2.drm_fd; 417 info->dri->drmFD = info->dri2.drm_fd; 418 return TRUE; 419} 420 421Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) 422{ 423 RADEONInfoPtr info; 424 RADEONEntPtr pRADEONEnt; 425 DevUnion* pPriv; 426 Gamma zeros = { 0.0, 0.0, 0.0 }; 427 428 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 429 "RADEONPreInit_KMS\n"); 430 if (pScrn->numEntities != 1) return FALSE; 431 if (!RADEONGetRec(pScrn)) return FALSE; 432 433 info = RADEONPTR(pScrn); 434 info->MMIO = NULL; 435 info->IsSecondary = FALSE; 436 info->IsPrimary = FALSE; 437 info->kms_enabled = TRUE; 438 info->pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]); 439 if (info->pEnt->location.type != BUS_PCI) goto fail; 440 441 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], 442 getRADEONEntityIndex()); 443 pRADEONEnt = pPriv->ptr; 444 445 if(xf86IsEntityShared(pScrn->entityList[0])) 446 { 447 if(xf86IsPrimInitDone(pScrn->entityList[0])) 448 { 449 info->IsSecondary = TRUE; 450 pRADEONEnt->pSecondaryScrn = pScrn; 451 } 452 else 453 { 454 info->IsPrimary = TRUE; 455 xf86SetPrimInitDone(pScrn->entityList[0]); 456 pRADEONEnt->pPrimaryScrn = pScrn; 457 pRADEONEnt->HasSecondary = FALSE; 458 } 459 } 460 461 info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index); 462 pScrn->monitor = pScrn->confScreen->monitor; 463 464 if (!RADEONPreInitVisual(pScrn)) 465 goto fail; 466 467 xf86CollectOptions(pScrn, NULL); 468 if (!(info->Options = xalloc(sizeof(RADEONOptions_KMS)))) 469 goto fail; 470 471 memcpy(info->Options, RADEONOptions_KMS, sizeof(RADEONOptions_KMS)); 472 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options); 473 474 if (!RADEONPreInitWeight(pScrn)) 475 goto fail; 476 477 if (!RADEONPreInitChipType_KMS(pScrn)) 478 goto fail; 479 480 if (!radeon_alloc_dri(pScrn)) 481 return FALSE; 482 483 info->allowColorTiling = xf86ReturnOptValBool(info->Options, 484 OPTION_COLOR_TILING, FALSE); 485 if (info->ChipFamily >= CHIP_FAMILY_R600) { 486 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Color tiling is not yet supported on R600/R700\n"); 487 info->allowColorTiling = FALSE; 488 } 489 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 490 "KMS Color Tiling: %sabled\n", info->allowColorTiling ? "en" : "dis"); 491 492 if (radeon_open_drm_master(pScrn) == FALSE) { 493 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n"); 494 goto fail; 495 } 496 if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == FALSE) { 497 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n"); 498 goto fail; 499 } 500 501 info->dri2.enabled = FALSE; 502 info->dri->pKernelDRMVersion = drmGetVersion(info->dri->drmFD); 503 if (info->dri->pKernelDRMVersion == NULL) { 504 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 505 "RADEONDRIGetVersion failed to get the DRM version\n"); 506 goto fail; 507 } 508 509 { 510 struct drm_radeon_gem_info mminfo; 511 512 if (!drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo))) 513 { 514 info->vram_size = mminfo.vram_visible; 515 info->gart_size = mminfo.gart_size; 516 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 517 "mem size init: gart size :%llx vram size: s:%llx visible:%llx\n", 518 (unsigned long long)mminfo.gart_size, 519 (unsigned long long)mminfo.vram_size, 520 (unsigned long long)mminfo.vram_visible); 521 } 522 } 523 524 info->exa_pixmaps = xf86ReturnOptValBool(info->Options, 525 OPTION_EXA_PIXMAPS, 526 ((info->vram_size > (32 * 1024 * 1024) && 527 info->RenderAccel))); 528 if (info->exa_pixmaps) 529 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 530 "EXA: Driver will allow EXA pixmaps in VRAM\n"); 531 else 532 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 533 "EXA: Driver will not allow EXA pixmaps in VRAM\n"); 534 RADEONSetPitch(pScrn); 535 536 /* Set display resolution */ 537 xf86SetDpi(pScrn, 0, 0); 538 539 /* Get ScreenInit function */ 540 if (!xf86LoadSubModule(pScrn, "fb")) return FALSE; 541 542 if (!xf86SetGamma(pScrn, zeros)) return FALSE; 543 544 if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) { 545 if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE; 546 } 547 548 if (!RADEONPreInitAccel_KMS(pScrn)) goto fail; 549 550 if (pScrn->modes == NULL) { 551 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); 552 goto fail; 553 } 554 555 return TRUE; 556 fail: 557 RADEONFreeRec(pScrn); 558 return FALSE; 559 560} 561 562static Bool RADEONCursorInit_KMS(ScreenPtr pScreen) 563{ 564 return xf86_cursors_init (pScreen, CURSOR_WIDTH, CURSOR_HEIGHT, 565 (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 566 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 567 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | 568 HARDWARE_CURSOR_UPDATE_UNHIDDEN | 569 HARDWARE_CURSOR_ARGB)); 570} 571 572static Bool RADEONSaveScreen_KMS(ScreenPtr pScreen, int mode) 573{ 574 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 575 Bool unblank; 576 577 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 578 "RADEONSaveScreen(%d)\n", mode); 579 580 unblank = xf86IsUnblank(mode); 581 if (unblank) SetTimeSinceLastInputEvent(); 582 583 if ((pScrn != NULL) && pScrn->vtSema) { 584 if (unblank) 585 RADEONUnblank(pScrn); 586 else 587 RADEONBlank(pScrn); 588 } 589 return TRUE; 590} 591 592/* Called at the end of each server generation. Restore the original 593 * text mode, unmap video memory, and unwrap and call the saved 594 * CloseScreen function. 595 */ 596static Bool RADEONCloseScreen_KMS(int scrnIndex, ScreenPtr pScreen) 597{ 598 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 599 RADEONInfoPtr info = RADEONPTR(pScrn); 600 601 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 602 "RADEONCloseScreen\n"); 603 604 if (info->cs) 605 radeon_cs_flush_indirect(pScrn); 606 607 if (info->accel_state->exa) { 608 exaDriverFini(pScreen); 609 xfree(info->accel_state->exa); 610 info->accel_state->exa = NULL; 611 } 612 613 if (info->accel_state->use_vbos) 614 radeon_vbo_free_lists(pScrn); 615 616 drmDropMaster(info->dri->drmFD); 617 618 if (info->cursor) xf86DestroyCursorInfoRec(info->cursor); 619 info->cursor = NULL; 620 621 radeon_dri2_close_screen(pScreen); 622 623 pScrn->vtSema = FALSE; 624 xf86ClearPrimInitDone(info->pEnt->index); 625 pScreen->BlockHandler = info->BlockHandler; 626 pScreen->CloseScreen = info->CloseScreen; 627 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 628} 629 630 631void RADEONFreeScreen_KMS(int scrnIndex, int flags) 632{ 633 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 634 RADEONInfoPtr info = RADEONPTR(pScrn); 635 636 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 637 "RADEONFreeScreen\n"); 638 639 /* when server quits at PreInit, we don't need do this anymore*/ 640 if (!info) return; 641 642 RADEONFreeRec(pScrn); 643} 644 645Bool RADEONScreenInit_KMS(int scrnIndex, ScreenPtr pScreen, 646 int argc, char **argv) 647{ 648 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 649 RADEONInfoPtr info = RADEONPTR(pScrn); 650 int subPixelOrder = SubPixelUnknown; 651 char* s; 652 void *front_ptr; 653 int ret; 654 655 pScrn->fbOffset = 0; 656 657 miClearVisualTypes(); 658 if (!miSetVisualTypes(pScrn->depth, 659 miGetDefaultVisualMask(pScrn->depth), 660 pScrn->rgbBits, 661 pScrn->defaultVisual)) return FALSE; 662 miSetPixmapDepths (); 663 664 ret = drmSetMaster(info->dri->drmFD); 665 if (ret) { 666 ErrorF("Unable to retrieve master\n"); 667 return FALSE; 668 } 669 info->directRenderingEnabled = FALSE; 670 if (info->r600_shadow_fb == FALSE) 671 info->directRenderingEnabled = radeon_dri2_screen_init(pScreen); 672 673 front_ptr = info->FB; 674 675 if (!info->bufmgr) 676 info->bufmgr = radeon_bo_manager_gem_ctor(info->dri->drmFD); 677 if (!info->bufmgr) { 678 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 679 "failed to initialise GEM buffer manager"); 680 return FALSE; 681 } 682 drmmode_set_bufmgr(pScrn, &info->drmmode, info->bufmgr); 683 684 if (!info->csm) 685 info->csm = radeon_cs_manager_gem_ctor(info->dri->drmFD); 686 if (!info->csm) { 687 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 688 "failed to initialise command submission manager"); 689 return FALSE; 690 } 691 692 if (!info->cs) 693 info->cs = radeon_cs_create(info->csm, RADEON_BUFFER_SIZE/4); 694 if (!info->cs) { 695 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 696 "failed to initialise command submission buffer"); 697 return FALSE; 698 } 699 700 radeon_cs_set_limit(info->cs, RADEON_GEM_DOMAIN_GTT, info->gart_size); 701 radeon_cs_space_set_flush(info->cs, (void(*)(void *))radeon_cs_flush_indirect, pScrn); 702 703 radeon_setup_kernel_mem(pScreen); 704 front_ptr = info->front_bo->ptr; 705 706 if (info->r600_shadow_fb) { 707 info->fb_shadow = xcalloc(1, 708 pScrn->displayWidth * pScrn->virtualY * 709 ((pScrn->bitsPerPixel + 7) >> 3)); 710 if (info->fb_shadow == NULL) { 711 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 712 "Failed to allocate shadow framebuffer\n"); 713 info->r600_shadow_fb = FALSE; 714 } else { 715 if (!fbScreenInit(pScreen, info->fb_shadow, 716 pScrn->virtualX, pScrn->virtualY, 717 pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, 718 pScrn->bitsPerPixel)) 719 return FALSE; 720 } 721 } 722 723 if (info->r600_shadow_fb == FALSE) { 724 /* Init fb layer */ 725 if (!fbScreenInit(pScreen, front_ptr, 726 pScrn->virtualX, pScrn->virtualY, 727 pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, 728 pScrn->bitsPerPixel)) 729 return FALSE; 730 } 731 732 xf86SetBlackWhitePixels(pScreen); 733 734 if (pScrn->bitsPerPixel > 8) { 735 VisualPtr visual; 736 737 visual = pScreen->visuals + pScreen->numVisuals; 738 while (--visual >= pScreen->visuals) { 739 if ((visual->class | DynamicClass) == DirectColor) { 740 visual->offsetRed = pScrn->offset.red; 741 visual->offsetGreen = pScrn->offset.green; 742 visual->offsetBlue = pScrn->offset.blue; 743 visual->redMask = pScrn->mask.red; 744 visual->greenMask = pScrn->mask.green; 745 visual->blueMask = pScrn->mask.blue; 746 } 747 } 748 } 749 750 /* Must be after RGB order fixed */ 751 fbPictureInit (pScreen, 0, 0); 752 753#ifdef RENDER 754 if ((s = xf86GetOptValString(info->Options, OPTION_SUBPIXEL_ORDER))) { 755 if (strcmp(s, "RGB") == 0) subPixelOrder = SubPixelHorizontalRGB; 756 else if (strcmp(s, "BGR") == 0) subPixelOrder = SubPixelHorizontalBGR; 757 else if (strcmp(s, "NONE") == 0) subPixelOrder = SubPixelNone; 758 PictureSetSubpixelOrder (pScreen, subPixelOrder); 759 } 760#endif 761 762 pScrn->vtSema = TRUE; 763 /* Backing store setup */ 764 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 765 "Initializing backing store\n"); 766 miInitializeBackingStore(pScreen); 767 xf86SetBackingStore(pScreen); 768 769 770 if (info->directRenderingEnabled) { 771 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); 772 } else { 773 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 774 "Direct rendering disabled\n"); 775 } 776 777 if (info->r600_shadow_fb) { 778 xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); 779 info->accelOn = FALSE; 780 } else { 781 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 782 "Initializing Acceleration\n"); 783 if (RADEONAccelInit(pScreen)) { 784 xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); 785 info->accelOn = TRUE; 786 } else { 787 xf86DrvMsg(scrnIndex, X_ERROR, 788 "Acceleration initialization failed\n"); 789 xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); 790 info->accelOn = FALSE; 791 } 792 } 793 794 /* Init DPMS */ 795 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 796 "Initializing DPMS\n"); 797 xf86DPMSInit(pScreen, xf86DPMSSet, 0); 798 799 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 800 "Initializing Cursor\n"); 801 802 /* Set Silken Mouse */ 803 xf86SetSilkenMouse(pScreen); 804 805 /* Cursor setup */ 806 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 807 808 if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) { 809 if (RADEONCursorInit_KMS(pScreen)) { 810 } 811 } 812 813 /* DGA setup */ 814#ifdef XFreeXDGA 815 /* DGA is dangerous on kms as the base and framebuffer location may change: 816 * http://lists.freedesktop.org/archives/xorg-devel/2009-September/002113.html 817 */ 818 /* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */ 819#endif 820 if (info->r600_shadow_fb == FALSE) { 821 /* Init Xv */ 822 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 823 "Initializing Xv\n"); 824 RADEONInitVideo(pScreen); 825 } 826 827 if (info->r600_shadow_fb == TRUE) { 828 if (!shadowSetup(pScreen)) { 829 xf86DrvMsg(scrnIndex, X_ERROR, 830 "Shadowfb initialization failed\n"); 831 return FALSE; 832 } 833 } 834 pScrn->pScreen = pScreen; 835 836 if (!drmmode_set_desired_modes(pScrn, &info->drmmode)) 837 return FALSE; 838 839 /* Provide SaveScreen & wrap BlockHandler and CloseScreen */ 840 /* Wrap CloseScreen */ 841 info->CloseScreen = pScreen->CloseScreen; 842 pScreen->CloseScreen = RADEONCloseScreen_KMS; 843 pScreen->SaveScreen = RADEONSaveScreen_KMS; 844 info->BlockHandler = pScreen->BlockHandler; 845 pScreen->BlockHandler = RADEONBlockHandler_KMS; 846 info->CreateScreenResources = pScreen->CreateScreenResources; 847 pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS; 848 849 if (!xf86CrtcScreenInit (pScreen)) 850 return FALSE; 851 852 /* Wrap pointer motion to flip touch screen around */ 853// info->PointerMoved = pScrn->PointerMoved; 854// pScrn->PointerMoved = RADEONPointerMoved; 855 856 if (!drmmode_setup_colormap(pScreen, pScrn)) 857 return FALSE; 858 859 /* Note unused options */ 860 if (serverGeneration == 1) 861 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 862 863 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 864 "RADEONScreenInit finished\n"); 865 866 info->accel_state->XInited3D = FALSE; 867 info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; 868 869 return TRUE; 870} 871 872Bool RADEONEnterVT_KMS(int scrnIndex, int flags) 873{ 874 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 875 RADEONInfoPtr info = RADEONPTR(pScrn); 876 int ret; 877 878 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 879 "RADEONEnterVT_KMS\n"); 880 881 882 ret = drmSetMaster(info->dri->drmFD); 883 if (ret) 884 ErrorF("Unable to retrieve master\n"); 885 info->accel_state->XInited3D = FALSE; 886 info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; 887 888 pScrn->vtSema = TRUE; 889 890 if (!drmmode_set_desired_modes(pScrn, &info->drmmode)) 891 return FALSE; 892 893 if (info->adaptor) 894 RADEONResetVideo(pScrn); 895 896 return TRUE; 897} 898 899 900void RADEONLeaveVT_KMS(int scrnIndex, int flags) 901{ 902 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 903 RADEONInfoPtr info = RADEONPTR(pScrn); 904 905 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 906 "RADEONLeaveVT_KMS\n"); 907 908 drmDropMaster(info->dri->drmFD); 909 910#ifdef HAVE_FREE_SHADOW 911 xf86RotateFreeShadow(pScrn); 912#endif 913 914 xf86_hide_cursors (pScrn); 915 info->accel_state->XInited3D = FALSE; 916 info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; 917 918 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 919 "Ok, leaving now...\n"); 920} 921 922 923Bool RADEONSwitchMode_KMS(int scrnIndex, DisplayModePtr mode, int flags) 924{ 925 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 926 Bool ret; 927 ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0); 928 return ret; 929 930} 931 932void RADEONAdjustFrame_KMS(int scrnIndex, int x, int y, int flags) 933{ 934 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 935 RADEONInfoPtr info = RADEONPTR(pScrn); 936 drmmode_adjust_frame(pScrn, &info->drmmode, x, y, flags); 937 return; 938} 939 940static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) 941{ 942 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 943 RADEONInfoPtr info = RADEONPTR(pScrn); 944 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 945 int cpp = info->CurrentLayout.pixel_bytes; 946 int screen_size; 947 int stride = pScrn->displayWidth * cpp; 948 int total_size_bytes = 0, remain_size_bytes; 949 950 if (info->accel_state->exa != NULL) { 951 xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map already initialized\n"); 952 return FALSE; 953 } 954 if (info->r600_shadow_fb == FALSE) { 955 info->accel_state->exa = exaDriverAlloc(); 956 if (info->accel_state->exa == NULL) 957 return FALSE; 958 } 959 960 screen_size = RADEON_ALIGN(pScrn->virtualY, 16) * stride; 961 { 962 int cursor_size = 64 * 4 * 64; 963 int c; 964 965 cursor_size = RADEON_ALIGN(cursor_size, RADEON_GPU_PAGE_SIZE); 966 for (c = 0; c < xf86_config->num_crtc; c++) { 967 /* cursor objects */ 968 if (info->cursor_bo[c] == NULL) { 969 info->cursor_bo[c] = radeon_bo_open(info->bufmgr, 0, 970 cursor_size, 0, 971 RADEON_GEM_DOMAIN_VRAM, 0); 972 if (!info->cursor_bo[c]) { 973 return FALSE; 974 } 975 976#if X_BYTE_ORDER == X_BIG_ENDIAN 977 radeon_bo_set_tiling(info->cursor_bo[c], RADEON_TILING_SWAP_32BIT | 978 RADEON_TILING_SURFACE, stride); 979#endif 980 981 if (radeon_bo_map(info->cursor_bo[c], 1)) { 982 ErrorF("Failed to map cursor buffer memory\n"); 983 } 984 985 drmmode_set_cursor(pScrn, &info->drmmode, c, info->cursor_bo[c]); 986 total_size_bytes += cursor_size; 987 } 988 } 989 } 990 991 screen_size = RADEON_ALIGN(screen_size, RADEON_GPU_PAGE_SIZE); 992 /* keep area front front buffer - but don't allocate it yet */ 993 total_size_bytes += screen_size; 994 995 /* work out from the mm size what the exa / tex sizes need to be */ 996 remain_size_bytes = info->vram_size - total_size_bytes; 997 998 info->dri->textureSize = 0; 999 1000 if (info->front_bo == NULL) { 1001 uint32_t tiling_flags = 0; 1002 1003 info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size, 1004 0, RADEON_GEM_DOMAIN_VRAM, 0); 1005 if (info->r600_shadow_fb == TRUE) { 1006 if (radeon_bo_map(info->front_bo, 1)) { 1007 ErrorF("Failed to map cursor buffer memory\n"); 1008 } 1009 } 1010 if (info->allowColorTiling) { 1011 tiling_flags |= RADEON_TILING_MACRO; 1012 } 1013#if X_BYTE_ORDER == X_BIG_ENDIAN 1014 switch (cpp) { 1015 case 4: 1016 tiling_flags |= RADEON_TILING_SWAP_32BIT; 1017 break; 1018 case 2: 1019 tiling_flags |= RADEON_TILING_SWAP_16BIT; 1020 break; 1021 } 1022#endif 1023 if (tiling_flags) { 1024 radeon_bo_set_tiling(info->front_bo, 1025 tiling_flags | RADEON_TILING_SURFACE, stride); 1026 } 1027 } 1028 1029 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer size: %dK\n", info->front_bo->size/1024); 1030 radeon_kms_update_vram_limit(pScrn, screen_size); 1031 return TRUE; 1032} 1033 1034void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, int new_fb_size) 1035{ 1036 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1037 RADEONInfoPtr info = RADEONPTR(pScrn); 1038 int remain_size_bytes; 1039 int total_size_bytes; 1040 int c; 1041 1042 for (c = 0; c < xf86_config->num_crtc; c++) { 1043 if (info->cursor_bo[c] != NULL) { 1044 total_size_bytes += (64 * 4 * 64); 1045 } 1046 } 1047 1048 total_size_bytes += new_fb_size; 1049 remain_size_bytes = info->vram_size - new_fb_size; 1050 remain_size_bytes = (remain_size_bytes / 10) * 9; 1051 radeon_cs_set_limit(info->cs, RADEON_GEM_DOMAIN_VRAM, remain_size_bytes); 1052 1053 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VRAM usage limit set to %dK\n", remain_size_bytes / 1024); 1054} 1055 1056 1057#endif 1058