.. | .. |
---|
20 | 20 | * OF THIS SOFTWARE. |
---|
21 | 21 | */ |
---|
22 | 22 | |
---|
23 | | -#include <drm/drmP.h> |
---|
| 23 | +#include <linux/slab.h> |
---|
| 24 | +#include <linux/uaccess.h> |
---|
| 25 | + |
---|
24 | 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_vblank.h> |
---|
25 | 34 | |
---|
26 | 35 | #include "drm_crtc_internal.h" |
---|
27 | 36 | |
---|
.. | .. |
---|
177 | 186 | if (WARN_ON(config->num_total_plane >= 32)) |
---|
178 | 187 | return -EINVAL; |
---|
179 | 188 | |
---|
| 189 | + /* |
---|
| 190 | + * First driver to need more than 64 formats needs to fix this. Each |
---|
| 191 | + * format is encoded as a bit and the current code only supports a u64. |
---|
| 192 | + */ |
---|
| 193 | + if (WARN_ON(format_count > 64)) |
---|
| 194 | + return -EINVAL; |
---|
| 195 | + |
---|
180 | 196 | WARN_ON(drm_drv_uses_atomic_modeset(dev) && |
---|
181 | 197 | (!funcs->atomic_destroy_state || |
---|
182 | 198 | !funcs->atomic_duplicate_state)); |
---|
.. | .. |
---|
198 | 214 | return -ENOMEM; |
---|
199 | 215 | } |
---|
200 | 216 | |
---|
201 | | - /* |
---|
202 | | - * First driver to need more than 64 formats needs to fix this. Each |
---|
203 | | - * format is encoded as a bit and the current code only supports a u64. |
---|
204 | | - */ |
---|
205 | | - if (WARN_ON(format_count > 64)) |
---|
206 | | - return -EINVAL; |
---|
207 | | - |
---|
208 | 217 | if (format_modifiers) { |
---|
209 | 218 | const uint64_t *temp_modifiers = format_modifiers; |
---|
| 219 | + |
---|
210 | 220 | while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID) |
---|
211 | 221 | format_modifier_count++; |
---|
212 | 222 | } |
---|
.. | .. |
---|
280 | 290 | |
---|
281 | 291 | int drm_plane_register_all(struct drm_device *dev) |
---|
282 | 292 | { |
---|
| 293 | + unsigned int num_planes = 0; |
---|
| 294 | + unsigned int num_zpos = 0; |
---|
283 | 295 | struct drm_plane *plane; |
---|
284 | 296 | int ret = 0; |
---|
285 | 297 | |
---|
.. | .. |
---|
288 | 300 | ret = plane->funcs->late_register(plane); |
---|
289 | 301 | if (ret) |
---|
290 | 302 | return ret; |
---|
| 303 | + |
---|
| 304 | + if (plane->zpos_property) |
---|
| 305 | + num_zpos++; |
---|
| 306 | + num_planes++; |
---|
291 | 307 | } |
---|
| 308 | + |
---|
| 309 | + drm_WARN(dev, num_zpos && num_planes != num_zpos, |
---|
| 310 | + "Mixing planes with and without zpos property is invalid\n"); |
---|
292 | 311 | |
---|
293 | 312 | return 0; |
---|
294 | 313 | } |
---|
.. | .. |
---|
466 | 485 | struct drm_file *file_priv) |
---|
467 | 486 | { |
---|
468 | 487 | struct drm_mode_get_plane_res *plane_resp = data; |
---|
469 | | - struct drm_mode_config *config; |
---|
470 | 488 | struct drm_plane *plane; |
---|
471 | 489 | uint32_t __user *plane_ptr; |
---|
472 | 490 | int count = 0; |
---|
473 | 491 | |
---|
474 | 492 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
---|
475 | | - return -EINVAL; |
---|
| 493 | + return -EOPNOTSUPP; |
---|
476 | 494 | |
---|
477 | | - config = &dev->mode_config; |
---|
478 | 495 | plane_ptr = u64_to_user_ptr(plane_resp->plane_id_ptr); |
---|
479 | 496 | |
---|
480 | 497 | /* |
---|
.. | .. |
---|
510 | 527 | uint32_t __user *format_ptr; |
---|
511 | 528 | |
---|
512 | 529 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
---|
513 | | - return -EINVAL; |
---|
| 530 | + return -EOPNOTSUPP; |
---|
514 | 531 | |
---|
515 | 532 | plane = drm_plane_find(dev, file_priv, plane_resp->plane_id); |
---|
516 | 533 | if (!plane) |
---|
.. | .. |
---|
632 | 649 | return 0; |
---|
633 | 650 | } |
---|
634 | 651 | |
---|
| 652 | +/** |
---|
| 653 | + * drm_any_plane_has_format - Check whether any plane supports this format and modifier combination |
---|
| 654 | + * @dev: DRM device |
---|
| 655 | + * @format: pixel format (DRM_FORMAT_*) |
---|
| 656 | + * @modifier: data layout modifier |
---|
| 657 | + * |
---|
| 658 | + * Returns: |
---|
| 659 | + * Whether at least one plane supports the specified format and modifier combination. |
---|
| 660 | + */ |
---|
| 661 | +bool drm_any_plane_has_format(struct drm_device *dev, |
---|
| 662 | + u32 format, u64 modifier) |
---|
| 663 | +{ |
---|
| 664 | + struct drm_plane *plane; |
---|
| 665 | + |
---|
| 666 | + drm_for_each_plane(plane, dev) { |
---|
| 667 | + if (drm_plane_check_pixel_format(plane, format, modifier) == 0) |
---|
| 668 | + return true; |
---|
| 669 | + } |
---|
| 670 | + |
---|
| 671 | + return false; |
---|
| 672 | +} |
---|
| 673 | +EXPORT_SYMBOL(drm_any_plane_has_format); |
---|
| 674 | + |
---|
635 | 675 | /* |
---|
636 | 676 | * __setplane_internal - setplane handler for internal callers |
---|
637 | 677 | * |
---|
.. | .. |
---|
740 | 780 | struct drm_modeset_acquire_ctx ctx; |
---|
741 | 781 | int ret; |
---|
742 | 782 | |
---|
743 | | - drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); |
---|
744 | | -retry: |
---|
745 | | - ret = drm_modeset_lock_all_ctx(plane->dev, &ctx); |
---|
746 | | - if (ret) |
---|
747 | | - goto fail; |
---|
| 783 | + DRM_MODESET_LOCK_ALL_BEGIN(plane->dev, ctx, |
---|
| 784 | + DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret); |
---|
748 | 785 | |
---|
749 | 786 | if (drm_drv_uses_atomic_modeset(plane->dev)) |
---|
750 | 787 | ret = __setplane_atomic(plane, crtc, fb, |
---|
.. | .. |
---|
755 | 792 | crtc_x, crtc_y, crtc_w, crtc_h, |
---|
756 | 793 | src_x, src_y, src_w, src_h, &ctx); |
---|
757 | 794 | |
---|
758 | | -fail: |
---|
759 | | - if (ret == -EDEADLK) { |
---|
760 | | - ret = drm_modeset_backoff(&ctx); |
---|
761 | | - if (!ret) |
---|
762 | | - goto retry; |
---|
763 | | - } |
---|
764 | | - drm_modeset_drop_locks(&ctx); |
---|
765 | | - drm_modeset_acquire_fini(&ctx); |
---|
| 795 | + DRM_MODESET_LOCK_ALL_END(plane->dev, ctx, ret); |
---|
766 | 796 | |
---|
767 | 797 | return ret; |
---|
768 | 798 | } |
---|
.. | .. |
---|
777 | 807 | int ret; |
---|
778 | 808 | |
---|
779 | 809 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
---|
780 | | - return -EINVAL; |
---|
| 810 | + return -EOPNOTSUPP; |
---|
781 | 811 | |
---|
782 | 812 | /* |
---|
783 | 813 | * First, find the plane, crtc, and fb objects. If not available, |
---|
.. | .. |
---|
915 | 945 | int ret = 0; |
---|
916 | 946 | |
---|
917 | 947 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
---|
918 | | - return -EINVAL; |
---|
| 948 | + return -EOPNOTSUPP; |
---|
919 | 949 | |
---|
920 | 950 | if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) |
---|
921 | 951 | return -EINVAL; |
---|
.. | .. |
---|
1024 | 1054 | int ret = -EINVAL; |
---|
1025 | 1055 | |
---|
1026 | 1056 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
---|
1027 | | - return -EINVAL; |
---|
| 1057 | + return -EOPNOTSUPP; |
---|
1028 | 1058 | |
---|
1029 | 1059 | if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS) |
---|
1030 | 1060 | return -EINVAL; |
---|