amdgpu_kms.c revision 504d986f
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 "amdgpu_drv.h" 35#include "amdgpu_drm_queue.h" 36#include "amdgpu_glamor.h" 37#include "amdgpu_probe.h" 38#include "micmap.h" 39 40#include "amdgpu_version.h" 41#include "shadow.h" 42#include <xf86Priv.h> 43 44#include "amdpciids.h" 45 46/* DPMS */ 47#ifdef HAVE_XEXTPROTO_71 48#include <X11/extensions/dpmsconst.h> 49#else 50#define DPMS_SERVER 51#include <X11/extensions/dpms.h> 52#endif 53 54#include <X11/extensions/damageproto.h> 55 56#include "amdgpu_chipinfo_gen.h" 57#include "amdgpu_bo_helper.h" 58#include "amdgpu_pixmap.h" 59 60#include <gbm.h> 61 62static DevScreenPrivateKeyRec amdgpu_client_private_key; 63 64extern SymTabRec AMDGPUChipsets[]; 65static Bool amdgpu_setup_kernel_mem(ScreenPtr pScreen); 66 67const OptionInfoRec AMDGPUOptions_KMS[] = { 68 {OPTION_ACCEL, "Accel", OPTV_BOOLEAN, {0}, FALSE}, 69 {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, 70 {OPTION_PAGE_FLIP, "EnablePageFlip", OPTV_BOOLEAN, {0}, FALSE}, 71 {OPTION_SUBPIXEL_ORDER, "SubPixelOrder", OPTV_ANYSTR, {0}, FALSE}, 72 {OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE}, 73 {OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE}, 74 {OPTION_DRI3, "DRI3", OPTV_BOOLEAN, {0}, FALSE}, 75 {OPTION_DRI, "DRI", OPTV_INTEGER, {0}, FALSE}, 76 {OPTION_SHADOW_PRIMARY, "ShadowPrimary", OPTV_BOOLEAN, {0}, FALSE}, 77 {OPTION_TEAR_FREE, "TearFree", OPTV_BOOLEAN, {0}, FALSE}, 78 {OPTION_DELETE_DP12, "DeleteUnusedDP12Displays", OPTV_BOOLEAN, {0}, FALSE}, 79 {-1, NULL, OPTV_NONE, {0}, FALSE} 80}; 81 82const OptionInfoRec *AMDGPUOptionsWeak(void) 83{ 84 return AMDGPUOptions_KMS; 85} 86 87extern _X_EXPORT int gAMDGPUEntityIndex; 88 89static int getAMDGPUEntityIndex(void) 90{ 91 return gAMDGPUEntityIndex; 92} 93 94AMDGPUEntPtr AMDGPUEntPriv(ScrnInfoPtr pScrn) 95{ 96 DevUnion *pPriv; 97 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 98 pPriv = xf86GetEntityPrivate(info->pEnt->index, getAMDGPUEntityIndex()); 99 return pPriv->ptr; 100} 101 102/* Allocate our private AMDGPUInfoRec */ 103static Bool AMDGPUGetRec(ScrnInfoPtr pScrn) 104{ 105 if (pScrn->driverPrivate) 106 return TRUE; 107 108 pScrn->driverPrivate = xnfcalloc(sizeof(AMDGPUInfoRec), 1); 109 return TRUE; 110} 111 112/* Free our private AMDGPUInfoRec */ 113static void AMDGPUFreeRec(ScrnInfoPtr pScrn) 114{ 115 DevUnion *pPriv; 116 AMDGPUEntPtr pAMDGPUEnt; 117 AMDGPUInfoPtr info; 118 119 if (!pScrn) 120 return; 121 122 info = AMDGPUPTR(pScrn); 123 if (info && info->fbcon_pixmap) 124 pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap); 125 126 pPriv = xf86GetEntityPrivate(xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1])->index, 127 gAMDGPUEntityIndex); 128 pAMDGPUEnt = pPriv->ptr; 129 if (pAMDGPUEnt->fd > 0) { 130 DevUnion *pPriv; 131 AMDGPUEntPtr pAMDGPUEnt; 132 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], 133 getAMDGPUEntityIndex()); 134 135 pAMDGPUEnt = pPriv->ptr; 136 pAMDGPUEnt->fd_ref--; 137 if (!pAMDGPUEnt->fd_ref) { 138 amdgpu_device_deinitialize(pAMDGPUEnt->pDev); 139#ifdef XF86_PDEV_SERVER_FD 140 if (!(pAMDGPUEnt->platform_dev && 141 pAMDGPUEnt->platform_dev->flags & XF86_PDEV_SERVER_FD)) 142#endif 143 drmClose(pAMDGPUEnt->fd); 144 pAMDGPUEnt->fd = 0; 145 } 146 } 147 148 free(pScrn->driverPrivate); 149 pScrn->driverPrivate = NULL; 150} 151 152static void *amdgpuShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, 153 int mode, CARD32 * size, void *closure) 154{ 155 ScrnInfoPtr pScrn = xf86ScreenToScrn(screen); 156 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 157 int stride; 158 159 stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8; 160 *size = stride; 161 162 return ((uint8_t *) info->front_buffer->cpu_ptr + row * stride + offset); 163} 164 165static void 166amdgpuUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf) 167{ 168 shadowUpdatePacked(pScreen, pBuf); 169} 170 171static Bool 172callback_needs_flush(AMDGPUInfoPtr info, struct amdgpu_client_priv *client_priv) 173{ 174 return (int)(client_priv->needs_flush - info->gpu_flushed) > 0; 175} 176 177static void 178amdgpu_event_callback(CallbackListPtr *list, 179 pointer user_data, pointer call_data) 180{ 181 EventInfoRec *eventinfo = call_data; 182 ScrnInfoPtr pScrn = user_data; 183 ScreenPtr pScreen = pScrn->pScreen; 184 struct amdgpu_client_priv *client_priv = 185 dixLookupScreenPrivate(&eventinfo->client->devPrivates, 186 &amdgpu_client_private_key, pScreen); 187 struct amdgpu_client_priv *server_priv = 188 dixLookupScreenPrivate(&serverClient->devPrivates, 189 &amdgpu_client_private_key, pScreen); 190 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 191 int i; 192 193 if (callback_needs_flush(info, client_priv) || 194 callback_needs_flush(info, server_priv)) 195 return; 196 197 /* Don't let gpu_flushed get too far ahead of needs_flush, in order 198 * to prevent false positives in callback_needs_flush() 199 */ 200 client_priv->needs_flush = info->gpu_flushed; 201 server_priv->needs_flush = info->gpu_flushed; 202 203 for (i = 0; i < eventinfo->count; i++) { 204 if (eventinfo->events[i].u.u.type == info->callback_event_type) { 205 client_priv->needs_flush++; 206 server_priv->needs_flush++; 207 return; 208 } 209 } 210} 211 212static void 213amdgpu_flush_callback(CallbackListPtr *list, 214 pointer user_data, pointer call_data) 215{ 216 ScrnInfoPtr pScrn = user_data; 217 ScreenPtr pScreen = pScrn->pScreen; 218 ClientPtr client = call_data ? call_data : serverClient; 219 struct amdgpu_client_priv *client_priv = 220 dixLookupScreenPrivate(&client->devPrivates, 221 &amdgpu_client_private_key, pScreen); 222 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 223 224 if (pScrn->vtSema && callback_needs_flush(info, client_priv)) 225 amdgpu_glamor_flush(pScrn); 226} 227 228static Bool AMDGPUCreateScreenResources_KMS(ScreenPtr pScreen) 229{ 230 ExtensionEntry *damage_ext = CheckExtension("DAMAGE"); 231 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 232 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 233 PixmapPtr pixmap; 234 235 pScreen->CreateScreenResources = info->CreateScreenResources; 236 if (!(*pScreen->CreateScreenResources) (pScreen)) 237 return FALSE; 238 pScreen->CreateScreenResources = AMDGPUCreateScreenResources_KMS; 239 240 /* Set the RandR primary output if Xorg hasn't */ 241 if (dixPrivateKeyRegistered(rrPrivKey)) { 242 rrScrPrivPtr rrScrPriv = rrGetScrPriv(pScreen); 243 244 if ( 245#ifdef AMDGPU_PIXMAP_SHARING 246 !pScreen->isGPU && 247#endif 248 !rrScrPriv->primaryOutput) 249 { 250 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 251 252 rrScrPriv->primaryOutput = xf86_config->output[0]->randr_output; 253 RROutputChanged(rrScrPriv->primaryOutput, FALSE); 254 rrScrPriv->layoutChanged = TRUE; 255 } 256 } 257 258 if (!drmmode_set_desired_modes(pScrn, &info->drmmode, pScrn->is_gpu)) 259 return FALSE; 260 261 drmmode_uevent_init(pScrn, &info->drmmode); 262 263 if (info->shadow_fb) { 264 pixmap = pScreen->GetScreenPixmap(pScreen); 265 266 if (!shadowAdd(pScreen, pixmap, amdgpuUpdatePacked, 267 amdgpuShadowWindow, 0, NULL)) 268 return FALSE; 269 } 270 271 if (info->dri2.enabled || info->use_glamor) { 272 if (info->front_buffer) { 273 PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); 274 275 if (!amdgpu_set_pixmap_bo(pPix, info->front_buffer)) 276 return FALSE; 277 } 278 } 279 280 if (info->use_glamor) 281 amdgpu_glamor_create_screen_resources(pScreen); 282 283 info->callback_event_type = -1; 284 if (damage_ext) { 285 info->callback_event_type = damage_ext->eventBase + XDamageNotify; 286 287 if (!AddCallback(&FlushCallback, amdgpu_flush_callback, pScrn)) 288 return FALSE; 289 290 if (!AddCallback(&EventCallback, amdgpu_event_callback, pScrn)) { 291 DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn); 292 return FALSE; 293 } 294 295 if (!dixRegisterScreenPrivateKey(&amdgpu_client_private_key, pScreen, 296 PRIVATE_CLIENT, sizeof(struct amdgpu_client_priv))) { 297 DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn); 298 DeleteCallback(&EventCallback, amdgpu_event_callback, pScrn); 299 return FALSE; 300 } 301 } 302 303 return TRUE; 304} 305 306static Bool 307amdgpu_scanout_extents_intersect(xf86CrtcPtr xf86_crtc, BoxPtr extents) 308{ 309 extents->x1 -= xf86_crtc->filter_width >> 1; 310 extents->x2 += xf86_crtc->filter_width >> 1; 311 extents->y1 -= xf86_crtc->filter_height >> 1; 312 extents->y2 += xf86_crtc->filter_height >> 1; 313 pixman_f_transform_bounds(&xf86_crtc->f_framebuffer_to_crtc, extents); 314 315 extents->x1 = max(extents->x1, 0); 316 extents->y1 = max(extents->y1, 0); 317 extents->x2 = min(extents->x2, xf86_crtc->mode.HDisplay); 318 extents->y2 = min(extents->y2, xf86_crtc->mode.VDisplay); 319 320 return (extents->x1 < extents->x2 && extents->y1 < extents->y2); 321} 322 323static RegionPtr 324transform_region(RegionPtr region, struct pict_f_transform *transform, 325 int w, int h) 326{ 327 BoxPtr boxes = RegionRects(region); 328 int nboxes = RegionNumRects(region); 329 xRectanglePtr rects = malloc(nboxes * sizeof(*rects)); 330 RegionPtr transformed; 331 int nrects = 0; 332 BoxRec box; 333 int i; 334 335 for (i = 0; i < nboxes; i++) { 336 box.x1 = boxes[i].x1; 337 box.x2 = boxes[i].x2; 338 box.y1 = boxes[i].y1; 339 box.y2 = boxes[i].y2; 340 pixman_f_transform_bounds(transform, &box); 341 342 box.x1 = max(box.x1, 0); 343 box.y1 = max(box.y1, 0); 344 box.x2 = min(box.x2, w); 345 box.y2 = min(box.y2, h); 346 if (box.x1 >= box.x2 || box.y1 >= box.y2) 347 continue; 348 349 rects[nrects].x = box.x1; 350 rects[nrects].y = box.y1; 351 rects[nrects].width = box.x2 - box.x1; 352 rects[nrects].height = box.y2 - box.y1; 353 nrects++; 354 } 355 356 transformed = RegionFromRects(nrects, rects, CT_UNSORTED); 357 free(rects); 358 return transformed; 359} 360 361static void 362amdgpu_sync_scanout_pixmaps(xf86CrtcPtr xf86_crtc, RegionPtr new_region, 363 int scanout_id) 364{ 365 drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; 366 DrawablePtr dst = &drmmode_crtc->scanout[scanout_id].pixmap->drawable; 367 DrawablePtr src = &drmmode_crtc->scanout[scanout_id ^ 1].pixmap->drawable; 368 RegionPtr last_region = &drmmode_crtc->scanout_last_region; 369 ScrnInfoPtr scrn = xf86_crtc->scrn; 370 ScreenPtr pScreen = scrn->pScreen; 371 RegionRec remaining; 372 RegionPtr sync_region = NULL; 373 BoxRec extents; 374 GCPtr gc; 375 376 if (RegionNil(last_region)) 377 return; 378 379 RegionNull(&remaining); 380 RegionSubtract(&remaining, last_region, new_region); 381 if (RegionNil(&remaining)) 382 goto uninit; 383 384 extents = *RegionExtents(&remaining); 385 if (!amdgpu_scanout_extents_intersect(xf86_crtc, &extents)) 386 goto uninit; 387 388#if XF86_CRTC_VERSION >= 4 389 if (xf86_crtc->driverIsPerformingTransform) { 390 sync_region = transform_region(&remaining, 391 &xf86_crtc->f_framebuffer_to_crtc, 392 dst->width, dst->height); 393 } else 394#endif /* XF86_CRTC_VERSION >= 4 */ 395 { 396 sync_region = RegionDuplicate(&remaining); 397 RegionTranslate(sync_region, -xf86_crtc->x, -xf86_crtc->y); 398 } 399 400 gc = GetScratchGC(dst->depth, pScreen); 401 if (gc) { 402 ValidateGC(dst, gc); 403 gc->funcs->ChangeClip(gc, CT_REGION, sync_region, 0); 404 sync_region = NULL; 405 gc->ops->CopyArea(src, dst, gc, 0, 0, dst->width, dst->height, 0, 0); 406 FreeScratchGC(gc); 407 } 408 409 uninit: 410 if (sync_region) 411 RegionDestroy(sync_region); 412 RegionUninit(&remaining); 413} 414 415#ifdef AMDGPU_PIXMAP_SHARING 416 417static RegionPtr 418dirty_region(PixmapDirtyUpdatePtr dirty) 419{ 420 RegionPtr damageregion = DamageRegion(dirty->damage); 421 RegionPtr dstregion; 422 423#ifdef HAS_DIRTYTRACKING_ROTATION 424 if (dirty->rotation != RR_Rotate_0) { 425 dstregion = transform_region(damageregion, 426 &dirty->f_inverse, 427 dirty->slave_dst->drawable.width, 428 dirty->slave_dst->drawable.height); 429 } else 430#endif 431 { 432 RegionRec pixregion; 433 434 dstregion = RegionDuplicate(damageregion); 435 RegionTranslate(dstregion, -dirty->x, -dirty->y); 436 PixmapRegionInit(&pixregion, dirty->slave_dst); 437 RegionIntersect(dstregion, dstregion, &pixregion); 438 RegionUninit(&pixregion); 439 } 440 441 return dstregion; 442} 443 444static void 445redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region) 446{ 447 ScrnInfoPtr scrn = xf86ScreenToScrn(dirty->src->drawable.pScreen); 448 449 if (RegionNil(region)) 450 goto out; 451 452 if (dirty->slave_dst->master_pixmap) 453 DamageRegionAppend(&dirty->slave_dst->drawable, region); 454 455#ifdef HAS_DIRTYTRACKING_ROTATION 456 PixmapSyncDirtyHelper(dirty); 457#else 458 PixmapSyncDirtyHelper(dirty, region); 459#endif 460 461 amdgpu_glamor_flush(scrn); 462 if (dirty->slave_dst->master_pixmap) 463 DamageRegionProcessPending(&dirty->slave_dst->drawable); 464 465out: 466 DamageEmpty(dirty->damage); 467} 468 469static void 470amdgpu_prime_scanout_update_abort(xf86CrtcPtr crtc, void *event_data) 471{ 472 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 473 474 drmmode_crtc->scanout_update_pending = FALSE; 475} 476 477void 478amdgpu_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty) 479{ 480 ScreenPtr master_screen = dirty->src->master_pixmap->drawable.pScreen; 481 PixmapDirtyUpdatePtr ent; 482 RegionPtr region; 483 484 xorg_list_for_each_entry(ent, &master_screen->pixmap_dirty_list, ent) { 485 if (ent->slave_dst != dirty->src) 486 continue; 487 488 region = dirty_region(ent); 489 redisplay_dirty(ent, region); 490 RegionDestroy(region); 491 } 492} 493 494 495#if HAS_SYNC_SHARED_PIXMAP 496 497static Bool 498master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) 499{ 500 ScreenPtr master_screen = dirty->src->master_pixmap->drawable.pScreen; 501 502 return master_screen->SyncSharedPixmap != NULL; 503} 504 505static Bool 506slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) 507{ 508 ScreenPtr slave_screen = dirty->slave_dst->drawable.pScreen; 509 510 return slave_screen->SyncSharedPixmap != NULL; 511} 512 513static void 514call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty) 515{ 516 ScreenPtr master_screen = dirty->src->master_pixmap->drawable.pScreen; 517 518 master_screen->SyncSharedPixmap(dirty); 519} 520 521#else /* !HAS_SYNC_SHARED_PIXMAP */ 522 523static Bool 524master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) 525{ 526 ScrnInfoPtr master_scrn = xf86ScreenToScrn(dirty->src->master_pixmap->drawable.pScreen); 527 528 return master_scrn->driverName == scrn->driverName; 529} 530 531static Bool 532slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) 533{ 534 ScrnInfoPtr slave_scrn = xf86ScreenToScrn(dirty->slave_dst->drawable.pScreen); 535 536 return slave_scrn->driverName == scrn->driverName; 537} 538 539static void 540call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty) 541{ 542 amdgpu_sync_shared_pixmap(dirty); 543} 544 545#endif /* HAS_SYNC_SHARED_PIXMAPS */ 546 547 548static Bool 549amdgpu_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id) 550{ 551 ScrnInfoPtr scrn = crtc->scrn; 552 ScreenPtr screen = scrn->pScreen; 553 AMDGPUInfoPtr info = AMDGPUPTR(scrn); 554 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 555 PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap; 556 PixmapDirtyUpdatePtr dirty; 557 Bool ret = FALSE; 558 559 xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { 560 if (dirty->src == scanoutpix && dirty->slave_dst == 561 drmmode_crtc->scanout[scanout_id ^ info->tear_free].pixmap) { 562 RegionPtr region; 563 564 if (master_has_sync_shared_pixmap(scrn, dirty)) 565 call_sync_shared_pixmap(dirty); 566 567 region = dirty_region(dirty); 568 if (RegionNil(region)) 569 goto destroy; 570 571 if (info->tear_free) { 572 RegionTranslate(region, crtc->x, crtc->y); 573 amdgpu_sync_scanout_pixmaps(crtc, region, scanout_id); 574 amdgpu_glamor_flush(scrn); 575 RegionCopy(&drmmode_crtc->scanout_last_region, region); 576 RegionTranslate(region, -crtc->x, -crtc->y); 577 dirty->slave_dst = drmmode_crtc->scanout[scanout_id].pixmap; 578 } 579 580 redisplay_dirty(dirty, region); 581 ret = TRUE; 582 destroy: 583 RegionDestroy(region); 584 break; 585 } 586 } 587 588 return ret; 589} 590 591void 592amdgpu_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, 593 void *event_data) 594{ 595 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 596 597 amdgpu_prime_scanout_do_update(crtc, 0); 598 drmmode_crtc->scanout_update_pending = FALSE; 599} 600 601static void 602amdgpu_prime_scanout_update(PixmapDirtyUpdatePtr dirty) 603{ 604 ScreenPtr screen = dirty->slave_dst->drawable.pScreen; 605 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 606 AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn); 607 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 608 xf86CrtcPtr xf86_crtc = NULL; 609 drmmode_crtc_private_ptr drmmode_crtc = NULL; 610 uintptr_t drm_queue_seq; 611 drmVBlank vbl; 612 int c; 613 614 /* Find the CRTC which is scanning out from this slave pixmap */ 615 for (c = 0; c < xf86_config->num_crtc; c++) { 616 xf86_crtc = xf86_config->crtc[c]; 617 drmmode_crtc = xf86_crtc->driver_private; 618 if (drmmode_crtc->scanout[0].pixmap == dirty->slave_dst) 619 break; 620 } 621 622 if (c == xf86_config->num_crtc || 623 !xf86_crtc->enabled || 624 drmmode_crtc->scanout_update_pending || 625 !drmmode_crtc->scanout[0].pixmap || 626 drmmode_crtc->pending_dpms_mode != DPMSModeOn) 627 return; 628 629 drm_queue_seq = amdgpu_drm_queue_alloc(xf86_crtc, 630 AMDGPU_DRM_QUEUE_CLIENT_DEFAULT, 631 AMDGPU_DRM_QUEUE_ID_DEFAULT, NULL, 632 amdgpu_prime_scanout_update_handler, 633 amdgpu_prime_scanout_update_abort); 634 if (drm_queue_seq == AMDGPU_DRM_QUEUE_ERROR) { 635 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 636 "amdgpu_drm_queue_alloc failed for PRIME update\n"); 637 return; 638 } 639 640 vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT; 641 vbl.request.type |= amdgpu_populate_vbl_request_type(xf86_crtc); 642 vbl.request.sequence = 1; 643 vbl.request.signal = drm_queue_seq; 644 if (drmWaitVBlank(pAMDGPUEnt->fd, &vbl)) { 645 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 646 "drmWaitVBlank failed for PRIME update: %s\n", 647 strerror(errno)); 648 amdgpu_drm_abort_entry(drm_queue_seq); 649 return; 650 } 651 652 drmmode_crtc->scanout_update_pending = TRUE; 653} 654 655static void 656amdgpu_prime_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data) 657{ 658 drmmode_crtc_private_ptr drmmode_crtc = event_data; 659 660 drmmode_crtc->scanout_update_pending = FALSE; 661 drmmode_clear_pending_flip(crtc); 662} 663 664static void 665amdgpu_prime_scanout_flip(PixmapDirtyUpdatePtr ent) 666{ 667 ScreenPtr screen = ent->slave_dst->drawable.pScreen; 668 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 669 AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn); 670 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 671 xf86CrtcPtr crtc = NULL; 672 drmmode_crtc_private_ptr drmmode_crtc = NULL; 673 uintptr_t drm_queue_seq; 674 unsigned scanout_id; 675 int c; 676 677 /* Find the CRTC which is scanning out from this slave pixmap */ 678 for (c = 0; c < xf86_config->num_crtc; c++) { 679 crtc = xf86_config->crtc[c]; 680 drmmode_crtc = crtc->driver_private; 681 scanout_id = drmmode_crtc->scanout_id; 682 if (drmmode_crtc->scanout[scanout_id].pixmap == ent->slave_dst) 683 break; 684 } 685 686 if (c == xf86_config->num_crtc || 687 !crtc->enabled || 688 drmmode_crtc->scanout_update_pending || 689 !drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap || 690 drmmode_crtc->pending_dpms_mode != DPMSModeOn) 691 return; 692 693 scanout_id = drmmode_crtc->scanout_id ^ 1; 694 if (!amdgpu_prime_scanout_do_update(crtc, scanout_id)) 695 return; 696 697 drm_queue_seq = amdgpu_drm_queue_alloc(crtc, 698 AMDGPU_DRM_QUEUE_CLIENT_DEFAULT, 699 AMDGPU_DRM_QUEUE_ID_DEFAULT, 700 drmmode_crtc, NULL, 701 amdgpu_prime_scanout_flip_abort); 702 if (drm_queue_seq == AMDGPU_DRM_QUEUE_ERROR) { 703 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 704 "Allocating DRM event queue entry failed for PRIME flip.\n"); 705 return; 706 } 707 708 if (drmModePageFlip(pAMDGPUEnt->fd, drmmode_crtc->mode_crtc->crtc_id, 709 drmmode_crtc->scanout[scanout_id].fb_id, 710 DRM_MODE_PAGE_FLIP_EVENT, (void*)drm_queue_seq)) { 711 xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n", 712 __func__, strerror(errno)); 713 return; 714 } 715 716 drmmode_crtc->scanout_id = scanout_id; 717 drmmode_crtc->scanout_update_pending = TRUE; 718 drmmode_crtc->flip_pending = TRUE; 719} 720 721static void 722amdgpu_dirty_update(ScrnInfoPtr scrn) 723{ 724 AMDGPUInfoPtr info = AMDGPUPTR(scrn); 725 ScreenPtr screen = scrn->pScreen; 726 PixmapDirtyUpdatePtr ent; 727 RegionPtr region; 728 729 xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) { 730 if (screen->isGPU) { 731 PixmapDirtyUpdatePtr region_ent = ent; 732 733 if (master_has_sync_shared_pixmap(scrn, ent)) { 734 ScreenPtr master_screen = ent->src->master_pixmap->drawable.pScreen; 735 736 xorg_list_for_each_entry(region_ent, &master_screen->pixmap_dirty_list, ent) { 737 if (region_ent->slave_dst == ent->src) 738 break; 739 } 740 } 741 742 region = dirty_region(region_ent); 743 744 if (RegionNotEmpty(region)) { 745 if (info->tear_free) 746 amdgpu_prime_scanout_flip(ent); 747 else 748 amdgpu_prime_scanout_update(ent); 749 } else { 750 DamageEmpty(region_ent->damage); 751 } 752 753 RegionDestroy(region); 754 } else { 755 if (slave_has_sync_shared_pixmap(scrn, ent)) 756 continue; 757 758 region = dirty_region(ent); 759 redisplay_dirty(ent, region); 760 RegionDestroy(region); 761 } 762 } 763} 764#endif 765 766static Bool 767amdgpu_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id) 768{ 769 drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; 770 RegionPtr pRegion = DamageRegion(drmmode_crtc->scanout_damage); 771 ScrnInfoPtr scrn = xf86_crtc->scrn; 772 ScreenPtr pScreen = scrn->pScreen; 773 AMDGPUInfoPtr info = AMDGPUPTR(scrn); 774 DrawablePtr pDraw; 775 BoxRec extents; 776 777 if (!xf86_crtc->enabled || 778 drmmode_crtc->pending_dpms_mode != DPMSModeOn || 779 !drmmode_crtc->scanout[scanout_id].pixmap) 780 return FALSE; 781 782 if (!RegionNotEmpty(pRegion)) 783 return FALSE; 784 785 pDraw = &drmmode_crtc->scanout[scanout_id].pixmap->drawable; 786 extents = *RegionExtents(pRegion); 787 if (!amdgpu_scanout_extents_intersect(xf86_crtc, &extents)) 788 return FALSE; 789 790 if (info->tear_free) { 791 amdgpu_sync_scanout_pixmaps(xf86_crtc, pRegion, scanout_id); 792 RegionCopy(&drmmode_crtc->scanout_last_region, pRegion); 793 } 794 RegionEmpty(pRegion); 795 796#if XF86_CRTC_VERSION >= 4 797 if (xf86_crtc->driverIsPerformingTransform) { 798 SourceValidateProcPtr SourceValidate = pScreen->SourceValidate; 799 PictFormatPtr format = PictureWindowFormat(pScreen->root); 800 int error; 801 PicturePtr src, dst; 802 XID include_inferiors = IncludeInferiors; 803 804 src = CreatePicture(None, 805 &pScreen->root->drawable, 806 format, 807 CPSubwindowMode, 808 &include_inferiors, serverClient, &error); 809 if (!src) { 810 ErrorF("Failed to create source picture for transformed scanout " 811 "update\n"); 812 goto out; 813 } 814 815 dst = CreatePicture(None, pDraw, format, 0L, NULL, serverClient, &error); 816 if (!dst) { 817 ErrorF("Failed to create destination picture for transformed scanout " 818 "update\n"); 819 goto free_src; 820 } 821 error = SetPictureTransform(src, &xf86_crtc->crtc_to_framebuffer); 822 if (error) { 823 ErrorF("SetPictureTransform failed for transformed scanout " 824 "update\n"); 825 goto free_dst; 826 } 827 828 if (xf86_crtc->filter) 829 SetPicturePictFilter(src, xf86_crtc->filter, xf86_crtc->params, 830 xf86_crtc->nparams); 831 832 pScreen->SourceValidate = NULL; 833 CompositePicture(PictOpSrc, 834 src, NULL, dst, 835 extents.x1, extents.y1, 0, 0, extents.x1, 836 extents.y1, extents.x2 - extents.x1, 837 extents.y2 - extents.y1); 838 pScreen->SourceValidate = SourceValidate; 839 840 free_dst: 841 FreePicture(dst, None); 842 free_src: 843 FreePicture(src, None); 844 } else 845 out: 846#endif /* XF86_CRTC_VERSION >= 4 */ 847 { 848 GCPtr gc = GetScratchGC(pDraw->depth, pScreen); 849 850 ValidateGC(pDraw, gc); 851 (*gc->ops->CopyArea)(&pScreen->GetScreenPixmap(pScreen)->drawable, 852 pDraw, gc, 853 xf86_crtc->x + extents.x1, xf86_crtc->y + extents.y1, 854 extents.x2 - extents.x1, extents.y2 - extents.y1, 855 extents.x1, extents.y1); 856 FreeScratchGC(gc); 857 } 858 859 amdgpu_glamor_flush(xf86_crtc->scrn); 860 861 return TRUE; 862} 863 864static void 865amdgpu_scanout_update_abort(xf86CrtcPtr crtc, void *event_data) 866{ 867 drmmode_crtc_private_ptr drmmode_crtc = event_data; 868 869 drmmode_crtc->scanout_update_pending = FALSE; 870} 871 872void 873amdgpu_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, 874 void *event_data) 875{ 876 amdgpu_scanout_do_update(crtc, 0); 877 878 amdgpu_scanout_update_abort(crtc, event_data); 879} 880 881static void 882amdgpu_scanout_update(xf86CrtcPtr xf86_crtc) 883{ 884 drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; 885 uintptr_t drm_queue_seq; 886 ScrnInfoPtr scrn; 887 AMDGPUEntPtr pAMDGPUEnt; 888 drmVBlank vbl; 889 DamagePtr pDamage; 890 RegionPtr pRegion; 891 BoxRec extents; 892 893 if (!xf86_crtc->enabled || 894 drmmode_crtc->scanout_update_pending || 895 !drmmode_crtc->scanout[0].pixmap || 896 drmmode_crtc->pending_dpms_mode != DPMSModeOn) 897 return; 898 899 pDamage = drmmode_crtc->scanout_damage; 900 if (!pDamage) 901 return; 902 903 pRegion = DamageRegion(pDamage); 904 if (!RegionNotEmpty(pRegion)) 905 return; 906 907 extents = *RegionExtents(pRegion); 908 if (!amdgpu_scanout_extents_intersect(xf86_crtc, &extents)) { 909 RegionEmpty(pRegion); 910 return; 911 } 912 913 scrn = xf86_crtc->scrn; 914 drm_queue_seq = amdgpu_drm_queue_alloc(xf86_crtc, 915 AMDGPU_DRM_QUEUE_CLIENT_DEFAULT, 916 AMDGPU_DRM_QUEUE_ID_DEFAULT, 917 drmmode_crtc, 918 amdgpu_scanout_update_handler, 919 amdgpu_scanout_update_abort); 920 if (drm_queue_seq == AMDGPU_DRM_QUEUE_ERROR) { 921 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 922 "amdgpu_drm_queue_alloc failed for scanout update\n"); 923 return; 924 } 925 926 pAMDGPUEnt = AMDGPUEntPriv(scrn); 927 vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT; 928 vbl.request.type |= amdgpu_populate_vbl_request_type(xf86_crtc); 929 vbl.request.sequence = 1; 930 vbl.request.signal = drm_queue_seq; 931 if (drmWaitVBlank(pAMDGPUEnt->fd, &vbl)) { 932 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 933 "drmWaitVBlank failed for scanout update: %s\n", 934 strerror(errno)); 935 amdgpu_drm_abort_entry(drm_queue_seq); 936 return; 937 } 938 939 drmmode_crtc->scanout_update_pending = TRUE; 940} 941 942static void 943amdgpu_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data) 944{ 945 drmmode_crtc_private_ptr drmmode_crtc = event_data; 946 947 drmmode_crtc->scanout_update_pending = FALSE; 948 drmmode_clear_pending_flip(crtc); 949} 950 951static void 952amdgpu_scanout_flip(ScreenPtr pScreen, AMDGPUInfoPtr info, 953 xf86CrtcPtr xf86_crtc) 954{ 955 drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; 956 ScrnInfoPtr scrn; 957 AMDGPUEntPtr pAMDGPUEnt; 958 uintptr_t drm_queue_seq; 959 unsigned scanout_id; 960 961 if (drmmode_crtc->scanout_update_pending) 962 return; 963 964 scanout_id = drmmode_crtc->scanout_id ^ 1; 965 if (!amdgpu_scanout_do_update(xf86_crtc, scanout_id)) 966 return; 967 968 scrn = xf86_crtc->scrn; 969 drm_queue_seq = amdgpu_drm_queue_alloc(xf86_crtc, 970 AMDGPU_DRM_QUEUE_CLIENT_DEFAULT, 971 AMDGPU_DRM_QUEUE_ID_DEFAULT, 972 drmmode_crtc, NULL, 973 amdgpu_scanout_flip_abort); 974 if (drm_queue_seq == AMDGPU_DRM_QUEUE_ERROR) { 975 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 976 "Allocating DRM event queue entry failed.\n"); 977 return; 978 } 979 980 pAMDGPUEnt = AMDGPUEntPriv(scrn); 981 if (drmModePageFlip(pAMDGPUEnt->fd, drmmode_crtc->mode_crtc->crtc_id, 982 drmmode_crtc->scanout[scanout_id].fb_id, 983 DRM_MODE_PAGE_FLIP_EVENT, (void*)drm_queue_seq)) { 984 xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n", 985 __func__, strerror(errno)); 986 return; 987 } 988 989 drmmode_crtc->scanout_id = scanout_id; 990 drmmode_crtc->scanout_update_pending = TRUE; 991 drmmode_crtc->flip_pending = TRUE; 992} 993 994static void AMDGPUBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) 995{ 996 SCREEN_PTR(arg); 997 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 998 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 999 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1000 int c; 1001 1002 pScreen->BlockHandler = info->BlockHandler; 1003 (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); 1004 pScreen->BlockHandler = AMDGPUBlockHandler_KMS; 1005 1006#ifdef AMDGPU_PIXMAP_SHARING 1007 if (!pScreen->isGPU) 1008#endif 1009 { 1010 for (c = 0; c < xf86_config->num_crtc; c++) { 1011 if (info->tear_free) 1012 amdgpu_scanout_flip(pScreen, info, xf86_config->crtc[c]); 1013 else if (info->shadow_primary 1014#if XF86_CRTC_VERSION >= 4 1015 || xf86_config->crtc[c]->driverIsPerformingTransform 1016#endif 1017 ) 1018 amdgpu_scanout_update(xf86_config->crtc[c]); 1019 } 1020 } 1021 1022 if (info->use_glamor) 1023 amdgpu_glamor_flush(pScrn); 1024 1025#ifdef AMDGPU_PIXMAP_SHARING 1026 amdgpu_dirty_update(pScrn); 1027#endif 1028} 1029 1030static void AMDGPUBlockHandler_oneshot(BLOCKHANDLER_ARGS_DECL) 1031{ 1032 SCREEN_PTR(arg); 1033 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1034 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 1035 1036 AMDGPUBlockHandler_KMS(BLOCKHANDLER_ARGS); 1037 1038 drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE); 1039} 1040 1041/* This is called by AMDGPUPreInit to set up the default visual */ 1042static Bool AMDGPUPreInitVisual(ScrnInfoPtr pScrn) 1043{ 1044 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 1045 1046 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) 1047 return FALSE; 1048 1049 switch (pScrn->depth) { 1050 case 8: 1051 case 15: 1052 case 16: 1053 case 24: 1054 break; 1055 1056 default: 1057 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1058 "Given depth (%d) is not supported by %s driver\n", 1059 pScrn->depth, AMDGPU_DRIVER_NAME); 1060 return FALSE; 1061 } 1062 1063 xf86PrintDepthBpp(pScrn); 1064 1065 info->pix24bpp = xf86GetBppFromDepth(pScrn, pScrn->depth); 1066 info->pixel_bytes = pScrn->bitsPerPixel / 8; 1067 1068 if (info->pix24bpp == 24) { 1069 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1070 "Amdgpu does NOT support 24bpp\n"); 1071 return FALSE; 1072 } 1073 1074 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1075 "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n", 1076 pScrn->depth, 1077 info->pixel_bytes, 1078 info->pixel_bytes > 1 ? "s" : "", info->pix24bpp); 1079 1080 if (!xf86SetDefaultVisual(pScrn, -1)) 1081 return FALSE; 1082 1083 if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 1084 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1085 "Default visual (%s) is not supported at depth %d\n", 1086 xf86GetVisualName(pScrn->defaultVisual), 1087 pScrn->depth); 1088 return FALSE; 1089 } 1090 return TRUE; 1091} 1092 1093/* This is called by AMDGPUPreInit to handle all color weight issues */ 1094static Bool AMDGPUPreInitWeight(ScrnInfoPtr pScrn) 1095{ 1096 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 1097 1098 /* Save flag for 6 bit DAC to use for 1099 setting CRTC registers. Otherwise use 1100 an 8 bit DAC, even if xf86SetWeight sets 1101 pScrn->rgbBits to some value other than 1102 8. */ 1103 info->dac6bits = FALSE; 1104 1105 if (pScrn->depth > 8) { 1106 rgb defaultWeight = { 0, 0, 0 }; 1107 1108 if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) 1109 return FALSE; 1110 } else { 1111 pScrn->rgbBits = 8; 1112 } 1113 1114 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1115 "Using %d bits per RGB (%d bit DAC)\n", 1116 pScrn->rgbBits, info->dac6bits ? 6 : 8); 1117 1118 return TRUE; 1119} 1120 1121static Bool AMDGPUPreInitAccel_KMS(ScrnInfoPtr pScrn) 1122{ 1123 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 1124 1125 if (xf86ReturnOptValBool(info->Options, OPTION_ACCEL, TRUE)) { 1126 AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); 1127 Bool use_glamor = TRUE; 1128#ifdef HAVE_GBM_BO_USE_LINEAR 1129 const char *accel_method; 1130 1131 accel_method = xf86GetOptValString(info->Options, OPTION_ACCEL_METHOD); 1132 if ((accel_method && !strcmp(accel_method, "none"))) 1133 use_glamor = FALSE; 1134#endif 1135 1136#ifdef DRI2 1137 info->dri2.available = ! !xf86LoadSubModule(pScrn, "dri2"); 1138#endif 1139 1140 if (info->dri2.available) 1141 info->gbm = gbm_create_device(pAMDGPUEnt->fd); 1142 if (info->gbm == NULL) 1143 info->dri2.available = FALSE; 1144 1145 if (use_glamor && 1146 amdgpu_glamor_pre_init(pScrn)) 1147 return TRUE; 1148 1149 if (info->dri2.available) 1150 return TRUE; 1151 } 1152 1153 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1154 "GPU accel disabled or not working, using shadowfb for KMS\n"); 1155 info->shadow_fb = TRUE; 1156 if (!xf86LoadSubModule(pScrn, "shadow")) 1157 info->shadow_fb = FALSE; 1158 1159 return TRUE; 1160} 1161 1162static Bool AMDGPUPreInitChipType_KMS(ScrnInfoPtr pScrn) 1163{ 1164 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 1165 int i; 1166 1167 info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo); 1168 pScrn->chipset = 1169 (char *)xf86TokenToString(AMDGPUChipsets, info->Chipset); 1170 if (!pScrn->chipset) { 1171 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1172 "ChipID 0x%04x is not recognized\n", info->Chipset); 1173 return FALSE; 1174 } 1175 1176 if (info->Chipset < 0) { 1177 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1178 "Chipset \"%s\" is not recognized\n", 1179 pScrn->chipset); 1180 return FALSE; 1181 } 1182 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1183 "Chipset: \"%s\" (ChipID = 0x%04x)\n", 1184 pScrn->chipset, info->Chipset); 1185 1186 for (i = 0; i < sizeof(AMDGPUCards) / sizeof(AMDGPUCardInfo); i++) { 1187 if (info->Chipset == AMDGPUCards[i].pci_device_id) { 1188 AMDGPUCardInfo *card = &AMDGPUCards[i]; 1189 info->ChipFamily = card->chip_family; 1190 break; 1191 } 1192 } 1193 1194 return TRUE; 1195} 1196 1197static Bool amdgpu_get_tile_config(ScrnInfoPtr pScrn) 1198{ 1199 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 1200 AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); 1201 struct amdgpu_gpu_info gpu_info; 1202 1203 memset(&gpu_info, 0, sizeof(gpu_info)); 1204 amdgpu_query_gpu_info(pAMDGPUEnt->pDev, &gpu_info); 1205 1206 switch ((gpu_info.gb_addr_cfg & 0x70) >> 4) { 1207 case 0: 1208 info->group_bytes = 256; 1209 break; 1210 case 1: 1211 info->group_bytes = 512; 1212 break; 1213 default: 1214 return FALSE; 1215 } 1216 1217 info->have_tiling_info = TRUE; 1218 return TRUE; 1219} 1220 1221static void AMDGPUSetupCapabilities(ScrnInfoPtr pScrn) 1222{ 1223#ifdef AMDGPU_PIXMAP_SHARING 1224 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 1225 AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); 1226 uint64_t value; 1227 int ret; 1228 1229 pScrn->capabilities = 0; 1230 1231 /* PRIME offloading requires acceleration */ 1232 if (!info->use_glamor) 1233 return; 1234 1235 ret = drmGetCap(pAMDGPUEnt->fd, DRM_CAP_PRIME, &value); 1236 if (ret == 0) { 1237 if (value & DRM_PRIME_CAP_EXPORT) 1238 pScrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SourceOffload; 1239 if (value & DRM_PRIME_CAP_IMPORT) { 1240 pScrn->capabilities |= RR_Capability_SinkOffload; 1241 if (info->drmmode.count_crtcs) 1242 pScrn->capabilities |= RR_Capability_SinkOutput; 1243 } 1244 } 1245#endif 1246} 1247 1248/* When the root window is created, initialize the screen contents from 1249 * console if -background none was specified on the command line 1250 */ 1251static Bool AMDGPUCreateWindow_oneshot(WindowPtr pWin) 1252{ 1253 ScreenPtr pScreen = pWin->drawable.pScreen; 1254 ScrnInfoPtr pScrn; 1255 AMDGPUInfoPtr info; 1256 Bool ret; 1257 1258 if (pWin != pScreen->root) 1259 ErrorF("%s called for non-root window %p\n", __func__, pWin); 1260 1261 pScrn = xf86ScreenToScrn(pScreen); 1262 info = AMDGPUPTR(pScrn); 1263 pScreen->CreateWindow = info->CreateWindow; 1264 ret = pScreen->CreateWindow(pWin); 1265 1266 if (ret) 1267 drmmode_copy_fb(pScrn, &info->drmmode); 1268 1269 return ret; 1270} 1271 1272Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags) 1273{ 1274 AMDGPUInfoPtr info; 1275 AMDGPUEntPtr pAMDGPUEnt; 1276 DevUnion *pPriv; 1277 Gamma zeros = { 0.0, 0.0, 0.0 }; 1278 int cpp; 1279 uint64_t heap_size = 0; 1280 uint64_t max_allocation = 0; 1281 Bool sw_cursor; 1282 1283 if (flags & PROBE_DETECT) 1284 return TRUE; 1285 1286 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, 1287 "AMDGPUPreInit_KMS\n"); 1288 if (pScrn->numEntities != 1) 1289 return FALSE; 1290 if (!AMDGPUGetRec(pScrn)) 1291 return FALSE; 1292 1293 info = AMDGPUPTR(pScrn); 1294 info->IsSecondary = FALSE; 1295 info->pEnt = 1296 xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]); 1297 if (info->pEnt->location.type != BUS_PCI 1298#ifdef XSERVER_PLATFORM_BUS 1299 && info->pEnt->location.type != BUS_PLATFORM 1300#endif 1301 ) 1302 goto fail; 1303 1304 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], 1305 getAMDGPUEntityIndex()); 1306 pAMDGPUEnt = pPriv->ptr; 1307 1308 if (xf86IsEntityShared(pScrn->entityList[0])) { 1309 if (xf86IsPrimInitDone(pScrn->entityList[0])) { 1310 info->IsSecondary = TRUE; 1311 } else { 1312 xf86SetPrimInitDone(pScrn->entityList[0]); 1313 } 1314 } 1315 1316 if (info->IsSecondary) 1317 pAMDGPUEnt->secondary_scrn = pScrn; 1318 else 1319 pAMDGPUEnt->primary_scrn = pScrn; 1320 1321 info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index); 1322 pScrn->monitor = pScrn->confScreen->monitor; 1323 1324 if (!AMDGPUPreInitVisual(pScrn)) 1325 goto fail; 1326 1327 xf86CollectOptions(pScrn, NULL); 1328 if (!(info->Options = malloc(sizeof(AMDGPUOptions_KMS)))) 1329 goto fail; 1330 1331 memcpy(info->Options, AMDGPUOptions_KMS, sizeof(AMDGPUOptions_KMS)); 1332 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options); 1333 1334 if (!AMDGPUPreInitWeight(pScrn)) 1335 goto fail; 1336 1337 if (!AMDGPUPreInitChipType_KMS(pScrn)) 1338 goto fail; 1339 1340 info->dri2.available = FALSE; 1341 info->dri2.enabled = FALSE; 1342 info->dri2.pKernelDRMVersion = drmGetVersion(pAMDGPUEnt->fd); 1343 if (info->dri2.pKernelDRMVersion == NULL) { 1344 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1345 "AMDGPUDRIGetVersion failed to get the DRM version\n"); 1346 goto fail; 1347 } 1348 1349 /* Get ScreenInit function */ 1350 if (!xf86LoadSubModule(pScrn, "fb")) 1351 return FALSE; 1352 1353 if (!AMDGPUPreInitAccel_KMS(pScrn)) 1354 goto fail; 1355 1356 amdgpu_drm_queue_init(); 1357 1358 /* don't enable tiling if accel is not enabled */ 1359 if (info->use_glamor) { 1360 /* set default group bytes, overridden by kernel info below */ 1361 info->group_bytes = 256; 1362 info->have_tiling_info = FALSE; 1363 amdgpu_get_tile_config(pScrn); 1364 } 1365 1366 if (info->use_glamor) { 1367 info->tear_free = xf86ReturnOptValBool(info->Options, 1368 OPTION_TEAR_FREE, FALSE); 1369 1370 if (info->tear_free) 1371 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1372 "TearFree enabled\n"); 1373 1374 info->shadow_primary = 1375 xf86ReturnOptValBool(info->Options, OPTION_SHADOW_PRIMARY, FALSE); 1376 1377 if (info->shadow_primary) 1378 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowPrimary enabled\n"); 1379 } 1380 1381 sw_cursor = xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE); 1382 1383 info->allowPageFlip = xf86ReturnOptValBool(info->Options, 1384 OPTION_PAGE_FLIP, 1385 TRUE); 1386 if (sw_cursor || info->tear_free || info->shadow_primary) { 1387 xf86DrvMsg(pScrn->scrnIndex, 1388 info->allowPageFlip ? X_WARNING : X_DEFAULT, 1389 "KMS Pageflipping: disabled%s\n", 1390 info->allowPageFlip ? 1391 (sw_cursor ? " because of SWcursor" : 1392 " because of ShadowPrimary/TearFree") : ""); 1393 info->allowPageFlip = FALSE; 1394 } else { 1395 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1396 "KMS Pageflipping: %sabled\n", 1397 info->allowPageFlip ? "en" : "dis"); 1398 } 1399 1400 if (xf86ReturnOptValBool(info->Options, OPTION_DELETE_DP12, FALSE)) { 1401 info->drmmode.delete_dp_12_displays = TRUE; 1402 } 1403 1404 if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == 1405 FALSE) { 1406 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1407 "Kernel modesetting setup failed\n"); 1408 goto fail; 1409 } 1410 1411 AMDGPUSetupCapabilities(pScrn); 1412 1413 if (info->drmmode.count_crtcs == 1) 1414 pAMDGPUEnt->HasCRTC2 = FALSE; 1415 else 1416 pAMDGPUEnt->HasCRTC2 = TRUE; 1417 1418 if (info->ChipFamily >= CHIP_FAMILY_TAHITI && 1419 info->ChipFamily <= CHIP_FAMILY_HAINAN) { 1420 info->cursor_w = CURSOR_WIDTH; 1421 info->cursor_h = CURSOR_HEIGHT; 1422 } else { 1423 info->cursor_w = CURSOR_WIDTH_CIK; 1424 info->cursor_h = CURSOR_HEIGHT_CIK; 1425 } 1426 1427 amdgpu_query_heap_size(pAMDGPUEnt->pDev, AMDGPU_GEM_DOMAIN_GTT, 1428 &heap_size, &max_allocation); 1429 info->gart_size = heap_size; 1430 amdgpu_query_heap_size(pAMDGPUEnt->pDev, AMDGPU_GEM_DOMAIN_VRAM, 1431 &heap_size, &max_allocation); 1432 info->vram_size = max_allocation; 1433 1434 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1435 "mem size init: gart size :%llx vram size: s:%llx visible:%llx\n", 1436 (unsigned long long)info->gart_size, 1437 (unsigned long long)heap_size, 1438 (unsigned long long)max_allocation); 1439 1440 cpp = pScrn->bitsPerPixel / 8; 1441 pScrn->displayWidth = 1442 AMDGPU_ALIGN(pScrn->virtualX, drmmode_get_pitch_align(pScrn, cpp)); 1443 1444 /* Set display resolution */ 1445 xf86SetDpi(pScrn, 0, 0); 1446 1447 if (!xf86SetGamma(pScrn, zeros)) 1448 return FALSE; 1449 1450 if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) { 1451 if (!xf86LoadSubModule(pScrn, "ramdac")) 1452 return FALSE; 1453 } 1454 1455 if (pScrn->modes == NULL 1456#ifdef XSERVER_PLATFORM_BUS 1457 && !pScrn->is_gpu 1458#endif 1459 ) { 1460 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); 1461 goto fail; 1462 } 1463 1464 return TRUE; 1465fail: 1466 AMDGPUFreeRec(pScrn); 1467 return FALSE; 1468 1469} 1470 1471static Bool AMDGPUCursorInit_KMS(ScreenPtr pScreen) 1472{ 1473 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1474 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 1475 1476 return xf86_cursors_init(pScreen, info->cursor_w, info->cursor_h, 1477 (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 1478 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 1479 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | 1480 HARDWARE_CURSOR_UPDATE_UNHIDDEN | 1481 HARDWARE_CURSOR_ARGB)); 1482} 1483 1484void AMDGPUBlank(ScrnInfoPtr pScrn) 1485{ 1486 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1487 xf86OutputPtr output; 1488 xf86CrtcPtr crtc; 1489 int o, c; 1490 1491 for (c = 0; c < xf86_config->num_crtc; c++) { 1492 crtc = xf86_config->crtc[c]; 1493 for (o = 0; o < xf86_config->num_output; o++) { 1494 output = xf86_config->output[o]; 1495 if (output->crtc != crtc) 1496 continue; 1497 1498 output->funcs->dpms(output, DPMSModeOff); 1499 } 1500 crtc->funcs->dpms(crtc, DPMSModeOff); 1501 } 1502} 1503 1504void AMDGPUUnblank(ScrnInfoPtr pScrn) 1505{ 1506 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1507 xf86OutputPtr output; 1508 xf86CrtcPtr crtc; 1509 int o, c; 1510 for (c = 0; c < xf86_config->num_crtc; c++) { 1511 crtc = xf86_config->crtc[c]; 1512 if (!crtc->enabled) 1513 continue; 1514 crtc->funcs->dpms(crtc, DPMSModeOn); 1515 for (o = 0; o < xf86_config->num_output; o++) { 1516 output = xf86_config->output[o]; 1517 if (output->crtc != crtc) 1518 continue; 1519 output->funcs->dpms(output, DPMSModeOn); 1520 } 1521 } 1522} 1523 1524static Bool amdgpu_set_drm_master(ScrnInfoPtr pScrn) 1525{ 1526 AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); 1527 int err; 1528 1529#ifdef XF86_PDEV_SERVER_FD 1530 if (pAMDGPUEnt->platform_dev && 1531 (pAMDGPUEnt->platform_dev->flags & XF86_PDEV_SERVER_FD)) 1532 return TRUE; 1533#endif 1534 1535 err = drmSetMaster(pAMDGPUEnt->fd); 1536 if (err) 1537 ErrorF("Unable to retrieve master\n"); 1538 1539 return err == 0; 1540} 1541 1542static void amdgpu_drop_drm_master(ScrnInfoPtr pScrn) 1543{ 1544 AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); 1545 1546#ifdef XF86_PDEV_SERVER_FD 1547 if (pAMDGPUEnt->platform_dev && 1548 (pAMDGPUEnt->platform_dev->flags & XF86_PDEV_SERVER_FD)) 1549 return; 1550#endif 1551 1552 drmDropMaster(pAMDGPUEnt->fd); 1553} 1554 1555 1556 1557static Bool AMDGPUSaveScreen_KMS(ScreenPtr pScreen, int mode) 1558{ 1559 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1560 Bool unblank; 1561 1562 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, 1563 "AMDGPUSaveScreen(%d)\n", mode); 1564 1565 unblank = xf86IsUnblank(mode); 1566 if (unblank) 1567 SetTimeSinceLastInputEvent(); 1568 1569 if ((pScrn != NULL) && pScrn->vtSema) { 1570 if (unblank) 1571 AMDGPUUnblank(pScrn); 1572 else 1573 AMDGPUBlank(pScrn); 1574 } 1575 return TRUE; 1576} 1577 1578/* Called at the end of each server generation. Restore the original 1579 * text mode, unmap video memory, and unwrap and call the saved 1580 * CloseScreen function. 1581 */ 1582static Bool AMDGPUCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL) 1583{ 1584 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1585 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 1586 AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); 1587 1588 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, 1589 "AMDGPUCloseScreen\n"); 1590 1591 /* Clear mask of assigned crtc's in this generation */ 1592 pAMDGPUEnt->assigned_crtcs = 0; 1593 1594 drmmode_uevent_fini(pScrn, &info->drmmode); 1595 amdgpu_drm_queue_close(pScrn); 1596 1597 if (info->callback_event_type != -1) { 1598 DeleteCallback(&EventCallback, amdgpu_event_callback, pScrn); 1599 DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn); 1600 } 1601 1602 amdgpu_sync_close(pScreen); 1603 amdgpu_drop_drm_master(pScrn); 1604 1605 drmmode_fini(pScrn, &info->drmmode); 1606 if (info->dri2.enabled) { 1607 amdgpu_dri2_close_screen(pScreen); 1608 } 1609 amdgpu_glamor_fini(pScreen); 1610 pScrn->vtSema = FALSE; 1611 xf86ClearPrimInitDone(info->pEnt->index); 1612 pScreen->BlockHandler = info->BlockHandler; 1613 pScreen->CloseScreen = info->CloseScreen; 1614 return (*pScreen->CloseScreen) (CLOSE_SCREEN_ARGS); 1615} 1616 1617void AMDGPUFreeScreen_KMS(FREE_SCREEN_ARGS_DECL) 1618{ 1619 SCRN_INFO_PTR(arg); 1620 1621 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, 1622 "AMDGPUFreeScreen\n"); 1623 1624 AMDGPUFreeRec(pScrn); 1625} 1626 1627Bool AMDGPUScreenInit_KMS(SCREEN_INIT_ARGS_DECL) 1628{ 1629 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1630 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 1631 int subPixelOrder = SubPixelUnknown; 1632 MessageType from; 1633 Bool value; 1634 int driLevel; 1635 const char *s; 1636 void *front_ptr; 1637 1638 pScrn->fbOffset = 0; 1639 1640 miClearVisualTypes(); 1641 if (!miSetVisualTypes(pScrn->depth, 1642 miGetDefaultVisualMask(pScrn->depth), 1643 pScrn->rgbBits, pScrn->defaultVisual)) 1644 return FALSE; 1645 miSetPixmapDepths(); 1646 1647 if (!amdgpu_set_drm_master(pScrn)) 1648 return FALSE; 1649 1650 info->directRenderingEnabled = FALSE; 1651 if (info->shadow_fb == FALSE) 1652 info->directRenderingEnabled = amdgpu_dri2_screen_init(pScreen); 1653 1654 if (!amdgpu_setup_kernel_mem(pScreen)) { 1655 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1656 "amdgpu_setup_kernel_mem failed\n"); 1657 return FALSE; 1658 } 1659 front_ptr = info->front_buffer->cpu_ptr; 1660 1661 if (info->shadow_fb) { 1662 info->fb_shadow = calloc(1, 1663 pScrn->displayWidth * pScrn->virtualY * 1664 ((pScrn->bitsPerPixel + 7) >> 3)); 1665 if (info->fb_shadow == NULL) { 1666 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1667 "Failed to allocate shadow framebuffer\n"); 1668 info->shadow_fb = FALSE; 1669 } else { 1670 if (!fbScreenInit(pScreen, info->fb_shadow, 1671 pScrn->virtualX, pScrn->virtualY, 1672 pScrn->xDpi, pScrn->yDpi, 1673 pScrn->displayWidth, 1674 pScrn->bitsPerPixel)) 1675 return FALSE; 1676 } 1677 } 1678 1679 if (info->shadow_fb == FALSE) { 1680 /* Init fb layer */ 1681 if (!fbScreenInit(pScreen, front_ptr, 1682 pScrn->virtualX, pScrn->virtualY, 1683 pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, 1684 pScrn->bitsPerPixel)) 1685 return FALSE; 1686 } 1687 1688 xf86SetBlackWhitePixels(pScreen); 1689 1690 if (pScrn->bitsPerPixel > 8) { 1691 VisualPtr visual; 1692 1693 visual = pScreen->visuals + pScreen->numVisuals; 1694 while (--visual >= pScreen->visuals) { 1695 if ((visual->class | DynamicClass) == DirectColor) { 1696 visual->offsetRed = pScrn->offset.red; 1697 visual->offsetGreen = pScrn->offset.green; 1698 visual->offsetBlue = pScrn->offset.blue; 1699 visual->redMask = pScrn->mask.red; 1700 visual->greenMask = pScrn->mask.green; 1701 visual->blueMask = pScrn->mask.blue; 1702 } 1703 } 1704 } 1705 1706 /* Must be after RGB order fixed */ 1707 fbPictureInit(pScreen, 0, 0); 1708 1709#ifdef RENDER 1710 if ((s = xf86GetOptValString(info->Options, OPTION_SUBPIXEL_ORDER))) { 1711 if (strcmp(s, "RGB") == 0) 1712 subPixelOrder = SubPixelHorizontalRGB; 1713 else if (strcmp(s, "BGR") == 0) 1714 subPixelOrder = SubPixelHorizontalBGR; 1715 else if (strcmp(s, "NONE") == 0) 1716 subPixelOrder = SubPixelNone; 1717 PictureSetSubpixelOrder(pScreen, subPixelOrder); 1718 } 1719#endif 1720 1721 value = xorgGetVersion() >= XORG_VERSION_NUMERIC(1,18,3,0,0); 1722 from = X_DEFAULT; 1723 1724 if (info->use_glamor) { 1725 if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value)) 1726 from = X_CONFIG; 1727 1728 if (xf86GetOptValInteger(info->Options, OPTION_DRI, &driLevel) && 1729 (driLevel == 2 || driLevel == 3)) { 1730 from = X_CONFIG; 1731 value = driLevel == 3; 1732 } 1733 } 1734 1735 if (value) { 1736 value = amdgpu_sync_init(pScreen) && 1737 amdgpu_present_screen_init(pScreen) && 1738 amdgpu_dri3_screen_init(pScreen); 1739 1740 if (!value) 1741 from = X_WARNING; 1742 } 1743 1744 xf86DrvMsg(pScrn->scrnIndex, from, "DRI3 %sabled\n", value ? "en" : "dis"); 1745 1746 pScrn->vtSema = TRUE; 1747 xf86SetBackingStore(pScreen); 1748 1749 if (info->directRenderingEnabled) { 1750 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1751 "Direct rendering enabled\n"); 1752 } else { 1753 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1754 "Direct rendering disabled\n"); 1755 } 1756 1757 if (info->use_glamor && info->directRenderingEnabled) { 1758 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, 1759 "Initializing Acceleration\n"); 1760 if (amdgpu_glamor_init(pScreen)) { 1761 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1762 "Acceleration enabled\n"); 1763 } else { 1764 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1765 "Acceleration initialization failed\n"); 1766 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1767 "2D and 3D acceleration disabled\n"); 1768 info->use_glamor = FALSE; 1769 } 1770 } else if (info->directRenderingEnabled) { 1771 if (!amdgpu_pixmap_init(pScreen)) 1772 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D acceleration disabled\n"); 1773 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D acceleration disabled\n"); 1774 } else { 1775 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D and 3D cceleration disabled\n"); 1776 } 1777 1778 /* Init DPMS */ 1779 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, 1780 "Initializing DPMS\n"); 1781 xf86DPMSInit(pScreen, xf86DPMSSet, 0); 1782 1783 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, 1784 "Initializing Cursor\n"); 1785 1786 /* Set Silken Mouse */ 1787 xf86SetSilkenMouse(pScreen); 1788 1789 /* Cursor setup */ 1790 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 1791 1792 if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) { 1793 if (AMDGPUCursorInit_KMS(pScreen)) { 1794 } 1795 } 1796 1797 /* DGA setup */ 1798#ifdef XFreeXDGA 1799 /* DGA is dangerous on kms as the base and framebuffer location may change: 1800 * http://lists.freedesktop.org/archives/xorg-devel/2009-September/002113.html 1801 */ 1802 /* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */ 1803#endif 1804 if (info->shadow_fb == FALSE) { 1805 /* Init Xv */ 1806 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, 1807 "Initializing Xv\n"); 1808 AMDGPUInitVideo(pScreen); 1809 } 1810 1811 if (info->shadow_fb == TRUE) { 1812 if (!shadowSetup(pScreen)) { 1813 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1814 "Shadowfb initialization failed\n"); 1815 return FALSE; 1816 } 1817 } 1818 pScrn->pScreen = pScreen; 1819 1820 if (serverGeneration == 1 && bgNoneRoot && info->use_glamor) { 1821 info->CreateWindow = pScreen->CreateWindow; 1822 pScreen->CreateWindow = AMDGPUCreateWindow_oneshot; 1823 } 1824 1825 /* Provide SaveScreen & wrap BlockHandler and CloseScreen */ 1826 /* Wrap CloseScreen */ 1827 info->CloseScreen = pScreen->CloseScreen; 1828 pScreen->CloseScreen = AMDGPUCloseScreen_KMS; 1829 pScreen->SaveScreen = AMDGPUSaveScreen_KMS; 1830 info->BlockHandler = pScreen->BlockHandler; 1831 pScreen->BlockHandler = AMDGPUBlockHandler_oneshot; 1832 1833 info->CreateScreenResources = pScreen->CreateScreenResources; 1834 pScreen->CreateScreenResources = AMDGPUCreateScreenResources_KMS; 1835 1836#ifdef AMDGPU_PIXMAP_SHARING 1837 pScreen->StartPixmapTracking = PixmapStartDirtyTracking; 1838 pScreen->StopPixmapTracking = PixmapStopDirtyTracking; 1839#if HAS_SYNC_SHARED_PIXMAP 1840 pScreen->SyncSharedPixmap = amdgpu_sync_shared_pixmap; 1841#endif 1842#endif 1843 1844 if (!xf86CrtcScreenInit(pScreen)) 1845 return FALSE; 1846 1847 /* Wrap pointer motion to flip touch screen around */ 1848// info->PointerMoved = pScrn->PointerMoved; 1849// pScrn->PointerMoved = AMDGPUPointerMoved; 1850 1851 if (!drmmode_setup_colormap(pScreen, pScrn)) 1852 return FALSE; 1853 1854 /* Note unused options */ 1855 if (serverGeneration == 1) 1856 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 1857 1858 drmmode_init(pScrn, &info->drmmode); 1859 1860 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, 1861 "AMDGPUScreenInit finished\n"); 1862 1863 return TRUE; 1864} 1865 1866Bool AMDGPUEnterVT_KMS(VT_FUNC_ARGS_DECL) 1867{ 1868 SCRN_INFO_PTR(arg); 1869 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 1870 1871 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, 1872 "AMDGPUEnterVT_KMS\n"); 1873 1874 amdgpu_set_drm_master(pScrn); 1875 1876 pScrn->vtSema = TRUE; 1877 1878 if (!drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE)) 1879 return FALSE; 1880 1881 return TRUE; 1882} 1883 1884void AMDGPULeaveVT_KMS(VT_FUNC_ARGS_DECL) 1885{ 1886 SCRN_INFO_PTR(arg); 1887 1888 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, 1889 "AMDGPULeaveVT_KMS\n"); 1890 1891 amdgpu_drop_drm_master(pScrn); 1892 1893 xf86RotateFreeShadow(pScrn); 1894 drmmode_scanout_free(pScrn); 1895 1896 xf86_hide_cursors(pScrn); 1897 1898 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, 1899 "Ok, leaving now...\n"); 1900} 1901 1902Bool AMDGPUSwitchMode_KMS(SWITCH_MODE_ARGS_DECL) 1903{ 1904 SCRN_INFO_PTR(arg); 1905 Bool ret; 1906 ret = xf86SetSingleMode(pScrn, mode, RR_Rotate_0); 1907 return ret; 1908 1909} 1910 1911void AMDGPUAdjustFrame_KMS(ADJUST_FRAME_ARGS_DECL) 1912{ 1913 SCRN_INFO_PTR(arg); 1914 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 1915 drmmode_adjust_frame(pScrn, &info->drmmode, x, y); 1916 return; 1917} 1918 1919static Bool amdgpu_setup_kernel_mem(ScreenPtr pScreen) 1920{ 1921 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1922 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 1923 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1924 int cpp = info->pixel_bytes; 1925 int cursor_size; 1926 int c; 1927 1928 cursor_size = info->cursor_w * info->cursor_h * 4; 1929 cursor_size = AMDGPU_ALIGN(cursor_size, AMDGPU_GPU_PAGE_SIZE); 1930 for (c = 0; c < xf86_config->num_crtc; c++) { 1931 /* cursor objects */ 1932 if (info->cursor_buffer[c] == NULL) { 1933 if (info->gbm) { 1934 info->cursor_buffer[c] = (struct amdgpu_buffer *)calloc(1, sizeof(struct amdgpu_buffer)); 1935 if (!info->cursor_buffer[c]) { 1936 return FALSE; 1937 } 1938 info->cursor_buffer[c]->ref_count = 1; 1939 info->cursor_buffer[c]->flags = AMDGPU_BO_FLAGS_GBM; 1940 1941 info->cursor_buffer[c]->bo.gbm = gbm_bo_create(info->gbm, 1942 info->cursor_w, 1943 info->cursor_h, 1944 GBM_FORMAT_ARGB8888, 1945 GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE); 1946 if (!info->cursor_buffer[c]->bo.gbm) { 1947 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1948 "Failed to allocate cursor buffer memory\n"); 1949 free(info->cursor_buffer[c]); 1950 return FALSE; 1951 } 1952 } else { 1953 AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); 1954 info->cursor_buffer[c] = amdgpu_bo_open(pAMDGPUEnt->pDev, 1955 cursor_size, 1956 0, 1957 AMDGPU_GEM_DOMAIN_VRAM); 1958 if (!(info->cursor_buffer[c])) { 1959 ErrorF("Failed to allocate cursor buffer memory\n"); 1960 return FALSE; 1961 } 1962 1963 if (amdgpu_bo_cpu_map(info->cursor_buffer[c]->bo.amdgpu, 1964 &info->cursor_buffer[c]->cpu_ptr)) { 1965 ErrorF("Failed to map cursor buffer memory\n"); 1966 } 1967 } 1968 1969 drmmode_set_cursor(pScrn, &info->drmmode, c, 1970 info->cursor_buffer[c]); 1971 } 1972 } 1973 1974 if (info->front_buffer == NULL) { 1975 int pitch; 1976 int hint = 0; 1977 1978 if (info->shadow_primary) 1979 hint = AMDGPU_CREATE_PIXMAP_LINEAR | AMDGPU_CREATE_PIXMAP_GTT; 1980 else if (!info->use_glamor) 1981 hint = AMDGPU_CREATE_PIXMAP_LINEAR; 1982 1983 info->front_buffer = 1984 amdgpu_alloc_pixmap_bo(pScrn, pScrn->virtualX, 1985 pScrn->virtualY, pScrn->depth, 1986 hint, pScrn->bitsPerPixel, 1987 &pitch); 1988 if (!(info->front_buffer)) { 1989 ErrorF("Failed to allocate front buffer memory\n"); 1990 return FALSE; 1991 } 1992 1993 if (!info->use_glamor && 1994 amdgpu_bo_map(pScrn, info->front_buffer) != 0) { 1995 ErrorF("Failed to map front buffer memory\n"); 1996 return FALSE; 1997 } 1998 1999 pScrn->displayWidth = pitch / cpp; 2000 } 2001 2002 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer pitch: %d bytes\n", 2003 pScrn->displayWidth * cpp); 2004 return TRUE; 2005} 2006 2007/* Used to disallow modes that are not supported by the hardware */ 2008ModeStatus AMDGPUValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, 2009 Bool verbose, int flag) 2010{ 2011 /* There are problems with double scan mode at high clocks 2012 * They're likely related PLL and display buffer settings. 2013 * Disable these modes for now. 2014 */ 2015 if (mode->Flags & V_DBLSCAN) { 2016 if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768)) 2017 return MODE_CLOCK_RANGE; 2018 } 2019 return MODE_OK; 2020} 2021