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