drmmode_display.c revision 3ed65abb
1/* 2 * Copyright © 2007 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 28#ifdef HAVE_CONFIG_H 29#include "config.h" 30#endif 31 32#include <errno.h> 33#include <sys/ioctl.h> 34#include <time.h> 35#include "cursorstr.h" 36#include "damagestr.h" 37#include "micmap.h" 38#include "xf86cmap.h" 39#include "xf86Priv.h" 40#include "radeon.h" 41#include "radeon_bo_helper.h" 42#include "radeon_glamor.h" 43#include "radeon_list.h" 44#include "radeon_reg.h" 45 46#ifdef RADEON_PIXMAP_SHARING 47#include <dri.h> 48#endif 49 50#include "drmmode_display.h" 51 52/* DPMS */ 53#ifdef HAVE_XEXTPROTO_71 54#include <X11/extensions/dpmsconst.h> 55#else 56#define DPMS_SERVER 57#include <X11/extensions/dpms.h> 58#endif 59 60#define DEFAULT_NOMINAL_FRAME_RATE 60 61 62#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 22 63#define HAVE_NOTIFY_FD 1 64#endif 65 66static Bool 67drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height); 68 69static Bool 70RADEONZaphodStringMatches(ScrnInfoPtr pScrn, const char *s, char *output_name) 71{ 72 int i = 0; 73 char s1[20]; 74 75 do { 76 switch(*s) { 77 case ',': 78 s1[i] = '\0'; 79 i = 0; 80 if (strcmp(s1, output_name) == 0) 81 return TRUE; 82 break; 83 case ' ': 84 case '\t': 85 case '\n': 86 case '\r': 87 break; 88 default: 89 s1[i] = *s; 90 i++; 91 break; 92 } 93 } while(*s++); 94 95 s1[i] = '\0'; 96 if (strcmp(s1, output_name) == 0) 97 return TRUE; 98 99 return FALSE; 100} 101 102static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, 103 int width, int height, 104 int depth, int bpp, 105 int pitch, 106 struct radeon_bo *bo, struct radeon_surface *psurf) 107{ 108 RADEONInfoPtr info = RADEONPTR(pScrn); 109 ScreenPtr pScreen = pScrn->pScreen; 110 PixmapPtr pixmap; 111 struct radeon_surface *surface; 112 uint32_t tiling; 113 114 pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 115 RADEON_CREATE_PIXMAP_SCANOUT); 116 if (!pixmap) 117 return NULL; 118 119 if (!(*pScreen->ModifyPixmapHeader)(pixmap, width, height, 120 depth, bpp, pitch, NULL)) { 121 goto fail; 122 } 123 124 if (!info->use_glamor) 125 exaMoveInPixmap(pixmap); 126 127 if (!radeon_set_pixmap_bo(pixmap, bo)) 128 goto fail; 129 130 if (info->ChipFamily >= CHIP_FAMILY_R600) { 131 surface = radeon_get_pixmap_surface(pixmap); 132 if (surface && psurf) 133 *surface = *psurf; 134 else if (surface) { 135 memset(surface, 0, sizeof(struct radeon_surface)); 136 surface->npix_x = width; 137 surface->npix_y = height; 138 surface->npix_z = 1; 139 surface->blk_w = 1; 140 surface->blk_h = 1; 141 surface->blk_d = 1; 142 surface->array_size = 1; 143 surface->last_level = 0; 144 surface->bpe = bpp / 8; 145 surface->nsamples = 1; 146 surface->flags = RADEON_SURF_SCANOUT; 147 /* we are requiring a recent enough libdrm version */ 148 surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; 149 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); 150 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); 151 tiling = radeon_get_pixmap_tiling_flags(pixmap); 152 if (tiling & RADEON_TILING_MICRO) { 153 surface->flags = RADEON_SURF_CLR(surface->flags, MODE); 154 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); 155 } 156 if (tiling & RADEON_TILING_MACRO) { 157 surface->flags = RADEON_SURF_CLR(surface->flags, MODE); 158 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); 159 } 160 if (radeon_surface_best(info->surf_man, surface)) { 161 goto fail; 162 } 163 if (radeon_surface_init(info->surf_man, surface)) { 164 goto fail; 165 } 166 } 167 } 168 169 if (!info->use_glamor || 170 radeon_glamor_create_textured_pixmap(pixmap, 171 radeon_get_pixmap_private(pixmap))) 172 return pixmap; 173 174fail: 175 pScreen->DestroyPixmap(pixmap); 176 return NULL; 177} 178 179static void drmmode_destroy_bo_pixmap(PixmapPtr pixmap) 180{ 181 ScreenPtr pScreen = pixmap->drawable.pScreen; 182 183 (*pScreen->DestroyPixmap)(pixmap); 184} 185 186static void 187drmmode_ConvertFromKMode(ScrnInfoPtr scrn, 188 drmModeModeInfo *kmode, 189 DisplayModePtr mode) 190{ 191 memset(mode, 0, sizeof(DisplayModeRec)); 192 mode->status = MODE_OK; 193 194 mode->Clock = kmode->clock; 195 196 mode->HDisplay = kmode->hdisplay; 197 mode->HSyncStart = kmode->hsync_start; 198 mode->HSyncEnd = kmode->hsync_end; 199 mode->HTotal = kmode->htotal; 200 mode->HSkew = kmode->hskew; 201 202 mode->VDisplay = kmode->vdisplay; 203 mode->VSyncStart = kmode->vsync_start; 204 mode->VSyncEnd = kmode->vsync_end; 205 mode->VTotal = kmode->vtotal; 206 mode->VScan = kmode->vscan; 207 208 mode->Flags = kmode->flags; //& FLAG_BITS; 209 mode->name = strdup(kmode->name); 210 211 if (kmode->type & DRM_MODE_TYPE_DRIVER) 212 mode->type = M_T_DRIVER; 213 if (kmode->type & DRM_MODE_TYPE_PREFERRED) 214 mode->type |= M_T_PREFERRED; 215 xf86SetModeCrtc (mode, scrn->adjustFlags); 216} 217 218static void 219drmmode_ConvertToKMode(ScrnInfoPtr scrn, 220 drmModeModeInfo *kmode, 221 DisplayModePtr mode) 222{ 223 memset(kmode, 0, sizeof(*kmode)); 224 225 kmode->clock = mode->Clock; 226 kmode->hdisplay = mode->HDisplay; 227 kmode->hsync_start = mode->HSyncStart; 228 kmode->hsync_end = mode->HSyncEnd; 229 kmode->htotal = mode->HTotal; 230 kmode->hskew = mode->HSkew; 231 232 kmode->vdisplay = mode->VDisplay; 233 kmode->vsync_start = mode->VSyncStart; 234 kmode->vsync_end = mode->VSyncEnd; 235 kmode->vtotal = mode->VTotal; 236 kmode->vscan = mode->VScan; 237 238 kmode->flags = mode->Flags; //& FLAG_BITS; 239 if (mode->name) 240 strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN); 241 kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0; 242 243} 244 245/* 246 * Retrieves present time in microseconds that is compatible 247 * with units used by vblank timestamps. Depending on the kernel 248 * version and DRM kernel module configuration, the vblank 249 * timestamp can either be in real time or monotonic time 250 */ 251int drmmode_get_current_ust(int drm_fd, CARD64 *ust) 252{ 253 uint64_t cap_value; 254 int ret; 255 struct timespec now; 256 257 ret = drmGetCap(drm_fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap_value); 258 if (ret || !cap_value) 259 /* old kernel or drm_timestamp_monotonic turned off */ 260 ret = clock_gettime(CLOCK_REALTIME, &now); 261 else 262 ret = clock_gettime(CLOCK_MONOTONIC, &now); 263 if (ret) 264 return ret; 265 *ust = ((CARD64)now.tv_sec * 1000000) + ((CARD64)now.tv_nsec / 1000); 266 return 0; 267} 268 269/* 270 * Get current frame count and frame count timestamp of the crtc. 271 */ 272int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc) 273{ 274 ScrnInfoPtr scrn = crtc->scrn; 275 RADEONInfoPtr info = RADEONPTR(scrn); 276 drmVBlank vbl; 277 int ret; 278 279 vbl.request.type = DRM_VBLANK_RELATIVE; 280 vbl.request.type |= radeon_populate_vbl_request_type(crtc); 281 vbl.request.sequence = 0; 282 283 ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); 284 if (ret) { 285 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 286 "get vblank counter failed: %s\n", strerror(errno)); 287 return ret; 288 } 289 290 *ust = ((CARD64)vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec; 291 *msc = vbl.reply.sequence; 292 293 return Success; 294} 295 296static void 297drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode) 298{ 299 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 300 ScrnInfoPtr scrn = crtc->scrn; 301 RADEONInfoPtr info = RADEONPTR(scrn); 302 CARD64 ust; 303 int ret; 304 305 drmmode_crtc->pending_dpms_mode = mode; 306 307 if (drmmode_crtc->dpms_mode == DPMSModeOn && mode != DPMSModeOn) { 308 drmVBlank vbl; 309 310 /* Wait for any pending flip to finish */ 311 if (drmmode_crtc->flip_pending) 312 return; 313 314 /* 315 * On->Off transition: record the last vblank time, 316 * sequence number and frame period. 317 */ 318 vbl.request.type = DRM_VBLANK_RELATIVE; 319 vbl.request.type |= radeon_populate_vbl_request_type(crtc); 320 vbl.request.sequence = 0; 321 ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); 322 if (ret) 323 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 324 "%s cannot get last vblank counter\n", 325 __func__); 326 else { 327 CARD64 seq = (CARD64)vbl.reply.sequence; 328 CARD64 nominal_frame_rate, pix_in_frame; 329 330 ust = ((CARD64)vbl.reply.tval_sec * 1000000) + 331 vbl.reply.tval_usec; 332 drmmode_crtc->dpms_last_ust = ust; 333 drmmode_crtc->dpms_last_seq = seq; 334 nominal_frame_rate = crtc->mode.Clock; 335 nominal_frame_rate *= 1000; 336 pix_in_frame = crtc->mode.HTotal * crtc->mode.VTotal; 337 if (nominal_frame_rate == 0 || pix_in_frame == 0) 338 nominal_frame_rate = DEFAULT_NOMINAL_FRAME_RATE; 339 else 340 nominal_frame_rate /= pix_in_frame; 341 drmmode_crtc->dpms_last_fps = nominal_frame_rate; 342 } 343 } else if (drmmode_crtc->dpms_mode != DPMSModeOn && mode == DPMSModeOn) { 344 /* 345 * Off->On transition: calculate and accumulate the 346 * number of interpolated vblanks while we were in Off state 347 */ 348 ret = drmmode_get_current_ust(info->dri2.drm_fd, &ust); 349 if (ret) 350 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 351 "%s cannot get current time\n", __func__); 352 else if (drmmode_crtc->dpms_last_ust) { 353 CARD64 time_elapsed, delta_seq; 354 time_elapsed = ust - drmmode_crtc->dpms_last_ust; 355 delta_seq = time_elapsed * drmmode_crtc->dpms_last_fps; 356 delta_seq /= 1000000; 357 drmmode_crtc->interpolated_vblanks += delta_seq; 358 359 } 360 } 361 drmmode_crtc->dpms_mode = mode; 362} 363 364static void 365drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) 366{ 367 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 368 drmmode_ptr drmmode = drmmode_crtc->drmmode; 369 370 /* Disable unused CRTCs */ 371 if (!crtc->enabled || mode != DPMSModeOn) { 372 /* Wait for any pending flip to finish */ 373 if (drmmode_crtc->flip_pending) 374 return; 375 376 drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 377 0, 0, 0, NULL, 0, NULL); 378 } else if (drmmode_crtc->dpms_mode != DPMSModeOn) 379 crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation, 380 crtc->x, crtc->y); 381} 382 383static PixmapPtr 384create_pixmap_for_fbcon(drmmode_ptr drmmode, 385 ScrnInfoPtr pScrn, int fbcon_id) 386{ 387 RADEONInfoPtr info = RADEONPTR(pScrn); 388 PixmapPtr pixmap = info->fbcon_pixmap; 389 struct radeon_bo *bo; 390 drmModeFBPtr fbcon; 391 struct drm_gem_flink flink; 392 393 if (pixmap) 394 return pixmap; 395 396 fbcon = drmModeGetFB(drmmode->fd, fbcon_id); 397 if (fbcon == NULL) 398 return NULL; 399 400 if (fbcon->depth != pScrn->depth || 401 fbcon->width != pScrn->virtualX || 402 fbcon->height != pScrn->virtualY) 403 goto out_free_fb; 404 405 flink.handle = fbcon->handle; 406 if (ioctl(drmmode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { 407 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 408 "Couldn't flink fbcon handle\n"); 409 goto out_free_fb; 410 } 411 412 bo = radeon_bo_open(drmmode->bufmgr, flink.name, 0, 0, 0, 0); 413 if (bo == NULL) { 414 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 415 "Couldn't allocate bo for fbcon handle\n"); 416 goto out_free_fb; 417 } 418 419 pixmap = drmmode_create_bo_pixmap(pScrn, fbcon->width, fbcon->height, 420 fbcon->depth, fbcon->bpp, fbcon->pitch, 421 bo, NULL); 422 info->fbcon_pixmap = pixmap; 423 radeon_bo_unref(bo); 424out_free_fb: 425 drmModeFreeFB(fbcon); 426 return pixmap; 427} 428 429static void 430destroy_pixmap_for_fbcon(ScrnInfoPtr pScrn) 431{ 432 RADEONInfoPtr info = RADEONPTR(pScrn); 433 434 /* XXX: The current GPUVM support in the kernel doesn't allow removing 435 * the virtual address range for this BO, so we need to keep around 436 * the pixmap to avoid breaking glamor with GPUVM 437 */ 438 if (info->use_glamor && info->ChipFamily >= CHIP_FAMILY_CAYMAN) 439 return; 440 441 if (info->fbcon_pixmap) 442 pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap); 443 info->fbcon_pixmap = NULL; 444} 445 446void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) 447{ 448 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 449 RADEONInfoPtr info = RADEONPTR(pScrn); 450 PixmapPtr src, dst; 451 ScreenPtr pScreen = pScrn->pScreen; 452 int fbcon_id = 0; 453 Bool force; 454 GCPtr gc; 455 int i; 456 457 for (i = 0; i < xf86_config->num_crtc; i++) { 458 drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[i]->driver_private; 459 460 if (drmmode_crtc->mode_crtc->buffer_id) 461 fbcon_id = drmmode_crtc->mode_crtc->buffer_id; 462 } 463 464 if (!fbcon_id) 465 return; 466 467 if (fbcon_id == drmmode->fb_id) { 468 /* in some rare case there might be no fbcon and we might already 469 * be the one with the current fb to avoid a false deadlck in 470 * kernel ttm code just do nothing as anyway there is nothing 471 * to do 472 */ 473 return; 474 } 475 476 src = create_pixmap_for_fbcon(drmmode, pScrn, fbcon_id); 477 if (!src) 478 return; 479 480 dst = pScreen->GetScreenPixmap(pScreen); 481 482 gc = GetScratchGC(pScrn->depth, pScreen); 483 ValidateGC(&dst->drawable, gc); 484 485 force = info->accel_state->force; 486 info->accel_state->force = TRUE; 487 (*gc->ops->CopyArea)(&src->drawable, &dst->drawable, gc, 0, 0, 488 pScrn->virtualX, pScrn->virtualY, 0, 0); 489 info->accel_state->force = force; 490 491 FreeScratchGC(gc); 492 493 pScreen->canDoBGNoneRoot = TRUE; 494 destroy_pixmap_for_fbcon(pScrn); 495 return; 496} 497 498static void 499drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, 500 struct drmmode_scanout *scanout) 501{ 502 if (scanout->pixmap) { 503 drmmode_destroy_bo_pixmap(scanout->pixmap); 504 scanout->pixmap = NULL; 505 } 506 507 if (scanout->bo) { 508 drmModeRmFB(drmmode->fd, scanout->fb_id); 509 scanout->fb_id = 0; 510 radeon_bo_unmap(scanout->bo); 511 radeon_bo_unref(scanout->bo); 512 scanout->bo = NULL; 513 } 514} 515 516static void 517drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc) 518{ 519 if (drmmode_crtc->flip_pending) { 520 drmmode_crtc->scanout_destroy[0] = drmmode_crtc->scanout[0]; 521 drmmode_crtc->scanout[0].pixmap = NULL; 522 drmmode_crtc->scanout[0].bo = NULL; 523 drmmode_crtc->scanout_destroy[1] = drmmode_crtc->scanout[1]; 524 drmmode_crtc->scanout[1].pixmap = NULL; 525 drmmode_crtc->scanout[1].bo = NULL; 526 } else { 527 drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, 528 &drmmode_crtc->scanout[0]); 529 drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, 530 &drmmode_crtc->scanout[1]); 531 } 532 533 if (drmmode_crtc->scanout_damage) { 534 DamageDestroy(drmmode_crtc->scanout_damage); 535 drmmode_crtc->scanout_damage = NULL; 536 RegionUninit(&drmmode_crtc->scanout_last_region); 537 } 538} 539 540void 541drmmode_scanout_free(ScrnInfoPtr scrn) 542{ 543 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 544 int c; 545 546 for (c = 0; c < xf86_config->num_crtc; c++) 547 drmmode_crtc_scanout_free(xf86_config->crtc[c]->driver_private); 548} 549 550static PixmapPtr 551drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, 552 int width, int height) 553{ 554 ScrnInfoPtr pScrn = crtc->scrn; 555 RADEONInfoPtr info = RADEONPTR(pScrn); 556 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 557 drmmode_ptr drmmode = drmmode_crtc->drmmode; 558 struct radeon_surface surface; 559 uint32_t tiling = RADEON_CREATE_PIXMAP_TILING_MACRO; 560 int pitch; 561 562 if (scanout->pixmap) { 563 if (scanout->width == width && scanout->height == height) 564 return scanout->pixmap; 565 566 drmmode_crtc_scanout_destroy(drmmode, scanout); 567 } 568 569 if (info->ChipFamily >= CHIP_FAMILY_R600) 570 tiling |= RADEON_CREATE_PIXMAP_TILING_MICRO; 571 scanout->bo = radeon_alloc_pixmap_bo(pScrn, width, height, pScrn->depth, 572 tiling, pScrn->bitsPerPixel, 573 &pitch, &surface, &tiling); 574 if (scanout->bo == NULL) 575 goto error; 576 577 if (drmModeAddFB(drmmode->fd, width, height, pScrn->depth, 578 pScrn->bitsPerPixel, pitch, 579 scanout->bo->handle, 580 &scanout->fb_id) != 0) { 581 ErrorF("failed to add scanout fb\n"); 582 goto error; 583 } 584 585 scanout->pixmap = drmmode_create_bo_pixmap(pScrn, 586 width, height, 587 pScrn->depth, 588 pScrn->bitsPerPixel, 589 pitch, scanout->bo, NULL); 590 if (scanout->pixmap) { 591 scanout->width = width; 592 scanout->height = height; 593 } else { 594 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 595 "Couldn't allocate scanout pixmap for CRTC\n"); 596error: 597 drmmode_crtc_scanout_destroy(drmmode, scanout); 598 } 599 600 return scanout->pixmap; 601} 602 603static void 604radeon_screen_damage_report(DamagePtr damage, RegionPtr region, void *closure) 605{ 606 /* Only keep track of the extents */ 607 RegionUninit(&damage->damage); 608 damage->damage.data = NULL; 609} 610 611static Bool 612drmmode_can_use_hw_cursor(xf86CrtcPtr crtc) 613{ 614 RADEONInfoPtr info = RADEONPTR(crtc->scrn); 615 616 /* Check for Option "SWcursor" */ 617 if (xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) 618 return FALSE; 619 620 /* Fall back to SW cursor if the CRTC is transformed */ 621 if (crtc->transformPresent) 622 return FALSE; 623 624#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7 625 /* Xorg doesn't correctly handle cursor position transform in the 626 * rotation case 627 */ 628 if (crtc->driverIsPerformingTransform && 629 (crtc->rotation & 0xf) != RR_Rotate_0) 630 return FALSE; 631#endif 632 633#if defined(RADEON_PIXMAP_SHARING) 634 /* HW cursor not supported with RandR 1.4 multihead up to 1.18.99.901 */ 635 if (xorgGetVersion() <= XORG_VERSION_NUMERIC(1,18,99,901,0) && 636 !xorg_list_is_empty(&crtc->scrn->pScreen->pixmap_dirty_list)) 637 return FALSE; 638#endif 639 640 return TRUE; 641} 642 643static void 644drmmode_crtc_update_tear_free(xf86CrtcPtr crtc) 645{ 646 RADEONInfoPtr info = RADEONPTR(crtc->scrn); 647 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 648 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 649 int i; 650 651 drmmode_crtc->tear_free = FALSE; 652 653 for (i = 0; i < xf86_config->num_output; i++) { 654 xf86OutputPtr output = xf86_config->output[i]; 655 drmmode_output_private_ptr drmmode_output = output->driver_private; 656 657 if (output->crtc != crtc) 658 continue; 659 660 if (drmmode_output->tear_free == 1 || 661 (drmmode_output->tear_free == 2 && 662 (radeon_is_gpu_screen(crtc->scrn->pScreen) || 663 info->shadow_primary || 664 crtc->transformPresent || crtc->rotation != RR_Rotate_0))) { 665 drmmode_crtc->tear_free = TRUE; 666 return; 667 } 668 } 669} 670 671#if XF86_CRTC_VERSION >= 4 672 673#if XF86_CRTC_VERSION < 7 674#define XF86DriverTransformOutput TRUE 675#define XF86DriverTransformNone FALSE 676#endif 677 678static Bool 679drmmode_handle_transform(xf86CrtcPtr crtc) 680{ 681 Bool ret; 682 683 if (crtc->transformPresent || crtc->rotation != RR_Rotate_0) 684 crtc->driverIsPerformingTransform = XF86DriverTransformOutput; 685 else 686 crtc->driverIsPerformingTransform = XF86DriverTransformNone; 687 688 ret = xf86CrtcRotate(crtc); 689 690 crtc->driverIsPerformingTransform &= ret && crtc->transform_in_use; 691 692 return ret; 693} 694 695#else 696 697static Bool 698drmmode_handle_transform(xf86CrtcPtr crtc) 699{ 700 return xf86CrtcRotate(crtc); 701} 702 703#endif 704 705#ifdef RADEON_PIXMAP_SHARING 706 707static void 708drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, 709 unsigned scanout_id, int *fb_id, int *x, 710 int *y) 711{ 712 ScrnInfoPtr scrn = crtc->scrn; 713 ScreenPtr screen = scrn->pScreen; 714 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 715 716 if (drmmode_crtc->tear_free && 717 !drmmode_crtc->scanout[1].pixmap) { 718 RegionPtr region; 719 BoxPtr box; 720 721 drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1], 722 mode->HDisplay, 723 mode->VDisplay); 724 region = &drmmode_crtc->scanout_last_region; 725 RegionUninit(region); 726 region->data = NULL; 727 box = RegionExtents(region); 728 box->x1 = crtc->x; 729 box->y1 = crtc->y; 730 box->x2 = crtc->x + mode->HDisplay; 731 box->y2 = crtc->y + mode->VDisplay; 732 } 733 734 if (scanout_id != drmmode_crtc->scanout_id) { 735 PixmapDirtyUpdatePtr dirty = NULL; 736 737 xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, 738 ent) { 739 if (dirty->src == crtc->randr_crtc->scanout_pixmap && 740 dirty->slave_dst == 741 drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap) { 742 dirty->slave_dst = 743 drmmode_crtc->scanout[scanout_id].pixmap; 744 break; 745 } 746 } 747 748 if (!drmmode_crtc->tear_free) { 749 GCPtr gc = GetScratchGC(scrn->depth, screen); 750 751 ValidateGC(&drmmode_crtc->scanout[0].pixmap->drawable, gc); 752 gc->ops->CopyArea(&drmmode_crtc->scanout[1].pixmap->drawable, 753 &drmmode_crtc->scanout[0].pixmap->drawable, 754 gc, 0, 0, mode->HDisplay, mode->VDisplay, 755 0, 0); 756 FreeScratchGC(gc); 757 radeon_cs_flush_indirect(scrn); 758 radeon_bo_wait(drmmode_crtc->scanout[0].bo); 759 } 760 } 761 762 *fb_id = drmmode_crtc->scanout[scanout_id].fb_id; 763 *x = *y = 0; 764 drmmode_crtc->scanout_id = scanout_id; 765} 766 767#endif /* RADEON_PIXMAP_SHARING */ 768 769static void 770drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, 771 unsigned scanout_id, int *fb_id, int *x, int *y) 772{ 773 ScrnInfoPtr scrn = crtc->scrn; 774 ScreenPtr screen = scrn->pScreen; 775 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 776 777 drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0], 778 mode->HDisplay, mode->VDisplay); 779 if (drmmode_crtc->tear_free) { 780 drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1], 781 mode->HDisplay, mode->VDisplay); 782 } 783 784 if (drmmode_crtc->scanout[0].pixmap && 785 (!drmmode_crtc->tear_free || drmmode_crtc->scanout[1].pixmap)) { 786 RegionPtr region; 787 BoxPtr box; 788 789 if (!drmmode_crtc->scanout_damage) { 790 drmmode_crtc->scanout_damage = 791 DamageCreate(radeon_screen_damage_report, 792 NULL, DamageReportRawRegion, 793 TRUE, screen, NULL); 794 DamageRegister(&screen->GetScreenPixmap(screen)->drawable, 795 drmmode_crtc->scanout_damage); 796 } 797 798 region = DamageRegion(drmmode_crtc->scanout_damage); 799 RegionUninit(region); 800 region->data = NULL; 801 box = RegionExtents(region); 802 box->x1 = 0; 803 box->y1 = 0; 804 box->x2 = max(box->x2, scrn->virtualX); 805 box->y2 = max(box->y2, scrn->virtualY); 806 807 *fb_id = drmmode_crtc->scanout[scanout_id].fb_id; 808 *x = *y = 0; 809 810 radeon_scanout_do_update(crtc, scanout_id); 811 radeon_bo_wait(drmmode_crtc->scanout[scanout_id].bo); 812 } 813} 814 815static Bool 816drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, 817 Rotation rotation, int x, int y) 818{ 819 ScrnInfoPtr pScrn = crtc->scrn; 820 ScreenPtr pScreen = pScrn->pScreen; 821 RADEONInfoPtr info = RADEONPTR(pScrn); 822 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 823 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 824 unsigned scanout_id = 0; 825 drmmode_ptr drmmode = drmmode_crtc->drmmode; 826 int saved_x, saved_y; 827 Rotation saved_rotation; 828 DisplayModeRec saved_mode; 829 uint32_t *output_ids = NULL; 830 int output_count = 0; 831 Bool ret = FALSE; 832 int i; 833 int fb_id; 834 drmModeModeInfo kmode; 835 836 saved_mode = crtc->mode; 837 saved_x = crtc->x; 838 saved_y = crtc->y; 839 saved_rotation = crtc->rotation; 840 841 if (mode) { 842 crtc->mode = *mode; 843 crtc->x = x; 844 crtc->y = y; 845 crtc->rotation = rotation; 846 847 output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); 848 if (!output_ids) 849 goto done; 850 851 for (i = 0; i < xf86_config->num_output; i++) { 852 xf86OutputPtr output = xf86_config->output[i]; 853 drmmode_output_private_ptr drmmode_output; 854 855 if (output->crtc != crtc) 856 continue; 857 858 drmmode_output = output->driver_private; 859 output_ids[output_count] = drmmode_output->mode_output->connector_id; 860 output_count++; 861 } 862 863 if (!drmmode_handle_transform(crtc)) 864 goto done; 865 866 drmmode_crtc_update_tear_free(crtc); 867 if (drmmode_crtc->tear_free) 868 scanout_id = drmmode_crtc->scanout_id; 869 870 crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, 871 crtc->gamma_blue, crtc->gamma_size); 872 873 drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); 874 875 fb_id = drmmode->fb_id; 876#ifdef RADEON_PIXMAP_SHARING 877 if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) { 878 drmmode_crtc_prime_scanout_update(crtc, mode, scanout_id, 879 &fb_id, &x, &y); 880 } else 881#endif 882 if (drmmode_crtc->rotate.fb_id) { 883 fb_id = drmmode_crtc->rotate.fb_id; 884 x = y = 0; 885 886 } else if (!radeon_is_gpu_screen(pScreen) && 887 (drmmode_crtc->tear_free || 888#if XF86_CRTC_VERSION >= 4 889 crtc->driverIsPerformingTransform || 890#endif 891 info->shadow_primary)) { 892 drmmode_crtc_scanout_update(crtc, mode, scanout_id, 893 &fb_id, &x, &y); 894 } 895 896 if (fb_id == 0) { 897 if (drmModeAddFB(drmmode->fd, 898 pScrn->virtualX, 899 pScrn->virtualY, 900 pScrn->depth, pScrn->bitsPerPixel, 901 pScrn->displayWidth * info->pixel_bytes, 902 info->front_bo->handle, 903 &drmmode->fb_id) < 0) { 904 ErrorF("failed to add fb\n"); 905 goto done; 906 } 907 908 fb_id = drmmode->fb_id; 909 } 910 911 /* Wait for any pending flip to finish */ 912 do {} while (drmmode_crtc->flip_pending && 913 drmHandleEvent(drmmode->fd, 914 &drmmode->event_context) > 0); 915 916 if (drmModeSetCrtc(drmmode->fd, 917 drmmode_crtc->mode_crtc->crtc_id, 918 fb_id, x, y, output_ids, 919 output_count, &kmode) != 0) { 920 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, 921 "failed to set mode: %s\n", strerror(errno)); 922 goto done; 923 } else 924 ret = TRUE; 925 926 if (pScreen) 927 xf86CrtcSetScreenSubpixelOrder(pScreen); 928 929 drmmode_crtc->need_modeset = FALSE; 930 931 /* go through all the outputs and force DPMS them back on? */ 932 for (i = 0; i < xf86_config->num_output; i++) { 933 xf86OutputPtr output = xf86_config->output[i]; 934 935 if (output->crtc != crtc) 936 continue; 937 938 output->funcs->dpms(output, DPMSModeOn); 939 } 940 } 941 942 /* Compute index of this CRTC into xf86_config->crtc */ 943 for (i = 0; i < xf86_config->num_crtc; i++) { 944 if (xf86_config->crtc[i] != crtc) 945 continue; 946 947 if (!crtc->enabled || drmmode_can_use_hw_cursor(crtc)) 948 info->hwcursor_disabled &= ~(1 << i); 949 else 950 info->hwcursor_disabled |= 1 << i; 951 952 break; 953 } 954 955#ifndef HAVE_XF86_CURSOR_RESET_CURSOR 956 if (!info->hwcursor_disabled) 957 xf86_reload_cursors(pScreen); 958#endif 959 960done: 961 if (!ret) { 962 crtc->x = saved_x; 963 crtc->y = saved_y; 964 crtc->rotation = saved_rotation; 965 crtc->mode = saved_mode; 966 } else { 967 crtc->active = TRUE; 968 969 if (fb_id != drmmode_crtc->scanout[scanout_id].fb_id) 970 drmmode_crtc_scanout_free(drmmode_crtc); 971 else if (!drmmode_crtc->tear_free) { 972 drmmode_crtc_scanout_destroy(drmmode, 973 &drmmode_crtc->scanout[1]); 974 } 975 } 976 977 free(output_ids); 978 979 return ret; 980} 981 982static void 983drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) 984{ 985 986} 987 988static void 989drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y) 990{ 991 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 992 drmmode_ptr drmmode = drmmode_crtc->drmmode; 993 994#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7 995 if (crtc->driverIsPerformingTransform) { 996 x += crtc->x; 997 y += crtc->y; 998 xf86CrtcTransformCursorPos(crtc, &x, &y); 999 } 1000#endif 1001 1002 drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); 1003} 1004 1005#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7 1006 1007static int 1008drmmode_cursor_src_offset(Rotation rotation, int width, int height, 1009 int x_dst, int y_dst) 1010{ 1011 int t; 1012 1013 switch (rotation & 0xf) { 1014 case RR_Rotate_90: 1015 t = x_dst; 1016 x_dst = height - y_dst - 1; 1017 y_dst = t; 1018 break; 1019 case RR_Rotate_180: 1020 x_dst = width - x_dst - 1; 1021 y_dst = height - y_dst - 1; 1022 break; 1023 case RR_Rotate_270: 1024 t = x_dst; 1025 x_dst = y_dst; 1026 y_dst = width - t - 1; 1027 break; 1028 } 1029 1030 if (rotation & RR_Reflect_X) 1031 x_dst = width - x_dst - 1; 1032 if (rotation & RR_Reflect_Y) 1033 y_dst = height - y_dst - 1; 1034 1035 return y_dst * height + x_dst; 1036} 1037 1038#endif 1039 1040static void 1041drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) 1042{ 1043 ScrnInfoPtr pScrn = crtc->scrn; 1044 RADEONInfoPtr info = RADEONPTR(pScrn); 1045 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1046 uint32_t *ptr; 1047 1048 /* cursor should be mapped already */ 1049 ptr = (uint32_t *)(drmmode_crtc->cursor_bo->ptr); 1050 1051#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7 1052 if (crtc->driverIsPerformingTransform) { 1053 uint32_t cursor_w = info->cursor_w, cursor_h = info->cursor_h; 1054 int dstx, dsty; 1055 int srcoffset; 1056 1057 for (dsty = 0; dsty < cursor_h; dsty++) { 1058 for (dstx = 0; dstx < cursor_w; dstx++) { 1059 srcoffset = drmmode_cursor_src_offset(crtc->rotation, 1060 cursor_w, 1061 cursor_h, 1062 dstx, dsty); 1063 1064 ptr[dsty * info->cursor_w + dstx] = 1065 cpu_to_le32(image[srcoffset]); 1066 } 1067 } 1068 } else 1069#endif 1070 { 1071 uint32_t cursor_size = info->cursor_w * info->cursor_h; 1072 int i; 1073 1074 for (i = 0; i < cursor_size; i++) 1075 ptr[i] = cpu_to_le32(image[i]); 1076 } 1077} 1078 1079#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,903,0) 1080 1081static Bool drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 * image) 1082{ 1083 if (!drmmode_can_use_hw_cursor(crtc)) 1084 return FALSE; 1085 1086 drmmode_load_cursor_argb(crtc, image); 1087 return TRUE; 1088} 1089 1090#endif 1091 1092static void 1093drmmode_hide_cursor (xf86CrtcPtr crtc) 1094{ 1095 ScrnInfoPtr pScrn = crtc->scrn; 1096 RADEONInfoPtr info = RADEONPTR(pScrn); 1097 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1098 drmmode_ptr drmmode = drmmode_crtc->drmmode; 1099 1100 drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 1101 info->cursor_w, info->cursor_h); 1102 1103} 1104 1105static void 1106drmmode_show_cursor (xf86CrtcPtr crtc) 1107{ 1108 ScrnInfoPtr pScrn = crtc->scrn; 1109 RADEONInfoPtr info = RADEONPTR(pScrn); 1110 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1111 drmmode_ptr drmmode = drmmode_crtc->drmmode; 1112 uint32_t handle = drmmode_crtc->cursor_bo->handle; 1113 static Bool use_set_cursor2 = TRUE; 1114 1115 if (use_set_cursor2) { 1116 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 1117 CursorPtr cursor = xf86_config->cursor; 1118 int xhot = cursor->bits->xhot; 1119 int yhot = cursor->bits->yhot; 1120 int ret; 1121 1122 if (crtc->rotation != RR_Rotate_0 && 1123 crtc->rotation != (RR_Rotate_180 | RR_Reflect_X | 1124 RR_Reflect_Y)) { 1125 int t; 1126 1127 /* Reflect & rotate hotspot position */ 1128 if (crtc->rotation & RR_Reflect_X) 1129 xhot = info->cursor_w - xhot - 1; 1130 if (crtc->rotation & RR_Reflect_Y) 1131 yhot = info->cursor_h - yhot - 1; 1132 1133 switch (crtc->rotation & 0xf) { 1134 case RR_Rotate_90: 1135 t = xhot; 1136 xhot = yhot; 1137 yhot = info->cursor_w - t - 1; 1138 break; 1139 case RR_Rotate_180: 1140 xhot = info->cursor_w - xhot - 1; 1141 yhot = info->cursor_h - yhot - 1; 1142 break; 1143 case RR_Rotate_270: 1144 t = xhot; 1145 xhot = info->cursor_h - yhot - 1; 1146 yhot = t; 1147 } 1148 } 1149 1150 ret = 1151 drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 1152 handle, info->cursor_w, info->cursor_h, 1153 xhot, yhot); 1154 if (ret == -EINVAL) 1155 use_set_cursor2 = FALSE; 1156 else 1157 return; 1158 } 1159 1160 drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, 1161 info->cursor_w, info->cursor_h); 1162} 1163 1164/* Xorg expects a non-NULL return value from drmmode_crtc_shadow_allocate, and 1165 * passes that back to drmmode_crtc_scanout_create; it doesn't use it for 1166 * anything else. 1167 */ 1168static void * 1169drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) 1170{ 1171 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1172 1173 if (!drmmode_crtc_scanout_create(crtc, &drmmode_crtc->rotate, width, 1174 height)) 1175 return NULL; 1176 1177 return (void*)~0UL; 1178} 1179 1180static PixmapPtr 1181drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 1182{ 1183 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1184 1185 if (!data) { 1186 drmmode_crtc_scanout_create(crtc, &drmmode_crtc->rotate, width, 1187 height); 1188 } 1189 1190 return drmmode_crtc->rotate.pixmap; 1191} 1192 1193static void 1194drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 1195{ 1196 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1197 drmmode_ptr drmmode = drmmode_crtc->drmmode; 1198 1199 drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->rotate); 1200} 1201 1202static void 1203drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green, 1204 uint16_t *blue, int size) 1205{ 1206 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1207 drmmode_ptr drmmode = drmmode_crtc->drmmode; 1208 1209 drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 1210 size, red, green, blue); 1211} 1212 1213#ifdef RADEON_PIXMAP_SHARING 1214static Bool 1215drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) 1216{ 1217 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1218 unsigned scanout_id = drmmode_crtc->scanout_id; 1219 ScreenPtr screen = crtc->scrn->pScreen; 1220 PixmapDirtyUpdatePtr dirty; 1221 1222 xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { 1223 if (dirty->slave_dst != drmmode_crtc->scanout[scanout_id].pixmap) 1224 continue; 1225 1226 PixmapStopDirtyTracking(dirty->src, dirty->slave_dst); 1227 drmmode_crtc_scanout_free(drmmode_crtc); 1228 break; 1229 } 1230 1231 if (!ppix) 1232 return TRUE; 1233 1234 if (!drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0], 1235 ppix->drawable.width, 1236 ppix->drawable.height)) 1237 return FALSE; 1238 1239 if (drmmode_crtc->tear_free && 1240 !drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1], 1241 ppix->drawable.width, 1242 ppix->drawable.height)) { 1243 drmmode_crtc_scanout_free(drmmode_crtc); 1244 return FALSE; 1245 } 1246 1247#ifdef HAS_DIRTYTRACKING_ROTATION 1248 PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[scanout_id].pixmap, 1249 0, 0, 0, 0, RR_Rotate_0); 1250#elif defined(HAS_DIRTYTRACKING2) 1251 PixmapStartDirtyTracking2(ppix, drmmode_crtc->scanout[scanout_id].pixmap, 1252 0, 0, 0, 0); 1253#else 1254 PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[scanout_id].pixmap, 0, 0); 1255#endif 1256 return TRUE; 1257} 1258#endif 1259 1260static xf86CrtcFuncsRec drmmode_crtc_funcs = { 1261 .dpms = drmmode_crtc_dpms, 1262 .set_mode_major = drmmode_set_mode_major, 1263 .set_cursor_colors = drmmode_set_cursor_colors, 1264 .set_cursor_position = drmmode_set_cursor_position, 1265 .show_cursor = drmmode_show_cursor, 1266 .hide_cursor = drmmode_hide_cursor, 1267 .load_cursor_argb = drmmode_load_cursor_argb, 1268#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,903,0) 1269 .load_cursor_argb_check = drmmode_load_cursor_argb_check, 1270#endif 1271 1272 .gamma_set = drmmode_crtc_gamma_set, 1273 .shadow_create = drmmode_crtc_shadow_create, 1274 .shadow_allocate = drmmode_crtc_shadow_allocate, 1275 .shadow_destroy = drmmode_crtc_shadow_destroy, 1276 .destroy = NULL, /* XXX */ 1277#ifdef RADEON_PIXMAP_SHARING 1278 .set_scanout_pixmap = drmmode_set_scanout_pixmap, 1279#endif 1280}; 1281 1282int drmmode_get_crtc_id(xf86CrtcPtr crtc) 1283{ 1284 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1285 return drmmode_crtc->hw_id; 1286} 1287 1288void drmmode_crtc_hw_id(xf86CrtcPtr crtc) 1289{ 1290 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1291 ScrnInfoPtr pScrn = crtc->scrn; 1292 RADEONInfoPtr info = RADEONPTR(pScrn); 1293 struct drm_radeon_info ginfo; 1294 int r; 1295 uint32_t tmp; 1296 1297 memset(&ginfo, 0, sizeof(ginfo)); 1298 ginfo.request = 0x4; 1299 tmp = drmmode_crtc->mode_crtc->crtc_id; 1300 ginfo.value = (uintptr_t)&tmp; 1301 r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo)); 1302 if (r) { 1303 drmmode_crtc->hw_id = -1; 1304 return; 1305 } 1306 drmmode_crtc->hw_id = tmp; 1307} 1308 1309static unsigned int 1310drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num) 1311{ 1312 xf86CrtcPtr crtc; 1313 drmmode_crtc_private_ptr drmmode_crtc; 1314 RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 1315 1316 crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs); 1317 if (crtc == NULL) 1318 return 0; 1319 1320 drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 1321 drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, mode_res->crtcs[num]); 1322 drmmode_crtc->drmmode = drmmode; 1323 drmmode_crtc->dpms_mode = DPMSModeOff; 1324 drmmode_crtc->pending_dpms_mode = DPMSModeOff; 1325 crtc->driver_private = drmmode_crtc; 1326 drmmode_crtc_hw_id(crtc); 1327 1328 /* Mark num'th crtc as in use on this device. */ 1329 pRADEONEnt->assigned_crtcs |= (1 << num); 1330 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 1331 "Allocated crtc nr. %d to this screen.\n", num); 1332 1333 return 1; 1334} 1335 1336static xf86OutputStatus 1337drmmode_output_detect(xf86OutputPtr output) 1338{ 1339 /* go to the hw and retrieve a new output struct */ 1340 drmmode_output_private_ptr drmmode_output = output->driver_private; 1341 drmmode_ptr drmmode = drmmode_output->drmmode; 1342 xf86OutputStatus status; 1343 drmModeFreeConnector(drmmode_output->mode_output); 1344 1345 drmmode_output->mode_output = drmModeGetConnector(drmmode->fd, drmmode_output->output_id); 1346 if (!drmmode_output->mode_output) 1347 return XF86OutputStatusDisconnected; 1348 1349 switch (drmmode_output->mode_output->connection) { 1350 case DRM_MODE_CONNECTED: 1351 status = XF86OutputStatusConnected; 1352 break; 1353 case DRM_MODE_DISCONNECTED: 1354 status = XF86OutputStatusDisconnected; 1355 break; 1356 default: 1357 case DRM_MODE_UNKNOWNCONNECTION: 1358 status = XF86OutputStatusUnknown; 1359 break; 1360 } 1361 return status; 1362} 1363 1364static Bool 1365drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) 1366{ 1367 return MODE_OK; 1368} 1369 1370static DisplayModePtr 1371drmmode_output_get_modes(xf86OutputPtr output) 1372{ 1373 drmmode_output_private_ptr drmmode_output = output->driver_private; 1374 drmModeConnectorPtr koutput = drmmode_output->mode_output; 1375 drmmode_ptr drmmode = drmmode_output->drmmode; 1376 int i; 1377 DisplayModePtr Modes = NULL, Mode; 1378 drmModePropertyPtr props; 1379 xf86MonPtr mon = NULL; 1380 1381 if (!koutput) 1382 return NULL; 1383 1384 /* look for an EDID property */ 1385 for (i = 0; i < koutput->count_props; i++) { 1386 props = drmModeGetProperty(drmmode->fd, koutput->props[i]); 1387 if (props && (props->flags & DRM_MODE_PROP_BLOB)) { 1388 if (!strcmp(props->name, "EDID")) { 1389 if (drmmode_output->edid_blob) 1390 drmModeFreePropertyBlob(drmmode_output->edid_blob); 1391 drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); 1392 } 1393 } 1394 if (props) 1395 drmModeFreeProperty(props); 1396 } 1397 1398 if (drmmode_output->edid_blob) { 1399 mon = xf86InterpretEDID(output->scrn->scrnIndex, 1400 drmmode_output->edid_blob->data); 1401 if (mon && drmmode_output->edid_blob->length > 128) 1402 mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA; 1403 } 1404 xf86OutputSetEDID(output, mon); 1405 1406 /* modes should already be available */ 1407 for (i = 0; i < koutput->count_modes; i++) { 1408 Mode = xnfalloc(sizeof(DisplayModeRec)); 1409 1410 drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode); 1411 Modes = xf86ModesAdd(Modes, Mode); 1412 1413 } 1414 return Modes; 1415} 1416 1417static void 1418drmmode_output_destroy(xf86OutputPtr output) 1419{ 1420 drmmode_output_private_ptr drmmode_output = output->driver_private; 1421 int i; 1422 1423 if (drmmode_output->edid_blob) 1424 drmModeFreePropertyBlob(drmmode_output->edid_blob); 1425 for (i = 0; i < drmmode_output->num_props; i++) { 1426 drmModeFreeProperty(drmmode_output->props[i].mode_prop); 1427 free(drmmode_output->props[i].atoms); 1428 } 1429 for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) { 1430 drmModeFreeEncoder(drmmode_output->mode_encoders[i]); 1431 } 1432 free(drmmode_output->mode_encoders); 1433 free(drmmode_output->props); 1434 drmModeFreeConnector(drmmode_output->mode_output); 1435 free(drmmode_output); 1436 output->driver_private = NULL; 1437} 1438 1439static void 1440drmmode_output_dpms(xf86OutputPtr output, int mode) 1441{ 1442 drmmode_output_private_ptr drmmode_output = output->driver_private; 1443 xf86CrtcPtr crtc = output->crtc; 1444 drmModeConnectorPtr koutput = drmmode_output->mode_output; 1445 drmmode_ptr drmmode = drmmode_output->drmmode; 1446 1447 if (!koutput) 1448 return; 1449 1450 if (mode != DPMSModeOn && crtc) { 1451 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1452 1453 drmmode_do_crtc_dpms(crtc, mode); 1454 1455 /* Wait for any pending flip to finish */ 1456 if (drmmode_crtc->flip_pending) 1457 return; 1458 } 1459 1460 drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id, 1461 drmmode_output->dpms_enum_id, mode); 1462 1463 if (mode == DPMSModeOn && crtc) { 1464 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1465 1466 if (drmmode_crtc->need_modeset) 1467 drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, 1468 crtc->y); 1469 else 1470 drmmode_do_crtc_dpms(crtc, mode); 1471 } 1472} 1473 1474 1475static Bool 1476drmmode_property_ignore(drmModePropertyPtr prop) 1477{ 1478 if (!prop) 1479 return TRUE; 1480 /* ignore blob prop */ 1481 if (prop->flags & DRM_MODE_PROP_BLOB) 1482 return TRUE; 1483 /* ignore standard property */ 1484 if (!strcmp(prop->name, "EDID") || 1485 !strcmp(prop->name, "DPMS")) 1486 return TRUE; 1487 1488 return FALSE; 1489} 1490 1491static void 1492drmmode_output_create_resources(xf86OutputPtr output) 1493{ 1494 RADEONInfoPtr info = RADEONPTR(output->scrn); 1495 drmmode_output_private_ptr drmmode_output = output->driver_private; 1496 drmModeConnectorPtr mode_output = drmmode_output->mode_output; 1497 drmmode_ptr drmmode = drmmode_output->drmmode; 1498 drmModePropertyPtr drmmode_prop, tearfree_prop; 1499 int i, j, err; 1500 1501 drmmode_output->props = calloc(mode_output->count_props + 1, sizeof(drmmode_prop_rec)); 1502 if (!drmmode_output->props) 1503 return; 1504 1505 drmmode_output->num_props = 0; 1506 for (i = 0, j = 0; i < mode_output->count_props; i++) { 1507 drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]); 1508 if (drmmode_property_ignore(drmmode_prop)) { 1509 drmModeFreeProperty(drmmode_prop); 1510 continue; 1511 } 1512 drmmode_output->props[j].mode_prop = drmmode_prop; 1513 drmmode_output->props[j].value = mode_output->prop_values[i]; 1514 drmmode_output->num_props++; 1515 j++; 1516 } 1517 1518 /* Userspace-only property for TearFree */ 1519 tearfree_prop = calloc(1, sizeof(*tearfree_prop)); 1520 tearfree_prop->flags = DRM_MODE_PROP_ENUM; 1521 strncpy(tearfree_prop->name, "TearFree", 8); 1522 tearfree_prop->count_enums = 3; 1523 tearfree_prop->enums = calloc(tearfree_prop->count_enums, 1524 sizeof(*tearfree_prop->enums)); 1525 strncpy(tearfree_prop->enums[0].name, "off", 3); 1526 strncpy(tearfree_prop->enums[1].name, "on", 2); 1527 tearfree_prop->enums[1].value = 1; 1528 strncpy(tearfree_prop->enums[2].name, "auto", 4); 1529 tearfree_prop->enums[2].value = 2; 1530 drmmode_output->props[j].mode_prop = tearfree_prop; 1531 drmmode_output->props[j].value = info->tear_free; 1532 drmmode_output->tear_free = info->tear_free; 1533 drmmode_output->num_props++; 1534 1535 for (i = 0; i < drmmode_output->num_props; i++) { 1536 drmmode_prop_ptr p = &drmmode_output->props[i]; 1537 drmmode_prop = p->mode_prop; 1538 1539 if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) { 1540 INT32 range[2]; 1541 INT32 value = p->value; 1542 1543 p->num_atoms = 1; 1544 p->atoms = calloc(p->num_atoms, sizeof(Atom)); 1545 if (!p->atoms) 1546 continue; 1547 p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); 1548 range[0] = drmmode_prop->values[0]; 1549 range[1] = drmmode_prop->values[1]; 1550 err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], 1551 FALSE, TRUE, 1552 drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE, 1553 2, range); 1554 if (err != 0) { 1555 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 1556 "RRConfigureOutputProperty error, %d\n", err); 1557 } 1558 err = RRChangeOutputProperty(output->randr_output, p->atoms[0], 1559 XA_INTEGER, 32, PropModeReplace, 1, &value, FALSE, TRUE); 1560 if (err != 0) { 1561 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 1562 "RRChangeOutputProperty error, %d\n", err); 1563 } 1564 } else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) { 1565 p->num_atoms = drmmode_prop->count_enums + 1; 1566 p->atoms = calloc(p->num_atoms, sizeof(Atom)); 1567 if (!p->atoms) 1568 continue; 1569 p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); 1570 for (j = 1; j <= drmmode_prop->count_enums; j++) { 1571 struct drm_mode_property_enum *e = &drmmode_prop->enums[j-1]; 1572 p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE); 1573 } 1574 err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], 1575 FALSE, FALSE, 1576 drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE, 1577 p->num_atoms - 1, (INT32 *)&p->atoms[1]); 1578 if (err != 0) { 1579 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 1580 "RRConfigureOutputProperty error, %d\n", err); 1581 } 1582 for (j = 0; j < drmmode_prop->count_enums; j++) 1583 if (drmmode_prop->enums[j].value == p->value) 1584 break; 1585 /* there's always a matching value */ 1586 err = RRChangeOutputProperty(output->randr_output, p->atoms[0], 1587 XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, TRUE); 1588 if (err != 0) { 1589 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 1590 "RRChangeOutputProperty error, %d\n", err); 1591 } 1592 } 1593 } 1594} 1595 1596static Bool 1597drmmode_output_set_property(xf86OutputPtr output, Atom property, 1598 RRPropertyValuePtr value) 1599{ 1600 drmmode_output_private_ptr drmmode_output = output->driver_private; 1601 drmmode_ptr drmmode = drmmode_output->drmmode; 1602 int i; 1603 1604 for (i = 0; i < drmmode_output->num_props; i++) { 1605 drmmode_prop_ptr p = &drmmode_output->props[i]; 1606 1607 if (p->atoms[0] != property) 1608 continue; 1609 1610 if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) { 1611 uint32_t val; 1612 1613 if (value->type != XA_INTEGER || value->format != 32 || 1614 value->size != 1) 1615 return FALSE; 1616 val = *(uint32_t *)value->data; 1617 1618 drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, 1619 p->mode_prop->prop_id, (uint64_t)val); 1620 return TRUE; 1621 } else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) { 1622 Atom atom; 1623 const char *name; 1624 int j; 1625 1626 if (value->type != XA_ATOM || value->format != 32 || value->size != 1) 1627 return FALSE; 1628 memcpy(&atom, value->data, 4); 1629 name = NameForAtom(atom); 1630 1631 /* search for matching name string, then set its value down */ 1632 for (j = 0; j < p->mode_prop->count_enums; j++) { 1633 if (!strcmp(p->mode_prop->enums[j].name, name)) { 1634 if (i == (drmmode_output->num_props - 1)) { 1635 if (drmmode_output->tear_free != j) { 1636 xf86CrtcPtr crtc = output->crtc; 1637 1638 drmmode_output->tear_free = j; 1639 if (crtc) { 1640 drmmode_set_mode_major(crtc, &crtc->mode, 1641 crtc->rotation, 1642 crtc->x, crtc->y); 1643 } 1644 } 1645 } else { 1646 drmModeConnectorSetProperty(drmmode->fd, 1647 drmmode_output->output_id, 1648 p->mode_prop->prop_id, 1649 p->mode_prop->enums[j].value); 1650 } 1651 1652 return TRUE; 1653 } 1654 } 1655 } 1656 } 1657 1658 return TRUE; 1659} 1660 1661static Bool 1662drmmode_output_get_property(xf86OutputPtr output, Atom property) 1663{ 1664 return TRUE; 1665} 1666 1667static const xf86OutputFuncsRec drmmode_output_funcs = { 1668 .dpms = drmmode_output_dpms, 1669 .create_resources = drmmode_output_create_resources, 1670 .set_property = drmmode_output_set_property, 1671 .get_property = drmmode_output_get_property, 1672#if 0 1673 1674 .save = drmmode_crt_save, 1675 .restore = drmmode_crt_restore, 1676 .mode_fixup = drmmode_crt_mode_fixup, 1677 .prepare = drmmode_output_prepare, 1678 .mode_set = drmmode_crt_mode_set, 1679 .commit = drmmode_output_commit, 1680#endif 1681 .detect = drmmode_output_detect, 1682 .mode_valid = drmmode_output_mode_valid, 1683 1684 .get_modes = drmmode_output_get_modes, 1685 .destroy = drmmode_output_destroy 1686}; 1687 1688static int subpixel_conv_table[7] = { 0, SubPixelUnknown, 1689 SubPixelHorizontalRGB, 1690 SubPixelHorizontalBGR, 1691 SubPixelVerticalRGB, 1692 SubPixelVerticalBGR, 1693 SubPixelNone }; 1694 1695const char *output_names[] = { "None", 1696 "VGA", 1697 "DVI", 1698 "DVI", 1699 "DVI", 1700 "Composite", 1701 "S-video", 1702 "LVDS", 1703 "CTV", 1704 "DIN", 1705 "DisplayPort", 1706 "HDMI", 1707 "HDMI", 1708 "TV", 1709 "eDP" 1710}; 1711 1712#define NUM_OUTPUT_NAMES (sizeof(output_names) / sizeof(output_names[0])) 1713 1714static xf86OutputPtr find_output(ScrnInfoPtr pScrn, int id) 1715{ 1716 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1717 int i; 1718 for (i = 0; i < xf86_config->num_output; i++) { 1719 xf86OutputPtr output = xf86_config->output[i]; 1720 drmmode_output_private_ptr drmmode_output; 1721 1722 drmmode_output = output->driver_private; 1723 if (drmmode_output->output_id == id) 1724 return output; 1725 } 1726 return NULL; 1727} 1728 1729static int parse_path_blob(drmModePropertyBlobPtr path_blob, int *conn_base_id, char **path) 1730{ 1731 char *conn; 1732 char conn_id[5]; 1733 int id, len; 1734 char *blob_data; 1735 1736 if (!path_blob) 1737 return -1; 1738 1739 blob_data = path_blob->data; 1740 /* we only handle MST paths for now */ 1741 if (strncmp(blob_data, "mst:", 4)) 1742 return -1; 1743 1744 conn = strchr(blob_data + 4, '-'); 1745 if (!conn) 1746 return -1; 1747 len = conn - (blob_data + 4); 1748 if (len + 1 > 5) 1749 return -1; 1750 memcpy(conn_id, blob_data + 4, len); 1751 conn_id[len] = '\0'; 1752 id = strtoul(conn_id, NULL, 10); 1753 1754 *conn_base_id = id; 1755 1756 *path = conn + 1; 1757 return 0; 1758} 1759 1760static void 1761drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name, 1762 drmModePropertyBlobPtr path_blob, int *num_dvi, int *num_hdmi) 1763{ 1764 xf86OutputPtr output; 1765 int conn_id; 1766 char *extra_path; 1767 1768 output = NULL; 1769 if (parse_path_blob(path_blob, &conn_id, &extra_path) == 0) 1770 output = find_output(pScrn, conn_id); 1771 if (output) { 1772 snprintf(name, 32, "%s-%s", output->name, extra_path); 1773 } else { 1774 if (koutput->connector_type >= NUM_OUTPUT_NAMES) 1775 snprintf(name, 32, "Unknown%d-%d", koutput->connector_type, 1776 koutput->connector_type_id - 1); 1777#ifdef RADEON_PIXMAP_SHARING 1778 else if (pScrn->is_gpu) 1779 snprintf(name, 32, "%s-%d-%d", 1780 output_names[koutput->connector_type], pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, 1781 koutput->connector_type_id - 1); 1782#endif 1783 else { 1784 /* need to do smart conversion here for compat with non-kms ATI driver */ 1785 if (koutput->connector_type_id == 1) { 1786 switch(koutput->connector_type) { 1787 case DRM_MODE_CONNECTOR_DVII: 1788 case DRM_MODE_CONNECTOR_DVID: 1789 case DRM_MODE_CONNECTOR_DVIA: 1790 snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], *num_dvi); 1791 (*num_dvi)++; 1792 break; 1793 case DRM_MODE_CONNECTOR_HDMIA: 1794 case DRM_MODE_CONNECTOR_HDMIB: 1795 snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], *num_hdmi); 1796 (*num_hdmi)++; 1797 break; 1798 case DRM_MODE_CONNECTOR_VGA: 1799 case DRM_MODE_CONNECTOR_DisplayPort: 1800 snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], 1801 koutput->connector_type_id - 1); 1802 break; 1803 default: 1804 snprintf(name, 32, "%s", output_names[koutput->connector_type]); 1805 break; 1806 } 1807 } else { 1808 snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], 1809 koutput->connector_type_id - 1); 1810 } 1811 } 1812 } 1813} 1814 1815static unsigned int 1816drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, int *num_dvi, int *num_hdmi, int dynamic) 1817{ 1818 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1819 RADEONInfoPtr info = RADEONPTR(pScrn); 1820 xf86OutputPtr output; 1821 drmModeConnectorPtr koutput; 1822 drmModeEncoderPtr *kencoders = NULL; 1823 drmmode_output_private_ptr drmmode_output; 1824 drmModePropertyPtr props; 1825 drmModePropertyBlobPtr path_blob = NULL; 1826 char name[32]; 1827 int i; 1828 const char *s; 1829 1830 koutput = drmModeGetConnector(drmmode->fd, mode_res->connectors[num]); 1831 if (!koutput) 1832 return 0; 1833 1834 for (i = 0; i < koutput->count_props; i++) { 1835 props = drmModeGetProperty(drmmode->fd, koutput->props[i]); 1836 if (props && (props->flags & DRM_MODE_PROP_BLOB)) { 1837 if (!strcmp(props->name, "PATH")) { 1838 path_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); 1839 drmModeFreeProperty(props); 1840 break; 1841 } 1842 drmModeFreeProperty(props); 1843 } 1844 } 1845 1846 kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders); 1847 if (!kencoders) { 1848 goto out_free_encoders; 1849 } 1850 1851 for (i = 0; i < koutput->count_encoders; i++) { 1852 kencoders[i] = drmModeGetEncoder(drmmode->fd, koutput->encoders[i]); 1853 if (!kencoders[i]) { 1854 goto out_free_encoders; 1855 } 1856 } 1857 1858 drmmode_create_name(pScrn, koutput, name, path_blob, num_dvi, num_hdmi); 1859 if (path_blob) 1860 drmModeFreePropertyBlob(path_blob); 1861 1862 if (path_blob && dynamic) { 1863 /* See if we have an output with this name already 1864 * and hook stuff up. 1865 */ 1866 for (i = 0; i < xf86_config->num_output; i++) { 1867 output = xf86_config->output[i]; 1868 1869 if (strncmp(output->name, name, 32)) 1870 continue; 1871 1872 drmmode_output = output->driver_private; 1873 drmmode_output->output_id = mode_res->connectors[num]; 1874 drmmode_output->mode_output = koutput; 1875 for (i = 0; i < koutput->count_encoders; i++) 1876 drmModeFreeEncoder(kencoders[i]); 1877 free(kencoders); 1878 return 0; 1879 } 1880 } 1881 1882 if (xf86IsEntityShared(pScrn->entityList[0])) { 1883 if ((s = xf86GetOptValString(info->Options, OPTION_ZAPHOD_HEADS))) { 1884 if (!RADEONZaphodStringMatches(pScrn, s, name)) 1885 goto out_free_encoders; 1886 } else { 1887 if (!info->IsSecondary && (num != 0)) 1888 goto out_free_encoders; 1889 else if (info->IsSecondary && (num != 1)) 1890 goto out_free_encoders; 1891 } 1892 } 1893 1894 output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name); 1895 if (!output) { 1896 goto out_free_encoders; 1897 } 1898 1899 drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1); 1900 if (!drmmode_output) { 1901 xf86OutputDestroy(output); 1902 goto out_free_encoders; 1903 } 1904 1905 drmmode_output->output_id = mode_res->connectors[num]; 1906 drmmode_output->mode_output = koutput; 1907 drmmode_output->mode_encoders = kencoders; 1908 drmmode_output->drmmode = drmmode; 1909 output->mm_width = koutput->mmWidth; 1910 output->mm_height = koutput->mmHeight; 1911 1912 output->subpixel_order = subpixel_conv_table[koutput->subpixel]; 1913 output->interlaceAllowed = TRUE; 1914 output->doubleScanAllowed = TRUE; 1915 output->driver_private = drmmode_output; 1916 1917 output->possible_crtcs = 0xffffffff; 1918 for (i = 0; i < koutput->count_encoders; i++) { 1919 output->possible_crtcs &= kencoders[i]->possible_crtcs; 1920 } 1921 /* work out the possible clones later */ 1922 output->possible_clones = 0; 1923 1924 for (i = 0; i < koutput->count_props; i++) { 1925 props = drmModeGetProperty(drmmode->fd, koutput->props[i]); 1926 if (props && (props->flags & DRM_MODE_PROP_ENUM)) { 1927 if (!strcmp(props->name, "DPMS")) { 1928 drmmode_output->dpms_enum_id = koutput->props[i]; 1929 drmModeFreeProperty(props); 1930 break; 1931 } 1932 drmModeFreeProperty(props); 1933 } 1934 } 1935 1936 if (dynamic) { 1937 output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output); 1938 drmmode_output_create_resources(output); 1939 } 1940 1941 return 1; 1942out_free_encoders: 1943 if (kencoders){ 1944 for (i = 0; i < koutput->count_encoders; i++) 1945 drmModeFreeEncoder(kencoders[i]); 1946 free(kencoders); 1947 } 1948 drmModeFreeConnector(koutput); 1949 return 0; 1950} 1951 1952uint32_t find_clones(ScrnInfoPtr scrn, xf86OutputPtr output) 1953{ 1954 drmmode_output_private_ptr drmmode_output = output->driver_private, clone_drmout; 1955 int i; 1956 xf86OutputPtr clone_output; 1957 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 1958 int index_mask = 0; 1959 1960 if (drmmode_output->enc_clone_mask == 0) 1961 return index_mask; 1962 1963 for (i = 0; i < xf86_config->num_output; i++) { 1964 clone_output = xf86_config->output[i]; 1965 clone_drmout = clone_output->driver_private; 1966 if (output == clone_output) 1967 continue; 1968 1969 if (clone_drmout->enc_mask == 0) 1970 continue; 1971 if (drmmode_output->enc_clone_mask == clone_drmout->enc_mask) 1972 index_mask |= (1 << i); 1973 } 1974 return index_mask; 1975} 1976 1977 1978static void 1979drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, drmModeResPtr mode_res) 1980{ 1981 int i, j; 1982 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 1983 1984 for (i = 0; i < xf86_config->num_output; i++) { 1985 xf86OutputPtr output = xf86_config->output[i]; 1986 drmmode_output_private_ptr drmmode_output; 1987 1988 drmmode_output = output->driver_private; 1989 drmmode_output->enc_clone_mask = 0xff; 1990 /* and all the possible encoder clones for this output together */ 1991 for (j = 0; j < drmmode_output->mode_output->count_encoders; j++) 1992 { 1993 int k; 1994 for (k = 0; k < mode_res->count_encoders; k++) { 1995 if (mode_res->encoders[k] == drmmode_output->mode_encoders[j]->encoder_id) 1996 drmmode_output->enc_mask |= (1 << k); 1997 } 1998 1999 drmmode_output->enc_clone_mask &= drmmode_output->mode_encoders[j]->possible_clones; 2000 } 2001 } 2002 2003 for (i = 0; i < xf86_config->num_output; i++) { 2004 xf86OutputPtr output = xf86_config->output[i]; 2005 output->possible_clones = find_clones(scrn, output); 2006 } 2007} 2008 2009/* returns height alignment in pixels */ 2010int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling) 2011{ 2012 RADEONInfoPtr info = RADEONPTR(scrn); 2013 int height_align = 1; 2014 2015 if (info->ChipFamily >= CHIP_FAMILY_R600) { 2016 if (tiling & RADEON_TILING_MACRO) 2017 height_align = info->num_channels * 8; 2018 else if (tiling & RADEON_TILING_MICRO) 2019 height_align = 8; 2020 else 2021 height_align = 8; 2022 } else { 2023 if (tiling & RADEON_TILING_MICRO_SQUARE) 2024 height_align = 32; 2025 else if (tiling) 2026 height_align = 16; 2027 else 2028 height_align = 1; 2029 } 2030 return height_align; 2031} 2032 2033/* returns pitch alignment in pixels */ 2034int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling) 2035{ 2036 RADEONInfoPtr info = RADEONPTR(scrn); 2037 int pitch_align = 1; 2038 2039 if (info->ChipFamily >= CHIP_FAMILY_R600) { 2040 if (tiling & RADEON_TILING_MACRO) { 2041 /* general surface requirements */ 2042 pitch_align = MAX(info->num_banks, 2043 (((info->group_bytes / 8) / bpe) * info->num_banks)) * 8; 2044 /* further restrictions for scanout */ 2045 pitch_align = MAX(info->num_banks * 8, pitch_align); 2046 } else if (tiling & RADEON_TILING_MICRO) { 2047 /* general surface requirements */ 2048 pitch_align = MAX(8, (info->group_bytes / (8 * bpe))); 2049 /* further restrictions for scanout */ 2050 pitch_align = MAX(info->group_bytes / bpe, pitch_align); 2051 } else { 2052 if (info->have_tiling_info) 2053 /* linear aligned requirements */ 2054 pitch_align = MAX(64, info->group_bytes / bpe); 2055 else 2056 /* default to 512 elements if we don't know the real 2057 * group size otherwise the kernel may reject the CS 2058 * if the group sizes don't match as the pitch won't 2059 * be aligned properly. 2060 */ 2061 pitch_align = 512; 2062 } 2063 } else { 2064 /* general surface requirements */ 2065 if (tiling) 2066 pitch_align = 256 / bpe; 2067 else 2068 pitch_align = 64; 2069 } 2070 return pitch_align; 2071} 2072 2073/* returns base alignment in bytes */ 2074int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling) 2075{ 2076 RADEONInfoPtr info = RADEONPTR(scrn); 2077 int pixel_align = drmmode_get_pitch_align(scrn, bpe, tiling); 2078 int height_align = drmmode_get_height_align(scrn, tiling); 2079 int base_align = RADEON_GPU_PAGE_SIZE; 2080 2081 if (info->ChipFamily >= CHIP_FAMILY_R600) { 2082 if (tiling & RADEON_TILING_MACRO) 2083 base_align = MAX(info->num_banks * info->num_channels * 8 * 8 * bpe, 2084 pixel_align * bpe * height_align); 2085 else { 2086 if (info->have_tiling_info) 2087 base_align = info->group_bytes; 2088 else 2089 /* default to 512 if we don't know the real 2090 * group size otherwise the kernel may reject the CS 2091 * if the group sizes don't match as the base won't 2092 * be aligned properly. 2093 */ 2094 base_align = 512; 2095 } 2096 } 2097 return base_align; 2098} 2099 2100static Bool 2101drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) 2102{ 2103 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 2104 drmmode_crtc_private_ptr 2105 drmmode_crtc = xf86_config->crtc[0]->driver_private; 2106 drmmode_ptr drmmode = drmmode_crtc->drmmode; 2107 RADEONInfoPtr info = RADEONPTR(scrn); 2108 struct radeon_bo *old_front = NULL; 2109 ScreenPtr screen = xf86ScrnToScreen(scrn); 2110 uint32_t old_fb_id; 2111 int i, pitch, old_width, old_height, old_pitch; 2112 int aligned_height; 2113 uint32_t screen_size; 2114 int cpp = info->pixel_bytes; 2115 struct radeon_bo *front_bo; 2116 struct radeon_surface surface; 2117 struct radeon_surface *psurface; 2118 uint32_t tiling_flags = 0, base_align; 2119 PixmapPtr ppix = screen->GetScreenPixmap(screen); 2120 void *fb_shadow; 2121 xRectangle rect; 2122 Bool force; 2123 GCPtr gc; 2124 2125 if (scrn->virtualX == width && scrn->virtualY == height) 2126 return TRUE; 2127 2128 front_bo = info->front_bo; 2129 radeon_cs_flush_indirect(scrn); 2130 2131 if (front_bo) 2132 radeon_bo_wait(front_bo); 2133 2134 if (info->allowColorTiling && !info->shadow_primary) { 2135 if (info->ChipFamily >= CHIP_FAMILY_R600) { 2136 if (info->allowColorTiling2D) { 2137 tiling_flags |= RADEON_TILING_MACRO; 2138 } else { 2139 tiling_flags |= RADEON_TILING_MICRO; 2140 } 2141 } else 2142 tiling_flags |= RADEON_TILING_MACRO; 2143 } 2144 2145 pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(scrn, cpp, tiling_flags)) * cpp; 2146 aligned_height = RADEON_ALIGN(height, drmmode_get_height_align(scrn, tiling_flags)); 2147 screen_size = RADEON_ALIGN(pitch * aligned_height, RADEON_GPU_PAGE_SIZE); 2148 base_align = 4096; 2149 if (info->ChipFamily >= CHIP_FAMILY_R600) { 2150 memset(&surface, 0, sizeof(struct radeon_surface)); 2151 surface.npix_x = width; 2152 surface.npix_y = height; 2153 surface.npix_z = 1; 2154 surface.blk_w = 1; 2155 surface.blk_h = 1; 2156 surface.blk_d = 1; 2157 surface.array_size = 1; 2158 surface.last_level = 0; 2159 surface.bpe = cpp; 2160 surface.nsamples = 1; 2161 surface.flags = RADEON_SURF_SCANOUT; 2162 /* we are requiring a recent enough libdrm version */ 2163 surface.flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; 2164 surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); 2165 surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); 2166 if (tiling_flags & RADEON_TILING_MICRO) { 2167 surface.flags = RADEON_SURF_CLR(surface.flags, MODE); 2168 surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); 2169 } 2170 if (tiling_flags & RADEON_TILING_MACRO) { 2171 surface.flags = RADEON_SURF_CLR(surface.flags, MODE); 2172 surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); 2173 } 2174 if (radeon_surface_best(info->surf_man, &surface)) { 2175 return FALSE; 2176 } 2177 if (radeon_surface_init(info->surf_man, &surface)) { 2178 return FALSE; 2179 } 2180 screen_size = surface.bo_size; 2181 base_align = surface.bo_alignment; 2182 pitch = surface.level[0].pitch_bytes; 2183 tiling_flags = 0; 2184 switch (surface.level[0].mode) { 2185 case RADEON_SURF_MODE_2D: 2186 tiling_flags |= RADEON_TILING_MACRO; 2187 tiling_flags |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT; 2188 tiling_flags |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT; 2189 tiling_flags |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT; 2190 if (surface.tile_split) 2191 tiling_flags |= eg_tile_split(surface.tile_split) 2192 << RADEON_TILING_EG_TILE_SPLIT_SHIFT; 2193 break; 2194 case RADEON_SURF_MODE_1D: 2195 tiling_flags |= RADEON_TILING_MICRO; 2196 break; 2197 default: 2198 break; 2199 } 2200 info->front_surface = surface; 2201 } 2202 2203 xf86DrvMsg(scrn->scrnIndex, X_INFO, 2204 "Allocate new frame buffer %dx%d stride %d\n", 2205 width, height, pitch / cpp); 2206 2207 old_width = scrn->virtualX; 2208 old_height = scrn->virtualY; 2209 old_pitch = scrn->displayWidth; 2210 old_fb_id = drmmode->fb_id; 2211 drmmode->fb_id = 0; 2212 old_front = info->front_bo; 2213 2214 scrn->virtualX = width; 2215 scrn->virtualY = height; 2216 scrn->displayWidth = pitch / cpp; 2217 2218 info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size, base_align, 2219 info->shadow_primary ? 2220 RADEON_GEM_DOMAIN_GTT : 2221 RADEON_GEM_DOMAIN_VRAM, 2222 tiling_flags ? RADEON_GEM_NO_CPU_ACCESS : 0); 2223 if (!info->front_bo) 2224 goto fail; 2225 2226#if X_BYTE_ORDER == X_BIG_ENDIAN 2227 switch (cpp) { 2228 case 4: 2229 tiling_flags |= RADEON_TILING_SWAP_32BIT; 2230 break; 2231 case 2: 2232 tiling_flags |= RADEON_TILING_SWAP_16BIT; 2233 break; 2234 } 2235 if (info->ChipFamily < CHIP_FAMILY_R600 && 2236 info->r600_shadow_fb && tiling_flags) 2237 tiling_flags |= RADEON_TILING_SURFACE; 2238#endif 2239 if (tiling_flags) 2240 radeon_bo_set_tiling(info->front_bo, tiling_flags, pitch); 2241 2242 if (!info->r600_shadow_fb) { 2243 psurface = radeon_get_pixmap_surface(ppix); 2244 *psurface = info->front_surface; 2245 screen->ModifyPixmapHeader(ppix, 2246 width, height, -1, -1, pitch, NULL); 2247 } else { 2248 if (radeon_bo_map(info->front_bo, 1)) 2249 goto fail; 2250 fb_shadow = calloc(1, screen_size); 2251 if (fb_shadow == NULL) 2252 goto fail; 2253 free(info->fb_shadow); 2254 info->fb_shadow = fb_shadow; 2255 screen->ModifyPixmapHeader(ppix, 2256 width, height, -1, -1, pitch, 2257 info->fb_shadow); 2258 } 2259 2260 if (info->use_glamor) 2261 radeon_glamor_create_screen_resources(scrn->pScreen); 2262 2263 if (!info->r600_shadow_fb) { 2264 if (!radeon_set_pixmap_bo(ppix, info->front_bo)) 2265 goto fail; 2266 } 2267 2268 /* Clear new buffer */ 2269 gc = GetScratchGC(ppix->drawable.depth, scrn->pScreen); 2270 force = info->accel_state->force; 2271 info->accel_state->force = TRUE; 2272 ValidateGC(&ppix->drawable, gc); 2273 rect.x = 0; 2274 rect.y = 0; 2275 rect.width = width; 2276 rect.height = height; 2277 (*gc->ops->PolyFillRect)(&ppix->drawable, gc, 1, &rect); 2278 FreeScratchGC(gc); 2279 info->accel_state->force = force; 2280 radeon_cs_flush_indirect(scrn); 2281 radeon_bo_wait(info->front_bo); 2282 2283 for (i = 0; i < xf86_config->num_crtc; i++) { 2284 xf86CrtcPtr crtc = xf86_config->crtc[i]; 2285 2286 if (!crtc->enabled) 2287 continue; 2288 2289 drmmode_set_mode_major(crtc, &crtc->mode, 2290 crtc->rotation, crtc->x, crtc->y); 2291 } 2292 2293 if (old_fb_id) 2294 drmModeRmFB(drmmode->fd, old_fb_id); 2295 if (old_front) 2296 radeon_bo_unref(old_front); 2297 2298 radeon_kms_update_vram_limit(scrn, screen_size); 2299 return TRUE; 2300 2301 fail: 2302 if (info->front_bo) 2303 radeon_bo_unref(info->front_bo); 2304 info->front_bo = old_front; 2305 scrn->virtualX = old_width; 2306 scrn->virtualY = old_height; 2307 scrn->displayWidth = old_pitch; 2308 drmmode->fb_id = old_fb_id; 2309 2310 return FALSE; 2311} 2312 2313static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { 2314 drmmode_xf86crtc_resize 2315}; 2316 2317void 2318drmmode_clear_pending_flip(xf86CrtcPtr crtc) 2319{ 2320 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 2321 2322 drmmode_crtc->flip_pending = FALSE; 2323 2324 if (!crtc->enabled || 2325 (drmmode_crtc->pending_dpms_mode != DPMSModeOn && 2326 drmmode_crtc->dpms_mode != drmmode_crtc->pending_dpms_mode)) { 2327 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 2328 int o; 2329 2330 for (o = 0; o < xf86_config->num_output; o++) { 2331 xf86OutputPtr output = xf86_config->output[o]; 2332 2333 if (output->crtc != crtc) 2334 continue; 2335 2336 drmmode_output_dpms(output, drmmode_crtc->pending_dpms_mode); 2337 } 2338 2339 drmmode_crtc_dpms(crtc, drmmode_crtc->pending_dpms_mode); 2340 } 2341 2342 drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, 2343 &drmmode_crtc->scanout_destroy[0]); 2344 drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, 2345 &drmmode_crtc->scanout_destroy[1]); 2346} 2347 2348static void 2349drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data) 2350{ 2351 drmmode_flipdata_ptr flipdata = event_data; 2352 2353 if (--flipdata->flip_count == 0) { 2354 if (!flipdata->fe_crtc) 2355 flipdata->fe_crtc = crtc; 2356 flipdata->abort(flipdata->fe_crtc, flipdata->event_data); 2357 free(flipdata); 2358 } 2359 2360 drmmode_clear_pending_flip(crtc); 2361} 2362 2363static void 2364drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data) 2365{ 2366 RADEONInfoPtr info = RADEONPTR(crtc->scrn); 2367 drmmode_flipdata_ptr flipdata = event_data; 2368 2369 /* Is this the event whose info shall be delivered to higher level? */ 2370 if (crtc == flipdata->fe_crtc) { 2371 /* Yes: Cache msc, ust for later delivery. */ 2372 flipdata->fe_frame = frame; 2373 flipdata->fe_usec = usec; 2374 } 2375 2376 if (--flipdata->flip_count == 0) { 2377 /* Deliver MSC & UST from reference/current CRTC to flip event 2378 * handler 2379 */ 2380 if (flipdata->fe_crtc) 2381 flipdata->handler(flipdata->fe_crtc, flipdata->fe_frame, 2382 flipdata->fe_usec, flipdata->event_data); 2383 else 2384 flipdata->handler(crtc, frame, usec, flipdata->event_data); 2385 2386 /* Release framebuffer */ 2387 drmModeRmFB(info->drmmode.fd, flipdata->old_fb_id); 2388 2389 free(flipdata); 2390 } 2391 2392 drmmode_clear_pending_flip(crtc); 2393} 2394 2395 2396#if HAVE_NOTIFY_FD 2397static void 2398drm_notify_fd(int fd, int ready, void *data) 2399#else 2400static void 2401drm_wakeup_handler(pointer data, int err, pointer p) 2402#endif 2403{ 2404 drmmode_ptr drmmode = data; 2405#if !HAVE_NOTIFY_FD 2406 fd_set *read_mask = p; 2407 2408 if (err >= 0 && FD_ISSET(drmmode->fd, read_mask)) 2409#endif 2410 { 2411 drmHandleEvent(drmmode->fd, &drmmode->event_context); 2412 } 2413} 2414 2415static Bool drmmode_probe_page_flip_target(drmmode_ptr drmmode) 2416{ 2417#ifdef DRM_CAP_PAGE_FLIP_TARGET 2418 uint64_t cap_value; 2419 2420 return drmGetCap(drmmode->fd, DRM_CAP_PAGE_FLIP_TARGET, 2421 &cap_value) == 0 && cap_value != 0; 2422#else 2423 return FALSE; 2424#endif 2425} 2426 2427static int 2428drmmode_page_flip(drmmode_crtc_private_ptr drmmode_crtc, int fb_id, 2429 uint32_t flags, uintptr_t drm_queue_seq) 2430{ 2431 drmmode_ptr drmmode = drmmode_crtc->drmmode; 2432 2433 flags |= DRM_MODE_PAGE_FLIP_EVENT; 2434 return drmModePageFlip(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 2435 fb_id, flags, (void*)drm_queue_seq); 2436} 2437 2438int 2439drmmode_page_flip_target_absolute(RADEONEntPtr pRADEONEnt, 2440 drmmode_crtc_private_ptr drmmode_crtc, 2441 int fb_id, uint32_t flags, 2442 uintptr_t drm_queue_seq, uint32_t target_msc) 2443{ 2444#ifdef DRM_MODE_PAGE_FLIP_TARGET 2445 if (pRADEONEnt->has_page_flip_target) { 2446 drmmode_ptr drmmode = drmmode_crtc->drmmode; 2447 2448 flags |= DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE; 2449 return drmModePageFlipTarget(drmmode->fd, 2450 drmmode_crtc->mode_crtc->crtc_id, 2451 fb_id, flags, (void*)drm_queue_seq, 2452 target_msc); 2453 } 2454#endif 2455 2456 return drmmode_page_flip(drmmode_crtc, fb_id, flags, drm_queue_seq); 2457} 2458 2459int 2460drmmode_page_flip_target_relative(RADEONEntPtr pRADEONEnt, 2461 drmmode_crtc_private_ptr drmmode_crtc, 2462 int fb_id, uint32_t flags, 2463 uintptr_t drm_queue_seq, uint32_t target_msc) 2464{ 2465#ifdef DRM_MODE_PAGE_FLIP_TARGET 2466 if (pRADEONEnt->has_page_flip_target) { 2467 drmmode_ptr drmmode = drmmode_crtc->drmmode; 2468 2469 flags |= DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_PAGE_FLIP_TARGET_RELATIVE; 2470 return drmModePageFlipTarget(drmmode->fd, 2471 drmmode_crtc->mode_crtc->crtc_id, 2472 fb_id, flags, (void*)drm_queue_seq, 2473 target_msc); 2474 } 2475#endif 2476 2477 return drmmode_page_flip(drmmode_crtc, fb_id, flags, drm_queue_seq); 2478} 2479 2480Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) 2481{ 2482 RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 2483 RADEONInfoPtr info = RADEONPTR(pScrn); 2484 int i, num_dvi = 0, num_hdmi = 0; 2485 drmModeResPtr mode_res; 2486 unsigned int crtcs_needed = 0; 2487#ifdef RADEON_PIXMAP_SHARING 2488 char *bus_id_string, *provider_name; 2489#endif 2490 2491 xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); 2492 2493 drmmode->scrn = pScrn; 2494 drmmode->cpp = cpp; 2495 mode_res = drmModeGetResources(drmmode->fd); 2496 if (!mode_res) 2497 return FALSE; 2498 2499 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 2500 "Initializing outputs ...\n"); 2501 for (i = 0; i < mode_res->count_connectors; i++) 2502 crtcs_needed += drmmode_output_init(pScrn, drmmode, mode_res, 2503 i, &num_dvi, &num_hdmi, 0); 2504 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 2505 "%d crtcs needed for screen.\n", crtcs_needed); 2506 2507 if (info->r600_shadow_fb) { 2508 /* Rotation requires hardware acceleration */ 2509 drmmode_crtc_funcs.shadow_allocate = NULL; 2510 drmmode_crtc_funcs.shadow_create = NULL; 2511 drmmode_crtc_funcs.shadow_destroy = NULL; 2512 } 2513 2514 drmmode->count_crtcs = mode_res->count_crtcs; 2515 xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width, mode_res->max_height); 2516 2517 for (i = 0; i < mode_res->count_crtcs; i++) 2518 if (!xf86IsEntityShared(pScrn->entityList[0]) || 2519 (crtcs_needed && !(pRADEONEnt->assigned_crtcs & (1 << i)))) 2520 crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, mode_res, i); 2521 2522 /* All ZaphodHeads outputs provided with matching crtcs? */ 2523 if (xf86IsEntityShared(pScrn->entityList[0]) && (crtcs_needed > 0)) 2524 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2525 "%d ZaphodHeads crtcs unavailable. Some outputs will stay off.\n", 2526 crtcs_needed); 2527 2528 /* workout clones */ 2529 drmmode_clones_init(pScrn, drmmode, mode_res); 2530 2531#ifdef RADEON_PIXMAP_SHARING 2532 bus_id_string = DRICreatePCIBusID(info->PciInfo); 2533 XNFasprintf(&provider_name, "%s @ %s", pScrn->chipset, bus_id_string); 2534 free(bus_id_string); 2535 xf86ProviderSetup(pScrn, NULL, provider_name); 2536 free(provider_name); 2537#endif 2538 2539 xf86InitialConfiguration(pScrn, TRUE); 2540 2541 drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION; 2542 drmmode->event_context.vblank_handler = radeon_drm_queue_handler; 2543 drmmode->event_context.page_flip_handler = radeon_drm_queue_handler; 2544 2545 pRADEONEnt->has_page_flip_target = drmmode_probe_page_flip_target(drmmode); 2546 2547 drmModeFreeResources(mode_res); 2548 return TRUE; 2549} 2550 2551void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode) 2552{ 2553 RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 2554 RADEONInfoPtr info = RADEONPTR(pScrn); 2555 2556 if (info->dri2.pKernelDRMVersion->version_minor < 4) 2557 return; 2558 2559 info->drmmode_inited = TRUE; 2560 if (pRADEONEnt->fd_wakeup_registered != serverGeneration) { 2561#if HAVE_NOTIFY_FD 2562 SetNotifyFd(drmmode->fd, drm_notify_fd, X_NOTIFY_READ, drmmode); 2563#else 2564 AddGeneralSocket(drmmode->fd); 2565 RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, 2566 drm_wakeup_handler, drmmode); 2567#endif 2568 pRADEONEnt->fd_wakeup_registered = serverGeneration; 2569 pRADEONEnt->fd_wakeup_ref = 1; 2570 } else 2571 pRADEONEnt->fd_wakeup_ref++; 2572} 2573 2574void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode) 2575{ 2576 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 2577 RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 2578 RADEONInfoPtr info = RADEONPTR(pScrn); 2579 int c; 2580 2581 if (info->dri2.pKernelDRMVersion->version_minor < 4 || !info->drmmode_inited) 2582 return; 2583 2584 if (pRADEONEnt->fd_wakeup_registered == serverGeneration && 2585 !--pRADEONEnt->fd_wakeup_ref) { 2586#if HAVE_NOTIFY_FD 2587 RemoveNotifyFd(drmmode->fd); 2588#else 2589 RemoveGeneralSocket(drmmode->fd); 2590 RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, 2591 drm_wakeup_handler, drmmode); 2592#endif 2593 } 2594 2595 for (c = 0; c < config->num_crtc; c++) 2596 drmmode_crtc_scanout_free(config->crtc[c]->driver_private); 2597} 2598 2599 2600Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr) 2601{ 2602 drmmode->bufmgr = bufmgr; 2603 return TRUE; 2604} 2605 2606 2607 2608void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo) 2609{ 2610 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 2611 xf86CrtcPtr crtc = xf86_config->crtc[id]; 2612 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 2613 2614 drmmode_crtc->cursor_bo = bo; 2615} 2616 2617void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y) 2618{ 2619 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 2620 xf86OutputPtr output = config->output[config->compat_output]; 2621 xf86CrtcPtr crtc = output->crtc; 2622 2623 if (crtc && crtc->enabled) { 2624 drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, 2625 x, y); 2626 } 2627} 2628 2629Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, 2630 Bool set_hw) 2631{ 2632 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 2633 int c; 2634 2635 for (c = 0; c < config->num_crtc; c++) { 2636 xf86CrtcPtr crtc = config->crtc[c]; 2637 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 2638 xf86OutputPtr output = NULL; 2639 int o; 2640 2641 /* Skip disabled CRTCs */ 2642 if (!crtc->enabled) { 2643 if (set_hw) { 2644 drmmode_do_crtc_dpms(crtc, DPMSModeOff); 2645 drmModeSetCrtc(drmmode->fd, 2646 drmmode_crtc->mode_crtc->crtc_id, 2647 0, 0, 0, NULL, 0, NULL); 2648 } 2649 continue; 2650 } 2651 2652 if (config->output[config->compat_output]->crtc == crtc) 2653 output = config->output[config->compat_output]; 2654 else 2655 { 2656 for (o = 0; o < config->num_output; o++) 2657 if (config->output[o]->crtc == crtc) 2658 { 2659 output = config->output[o]; 2660 break; 2661 } 2662 } 2663 /* paranoia */ 2664 if (!output) 2665 continue; 2666 2667 /* Mark that we'll need to re-set the mode for sure */ 2668 memset(&crtc->mode, 0, sizeof(crtc->mode)); 2669 if (!crtc->desiredMode.CrtcHDisplay) 2670 { 2671 DisplayModePtr mode = xf86OutputFindClosestMode (output, pScrn->currentMode); 2672 2673 if (!mode) 2674 return FALSE; 2675 crtc->desiredMode = *mode; 2676 crtc->desiredRotation = RR_Rotate_0; 2677 crtc->desiredX = 0; 2678 crtc->desiredY = 0; 2679 } 2680 2681 if (set_hw) { 2682 if (!crtc->funcs->set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation, 2683 crtc->desiredX, crtc->desiredY)) 2684 return FALSE; 2685 } else { 2686 crtc->mode = crtc->desiredMode; 2687 crtc->rotation = crtc->desiredRotation; 2688 crtc->x = crtc->desiredX; 2689 crtc->y = crtc->desiredY; 2690 if (!drmmode_handle_transform(crtc)) 2691 return FALSE; 2692 } 2693 } 2694 return TRUE; 2695} 2696 2697Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn) 2698{ 2699 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2700 2701 if (xf86_config->num_crtc) { 2702 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 2703 "Initializing kms color map\n"); 2704 if (!miCreateDefColormap(pScreen)) 2705 return FALSE; 2706 /* all radeons support 10 bit CLUTs */ 2707 if (!xf86HandleColormaps(pScreen, 256, 10, 2708 NULL, NULL, 2709 CMAP_PALETTED_TRUECOLOR 2710#if 0 /* This option messes up text mode! (eich@suse.de) */ 2711 | CMAP_LOAD_EVEN_IF_OFFSCREEN 2712#endif 2713 | CMAP_RELOAD_ON_MODE_SWITCH)) 2714 return FALSE; 2715 } 2716 return TRUE; 2717} 2718 2719static Bool 2720drmmode_find_output(ScrnInfoPtr scrn, int output_id, int *num_dvi, 2721 int *num_hdmi) 2722{ 2723 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); 2724 int i; 2725 2726 for (i = 0; i < config->num_output; i++) { 2727 xf86OutputPtr output = config->output[i]; 2728 drmmode_output_private_ptr drmmode_output = output->driver_private; 2729 2730 if (drmmode_output->output_id == output_id) { 2731 switch(drmmode_output->mode_output->connector_type) { 2732 case DRM_MODE_CONNECTOR_DVII: 2733 case DRM_MODE_CONNECTOR_DVID: 2734 case DRM_MODE_CONNECTOR_DVIA: 2735 (*num_dvi)++; 2736 break; 2737 case DRM_MODE_CONNECTOR_HDMIA: 2738 case DRM_MODE_CONNECTOR_HDMIB: 2739 (*num_hdmi)++; 2740 break; 2741 } 2742 2743 return TRUE; 2744 } 2745 } 2746 2747 return FALSE; 2748} 2749 2750void 2751radeon_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr drmmode) 2752{ 2753 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); 2754 RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); 2755 drmModeResPtr mode_res; 2756 int i, j; 2757 Bool found; 2758 Bool changed = FALSE; 2759 int num_dvi = 0, num_hdmi = 0; 2760 2761 mode_res = drmModeGetResources(drmmode->fd); 2762 if (!mode_res) 2763 goto out; 2764 2765restart_destroy: 2766 for (i = 0; i < config->num_output; i++) { 2767 xf86OutputPtr output = config->output[i]; 2768 drmmode_output_private_ptr drmmode_output = output->driver_private; 2769 found = FALSE; 2770 for (j = 0; j < mode_res->count_connectors; j++) { 2771 if (mode_res->connectors[j] == drmmode_output->output_id) { 2772 found = TRUE; 2773 break; 2774 } 2775 } 2776 if (found) 2777 continue; 2778 2779 drmModeFreeConnector(drmmode_output->mode_output); 2780 drmmode_output->mode_output = NULL; 2781 drmmode_output->output_id = -1; 2782 2783 changed = TRUE; 2784 if (drmmode->delete_dp_12_displays) { 2785 RROutputDestroy(output->randr_output); 2786 xf86OutputDestroy(output); 2787 goto restart_destroy; 2788 } 2789 } 2790 2791 /* find new output ids we don't have outputs for */ 2792 for (i = 0; i < mode_res->count_connectors; i++) { 2793 if (drmmode_find_output(pRADEONEnt->primary_scrn, 2794 mode_res->connectors[i], 2795 &num_dvi, &num_hdmi) || 2796 (pRADEONEnt->secondary_scrn && 2797 drmmode_find_output(pRADEONEnt->secondary_scrn, 2798 mode_res->connectors[i], 2799 &num_dvi, &num_hdmi))) 2800 continue; 2801 2802 if (drmmode_output_init(scrn, drmmode, mode_res, i, &num_dvi, 2803 &num_hdmi, 1) != 0) 2804 changed = TRUE; 2805 } 2806 2807 if (changed && dixPrivateKeyRegistered(rrPrivKey)) { 2808#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,2,0) 2809 RRSetChanged(xf86ScrnToScreen(scrn)); 2810#else 2811 rrScrPrivPtr rrScrPriv = rrGetScrPriv(scrn->pScreen); 2812 rrScrPriv->changed = TRUE; 2813#endif 2814 RRTellChanged(xf86ScrnToScreen(scrn)); 2815 } 2816 2817 drmModeFreeResources(mode_res); 2818out: 2819 RRGetInfo(xf86ScrnToScreen(scrn), TRUE); 2820} 2821#ifdef HAVE_LIBUDEV 2822static void 2823drmmode_handle_uevents(int fd, void *closure) 2824{ 2825 drmmode_ptr drmmode = closure; 2826 ScrnInfoPtr scrn = drmmode->scrn; 2827 struct udev_device *dev; 2828 Bool received = FALSE; 2829 struct timeval tv = { 0, 0 }; 2830 fd_set readfd; 2831 2832 FD_ZERO(&readfd); 2833 FD_SET(fd, &readfd); 2834 2835 while (select(fd + 1, &readfd, NULL, NULL, &tv) > 0 && 2836 FD_ISSET(fd, &readfd)) { 2837 /* select() ensured that this will not block */ 2838 dev = udev_monitor_receive_device(drmmode->uevent_monitor); 2839 if (dev) { 2840 udev_device_unref(dev); 2841 received = TRUE; 2842 } 2843 } 2844 2845 if (received) 2846 radeon_mode_hotplug(scrn, drmmode); 2847} 2848#endif 2849 2850void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode) 2851{ 2852#ifdef HAVE_LIBUDEV 2853 struct udev *u; 2854 struct udev_monitor *mon; 2855 2856 u = udev_new(); 2857 if (!u) 2858 return; 2859 mon = udev_monitor_new_from_netlink(u, "udev"); 2860 if (!mon) { 2861 udev_unref(u); 2862 return; 2863 } 2864 2865 if (udev_monitor_filter_add_match_subsystem_devtype(mon, 2866 "drm", 2867 "drm_minor") < 0 || 2868 udev_monitor_enable_receiving(mon) < 0) { 2869 udev_monitor_unref(mon); 2870 udev_unref(u); 2871 return; 2872 } 2873 2874 drmmode->uevent_handler = 2875 xf86AddGeneralHandler(udev_monitor_get_fd(mon), 2876 drmmode_handle_uevents, 2877 drmmode); 2878 2879 drmmode->uevent_monitor = mon; 2880#endif 2881} 2882 2883void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode) 2884{ 2885#ifdef HAVE_LIBUDEV 2886 if (drmmode->uevent_handler) { 2887 struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor); 2888 xf86RemoveGeneralHandler(drmmode->uevent_handler); 2889 2890 udev_monitor_unref(drmmode->uevent_monitor); 2891 udev_unref(u); 2892 } 2893#endif 2894} 2895 2896Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, 2897 uint32_t new_front_handle, uint64_t id, void *data, 2898 int ref_crtc_hw_id, radeon_drm_handler_proc handler, 2899 radeon_drm_abort_proc abort, 2900 enum drmmode_flip_sync flip_sync, 2901 uint32_t target_msc) 2902{ 2903 RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); 2904 RADEONInfoPtr info = RADEONPTR(scrn); 2905 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); 2906 xf86CrtcPtr crtc = NULL; 2907 drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private; 2908 drmmode_ptr drmmode = drmmode_crtc->drmmode; 2909 unsigned int pitch; 2910 int i; 2911 uint32_t tiling_flags = 0; 2912 uint32_t flip_flags = flip_sync == FLIP_ASYNC ? DRM_MODE_PAGE_FLIP_ASYNC : 0; 2913 drmmode_flipdata_ptr flipdata; 2914 uintptr_t drm_queue_seq = 0; 2915 2916 if (info->allowColorTiling) { 2917 if (info->ChipFamily >= CHIP_FAMILY_R600) 2918 tiling_flags |= RADEON_TILING_MICRO; 2919 else 2920 tiling_flags |= RADEON_TILING_MACRO; 2921 } 2922 2923 pitch = RADEON_ALIGN(scrn->displayWidth, drmmode_get_pitch_align(scrn, info->pixel_bytes, tiling_flags)) * 2924 info->pixel_bytes; 2925 if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) { 2926 pitch = info->front_surface.level[0].pitch_bytes; 2927 } 2928 2929 flipdata = calloc(1, sizeof(drmmode_flipdata_rec)); 2930 if (!flipdata) { 2931 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 2932 "flip queue: data alloc failed.\n"); 2933 goto error; 2934 } 2935 2936 /* 2937 * Create a new handle for the back buffer 2938 */ 2939 flipdata->old_fb_id = drmmode->fb_id; 2940 if (drmModeAddFB(drmmode->fd, scrn->virtualX, scrn->virtualY, 2941 scrn->depth, scrn->bitsPerPixel, pitch, 2942 new_front_handle, &drmmode->fb_id)) 2943 goto error; 2944 2945 /* 2946 * Queue flips on all enabled CRTCs 2947 * Note that if/when we get per-CRTC buffers, we'll have to update this. 2948 * Right now it assumes a single shared fb across all CRTCs, with the 2949 * kernel fixing up the offset of each CRTC as necessary. 2950 * 2951 * Also, flips queued on disabled or incorrectly configured displays 2952 * may never complete; this is a configuration error. 2953 */ 2954 2955 flipdata->event_data = data; 2956 flipdata->handler = handler; 2957 flipdata->abort = abort; 2958 2959 for (i = 0; i < config->num_crtc; i++) { 2960 crtc = config->crtc[i]; 2961 2962 if (!crtc->enabled) 2963 continue; 2964 2965 flipdata->flip_count++; 2966 drmmode_crtc = crtc->driver_private; 2967 2968 /* Only the reference crtc will finally deliver its page flip 2969 * completion event. All other crtc's events will be discarded. 2970 */ 2971 if (drmmode_crtc->hw_id == ref_crtc_hw_id) 2972 flipdata->fe_crtc = crtc; 2973 2974 drm_queue_seq = radeon_drm_queue_alloc(crtc, client, id, 2975 flipdata, 2976 drmmode_flip_handler, 2977 drmmode_flip_abort); 2978 if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { 2979 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 2980 "Allocating DRM queue event entry failed.\n"); 2981 goto error; 2982 } 2983 2984 if (drmmode_crtc->hw_id == ref_crtc_hw_id) { 2985 if (drmmode_page_flip_target_absolute(pRADEONEnt, 2986 drmmode_crtc, 2987 drmmode->fb_id, 2988 flip_flags, 2989 drm_queue_seq, 2990 target_msc) != 0) 2991 goto flip_error; 2992 } else { 2993 if (drmmode_page_flip_target_relative(pRADEONEnt, 2994 drmmode_crtc, 2995 drmmode->fb_id, 2996 flip_flags, 2997 drm_queue_seq, 0) != 0) 2998 goto flip_error; 2999 } 3000 3001 drmmode_crtc->flip_pending = TRUE; 3002 drm_queue_seq = 0; 3003 } 3004 3005 if (flipdata->flip_count > 0) 3006 return TRUE; 3007 3008flip_error: 3009 xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed: %s\n", 3010 strerror(errno)); 3011 3012error: 3013 if (flipdata && flipdata->flip_count <= 1 && 3014 drmmode->fb_id != flipdata->old_fb_id) { 3015 drmModeRmFB(drmmode->fd, drmmode->fb_id); 3016 drmmode->fb_id = flipdata->old_fb_id; 3017 } 3018 3019 if (drm_queue_seq) 3020 radeon_drm_abort_entry(drm_queue_seq); 3021 else if (crtc) 3022 drmmode_flip_abort(crtc, flipdata); 3023 else { 3024 abort(NULL, data); 3025 free(flipdata); 3026 } 3027 3028 xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n", 3029 strerror(errno)); 3030 return FALSE; 3031} 3032