Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915/display: split out load detect to a separate file

Load detect is shared between tv and crt but otherwise isolated in
intel_display.c.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230417153741.1074692-1-jani.nikula@intel.com

+260 -230
+1
drivers/gpu/drm/i915/Makefile
··· 261 261 display/intel_hdcp_gsc.o \ 262 262 display/intel_hotplug.o \ 263 263 display/intel_hti.o \ 264 + display/intel_load_detect.o \ 264 265 display/intel_lpe_audio.o \ 265 266 display/intel_modeset_verify.o \ 266 267 display/intel_modeset_setup.o \
+3 -2
drivers/gpu/drm/i915/display/intel_crt.c
··· 48 48 #include "intel_fifo_underrun.h" 49 49 #include "intel_gmbus.h" 50 50 #include "intel_hotplug.h" 51 + #include "intel_load_detect.h" 51 52 #include "intel_pch_display.h" 52 53 #include "intel_pch_refclk.h" 53 54 ··· 882 881 } 883 882 884 883 /* for pre-945g platforms use load detect */ 885 - ret = intel_get_load_detect_pipe(connector, &tmp, ctx); 884 + ret = intel_load_detect_get_pipe(connector, &tmp, ctx); 886 885 if (ret > 0) { 887 886 if (intel_crt_detect_ddc(connector)) 888 887 status = connector_status_connected; ··· 893 892 status = connector_status_disconnected; 894 893 else 895 894 status = connector_status_unknown; 896 - intel_release_load_detect_pipe(connector, &tmp, ctx); 895 + intel_load_detect_release_pipe(connector, &tmp, ctx); 897 896 } else if (ret == 0) { 898 897 status = connector_status_unknown; 899 898 } else {
-215
drivers/gpu/drm/i915/display/intel_display.c
··· 3821 3821 return true; 3822 3822 } 3823 3823 3824 - /* VESA 640x480x72Hz mode to set on the pipe */ 3825 - static const struct drm_display_mode load_detect_mode = { 3826 - DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664, 3827 - 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 3828 - }; 3829 - 3830 - static int intel_modeset_disable_planes(struct drm_atomic_state *state, 3831 - struct drm_crtc *crtc) 3832 - { 3833 - struct drm_plane *plane; 3834 - struct drm_plane_state *plane_state; 3835 - int ret, i; 3836 - 3837 - ret = drm_atomic_add_affected_planes(state, crtc); 3838 - if (ret) 3839 - return ret; 3840 - 3841 - for_each_new_plane_in_state(state, plane, plane_state, i) { 3842 - if (plane_state->crtc != crtc) 3843 - continue; 3844 - 3845 - ret = drm_atomic_set_crtc_for_plane(plane_state, NULL); 3846 - if (ret) 3847 - return ret; 3848 - 3849 - drm_atomic_set_fb_for_plane(plane_state, NULL); 3850 - } 3851 - 3852 - return 0; 3853 - } 3854 - 3855 - int intel_get_load_detect_pipe(struct drm_connector *connector, 3856 - struct intel_load_detect_pipe *old, 3857 - struct drm_modeset_acquire_ctx *ctx) 3858 - { 3859 - struct intel_encoder *encoder = 3860 - intel_attached_encoder(to_intel_connector(connector)); 3861 - struct intel_crtc *possible_crtc; 3862 - struct intel_crtc *crtc = NULL; 3863 - struct drm_device *dev = encoder->base.dev; 3864 - struct drm_i915_private *dev_priv = to_i915(dev); 3865 - struct drm_mode_config *config = &dev->mode_config; 3866 - struct drm_atomic_state *state = NULL, *restore_state = NULL; 3867 - struct drm_connector_state *connector_state; 3868 - struct intel_crtc_state *crtc_state; 3869 - int ret; 3870 - 3871 - drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", 3872 - connector->base.id, connector->name, 3873 - encoder->base.base.id, encoder->base.name); 3874 - 3875 - old->restore_state = NULL; 3876 - 3877 - drm_WARN_ON(dev, !drm_modeset_is_locked(&config->connection_mutex)); 3878 - 3879 - /* 3880 - * Algorithm gets a little messy: 3881 - * 3882 - * - if the connector already has an assigned crtc, use it (but make 3883 - * sure it's on first) 3884 - * 3885 - * - try to find the first unused crtc that can drive this connector, 3886 - * and use that if we find one 3887 - */ 3888 - 3889 - /* See if we already have a CRTC for this connector */ 3890 - if (connector->state->crtc) { 3891 - crtc = to_intel_crtc(connector->state->crtc); 3892 - 3893 - ret = drm_modeset_lock(&crtc->base.mutex, ctx); 3894 - if (ret) 3895 - goto fail; 3896 - 3897 - /* Make sure the crtc and connector are running */ 3898 - goto found; 3899 - } 3900 - 3901 - /* Find an unused one (if possible) */ 3902 - for_each_intel_crtc(dev, possible_crtc) { 3903 - if (!(encoder->base.possible_crtcs & 3904 - drm_crtc_mask(&possible_crtc->base))) 3905 - continue; 3906 - 3907 - ret = drm_modeset_lock(&possible_crtc->base.mutex, ctx); 3908 - if (ret) 3909 - goto fail; 3910 - 3911 - if (possible_crtc->base.state->enable) { 3912 - drm_modeset_unlock(&possible_crtc->base.mutex); 3913 - continue; 3914 - } 3915 - 3916 - crtc = possible_crtc; 3917 - break; 3918 - } 3919 - 3920 - /* 3921 - * If we didn't find an unused CRTC, don't use any. 3922 - */ 3923 - if (!crtc) { 3924 - drm_dbg_kms(&dev_priv->drm, 3925 - "no pipe available for load-detect\n"); 3926 - ret = -ENODEV; 3927 - goto fail; 3928 - } 3929 - 3930 - found: 3931 - state = drm_atomic_state_alloc(dev); 3932 - restore_state = drm_atomic_state_alloc(dev); 3933 - if (!state || !restore_state) { 3934 - ret = -ENOMEM; 3935 - goto fail; 3936 - } 3937 - 3938 - state->acquire_ctx = ctx; 3939 - to_intel_atomic_state(state)->internal = true; 3940 - 3941 - restore_state->acquire_ctx = ctx; 3942 - to_intel_atomic_state(restore_state)->internal = true; 3943 - 3944 - connector_state = drm_atomic_get_connector_state(state, connector); 3945 - if (IS_ERR(connector_state)) { 3946 - ret = PTR_ERR(connector_state); 3947 - goto fail; 3948 - } 3949 - 3950 - ret = drm_atomic_set_crtc_for_connector(connector_state, &crtc->base); 3951 - if (ret) 3952 - goto fail; 3953 - 3954 - crtc_state = intel_atomic_get_crtc_state(state, crtc); 3955 - if (IS_ERR(crtc_state)) { 3956 - ret = PTR_ERR(crtc_state); 3957 - goto fail; 3958 - } 3959 - 3960 - crtc_state->uapi.active = true; 3961 - 3962 - ret = drm_atomic_set_mode_for_crtc(&crtc_state->uapi, 3963 - &load_detect_mode); 3964 - if (ret) 3965 - goto fail; 3966 - 3967 - ret = intel_modeset_disable_planes(state, &crtc->base); 3968 - if (ret) 3969 - goto fail; 3970 - 3971 - ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(restore_state, connector)); 3972 - if (!ret) 3973 - ret = PTR_ERR_OR_ZERO(drm_atomic_get_crtc_state(restore_state, &crtc->base)); 3974 - if (!ret) 3975 - ret = drm_atomic_add_affected_planes(restore_state, &crtc->base); 3976 - if (ret) { 3977 - drm_dbg_kms(&dev_priv->drm, 3978 - "Failed to create a copy of old state to restore: %i\n", 3979 - ret); 3980 - goto fail; 3981 - } 3982 - 3983 - ret = drm_atomic_commit(state); 3984 - if (ret) { 3985 - drm_dbg_kms(&dev_priv->drm, 3986 - "failed to set mode on load-detect pipe\n"); 3987 - goto fail; 3988 - } 3989 - 3990 - old->restore_state = restore_state; 3991 - drm_atomic_state_put(state); 3992 - 3993 - /* let the connector get through one full cycle before testing */ 3994 - intel_crtc_wait_for_next_vblank(crtc); 3995 - 3996 - return true; 3997 - 3998 - fail: 3999 - if (state) { 4000 - drm_atomic_state_put(state); 4001 - state = NULL; 4002 - } 4003 - if (restore_state) { 4004 - drm_atomic_state_put(restore_state); 4005 - restore_state = NULL; 4006 - } 4007 - 4008 - if (ret == -EDEADLK) 4009 - return ret; 4010 - 4011 - return false; 4012 - } 4013 - 4014 - void intel_release_load_detect_pipe(struct drm_connector *connector, 4015 - struct intel_load_detect_pipe *old, 4016 - struct drm_modeset_acquire_ctx *ctx) 4017 - { 4018 - struct intel_encoder *intel_encoder = 4019 - intel_attached_encoder(to_intel_connector(connector)); 4020 - struct drm_i915_private *i915 = to_i915(intel_encoder->base.dev); 4021 - struct drm_encoder *encoder = &intel_encoder->base; 4022 - struct drm_atomic_state *state = old->restore_state; 4023 - int ret; 4024 - 4025 - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", 4026 - connector->base.id, connector->name, 4027 - encoder->base.id, encoder->name); 4028 - 4029 - if (!state) 4030 - return; 4031 - 4032 - ret = drm_atomic_helper_commit_duplicated_state(state, ctx); 4033 - if (ret) 4034 - drm_dbg_kms(&i915->drm, 4035 - "Couldn't release load detect pipe: %i\n", ret); 4036 - drm_atomic_state_put(state); 4037 - } 4038 - 4039 3824 static int i9xx_pll_refclk(struct drm_device *dev, 4040 3825 const struct intel_crtc_state *pipe_config) 4041 3826 {
-7
drivers/gpu/drm/i915/display/intel_display.h
··· 56 56 struct intel_encoder; 57 57 struct intel_initial_plane_config; 58 58 struct intel_link_m_n; 59 - struct intel_load_detect_pipe; 60 59 struct intel_plane; 61 60 struct intel_plane_state; 62 61 struct intel_power_domain_mask; ··· 454 455 void vlv_wait_port_ready(struct drm_i915_private *dev_priv, 455 456 struct intel_digital_port *dig_port, 456 457 unsigned int expected_mask); 457 - int intel_get_load_detect_pipe(struct drm_connector *connector, 458 - struct intel_load_detect_pipe *old, 459 - struct drm_modeset_acquire_ctx *ctx); 460 - void intel_release_load_detect_pipe(struct drm_connector *connector, 461 - struct intel_load_detect_pipe *old, 462 - struct drm_modeset_acquire_ctx *ctx); 463 458 struct drm_framebuffer * 464 459 intel_framebuffer_create(struct drm_i915_gem_object *obj, 465 460 struct drm_mode_fb_cmd2 *mode_cmd);
-4
drivers/gpu/drm/i915/display/intel_display_types.h
··· 1838 1838 struct intel_connector *connector; 1839 1839 }; 1840 1840 1841 - struct intel_load_detect_pipe { 1842 - struct drm_atomic_state *restore_state; 1843 - }; 1844 - 1845 1841 static inline struct intel_encoder * 1846 1842 intel_attached_encoder(struct intel_connector *connector) 1847 1843 {
+229
drivers/gpu/drm/i915/display/intel_load_detect.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright © 2023 Intel Corporation 4 + */ 5 + 6 + #include <drm/drm_atomic.h> 7 + #include <drm/drm_atomic_helper.h> 8 + #include <drm/drm_atomic_uapi.h> 9 + 10 + #include "i915_drv.h" 11 + #include "intel_atomic.h" 12 + #include "intel_crtc.h" 13 + #include "intel_display_types.h" 14 + #include "intel_load_detect.h" 15 + 16 + /* VESA 640x480x72Hz mode to set on the pipe */ 17 + static const struct drm_display_mode load_detect_mode = { 18 + DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664, 19 + 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 20 + }; 21 + 22 + static int intel_modeset_disable_planes(struct drm_atomic_state *state, 23 + struct drm_crtc *crtc) 24 + { 25 + struct drm_plane *plane; 26 + struct drm_plane_state *plane_state; 27 + int ret, i; 28 + 29 + ret = drm_atomic_add_affected_planes(state, crtc); 30 + if (ret) 31 + return ret; 32 + 33 + for_each_new_plane_in_state(state, plane, plane_state, i) { 34 + if (plane_state->crtc != crtc) 35 + continue; 36 + 37 + ret = drm_atomic_set_crtc_for_plane(plane_state, NULL); 38 + if (ret) 39 + return ret; 40 + 41 + drm_atomic_set_fb_for_plane(plane_state, NULL); 42 + } 43 + 44 + return 0; 45 + } 46 + 47 + int intel_load_detect_get_pipe(struct drm_connector *connector, 48 + struct intel_load_detect_pipe *old, 49 + struct drm_modeset_acquire_ctx *ctx) 50 + { 51 + struct intel_encoder *encoder = 52 + intel_attached_encoder(to_intel_connector(connector)); 53 + struct intel_crtc *possible_crtc; 54 + struct intel_crtc *crtc = NULL; 55 + struct drm_device *dev = encoder->base.dev; 56 + struct drm_i915_private *dev_priv = to_i915(dev); 57 + struct drm_mode_config *config = &dev->mode_config; 58 + struct drm_atomic_state *state = NULL, *restore_state = NULL; 59 + struct drm_connector_state *connector_state; 60 + struct intel_crtc_state *crtc_state; 61 + int ret; 62 + 63 + drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", 64 + connector->base.id, connector->name, 65 + encoder->base.base.id, encoder->base.name); 66 + 67 + old->restore_state = NULL; 68 + 69 + drm_WARN_ON(dev, !drm_modeset_is_locked(&config->connection_mutex)); 70 + 71 + /* 72 + * Algorithm gets a little messy: 73 + * 74 + * - if the connector already has an assigned crtc, use it (but make 75 + * sure it's on first) 76 + * 77 + * - try to find the first unused crtc that can drive this connector, 78 + * and use that if we find one 79 + */ 80 + 81 + /* See if we already have a CRTC for this connector */ 82 + if (connector->state->crtc) { 83 + crtc = to_intel_crtc(connector->state->crtc); 84 + 85 + ret = drm_modeset_lock(&crtc->base.mutex, ctx); 86 + if (ret) 87 + goto fail; 88 + 89 + /* Make sure the crtc and connector are running */ 90 + goto found; 91 + } 92 + 93 + /* Find an unused one (if possible) */ 94 + for_each_intel_crtc(dev, possible_crtc) { 95 + if (!(encoder->base.possible_crtcs & 96 + drm_crtc_mask(&possible_crtc->base))) 97 + continue; 98 + 99 + ret = drm_modeset_lock(&possible_crtc->base.mutex, ctx); 100 + if (ret) 101 + goto fail; 102 + 103 + if (possible_crtc->base.state->enable) { 104 + drm_modeset_unlock(&possible_crtc->base.mutex); 105 + continue; 106 + } 107 + 108 + crtc = possible_crtc; 109 + break; 110 + } 111 + 112 + /* 113 + * If we didn't find an unused CRTC, don't use any. 114 + */ 115 + if (!crtc) { 116 + drm_dbg_kms(&dev_priv->drm, 117 + "no pipe available for load-detect\n"); 118 + ret = -ENODEV; 119 + goto fail; 120 + } 121 + 122 + found: 123 + state = drm_atomic_state_alloc(dev); 124 + restore_state = drm_atomic_state_alloc(dev); 125 + if (!state || !restore_state) { 126 + ret = -ENOMEM; 127 + goto fail; 128 + } 129 + 130 + state->acquire_ctx = ctx; 131 + to_intel_atomic_state(state)->internal = true; 132 + 133 + restore_state->acquire_ctx = ctx; 134 + to_intel_atomic_state(restore_state)->internal = true; 135 + 136 + connector_state = drm_atomic_get_connector_state(state, connector); 137 + if (IS_ERR(connector_state)) { 138 + ret = PTR_ERR(connector_state); 139 + goto fail; 140 + } 141 + 142 + ret = drm_atomic_set_crtc_for_connector(connector_state, &crtc->base); 143 + if (ret) 144 + goto fail; 145 + 146 + crtc_state = intel_atomic_get_crtc_state(state, crtc); 147 + if (IS_ERR(crtc_state)) { 148 + ret = PTR_ERR(crtc_state); 149 + goto fail; 150 + } 151 + 152 + crtc_state->uapi.active = true; 153 + 154 + ret = drm_atomic_set_mode_for_crtc(&crtc_state->uapi, 155 + &load_detect_mode); 156 + if (ret) 157 + goto fail; 158 + 159 + ret = intel_modeset_disable_planes(state, &crtc->base); 160 + if (ret) 161 + goto fail; 162 + 163 + ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(restore_state, connector)); 164 + if (!ret) 165 + ret = PTR_ERR_OR_ZERO(drm_atomic_get_crtc_state(restore_state, &crtc->base)); 166 + if (!ret) 167 + ret = drm_atomic_add_affected_planes(restore_state, &crtc->base); 168 + if (ret) { 169 + drm_dbg_kms(&dev_priv->drm, 170 + "Failed to create a copy of old state to restore: %i\n", 171 + ret); 172 + goto fail; 173 + } 174 + 175 + ret = drm_atomic_commit(state); 176 + if (ret) { 177 + drm_dbg_kms(&dev_priv->drm, 178 + "failed to set mode on load-detect pipe\n"); 179 + goto fail; 180 + } 181 + 182 + old->restore_state = restore_state; 183 + drm_atomic_state_put(state); 184 + 185 + /* let the connector get through one full cycle before testing */ 186 + intel_crtc_wait_for_next_vblank(crtc); 187 + 188 + return true; 189 + 190 + fail: 191 + if (state) { 192 + drm_atomic_state_put(state); 193 + state = NULL; 194 + } 195 + if (restore_state) { 196 + drm_atomic_state_put(restore_state); 197 + restore_state = NULL; 198 + } 199 + 200 + if (ret == -EDEADLK) 201 + return ret; 202 + 203 + return false; 204 + } 205 + 206 + void intel_load_detect_release_pipe(struct drm_connector *connector, 207 + struct intel_load_detect_pipe *old, 208 + struct drm_modeset_acquire_ctx *ctx) 209 + { 210 + struct intel_encoder *intel_encoder = 211 + intel_attached_encoder(to_intel_connector(connector)); 212 + struct drm_i915_private *i915 = to_i915(intel_encoder->base.dev); 213 + struct drm_encoder *encoder = &intel_encoder->base; 214 + struct drm_atomic_state *state = old->restore_state; 215 + int ret; 216 + 217 + drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", 218 + connector->base.id, connector->name, 219 + encoder->base.id, encoder->name); 220 + 221 + if (!state) 222 + return; 223 + 224 + ret = drm_atomic_helper_commit_duplicated_state(state, ctx); 225 + if (ret) 226 + drm_dbg_kms(&i915->drm, 227 + "Couldn't release load detect pipe: %i\n", ret); 228 + drm_atomic_state_put(state); 229 + }
+24
drivers/gpu/drm/i915/display/intel_load_detect.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Copyright © 2023 Intel Corporation 4 + */ 5 + 6 + #ifndef __INTEL_LOAD_DETECT_H__ 7 + #define __INTEL_LOAD_DETECT_H__ 8 + 9 + struct drm_atomic_state; 10 + struct drm_connector; 11 + struct drm_modeset_acquire_ctx; 12 + 13 + struct intel_load_detect_pipe { 14 + struct drm_atomic_state *restore_state; 15 + }; 16 + 17 + int intel_load_detect_get_pipe(struct drm_connector *connector, 18 + struct intel_load_detect_pipe *old, 19 + struct drm_modeset_acquire_ctx *ctx); 20 + void intel_load_detect_release_pipe(struct drm_connector *connector, 21 + struct intel_load_detect_pipe *old, 22 + struct drm_modeset_acquire_ctx *ctx); 23 + 24 + #endif /* __INTEL_LOAD_DETECT_H__ */
+3 -2
drivers/gpu/drm/i915/display/intel_tv.c
··· 43 43 #include "intel_display_types.h" 44 44 #include "intel_dpll.h" 45 45 #include "intel_hotplug.h" 46 + #include "intel_load_detect.h" 46 47 #include "intel_tv.h" 47 48 #include "intel_tv_regs.h" 48 49 ··· 1726 1725 struct intel_load_detect_pipe tmp; 1727 1726 int ret; 1728 1727 1729 - ret = intel_get_load_detect_pipe(connector, &tmp, ctx); 1728 + ret = intel_load_detect_get_pipe(connector, &tmp, ctx); 1730 1729 if (ret < 0) 1731 1730 return ret; 1732 1731 1733 1732 if (ret > 0) { 1734 1733 type = intel_tv_detect_type(intel_tv, connector); 1735 - intel_release_load_detect_pipe(connector, &tmp, ctx); 1734 + intel_load_detect_release_pipe(connector, &tmp, ctx); 1736 1735 status = type < 0 ? 1737 1736 connector_status_disconnected : 1738 1737 connector_status_connected;