diff mbox

[Trusty,SRU] drm/i915: Allow user modes to exceed DVI 165MHz limit

Message ID 1403202152-2734-1-git-send-email-tim.gardner@canonical.com
State New
Headers show

Commit Message

Tim Gardner June 19, 2014, 6:22 p.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

BugLink: http://bugs.launchpad.net/bugs/1332220

In commit
 commit 6375b768a9850b6154478993e5fb566fa4614a9c
 Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
 Date:   Mon Mar 3 11:33:36 2014 +0200

    drm/i915: Reject >165MHz modes w/ DVI monitors

the driver started to filter out display modes which exceed the
single-link DVI 165Mz dotclock limits when the monitor doesn't report
itself as being HDMI compliant. The intent was to filter out all
EDID derived modes that require dual-link DVI to operate since we
don't support dual-link.

However the patch went a bit too far and also causes the driver to reject
such modes even when specified by the user. Normally we don't check the
sink limitations when setting a mode from the user. This allows the user
to specify any mode whether the sink reports to support it or not. This
can be useful since often the sinks support more modes than they report
in the EDID.

So relax the checks a bit, and apply the single-link DVI dotclock limit
only when filtering the mode list, and ignore the limit when setting
a user specified mode.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=72961
Tested-by: Nicholas Vinson <nvinson@comcast.net>
Cc: stable@vger.kernel.org [3.14]
Reviewed-by: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
(cherry picked from commit 40478455fefdc0bde24ae872c3f88d58a1b0e435)
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
---

testing appears to imply that this patch also works for 3.13.

 drivers/gpu/drm/i915/intel_hdmi.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

Comments

Andy Whitcroft June 19, 2014, 7:31 p.m. UTC | #1
On Thu, Jun 19, 2014 at 12:22:32PM -0600, Tim Gardner wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> BugLink: http://bugs.launchpad.net/bugs/1332220
> 
> In commit
>  commit 6375b768a9850b6154478993e5fb566fa4614a9c
>  Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
>  Date:   Mon Mar 3 11:33:36 2014 +0200
> 
>     drm/i915: Reject >165MHz modes w/ DVI monitors
> 
> the driver started to filter out display modes which exceed the
> single-link DVI 165Mz dotclock limits when the monitor doesn't report
> itself as being HDMI compliant. The intent was to filter out all
> EDID derived modes that require dual-link DVI to operate since we
> don't support dual-link.
> 
> However the patch went a bit too far and also causes the driver to reject
> such modes even when specified by the user. Normally we don't check the
> sink limitations when setting a mode from the user. This allows the user
> to specify any mode whether the sink reports to support it or not. This
> can be useful since often the sinks support more modes than they report
> in the EDID.
> 
> So relax the checks a bit, and apply the single-link DVI dotclock limit
> only when filtering the mode list, and ignore the limit when setting
> a user specified mode.
> 
> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=72961
> Tested-by: Nicholas Vinson <nvinson@comcast.net>
> Cc: stable@vger.kernel.org [3.14]
> Reviewed-by: Daniel Vetter <daniel@ffwll.ch>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> (cherry picked from commit 40478455fefdc0bde24ae872c3f88d58a1b0e435)
> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
> ---
> 
> testing appears to imply that this patch also works for 3.13.
> 
>  drivers/gpu/drm/i915/intel_hdmi.c | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index bb850b3..4f4a174 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -841,11 +841,11 @@ static void intel_disable_hdmi(struct intel_encoder *encoder)
>  	}
>  }
>  
> -static int hdmi_portclock_limit(struct intel_hdmi *hdmi)
> +static int hdmi_portclock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit)
>  {
>  	struct drm_device *dev = intel_hdmi_to_dev(hdmi);
>  
> -	if (!hdmi->has_hdmi_sink || IS_G4X(dev))
> +	if ((respect_dvi_limit && !hdmi->has_hdmi_sink) || IS_G4X(dev))
>  		return 165000;
>  	else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8)
>  		return 300000;
> @@ -856,7 +856,8 @@ static int hdmi_portclock_limit(struct intel_hdmi *hdmi)
>  static int intel_hdmi_mode_valid(struct drm_connector *connector,
>  				 struct drm_display_mode *mode)
>  {
> -	if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector)))
> +	if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector),
> +					       true))
>  		return MODE_CLOCK_HIGH;
>  	if (mode->clock < 20000)
>  		return MODE_CLOCK_LOW;
> @@ -874,7 +875,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
>  	int clock_12bpc = pipe_config->adjusted_mode.crtc_clock * 3 / 2;
> -	int portclock_limit = hdmi_portclock_limit(intel_hdmi);
> +	int portclock_limit = hdmi_portclock_limit(intel_hdmi, false);
>  	int desired_bpp;
>  
>  	if (intel_hdmi->color_range_auto) {

Looks reasonable.

Acked-by: Andy Whitcroft <apw@canonical.com>

-apw
Tim Gardner June 19, 2014, 7:35 p.m. UTC | #2

diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index bb850b3..4f4a174 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -841,11 +841,11 @@  static void intel_disable_hdmi(struct intel_encoder *encoder)
 	}
 }
 
-static int hdmi_portclock_limit(struct intel_hdmi *hdmi)
+static int hdmi_portclock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit)
 {
 	struct drm_device *dev = intel_hdmi_to_dev(hdmi);
 
-	if (!hdmi->has_hdmi_sink || IS_G4X(dev))
+	if ((respect_dvi_limit && !hdmi->has_hdmi_sink) || IS_G4X(dev))
 		return 165000;
 	else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8)
 		return 300000;
@@ -856,7 +856,8 @@  static int hdmi_portclock_limit(struct intel_hdmi *hdmi)
 static int intel_hdmi_mode_valid(struct drm_connector *connector,
 				 struct drm_display_mode *mode)
 {
-	if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector)))
+	if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector),
+					       true))
 		return MODE_CLOCK_HIGH;
 	if (mode->clock < 20000)
 		return MODE_CLOCK_LOW;
@@ -874,7 +875,7 @@  bool intel_hdmi_compute_config(struct intel_encoder *encoder,
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
 	int clock_12bpc = pipe_config->adjusted_mode.crtc_clock * 3 / 2;
-	int portclock_limit = hdmi_portclock_limit(intel_hdmi);
+	int portclock_limit = hdmi_portclock_limit(intel_hdmi, false);
 	int desired_bpp;
 
 	if (intel_hdmi->color_range_auto) {