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