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