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

drm/sun4i: hdmi: Move the mode_valid callback to the encoder

When attached to the connector, the mode_valid callback will only filter
the modes provided by the connector itself as part of its probe.

However, it will not be doing it when the mode is provided by the
userspace, which still might result in a broken configuration.

In order to enforce these constraints, move our mode_valid callback to the
encoder which doesn't have this behaviour.

Acked-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
[maxime: Wrote the commit log in order to update the patch from the merged
v3 to the v4 that was correct.]
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Link: https://patchwork.freedesktop.org/patch/msgid/0fa230a8-d01d-561a-f74f-6b4fd421255b@xs4all.nl

+20 -19
+20 -19
drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
··· 175 175 writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG); 176 176 } 177 177 178 + static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder, 179 + const struct drm_display_mode *mode) 180 + { 181 + struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); 182 + unsigned long rate = mode->clock * 1000; 183 + unsigned long diff = rate / 200; /* +-0.5% allowed by HDMI spec */ 184 + long rounded_rate; 185 + 186 + /* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */ 187 + if (rate > 165000000) 188 + return MODE_CLOCK_HIGH; 189 + rounded_rate = clk_round_rate(hdmi->tmds_clk, rate); 190 + if (rounded_rate > 0 && 191 + max_t(unsigned long, rounded_rate, rate) - 192 + min_t(unsigned long, rounded_rate, rate) < diff) 193 + return MODE_OK; 194 + return MODE_NOCLOCK; 195 + } 196 + 178 197 static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = { 179 198 .atomic_check = sun4i_hdmi_atomic_check, 180 199 .disable = sun4i_hdmi_disable, 181 200 .enable = sun4i_hdmi_enable, 182 201 .mode_set = sun4i_hdmi_mode_set, 202 + .mode_valid = sun4i_hdmi_mode_valid, 183 203 }; 184 204 185 205 static const struct drm_encoder_funcs sun4i_hdmi_funcs = { ··· 228 208 return ret; 229 209 } 230 210 231 - static int sun4i_hdmi_mode_valid(struct drm_connector *connector, 232 - struct drm_display_mode *mode) 233 - { 234 - struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector); 235 - long rate = mode->clock * 1000; 236 - long diff = rate / 200; /* +-0.5% allowed by HDMI spec */ 237 - long rounded_rate; 238 - 239 - /* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */ 240 - if (rate > 165000000) 241 - return MODE_CLOCK_HIGH; 242 - rounded_rate = clk_round_rate(hdmi->tmds_clk, rate); 243 - if (max(rounded_rate, rate) - min(rounded_rate, rate) < diff && 244 - rounded_rate > 0) 245 - return MODE_OK; 246 - return MODE_NOCLOCK; 247 - } 248 - 249 211 static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = { 250 212 .get_modes = sun4i_hdmi_get_modes, 251 - .mode_valid = sun4i_hdmi_mode_valid, 252 213 }; 253 214 254 215 static enum drm_connector_status