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