Lines Matching +full:display +full:- +full:hint

44  * of that image, and where it is placed on the visible area of a display
47 * rotation or Z-position. All these properties are stored in &drm_plane_state.
82 * For user-space which has enabled the &DRM_CLIENT_CAP_ATOMIC capability,
83 * the plane type is just a hint and is mostly superseded by atomic
84 * test-only commits. The type hint can still be used to come up more
94 * Drivers may support more features for the primary plane, user-space
95 * can find out with test-only atomic commits.
99 * Therefore user-space must not mix explicit usage of any primary
107 * - If the driver provides the capabilities &DRM_CAP_CURSOR_WIDTH and
110 * - If the driver doesn't support modifiers, create a framebuffer with
113 * Drivers may support more features for the cursor plane, user-space
114 * can find out with test-only atomic commits.
118 * Therefore user-space must not mix explicit usage of any cursor
142 * flag and per-plane properties.
179 return (u32 *)(((char *)blob) + blob->formats_offset); in formats_ptr()
185 return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset); in modifiers_ptr()
190 const struct drm_mode_config *config = &dev->mode_config; in create_in_format_blob()
197 formats_size = sizeof(__u32) * plane->format_count; in create_in_format_blob()
204 sizeof(struct drm_format_modifier) * plane->modifier_count; in create_in_format_blob()
216 return -1; in create_in_format_blob()
218 blob_data = blob->data; in create_in_format_blob()
219 blob_data->version = FORMAT_BLOB_CURRENT; in create_in_format_blob()
220 blob_data->count_formats = plane->format_count; in create_in_format_blob()
221 blob_data->formats_offset = sizeof(struct drm_format_modifier_blob); in create_in_format_blob()
222 blob_data->count_modifiers = plane->modifier_count; in create_in_format_blob()
224 blob_data->modifiers_offset = in create_in_format_blob()
225 ALIGN(blob_data->formats_offset + formats_size, 8); in create_in_format_blob()
227 memcpy(formats_ptr(blob_data), plane->format_types, formats_size); in create_in_format_blob()
230 for (i = 0; i < plane->modifier_count; i++) { in create_in_format_blob()
231 for (j = 0; j < plane->format_count; j++) { in create_in_format_blob()
232 if (!plane->funcs->format_mod_supported || in create_in_format_blob()
233 plane->funcs->format_mod_supported(plane, in create_in_format_blob()
234 plane->format_types[j], in create_in_format_blob()
235 plane->modifiers[i])) { in create_in_format_blob()
236 mod->formats |= 1ULL << j; in create_in_format_blob()
240 mod->modifier = plane->modifiers[i]; in create_in_format_blob()
241 mod->offset = 0; in create_in_format_blob()
242 mod->pad = 0; in create_in_format_blob()
246 drm_object_attach_property(&plane->base, config->modifiers_property, in create_in_format_blob()
247 blob->base.id); in create_in_format_blob()
258 * When the plane is being used as a cursor image to display a mouse pointer,
262 * Positive values move the hotspot from the top-left corner of the cursor
265 * Most display drivers do not need this information because the
267 * However, this is necessary for display drivers like the para-virtualized
270 * network, they would otherwise have to wait to display the pointer movement to
271 * the user until a full network round-trip has occurred. New mouse events have
280 * space. This is typically sent to the para-virtualized drivers using some
281 * driver-specific method, and the driver then forwards it to the console by
282 * way of the virtual display device or hypervisor.
286 * into the same global pointer. Para-virtualized drivers that require this
295 * console, or as a free-floating cursor plane on the user's console
308 * drm_plane_create_hotspot_properties - creates the mouse hotspot
318 * Zero for success or -errno
325 drm_WARN_ON(plane->dev, in drm_plane_create_hotspot_properties()
326 !drm_core_check_feature(plane->dev, in drm_plane_create_hotspot_properties()
329 prop_x = drm_property_create_signed_range(plane->dev, 0, "HOTSPOT_X", in drm_plane_create_hotspot_properties()
334 prop_y = drm_property_create_signed_range(plane->dev, 0, "HOTSPOT_Y", in drm_plane_create_hotspot_properties()
337 drm_property_destroy(plane->dev, prop_x); in drm_plane_create_hotspot_properties()
341 drm_object_attach_property(&plane->base, prop_x, 0); in drm_plane_create_hotspot_properties()
342 drm_object_attach_property(&plane->base, prop_y, 0); in drm_plane_create_hotspot_properties()
343 plane->hotspot_x_property = prop_x; in drm_plane_create_hotspot_properties()
344 plane->hotspot_y_property = prop_y; in drm_plane_create_hotspot_properties()
360 struct drm_mode_config *config = &dev->mode_config; in __drm_universal_plane_init()
368 if (WARN_ON(config->num_total_plane >= 32)) in __drm_universal_plane_init()
369 return -EINVAL; in __drm_universal_plane_init()
376 return -EINVAL; in __drm_universal_plane_init()
379 (!funcs->atomic_destroy_state || in __drm_universal_plane_init()
380 !funcs->atomic_duplicate_state)); in __drm_universal_plane_init()
382 ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE); in __drm_universal_plane_init()
386 drm_modeset_lock_init(&plane->mutex); in __drm_universal_plane_init()
388 plane->base.properties = &plane->properties; in __drm_universal_plane_init()
389 plane->dev = dev; in __drm_universal_plane_init()
390 plane->funcs = funcs; in __drm_universal_plane_init()
391 plane->format_types = kmalloc_array(format_count, sizeof(uint32_t), in __drm_universal_plane_init()
393 if (!plane->format_types) { in __drm_universal_plane_init()
395 drm_mode_object_unregister(dev, &plane->base); in __drm_universal_plane_init()
396 return -ENOMEM; in __drm_universal_plane_init()
405 if (!dev->mode_config.fb_modifiers_not_supported) { in __drm_universal_plane_init()
412 drm_WARN_ON(dev, config->fb_modifiers_not_supported && in __drm_universal_plane_init()
415 plane->modifier_count = format_modifier_count; in __drm_universal_plane_init()
416 plane->modifiers = kmalloc_array(format_modifier_count, in __drm_universal_plane_init()
420 if (format_modifier_count && !plane->modifiers) { in __drm_universal_plane_init()
422 kfree(plane->format_types); in __drm_universal_plane_init()
423 drm_mode_object_unregister(dev, &plane->base); in __drm_universal_plane_init()
424 return -ENOMEM; in __drm_universal_plane_init()
428 plane->name = kvasprintf(GFP_KERNEL, name, ap); in __drm_universal_plane_init()
430 plane->name = kasprintf(GFP_KERNEL, "plane-%d", in __drm_universal_plane_init()
433 if (!plane->name) { in __drm_universal_plane_init()
434 kfree(plane->format_types); in __drm_universal_plane_init()
435 kfree(plane->modifiers); in __drm_universal_plane_init()
436 drm_mode_object_unregister(dev, &plane->base); in __drm_universal_plane_init()
437 return -ENOMEM; in __drm_universal_plane_init()
440 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); in __drm_universal_plane_init()
441 plane->format_count = format_count; in __drm_universal_plane_init()
442 memcpy(plane->modifiers, format_modifiers, in __drm_universal_plane_init()
444 plane->possible_crtcs = possible_crtcs; in __drm_universal_plane_init()
445 plane->type = type; in __drm_universal_plane_init()
447 list_add_tail(&plane->head, &config->plane_list); in __drm_universal_plane_init()
448 plane->index = config->num_total_plane++; in __drm_universal_plane_init()
450 drm_object_attach_property(&plane->base, in __drm_universal_plane_init()
451 config->plane_type_property, in __drm_universal_plane_init()
452 plane->type); in __drm_universal_plane_init()
455 drm_object_attach_property(&plane->base, config->prop_fb_id, 0); in __drm_universal_plane_init()
456 drm_object_attach_property(&plane->base, config->prop_in_fence_fd, -1); in __drm_universal_plane_init()
457 drm_object_attach_property(&plane->base, config->prop_crtc_id, 0); in __drm_universal_plane_init()
458 drm_object_attach_property(&plane->base, config->prop_crtc_x, 0); in __drm_universal_plane_init()
459 drm_object_attach_property(&plane->base, config->prop_crtc_y, 0); in __drm_universal_plane_init()
460 drm_object_attach_property(&plane->base, config->prop_crtc_w, 0); in __drm_universal_plane_init()
461 drm_object_attach_property(&plane->base, config->prop_crtc_h, 0); in __drm_universal_plane_init()
462 drm_object_attach_property(&plane->base, config->prop_src_x, 0); in __drm_universal_plane_init()
463 drm_object_attach_property(&plane->base, config->prop_src_y, 0); in __drm_universal_plane_init()
464 drm_object_attach_property(&plane->base, config->prop_src_w, 0); in __drm_universal_plane_init()
465 drm_object_attach_property(&plane->base, config->prop_src_h, 0); in __drm_universal_plane_init()
479 * drm_universal_plane_init - Initialize a new universal plane object
516 WARN_ON(!funcs->destroy); in drm_universal_plane_init()
531 if (WARN_ON(!plane->dev)) in drmm_universal_plane_alloc_release()
550 if (WARN_ON(!funcs || funcs->destroy)) in __drmm_universal_plane_alloc()
551 return ERR_PTR(-EINVAL); in __drmm_universal_plane_alloc()
555 return ERR_PTR(-ENOMEM); in __drmm_universal_plane_alloc()
590 return ERR_PTR(-EINVAL); in __drm_universal_plane_alloc()
594 return ERR_PTR(-ENOMEM); in __drm_universal_plane_alloc()
622 if (plane->funcs->late_register) in drm_plane_register_all()
623 ret = plane->funcs->late_register(plane); in drm_plane_register_all()
627 if (plane->zpos_property) in drm_plane_register_all()
643 if (plane->funcs->early_unregister) in drm_plane_unregister_all()
644 plane->funcs->early_unregister(plane); in drm_plane_unregister_all()
649 * drm_plane_cleanup - Clean up the core plane usage
658 struct drm_device *dev = plane->dev; in drm_plane_cleanup()
660 drm_modeset_lock_fini(&plane->mutex); in drm_plane_cleanup()
662 kfree(plane->format_types); in drm_plane_cleanup()
663 kfree(plane->modifiers); in drm_plane_cleanup()
664 drm_mode_object_unregister(dev, &plane->base); in drm_plane_cleanup()
666 BUG_ON(list_empty(&plane->head)); in drm_plane_cleanup()
673 list_del(&plane->head); in drm_plane_cleanup()
674 dev->mode_config.num_total_plane--; in drm_plane_cleanup()
676 WARN_ON(plane->state && !plane->funcs->atomic_destroy_state); in drm_plane_cleanup()
677 if (plane->state && plane->funcs->atomic_destroy_state) in drm_plane_cleanup()
678 plane->funcs->atomic_destroy_state(plane, plane->state); in drm_plane_cleanup()
680 kfree(plane->name); in drm_plane_cleanup()
687 * drm_plane_from_index - find the registered plane at an index
700 if (idx == plane->index) in drm_plane_from_index()
708 * drm_plane_force_disable - Forcibly disable a plane
726 if (!plane->fb) in drm_plane_force_disable()
729 WARN_ON(drm_drv_uses_atomic_modeset(plane->dev)); in drm_plane_force_disable()
731 plane->old_fb = plane->fb; in drm_plane_force_disable()
732 ret = plane->funcs->disable_plane(plane, NULL); in drm_plane_force_disable()
735 plane->old_fb = NULL; in drm_plane_force_disable()
739 drm_framebuffer_put(plane->old_fb); in drm_plane_force_disable()
740 plane->old_fb = NULL; in drm_plane_force_disable()
741 plane->fb = NULL; in drm_plane_force_disable()
742 plane->crtc = NULL; in drm_plane_force_disable()
747 * drm_mode_plane_set_obj_prop - set the value of a property
753 * calls the driver's ->set_property callback and changes the software state of
763 int ret = -EINVAL; in drm_mode_plane_set_obj_prop()
764 struct drm_mode_object *obj = &plane->base; in drm_mode_plane_set_obj_prop()
766 if (plane->funcs->set_property) in drm_mode_plane_set_obj_prop()
767 ret = plane->funcs->set_property(plane, property, value); in drm_mode_plane_set_obj_prop()
784 return -EOPNOTSUPP; in drm_mode_getplane_res()
786 plane_ptr = u64_to_user_ptr(plane_resp->plane_id_ptr); in drm_mode_getplane_res()
797 if (plane->type != DRM_PLANE_TYPE_OVERLAY && in drm_mode_getplane_res()
798 !file_priv->universal_planes) in drm_mode_getplane_res()
808 if (plane->type == DRM_PLANE_TYPE_CURSOR && in drm_mode_getplane_res()
810 file_priv->atomic && in drm_mode_getplane_res()
811 !file_priv->supports_virtualized_cursor_plane) in drm_mode_getplane_res()
814 if (drm_lease_held(file_priv, plane->base.id)) { in drm_mode_getplane_res()
815 if (count < plane_resp->count_planes && in drm_mode_getplane_res()
816 put_user(plane->base.id, plane_ptr + count)) in drm_mode_getplane_res()
817 return -EFAULT; in drm_mode_getplane_res()
821 plane_resp->count_planes = count; in drm_mode_getplane_res()
834 return -EOPNOTSUPP; in drm_mode_getplane()
836 plane = drm_plane_find(dev, file_priv, plane_resp->plane_id); in drm_mode_getplane()
838 return -ENOENT; in drm_mode_getplane()
840 drm_modeset_lock(&plane->mutex, NULL); in drm_mode_getplane()
841 if (plane->state && plane->state->crtc && drm_lease_held(file_priv, plane->state->crtc->base.id)) in drm_mode_getplane()
842 plane_resp->crtc_id = plane->state->crtc->base.id; in drm_mode_getplane()
843 else if (!plane->state && plane->crtc && drm_lease_held(file_priv, plane->crtc->base.id)) in drm_mode_getplane()
844 plane_resp->crtc_id = plane->crtc->base.id; in drm_mode_getplane()
846 plane_resp->crtc_id = 0; in drm_mode_getplane()
848 if (plane->state && plane->state->fb) in drm_mode_getplane()
849 plane_resp->fb_id = plane->state->fb->base.id; in drm_mode_getplane()
850 else if (!plane->state && plane->fb) in drm_mode_getplane()
851 plane_resp->fb_id = plane->fb->base.id; in drm_mode_getplane()
853 plane_resp->fb_id = 0; in drm_mode_getplane()
854 drm_modeset_unlock(&plane->mutex); in drm_mode_getplane()
856 plane_resp->plane_id = plane->base.id; in drm_mode_getplane()
857 plane_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv, in drm_mode_getplane()
858 plane->possible_crtcs); in drm_mode_getplane()
860 plane_resp->gamma_size = 0; in drm_mode_getplane()
866 if (plane->format_count && in drm_mode_getplane()
867 (plane_resp->count_format_types >= plane->format_count)) { in drm_mode_getplane()
868 format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr; in drm_mode_getplane()
870 plane->format_types, in drm_mode_getplane()
871 sizeof(uint32_t) * plane->format_count)) { in drm_mode_getplane()
872 return -EFAULT; in drm_mode_getplane()
875 plane_resp->count_format_types = plane->format_count; in drm_mode_getplane()
881 * drm_plane_has_format - Check whether the plane supports this format and modifier combination
894 for (i = 0; i < plane->format_count; i++) { in drm_plane_has_format()
895 if (format == plane->format_types[i]) in drm_plane_has_format()
898 if (i == plane->format_count) in drm_plane_has_format()
901 if (plane->funcs->format_mod_supported) { in drm_plane_has_format()
902 if (!plane->funcs->format_mod_supported(plane, format, modifier)) in drm_plane_has_format()
905 if (!plane->modifier_count) in drm_plane_has_format()
908 for (i = 0; i < plane->modifier_count; i++) { in drm_plane_has_format()
909 if (modifier == plane->modifiers[i]) in drm_plane_has_format()
912 if (i == plane->modifier_count) in drm_plane_has_format()
931 if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) { in __setplane_check()
933 return -EINVAL; in __setplane_check()
937 if (!drm_plane_has_format(plane, fb->format->format, fb->modifier)) { in __setplane_check()
939 &fb->format->format, fb->modifier); in __setplane_check()
940 return -EINVAL; in __setplane_check()
945 crtc_x > INT_MAX - (int32_t) crtc_w || in __setplane_check()
947 crtc_y > INT_MAX - (int32_t) crtc_h) { in __setplane_check()
950 return -ERANGE; in __setplane_check()
961 * drm_any_plane_has_format - Check whether any plane supports this format and modifier combination
984 * __setplane_internal - setplane handler for internal callers
1003 WARN_ON(drm_drv_uses_atomic_modeset(plane->dev)); in __setplane_internal()
1007 plane->old_fb = plane->fb; in __setplane_internal()
1008 ret = plane->funcs->disable_plane(plane, ctx); in __setplane_internal()
1010 plane->crtc = NULL; in __setplane_internal()
1011 plane->fb = NULL; in __setplane_internal()
1013 plane->old_fb = NULL; in __setplane_internal()
1024 plane->old_fb = plane->fb; in __setplane_internal()
1025 ret = plane->funcs->update_plane(plane, crtc, fb, in __setplane_internal()
1029 plane->crtc = crtc; in __setplane_internal()
1030 plane->fb = fb; in __setplane_internal()
1031 drm_framebuffer_get(plane->fb); in __setplane_internal()
1033 plane->old_fb = NULL; in __setplane_internal()
1037 if (plane->old_fb) in __setplane_internal()
1038 drm_framebuffer_put(plane->old_fb); in __setplane_internal()
1039 plane->old_fb = NULL; in __setplane_internal()
1055 WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev)); in __setplane_atomic()
1059 return plane->funcs->disable_plane(plane, ctx); in __setplane_atomic()
1074 return plane->funcs->update_plane(plane, crtc, fb, in __setplane_atomic()
1091 DRM_MODESET_LOCK_ALL_BEGIN(plane->dev, ctx, in setplane_internal()
1094 if (drm_drv_uses_atomic_modeset(plane->dev)) in setplane_internal()
1103 DRM_MODESET_LOCK_ALL_END(plane->dev, ctx, ret); in setplane_internal()
1118 return -EOPNOTSUPP; in drm_mode_setplane()
1124 plane = drm_plane_find(dev, file_priv, plane_req->plane_id); in drm_mode_setplane()
1127 plane_req->plane_id); in drm_mode_setplane()
1128 return -ENOENT; in drm_mode_setplane()
1131 if (plane_req->fb_id) { in drm_mode_setplane()
1132 fb = drm_framebuffer_lookup(dev, file_priv, plane_req->fb_id); in drm_mode_setplane()
1135 plane_req->fb_id); in drm_mode_setplane()
1136 return -ENOENT; in drm_mode_setplane()
1139 crtc = drm_crtc_find(dev, file_priv, plane_req->crtc_id); in drm_mode_setplane()
1143 plane_req->crtc_id); in drm_mode_setplane()
1144 return -ENOENT; in drm_mode_setplane()
1149 plane_req->crtc_x, plane_req->crtc_y, in drm_mode_setplane()
1150 plane_req->crtc_w, plane_req->crtc_h, in drm_mode_setplane()
1151 plane_req->src_x, plane_req->src_y, in drm_mode_setplane()
1152 plane_req->src_w, plane_req->src_h); in drm_mode_setplane()
1165 struct drm_device *dev = crtc->dev; in drm_mode_cursor_universal()
1166 struct drm_plane *plane = crtc->cursor; in drm_mode_cursor_universal()
1169 .width = req->width, in drm_mode_cursor_universal()
1170 .height = req->height, in drm_mode_cursor_universal()
1172 .pitches = { req->width * 4 }, in drm_mode_cursor_universal()
1173 .handles = { req->handle }, in drm_mode_cursor_universal()
1181 WARN_ON(plane->crtc != crtc && plane->crtc != NULL); in drm_mode_cursor_universal()
1188 if (req->flags & DRM_MODE_CURSOR_BO) { in drm_mode_cursor_universal()
1189 if (req->handle) { in drm_mode_cursor_universal()
1196 if (plane->hotspot_x_property && plane->state) in drm_mode_cursor_universal()
1197 plane->state->hotspot_x = req->hot_x; in drm_mode_cursor_universal()
1198 if (plane->hotspot_y_property && plane->state) in drm_mode_cursor_universal()
1199 plane->state->hotspot_y = req->hot_y; in drm_mode_cursor_universal()
1204 if (plane->state) in drm_mode_cursor_universal()
1205 fb = plane->state->fb; in drm_mode_cursor_universal()
1207 fb = plane->fb; in drm_mode_cursor_universal()
1213 if (req->flags & DRM_MODE_CURSOR_MOVE) { in drm_mode_cursor_universal()
1214 crtc_x = req->x; in drm_mode_cursor_universal()
1215 crtc_y = req->y; in drm_mode_cursor_universal()
1217 crtc_x = crtc->cursor_x; in drm_mode_cursor_universal()
1218 crtc_y = crtc->cursor_y; in drm_mode_cursor_universal()
1222 crtc_w = fb->width; in drm_mode_cursor_universal()
1223 crtc_h = fb->height; in drm_mode_cursor_universal()
1224 src_w = fb->width << 16; in drm_mode_cursor_universal()
1225 src_h = fb->height << 16; in drm_mode_cursor_universal()
1241 if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) { in drm_mode_cursor_universal()
1242 crtc->cursor_x = req->x; in drm_mode_cursor_universal()
1243 crtc->cursor_y = req->y; in drm_mode_cursor_universal()
1258 return -EOPNOTSUPP; in drm_mode_cursor_common()
1260 if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) in drm_mode_cursor_common()
1261 return -EINVAL; in drm_mode_cursor_common()
1263 crtc = drm_crtc_find(dev, file_priv, req->crtc_id); in drm_mode_cursor_common()
1265 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id); in drm_mode_cursor_common()
1266 return -ENOENT; in drm_mode_cursor_common()
1271 ret = drm_modeset_lock(&crtc->mutex, &ctx); in drm_mode_cursor_common()
1278 if (crtc->cursor) { in drm_mode_cursor_common()
1279 ret = drm_modeset_lock(&crtc->cursor->mutex, &ctx); in drm_mode_cursor_common()
1283 if (!drm_lease_held(file_priv, crtc->cursor->base.id)) { in drm_mode_cursor_common()
1284 ret = -EACCES; in drm_mode_cursor_common()
1292 if (req->flags & DRM_MODE_CURSOR_BO) { in drm_mode_cursor_common()
1293 if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) { in drm_mode_cursor_common()
1294 ret = -ENXIO; in drm_mode_cursor_common()
1298 if (crtc->funcs->cursor_set2) in drm_mode_cursor_common()
1299 ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle, in drm_mode_cursor_common()
1300 req->width, req->height, req->hot_x, req->hot_y); in drm_mode_cursor_common()
1302 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle, in drm_mode_cursor_common()
1303 req->width, req->height); in drm_mode_cursor_common()
1306 if (req->flags & DRM_MODE_CURSOR_MOVE) { in drm_mode_cursor_common()
1307 if (crtc->funcs->cursor_move) { in drm_mode_cursor_common()
1308 ret = crtc->funcs->cursor_move(crtc, req->x, req->y); in drm_mode_cursor_common()
1310 ret = -EFAULT; in drm_mode_cursor_common()
1315 if (ret == -EDEADLK) { in drm_mode_cursor_common()
1362 u32 target_vblank = page_flip->sequence; in drm_mode_page_flip_ioctl()
1364 int ret = -EINVAL; in drm_mode_page_flip_ioctl()
1367 return -EOPNOTSUPP; in drm_mode_page_flip_ioctl()
1369 if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS) in drm_mode_page_flip_ioctl()
1370 return -EINVAL; in drm_mode_page_flip_ioctl()
1372 if (page_flip->sequence != 0 && !(page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) in drm_mode_page_flip_ioctl()
1373 return -EINVAL; in drm_mode_page_flip_ioctl()
1378 if ((page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) == DRM_MODE_PAGE_FLIP_TARGET) in drm_mode_page_flip_ioctl()
1379 return -EINVAL; in drm_mode_page_flip_ioctl()
1381 if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip) in drm_mode_page_flip_ioctl()
1382 return -EINVAL; in drm_mode_page_flip_ioctl()
1384 crtc = drm_crtc_find(dev, file_priv, page_flip->crtc_id); in drm_mode_page_flip_ioctl()
1386 return -ENOENT; in drm_mode_page_flip_ioctl()
1388 plane = crtc->primary; in drm_mode_page_flip_ioctl()
1390 if (!drm_lease_held(file_priv, plane->base.id)) in drm_mode_page_flip_ioctl()
1391 return -EACCES; in drm_mode_page_flip_ioctl()
1393 if (crtc->funcs->page_flip_target) { in drm_mode_page_flip_ioctl()
1403 switch (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) { in drm_mode_page_flip_ioctl()
1405 if ((int)(target_vblank - current_vblank) > 1) { in drm_mode_page_flip_ioctl()
1410 return -EINVAL; in drm_mode_page_flip_ioctl()
1418 return -EINVAL; in drm_mode_page_flip_ioctl()
1424 !(page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC); in drm_mode_page_flip_ioctl()
1427 } else if (crtc->funcs->page_flip == NULL || in drm_mode_page_flip_ioctl()
1428 (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET)) { in drm_mode_page_flip_ioctl()
1429 return -EINVAL; in drm_mode_page_flip_ioctl()
1434 ret = drm_modeset_lock(&crtc->mutex, &ctx); in drm_mode_page_flip_ioctl()
1437 ret = drm_modeset_lock(&plane->mutex, &ctx); in drm_mode_page_flip_ioctl()
1441 if (plane->state) in drm_mode_page_flip_ioctl()
1442 old_fb = plane->state->fb; in drm_mode_page_flip_ioctl()
1444 old_fb = plane->fb; in drm_mode_page_flip_ioctl()
1451 ret = -EBUSY; in drm_mode_page_flip_ioctl()
1455 fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id); in drm_mode_page_flip_ioctl()
1457 ret = -ENOENT; in drm_mode_page_flip_ioctl()
1461 if (plane->state) { in drm_mode_page_flip_ioctl()
1462 const struct drm_plane_state *state = plane->state; in drm_mode_page_flip_ioctl()
1464 ret = drm_framebuffer_check_src_coords(state->src_x, in drm_mode_page_flip_ioctl()
1465 state->src_y, in drm_mode_page_flip_ioctl()
1466 state->src_w, in drm_mode_page_flip_ioctl()
1467 state->src_h, in drm_mode_page_flip_ioctl()
1470 ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, in drm_mode_page_flip_ioctl()
1471 &crtc->mode, fb); in drm_mode_page_flip_ioctl()
1479 * checks in their ->atomic_check implementation, which will in drm_mode_page_flip_ioctl()
1480 * return -EINVAL if any hw or driver constraint is violated due in drm_mode_page_flip_ioctl()
1483 if (old_fb->format->format != fb->format->format) { in drm_mode_page_flip_ioctl()
1485 ret = -EINVAL; in drm_mode_page_flip_ioctl()
1489 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { in drm_mode_page_flip_ioctl()
1492 ret = -ENOMEM; in drm_mode_page_flip_ioctl()
1496 e->event.base.type = DRM_EVENT_FLIP_COMPLETE; in drm_mode_page_flip_ioctl()
1497 e->event.base.length = sizeof(e->event); in drm_mode_page_flip_ioctl()
1498 e->event.vbl.user_data = page_flip->user_data; in drm_mode_page_flip_ioctl()
1499 e->event.vbl.crtc_id = crtc->base.id; in drm_mode_page_flip_ioctl()
1501 ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); in drm_mode_page_flip_ioctl()
1509 plane->old_fb = plane->fb; in drm_mode_page_flip_ioctl()
1510 if (crtc->funcs->page_flip_target) in drm_mode_page_flip_ioctl()
1511 ret = crtc->funcs->page_flip_target(crtc, fb, e, in drm_mode_page_flip_ioctl()
1512 page_flip->flags, in drm_mode_page_flip_ioctl()
1516 ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags, in drm_mode_page_flip_ioctl()
1519 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) in drm_mode_page_flip_ioctl()
1520 drm_event_cancel_free(dev, &e->base); in drm_mode_page_flip_ioctl()
1522 plane->old_fb = NULL; in drm_mode_page_flip_ioctl()
1524 if (!plane->state) { in drm_mode_page_flip_ioctl()
1525 plane->fb = fb; in drm_mode_page_flip_ioctl()
1534 if (plane->old_fb) in drm_mode_page_flip_ioctl()
1535 drm_framebuffer_put(plane->old_fb); in drm_mode_page_flip_ioctl()
1536 plane->old_fb = NULL; in drm_mode_page_flip_ioctl()
1538 if (ret == -EDEADLK) { in drm_mode_page_flip_ioctl()
1547 if (ret && crtc->funcs->page_flip_target) in drm_mode_page_flip_ioctl()
1560 * page-flip), irrespective of whether currently attached framebuffer is same as
1563 * FB_DAMAGE_CLIPS is a hint to kernel which could be helpful for some drivers
1567 * Since FB_DAMAGE_CLIPS is a hint so it is an optional property. User-space can
1572 * is free to read more, user-space must always render the entire visible
1573 * framebuffer. Otherwise there can be corruptions. Also, if a user-space
1592 * target. Drivers implementing a per-plane or per-CRTC upload target need to
1593 * handle frame damage, while drivers implementing a per-buffer upload target
1605 * Drivers with a per-buffer upload target could compare the &drm_plane_state.fb
1610 * That is because drivers with a per-plane upload target, expect the backing
1614 * damage helpers, similarly to how user-space already handle this case as it is
1618 * https://emersion.fr/blog/2019/intro-to-damage-tracking/
1622 * drm_plane_enable_fb_damage_clips - Enables plane fb damage clips property.
1629 struct drm_device *dev = plane->dev; in drm_plane_enable_fb_damage_clips()
1630 struct drm_mode_config *config = &dev->mode_config; in drm_plane_enable_fb_damage_clips()
1632 drm_object_attach_property(&plane->base, config->prop_fb_damage_clips, in drm_plane_enable_fb_damage_clips()
1638 * drm_plane_get_damage_clips_count - Returns damage clips count.
1641 * Simple helper to get the number of &drm_mode_rect clips set by user-space
1649 return (state && state->fb_damage_clips) ? in drm_plane_get_damage_clips_count()
1650 state->fb_damage_clips->length/sizeof(struct drm_mode_rect) : 0; in drm_plane_get_damage_clips_count()
1657 return (struct drm_mode_rect *)((state && state->fb_damage_clips) ? in __drm_plane_get_damage_clips()
1658 state->fb_damage_clips->data : NULL); in __drm_plane_get_damage_clips()
1662 * drm_plane_get_damage_clips - Returns damage clips.
1675 struct drm_device *dev = state->plane->dev; in drm_plane_get_damage_clips()
1676 struct drm_mode_config *config = &dev->mode_config; in drm_plane_get_damage_clips()
1679 if (!drm_mode_obj_find_prop_id(&state->plane->base, in drm_plane_get_damage_clips()
1680 config->prop_fb_damage_clips->base.id)) in drm_plane_get_damage_clips()
1702 return ERR_PTR(-EINVAL); in drm_create_scaling_filter_prop()
1708 return ERR_PTR(-ENOMEM); in drm_create_scaling_filter_prop()
1730 * drm_plane_create_scaling_filter_property - create a new scaling filter
1741 * Zero for success or -errno
1747 drm_create_scaling_filter_prop(plane->dev, supported_filters); in drm_plane_create_scaling_filter_property()
1752 drm_object_attach_property(&plane->base, prop, in drm_plane_create_scaling_filter_property()
1754 plane->scaling_filter_property = prop; in drm_plane_create_scaling_filter_property()
1761 * drm_plane_add_size_hints_property - create a size hints property
1770 * Zero for success or -errno
1776 struct drm_device *dev = plane->dev; in drm_plane_add_size_hints_property()
1777 struct drm_mode_config *config = &dev->mode_config; in drm_plane_add_size_hints_property()
1781 if (drm_WARN_ON(dev, plane->type != DRM_PLANE_TYPE_CURSOR)) in drm_plane_add_size_hints_property()
1782 return -EINVAL; in drm_plane_add_size_hints_property()
1790 drm_object_attach_property(&plane->base, config->size_hints_property, in drm_plane_add_size_hints_property()
1791 blob->base.id); in drm_plane_add_size_hints_property()