diff mbox

[4/4] drm/i915: Detect USB-C specific dongles before reducing M and N

Message ID 289a55a53f8b52a252e06f76991e3facaa24a571.1495030890.git.jani.nikula@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jani Nikula May 17, 2017, 2:25 p.m. UTC
The Analogix 7737 DP to HDMI converter requires reduced M and N values
when to operate correctly at HBR2. Detect this IC by its OUI value of
0x0022B9 via the DPCD quirk list.

v2 by Jani: Rebased on the DP quirk database

v3 by Jani: Rebased on the reworked DP quirk database

Fixes: 9a86cda07af2 ("drm/i915/dp: reduce link M/N parameters")
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93578
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100755
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  3 ++-
 drivers/gpu/drm/i915/intel_display.c | 22 ++++++++++++++--------
 drivers/gpu/drm/i915/intel_dp.c      |  8 ++++++--
 drivers/gpu/drm/i915/intel_dp_mst.c  |  5 ++++-
 4 files changed, 26 insertions(+), 12 deletions(-)

Comments

Daniel Vetter May 18, 2017, 6:09 a.m. UTC | #1
On Wed, May 17, 2017 at 05:25:16PM +0300, Jani Nikula wrote:
> The Analogix 7737 DP to HDMI converter requires reduced M and N values
> when to operate correctly at HBR2. Detect this IC by its OUI value of
> 0x0022B9 via the DPCD quirk list.

Commit message is a bit confusing since this sounds like you're fixing
things for the offending analogix bridge, but what this does is fix things
for other broken chips. That part is only clear when looking at the Fixes:
commit and bug reports.

With the commit message fixed up to make this clear:

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Also patches 1&3 look good now, also Reviewed-by: Daniel Vetter
<daniel.vetter@ffwll.ch> for those.

Cheers, Daniel

> 
> v2 by Jani: Rebased on the DP quirk database
> 
> v3 by Jani: Rebased on the reworked DP quirk database
> 
> Fixes: 9a86cda07af2 ("drm/i915/dp: reduce link M/N parameters")
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93578
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100755
> Cc: Jani Nikula <jani.nikula@intel.com>
> Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  3 ++-
>  drivers/gpu/drm/i915/intel_display.c | 22 ++++++++++++++--------
>  drivers/gpu/drm/i915/intel_dp.c      |  8 ++++++--
>  drivers/gpu/drm/i915/intel_dp_mst.c  |  5 ++++-
>  4 files changed, 26 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index a6f20471b4cd..699e07362044 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -563,7 +563,8 @@ struct intel_link_m_n {
>  
>  void intel_link_compute_m_n(int bpp, int nlanes,
>  			    int pixel_clock, int link_clock,
> -			    struct intel_link_m_n *m_n);
> +			    struct intel_link_m_n *m_n,
> +			    bool reduce_m_n);
>  
>  /* Interface history:
>   *
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 8217ed0e7132..ea4f116bd410 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -6116,7 +6116,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>  	pipe_config->fdi_lanes = lane;
>  
>  	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
> -			       link_bw, &pipe_config->fdi_m_n);
> +			       link_bw, &pipe_config->fdi_m_n, false);
>  
>  	ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
>  	if (ret == -EINVAL && pipe_config->pipe_bpp > 6*3) {
> @@ -6292,7 +6292,8 @@ intel_reduce_m_n_ratio(uint32_t *num, uint32_t *den)
>  }
>  
>  static void compute_m_n(unsigned int m, unsigned int n,
> -			uint32_t *ret_m, uint32_t *ret_n)
> +			uint32_t *ret_m, uint32_t *ret_n,
> +			bool reduce_m_n)
>  {
>  	/*
>  	 * Reduce M/N as much as possible without loss in precision. Several DP
> @@ -6300,9 +6301,11 @@ static void compute_m_n(unsigned int m, unsigned int n,
>  	 * values. The passed in values are more likely to have the least
>  	 * significant bits zero than M after rounding below, so do this first.
>  	 */
> -	while ((m & 1) == 0 && (n & 1) == 0) {
> -		m >>= 1;
> -		n >>= 1;
> +	if (reduce_m_n) {
> +		while ((m & 1) == 0 && (n & 1) == 0) {
> +			m >>= 1;
> +			n >>= 1;
> +		}
>  	}
>  
>  	*ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX);
> @@ -6313,16 +6316,19 @@ static void compute_m_n(unsigned int m, unsigned int n,
>  void
>  intel_link_compute_m_n(int bits_per_pixel, int nlanes,
>  		       int pixel_clock, int link_clock,
> -		       struct intel_link_m_n *m_n)
> +		       struct intel_link_m_n *m_n,
> +		       bool reduce_m_n)
>  {
>  	m_n->tu = 64;
>  
>  	compute_m_n(bits_per_pixel * pixel_clock,
>  		    link_clock * nlanes * 8,
> -		    &m_n->gmch_m, &m_n->gmch_n);
> +		    &m_n->gmch_m, &m_n->gmch_n,
> +		    reduce_m_n);
>  
>  	compute_m_n(pixel_clock, link_clock,
> -		    &m_n->link_m, &m_n->link_n);
> +		    &m_n->link_m, &m_n->link_n,
> +		    reduce_m_n);
>  }
>  
>  static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 2a5f385e8f44..1ae9de5cf39c 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1627,6 +1627,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  	int link_avail, link_clock;
>  	int common_len;
>  	uint8_t link_bw, rate_select;
> +	bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc,
> +					   DP_DPCD_QUIRK_LIMITED_M_N);
>  
>  	common_len = intel_dp_common_len_rate_limit(intel_dp,
>  						    intel_dp->max_link_rate);
> @@ -1759,7 +1761,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  	intel_link_compute_m_n(bpp, lane_count,
>  			       adjusted_mode->crtc_clock,
>  			       pipe_config->port_clock,
> -			       &pipe_config->dp_m_n);
> +			       &pipe_config->dp_m_n,
> +			       reduce_m_n);
>  
>  	if (intel_connector->panel.downclock_mode != NULL &&
>  		dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
> @@ -1767,7 +1770,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  			intel_link_compute_m_n(bpp, lane_count,
>  				intel_connector->panel.downclock_mode->clock,
>  				pipe_config->port_clock,
> -				&pipe_config->dp_m2_n2);
> +				&pipe_config->dp_m2_n2,
> +				reduce_m_n);
>  	}
>  
>  	/*
> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
> index 68c788eb0b95..125917cebc60 100644
> --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> @@ -44,6 +44,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
>  	int lane_count, slots;
>  	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>  	int mst_pbn;
> +	bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc,
> +					   DP_DPCD_QUIRK_LIMITED_M_N);
>  
>  	pipe_config->has_pch_encoder = false;
>  	bpp = 24;
> @@ -79,7 +81,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
>  	intel_link_compute_m_n(bpp, lane_count,
>  			       adjusted_mode->crtc_clock,
>  			       pipe_config->port_clock,
> -			       &pipe_config->dp_m_n);
> +			       &pipe_config->dp_m_n,
> +			       reduce_m_n);
>  
>  	pipe_config->dp_m_n.tu = slots;
>  
> -- 
> 2.11.0
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a6f20471b4cd..699e07362044 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -563,7 +563,8 @@  struct intel_link_m_n {
 
 void intel_link_compute_m_n(int bpp, int nlanes,
 			    int pixel_clock, int link_clock,
-			    struct intel_link_m_n *m_n);
+			    struct intel_link_m_n *m_n,
+			    bool reduce_m_n);
 
 /* Interface history:
  *
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8217ed0e7132..ea4f116bd410 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6116,7 +6116,7 @@  static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
 	pipe_config->fdi_lanes = lane;
 
 	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
-			       link_bw, &pipe_config->fdi_m_n);
+			       link_bw, &pipe_config->fdi_m_n, false);
 
 	ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
 	if (ret == -EINVAL && pipe_config->pipe_bpp > 6*3) {
@@ -6292,7 +6292,8 @@  intel_reduce_m_n_ratio(uint32_t *num, uint32_t *den)
 }
 
 static void compute_m_n(unsigned int m, unsigned int n,
-			uint32_t *ret_m, uint32_t *ret_n)
+			uint32_t *ret_m, uint32_t *ret_n,
+			bool reduce_m_n)
 {
 	/*
 	 * Reduce M/N as much as possible without loss in precision. Several DP
@@ -6300,9 +6301,11 @@  static void compute_m_n(unsigned int m, unsigned int n,
 	 * values. The passed in values are more likely to have the least
 	 * significant bits zero than M after rounding below, so do this first.
 	 */
-	while ((m & 1) == 0 && (n & 1) == 0) {
-		m >>= 1;
-		n >>= 1;
+	if (reduce_m_n) {
+		while ((m & 1) == 0 && (n & 1) == 0) {
+			m >>= 1;
+			n >>= 1;
+		}
 	}
 
 	*ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX);
@@ -6313,16 +6316,19 @@  static void compute_m_n(unsigned int m, unsigned int n,
 void
 intel_link_compute_m_n(int bits_per_pixel, int nlanes,
 		       int pixel_clock, int link_clock,
-		       struct intel_link_m_n *m_n)
+		       struct intel_link_m_n *m_n,
+		       bool reduce_m_n)
 {
 	m_n->tu = 64;
 
 	compute_m_n(bits_per_pixel * pixel_clock,
 		    link_clock * nlanes * 8,
-		    &m_n->gmch_m, &m_n->gmch_n);
+		    &m_n->gmch_m, &m_n->gmch_n,
+		    reduce_m_n);
 
 	compute_m_n(pixel_clock, link_clock,
-		    &m_n->link_m, &m_n->link_n);
+		    &m_n->link_m, &m_n->link_n,
+		    reduce_m_n);
 }
 
 static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 2a5f385e8f44..1ae9de5cf39c 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1627,6 +1627,8 @@  intel_dp_compute_config(struct intel_encoder *encoder,
 	int link_avail, link_clock;
 	int common_len;
 	uint8_t link_bw, rate_select;
+	bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc,
+					   DP_DPCD_QUIRK_LIMITED_M_N);
 
 	common_len = intel_dp_common_len_rate_limit(intel_dp,
 						    intel_dp->max_link_rate);
@@ -1759,7 +1761,8 @@  intel_dp_compute_config(struct intel_encoder *encoder,
 	intel_link_compute_m_n(bpp, lane_count,
 			       adjusted_mode->crtc_clock,
 			       pipe_config->port_clock,
-			       &pipe_config->dp_m_n);
+			       &pipe_config->dp_m_n,
+			       reduce_m_n);
 
 	if (intel_connector->panel.downclock_mode != NULL &&
 		dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
@@ -1767,7 +1770,8 @@  intel_dp_compute_config(struct intel_encoder *encoder,
 			intel_link_compute_m_n(bpp, lane_count,
 				intel_connector->panel.downclock_mode->clock,
 				pipe_config->port_clock,
-				&pipe_config->dp_m2_n2);
+				&pipe_config->dp_m2_n2,
+				reduce_m_n);
 	}
 
 	/*
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 68c788eb0b95..125917cebc60 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -44,6 +44,8 @@  static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 	int lane_count, slots;
 	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 	int mst_pbn;
+	bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc,
+					   DP_DPCD_QUIRK_LIMITED_M_N);
 
 	pipe_config->has_pch_encoder = false;
 	bpp = 24;
@@ -79,7 +81,8 @@  static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 	intel_link_compute_m_n(bpp, lane_count,
 			       adjusted_mode->crtc_clock,
 			       pipe_config->port_clock,
-			       &pipe_config->dp_m_n);
+			       &pipe_config->dp_m_n,
+			       reduce_m_n);
 
 	pipe_config->dp_m_n.tu = slots;