diff mbox

drm/sun4i: validate modes for HDMI

Message ID 50a4a5fd-d111-616a-8793-b5f68fea85f8@xs4all.nl (mailing list archive)
State New, archived
Headers show

Commit Message

Hans Verkuil Dec. 8, 2017, 3:45 p.m. UTC
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.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---

Comments

Hans Verkuil Dec. 8, 2017, 3:48 p.m. UTC | #1
Please ignore, this patch was on top of my old hack instead of being a proper patch.
I'll resend.

	Hans

On 12/08/2017 04:45 PM, Hans Verkuil wrote:
> 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.
> 
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> index 6d19d2ac68d1..62d52102d0f7 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> @@ -211,7 +211,17 @@ static int sun4i_hdmi_get_modes(struct drm_connector *connector)
>  static int sun4i_hdmi_mode_valid(struct drm_connector *connector,
>  				 struct drm_display_mode *mode)
>  {
> -	if (mode->clock > 170000)
> +	struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
> +	unsigned long rate = mode->clock * 1000;
> +	long rounded_rate;
> +
> +	/* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */
> +	if (rate > 165000000)
> +		return MODE_CLOCK_HIGH;
> +	rounded_rate = clk_round_rate(hdmi->tmds_clk, rate);
> +	if (rounded_rate < rate)
> +		return MODE_CLOCK_LOW;
> +	if (rounded_rate > rate)
>  		return MODE_CLOCK_HIGH;
>  	return MODE_OK;
>  }
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 6d19d2ac68d1..62d52102d0f7 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -211,7 +211,17 @@  static int sun4i_hdmi_get_modes(struct drm_connector *connector)
 static int sun4i_hdmi_mode_valid(struct drm_connector *connector,
 				 struct drm_display_mode *mode)
 {
-	if (mode->clock > 170000)
+	struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
+	unsigned long rate = mode->clock * 1000;
+	long rounded_rate;
+
+	/* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */
+	if (rate > 165000000)
+		return MODE_CLOCK_HIGH;
+	rounded_rate = clk_round_rate(hdmi->tmds_clk, rate);
+	if (rounded_rate < rate)
+		return MODE_CLOCK_LOW;
+	if (rounded_rate > rate)
 		return MODE_CLOCK_HIGH;
 	return MODE_OK;
 }