Re: [Intel-gfx] [PATCH 27/24] drm/i915/dp: Add support for HBR3 and TPS4 during link training

2018-05-25 Thread James Ausmus
On Thu, May 24, 2018 at 04:42:38PM -0700, Paulo Zanoni wrote:
> From: Manasi Navare 
> 
> DP spec 1.4 supports training pattern set 4 (TPS4) for HBR3 link
> rate. This will be used in link training's channel equalization
> phase if supported by both source and sink.
> This patch adds the helpers to check if HBR3 is supported and uses
> TPS4 in training pattern selection during link training.
> 
> Cc: James Ausmus 
> Cc: Rodrigo Vivi 
> Cc: Jani Nikula 
> Signed-off-by: Manasi Navare 

Reviewed-by: James Ausmus 

> ---
>  drivers/gpu/drm/i915/i915_reg.h   |  1 +
>  drivers/gpu/drm/i915/intel_dp.c   | 17 +---
>  drivers/gpu/drm/i915/intel_dp_link_training.c | 39 
> +++
>  drivers/gpu/drm/i915/intel_drv.h  |  1 +
>  4 files changed, 44 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index e48b717769b2..ae7070c0806d 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -8791,6 +8791,7 @@ enum skl_power_gate {
>  #define  DP_TP_CTL_LINK_TRAIN_PAT1   (0<<8)
>  #define  DP_TP_CTL_LINK_TRAIN_PAT2   (1<<8)
>  #define  DP_TP_CTL_LINK_TRAIN_PAT3   (4<<8)
> +#define  DP_TP_CTL_LINK_TRAIN_PAT4   (5<<8)
>  #define  DP_TP_CTL_LINK_TRAIN_IDLE   (2<<8)
>  #define  DP_TP_CTL_LINK_TRAIN_NORMAL (3<<8)
>  #define  DP_TP_CTL_SCRAMBLE_DISABLE  (1<<7)
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 3ee8e74cf2b8..bcc3f330b301 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1721,6 +1721,13 @@ bool intel_dp_source_supports_hbr2(struct intel_dp 
> *intel_dp)
>   return max_rate >= 54;
>  }
>  
> +bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp)
> +{
> + int max_rate = intel_dp->source_rates[intel_dp->num_source_rates - 1];
> +
> + return max_rate >= 81;
> +}
> +
>  static void
>  intel_dp_set_clock(struct intel_encoder *encoder,
>  struct intel_crtc_state *pipe_config)
> @@ -3046,10 +3053,11 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
>   struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
>   struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>   enum port port = intel_dig_port->base.port;
> + uint8_t train_pat_mask = drm_dp_training_pattern_mask(intel_dp->dpcd);
>  
> - if (dp_train_pat & DP_TRAINING_PATTERN_MASK)
> + if (dp_train_pat & train_pat_mask)
>   DRM_DEBUG_KMS("Using DP training pattern TPS%d\n",
> -   dp_train_pat & DP_TRAINING_PATTERN_MASK);
> +   dp_train_pat & train_pat_mask);
>  
>   if (HAS_DDI(dev_priv)) {
>   uint32_t temp = I915_READ(DP_TP_CTL(port));
> @@ -3060,7 +3068,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
>   temp &= ~DP_TP_CTL_SCRAMBLE_DISABLE;
>  
>   temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
> - switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
> + switch (dp_train_pat & train_pat_mask) {
>   case DP_TRAINING_PATTERN_DISABLE:
>   temp |= DP_TP_CTL_LINK_TRAIN_NORMAL;
>  
> @@ -3074,6 +3082,9 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
>   case DP_TRAINING_PATTERN_3:
>   temp |= DP_TP_CTL_LINK_TRAIN_PAT3;
>   break;
> + case DP_TRAINING_PATTERN_4:
> + temp |= DP_TP_CTL_LINK_TRAIN_PAT4;
> + break;
>   }
>   I915_WRITE(DP_TP_CTL(port), temp);
>  
> diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c 
> b/drivers/gpu/drm/i915/intel_dp_link_training.c
> index 3fcaa98b9055..4da6e33c7fa1 100644
> --- a/drivers/gpu/drm/i915/intel_dp_link_training.c
> +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
> @@ -219,14 +219,30 @@ intel_dp_link_training_clock_recovery(struct intel_dp 
> *intel_dp)
>  }
>  
>  /*
> - * Pick training pattern for channel equalization. Training Pattern 3 for 
> HBR2
> + * Pick training pattern for channel equalization. Training pattern 4 for 
> HBR3
> + * or for 1.4 devices that support it, training Pattern 3 for HBR2
>   * or 1.2 devices that support it, Training Pattern 2 otherwise.
>   */
>  static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
>  {
> - u32 training_pattern = DP_TRAINING_PATTERN_2;
> - bool source_tps3, sink_tps3;
> + bool source_tps3, sink_tps3, source_tps4, sink_tps4;
>  
> + /*
> +  * Intel platforms that support HBR3 also support TPS4. It is mandatory
> +  * for all downstream devices that support HBR3. There are no known eDP
> +  

[Intel-gfx] [PATCH 27/24] drm/i915/dp: Add support for HBR3 and TPS4 during link training

2018-05-24 Thread Paulo Zanoni
From: Manasi Navare 

DP spec 1.4 supports training pattern set 4 (TPS4) for HBR3 link
rate. This will be used in link training's channel equalization
phase if supported by both source and sink.
This patch adds the helpers to check if HBR3 is supported and uses
TPS4 in training pattern selection during link training.

Cc: James Ausmus 
Cc: Rodrigo Vivi 
Cc: Jani Nikula 
Signed-off-by: Manasi Navare 
---
 drivers/gpu/drm/i915/i915_reg.h   |  1 +
 drivers/gpu/drm/i915/intel_dp.c   | 17 +---
 drivers/gpu/drm/i915/intel_dp_link_training.c | 39 +++
 drivers/gpu/drm/i915/intel_drv.h  |  1 +
 4 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e48b717769b2..ae7070c0806d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -8791,6 +8791,7 @@ enum skl_power_gate {
 #define  DP_TP_CTL_LINK_TRAIN_PAT1 (0<<8)
 #define  DP_TP_CTL_LINK_TRAIN_PAT2 (1<<8)
 #define  DP_TP_CTL_LINK_TRAIN_PAT3 (4<<8)
+#define  DP_TP_CTL_LINK_TRAIN_PAT4 (5<<8)
 #define  DP_TP_CTL_LINK_TRAIN_IDLE (2<<8)
 #define  DP_TP_CTL_LINK_TRAIN_NORMAL   (3<<8)
 #define  DP_TP_CTL_SCRAMBLE_DISABLE(1<<7)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 3ee8e74cf2b8..bcc3f330b301 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1721,6 +1721,13 @@ bool intel_dp_source_supports_hbr2(struct intel_dp 
*intel_dp)
return max_rate >= 54;
 }
 
+bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp)
+{
+   int max_rate = intel_dp->source_rates[intel_dp->num_source_rates - 1];
+
+   return max_rate >= 81;
+}
+
 static void
 intel_dp_set_clock(struct intel_encoder *encoder,
   struct intel_crtc_state *pipe_config)
@@ -3046,10 +3053,11 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
enum port port = intel_dig_port->base.port;
+   uint8_t train_pat_mask = drm_dp_training_pattern_mask(intel_dp->dpcd);
 
-   if (dp_train_pat & DP_TRAINING_PATTERN_MASK)
+   if (dp_train_pat & train_pat_mask)
DRM_DEBUG_KMS("Using DP training pattern TPS%d\n",
- dp_train_pat & DP_TRAINING_PATTERN_MASK);
+ dp_train_pat & train_pat_mask);
 
if (HAS_DDI(dev_priv)) {
uint32_t temp = I915_READ(DP_TP_CTL(port));
@@ -3060,7 +3068,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
temp &= ~DP_TP_CTL_SCRAMBLE_DISABLE;
 
temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
-   switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
+   switch (dp_train_pat & train_pat_mask) {
case DP_TRAINING_PATTERN_DISABLE:
temp |= DP_TP_CTL_LINK_TRAIN_NORMAL;
 
@@ -3074,6 +3082,9 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
case DP_TRAINING_PATTERN_3:
temp |= DP_TP_CTL_LINK_TRAIN_PAT3;
break;
+   case DP_TRAINING_PATTERN_4:
+   temp |= DP_TP_CTL_LINK_TRAIN_PAT4;
+   break;
}
I915_WRITE(DP_TP_CTL(port), temp);
 
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c 
b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 3fcaa98b9055..4da6e33c7fa1 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -219,14 +219,30 @@ intel_dp_link_training_clock_recovery(struct intel_dp 
*intel_dp)
 }
 
 /*
- * Pick training pattern for channel equalization. Training Pattern 3 for HBR2
+ * Pick training pattern for channel equalization. Training pattern 4 for HBR3
+ * or for 1.4 devices that support it, training Pattern 3 for HBR2
  * or 1.2 devices that support it, Training Pattern 2 otherwise.
  */
 static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
 {
-   u32 training_pattern = DP_TRAINING_PATTERN_2;
-   bool source_tps3, sink_tps3;
+   bool source_tps3, sink_tps3, source_tps4, sink_tps4;
 
+   /*
+* Intel platforms that support HBR3 also support TPS4. It is mandatory
+* for all downstream devices that support HBR3. There are no known eDP
+* panels that support TPS4 as of Feb 2018 as per VESA eDP_v1.4b_E1
+* specification.
+*/
+   source_tps4 = intel_dp_source_supports_hbr3(intel_dp);
+   sink_tps4 = drm_dp_tps4_supported(intel_dp->dpcd);
+   if (source_tps4 &&