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