1 /* 2 * Copyright (c) 2016 Intel Corporation 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that copyright 7 * notice and this permission notice appear in supporting documentation, and 8 * that the name of the copyright holders not be used in advertising or 9 * publicity pertaining to distribution of the software without specific, 10 * written prior permission. The copyright holders make no representations 11 * about the suitability of this software for any purpose. It is provided "as 12 * is" without express or implied warranty. 13 * 14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 * OF THIS SOFTWARE. 21 */ 22 23 #include <drm/drmP.h> 24 #include <drm/drm_plane.h> 25 26 #include "drm_crtc_internal.h" 27 28 /** 29 * DOC: overview 30 * 31 * A plane represents an image source that can be blended with or overlayed on 32 * top of a CRTC during the scanout process. Planes take their input data from a 33 * &drm_framebuffer object. The plane itself specifies the cropping and scaling 34 * of that image, and where it is placed on the visible are of a display 35 * pipeline, represented by &drm_crtc. A plane can also have additional 36 * properties that specify how the pixels are positioned and blended, like 37 * rotation or Z-position. All these properties are stored in &drm_plane_state. 38 * 39 * To create a plane, a KMS drivers allocates and zeroes an instances of 40 * &struct drm_plane (possibly as part of a larger structure) and registers it 41 * with a call to drm_universal_plane_init(). 42 * 43 * Cursor and overlay planes are optional. All drivers should provide one 44 * primary plane per CRTC to avoid surprising userspace too much. See enum 45 * drm_plane_type for a more in-depth discussion of these special uapi-relevant 46 * plane types. Special planes are associated with their CRTC by calling 47 * drm_crtc_init_with_planes(). 48 * 49 * The type of a plane is exposed in the immutable "type" enumeration property, 50 * which has one of the following values: "Overlay", "Primary", "Cursor". 51 */ 52 53 static unsigned int drm_num_planes(struct drm_device *dev) 54 { 55 unsigned int num = 0; 56 struct drm_plane *tmp; 57 58 drm_for_each_plane(tmp, dev) { 59 num++; 60 } 61 62 return num; 63 } 64 65 /** 66 * drm_universal_plane_init - Initialize a new universal plane object 67 * @dev: DRM device 68 * @plane: plane object to init 69 * @possible_crtcs: bitmask of possible CRTCs 70 * @funcs: callbacks for the new plane 71 * @formats: array of supported formats (DRM_FORMAT\_\*) 72 * @format_count: number of elements in @formats 73 * @type: type of plane (overlay, primary, cursor) 74 * @name: printf style format string for the plane name, or NULL for default name 75 * 76 * Initializes a plane object of type @type. 77 * 78 * Returns: 79 * Zero on success, error code on failure. 80 */ 81 int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, 82 uint32_t possible_crtcs, 83 const struct drm_plane_funcs *funcs, 84 const uint32_t *formats, unsigned int format_count, 85 enum drm_plane_type type, 86 const char *name, ...) 87 { 88 struct drm_mode_config *config = &dev->mode_config; 89 int ret; 90 91 ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE); 92 if (ret) 93 return ret; 94 95 drm_modeset_lock_init(&plane->mutex); 96 97 plane->base.properties = &plane->properties; 98 plane->dev = dev; 99 plane->funcs = funcs; 100 plane->format_types = kmalloc_array(format_count, sizeof(uint32_t), 101 GFP_KERNEL); 102 if (!plane->format_types) { 103 DRM_DEBUG_KMS("out of memory when allocating plane\n"); 104 drm_mode_object_unregister(dev, &plane->base); 105 return -ENOMEM; 106 } 107 108 if (name) { 109 va_list ap; 110 111 va_start(ap, name); 112 plane->name = kvasprintf(GFP_KERNEL, name, ap); 113 va_end(ap); 114 } else { 115 plane->name = kasprintf(GFP_KERNEL, "plane-%d", 116 drm_num_planes(dev)); 117 } 118 if (!plane->name) { 119 kfree(plane->format_types); 120 drm_mode_object_unregister(dev, &plane->base); 121 return -ENOMEM; 122 } 123 124 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); 125 plane->format_count = format_count; 126 plane->possible_crtcs = possible_crtcs; 127 plane->type = type; 128 129 list_add_tail(&plane->head, &config->plane_list); 130 plane->index = config->num_total_plane++; 131 if (plane->type == DRM_PLANE_TYPE_OVERLAY) 132 config->num_overlay_plane++; 133 134 drm_object_attach_property(&plane->base, 135 config->plane_type_property, 136 plane->type); 137 138 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { 139 drm_object_attach_property(&plane->base, config->prop_fb_id, 0); 140 drm_object_attach_property(&plane->base, config->prop_in_fence_fd, -1); 141 drm_object_attach_property(&plane->base, config->prop_crtc_id, 0); 142 drm_object_attach_property(&plane->base, config->prop_crtc_x, 0); 143 drm_object_attach_property(&plane->base, config->prop_crtc_y, 0); 144 drm_object_attach_property(&plane->base, config->prop_crtc_w, 0); 145 drm_object_attach_property(&plane->base, config->prop_crtc_h, 0); 146 drm_object_attach_property(&plane->base, config->prop_src_x, 0); 147 drm_object_attach_property(&plane->base, config->prop_src_y, 0); 148 drm_object_attach_property(&plane->base, config->prop_src_w, 0); 149 drm_object_attach_property(&plane->base, config->prop_src_h, 0); 150 } 151 152 return 0; 153 } 154 EXPORT_SYMBOL(drm_universal_plane_init); 155 156 int drm_plane_register_all(struct drm_device *dev) 157 { 158 struct drm_plane *plane; 159 int ret = 0; 160 161 drm_for_each_plane(plane, dev) { 162 if (plane->funcs->late_register) 163 ret = plane->funcs->late_register(plane); 164 if (ret) 165 return ret; 166 } 167 168 return 0; 169 } 170 171 void drm_plane_unregister_all(struct drm_device *dev) 172 { 173 struct drm_plane *plane; 174 175 drm_for_each_plane(plane, dev) { 176 if (plane->funcs->early_unregister) 177 plane->funcs->early_unregister(plane); 178 } 179 } 180 181 /** 182 * drm_plane_init - Initialize a legacy plane 183 * @dev: DRM device 184 * @plane: plane object to init 185 * @possible_crtcs: bitmask of possible CRTCs 186 * @funcs: callbacks for the new plane 187 * @formats: array of supported formats (DRM_FORMAT\_\*) 188 * @format_count: number of elements in @formats 189 * @is_primary: plane type (primary vs overlay) 190 * 191 * Legacy API to initialize a DRM plane. 192 * 193 * New drivers should call drm_universal_plane_init() instead. 194 * 195 * Returns: 196 * Zero on success, error code on failure. 197 */ 198 int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, 199 uint32_t possible_crtcs, 200 const struct drm_plane_funcs *funcs, 201 const uint32_t *formats, unsigned int format_count, 202 bool is_primary) 203 { 204 enum drm_plane_type type; 205 206 type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; 207 return drm_universal_plane_init(dev, plane, possible_crtcs, funcs, 208 formats, format_count, type, NULL); 209 } 210 EXPORT_SYMBOL(drm_plane_init); 211 212 /** 213 * drm_plane_cleanup - Clean up the core plane usage 214 * @plane: plane to cleanup 215 * 216 * This function cleans up @plane and removes it from the DRM mode setting 217 * core. Note that the function does *not* free the plane structure itself, 218 * this is the responsibility of the caller. 219 */ 220 void drm_plane_cleanup(struct drm_plane *plane) 221 { 222 struct drm_device *dev = plane->dev; 223 224 drm_modeset_lock_fini(&plane->mutex); 225 226 kfree(plane->format_types); 227 drm_mode_object_unregister(dev, &plane->base); 228 229 BUG_ON(list_empty(&plane->head)); 230 231 /* Note that the plane_list is considered to be static; should we 232 * remove the drm_plane at runtime we would have to decrement all 233 * the indices on the drm_plane after us in the plane_list. 234 */ 235 236 list_del(&plane->head); 237 dev->mode_config.num_total_plane--; 238 if (plane->type == DRM_PLANE_TYPE_OVERLAY) 239 dev->mode_config.num_overlay_plane--; 240 241 WARN_ON(plane->state && !plane->funcs->atomic_destroy_state); 242 if (plane->state && plane->funcs->atomic_destroy_state) 243 plane->funcs->atomic_destroy_state(plane, plane->state); 244 245 kfree(plane->name); 246 247 memset(plane, 0, sizeof(*plane)); 248 } 249 EXPORT_SYMBOL(drm_plane_cleanup); 250 251 /** 252 * drm_plane_from_index - find the registered plane at an index 253 * @dev: DRM device 254 * @idx: index of registered plane to find for 255 * 256 * Given a plane index, return the registered plane from DRM device's 257 * list of planes with matching index. This is the inverse of drm_plane_index(). 258 */ 259 struct drm_plane * 260 drm_plane_from_index(struct drm_device *dev, int idx) 261 { 262 struct drm_plane *plane; 263 264 drm_for_each_plane(plane, dev) 265 if (idx == plane->index) 266 return plane; 267 268 return NULL; 269 } 270 EXPORT_SYMBOL(drm_plane_from_index); 271 272 /** 273 * drm_plane_force_disable - Forcibly disable a plane 274 * @plane: plane to disable 275 * 276 * Forces the plane to be disabled. 277 * 278 * Used when the plane's current framebuffer is destroyed, 279 * and when restoring fbdev mode. 280 * 281 * Note that this function is not suitable for atomic drivers, since it doesn't 282 * wire through the lock acquisition context properly and hence can't handle 283 * retries or driver private locks. You probably want to use 284 * drm_atomic_helper_disable_plane() or 285 * drm_atomic_helper_disable_planes_on_crtc() instead. 286 */ 287 void drm_plane_force_disable(struct drm_plane *plane) 288 { 289 int ret; 290 291 if (!plane->fb) 292 return; 293 294 WARN_ON(drm_drv_uses_atomic_modeset(plane->dev)); 295 296 plane->old_fb = plane->fb; 297 ret = plane->funcs->disable_plane(plane, NULL); 298 if (ret) { 299 DRM_ERROR("failed to disable plane with busy fb\n"); 300 plane->old_fb = NULL; 301 return; 302 } 303 /* disconnect the plane from the fb and crtc: */ 304 drm_framebuffer_put(plane->old_fb); 305 plane->old_fb = NULL; 306 plane->fb = NULL; 307 plane->crtc = NULL; 308 } 309 EXPORT_SYMBOL(drm_plane_force_disable); 310 311 /** 312 * drm_mode_plane_set_obj_prop - set the value of a property 313 * @plane: drm plane object to set property value for 314 * @property: property to set 315 * @value: value the property should be set to 316 * 317 * This functions sets a given property on a given plane object. This function 318 * calls the driver's ->set_property callback and changes the software state of 319 * the property if the callback succeeds. 320 * 321 * Returns: 322 * Zero on success, error code on failure. 323 */ 324 int drm_mode_plane_set_obj_prop(struct drm_plane *plane, 325 struct drm_property *property, 326 uint64_t value) 327 { 328 int ret = -EINVAL; 329 struct drm_mode_object *obj = &plane->base; 330 331 if (plane->funcs->set_property) 332 ret = plane->funcs->set_property(plane, property, value); 333 if (!ret) 334 drm_object_property_set_value(obj, property, value); 335 336 return ret; 337 } 338 EXPORT_SYMBOL(drm_mode_plane_set_obj_prop); 339 340 int drm_mode_getplane_res(struct drm_device *dev, void *data, 341 struct drm_file *file_priv) 342 { 343 struct drm_mode_get_plane_res *plane_resp = data; 344 struct drm_mode_config *config; 345 struct drm_plane *plane; 346 uint32_t __user *plane_ptr; 347 int copied = 0; 348 unsigned num_planes; 349 350 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 351 return -EINVAL; 352 353 config = &dev->mode_config; 354 355 if (file_priv->universal_planes) 356 num_planes = config->num_total_plane; 357 else 358 num_planes = config->num_overlay_plane; 359 360 /* 361 * This ioctl is called twice, once to determine how much space is 362 * needed, and the 2nd time to fill it. 363 */ 364 if (num_planes && 365 (plane_resp->count_planes >= num_planes)) { 366 plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr; 367 368 /* Plane lists are invariant, no locking needed. */ 369 drm_for_each_plane(plane, dev) { 370 /* 371 * Unless userspace set the 'universal planes' 372 * capability bit, only advertise overlays. 373 */ 374 if (plane->type != DRM_PLANE_TYPE_OVERLAY && 375 !file_priv->universal_planes) 376 continue; 377 378 if (put_user(plane->base.id, plane_ptr + copied)) 379 return -EFAULT; 380 copied++; 381 } 382 } 383 plane_resp->count_planes = num_planes; 384 385 return 0; 386 } 387 388 int drm_mode_getplane(struct drm_device *dev, void *data, 389 struct drm_file *file_priv) 390 { 391 struct drm_mode_get_plane *plane_resp = data; 392 struct drm_plane *plane; 393 uint32_t __user *format_ptr; 394 395 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 396 return -EINVAL; 397 398 plane = drm_plane_find(dev, plane_resp->plane_id); 399 if (!plane) 400 return -ENOENT; 401 402 drm_modeset_lock(&plane->mutex, NULL); 403 if (plane->state && plane->state->crtc) 404 plane_resp->crtc_id = plane->state->crtc->base.id; 405 else if (!plane->state && plane->crtc) 406 plane_resp->crtc_id = plane->crtc->base.id; 407 else 408 plane_resp->crtc_id = 0; 409 410 if (plane->state && plane->state->fb) 411 plane_resp->fb_id = plane->state->fb->base.id; 412 else if (!plane->state && plane->fb) 413 plane_resp->fb_id = plane->fb->base.id; 414 else 415 plane_resp->fb_id = 0; 416 drm_modeset_unlock(&plane->mutex); 417 418 plane_resp->plane_id = plane->base.id; 419 plane_resp->possible_crtcs = plane->possible_crtcs; 420 plane_resp->gamma_size = 0; 421 422 /* 423 * This ioctl is called twice, once to determine how much space is 424 * needed, and the 2nd time to fill it. 425 */ 426 if (plane->format_count && 427 (plane_resp->count_format_types >= plane->format_count)) { 428 format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr; 429 if (copy_to_user(format_ptr, 430 plane->format_types, 431 sizeof(uint32_t) * plane->format_count)) { 432 return -EFAULT; 433 } 434 } 435 plane_resp->count_format_types = plane->format_count; 436 437 return 0; 438 } 439 440 int drm_plane_check_pixel_format(const struct drm_plane *plane, u32 format) 441 { 442 unsigned int i; 443 444 for (i = 0; i < plane->format_count; i++) { 445 if (format == plane->format_types[i]) 446 return 0; 447 } 448 449 return -EINVAL; 450 } 451 452 /* 453 * setplane_internal - setplane handler for internal callers 454 * 455 * Note that we assume an extra reference has already been taken on fb. If the 456 * update fails, this reference will be dropped before return; if it succeeds, 457 * the previous framebuffer (if any) will be unreferenced instead. 458 * 459 * src_{x,y,w,h} are provided in 16.16 fixed point format 460 */ 461 static int __setplane_internal(struct drm_plane *plane, 462 struct drm_crtc *crtc, 463 struct drm_framebuffer *fb, 464 int32_t crtc_x, int32_t crtc_y, 465 uint32_t crtc_w, uint32_t crtc_h, 466 /* src_{x,y,w,h} values are 16.16 fixed point */ 467 uint32_t src_x, uint32_t src_y, 468 uint32_t src_w, uint32_t src_h, 469 struct drm_modeset_acquire_ctx *ctx) 470 { 471 int ret = 0; 472 473 /* No fb means shut it down */ 474 if (!fb) { 475 plane->old_fb = plane->fb; 476 ret = plane->funcs->disable_plane(plane, ctx); 477 if (!ret) { 478 plane->crtc = NULL; 479 plane->fb = NULL; 480 } else { 481 plane->old_fb = NULL; 482 } 483 goto out; 484 } 485 486 /* Check whether this plane is usable on this CRTC */ 487 if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) { 488 DRM_DEBUG_KMS("Invalid crtc for plane\n"); 489 ret = -EINVAL; 490 goto out; 491 } 492 493 /* Check whether this plane supports the fb pixel format. */ 494 ret = drm_plane_check_pixel_format(plane, fb->format->format); 495 if (ret) { 496 struct drm_format_name_buf format_name; 497 DRM_DEBUG_KMS("Invalid pixel format %s\n", 498 drm_get_format_name(fb->format->format, 499 &format_name)); 500 goto out; 501 } 502 503 /* Give drivers some help against integer overflows */ 504 if (crtc_w > INT_MAX || 505 crtc_x > INT_MAX - (int32_t) crtc_w || 506 crtc_h > INT_MAX || 507 crtc_y > INT_MAX - (int32_t) crtc_h) { 508 DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n", 509 crtc_w, crtc_h, crtc_x, crtc_y); 510 ret = -ERANGE; 511 goto out; 512 } 513 514 ret = drm_framebuffer_check_src_coords(src_x, src_y, src_w, src_h, fb); 515 if (ret) 516 goto out; 517 518 plane->old_fb = plane->fb; 519 ret = plane->funcs->update_plane(plane, crtc, fb, 520 crtc_x, crtc_y, crtc_w, crtc_h, 521 src_x, src_y, src_w, src_h, ctx); 522 if (!ret) { 523 plane->crtc = crtc; 524 plane->fb = fb; 525 fb = NULL; 526 } else { 527 plane->old_fb = NULL; 528 } 529 530 out: 531 if (fb) 532 drm_framebuffer_put(fb); 533 if (plane->old_fb) 534 drm_framebuffer_put(plane->old_fb); 535 plane->old_fb = NULL; 536 537 return ret; 538 } 539 540 static int setplane_internal(struct drm_plane *plane, 541 struct drm_crtc *crtc, 542 struct drm_framebuffer *fb, 543 int32_t crtc_x, int32_t crtc_y, 544 uint32_t crtc_w, uint32_t crtc_h, 545 /* src_{x,y,w,h} values are 16.16 fixed point */ 546 uint32_t src_x, uint32_t src_y, 547 uint32_t src_w, uint32_t src_h) 548 { 549 struct drm_modeset_acquire_ctx ctx; 550 int ret; 551 552 drm_modeset_acquire_init(&ctx, 0); 553 retry: 554 ret = drm_modeset_lock_all_ctx(plane->dev, &ctx); 555 if (ret) 556 goto fail; 557 ret = __setplane_internal(plane, crtc, fb, 558 crtc_x, crtc_y, crtc_w, crtc_h, 559 src_x, src_y, src_w, src_h, &ctx); 560 561 fail: 562 if (ret == -EDEADLK) { 563 drm_modeset_backoff(&ctx); 564 goto retry; 565 } 566 drm_modeset_drop_locks(&ctx); 567 drm_modeset_acquire_fini(&ctx); 568 569 return ret; 570 } 571 572 int drm_mode_setplane(struct drm_device *dev, void *data, 573 struct drm_file *file_priv) 574 { 575 struct drm_mode_set_plane *plane_req = data; 576 struct drm_plane *plane; 577 struct drm_crtc *crtc = NULL; 578 struct drm_framebuffer *fb = NULL; 579 580 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 581 return -EINVAL; 582 583 /* 584 * First, find the plane, crtc, and fb objects. If not available, 585 * we don't bother to call the driver. 586 */ 587 plane = drm_plane_find(dev, plane_req->plane_id); 588 if (!plane) { 589 DRM_DEBUG_KMS("Unknown plane ID %d\n", 590 plane_req->plane_id); 591 return -ENOENT; 592 } 593 594 if (plane_req->fb_id) { 595 fb = drm_framebuffer_lookup(dev, plane_req->fb_id); 596 if (!fb) { 597 DRM_DEBUG_KMS("Unknown framebuffer ID %d\n", 598 plane_req->fb_id); 599 return -ENOENT; 600 } 601 602 crtc = drm_crtc_find(dev, plane_req->crtc_id); 603 if (!crtc) { 604 drm_framebuffer_put(fb); 605 DRM_DEBUG_KMS("Unknown crtc ID %d\n", 606 plane_req->crtc_id); 607 return -ENOENT; 608 } 609 } 610 611 /* 612 * setplane_internal will take care of deref'ing either the old or new 613 * framebuffer depending on success. 614 */ 615 return setplane_internal(plane, crtc, fb, 616 plane_req->crtc_x, plane_req->crtc_y, 617 plane_req->crtc_w, plane_req->crtc_h, 618 plane_req->src_x, plane_req->src_y, 619 plane_req->src_w, plane_req->src_h); 620 } 621 622 static int drm_mode_cursor_universal(struct drm_crtc *crtc, 623 struct drm_mode_cursor2 *req, 624 struct drm_file *file_priv, 625 struct drm_modeset_acquire_ctx *ctx) 626 { 627 struct drm_device *dev = crtc->dev; 628 struct drm_framebuffer *fb = NULL; 629 struct drm_mode_fb_cmd2 fbreq = { 630 .width = req->width, 631 .height = req->height, 632 .pixel_format = DRM_FORMAT_ARGB8888, 633 .pitches = { req->width * 4 }, 634 .handles = { req->handle }, 635 }; 636 int32_t crtc_x, crtc_y; 637 uint32_t crtc_w = 0, crtc_h = 0; 638 uint32_t src_w = 0, src_h = 0; 639 int ret = 0; 640 641 BUG_ON(!crtc->cursor); 642 WARN_ON(crtc->cursor->crtc != crtc && crtc->cursor->crtc != NULL); 643 644 /* 645 * Obtain fb we'll be using (either new or existing) and take an extra 646 * reference to it if fb != null. setplane will take care of dropping 647 * the reference if the plane update fails. 648 */ 649 if (req->flags & DRM_MODE_CURSOR_BO) { 650 if (req->handle) { 651 fb = drm_internal_framebuffer_create(dev, &fbreq, file_priv); 652 if (IS_ERR(fb)) { 653 DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n"); 654 return PTR_ERR(fb); 655 } 656 fb->hot_x = req->hot_x; 657 fb->hot_y = req->hot_y; 658 } else { 659 fb = NULL; 660 } 661 } else { 662 fb = crtc->cursor->fb; 663 if (fb) 664 drm_framebuffer_get(fb); 665 } 666 667 if (req->flags & DRM_MODE_CURSOR_MOVE) { 668 crtc_x = req->x; 669 crtc_y = req->y; 670 } else { 671 crtc_x = crtc->cursor_x; 672 crtc_y = crtc->cursor_y; 673 } 674 675 if (fb) { 676 crtc_w = fb->width; 677 crtc_h = fb->height; 678 src_w = fb->width << 16; 679 src_h = fb->height << 16; 680 } 681 682 /* 683 * setplane_internal will take care of deref'ing either the old or new 684 * framebuffer depending on success. 685 */ 686 ret = __setplane_internal(crtc->cursor, crtc, fb, 687 crtc_x, crtc_y, crtc_w, crtc_h, 688 0, 0, src_w, src_h, ctx); 689 690 /* Update successful; save new cursor position, if necessary */ 691 if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) { 692 crtc->cursor_x = req->x; 693 crtc->cursor_y = req->y; 694 } 695 696 return ret; 697 } 698 699 static int drm_mode_cursor_common(struct drm_device *dev, 700 struct drm_mode_cursor2 *req, 701 struct drm_file *file_priv) 702 { 703 struct drm_crtc *crtc; 704 struct drm_modeset_acquire_ctx ctx; 705 int ret = 0; 706 707 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 708 return -EINVAL; 709 710 if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) 711 return -EINVAL; 712 713 crtc = drm_crtc_find(dev, req->crtc_id); 714 if (!crtc) { 715 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id); 716 return -ENOENT; 717 } 718 719 drm_modeset_acquire_init(&ctx, 0); 720 retry: 721 ret = drm_modeset_lock(&crtc->mutex, &ctx); 722 if (ret) 723 goto out; 724 /* 725 * If this crtc has a universal cursor plane, call that plane's update 726 * handler rather than using legacy cursor handlers. 727 */ 728 if (crtc->cursor) { 729 ret = drm_modeset_lock(&crtc->cursor->mutex, &ctx); 730 if (ret) 731 goto out; 732 733 ret = drm_mode_cursor_universal(crtc, req, file_priv, &ctx); 734 goto out; 735 } 736 737 if (req->flags & DRM_MODE_CURSOR_BO) { 738 if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) { 739 ret = -ENXIO; 740 goto out; 741 } 742 /* Turns off the cursor if handle is 0 */ 743 if (crtc->funcs->cursor_set2) 744 ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle, 745 req->width, req->height, req->hot_x, req->hot_y); 746 else 747 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle, 748 req->width, req->height); 749 } 750 751 if (req->flags & DRM_MODE_CURSOR_MOVE) { 752 if (crtc->funcs->cursor_move) { 753 ret = crtc->funcs->cursor_move(crtc, req->x, req->y); 754 } else { 755 ret = -EFAULT; 756 goto out; 757 } 758 } 759 out: 760 if (ret == -EDEADLK) { 761 drm_modeset_backoff(&ctx); 762 goto retry; 763 } 764 765 drm_modeset_drop_locks(&ctx); 766 drm_modeset_acquire_fini(&ctx); 767 768 return ret; 769 770 } 771 772 773 int drm_mode_cursor_ioctl(struct drm_device *dev, 774 void *data, struct drm_file *file_priv) 775 { 776 struct drm_mode_cursor *req = data; 777 struct drm_mode_cursor2 new_req; 778 779 memcpy(&new_req, req, sizeof(struct drm_mode_cursor)); 780 new_req.hot_x = new_req.hot_y = 0; 781 782 return drm_mode_cursor_common(dev, &new_req, file_priv); 783 } 784 785 /* 786 * Set the cursor configuration based on user request. This implements the 2nd 787 * version of the cursor ioctl, which allows userspace to additionally specify 788 * the hotspot of the pointer. 789 */ 790 int drm_mode_cursor2_ioctl(struct drm_device *dev, 791 void *data, struct drm_file *file_priv) 792 { 793 struct drm_mode_cursor2 *req = data; 794 795 return drm_mode_cursor_common(dev, req, file_priv); 796 } 797 798 int drm_mode_page_flip_ioctl(struct drm_device *dev, 799 void *data, struct drm_file *file_priv) 800 { 801 struct drm_mode_crtc_page_flip_target *page_flip = data; 802 struct drm_crtc *crtc; 803 struct drm_framebuffer *fb = NULL; 804 struct drm_pending_vblank_event *e = NULL; 805 u32 target_vblank = page_flip->sequence; 806 struct drm_modeset_acquire_ctx ctx; 807 int ret = -EINVAL; 808 809 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 810 return -EINVAL; 811 812 if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS) 813 return -EINVAL; 814 815 if (page_flip->sequence != 0 && !(page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) 816 return -EINVAL; 817 818 /* Only one of the DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags 819 * can be specified 820 */ 821 if ((page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) == DRM_MODE_PAGE_FLIP_TARGET) 822 return -EINVAL; 823 824 if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip) 825 return -EINVAL; 826 827 crtc = drm_crtc_find(dev, page_flip->crtc_id); 828 if (!crtc) 829 return -ENOENT; 830 831 if (crtc->funcs->page_flip_target) { 832 u32 current_vblank; 833 int r; 834 835 r = drm_crtc_vblank_get(crtc); 836 if (r) 837 return r; 838 839 current_vblank = drm_crtc_vblank_count(crtc); 840 841 switch (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) { 842 case DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE: 843 if ((int)(target_vblank - current_vblank) > 1) { 844 DRM_DEBUG("Invalid absolute flip target %u, " 845 "must be <= %u\n", target_vblank, 846 current_vblank + 1); 847 drm_crtc_vblank_put(crtc); 848 return -EINVAL; 849 } 850 break; 851 case DRM_MODE_PAGE_FLIP_TARGET_RELATIVE: 852 if (target_vblank != 0 && target_vblank != 1) { 853 DRM_DEBUG("Invalid relative flip target %u, " 854 "must be 0 or 1\n", target_vblank); 855 drm_crtc_vblank_put(crtc); 856 return -EINVAL; 857 } 858 target_vblank += current_vblank; 859 break; 860 default: 861 target_vblank = current_vblank + 862 !(page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC); 863 break; 864 } 865 } else if (crtc->funcs->page_flip == NULL || 866 (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) { 867 return -EINVAL; 868 } 869 870 drm_modeset_acquire_init(&ctx, 0); 871 retry: 872 ret = drm_modeset_lock(&crtc->mutex, &ctx); 873 if (ret) 874 goto out; 875 ret = drm_modeset_lock(&crtc->primary->mutex, &ctx); 876 if (ret) 877 goto out; 878 879 if (crtc->primary->fb == NULL) { 880 /* The framebuffer is currently unbound, presumably 881 * due to a hotplug event, that userspace has not 882 * yet discovered. 883 */ 884 ret = -EBUSY; 885 goto out; 886 } 887 888 fb = drm_framebuffer_lookup(dev, page_flip->fb_id); 889 if (!fb) { 890 ret = -ENOENT; 891 goto out; 892 } 893 894 if (crtc->state) { 895 const struct drm_plane_state *state = crtc->primary->state; 896 897 ret = drm_framebuffer_check_src_coords(state->src_x, 898 state->src_y, 899 state->src_w, 900 state->src_h, 901 fb); 902 } else { 903 ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, &crtc->mode, fb); 904 } 905 if (ret) 906 goto out; 907 908 if (crtc->primary->fb->format != fb->format) { 909 DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); 910 ret = -EINVAL; 911 goto out; 912 } 913 914 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { 915 e = kzalloc(sizeof *e, GFP_KERNEL); 916 if (!e) { 917 ret = -ENOMEM; 918 goto out; 919 } 920 e->event.base.type = DRM_EVENT_FLIP_COMPLETE; 921 e->event.base.length = sizeof(e->event); 922 e->event.user_data = page_flip->user_data; 923 ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); 924 if (ret) { 925 kfree(e); 926 e = NULL; 927 goto out; 928 } 929 } 930 931 crtc->primary->old_fb = crtc->primary->fb; 932 if (crtc->funcs->page_flip_target) 933 ret = crtc->funcs->page_flip_target(crtc, fb, e, 934 page_flip->flags, 935 target_vblank, 936 &ctx); 937 else 938 ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags, 939 &ctx); 940 if (ret) { 941 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) 942 drm_event_cancel_free(dev, &e->base); 943 /* Keep the old fb, don't unref it. */ 944 crtc->primary->old_fb = NULL; 945 } else { 946 crtc->primary->fb = fb; 947 /* Unref only the old framebuffer. */ 948 fb = NULL; 949 } 950 951 out: 952 if (fb) 953 drm_framebuffer_put(fb); 954 if (crtc->primary->old_fb) 955 drm_framebuffer_put(crtc->primary->old_fb); 956 crtc->primary->old_fb = NULL; 957 958 if (ret == -EDEADLK) { 959 drm_modeset_backoff(&ctx); 960 goto retry; 961 } 962 963 drm_modeset_drop_locks(&ctx); 964 drm_modeset_acquire_fini(&ctx); 965 966 if (ret && crtc->funcs->page_flip_target) 967 drm_crtc_vblank_put(crtc); 968 969 return ret; 970 } 971