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