All of lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code
@ 2020-05-06 11:23 Ville Syrjala
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 1/9] drm/i915: Fix cpt/ppt max pre-emphasis Ville Syrjala
                   ` (11 more replies)
  0 siblings, 12 replies; 15+ messages in thread
From: Ville Syrjala @ 2020-05-06 11:23 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Final pieces for plumbing the crtc state all the way down to the guts of
the link trainign code. Allows us to eliminate a bunch of adhoc state
from intel_dp, and nukes some of the remaining crtc->config usages.

I'm also fixing the DP spec violations around the vswing/pre-emphasis
selection. Someone pointed that issue out a while ago but there was
never any followup to that discussion AFAICS.

I had to neuter the phy test code since it has snuck in some duplicated
low level modeset code straight into the short hpd handler in intel_dp.c,
which is definitely not the way we want to do things. So that stuff
needs a real redesign at some point.

Ville Syrjälä (9):
  drm/i915: Fix cpt/ppt max pre-emphasis
  drm/i915: Fix ibx max vswing/preemph
  drm/i915: Fix ivb cpu edp vswing
  drm/i915: Add {preemph,voltage}_max() vfuncs
  drm/i915: Reverse preemph vs. voltage swing preference
  drm/i915: Fix DP_TRAIN_MAX_{PRE_EMPHASIS,SWING}_REACHED handling
  drm/i915: Replace some hand rolled max()s
  drm/i915: Plumb crtc_state to link training
  drm/i915: Eliminate intel_dp.regs.dp_tp_{ctl,status}

 drivers/gpu/drm/i915/display/intel_ddi.c      | 454 +++++++++---------
 drivers/gpu/drm/i915/display/intel_ddi.h      |  14 +-
 .../drm/i915/display/intel_display_types.h    |  26 +-
 drivers/gpu/drm/i915/display/intel_dp.c       | 216 +++++----
 drivers/gpu/drm/i915/display/intel_dp.h       |  15 +-
 .../drm/i915/display/intel_dp_link_training.c | 136 +++---
 .../drm/i915/display/intel_dp_link_training.h |   7 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  10 +-
 drivers/gpu/drm/i915/display/intel_dpio_phy.c |  23 +-
 drivers/gpu/drm/i915/display/intel_dpio_phy.h |   2 +
 drivers/gpu/drm/i915/display/intel_hdmi.c     |   7 +-
 11 files changed, 467 insertions(+), 443 deletions(-)

-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Intel-gfx] [PATCH 1/9] drm/i915: Fix cpt/ppt max pre-emphasis
  2020-05-06 11:23 [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code Ville Syrjala
@ 2020-05-06 11:23 ` Ville Syrjala
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 2/9] drm/i915: Fix ibx max vswing/preemph Ville Syrjala
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Ville Syrjala @ 2020-05-06 11:23 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

cpt/ppt support pre-emphasis level 3. Let's actually declare
support for it, instead of clamping things to level 2.

Also tweak the if-ladder in intel_dp_voltage_max() to match
intel_dp_pre_emphasis_max() to make it easier to compare them.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 6952b0295096..8680133ef607 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3957,12 +3957,11 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
 
 	if (HAS_DDI(dev_priv))
 		return intel_ddi_dp_voltage_max(encoder);
-	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
+		 (HAS_PCH_CPT(dev_priv) && port != PORT_A))
 		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
 	else if (IS_IVYBRIDGE(dev_priv) && port == PORT_A)
 		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-	else if (HAS_PCH_CPT(dev_priv) && port != PORT_A)
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
 	else
 		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
 }
@@ -3976,7 +3975,8 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, u8 voltage_swing)
 
 	if (HAS_DDI(dev_priv)) {
 		return intel_ddi_dp_pre_emphasis_max(encoder, voltage_swing);
-	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
+		   (HAS_PCH_CPT(dev_priv) && port != PORT_A)) {
 		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
 			return DP_TRAIN_PRE_EMPH_LEVEL_3;
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Intel-gfx] [PATCH 2/9] drm/i915: Fix ibx max vswing/preemph
  2020-05-06 11:23 [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code Ville Syrjala
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 1/9] drm/i915: Fix cpt/ppt max pre-emphasis Ville Syrjala
@ 2020-05-06 11:23 ` Ville Syrjala
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 3/9] drm/i915: Fix ivb cpu edp vswing Ville Syrjala
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Ville Syrjala @ 2020-05-06 11:23 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

IBX supports vswing level 3 and pre-emphasis level 3. Don't
limit it to level 2 for those.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 8680133ef607..91f26f7b758b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3958,7 +3958,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
 	if (HAS_DDI(dev_priv))
 		return intel_ddi_dp_voltage_max(encoder);
 	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
-		 (HAS_PCH_CPT(dev_priv) && port != PORT_A))
+		 (HAS_PCH_SPLIT(dev_priv) && port != PORT_A))
 		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
 	else if (IS_IVYBRIDGE(dev_priv) && port == PORT_A)
 		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
@@ -3976,7 +3976,7 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, u8 voltage_swing)
 	if (HAS_DDI(dev_priv)) {
 		return intel_ddi_dp_pre_emphasis_max(encoder, voltage_swing);
 	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
-		   (HAS_PCH_CPT(dev_priv) && port != PORT_A)) {
+		   (HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) {
 		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
 			return DP_TRAIN_PRE_EMPH_LEVEL_3;
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Intel-gfx] [PATCH 3/9] drm/i915: Fix ivb cpu edp vswing
  2020-05-06 11:23 [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code Ville Syrjala
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 1/9] drm/i915: Fix cpt/ppt max pre-emphasis Ville Syrjala
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 2/9] drm/i915: Fix ibx max vswing/preemph Ville Syrjala
@ 2020-05-06 11:23 ` Ville Syrjala
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 4/9] drm/i915: Add {preemph, voltage}_max() vfuncs Ville Syrjala
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Ville Syrjala @ 2020-05-06 11:23 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

According to the DP spec supporting vswing 1 + preemph 2 is
mandatory. We don't have the hw settings for that though. In
order to pretend to follow the DP spec let's just select
vswing 0 + preemph 2 in this case (the DP spec says to use
the requested preemph in preference to the vswing when the
requested values aren't supported).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 91f26f7b758b..a52f01c48644 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3960,8 +3960,6 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
 	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
 		 (HAS_PCH_SPLIT(dev_priv) && port != PORT_A))
 		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else if (IS_IVYBRIDGE(dev_priv) && port == PORT_A)
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
 	else
 		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
 }
@@ -3988,16 +3986,6 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, u8 voltage_swing)
 		default:
 			return DP_TRAIN_PRE_EMPH_LEVEL_0;
 		}
-	} else if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) {
-		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			return DP_TRAIN_PRE_EMPH_LEVEL_1;
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
 	} else {
 		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
 		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
@@ -4293,6 +4281,7 @@ static u32 ivb_cpu_edp_signal_levels(u8 train_set)
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
 		return EDP_LINK_TRAIN_400MV_3_5DB_IVB;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
 		return EDP_LINK_TRAIN_400MV_6DB_IVB;
 
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Intel-gfx] [PATCH 4/9] drm/i915: Add {preemph, voltage}_max() vfuncs
  2020-05-06 11:23 [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code Ville Syrjala
                   ` (2 preceding siblings ...)
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 3/9] drm/i915: Fix ivb cpu edp vswing Ville Syrjala
@ 2020-05-06 11:23 ` Ville Syrjala
  2020-05-07  7:09   ` Ville Syrjälä
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 5/9] drm/i915: Reverse preemph vs. voltage swing preference Ville Syrjala
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 15+ messages in thread
From: Ville Syrjala @ 2020-05-06 11:23 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Different platforms have different max vswing/preemph settings.
Turn that into a pair vfuncs so we can decouple intel_dp.c and
intel_ddi.c further.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      | 21 ++----
 drivers/gpu/drm/i915/display/intel_ddi.h      |  3 -
 .../drm/i915/display/intel_display_types.h    |  3 +
 drivers/gpu/drm/i915/display/intel_dp.c       | 67 ++++++-------------
 drivers/gpu/drm/i915/display/intel_dp.h       |  4 --
 .../drm/i915/display/intel_dp_link_training.c | 20 +++++-
 6 files changed, 49 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 5601673c3f30..409b8a68570f 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -2095,10 +2095,10 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
 				     ddi_translations[level].deemphasis);
 }
 
-u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
+static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp)
 {
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	enum port port = encoder->port;
 	enum phy phy = intel_port_to_phy(dev_priv, port);
 	int n_entries;
@@ -2151,19 +2151,9 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
  * used on all DDI platforms. Should that change we need to
  * rethink this code.
  */
-u8 intel_ddi_dp_pre_emphasis_max(struct intel_encoder *encoder, u8 voltage_swing)
+static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp)
 {
-	switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-		return DP_TRAIN_PRE_EMPH_LEVEL_3;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-		return DP_TRAIN_PRE_EMPH_LEVEL_2;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-		return DP_TRAIN_PRE_EMPH_LEVEL_1;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-	default:
-		return DP_TRAIN_PRE_EMPH_LEVEL_0;
-	}
+	return DP_TRAIN_PRE_EMPH_LEVEL_3;
 }
 
 static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
@@ -4510,6 +4500,9 @@ intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
 	else
 		intel_dig_port->dp.set_signal_levels = hsw_set_signal_levels;
 
+	intel_dig_port->dp.voltage_max = intel_ddi_dp_voltage_max;
+	intel_dig_port->dp.preemph_max = intel_ddi_dp_preemph_max;
+
 	if (INTEL_GEN(dev_priv) < 12) {
 		intel_dig_port->dp.regs.dp_tp_ctl = DP_TP_CTL(port);
 		intel_dig_port->dp.regs.dp_tp_status = DP_TP_STATUS(port);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h
index fbdf8ddde486..077e9dbbe367 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -42,9 +42,6 @@ void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
 					 struct intel_crtc_state *crtc_state);
 u32 bxt_signal_levels(struct intel_dp *intel_dp);
 u32 ddi_signal_levels(struct intel_dp *intel_dp);
-u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
-u8 intel_ddi_dp_pre_emphasis_max(struct intel_encoder *encoder,
-				 u8 voltage_swing);
 int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
 				     bool enable);
 void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 9488449e4b94..e0384af489c2 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1371,6 +1371,9 @@ struct intel_dp {
 	void (*set_idle_link_train)(struct intel_dp *intel_dp);
 	void (*set_signal_levels)(struct intel_dp *intel_dp);
 
+	u8 (*preemph_max)(struct intel_dp *intel_dp);
+	u8 (*voltage_max)(struct intel_dp *intel_dp);
+
 	/* Displayport compliance testing */
 	struct intel_dp_compliance compliance;
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index a52f01c48644..1b786d5af383 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3947,58 +3947,24 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATU
 				DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
 }
 
-/* These are source-specific values. */
-u8
-intel_dp_voltage_max(struct intel_dp *intel_dp)
+static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp)
 {
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
-	enum port port = encoder->port;
+	return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+}
 
-	if (HAS_DDI(dev_priv))
-		return intel_ddi_dp_voltage_max(encoder);
-	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
-		 (HAS_PCH_SPLIT(dev_priv) && port != PORT_A))
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp)
+{
+	return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
 }
 
-u8
-intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, u8 voltage_swing)
+static u8 intel_dp_pre_empemph_max_2(struct intel_dp *intel_dp)
 {
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
-	enum port port = encoder->port;
+	return DP_TRAIN_PRE_EMPH_LEVEL_2;
+}
 
-	if (HAS_DDI(dev_priv)) {
-		return intel_ddi_dp_pre_emphasis_max(encoder, voltage_swing);
-	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
-		   (HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) {
-		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			return DP_TRAIN_PRE_EMPH_LEVEL_3;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			return DP_TRAIN_PRE_EMPH_LEVEL_1;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	} else {
-		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			return DP_TRAIN_PRE_EMPH_LEVEL_2;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			return DP_TRAIN_PRE_EMPH_LEVEL_1;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	}
+static u8 intel_dp_pre_empemph_max_3(struct intel_dp *intel_dp)
+{
+	return DP_TRAIN_PRE_EMPH_LEVEL_3;
 }
 
 static void vlv_set_signal_levels(struct intel_dp *intel_dp)
@@ -8491,6 +8457,15 @@ bool intel_dp_init(struct drm_i915_private *dev_priv,
 	else
 		intel_dig_port->dp.set_signal_levels = g4x_set_signal_levels;
 
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
+	    (HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) {
+		intel_dig_port->dp.preemph_max = intel_dp_pre_empemph_max_3;
+		intel_dig_port->dp.voltage_max = intel_dp_voltage_max_3;
+	} else {
+		intel_dig_port->dp.preemph_max = intel_dp_pre_empemph_max_2;
+		intel_dig_port->dp.voltage_max = intel_dp_voltage_max_2;
+	}
+
 	intel_dig_port->dp.output_reg = output_reg;
 	intel_dig_port->max_lanes = 4;
 	intel_dig_port->dp.regs.dp_tp_ctl = DP_TP_CTL(port);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 6659ce15a693..e8375a75c3ec 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -91,10 +91,6 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
 void
 intel_dp_set_signal_levels(struct intel_dp *intel_dp);
 void intel_dp_set_idle_link_train(struct intel_dp *intel_dp);
-u8
-intel_dp_voltage_max(struct intel_dp *intel_dp);
-u8
-intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, u8 voltage_swing);
 void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
 			   u8 *link_bw, u8 *rate_select);
 bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index e4f1843170b7..171d9e842fc0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -34,6 +34,21 @@ intel_dp_dump_link_status(const u8 link_status[DP_LINK_STATUS_SIZE])
 		      link_status[3], link_status[4], link_status[5]);
 }
 
+static u8 dp_pre_emphasis_max(u8 voltage_swing)
+{
+	switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+		return DP_TRAIN_PRE_EMPH_LEVEL_3;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+		return DP_TRAIN_PRE_EMPH_LEVEL_2;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+		return DP_TRAIN_PRE_EMPH_LEVEL_1;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+	default:
+		return DP_TRAIN_PRE_EMPH_LEVEL_0;
+	}
+}
+
 void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
 			       const u8 link_status[DP_LINK_STATUS_SIZE])
 {
@@ -53,11 +68,12 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
 			p = this_p;
 	}
 
-	voltage_max = intel_dp_voltage_max(intel_dp);
+	voltage_max = intel_dp->voltage_max(intel_dp);
 	if (v >= voltage_max)
 		v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;
 
-	preemph_max = intel_dp_pre_emphasis_max(intel_dp, v);
+	preemph_max = min(intel_dp->preemph_max(intel_dp),
+			  dp_pre_emphasis_max(v));
 	if (p >= preemph_max)
 		p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Intel-gfx] [PATCH 5/9] drm/i915: Reverse preemph vs. voltage swing preference
  2020-05-06 11:23 [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code Ville Syrjala
                   ` (3 preceding siblings ...)
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 4/9] drm/i915: Add {preemph, voltage}_max() vfuncs Ville Syrjala
@ 2020-05-06 11:23 ` Ville Syrjala
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 6/9] drm/i915: Fix DP_TRAIN_MAX_{PRE_EMPHASIS, SWING}_REACHED handling Ville Syrjala
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Ville Syrjala @ 2020-05-06 11:23 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

The DP spec says:
"When the combination of the requested pre-emphasis level and
 voltage swing exceeds the capability of a DPTX, the DPTX shall
 set the pre-emphasis level according to the request and use the
 highest voltage swing it can output with the given pre-emphasis level."
and
"When a DPTX reads a request beyond the limits of this Standard,
 the DPTX shall set the pre-emphasis level according to the request
 and set the highest voltage swing level it can output with the
 given pre-emphasis level. If a DPTX is requested for 9.5dB of
 pre-emphasis level (may be supported for a DPTX) and cannot support
 that level, it shall set the pre-emphasis level to the next
 highest level, 6dB."

Ie. we should first validate the pre-emphasis, and then select
the appropriate vswing for it.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 .../drm/i915/display/intel_dp_link_training.c | 32 +++++++++----------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index 171d9e842fc0..573f93779449 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -34,18 +34,18 @@ intel_dp_dump_link_status(const u8 link_status[DP_LINK_STATUS_SIZE])
 		      link_status[3], link_status[4], link_status[5]);
 }
 
-static u8 dp_pre_emphasis_max(u8 voltage_swing)
+static u8 dp_voltage_max(u8 preemph)
 {
-	switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-		return DP_TRAIN_PRE_EMPH_LEVEL_3;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-		return DP_TRAIN_PRE_EMPH_LEVEL_2;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-		return DP_TRAIN_PRE_EMPH_LEVEL_1;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+	switch (preemph & DP_TRAIN_PRE_EMPHASIS_MASK) {
+	case DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+	case DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+	case DP_TRAIN_PRE_EMPH_LEVEL_2:
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_1;
+	case DP_TRAIN_PRE_EMPH_LEVEL_3:
 	default:
-		return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
 	}
 }
 
@@ -68,15 +68,15 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
 			p = this_p;
 	}
 
-	voltage_max = intel_dp->voltage_max(intel_dp);
-	if (v >= voltage_max)
-		v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;
-
-	preemph_max = min(intel_dp->preemph_max(intel_dp),
-			  dp_pre_emphasis_max(v));
+	preemph_max = intel_dp->preemph_max(intel_dp);
 	if (p >= preemph_max)
 		p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 
+	voltage_max = min(intel_dp->voltage_max(intel_dp),
+			  dp_voltage_max(p));
+	if (v >= voltage_max)
+		v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;
+
 	for (lane = 0; lane < 4; lane++)
 		intel_dp->train_set[lane] = v | p;
 }
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Intel-gfx] [PATCH 6/9] drm/i915: Fix DP_TRAIN_MAX_{PRE_EMPHASIS, SWING}_REACHED handling
  2020-05-06 11:23 [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code Ville Syrjala
                   ` (4 preceding siblings ...)
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 5/9] drm/i915: Reverse preemph vs. voltage swing preference Ville Syrjala
@ 2020-05-06 11:23 ` Ville Syrjala
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 7/9] drm/i915: Replace some hand rolled max()s Ville Syrjala
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Ville Syrjala @ 2020-05-06 11:23 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

The DP spec says:
"The transmitter shall support at least three levels of voltage
 swing (Levels 0, 1, and 2).

 If only three levels of voltage swing are supported (VOLTAGE
 SWING SET field (bits 1:0) are programmed to 10 (Level 2)),
 this bit shall be set to 1, and cleared in all other cases.

 If all four levels of voltage swing are supported (VOLTAGE
 SWING SET field (bits 1:0) are programmed to 11 (Level 3)),
 this bit shall be set to 1,and cleared in all other cases."

Let's follow that exactly instead of the current apporach
where we can set those also for vswing/preemph levels 0 or 1
(or 2 when the platform max is 3).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp_link_training.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index 573f93779449..aa7af531bcb8 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -72,8 +72,9 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
 	if (p >= preemph_max)
 		p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 
-	voltage_max = min(intel_dp->voltage_max(intel_dp),
-			  dp_voltage_max(p));
+	v = min(v, dp_voltage_max(p));
+
+	voltage_max = intel_dp->voltage_max(intel_dp);
 	if (v >= voltage_max)
 		v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;
 
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Intel-gfx] [PATCH 7/9] drm/i915: Replace some hand rolled max()s
  2020-05-06 11:23 [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code Ville Syrjala
                   ` (5 preceding siblings ...)
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 6/9] drm/i915: Fix DP_TRAIN_MAX_{PRE_EMPHASIS, SWING}_REACHED handling Ville Syrjala
@ 2020-05-06 11:23 ` Ville Syrjala
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 8/9] drm/i915: Plumb crtc_state to link training Ville Syrjala
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Ville Syrjala @ 2020-05-06 11:23 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Use max() instead of hand rolling it.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp_link_training.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index aa7af531bcb8..2493142a70e9 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -59,13 +59,8 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
 	u8 preemph_max;
 
 	for (lane = 0; lane < intel_dp->lane_count; lane++) {
-		u8 this_v = drm_dp_get_adjust_request_voltage(link_status, lane);
-		u8 this_p = drm_dp_get_adjust_request_pre_emphasis(link_status, lane);
-
-		if (this_v > v)
-			v = this_v;
-		if (this_p > p)
-			p = this_p;
+		v = max(v, drm_dp_get_adjust_request_voltage(link_status, lane));
+		p = max(p, drm_dp_get_adjust_request_pre_emphasis(link_status, lane));
 	}
 
 	preemph_max = intel_dp->preemph_max(intel_dp);
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Intel-gfx] [PATCH 8/9] drm/i915: Plumb crtc_state to link training
  2020-05-06 11:23 [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code Ville Syrjala
                   ` (6 preceding siblings ...)
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 7/9] drm/i915: Replace some hand rolled max()s Ville Syrjala
@ 2020-05-06 11:23 ` Ville Syrjala
  2020-05-06 12:05   ` [Intel-gfx] [PATCH v2 " Ville Syrjala
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 9/9] drm/i915: Eliminate intel_dp.regs.dp_tp_{ctl, status} Ville Syrjala
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 15+ messages in thread
From: Ville Syrjala @ 2020-05-06 11:23 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Get rid of mode crtc->config usage, and some ad-hoc intel_dp state
usage by plumbing the crtc state all the way down to the link training
code.

Unfortunately we do have to keep some cached state in intel_dp so
that we can do the "does the link need retraining?" checks from
the short hpd handler.

The PHY test code seems to have started to build some kind of NIH
modeset code right into intel_dp.c. That's not how we should do
things, and instead we should just go through the normal modeset
machinery for that (meaning it all needs to move into the hotplug
work as well, just like we've already done for normal link retraining).
For now just neuter that code and toss in a FIXME.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      | 334 +++++++++---------
 drivers/gpu/drm/i915/display/intel_ddi.h      |   6 +-
 .../drm/i915/display/intel_display_types.h    |  17 +-
 drivers/gpu/drm/i915/display/intel_dp.c       | 138 +++++---
 drivers/gpu/drm/i915/display/intel_dp.h       |  11 +-
 .../drm/i915/display/intel_dp_link_training.c | 102 +++---
 .../drm/i915/display/intel_dp_link_training.h |   7 +-
 drivers/gpu/drm/i915/display/intel_dpio_phy.c |  23 +-
 drivers/gpu/drm/i915/display/intel_dpio_phy.h |   2 +
 drivers/gpu/drm/i915/display/intel_hdmi.c     |   7 +-
 10 files changed, 349 insertions(+), 298 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 409b8a68570f..77d2021d0bcd 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -953,68 +953,75 @@ cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
 }
 
 static const struct cnl_ddi_buf_trans *
-icl_get_combo_buf_trans(struct drm_i915_private *dev_priv, int type, int rate,
+icl_get_combo_buf_trans(const struct intel_crtc_state *crtc_state,
 			int *n_entries)
 {
-	if (type == INTEL_OUTPUT_HDMI) {
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
 		*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
 		return icl_combo_phy_ddi_translations_hdmi;
-	} else if (rate > 540000 && type == INTEL_OUTPUT_EDP) {
+	} else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+		   crtc_state->port_clock > 540000) {
 		*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3);
 		return icl_combo_phy_ddi_translations_edp_hbr3;
-	} else if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) {
+	} else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+		   dev_priv->vbt.edp.low_vswing) {
 		*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2);
 		return icl_combo_phy_ddi_translations_edp_hbr2;
+	} else {
+		*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2);
+		return icl_combo_phy_ddi_translations_dp_hbr2;
 	}
-
-	*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2);
-	return icl_combo_phy_ddi_translations_dp_hbr2;
 }
 
 static const struct icl_mg_phy_ddi_buf_trans *
-icl_get_mg_buf_trans(struct drm_i915_private *dev_priv, int type, int rate,
+icl_get_mg_buf_trans(const struct intel_crtc_state *crtc_state,
 		     int *n_entries)
 {
-	if (type == INTEL_OUTPUT_HDMI) {
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
 		*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hdmi);
 		return icl_mg_phy_ddi_translations_hdmi;
-	} else if (rate > 270000) {
+	} else if (crtc_state->port_clock > 270000) {
 		*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hbr2_hbr3);
 		return icl_mg_phy_ddi_translations_hbr2_hbr3;
+	} else {
+		*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_rbr_hbr);
+		return icl_mg_phy_ddi_translations_rbr_hbr;
 	}
-
-	*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_rbr_hbr);
-	return icl_mg_phy_ddi_translations_rbr_hbr;
 }
 
 static const struct cnl_ddi_buf_trans *
-ehl_get_combo_buf_trans(struct drm_i915_private *dev_priv, int type, int rate,
+ehl_get_combo_buf_trans(const struct intel_crtc_state *crtc_state,
 			int *n_entries)
 {
-	if (type != INTEL_OUTPUT_HDMI && type != INTEL_OUTPUT_EDP) {
+	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
+	    !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) {
 		*n_entries = ARRAY_SIZE(ehl_combo_phy_ddi_translations_dp);
 		return ehl_combo_phy_ddi_translations_dp;
+	} else {
+		return icl_get_combo_buf_trans(crtc_state, n_entries);
 	}
-
-	return icl_get_combo_buf_trans(dev_priv, type, rate, n_entries);
 }
 
 static const struct cnl_ddi_buf_trans *
-tgl_get_combo_buf_trans(struct drm_i915_private *dev_priv, int type, int rate,
+tgl_get_combo_buf_trans(const struct intel_crtc_state *crtc_state,
 			int *n_entries)
 {
-	if (type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_EDP) {
-		return icl_get_combo_buf_trans(dev_priv, type, rate, n_entries);
-	} else if (rate > 270000) {
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) ||
+	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) {
+		return icl_get_combo_buf_trans(crtc_state, n_entries);
+	} else if (crtc_state->port_clock > 270000) {
 		*n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr2);
 		return tgl_combo_phy_ddi_translations_dp_hbr2;
+	} else {
+		*n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr);
+		return tgl_combo_phy_ddi_translations_dp_hbr;
 	}
-
-	*n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr);
-	return tgl_combo_phy_ddi_translations_dp_hbr;
 }
 
-static int intel_ddi_hdmi_level(struct intel_encoder *encoder)
+static int intel_ddi_hdmi_level(struct intel_encoder *encoder,
+				const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	int n_entries, level, default_entry;
@@ -1022,18 +1029,15 @@ static int intel_ddi_hdmi_level(struct intel_encoder *encoder)
 
 	if (INTEL_GEN(dev_priv) >= 12) {
 		if (intel_phy_is_combo(dev_priv, phy))
-			tgl_get_combo_buf_trans(dev_priv, INTEL_OUTPUT_HDMI,
-						0, &n_entries);
+			tgl_get_combo_buf_trans(crtc_state, &n_entries);
 		else
 			n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
 		default_entry = n_entries - 1;
 	} else if (INTEL_GEN(dev_priv) == 11) {
 		if (intel_phy_is_combo(dev_priv, phy))
-			icl_get_combo_buf_trans(dev_priv, INTEL_OUTPUT_HDMI,
-						0, &n_entries);
+			icl_get_combo_buf_trans(crtc_state, &n_entries);
 		else
-			icl_get_mg_buf_trans(dev_priv, INTEL_OUTPUT_HDMI, 0,
-					     &n_entries);
+			icl_get_mg_buf_trans(crtc_state, &n_entries);
 		default_entry = n_entries - 1;
 	} else if (IS_CANNONLAKE(dev_priv)) {
 		cnl_get_buf_trans_hdmi(dev_priv, &n_entries);
@@ -1346,7 +1350,8 @@ void hsw_fdi_link_train(struct intel_encoder *encoder,
 		       DP_TP_CTL_ENABLE);
 }
 
-static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
+static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder,
+				      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	struct intel_digital_port *intel_dig_port =
@@ -1354,7 +1359,7 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
 
 	intel_dp->DP = intel_dig_port->saved_port_bits |
 		DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
-	intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
+	intel_dp->DP |= DDI_PORT_WIDTH(crtc_state->lane_count);
 }
 
 static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv,
@@ -2025,14 +2030,15 @@ static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
 }
 
 static void skl_ddi_set_iboost(struct intel_encoder *encoder,
-			       int level, enum intel_output_type type)
+			       const struct intel_crtc_state *crtc_state,
+			       int level)
 {
 	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum port port = encoder->port;
 	u8 iboost;
 
-	if (type == INTEL_OUTPUT_HDMI)
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 		iboost = intel_bios_hdmi_boost_level(encoder);
 	else
 		iboost = intel_bios_dp_boost_level(encoder);
@@ -2041,9 +2047,9 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,
 		const struct ddi_buf_trans *ddi_translations;
 		int n_entries;
 
-		if (type == INTEL_OUTPUT_HDMI)
+		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 			ddi_translations = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries);
-		else if (type == INTEL_OUTPUT_EDP)
+		else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
 			ddi_translations = intel_ddi_get_buf_trans_edp(dev_priv, port, &n_entries);
 		else
 			ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, port, &n_entries);
@@ -2069,16 +2075,17 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,
 }
 
 static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
-				    int level, enum intel_output_type type)
+				    const struct intel_crtc_state *crtc_state,
+				    int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	const struct bxt_ddi_buf_trans *ddi_translations;
 	enum port port = encoder->port;
 	int n_entries;
 
-	if (type == INTEL_OUTPUT_HDMI)
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 		ddi_translations = bxt_get_buf_trans_hdmi(dev_priv, &n_entries);
-	else if (type == INTEL_OUTPUT_EDP)
+	else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
 		ddi_translations = bxt_get_buf_trans_edp(dev_priv, &n_entries);
 	else
 		ddi_translations = bxt_get_buf_trans_dp(dev_priv, &n_entries);
@@ -2095,7 +2102,8 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
 				     ddi_translations[level].deemphasis);
 }
 
-static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp)
+static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp,
+				   const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -2105,32 +2113,28 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp)
 
 	if (INTEL_GEN(dev_priv) >= 12) {
 		if (intel_phy_is_combo(dev_priv, phy))
-			tgl_get_combo_buf_trans(dev_priv, encoder->type,
-						intel_dp->link_rate, &n_entries);
+			tgl_get_combo_buf_trans(crtc_state, &n_entries);
 		else
 			n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans);
 	} else if (INTEL_GEN(dev_priv) == 11) {
 		if (IS_ELKHARTLAKE(dev_priv))
-			ehl_get_combo_buf_trans(dev_priv, encoder->type,
-						intel_dp->link_rate, &n_entries);
+			ehl_get_combo_buf_trans(crtc_state, &n_entries);
 		else if (intel_phy_is_combo(dev_priv, phy))
-			icl_get_combo_buf_trans(dev_priv, encoder->type,
-						intel_dp->link_rate, &n_entries);
+			icl_get_combo_buf_trans(crtc_state, &n_entries);
 		else
-			icl_get_mg_buf_trans(dev_priv, encoder->type,
-					     intel_dp->link_rate, &n_entries);
+			icl_get_mg_buf_trans(crtc_state, &n_entries);
 	} else if (IS_CANNONLAKE(dev_priv)) {
-		if (encoder->type == INTEL_OUTPUT_EDP)
+		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
 			cnl_get_buf_trans_edp(dev_priv, &n_entries);
 		else
 			cnl_get_buf_trans_dp(dev_priv, &n_entries);
 	} else if (IS_GEN9_LP(dev_priv)) {
-		if (encoder->type == INTEL_OUTPUT_EDP)
+		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
 			bxt_get_buf_trans_edp(dev_priv, &n_entries);
 		else
 			bxt_get_buf_trans_dp(dev_priv, &n_entries);
 	} else {
-		if (encoder->type == INTEL_OUTPUT_EDP)
+		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
 			intel_ddi_get_buf_trans_edp(dev_priv, port, &n_entries);
 		else
 			intel_ddi_get_buf_trans_dp(dev_priv, port, &n_entries);
@@ -2157,7 +2161,8 @@ static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp)
 }
 
 static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
-				   int level, enum intel_output_type type)
+				   const struct intel_crtc_state *crtc_state,
+				   int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	const struct cnl_ddi_buf_trans *ddi_translations;
@@ -2165,9 +2170,9 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
 	int n_entries, ln;
 	u32 val;
 
-	if (type == INTEL_OUTPUT_HDMI)
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 		ddi_translations = cnl_get_buf_trans_hdmi(dev_priv, &n_entries);
-	else if (type == INTEL_OUTPUT_EDP)
+	else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
 		ddi_translations = cnl_get_buf_trans_edp(dev_priv, &n_entries);
 	else
 		ddi_translations = cnl_get_buf_trans_dp(dev_priv, &n_entries);
@@ -2221,22 +2226,16 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
 }
 
 static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
-				    int level, enum intel_output_type type)
+				    const struct intel_crtc_state *crtc_state,
+				    int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum port port = encoder->port;
 	int width, rate, ln;
 	u32 val;
 
-	if (type == INTEL_OUTPUT_HDMI) {
-		width = 4;
-		rate = 0; /* Rate is always < than 6GHz for HDMI */
-	} else {
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-		width = intel_dp->lane_count;
-		rate = intel_dp->link_rate;
-	}
+	width = crtc_state->lane_count;
+	rate = crtc_state->port_clock;
 
 	/*
 	 * 1. If port type is eDP or DP,
@@ -2244,10 +2243,10 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
 	 * else clear to 0b.
 	 */
 	val = intel_de_read(dev_priv, CNL_PORT_PCS_DW1_LN0(port));
-	if (type != INTEL_OUTPUT_HDMI)
-		val |= COMMON_KEEPER_EN;
-	else
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 		val &= ~COMMON_KEEPER_EN;
+	else
+		val |= COMMON_KEEPER_EN;
 	intel_de_write(dev_priv, CNL_PORT_PCS_DW1_GRP(port), val);
 
 	/* 2. Program loadgen select */
@@ -2279,7 +2278,7 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
 	intel_de_write(dev_priv, CNL_PORT_TX_DW5_GRP(port), val);
 
 	/* 5. Program swing and de-emphasis */
-	cnl_ddi_vswing_program(encoder, level, type);
+	cnl_ddi_vswing_program(encoder, crtc_state, level);
 
 	/* 6. Set training enable to trigger update */
 	val = intel_de_read(dev_priv, CNL_PORT_TX_DW5_LN0(port));
@@ -2287,23 +2286,22 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
 	intel_de_write(dev_priv, CNL_PORT_TX_DW5_GRP(port), val);
 }
 
-static void icl_ddi_combo_vswing_program(struct drm_i915_private *dev_priv,
-					u32 level, enum phy phy, int type,
-					int rate)
+static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
+					 const struct intel_crtc_state *crtc_state,
+					 int level)
 {
-	const struct cnl_ddi_buf_trans *ddi_translations = NULL;
-	u32 n_entries, val;
-	int ln;
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	const struct cnl_ddi_buf_trans *ddi_translations;
+	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
+	int n_entries, ln;
+	u32 val;
 
 	if (INTEL_GEN(dev_priv) >= 12)
-		ddi_translations = tgl_get_combo_buf_trans(dev_priv, type, rate,
-							   &n_entries);
+		ddi_translations = tgl_get_combo_buf_trans(crtc_state, &n_entries);
 	else if (IS_ELKHARTLAKE(dev_priv))
-		ddi_translations = ehl_get_combo_buf_trans(dev_priv, type, rate,
-							   &n_entries);
+		ddi_translations = ehl_get_combo_buf_trans(crtc_state, &n_entries);
 	else
-		ddi_translations = icl_get_combo_buf_trans(dev_priv, type, rate,
-							   &n_entries);
+		ddi_translations = icl_get_combo_buf_trans(crtc_state, &n_entries);
 	if (!ddi_translations)
 		return;
 
@@ -2353,25 +2351,16 @@ static void icl_ddi_combo_vswing_program(struct drm_i915_private *dev_priv,
 }
 
 static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
-					      u32 level,
-					      enum intel_output_type type)
+					      const struct intel_crtc_state *crtc_state,
+					      int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
-	int width = 0;
-	int rate = 0;
+	int width, rate, ln;
 	u32 val;
-	int ln = 0;
 
-	if (type == INTEL_OUTPUT_HDMI) {
-		width = 4;
-		/* Rate is always < than 6GHz for HDMI */
-	} else {
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-		width = intel_dp->lane_count;
-		rate = intel_dp->link_rate;
-	}
+	width = crtc_state->lane_count;
+	rate = crtc_state->port_clock;
 
 	/*
 	 * 1. If port type is eDP or DP,
@@ -2379,7 +2368,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 	 * else clear to 0b.
 	 */
 	val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN0(phy));
-	if (type == INTEL_OUTPUT_HDMI)
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 		val &= ~COMMON_KEEPER_EN;
 	else
 		val |= COMMON_KEEPER_EN;
@@ -2414,7 +2403,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 	intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val);
 
 	/* 5. Program swing and de-emphasis */
-	icl_ddi_combo_vswing_program(dev_priv, level, phy, type, rate);
+	icl_ddi_combo_vswing_program(encoder, crtc_state, level);
 
 	/* 6. Set training enable to trigger update */
 	val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy));
@@ -2423,23 +2412,16 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 }
 
 static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
-					   int link_clock, u32 level,
-					   enum intel_output_type type)
+					   const struct intel_crtc_state *crtc_state,
+					   int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
 	const struct icl_mg_phy_ddi_buf_trans *ddi_translations;
-	u32 n_entries, val;
-	int ln, rate = 0;
+	int n_entries, ln;
+	u32 val;
 
-	if (type != INTEL_OUTPUT_HDMI) {
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-		rate = intel_dp->link_rate;
-	}
-
-	ddi_translations = icl_get_mg_buf_trans(dev_priv, type, rate,
-						&n_entries);
+	ddi_translations = icl_get_mg_buf_trans(crtc_state, &n_entries);
 	/* The table does not have values for level 3 and level 9. */
 	if (level >= n_entries || level == 3 || level == 9) {
 		drm_dbg_kms(&dev_priv->drm,
@@ -2506,7 +2488,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 	 */
 	for (ln = 0; ln < 2; ln++) {
 		val = intel_de_read(dev_priv, MG_CLKHUB(ln, tc_port));
-		if (link_clock < 300000)
+		if (crtc_state->port_clock < 300000)
 			val |= CFG_LOW_RATE_LKREN_EN;
 		else
 			val &= ~CFG_LOW_RATE_LKREN_EN;
@@ -2517,7 +2499,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 	for (ln = 0; ln < 2; ln++) {
 		val = intel_de_read(dev_priv, MG_TX1_DCC(ln, tc_port));
 		val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
-		if (link_clock <= 500000) {
+		if (crtc_state->port_clock <= 500000) {
 			val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
 		} else {
 			val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
@@ -2527,7 +2509,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 
 		val = intel_de_read(dev_priv, MG_TX2_DCC(ln, tc_port));
 		val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
-		if (link_clock <= 500000) {
+		if (crtc_state->port_clock <= 500000) {
 			val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
 		} else {
 			val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
@@ -2553,28 +2535,28 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 }
 
 static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
-				    int link_clock,
-				    u32 level,
-				    enum intel_output_type type)
+				    const struct intel_crtc_state *crtc_state,
+				    int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
 
 	if (intel_phy_is_combo(dev_priv, phy))
-		icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
+		icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level);
 	else
-		icl_mg_phy_ddi_vswing_sequence(encoder, link_clock, level,
-					       type);
+		icl_mg_phy_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
-				u32 level)
+tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
+				const struct intel_crtc_state *crtc_state,
+				int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
 	const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations;
-	u32 n_entries, val, ln, dpcnt_mask, dpcnt_val;
+	u32 val, dpcnt_mask, dpcnt_val;
+	int n_entries, ln;
 
 	if (encoder->type == INTEL_OUTPUT_HDMI) {
 		n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
@@ -2618,20 +2600,20 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
 }
 
 static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder,
-				    int link_clock,
-				    u32 level,
-				    enum intel_output_type type)
+				    const struct intel_crtc_state *crtc_state,
+				    int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
 
 	if (intel_phy_is_combo(dev_priv, phy))
-		icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
+		icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level);
 	else
-		tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level);
+		tgl_dkl_phy_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
-static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels)
+static int translate_signal_level(struct intel_dp *intel_dp,
+				  u8 signal_levels)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	int i;
@@ -2648,55 +2630,58 @@ static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels)
 	return 0;
 }
 
-static u32 intel_ddi_dp_level(struct intel_dp *intel_dp)
+static int intel_ddi_dp_level(struct intel_dp *intel_dp)
 {
 	u8 train_set = intel_dp->train_set[0];
-	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-					 DP_TRAIN_PRE_EMPHASIS_MASK);
+	u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+					DP_TRAIN_PRE_EMPHASIS_MASK);
 
 	return translate_signal_level(intel_dp, signal_levels);
 }
 
 static void
-tgl_set_signal_levels(struct intel_dp *intel_dp)
+tgl_set_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	int level = intel_ddi_dp_level(intel_dp);
 
-	tgl_ddi_vswing_sequence(encoder, intel_dp->link_rate,
-				level, encoder->type);
+	tgl_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-icl_set_signal_levels(struct intel_dp *intel_dp)
+icl_set_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	int level = intel_ddi_dp_level(intel_dp);
 
-	icl_ddi_vswing_sequence(encoder, intel_dp->link_rate,
-				level, encoder->type);
+	icl_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-cnl_set_signal_levels(struct intel_dp *intel_dp)
+cnl_set_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	int level = intel_ddi_dp_level(intel_dp);
 
-	cnl_ddi_vswing_sequence(encoder, level, encoder->type);
+	cnl_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-bxt_set_signal_levels(struct intel_dp *intel_dp)
+bxt_set_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	int level = intel_ddi_dp_level(intel_dp);
 
-	bxt_ddi_vswing_sequence(encoder, level, encoder->type);
+	bxt_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-hsw_set_signal_levels(struct intel_dp *intel_dp)
+hsw_set_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -2713,7 +2698,7 @@ hsw_set_signal_levels(struct intel_dp *intel_dp)
 	intel_dp->DP |= signal_levels;
 
 	if (IS_GEN9_BC(dev_priv))
-		skl_ddi_set_iboost(encoder, level, encoder->type);
+		skl_ddi_set_iboost(encoder, crtc_state, level);
 
 	intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
 	intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
@@ -3108,8 +3093,9 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	int level = intel_ddi_dp_level(intel_dp);
 	enum transcoder transcoder = crtc_state->cpu_transcoder;
 
-	intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
-				 crtc_state->lane_count, is_mst);
+	intel_dp_set_link_params(intel_dp,
+				 crtc_state->port_clock,
+				 crtc_state->lane_count);
 
 	intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
 	intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
@@ -3181,8 +3167,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	 */
 
 	/* 7.e Configure voltage swing and related IO settings */
-	tgl_ddi_vswing_sequence(encoder, crtc_state->port_clock, level,
-				encoder->type);
+	tgl_ddi_vswing_sequence(encoder, crtc_state, level);
 
 	/*
 	 * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up
@@ -3205,7 +3190,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	 * We only configure what the register value will be here.  Actual
 	 * enabling happens during link training farther down.
 	 */
-	intel_ddi_init_dp_buf_reg(encoder);
+	intel_ddi_init_dp_buf_reg(encoder, crtc_state);
 
 	if (!is_mst)
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
@@ -3225,11 +3210,11 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	 *     Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent)
 	 *     (timeout after 800 us)
 	 */
-	intel_dp_start_link_train(intel_dp);
+	intel_dp_start_link_train(intel_dp, crtc_state);
 
 	/* 7.k Set DP_TP_CTL link training to Normal */
 	if (!is_trans_port_sync_mode(crtc_state))
-		intel_dp_stop_link_train(intel_dp);
+		intel_dp_stop_link_train(intel_dp, crtc_state);
 
 	/* 7.l Configure and enable FEC if needed */
 	intel_ddi_enable_fec(encoder, crtc_state);
@@ -3255,8 +3240,9 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	else
 		drm_WARN_ON(&dev_priv->drm, is_mst && port == PORT_A);
 
-	intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
-				 crtc_state->lane_count, is_mst);
+	intel_dp_set_link_params(intel_dp,
+				 crtc_state->port_clock,
+				 crtc_state->lane_count);
 
 	intel_edp_panel_on(intel_dp);
 
@@ -3270,12 +3256,11 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	icl_program_mg_dp_mode(dig_port, crtc_state);
 
 	if (INTEL_GEN(dev_priv) >= 11)
-		icl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
-					level, encoder->type);
+		icl_ddi_vswing_sequence(encoder, crtc_state, level);
 	else if (IS_CANNONLAKE(dev_priv))
-		cnl_ddi_vswing_sequence(encoder, level, encoder->type);
+		cnl_ddi_vswing_sequence(encoder, crtc_state, level);
 	else if (IS_GEN9_LP(dev_priv))
-		bxt_ddi_vswing_sequence(encoder, level, encoder->type);
+		bxt_ddi_vswing_sequence(encoder, crtc_state, level);
 	else
 		intel_prepare_dp_ddi_buffers(encoder, crtc_state);
 
@@ -3288,16 +3273,16 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
 					       lane_reversal);
 	}
 
-	intel_ddi_init_dp_buf_reg(encoder);
+	intel_ddi_init_dp_buf_reg(encoder, crtc_state);
 	if (!is_mst)
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
 	intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
 					      true);
 	intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
-	intel_dp_start_link_train(intel_dp);
+	intel_dp_start_link_train(intel_dp, crtc_state);
 	if ((port != PORT_A || INTEL_GEN(dev_priv) >= 9) &&
 	    !is_trans_port_sync_mode(crtc_state))
-		intel_dp_stop_link_train(intel_dp);
+		intel_dp_stop_link_train(intel_dp, crtc_state);
 
 	intel_ddi_enable_fec(encoder, crtc_state);
 
@@ -3337,7 +3322,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
 	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
 	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	int level = intel_ddi_hdmi_level(encoder);
+	int level = intel_ddi_hdmi_level(encoder, crtc_state);
 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 
 	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
@@ -3348,20 +3333,18 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
 	icl_program_mg_dp_mode(dig_port, crtc_state);
 
 	if (INTEL_GEN(dev_priv) >= 12)
-		tgl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
-					level, INTEL_OUTPUT_HDMI);
+		tgl_ddi_vswing_sequence(encoder, crtc_state, level);
 	else if (INTEL_GEN(dev_priv) == 11)
-		icl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
-					level, INTEL_OUTPUT_HDMI);
+		icl_ddi_vswing_sequence(encoder, crtc_state, level);
 	else if (IS_CANNONLAKE(dev_priv))
-		cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
+		cnl_ddi_vswing_sequence(encoder, crtc_state, level);
 	else if (IS_GEN9_LP(dev_priv))
-		bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
+		bxt_ddi_vswing_sequence(encoder, crtc_state, level);
 	else
 		intel_prepare_hdmi_ddi_buffers(encoder, level);
 
 	if (IS_GEN9_BC(dev_priv))
-		skl_ddi_set_iboost(encoder, level, INTEL_OUTPUT_HDMI);
+		skl_ddi_set_iboost(encoder, crtc_state, level);
 
 	intel_ddi_enable_pipe_clock(encoder, crtc_state);
 
@@ -3649,12 +3632,14 @@ static void trans_port_sync_stop_link_train(struct intel_atomic_state *state,
 		    crtc_state->cpu_transcoder)
 			continue;
 
-		intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder));
+		intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder),
+					 slave_crtc_state);
 	}
 
 	usleep_range(200, 400);
 
-	intel_dp_stop_link_train(enc_to_intel_dp(encoder));
+	intel_dp_stop_link_train(enc_to_intel_dp(encoder),
+				 crtc_state);
 }
 
 static void intel_enable_ddi_dp(struct intel_atomic_state *state,
@@ -3667,7 +3652,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
 	enum port port = encoder->port;
 
 	if (port == PORT_A && INTEL_GEN(dev_priv) < 9)
-		intel_dp_stop_link_train(intel_dp);
+		intel_dp_stop_link_train(intel_dp, crtc_state);
 
 	intel_edp_backlight_on(crtc_state, conn_state);
 	intel_psr_enable(intel_dp, crtc_state);
@@ -3927,7 +3912,8 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
 						crtc_state->lane_lat_optim_mask);
 }
 
-static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
+static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
+					   const struct intel_crtc_state *crtc_state)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_i915_private *dev_priv =
@@ -3957,9 +3943,9 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
 
 	dp_tp_ctl = DP_TP_CTL_ENABLE |
 		    DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
-	if (intel_dp->link_mst)
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
 		dp_tp_ctl |= DP_TP_CTL_MODE_MST;
-	else {
+	} else {
 		dp_tp_ctl |= DP_TP_CTL_MODE_SST;
 		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
 			dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
@@ -3975,6 +3961,7 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
 }
 
 static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
+				     const struct intel_crtc_state *crtc_state,
 				     u8 dp_train_pat)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -4014,7 +4001,8 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
 	intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
 }
 
-static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp)
+static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp,
+					  const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h
index 077e9dbbe367..7a06bb942d21 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -40,8 +40,10 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
 				    bool state);
 void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
 					 struct intel_crtc_state *crtc_state);
-u32 bxt_signal_levels(struct intel_dp *intel_dp);
-u32 ddi_signal_levels(struct intel_dp *intel_dp);
+u32 bxt_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state);
+u32 ddi_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state);
 int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
 				     bool enable);
 void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index e0384af489c2..b7177134acc3 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1274,7 +1274,6 @@ struct intel_dp {
 	int link_rate;
 	u8 lane_count;
 	u8 sink_count;
-	bool link_mst;
 	bool link_trained;
 	bool has_audio;
 	bool reset_link_params;
@@ -1366,13 +1365,19 @@ struct intel_dp {
 	i915_reg_t (*aux_ch_data_reg)(struct intel_dp *dp, int index);
 
 	/* This is called before a link training is starterd */
-	void (*prepare_link_retrain)(struct intel_dp *intel_dp);
-	void (*set_link_train)(struct intel_dp *intel_dp, u8 dp_train_pat);
-	void (*set_idle_link_train)(struct intel_dp *intel_dp);
-	void (*set_signal_levels)(struct intel_dp *intel_dp);
+	void (*prepare_link_retrain)(struct intel_dp *intel_dp,
+				     const struct intel_crtc_state *crtc_state);
+	void (*set_link_train)(struct intel_dp *intel_dp,
+			       const struct intel_crtc_state *crtc_state,
+			       u8 dp_train_pat);
+	void (*set_idle_link_train)(struct intel_dp *intel_dp,
+				    const struct intel_crtc_state *crtc_state);
+	void (*set_signal_levels)(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *crtc_state);
 
 	u8 (*preemph_max)(struct intel_dp *intel_dp);
-	u8 (*voltage_max)(struct intel_dp *intel_dp);
+	u8 (*voltage_max)(struct intel_dp *intel_dp,
+			  const struct intel_crtc_state *crtc_state);
 
 	/* Displayport compliance testing */
 	struct intel_dp_compliance compliance;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 1b786d5af383..562cb560d6c0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2627,13 +2627,11 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 }
 
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
-			      int link_rate, u8 lane_count,
-			      bool link_mst)
+			      int link_rate, int lane_count)
 {
 	intel_dp->link_trained = false;
 	intel_dp->link_rate = link_rate;
 	intel_dp->lane_count = lane_count;
-	intel_dp->link_mst = link_mst;
 }
 
 static void intel_dp_prepare(struct intel_encoder *encoder,
@@ -2645,10 +2643,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 
-	intel_dp_set_link_params(intel_dp, pipe_config->port_clock,
-				 pipe_config->lane_count,
-				 intel_crtc_has_type(pipe_config,
-						     INTEL_OUTPUT_DP_MST));
+	intel_dp_set_link_params(intel_dp,
+				 pipe_config->port_clock,
+				 pipe_config->lane_count);
 
 	/*
 	 * There are four kinds of DP registers:
@@ -3619,6 +3616,7 @@ static void chv_post_disable_dp(struct intel_atomic_state *state,
 
 static void
 cpt_set_link_train(struct intel_dp *intel_dp,
+		   const struct intel_crtc_state *crtc_state,
 		   u8 dp_train_pat)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -3649,6 +3647,7 @@ cpt_set_link_train(struct intel_dp *intel_dp,
 
 static void
 g4x_set_link_train(struct intel_dp *intel_dp,
+		   const struct intel_crtc_state *crtc_state,
 		   u8 dp_train_pat)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -3678,13 +3677,14 @@ g4x_set_link_train(struct intel_dp *intel_dp,
 }
 
 static void intel_dp_enable_port(struct intel_dp *intel_dp,
-				 const struct intel_crtc_state *old_crtc_state)
+				 const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
 	/* enable with pattern 1 (as per spec) */
 
-	intel_dp_program_link_training_pattern(intel_dp, DP_TRAINING_PATTERN_1);
+	intel_dp_program_link_training_pattern(intel_dp, crtc_state,
+					       DP_TRAINING_PATTERN_1);
 
 	/*
 	 * Magic for VLV/CHV. We _must_ first set up the register
@@ -3693,7 +3693,7 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp,
 	 * fail when the power sequencer is freshly used for this port.
 	 */
 	intel_dp->DP |= DP_PORT_EN;
-	if (old_crtc_state->has_audio)
+	if (crtc_state->has_audio)
 		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
 
 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
@@ -3737,8 +3737,8 @@ static void intel_enable_dp(struct intel_atomic_state *state,
 	}
 
 	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
-	intel_dp_start_link_train(intel_dp);
-	intel_dp_stop_link_train(intel_dp);
+	intel_dp_start_link_train(intel_dp, pipe_config);
+	intel_dp_stop_link_train(intel_dp, pipe_config);
 
 	if (pipe_config->has_audio) {
 		drm_dbg(&dev_priv->drm, "Enabling DP audio on pipe %c\n",
@@ -3947,12 +3947,14 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATU
 				DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
 }
 
-static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp)
+static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp,
+				 const struct intel_crtc_state *crtc_state)
 {
 	return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
 }
 
-static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp)
+static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp,
+				 const struct intel_crtc_state *crtc_state)
 {
 	return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
 }
@@ -3967,7 +3969,8 @@ static u8 intel_dp_pre_empemph_max_3(struct intel_dp *intel_dp)
 	return DP_TRAIN_PRE_EMPH_LEVEL_3;
 }
 
-static void vlv_set_signal_levels(struct intel_dp *intel_dp)
+static void vlv_set_signal_levels(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	unsigned long demph_reg_value, preemph_reg_value,
@@ -4047,11 +4050,13 @@ static void vlv_set_signal_levels(struct intel_dp *intel_dp)
 		return;
 	}
 
-	vlv_set_phy_signal_level(encoder, demph_reg_value, preemph_reg_value,
+	vlv_set_phy_signal_level(encoder, crtc_state,
+				 demph_reg_value, preemph_reg_value,
 				 uniqtranscale_reg_value, 0);
 }
 
-static void chv_set_signal_levels(struct intel_dp *intel_dp)
+static void chv_set_signal_levels(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	u32 deemph_reg_value, margin_reg_value;
@@ -4128,8 +4133,9 @@ static void chv_set_signal_levels(struct intel_dp *intel_dp)
 		return;
 	}
 
-	chv_set_phy_signal_level(encoder, deemph_reg_value,
-				 margin_reg_value, uniq_trans_scale);
+	chv_set_phy_signal_level(encoder, crtc_state,
+				 deemph_reg_value, margin_reg_value,
+				 uniq_trans_scale);
 }
 
 static u32 g4x_signal_levels(u8 train_set)
@@ -4170,7 +4176,8 @@ static u32 g4x_signal_levels(u8 train_set)
 }
 
 static void
-g4x_set_signal_levels(struct intel_dp *intel_dp)
+g4x_set_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u8 train_set = intel_dp->train_set[0];
@@ -4217,7 +4224,8 @@ static u32 snb_cpu_edp_signal_levels(u8 train_set)
 }
 
 static void
-snb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp)
+snb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp,
+			      const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u8 train_set = intel_dp->train_set[0];
@@ -4268,7 +4276,8 @@ static u32 ivb_cpu_edp_signal_levels(u8 train_set)
 }
 
 static void
-ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp)
+ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp,
+			      const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u8 train_set = intel_dp->train_set[0];
@@ -4286,7 +4295,8 @@ ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp)
 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
 }
 
-void intel_dp_set_signal_levels(struct intel_dp *intel_dp)
+void intel_dp_set_signal_levels(struct intel_dp *intel_dp,
+				const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u8 train_set = intel_dp->train_set[0];
@@ -4300,11 +4310,12 @@ void intel_dp_set_signal_levels(struct intel_dp *intel_dp)
 		    train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ?
 		    " (max)" : "");
 
-	intel_dp->set_signal_levels(intel_dp);
+	intel_dp->set_signal_levels(intel_dp, crtc_state);
 }
 
 void
 intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
+				       const struct intel_crtc_state *crtc_state,
 				       u8 dp_train_pat)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -4315,13 +4326,14 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
 			    "Using DP training pattern TPS%d\n",
 			    dp_train_pat & train_pat_mask);
 
-	intel_dp->set_link_train(intel_dp, dp_train_pat);
+	intel_dp->set_link_train(intel_dp, crtc_state, dp_train_pat);
 }
 
-void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
+void intel_dp_set_idle_link_train(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *crtc_state)
 {
 	if (intel_dp->set_idle_link_train)
-		intel_dp->set_idle_link_train(intel_dp);
+		intel_dp->set_idle_link_train(intel_dp, crtc_state);
 }
 
 static void
@@ -5312,23 +5324,17 @@ static u8 intel_dp_prepare_phytest(struct intel_dp *intel_dp)
 		return DP_TEST_NAK;
 	}
 
-	/*
-	 * link_mst is set to false to avoid executing mst related code
-	 * during compliance testing.
-	 */
-	intel_dp->link_mst = false;
-
 	return DP_TEST_ACK;
 }
 
-static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp)
+static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
+					const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv =
 			to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_dp_phy_test_params *data =
 			&intel_dp->compliance.test_data.phytest;
-	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	enum pipe pipe = crtc->pipe;
 	u32 pattern_val;
 
@@ -5388,7 +5394,8 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp)
 }
 
 static void
-intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp)
+intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *crtc_state)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = intel_dig_port->base.base.dev;
@@ -5414,7 +5421,8 @@ intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp)
 }
 
 static void
-intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, uint8_t lane_cnt)
+intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp,
+				 const struct intel_crtc_state *crtc_state)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = intel_dig_port->base.base.dev;
@@ -5440,7 +5448,8 @@ intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, uint8_t lane_cnt)
 		       trans_ddi_func_ctl_value);
 }
 
-void intel_dp_process_phy_request(struct intel_dp *intel_dp)
+static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
+					 const struct intel_crtc_state *crtc_state)
 {
 	struct drm_dp_phy_test_params *data =
 		&intel_dp->compliance.test_data.phytest;
@@ -5452,21 +5461,22 @@ void intel_dp_process_phy_request(struct intel_dp *intel_dp)
 	}
 
 	/* retrieve vswing & pre-emphasis setting */
-	intel_dp_get_adjust_train(intel_dp, link_status);
+	intel_dp_get_adjust_train(intel_dp, crtc_state, link_status);
 
-	intel_dp_autotest_phy_ddi_disable(intel_dp);
+	intel_dp_autotest_phy_ddi_disable(intel_dp, crtc_state);
 
-	intel_dp_set_signal_levels(intel_dp);
+	intel_dp_set_signal_levels(intel_dp, crtc_state);
 
-	intel_dp_phy_pattern_update(intel_dp);
+	intel_dp_phy_pattern_update(intel_dp, crtc_state);
 
-	intel_dp_autotest_phy_ddi_enable(intel_dp, data->num_lanes);
+	intel_dp_autotest_phy_ddi_enable(intel_dp, crtc_state);
 
 	drm_dp_set_phy_test_pattern(&intel_dp->aux, data,
 				    link_status[DP_DPCD_REV]);
 }
 
-static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp)
+static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp,
+					const struct intel_crtc_state *crtc_state)
 {
 	u8 test_result;
 
@@ -5474,12 +5484,13 @@ static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp)
 	if (test_result != DP_TEST_ACK)
 		DRM_ERROR("Phy test preparation failed\n");
 
-	intel_dp_process_phy_request(intel_dp);
+	intel_dp_process_phy_request(intel_dp, crtc_state);
 
 	return test_result;
 }
 
-static void intel_dp_handle_test_request(struct intel_dp *intel_dp)
+static void intel_dp_handle_test_request(struct intel_dp *intel_dp,
+					 const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 response = DP_TEST_NAK;
@@ -5508,7 +5519,9 @@ static void intel_dp_handle_test_request(struct intel_dp *intel_dp)
 		break;
 	case DP_TEST_LINK_PHY_TEST_PATTERN:
 		drm_dbg_kms(&i915->drm, "PHY_PATTERN test requested\n");
-		response = intel_dp_autotest_phy_pattern(intel_dp);
+		/* FIXME see intel_dp_check_service_irq() */
+		if (crtc_state)
+			response = intel_dp_autotest_phy_pattern(intel_dp, crtc_state);
 		break;
 	default:
 		drm_dbg_kms(&i915->drm, "Invalid test request '%02x'\n",
@@ -5602,6 +5615,10 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
 	/*
 	 * Validate the cached values of intel_dp->link_rate and
 	 * intel_dp->lane_count before attempting to retrain.
+	 *
+	 * FIXME would be nice to user the crtc state here, but since
+	 * we need to call this from the short HPD handler that seems
+	 * a bit hard.
 	 */
 	if (!intel_dp_link_params_valid(intel_dp, intel_dp->link_rate,
 					intel_dp->lane_count))
@@ -5735,8 +5752,20 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
 							      intel_crtc_pch_transcoder(crtc), false);
 	}
 
-	intel_dp_start_link_train(intel_dp);
-	intel_dp_stop_link_train(intel_dp);
+	for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) {
+		const struct intel_crtc_state *crtc_state =
+			to_intel_crtc_state(crtc->base.state);
+
+		/* retrain on the MST master transcoder */
+		if (INTEL_GEN(dev_priv) >= 12 &&
+		    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
+		    crtc_state->cpu_transcoder != crtc_state->mst_master_transcoder)
+			continue;
+
+		intel_dp_start_link_train(intel_dp, crtc_state);
+		intel_dp_stop_link_train(intel_dp, crtc_state);
+		break;
+	}
 
 	for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) {
 		const struct intel_crtc_state *crtc_state =
@@ -5818,8 +5847,15 @@ static void intel_dp_check_service_irq(struct intel_dp *intel_dp)
 
 	drm_dp_dpcd_writeb(&intel_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR, val);
 
+	/*
+	 * FIXME get rid of the hand rolled modeset code from
+	 * the phy test code and just do proper modesets instead.
+	 * Doing modesets from the short hpd handler is a total
+	 * no no anyway. For now this will not work since we don't
+	 * have a crtc state.
+	 */
 	if (val & DP_AUTOMATED_TEST_REQUEST)
-		intel_dp_handle_test_request(intel_dp);
+		intel_dp_handle_test_request(intel_dp, NULL);
 
 	if (val & DP_CP_IRQ)
 		intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index e8375a75c3ec..25d55c06af19 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -42,8 +42,7 @@ bool intel_dp_init(struct drm_i915_private *dev_priv, i915_reg_t output_reg,
 bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 			     struct intel_connector *intel_connector);
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
-			      int link_rate, u8 lane_count,
-			      bool link_mst);
+			      int link_rate, int lane_count);
 int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 					    int link_rate, u8 lane_count);
 int intel_dp_retrain_link(struct intel_encoder *encoder,
@@ -87,10 +86,13 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
 
 void
 intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
+				       const struct intel_crtc_state *crtc_state,
 				       u8 dp_train_pat);
 void
-intel_dp_set_signal_levels(struct intel_dp *intel_dp);
-void intel_dp_set_idle_link_train(struct intel_dp *intel_dp);
+intel_dp_set_signal_levels(struct intel_dp *intel_dp,
+			   const struct intel_crtc_state *crtc_state);
+void intel_dp_set_idle_link_train(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *crtc_state);
 void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
 			   u8 *link_bw, u8 *rate_select);
 bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
@@ -114,7 +116,6 @@ void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable,
 			     const struct intel_crtc_state *crtc_state,
 			     const struct drm_connector_state *conn_state);
 bool intel_digital_port_connected(struct intel_encoder *encoder);
-void intel_dp_process_phy_request(struct intel_dp *intel_dp);
 
 static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index 2493142a70e9..1b0595715383 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -49,8 +49,10 @@ static u8 dp_voltage_max(u8 preemph)
 	}
 }
 
-void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
-			       const u8 link_status[DP_LINK_STATUS_SIZE])
+void
+intel_dp_get_adjust_train(struct intel_dp *intel_dp,
+			  const struct intel_crtc_state *crtc_state,
+			  const u8 link_status[DP_LINK_STATUS_SIZE])
 {
 	u8 v = 0;
 	u8 p = 0;
@@ -58,7 +60,7 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
 	u8 voltage_max;
 	u8 preemph_max;
 
-	for (lane = 0; lane < intel_dp->lane_count; lane++) {
+	for (lane = 0; lane < crtc_state->lane_count; lane++) {
 		v = max(v, drm_dp_get_adjust_request_voltage(link_status, lane));
 		p = max(p, drm_dp_get_adjust_request_pre_emphasis(link_status, lane));
 	}
@@ -69,7 +71,7 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
 
 	v = min(v, dp_voltage_max(p));
 
-	voltage_max = intel_dp->voltage_max(intel_dp);
+	voltage_max = intel_dp->voltage_max(intel_dp, crtc_state);
 	if (v >= voltage_max)
 		v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;
 
@@ -79,12 +81,14 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
 
 static bool
 intel_dp_set_link_train(struct intel_dp *intel_dp,
+			const struct intel_crtc_state *crtc_state,
 			u8 dp_train_pat)
 {
 	u8 buf[sizeof(intel_dp->train_set) + 1];
 	int ret, len;
 
-	intel_dp_program_link_training_pattern(intel_dp, dp_train_pat);
+	intel_dp_program_link_training_pattern(intel_dp, crtc_state,
+					       dp_train_pat);
 
 	buf[0] = dp_train_pat;
 	if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==
@@ -93,8 +97,8 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 		len = 1;
 	} else {
 		/* DP_TRAINING_LANEx_SET follow DP_TRAINING_PATTERN_SET */
-		memcpy(buf + 1, intel_dp->train_set, intel_dp->lane_count);
-		len = intel_dp->lane_count + 1;
+		memcpy(buf + 1, intel_dp->train_set, crtc_state->lane_count);
+		len = crtc_state->lane_count + 1;
 	}
 
 	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET,
@@ -105,31 +109,34 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 
 static bool
 intel_dp_reset_link_train(struct intel_dp *intel_dp,
-			u8 dp_train_pat)
+			  const struct intel_crtc_state *crtc_state,
+			  u8 dp_train_pat)
 {
 	memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
-	intel_dp_set_signal_levels(intel_dp);
-	return intel_dp_set_link_train(intel_dp, dp_train_pat);
+	intel_dp_set_signal_levels(intel_dp, crtc_state);
+	return intel_dp_set_link_train(intel_dp, crtc_state, dp_train_pat);
 }
 
 static bool
-intel_dp_update_link_train(struct intel_dp *intel_dp)
+intel_dp_update_link_train(struct intel_dp *intel_dp,
+			   const struct intel_crtc_state *crtc_state)
 {
 	int ret;
 
-	intel_dp_set_signal_levels(intel_dp);
+	intel_dp_set_signal_levels(intel_dp, crtc_state);
 
 	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
-				intel_dp->train_set, intel_dp->lane_count);
+				intel_dp->train_set, crtc_state->lane_count);
 
-	return ret == intel_dp->lane_count;
+	return ret == crtc_state->lane_count;
 }
 
-static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp)
+static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp,
+					     const struct intel_crtc_state *crtc_state)
 {
 	int lane;
 
-	for (lane = 0; lane < intel_dp->lane_count; lane++)
+	for (lane = 0; lane < crtc_state->lane_count; lane++)
 		if ((intel_dp->train_set[lane] &
 		     DP_TRAIN_MAX_SWING_REACHED) == 0)
 			return false;
@@ -139,7 +146,8 @@ static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp)
 
 /* Enable corresponding port and start training pattern 1 */
 static bool
-intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
+intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp,
+				      const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 voltage;
@@ -149,9 +157,9 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 	u8 link_bw, rate_select;
 
 	if (intel_dp->prepare_link_retrain)
-		intel_dp->prepare_link_retrain(intel_dp);
+		intel_dp->prepare_link_retrain(intel_dp, crtc_state);
 
-	intel_dp_compute_rate(intel_dp, intel_dp->link_rate,
+	intel_dp_compute_rate(intel_dp, crtc_state->port_clock,
 			      &link_bw, &rate_select);
 
 	if (link_bw)
@@ -163,7 +171,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 
 	/* Write the link configuration data */
 	link_config[0] = link_bw;
-	link_config[1] = intel_dp->lane_count;
+	link_config[1] = crtc_state->lane_count;
 	if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
 		link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
 	drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2);
@@ -180,7 +188,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 	intel_dp->DP |= DP_PORT_EN;
 
 	/* clock recovery */
-	if (!intel_dp_reset_link_train(intel_dp,
+	if (!intel_dp_reset_link_train(intel_dp, crtc_state,
 				       DP_TRAINING_PATTERN_1 |
 				       DP_LINK_SCRAMBLING_DISABLE)) {
 		drm_err(&i915->drm, "failed to enable link training\n");
@@ -211,7 +219,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 			return false;
 		}
 
-		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
+		if (drm_dp_clock_recovery_ok(link_status, crtc_state->lane_count)) {
 			drm_dbg_kms(&i915->drm, "clock recovery OK\n");
 			return true;
 		}
@@ -230,8 +238,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
 		/* Update training set as requested by target */
-		intel_dp_get_adjust_train(intel_dp, link_status);
-		if (!intel_dp_update_link_train(intel_dp)) {
+		intel_dp_get_adjust_train(intel_dp, crtc_state, link_status);
+		if (!intel_dp_update_link_train(intel_dp, crtc_state)) {
 			drm_err(&i915->drm,
 				"failed to update link training\n");
 			return false;
@@ -243,7 +251,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 		else
 			voltage_tries = 1;
 
-		if (intel_dp_link_max_vswing_reached(intel_dp))
+		if (intel_dp_link_max_vswing_reached(intel_dp, crtc_state))
 			max_vswing_reached = true;
 
 	}
@@ -257,7 +265,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
  * 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)
+static u32 intel_dp_training_pattern(struct intel_dp *intel_dp,
+				     const struct intel_crtc_state *crtc_state)
 {
 	bool source_tps3, sink_tps3, source_tps4, sink_tps4;
 
@@ -271,7 +280,7 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
 	sink_tps4 = drm_dp_tps4_supported(intel_dp->dpcd);
 	if (source_tps4 && sink_tps4) {
 		return DP_TRAINING_PATTERN_4;
-	} else if (intel_dp->link_rate == 810000) {
+	} else if (crtc_state->port_clock == 810000) {
 		if (!source_tps4)
 			drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
 				    "8.1 Gbps link rate without source HBR3/TPS4 support\n");
@@ -288,7 +297,7 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
 	sink_tps3 = drm_dp_tps3_supported(intel_dp->dpcd);
 	if (source_tps3 && sink_tps3) {
 		return  DP_TRAINING_PATTERN_3;
-	} else if (intel_dp->link_rate >= 540000) {
+	} else if (crtc_state->port_clock >= 540000) {
 		if (!source_tps3)
 			drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
 				    ">=5.4/6.48 Gbps link rate without source HBR2/TPS3 support\n");
@@ -301,7 +310,8 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
 }
 
 static bool
-intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
+intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp,
+					    const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	int tries;
@@ -309,13 +319,13 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 	u8 link_status[DP_LINK_STATUS_SIZE];
 	bool channel_eq = false;
 
-	training_pattern = intel_dp_training_pattern(intel_dp);
+	training_pattern = intel_dp_training_pattern(intel_dp, crtc_state);
 	/* Scrambling is disabled for TPS2/3 and enabled for TPS4 */
 	if (training_pattern != DP_TRAINING_PATTERN_4)
 		training_pattern |= DP_LINK_SCRAMBLING_DISABLE;
 
 	/* channel equalization */
-	if (!intel_dp_set_link_train(intel_dp,
+	if (!intel_dp_set_link_train(intel_dp, crtc_state,
 				     training_pattern)) {
 		drm_err(&i915->drm, "failed to start channel equalization\n");
 		return false;
@@ -332,7 +342,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 
 		/* Make sure clock is still ok */
 		if (!drm_dp_clock_recovery_ok(link_status,
-					      intel_dp->lane_count)) {
+					      crtc_state->lane_count)) {
 			intel_dp_dump_link_status(link_status);
 			drm_dbg_kms(&i915->drm,
 				    "Clock recovery check failed, cannot "
@@ -341,7 +351,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 		}
 
 		if (drm_dp_channel_eq_ok(link_status,
-					 intel_dp->lane_count)) {
+					 crtc_state->lane_count)) {
 			channel_eq = true;
 			drm_dbg_kms(&i915->drm, "Channel EQ done. DP Training "
 				    "successful\n");
@@ -349,8 +359,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 		}
 
 		/* Update training set as requested by target */
-		intel_dp_get_adjust_train(intel_dp, link_status);
-		if (!intel_dp_update_link_train(intel_dp)) {
+		intel_dp_get_adjust_train(intel_dp, crtc_state, link_status);
+		if (!intel_dp_update_link_train(intel_dp, crtc_state)) {
 			drm_err(&i915->drm,
 				"failed to update link training\n");
 			break;
@@ -364,35 +374,37 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 			    "Channel equalization failed 5 times\n");
 	}
 
-	intel_dp_set_idle_link_train(intel_dp);
+	intel_dp_set_idle_link_train(intel_dp, crtc_state);
 
 	return channel_eq;
 
 }
 
-void intel_dp_stop_link_train(struct intel_dp *intel_dp)
+void intel_dp_stop_link_train(struct intel_dp *intel_dp,
+			      const struct intel_crtc_state *crtc_state)
 {
 	intel_dp->link_trained = true;
 
-	intel_dp_set_link_train(intel_dp,
+	intel_dp_set_link_train(intel_dp, crtc_state,
 				DP_TRAINING_PATTERN_DISABLE);
 }
 
 void
-intel_dp_start_link_train(struct intel_dp *intel_dp)
+intel_dp_start_link_train(struct intel_dp *intel_dp,
+			  const struct intel_crtc_state *crtc_state)
 {
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
 
-	if (!intel_dp_link_training_clock_recovery(intel_dp))
+	if (!intel_dp_link_training_clock_recovery(intel_dp, crtc_state))
 		goto failure_handling;
-	if (!intel_dp_link_training_channel_equalization(intel_dp))
+	if (!intel_dp_link_training_channel_equalization(intel_dp, crtc_state))
 		goto failure_handling;
 
 	drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
 		    "[CONNECTOR:%d:%s] Link Training Passed at Link Rate = %d, Lane count = %d",
 		    intel_connector->base.base.id,
 		    intel_connector->base.name,
-		    intel_dp->link_rate, intel_dp->lane_count);
+		    crtc_state->port_clock, crtc_state->lane_count);
 	return;
 
  failure_handling:
@@ -400,10 +412,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 		    "[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
 		    intel_connector->base.base.id,
 		    intel_connector->base.name,
-		    intel_dp->link_rate, intel_dp->lane_count);
+		    crtc_state->port_clock, crtc_state->lane_count);
 	if (!intel_dp_get_link_train_fallback_values(intel_dp,
-						     intel_dp->link_rate,
-						     intel_dp->lane_count))
+						     crtc_state->port_clock,
+						     crtc_state->lane_count))
 		/* Schedule a Hotplug Uevent to userspace to start modeset */
 		schedule_work(&intel_connector->modeset_retry_work);
 	return;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
index 01f1dabbb060..ae804ec1324c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
@@ -11,8 +11,11 @@
 struct intel_dp;
 
 void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
+			       const struct intel_crtc_state *crtc_state,
 			       const u8 link_status[DP_LINK_STATUS_SIZE]);
-void intel_dp_start_link_train(struct intel_dp *intel_dp);
-void intel_dp_stop_link_train(struct intel_dp *intel_dp);
+void intel_dp_start_link_train(struct intel_dp *intel_dp,
+			       const struct intel_crtc_state *crtc_state);
+void intel_dp_stop_link_train(struct intel_dp *intel_dp,
+			      const struct intel_crtc_state *crtc_state);
 
 #endif /* __INTEL_DP_LINK_TRAINING_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index 399a7edb4568..79da281d46db 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -644,16 +644,16 @@ bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder)
 	return mask;
 }
 
-
 void chv_set_phy_signal_level(struct intel_encoder *encoder,
+			      const struct intel_crtc_state *crtc_state,
 			      u32 deemph_reg_value, u32 margin_reg_value,
 			      bool uniq_trans_scale)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_digital_port *dport = enc_to_dig_port(encoder);
-	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	enum dpio_channel ch = vlv_dport_to_channel(dport);
-	enum pipe pipe = intel_crtc->pipe;
+	enum pipe pipe = crtc->pipe;
 	u32 val;
 	int i;
 
@@ -666,7 +666,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 	val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
 
-	if (intel_crtc->config->lane_count > 2) {
+	if (crtc_state->lane_count > 2) {
 		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
 		val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
 		val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
@@ -679,7 +679,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 	val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val);
 
-	if (intel_crtc->config->lane_count > 2) {
+	if (crtc_state->lane_count > 2) {
 		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
 		val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
 		val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
@@ -687,7 +687,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 	}
 
 	/* Program swing deemph */
-	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+	for (i = 0; i < crtc_state->lane_count; i++) {
 		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i));
 		val &= ~DPIO_SWING_DEEMPH9P5_MASK;
 		val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT;
@@ -695,7 +695,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 	}
 
 	/* Program swing margin */
-	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+	for (i = 0; i < crtc_state->lane_count; i++) {
 		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
 
 		val &= ~DPIO_SWING_MARGIN000_MASK;
@@ -718,7 +718,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 	 * For now, for this unique transition scale selection, set bit
 	 * 27 for ch0 and ch1.
 	 */
-	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+	for (i = 0; i < crtc_state->lane_count; i++) {
 		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
 		if (uniq_trans_scale)
 			val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
@@ -732,7 +732,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 	val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
 
-	if (intel_crtc->config->lane_count > 2) {
+	if (crtc_state->lane_count > 2) {
 		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
 		val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
 		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
@@ -992,14 +992,15 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder,
 }
 
 void vlv_set_phy_signal_level(struct intel_encoder *encoder,
+			      const struct intel_crtc_state *crtc_state,
 			      u32 demph_reg_value, u32 preemph_reg_value,
 			      u32 uniqtranscale_reg_value, u32 tx3_demph)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_digital_port *dport = enc_to_dig_port(encoder);
 	enum dpio_channel port = vlv_dport_to_channel(dport);
-	enum pipe pipe = intel_crtc->pipe;
+	enum pipe pipe = crtc->pipe;
 
 	vlv_dpio_get(dev_priv);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.h b/drivers/gpu/drm/i915/display/intel_dpio_phy.h
index f418aab90b7e..6473440e7457 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.h
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.h
@@ -32,6 +32,7 @@ void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder,
 u8 bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder);
 
 void chv_set_phy_signal_level(struct intel_encoder *encoder,
+			      const struct intel_crtc_state *crtc_state,
 			      u32 deemph_reg_value, u32 margin_reg_value,
 			      bool uniq_trans_scale);
 void chv_data_lane_soft_reset(struct intel_encoder *encoder,
@@ -46,6 +47,7 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder,
 			      const struct intel_crtc_state *old_crtc_state);
 
 void vlv_set_phy_signal_level(struct intel_encoder *encoder,
+			      const struct intel_crtc_state *crtc_state,
 			      u32 demph_reg_value, u32 preemph_reg_value,
 			      u32 uniqtranscale_reg_value, u32 tx3_demph);
 void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 010f37240710..81218d968a7e 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2730,8 +2730,9 @@ static void vlv_hdmi_pre_enable(struct intel_atomic_state *state,
 	vlv_phy_pre_encoder_enable(encoder, pipe_config);
 
 	/* HDMI 1.0V-2dB */
-	vlv_set_phy_signal_level(encoder, 0x2b245f5f, 0x00002000, 0x5578b83a,
-				 0x2b247878);
+	vlv_set_phy_signal_level(encoder, pipe_config,
+				 0x2b245f5f, 0x00002000,
+				 0x5578b83a, 0x2b247878);
 
 	dport->set_infoframes(encoder,
 			      pipe_config->has_infoframe,
@@ -2808,7 +2809,7 @@ static void chv_hdmi_pre_enable(struct intel_atomic_state *state,
 
 	/* FIXME: Program the support xxx V-dB */
 	/* Use 800mV-0dB */
-	chv_set_phy_signal_level(encoder, 128, 102, false);
+	chv_set_phy_signal_level(encoder, pipe_config, 128, 102, false);
 
 	dport->set_infoframes(encoder,
 			      pipe_config->has_infoframe,
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Intel-gfx] [PATCH 9/9] drm/i915: Eliminate intel_dp.regs.dp_tp_{ctl, status}
  2020-05-06 11:23 [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code Ville Syrjala
                   ` (7 preceding siblings ...)
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 8/9] drm/i915: Plumb crtc_state to link training Ville Syrjala
@ 2020-05-06 11:23 ` Ville Syrjala
  2020-05-06 11:29 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for drm/i915: Plumb crtc state to link training code Patchwork
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Ville Syrjala @ 2020-05-06 11:23 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Now that we've plumbed the crtc state all the way down we can
eliminate the DP_TP_{CTL,STATUS} register offsets from intel_dp,
and instead we derive them directly from the crtc state.

And thus we can get rid of the nasty hack in intel_ddi_get_config()
which mutates intel_dp during the readout.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      | 103 ++++++++++--------
 drivers/gpu/drm/i915/display/intel_ddi.h      |   5 +
 .../drm/i915/display/intel_display_types.h    |   8 --
 drivers/gpu/drm/i915/display/intel_dp.c       |   2 -
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  10 +-
 5 files changed, 68 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 77d2021d0bcd..8e7caf78ea09 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3029,6 +3029,37 @@ icl_program_mg_dp_mode(struct intel_digital_port *intel_dig_port,
 	}
 }
 
+static enum transcoder
+tgl_dp_tp_transcoder(const struct intel_crtc_state *crtc_state)
+{
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))
+		return crtc_state->mst_master_transcoder;
+	else
+		return crtc_state->cpu_transcoder;
+}
+
+i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder,
+			 const struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+	if (INTEL_GEN(dev_priv) >= 12)
+		return TGL_DP_TP_CTL(tgl_dp_tp_transcoder(crtc_state));
+	else
+		return DP_TP_CTL(encoder->port);
+}
+
+i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder,
+			    const struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+	if (INTEL_GEN(dev_priv) >= 12)
+		return TGL_DP_TP_STATUS(tgl_dp_tp_transcoder(crtc_state));
+	else
+		return DP_TP_STATUS(encoder->port);
+}
+
 static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
 					const struct intel_crtc_state *crtc_state)
 {
@@ -3053,11 +3084,12 @@ static void intel_ddi_enable_fec(struct intel_encoder *encoder,
 		return;
 
 	intel_dp = enc_to_intel_dp(encoder);
-	val = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+	val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 	val |= DP_TP_CTL_FEC_ENABLE;
-	intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, val);
+	intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
 
-	if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
+	if (intel_de_wait_for_set(dev_priv,
+				  dp_tp_status_reg(encoder, crtc_state),
 				  DP_TP_STATUS_FEC_ENABLE_LIVE, 1))
 		drm_err(&dev_priv->drm,
 			"Timed out waiting for FEC Enable Status\n");
@@ -3074,10 +3106,10 @@ static void intel_ddi_disable_fec_state(struct intel_encoder *encoder,
 		return;
 
 	intel_dp = enc_to_intel_dp(encoder);
-	val = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+	val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 	val &= ~DP_TP_CTL_FEC_ENABLE;
-	intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, val);
-	intel_de_posting_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+	intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
+	intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 }
 
 static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
@@ -3091,15 +3123,11 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 	bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST);
 	int level = intel_ddi_dp_level(intel_dp);
-	enum transcoder transcoder = crtc_state->cpu_transcoder;
 
 	intel_dp_set_link_params(intel_dp,
 				 crtc_state->port_clock,
 				 crtc_state->lane_count);
 
-	intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
-	intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
-
 	/*
 	 * 1. Enable Power Wells
 	 *
@@ -3418,12 +3446,10 @@ static void intel_disable_ddi_buf(struct intel_encoder *encoder,
 	}
 
 	if (intel_crtc_has_dp_encoder(crtc_state)) {
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-		val = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+		val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 		val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
 		val |= DP_TP_CTL_LINK_TRAIN_PAT1;
-		intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, val);
+		intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
 	}
 
 	/* Disable FEC in DP Sink */
@@ -3915,14 +3941,13 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
 static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
 					   const struct intel_crtc_state *crtc_state)
 {
-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	struct drm_i915_private *dev_priv =
-		to_i915(intel_dig_port->base.base.dev);
-	enum port port = intel_dig_port->base.port;
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum port port = encoder->port;
 	u32 dp_tp_ctl, ddi_buf_ctl;
 	bool wait = false;
 
-	dp_tp_ctl = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+	dp_tp_ctl = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 
 	if (dp_tp_ctl & DP_TP_CTL_ENABLE) {
 		ddi_buf_ctl = intel_de_read(dev_priv, DDI_BUF_CTL(port));
@@ -3934,8 +3959,8 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
 
 		dp_tp_ctl &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
 		dp_tp_ctl |= DP_TP_CTL_LINK_TRAIN_PAT1;
-		intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, dp_tp_ctl);
-		intel_de_posting_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+		intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl);
+		intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 
 		if (wait)
 			intel_wait_ddi_buf_idle(dev_priv, port);
@@ -3950,8 +3975,8 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
 		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
 			dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
 	}
-	intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, dp_tp_ctl);
-	intel_de_posting_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+	intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl);
+	intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 
 	intel_dp->DP |= DDI_BUF_CTL_ENABLE;
 	intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
@@ -3964,12 +3989,13 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
 				     const struct intel_crtc_state *crtc_state,
 				     u8 dp_train_pat)
 {
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	u8 train_pat_mask = drm_dp_training_pattern_mask(intel_dp->dpcd);
 	enum port port = dp_to_dig_port(intel_dp)->base.port;
 	u32 temp;
 
-	temp = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+	temp = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 
 	if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE)
 		temp |= DP_TP_CTL_SCRAMBLE_DISABLE;
@@ -3995,7 +4021,7 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
 		break;
 	}
 
-	intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, temp);
+	intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), temp);
 
 	intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
 	intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
@@ -4009,10 +4035,10 @@ static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp,
 	enum port port = encoder->port;
 	u32 val;
 
-	val = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+	val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 	val &= ~DP_TP_CTL_LINK_TRAIN_MASK;
 	val |= DP_TP_CTL_LINK_TRAIN_IDLE;
-	intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, val);
+	intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
 
 	/*
 	 * Until TGL on PORT_A we can have only eDP in SST mode. There the only
@@ -4024,7 +4050,8 @@ static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp,
 	if (port == PORT_A && INTEL_GEN(dev_priv) < 12)
 		return;
 
-	if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
+	if (intel_de_wait_for_set(dev_priv,
+				  dp_tp_status_reg(encoder, crtc_state),
 				  DP_TP_STATUS_IDLE_DONE, 1))
 		drm_err(&dev_priv->drm,
 			"Timed out waiting for DP idle patterns\n");
@@ -4122,18 +4149,12 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
-	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	u32 temp, flags = 0;
 
 	/* XXX: DSI transcoder paranoia */
 	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
 		return;
 
-	if (INTEL_GEN(dev_priv) >= 12) {
-		intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(cpu_transcoder);
-		intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(cpu_transcoder);
-	}
-
 	intel_dsc_get_config(encoder, pipe_config);
 
 	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
@@ -4197,12 +4218,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 		intel_dp_get_m_n(intel_crtc, pipe_config);
 
 		if (INTEL_GEN(dev_priv) >= 11) {
-			i915_reg_t dp_tp_ctl;
-
-			if (IS_GEN(dev_priv, 11))
-				dp_tp_ctl = DP_TP_CTL(encoder->port);
-			else
-				dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
+			i915_reg_t dp_tp_ctl = dp_tp_ctl_reg(encoder, pipe_config);
 
 			pipe_config->fec_enable =
 				intel_de_read(dev_priv, dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
@@ -4491,11 +4507,6 @@ intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
 	intel_dig_port->dp.voltage_max = intel_ddi_dp_voltage_max;
 	intel_dig_port->dp.preemph_max = intel_ddi_dp_preemph_max;
 
-	if (INTEL_GEN(dev_priv) < 12) {
-		intel_dig_port->dp.regs.dp_tp_ctl = DP_TP_CTL(port);
-		intel_dig_port->dp.regs.dp_tp_status = DP_TP_STATUS(port);
-	}
-
 	if (!intel_dp_init_connector(intel_dig_port, connector)) {
 		kfree(connector);
 		return NULL;
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h
index 7a06bb942d21..c4c90815c5f6 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -7,6 +7,7 @@
 #define __INTEL_DDI_H__
 
 #include "intel_display.h"
+#include "i915_reg.h"
 
 struct drm_connector_state;
 struct drm_i915_private;
@@ -17,6 +18,10 @@ struct intel_dp;
 struct intel_dpll_hw_state;
 struct intel_encoder;
 
+i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder,
+			 const struct intel_crtc_state *crtc_state);
+i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder,
+			    const struct intel_crtc_state *crtc_state);
 void intel_ddi_fdi_post_disable(struct intel_atomic_state *state,
 				struct intel_encoder *intel_encoder,
 				const struct intel_crtc_state *old_crtc_state,
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index b7177134acc3..97ca779f7470 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1338,14 +1338,6 @@ struct intel_dp {
 	bool is_mst;
 	int active_mst_links;
 
-	/*
-	 * DP_TP_* registers may be either on port or transcoder register space.
-	 */
-	struct {
-		i915_reg_t dp_tp_ctl;
-		i915_reg_t dp_tp_status;
-	} regs;
-
 	/* connector directly attached - won't be use for modeset in mst world */
 	struct intel_connector *attached_connector;
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 562cb560d6c0..c613fc087201 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -8504,8 +8504,6 @@ bool intel_dp_init(struct drm_i915_private *dev_priv,
 
 	intel_dig_port->dp.output_reg = output_reg;
 	intel_dig_port->max_lanes = 4;
-	intel_dig_port->dp.regs.dp_tp_ctl = DP_TP_CTL(port);
-	intel_dig_port->dp.regs.dp_tp_status = DP_TP_STATUS(port);
 
 	intel_encoder->type = INTEL_OUTPUT_DP;
 	intel_encoder->power_domain = intel_port_to_power_domain(port);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 4d2384650383..9a05200a74f4 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -376,7 +376,8 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
 		       TRANS_DDI_FUNC_CTL(old_crtc_state->cpu_transcoder),
 		       val);
 
-	if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
+	if (intel_de_wait_for_set(dev_priv,
+				  dp_tp_ctl_reg(encoder, old_crtc_state),
 				  DP_TP_STATUS_ACT_SENT, 1))
 		drm_err(&dev_priv->drm,
 			"Timed out waiting for ACT sent when disabling\n");
@@ -476,8 +477,8 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
 		drm_err(&dev_priv->drm, "failed to allocate vcpi\n");
 
 	intel_dp->active_mst_links++;
-	temp = intel_de_read(dev_priv, intel_dp->regs.dp_tp_status);
-	intel_de_write(dev_priv, intel_dp->regs.dp_tp_status, temp);
+	temp = intel_de_read(dev_priv, dp_tp_status_reg(encoder, pipe_config));
+	intel_de_write(dev_priv, dp_tp_status_reg(encoder, pipe_config), temp);
 
 	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
 
@@ -517,7 +518,8 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
 	drm_dbg_kms(&dev_priv->drm, "active links %d\n",
 		    intel_dp->active_mst_links);
 
-	if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
+	if (intel_de_wait_for_set(dev_priv,
+				  dp_tp_status_reg(encoder, pipe_config),
 				  DP_TP_STATUS_ACT_SENT, 1))
 		drm_err(&dev_priv->drm, "Timed out waiting for ACT sent\n");
 
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Intel-gfx] ✗ Fi.CI.BUILD: failure for drm/i915: Plumb crtc state to link training code
  2020-05-06 11:23 [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code Ville Syrjala
                   ` (8 preceding siblings ...)
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 9/9] drm/i915: Eliminate intel_dp.regs.dp_tp_{ctl, status} Ville Syrjala
@ 2020-05-06 11:29 ` Patchwork
  2020-05-06 12:49 ` [Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: Plumb crtc state to link training code (rev2) Patchwork
  2020-05-06 13:48 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
  11 siblings, 0 replies; 15+ messages in thread
From: Patchwork @ 2020-05-06 11:29 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Plumb crtc state to link training code
URL   : https://patchwork.freedesktop.org/series/76993/
State : failure

== Summary ==

CALL    scripts/checksyscalls.sh
  CALL    scripts/atomic/check-atomics.sh
  DESCEND  objtool
  CHK     include/generated/compile.h
  HDRTEST drivers/gpu/drm/i915/display/intel_dp_link_training.h
In file included from <command-line>:0:0:
./drivers/gpu/drm/i915/display/intel_dp_link_training.h:14:24: error: ‘struct intel_crtc_state’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
           const struct intel_crtc_state *crtc_state,
                        ^~~~~~~~~~~~~~~~
./drivers/gpu/drm/i915/display/intel_dp_link_training.h:17:24: error: ‘struct intel_crtc_state’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
           const struct intel_crtc_state *crtc_state);
                        ^~~~~~~~~~~~~~~~
./drivers/gpu/drm/i915/display/intel_dp_link_training.h:19:23: error: ‘struct intel_crtc_state’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
          const struct intel_crtc_state *crtc_state);
                       ^~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
drivers/gpu/drm/i915/Makefile:299: recipe for target 'drivers/gpu/drm/i915/display/intel_dp_link_training.hdrtest' failed
make[4]: *** [drivers/gpu/drm/i915/display/intel_dp_link_training.hdrtest] Error 1
scripts/Makefile.build:488: recipe for target 'drivers/gpu/drm/i915' failed
make[3]: *** [drivers/gpu/drm/i915] Error 2
scripts/Makefile.build:488: recipe for target 'drivers/gpu/drm' failed
make[2]: *** [drivers/gpu/drm] Error 2
scripts/Makefile.build:488: recipe for target 'drivers/gpu' failed
make[1]: *** [drivers/gpu] Error 2
Makefile:1722: recipe for target 'drivers' failed
make: *** [drivers] Error 2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Intel-gfx] [PATCH v2 8/9] drm/i915: Plumb crtc_state to link training
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 8/9] drm/i915: Plumb crtc_state to link training Ville Syrjala
@ 2020-05-06 12:05   ` Ville Syrjala
  0 siblings, 0 replies; 15+ messages in thread
From: Ville Syrjala @ 2020-05-06 12:05 UTC (permalink / raw)
  To: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Get rid of mode crtc->config usage, and some ad-hoc intel_dp state
usage by plumbing the crtc state all the way down to the link training
code.

Unfortunately we do have to keep some cached state in intel_dp so
that we can do the "does the link need retraining?" checks from
the short hpd handler.

The PHY test code seems to have started to build some kind of NIH
modeset code right into intel_dp.c. That's not how we should do
things, and instead we should just go through the normal modeset
machinery for that (meaning it all needs to move into the hotplug
work as well, just like we've already done for normal link retraining).
For now just neuter that code and toss in a FIXME.

v2: Add intel_crtc_state forward declaration

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      | 334 +++++++++---------
 drivers/gpu/drm/i915/display/intel_ddi.h      |   6 +-
 .../drm/i915/display/intel_display_types.h    |  17 +-
 drivers/gpu/drm/i915/display/intel_dp.c       | 138 +++++---
 drivers/gpu/drm/i915/display/intel_dp.h       |  11 +-
 .../drm/i915/display/intel_dp_link_training.c | 102 +++---
 .../drm/i915/display/intel_dp_link_training.h |   8 +-
 drivers/gpu/drm/i915/display/intel_dpio_phy.c |  23 +-
 drivers/gpu/drm/i915/display/intel_dpio_phy.h |   2 +
 drivers/gpu/drm/i915/display/intel_hdmi.c     |   7 +-
 10 files changed, 350 insertions(+), 298 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 409b8a68570f..77d2021d0bcd 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -953,68 +953,75 @@ cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
 }
 
 static const struct cnl_ddi_buf_trans *
-icl_get_combo_buf_trans(struct drm_i915_private *dev_priv, int type, int rate,
+icl_get_combo_buf_trans(const struct intel_crtc_state *crtc_state,
 			int *n_entries)
 {
-	if (type == INTEL_OUTPUT_HDMI) {
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
 		*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
 		return icl_combo_phy_ddi_translations_hdmi;
-	} else if (rate > 540000 && type == INTEL_OUTPUT_EDP) {
+	} else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+		   crtc_state->port_clock > 540000) {
 		*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3);
 		return icl_combo_phy_ddi_translations_edp_hbr3;
-	} else if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) {
+	} else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+		   dev_priv->vbt.edp.low_vswing) {
 		*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2);
 		return icl_combo_phy_ddi_translations_edp_hbr2;
+	} else {
+		*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2);
+		return icl_combo_phy_ddi_translations_dp_hbr2;
 	}
-
-	*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2);
-	return icl_combo_phy_ddi_translations_dp_hbr2;
 }
 
 static const struct icl_mg_phy_ddi_buf_trans *
-icl_get_mg_buf_trans(struct drm_i915_private *dev_priv, int type, int rate,
+icl_get_mg_buf_trans(const struct intel_crtc_state *crtc_state,
 		     int *n_entries)
 {
-	if (type == INTEL_OUTPUT_HDMI) {
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
 		*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hdmi);
 		return icl_mg_phy_ddi_translations_hdmi;
-	} else if (rate > 270000) {
+	} else if (crtc_state->port_clock > 270000) {
 		*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hbr2_hbr3);
 		return icl_mg_phy_ddi_translations_hbr2_hbr3;
+	} else {
+		*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_rbr_hbr);
+		return icl_mg_phy_ddi_translations_rbr_hbr;
 	}
-
-	*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_rbr_hbr);
-	return icl_mg_phy_ddi_translations_rbr_hbr;
 }
 
 static const struct cnl_ddi_buf_trans *
-ehl_get_combo_buf_trans(struct drm_i915_private *dev_priv, int type, int rate,
+ehl_get_combo_buf_trans(const struct intel_crtc_state *crtc_state,
 			int *n_entries)
 {
-	if (type != INTEL_OUTPUT_HDMI && type != INTEL_OUTPUT_EDP) {
+	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
+	    !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) {
 		*n_entries = ARRAY_SIZE(ehl_combo_phy_ddi_translations_dp);
 		return ehl_combo_phy_ddi_translations_dp;
+	} else {
+		return icl_get_combo_buf_trans(crtc_state, n_entries);
 	}
-
-	return icl_get_combo_buf_trans(dev_priv, type, rate, n_entries);
 }
 
 static const struct cnl_ddi_buf_trans *
-tgl_get_combo_buf_trans(struct drm_i915_private *dev_priv, int type, int rate,
+tgl_get_combo_buf_trans(const struct intel_crtc_state *crtc_state,
 			int *n_entries)
 {
-	if (type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_EDP) {
-		return icl_get_combo_buf_trans(dev_priv, type, rate, n_entries);
-	} else if (rate > 270000) {
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) ||
+	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) {
+		return icl_get_combo_buf_trans(crtc_state, n_entries);
+	} else if (crtc_state->port_clock > 270000) {
 		*n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr2);
 		return tgl_combo_phy_ddi_translations_dp_hbr2;
+	} else {
+		*n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr);
+		return tgl_combo_phy_ddi_translations_dp_hbr;
 	}
-
-	*n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr);
-	return tgl_combo_phy_ddi_translations_dp_hbr;
 }
 
-static int intel_ddi_hdmi_level(struct intel_encoder *encoder)
+static int intel_ddi_hdmi_level(struct intel_encoder *encoder,
+				const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	int n_entries, level, default_entry;
@@ -1022,18 +1029,15 @@ static int intel_ddi_hdmi_level(struct intel_encoder *encoder)
 
 	if (INTEL_GEN(dev_priv) >= 12) {
 		if (intel_phy_is_combo(dev_priv, phy))
-			tgl_get_combo_buf_trans(dev_priv, INTEL_OUTPUT_HDMI,
-						0, &n_entries);
+			tgl_get_combo_buf_trans(crtc_state, &n_entries);
 		else
 			n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
 		default_entry = n_entries - 1;
 	} else if (INTEL_GEN(dev_priv) == 11) {
 		if (intel_phy_is_combo(dev_priv, phy))
-			icl_get_combo_buf_trans(dev_priv, INTEL_OUTPUT_HDMI,
-						0, &n_entries);
+			icl_get_combo_buf_trans(crtc_state, &n_entries);
 		else
-			icl_get_mg_buf_trans(dev_priv, INTEL_OUTPUT_HDMI, 0,
-					     &n_entries);
+			icl_get_mg_buf_trans(crtc_state, &n_entries);
 		default_entry = n_entries - 1;
 	} else if (IS_CANNONLAKE(dev_priv)) {
 		cnl_get_buf_trans_hdmi(dev_priv, &n_entries);
@@ -1346,7 +1350,8 @@ void hsw_fdi_link_train(struct intel_encoder *encoder,
 		       DP_TP_CTL_ENABLE);
 }
 
-static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
+static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder,
+				      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	struct intel_digital_port *intel_dig_port =
@@ -1354,7 +1359,7 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
 
 	intel_dp->DP = intel_dig_port->saved_port_bits |
 		DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
-	intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
+	intel_dp->DP |= DDI_PORT_WIDTH(crtc_state->lane_count);
 }
 
 static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv,
@@ -2025,14 +2030,15 @@ static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
 }
 
 static void skl_ddi_set_iboost(struct intel_encoder *encoder,
-			       int level, enum intel_output_type type)
+			       const struct intel_crtc_state *crtc_state,
+			       int level)
 {
 	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum port port = encoder->port;
 	u8 iboost;
 
-	if (type == INTEL_OUTPUT_HDMI)
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 		iboost = intel_bios_hdmi_boost_level(encoder);
 	else
 		iboost = intel_bios_dp_boost_level(encoder);
@@ -2041,9 +2047,9 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,
 		const struct ddi_buf_trans *ddi_translations;
 		int n_entries;
 
-		if (type == INTEL_OUTPUT_HDMI)
+		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 			ddi_translations = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries);
-		else if (type == INTEL_OUTPUT_EDP)
+		else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
 			ddi_translations = intel_ddi_get_buf_trans_edp(dev_priv, port, &n_entries);
 		else
 			ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, port, &n_entries);
@@ -2069,16 +2075,17 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,
 }
 
 static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
-				    int level, enum intel_output_type type)
+				    const struct intel_crtc_state *crtc_state,
+				    int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	const struct bxt_ddi_buf_trans *ddi_translations;
 	enum port port = encoder->port;
 	int n_entries;
 
-	if (type == INTEL_OUTPUT_HDMI)
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 		ddi_translations = bxt_get_buf_trans_hdmi(dev_priv, &n_entries);
-	else if (type == INTEL_OUTPUT_EDP)
+	else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
 		ddi_translations = bxt_get_buf_trans_edp(dev_priv, &n_entries);
 	else
 		ddi_translations = bxt_get_buf_trans_dp(dev_priv, &n_entries);
@@ -2095,7 +2102,8 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
 				     ddi_translations[level].deemphasis);
 }
 
-static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp)
+static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp,
+				   const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -2105,32 +2113,28 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp)
 
 	if (INTEL_GEN(dev_priv) >= 12) {
 		if (intel_phy_is_combo(dev_priv, phy))
-			tgl_get_combo_buf_trans(dev_priv, encoder->type,
-						intel_dp->link_rate, &n_entries);
+			tgl_get_combo_buf_trans(crtc_state, &n_entries);
 		else
 			n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans);
 	} else if (INTEL_GEN(dev_priv) == 11) {
 		if (IS_ELKHARTLAKE(dev_priv))
-			ehl_get_combo_buf_trans(dev_priv, encoder->type,
-						intel_dp->link_rate, &n_entries);
+			ehl_get_combo_buf_trans(crtc_state, &n_entries);
 		else if (intel_phy_is_combo(dev_priv, phy))
-			icl_get_combo_buf_trans(dev_priv, encoder->type,
-						intel_dp->link_rate, &n_entries);
+			icl_get_combo_buf_trans(crtc_state, &n_entries);
 		else
-			icl_get_mg_buf_trans(dev_priv, encoder->type,
-					     intel_dp->link_rate, &n_entries);
+			icl_get_mg_buf_trans(crtc_state, &n_entries);
 	} else if (IS_CANNONLAKE(dev_priv)) {
-		if (encoder->type == INTEL_OUTPUT_EDP)
+		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
 			cnl_get_buf_trans_edp(dev_priv, &n_entries);
 		else
 			cnl_get_buf_trans_dp(dev_priv, &n_entries);
 	} else if (IS_GEN9_LP(dev_priv)) {
-		if (encoder->type == INTEL_OUTPUT_EDP)
+		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
 			bxt_get_buf_trans_edp(dev_priv, &n_entries);
 		else
 			bxt_get_buf_trans_dp(dev_priv, &n_entries);
 	} else {
-		if (encoder->type == INTEL_OUTPUT_EDP)
+		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
 			intel_ddi_get_buf_trans_edp(dev_priv, port, &n_entries);
 		else
 			intel_ddi_get_buf_trans_dp(dev_priv, port, &n_entries);
@@ -2157,7 +2161,8 @@ static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp)
 }
 
 static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
-				   int level, enum intel_output_type type)
+				   const struct intel_crtc_state *crtc_state,
+				   int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	const struct cnl_ddi_buf_trans *ddi_translations;
@@ -2165,9 +2170,9 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
 	int n_entries, ln;
 	u32 val;
 
-	if (type == INTEL_OUTPUT_HDMI)
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 		ddi_translations = cnl_get_buf_trans_hdmi(dev_priv, &n_entries);
-	else if (type == INTEL_OUTPUT_EDP)
+	else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
 		ddi_translations = cnl_get_buf_trans_edp(dev_priv, &n_entries);
 	else
 		ddi_translations = cnl_get_buf_trans_dp(dev_priv, &n_entries);
@@ -2221,22 +2226,16 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
 }
 
 static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
-				    int level, enum intel_output_type type)
+				    const struct intel_crtc_state *crtc_state,
+				    int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum port port = encoder->port;
 	int width, rate, ln;
 	u32 val;
 
-	if (type == INTEL_OUTPUT_HDMI) {
-		width = 4;
-		rate = 0; /* Rate is always < than 6GHz for HDMI */
-	} else {
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-		width = intel_dp->lane_count;
-		rate = intel_dp->link_rate;
-	}
+	width = crtc_state->lane_count;
+	rate = crtc_state->port_clock;
 
 	/*
 	 * 1. If port type is eDP or DP,
@@ -2244,10 +2243,10 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
 	 * else clear to 0b.
 	 */
 	val = intel_de_read(dev_priv, CNL_PORT_PCS_DW1_LN0(port));
-	if (type != INTEL_OUTPUT_HDMI)
-		val |= COMMON_KEEPER_EN;
-	else
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 		val &= ~COMMON_KEEPER_EN;
+	else
+		val |= COMMON_KEEPER_EN;
 	intel_de_write(dev_priv, CNL_PORT_PCS_DW1_GRP(port), val);
 
 	/* 2. Program loadgen select */
@@ -2279,7 +2278,7 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
 	intel_de_write(dev_priv, CNL_PORT_TX_DW5_GRP(port), val);
 
 	/* 5. Program swing and de-emphasis */
-	cnl_ddi_vswing_program(encoder, level, type);
+	cnl_ddi_vswing_program(encoder, crtc_state, level);
 
 	/* 6. Set training enable to trigger update */
 	val = intel_de_read(dev_priv, CNL_PORT_TX_DW5_LN0(port));
@@ -2287,23 +2286,22 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
 	intel_de_write(dev_priv, CNL_PORT_TX_DW5_GRP(port), val);
 }
 
-static void icl_ddi_combo_vswing_program(struct drm_i915_private *dev_priv,
-					u32 level, enum phy phy, int type,
-					int rate)
+static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
+					 const struct intel_crtc_state *crtc_state,
+					 int level)
 {
-	const struct cnl_ddi_buf_trans *ddi_translations = NULL;
-	u32 n_entries, val;
-	int ln;
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	const struct cnl_ddi_buf_trans *ddi_translations;
+	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
+	int n_entries, ln;
+	u32 val;
 
 	if (INTEL_GEN(dev_priv) >= 12)
-		ddi_translations = tgl_get_combo_buf_trans(dev_priv, type, rate,
-							   &n_entries);
+		ddi_translations = tgl_get_combo_buf_trans(crtc_state, &n_entries);
 	else if (IS_ELKHARTLAKE(dev_priv))
-		ddi_translations = ehl_get_combo_buf_trans(dev_priv, type, rate,
-							   &n_entries);
+		ddi_translations = ehl_get_combo_buf_trans(crtc_state, &n_entries);
 	else
-		ddi_translations = icl_get_combo_buf_trans(dev_priv, type, rate,
-							   &n_entries);
+		ddi_translations = icl_get_combo_buf_trans(crtc_state, &n_entries);
 	if (!ddi_translations)
 		return;
 
@@ -2353,25 +2351,16 @@ static void icl_ddi_combo_vswing_program(struct drm_i915_private *dev_priv,
 }
 
 static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
-					      u32 level,
-					      enum intel_output_type type)
+					      const struct intel_crtc_state *crtc_state,
+					      int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
-	int width = 0;
-	int rate = 0;
+	int width, rate, ln;
 	u32 val;
-	int ln = 0;
 
-	if (type == INTEL_OUTPUT_HDMI) {
-		width = 4;
-		/* Rate is always < than 6GHz for HDMI */
-	} else {
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-		width = intel_dp->lane_count;
-		rate = intel_dp->link_rate;
-	}
+	width = crtc_state->lane_count;
+	rate = crtc_state->port_clock;
 
 	/*
 	 * 1. If port type is eDP or DP,
@@ -2379,7 +2368,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 	 * else clear to 0b.
 	 */
 	val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN0(phy));
-	if (type == INTEL_OUTPUT_HDMI)
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 		val &= ~COMMON_KEEPER_EN;
 	else
 		val |= COMMON_KEEPER_EN;
@@ -2414,7 +2403,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 	intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val);
 
 	/* 5. Program swing and de-emphasis */
-	icl_ddi_combo_vswing_program(dev_priv, level, phy, type, rate);
+	icl_ddi_combo_vswing_program(encoder, crtc_state, level);
 
 	/* 6. Set training enable to trigger update */
 	val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy));
@@ -2423,23 +2412,16 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 }
 
 static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
-					   int link_clock, u32 level,
-					   enum intel_output_type type)
+					   const struct intel_crtc_state *crtc_state,
+					   int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
 	const struct icl_mg_phy_ddi_buf_trans *ddi_translations;
-	u32 n_entries, val;
-	int ln, rate = 0;
+	int n_entries, ln;
+	u32 val;
 
-	if (type != INTEL_OUTPUT_HDMI) {
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-		rate = intel_dp->link_rate;
-	}
-
-	ddi_translations = icl_get_mg_buf_trans(dev_priv, type, rate,
-						&n_entries);
+	ddi_translations = icl_get_mg_buf_trans(crtc_state, &n_entries);
 	/* The table does not have values for level 3 and level 9. */
 	if (level >= n_entries || level == 3 || level == 9) {
 		drm_dbg_kms(&dev_priv->drm,
@@ -2506,7 +2488,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 	 */
 	for (ln = 0; ln < 2; ln++) {
 		val = intel_de_read(dev_priv, MG_CLKHUB(ln, tc_port));
-		if (link_clock < 300000)
+		if (crtc_state->port_clock < 300000)
 			val |= CFG_LOW_RATE_LKREN_EN;
 		else
 			val &= ~CFG_LOW_RATE_LKREN_EN;
@@ -2517,7 +2499,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 	for (ln = 0; ln < 2; ln++) {
 		val = intel_de_read(dev_priv, MG_TX1_DCC(ln, tc_port));
 		val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
-		if (link_clock <= 500000) {
+		if (crtc_state->port_clock <= 500000) {
 			val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
 		} else {
 			val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
@@ -2527,7 +2509,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 
 		val = intel_de_read(dev_priv, MG_TX2_DCC(ln, tc_port));
 		val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
-		if (link_clock <= 500000) {
+		if (crtc_state->port_clock <= 500000) {
 			val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
 		} else {
 			val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
@@ -2553,28 +2535,28 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
 }
 
 static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
-				    int link_clock,
-				    u32 level,
-				    enum intel_output_type type)
+				    const struct intel_crtc_state *crtc_state,
+				    int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
 
 	if (intel_phy_is_combo(dev_priv, phy))
-		icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
+		icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level);
 	else
-		icl_mg_phy_ddi_vswing_sequence(encoder, link_clock, level,
-					       type);
+		icl_mg_phy_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
-				u32 level)
+tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
+				const struct intel_crtc_state *crtc_state,
+				int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
 	const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations;
-	u32 n_entries, val, ln, dpcnt_mask, dpcnt_val;
+	u32 val, dpcnt_mask, dpcnt_val;
+	int n_entries, ln;
 
 	if (encoder->type == INTEL_OUTPUT_HDMI) {
 		n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
@@ -2618,20 +2600,20 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
 }
 
 static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder,
-				    int link_clock,
-				    u32 level,
-				    enum intel_output_type type)
+				    const struct intel_crtc_state *crtc_state,
+				    int level)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
 
 	if (intel_phy_is_combo(dev_priv, phy))
-		icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
+		icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level);
 	else
-		tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level);
+		tgl_dkl_phy_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
-static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels)
+static int translate_signal_level(struct intel_dp *intel_dp,
+				  u8 signal_levels)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	int i;
@@ -2648,55 +2630,58 @@ static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels)
 	return 0;
 }
 
-static u32 intel_ddi_dp_level(struct intel_dp *intel_dp)
+static int intel_ddi_dp_level(struct intel_dp *intel_dp)
 {
 	u8 train_set = intel_dp->train_set[0];
-	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-					 DP_TRAIN_PRE_EMPHASIS_MASK);
+	u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+					DP_TRAIN_PRE_EMPHASIS_MASK);
 
 	return translate_signal_level(intel_dp, signal_levels);
 }
 
 static void
-tgl_set_signal_levels(struct intel_dp *intel_dp)
+tgl_set_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	int level = intel_ddi_dp_level(intel_dp);
 
-	tgl_ddi_vswing_sequence(encoder, intel_dp->link_rate,
-				level, encoder->type);
+	tgl_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-icl_set_signal_levels(struct intel_dp *intel_dp)
+icl_set_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	int level = intel_ddi_dp_level(intel_dp);
 
-	icl_ddi_vswing_sequence(encoder, intel_dp->link_rate,
-				level, encoder->type);
+	icl_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-cnl_set_signal_levels(struct intel_dp *intel_dp)
+cnl_set_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	int level = intel_ddi_dp_level(intel_dp);
 
-	cnl_ddi_vswing_sequence(encoder, level, encoder->type);
+	cnl_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-bxt_set_signal_levels(struct intel_dp *intel_dp)
+bxt_set_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	int level = intel_ddi_dp_level(intel_dp);
 
-	bxt_ddi_vswing_sequence(encoder, level, encoder->type);
+	bxt_ddi_vswing_sequence(encoder, crtc_state, level);
 }
 
 static void
-hsw_set_signal_levels(struct intel_dp *intel_dp)
+hsw_set_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -2713,7 +2698,7 @@ hsw_set_signal_levels(struct intel_dp *intel_dp)
 	intel_dp->DP |= signal_levels;
 
 	if (IS_GEN9_BC(dev_priv))
-		skl_ddi_set_iboost(encoder, level, encoder->type);
+		skl_ddi_set_iboost(encoder, crtc_state, level);
 
 	intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
 	intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
@@ -3108,8 +3093,9 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	int level = intel_ddi_dp_level(intel_dp);
 	enum transcoder transcoder = crtc_state->cpu_transcoder;
 
-	intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
-				 crtc_state->lane_count, is_mst);
+	intel_dp_set_link_params(intel_dp,
+				 crtc_state->port_clock,
+				 crtc_state->lane_count);
 
 	intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
 	intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
@@ -3181,8 +3167,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	 */
 
 	/* 7.e Configure voltage swing and related IO settings */
-	tgl_ddi_vswing_sequence(encoder, crtc_state->port_clock, level,
-				encoder->type);
+	tgl_ddi_vswing_sequence(encoder, crtc_state, level);
 
 	/*
 	 * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up
@@ -3205,7 +3190,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	 * We only configure what the register value will be here.  Actual
 	 * enabling happens during link training farther down.
 	 */
-	intel_ddi_init_dp_buf_reg(encoder);
+	intel_ddi_init_dp_buf_reg(encoder, crtc_state);
 
 	if (!is_mst)
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
@@ -3225,11 +3210,11 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	 *     Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent)
 	 *     (timeout after 800 us)
 	 */
-	intel_dp_start_link_train(intel_dp);
+	intel_dp_start_link_train(intel_dp, crtc_state);
 
 	/* 7.k Set DP_TP_CTL link training to Normal */
 	if (!is_trans_port_sync_mode(crtc_state))
-		intel_dp_stop_link_train(intel_dp);
+		intel_dp_stop_link_train(intel_dp, crtc_state);
 
 	/* 7.l Configure and enable FEC if needed */
 	intel_ddi_enable_fec(encoder, crtc_state);
@@ -3255,8 +3240,9 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	else
 		drm_WARN_ON(&dev_priv->drm, is_mst && port == PORT_A);
 
-	intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
-				 crtc_state->lane_count, is_mst);
+	intel_dp_set_link_params(intel_dp,
+				 crtc_state->port_clock,
+				 crtc_state->lane_count);
 
 	intel_edp_panel_on(intel_dp);
 
@@ -3270,12 +3256,11 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	icl_program_mg_dp_mode(dig_port, crtc_state);
 
 	if (INTEL_GEN(dev_priv) >= 11)
-		icl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
-					level, encoder->type);
+		icl_ddi_vswing_sequence(encoder, crtc_state, level);
 	else if (IS_CANNONLAKE(dev_priv))
-		cnl_ddi_vswing_sequence(encoder, level, encoder->type);
+		cnl_ddi_vswing_sequence(encoder, crtc_state, level);
 	else if (IS_GEN9_LP(dev_priv))
-		bxt_ddi_vswing_sequence(encoder, level, encoder->type);
+		bxt_ddi_vswing_sequence(encoder, crtc_state, level);
 	else
 		intel_prepare_dp_ddi_buffers(encoder, crtc_state);
 
@@ -3288,16 +3273,16 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
 					       lane_reversal);
 	}
 
-	intel_ddi_init_dp_buf_reg(encoder);
+	intel_ddi_init_dp_buf_reg(encoder, crtc_state);
 	if (!is_mst)
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
 	intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
 					      true);
 	intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
-	intel_dp_start_link_train(intel_dp);
+	intel_dp_start_link_train(intel_dp, crtc_state);
 	if ((port != PORT_A || INTEL_GEN(dev_priv) >= 9) &&
 	    !is_trans_port_sync_mode(crtc_state))
-		intel_dp_stop_link_train(intel_dp);
+		intel_dp_stop_link_train(intel_dp, crtc_state);
 
 	intel_ddi_enable_fec(encoder, crtc_state);
 
@@ -3337,7 +3322,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
 	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
 	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	int level = intel_ddi_hdmi_level(encoder);
+	int level = intel_ddi_hdmi_level(encoder, crtc_state);
 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 
 	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
@@ -3348,20 +3333,18 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
 	icl_program_mg_dp_mode(dig_port, crtc_state);
 
 	if (INTEL_GEN(dev_priv) >= 12)
-		tgl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
-					level, INTEL_OUTPUT_HDMI);
+		tgl_ddi_vswing_sequence(encoder, crtc_state, level);
 	else if (INTEL_GEN(dev_priv) == 11)
-		icl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
-					level, INTEL_OUTPUT_HDMI);
+		icl_ddi_vswing_sequence(encoder, crtc_state, level);
 	else if (IS_CANNONLAKE(dev_priv))
-		cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
+		cnl_ddi_vswing_sequence(encoder, crtc_state, level);
 	else if (IS_GEN9_LP(dev_priv))
-		bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
+		bxt_ddi_vswing_sequence(encoder, crtc_state, level);
 	else
 		intel_prepare_hdmi_ddi_buffers(encoder, level);
 
 	if (IS_GEN9_BC(dev_priv))
-		skl_ddi_set_iboost(encoder, level, INTEL_OUTPUT_HDMI);
+		skl_ddi_set_iboost(encoder, crtc_state, level);
 
 	intel_ddi_enable_pipe_clock(encoder, crtc_state);
 
@@ -3649,12 +3632,14 @@ static void trans_port_sync_stop_link_train(struct intel_atomic_state *state,
 		    crtc_state->cpu_transcoder)
 			continue;
 
-		intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder));
+		intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder),
+					 slave_crtc_state);
 	}
 
 	usleep_range(200, 400);
 
-	intel_dp_stop_link_train(enc_to_intel_dp(encoder));
+	intel_dp_stop_link_train(enc_to_intel_dp(encoder),
+				 crtc_state);
 }
 
 static void intel_enable_ddi_dp(struct intel_atomic_state *state,
@@ -3667,7 +3652,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
 	enum port port = encoder->port;
 
 	if (port == PORT_A && INTEL_GEN(dev_priv) < 9)
-		intel_dp_stop_link_train(intel_dp);
+		intel_dp_stop_link_train(intel_dp, crtc_state);
 
 	intel_edp_backlight_on(crtc_state, conn_state);
 	intel_psr_enable(intel_dp, crtc_state);
@@ -3927,7 +3912,8 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
 						crtc_state->lane_lat_optim_mask);
 }
 
-static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
+static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
+					   const struct intel_crtc_state *crtc_state)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_i915_private *dev_priv =
@@ -3957,9 +3943,9 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
 
 	dp_tp_ctl = DP_TP_CTL_ENABLE |
 		    DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
-	if (intel_dp->link_mst)
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
 		dp_tp_ctl |= DP_TP_CTL_MODE_MST;
-	else {
+	} else {
 		dp_tp_ctl |= DP_TP_CTL_MODE_SST;
 		if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
 			dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
@@ -3975,6 +3961,7 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
 }
 
 static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
+				     const struct intel_crtc_state *crtc_state,
 				     u8 dp_train_pat)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -4014,7 +4001,8 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
 	intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
 }
 
-static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp)
+static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp,
+					  const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h
index 077e9dbbe367..7a06bb942d21 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -40,8 +40,10 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
 				    bool state);
 void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
 					 struct intel_crtc_state *crtc_state);
-u32 bxt_signal_levels(struct intel_dp *intel_dp);
-u32 ddi_signal_levels(struct intel_dp *intel_dp);
+u32 bxt_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state);
+u32 ddi_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state);
 int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
 				     bool enable);
 void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index e0384af489c2..b7177134acc3 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1274,7 +1274,6 @@ struct intel_dp {
 	int link_rate;
 	u8 lane_count;
 	u8 sink_count;
-	bool link_mst;
 	bool link_trained;
 	bool has_audio;
 	bool reset_link_params;
@@ -1366,13 +1365,19 @@ struct intel_dp {
 	i915_reg_t (*aux_ch_data_reg)(struct intel_dp *dp, int index);
 
 	/* This is called before a link training is starterd */
-	void (*prepare_link_retrain)(struct intel_dp *intel_dp);
-	void (*set_link_train)(struct intel_dp *intel_dp, u8 dp_train_pat);
-	void (*set_idle_link_train)(struct intel_dp *intel_dp);
-	void (*set_signal_levels)(struct intel_dp *intel_dp);
+	void (*prepare_link_retrain)(struct intel_dp *intel_dp,
+				     const struct intel_crtc_state *crtc_state);
+	void (*set_link_train)(struct intel_dp *intel_dp,
+			       const struct intel_crtc_state *crtc_state,
+			       u8 dp_train_pat);
+	void (*set_idle_link_train)(struct intel_dp *intel_dp,
+				    const struct intel_crtc_state *crtc_state);
+	void (*set_signal_levels)(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *crtc_state);
 
 	u8 (*preemph_max)(struct intel_dp *intel_dp);
-	u8 (*voltage_max)(struct intel_dp *intel_dp);
+	u8 (*voltage_max)(struct intel_dp *intel_dp,
+			  const struct intel_crtc_state *crtc_state);
 
 	/* Displayport compliance testing */
 	struct intel_dp_compliance compliance;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 1b786d5af383..562cb560d6c0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2627,13 +2627,11 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 }
 
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
-			      int link_rate, u8 lane_count,
-			      bool link_mst)
+			      int link_rate, int lane_count)
 {
 	intel_dp->link_trained = false;
 	intel_dp->link_rate = link_rate;
 	intel_dp->lane_count = lane_count;
-	intel_dp->link_mst = link_mst;
 }
 
 static void intel_dp_prepare(struct intel_encoder *encoder,
@@ -2645,10 +2643,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 
-	intel_dp_set_link_params(intel_dp, pipe_config->port_clock,
-				 pipe_config->lane_count,
-				 intel_crtc_has_type(pipe_config,
-						     INTEL_OUTPUT_DP_MST));
+	intel_dp_set_link_params(intel_dp,
+				 pipe_config->port_clock,
+				 pipe_config->lane_count);
 
 	/*
 	 * There are four kinds of DP registers:
@@ -3619,6 +3616,7 @@ static void chv_post_disable_dp(struct intel_atomic_state *state,
 
 static void
 cpt_set_link_train(struct intel_dp *intel_dp,
+		   const struct intel_crtc_state *crtc_state,
 		   u8 dp_train_pat)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -3649,6 +3647,7 @@ cpt_set_link_train(struct intel_dp *intel_dp,
 
 static void
 g4x_set_link_train(struct intel_dp *intel_dp,
+		   const struct intel_crtc_state *crtc_state,
 		   u8 dp_train_pat)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -3678,13 +3677,14 @@ g4x_set_link_train(struct intel_dp *intel_dp,
 }
 
 static void intel_dp_enable_port(struct intel_dp *intel_dp,
-				 const struct intel_crtc_state *old_crtc_state)
+				 const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
 	/* enable with pattern 1 (as per spec) */
 
-	intel_dp_program_link_training_pattern(intel_dp, DP_TRAINING_PATTERN_1);
+	intel_dp_program_link_training_pattern(intel_dp, crtc_state,
+					       DP_TRAINING_PATTERN_1);
 
 	/*
 	 * Magic for VLV/CHV. We _must_ first set up the register
@@ -3693,7 +3693,7 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp,
 	 * fail when the power sequencer is freshly used for this port.
 	 */
 	intel_dp->DP |= DP_PORT_EN;
-	if (old_crtc_state->has_audio)
+	if (crtc_state->has_audio)
 		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
 
 	intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP);
@@ -3737,8 +3737,8 @@ static void intel_enable_dp(struct intel_atomic_state *state,
 	}
 
 	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
-	intel_dp_start_link_train(intel_dp);
-	intel_dp_stop_link_train(intel_dp);
+	intel_dp_start_link_train(intel_dp, pipe_config);
+	intel_dp_stop_link_train(intel_dp, pipe_config);
 
 	if (pipe_config->has_audio) {
 		drm_dbg(&dev_priv->drm, "Enabling DP audio on pipe %c\n",
@@ -3947,12 +3947,14 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATU
 				DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
 }
 
-static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp)
+static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp,
+				 const struct intel_crtc_state *crtc_state)
 {
 	return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
 }
 
-static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp)
+static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp,
+				 const struct intel_crtc_state *crtc_state)
 {
 	return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
 }
@@ -3967,7 +3969,8 @@ static u8 intel_dp_pre_empemph_max_3(struct intel_dp *intel_dp)
 	return DP_TRAIN_PRE_EMPH_LEVEL_3;
 }
 
-static void vlv_set_signal_levels(struct intel_dp *intel_dp)
+static void vlv_set_signal_levels(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	unsigned long demph_reg_value, preemph_reg_value,
@@ -4047,11 +4050,13 @@ static void vlv_set_signal_levels(struct intel_dp *intel_dp)
 		return;
 	}
 
-	vlv_set_phy_signal_level(encoder, demph_reg_value, preemph_reg_value,
+	vlv_set_phy_signal_level(encoder, crtc_state,
+				 demph_reg_value, preemph_reg_value,
 				 uniqtranscale_reg_value, 0);
 }
 
-static void chv_set_signal_levels(struct intel_dp *intel_dp)
+static void chv_set_signal_levels(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *crtc_state)
 {
 	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
 	u32 deemph_reg_value, margin_reg_value;
@@ -4128,8 +4133,9 @@ static void chv_set_signal_levels(struct intel_dp *intel_dp)
 		return;
 	}
 
-	chv_set_phy_signal_level(encoder, deemph_reg_value,
-				 margin_reg_value, uniq_trans_scale);
+	chv_set_phy_signal_level(encoder, crtc_state,
+				 deemph_reg_value, margin_reg_value,
+				 uniq_trans_scale);
 }
 
 static u32 g4x_signal_levels(u8 train_set)
@@ -4170,7 +4176,8 @@ static u32 g4x_signal_levels(u8 train_set)
 }
 
 static void
-g4x_set_signal_levels(struct intel_dp *intel_dp)
+g4x_set_signal_levels(struct intel_dp *intel_dp,
+		      const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u8 train_set = intel_dp->train_set[0];
@@ -4217,7 +4224,8 @@ static u32 snb_cpu_edp_signal_levels(u8 train_set)
 }
 
 static void
-snb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp)
+snb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp,
+			      const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u8 train_set = intel_dp->train_set[0];
@@ -4268,7 +4276,8 @@ static u32 ivb_cpu_edp_signal_levels(u8 train_set)
 }
 
 static void
-ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp)
+ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp,
+			      const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u8 train_set = intel_dp->train_set[0];
@@ -4286,7 +4295,8 @@ ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp)
 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
 }
 
-void intel_dp_set_signal_levels(struct intel_dp *intel_dp)
+void intel_dp_set_signal_levels(struct intel_dp *intel_dp,
+				const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u8 train_set = intel_dp->train_set[0];
@@ -4300,11 +4310,12 @@ void intel_dp_set_signal_levels(struct intel_dp *intel_dp)
 		    train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ?
 		    " (max)" : "");
 
-	intel_dp->set_signal_levels(intel_dp);
+	intel_dp->set_signal_levels(intel_dp, crtc_state);
 }
 
 void
 intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
+				       const struct intel_crtc_state *crtc_state,
 				       u8 dp_train_pat)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -4315,13 +4326,14 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
 			    "Using DP training pattern TPS%d\n",
 			    dp_train_pat & train_pat_mask);
 
-	intel_dp->set_link_train(intel_dp, dp_train_pat);
+	intel_dp->set_link_train(intel_dp, crtc_state, dp_train_pat);
 }
 
-void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
+void intel_dp_set_idle_link_train(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *crtc_state)
 {
 	if (intel_dp->set_idle_link_train)
-		intel_dp->set_idle_link_train(intel_dp);
+		intel_dp->set_idle_link_train(intel_dp, crtc_state);
 }
 
 static void
@@ -5312,23 +5324,17 @@ static u8 intel_dp_prepare_phytest(struct intel_dp *intel_dp)
 		return DP_TEST_NAK;
 	}
 
-	/*
-	 * link_mst is set to false to avoid executing mst related code
-	 * during compliance testing.
-	 */
-	intel_dp->link_mst = false;
-
 	return DP_TEST_ACK;
 }
 
-static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp)
+static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
+					const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv =
 			to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_dp_phy_test_params *data =
 			&intel_dp->compliance.test_data.phytest;
-	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	enum pipe pipe = crtc->pipe;
 	u32 pattern_val;
 
@@ -5388,7 +5394,8 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp)
 }
 
 static void
-intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp)
+intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *crtc_state)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = intel_dig_port->base.base.dev;
@@ -5414,7 +5421,8 @@ intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp)
 }
 
 static void
-intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, uint8_t lane_cnt)
+intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp,
+				 const struct intel_crtc_state *crtc_state)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = intel_dig_port->base.base.dev;
@@ -5440,7 +5448,8 @@ intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, uint8_t lane_cnt)
 		       trans_ddi_func_ctl_value);
 }
 
-void intel_dp_process_phy_request(struct intel_dp *intel_dp)
+static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
+					 const struct intel_crtc_state *crtc_state)
 {
 	struct drm_dp_phy_test_params *data =
 		&intel_dp->compliance.test_data.phytest;
@@ -5452,21 +5461,22 @@ void intel_dp_process_phy_request(struct intel_dp *intel_dp)
 	}
 
 	/* retrieve vswing & pre-emphasis setting */
-	intel_dp_get_adjust_train(intel_dp, link_status);
+	intel_dp_get_adjust_train(intel_dp, crtc_state, link_status);
 
-	intel_dp_autotest_phy_ddi_disable(intel_dp);
+	intel_dp_autotest_phy_ddi_disable(intel_dp, crtc_state);
 
-	intel_dp_set_signal_levels(intel_dp);
+	intel_dp_set_signal_levels(intel_dp, crtc_state);
 
-	intel_dp_phy_pattern_update(intel_dp);
+	intel_dp_phy_pattern_update(intel_dp, crtc_state);
 
-	intel_dp_autotest_phy_ddi_enable(intel_dp, data->num_lanes);
+	intel_dp_autotest_phy_ddi_enable(intel_dp, crtc_state);
 
 	drm_dp_set_phy_test_pattern(&intel_dp->aux, data,
 				    link_status[DP_DPCD_REV]);
 }
 
-static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp)
+static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp,
+					const struct intel_crtc_state *crtc_state)
 {
 	u8 test_result;
 
@@ -5474,12 +5484,13 @@ static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp)
 	if (test_result != DP_TEST_ACK)
 		DRM_ERROR("Phy test preparation failed\n");
 
-	intel_dp_process_phy_request(intel_dp);
+	intel_dp_process_phy_request(intel_dp, crtc_state);
 
 	return test_result;
 }
 
-static void intel_dp_handle_test_request(struct intel_dp *intel_dp)
+static void intel_dp_handle_test_request(struct intel_dp *intel_dp,
+					 const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 response = DP_TEST_NAK;
@@ -5508,7 +5519,9 @@ static void intel_dp_handle_test_request(struct intel_dp *intel_dp)
 		break;
 	case DP_TEST_LINK_PHY_TEST_PATTERN:
 		drm_dbg_kms(&i915->drm, "PHY_PATTERN test requested\n");
-		response = intel_dp_autotest_phy_pattern(intel_dp);
+		/* FIXME see intel_dp_check_service_irq() */
+		if (crtc_state)
+			response = intel_dp_autotest_phy_pattern(intel_dp, crtc_state);
 		break;
 	default:
 		drm_dbg_kms(&i915->drm, "Invalid test request '%02x'\n",
@@ -5602,6 +5615,10 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
 	/*
 	 * Validate the cached values of intel_dp->link_rate and
 	 * intel_dp->lane_count before attempting to retrain.
+	 *
+	 * FIXME would be nice to user the crtc state here, but since
+	 * we need to call this from the short HPD handler that seems
+	 * a bit hard.
 	 */
 	if (!intel_dp_link_params_valid(intel_dp, intel_dp->link_rate,
 					intel_dp->lane_count))
@@ -5735,8 +5752,20 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
 							      intel_crtc_pch_transcoder(crtc), false);
 	}
 
-	intel_dp_start_link_train(intel_dp);
-	intel_dp_stop_link_train(intel_dp);
+	for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) {
+		const struct intel_crtc_state *crtc_state =
+			to_intel_crtc_state(crtc->base.state);
+
+		/* retrain on the MST master transcoder */
+		if (INTEL_GEN(dev_priv) >= 12 &&
+		    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
+		    crtc_state->cpu_transcoder != crtc_state->mst_master_transcoder)
+			continue;
+
+		intel_dp_start_link_train(intel_dp, crtc_state);
+		intel_dp_stop_link_train(intel_dp, crtc_state);
+		break;
+	}
 
 	for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) {
 		const struct intel_crtc_state *crtc_state =
@@ -5818,8 +5847,15 @@ static void intel_dp_check_service_irq(struct intel_dp *intel_dp)
 
 	drm_dp_dpcd_writeb(&intel_dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR, val);
 
+	/*
+	 * FIXME get rid of the hand rolled modeset code from
+	 * the phy test code and just do proper modesets instead.
+	 * Doing modesets from the short hpd handler is a total
+	 * no no anyway. For now this will not work since we don't
+	 * have a crtc state.
+	 */
 	if (val & DP_AUTOMATED_TEST_REQUEST)
-		intel_dp_handle_test_request(intel_dp);
+		intel_dp_handle_test_request(intel_dp, NULL);
 
 	if (val & DP_CP_IRQ)
 		intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index e8375a75c3ec..25d55c06af19 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -42,8 +42,7 @@ bool intel_dp_init(struct drm_i915_private *dev_priv, i915_reg_t output_reg,
 bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 			     struct intel_connector *intel_connector);
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
-			      int link_rate, u8 lane_count,
-			      bool link_mst);
+			      int link_rate, int lane_count);
 int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 					    int link_rate, u8 lane_count);
 int intel_dp_retrain_link(struct intel_encoder *encoder,
@@ -87,10 +86,13 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
 
 void
 intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
+				       const struct intel_crtc_state *crtc_state,
 				       u8 dp_train_pat);
 void
-intel_dp_set_signal_levels(struct intel_dp *intel_dp);
-void intel_dp_set_idle_link_train(struct intel_dp *intel_dp);
+intel_dp_set_signal_levels(struct intel_dp *intel_dp,
+			   const struct intel_crtc_state *crtc_state);
+void intel_dp_set_idle_link_train(struct intel_dp *intel_dp,
+				  const struct intel_crtc_state *crtc_state);
 void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
 			   u8 *link_bw, u8 *rate_select);
 bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
@@ -114,7 +116,6 @@ void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable,
 			     const struct intel_crtc_state *crtc_state,
 			     const struct drm_connector_state *conn_state);
 bool intel_digital_port_connected(struct intel_encoder *encoder);
-void intel_dp_process_phy_request(struct intel_dp *intel_dp);
 
 static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index 2493142a70e9..1b0595715383 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -49,8 +49,10 @@ static u8 dp_voltage_max(u8 preemph)
 	}
 }
 
-void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
-			       const u8 link_status[DP_LINK_STATUS_SIZE])
+void
+intel_dp_get_adjust_train(struct intel_dp *intel_dp,
+			  const struct intel_crtc_state *crtc_state,
+			  const u8 link_status[DP_LINK_STATUS_SIZE])
 {
 	u8 v = 0;
 	u8 p = 0;
@@ -58,7 +60,7 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
 	u8 voltage_max;
 	u8 preemph_max;
 
-	for (lane = 0; lane < intel_dp->lane_count; lane++) {
+	for (lane = 0; lane < crtc_state->lane_count; lane++) {
 		v = max(v, drm_dp_get_adjust_request_voltage(link_status, lane));
 		p = max(p, drm_dp_get_adjust_request_pre_emphasis(link_status, lane));
 	}
@@ -69,7 +71,7 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
 
 	v = min(v, dp_voltage_max(p));
 
-	voltage_max = intel_dp->voltage_max(intel_dp);
+	voltage_max = intel_dp->voltage_max(intel_dp, crtc_state);
 	if (v >= voltage_max)
 		v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;
 
@@ -79,12 +81,14 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
 
 static bool
 intel_dp_set_link_train(struct intel_dp *intel_dp,
+			const struct intel_crtc_state *crtc_state,
 			u8 dp_train_pat)
 {
 	u8 buf[sizeof(intel_dp->train_set) + 1];
 	int ret, len;
 
-	intel_dp_program_link_training_pattern(intel_dp, dp_train_pat);
+	intel_dp_program_link_training_pattern(intel_dp, crtc_state,
+					       dp_train_pat);
 
 	buf[0] = dp_train_pat;
 	if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==
@@ -93,8 +97,8 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 		len = 1;
 	} else {
 		/* DP_TRAINING_LANEx_SET follow DP_TRAINING_PATTERN_SET */
-		memcpy(buf + 1, intel_dp->train_set, intel_dp->lane_count);
-		len = intel_dp->lane_count + 1;
+		memcpy(buf + 1, intel_dp->train_set, crtc_state->lane_count);
+		len = crtc_state->lane_count + 1;
 	}
 
 	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET,
@@ -105,31 +109,34 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 
 static bool
 intel_dp_reset_link_train(struct intel_dp *intel_dp,
-			u8 dp_train_pat)
+			  const struct intel_crtc_state *crtc_state,
+			  u8 dp_train_pat)
 {
 	memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
-	intel_dp_set_signal_levels(intel_dp);
-	return intel_dp_set_link_train(intel_dp, dp_train_pat);
+	intel_dp_set_signal_levels(intel_dp, crtc_state);
+	return intel_dp_set_link_train(intel_dp, crtc_state, dp_train_pat);
 }
 
 static bool
-intel_dp_update_link_train(struct intel_dp *intel_dp)
+intel_dp_update_link_train(struct intel_dp *intel_dp,
+			   const struct intel_crtc_state *crtc_state)
 {
 	int ret;
 
-	intel_dp_set_signal_levels(intel_dp);
+	intel_dp_set_signal_levels(intel_dp, crtc_state);
 
 	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
-				intel_dp->train_set, intel_dp->lane_count);
+				intel_dp->train_set, crtc_state->lane_count);
 
-	return ret == intel_dp->lane_count;
+	return ret == crtc_state->lane_count;
 }
 
-static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp)
+static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp,
+					     const struct intel_crtc_state *crtc_state)
 {
 	int lane;
 
-	for (lane = 0; lane < intel_dp->lane_count; lane++)
+	for (lane = 0; lane < crtc_state->lane_count; lane++)
 		if ((intel_dp->train_set[lane] &
 		     DP_TRAIN_MAX_SWING_REACHED) == 0)
 			return false;
@@ -139,7 +146,8 @@ static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp)
 
 /* Enable corresponding port and start training pattern 1 */
 static bool
-intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
+intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp,
+				      const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 voltage;
@@ -149,9 +157,9 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 	u8 link_bw, rate_select;
 
 	if (intel_dp->prepare_link_retrain)
-		intel_dp->prepare_link_retrain(intel_dp);
+		intel_dp->prepare_link_retrain(intel_dp, crtc_state);
 
-	intel_dp_compute_rate(intel_dp, intel_dp->link_rate,
+	intel_dp_compute_rate(intel_dp, crtc_state->port_clock,
 			      &link_bw, &rate_select);
 
 	if (link_bw)
@@ -163,7 +171,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 
 	/* Write the link configuration data */
 	link_config[0] = link_bw;
-	link_config[1] = intel_dp->lane_count;
+	link_config[1] = crtc_state->lane_count;
 	if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
 		link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
 	drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2);
@@ -180,7 +188,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 	intel_dp->DP |= DP_PORT_EN;
 
 	/* clock recovery */
-	if (!intel_dp_reset_link_train(intel_dp,
+	if (!intel_dp_reset_link_train(intel_dp, crtc_state,
 				       DP_TRAINING_PATTERN_1 |
 				       DP_LINK_SCRAMBLING_DISABLE)) {
 		drm_err(&i915->drm, "failed to enable link training\n");
@@ -211,7 +219,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 			return false;
 		}
 
-		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
+		if (drm_dp_clock_recovery_ok(link_status, crtc_state->lane_count)) {
 			drm_dbg_kms(&i915->drm, "clock recovery OK\n");
 			return true;
 		}
@@ -230,8 +238,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
 		/* Update training set as requested by target */
-		intel_dp_get_adjust_train(intel_dp, link_status);
-		if (!intel_dp_update_link_train(intel_dp)) {
+		intel_dp_get_adjust_train(intel_dp, crtc_state, link_status);
+		if (!intel_dp_update_link_train(intel_dp, crtc_state)) {
 			drm_err(&i915->drm,
 				"failed to update link training\n");
 			return false;
@@ -243,7 +251,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 		else
 			voltage_tries = 1;
 
-		if (intel_dp_link_max_vswing_reached(intel_dp))
+		if (intel_dp_link_max_vswing_reached(intel_dp, crtc_state))
 			max_vswing_reached = true;
 
 	}
@@ -257,7 +265,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
  * 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)
+static u32 intel_dp_training_pattern(struct intel_dp *intel_dp,
+				     const struct intel_crtc_state *crtc_state)
 {
 	bool source_tps3, sink_tps3, source_tps4, sink_tps4;
 
@@ -271,7 +280,7 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
 	sink_tps4 = drm_dp_tps4_supported(intel_dp->dpcd);
 	if (source_tps4 && sink_tps4) {
 		return DP_TRAINING_PATTERN_4;
-	} else if (intel_dp->link_rate == 810000) {
+	} else if (crtc_state->port_clock == 810000) {
 		if (!source_tps4)
 			drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
 				    "8.1 Gbps link rate without source HBR3/TPS4 support\n");
@@ -288,7 +297,7 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
 	sink_tps3 = drm_dp_tps3_supported(intel_dp->dpcd);
 	if (source_tps3 && sink_tps3) {
 		return  DP_TRAINING_PATTERN_3;
-	} else if (intel_dp->link_rate >= 540000) {
+	} else if (crtc_state->port_clock >= 540000) {
 		if (!source_tps3)
 			drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
 				    ">=5.4/6.48 Gbps link rate without source HBR2/TPS3 support\n");
@@ -301,7 +310,8 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
 }
 
 static bool
-intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
+intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp,
+					    const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	int tries;
@@ -309,13 +319,13 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 	u8 link_status[DP_LINK_STATUS_SIZE];
 	bool channel_eq = false;
 
-	training_pattern = intel_dp_training_pattern(intel_dp);
+	training_pattern = intel_dp_training_pattern(intel_dp, crtc_state);
 	/* Scrambling is disabled for TPS2/3 and enabled for TPS4 */
 	if (training_pattern != DP_TRAINING_PATTERN_4)
 		training_pattern |= DP_LINK_SCRAMBLING_DISABLE;
 
 	/* channel equalization */
-	if (!intel_dp_set_link_train(intel_dp,
+	if (!intel_dp_set_link_train(intel_dp, crtc_state,
 				     training_pattern)) {
 		drm_err(&i915->drm, "failed to start channel equalization\n");
 		return false;
@@ -332,7 +342,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 
 		/* Make sure clock is still ok */
 		if (!drm_dp_clock_recovery_ok(link_status,
-					      intel_dp->lane_count)) {
+					      crtc_state->lane_count)) {
 			intel_dp_dump_link_status(link_status);
 			drm_dbg_kms(&i915->drm,
 				    "Clock recovery check failed, cannot "
@@ -341,7 +351,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 		}
 
 		if (drm_dp_channel_eq_ok(link_status,
-					 intel_dp->lane_count)) {
+					 crtc_state->lane_count)) {
 			channel_eq = true;
 			drm_dbg_kms(&i915->drm, "Channel EQ done. DP Training "
 				    "successful\n");
@@ -349,8 +359,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 		}
 
 		/* Update training set as requested by target */
-		intel_dp_get_adjust_train(intel_dp, link_status);
-		if (!intel_dp_update_link_train(intel_dp)) {
+		intel_dp_get_adjust_train(intel_dp, crtc_state, link_status);
+		if (!intel_dp_update_link_train(intel_dp, crtc_state)) {
 			drm_err(&i915->drm,
 				"failed to update link training\n");
 			break;
@@ -364,35 +374,37 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 			    "Channel equalization failed 5 times\n");
 	}
 
-	intel_dp_set_idle_link_train(intel_dp);
+	intel_dp_set_idle_link_train(intel_dp, crtc_state);
 
 	return channel_eq;
 
 }
 
-void intel_dp_stop_link_train(struct intel_dp *intel_dp)
+void intel_dp_stop_link_train(struct intel_dp *intel_dp,
+			      const struct intel_crtc_state *crtc_state)
 {
 	intel_dp->link_trained = true;
 
-	intel_dp_set_link_train(intel_dp,
+	intel_dp_set_link_train(intel_dp, crtc_state,
 				DP_TRAINING_PATTERN_DISABLE);
 }
 
 void
-intel_dp_start_link_train(struct intel_dp *intel_dp)
+intel_dp_start_link_train(struct intel_dp *intel_dp,
+			  const struct intel_crtc_state *crtc_state)
 {
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
 
-	if (!intel_dp_link_training_clock_recovery(intel_dp))
+	if (!intel_dp_link_training_clock_recovery(intel_dp, crtc_state))
 		goto failure_handling;
-	if (!intel_dp_link_training_channel_equalization(intel_dp))
+	if (!intel_dp_link_training_channel_equalization(intel_dp, crtc_state))
 		goto failure_handling;
 
 	drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
 		    "[CONNECTOR:%d:%s] Link Training Passed at Link Rate = %d, Lane count = %d",
 		    intel_connector->base.base.id,
 		    intel_connector->base.name,
-		    intel_dp->link_rate, intel_dp->lane_count);
+		    crtc_state->port_clock, crtc_state->lane_count);
 	return;
 
  failure_handling:
@@ -400,10 +412,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 		    "[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
 		    intel_connector->base.base.id,
 		    intel_connector->base.name,
-		    intel_dp->link_rate, intel_dp->lane_count);
+		    crtc_state->port_clock, crtc_state->lane_count);
 	if (!intel_dp_get_link_train_fallback_values(intel_dp,
-						     intel_dp->link_rate,
-						     intel_dp->lane_count))
+						     crtc_state->port_clock,
+						     crtc_state->lane_count))
 		/* Schedule a Hotplug Uevent to userspace to start modeset */
 		schedule_work(&intel_connector->modeset_retry_work);
 	return;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
index 01f1dabbb060..648a6d1f9fa2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
@@ -8,11 +8,15 @@
 
 #include <drm/drm_dp_helper.h>
 
+struct intel_crtc_state;
 struct intel_dp;
 
 void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
+			       const struct intel_crtc_state *crtc_state,
 			       const u8 link_status[DP_LINK_STATUS_SIZE]);
-void intel_dp_start_link_train(struct intel_dp *intel_dp);
-void intel_dp_stop_link_train(struct intel_dp *intel_dp);
+void intel_dp_start_link_train(struct intel_dp *intel_dp,
+			       const struct intel_crtc_state *crtc_state);
+void intel_dp_stop_link_train(struct intel_dp *intel_dp,
+			      const struct intel_crtc_state *crtc_state);
 
 #endif /* __INTEL_DP_LINK_TRAINING_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index 399a7edb4568..79da281d46db 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -644,16 +644,16 @@ bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder)
 	return mask;
 }
 
-
 void chv_set_phy_signal_level(struct intel_encoder *encoder,
+			      const struct intel_crtc_state *crtc_state,
 			      u32 deemph_reg_value, u32 margin_reg_value,
 			      bool uniq_trans_scale)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_digital_port *dport = enc_to_dig_port(encoder);
-	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	enum dpio_channel ch = vlv_dport_to_channel(dport);
-	enum pipe pipe = intel_crtc->pipe;
+	enum pipe pipe = crtc->pipe;
 	u32 val;
 	int i;
 
@@ -666,7 +666,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 	val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
 
-	if (intel_crtc->config->lane_count > 2) {
+	if (crtc_state->lane_count > 2) {
 		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
 		val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
 		val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
@@ -679,7 +679,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 	val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val);
 
-	if (intel_crtc->config->lane_count > 2) {
+	if (crtc_state->lane_count > 2) {
 		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
 		val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
 		val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
@@ -687,7 +687,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 	}
 
 	/* Program swing deemph */
-	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+	for (i = 0; i < crtc_state->lane_count; i++) {
 		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i));
 		val &= ~DPIO_SWING_DEEMPH9P5_MASK;
 		val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT;
@@ -695,7 +695,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 	}
 
 	/* Program swing margin */
-	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+	for (i = 0; i < crtc_state->lane_count; i++) {
 		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
 
 		val &= ~DPIO_SWING_MARGIN000_MASK;
@@ -718,7 +718,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 	 * For now, for this unique transition scale selection, set bit
 	 * 27 for ch0 and ch1.
 	 */
-	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+	for (i = 0; i < crtc_state->lane_count; i++) {
 		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
 		if (uniq_trans_scale)
 			val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
@@ -732,7 +732,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 	val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
 
-	if (intel_crtc->config->lane_count > 2) {
+	if (crtc_state->lane_count > 2) {
 		val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
 		val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
 		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
@@ -992,14 +992,15 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder,
 }
 
 void vlv_set_phy_signal_level(struct intel_encoder *encoder,
+			      const struct intel_crtc_state *crtc_state,
 			      u32 demph_reg_value, u32 preemph_reg_value,
 			      u32 uniqtranscale_reg_value, u32 tx3_demph)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_digital_port *dport = enc_to_dig_port(encoder);
 	enum dpio_channel port = vlv_dport_to_channel(dport);
-	enum pipe pipe = intel_crtc->pipe;
+	enum pipe pipe = crtc->pipe;
 
 	vlv_dpio_get(dev_priv);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.h b/drivers/gpu/drm/i915/display/intel_dpio_phy.h
index f418aab90b7e..6473440e7457 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.h
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.h
@@ -32,6 +32,7 @@ void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder,
 u8 bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder);
 
 void chv_set_phy_signal_level(struct intel_encoder *encoder,
+			      const struct intel_crtc_state *crtc_state,
 			      u32 deemph_reg_value, u32 margin_reg_value,
 			      bool uniq_trans_scale);
 void chv_data_lane_soft_reset(struct intel_encoder *encoder,
@@ -46,6 +47,7 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder,
 			      const struct intel_crtc_state *old_crtc_state);
 
 void vlv_set_phy_signal_level(struct intel_encoder *encoder,
+			      const struct intel_crtc_state *crtc_state,
 			      u32 demph_reg_value, u32 preemph_reg_value,
 			      u32 uniqtranscale_reg_value, u32 tx3_demph);
 void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 010f37240710..81218d968a7e 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2730,8 +2730,9 @@ static void vlv_hdmi_pre_enable(struct intel_atomic_state *state,
 	vlv_phy_pre_encoder_enable(encoder, pipe_config);
 
 	/* HDMI 1.0V-2dB */
-	vlv_set_phy_signal_level(encoder, 0x2b245f5f, 0x00002000, 0x5578b83a,
-				 0x2b247878);
+	vlv_set_phy_signal_level(encoder, pipe_config,
+				 0x2b245f5f, 0x00002000,
+				 0x5578b83a, 0x2b247878);
 
 	dport->set_infoframes(encoder,
 			      pipe_config->has_infoframe,
@@ -2808,7 +2809,7 @@ static void chv_hdmi_pre_enable(struct intel_atomic_state *state,
 
 	/* FIXME: Program the support xxx V-dB */
 	/* Use 800mV-0dB */
-	chv_set_phy_signal_level(encoder, 128, 102, false);
+	chv_set_phy_signal_level(encoder, pipe_config, 128, 102, false);
 
 	dport->set_infoframes(encoder,
 			      pipe_config->has_infoframe,
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: Plumb crtc state to link training code (rev2)
  2020-05-06 11:23 [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code Ville Syrjala
                   ` (9 preceding siblings ...)
  2020-05-06 11:29 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for drm/i915: Plumb crtc state to link training code Patchwork
@ 2020-05-06 12:49 ` Patchwork
  2020-05-06 13:48 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
  11 siblings, 0 replies; 15+ messages in thread
From: Patchwork @ 2020-05-06 12:49 UTC (permalink / raw)
  To: Ville Syrjala; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Plumb crtc state to link training code (rev2)
URL   : https://patchwork.freedesktop.org/series/76993/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8433 -> Patchwork_17588
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/index.html

Known issues
------------

  Here are the changes found in Patchwork_17588 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@i915_selftest@live@reset:
    - fi-bwr-2160:        [PASS][1] -> [INCOMPLETE][2] ([i915#489])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/fi-bwr-2160/igt@i915_selftest@live@reset.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/fi-bwr-2160/igt@i915_selftest@live@reset.html

  
  [i915#489]: https://gitlab.freedesktop.org/drm/intel/issues/489


Participating hosts (51 -> 43)
------------------------------

  Missing    (8): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-kbl-7560u fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_8433 -> Patchwork_17588

  CI-20190529: 20190529
  CI_DRM_8433: db68fed086f2ddcdc30e0d9ca5faaba5e55d0d01 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5633: c8c2e5ed5cd8e4b7a69a903f3f1653612086abcc @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_17588: 8ec6f4b1e7f06bdfd404ecfdf54337e9f645261f @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

8ec6f4b1e7f0 drm/i915: Eliminate intel_dp.regs.dp_tp_{ctl, status}
fa64a8214369 drm/i915: Plumb crtc_state to link training
2cb6124763bb drm/i915: Replace some hand rolled max()s
35e76930c74d drm/i915: Fix DP_TRAIN_MAX_{PRE_EMPHASIS, SWING}_REACHED handling
1e68b2953b0e drm/i915: Reverse preemph vs. voltage swing preference
3949c1110159 drm/i915: Add {preemph, voltage}_max() vfuncs
d80fba24e659 drm/i915: Fix ivb cpu edp vswing
18c9808e0356 drm/i915: Fix ibx max vswing/preemph
d43ebfb8437f drm/i915: Fix cpt/ppt max pre-emphasis

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Intel-gfx] ✓ Fi.CI.IGT: success for drm/i915: Plumb crtc state to link training code (rev2)
  2020-05-06 11:23 [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code Ville Syrjala
                   ` (10 preceding siblings ...)
  2020-05-06 12:49 ` [Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: Plumb crtc state to link training code (rev2) Patchwork
@ 2020-05-06 13:48 ` Patchwork
  11 siblings, 0 replies; 15+ messages in thread
From: Patchwork @ 2020-05-06 13:48 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Plumb crtc state to link training code (rev2)
URL   : https://patchwork.freedesktop.org/series/76993/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8433_full -> Patchwork_17588_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Known issues
------------

  Here are the changes found in Patchwork_17588_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_persistence@engines-mixed-process@vcs0:
    - shard-skl:          [PASS][1] -> [FAIL][2] ([i915#1528])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-skl4/igt@gem_ctx_persistence@engines-mixed-process@vcs0.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-skl10/igt@gem_ctx_persistence@engines-mixed-process@vcs0.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-glk:          [PASS][3] -> [DMESG-WARN][4] ([i915#716])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-glk6/igt@gen9_exec_parse@allowed-all.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-glk8/igt@gen9_exec_parse@allowed-all.html

  * igt@kms_cursor_crc@pipe-b-cursor-suspend:
    - shard-kbl:          [PASS][5] -> [DMESG-WARN][6] ([i915#180])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-kbl4/igt@kms_cursor_crc@pipe-b-cursor-suspend.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-kbl1/igt@kms_cursor_crc@pipe-b-cursor-suspend.html

  * igt@kms_cursor_legacy@flip-vs-cursor-legacy:
    - shard-skl:          [PASS][7] -> [FAIL][8] ([IGT#5])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-skl5/igt@kms_cursor_legacy@flip-vs-cursor-legacy.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-skl3/igt@kms_cursor_legacy@flip-vs-cursor-legacy.html

  * igt@kms_flip_tiling@flip-changes-tiling:
    - shard-kbl:          [PASS][9] -> [FAIL][10] ([i915#699] / [i915#93] / [i915#95])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-kbl4/igt@kms_flip_tiling@flip-changes-tiling.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-kbl4/igt@kms_flip_tiling@flip-changes-tiling.html

  * igt@kms_hdr@bpc-switch-dpms:
    - shard-skl:          [PASS][11] -> [FAIL][12] ([i915#1188]) +1 similar issue
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-skl1/igt@kms_hdr@bpc-switch-dpms.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-skl9/igt@kms_hdr@bpc-switch-dpms.html

  * igt@kms_psr@psr2_cursor_plane_onoff:
    - shard-iclb:         [PASS][13] -> [SKIP][14] ([fdo#109441]) +3 similar issues
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-iclb2/igt@kms_psr@psr2_cursor_plane_onoff.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-iclb3/igt@kms_psr@psr2_cursor_plane_onoff.html

  * igt@kms_vblank@pipe-a-ts-continuation-suspend:
    - shard-apl:          [PASS][15] -> [DMESG-WARN][16] ([i915#180]) +1 similar issue
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-apl3/igt@kms_vblank@pipe-a-ts-continuation-suspend.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-apl2/igt@kms_vblank@pipe-a-ts-continuation-suspend.html

  * igt@kms_vblank@pipe-c-accuracy-idle:
    - shard-skl:          [PASS][17] -> [FAIL][18] ([i915#43])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-skl3/igt@kms_vblank@pipe-c-accuracy-idle.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-skl1/igt@kms_vblank@pipe-c-accuracy-idle.html

  
#### Possible fixes ####

  * igt@gem_ctx_persistence@engines-mixed-process@vecs0:
    - shard-skl:          [FAIL][19] ([i915#1528]) -> [PASS][20]
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-skl4/igt@gem_ctx_persistence@engines-mixed-process@vecs0.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-skl10/igt@gem_ctx_persistence@engines-mixed-process@vecs0.html

  * {igt@kms_flip@flip-vs-suspend-interruptible@a-dp1}:
    - shard-kbl:          [DMESG-WARN][21] ([i915#180]) -> [PASS][22] +3 similar issues
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-kbl1/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-kbl3/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html

  * {igt@kms_flip@flip-vs-suspend-interruptible@c-dp1}:
    - shard-apl:          [DMESG-WARN][23] ([i915#180]) -> [PASS][24] +2 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-apl2/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-apl1/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html

  * igt@kms_frontbuffer_tracking@fbc-suspend:
    - shard-kbl:          [DMESG-WARN][25] ([i915#180] / [i915#93] / [i915#95]) -> [PASS][26]
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-kbl1/igt@kms_frontbuffer_tracking@fbc-suspend.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-kbl7/igt@kms_frontbuffer_tracking@fbc-suspend.html

  * igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-gtt:
    - shard-tglb:         [SKIP][27] ([i915#668]) -> [PASS][28] +6 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-tglb6/igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-gtt.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-tglb2/igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-gtt.html

  * igt@kms_plane_alpha_blend@pipe-b-coverage-7efc:
    - shard-skl:          [FAIL][29] ([fdo#108145] / [i915#265]) -> [PASS][30] +1 similar issue
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-skl7/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-skl1/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html

  * igt@kms_psr2_su@frontbuffer:
    - shard-iclb:         [SKIP][31] ([fdo#109642] / [fdo#111068]) -> [PASS][32]
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-iclb7/igt@kms_psr2_su@frontbuffer.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-iclb2/igt@kms_psr2_su@frontbuffer.html

  * igt@kms_psr@psr2_cursor_mmap_cpu:
    - shard-iclb:         [SKIP][33] ([fdo#109441]) -> [PASS][34] +1 similar issue
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-iclb1/igt@kms_psr@psr2_cursor_mmap_cpu.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-iclb2/igt@kms_psr@psr2_cursor_mmap_cpu.html

  * {igt@perf@blocking-parameterized}:
    - shard-tglb:         [FAIL][35] ([i915#1542]) -> [PASS][36]
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-tglb6/igt@perf@blocking-parameterized.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-tglb3/igt@perf@blocking-parameterized.html

  
#### Warnings ####

  * igt@i915_pm_dc@dc6-psr:
    - shard-tglb:         [FAIL][37] ([i915#454]) -> [SKIP][38] ([i915#468])
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-tglb1/igt@i915_pm_dc@dc6-psr.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-tglb2/igt@i915_pm_dc@dc6-psr.html

  * igt@i915_pm_rpm@pm-caching:
    - shard-snb:          [INCOMPLETE][39] ([i915#82]) -> [SKIP][40] ([fdo#109271])
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-snb1/igt@i915_pm_rpm@pm-caching.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-snb5/igt@i915_pm_rpm@pm-caching.html

  * igt@kms_content_protection@atomic-dpms:
    - shard-apl:          [FAIL][41] ([fdo#110321] / [fdo#110336] / [i915#95]) -> [TIMEOUT][42] ([i915#1319])
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-apl4/igt@kms_content_protection@atomic-dpms.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-apl2/igt@kms_content_protection@atomic-dpms.html

  * igt@kms_content_protection@legacy:
    - shard-apl:          [FAIL][43] ([fdo#110321] / [fdo#110336]) -> [TIMEOUT][44] ([i915#1319])
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-apl7/igt@kms_content_protection@legacy.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-apl8/igt@kms_content_protection@legacy.html

  * igt@kms_content_protection@lic:
    - shard-apl:          [TIMEOUT][45] ([i915#1319]) -> [FAIL][46] ([fdo#110321])
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-apl2/igt@kms_content_protection@lic.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-apl1/igt@kms_content_protection@lic.html

  * igt@kms_content_protection@srm:
    - shard-apl:          [FAIL][47] ([fdo#110321]) -> [TIMEOUT][48] ([i915#1319])
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8433/shard-apl4/igt@kms_content_protection@srm.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/shard-apl6/igt@kms_content_protection@srm.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [IGT#5]: https://gitlab.freedesktop.org/drm/igt-gpu-tools/issues/5
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
  [fdo#110321]: https://bugs.freedesktop.org/show_bug.cgi?id=110321
  [fdo#110336]: https://bugs.freedesktop.org/show_bug.cgi?id=110336
  [fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
  [i915#1188]: https://gitlab.freedesktop.org/drm/intel/issues/1188
  [i915#1319]: https://gitlab.freedesktop.org/drm/intel/issues/1319
  [i915#1528]: https://gitlab.freedesktop.org/drm/intel/issues/1528
  [i915#1542]: https://gitlab.freedesktop.org/drm/intel/issues/1542
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#198]: https://gitlab.freedesktop.org/drm/intel/issues/198
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#43]: https://gitlab.freedesktop.org/drm/intel/issues/43
  [i915#454]: https://gitlab.freedesktop.org/drm/intel/issues/454
  [i915#468]: https://gitlab.freedesktop.org/drm/intel/issues/468
  [i915#488]: https://gitlab.freedesktop.org/drm/intel/issues/488
  [i915#668]: https://gitlab.freedesktop.org/drm/intel/issues/668
  [i915#699]: https://gitlab.freedesktop.org/drm/intel/issues/699
  [i915#716]: https://gitlab.freedesktop.org/drm/intel/issues/716
  [i915#82]: https://gitlab.freedesktop.org/drm/intel/issues/82
  [i915#93]: https://gitlab.freedesktop.org/drm/intel/issues/93
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (11 -> 10)
------------------------------

  Missing    (1): pig-icl-1065g7 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_8433 -> Patchwork_17588

  CI-20190529: 20190529
  CI_DRM_8433: db68fed086f2ddcdc30e0d9ca5faaba5e55d0d01 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5633: c8c2e5ed5cd8e4b7a69a903f3f1653612086abcc @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_17588: 8ec6f4b1e7f06bdfd404ecfdf54337e9f645261f @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_17588/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Intel-gfx] [PATCH 4/9] drm/i915: Add {preemph, voltage}_max() vfuncs
  2020-05-06 11:23 ` [Intel-gfx] [PATCH 4/9] drm/i915: Add {preemph, voltage}_max() vfuncs Ville Syrjala
@ 2020-05-07  7:09   ` Ville Syrjälä
  0 siblings, 0 replies; 15+ messages in thread
From: Ville Syrjälä @ 2020-05-07  7:09 UTC (permalink / raw)
  To: intel-gfx

On Wed, May 06, 2020 at 02:23:23PM +0300, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Different platforms have different max vswing/preemph settings.
> Turn that into a pair vfuncs so we can decouple intel_dp.c and
> intel_ddi.c further.

Forgot to mention that it not only depends on the platform, but also
the link rate which is a runtime thing. So unfortunately can't just
make these into fixed init time assignments.

Though I have been pondering about making an init time split
between eDP vs. eDP low vswing vs. DP vs. HDMI though. That
could potentially make some of the if ladders in the ddi dbuf
trans code less confusing. Haven't actually tried to code
it up to see how it would look in the end.

> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c      | 21 ++----
>  drivers/gpu/drm/i915/display/intel_ddi.h      |  3 -
>  .../drm/i915/display/intel_display_types.h    |  3 +
>  drivers/gpu/drm/i915/display/intel_dp.c       | 67 ++++++-------------
>  drivers/gpu/drm/i915/display/intel_dp.h       |  4 --
>  .../drm/i915/display/intel_dp_link_training.c | 20 +++++-
>  6 files changed, 49 insertions(+), 69 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 5601673c3f30..409b8a68570f 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2095,10 +2095,10 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
>  				     ddi_translations[level].deemphasis);
>  }
>  
> -u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
> +static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp)
>  {
> +	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>  	enum port port = encoder->port;
>  	enum phy phy = intel_port_to_phy(dev_priv, port);
>  	int n_entries;
> @@ -2151,19 +2151,9 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
>   * used on all DDI platforms. Should that change we need to
>   * rethink this code.
>   */
> -u8 intel_ddi_dp_pre_emphasis_max(struct intel_encoder *encoder, u8 voltage_swing)
> +static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp)
>  {
> -	switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
> -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
> -		return DP_TRAIN_PRE_EMPH_LEVEL_3;
> -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
> -		return DP_TRAIN_PRE_EMPH_LEVEL_2;
> -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
> -		return DP_TRAIN_PRE_EMPH_LEVEL_1;
> -	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
> -	default:
> -		return DP_TRAIN_PRE_EMPH_LEVEL_0;
> -	}
> +	return DP_TRAIN_PRE_EMPH_LEVEL_3;
>  }
>  
>  static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
> @@ -4510,6 +4500,9 @@ intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
>  	else
>  		intel_dig_port->dp.set_signal_levels = hsw_set_signal_levels;
>  
> +	intel_dig_port->dp.voltage_max = intel_ddi_dp_voltage_max;
> +	intel_dig_port->dp.preemph_max = intel_ddi_dp_preemph_max;
> +
>  	if (INTEL_GEN(dev_priv) < 12) {
>  		intel_dig_port->dp.regs.dp_tp_ctl = DP_TP_CTL(port);
>  		intel_dig_port->dp.regs.dp_tp_status = DP_TP_STATUS(port);
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h
> index fbdf8ddde486..077e9dbbe367 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.h
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.h
> @@ -42,9 +42,6 @@ void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
>  					 struct intel_crtc_state *crtc_state);
>  u32 bxt_signal_levels(struct intel_dp *intel_dp);
>  u32 ddi_signal_levels(struct intel_dp *intel_dp);
> -u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
> -u8 intel_ddi_dp_pre_emphasis_max(struct intel_encoder *encoder,
> -				 u8 voltage_swing);
>  int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
>  				     bool enable);
>  void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 9488449e4b94..e0384af489c2 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1371,6 +1371,9 @@ struct intel_dp {
>  	void (*set_idle_link_train)(struct intel_dp *intel_dp);
>  	void (*set_signal_levels)(struct intel_dp *intel_dp);
>  
> +	u8 (*preemph_max)(struct intel_dp *intel_dp);
> +	u8 (*voltage_max)(struct intel_dp *intel_dp);
> +
>  	/* Displayport compliance testing */
>  	struct intel_dp_compliance compliance;
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index a52f01c48644..1b786d5af383 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -3947,58 +3947,24 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATU
>  				DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
>  }
>  
> -/* These are source-specific values. */
> -u8
> -intel_dp_voltage_max(struct intel_dp *intel_dp)
> +static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp)
>  {
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> -	enum port port = encoder->port;
> +	return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
> +}
>  
> -	if (HAS_DDI(dev_priv))
> -		return intel_ddi_dp_voltage_max(encoder);
> -	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
> -		 (HAS_PCH_SPLIT(dev_priv) && port != PORT_A))
> -		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
> -	else
> -		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
> +static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp)
> +{
> +	return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
>  }
>  
> -u8
> -intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, u8 voltage_swing)
> +static u8 intel_dp_pre_empemph_max_2(struct intel_dp *intel_dp)
>  {
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> -	enum port port = encoder->port;
> +	return DP_TRAIN_PRE_EMPH_LEVEL_2;
> +}
>  
> -	if (HAS_DDI(dev_priv)) {
> -		return intel_ddi_dp_pre_emphasis_max(encoder, voltage_swing);
> -	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
> -		   (HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) {
> -		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
> -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
> -			return DP_TRAIN_PRE_EMPH_LEVEL_3;
> -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
> -			return DP_TRAIN_PRE_EMPH_LEVEL_2;
> -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
> -			return DP_TRAIN_PRE_EMPH_LEVEL_1;
> -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
> -		default:
> -			return DP_TRAIN_PRE_EMPH_LEVEL_0;
> -		}
> -	} else {
> -		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
> -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
> -			return DP_TRAIN_PRE_EMPH_LEVEL_2;
> -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
> -			return DP_TRAIN_PRE_EMPH_LEVEL_2;
> -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
> -			return DP_TRAIN_PRE_EMPH_LEVEL_1;
> -		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
> -		default:
> -			return DP_TRAIN_PRE_EMPH_LEVEL_0;
> -		}
> -	}
> +static u8 intel_dp_pre_empemph_max_3(struct intel_dp *intel_dp)
> +{
> +	return DP_TRAIN_PRE_EMPH_LEVEL_3;
>  }
>  
>  static void vlv_set_signal_levels(struct intel_dp *intel_dp)
> @@ -8491,6 +8457,15 @@ bool intel_dp_init(struct drm_i915_private *dev_priv,
>  	else
>  		intel_dig_port->dp.set_signal_levels = g4x_set_signal_levels;
>  
> +	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
> +	    (HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) {
> +		intel_dig_port->dp.preemph_max = intel_dp_pre_empemph_max_3;
> +		intel_dig_port->dp.voltage_max = intel_dp_voltage_max_3;
> +	} else {
> +		intel_dig_port->dp.preemph_max = intel_dp_pre_empemph_max_2;
> +		intel_dig_port->dp.voltage_max = intel_dp_voltage_max_2;
> +	}
> +
>  	intel_dig_port->dp.output_reg = output_reg;
>  	intel_dig_port->max_lanes = 4;
>  	intel_dig_port->dp.regs.dp_tp_ctl = DP_TP_CTL(port);
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> index 6659ce15a693..e8375a75c3ec 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -91,10 +91,6 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
>  void
>  intel_dp_set_signal_levels(struct intel_dp *intel_dp);
>  void intel_dp_set_idle_link_train(struct intel_dp *intel_dp);
> -u8
> -intel_dp_voltage_max(struct intel_dp *intel_dp);
> -u8
> -intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, u8 voltage_swing);
>  void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
>  			   u8 *link_bw, u8 *rate_select);
>  bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> index e4f1843170b7..171d9e842fc0 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
> @@ -34,6 +34,21 @@ intel_dp_dump_link_status(const u8 link_status[DP_LINK_STATUS_SIZE])
>  		      link_status[3], link_status[4], link_status[5]);
>  }
>  
> +static u8 dp_pre_emphasis_max(u8 voltage_swing)
> +{
> +	switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
> +	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
> +		return DP_TRAIN_PRE_EMPH_LEVEL_3;
> +	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
> +		return DP_TRAIN_PRE_EMPH_LEVEL_2;
> +	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
> +		return DP_TRAIN_PRE_EMPH_LEVEL_1;
> +	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
> +	default:
> +		return DP_TRAIN_PRE_EMPH_LEVEL_0;
> +	}
> +}
> +
>  void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
>  			       const u8 link_status[DP_LINK_STATUS_SIZE])
>  {
> @@ -53,11 +68,12 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
>  			p = this_p;
>  	}
>  
> -	voltage_max = intel_dp_voltage_max(intel_dp);
> +	voltage_max = intel_dp->voltage_max(intel_dp);
>  	if (v >= voltage_max)
>  		v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;
>  
> -	preemph_max = intel_dp_pre_emphasis_max(intel_dp, v);
> +	preemph_max = min(intel_dp->preemph_max(intel_dp),
> +			  dp_pre_emphasis_max(v));
>  	if (p >= preemph_max)
>  		p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
>  
> -- 
> 2.24.1

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2020-05-07  7:16 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-06 11:23 [Intel-gfx] [PATCH 0/9] drm/i915: Plumb crtc state to link training code Ville Syrjala
2020-05-06 11:23 ` [Intel-gfx] [PATCH 1/9] drm/i915: Fix cpt/ppt max pre-emphasis Ville Syrjala
2020-05-06 11:23 ` [Intel-gfx] [PATCH 2/9] drm/i915: Fix ibx max vswing/preemph Ville Syrjala
2020-05-06 11:23 ` [Intel-gfx] [PATCH 3/9] drm/i915: Fix ivb cpu edp vswing Ville Syrjala
2020-05-06 11:23 ` [Intel-gfx] [PATCH 4/9] drm/i915: Add {preemph, voltage}_max() vfuncs Ville Syrjala
2020-05-07  7:09   ` Ville Syrjälä
2020-05-06 11:23 ` [Intel-gfx] [PATCH 5/9] drm/i915: Reverse preemph vs. voltage swing preference Ville Syrjala
2020-05-06 11:23 ` [Intel-gfx] [PATCH 6/9] drm/i915: Fix DP_TRAIN_MAX_{PRE_EMPHASIS, SWING}_REACHED handling Ville Syrjala
2020-05-06 11:23 ` [Intel-gfx] [PATCH 7/9] drm/i915: Replace some hand rolled max()s Ville Syrjala
2020-05-06 11:23 ` [Intel-gfx] [PATCH 8/9] drm/i915: Plumb crtc_state to link training Ville Syrjala
2020-05-06 12:05   ` [Intel-gfx] [PATCH v2 " Ville Syrjala
2020-05-06 11:23 ` [Intel-gfx] [PATCH 9/9] drm/i915: Eliminate intel_dp.regs.dp_tp_{ctl, status} Ville Syrjala
2020-05-06 11:29 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for drm/i915: Plumb crtc state to link training code Patchwork
2020-05-06 12:49 ` [Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: Plumb crtc state to link training code (rev2) Patchwork
2020-05-06 13:48 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.