Lines Matching full:plane
41 * A plane represents an image source that can be blended with or overlaid on
43 * &drm_framebuffer object. The plane itself specifies the cropping and scaling
45 * pipeline, represented by &drm_crtc. A plane can also have additional
49 * To create a plane, a KMS drivers allocates and zeroes an instances of
53 * Each plane has a type, see enum drm_plane_type. A plane can be compatible
56 * Each CRTC must have a unique primary plane userspace can attach to enable
58 * primary plane to each CRTC at the same time. Primary planes can still be
63 * relies on the driver to set the primary and optionally the cursor plane used
65 * drivers must provide one primary plane per CRTC to avoid surprising legacy
70 * DOC: standard plane properties
75 * Immutable property describing the type of the plane.
78 * the plane type is just a hint and is mostly superseded by atomic
80 * easily with a plane configuration accepted by the driver.
85 * To light up a CRTC, attaching a primary plane is the most likely to
89 * Drivers may support more features for the primary plane, user-space
95 * plane (e.g. through an atomic commit) with these legacy IOCTLs.
98 * To enable this plane, using a framebuffer configured without scaling
106 * a linear layout. Otherwise, use the IN_FORMATS plane property.
108 * Drivers may support more features for the cursor plane, user-space
114 * plane (e.g. through an atomic commit) with these legacy IOCTLs.
116 * Some drivers may support cursors even if no cursor plane is exposed.
128 * pairs supported by this plane. The blob is a struct
129 * drm_format_modifier_blob. Without this property the plane doesn't
134 * plane will have the IN_FORMATS property, even when it only supports
137 * flag and per-plane properties.
164 static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane) in create_in_format_blob() argument
173 formats_size = sizeof(__u32) * plane->format_count; in create_in_format_blob()
180 sizeof(struct drm_format_modifier) * plane->modifier_count; in create_in_format_blob()
196 blob_data->count_formats = plane->format_count; in create_in_format_blob()
198 blob_data->count_modifiers = plane->modifier_count; in create_in_format_blob()
203 memcpy(formats_ptr(blob_data), plane->format_types, formats_size); in create_in_format_blob()
206 if (!plane->funcs->format_mod_supported) in create_in_format_blob()
210 for (i = 0; i < plane->modifier_count; i++) { in create_in_format_blob()
211 for (j = 0; j < plane->format_count; j++) { in create_in_format_blob()
212 if (plane->funcs->format_mod_supported(plane, in create_in_format_blob()
213 plane->format_types[j], in create_in_format_blob()
214 plane->modifiers[i])) { in create_in_format_blob()
220 mod->modifier = plane->modifiers[i]; in create_in_format_blob()
227 drm_object_attach_property(&plane->base, config->modifiers_property, in create_in_format_blob()
235 struct drm_plane *plane, in __drm_universal_plane_init() argument
248 /* plane index is used with 32bit bitmasks */ in __drm_universal_plane_init()
256 ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE); in __drm_universal_plane_init()
260 drm_modeset_lock_init(&plane->mutex); in __drm_universal_plane_init()
262 plane->base.properties = &plane->properties; in __drm_universal_plane_init()
263 plane->dev = dev; in __drm_universal_plane_init()
264 plane->funcs = funcs; in __drm_universal_plane_init()
265 plane->format_types = kmalloc_array(format_count, sizeof(uint32_t), in __drm_universal_plane_init()
267 if (!plane->format_types) { in __drm_universal_plane_init()
268 DRM_DEBUG_KMS("out of memory when allocating plane\n"); in __drm_universal_plane_init()
269 drm_mode_object_unregister(dev, &plane->base); in __drm_universal_plane_init()
296 plane->modifier_count = format_modifier_count; in __drm_universal_plane_init()
297 plane->modifiers = kmalloc_array(format_modifier_count, in __drm_universal_plane_init()
301 if (format_modifier_count && !plane->modifiers) { in __drm_universal_plane_init()
302 DRM_DEBUG_KMS("out of memory when allocating plane\n"); in __drm_universal_plane_init()
303 kfree(plane->format_types); in __drm_universal_plane_init()
304 drm_mode_object_unregister(dev, &plane->base); in __drm_universal_plane_init()
309 plane->name = kvasprintf(GFP_KERNEL, name, ap); in __drm_universal_plane_init()
311 plane->name = kasprintf(GFP_KERNEL, "plane-%d", in __drm_universal_plane_init()
314 if (!plane->name) { in __drm_universal_plane_init()
315 kfree(plane->format_types); in __drm_universal_plane_init()
316 kfree(plane->modifiers); in __drm_universal_plane_init()
317 drm_mode_object_unregister(dev, &plane->base); in __drm_universal_plane_init()
321 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); in __drm_universal_plane_init()
322 plane->format_count = format_count; in __drm_universal_plane_init()
323 memcpy(plane->modifiers, format_modifiers, in __drm_universal_plane_init()
325 plane->possible_crtcs = possible_crtcs; in __drm_universal_plane_init()
326 plane->type = type; in __drm_universal_plane_init()
328 list_add_tail(&plane->head, &config->plane_list); in __drm_universal_plane_init()
329 plane->index = config->num_total_plane++; in __drm_universal_plane_init()
331 drm_object_attach_property(&plane->base, in __drm_universal_plane_init()
333 plane->type); in __drm_universal_plane_init()
336 drm_object_attach_property(&plane->base, config->prop_fb_id, 0); in __drm_universal_plane_init()
337 drm_object_attach_property(&plane->base, config->prop_in_fence_fd, -1); in __drm_universal_plane_init()
338 drm_object_attach_property(&plane->base, config->prop_crtc_id, 0); in __drm_universal_plane_init()
339 drm_object_attach_property(&plane->base, config->prop_crtc_x, 0); in __drm_universal_plane_init()
340 drm_object_attach_property(&plane->base, config->prop_crtc_y, 0); in __drm_universal_plane_init()
341 drm_object_attach_property(&plane->base, config->prop_crtc_w, 0); in __drm_universal_plane_init()
342 drm_object_attach_property(&plane->base, config->prop_crtc_h, 0); in __drm_universal_plane_init()
343 drm_object_attach_property(&plane->base, config->prop_src_x, 0); in __drm_universal_plane_init()
344 drm_object_attach_property(&plane->base, config->prop_src_y, 0); in __drm_universal_plane_init()
345 drm_object_attach_property(&plane->base, config->prop_src_w, 0); in __drm_universal_plane_init()
346 drm_object_attach_property(&plane->base, config->prop_src_h, 0); in __drm_universal_plane_init()
350 create_in_format_blob(dev, plane); in __drm_universal_plane_init()
356 * drm_universal_plane_init - Initialize a new universal plane object
358 * @plane: plane object to init
360 * @funcs: callbacks for the new plane
365 * @type: type of plane (overlay, primary, cursor)
366 * @name: printf style format string for the plane name, or NULL for default name
368 * Initializes a plane object of type @type. The &drm_plane_funcs.destroy hook
369 * should call drm_plane_cleanup() and kfree() the plane structure. The plane
382 int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, in drm_universal_plane_init() argument
396 ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs, in drm_universal_plane_init()
406 struct drm_plane *plane = ptr; in drmm_universal_plane_alloc_release() local
408 if (WARN_ON(!plane->dev)) in drmm_universal_plane_alloc_release()
411 drm_plane_cleanup(plane); in drmm_universal_plane_alloc_release()
423 struct drm_plane *plane; in __drmm_universal_plane_alloc() local
434 plane = container + offset; in __drmm_universal_plane_alloc()
437 ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs, in __drmm_universal_plane_alloc()
445 plane); in __drmm_universal_plane_alloc()
457 struct drm_plane *plane; in drm_plane_register_all() local
460 drm_for_each_plane(plane, dev) { in drm_plane_register_all()
461 if (plane->funcs->late_register) in drm_plane_register_all()
462 ret = plane->funcs->late_register(plane); in drm_plane_register_all()
466 if (plane->zpos_property) in drm_plane_register_all()
479 struct drm_plane *plane; in drm_plane_unregister_all() local
481 drm_for_each_plane(plane, dev) { in drm_plane_unregister_all()
482 if (plane->funcs->early_unregister) in drm_plane_unregister_all()
483 plane->funcs->early_unregister(plane); in drm_plane_unregister_all()
488 * drm_plane_init - Initialize a legacy plane
490 * @plane: plane object to init
492 * @funcs: callbacks for the new plane
495 * @is_primary: plane type (primary vs overlay)
497 * Legacy API to initialize a DRM plane.
504 int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, in drm_plane_init() argument
513 return drm_universal_plane_init(dev, plane, possible_crtcs, funcs, in drm_plane_init()
520 * drm_plane_cleanup - Clean up the core plane usage
521 * @plane: plane to cleanup
523 * This function cleans up @plane and removes it from the DRM mode setting
524 * core. Note that the function does *not* free the plane structure itself,
527 void drm_plane_cleanup(struct drm_plane *plane) in drm_plane_cleanup() argument
529 struct drm_device *dev = plane->dev; in drm_plane_cleanup()
531 drm_modeset_lock_fini(&plane->mutex); in drm_plane_cleanup()
533 kfree(plane->format_types); in drm_plane_cleanup()
534 kfree(plane->modifiers); in drm_plane_cleanup()
535 drm_mode_object_unregister(dev, &plane->base); in drm_plane_cleanup()
537 BUG_ON(list_empty(&plane->head)); in drm_plane_cleanup()
544 list_del(&plane->head); in drm_plane_cleanup()
547 WARN_ON(plane->state && !plane->funcs->atomic_destroy_state); in drm_plane_cleanup()
548 if (plane->state && plane->funcs->atomic_destroy_state) in drm_plane_cleanup()
549 plane->funcs->atomic_destroy_state(plane, plane->state); in drm_plane_cleanup()
551 kfree(plane->name); in drm_plane_cleanup()
553 memset(plane, 0, sizeof(*plane)); in drm_plane_cleanup()
558 * drm_plane_from_index - find the registered plane at an index
560 * @idx: index of registered plane to find for
562 * Given a plane index, return the registered plane from DRM device's
568 struct drm_plane *plane; in drm_plane_from_index() local
570 drm_for_each_plane(plane, dev) in drm_plane_from_index()
571 if (idx == plane->index) in drm_plane_from_index()
572 return plane; in drm_plane_from_index()
579 * drm_plane_force_disable - Forcibly disable a plane
580 * @plane: plane to disable
582 * Forces the plane to be disabled.
584 * Used when the plane's current framebuffer is destroyed,
593 void drm_plane_force_disable(struct drm_plane *plane) in drm_plane_force_disable() argument
597 if (!plane->fb) in drm_plane_force_disable()
600 WARN_ON(drm_drv_uses_atomic_modeset(plane->dev)); in drm_plane_force_disable()
602 plane->old_fb = plane->fb; in drm_plane_force_disable()
603 ret = plane->funcs->disable_plane(plane, NULL); in drm_plane_force_disable()
605 DRM_ERROR("failed to disable plane with busy fb\n"); in drm_plane_force_disable()
606 plane->old_fb = NULL; in drm_plane_force_disable()
609 /* disconnect the plane from the fb and crtc: */ in drm_plane_force_disable()
610 drm_framebuffer_put(plane->old_fb); in drm_plane_force_disable()
611 plane->old_fb = NULL; in drm_plane_force_disable()
612 plane->fb = NULL; in drm_plane_force_disable()
613 plane->crtc = NULL; in drm_plane_force_disable()
619 * @plane: drm plane object to set property value for
623 * This functions sets a given property on a given plane object. This function
630 int drm_mode_plane_set_obj_prop(struct drm_plane *plane, in drm_mode_plane_set_obj_prop() argument
635 struct drm_mode_object *obj = &plane->base; in drm_mode_plane_set_obj_prop()
637 if (plane->funcs->set_property) in drm_mode_plane_set_obj_prop()
638 ret = plane->funcs->set_property(plane, property, value); in drm_mode_plane_set_obj_prop()
650 struct drm_plane *plane; in drm_mode_getplane_res() local
663 drm_for_each_plane(plane, dev) { in drm_mode_getplane_res()
668 if (plane->type != DRM_PLANE_TYPE_OVERLAY && in drm_mode_getplane_res()
672 if (drm_lease_held(file_priv, plane->base.id)) { in drm_mode_getplane_res()
674 put_user(plane->base.id, plane_ptr + count)) in drm_mode_getplane_res()
688 struct drm_plane *plane; in drm_mode_getplane() local
694 plane = drm_plane_find(dev, file_priv, plane_resp->plane_id); in drm_mode_getplane()
695 if (!plane) in drm_mode_getplane()
698 drm_modeset_lock(&plane->mutex, NULL); in drm_mode_getplane()
699 if (plane->state && plane->state->crtc && drm_lease_held(file_priv, plane->state->crtc->base.id)) in drm_mode_getplane()
700 plane_resp->crtc_id = plane->state->crtc->base.id; in drm_mode_getplane()
701 else if (!plane->state && plane->crtc && drm_lease_held(file_priv, plane->crtc->base.id)) in drm_mode_getplane()
702 plane_resp->crtc_id = plane->crtc->base.id; in drm_mode_getplane()
706 if (plane->state && plane->state->fb) in drm_mode_getplane()
707 plane_resp->fb_id = plane->state->fb->base.id; in drm_mode_getplane()
708 else if (!plane->state && plane->fb) in drm_mode_getplane()
709 plane_resp->fb_id = plane->fb->base.id; in drm_mode_getplane()
712 drm_modeset_unlock(&plane->mutex); in drm_mode_getplane()
714 plane_resp->plane_id = plane->base.id; in drm_mode_getplane()
716 plane->possible_crtcs); in drm_mode_getplane()
724 if (plane->format_count && in drm_mode_getplane()
725 (plane_resp->count_format_types >= plane->format_count)) { in drm_mode_getplane()
728 plane->format_types, in drm_mode_getplane()
729 sizeof(uint32_t) * plane->format_count)) { in drm_mode_getplane()
733 plane_resp->count_format_types = plane->format_count; in drm_mode_getplane()
738 int drm_plane_check_pixel_format(struct drm_plane *plane, in drm_plane_check_pixel_format() argument
743 for (i = 0; i < plane->format_count; i++) { in drm_plane_check_pixel_format()
744 if (format == plane->format_types[i]) in drm_plane_check_pixel_format()
747 if (i == plane->format_count) in drm_plane_check_pixel_format()
750 if (plane->funcs->format_mod_supported) { in drm_plane_check_pixel_format()
751 if (!plane->funcs->format_mod_supported(plane, format, modifier)) in drm_plane_check_pixel_format()
754 if (!plane->modifier_count) in drm_plane_check_pixel_format()
757 for (i = 0; i < plane->modifier_count; i++) { in drm_plane_check_pixel_format()
758 if (modifier == plane->modifiers[i]) in drm_plane_check_pixel_format()
761 if (i == plane->modifier_count) in drm_plane_check_pixel_format()
768 static int __setplane_check(struct drm_plane *plane, in __setplane_check() argument
778 /* Check whether this plane is usable on this CRTC */ in __setplane_check()
779 if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) { in __setplane_check()
780 DRM_DEBUG_KMS("Invalid crtc for plane\n"); in __setplane_check()
784 /* Check whether this plane supports the fb pixel format. */ in __setplane_check()
785 ret = drm_plane_check_pixel_format(plane, fb->format->format, in __setplane_check()
811 * drm_any_plane_has_format - Check whether any plane supports this format and modifier combination
817 * Whether at least one plane supports the specified format and modifier combination.
822 struct drm_plane *plane; in drm_any_plane_has_format() local
824 drm_for_each_plane(plane, dev) { in drm_any_plane_has_format()
825 if (drm_plane_check_pixel_format(plane, format, modifier) == 0) in drm_any_plane_has_format()
836 * This function will take a reference on the new fb for the plane
841 static int __setplane_internal(struct drm_plane *plane, in __setplane_internal() argument
853 WARN_ON(drm_drv_uses_atomic_modeset(plane->dev)); in __setplane_internal()
857 plane->old_fb = plane->fb; in __setplane_internal()
858 ret = plane->funcs->disable_plane(plane, ctx); in __setplane_internal()
860 plane->crtc = NULL; in __setplane_internal()
861 plane->fb = NULL; in __setplane_internal()
863 plane->old_fb = NULL; in __setplane_internal()
868 ret = __setplane_check(plane, crtc, fb, in __setplane_internal()
874 plane->old_fb = plane->fb; in __setplane_internal()
875 ret = plane->funcs->update_plane(plane, crtc, fb, in __setplane_internal()
879 plane->crtc = crtc; in __setplane_internal()
880 plane->fb = fb; in __setplane_internal()
881 drm_framebuffer_get(plane->fb); in __setplane_internal()
883 plane->old_fb = NULL; in __setplane_internal()
887 if (plane->old_fb) in __setplane_internal()
888 drm_framebuffer_put(plane->old_fb); in __setplane_internal()
889 plane->old_fb = NULL; in __setplane_internal()
894 static int __setplane_atomic(struct drm_plane *plane, in __setplane_atomic() argument
905 WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev)); in __setplane_atomic()
909 return plane->funcs->disable_plane(plane, ctx); in __setplane_atomic()
918 ret = __setplane_check(plane, crtc, fb, in __setplane_atomic()
924 return plane->funcs->update_plane(plane, crtc, fb, in __setplane_atomic()
929 static int setplane_internal(struct drm_plane *plane, in setplane_internal() argument
941 DRM_MODESET_LOCK_ALL_BEGIN(plane->dev, ctx, in setplane_internal()
944 if (drm_drv_uses_atomic_modeset(plane->dev)) in setplane_internal()
945 ret = __setplane_atomic(plane, crtc, fb, in setplane_internal()
949 ret = __setplane_internal(plane, crtc, fb, in setplane_internal()
953 DRM_MODESET_LOCK_ALL_END(plane->dev, ctx, ret); in setplane_internal()
962 struct drm_plane *plane; in drm_mode_setplane() local
971 * First, find the plane, crtc, and fb objects. If not available, in drm_mode_setplane()
974 plane = drm_plane_find(dev, file_priv, plane_req->plane_id); in drm_mode_setplane()
975 if (!plane) { in drm_mode_setplane()
976 DRM_DEBUG_KMS("Unknown plane ID %d\n", in drm_mode_setplane()
998 ret = setplane_internal(plane, crtc, fb, in drm_mode_setplane()
1016 struct drm_plane *plane = crtc->cursor; in drm_mode_cursor_universal() local
1030 BUG_ON(!plane); in drm_mode_cursor_universal()
1031 WARN_ON(plane->crtc != crtc && plane->crtc != NULL); in drm_mode_cursor_universal()
1036 * the reference if the plane update fails. in drm_mode_cursor_universal()
1052 if (plane->state) in drm_mode_cursor_universal()
1053 fb = plane->state->fb; in drm_mode_cursor_universal()
1055 fb = plane->fb; in drm_mode_cursor_universal()
1077 ret = __setplane_atomic(plane, crtc, fb, in drm_mode_cursor_universal()
1081 ret = __setplane_internal(plane, crtc, fb, in drm_mode_cursor_universal()
1123 * If this crtc has a universal cursor plane, call that plane's update in drm_mode_cursor_common()
1207 struct drm_plane *plane; in drm_mode_page_flip_ioctl() local
1236 plane = crtc->primary; in drm_mode_page_flip_ioctl()
1238 if (!drm_lease_held(file_priv, plane->base.id)) in drm_mode_page_flip_ioctl()
1285 ret = drm_modeset_lock(&plane->mutex, &ctx); in drm_mode_page_flip_ioctl()
1289 if (plane->state) in drm_mode_page_flip_ioctl()
1290 old_fb = plane->state->fb; in drm_mode_page_flip_ioctl()
1292 old_fb = plane->fb; in drm_mode_page_flip_ioctl()
1309 if (plane->state) { in drm_mode_page_flip_ioctl()
1310 const struct drm_plane_state *state = plane->state; in drm_mode_page_flip_ioctl()
1357 plane->old_fb = plane->fb; in drm_mode_page_flip_ioctl()
1370 plane->old_fb = NULL; in drm_mode_page_flip_ioctl()
1372 if (!plane->state) { in drm_mode_page_flip_ioctl()
1373 plane->fb = fb; in drm_mode_page_flip_ioctl()
1381 if (plane->old_fb) in drm_mode_page_flip_ioctl()
1382 drm_framebuffer_put(plane->old_fb); in drm_mode_page_flip_ioctl()
1383 plane->old_fb = NULL; in drm_mode_page_flip_ioctl()
1403 * FB_DAMAGE_CLIPS is an optional plane property which provides a means to
1404 * specify a list of damage rectangles on a plane in framebuffer coordinates of
1405 * the framebuffer attached to the plane. In current context damage is the area
1406 * of plane framebuffer that has changed since last plane update (also called
1408 * framebuffer attached during last plane update or not.
1415 * ignore damage clips property and in that case driver will do a full plane
1417 * inside damage clips will be updated to plane. For efficiency driver can do
1422 * framebuffer (since last plane update) can result in incorrect rendering.
1425 * array of &drm_mode_rect. Unlike plane &drm_plane_state.src coordinates,
1426 * damage clips are not in 16.16 fixed point. Similar to plane src in
1431 * Drivers that are interested in damage interface for plane should enable
1439 * drm_plane_enable_fb_damage_clips - Enables plane fb damage clips property.
1440 * @plane: Plane on which to enable damage clips property.
1442 * This function lets driver to enable the damage clips property on a plane.
1444 void drm_plane_enable_fb_damage_clips(struct drm_plane *plane) in drm_plane_enable_fb_damage_clips() argument
1446 struct drm_device *dev = plane->dev; in drm_plane_enable_fb_damage_clips()
1449 drm_object_attach_property(&plane->base, config->prop_fb_damage_clips, in drm_plane_enable_fb_damage_clips()
1456 * @state: Plane state.
1459 * during plane update.
1461 * Return: Number of clips in plane fb_damage_clips blob property.
1480 * @state: Plane state.
1487 * Return: Damage clips in plane fb_damage_clips blob property.
1492 struct drm_device *dev = state->plane->dev; in drm_plane_get_damage_clips()
1496 if (!drm_mode_obj_find_prop_id(&state->plane->base, in drm_plane_get_damage_clips()
1550 * @plane: drm plane
1555 * plane.
1560 int drm_plane_create_scaling_filter_property(struct drm_plane *plane, in drm_plane_create_scaling_filter_property() argument
1564 drm_create_scaling_filter_prop(plane->dev, supported_filters); in drm_plane_create_scaling_filter_property()
1569 drm_object_attach_property(&plane->base, prop, in drm_plane_create_scaling_filter_property()
1571 plane->scaling_filter_property = prop; in drm_plane_create_scaling_filter_property()