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_get(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 void drm_plane_force_disable(struct drm_plane *plane) 282 { 283 int ret; 284 285 if (!plane->fb) 286 return; 287 288 plane->old_fb = plane->fb; 289 ret = plane->funcs->disable_plane(plane); 290 if (ret) { 291 DRM_ERROR("failed to disable plane with busy fb\n"); 292 plane->old_fb = NULL; 293 return; 294 } 295 /* disconnect the plane from the fb and crtc: */ 296 drm_framebuffer_unreference(plane->old_fb); 297 plane->old_fb = NULL; 298 plane->fb = NULL; 299 plane->crtc = NULL; 300 } 301 EXPORT_SYMBOL(drm_plane_force_disable); 302 303 /** 304 * drm_mode_plane_set_obj_prop - set the value of a property 305 * @plane: drm plane object to set property value for 306 * @property: property to set 307 * @value: value the property should be set to 308 * 309 * This functions sets a given property on a given plane object. This function 310 * calls the driver's ->set_property callback and changes the software state of 311 * the property if the callback succeeds. 312 * 313 * Returns: 314 * Zero on success, error code on failure. 315 */ 316 int drm_mode_plane_set_obj_prop(struct drm_plane *plane, 317 struct drm_property *property, 318 uint64_t value) 319 { 320 int ret = -EINVAL; 321 struct drm_mode_object *obj = &plane->base; 322 323 if (plane->funcs->set_property) 324 ret = plane->funcs->set_property(plane, property, value); 325 if (!ret) 326 drm_object_property_set_value(obj, property, value); 327 328 return ret; 329 } 330 EXPORT_SYMBOL(drm_mode_plane_set_obj_prop); 331 332 int drm_mode_getplane_res(struct drm_device *dev, void *data, 333 struct drm_file *file_priv) 334 { 335 struct drm_mode_get_plane_res *plane_resp = data; 336 struct drm_mode_config *config; 337 struct drm_plane *plane; 338 uint32_t __user *plane_ptr; 339 int copied = 0; 340 unsigned num_planes; 341 342 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 343 return -EINVAL; 344 345 config = &dev->mode_config; 346 347 if (file_priv->universal_planes) 348 num_planes = config->num_total_plane; 349 else 350 num_planes = config->num_overlay_plane; 351 352 /* 353 * This ioctl is called twice, once to determine how much space is 354 * needed, and the 2nd time to fill it. 355 */ 356 if (num_planes && 357 (plane_resp->count_planes >= num_planes)) { 358 plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr; 359 360 /* Plane lists are invariant, no locking needed. */ 361 drm_for_each_plane(plane, dev) { 362 /* 363 * Unless userspace set the 'universal planes' 364 * capability bit, only advertise overlays. 365 */ 366 if (plane->type != DRM_PLANE_TYPE_OVERLAY && 367 !file_priv->universal_planes) 368 continue; 369 370 if (put_user(plane->base.id, plane_ptr + copied)) 371 return -EFAULT; 372 copied++; 373 } 374 } 375 plane_resp->count_planes = num_planes; 376 377 return 0; 378 } 379 380 int drm_mode_getplane(struct drm_device *dev, void *data, 381 struct drm_file *file_priv) 382 { 383 struct drm_mode_get_plane *plane_resp = data; 384 struct drm_plane *plane; 385 uint32_t __user *format_ptr; 386 387 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 388 return -EINVAL; 389 390 plane = drm_plane_find(dev, plane_resp->plane_id); 391 if (!plane) 392 return -ENOENT; 393 394 drm_modeset_lock(&plane->mutex, NULL); 395 if (plane->state && plane->state->crtc) 396 plane_resp->crtc_id = plane->state->crtc->base.id; 397 else if (!plane->state && plane->crtc) 398 plane_resp->crtc_id = plane->crtc->base.id; 399 else 400 plane_resp->crtc_id = 0; 401 402 if (plane->state && plane->state->fb) 403 plane_resp->fb_id = plane->state->fb->base.id; 404 else if (!plane->state && plane->fb) 405 plane_resp->fb_id = plane->fb->base.id; 406 else 407 plane_resp->fb_id = 0; 408 drm_modeset_unlock(&plane->mutex); 409 410 plane_resp->plane_id = plane->base.id; 411 plane_resp->possible_crtcs = plane->possible_crtcs; 412 plane_resp->gamma_size = 0; 413 414 /* 415 * This ioctl is called twice, once to determine how much space is 416 * needed, and the 2nd time to fill it. 417 */ 418 if (plane->format_count && 419 (plane_resp->count_format_types >= plane->format_count)) { 420 format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr; 421 if (copy_to_user(format_ptr, 422 plane->format_types, 423 sizeof(uint32_t) * plane->format_count)) { 424 return -EFAULT; 425 } 426 } 427 plane_resp->count_format_types = plane->format_count; 428 429 return 0; 430 } 431 432 int drm_plane_check_pixel_format(const struct drm_plane *plane, u32 format) 433 { 434 unsigned int i; 435 436 for (i = 0; i < plane->format_count; i++) { 437 if (format == plane->format_types[i]) 438 return 0; 439 } 440 441 return -EINVAL; 442 } 443 444 /* 445 * setplane_internal - setplane handler for internal callers 446 * 447 * Note that we assume an extra reference has already been taken on fb. If the 448 * update fails, this reference will be dropped before return; if it succeeds, 449 * the previous framebuffer (if any) will be unreferenced instead. 450 * 451 * src_{x,y,w,h} are provided in 16.16 fixed point format 452 */ 453 static int __setplane_internal(struct drm_plane *plane, 454 struct drm_crtc *crtc, 455 struct drm_framebuffer *fb, 456 int32_t crtc_x, int32_t crtc_y, 457 uint32_t crtc_w, uint32_t crtc_h, 458 /* src_{x,y,w,h} values are 16.16 fixed point */ 459 uint32_t src_x, uint32_t src_y, 460 uint32_t src_w, uint32_t src_h) 461 { 462 int ret = 0; 463 464 /* No fb means shut it down */ 465 if (!fb) { 466 plane->old_fb = plane->fb; 467 ret = plane->funcs->disable_plane(plane); 468 if (!ret) { 469 plane->crtc = NULL; 470 plane->fb = NULL; 471 } else { 472 plane->old_fb = NULL; 473 } 474 goto out; 475 } 476 477 /* Check whether this plane is usable on this CRTC */ 478 if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) { 479 DRM_DEBUG_KMS("Invalid crtc for plane\n"); 480 ret = -EINVAL; 481 goto out; 482 } 483 484 /* Check whether this plane supports the fb pixel format. */ 485 ret = drm_plane_check_pixel_format(plane, fb->format->format); 486 if (ret) { 487 struct drm_format_name_buf format_name; 488 DRM_DEBUG_KMS("Invalid pixel format %s\n", 489 drm_get_format_name(fb->format->format, 490 &format_name)); 491 goto out; 492 } 493 494 /* Give drivers some help against integer overflows */ 495 if (crtc_w > INT_MAX || 496 crtc_x > INT_MAX - (int32_t) crtc_w || 497 crtc_h > INT_MAX || 498 crtc_y > INT_MAX - (int32_t) crtc_h) { 499 DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n", 500 crtc_w, crtc_h, crtc_x, crtc_y); 501 ret = -ERANGE; 502 goto out; 503 } 504 505 ret = drm_framebuffer_check_src_coords(src_x, src_y, src_w, src_h, fb); 506 if (ret) 507 goto out; 508 509 plane->old_fb = plane->fb; 510 ret = plane->funcs->update_plane(plane, crtc, fb, 511 crtc_x, crtc_y, crtc_w, crtc_h, 512 src_x, src_y, src_w, src_h); 513 if (!ret) { 514 plane->crtc = crtc; 515 plane->fb = fb; 516 fb = NULL; 517 } else { 518 plane->old_fb = NULL; 519 } 520 521 out: 522 if (fb) 523 drm_framebuffer_unreference(fb); 524 if (plane->old_fb) 525 drm_framebuffer_unreference(plane->old_fb); 526 plane->old_fb = NULL; 527 528 return ret; 529 } 530 531 static int setplane_internal(struct drm_plane *plane, 532 struct drm_crtc *crtc, 533 struct drm_framebuffer *fb, 534 int32_t crtc_x, int32_t crtc_y, 535 uint32_t crtc_w, uint32_t crtc_h, 536 /* src_{x,y,w,h} values are 16.16 fixed point */ 537 uint32_t src_x, uint32_t src_y, 538 uint32_t src_w, uint32_t src_h) 539 { 540 int ret; 541 542 drm_modeset_lock_all(plane->dev); 543 ret = __setplane_internal(plane, crtc, fb, 544 crtc_x, crtc_y, crtc_w, crtc_h, 545 src_x, src_y, src_w, src_h); 546 drm_modeset_unlock_all(plane->dev); 547 548 return ret; 549 } 550 551 int drm_mode_setplane(struct drm_device *dev, void *data, 552 struct drm_file *file_priv) 553 { 554 struct drm_mode_set_plane *plane_req = data; 555 struct drm_plane *plane; 556 struct drm_crtc *crtc = NULL; 557 struct drm_framebuffer *fb = NULL; 558 559 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 560 return -EINVAL; 561 562 /* 563 * First, find the plane, crtc, and fb objects. If not available, 564 * we don't bother to call the driver. 565 */ 566 plane = drm_plane_find(dev, plane_req->plane_id); 567 if (!plane) { 568 DRM_DEBUG_KMS("Unknown plane ID %d\n", 569 plane_req->plane_id); 570 return -ENOENT; 571 } 572 573 if (plane_req->fb_id) { 574 fb = drm_framebuffer_lookup(dev, plane_req->fb_id); 575 if (!fb) { 576 DRM_DEBUG_KMS("Unknown framebuffer ID %d\n", 577 plane_req->fb_id); 578 return -ENOENT; 579 } 580 581 crtc = drm_crtc_find(dev, plane_req->crtc_id); 582 if (!crtc) { 583 DRM_DEBUG_KMS("Unknown crtc ID %d\n", 584 plane_req->crtc_id); 585 return -ENOENT; 586 } 587 } 588 589 /* 590 * setplane_internal will take care of deref'ing either the old or new 591 * framebuffer depending on success. 592 */ 593 return setplane_internal(plane, crtc, fb, 594 plane_req->crtc_x, plane_req->crtc_y, 595 plane_req->crtc_w, plane_req->crtc_h, 596 plane_req->src_x, plane_req->src_y, 597 plane_req->src_w, plane_req->src_h); 598 } 599 600 static int drm_mode_cursor_universal(struct drm_crtc *crtc, 601 struct drm_mode_cursor2 *req, 602 struct drm_file *file_priv) 603 { 604 struct drm_device *dev = crtc->dev; 605 struct drm_framebuffer *fb = NULL; 606 struct drm_mode_fb_cmd2 fbreq = { 607 .width = req->width, 608 .height = req->height, 609 .pixel_format = DRM_FORMAT_ARGB8888, 610 .pitches = { req->width * 4 }, 611 .handles = { req->handle }, 612 }; 613 int32_t crtc_x, crtc_y; 614 uint32_t crtc_w = 0, crtc_h = 0; 615 uint32_t src_w = 0, src_h = 0; 616 int ret = 0; 617 618 BUG_ON(!crtc->cursor); 619 WARN_ON(crtc->cursor->crtc != crtc && crtc->cursor->crtc != NULL); 620 621 /* 622 * Obtain fb we'll be using (either new or existing) and take an extra 623 * reference to it if fb != null. setplane will take care of dropping 624 * the reference if the plane update fails. 625 */ 626 if (req->flags & DRM_MODE_CURSOR_BO) { 627 if (req->handle) { 628 fb = drm_internal_framebuffer_create(dev, &fbreq, file_priv); 629 if (IS_ERR(fb)) { 630 DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n"); 631 return PTR_ERR(fb); 632 } 633 fb->hot_x = req->hot_x; 634 fb->hot_y = req->hot_y; 635 } else { 636 fb = NULL; 637 } 638 } else { 639 fb = crtc->cursor->fb; 640 if (fb) 641 drm_framebuffer_reference(fb); 642 } 643 644 if (req->flags & DRM_MODE_CURSOR_MOVE) { 645 crtc_x = req->x; 646 crtc_y = req->y; 647 } else { 648 crtc_x = crtc->cursor_x; 649 crtc_y = crtc->cursor_y; 650 } 651 652 if (fb) { 653 crtc_w = fb->width; 654 crtc_h = fb->height; 655 src_w = fb->width << 16; 656 src_h = fb->height << 16; 657 } 658 659 /* 660 * setplane_internal will take care of deref'ing either the old or new 661 * framebuffer depending on success. 662 */ 663 ret = __setplane_internal(crtc->cursor, crtc, fb, 664 crtc_x, crtc_y, crtc_w, crtc_h, 665 0, 0, src_w, src_h); 666 667 /* Update successful; save new cursor position, if necessary */ 668 if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) { 669 crtc->cursor_x = req->x; 670 crtc->cursor_y = req->y; 671 } 672 673 return ret; 674 } 675 676 static int drm_mode_cursor_common(struct drm_device *dev, 677 struct drm_mode_cursor2 *req, 678 struct drm_file *file_priv) 679 { 680 struct drm_crtc *crtc; 681 int ret = 0; 682 683 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 684 return -EINVAL; 685 686 if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) 687 return -EINVAL; 688 689 crtc = drm_crtc_find(dev, req->crtc_id); 690 if (!crtc) { 691 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id); 692 return -ENOENT; 693 } 694 695 /* 696 * If this crtc has a universal cursor plane, call that plane's update 697 * handler rather than using legacy cursor handlers. 698 */ 699 drm_modeset_lock_crtc(crtc, crtc->cursor); 700 if (crtc->cursor) { 701 ret = drm_mode_cursor_universal(crtc, req, file_priv); 702 goto out; 703 } 704 705 if (req->flags & DRM_MODE_CURSOR_BO) { 706 if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) { 707 ret = -ENXIO; 708 goto out; 709 } 710 /* Turns off the cursor if handle is 0 */ 711 if (crtc->funcs->cursor_set2) 712 ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle, 713 req->width, req->height, req->hot_x, req->hot_y); 714 else 715 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle, 716 req->width, req->height); 717 } 718 719 if (req->flags & DRM_MODE_CURSOR_MOVE) { 720 if (crtc->funcs->cursor_move) { 721 ret = crtc->funcs->cursor_move(crtc, req->x, req->y); 722 } else { 723 ret = -EFAULT; 724 goto out; 725 } 726 } 727 out: 728 drm_modeset_unlock_crtc(crtc); 729 730 return ret; 731 732 } 733 734 735 int drm_mode_cursor_ioctl(struct drm_device *dev, 736 void *data, struct drm_file *file_priv) 737 { 738 struct drm_mode_cursor *req = data; 739 struct drm_mode_cursor2 new_req; 740 741 memcpy(&new_req, req, sizeof(struct drm_mode_cursor)); 742 new_req.hot_x = new_req.hot_y = 0; 743 744 return drm_mode_cursor_common(dev, &new_req, file_priv); 745 } 746 747 /* 748 * Set the cursor configuration based on user request. This implements the 2nd 749 * version of the cursor ioctl, which allows userspace to additionally specify 750 * the hotspot of the pointer. 751 */ 752 int drm_mode_cursor2_ioctl(struct drm_device *dev, 753 void *data, struct drm_file *file_priv) 754 { 755 struct drm_mode_cursor2 *req = data; 756 757 return drm_mode_cursor_common(dev, req, file_priv); 758 } 759 760 int drm_mode_page_flip_ioctl(struct drm_device *dev, 761 void *data, struct drm_file *file_priv) 762 { 763 struct drm_mode_crtc_page_flip_target *page_flip = data; 764 struct drm_crtc *crtc; 765 struct drm_framebuffer *fb = NULL; 766 struct drm_pending_vblank_event *e = NULL; 767 u32 target_vblank = page_flip->sequence; 768 int ret = -EINVAL; 769 770 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 771 return -EINVAL; 772 773 if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS) 774 return -EINVAL; 775 776 if (page_flip->sequence != 0 && !(page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) 777 return -EINVAL; 778 779 /* Only one of the DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags 780 * can be specified 781 */ 782 if ((page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) == DRM_MODE_PAGE_FLIP_TARGET) 783 return -EINVAL; 784 785 if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip) 786 return -EINVAL; 787 788 crtc = drm_crtc_find(dev, page_flip->crtc_id); 789 if (!crtc) 790 return -ENOENT; 791 792 if (crtc->funcs->page_flip_target) { 793 u32 current_vblank; 794 int r; 795 796 r = drm_crtc_vblank_get(crtc); 797 if (r) 798 return r; 799 800 current_vblank = drm_crtc_vblank_count(crtc); 801 802 switch (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) { 803 case DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE: 804 if ((int)(target_vblank - current_vblank) > 1) { 805 DRM_DEBUG("Invalid absolute flip target %u, " 806 "must be <= %u\n", target_vblank, 807 current_vblank + 1); 808 drm_crtc_vblank_put(crtc); 809 return -EINVAL; 810 } 811 break; 812 case DRM_MODE_PAGE_FLIP_TARGET_RELATIVE: 813 if (target_vblank != 0 && target_vblank != 1) { 814 DRM_DEBUG("Invalid relative flip target %u, " 815 "must be 0 or 1\n", target_vblank); 816 drm_crtc_vblank_put(crtc); 817 return -EINVAL; 818 } 819 target_vblank += current_vblank; 820 break; 821 default: 822 target_vblank = current_vblank + 823 !(page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC); 824 break; 825 } 826 } else if (crtc->funcs->page_flip == NULL || 827 (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) { 828 return -EINVAL; 829 } 830 831 drm_modeset_lock_crtc(crtc, crtc->primary); 832 if (crtc->primary->fb == NULL) { 833 /* The framebuffer is currently unbound, presumably 834 * due to a hotplug event, that userspace has not 835 * yet discovered. 836 */ 837 ret = -EBUSY; 838 goto out; 839 } 840 841 fb = drm_framebuffer_lookup(dev, page_flip->fb_id); 842 if (!fb) { 843 ret = -ENOENT; 844 goto out; 845 } 846 847 if (crtc->state) { 848 const struct drm_plane_state *state = crtc->primary->state; 849 850 ret = drm_framebuffer_check_src_coords(state->src_x, 851 state->src_y, 852 state->src_w, 853 state->src_h, 854 fb); 855 } else { 856 ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, &crtc->mode, fb); 857 } 858 if (ret) 859 goto out; 860 861 if (crtc->primary->fb->format != fb->format) { 862 DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); 863 ret = -EINVAL; 864 goto out; 865 } 866 867 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { 868 e = kzalloc(sizeof *e, GFP_KERNEL); 869 if (!e) { 870 ret = -ENOMEM; 871 goto out; 872 } 873 e->event.base.type = DRM_EVENT_FLIP_COMPLETE; 874 e->event.base.length = sizeof(e->event); 875 e->event.user_data = page_flip->user_data; 876 ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); 877 if (ret) { 878 kfree(e); 879 goto out; 880 } 881 } 882 883 crtc->primary->old_fb = crtc->primary->fb; 884 if (crtc->funcs->page_flip_target) 885 ret = crtc->funcs->page_flip_target(crtc, fb, e, 886 page_flip->flags, 887 target_vblank); 888 else 889 ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags); 890 if (ret) { 891 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) 892 drm_event_cancel_free(dev, &e->base); 893 /* Keep the old fb, don't unref it. */ 894 crtc->primary->old_fb = NULL; 895 } else { 896 crtc->primary->fb = fb; 897 /* Unref only the old framebuffer. */ 898 fb = NULL; 899 } 900 901 out: 902 if (ret && crtc->funcs->page_flip_target) 903 drm_crtc_vblank_put(crtc); 904 if (fb) 905 drm_framebuffer_unreference(fb); 906 if (crtc->primary->old_fb) 907 drm_framebuffer_unreference(crtc->primary->old_fb); 908 crtc->primary->old_fb = NULL; 909 drm_modeset_unlock_crtc(crtc); 910 911 return ret; 912 } 913