.. | .. |
---|
34 | 34 | #include <linux/slab.h> |
---|
35 | 35 | #include <linux/export.h> |
---|
36 | 36 | #include <linux/dma-fence.h> |
---|
37 | | -#include <drm/drmP.h> |
---|
| 37 | +#include <linux/uaccess.h> |
---|
38 | 38 | #include <drm/drm_crtc.h> |
---|
39 | 39 | #include <drm/drm_edid.h> |
---|
40 | 40 | #include <drm/drm_fourcc.h> |
---|
.. | .. |
---|
42 | 42 | #include <drm/drm_atomic.h> |
---|
43 | 43 | #include <drm/drm_auth.h> |
---|
44 | 44 | #include <drm/drm_debugfs_crc.h> |
---|
| 45 | +#include <drm/drm_drv.h> |
---|
| 46 | +#include <drm/drm_print.h> |
---|
| 47 | +#include <drm/drm_file.h> |
---|
45 | 48 | |
---|
46 | 49 | #include "drm_crtc_internal.h" |
---|
47 | 50 | #include "drm_internal.h" |
---|
.. | .. |
---|
90 | 93 | } |
---|
91 | 94 | EXPORT_SYMBOL(drm_crtc_from_index); |
---|
92 | 95 | |
---|
93 | | -/** |
---|
94 | | - * drm_crtc_force_disable - Forcibly turn off a CRTC |
---|
95 | | - * @crtc: CRTC to turn off |
---|
96 | | - * |
---|
97 | | - * Note: This should only be used by non-atomic legacy drivers. |
---|
98 | | - * |
---|
99 | | - * Returns: |
---|
100 | | - * Zero on success, error code on failure. |
---|
101 | | - */ |
---|
102 | 96 | int drm_crtc_force_disable(struct drm_crtc *crtc) |
---|
103 | 97 | { |
---|
104 | 98 | struct drm_mode_set set = { |
---|
.. | .. |
---|
109 | 103 | |
---|
110 | 104 | return drm_mode_set_config_internal(&set); |
---|
111 | 105 | } |
---|
112 | | -EXPORT_SYMBOL(drm_crtc_force_disable); |
---|
113 | | - |
---|
114 | | -/** |
---|
115 | | - * drm_crtc_force_disable_all - Forcibly turn off all enabled CRTCs |
---|
116 | | - * @dev: DRM device whose CRTCs to turn off |
---|
117 | | - * |
---|
118 | | - * Drivers may want to call this on unload to ensure that all displays are |
---|
119 | | - * unlit and the GPU is in a consistent, low power state. Takes modeset locks. |
---|
120 | | - * |
---|
121 | | - * Note: This should only be used by non-atomic legacy drivers. For an atomic |
---|
122 | | - * version look at drm_atomic_helper_shutdown(). |
---|
123 | | - * |
---|
124 | | - * Returns: |
---|
125 | | - * Zero on success, error code on failure. |
---|
126 | | - */ |
---|
127 | | -int drm_crtc_force_disable_all(struct drm_device *dev) |
---|
128 | | -{ |
---|
129 | | - struct drm_crtc *crtc; |
---|
130 | | - int ret = 0; |
---|
131 | | - |
---|
132 | | - drm_modeset_lock_all(dev); |
---|
133 | | - drm_for_each_crtc(crtc, dev) |
---|
134 | | - if (crtc->enabled) { |
---|
135 | | - ret = drm_crtc_force_disable(crtc); |
---|
136 | | - if (ret) |
---|
137 | | - goto out; |
---|
138 | | - } |
---|
139 | | -out: |
---|
140 | | - drm_modeset_unlock_all(dev); |
---|
141 | | - return ret; |
---|
142 | | -} |
---|
143 | | -EXPORT_SYMBOL(drm_crtc_force_disable_all); |
---|
144 | 106 | |
---|
145 | 107 | static unsigned int drm_num_crtcs(struct drm_device *dev) |
---|
146 | 108 | { |
---|
.. | .. |
---|
160 | 122 | int ret = 0; |
---|
161 | 123 | |
---|
162 | 124 | drm_for_each_crtc(crtc, dev) { |
---|
163 | | - if (drm_debugfs_crtc_add(crtc)) |
---|
164 | | - DRM_ERROR("Failed to initialize debugfs entry for CRTC '%s'.\n", |
---|
165 | | - crtc->name); |
---|
| 125 | + drm_debugfs_crtc_add(crtc); |
---|
166 | 126 | |
---|
167 | 127 | if (crtc->funcs->late_register) |
---|
168 | 128 | ret = crtc->funcs->late_register(crtc); |
---|
.. | .. |
---|
243 | 203 | |
---|
244 | 204 | return fence; |
---|
245 | 205 | } |
---|
| 206 | + |
---|
| 207 | +/** |
---|
| 208 | + * DOC: standard CRTC properties |
---|
| 209 | + * |
---|
| 210 | + * DRM CRTCs have a few standardized properties: |
---|
| 211 | + * |
---|
| 212 | + * ACTIVE: |
---|
| 213 | + * Atomic property for setting the power state of the CRTC. When set to 1 |
---|
| 214 | + * the CRTC will actively display content. When set to 0 the CRTC will be |
---|
| 215 | + * powered off. There is no expectation that user-space will reset CRTC |
---|
| 216 | + * resources like the mode and planes when setting ACTIVE to 0. |
---|
| 217 | + * |
---|
| 218 | + * User-space can rely on an ACTIVE change to 1 to never fail an atomic |
---|
| 219 | + * test as long as no other property has changed. If a change to ACTIVE |
---|
| 220 | + * fails an atomic test, this is a driver bug. For this reason setting |
---|
| 221 | + * ACTIVE to 0 must not release internal resources (like reserved memory |
---|
| 222 | + * bandwidth or clock generators). |
---|
| 223 | + * |
---|
| 224 | + * Note that the legacy DPMS property on connectors is internally routed |
---|
| 225 | + * to control this property for atomic drivers. |
---|
| 226 | + * MODE_ID: |
---|
| 227 | + * Atomic property for setting the CRTC display timings. The value is the |
---|
| 228 | + * ID of a blob containing the DRM mode info. To disable the CRTC, |
---|
| 229 | + * user-space must set this property to 0. |
---|
| 230 | + * |
---|
| 231 | + * Setting MODE_ID to 0 will release reserved resources for the CRTC. |
---|
| 232 | + */ |
---|
246 | 233 | |
---|
247 | 234 | /** |
---|
248 | 235 | * drm_crtc_init_with_planes - Initialise a new CRTC object with |
---|
.. | .. |
---|
337 | 324 | drm_object_attach_property(&crtc->base, config->prop_mode_id, 0); |
---|
338 | 325 | drm_object_attach_property(&crtc->base, |
---|
339 | 326 | config->prop_out_fence_ptr, 0); |
---|
| 327 | + drm_object_attach_property(&crtc->base, |
---|
| 328 | + config->prop_vrr_enabled, 0); |
---|
340 | 329 | } |
---|
341 | 330 | |
---|
342 | 331 | return 0; |
---|
.. | .. |
---|
402 | 391 | struct drm_plane *plane; |
---|
403 | 392 | |
---|
404 | 393 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
---|
405 | | - return -EINVAL; |
---|
| 394 | + return -EOPNOTSUPP; |
---|
406 | 395 | |
---|
407 | 396 | crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id); |
---|
408 | 397 | if (!crtc) |
---|
.. | .. |
---|
567 | 556 | struct drm_mode_crtc *crtc_req = data; |
---|
568 | 557 | struct drm_crtc *crtc; |
---|
569 | 558 | struct drm_plane *plane; |
---|
570 | | - struct drm_connector **connector_set, *connector; |
---|
571 | | - struct drm_framebuffer *fb; |
---|
572 | | - struct drm_display_mode *mode; |
---|
| 559 | + struct drm_connector **connector_set = NULL, *connector; |
---|
| 560 | + struct drm_framebuffer *fb = NULL; |
---|
| 561 | + struct drm_display_mode *mode = NULL; |
---|
573 | 562 | struct drm_mode_set set; |
---|
574 | 563 | uint32_t __user *set_connectors_ptr; |
---|
575 | 564 | struct drm_modeset_acquire_ctx ctx; |
---|
.. | .. |
---|
577 | 566 | int i; |
---|
578 | 567 | |
---|
579 | 568 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
---|
580 | | - return -EINVAL; |
---|
| 569 | + return -EOPNOTSUPP; |
---|
581 | 570 | |
---|
582 | 571 | /* |
---|
583 | 572 | * Universal plane src offsets are only 16.16, prevent havoc for |
---|
.. | .. |
---|
599 | 588 | if (crtc_req->mode_valid && !drm_lease_held(file_priv, plane->base.id)) |
---|
600 | 589 | return -EACCES; |
---|
601 | 590 | |
---|
602 | | - mutex_lock(&crtc->dev->mode_config.mutex); |
---|
603 | | - drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); |
---|
604 | | -retry: |
---|
605 | | - connector_set = NULL; |
---|
606 | | - fb = NULL; |
---|
607 | | - mode = NULL; |
---|
608 | | - |
---|
609 | | - ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx); |
---|
610 | | - if (ret) |
---|
611 | | - goto out; |
---|
| 591 | + DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, |
---|
| 592 | + DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret); |
---|
612 | 593 | |
---|
613 | 594 | if (crtc_req->mode_valid) { |
---|
614 | 595 | /* If we have a mode we need a framebuffer. */ |
---|
.. | .. |
---|
674 | 655 | fb->modifier); |
---|
675 | 656 | if (ret) { |
---|
676 | 657 | struct drm_format_name_buf format_name; |
---|
| 658 | + |
---|
677 | 659 | DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n", |
---|
678 | 660 | drm_get_format_name(fb->format->format, |
---|
679 | 661 | &format_name), |
---|
.. | .. |
---|
767 | 749 | } |
---|
768 | 750 | kfree(connector_set); |
---|
769 | 751 | drm_mode_destroy(dev, mode); |
---|
770 | | - if (ret == -EDEADLK) { |
---|
771 | | - ret = drm_modeset_backoff(&ctx); |
---|
772 | | - if (!ret) |
---|
773 | | - goto retry; |
---|
774 | | - } |
---|
775 | | - drm_modeset_drop_locks(&ctx); |
---|
776 | | - drm_modeset_acquire_fini(&ctx); |
---|
777 | | - mutex_unlock(&crtc->dev->mode_config.mutex); |
---|
| 752 | + |
---|
| 753 | + /* In case we need to retry... */ |
---|
| 754 | + connector_set = NULL; |
---|
| 755 | + fb = NULL; |
---|
| 756 | + mode = NULL; |
---|
| 757 | + |
---|
| 758 | + DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); |
---|
778 | 759 | |
---|
779 | 760 | return ret; |
---|
780 | 761 | } |
---|