diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2017-12-15 10:21:50 -0500 |
---|---|---|
committer | Maxime Ripard <maxime.ripard@free-electrons.com> | 2017-12-15 16:24:03 -0500 |
commit | caea4f384858ee7861367920df36995e7acfe160 (patch) | |
tree | 65b7874cc1664af83df979e728ea7658dc9c8812 | |
parent | bd36d3bab2e3d08f80766c86487090dbceed4651 (diff) |
drm/sun4i: validate modes for HDMI
When I connected my cubieboard running 4.15-rc1 to my 4k display I got no
picture. Some digging found that there is no check against the upper
pixelclock limit of the HDMI output, so X selects a 4kp60 format at 594
MHz, which obviously won't work.
The patch below adds a check for the upper bound of what this hardware can
do, and it checks if the requested tmds clock can be obtained.
It also allows for the +/- 0.5% pixel clock variation that the HDMI spec permits.
That code is based on commit 22d0be2a557e ("drm: arcpgu: Allow some clock
deviation in crtc->mode_valid() callback") from Jose Abreu for drm/arc.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Thanks-to: Jose Abreu <Jose.Abreu@synopsys.com>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Link: https://patchwork.freedesktop.org/patch/msgid/162854cb-c7bd-d9ce-9fa0-9a6cd89c621b@xs4all.nl
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index dda904ec0534..c12f9bd12904 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | |||
@@ -208,8 +208,27 @@ static int sun4i_hdmi_get_modes(struct drm_connector *connector) | |||
208 | return ret; | 208 | return ret; |
209 | } | 209 | } |
210 | 210 | ||
211 | static int sun4i_hdmi_mode_valid(struct drm_connector *connector, | ||
212 | struct drm_display_mode *mode) | ||
213 | { | ||
214 | struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector); | ||
215 | long rate = mode->clock * 1000; | ||
216 | long diff = rate / 200; /* +-0.5% allowed by HDMI spec */ | ||
217 | long rounded_rate; | ||
218 | |||
219 | /* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */ | ||
220 | if (rate > 165000000) | ||
221 | return MODE_CLOCK_HIGH; | ||
222 | rounded_rate = clk_round_rate(hdmi->tmds_clk, rate); | ||
223 | if (max(rounded_rate, rate) - min(rounded_rate, rate) < diff && | ||
224 | rounded_rate > 0) | ||
225 | return MODE_OK; | ||
226 | return MODE_NOCLOCK; | ||
227 | } | ||
228 | |||
211 | static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = { | 229 | static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = { |
212 | .get_modes = sun4i_hdmi_get_modes, | 230 | .get_modes = sun4i_hdmi_get_modes, |
231 | .mode_valid = sun4i_hdmi_mode_valid, | ||
213 | }; | 232 | }; |
214 | 233 | ||
215 | static enum drm_connector_status | 234 | static enum drm_connector_status |