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 <linux/slab.h> 24 #include <linux/uaccess.h> 25 26 #include <drm/drm_plane.h> 27 #include <drm/drm_drv.h> 28 #include <drm/drm_print.h> 29 #include <drm/drm_framebuffer.h> 30 #include <drm/drm_file.h> 31 #include <drm/drm_crtc.h> 32 #include <drm/drm_fourcc.h> 33 #include <drm/drm_managed.h> 34 #include <drm/drm_vblank.h> 35 36 #include "drm_crtc_internal.h" 37 38 /** 39 * DOC: overview 40 * 41 * A plane represents an image source that can be blended with or overlayed on 42 * top of a CRTC during the scanout process. Planes take their input data from a 43 * &drm_framebuffer object. The plane itself specifies the cropping and scaling 44 * of that image, and where it is placed on the visible area of a display 45 * pipeline, represented by &drm_crtc. A plane can also have additional 46 * properties that specify how the pixels are positioned and blended, like 47 * rotation or Z-position. All these properties are stored in &drm_plane_state. 48 * 49 * To create a plane, a KMS drivers allocates and zeroes an instances of 50 * &struct drm_plane (possibly as part of a larger structure) and registers it 51 * with a call to drm_universal_plane_init(). 52 * 53 * The type of a plane is exposed in the immutable "type" enumeration property, 54 * which has one of the following values: "Overlay", "Primary", "Cursor" (see 55 * enum drm_plane_type). A plane can be compatible with multiple CRTCs, see 56 * &drm_plane.possible_crtcs. 57 * 58 * Each CRTC must have a unique primary plane userspace can attach to enable 59 * the CRTC. In other words, userspace must be able to attach a different 60 * primary plane to each CRTC at the same time. Primary planes can still be 61 * compatible with multiple CRTCs. There must be exactly as many primary planes 62 * as there are CRTCs. 63 * 64 * Legacy uAPI doesn't expose the primary and cursor planes directly. DRM core 65 * relies on the driver to set the primary and optionally the cursor plane used 66 * for legacy IOCTLs. This is done by calling drm_crtc_init_with_planes(). All 67 * drivers must provide one primary plane per CRTC to avoid surprising legacy 68 * userspace too much. 69 */ 70 71 /** 72 * DOC: standard plane properties 73 * 74 * DRM planes have a few standardized properties: 75 * 76 * IN_FORMATS: 77 * Blob property which contains the set of buffer format and modifier 78 * pairs supported by this plane. The blob is a struct 79 * drm_format_modifier_blob. Without this property the plane doesn't 80 * support buffers with modifiers. Userspace cannot change this property. 81 */ 82 83 static unsigned int drm_num_planes(struct drm_device *dev) 84 { 85 unsigned int num = 0; 86 struct drm_plane *tmp; 87 88 drm_for_each_plane(tmp, dev) { 89 num++; 90 } 91 92 return num; 93 } 94 95 static inline u32 * 96 formats_ptr(struct drm_format_modifier_blob *blob) 97 { 98 return (u32 *)(((char *)blob) + blob->formats_offset); 99 } 100 101 static inline struct drm_format_modifier * 102 modifiers_ptr(struct drm_format_modifier_blob *blob) 103 { 104 return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset); 105 } 106 107 static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane) 108 { 109 const struct drm_mode_config *config = &dev->mode_config; 110 struct drm_property_blob *blob; 111 struct drm_format_modifier *mod; 112 size_t blob_size, formats_size, modifiers_size; 113 struct drm_format_modifier_blob *blob_data; 114 unsigned int i, j; 115 116 formats_size = sizeof(__u32) * plane->format_count; 117 if (WARN_ON(!formats_size)) { 118 /* 0 formats are never expected */ 119 return 0; 120 } 121 122 modifiers_size = 123 sizeof(struct drm_format_modifier) * plane->modifier_count; 124 125 blob_size = sizeof(struct drm_format_modifier_blob); 126 /* Modifiers offset is a pointer to a struct with a 64 bit field so it 127 * should be naturally aligned to 8B. 128 */ 129 BUILD_BUG_ON(sizeof(struct drm_format_modifier_blob) % 8); 130 blob_size += ALIGN(formats_size, 8); 131 blob_size += modifiers_size; 132 133 blob = drm_property_create_blob(dev, blob_size, NULL); 134 if (IS_ERR(blob)) 135 return -1; 136 137 blob_data = blob->data; 138 blob_data->version = FORMAT_BLOB_CURRENT; 139 blob_data->count_formats = plane->format_count; 140 blob_data->formats_offset = sizeof(struct drm_format_modifier_blob); 141 blob_data->count_modifiers = plane->modifier_count; 142 143 blob_data->modifiers_offset = 144 ALIGN(blob_data->formats_offset + formats_size, 8); 145 146 memcpy(formats_ptr(blob_data), plane->format_types, formats_size); 147 148 /* If we can't determine support, just bail */ 149 if (!plane->funcs->format_mod_supported) 150 goto done; 151 152 mod = modifiers_ptr(blob_data); 153 for (i = 0; i < plane->modifier_count; i++) { 154 for (j = 0; j < plane->format_count; j++) { 155 if (plane->funcs->format_mod_supported(plane, 156 plane->format_types[j], 157 plane->modifiers[i])) { 158 159 mod->formats |= 1ULL << j; 160 } 161 } 162 163 mod->modifier = plane->modifiers[i]; 164 mod->offset = 0; 165 mod->pad = 0; 166 mod++; 167 } 168 169 done: 170 drm_object_attach_property(&plane->base, config->modifiers_property, 171 blob->base.id); 172 173 return 0; 174 } 175 176 __printf(9, 0) 177 static int __drm_universal_plane_init(struct drm_device *dev, 178 struct drm_plane *plane, 179 uint32_t possible_crtcs, 180 const struct drm_plane_funcs *funcs, 181 const uint32_t *formats, 182 unsigned int format_count, 183 const uint64_t *format_modifiers, 184 enum drm_plane_type type, 185 const char *name, va_list ap) 186 { 187 struct drm_mode_config *config = &dev->mode_config; 188 unsigned int format_modifier_count = 0; 189 int ret; 190 191 /* plane index is used with 32bit bitmasks */ 192 if (WARN_ON(config->num_total_plane >= 32)) 193 return -EINVAL; 194 195 WARN_ON(drm_drv_uses_atomic_modeset(dev) && 196 (!funcs->atomic_destroy_state || 197 !funcs->atomic_duplicate_state)); 198 199 ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE); 200 if (ret) 201 return ret; 202 203 drm_modeset_lock_init(&plane->mutex); 204 205 plane->base.properties = &plane->properties; 206 plane->dev = dev; 207 plane->funcs = funcs; 208 plane->format_types = kmalloc_array(format_count, sizeof(uint32_t), 209 GFP_KERNEL); 210 if (!plane->format_types) { 211 DRM_DEBUG_KMS("out of memory when allocating plane\n"); 212 drm_mode_object_unregister(dev, &plane->base); 213 return -ENOMEM; 214 } 215 216 /* 217 * First driver to need more than 64 formats needs to fix this. Each 218 * format is encoded as a bit and the current code only supports a u64. 219 */ 220 if (WARN_ON(format_count > 64)) 221 return -EINVAL; 222 223 if (format_modifiers) { 224 const uint64_t *temp_modifiers = format_modifiers; 225 226 while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID) 227 format_modifier_count++; 228 } 229 230 if (format_modifier_count) 231 config->allow_fb_modifiers = true; 232 233 plane->modifier_count = format_modifier_count; 234 plane->modifiers = kmalloc_array(format_modifier_count, 235 sizeof(format_modifiers[0]), 236 GFP_KERNEL); 237 238 if (format_modifier_count && !plane->modifiers) { 239 DRM_DEBUG_KMS("out of memory when allocating plane\n"); 240 kfree(plane->format_types); 241 drm_mode_object_unregister(dev, &plane->base); 242 return -ENOMEM; 243 } 244 245 if (name) { 246 plane->name = kvasprintf(GFP_KERNEL, name, ap); 247 } else { 248 plane->name = kasprintf(GFP_KERNEL, "plane-%d", 249 drm_num_planes(dev)); 250 } 251 if (!plane->name) { 252 kfree(plane->format_types); 253 kfree(plane->modifiers); 254 drm_mode_object_unregister(dev, &plane->base); 255 return -ENOMEM; 256 } 257 258 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); 259 plane->format_count = format_count; 260 memcpy(plane->modifiers, format_modifiers, 261 format_modifier_count * sizeof(format_modifiers[0])); 262 plane->possible_crtcs = possible_crtcs; 263 plane->type = type; 264 265 list_add_tail(&plane->head, &config->plane_list); 266 plane->index = config->num_total_plane++; 267 268 drm_object_attach_property(&plane->base, 269 config->plane_type_property, 270 plane->type); 271 272 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { 273 drm_object_attach_property(&plane->base, config->prop_fb_id, 0); 274 drm_object_attach_property(&plane->base, config->prop_in_fence_fd, -1); 275 drm_object_attach_property(&plane->base, config->prop_crtc_id, 0); 276 drm_object_attach_property(&plane->base, config->prop_crtc_x, 0); 277 drm_object_attach_property(&plane->base, config->prop_crtc_y, 0); 278 drm_object_attach_property(&plane->base, config->prop_crtc_w, 0); 279 drm_object_attach_property(&plane->base, config->prop_crtc_h, 0); 280 drm_object_attach_property(&plane->base, config->prop_src_x, 0); 281 drm_object_attach_property(&plane->base, config->prop_src_y, 0); 282 drm_object_attach_property(&plane->base, config->prop_src_w, 0); 283 drm_object_attach_property(&plane->base, config->prop_src_h, 0); 284 } 285 286 if (config->allow_fb_modifiers) 287 create_in_format_blob(dev, plane); 288 289 return 0; 290 } 291 292 /** 293 * drm_universal_plane_init - Initialize a new universal plane object 294 * @dev: DRM device 295 * @plane: plane object to init 296 * @possible_crtcs: bitmask of possible CRTCs 297 * @funcs: callbacks for the new plane 298 * @formats: array of supported formats (DRM_FORMAT\_\*) 299 * @format_count: number of elements in @formats 300 * @format_modifiers: array of struct drm_format modifiers terminated by 301 * DRM_FORMAT_MOD_INVALID 302 * @type: type of plane (overlay, primary, cursor) 303 * @name: printf style format string for the plane name, or NULL for default name 304 * 305 * Initializes a plane object of type @type. The &drm_plane_funcs.destroy hook 306 * should call drm_plane_cleanup() and kfree() the plane structure. The plane 307 * structure should not be allocated with devm_kzalloc(). 308 * 309 * Note: consider using drmm_universal_plane_alloc() instead of 310 * drm_universal_plane_init() to let the DRM managed resource infrastructure 311 * take care of cleanup and deallocation. 312 * 313 * Returns: 314 * Zero on success, error code on failure. 315 */ 316 int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, 317 uint32_t possible_crtcs, 318 const struct drm_plane_funcs *funcs, 319 const uint32_t *formats, unsigned int format_count, 320 const uint64_t *format_modifiers, 321 enum drm_plane_type type, 322 const char *name, ...) 323 { 324 va_list ap; 325 int ret; 326 327 WARN_ON(!funcs->destroy); 328 329 va_start(ap, name); 330 ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs, 331 formats, format_count, format_modifiers, 332 type, name, ap); 333 va_end(ap); 334 return ret; 335 } 336 EXPORT_SYMBOL(drm_universal_plane_init); 337 338 static void drmm_universal_plane_alloc_release(struct drm_device *dev, void *ptr) 339 { 340 struct drm_plane *plane = ptr; 341 342 if (WARN_ON(!plane->dev)) 343 return; 344 345 drm_plane_cleanup(plane); 346 } 347 348 void *__drmm_universal_plane_alloc(struct drm_device *dev, size_t size, 349 size_t offset, uint32_t possible_crtcs, 350 const struct drm_plane_funcs *funcs, 351 const uint32_t *formats, unsigned int format_count, 352 const uint64_t *format_modifiers, 353 enum drm_plane_type type, 354 const char *name, ...) 355 { 356 void *container; 357 struct drm_plane *plane; 358 va_list ap; 359 int ret; 360 361 if (WARN_ON(!funcs || funcs->destroy)) 362 return ERR_PTR(-EINVAL); 363 364 container = drmm_kzalloc(dev, size, GFP_KERNEL); 365 if (!container) 366 return ERR_PTR(-ENOMEM); 367 368 plane = container + offset; 369 370 va_start(ap, name); 371 ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs, 372 formats, format_count, format_modifiers, 373 type, name, ap); 374 va_end(ap); 375 if (ret) 376 return ERR_PTR(ret); 377 378 ret = drmm_add_action_or_reset(dev, drmm_universal_plane_alloc_release, 379 plane); 380 if (ret) 381 return ERR_PTR(ret); 382 383 return container; 384 } 385 EXPORT_SYMBOL(__drmm_universal_plane_alloc); 386 387 int drm_plane_register_all(struct drm_device *dev) 388 { 389 unsigned int num_planes = 0; 390 unsigned int num_zpos = 0; 391 struct drm_plane *plane; 392 int ret = 0; 393 394 drm_for_each_plane(plane, dev) { 395 if (plane->funcs->late_register) 396 ret = plane->funcs->late_register(plane); 397 if (ret) 398 return ret; 399 400 if (plane->zpos_property) 401 num_zpos++; 402 num_planes++; 403 } 404 405 drm_WARN(dev, num_zpos && num_planes != num_zpos, 406 "Mixing planes with and without zpos property is invalid\n"); 407 408 return 0; 409 } 410 411 void drm_plane_unregister_all(struct drm_device *dev) 412 { 413 struct drm_plane *plane; 414 415 drm_for_each_plane(plane, dev) { 416 if (plane->funcs->early_unregister) 417 plane->funcs->early_unregister(plane); 418 } 419 } 420 421 /** 422 * drm_plane_init - Initialize a legacy plane 423 * @dev: DRM device 424 * @plane: plane object to init 425 * @possible_crtcs: bitmask of possible CRTCs 426 * @funcs: callbacks for the new plane 427 * @formats: array of supported formats (DRM_FORMAT\_\*) 428 * @format_count: number of elements in @formats 429 * @is_primary: plane type (primary vs overlay) 430 * 431 * Legacy API to initialize a DRM plane. 432 * 433 * New drivers should call drm_universal_plane_init() instead. 434 * 435 * Returns: 436 * Zero on success, error code on failure. 437 */ 438 int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, 439 uint32_t possible_crtcs, 440 const struct drm_plane_funcs *funcs, 441 const uint32_t *formats, unsigned int format_count, 442 bool is_primary) 443 { 444 enum drm_plane_type type; 445 446 type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; 447 return drm_universal_plane_init(dev, plane, possible_crtcs, funcs, 448 formats, format_count, 449 NULL, type, NULL); 450 } 451 EXPORT_SYMBOL(drm_plane_init); 452 453 /** 454 * drm_plane_cleanup - Clean up the core plane usage 455 * @plane: plane to cleanup 456 * 457 * This function cleans up @plane and removes it from the DRM mode setting 458 * core. Note that the function does *not* free the plane structure itself, 459 * this is the responsibility of the caller. 460 */ 461 void drm_plane_cleanup(struct drm_plane *plane) 462 { 463 struct drm_device *dev = plane->dev; 464 465 drm_modeset_lock_fini(&plane->mutex); 466 467 kfree(plane->format_types); 468 kfree(plane->modifiers); 469 drm_mode_object_unregister(dev, &plane->base); 470 471 BUG_ON(list_empty(&plane->head)); 472 473 /* Note that the plane_list is considered to be static; should we 474 * remove the drm_plane at runtime we would have to decrement all 475 * the indices on the drm_plane after us in the plane_list. 476 */ 477 478 list_del(&plane->head); 479 dev->mode_config.num_total_plane--; 480 481 WARN_ON(plane->state && !plane->funcs->atomic_destroy_state); 482 if (plane->state && plane->funcs->atomic_destroy_state) 483 plane->funcs->atomic_destroy_state(plane, plane->state); 484 485 kfree(plane->name); 486 487 memset(plane, 0, sizeof(*plane)); 488 } 489 EXPORT_SYMBOL(drm_plane_cleanup); 490 491 /** 492 * drm_plane_from_index - find the registered plane at an index 493 * @dev: DRM device 494 * @idx: index of registered plane to find for 495 * 496 * Given a plane index, return the registered plane from DRM device's 497 * list of planes with matching index. This is the inverse of drm_plane_index(). 498 */ 499 struct drm_plane * 500 drm_plane_from_index(struct drm_device *dev, int idx) 501 { 502 struct drm_plane *plane; 503 504 drm_for_each_plane(plane, dev) 505 if (idx == plane->index) 506 return plane; 507 508 return NULL; 509 } 510 EXPORT_SYMBOL(drm_plane_from_index); 511 512 /** 513 * drm_plane_force_disable - Forcibly disable a plane 514 * @plane: plane to disable 515 * 516 * Forces the plane to be disabled. 517 * 518 * Used when the plane's current framebuffer is destroyed, 519 * and when restoring fbdev mode. 520 * 521 * Note that this function is not suitable for atomic drivers, since it doesn't 522 * wire through the lock acquisition context properly and hence can't handle 523 * retries or driver private locks. You probably want to use 524 * drm_atomic_helper_disable_plane() or 525 * drm_atomic_helper_disable_planes_on_crtc() instead. 526 */ 527 void drm_plane_force_disable(struct drm_plane *plane) 528 { 529 int ret; 530 531 if (!plane->fb) 532 return; 533 534 WARN_ON(drm_drv_uses_atomic_modeset(plane->dev)); 535 536 plane->old_fb = plane->fb; 537 ret = plane->funcs->disable_plane(plane, NULL); 538 if (ret) { 539 DRM_ERROR("failed to disable plane with busy fb\n"); 540 plane->old_fb = NULL; 541 return; 542 } 543 /* disconnect the plane from the fb and crtc: */ 544 drm_framebuffer_put(plane->old_fb); 545 plane->old_fb = NULL; 546 plane->fb = NULL; 547 plane->crtc = NULL; 548 } 549 EXPORT_SYMBOL(drm_plane_force_disable); 550 551 /** 552 * drm_mode_plane_set_obj_prop - set the value of a property 553 * @plane: drm plane object to set property value for 554 * @property: property to set 555 * @value: value the property should be set to 556 * 557 * This functions sets a given property on a given plane object. This function 558 * calls the driver's ->set_property callback and changes the software state of 559 * the property if the callback succeeds. 560 * 561 * Returns: 562 * Zero on success, error code on failure. 563 */ 564 int drm_mode_plane_set_obj_prop(struct drm_plane *plane, 565 struct drm_property *property, 566 uint64_t value) 567 { 568 int ret = -EINVAL; 569 struct drm_mode_object *obj = &plane->base; 570 571 if (plane->funcs->set_property) 572 ret = plane->funcs->set_property(plane, property, value); 573 if (!ret) 574 drm_object_property_set_value(obj, property, value); 575 576 return ret; 577 } 578 EXPORT_SYMBOL(drm_mode_plane_set_obj_prop); 579 580 int drm_mode_getplane_res(struct drm_device *dev, void *data, 581 struct drm_file *file_priv) 582 { 583 struct drm_mode_get_plane_res *plane_resp = data; 584 struct drm_plane *plane; 585 uint32_t __user *plane_ptr; 586 int count = 0; 587 588 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 589 return -EOPNOTSUPP; 590 591 plane_ptr = u64_to_user_ptr(plane_resp->plane_id_ptr); 592 593 /* 594 * This ioctl is called twice, once to determine how much space is 595 * needed, and the 2nd time to fill it. 596 */ 597 drm_for_each_plane(plane, dev) { 598 /* 599 * Unless userspace set the 'universal planes' 600 * capability bit, only advertise overlays. 601 */ 602 if (plane->type != DRM_PLANE_TYPE_OVERLAY && 603 !file_priv->universal_planes) 604 continue; 605 606 if (drm_lease_held(file_priv, plane->base.id)) { 607 if (count < plane_resp->count_planes && 608 put_user(plane->base.id, plane_ptr + count)) 609 return -EFAULT; 610 count++; 611 } 612 } 613 plane_resp->count_planes = count; 614 615 return 0; 616 } 617 618 int drm_mode_getplane(struct drm_device *dev, void *data, 619 struct drm_file *file_priv) 620 { 621 struct drm_mode_get_plane *plane_resp = data; 622 struct drm_plane *plane; 623 uint32_t __user *format_ptr; 624 625 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 626 return -EOPNOTSUPP; 627 628 plane = drm_plane_find(dev, file_priv, plane_resp->plane_id); 629 if (!plane) 630 return -ENOENT; 631 632 drm_modeset_lock(&plane->mutex, NULL); 633 if (plane->state && plane->state->crtc && drm_lease_held(file_priv, plane->state->crtc->base.id)) 634 plane_resp->crtc_id = plane->state->crtc->base.id; 635 else if (!plane->state && plane->crtc && drm_lease_held(file_priv, plane->crtc->base.id)) 636 plane_resp->crtc_id = plane->crtc->base.id; 637 else 638 plane_resp->crtc_id = 0; 639 640 if (plane->state && plane->state->fb) 641 plane_resp->fb_id = plane->state->fb->base.id; 642 else if (!plane->state && plane->fb) 643 plane_resp->fb_id = plane->fb->base.id; 644 else 645 plane_resp->fb_id = 0; 646 drm_modeset_unlock(&plane->mutex); 647 648 plane_resp->plane_id = plane->base.id; 649 plane_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv, 650 plane->possible_crtcs); 651 652 plane_resp->gamma_size = 0; 653 654 /* 655 * This ioctl is called twice, once to determine how much space is 656 * needed, and the 2nd time to fill it. 657 */ 658 if (plane->format_count && 659 (plane_resp->count_format_types >= plane->format_count)) { 660 format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr; 661 if (copy_to_user(format_ptr, 662 plane->format_types, 663 sizeof(uint32_t) * plane->format_count)) { 664 return -EFAULT; 665 } 666 } 667 plane_resp->count_format_types = plane->format_count; 668 669 return 0; 670 } 671 672 int drm_plane_check_pixel_format(struct drm_plane *plane, 673 u32 format, u64 modifier) 674 { 675 unsigned int i; 676 677 for (i = 0; i < plane->format_count; i++) { 678 if (format == plane->format_types[i]) 679 break; 680 } 681 if (i == plane->format_count) 682 return -EINVAL; 683 684 if (plane->funcs->format_mod_supported) { 685 if (!plane->funcs->format_mod_supported(plane, format, modifier)) 686 return -EINVAL; 687 } else { 688 if (!plane->modifier_count) 689 return 0; 690 691 for (i = 0; i < plane->modifier_count; i++) { 692 if (modifier == plane->modifiers[i]) 693 break; 694 } 695 if (i == plane->modifier_count) 696 return -EINVAL; 697 } 698 699 return 0; 700 } 701 702 static int __setplane_check(struct drm_plane *plane, 703 struct drm_crtc *crtc, 704 struct drm_framebuffer *fb, 705 int32_t crtc_x, int32_t crtc_y, 706 uint32_t crtc_w, uint32_t crtc_h, 707 uint32_t src_x, uint32_t src_y, 708 uint32_t src_w, uint32_t src_h) 709 { 710 int ret; 711 712 /* Check whether this plane is usable on this CRTC */ 713 if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) { 714 DRM_DEBUG_KMS("Invalid crtc for plane\n"); 715 return -EINVAL; 716 } 717 718 /* Check whether this plane supports the fb pixel format. */ 719 ret = drm_plane_check_pixel_format(plane, fb->format->format, 720 fb->modifier); 721 if (ret) { 722 struct drm_format_name_buf format_name; 723 724 DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n", 725 drm_get_format_name(fb->format->format, 726 &format_name), 727 fb->modifier); 728 return ret; 729 } 730 731 /* Give drivers some help against integer overflows */ 732 if (crtc_w > INT_MAX || 733 crtc_x > INT_MAX - (int32_t) crtc_w || 734 crtc_h > INT_MAX || 735 crtc_y > INT_MAX - (int32_t) crtc_h) { 736 DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n", 737 crtc_w, crtc_h, crtc_x, crtc_y); 738 return -ERANGE; 739 } 740 741 ret = drm_framebuffer_check_src_coords(src_x, src_y, src_w, src_h, fb); 742 if (ret) 743 return ret; 744 745 return 0; 746 } 747 748 /** 749 * drm_any_plane_has_format - Check whether any plane supports this format and modifier combination 750 * @dev: DRM device 751 * @format: pixel format (DRM_FORMAT_*) 752 * @modifier: data layout modifier 753 * 754 * Returns: 755 * Whether at least one plane supports the specified format and modifier combination. 756 */ 757 bool drm_any_plane_has_format(struct drm_device *dev, 758 u32 format, u64 modifier) 759 { 760 struct drm_plane *plane; 761 762 drm_for_each_plane(plane, dev) { 763 if (drm_plane_check_pixel_format(plane, format, modifier) == 0) 764 return true; 765 } 766 767 return false; 768 } 769 EXPORT_SYMBOL(drm_any_plane_has_format); 770 771 /* 772 * __setplane_internal - setplane handler for internal callers 773 * 774 * This function will take a reference on the new fb for the plane 775 * on success. 776 * 777 * src_{x,y,w,h} are provided in 16.16 fixed point format 778 */ 779 static int __setplane_internal(struct drm_plane *plane, 780 struct drm_crtc *crtc, 781 struct drm_framebuffer *fb, 782 int32_t crtc_x, int32_t crtc_y, 783 uint32_t crtc_w, uint32_t crtc_h, 784 /* src_{x,y,w,h} values are 16.16 fixed point */ 785 uint32_t src_x, uint32_t src_y, 786 uint32_t src_w, uint32_t src_h, 787 struct drm_modeset_acquire_ctx *ctx) 788 { 789 int ret = 0; 790 791 WARN_ON(drm_drv_uses_atomic_modeset(plane->dev)); 792 793 /* No fb means shut it down */ 794 if (!fb) { 795 plane->old_fb = plane->fb; 796 ret = plane->funcs->disable_plane(plane, ctx); 797 if (!ret) { 798 plane->crtc = NULL; 799 plane->fb = NULL; 800 } else { 801 plane->old_fb = NULL; 802 } 803 goto out; 804 } 805 806 ret = __setplane_check(plane, crtc, fb, 807 crtc_x, crtc_y, crtc_w, crtc_h, 808 src_x, src_y, src_w, src_h); 809 if (ret) 810 goto out; 811 812 plane->old_fb = plane->fb; 813 ret = plane->funcs->update_plane(plane, crtc, fb, 814 crtc_x, crtc_y, crtc_w, crtc_h, 815 src_x, src_y, src_w, src_h, ctx); 816 if (!ret) { 817 plane->crtc = crtc; 818 plane->fb = fb; 819 drm_framebuffer_get(plane->fb); 820 } else { 821 plane->old_fb = NULL; 822 } 823 824 out: 825 if (plane->old_fb) 826 drm_framebuffer_put(plane->old_fb); 827 plane->old_fb = NULL; 828 829 return ret; 830 } 831 832 static int __setplane_atomic(struct drm_plane *plane, 833 struct drm_crtc *crtc, 834 struct drm_framebuffer *fb, 835 int32_t crtc_x, int32_t crtc_y, 836 uint32_t crtc_w, uint32_t crtc_h, 837 uint32_t src_x, uint32_t src_y, 838 uint32_t src_w, uint32_t src_h, 839 struct drm_modeset_acquire_ctx *ctx) 840 { 841 int ret; 842 843 WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev)); 844 845 /* No fb means shut it down */ 846 if (!fb) 847 return plane->funcs->disable_plane(plane, ctx); 848 849 /* 850 * FIXME: This is redundant with drm_atomic_plane_check(), 851 * but the legacy cursor/"async" .update_plane() tricks 852 * don't call that so we still need this here. Should remove 853 * this when all .update_plane() implementations have been 854 * fixed to call drm_atomic_plane_check(). 855 */ 856 ret = __setplane_check(plane, crtc, fb, 857 crtc_x, crtc_y, crtc_w, crtc_h, 858 src_x, src_y, src_w, src_h); 859 if (ret) 860 return ret; 861 862 return plane->funcs->update_plane(plane, crtc, fb, 863 crtc_x, crtc_y, crtc_w, crtc_h, 864 src_x, src_y, src_w, src_h, ctx); 865 } 866 867 static int setplane_internal(struct drm_plane *plane, 868 struct drm_crtc *crtc, 869 struct drm_framebuffer *fb, 870 int32_t crtc_x, int32_t crtc_y, 871 uint32_t crtc_w, uint32_t crtc_h, 872 /* src_{x,y,w,h} values are 16.16 fixed point */ 873 uint32_t src_x, uint32_t src_y, 874 uint32_t src_w, uint32_t src_h) 875 { 876 struct drm_modeset_acquire_ctx ctx; 877 int ret; 878 879 DRM_MODESET_LOCK_ALL_BEGIN(plane->dev, ctx, 880 DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret); 881 882 if (drm_drv_uses_atomic_modeset(plane->dev)) 883 ret = __setplane_atomic(plane, crtc, fb, 884 crtc_x, crtc_y, crtc_w, crtc_h, 885 src_x, src_y, src_w, src_h, &ctx); 886 else 887 ret = __setplane_internal(plane, crtc, fb, 888 crtc_x, crtc_y, crtc_w, crtc_h, 889 src_x, src_y, src_w, src_h, &ctx); 890 891 DRM_MODESET_LOCK_ALL_END(plane->dev, ctx, ret); 892 893 return ret; 894 } 895 896 int drm_mode_setplane(struct drm_device *dev, void *data, 897 struct drm_file *file_priv) 898 { 899 struct drm_mode_set_plane *plane_req = data; 900 struct drm_plane *plane; 901 struct drm_crtc *crtc = NULL; 902 struct drm_framebuffer *fb = NULL; 903 int ret; 904 905 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 906 return -EOPNOTSUPP; 907 908 /* 909 * First, find the plane, crtc, and fb objects. If not available, 910 * we don't bother to call the driver. 911 */ 912 plane = drm_plane_find(dev, file_priv, plane_req->plane_id); 913 if (!plane) { 914 DRM_DEBUG_KMS("Unknown plane ID %d\n", 915 plane_req->plane_id); 916 return -ENOENT; 917 } 918 919 if (plane_req->fb_id) { 920 fb = drm_framebuffer_lookup(dev, file_priv, plane_req->fb_id); 921 if (!fb) { 922 DRM_DEBUG_KMS("Unknown framebuffer ID %d\n", 923 plane_req->fb_id); 924 return -ENOENT; 925 } 926 927 crtc = drm_crtc_find(dev, file_priv, plane_req->crtc_id); 928 if (!crtc) { 929 drm_framebuffer_put(fb); 930 DRM_DEBUG_KMS("Unknown crtc ID %d\n", 931 plane_req->crtc_id); 932 return -ENOENT; 933 } 934 } 935 936 ret = setplane_internal(plane, crtc, fb, 937 plane_req->crtc_x, plane_req->crtc_y, 938 plane_req->crtc_w, plane_req->crtc_h, 939 plane_req->src_x, plane_req->src_y, 940 plane_req->src_w, plane_req->src_h); 941 942 if (fb) 943 drm_framebuffer_put(fb); 944 945 return ret; 946 } 947 948 static int drm_mode_cursor_universal(struct drm_crtc *crtc, 949 struct drm_mode_cursor2 *req, 950 struct drm_file *file_priv, 951 struct drm_modeset_acquire_ctx *ctx) 952 { 953 struct drm_device *dev = crtc->dev; 954 struct drm_plane *plane = crtc->cursor; 955 struct drm_framebuffer *fb = NULL; 956 struct drm_mode_fb_cmd2 fbreq = { 957 .width = req->width, 958 .height = req->height, 959 .pixel_format = DRM_FORMAT_ARGB8888, 960 .pitches = { req->width * 4 }, 961 .handles = { req->handle }, 962 }; 963 int32_t crtc_x, crtc_y; 964 uint32_t crtc_w = 0, crtc_h = 0; 965 uint32_t src_w = 0, src_h = 0; 966 int ret = 0; 967 968 BUG_ON(!plane); 969 WARN_ON(plane->crtc != crtc && plane->crtc != NULL); 970 971 /* 972 * Obtain fb we'll be using (either new or existing) and take an extra 973 * reference to it if fb != null. setplane will take care of dropping 974 * the reference if the plane update fails. 975 */ 976 if (req->flags & DRM_MODE_CURSOR_BO) { 977 if (req->handle) { 978 fb = drm_internal_framebuffer_create(dev, &fbreq, file_priv); 979 if (IS_ERR(fb)) { 980 DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n"); 981 return PTR_ERR(fb); 982 } 983 984 fb->hot_x = req->hot_x; 985 fb->hot_y = req->hot_y; 986 } else { 987 fb = NULL; 988 } 989 } else { 990 if (plane->state) 991 fb = plane->state->fb; 992 else 993 fb = plane->fb; 994 995 if (fb) 996 drm_framebuffer_get(fb); 997 } 998 999 if (req->flags & DRM_MODE_CURSOR_MOVE) { 1000 crtc_x = req->x; 1001 crtc_y = req->y; 1002 } else { 1003 crtc_x = crtc->cursor_x; 1004 crtc_y = crtc->cursor_y; 1005 } 1006 1007 if (fb) { 1008 crtc_w = fb->width; 1009 crtc_h = fb->height; 1010 src_w = fb->width << 16; 1011 src_h = fb->height << 16; 1012 } 1013 1014 if (drm_drv_uses_atomic_modeset(dev)) 1015 ret = __setplane_atomic(plane, crtc, fb, 1016 crtc_x, crtc_y, crtc_w, crtc_h, 1017 0, 0, src_w, src_h, ctx); 1018 else 1019 ret = __setplane_internal(plane, crtc, fb, 1020 crtc_x, crtc_y, crtc_w, crtc_h, 1021 0, 0, src_w, src_h, ctx); 1022 1023 if (fb) 1024 drm_framebuffer_put(fb); 1025 1026 /* Update successful; save new cursor position, if necessary */ 1027 if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) { 1028 crtc->cursor_x = req->x; 1029 crtc->cursor_y = req->y; 1030 } 1031 1032 return ret; 1033 } 1034 1035 static int drm_mode_cursor_common(struct drm_device *dev, 1036 struct drm_mode_cursor2 *req, 1037 struct drm_file *file_priv) 1038 { 1039 struct drm_crtc *crtc; 1040 struct drm_modeset_acquire_ctx ctx; 1041 int ret = 0; 1042 1043 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1044 return -EOPNOTSUPP; 1045 1046 if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) 1047 return -EINVAL; 1048 1049 crtc = drm_crtc_find(dev, file_priv, req->crtc_id); 1050 if (!crtc) { 1051 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id); 1052 return -ENOENT; 1053 } 1054 1055 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); 1056 retry: 1057 ret = drm_modeset_lock(&crtc->mutex, &ctx); 1058 if (ret) 1059 goto out; 1060 /* 1061 * If this crtc has a universal cursor plane, call that plane's update 1062 * handler rather than using legacy cursor handlers. 1063 */ 1064 if (crtc->cursor) { 1065 ret = drm_modeset_lock(&crtc->cursor->mutex, &ctx); 1066 if (ret) 1067 goto out; 1068 1069 if (!drm_lease_held(file_priv, crtc->cursor->base.id)) { 1070 ret = -EACCES; 1071 goto out; 1072 } 1073 1074 ret = drm_mode_cursor_universal(crtc, req, file_priv, &ctx); 1075 goto out; 1076 } 1077 1078 if (req->flags & DRM_MODE_CURSOR_BO) { 1079 if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) { 1080 ret = -ENXIO; 1081 goto out; 1082 } 1083 /* Turns off the cursor if handle is 0 */ 1084 if (crtc->funcs->cursor_set2) 1085 ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle, 1086 req->width, req->height, req->hot_x, req->hot_y); 1087 else 1088 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle, 1089 req->width, req->height); 1090 } 1091 1092 if (req->flags & DRM_MODE_CURSOR_MOVE) { 1093 if (crtc->funcs->cursor_move) { 1094 ret = crtc->funcs->cursor_move(crtc, req->x, req->y); 1095 } else { 1096 ret = -EFAULT; 1097 goto out; 1098 } 1099 } 1100 out: 1101 if (ret == -EDEADLK) { 1102 ret = drm_modeset_backoff(&ctx); 1103 if (!ret) 1104 goto retry; 1105 } 1106 1107 drm_modeset_drop_locks(&ctx); 1108 drm_modeset_acquire_fini(&ctx); 1109 1110 return ret; 1111 1112 } 1113 1114 1115 int drm_mode_cursor_ioctl(struct drm_device *dev, 1116 void *data, struct drm_file *file_priv) 1117 { 1118 struct drm_mode_cursor *req = data; 1119 struct drm_mode_cursor2 new_req; 1120 1121 memcpy(&new_req, req, sizeof(struct drm_mode_cursor)); 1122 new_req.hot_x = new_req.hot_y = 0; 1123 1124 return drm_mode_cursor_common(dev, &new_req, file_priv); 1125 } 1126 1127 /* 1128 * Set the cursor configuration based on user request. This implements the 2nd 1129 * version of the cursor ioctl, which allows userspace to additionally specify 1130 * the hotspot of the pointer. 1131 */ 1132 int drm_mode_cursor2_ioctl(struct drm_device *dev, 1133 void *data, struct drm_file *file_priv) 1134 { 1135 struct drm_mode_cursor2 *req = data; 1136 1137 return drm_mode_cursor_common(dev, req, file_priv); 1138 } 1139 1140 int drm_mode_page_flip_ioctl(struct drm_device *dev, 1141 void *data, struct drm_file *file_priv) 1142 { 1143 struct drm_mode_crtc_page_flip_target *page_flip = data; 1144 struct drm_crtc *crtc; 1145 struct drm_plane *plane; 1146 struct drm_framebuffer *fb = NULL, *old_fb; 1147 struct drm_pending_vblank_event *e = NULL; 1148 u32 target_vblank = page_flip->sequence; 1149 struct drm_modeset_acquire_ctx ctx; 1150 int ret = -EINVAL; 1151 1152 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1153 return -EOPNOTSUPP; 1154 1155 if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS) 1156 return -EINVAL; 1157 1158 if (page_flip->sequence != 0 && !(page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) 1159 return -EINVAL; 1160 1161 /* Only one of the DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags 1162 * can be specified 1163 */ 1164 if ((page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) == DRM_MODE_PAGE_FLIP_TARGET) 1165 return -EINVAL; 1166 1167 if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip) 1168 return -EINVAL; 1169 1170 crtc = drm_crtc_find(dev, file_priv, page_flip->crtc_id); 1171 if (!crtc) 1172 return -ENOENT; 1173 1174 plane = crtc->primary; 1175 1176 if (!drm_lease_held(file_priv, plane->base.id)) 1177 return -EACCES; 1178 1179 if (crtc->funcs->page_flip_target) { 1180 u32 current_vblank; 1181 int r; 1182 1183 r = drm_crtc_vblank_get(crtc); 1184 if (r) 1185 return r; 1186 1187 current_vblank = (u32)drm_crtc_vblank_count(crtc); 1188 1189 switch (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) { 1190 case DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE: 1191 if ((int)(target_vblank - current_vblank) > 1) { 1192 DRM_DEBUG("Invalid absolute flip target %u, " 1193 "must be <= %u\n", target_vblank, 1194 current_vblank + 1); 1195 drm_crtc_vblank_put(crtc); 1196 return -EINVAL; 1197 } 1198 break; 1199 case DRM_MODE_PAGE_FLIP_TARGET_RELATIVE: 1200 if (target_vblank != 0 && target_vblank != 1) { 1201 DRM_DEBUG("Invalid relative flip target %u, " 1202 "must be 0 or 1\n", target_vblank); 1203 drm_crtc_vblank_put(crtc); 1204 return -EINVAL; 1205 } 1206 target_vblank += current_vblank; 1207 break; 1208 default: 1209 target_vblank = current_vblank + 1210 !(page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC); 1211 break; 1212 } 1213 } else if (crtc->funcs->page_flip == NULL || 1214 (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) { 1215 return -EINVAL; 1216 } 1217 1218 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); 1219 retry: 1220 ret = drm_modeset_lock(&crtc->mutex, &ctx); 1221 if (ret) 1222 goto out; 1223 ret = drm_modeset_lock(&plane->mutex, &ctx); 1224 if (ret) 1225 goto out; 1226 1227 if (plane->state) 1228 old_fb = plane->state->fb; 1229 else 1230 old_fb = plane->fb; 1231 1232 if (old_fb == NULL) { 1233 /* The framebuffer is currently unbound, presumably 1234 * due to a hotplug event, that userspace has not 1235 * yet discovered. 1236 */ 1237 ret = -EBUSY; 1238 goto out; 1239 } 1240 1241 fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id); 1242 if (!fb) { 1243 ret = -ENOENT; 1244 goto out; 1245 } 1246 1247 if (plane->state) { 1248 const struct drm_plane_state *state = plane->state; 1249 1250 ret = drm_framebuffer_check_src_coords(state->src_x, 1251 state->src_y, 1252 state->src_w, 1253 state->src_h, 1254 fb); 1255 } else { 1256 ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, 1257 &crtc->mode, fb); 1258 } 1259 if (ret) 1260 goto out; 1261 1262 /* 1263 * Only check the FOURCC format code, excluding modifiers. This is 1264 * enough for all legacy drivers. Atomic drivers have their own 1265 * checks in their ->atomic_check implementation, which will 1266 * return -EINVAL if any hw or driver constraint is violated due 1267 * to modifier changes. 1268 */ 1269 if (old_fb->format->format != fb->format->format) { 1270 DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); 1271 ret = -EINVAL; 1272 goto out; 1273 } 1274 1275 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { 1276 e = kzalloc(sizeof *e, GFP_KERNEL); 1277 if (!e) { 1278 ret = -ENOMEM; 1279 goto out; 1280 } 1281 1282 e->event.base.type = DRM_EVENT_FLIP_COMPLETE; 1283 e->event.base.length = sizeof(e->event); 1284 e->event.vbl.user_data = page_flip->user_data; 1285 e->event.vbl.crtc_id = crtc->base.id; 1286 1287 ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); 1288 if (ret) { 1289 kfree(e); 1290 e = NULL; 1291 goto out; 1292 } 1293 } 1294 1295 plane->old_fb = plane->fb; 1296 if (crtc->funcs->page_flip_target) 1297 ret = crtc->funcs->page_flip_target(crtc, fb, e, 1298 page_flip->flags, 1299 target_vblank, 1300 &ctx); 1301 else 1302 ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags, 1303 &ctx); 1304 if (ret) { 1305 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) 1306 drm_event_cancel_free(dev, &e->base); 1307 /* Keep the old fb, don't unref it. */ 1308 plane->old_fb = NULL; 1309 } else { 1310 if (!plane->state) { 1311 plane->fb = fb; 1312 drm_framebuffer_get(fb); 1313 } 1314 } 1315 1316 out: 1317 if (fb) 1318 drm_framebuffer_put(fb); 1319 if (plane->old_fb) 1320 drm_framebuffer_put(plane->old_fb); 1321 plane->old_fb = NULL; 1322 1323 if (ret == -EDEADLK) { 1324 ret = drm_modeset_backoff(&ctx); 1325 if (!ret) 1326 goto retry; 1327 } 1328 1329 drm_modeset_drop_locks(&ctx); 1330 drm_modeset_acquire_fini(&ctx); 1331 1332 if (ret && crtc->funcs->page_flip_target) 1333 drm_crtc_vblank_put(crtc); 1334 1335 return ret; 1336 } 1337 1338 struct drm_property * 1339 drm_create_scaling_filter_prop(struct drm_device *dev, 1340 unsigned int supported_filters) 1341 { 1342 struct drm_property *prop; 1343 static const struct drm_prop_enum_list props[] = { 1344 { DRM_SCALING_FILTER_DEFAULT, "Default" }, 1345 { DRM_SCALING_FILTER_NEAREST_NEIGHBOR, "Nearest Neighbor" }, 1346 }; 1347 unsigned int valid_mode_mask = BIT(DRM_SCALING_FILTER_DEFAULT) | 1348 BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR); 1349 int i; 1350 1351 if (WARN_ON((supported_filters & ~valid_mode_mask) || 1352 ((supported_filters & BIT(DRM_SCALING_FILTER_DEFAULT)) == 0))) 1353 return ERR_PTR(-EINVAL); 1354 1355 prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, 1356 "SCALING_FILTER", 1357 hweight32(supported_filters)); 1358 if (!prop) 1359 return ERR_PTR(-ENOMEM); 1360 1361 for (i = 0; i < ARRAY_SIZE(props); i++) { 1362 int ret; 1363 1364 if (!(BIT(props[i].type) & supported_filters)) 1365 continue; 1366 1367 ret = drm_property_add_enum(prop, props[i].type, 1368 props[i].name); 1369 1370 if (ret) { 1371 drm_property_destroy(dev, prop); 1372 1373 return ERR_PTR(ret); 1374 } 1375 } 1376 1377 return prop; 1378 } 1379 1380 /** 1381 * drm_plane_create_scaling_filter_property - create a new scaling filter 1382 * property 1383 * 1384 * @plane: drm plane 1385 * @supported_filters: bitmask of supported scaling filters, must include 1386 * BIT(DRM_SCALING_FILTER_DEFAULT). 1387 * 1388 * This function lets driver to enable the scaling filter property on a given 1389 * plane. 1390 * 1391 * RETURNS: 1392 * Zero for success or -errno 1393 */ 1394 int drm_plane_create_scaling_filter_property(struct drm_plane *plane, 1395 unsigned int supported_filters) 1396 { 1397 struct drm_property *prop = 1398 drm_create_scaling_filter_prop(plane->dev, supported_filters); 1399 1400 if (IS_ERR(prop)) 1401 return PTR_ERR(prop); 1402 1403 drm_object_attach_property(&plane->base, prop, 1404 DRM_SCALING_FILTER_DEFAULT); 1405 plane->scaling_filter_property = prop; 1406 1407 return 0; 1408 } 1409 EXPORT_SYMBOL(drm_plane_create_scaling_filter_property); 1410