All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/22] DP refactoring v2
@ 2015-10-23 10:01 Ander Conselvan de Oliveira
  2015-10-23 10:01 ` [PATCH 01/22] drm/i915: Don't pass *DP around to link training functions Ander Conselvan de Oliveira
                   ` (21 more replies)
  0 siblings, 22 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Hi,

Here is an updated version of the DP patches I have pending. I updated
the first patch with the comments from Sivakumar, and that required a
rebase, so I'm sending the patches out again. Other than that, the order
of the first few patches changed slightly so that there is no need to
create the new intel_dp_update_signal_levels() function.

I also included the patches of the second series I sent recently, that
moves the code for detemining maximum voltage swing and pre emphasis
levels to a new file.

Thanks,
Ander

Ander Conselvan de Oliveira (22):
  drm/i915: Don't pass *DP around to link training functions
  drm/i915: Split write of pattern to DP reg from
    intel_dp_set_link_train
  drm/i915 Call get_adjust_train() from clock recovery and channel eq
  drm/i915: Move register write into intel_dp_set_signal_levels()
  drm/i915: Move generic link training code to a separate file
  drm/i915: Create intel_dp->prepare_link_retrain() hook
  drm/i915: Make intel_dp_source_supports_hbr2() take an intel_dp
    pointer
  drm/i915: Move link training setup code to separate functions (v2)
  drm/i915: Move test for max voltage on all lanes to separate function
  drm/i915: Add function for getting the current link training voltage
  drm/i915: Split full retries loop out of clock recovery code (v2)
  drm/i915: Make the link training test for same voltage smaller
  drm/i915: Move the voltage changed check into intel_get_adjust_train()
  drm/i915: Add missing newline to link training debug message
  drm/i915: Split setting of vswing and pre_emph levels to separate file
  drm/i915: Introduce struct intel_dp_signal_levels
  drm/i915: Use struct intel_dp_signal_levels for eDP on SNB and IVB
  drm/i915: Use struct intel_dp_signal_levels for VLV
  drm/i915: Use struct intel_dp_signal_levels for CHV
  drm/i915: Use struct intel_dp_signal_levels for DDI platforms
  drm/i915: Remove old functions for maximum DP vswing and pre-emph
    levels
  drm/i915: Move ddi_signal_levels() to intel_dp_signal_levels.c

 drivers/gpu/drm/i915/Makefile                 |   2 +
 drivers/gpu/drm/i915/intel_ddi.c              |  86 +--
 drivers/gpu/drm/i915/intel_dp.c               | 864 +-------------------------
 drivers/gpu/drm/i915/intel_dp_link_training.c | 349 +++++++++++
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 689 ++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h              |  46 +-
 6 files changed, 1117 insertions(+), 919 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_dp_link_training.c
 create mode 100644 drivers/gpu/drm/i915/intel_dp_signal_levels.c

-- 
2.4.3

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

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

* [PATCH 01/22] drm/i915: Don't pass *DP around to link training functions
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-25  2:01   ` Thulasimani, Sivakumar
  2015-10-23 10:01 ` [PATCH 02/22] drm/i915: Split write of pattern to DP reg from intel_dp_set_link_train Ander Conselvan de Oliveira
                   ` (20 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

It just makes the code more confusing, so just reference intel_dp_>DP
directly.

Note that this also fix a bug where the value of intel_dp->DP could be
different than the last value written to the hw, due to an early return
that would skip the 'intel_dp->DP = DP' line.

v2: Don't preserve old DP value on failure. (Sivakumar)
  - Don't call drm_dp_clock_recovery_ok() twice. (Sivakumar)
  - Keep return type of clock recovery and channel equalization
    functions as void. (Ander)

v3: Remove DP parameter from intel_dp_set_signal_levels(). (Sivakumar)

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 47 ++++++++++++++++++-----------------------
 1 file changed, 20 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 8287df4..648300e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3552,7 +3552,7 @@ gen7_edp_signal_levels(uint8_t train_set)
 
 /* Properly updates "DP" with the correct signal levels. */
 static void
-intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
+intel_dp_set_signal_levels(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
@@ -3591,12 +3591,11 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
 		(train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
 			DP_TRAIN_PRE_EMPHASIS_SHIFT);
 
-	*DP = (*DP & ~mask) | signal_levels;
+	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
 }
 
 static bool
 intel_dp_set_link_train(struct intel_dp *intel_dp,
-			uint32_t *DP,
 			uint8_t dp_train_pat)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
@@ -3605,9 +3604,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 	uint8_t buf[sizeof(intel_dp->train_set) + 1];
 	int ret, len;
 
-	_intel_dp_set_link_train(intel_dp, DP, dp_train_pat);
+	_intel_dp_set_link_train(intel_dp, &intel_dp->DP, dp_train_pat);
 
-	I915_WRITE(intel_dp->output_reg, *DP);
+	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
 	POSTING_READ(intel_dp->output_reg);
 
 	buf[0] = dp_train_pat;
@@ -3628,17 +3627,17 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 }
 
 static bool
-intel_dp_reset_link_train(struct intel_dp *intel_dp, uint32_t *DP,
+intel_dp_reset_link_train(struct intel_dp *intel_dp,
 			uint8_t dp_train_pat)
 {
 	if (!intel_dp->train_set_valid)
 		memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
-	intel_dp_set_signal_levels(intel_dp, DP);
-	return intel_dp_set_link_train(intel_dp, DP, dp_train_pat);
+	intel_dp_set_signal_levels(intel_dp);
+	return intel_dp_set_link_train(intel_dp, dp_train_pat);
 }
 
 static bool
-intel_dp_update_link_train(struct intel_dp *intel_dp, uint32_t *DP,
+intel_dp_update_link_train(struct intel_dp *intel_dp,
 			   const uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
@@ -3647,9 +3646,9 @@ intel_dp_update_link_train(struct intel_dp *intel_dp, uint32_t *DP,
 	int ret;
 
 	intel_get_adjust_train(intel_dp, link_status);
-	intel_dp_set_signal_levels(intel_dp, DP);
+	intel_dp_set_signal_levels(intel_dp);
 
-	I915_WRITE(intel_dp->output_reg, *DP);
+	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
 	POSTING_READ(intel_dp->output_reg);
 
 	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
@@ -3698,7 +3697,6 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 	int i;
 	uint8_t voltage;
 	int voltage_tries, loop_tries;
-	uint32_t DP = intel_dp->DP;
 	uint8_t link_config[2];
 	uint8_t link_bw, rate_select;
 
@@ -3722,10 +3720,10 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 	link_config[1] = DP_SET_ANSI_8B10B;
 	drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
 
-	DP |= DP_PORT_EN;
+	intel_dp->DP |= DP_PORT_EN;
 
 	/* clock recovery */
-	if (!intel_dp_reset_link_train(intel_dp, &DP,
+	if (!intel_dp_reset_link_train(intel_dp,
 				       DP_TRAINING_PATTERN_1 |
 				       DP_LINK_SCRAMBLING_DISABLE)) {
 		DRM_ERROR("failed to enable link training\n");
@@ -3757,7 +3755,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 			DRM_DEBUG_KMS("clock recovery not ok, reset");
 			/* clear the flag as we are not reusing train set */
 			intel_dp->train_set_valid = false;
-			if (!intel_dp_reset_link_train(intel_dp, &DP,
+			if (!intel_dp_reset_link_train(intel_dp,
 						       DP_TRAINING_PATTERN_1 |
 						       DP_LINK_SCRAMBLING_DISABLE)) {
 				DRM_ERROR("failed to enable link training\n");
@@ -3776,7 +3774,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 				DRM_ERROR("too many full retries, give up\n");
 				break;
 			}
-			intel_dp_reset_link_train(intel_dp, &DP,
+			intel_dp_reset_link_train(intel_dp,
 						  DP_TRAINING_PATTERN_1 |
 						  DP_LINK_SCRAMBLING_DISABLE);
 			voltage_tries = 0;
@@ -3795,13 +3793,11 @@ 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 */
-		if (!intel_dp_update_link_train(intel_dp, &DP, link_status)) {
+		if (!intel_dp_update_link_train(intel_dp, link_status)) {
 			DRM_ERROR("failed to update link training\n");
 			break;
 		}
 	}
-
-	intel_dp->DP = DP;
 }
 
 static void
@@ -3811,7 +3807,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 	struct drm_device *dev = dig_port->base.base.dev;
 	bool channel_eq = false;
 	int tries, cr_tries;
-	uint32_t DP = intel_dp->DP;
 	uint32_t training_pattern = DP_TRAINING_PATTERN_2;
 
 	/*
@@ -3830,7 +3825,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 		DRM_ERROR("5.4 Gbps link rate without HBR2/TPS3 support\n");
 
 	/* channel equalization */
-	if (!intel_dp_set_link_train(intel_dp, &DP,
+	if (!intel_dp_set_link_train(intel_dp,
 				     training_pattern |
 				     DP_LINK_SCRAMBLING_DISABLE)) {
 		DRM_ERROR("failed to start channel equalization\n");
@@ -3859,7 +3854,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 					      intel_dp->lane_count)) {
 			intel_dp->train_set_valid = false;
 			intel_dp_link_training_clock_recovery(intel_dp);
-			intel_dp_set_link_train(intel_dp, &DP,
+			intel_dp_set_link_train(intel_dp,
 						training_pattern |
 						DP_LINK_SCRAMBLING_DISABLE);
 			cr_tries++;
@@ -3876,7 +3871,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 		if (tries > 5) {
 			intel_dp->train_set_valid = false;
 			intel_dp_link_training_clock_recovery(intel_dp);
-			intel_dp_set_link_train(intel_dp, &DP,
+			intel_dp_set_link_train(intel_dp,
 						training_pattern |
 						DP_LINK_SCRAMBLING_DISABLE);
 			tries = 0;
@@ -3885,7 +3880,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 		}
 
 		/* Update training set as requested by target */
-		if (!intel_dp_update_link_train(intel_dp, &DP, link_status)) {
+		if (!intel_dp_update_link_train(intel_dp, link_status)) {
 			DRM_ERROR("failed to update link training\n");
 			break;
 		}
@@ -3894,8 +3889,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 
 	intel_dp_set_idle_link_train(intel_dp);
 
-	intel_dp->DP = DP;
-
 	if (channel_eq) {
 		intel_dp->train_set_valid = true;
 		DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
@@ -3904,7 +3897,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 
 void intel_dp_stop_link_train(struct intel_dp *intel_dp)
 {
-	intel_dp_set_link_train(intel_dp, &intel_dp->DP,
+	intel_dp_set_link_train(intel_dp,
 				DP_TRAINING_PATTERN_DISABLE);
 }
 
-- 
2.4.3

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

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

* [PATCH 02/22] drm/i915: Split write of pattern to DP reg from intel_dp_set_link_train
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
  2015-10-23 10:01 ` [PATCH 01/22] drm/i915: Don't pass *DP around to link training functions Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-25  2:06   ` Thulasimani, Sivakumar
  2015-10-23 10:01 ` [PATCH 03/22] drm/i915 Call get_adjust_train() from clock recovery and channel eq Ander Conselvan de Oliveira
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Split the register write with the new link training pattern out of
intel_dp_set_link_train(), so that the i915 specific code is in a
separate function.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 648300e..0958cab 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3594,20 +3594,28 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
 	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
 }
 
-static bool
-intel_dp_set_link_train(struct intel_dp *intel_dp,
-			uint8_t dp_train_pat)
+static void
+intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
+				       uint8_t dp_train_pat)
 {
 	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);
-	uint8_t buf[sizeof(intel_dp->train_set) + 1];
-	int ret, len;
 
 	_intel_dp_set_link_train(intel_dp, &intel_dp->DP, dp_train_pat);
 
 	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
 	POSTING_READ(intel_dp->output_reg);
+}
+
+static bool
+intel_dp_set_link_train(struct intel_dp *intel_dp,
+			uint8_t dp_train_pat)
+{
+	uint8_t buf[sizeof(intel_dp->train_set) + 1];
+	int ret, len;
+
+	intel_dp_program_link_training_pattern(intel_dp, dp_train_pat);
 
 	buf[0] = dp_train_pat;
 	if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==
-- 
2.4.3

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

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

* [PATCH 03/22] drm/i915 Call get_adjust_train() from clock recovery and channel eq
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
  2015-10-23 10:01 ` [PATCH 01/22] drm/i915: Don't pass *DP around to link training functions Ander Conselvan de Oliveira
  2015-10-23 10:01 ` [PATCH 02/22] drm/i915: Split write of pattern to DP reg from intel_dp_set_link_train Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-25  2:11   ` Thulasimani, Sivakumar
  2015-10-23 10:01 ` [PATCH 04/22] drm/i915: Move register write into intel_dp_set_signal_levels() Ander Conselvan de Oliveira
                   ` (18 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Move the call to intel_dp_get_adjust_train() out of
intel_dp_update_link_train() and call it instead from the clock recovery
and channel equalization features. A follow up patch will remove the DP
register write from that function, so that it handles only the DPCD
write.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 0958cab..11f2385 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3645,15 +3645,13 @@ intel_dp_reset_link_train(struct intel_dp *intel_dp,
 }
 
 static bool
-intel_dp_update_link_train(struct intel_dp *intel_dp,
-			   const uint8_t link_status[DP_LINK_STATUS_SIZE])
+intel_dp_update_link_train(struct intel_dp *intel_dp)
 {
 	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);
 	int ret;
 
-	intel_get_adjust_train(intel_dp, link_status);
 	intel_dp_set_signal_levels(intel_dp);
 
 	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
@@ -3801,7 +3799,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 */
-		if (!intel_dp_update_link_train(intel_dp, link_status)) {
+		intel_get_adjust_train(intel_dp, link_status);
+		if (!intel_dp_update_link_train(intel_dp)) {
 			DRM_ERROR("failed to update link training\n");
 			break;
 		}
@@ -3888,7 +3887,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 		}
 
 		/* Update training set as requested by target */
-		if (!intel_dp_update_link_train(intel_dp, link_status)) {
+		intel_get_adjust_train(intel_dp, link_status);
+		if (!intel_dp_update_link_train(intel_dp)) {
 			DRM_ERROR("failed to update link training\n");
 			break;
 		}
-- 
2.4.3

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

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

* [PATCH 04/22] drm/i915: Move register write into intel_dp_set_signal_levels()
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (2 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 03/22] drm/i915 Call get_adjust_train() from clock recovery and channel eq Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-25  2:28   ` Thulasimani, Sivakumar
  2015-10-23 10:01 ` [PATCH 05/22] drm/i915: Move generic link training code to a separate file Ander Conselvan de Oliveira
                   ` (17 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Move register write from intel_dp_update_link_train() into
intel_dp_set_signal_levels(). This creates a better split between the
i915 specific code and the generic link training part. Note that this
causes an extra register write in intel_dp_reset_link_train(), since
both intel_dp_set_signal_levels() and intel_dp_set_link_train() write
to the DP register.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 11f2385..4ffb2e3 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3550,13 +3550,13 @@ gen7_edp_signal_levels(uint8_t train_set)
 	}
 }
 
-/* Properly updates "DP" with the correct signal levels. */
 static void
 intel_dp_set_signal_levels(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
 	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
 	uint32_t signal_levels, mask = 0;
 	uint8_t train_set = intel_dp->train_set[0];
 
@@ -3592,6 +3592,9 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
 			DP_TRAIN_PRE_EMPHASIS_SHIFT);
 
 	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
+
+	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
+	POSTING_READ(intel_dp->output_reg);
 }
 
 static void
@@ -3647,16 +3650,10 @@ intel_dp_reset_link_train(struct intel_dp *intel_dp,
 static bool
 intel_dp_update_link_train(struct intel_dp *intel_dp)
 {
-	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);
 	int ret;
 
 	intel_dp_set_signal_levels(intel_dp);
 
-	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
-	POSTING_READ(intel_dp->output_reg);
-
 	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
 				intel_dp->train_set, intel_dp->lane_count);
 
-- 
2.4.3

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

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

* [PATCH 05/22] drm/i915: Move generic link training code to a separate file
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (3 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 04/22] drm/i915: Move register write into intel_dp_set_signal_levels() Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-25  2:37   ` Thulasimani, Sivakumar
  2015-10-23 10:01 ` [PATCH 06/22] drm/i915: Create intel_dp->prepare_link_retrain() hook Ander Conselvan de Oliveira
                   ` (16 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

No functional changes, just moving code around.

v2: Rebase

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/Makefile                 |   1 +
 drivers/gpu/drm/i915/intel_dp.c               | 321 +------------------------
 drivers/gpu/drm/i915/intel_dp_link_training.c | 327 ++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h              |  16 ++
 4 files changed, 353 insertions(+), 312 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_dp_link_training.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 44d290a..0851de07 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -77,6 +77,7 @@ i915-y += dvo_ch7017.o \
 	  dvo_tfp410.o \
 	  intel_crt.o \
 	  intel_ddi.o \
+	  intel_dp_link_training.o \
 	  intel_dp_mst.o \
 	  intel_dp.o \
 	  intel_dsi.o \
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 4ffb2e3..4b88823 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1189,7 +1189,7 @@ intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
 	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
 }
 
-static bool intel_dp_source_supports_hbr2(struct drm_device *dev)
+bool intel_dp_source_supports_hbr2(struct drm_device *dev)
 {
 	/* WaDisableHBR2:skl */
 	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
@@ -1365,8 +1365,8 @@ int intel_dp_rate_select(struct intel_dp *intel_dp, int rate)
 	return rate_to_index(rate, intel_dp->sink_rates);
 }
 
-static void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
-				  uint8_t *link_bw, uint8_t *rate_select)
+void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
+			   uint8_t *link_bw, uint8_t *rate_select)
 {
 	if (intel_dp->num_sink_rates) {
 		*link_bw = 0;
@@ -3046,7 +3046,7 @@ intel_dp_dpcd_read_wake(struct drm_dp_aux *aux, unsigned int offset,
  * Fetch AUX CH registers 0x202 - 0x207 which contain
  * link status information
  */
-static bool
+bool
 intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
 	return intel_dp_dpcd_read_wake(&intel_dp->aux,
@@ -3056,7 +3056,7 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_
 }
 
 /* These are source-specific values. */
-static uint8_t
+uint8_t
 intel_dp_voltage_max(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
@@ -3079,7 +3079,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
 		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
 }
 
-static uint8_t
+uint8_t
 intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
@@ -3421,38 +3421,6 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
 	return 0;
 }
 
-static void
-intel_get_adjust_train(struct intel_dp *intel_dp,
-		       const uint8_t link_status[DP_LINK_STATUS_SIZE])
-{
-	uint8_t v = 0;
-	uint8_t p = 0;
-	int lane;
-	uint8_t voltage_max;
-	uint8_t preemph_max;
-
-	for (lane = 0; lane < intel_dp->lane_count; lane++) {
-		uint8_t this_v = drm_dp_get_adjust_request_voltage(link_status, lane);
-		uint8_t 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;
-	}
-
-	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);
-	if (p >= preemph_max)
-		p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
-
-	for (lane = 0; lane < 4; lane++)
-		intel_dp->train_set[lane] = v | p;
-}
-
 static uint32_t
 gen4_signal_levels(uint8_t train_set)
 {
@@ -3550,7 +3518,7 @@ gen7_edp_signal_levels(uint8_t train_set)
 	}
 }
 
-static void
+void
 intel_dp_set_signal_levels(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
@@ -3597,7 +3565,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
 	POSTING_READ(intel_dp->output_reg);
 }
 
-static void
+void
 intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
 				       uint8_t dp_train_pat)
 {
@@ -3611,56 +3579,7 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
 	POSTING_READ(intel_dp->output_reg);
 }
 
-static bool
-intel_dp_set_link_train(struct intel_dp *intel_dp,
-			uint8_t dp_train_pat)
-{
-	uint8_t buf[sizeof(intel_dp->train_set) + 1];
-	int ret, len;
-
-	intel_dp_program_link_training_pattern(intel_dp, dp_train_pat);
-
-	buf[0] = dp_train_pat;
-	if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==
-	    DP_TRAINING_PATTERN_DISABLE) {
-		/* don't write DP_TRAINING_LANEx_SET on disable */
-		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;
-	}
-
-	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET,
-				buf, len);
-
-	return ret == len;
-}
-
-static bool
-intel_dp_reset_link_train(struct intel_dp *intel_dp,
-			uint8_t dp_train_pat)
-{
-	if (!intel_dp->train_set_valid)
-		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);
-}
-
-static bool
-intel_dp_update_link_train(struct intel_dp *intel_dp)
-{
-	int ret;
-
-	intel_dp_set_signal_levels(intel_dp);
-
-	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
-				intel_dp->train_set, intel_dp->lane_count);
-
-	return ret == intel_dp->lane_count;
-}
-
-static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
+void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = intel_dig_port->base.base.dev;
@@ -3691,228 +3610,6 @@ static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
 		DRM_ERROR("Timed out waiting for DP idle patterns\n");
 }
 
-/* Enable corresponding port and start training pattern 1 */
-static void
-intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
-{
-	struct drm_encoder *encoder = &dp_to_dig_port(intel_dp)->base.base;
-	struct drm_device *dev = encoder->dev;
-	int i;
-	uint8_t voltage;
-	int voltage_tries, loop_tries;
-	uint8_t link_config[2];
-	uint8_t link_bw, rate_select;
-
-	if (HAS_DDI(dev))
-		intel_ddi_prepare_link_retrain(encoder);
-
-	intel_dp_compute_rate(intel_dp, intel_dp->link_rate,
-			      &link_bw, &rate_select);
-
-	/* Write the link configuration data */
-	link_config[0] = link_bw;
-	link_config[1] = intel_dp->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);
-	if (intel_dp->num_sink_rates)
-		drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_RATE_SET,
-				  &rate_select, 1);
-
-	link_config[0] = 0;
-	link_config[1] = DP_SET_ANSI_8B10B;
-	drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
-
-	intel_dp->DP |= DP_PORT_EN;
-
-	/* clock recovery */
-	if (!intel_dp_reset_link_train(intel_dp,
-				       DP_TRAINING_PATTERN_1 |
-				       DP_LINK_SCRAMBLING_DISABLE)) {
-		DRM_ERROR("failed to enable link training\n");
-		return;
-	}
-
-	voltage = 0xff;
-	voltage_tries = 0;
-	loop_tries = 0;
-	for (;;) {
-		uint8_t link_status[DP_LINK_STATUS_SIZE];
-
-		drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
-		if (!intel_dp_get_link_status(intel_dp, link_status)) {
-			DRM_ERROR("failed to get link status\n");
-			break;
-		}
-
-		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
-			DRM_DEBUG_KMS("clock recovery OK\n");
-			break;
-		}
-
-		/*
-		 * if we used previously trained voltage and pre-emphasis values
-		 * and we don't get clock recovery, reset link training values
-		 */
-		if (intel_dp->train_set_valid) {
-			DRM_DEBUG_KMS("clock recovery not ok, reset");
-			/* clear the flag as we are not reusing train set */
-			intel_dp->train_set_valid = false;
-			if (!intel_dp_reset_link_train(intel_dp,
-						       DP_TRAINING_PATTERN_1 |
-						       DP_LINK_SCRAMBLING_DISABLE)) {
-				DRM_ERROR("failed to enable link training\n");
-				return;
-			}
-			continue;
-		}
-
-		/* Check to see if we've tried the max voltage */
-		for (i = 0; i < intel_dp->lane_count; i++)
-			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
-				break;
-		if (i == intel_dp->lane_count) {
-			++loop_tries;
-			if (loop_tries == 5) {
-				DRM_ERROR("too many full retries, give up\n");
-				break;
-			}
-			intel_dp_reset_link_train(intel_dp,
-						  DP_TRAINING_PATTERN_1 |
-						  DP_LINK_SCRAMBLING_DISABLE);
-			voltage_tries = 0;
-			continue;
-		}
-
-		/* Check to see if we've tried the same voltage 5 times */
-		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
-			++voltage_tries;
-			if (voltage_tries == 5) {
-				DRM_ERROR("too many voltage retries, give up\n");
-				break;
-			}
-		} else
-			voltage_tries = 0;
-		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
-
-		/* Update training set as requested by target */
-		intel_get_adjust_train(intel_dp, link_status);
-		if (!intel_dp_update_link_train(intel_dp)) {
-			DRM_ERROR("failed to update link training\n");
-			break;
-		}
-	}
-}
-
-static void
-intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
-{
-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = dig_port->base.base.dev;
-	bool channel_eq = false;
-	int tries, cr_tries;
-	uint32_t training_pattern = DP_TRAINING_PATTERN_2;
-
-	/*
-	 * Training Pattern 3 for HBR2 or 1.2 devices that support it.
-	 *
-	 * Intel platforms that support HBR2 also support TPS3. TPS3 support is
-	 * also mandatory for downstream devices that support HBR2.
-	 *
-	 * Due to WaDisableHBR2 SKL < B0 is the only exception where TPS3 is
-	 * supported but still not enabled.
-	 */
-	if (intel_dp_source_supports_hbr2(dev) &&
-	    drm_dp_tps3_supported(intel_dp->dpcd))
-		training_pattern = DP_TRAINING_PATTERN_3;
-	else if (intel_dp->link_rate == 540000)
-		DRM_ERROR("5.4 Gbps link rate without HBR2/TPS3 support\n");
-
-	/* channel equalization */
-	if (!intel_dp_set_link_train(intel_dp,
-				     training_pattern |
-				     DP_LINK_SCRAMBLING_DISABLE)) {
-		DRM_ERROR("failed to start channel equalization\n");
-		return;
-	}
-
-	tries = 0;
-	cr_tries = 0;
-	channel_eq = false;
-	for (;;) {
-		uint8_t link_status[DP_LINK_STATUS_SIZE];
-
-		if (cr_tries > 5) {
-			DRM_ERROR("failed to train DP, aborting\n");
-			break;
-		}
-
-		drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
-		if (!intel_dp_get_link_status(intel_dp, link_status)) {
-			DRM_ERROR("failed to get link status\n");
-			break;
-		}
-
-		/* Make sure clock is still ok */
-		if (!drm_dp_clock_recovery_ok(link_status,
-					      intel_dp->lane_count)) {
-			intel_dp->train_set_valid = false;
-			intel_dp_link_training_clock_recovery(intel_dp);
-			intel_dp_set_link_train(intel_dp,
-						training_pattern |
-						DP_LINK_SCRAMBLING_DISABLE);
-			cr_tries++;
-			continue;
-		}
-
-		if (drm_dp_channel_eq_ok(link_status,
-					 intel_dp->lane_count)) {
-			channel_eq = true;
-			break;
-		}
-
-		/* Try 5 times, then try clock recovery if that fails */
-		if (tries > 5) {
-			intel_dp->train_set_valid = false;
-			intel_dp_link_training_clock_recovery(intel_dp);
-			intel_dp_set_link_train(intel_dp,
-						training_pattern |
-						DP_LINK_SCRAMBLING_DISABLE);
-			tries = 0;
-			cr_tries++;
-			continue;
-		}
-
-		/* Update training set as requested by target */
-		intel_get_adjust_train(intel_dp, link_status);
-		if (!intel_dp_update_link_train(intel_dp)) {
-			DRM_ERROR("failed to update link training\n");
-			break;
-		}
-		++tries;
-	}
-
-	intel_dp_set_idle_link_train(intel_dp);
-
-	if (channel_eq) {
-		intel_dp->train_set_valid = true;
-		DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
-	}
-}
-
-void intel_dp_stop_link_train(struct intel_dp *intel_dp)
-{
-	intel_dp_set_link_train(intel_dp,
-				DP_TRAINING_PATTERN_DISABLE);
-}
-
-void
-intel_dp_start_link_train(struct intel_dp *intel_dp)
-{
-	intel_dp_link_training_clock_recovery(intel_dp);
-	intel_dp_link_training_channel_equalization(intel_dp);
-}
-
 static void
 intel_dp_link_down(struct intel_dp *intel_dp)
 {
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
new file mode 100644
index 0000000..53f9c14
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright © 2008-2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "intel_drv.h"
+
+static void
+intel_get_adjust_train(struct intel_dp *intel_dp,
+		       const uint8_t link_status[DP_LINK_STATUS_SIZE])
+{
+	uint8_t v = 0;
+	uint8_t p = 0;
+	int lane;
+	uint8_t voltage_max;
+	uint8_t preemph_max;
+
+	for (lane = 0; lane < intel_dp->lane_count; lane++) {
+		uint8_t this_v = drm_dp_get_adjust_request_voltage(link_status, lane);
+		uint8_t 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;
+	}
+
+	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);
+	if (p >= preemph_max)
+		p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+
+	for (lane = 0; lane < 4; lane++)
+		intel_dp->train_set[lane] = v | p;
+}
+
+static bool
+intel_dp_set_link_train(struct intel_dp *intel_dp,
+			uint8_t dp_train_pat)
+{
+	uint8_t buf[sizeof(intel_dp->train_set) + 1];
+	int ret, len;
+
+	intel_dp_program_link_training_pattern(intel_dp, dp_train_pat);
+
+	buf[0] = dp_train_pat;
+	if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==
+	    DP_TRAINING_PATTERN_DISABLE) {
+		/* don't write DP_TRAINING_LANEx_SET on disable */
+		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;
+	}
+
+	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET,
+				buf, len);
+
+	return ret == len;
+}
+
+static bool
+intel_dp_reset_link_train(struct intel_dp *intel_dp,
+			uint8_t dp_train_pat)
+{
+	if (!intel_dp->train_set_valid)
+		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);
+}
+
+static bool
+intel_dp_update_link_train(struct intel_dp *intel_dp)
+{
+	int ret;
+
+	intel_dp_set_signal_levels(intel_dp);
+
+	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
+				intel_dp->train_set, intel_dp->lane_count);
+
+	return ret == intel_dp->lane_count;
+}
+
+/* Enable corresponding port and start training pattern 1 */
+static void
+intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
+{
+	struct drm_encoder *encoder = &dp_to_dig_port(intel_dp)->base.base;
+	struct drm_device *dev = encoder->dev;
+	int i;
+	uint8_t voltage;
+	int voltage_tries, loop_tries;
+	uint8_t link_config[2];
+	uint8_t link_bw, rate_select;
+
+	if (HAS_DDI(dev))
+		intel_ddi_prepare_link_retrain(encoder);
+
+	intel_dp_compute_rate(intel_dp, intel_dp->link_rate,
+			      &link_bw, &rate_select);
+
+	/* Write the link configuration data */
+	link_config[0] = link_bw;
+	link_config[1] = intel_dp->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);
+	if (intel_dp->num_sink_rates)
+		drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_RATE_SET,
+				  &rate_select, 1);
+
+	link_config[0] = 0;
+	link_config[1] = DP_SET_ANSI_8B10B;
+	drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
+
+	intel_dp->DP |= DP_PORT_EN;
+
+	/* clock recovery */
+	if (!intel_dp_reset_link_train(intel_dp,
+				       DP_TRAINING_PATTERN_1 |
+				       DP_LINK_SCRAMBLING_DISABLE)) {
+		DRM_ERROR("failed to enable link training\n");
+		return;
+	}
+
+	voltage = 0xff;
+	voltage_tries = 0;
+	loop_tries = 0;
+	for (;;) {
+		uint8_t link_status[DP_LINK_STATUS_SIZE];
+
+		drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
+		if (!intel_dp_get_link_status(intel_dp, link_status)) {
+			DRM_ERROR("failed to get link status\n");
+			break;
+		}
+
+		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
+			DRM_DEBUG_KMS("clock recovery OK\n");
+			break;
+		}
+
+		/*
+		 * if we used previously trained voltage and pre-emphasis values
+		 * and we don't get clock recovery, reset link training values
+		 */
+		if (intel_dp->train_set_valid) {
+			DRM_DEBUG_KMS("clock recovery not ok, reset");
+			/* clear the flag as we are not reusing train set */
+			intel_dp->train_set_valid = false;
+			if (!intel_dp_reset_link_train(intel_dp,
+						       DP_TRAINING_PATTERN_1 |
+						       DP_LINK_SCRAMBLING_DISABLE)) {
+				DRM_ERROR("failed to enable link training\n");
+				return;
+			}
+			continue;
+		}
+
+		/* Check to see if we've tried the max voltage */
+		for (i = 0; i < intel_dp->lane_count; i++)
+			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
+				break;
+		if (i == intel_dp->lane_count) {
+			++loop_tries;
+			if (loop_tries == 5) {
+				DRM_ERROR("too many full retries, give up\n");
+				break;
+			}
+			intel_dp_reset_link_train(intel_dp,
+						  DP_TRAINING_PATTERN_1 |
+						  DP_LINK_SCRAMBLING_DISABLE);
+			voltage_tries = 0;
+			continue;
+		}
+
+		/* Check to see if we've tried the same voltage 5 times */
+		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+			++voltage_tries;
+			if (voltage_tries == 5) {
+				DRM_ERROR("too many voltage retries, give up\n");
+				break;
+			}
+		} else
+			voltage_tries = 0;
+		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+
+		/* Update training set as requested by target */
+		intel_get_adjust_train(intel_dp, link_status);
+		if (!intel_dp_update_link_train(intel_dp)) {
+			DRM_ERROR("failed to update link training\n");
+			break;
+		}
+	}
+}
+
+static void
+intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+	bool channel_eq = false;
+	int tries, cr_tries;
+	uint32_t training_pattern = DP_TRAINING_PATTERN_2;
+
+	/*
+	 * Training Pattern 3 for HBR2 or 1.2 devices that support it.
+	 *
+	 * Intel platforms that support HBR2 also support TPS3. TPS3 support is
+	 * also mandatory for downstream devices that support HBR2.
+	 *
+	 * Due to WaDisableHBR2 SKL < B0 is the only exception where TPS3 is
+	 * supported but still not enabled.
+	 */
+	if (intel_dp_source_supports_hbr2(dev) &&
+	    drm_dp_tps3_supported(intel_dp->dpcd))
+		training_pattern = DP_TRAINING_PATTERN_3;
+	else if (intel_dp->link_rate == 540000)
+		DRM_ERROR("5.4 Gbps link rate without HBR2/TPS3 support\n");
+
+	/* channel equalization */
+	if (!intel_dp_set_link_train(intel_dp,
+				     training_pattern |
+				     DP_LINK_SCRAMBLING_DISABLE)) {
+		DRM_ERROR("failed to start channel equalization\n");
+		return;
+	}
+
+	tries = 0;
+	cr_tries = 0;
+	channel_eq = false;
+	for (;;) {
+		uint8_t link_status[DP_LINK_STATUS_SIZE];
+
+		if (cr_tries > 5) {
+			DRM_ERROR("failed to train DP, aborting\n");
+			break;
+		}
+
+		drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
+		if (!intel_dp_get_link_status(intel_dp, link_status)) {
+			DRM_ERROR("failed to get link status\n");
+			break;
+		}
+
+		/* Make sure clock is still ok */
+		if (!drm_dp_clock_recovery_ok(link_status,
+					      intel_dp->lane_count)) {
+			intel_dp->train_set_valid = false;
+			intel_dp_link_training_clock_recovery(intel_dp);
+			intel_dp_set_link_train(intel_dp,
+						training_pattern |
+						DP_LINK_SCRAMBLING_DISABLE);
+			cr_tries++;
+			continue;
+		}
+
+		if (drm_dp_channel_eq_ok(link_status,
+					 intel_dp->lane_count)) {
+			channel_eq = true;
+			break;
+		}
+
+		/* Try 5 times, then try clock recovery if that fails */
+		if (tries > 5) {
+			intel_dp->train_set_valid = false;
+			intel_dp_link_training_clock_recovery(intel_dp);
+			intel_dp_set_link_train(intel_dp,
+						training_pattern |
+						DP_LINK_SCRAMBLING_DISABLE);
+			tries = 0;
+			cr_tries++;
+			continue;
+		}
+
+		/* Update training set as requested by target */
+		intel_get_adjust_train(intel_dp, link_status);
+		if (!intel_dp_update_link_train(intel_dp)) {
+			DRM_ERROR("failed to update link training\n");
+			break;
+		}
+		++tries;
+	}
+
+	intel_dp_set_idle_link_train(intel_dp);
+
+	if (channel_eq) {
+		intel_dp->train_set_valid = true;
+		DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
+	}
+}
+
+void intel_dp_stop_link_train(struct intel_dp *intel_dp)
+{
+	intel_dp_set_link_train(intel_dp,
+				DP_TRAINING_PATTERN_DISABLE);
+}
+
+void
+intel_dp_start_link_train(struct intel_dp *intel_dp)
+{
+	intel_dp_link_training_clock_recovery(intel_dp);
+	intel_dp_link_training_channel_equalization(intel_dp);
+}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6790187..25ac5d2 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1236,6 +1236,22 @@ bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
 					 struct intel_digital_port *port);
 void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config);
 
+void
+intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
+				       uint8_t 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);
+uint8_t
+intel_dp_voltage_max(struct intel_dp *intel_dp);
+uint8_t
+intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing);
+void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
+			   uint8_t *link_bw, uint8_t *rate_select);
+bool intel_dp_source_supports_hbr2(struct drm_device *dev);
+bool
+intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]);
+
 /* intel_dp_mst.c */
 int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
 void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
-- 
2.4.3

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

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

* [PATCH 06/22] drm/i915: Create intel_dp->prepare_link_retrain() hook
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (4 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 05/22] drm/i915: Move generic link training code to a separate file Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-25  2:40   ` Thulasimani, Sivakumar
  2015-10-23 10:01 ` [PATCH 07/22] drm/i915: Make intel_dp_source_supports_hbr2() take an intel_dp pointer Ander Conselvan de Oliveira
                   ` (15 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

In order to prepare for a link training with DDI, the state machine
would call intel_ddi_prepare_link_retrain(). To remove the dependency to
the hardware information, replace that direct call with a callback.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c              | 8 ++++----
 drivers/gpu/drm/i915/intel_dp.c               | 3 +++
 drivers/gpu/drm/i915/intel_dp_link_training.c | 6 ++----
 drivers/gpu/drm/i915/intel_drv.h              | 6 +++++-
 4 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index a163741..80843d9 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2971,11 +2971,11 @@ void intel_ddi_pll_init(struct drm_device *dev)
 	}
 }
 
-void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
+void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
 {
-	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
-	struct intel_dp *intel_dp = &intel_dig_port->dp;
-	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+	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->port;
 	uint32_t val;
 	bool wait = false;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 4b88823..5b04ade 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5731,6 +5731,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	else
 		intel_dp->get_aux_send_ctl = i9xx_get_aux_send_ctl;
 
+	if (HAS_DDI(dev))
+		intel_dp->prepare_link_retrain = intel_ddi_prepare_link_retrain;
+
 	/* Preserve the current hw state. */
 	intel_dp->DP = I915_READ(intel_dp->output_reg);
 	intel_dp->attached_connector = intel_connector;
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 53f9c14..bb036d5 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -108,16 +108,14 @@ intel_dp_update_link_train(struct intel_dp *intel_dp)
 static void
 intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 {
-	struct drm_encoder *encoder = &dp_to_dig_port(intel_dp)->base.base;
-	struct drm_device *dev = encoder->dev;
 	int i;
 	uint8_t voltage;
 	int voltage_tries, loop_tries;
 	uint8_t link_config[2];
 	uint8_t link_bw, rate_select;
 
-	if (HAS_DDI(dev))
-		intel_ddi_prepare_link_retrain(encoder);
+	if (intel_dp->prepare_link_retrain)
+		intel_dp->prepare_link_retrain(intel_dp);
 
 	intel_dp_compute_rate(intel_dp, intel_dp->link_rate,
 			      &link_bw, &rate_select);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 25ac5d2..1c2a8ed 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -784,6 +784,10 @@ struct intel_dp {
 				     bool has_aux_irq,
 				     int send_bytes,
 				     uint32_t aux_clock_divider);
+
+	/* This is called before a link training is starterd */
+	void (*prepare_link_retrain)(struct intel_dp *intel_dp);
+
 	bool train_set_valid;
 
 	/* Displayport compliance testing */
@@ -988,7 +992,7 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
 bool intel_ddi_pll_select(struct intel_crtc *crtc,
 			  struct intel_crtc_state *crtc_state);
 void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
-void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
+void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp);
 bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
 void intel_ddi_fdi_disable(struct drm_crtc *crtc);
 void intel_ddi_get_config(struct intel_encoder *encoder,
-- 
2.4.3

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

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

* [PATCH 07/22] drm/i915: Make intel_dp_source_supports_hbr2() take an intel_dp pointer
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (5 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 06/22] drm/i915: Create intel_dp->prepare_link_retrain() hook Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-25  2:48   ` Thulasimani, Sivakumar
  2015-10-23 10:01 ` [PATCH 08/22] drm/i915: Move link training setup code to separate functions (v2) Ander Conselvan de Oliveira
                   ` (14 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

The function name implies it should get intel_dp, and it mostly used
where there is an intel_dp in the context.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c               | 19 +++++++++++--------
 drivers/gpu/drm/i915/intel_dp_link_training.c |  4 +---
 drivers/gpu/drm/i915/intel_drv.h              |  2 +-
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5b04ade..5344de4 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1189,8 +1189,11 @@ intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
 	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
 }
 
-bool intel_dp_source_supports_hbr2(struct drm_device *dev)
+bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
 {
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+
 	/* WaDisableHBR2:skl */
 	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
 		return false;
@@ -1203,8 +1206,10 @@ bool intel_dp_source_supports_hbr2(struct drm_device *dev)
 }
 
 static int
-intel_dp_source_rates(struct drm_device *dev, const int **source_rates)
+intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
 {
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
 	int size;
 
 	if (IS_BROXTON(dev)) {
@@ -1219,7 +1224,7 @@ intel_dp_source_rates(struct drm_device *dev, const int **source_rates)
 	}
 
 	/* This depends on the fact that 5.4 is last value in the array */
-	if (!intel_dp_source_supports_hbr2(dev))
+	if (!intel_dp_source_supports_hbr2(intel_dp))
 		size--;
 
 	return size;
@@ -1284,12 +1289,11 @@ static int intersect_rates(const int *source_rates, int source_len,
 static int intel_dp_common_rates(struct intel_dp *intel_dp,
 				 int *common_rates)
 {
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	const int *source_rates, *sink_rates;
 	int source_len, sink_len;
 
 	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
-	source_len = intel_dp_source_rates(dev, &source_rates);
+	source_len = intel_dp_source_rates(intel_dp, &source_rates);
 
 	return intersect_rates(source_rates, source_len,
 			       sink_rates, sink_len,
@@ -1314,7 +1318,6 @@ static void snprintf_int_array(char *str, size_t len,
 
 static void intel_dp_print_rates(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	const int *source_rates, *sink_rates;
 	int source_len, sink_len, common_len;
 	int common_rates[DP_MAX_SUPPORTED_RATES];
@@ -1323,7 +1326,7 @@ static void intel_dp_print_rates(struct intel_dp *intel_dp)
 	if ((drm_debug & DRM_UT_KMS) == 0)
 		return;
 
-	source_len = intel_dp_source_rates(dev, &source_rates);
+	source_len = intel_dp_source_rates(intel_dp, &source_rates);
 	snprintf_int_array(str, sizeof(str), source_rates, source_len);
 	DRM_DEBUG_KMS("source rates: %s\n", str);
 
@@ -3711,7 +3714,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
 	}
 
 	DRM_DEBUG_KMS("Display Port TPS3 support: source %s, sink %s\n",
-		      yesno(intel_dp_source_supports_hbr2(dev)),
+		      yesno(intel_dp_source_supports_hbr2(intel_dp)),
 		      yesno(drm_dp_tps3_supported(intel_dp->dpcd)));
 
 	/* Intermediate frequency support */
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index bb036d5..8888793 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -218,8 +218,6 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 static void
 intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 {
-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = dig_port->base.base.dev;
 	bool channel_eq = false;
 	int tries, cr_tries;
 	uint32_t training_pattern = DP_TRAINING_PATTERN_2;
@@ -233,7 +231,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 	 * Due to WaDisableHBR2 SKL < B0 is the only exception where TPS3 is
 	 * supported but still not enabled.
 	 */
-	if (intel_dp_source_supports_hbr2(dev) &&
+	if (intel_dp_source_supports_hbr2(intel_dp) &&
 	    drm_dp_tps3_supported(intel_dp->dpcd))
 		training_pattern = DP_TRAINING_PATTERN_3;
 	else if (intel_dp->link_rate == 540000)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1c2a8ed..3021e40 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1252,7 +1252,7 @@ uint8_t
 intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing);
 void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
 			   uint8_t *link_bw, uint8_t *rate_select);
-bool intel_dp_source_supports_hbr2(struct drm_device *dev);
+bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
 bool
 intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]);
 
-- 
2.4.3

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

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

* [PATCH 08/22] drm/i915: Move link training setup code to separate functions (v2)
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (6 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 07/22] drm/i915: Make intel_dp_source_supports_hbr2() take an intel_dp pointer Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-23 10:01 ` [PATCH 09/22] drm/i915: Move test for max voltage on all lanes to separate function Ander Conselvan de Oliveira
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Move the setup code for the different phases of link training into
functions separate from the training loop. This shouldn't cause any
change in behavior, but make the code slightly less hard to read.

Note that the extra checks performed by calling setup_channel_eq()
instead of intel_dp_set_link_train() in the fallback to clock recovery
path shouldn't cause any problems, since the link rate doesn't change
during the link training.

v2: Rebase

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp_link_training.c | 52 +++++++++++++++++----------
 1 file changed, 34 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 8888793..b39ed51 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -104,13 +104,9 @@ intel_dp_update_link_train(struct intel_dp *intel_dp)
 	return ret == intel_dp->lane_count;
 }
 
-/* Enable corresponding port and start training pattern 1 */
-static void
-intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
+static bool
+setup_clock_recovery(struct intel_dp *intel_dp)
 {
-	int i;
-	uint8_t voltage;
-	int voltage_tries, loop_tries;
 	uint8_t link_config[2];
 	uint8_t link_bw, rate_select;
 
@@ -141,9 +137,23 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 				       DP_TRAINING_PATTERN_1 |
 				       DP_LINK_SCRAMBLING_DISABLE)) {
 		DRM_ERROR("failed to enable link training\n");
-		return;
+		return false;
 	}
 
+	return true;
+}
+
+/* Enable corresponding port and start training pattern 1 */
+static void
+intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
+{
+	int i;
+	uint8_t voltage;
+	int voltage_tries, loop_tries;
+
+	if (!setup_clock_recovery(intel_dp))
+		return;
+
 	voltage = 0xff;
 	voltage_tries = 0;
 	loop_tries = 0;
@@ -215,11 +225,9 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 	}
 }
 
-static void
-intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
+static bool
+setup_channel_equalization(struct intel_dp *intel_dp)
 {
-	bool channel_eq = false;
-	int tries, cr_tries;
 	uint32_t training_pattern = DP_TRAINING_PATTERN_2;
 
 	/*
@@ -242,9 +250,21 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 				     training_pattern |
 				     DP_LINK_SCRAMBLING_DISABLE)) {
 		DRM_ERROR("failed to start channel equalization\n");
-		return;
+		return false;
 	}
 
+	return true;
+}
+
+static void
+intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
+{
+	bool channel_eq = false;
+	int tries, cr_tries;
+
+	if (!setup_channel_equalization(intel_dp))
+		return;
+
 	tries = 0;
 	cr_tries = 0;
 	channel_eq = false;
@@ -267,9 +287,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 					      intel_dp->lane_count)) {
 			intel_dp->train_set_valid = false;
 			intel_dp_link_training_clock_recovery(intel_dp);
-			intel_dp_set_link_train(intel_dp,
-						training_pattern |
-						DP_LINK_SCRAMBLING_DISABLE);
+			setup_channel_equalization(intel_dp);
 			cr_tries++;
 			continue;
 		}
@@ -284,9 +302,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 		if (tries > 5) {
 			intel_dp->train_set_valid = false;
 			intel_dp_link_training_clock_recovery(intel_dp);
-			intel_dp_set_link_train(intel_dp,
-						training_pattern |
-						DP_LINK_SCRAMBLING_DISABLE);
+			setup_channel_equalization(intel_dp);
 			tries = 0;
 			cr_tries++;
 			continue;
-- 
2.4.3

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

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

* [PATCH 09/22] drm/i915: Move test for max voltage on all lanes to separate function
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (7 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 08/22] drm/i915: Move link training setup code to separate functions (v2) Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-23 10:01 ` [PATCH 10/22] drm/i915: Add function for getting the current link training voltage Ander Conselvan de Oliveira
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Move the logic for checking if we have reached max voltage swing on all
lanes to a separate function to declutter the link training clock
recovery code.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp_link_training.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index b39ed51..9fdcc77 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -143,11 +143,22 @@ setup_clock_recovery(struct intel_dp *intel_dp)
 	return true;
 }
 
+static bool
+max_voltage_reached_on_all_lanes(struct intel_dp *intel_dp)
+{
+	int i;
+
+	for (i = 0; i < intel_dp->lane_count; i++)
+		if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
+			return false;
+
+	return true;
+}
+
 /* Enable corresponding port and start training pattern 1 */
 static void
 intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 {
-	int i;
 	uint8_t voltage;
 	int voltage_tries, loop_tries;
 
@@ -189,10 +200,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 		}
 
 		/* Check to see if we've tried the max voltage */
-		for (i = 0; i < intel_dp->lane_count; i++)
-			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
-				break;
-		if (i == intel_dp->lane_count) {
+		if (max_voltage_reached_on_all_lanes(intel_dp)) {
 			++loop_tries;
 			if (loop_tries == 5) {
 				DRM_ERROR("too many full retries, give up\n");
-- 
2.4.3

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

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

* [PATCH 10/22] drm/i915: Add function for getting the current link training voltage
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (8 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 09/22] drm/i915: Move test for max voltage on all lanes to separate function Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-25  3:56   ` Thulasimani, Sivakumar
  2015-10-23 10:01 ` [PATCH 11/22] drm/i915: Split full retries loop out of clock recovery code (v2) Ander Conselvan de Oliveira
                   ` (11 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Add a function for retrieving the current voltage swing being used for
link training. Using that function in the clock recovery code makes it a
bit more readable.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp_link_training.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 9fdcc77..e5b9410 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -155,6 +155,12 @@ max_voltage_reached_on_all_lanes(struct intel_dp *intel_dp)
 	return true;
 }
 
+static uint8_t
+intel_dp_get_train_voltage(struct intel_dp *intel_dp)
+{
+	return intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+}
+
 /* Enable corresponding port and start training pattern 1 */
 static void
 intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
@@ -214,7 +220,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 		}
 
 		/* Check to see if we've tried the same voltage 5 times */
-		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+		if (intel_dp_get_train_voltage(intel_dp) == voltage) {
 			++voltage_tries;
 			if (voltage_tries == 5) {
 				DRM_ERROR("too many voltage retries, give up\n");
@@ -222,7 +228,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 			}
 		} else
 			voltage_tries = 0;
-		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+		voltage = intel_dp_get_train_voltage(intel_dp);
 
 		/* Update training set as requested by target */
 		intel_get_adjust_train(intel_dp, link_status);
-- 
2.4.3

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

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

* [PATCH 11/22] drm/i915: Split full retries loop out of clock recovery code (v2)
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (9 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 10/22] drm/i915: Add function for getting the current link training voltage Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-23 10:01 ` [PATCH 12/22] drm/i915: Make the link training test for same voltage smaller Ander Conselvan de Oliveira
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

When a failure to achieve clock recovery happens, the link training code
repeats the training process starting with initial values up to five
times before giving up. The logic for the so called "full retries" and
the "voltage tries" was convoluted into a single loop. This patch splits
it into two separate loops, making it easier to follow.

Note that prior to this patch, a failure to get clock recovery with
previously know good values wouldn't count as a voltage or full retry
failure, but now that counts as a full retry failure.

v2: Rebase

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp_link_training.c | 79 +++++++++++++--------------
 1 file changed, 37 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index e5b9410..9f47d8e 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -132,14 +132,6 @@ setup_clock_recovery(struct intel_dp *intel_dp)
 
 	intel_dp->DP |= DP_PORT_EN;
 
-	/* clock recovery */
-	if (!intel_dp_reset_link_train(intel_dp,
-				       DP_TRAINING_PATTERN_1 |
-				       DP_LINK_SCRAMBLING_DISABLE)) {
-		DRM_ERROR("failed to enable link training\n");
-		return false;
-	}
-
 	return true;
 }
 
@@ -161,19 +153,12 @@ intel_dp_get_train_voltage(struct intel_dp *intel_dp)
 	return intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 }
 
-/* Enable corresponding port and start training pattern 1 */
-static void
-intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
+static bool
+clock_recovery_voltage_step(struct intel_dp *intel_dp)
 {
-	uint8_t voltage;
-	int voltage_tries, loop_tries;
-
-	if (!setup_clock_recovery(intel_dp))
-		return;
+	int voltage_tries = 0;
+	uint8_t voltage = 0xff;
 
-	voltage = 0xff;
-	voltage_tries = 0;
-	loop_tries = 0;
 	for (;;) {
 		uint8_t link_status[DP_LINK_STATUS_SIZE];
 
@@ -183,10 +168,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 			break;
 		}
 
-		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
-			DRM_DEBUG_KMS("clock recovery OK\n");
-			break;
-		}
+		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count))
+			return true;
 
 		/*
 		 * if we used previously trained voltage and pre-emphasis values
@@ -196,28 +179,12 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 			DRM_DEBUG_KMS("clock recovery not ok, reset");
 			/* clear the flag as we are not reusing train set */
 			intel_dp->train_set_valid = false;
-			if (!intel_dp_reset_link_train(intel_dp,
-						       DP_TRAINING_PATTERN_1 |
-						       DP_LINK_SCRAMBLING_DISABLE)) {
-				DRM_ERROR("failed to enable link training\n");
-				return;
-			}
-			continue;
+			break;
 		}
 
 		/* Check to see if we've tried the max voltage */
-		if (max_voltage_reached_on_all_lanes(intel_dp)) {
-			++loop_tries;
-			if (loop_tries == 5) {
-				DRM_ERROR("too many full retries, give up\n");
-				break;
-			}
-			intel_dp_reset_link_train(intel_dp,
-						  DP_TRAINING_PATTERN_1 |
-						  DP_LINK_SCRAMBLING_DISABLE);
-			voltage_tries = 0;
-			continue;
-		}
+		if (max_voltage_reached_on_all_lanes(intel_dp))
+			break;
 
 		/* Check to see if we've tried the same voltage 5 times */
 		if (intel_dp_get_train_voltage(intel_dp) == voltage) {
@@ -237,6 +204,34 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 			break;
 		}
 	}
+
+	return false;
+}
+
+/* Enable corresponding port and start training pattern 1 */
+static void
+intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
+{
+	int loop_tries;
+
+	if (!setup_clock_recovery(intel_dp))
+		return;
+
+	for (loop_tries = 0; loop_tries < 5; loop_tries++) {
+		if (!intel_dp_reset_link_train(intel_dp,
+					       DP_TRAINING_PATTERN_1 |
+					       DP_LINK_SCRAMBLING_DISABLE)) {
+			DRM_ERROR("failed to enable link training\n");
+			return;
+		}
+
+		if (clock_recovery_voltage_step(intel_dp)) {
+			DRM_DEBUG_KMS("clock recovery OK\n");
+			return;
+		}
+	}
+
+	DRM_ERROR("too many full retries, give up\n");
 }
 
 static bool
-- 
2.4.3

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

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

* [PATCH 12/22] drm/i915: Make the link training test for same voltage smaller
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (10 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 11/22] drm/i915: Split full retries loop out of clock recovery code (v2) Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-23 10:01 ` [PATCH 13/22] drm/i915: Move the voltage changed check into intel_get_adjust_train() Ander Conselvan de Oliveira
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

It makes it slightly easier to read.

v2: Add missing word in patch title. (Ander)

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp_link_training.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 9f47d8e..0da2133 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -187,14 +187,13 @@ clock_recovery_voltage_step(struct intel_dp *intel_dp)
 			break;
 
 		/* Check to see if we've tried the same voltage 5 times */
-		if (intel_dp_get_train_voltage(intel_dp) == voltage) {
-			++voltage_tries;
-			if (voltage_tries == 5) {
-				DRM_ERROR("too many voltage retries, give up\n");
-				break;
-			}
-		} else
+		if (intel_dp_get_train_voltage(intel_dp) != voltage) {
 			voltage_tries = 0;
+		} else if (++voltage_tries == 5) {
+			DRM_ERROR("too many voltage retries, give up\n");
+			break;
+		}
+
 		voltage = intel_dp_get_train_voltage(intel_dp);
 
 		/* Update training set as requested by target */
-- 
2.4.3

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

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

* [PATCH 13/22] drm/i915: Move the voltage changed check into intel_get_adjust_train()
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (11 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 12/22] drm/i915: Make the link training test for same voltage smaller Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-23 10:01 ` [PATCH 14/22] drm/i915: Add missing newline to link training debug message Ander Conselvan de Oliveira
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Move the check of whether the voltage changed into the function that
parses the sink adjust request, simplifying the voltage loop a bit.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp_link_training.c | 32 ++++++++++++++-------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 0da2133..fb449f5 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -23,7 +23,8 @@
 
 #include "intel_drv.h"
 
-static void
+/* Returns true if the voltage swing changed */
+static bool
 intel_get_adjust_train(struct intel_dp *intel_dp,
 		       const uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
@@ -32,6 +33,8 @@ intel_get_adjust_train(struct intel_dp *intel_dp,
 	int lane;
 	uint8_t voltage_max;
 	uint8_t preemph_max;
+	uint8_t mask;
+	bool voltage_changed = false;
 
 	for (lane = 0; lane < intel_dp->lane_count; lane++) {
 		uint8_t this_v = drm_dp_get_adjust_request_voltage(link_status, lane);
@@ -51,8 +54,16 @@ intel_get_adjust_train(struct intel_dp *intel_dp,
 	if (p >= preemph_max)
 		p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 
-	for (lane = 0; lane < 4; lane++)
+	mask = DP_TRAIN_VOLTAGE_SWING_MASK | DP_TRAIN_MAX_SWING_REACHED;
+
+	for (lane = 0; lane < 4; lane++) {
+		if ((intel_dp->train_set[lane] & mask) != v)
+			voltage_changed = true;
+
 		intel_dp->train_set[lane] = v | p;
+	}
+
+	return voltage_changed;
 }
 
 static bool
@@ -147,17 +158,10 @@ max_voltage_reached_on_all_lanes(struct intel_dp *intel_dp)
 	return true;
 }
 
-static uint8_t
-intel_dp_get_train_voltage(struct intel_dp *intel_dp)
-{
-	return intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
-}
-
 static bool
 clock_recovery_voltage_step(struct intel_dp *intel_dp)
 {
 	int voltage_tries = 0;
-	uint8_t voltage = 0xff;
 
 	for (;;) {
 		uint8_t link_status[DP_LINK_STATUS_SIZE];
@@ -186,18 +190,16 @@ clock_recovery_voltage_step(struct intel_dp *intel_dp)
 		if (max_voltage_reached_on_all_lanes(intel_dp))
 			break;
 
-		/* Check to see if we've tried the same voltage 5 times */
-		if (intel_dp_get_train_voltage(intel_dp) != voltage) {
+		/* Update training set and check to see if we've tried the same
+		 *  voltage 5 times */
+		if (intel_get_adjust_train(intel_dp, link_status)) {
 			voltage_tries = 0;
 		} else if (++voltage_tries == 5) {
 			DRM_ERROR("too many voltage retries, give up\n");
 			break;
 		}
 
-		voltage = intel_dp_get_train_voltage(intel_dp);
-
-		/* Update training set as requested by target */
-		intel_get_adjust_train(intel_dp, link_status);
+		/* Make the new training set effective */
 		if (!intel_dp_update_link_train(intel_dp)) {
 			DRM_ERROR("failed to update link training\n");
 			break;
-- 
2.4.3

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

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

* [PATCH 14/22] drm/i915: Add missing newline to link training debug message
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (12 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 13/22] drm/i915: Move the voltage changed check into intel_get_adjust_train() Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-23 10:01 ` [PATCH 15/22] drm/i915: Split setting of vswing and pre_emph levels to separate file Ander Conselvan de Oliveira
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp_link_training.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index fb449f5..63a6f3d 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -180,7 +180,7 @@ clock_recovery_voltage_step(struct intel_dp *intel_dp)
 		 * and we don't get clock recovery, reset link training values
 		 */
 		if (intel_dp->train_set_valid) {
-			DRM_DEBUG_KMS("clock recovery not ok, reset");
+			DRM_DEBUG_KMS("clock recovery not ok, reset\n");
 			/* clear the flag as we are not reusing train set */
 			intel_dp->train_set_valid = false;
 			break;
-- 
2.4.3

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

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

* [PATCH 15/22] drm/i915: Split setting of vswing and pre_emph levels to separate file
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (13 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 14/22] drm/i915: Add missing newline to link training debug message Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-23 10:01 ` [PATCH 16/22] drm/i915: Introduce struct intel_dp_signal_levels Ander Conselvan de Oliveira
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

No functional changes, just moving code around.

v2: Rebase

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/Makefile                 |   1 +
 drivers/gpu/drm/i915/intel_dp.c               | 517 -------------------------
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 534 ++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h              |   7 +
 4 files changed, 542 insertions(+), 517 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_dp_signal_levels.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0851de07..9cf9978 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -79,6 +79,7 @@ i915-y += dvo_ch7017.o \
 	  intel_ddi.o \
 	  intel_dp_link_training.o \
 	  intel_dp_mst.o \
+	  intel_dp_signal_levels.o \
 	  intel_dp.o \
 	  intel_dsi.o \
 	  intel_dsi_panel_vbt.o \
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5344de4..1236791 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -111,13 +111,6 @@ static bool is_edp(struct intel_dp *intel_dp)
 	return intel_dig_port->base.type == INTEL_OUTPUT_EDP;
 }
 
-static struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp)
-{
-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-
-	return intel_dig_port->base.base.dev;
-}
-
 static struct intel_dp *intel_attached_dp(struct drm_connector *connector)
 {
 	return enc_to_intel_dp(&intel_attached_encoder(connector)->base);
@@ -3058,516 +3051,6 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_
 				       DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
 }
 
-/* These are source-specific values. */
-uint8_t
-intel_dp_voltage_max(struct intel_dp *intel_dp)
-{
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	enum port port = dp_to_dig_port(intel_dp)->port;
-
-	if (IS_BROXTON(dev))
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else if (INTEL_INFO(dev)->gen >= 9) {
-		if (dev_priv->edp_low_vswing && port == PORT_A)
-			return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-	} else if (IS_VALLEYVIEW(dev))
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else if (IS_GEN7(dev) && port == PORT_A)
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-	else if (HAS_PCH_CPT(dev) && port != PORT_A)
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-}
-
-uint8_t
-intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
-{
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	enum port port = dp_to_dig_port(intel_dp)->port;
-
-	if (INTEL_INFO(dev)->gen >= 9) {
-		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:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
-		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 if (IS_VALLEYVIEW(dev)) {
-		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 if (IS_GEN7(dev) && 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:
-			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 uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
-{
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
-	struct intel_crtc *intel_crtc =
-		to_intel_crtc(dport->base.base.crtc);
-	unsigned long demph_reg_value, preemph_reg_value,
-		uniqtranscale_reg_value;
-	uint8_t train_set = intel_dp->train_set[0];
-	enum dpio_channel port = vlv_dport_to_channel(dport);
-	int pipe = intel_crtc->pipe;
-
-	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
-	case DP_TRAIN_PRE_EMPH_LEVEL_0:
-		preemph_reg_value = 0x0004000;
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			demph_reg_value = 0x2B405555;
-			uniqtranscale_reg_value = 0x552AB83A;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			demph_reg_value = 0x2B404040;
-			uniqtranscale_reg_value = 0x5548B83A;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			demph_reg_value = 0x2B245555;
-			uniqtranscale_reg_value = 0x5560B83A;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-			demph_reg_value = 0x2B405555;
-			uniqtranscale_reg_value = 0x5598DA3A;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_1:
-		preemph_reg_value = 0x0002000;
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			demph_reg_value = 0x2B404040;
-			uniqtranscale_reg_value = 0x5552B83A;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			demph_reg_value = 0x2B404848;
-			uniqtranscale_reg_value = 0x5580B83A;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			demph_reg_value = 0x2B404040;
-			uniqtranscale_reg_value = 0x55ADDA3A;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_2:
-		preemph_reg_value = 0x0000000;
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			demph_reg_value = 0x2B305555;
-			uniqtranscale_reg_value = 0x5570B83A;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			demph_reg_value = 0x2B2B4040;
-			uniqtranscale_reg_value = 0x55ADDA3A;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_3:
-		preemph_reg_value = 0x0006000;
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			demph_reg_value = 0x1B405555;
-			uniqtranscale_reg_value = 0x55ADDA3A;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	default:
-		return 0;
-	}
-
-	mutex_lock(&dev_priv->sb_lock);
-	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x00000000);
-	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), demph_reg_value);
-	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port),
-			 uniqtranscale_reg_value);
-	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(port), 0x0C782040);
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000);
-	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), preemph_reg_value);
-	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x80000000);
-	mutex_unlock(&dev_priv->sb_lock);
-
-	return 0;
-}
-
-static bool chv_need_uniq_trans_scale(uint8_t train_set)
-{
-	return (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) == DP_TRAIN_PRE_EMPH_LEVEL_0 &&
-		(train_set & DP_TRAIN_VOLTAGE_SWING_MASK) == DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-}
-
-static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
-{
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
-	struct intel_crtc *intel_crtc = to_intel_crtc(dport->base.base.crtc);
-	u32 deemph_reg_value, margin_reg_value, val;
-	uint8_t train_set = intel_dp->train_set[0];
-	enum dpio_channel ch = vlv_dport_to_channel(dport);
-	enum pipe pipe = intel_crtc->pipe;
-	int i;
-
-	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
-	case DP_TRAIN_PRE_EMPH_LEVEL_0:
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			deemph_reg_value = 128;
-			margin_reg_value = 52;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			deemph_reg_value = 128;
-			margin_reg_value = 77;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			deemph_reg_value = 128;
-			margin_reg_value = 102;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-			deemph_reg_value = 128;
-			margin_reg_value = 154;
-			/* FIXME extra to set for 1200 */
-			break;
-		default:
-			return 0;
-		}
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_1:
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			deemph_reg_value = 85;
-			margin_reg_value = 78;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			deemph_reg_value = 85;
-			margin_reg_value = 116;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-			deemph_reg_value = 85;
-			margin_reg_value = 154;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_2:
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			deemph_reg_value = 64;
-			margin_reg_value = 104;
-			break;
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-			deemph_reg_value = 64;
-			margin_reg_value = 154;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_3:
-		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-			deemph_reg_value = 43;
-			margin_reg_value = 154;
-			break;
-		default:
-			return 0;
-		}
-		break;
-	default:
-		return 0;
-	}
-
-	mutex_lock(&dev_priv->sb_lock);
-
-	/* Clear calc init */
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
-	val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
-	val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
-	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) {
-		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);
-		val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
-		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
-	}
-
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch));
-	val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
-	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) {
-		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;
-		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val);
-	}
-
-	/* Program swing deemph */
-	for (i = 0; i < intel_crtc->config->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;
-		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW4(ch, i), val);
-	}
-
-	/* Program swing margin */
-	for (i = 0; i < intel_crtc->config->lane_count; i++) {
-		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
-
-		val &= ~DPIO_SWING_MARGIN000_MASK;
-		val |= margin_reg_value << DPIO_SWING_MARGIN000_SHIFT;
-
-		/*
-		 * Supposedly this value shouldn't matter when unique transition
-		 * scale is disabled, but in fact it does matter. Let's just
-		 * always program the same value and hope it's OK.
-		 */
-		val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT);
-		val |= 0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT;
-
-		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
-	}
-
-	/*
-	 * The document said it needs to set bit 27 for ch0 and bit 26
-	 * for ch1. Might be a typo in the doc.
-	 * 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++) {
-		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
-		if (chv_need_uniq_trans_scale(train_set))
-			val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
-		else
-			val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
-		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
-	}
-
-	/* Start swing calculation */
-	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
-	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) {
-		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);
-	}
-
-	mutex_unlock(&dev_priv->sb_lock);
-
-	return 0;
-}
-
-static uint32_t
-gen4_signal_levels(uint8_t train_set)
-{
-	uint32_t	signal_levels = 0;
-
-	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-	default:
-		signal_levels |= DP_VOLTAGE_0_4;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-		signal_levels |= DP_VOLTAGE_0_6;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-		signal_levels |= DP_VOLTAGE_0_8;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-		signal_levels |= DP_VOLTAGE_1_2;
-		break;
-	}
-	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
-	case DP_TRAIN_PRE_EMPH_LEVEL_0:
-	default:
-		signal_levels |= DP_PRE_EMPHASIS_0;
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_1:
-		signal_levels |= DP_PRE_EMPHASIS_3_5;
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_2:
-		signal_levels |= DP_PRE_EMPHASIS_6;
-		break;
-	case DP_TRAIN_PRE_EMPH_LEVEL_3:
-		signal_levels |= DP_PRE_EMPHASIS_9_5;
-		break;
-	}
-	return signal_levels;
-}
-
-/* Gen6's DP voltage swing and pre-emphasis control */
-static uint32_t
-gen6_edp_signal_levels(uint8_t train_set)
-{
-	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-					 DP_TRAIN_PRE_EMPHASIS_MASK);
-	switch (signal_levels) {
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
-	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_400_600MV_6DB_SNB_B;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
-	default:
-		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
-			      "0x%x\n", signal_levels);
-		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
-	}
-}
-
-/* Gen7's DP voltage swing and pre-emphasis control */
-static uint32_t
-gen7_edp_signal_levels(uint8_t train_set)
-{
-	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-					 DP_TRAIN_PRE_EMPHASIS_MASK);
-	switch (signal_levels) {
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_400MV_0DB_IVB;
-	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:
-		return EDP_LINK_TRAIN_400MV_6DB_IVB;
-
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_600MV_0DB_IVB;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_600MV_3_5DB_IVB;
-
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_800MV_0DB_IVB;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_800MV_3_5DB_IVB;
-
-	default:
-		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
-			      "0x%x\n", signal_levels);
-		return EDP_LINK_TRAIN_500MV_0DB_IVB;
-	}
-}
-
-void
-intel_dp_set_signal_levels(struct intel_dp *intel_dp)
-{
-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	enum port port = intel_dig_port->port;
-	struct drm_device *dev = intel_dig_port->base.base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	uint32_t signal_levels, mask = 0;
-	uint8_t train_set = intel_dp->train_set[0];
-
-	if (HAS_DDI(dev)) {
-		signal_levels = ddi_signal_levels(intel_dp);
-
-		if (IS_BROXTON(dev))
-			signal_levels = 0;
-		else
-			mask = DDI_BUF_EMP_MASK;
-	} else if (IS_CHERRYVIEW(dev)) {
-		signal_levels = chv_signal_levels(intel_dp);
-	} else if (IS_VALLEYVIEW(dev)) {
-		signal_levels = vlv_signal_levels(intel_dp);
-	} else if (IS_GEN7(dev) && port == PORT_A) {
-		signal_levels = gen7_edp_signal_levels(train_set);
-		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
-	} else if (IS_GEN6(dev) && port == PORT_A) {
-		signal_levels = gen6_edp_signal_levels(train_set);
-		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
-	} else {
-		signal_levels = gen4_signal_levels(train_set);
-		mask = DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK;
-	}
-
-	if (mask)
-		DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
-
-	DRM_DEBUG_KMS("Using vswing level %d\n",
-		train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
-	DRM_DEBUG_KMS("Using pre-emphasis level %d\n",
-		(train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
-			DP_TRAIN_PRE_EMPHASIS_SHIFT);
-
-	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
-
-	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
-	POSTING_READ(intel_dp->output_reg);
-}
-
 void
 intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
 				       uint8_t dp_train_pat)
diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
new file mode 100644
index 0000000..e516dd2
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -0,0 +1,534 @@
+/*
+ * Copyright © 2008-2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "intel_drv.h"
+
+/* These are source-specific values. */
+uint8_t
+intel_dp_voltage_max(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = dp_to_dig_port(intel_dp)->port;
+
+	if (IS_BROXTON(dev))
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+	else if (INTEL_INFO(dev)->gen >= 9) {
+		if (dev_priv->edp_low_vswing && port == PORT_A)
+			return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+	} else if (IS_VALLEYVIEW(dev))
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+	else if (IS_GEN7(dev) && port == PORT_A)
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+	else if (HAS_PCH_CPT(dev) && port != PORT_A)
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+	else
+		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+}
+
+uint8_t
+intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	enum port port = dp_to_dig_port(intel_dp)->port;
+
+	if (INTEL_INFO(dev)->gen >= 9) {
+		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:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		default:
+			return DP_TRAIN_PRE_EMPH_LEVEL_0;
+		}
+	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+		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 if (IS_VALLEYVIEW(dev)) {
+		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 if (IS_GEN7(dev) && 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:
+			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 uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(dport->base.base.crtc);
+	unsigned long demph_reg_value, preemph_reg_value,
+		uniqtranscale_reg_value;
+	uint8_t train_set = intel_dp->train_set[0];
+	enum dpio_channel port = vlv_dport_to_channel(dport);
+	int pipe = intel_crtc->pipe;
+
+	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
+	case DP_TRAIN_PRE_EMPH_LEVEL_0:
+		preemph_reg_value = 0x0004000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			demph_reg_value = 0x2B405555;
+			uniqtranscale_reg_value = 0x552AB83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			demph_reg_value = 0x2B404040;
+			uniqtranscale_reg_value = 0x5548B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			demph_reg_value = 0x2B245555;
+			uniqtranscale_reg_value = 0x5560B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+			demph_reg_value = 0x2B405555;
+			uniqtranscale_reg_value = 0x5598DA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_1:
+		preemph_reg_value = 0x0002000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			demph_reg_value = 0x2B404040;
+			uniqtranscale_reg_value = 0x5552B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			demph_reg_value = 0x2B404848;
+			uniqtranscale_reg_value = 0x5580B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			demph_reg_value = 0x2B404040;
+			uniqtranscale_reg_value = 0x55ADDA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_2:
+		preemph_reg_value = 0x0000000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			demph_reg_value = 0x2B305555;
+			uniqtranscale_reg_value = 0x5570B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			demph_reg_value = 0x2B2B4040;
+			uniqtranscale_reg_value = 0x55ADDA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_3:
+		preemph_reg_value = 0x0006000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			demph_reg_value = 0x1B405555;
+			uniqtranscale_reg_value = 0x55ADDA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	default:
+		return 0;
+	}
+
+	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x00000000);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), demph_reg_value);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port),
+			 uniqtranscale_reg_value);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(port), 0x0C782040);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000);
+	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), preemph_reg_value);
+	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x80000000);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	return 0;
+}
+
+static bool chv_need_uniq_trans_scale(uint8_t train_set)
+{
+	return (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) == DP_TRAIN_PRE_EMPH_LEVEL_0 &&
+		(train_set & DP_TRAIN_VOLTAGE_SWING_MASK) == DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+}
+
+static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+	struct intel_crtc *intel_crtc = to_intel_crtc(dport->base.base.crtc);
+	u32 deemph_reg_value, margin_reg_value, val;
+	uint8_t train_set = intel_dp->train_set[0];
+	enum dpio_channel ch = vlv_dport_to_channel(dport);
+	enum pipe pipe = intel_crtc->pipe;
+	int i;
+
+	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
+	case DP_TRAIN_PRE_EMPH_LEVEL_0:
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			deemph_reg_value = 128;
+			margin_reg_value = 52;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			deemph_reg_value = 128;
+			margin_reg_value = 77;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			deemph_reg_value = 128;
+			margin_reg_value = 102;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+			deemph_reg_value = 128;
+			margin_reg_value = 154;
+			/* FIXME extra to set for 1200 */
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_1:
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			deemph_reg_value = 85;
+			margin_reg_value = 78;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			deemph_reg_value = 85;
+			margin_reg_value = 116;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+			deemph_reg_value = 85;
+			margin_reg_value = 154;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_2:
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			deemph_reg_value = 64;
+			margin_reg_value = 104;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+			deemph_reg_value = 64;
+			margin_reg_value = 154;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_3:
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+			deemph_reg_value = 43;
+			margin_reg_value = 154;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	default:
+		return 0;
+	}
+
+	mutex_lock(&dev_priv->sb_lock);
+
+	/* Clear calc init */
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
+	val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
+	val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
+	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) {
+		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);
+		val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
+	}
+
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch));
+	val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
+	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) {
+		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;
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val);
+	}
+
+	/* Program swing deemph */
+	for (i = 0; i < intel_crtc->config->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;
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW4(ch, i), val);
+	}
+
+	/* Program swing margin */
+	for (i = 0; i < intel_crtc->config->lane_count; i++) {
+		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
+
+		val &= ~DPIO_SWING_MARGIN000_MASK;
+		val |= margin_reg_value << DPIO_SWING_MARGIN000_SHIFT;
+
+		/*
+		 * Supposedly this value shouldn't matter when unique transition
+		 * scale is disabled, but in fact it does matter. Let's just
+		 * always program the same value and hope it's OK.
+		 */
+		val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT);
+		val |= 0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT;
+
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
+	}
+
+	/*
+	 * The document said it needs to set bit 27 for ch0 and bit 26
+	 * for ch1. Might be a typo in the doc.
+	 * 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++) {
+		val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
+		if (chv_need_uniq_trans_scale(train_set))
+			val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
+		else
+			val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
+		vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
+	}
+
+	/* Start swing calculation */
+	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
+	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) {
+		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);
+	}
+
+	mutex_unlock(&dev_priv->sb_lock);
+
+	return 0;
+}
+
+static uint32_t
+gen4_signal_levels(uint8_t train_set)
+{
+	uint32_t	signal_levels = 0;
+
+	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+	default:
+		signal_levels |= DP_VOLTAGE_0_4;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+		signal_levels |= DP_VOLTAGE_0_6;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+		signal_levels |= DP_VOLTAGE_0_8;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+		signal_levels |= DP_VOLTAGE_1_2;
+		break;
+	}
+	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
+	case DP_TRAIN_PRE_EMPH_LEVEL_0:
+	default:
+		signal_levels |= DP_PRE_EMPHASIS_0;
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_1:
+		signal_levels |= DP_PRE_EMPHASIS_3_5;
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_2:
+		signal_levels |= DP_PRE_EMPHASIS_6;
+		break;
+	case DP_TRAIN_PRE_EMPH_LEVEL_3:
+		signal_levels |= DP_PRE_EMPHASIS_9_5;
+		break;
+	}
+	return signal_levels;
+}
+
+/* Gen6's DP voltage swing and pre-emphasis control */
+static uint32_t
+gen6_edp_signal_levels(uint8_t train_set)
+{
+	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+					 DP_TRAIN_PRE_EMPHASIS_MASK);
+	switch (signal_levels) {
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
+	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_400_600MV_6DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
+	default:
+		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
+			      "0x%x\n", signal_levels);
+		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
+	}
+}
+
+/* Gen7's DP voltage swing and pre-emphasis control */
+static uint32_t
+gen7_edp_signal_levels(uint8_t train_set)
+{
+	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+					 DP_TRAIN_PRE_EMPHASIS_MASK);
+	switch (signal_levels) {
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_400MV_0DB_IVB;
+	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:
+		return EDP_LINK_TRAIN_400MV_6DB_IVB;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_600MV_0DB_IVB;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_600MV_3_5DB_IVB;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		return EDP_LINK_TRAIN_800MV_0DB_IVB;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		return EDP_LINK_TRAIN_800MV_3_5DB_IVB;
+
+	default:
+		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
+			      "0x%x\n", signal_levels);
+		return EDP_LINK_TRAIN_500MV_0DB_IVB;
+	}
+}
+
+void
+intel_dp_set_signal_levels(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	enum port port = intel_dig_port->port;
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	uint32_t signal_levels, mask = 0;
+	uint8_t train_set = intel_dp->train_set[0];
+
+	if (HAS_DDI(dev)) {
+		signal_levels = ddi_signal_levels(intel_dp);
+
+		if (IS_BROXTON(dev))
+			signal_levels = 0;
+		else
+			mask = DDI_BUF_EMP_MASK;
+	} else if (IS_CHERRYVIEW(dev)) {
+		signal_levels = chv_signal_levels(intel_dp);
+	} else if (IS_VALLEYVIEW(dev)) {
+		signal_levels = vlv_signal_levels(intel_dp);
+	} else if (IS_GEN7(dev) && port == PORT_A) {
+		signal_levels = gen7_edp_signal_levels(train_set);
+		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
+	} else if (IS_GEN6(dev) && port == PORT_A) {
+		signal_levels = gen6_edp_signal_levels(train_set);
+		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
+	} else {
+		signal_levels = gen4_signal_levels(train_set);
+		mask = DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK;
+	}
+
+	if (mask)
+		DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
+
+	DRM_DEBUG_KMS("Using vswing level %d\n",
+		train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+	DRM_DEBUG_KMS("Using pre-emphasis level %d\n",
+		(train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
+			DP_TRAIN_PRE_EMPHASIS_SHIFT);
+
+	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
+
+	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
+	POSTING_READ(intel_dp->output_reg);
+}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3021e40..d758e94 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -922,6 +922,13 @@ dp_to_dig_port(struct intel_dp *intel_dp)
 	return container_of(intel_dp, struct intel_digital_port, dp);
 }
 
+static inline struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+
+	return intel_dig_port->base.base.dev;
+}
+
 static inline struct intel_digital_port *
 hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
 {
-- 
2.4.3

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

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

* [PATCH 16/22] drm/i915: Introduce struct intel_dp_signal_levels
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (14 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 15/22] drm/i915: Split setting of vswing and pre_emph levels to separate file Ander Conselvan de Oliveira
@ 2015-10-23 10:01 ` Ander Conselvan de Oliveira
  2015-10-25  5:24   ` Thulasimani, Sivakumar
  2015-10-23 10:02 ` [PATCH 17/22] drm/i915: Use struct intel_dp_signal_levels for eDP on SNB and IVB Ander Conselvan de Oliveira
                   ` (5 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:01 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

In order to clarify which platforms support which combination of voltage
swing and pre emphasis level, introduce struct intel_dp_signal_levels.
With the new struct, the if ladder to determine the values used is put
in one place, intel_dp_init_signal_levels().

This also wires gens 4, 5 and non-eDP ports on gen 6 and 7 to use the
new struct.

v2: Rebase
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c               |   2 +
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 103 ++++++++++++++++++++++----
 drivers/gpu/drm/i915/intel_drv.h              |  11 +++
 3 files changed, 101 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 1236791..e640b59 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5220,6 +5220,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	if (HAS_DDI(dev))
 		intel_dp->prepare_link_retrain = intel_ddi_prepare_link_retrain;
 
+	intel_dp_init_signal_levels(intel_dp);
+
 	/* Preserve the current hw state. */
 	intel_dp->DP = I915_READ(intel_dp->output_reg);
 	intel_dp->attached_connector = intel_connector;
diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index e516dd2..365bdc4 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -24,8 +24,8 @@
 #include "intel_drv.h"
 
 /* These are source-specific values. */
-uint8_t
-intel_dp_voltage_max(struct intel_dp *intel_dp)
+static uint8_t
+_dp_voltage_max(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -47,8 +47,8 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
 		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
 }
 
-uint8_t
-intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
+static uint8_t
+_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	enum port port = dp_to_dig_port(intel_dp)->port;
@@ -389,10 +389,10 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
 	return 0;
 }
 
-static uint32_t
-gen4_signal_levels(uint8_t train_set)
+static void
+gen4_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
-	uint32_t	signal_levels = 0;
+	uint32_t signal_levels = 0;
 
 	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
@@ -424,9 +424,38 @@ gen4_signal_levels(uint8_t train_set)
 		signal_levels |= DP_PRE_EMPHASIS_9_5;
 		break;
 	}
-	return signal_levels;
+
+	DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
+
+	intel_dp->DP &= ~(DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK);
+	intel_dp->DP |= signal_levels;
 }
 
+static const struct signal_levels gen4_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_2,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = gen4_set_signal_levels,
+};
+
+/* Not for eDP */
+static const struct signal_levels snb_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = gen4_set_signal_levels,
+};
+
 /* Gen6's DP voltage swing and pre-emphasis control */
 static uint32_t
 gen6_edp_signal_levels(uint8_t train_set)
@@ -486,13 +515,12 @@ gen7_edp_signal_levels(uint8_t train_set)
 	}
 }
 
-void
-intel_dp_set_signal_levels(struct intel_dp *intel_dp)
+static void
+_update_signal_levels(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
 	struct drm_device *dev = intel_dig_port->base.base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
 	uint32_t signal_levels, mask = 0;
 	uint8_t train_set = intel_dp->train_set[0];
 
@@ -514,21 +542,66 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
 		signal_levels = gen6_edp_signal_levels(train_set);
 		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
 	} else {
-		signal_levels = gen4_signal_levels(train_set);
-		mask = DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK;
+		WARN(1, "Should be calling intel_dp->signal_levels->set instead.");
+		return;
 	}
 
 	if (mask)
 		DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
 
+	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
+}
+
+uint8_t
+intel_dp_voltage_max(struct intel_dp *intel_dp)
+{
+	if (intel_dp->signal_levels)
+		return intel_dp->signal_levels->max_voltage;
+	else
+		return _dp_voltage_max(intel_dp);
+}
+
+uint8_t
+intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
+{
+	if (intel_dp->signal_levels)
+		return intel_dp->signal_levels->max_pre_emph[voltage_swing];
+	else
+		return _dp_pre_emphasis_max(intel_dp, voltage_swing);
+}
+
+void
+intel_dp_set_signal_levels(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	uint8_t train_set = intel_dp->train_set[0];
+
+	if (intel_dp->signal_levels)
+		intel_dp->signal_levels->set(intel_dp, train_set);
+	else
+		_update_signal_levels(intel_dp);
+
 	DRM_DEBUG_KMS("Using vswing level %d\n",
 		train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
 	DRM_DEBUG_KMS("Using pre-emphasis level %d\n",
 		(train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
 			DP_TRAIN_PRE_EMPHASIS_SHIFT);
 
-	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
-
 	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
 	POSTING_READ(intel_dp->output_reg);
 }
+
+void
+intel_dp_init_signal_levels(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	enum port port = intel_dig_port->port;
+
+	if (port != PORT_A && (IS_IVYBRIDGE(dev) || IS_GEN6(dev)))
+		intel_dp->signal_levels = &snb_signal_levels;
+
+	if (INTEL_INFO(dev)->gen <= 5)
+		intel_dp->signal_levels = &gen4_signal_levels;
+}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d758e94..e00ce6c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -726,6 +726,14 @@ struct sink_crc {
 	int last_count;
 };
 
+struct intel_dp;
+struct signal_levels {
+	uint8_t max_voltage;
+	uint8_t max_pre_emph[4];
+
+	void (*set)(struct intel_dp *intel_dp, uint8_t train_set);
+};
+
 struct intel_dp {
 	uint32_t output_reg;
 	uint32_t aux_ch_ctl_reg;
@@ -744,6 +752,7 @@ struct intel_dp {
 	int sink_rates[DP_MAX_SUPPORTED_RATES];
 	struct sink_crc sink_crc;
 	struct drm_dp_aux aux;
+	const struct signal_levels *signal_levels;
 	uint8_t train_set[4];
 	int panel_power_up_delay;
 	int panel_power_down_delay;
@@ -1263,6 +1272,8 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
 bool
 intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]);
 
+void intel_dp_init_signal_levels(struct intel_dp *intel_dp);
+
 /* intel_dp_mst.c */
 int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
 void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
-- 
2.4.3

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

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

* [PATCH 17/22] drm/i915: Use struct intel_dp_signal_levels for eDP on SNB and IVB
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (15 preceding siblings ...)
  2015-10-23 10:01 ` [PATCH 16/22] drm/i915: Introduce struct intel_dp_signal_levels Ander Conselvan de Oliveira
@ 2015-10-23 10:02 ` Ander Conselvan de Oliveira
  2015-10-23 10:02 ` [PATCH 18/22] drm/i915: Use struct intel_dp_signal_levels for VLV Ander Conselvan de Oliveira
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:02 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Use the new struct intel_dp_signal_levels to store voltage swing and pre
emphasis levels for eDP on SNB and IVB.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 132 ++++++++++++++++++--------
 1 file changed, 91 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index 365bdc4..aedd35b 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -443,7 +443,6 @@ static const struct signal_levels gen4_signal_levels = {
 	.set = gen4_set_signal_levels,
 };
 
-/* Not for eDP */
 static const struct signal_levels snb_signal_levels = {
 	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
 	.max_pre_emph = {
@@ -456,73 +455,123 @@ static const struct signal_levels snb_signal_levels = {
 	.set = gen4_set_signal_levels,
 };
 
-/* Gen6's DP voltage swing and pre-emphasis control */
-static uint32_t
-gen6_edp_signal_levels(uint8_t train_set)
+/* SNB's DP voltage swing and pre-emphasis control */
+static void
+snb_edp_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
-	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-					 DP_TRAIN_PRE_EMPHASIS_MASK);
-	switch (signal_levels) {
+	uint32_t signal_levels;
+
+	train_set &=
+		(DP_TRAIN_VOLTAGE_SWING_MASK | DP_TRAIN_PRE_EMPHASIS_MASK);
+
+	switch (train_set) {
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
+		signal_levels =  EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
+		signal_levels = EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
+		break;
 	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_400_600MV_6DB_SNB_B;
+		signal_levels = EDP_LINK_TRAIN_400_600MV_6DB_SNB_B;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
+		signal_levels = EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
+		signal_levels = EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
+		break;
 	default:
 		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
-			      "0x%x\n", signal_levels);
-		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
+			      "0x%x\n", train_set);
+		signal_levels = EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
 	}
+
+	DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
+
+	intel_dp->DP &= ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
+	intel_dp->DP |= signal_levels;
 }
 
-/* Gen7's DP voltage swing and pre-emphasis control */
-static uint32_t
-gen7_edp_signal_levels(uint8_t train_set)
+static const struct signal_levels snb_edp_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_2,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = snb_edp_set_signal_levels,
+};
+
+/* IVB's DP voltage swing and pre-emphasis control */
+static void
+ivb_edp_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
-	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-					 DP_TRAIN_PRE_EMPHASIS_MASK);
-	switch (signal_levels) {
+	uint32_t signal_levels;
+
+	train_set &=
+		(DP_TRAIN_VOLTAGE_SWING_MASK | DP_TRAIN_PRE_EMPHASIS_MASK);
+
+	switch (train_set) {
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_400MV_0DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_400MV_0DB_IVB;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_400MV_3_5DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_400MV_3_5DB_IVB;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-		return EDP_LINK_TRAIN_400MV_6DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_400MV_6DB_IVB;
+		break;
 
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_600MV_0DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_600MV_0DB_IVB;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_600MV_3_5DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_600MV_3_5DB_IVB;
+		break;
 
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		return EDP_LINK_TRAIN_800MV_0DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_800MV_0DB_IVB;
+		break;
 	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		return EDP_LINK_TRAIN_800MV_3_5DB_IVB;
+		signal_levels = EDP_LINK_TRAIN_800MV_3_5DB_IVB;
+		break;
 
 	default:
 		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
-			      "0x%x\n", signal_levels);
-		return EDP_LINK_TRAIN_500MV_0DB_IVB;
+			      "0x%x\n", train_set);
+		signal_levels = EDP_LINK_TRAIN_500MV_0DB_IVB;
 	}
+
+	DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
+
+	intel_dp->DP &= ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
+	intel_dp->DP |= signal_levels;
 }
 
+static const struct signal_levels ivb_edp_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_2,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = ivb_edp_set_signal_levels,
+};
+
 static void
 _update_signal_levels(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	enum port port = intel_dig_port->port;
 	struct drm_device *dev = intel_dig_port->base.base.dev;
 	uint32_t signal_levels, mask = 0;
-	uint8_t train_set = intel_dp->train_set[0];
 
 	if (HAS_DDI(dev)) {
 		signal_levels = ddi_signal_levels(intel_dp);
@@ -535,12 +584,6 @@ _update_signal_levels(struct intel_dp *intel_dp)
 		signal_levels = chv_signal_levels(intel_dp);
 	} else if (IS_VALLEYVIEW(dev)) {
 		signal_levels = vlv_signal_levels(intel_dp);
-	} else if (IS_GEN7(dev) && port == PORT_A) {
-		signal_levels = gen7_edp_signal_levels(train_set);
-		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
-	} else if (IS_GEN6(dev) && port == PORT_A) {
-		signal_levels = gen6_edp_signal_levels(train_set);
-		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
 	} else {
 		WARN(1, "Should be calling intel_dp->signal_levels->set instead.");
 		return;
@@ -599,9 +642,16 @@ intel_dp_init_signal_levels(struct intel_dp *intel_dp)
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
 
-	if (port != PORT_A && (IS_IVYBRIDGE(dev) || IS_GEN6(dev)))
-		intel_dp->signal_levels = &snb_signal_levels;
-
-	if (INTEL_INFO(dev)->gen <= 5)
+	if (IS_IVYBRIDGE(dev)) {
+		if (port == PORT_A)
+			intel_dp->signal_levels = &ivb_edp_signal_levels;
+		else
+			intel_dp->signal_levels = &snb_signal_levels;
+	} else if (IS_GEN6(dev)) {
+		if (port == PORT_A)
+			intel_dp->signal_levels = &snb_edp_signal_levels;
+		else
+			intel_dp->signal_levels = &snb_signal_levels;
+	} else if (INTEL_INFO(dev)->gen <= 5)
 		intel_dp->signal_levels = &gen4_signal_levels;
 }
-- 
2.4.3

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

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

* [PATCH 18/22] drm/i915: Use struct intel_dp_signal_levels for VLV
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (16 preceding siblings ...)
  2015-10-23 10:02 ` [PATCH 17/22] drm/i915: Use struct intel_dp_signal_levels for eDP on SNB and IVB Ander Conselvan de Oliveira
@ 2015-10-23 10:02 ` Ander Conselvan de Oliveira
  2015-10-23 10:02 ` [PATCH 19/22] drm/i915: Use struct intel_dp_signal_levels for CHV Ander Conselvan de Oliveira
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:02 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Use the new struct intel_dp_signal_levels to store voltage swing and pre
emphasis levels for VLV.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 38 ++++++++++++++++++---------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index aedd35b..1d07f46 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -115,7 +115,7 @@ _dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 	}
 }
 
-static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
+static void vlv_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -124,7 +124,6 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
 		to_intel_crtc(dport->base.base.crtc);
 	unsigned long demph_reg_value, preemph_reg_value,
 		uniqtranscale_reg_value;
-	uint8_t train_set = intel_dp->train_set[0];
 	enum dpio_channel port = vlv_dport_to_channel(dport);
 	int pipe = intel_crtc->pipe;
 
@@ -149,7 +148,8 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
 			uniqtranscale_reg_value = 0x5598DA3A;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	case DP_TRAIN_PRE_EMPH_LEVEL_1:
@@ -168,7 +168,8 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
 			uniqtranscale_reg_value = 0x55ADDA3A;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	case DP_TRAIN_PRE_EMPH_LEVEL_2:
@@ -183,7 +184,8 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
 			uniqtranscale_reg_value = 0x55ADDA3A;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	case DP_TRAIN_PRE_EMPH_LEVEL_3:
@@ -194,11 +196,13 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
 			uniqtranscale_reg_value = 0x55ADDA3A;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	default:
-		return 0;
+		MISSING_CASE(train_set & DP_TRAIN_PRE_EMPHASIS_MASK);
+		return;
 	}
 
 	mutex_lock(&dev_priv->sb_lock);
@@ -211,10 +215,20 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), preemph_reg_value);
 	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x80000000);
 	mutex_unlock(&dev_priv->sb_lock);
-
-	return 0;
 }
 
+static const struct signal_levels vlv_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_3,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = vlv_set_signal_levels,
+};
+
 static bool chv_need_uniq_trans_scale(uint8_t train_set)
 {
 	return (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) == DP_TRAIN_PRE_EMPH_LEVEL_0 &&
@@ -582,8 +596,6 @@ _update_signal_levels(struct intel_dp *intel_dp)
 			mask = DDI_BUF_EMP_MASK;
 	} else if (IS_CHERRYVIEW(dev)) {
 		signal_levels = chv_signal_levels(intel_dp);
-	} else if (IS_VALLEYVIEW(dev)) {
-		signal_levels = vlv_signal_levels(intel_dp);
 	} else {
 		WARN(1, "Should be calling intel_dp->signal_levels->set instead.");
 		return;
@@ -642,7 +654,9 @@ intel_dp_init_signal_levels(struct intel_dp *intel_dp)
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
 
-	if (IS_IVYBRIDGE(dev)) {
+	if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
+		intel_dp->signal_levels = &vlv_signal_levels;
+	} else if (IS_IVYBRIDGE(dev)) {
 		if (port == PORT_A)
 			intel_dp->signal_levels = &ivb_edp_signal_levels;
 		else
-- 
2.4.3

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

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

* [PATCH 19/22] drm/i915: Use struct intel_dp_signal_levels for CHV
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (17 preceding siblings ...)
  2015-10-23 10:02 ` [PATCH 18/22] drm/i915: Use struct intel_dp_signal_levels for VLV Ander Conselvan de Oliveira
@ 2015-10-23 10:02 ` Ander Conselvan de Oliveira
  2015-10-23 10:02 ` [PATCH 20/22] drm/i915: Use struct intel_dp_signal_levels for DDI platforms Ander Conselvan de Oliveira
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:02 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Use the new struct intel_dp_signal_levels to store voltage swing and pre
emphasis levels for CHV.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 38 ++++++++++++++++++---------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index 1d07f46..3f396b1 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -235,14 +235,13 @@ static bool chv_need_uniq_trans_scale(uint8_t train_set)
 		(train_set & DP_TRAIN_VOLTAGE_SWING_MASK) == DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
 }
 
-static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
+static void chv_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
 	struct intel_crtc *intel_crtc = to_intel_crtc(dport->base.base.crtc);
 	u32 deemph_reg_value, margin_reg_value, val;
-	uint8_t train_set = intel_dp->train_set[0];
 	enum dpio_channel ch = vlv_dport_to_channel(dport);
 	enum pipe pipe = intel_crtc->pipe;
 	int i;
@@ -268,7 +267,8 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
 			/* FIXME extra to set for 1200 */
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	case DP_TRAIN_PRE_EMPH_LEVEL_1:
@@ -286,7 +286,8 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
 			margin_reg_value = 154;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	case DP_TRAIN_PRE_EMPH_LEVEL_2:
@@ -300,7 +301,8 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
 			margin_reg_value = 154;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	case DP_TRAIN_PRE_EMPH_LEVEL_3:
@@ -310,11 +312,13 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
 			margin_reg_value = 154;
 			break;
 		default:
-			return 0;
+			MISSING_CASE(train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
+			return;
 		}
 		break;
 	default:
-		return 0;
+		MISSING_CASE(train_set & DP_TRAIN_PRE_EMPHASIS_MASK);
+		return;
 	}
 
 	mutex_lock(&dev_priv->sb_lock);
@@ -399,10 +403,20 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
 	}
 
 	mutex_unlock(&dev_priv->sb_lock);
-
-	return 0;
 }
 
+static const struct signal_levels chv_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_3,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = chv_set_signal_levels,
+};
+
 static void
 gen4_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
@@ -594,8 +608,6 @@ _update_signal_levels(struct intel_dp *intel_dp)
 			signal_levels = 0;
 		else
 			mask = DDI_BUF_EMP_MASK;
-	} else if (IS_CHERRYVIEW(dev)) {
-		signal_levels = chv_signal_levels(intel_dp);
 	} else {
 		WARN(1, "Should be calling intel_dp->signal_levels->set instead.");
 		return;
@@ -654,7 +666,9 @@ intel_dp_init_signal_levels(struct intel_dp *intel_dp)
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
 
-	if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
+	if (IS_CHERRYVIEW(dev)) {
+		intel_dp->signal_levels = &chv_signal_levels;
+	} else if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
 		intel_dp->signal_levels = &vlv_signal_levels;
 	} else if (IS_IVYBRIDGE(dev)) {
 		if (port == PORT_A)
-- 
2.4.3

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

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

* [PATCH 20/22] drm/i915: Use struct intel_dp_signal_levels for DDI platforms
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (18 preceding siblings ...)
  2015-10-23 10:02 ` [PATCH 19/22] drm/i915: Use struct intel_dp_signal_levels for CHV Ander Conselvan de Oliveira
@ 2015-10-23 10:02 ` Ander Conselvan de Oliveira
  2015-10-23 10:02 ` [PATCH 21/22] drm/i915: Remove old functions for maximum DP vswing and pre-emph levels Ander Conselvan de Oliveira
  2015-10-23 10:02 ` [PATCH 22/22] drm/i915: Move ddi_signal_levels() to intel_dp_signal_levels.c Ander Conselvan de Oliveira
  21 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:02 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Use the new struct intel_dp_signal_levels to store voltage swing and pre
emphasis levels for DDI platforms.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 63 ++++++++++++++++++++++++++-
 1 file changed, 62 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index 3f396b1..d1eccd7 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -115,6 +115,59 @@ _dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 	}
 }
 
+static void
+hsw_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
+{
+	uint32_t signal_levels = ddi_signal_levels(intel_dp);
+
+	DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
+
+	intel_dp->DP &= ~DDI_BUF_EMP_MASK;
+	intel_dp->DP |= signal_levels;
+}
+
+static const struct signal_levels hsw_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_2,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_3,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = hsw_set_signal_levels,
+};
+
+static const struct signal_levels skl_edp_low_vswing_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_3,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = hsw_set_signal_levels,
+};
+
+static void
+bxt_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
+{
+	ddi_signal_levels(intel_dp);
+}
+
+static const struct signal_levels bxt_signal_levels = {
+	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
+	.max_pre_emph = {
+		DP_TRAIN_PRE_EMPH_LEVEL_3,
+		DP_TRAIN_PRE_EMPH_LEVEL_2,
+		DP_TRAIN_PRE_EMPH_LEVEL_1,
+		DP_TRAIN_PRE_EMPH_LEVEL_0,
+	},
+
+	.set = bxt_set_signal_levels,
+};
+
 static void vlv_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
@@ -663,10 +716,18 @@ void
 intel_dp_init_signal_levels(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
 
-	if (IS_CHERRYVIEW(dev)) {
+	if (IS_BROXTON(dev)) {
+		intel_dp->signal_levels = &bxt_signal_levels;
+	} else if (IS_SKYLAKE(dev) &&
+		   port == PORT_A && dev_priv->edp_low_vswing) {
+		intel_dp->signal_levels = &skl_edp_low_vswing_signal_levels;
+	} else if (HAS_DDI(dev)) {
+		intel_dp->signal_levels = &hsw_signal_levels;
+	} else if (IS_CHERRYVIEW(dev)) {
 		intel_dp->signal_levels = &chv_signal_levels;
 	} else if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
 		intel_dp->signal_levels = &vlv_signal_levels;
-- 
2.4.3

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

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

* [PATCH 21/22] drm/i915: Remove old functions for maximum DP vswing and pre-emph levels
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (19 preceding siblings ...)
  2015-10-23 10:02 ` [PATCH 20/22] drm/i915: Use struct intel_dp_signal_levels for DDI platforms Ander Conselvan de Oliveira
@ 2015-10-23 10:02 ` Ander Conselvan de Oliveira
  2015-10-23 10:02 ` [PATCH 22/22] drm/i915: Move ddi_signal_levels() to intel_dp_signal_levels.c Ander Conselvan de Oliveira
  21 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:02 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

Remove the old functions for maximum DP voltage swing and pre-emphasis
levels, now that all platforms use the new intel_dp_signal_values
struct.

v2: Rebase
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 132 +-------------------------
 1 file changed, 3 insertions(+), 129 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index d1eccd7..a972d86 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -23,98 +23,6 @@
 
 #include "intel_drv.h"
 
-/* These are source-specific values. */
-static uint8_t
-_dp_voltage_max(struct intel_dp *intel_dp)
-{
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	enum port port = dp_to_dig_port(intel_dp)->port;
-
-	if (IS_BROXTON(dev))
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else if (INTEL_INFO(dev)->gen >= 9) {
-		if (dev_priv->edp_low_vswing && port == PORT_A)
-			return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-	} else if (IS_VALLEYVIEW(dev))
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else if (IS_GEN7(dev) && port == PORT_A)
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-	else if (HAS_PCH_CPT(dev) && port != PORT_A)
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-	else
-		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
-}
-
-static uint8_t
-_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
-{
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	enum port port = dp_to_dig_port(intel_dp)->port;
-
-	if (INTEL_INFO(dev)->gen >= 9) {
-		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:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		default:
-			return DP_TRAIN_PRE_EMPH_LEVEL_0;
-		}
-	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
-		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 if (IS_VALLEYVIEW(dev)) {
-		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 if (IS_GEN7(dev) && 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:
-			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 void
 hsw_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
@@ -647,47 +555,16 @@ static const struct signal_levels ivb_edp_signal_levels = {
 	.set = ivb_edp_set_signal_levels,
 };
 
-static void
-_update_signal_levels(struct intel_dp *intel_dp)
-{
-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = intel_dig_port->base.base.dev;
-	uint32_t signal_levels, mask = 0;
-
-	if (HAS_DDI(dev)) {
-		signal_levels = ddi_signal_levels(intel_dp);
-
-		if (IS_BROXTON(dev))
-			signal_levels = 0;
-		else
-			mask = DDI_BUF_EMP_MASK;
-	} else {
-		WARN(1, "Should be calling intel_dp->signal_levels->set instead.");
-		return;
-	}
-
-	if (mask)
-		DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
-
-	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
-}
-
 uint8_t
 intel_dp_voltage_max(struct intel_dp *intel_dp)
 {
-	if (intel_dp->signal_levels)
-		return intel_dp->signal_levels->max_voltage;
-	else
-		return _dp_voltage_max(intel_dp);
+	return intel_dp->signal_levels->max_voltage;
 }
 
 uint8_t
 intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 {
-	if (intel_dp->signal_levels)
-		return intel_dp->signal_levels->max_pre_emph[voltage_swing];
-	else
-		return _dp_pre_emphasis_max(intel_dp, voltage_swing);
+	return intel_dp->signal_levels->max_pre_emph[voltage_swing];
 }
 
 void
@@ -697,10 +574,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	uint8_t train_set = intel_dp->train_set[0];
 
-	if (intel_dp->signal_levels)
-		intel_dp->signal_levels->set(intel_dp, train_set);
-	else
-		_update_signal_levels(intel_dp);
+	intel_dp->signal_levels->set(intel_dp, train_set);
 
 	DRM_DEBUG_KMS("Using vswing level %d\n",
 		train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
-- 
2.4.3

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

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

* [PATCH 22/22] drm/i915: Move ddi_signal_levels() to intel_dp_signal_levels.c
  2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
                   ` (20 preceding siblings ...)
  2015-10-23 10:02 ` [PATCH 21/22] drm/i915: Remove old functions for maximum DP vswing and pre-emph levels Ander Conselvan de Oliveira
@ 2015-10-23 10:02 ` Ander Conselvan de Oliveira
  21 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-10-23 10:02 UTC (permalink / raw)
  To: intel-gfx, jim.bride, sivakumar.thulasimani; +Cc: Ander Conselvan de Oliveira

The logic for writing the DP register based on the vswing and pre emph
values is in that file for all other platforms, so follow suit and move
ddi_signal_levels() to intel_dp_signal_levels.c too.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c              | 78 ++-------------------------
 drivers/gpu/drm/i915/intel_dp_signal_levels.c | 73 ++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_drv.h              |  6 ++-
 3 files changed, 80 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 80843d9..2b91ac6 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -301,9 +301,6 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
 	{ 154, 0x9A, 1, 128, true },	/* 9:	1200		0   */
 };
 
-static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
-				    enum port port, int type);
-
 static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
 				 struct intel_digital_port **dig_port,
 				 enum port *port)
@@ -2066,8 +2063,8 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
 			   TRANS_CLK_SEL_DISABLED);
 }
 
-static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
-			       enum port port, int type)
+void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
+			enum port port, int type)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	const struct ddi_buf_trans *ddi_translations;
@@ -2123,8 +2120,8 @@ static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
 	I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
 }
 
-static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
-				    enum port port, int type)
+void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
+			     enum port port, int type)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	const struct bxt_ddi_buf_trans *ddi_translations;
@@ -2192,73 +2189,6 @@ static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
 	I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
 }
 
-static uint32_t translate_signal_level(int signal_levels)
-{
-	uint32_t level;
-
-	switch (signal_levels) {
-	default:
-		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
-			      signal_levels);
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		level = 0;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		level = 1;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-		level = 2;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
-		level = 3;
-		break;
-
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		level = 4;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		level = 5;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
-		level = 6;
-		break;
-
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		level = 7;
-		break;
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
-		level = 8;
-		break;
-
-	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
-		level = 9;
-		break;
-	}
-
-	return level;
-}
-
-uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
-{
-	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = dport->base.base.dev;
-	struct intel_encoder *encoder = &dport->base;
-	uint8_t train_set = intel_dp->train_set[0];
-	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-					 DP_TRAIN_PRE_EMPHASIS_MASK);
-	enum port port = dport->port;
-	uint32_t level;
-
-	level = translate_signal_level(signal_levels);
-
-	if (IS_SKYLAKE(dev))
-		skl_ddi_set_iboost(dev, level, port, encoder->type);
-	else if (IS_BROXTON(dev))
-		bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
-
-	return DDI_BUF_TRANS_SELECT(level);
-}
-
 static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
index a972d86..e8d11f4 100644
--- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
+++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
@@ -23,10 +23,72 @@
 
 #include "intel_drv.h"
 
+static uint32_t ddi_translate_signal_level(uint8_t train_set)
+{
+	uint32_t level;
+
+	train_set &=
+		(DP_TRAIN_VOLTAGE_SWING_MASK | DP_TRAIN_PRE_EMPHASIS_MASK);
+
+	switch (train_set) {
+	default:
+		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
+			      train_set);
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		level = 0;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		level = 1;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
+		level = 2;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
+		level = 3;
+		break;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		level = 4;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		level = 5;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
+		level = 6;
+		break;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		level = 7;
+		break;
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
+		level = 8;
+		break;
+
+	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
+		level = 9;
+		break;
+	}
+
+	return level;
+}
+
 static void
 hsw_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
-	uint32_t signal_levels = ddi_signal_levels(intel_dp);
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	uint32_t ddi_level, signal_levels;
+
+	ddi_level = ddi_translate_signal_level(train_set);
+
+	if (IS_SKYLAKE(dev)) {
+		struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+		struct intel_encoder *encoder = &dport->base;
+		enum port port = dport->port;
+
+		skl_ddi_set_iboost(dev, ddi_level, port, encoder->type);
+	}
+
+	signal_levels = DDI_BUF_TRANS_SELECT(ddi_level);
 
 	DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
 
@@ -61,7 +123,14 @@ static const struct signal_levels skl_edp_low_vswing_signal_levels = {
 static void
 bxt_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
 {
-	ddi_signal_levels(intel_dp);
+	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dport->base.base.dev;
+	struct intel_encoder *encoder = &dport->base;
+	enum port port = dport->port;
+	uint32_t level;
+
+	level = ddi_translate_signal_level(train_set);
+	bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
 }
 
 static const struct signal_levels bxt_signal_levels = {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e00ce6c..6f33a8b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1020,7 +1020,11 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
 void intel_ddi_clock_get(struct intel_encoder *encoder,
 			 struct intel_crtc_state *pipe_config);
 void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
-uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
+
+void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
+			enum port port, int type);
+void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
+			     enum port port, int type);
 
 /* intel_frontbuffer.c */
 void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
-- 
2.4.3

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

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

* Re: [PATCH 01/22] drm/i915: Don't pass *DP around to link training functions
  2015-10-23 10:01 ` [PATCH 01/22] drm/i915: Don't pass *DP around to link training functions Ander Conselvan de Oliveira
@ 2015-10-25  2:01   ` Thulasimani, Sivakumar
  0 siblings, 0 replies; 34+ messages in thread
From: Thulasimani, Sivakumar @ 2015-10-25  2:01 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx, jim.bride

Thanks for making the changes suggested :)

Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>

On 10/23/2015 3:31 PM, Ander Conselvan de Oliveira wrote:
> It just makes the code more confusing, so just reference intel_dp_>DP
> directly.
>
> Note that this also fix a bug where the value of intel_dp->DP could be
> different than the last value written to the hw, due to an early return
> that would skip the 'intel_dp->DP = DP' line.
>
> v2: Don't preserve old DP value on failure. (Sivakumar)
>    - Don't call drm_dp_clock_recovery_ok() twice. (Sivakumar)
>    - Keep return type of clock recovery and channel equalization
>      functions as void. (Ander)
>
> v3: Remove DP parameter from intel_dp_set_signal_levels(). (Sivakumar)
>
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> ---
>   drivers/gpu/drm/i915/intel_dp.c | 47 ++++++++++++++++++-----------------------
>   1 file changed, 20 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 8287df4..648300e 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3552,7 +3552,7 @@ gen7_edp_signal_levels(uint8_t train_set)
>   
>   /* Properly updates "DP" with the correct signal levels. */
>   static void
> -intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
> +intel_dp_set_signal_levels(struct intel_dp *intel_dp)
>   {
>   	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>   	enum port port = intel_dig_port->port;
> @@ -3591,12 +3591,11 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
>   		(train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
>   			DP_TRAIN_PRE_EMPHASIS_SHIFT);
>   
> -	*DP = (*DP & ~mask) | signal_levels;
> +	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
>   }
>   
>   static bool
>   intel_dp_set_link_train(struct intel_dp *intel_dp,
> -			uint32_t *DP,
>   			uint8_t dp_train_pat)
>   {
>   	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> @@ -3605,9 +3604,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
>   	uint8_t buf[sizeof(intel_dp->train_set) + 1];
>   	int ret, len;
>   
> -	_intel_dp_set_link_train(intel_dp, DP, dp_train_pat);
> +	_intel_dp_set_link_train(intel_dp, &intel_dp->DP, dp_train_pat);
>   
> -	I915_WRITE(intel_dp->output_reg, *DP);
> +	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
>   	POSTING_READ(intel_dp->output_reg);
>   
>   	buf[0] = dp_train_pat;
> @@ -3628,17 +3627,17 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
>   }
>   
>   static bool
> -intel_dp_reset_link_train(struct intel_dp *intel_dp, uint32_t *DP,
> +intel_dp_reset_link_train(struct intel_dp *intel_dp,
>   			uint8_t dp_train_pat)
>   {
>   	if (!intel_dp->train_set_valid)
>   		memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
> -	intel_dp_set_signal_levels(intel_dp, DP);
> -	return intel_dp_set_link_train(intel_dp, DP, dp_train_pat);
> +	intel_dp_set_signal_levels(intel_dp);
> +	return intel_dp_set_link_train(intel_dp, dp_train_pat);
>   }
>   
>   static bool
> -intel_dp_update_link_train(struct intel_dp *intel_dp, uint32_t *DP,
> +intel_dp_update_link_train(struct intel_dp *intel_dp,
>   			   const uint8_t link_status[DP_LINK_STATUS_SIZE])
>   {
>   	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> @@ -3647,9 +3646,9 @@ intel_dp_update_link_train(struct intel_dp *intel_dp, uint32_t *DP,
>   	int ret;
>   
>   	intel_get_adjust_train(intel_dp, link_status);
> -	intel_dp_set_signal_levels(intel_dp, DP);
> +	intel_dp_set_signal_levels(intel_dp);
>   
> -	I915_WRITE(intel_dp->output_reg, *DP);
> +	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
>   	POSTING_READ(intel_dp->output_reg);
>   
>   	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
> @@ -3698,7 +3697,6 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
>   	int i;
>   	uint8_t voltage;
>   	int voltage_tries, loop_tries;
> -	uint32_t DP = intel_dp->DP;
>   	uint8_t link_config[2];
>   	uint8_t link_bw, rate_select;
>   
> @@ -3722,10 +3720,10 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
>   	link_config[1] = DP_SET_ANSI_8B10B;
>   	drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
>   
> -	DP |= DP_PORT_EN;
> +	intel_dp->DP |= DP_PORT_EN;
>   
>   	/* clock recovery */
> -	if (!intel_dp_reset_link_train(intel_dp, &DP,
> +	if (!intel_dp_reset_link_train(intel_dp,
>   				       DP_TRAINING_PATTERN_1 |
>   				       DP_LINK_SCRAMBLING_DISABLE)) {
>   		DRM_ERROR("failed to enable link training\n");
> @@ -3757,7 +3755,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
>   			DRM_DEBUG_KMS("clock recovery not ok, reset");
>   			/* clear the flag as we are not reusing train set */
>   			intel_dp->train_set_valid = false;
> -			if (!intel_dp_reset_link_train(intel_dp, &DP,
> +			if (!intel_dp_reset_link_train(intel_dp,
>   						       DP_TRAINING_PATTERN_1 |
>   						       DP_LINK_SCRAMBLING_DISABLE)) {
>   				DRM_ERROR("failed to enable link training\n");
> @@ -3776,7 +3774,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
>   				DRM_ERROR("too many full retries, give up\n");
>   				break;
>   			}
> -			intel_dp_reset_link_train(intel_dp, &DP,
> +			intel_dp_reset_link_train(intel_dp,
>   						  DP_TRAINING_PATTERN_1 |
>   						  DP_LINK_SCRAMBLING_DISABLE);
>   			voltage_tries = 0;
> @@ -3795,13 +3793,11 @@ 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 */
> -		if (!intel_dp_update_link_train(intel_dp, &DP, link_status)) {
> +		if (!intel_dp_update_link_train(intel_dp, link_status)) {
>   			DRM_ERROR("failed to update link training\n");
>   			break;
>   		}
>   	}
> -
> -	intel_dp->DP = DP;
>   }
>   
>   static void
> @@ -3811,7 +3807,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>   	struct drm_device *dev = dig_port->base.base.dev;
>   	bool channel_eq = false;
>   	int tries, cr_tries;
> -	uint32_t DP = intel_dp->DP;
>   	uint32_t training_pattern = DP_TRAINING_PATTERN_2;
>   
>   	/*
> @@ -3830,7 +3825,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>   		DRM_ERROR("5.4 Gbps link rate without HBR2/TPS3 support\n");
>   
>   	/* channel equalization */
> -	if (!intel_dp_set_link_train(intel_dp, &DP,
> +	if (!intel_dp_set_link_train(intel_dp,
>   				     training_pattern |
>   				     DP_LINK_SCRAMBLING_DISABLE)) {
>   		DRM_ERROR("failed to start channel equalization\n");
> @@ -3859,7 +3854,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>   					      intel_dp->lane_count)) {
>   			intel_dp->train_set_valid = false;
>   			intel_dp_link_training_clock_recovery(intel_dp);
> -			intel_dp_set_link_train(intel_dp, &DP,
> +			intel_dp_set_link_train(intel_dp,
>   						training_pattern |
>   						DP_LINK_SCRAMBLING_DISABLE);
>   			cr_tries++;
> @@ -3876,7 +3871,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>   		if (tries > 5) {
>   			intel_dp->train_set_valid = false;
>   			intel_dp_link_training_clock_recovery(intel_dp);
> -			intel_dp_set_link_train(intel_dp, &DP,
> +			intel_dp_set_link_train(intel_dp,
>   						training_pattern |
>   						DP_LINK_SCRAMBLING_DISABLE);
>   			tries = 0;
> @@ -3885,7 +3880,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>   		}
>   
>   		/* Update training set as requested by target */
> -		if (!intel_dp_update_link_train(intel_dp, &DP, link_status)) {
> +		if (!intel_dp_update_link_train(intel_dp, link_status)) {
>   			DRM_ERROR("failed to update link training\n");
>   			break;
>   		}
> @@ -3894,8 +3889,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>   
>   	intel_dp_set_idle_link_train(intel_dp);
>   
> -	intel_dp->DP = DP;
> -
>   	if (channel_eq) {
>   		intel_dp->train_set_valid = true;
>   		DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
> @@ -3904,7 +3897,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>   
>   void intel_dp_stop_link_train(struct intel_dp *intel_dp)
>   {
> -	intel_dp_set_link_train(intel_dp, &intel_dp->DP,
> +	intel_dp_set_link_train(intel_dp,
>   				DP_TRAINING_PATTERN_DISABLE);
>   }
>   

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

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

* Re: [PATCH 02/22] drm/i915: Split write of pattern to DP reg from intel_dp_set_link_train
  2015-10-23 10:01 ` [PATCH 02/22] drm/i915: Split write of pattern to DP reg from intel_dp_set_link_train Ander Conselvan de Oliveira
@ 2015-10-25  2:06   ` Thulasimani, Sivakumar
  0 siblings, 0 replies; 34+ messages in thread
From: Thulasimani, Sivakumar @ 2015-10-25  2:06 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx, jim.bride

Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>

On 10/23/2015 3:31 PM, Ander Conselvan de Oliveira wrote:
> Split the register write with the new link training pattern out of
> intel_dp_set_link_train(), so that the i915 specific code is in a
> separate function.
>
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> ---
>   drivers/gpu/drm/i915/intel_dp.c | 18 +++++++++++++-----
>   1 file changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 648300e..0958cab 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3594,20 +3594,28 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
>   	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
>   }
>   
> -static bool
> -intel_dp_set_link_train(struct intel_dp *intel_dp,
> -			uint8_t dp_train_pat)
> +static void
> +intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
> +				       uint8_t dp_train_pat)
>   {
>   	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);
> -	uint8_t buf[sizeof(intel_dp->train_set) + 1];
> -	int ret, len;
>   
>   	_intel_dp_set_link_train(intel_dp, &intel_dp->DP, dp_train_pat);
>   
>   	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
>   	POSTING_READ(intel_dp->output_reg);
> +}
> +
> +static bool
> +intel_dp_set_link_train(struct intel_dp *intel_dp,
> +			uint8_t dp_train_pat)
> +{
> +	uint8_t buf[sizeof(intel_dp->train_set) + 1];
> +	int ret, len;
> +
> +	intel_dp_program_link_training_pattern(intel_dp, dp_train_pat);
>   
>   	buf[0] = dp_train_pat;
>   	if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==

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

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

* Re: [PATCH 03/22] drm/i915 Call get_adjust_train() from clock recovery and channel eq
  2015-10-23 10:01 ` [PATCH 03/22] drm/i915 Call get_adjust_train() from clock recovery and channel eq Ander Conselvan de Oliveira
@ 2015-10-25  2:11   ` Thulasimani, Sivakumar
  0 siblings, 0 replies; 34+ messages in thread
From: Thulasimani, Sivakumar @ 2015-10-25  2:11 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx, jim.bride

Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>

On 10/23/2015 3:31 PM, Ander Conselvan de Oliveira wrote:
> Move the call to intel_dp_get_adjust_train() out of
> intel_dp_update_link_train() and call it instead from the clock recovery
> and channel equalization features. A follow up patch will remove the DP
> register write from that function, so that it handles only the DPCD
> write.
>
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> ---
>   drivers/gpu/drm/i915/intel_dp.c | 10 +++++-----
>   1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 0958cab..11f2385 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3645,15 +3645,13 @@ intel_dp_reset_link_train(struct intel_dp *intel_dp,
>   }
>   
>   static bool
> -intel_dp_update_link_train(struct intel_dp *intel_dp,
> -			   const uint8_t link_status[DP_LINK_STATUS_SIZE])
> +intel_dp_update_link_train(struct intel_dp *intel_dp)
>   {
>   	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);
>   	int ret;
>   
> -	intel_get_adjust_train(intel_dp, link_status);
>   	intel_dp_set_signal_levels(intel_dp);
>   
>   	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
> @@ -3801,7 +3799,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 */
> -		if (!intel_dp_update_link_train(intel_dp, link_status)) {
> +		intel_get_adjust_train(intel_dp, link_status);
> +		if (!intel_dp_update_link_train(intel_dp)) {
>   			DRM_ERROR("failed to update link training\n");
>   			break;
>   		}
> @@ -3888,7 +3887,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>   		}
>   
>   		/* Update training set as requested by target */
> -		if (!intel_dp_update_link_train(intel_dp, link_status)) {
> +		intel_get_adjust_train(intel_dp, link_status);
> +		if (!intel_dp_update_link_train(intel_dp)) {
>   			DRM_ERROR("failed to update link training\n");
>   			break;
>   		}

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

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

* Re: [PATCH 04/22] drm/i915: Move register write into intel_dp_set_signal_levels()
  2015-10-23 10:01 ` [PATCH 04/22] drm/i915: Move register write into intel_dp_set_signal_levels() Ander Conselvan de Oliveira
@ 2015-10-25  2:28   ` Thulasimani, Sivakumar
  0 siblings, 0 replies; 34+ messages in thread
From: Thulasimani, Sivakumar @ 2015-10-25  2:28 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx, jim.bride

Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>

On 10/23/2015 3:31 PM, Ander Conselvan de Oliveira wrote:
> Move register write from intel_dp_update_link_train() into
> intel_dp_set_signal_levels(). This creates a better split between the
> i915 specific code and the generic link training part. Note that this
> causes an extra register write in intel_dp_reset_link_train(), since
> both intel_dp_set_signal_levels() and intel_dp_set_link_train() write
> to the DP register.
>
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> ---
>   drivers/gpu/drm/i915/intel_dp.c | 11 ++++-------
>   1 file changed, 4 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 11f2385..4ffb2e3 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3550,13 +3550,13 @@ gen7_edp_signal_levels(uint8_t train_set)
>   	}
>   }
>   
> -/* Properly updates "DP" with the correct signal levels. */
>   static void
>   intel_dp_set_signal_levels(struct intel_dp *intel_dp)
>   {
>   	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>   	enum port port = intel_dig_port->port;
>   	struct drm_device *dev = intel_dig_port->base.base.dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
>   	uint32_t signal_levels, mask = 0;
>   	uint8_t train_set = intel_dp->train_set[0];
>   
> @@ -3592,6 +3592,9 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
>   			DP_TRAIN_PRE_EMPHASIS_SHIFT);
>   
>   	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
> +
> +	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
> +	POSTING_READ(intel_dp->output_reg);
>   }
>   
>   static void
> @@ -3647,16 +3650,10 @@ intel_dp_reset_link_train(struct intel_dp *intel_dp,
>   static bool
>   intel_dp_update_link_train(struct intel_dp *intel_dp)
>   {
> -	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);
>   	int ret;
>   
>   	intel_dp_set_signal_levels(intel_dp);
>   
> -	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
> -	POSTING_READ(intel_dp->output_reg);
> -
>   	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
>   				intel_dp->train_set, intel_dp->lane_count);
>   

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

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

* Re: [PATCH 05/22] drm/i915: Move generic link training code to a separate file
  2015-10-23 10:01 ` [PATCH 05/22] drm/i915: Move generic link training code to a separate file Ander Conselvan de Oliveira
@ 2015-10-25  2:37   ` Thulasimani, Sivakumar
  0 siblings, 0 replies; 34+ messages in thread
From: Thulasimani, Sivakumar @ 2015-10-25  2:37 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx, jim.bride

Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>

On 10/23/2015 3:31 PM, Ander Conselvan de Oliveira wrote:
> No functional changes, just moving code around.
>
> v2: Rebase
>
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> ---
>   drivers/gpu/drm/i915/Makefile                 |   1 +
>   drivers/gpu/drm/i915/intel_dp.c               | 321 +------------------------
>   drivers/gpu/drm/i915/intel_dp_link_training.c | 327 ++++++++++++++++++++++++++
>   drivers/gpu/drm/i915/intel_drv.h              |  16 ++
>   4 files changed, 353 insertions(+), 312 deletions(-)
>   create mode 100644 drivers/gpu/drm/i915/intel_dp_link_training.c
>
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 44d290a..0851de07 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -77,6 +77,7 @@ i915-y += dvo_ch7017.o \
>   	  dvo_tfp410.o \
>   	  intel_crt.o \
>   	  intel_ddi.o \
> +	  intel_dp_link_training.o \
>   	  intel_dp_mst.o \
>   	  intel_dp.o \
>   	  intel_dsi.o \
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 4ffb2e3..4b88823 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1189,7 +1189,7 @@ intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
>   	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
>   }
>   
> -static bool intel_dp_source_supports_hbr2(struct drm_device *dev)
> +bool intel_dp_source_supports_hbr2(struct drm_device *dev)
>   {
>   	/* WaDisableHBR2:skl */
>   	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
> @@ -1365,8 +1365,8 @@ int intel_dp_rate_select(struct intel_dp *intel_dp, int rate)
>   	return rate_to_index(rate, intel_dp->sink_rates);
>   }
>   
> -static void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
> -				  uint8_t *link_bw, uint8_t *rate_select)
> +void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
> +			   uint8_t *link_bw, uint8_t *rate_select)
>   {
>   	if (intel_dp->num_sink_rates) {
>   		*link_bw = 0;
> @@ -3046,7 +3046,7 @@ intel_dp_dpcd_read_wake(struct drm_dp_aux *aux, unsigned int offset,
>    * Fetch AUX CH registers 0x202 - 0x207 which contain
>    * link status information
>    */
> -static bool
> +bool
>   intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
>   {
>   	return intel_dp_dpcd_read_wake(&intel_dp->aux,
> @@ -3056,7 +3056,7 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_
>   }
>   
>   /* These are source-specific values. */
> -static uint8_t
> +uint8_t
>   intel_dp_voltage_max(struct intel_dp *intel_dp)
>   {
>   	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> @@ -3079,7 +3079,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
>   		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
>   }
>   
> -static uint8_t
> +uint8_t
>   intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
>   {
>   	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> @@ -3421,38 +3421,6 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
>   	return 0;
>   }
>   
> -static void
> -intel_get_adjust_train(struct intel_dp *intel_dp,
> -		       const uint8_t link_status[DP_LINK_STATUS_SIZE])
> -{
> -	uint8_t v = 0;
> -	uint8_t p = 0;
> -	int lane;
> -	uint8_t voltage_max;
> -	uint8_t preemph_max;
> -
> -	for (lane = 0; lane < intel_dp->lane_count; lane++) {
> -		uint8_t this_v = drm_dp_get_adjust_request_voltage(link_status, lane);
> -		uint8_t 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;
> -	}
> -
> -	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);
> -	if (p >= preemph_max)
> -		p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
> -
> -	for (lane = 0; lane < 4; lane++)
> -		intel_dp->train_set[lane] = v | p;
> -}
> -
>   static uint32_t
>   gen4_signal_levels(uint8_t train_set)
>   {
> @@ -3550,7 +3518,7 @@ gen7_edp_signal_levels(uint8_t train_set)
>   	}
>   }
>   
> -static void
> +void
>   intel_dp_set_signal_levels(struct intel_dp *intel_dp)
>   {
>   	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> @@ -3597,7 +3565,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
>   	POSTING_READ(intel_dp->output_reg);
>   }
>   
> -static void
> +void
>   intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
>   				       uint8_t dp_train_pat)
>   {
> @@ -3611,56 +3579,7 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
>   	POSTING_READ(intel_dp->output_reg);
>   }
>   
> -static bool
> -intel_dp_set_link_train(struct intel_dp *intel_dp,
> -			uint8_t dp_train_pat)
> -{
> -	uint8_t buf[sizeof(intel_dp->train_set) + 1];
> -	int ret, len;
> -
> -	intel_dp_program_link_training_pattern(intel_dp, dp_train_pat);
> -
> -	buf[0] = dp_train_pat;
> -	if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==
> -	    DP_TRAINING_PATTERN_DISABLE) {
> -		/* don't write DP_TRAINING_LANEx_SET on disable */
> -		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;
> -	}
> -
> -	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET,
> -				buf, len);
> -
> -	return ret == len;
> -}
> -
> -static bool
> -intel_dp_reset_link_train(struct intel_dp *intel_dp,
> -			uint8_t dp_train_pat)
> -{
> -	if (!intel_dp->train_set_valid)
> -		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);
> -}
> -
> -static bool
> -intel_dp_update_link_train(struct intel_dp *intel_dp)
> -{
> -	int ret;
> -
> -	intel_dp_set_signal_levels(intel_dp);
> -
> -	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
> -				intel_dp->train_set, intel_dp->lane_count);
> -
> -	return ret == intel_dp->lane_count;
> -}
> -
> -static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
> +void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
>   {
>   	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>   	struct drm_device *dev = intel_dig_port->base.base.dev;
> @@ -3691,228 +3610,6 @@ static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
>   		DRM_ERROR("Timed out waiting for DP idle patterns\n");
>   }
>   
> -/* Enable corresponding port and start training pattern 1 */
> -static void
> -intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
> -{
> -	struct drm_encoder *encoder = &dp_to_dig_port(intel_dp)->base.base;
> -	struct drm_device *dev = encoder->dev;
> -	int i;
> -	uint8_t voltage;
> -	int voltage_tries, loop_tries;
> -	uint8_t link_config[2];
> -	uint8_t link_bw, rate_select;
> -
> -	if (HAS_DDI(dev))
> -		intel_ddi_prepare_link_retrain(encoder);
> -
> -	intel_dp_compute_rate(intel_dp, intel_dp->link_rate,
> -			      &link_bw, &rate_select);
> -
> -	/* Write the link configuration data */
> -	link_config[0] = link_bw;
> -	link_config[1] = intel_dp->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);
> -	if (intel_dp->num_sink_rates)
> -		drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_RATE_SET,
> -				  &rate_select, 1);
> -
> -	link_config[0] = 0;
> -	link_config[1] = DP_SET_ANSI_8B10B;
> -	drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
> -
> -	intel_dp->DP |= DP_PORT_EN;
> -
> -	/* clock recovery */
> -	if (!intel_dp_reset_link_train(intel_dp,
> -				       DP_TRAINING_PATTERN_1 |
> -				       DP_LINK_SCRAMBLING_DISABLE)) {
> -		DRM_ERROR("failed to enable link training\n");
> -		return;
> -	}
> -
> -	voltage = 0xff;
> -	voltage_tries = 0;
> -	loop_tries = 0;
> -	for (;;) {
> -		uint8_t link_status[DP_LINK_STATUS_SIZE];
> -
> -		drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
> -		if (!intel_dp_get_link_status(intel_dp, link_status)) {
> -			DRM_ERROR("failed to get link status\n");
> -			break;
> -		}
> -
> -		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
> -			DRM_DEBUG_KMS("clock recovery OK\n");
> -			break;
> -		}
> -
> -		/*
> -		 * if we used previously trained voltage and pre-emphasis values
> -		 * and we don't get clock recovery, reset link training values
> -		 */
> -		if (intel_dp->train_set_valid) {
> -			DRM_DEBUG_KMS("clock recovery not ok, reset");
> -			/* clear the flag as we are not reusing train set */
> -			intel_dp->train_set_valid = false;
> -			if (!intel_dp_reset_link_train(intel_dp,
> -						       DP_TRAINING_PATTERN_1 |
> -						       DP_LINK_SCRAMBLING_DISABLE)) {
> -				DRM_ERROR("failed to enable link training\n");
> -				return;
> -			}
> -			continue;
> -		}
> -
> -		/* Check to see if we've tried the max voltage */
> -		for (i = 0; i < intel_dp->lane_count; i++)
> -			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
> -				break;
> -		if (i == intel_dp->lane_count) {
> -			++loop_tries;
> -			if (loop_tries == 5) {
> -				DRM_ERROR("too many full retries, give up\n");
> -				break;
> -			}
> -			intel_dp_reset_link_train(intel_dp,
> -						  DP_TRAINING_PATTERN_1 |
> -						  DP_LINK_SCRAMBLING_DISABLE);
> -			voltage_tries = 0;
> -			continue;
> -		}
> -
> -		/* Check to see if we've tried the same voltage 5 times */
> -		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
> -			++voltage_tries;
> -			if (voltage_tries == 5) {
> -				DRM_ERROR("too many voltage retries, give up\n");
> -				break;
> -			}
> -		} else
> -			voltage_tries = 0;
> -		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
> -
> -		/* Update training set as requested by target */
> -		intel_get_adjust_train(intel_dp, link_status);
> -		if (!intel_dp_update_link_train(intel_dp)) {
> -			DRM_ERROR("failed to update link training\n");
> -			break;
> -		}
> -	}
> -}
> -
> -static void
> -intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
> -{
> -	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> -	struct drm_device *dev = dig_port->base.base.dev;
> -	bool channel_eq = false;
> -	int tries, cr_tries;
> -	uint32_t training_pattern = DP_TRAINING_PATTERN_2;
> -
> -	/*
> -	 * Training Pattern 3 for HBR2 or 1.2 devices that support it.
> -	 *
> -	 * Intel platforms that support HBR2 also support TPS3. TPS3 support is
> -	 * also mandatory for downstream devices that support HBR2.
> -	 *
> -	 * Due to WaDisableHBR2 SKL < B0 is the only exception where TPS3 is
> -	 * supported but still not enabled.
> -	 */
> -	if (intel_dp_source_supports_hbr2(dev) &&
> -	    drm_dp_tps3_supported(intel_dp->dpcd))
> -		training_pattern = DP_TRAINING_PATTERN_3;
> -	else if (intel_dp->link_rate == 540000)
> -		DRM_ERROR("5.4 Gbps link rate without HBR2/TPS3 support\n");
> -
> -	/* channel equalization */
> -	if (!intel_dp_set_link_train(intel_dp,
> -				     training_pattern |
> -				     DP_LINK_SCRAMBLING_DISABLE)) {
> -		DRM_ERROR("failed to start channel equalization\n");
> -		return;
> -	}
> -
> -	tries = 0;
> -	cr_tries = 0;
> -	channel_eq = false;
> -	for (;;) {
> -		uint8_t link_status[DP_LINK_STATUS_SIZE];
> -
> -		if (cr_tries > 5) {
> -			DRM_ERROR("failed to train DP, aborting\n");
> -			break;
> -		}
> -
> -		drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
> -		if (!intel_dp_get_link_status(intel_dp, link_status)) {
> -			DRM_ERROR("failed to get link status\n");
> -			break;
> -		}
> -
> -		/* Make sure clock is still ok */
> -		if (!drm_dp_clock_recovery_ok(link_status,
> -					      intel_dp->lane_count)) {
> -			intel_dp->train_set_valid = false;
> -			intel_dp_link_training_clock_recovery(intel_dp);
> -			intel_dp_set_link_train(intel_dp,
> -						training_pattern |
> -						DP_LINK_SCRAMBLING_DISABLE);
> -			cr_tries++;
> -			continue;
> -		}
> -
> -		if (drm_dp_channel_eq_ok(link_status,
> -					 intel_dp->lane_count)) {
> -			channel_eq = true;
> -			break;
> -		}
> -
> -		/* Try 5 times, then try clock recovery if that fails */
> -		if (tries > 5) {
> -			intel_dp->train_set_valid = false;
> -			intel_dp_link_training_clock_recovery(intel_dp);
> -			intel_dp_set_link_train(intel_dp,
> -						training_pattern |
> -						DP_LINK_SCRAMBLING_DISABLE);
> -			tries = 0;
> -			cr_tries++;
> -			continue;
> -		}
> -
> -		/* Update training set as requested by target */
> -		intel_get_adjust_train(intel_dp, link_status);
> -		if (!intel_dp_update_link_train(intel_dp)) {
> -			DRM_ERROR("failed to update link training\n");
> -			break;
> -		}
> -		++tries;
> -	}
> -
> -	intel_dp_set_idle_link_train(intel_dp);
> -
> -	if (channel_eq) {
> -		intel_dp->train_set_valid = true;
> -		DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
> -	}
> -}
> -
> -void intel_dp_stop_link_train(struct intel_dp *intel_dp)
> -{
> -	intel_dp_set_link_train(intel_dp,
> -				DP_TRAINING_PATTERN_DISABLE);
> -}
> -
> -void
> -intel_dp_start_link_train(struct intel_dp *intel_dp)
> -{
> -	intel_dp_link_training_clock_recovery(intel_dp);
> -	intel_dp_link_training_channel_equalization(intel_dp);
> -}
> -
>   static void
>   intel_dp_link_down(struct intel_dp *intel_dp)
>   {
> diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
> new file mode 100644
> index 0000000..53f9c14
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
> @@ -0,0 +1,327 @@
> +/*
> + * Copyright © 2008-2015 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + */
> +
> +#include "intel_drv.h"
> +
> +static void
> +intel_get_adjust_train(struct intel_dp *intel_dp,
> +		       const uint8_t link_status[DP_LINK_STATUS_SIZE])
> +{
> +	uint8_t v = 0;
> +	uint8_t p = 0;
> +	int lane;
> +	uint8_t voltage_max;
> +	uint8_t preemph_max;
> +
> +	for (lane = 0; lane < intel_dp->lane_count; lane++) {
> +		uint8_t this_v = drm_dp_get_adjust_request_voltage(link_status, lane);
> +		uint8_t 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;
> +	}
> +
> +	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);
> +	if (p >= preemph_max)
> +		p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
> +
> +	for (lane = 0; lane < 4; lane++)
> +		intel_dp->train_set[lane] = v | p;
> +}
> +
> +static bool
> +intel_dp_set_link_train(struct intel_dp *intel_dp,
> +			uint8_t dp_train_pat)
> +{
> +	uint8_t buf[sizeof(intel_dp->train_set) + 1];
> +	int ret, len;
> +
> +	intel_dp_program_link_training_pattern(intel_dp, dp_train_pat);
> +
> +	buf[0] = dp_train_pat;
> +	if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==
> +	    DP_TRAINING_PATTERN_DISABLE) {
> +		/* don't write DP_TRAINING_LANEx_SET on disable */
> +		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;
> +	}
> +
> +	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET,
> +				buf, len);
> +
> +	return ret == len;
> +}
> +
> +static bool
> +intel_dp_reset_link_train(struct intel_dp *intel_dp,
> +			uint8_t dp_train_pat)
> +{
> +	if (!intel_dp->train_set_valid)
> +		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);
> +}
> +
> +static bool
> +intel_dp_update_link_train(struct intel_dp *intel_dp)
> +{
> +	int ret;
> +
> +	intel_dp_set_signal_levels(intel_dp);
> +
> +	ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
> +				intel_dp->train_set, intel_dp->lane_count);
> +
> +	return ret == intel_dp->lane_count;
> +}
> +
> +/* Enable corresponding port and start training pattern 1 */
> +static void
> +intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
> +{
> +	struct drm_encoder *encoder = &dp_to_dig_port(intel_dp)->base.base;
> +	struct drm_device *dev = encoder->dev;
> +	int i;
> +	uint8_t voltage;
> +	int voltage_tries, loop_tries;
> +	uint8_t link_config[2];
> +	uint8_t link_bw, rate_select;
> +
> +	if (HAS_DDI(dev))
> +		intel_ddi_prepare_link_retrain(encoder);
> +
> +	intel_dp_compute_rate(intel_dp, intel_dp->link_rate,
> +			      &link_bw, &rate_select);
> +
> +	/* Write the link configuration data */
> +	link_config[0] = link_bw;
> +	link_config[1] = intel_dp->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);
> +	if (intel_dp->num_sink_rates)
> +		drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_RATE_SET,
> +				  &rate_select, 1);
> +
> +	link_config[0] = 0;
> +	link_config[1] = DP_SET_ANSI_8B10B;
> +	drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
> +
> +	intel_dp->DP |= DP_PORT_EN;
> +
> +	/* clock recovery */
> +	if (!intel_dp_reset_link_train(intel_dp,
> +				       DP_TRAINING_PATTERN_1 |
> +				       DP_LINK_SCRAMBLING_DISABLE)) {
> +		DRM_ERROR("failed to enable link training\n");
> +		return;
> +	}
> +
> +	voltage = 0xff;
> +	voltage_tries = 0;
> +	loop_tries = 0;
> +	for (;;) {
> +		uint8_t link_status[DP_LINK_STATUS_SIZE];
> +
> +		drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
> +		if (!intel_dp_get_link_status(intel_dp, link_status)) {
> +			DRM_ERROR("failed to get link status\n");
> +			break;
> +		}
> +
> +		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
> +			DRM_DEBUG_KMS("clock recovery OK\n");
> +			break;
> +		}
> +
> +		/*
> +		 * if we used previously trained voltage and pre-emphasis values
> +		 * and we don't get clock recovery, reset link training values
> +		 */
> +		if (intel_dp->train_set_valid) {
> +			DRM_DEBUG_KMS("clock recovery not ok, reset");
> +			/* clear the flag as we are not reusing train set */
> +			intel_dp->train_set_valid = false;
> +			if (!intel_dp_reset_link_train(intel_dp,
> +						       DP_TRAINING_PATTERN_1 |
> +						       DP_LINK_SCRAMBLING_DISABLE)) {
> +				DRM_ERROR("failed to enable link training\n");
> +				return;
> +			}
> +			continue;
> +		}
> +
> +		/* Check to see if we've tried the max voltage */
> +		for (i = 0; i < intel_dp->lane_count; i++)
> +			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
> +				break;
> +		if (i == intel_dp->lane_count) {
> +			++loop_tries;
> +			if (loop_tries == 5) {
> +				DRM_ERROR("too many full retries, give up\n");
> +				break;
> +			}
> +			intel_dp_reset_link_train(intel_dp,
> +						  DP_TRAINING_PATTERN_1 |
> +						  DP_LINK_SCRAMBLING_DISABLE);
> +			voltage_tries = 0;
> +			continue;
> +		}
> +
> +		/* Check to see if we've tried the same voltage 5 times */
> +		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
> +			++voltage_tries;
> +			if (voltage_tries == 5) {
> +				DRM_ERROR("too many voltage retries, give up\n");
> +				break;
> +			}
> +		} else
> +			voltage_tries = 0;
> +		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
> +
> +		/* Update training set as requested by target */
> +		intel_get_adjust_train(intel_dp, link_status);
> +		if (!intel_dp_update_link_train(intel_dp)) {
> +			DRM_ERROR("failed to update link training\n");
> +			break;
> +		}
> +	}
> +}
> +
> +static void
> +intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
> +{
> +	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> +	struct drm_device *dev = dig_port->base.base.dev;
> +	bool channel_eq = false;
> +	int tries, cr_tries;
> +	uint32_t training_pattern = DP_TRAINING_PATTERN_2;
> +
> +	/*
> +	 * Training Pattern 3 for HBR2 or 1.2 devices that support it.
> +	 *
> +	 * Intel platforms that support HBR2 also support TPS3. TPS3 support is
> +	 * also mandatory for downstream devices that support HBR2.
> +	 *
> +	 * Due to WaDisableHBR2 SKL < B0 is the only exception where TPS3 is
> +	 * supported but still not enabled.
> +	 */
> +	if (intel_dp_source_supports_hbr2(dev) &&
> +	    drm_dp_tps3_supported(intel_dp->dpcd))
> +		training_pattern = DP_TRAINING_PATTERN_3;
> +	else if (intel_dp->link_rate == 540000)
> +		DRM_ERROR("5.4 Gbps link rate without HBR2/TPS3 support\n");
> +
> +	/* channel equalization */
> +	if (!intel_dp_set_link_train(intel_dp,
> +				     training_pattern |
> +				     DP_LINK_SCRAMBLING_DISABLE)) {
> +		DRM_ERROR("failed to start channel equalization\n");
> +		return;
> +	}
> +
> +	tries = 0;
> +	cr_tries = 0;
> +	channel_eq = false;
> +	for (;;) {
> +		uint8_t link_status[DP_LINK_STATUS_SIZE];
> +
> +		if (cr_tries > 5) {
> +			DRM_ERROR("failed to train DP, aborting\n");
> +			break;
> +		}
> +
> +		drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
> +		if (!intel_dp_get_link_status(intel_dp, link_status)) {
> +			DRM_ERROR("failed to get link status\n");
> +			break;
> +		}
> +
> +		/* Make sure clock is still ok */
> +		if (!drm_dp_clock_recovery_ok(link_status,
> +					      intel_dp->lane_count)) {
> +			intel_dp->train_set_valid = false;
> +			intel_dp_link_training_clock_recovery(intel_dp);
> +			intel_dp_set_link_train(intel_dp,
> +						training_pattern |
> +						DP_LINK_SCRAMBLING_DISABLE);
> +			cr_tries++;
> +			continue;
> +		}
> +
> +		if (drm_dp_channel_eq_ok(link_status,
> +					 intel_dp->lane_count)) {
> +			channel_eq = true;
> +			break;
> +		}
> +
> +		/* Try 5 times, then try clock recovery if that fails */
> +		if (tries > 5) {
> +			intel_dp->train_set_valid = false;
> +			intel_dp_link_training_clock_recovery(intel_dp);
> +			intel_dp_set_link_train(intel_dp,
> +						training_pattern |
> +						DP_LINK_SCRAMBLING_DISABLE);
> +			tries = 0;
> +			cr_tries++;
> +			continue;
> +		}
> +
> +		/* Update training set as requested by target */
> +		intel_get_adjust_train(intel_dp, link_status);
> +		if (!intel_dp_update_link_train(intel_dp)) {
> +			DRM_ERROR("failed to update link training\n");
> +			break;
> +		}
> +		++tries;
> +	}
> +
> +	intel_dp_set_idle_link_train(intel_dp);
> +
> +	if (channel_eq) {
> +		intel_dp->train_set_valid = true;
> +		DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
> +	}
> +}
> +
> +void intel_dp_stop_link_train(struct intel_dp *intel_dp)
> +{
> +	intel_dp_set_link_train(intel_dp,
> +				DP_TRAINING_PATTERN_DISABLE);
> +}
> +
> +void
> +intel_dp_start_link_train(struct intel_dp *intel_dp)
> +{
> +	intel_dp_link_training_clock_recovery(intel_dp);
> +	intel_dp_link_training_channel_equalization(intel_dp);
> +}
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 6790187..25ac5d2 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1236,6 +1236,22 @@ bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
>   					 struct intel_digital_port *port);
>   void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config);
>   
> +void
> +intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
> +				       uint8_t 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);
> +uint8_t
> +intel_dp_voltage_max(struct intel_dp *intel_dp);
> +uint8_t
> +intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing);
> +void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
> +			   uint8_t *link_bw, uint8_t *rate_select);
> +bool intel_dp_source_supports_hbr2(struct drm_device *dev);
> +bool
> +intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]);
> +
>   /* intel_dp_mst.c */
>   int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
>   void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);

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

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

* Re: [PATCH 06/22] drm/i915: Create intel_dp->prepare_link_retrain() hook
  2015-10-23 10:01 ` [PATCH 06/22] drm/i915: Create intel_dp->prepare_link_retrain() hook Ander Conselvan de Oliveira
@ 2015-10-25  2:40   ` Thulasimani, Sivakumar
  0 siblings, 0 replies; 34+ messages in thread
From: Thulasimani, Sivakumar @ 2015-10-25  2:40 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx, jim.bride

Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>

On 10/23/2015 3:31 PM, Ander Conselvan de Oliveira wrote:
> In order to prepare for a link training with DDI, the state machine
> would call intel_ddi_prepare_link_retrain(). To remove the dependency to
> the hardware information, replace that direct call with a callback.
>
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> ---
>   drivers/gpu/drm/i915/intel_ddi.c              | 8 ++++----
>   drivers/gpu/drm/i915/intel_dp.c               | 3 +++
>   drivers/gpu/drm/i915/intel_dp_link_training.c | 6 ++----
>   drivers/gpu/drm/i915/intel_drv.h              | 6 +++++-
>   4 files changed, 14 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index a163741..80843d9 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2971,11 +2971,11 @@ void intel_ddi_pll_init(struct drm_device *dev)
>   	}
>   }
>   
> -void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
> +void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
>   {
> -	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> -	struct intel_dp *intel_dp = &intel_dig_port->dp;
> -	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
> +	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->port;
>   	uint32_t val;
>   	bool wait = false;
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 4b88823..5b04ade 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -5731,6 +5731,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
>   	else
>   		intel_dp->get_aux_send_ctl = i9xx_get_aux_send_ctl;
>   
> +	if (HAS_DDI(dev))
> +		intel_dp->prepare_link_retrain = intel_ddi_prepare_link_retrain;
> +
>   	/* Preserve the current hw state. */
>   	intel_dp->DP = I915_READ(intel_dp->output_reg);
>   	intel_dp->attached_connector = intel_connector;
> diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
> index 53f9c14..bb036d5 100644
> --- a/drivers/gpu/drm/i915/intel_dp_link_training.c
> +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
> @@ -108,16 +108,14 @@ intel_dp_update_link_train(struct intel_dp *intel_dp)
>   static void
>   intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
>   {
> -	struct drm_encoder *encoder = &dp_to_dig_port(intel_dp)->base.base;
> -	struct drm_device *dev = encoder->dev;
>   	int i;
>   	uint8_t voltage;
>   	int voltage_tries, loop_tries;
>   	uint8_t link_config[2];
>   	uint8_t link_bw, rate_select;
>   
> -	if (HAS_DDI(dev))
> -		intel_ddi_prepare_link_retrain(encoder);
> +	if (intel_dp->prepare_link_retrain)
> +		intel_dp->prepare_link_retrain(intel_dp);
>   
>   	intel_dp_compute_rate(intel_dp, intel_dp->link_rate,
>   			      &link_bw, &rate_select);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 25ac5d2..1c2a8ed 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -784,6 +784,10 @@ struct intel_dp {
>   				     bool has_aux_irq,
>   				     int send_bytes,
>   				     uint32_t aux_clock_divider);
> +
> +	/* This is called before a link training is starterd */
> +	void (*prepare_link_retrain)(struct intel_dp *intel_dp);
> +
>   	bool train_set_valid;
>   
>   	/* Displayport compliance testing */
> @@ -988,7 +992,7 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
>   bool intel_ddi_pll_select(struct intel_crtc *crtc,
>   			  struct intel_crtc_state *crtc_state);
>   void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
> -void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
> +void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp);
>   bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
>   void intel_ddi_fdi_disable(struct drm_crtc *crtc);
>   void intel_ddi_get_config(struct intel_encoder *encoder,

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

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

* Re: [PATCH 07/22] drm/i915: Make intel_dp_source_supports_hbr2() take an intel_dp pointer
  2015-10-23 10:01 ` [PATCH 07/22] drm/i915: Make intel_dp_source_supports_hbr2() take an intel_dp pointer Ander Conselvan de Oliveira
@ 2015-10-25  2:48   ` Thulasimani, Sivakumar
  2015-11-05 13:22     ` Ander Conselvan De Oliveira
  0 siblings, 1 reply; 34+ messages in thread
From: Thulasimani, Sivakumar @ 2015-10-25  2:48 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx, jim.bride

Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>

On 10/23/2015 3:31 PM, Ander Conselvan de Oliveira wrote:
> The function name implies it should get intel_dp, and it mostly used
> where there is an intel_dp in the context.
>
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> ---
>   drivers/gpu/drm/i915/intel_dp.c               | 19 +++++++++++--------
>   drivers/gpu/drm/i915/intel_dp_link_training.c |  4 +---
>   drivers/gpu/drm/i915/intel_drv.h              |  2 +-
>   3 files changed, 13 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 5b04ade..5344de4 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1189,8 +1189,11 @@ intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
>   	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
>   }
>   
> -bool intel_dp_source_supports_hbr2(struct drm_device *dev)
> +bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
>   {
> +	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> +	struct drm_device *dev = dig_port->base.base.dev;
> +
>   	/* WaDisableHBR2:skl */
>   	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
>   		return false;
> @@ -1203,8 +1206,10 @@ bool intel_dp_source_supports_hbr2(struct drm_device *dev)
>   }
>   
>   static int
> -intel_dp_source_rates(struct drm_device *dev, const int **source_rates)
> +intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
>   {
> +	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> +	struct drm_device *dev = dig_port->base.base.dev;
>   	int size;
>   
>   	if (IS_BROXTON(dev)) {
> @@ -1219,7 +1224,7 @@ intel_dp_source_rates(struct drm_device *dev, const int **source_rates)
>   	}
>   
>   	/* This depends on the fact that 5.4 is last value in the array */
> -	if (!intel_dp_source_supports_hbr2(dev))
> +	if (!intel_dp_source_supports_hbr2(intel_dp))
>   		size--;
>   
>   	return size;
> @@ -1284,12 +1289,11 @@ static int intersect_rates(const int *source_rates, int source_len,
>   static int intel_dp_common_rates(struct intel_dp *intel_dp,
>   				 int *common_rates)
>   {
> -	struct drm_device *dev = intel_dp_to_dev(intel_dp);
>   	const int *source_rates, *sink_rates;
>   	int source_len, sink_len;
>   
>   	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
> -	source_len = intel_dp_source_rates(dev, &source_rates);
> +	source_len = intel_dp_source_rates(intel_dp, &source_rates);
>   
>   	return intersect_rates(source_rates, source_len,
>   			       sink_rates, sink_len,
> @@ -1314,7 +1318,6 @@ static void snprintf_int_array(char *str, size_t len,
>   
>   static void intel_dp_print_rates(struct intel_dp *intel_dp)
>   {
> -	struct drm_device *dev = intel_dp_to_dev(intel_dp);
>   	const int *source_rates, *sink_rates;
>   	int source_len, sink_len, common_len;
>   	int common_rates[DP_MAX_SUPPORTED_RATES];
> @@ -1323,7 +1326,7 @@ static void intel_dp_print_rates(struct intel_dp *intel_dp)
>   	if ((drm_debug & DRM_UT_KMS) == 0)
>   		return;
>   
> -	source_len = intel_dp_source_rates(dev, &source_rates);
> +	source_len = intel_dp_source_rates(intel_dp, &source_rates);
>   	snprintf_int_array(str, sizeof(str), source_rates, source_len);
>   	DRM_DEBUG_KMS("source rates: %s\n", str);
>   
> @@ -3711,7 +3714,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
>   	}
>   
>   	DRM_DEBUG_KMS("Display Port TPS3 support: source %s, sink %s\n",
> -		      yesno(intel_dp_source_supports_hbr2(dev)),
> +		      yesno(intel_dp_source_supports_hbr2(intel_dp)),
>   		      yesno(drm_dp_tps3_supported(intel_dp->dpcd)));
>   
>   	/* Intermediate frequency support */
> diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
> index bb036d5..8888793 100644
> --- a/drivers/gpu/drm/i915/intel_dp_link_training.c
> +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
> @@ -218,8 +218,6 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
>   static void
>   intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>   {
> -	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> -	struct drm_device *dev = dig_port->base.base.dev;
>   	bool channel_eq = false;
>   	int tries, cr_tries;
>   	uint32_t training_pattern = DP_TRAINING_PATTERN_2;
> @@ -233,7 +231,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>   	 * Due to WaDisableHBR2 SKL < B0 is the only exception where TPS3 is
>   	 * supported but still not enabled.
>   	 */
> -	if (intel_dp_source_supports_hbr2(dev) &&
> +	if (intel_dp_source_supports_hbr2(intel_dp) &&
>   	    drm_dp_tps3_supported(intel_dp->dpcd))
>   		training_pattern = DP_TRAINING_PATTERN_3;
>   	else if (intel_dp->link_rate == 540000)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 1c2a8ed..3021e40 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1252,7 +1252,7 @@ uint8_t
>   intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing);
>   void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
>   			   uint8_t *link_bw, uint8_t *rate_select);
> -bool intel_dp_source_supports_hbr2(struct drm_device *dev);
> +bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
>   bool
>   intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]);
>   

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

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

* Re: [PATCH 10/22] drm/i915: Add function for getting the current link training voltage
  2015-10-23 10:01 ` [PATCH 10/22] drm/i915: Add function for getting the current link training voltage Ander Conselvan de Oliveira
@ 2015-10-25  3:56   ` Thulasimani, Sivakumar
  0 siblings, 0 replies; 34+ messages in thread
From: Thulasimani, Sivakumar @ 2015-10-25  3:56 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx, jim.bride



On 10/23/2015 3:31 PM, Ander Conselvan de Oliveira wrote:
> Add a function for retrieving the current voltage swing being used for
> link training. Using that function in the clock recovery code makes it a
> bit more readable.
>
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> ---
>   drivers/gpu/drm/i915/intel_dp_link_training.c | 10 ++++++++--
>   1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
> index 9fdcc77..e5b9410 100644
> --- a/drivers/gpu/drm/i915/intel_dp_link_training.c
> +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
> @@ -155,6 +155,12 @@ max_voltage_reached_on_all_lanes(struct intel_dp *intel_dp)
>   	return true;
>   }
>   
> +static uint8_t
> +intel_dp_get_train_voltage(struct intel_dp *intel_dp)
> +{
> +	return intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
> +}
> +
>   /* Enable corresponding port and start training pattern 1 */
>   static void
>   intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
> @@ -214,7 +220,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
>   		}
>   
>   		/* Check to see if we've tried the same voltage 5 times */
> -		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
> +		if (intel_dp_get_train_voltage(intel_dp) == voltage) {
i understand this is related to taste/preference but wouldn't a macro be 
enough here ? something like
#define IS_MAX_SWING(train_set)    (train_set & DP_TRAIN_VOLTAGE_SWING_MASK)

regards,
Sivakumar
>   			++voltage_tries;
>   			if (voltage_tries == 5) {
>   				DRM_ERROR("too many voltage retries, give up\n");
> @@ -222,7 +228,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
>   			}
>   		} else
>   			voltage_tries = 0;
> -		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
> +		voltage = intel_dp_get_train_voltage(intel_dp);
>   
>   		/* Update training set as requested by target */
>   		intel_get_adjust_train(intel_dp, link_status);

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

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

* Re: [PATCH 16/22] drm/i915: Introduce struct intel_dp_signal_levels
  2015-10-23 10:01 ` [PATCH 16/22] drm/i915: Introduce struct intel_dp_signal_levels Ander Conselvan de Oliveira
@ 2015-10-25  5:24   ` Thulasimani, Sivakumar
  2015-10-26  7:22     ` Ander Conselvan De Oliveira
  0 siblings, 1 reply; 34+ messages in thread
From: Thulasimani, Sivakumar @ 2015-10-25  5:24 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx, jim.bride

This is a good simplification but for a wrong implementation :). we know 
that our current
implementation is wrong and needs to be done the opposite way to make
our code compliant with spec.  i assume that it will then be a question 
of when
this will be removed rather than if. In such a scenario is this and 
following
patches/optimizations needed "at present" ?

regards,
Sivakumar
On 10/23/2015 3:31 PM, Ander Conselvan de Oliveira wrote:
> In order to clarify which platforms support which combination of voltage
> swing and pre emphasis level, introduce struct intel_dp_signal_levels.
> With the new struct, the if ladder to determine the values used is put
> in one place, intel_dp_init_signal_levels().
>
> This also wires gens 4, 5 and non-eDP ports on gen 6 and 7 to use the
> new struct.
>
> v2: Rebase
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> ---
>   drivers/gpu/drm/i915/intel_dp.c               |   2 +
>   drivers/gpu/drm/i915/intel_dp_signal_levels.c | 103 ++++++++++++++++++++++----
>   drivers/gpu/drm/i915/intel_drv.h              |  11 +++
>   3 files changed, 101 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 1236791..e640b59 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -5220,6 +5220,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
>   	if (HAS_DDI(dev))
>   		intel_dp->prepare_link_retrain = intel_ddi_prepare_link_retrain;
>   
> +	intel_dp_init_signal_levels(intel_dp);
> +
>   	/* Preserve the current hw state. */
>   	intel_dp->DP = I915_READ(intel_dp->output_reg);
>   	intel_dp->attached_connector = intel_connector;
> diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
> index e516dd2..365bdc4 100644
> --- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
> +++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
> @@ -24,8 +24,8 @@
>   #include "intel_drv.h"
>   
>   /* These are source-specific values. */
> -uint8_t
> -intel_dp_voltage_max(struct intel_dp *intel_dp)
> +static uint8_t
> +_dp_voltage_max(struct intel_dp *intel_dp)
>   {
>   	struct drm_device *dev = intel_dp_to_dev(intel_dp);
>   	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -47,8 +47,8 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
>   		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
>   }
>   
> -uint8_t
> -intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
> +static uint8_t
> +_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
>   {
>   	struct drm_device *dev = intel_dp_to_dev(intel_dp);
>   	enum port port = dp_to_dig_port(intel_dp)->port;
> @@ -389,10 +389,10 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
>   	return 0;
>   }
>   
> -static uint32_t
> -gen4_signal_levels(uint8_t train_set)
> +static void
> +gen4_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
>   {
> -	uint32_t	signal_levels = 0;
> +	uint32_t signal_levels = 0;
>   
>   	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
>   	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
> @@ -424,9 +424,38 @@ gen4_signal_levels(uint8_t train_set)
>   		signal_levels |= DP_PRE_EMPHASIS_9_5;
>   		break;
>   	}
> -	return signal_levels;
> +
> +	DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
> +
> +	intel_dp->DP &= ~(DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK);
> +	intel_dp->DP |= signal_levels;
>   }
>   
> +static const struct signal_levels gen4_signal_levels = {
> +	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_2,
> +	.max_pre_emph = {
> +		DP_TRAIN_PRE_EMPH_LEVEL_2,
> +		DP_TRAIN_PRE_EMPH_LEVEL_2,
> +		DP_TRAIN_PRE_EMPH_LEVEL_1,
> +		DP_TRAIN_PRE_EMPH_LEVEL_0,
> +	},
> +
> +	.set = gen4_set_signal_levels,
> +};
> +
> +/* Not for eDP */
> +static const struct signal_levels snb_signal_levels = {
> +	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
> +	.max_pre_emph = {
> +		DP_TRAIN_PRE_EMPH_LEVEL_2,
> +		DP_TRAIN_PRE_EMPH_LEVEL_2,
> +		DP_TRAIN_PRE_EMPH_LEVEL_1,
> +		DP_TRAIN_PRE_EMPH_LEVEL_0,
> +	},
> +
> +	.set = gen4_set_signal_levels,
> +};
> +
>   /* Gen6's DP voltage swing and pre-emphasis control */
>   static uint32_t
>   gen6_edp_signal_levels(uint8_t train_set)
> @@ -486,13 +515,12 @@ gen7_edp_signal_levels(uint8_t train_set)
>   	}
>   }
>   
> -void
> -intel_dp_set_signal_levels(struct intel_dp *intel_dp)
> +static void
> +_update_signal_levels(struct intel_dp *intel_dp)
>   {
>   	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>   	enum port port = intel_dig_port->port;
>   	struct drm_device *dev = intel_dig_port->base.base.dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
>   	uint32_t signal_levels, mask = 0;
>   	uint8_t train_set = intel_dp->train_set[0];
>   
> @@ -514,21 +542,66 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
>   		signal_levels = gen6_edp_signal_levels(train_set);
>   		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
>   	} else {
> -		signal_levels = gen4_signal_levels(train_set);
> -		mask = DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK;
> +		WARN(1, "Should be calling intel_dp->signal_levels->set instead.");
> +		return;
>   	}
>   
>   	if (mask)
>   		DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
>   
> +	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
> +}
> +
> +uint8_t
> +intel_dp_voltage_max(struct intel_dp *intel_dp)
> +{
> +	if (intel_dp->signal_levels)
> +		return intel_dp->signal_levels->max_voltage;
> +	else
> +		return _dp_voltage_max(intel_dp);
> +}
> +
> +uint8_t
> +intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
> +{
> +	if (intel_dp->signal_levels)
> +		return intel_dp->signal_levels->max_pre_emph[voltage_swing];
> +	else
> +		return _dp_pre_emphasis_max(intel_dp, voltage_swing);
> +}
> +
> +void
> +intel_dp_set_signal_levels(struct intel_dp *intel_dp)
> +{
> +	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	uint8_t train_set = intel_dp->train_set[0];
> +
> +	if (intel_dp->signal_levels)
> +		intel_dp->signal_levels->set(intel_dp, train_set);
> +	else
> +		_update_signal_levels(intel_dp);
> +
>   	DRM_DEBUG_KMS("Using vswing level %d\n",
>   		train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
>   	DRM_DEBUG_KMS("Using pre-emphasis level %d\n",
>   		(train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
>   			DP_TRAIN_PRE_EMPHASIS_SHIFT);
>   
> -	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
> -
>   	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
>   	POSTING_READ(intel_dp->output_reg);
>   }
> +
> +void
> +intel_dp_init_signal_levels(struct intel_dp *intel_dp)
> +{
> +	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> +	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> +	enum port port = intel_dig_port->port;
> +
> +	if (port != PORT_A && (IS_IVYBRIDGE(dev) || IS_GEN6(dev)))
> +		intel_dp->signal_levels = &snb_signal_levels;
> +
> +	if (INTEL_INFO(dev)->gen <= 5)
> +		intel_dp->signal_levels = &gen4_signal_levels;
> +}
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index d758e94..e00ce6c 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -726,6 +726,14 @@ struct sink_crc {
>   	int last_count;
>   };
>   
> +struct intel_dp;
> +struct signal_levels {
> +	uint8_t max_voltage;
> +	uint8_t max_pre_emph[4];
> +
> +	void (*set)(struct intel_dp *intel_dp, uint8_t train_set);
> +};
> +
>   struct intel_dp {
>   	uint32_t output_reg;
>   	uint32_t aux_ch_ctl_reg;
> @@ -744,6 +752,7 @@ struct intel_dp {
>   	int sink_rates[DP_MAX_SUPPORTED_RATES];
>   	struct sink_crc sink_crc;
>   	struct drm_dp_aux aux;
> +	const struct signal_levels *signal_levels;
>   	uint8_t train_set[4];
>   	int panel_power_up_delay;
>   	int panel_power_down_delay;
> @@ -1263,6 +1272,8 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
>   bool
>   intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]);
>   
> +void intel_dp_init_signal_levels(struct intel_dp *intel_dp);
> +
>   /* intel_dp_mst.c */
>   int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
>   void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);

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

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

* Re: [PATCH 16/22] drm/i915: Introduce struct intel_dp_signal_levels
  2015-10-25  5:24   ` Thulasimani, Sivakumar
@ 2015-10-26  7:22     ` Ander Conselvan De Oliveira
  0 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-10-26  7:22 UTC (permalink / raw)
  To: Thulasimani, Sivakumar, intel-gfx, jim.bride

On Sun, 2015-10-25 at 10:54 +0530, Thulasimani, Sivakumar wrote:
> This is a good simplification but for a wrong implementation :). we know 
> that our current
> implementation is wrong and needs to be done the opposite way to make
> our code compliant with spec.  i assume that it will then be a question 
> of when
> this will be removed rather than if. In such a scenario is this and 
> following
> patches/optimizations needed "at present" ?

How much of this needs to be removed in order to make the implementation spec
compliant? I was under the impression it would be sufficient to change the
signature of intel_dp_voltage_max() and intel_dp_pre_emphasis_max() and change
the way we store the maximums so we can query the max voltage for a given pre
-emphasis level. But perhaps this is more complicated than I'm anticipating. It
would be good if you could share your patch that fixes this issue to clarify
what's necessary.

Thanks,
Ander


> regards,
> Sivakumar
> On 10/23/2015 3:31 PM, Ander Conselvan de Oliveira wrote:
> > In order to clarify which platforms support which combination of voltage
> > swing and pre emphasis level, introduce struct intel_dp_signal_levels.
> > With the new struct, the if ladder to determine the values used is put
> > in one place, intel_dp_init_signal_levels().
> > 
> > This also wires gens 4, 5 and non-eDP ports on gen 6 and 7 to use the
> > new struct.
> > 
> > v2: Rebase
> > Signed-off-by: Ander Conselvan de Oliveira <
> > ander.conselvan.de.oliveira@intel.com>
> > ---
> >   drivers/gpu/drm/i915/intel_dp.c               |   2 +
> >   drivers/gpu/drm/i915/intel_dp_signal_levels.c | 103 ++++++++++++++++++++++
> > ----
> >   drivers/gpu/drm/i915/intel_drv.h              |  11 +++
> >   3 files changed, 101 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c
> > b/drivers/gpu/drm/i915/intel_dp.c
> > index 1236791..e640b59 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -5220,6 +5220,8 @@ intel_dp_init_connector(struct intel_digital_port
> > *intel_dig_port,
> >   	if (HAS_DDI(dev))
> >   		intel_dp->prepare_link_retrain =
> > intel_ddi_prepare_link_retrain;
> >   
> > +	intel_dp_init_signal_levels(intel_dp);
> > +
> >   	/* Preserve the current hw state. */
> >   	intel_dp->DP = I915_READ(intel_dp->output_reg);
> >   	intel_dp->attached_connector = intel_connector;
> > diff --git a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
> > b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
> > index e516dd2..365bdc4 100644
> > --- a/drivers/gpu/drm/i915/intel_dp_signal_levels.c
> > +++ b/drivers/gpu/drm/i915/intel_dp_signal_levels.c
> > @@ -24,8 +24,8 @@
> >   #include "intel_drv.h"
> >   
> >   /* These are source-specific values. */
> > -uint8_t
> > -intel_dp_voltage_max(struct intel_dp *intel_dp)
> > +static uint8_t
> > +_dp_voltage_max(struct intel_dp *intel_dp)
> >   {
> >   	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> >   	struct drm_i915_private *dev_priv = dev->dev_private;
> > @@ -47,8 +47,8 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
> >   		return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
> >   }
> >   
> > -uint8_t
> > -intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
> > +static uint8_t
> > +_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
> >   {
> >   	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> >   	enum port port = dp_to_dig_port(intel_dp)->port;
> > @@ -389,10 +389,10 @@ static uint32_t chv_signal_levels(struct intel_dp
> > *intel_dp)
> >   	return 0;
> >   }
> >   
> > -static uint32_t
> > -gen4_signal_levels(uint8_t train_set)
> > +static void
> > +gen4_set_signal_levels(struct intel_dp *intel_dp, uint8_t train_set)
> >   {
> > -	uint32_t	signal_levels = 0;
> > +	uint32_t signal_levels = 0;
> >   
> >   	switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
> >   	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
> > @@ -424,9 +424,38 @@ gen4_signal_levels(uint8_t train_set)
> >   		signal_levels |= DP_PRE_EMPHASIS_9_5;
> >   		break;
> >   	}
> > -	return signal_levels;
> > +
> > +	DRM_DEBUG_KMS("Using signal levels %08x\n", signal_levels);
> > +
> > +	intel_dp->DP &= ~(DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK);
> > +	intel_dp->DP |= signal_levels;
> >   }
> >   
> > +static const struct signal_levels gen4_signal_levels = {
> > +	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_2,
> > +	.max_pre_emph = {
> > +		DP_TRAIN_PRE_EMPH_LEVEL_2,
> > +		DP_TRAIN_PRE_EMPH_LEVEL_2,
> > +		DP_TRAIN_PRE_EMPH_LEVEL_1,
> > +		DP_TRAIN_PRE_EMPH_LEVEL_0,
> > +	},
> > +
> > +	.set = gen4_set_signal_levels,
> > +};
> > +
> > +/* Not for eDP */
> > +static const struct signal_levels snb_signal_levels = {
> > +	.max_voltage = DP_TRAIN_VOLTAGE_SWING_LEVEL_3,
> > +	.max_pre_emph = {
> > +		DP_TRAIN_PRE_EMPH_LEVEL_2,
> > +		DP_TRAIN_PRE_EMPH_LEVEL_2,
> > +		DP_TRAIN_PRE_EMPH_LEVEL_1,
> > +		DP_TRAIN_PRE_EMPH_LEVEL_0,
> > +	},
> > +
> > +	.set = gen4_set_signal_levels,
> > +};
> > +
> >   /* Gen6's DP voltage swing and pre-emphasis control */
> >   static uint32_t
> >   gen6_edp_signal_levels(uint8_t train_set)
> > @@ -486,13 +515,12 @@ gen7_edp_signal_levels(uint8_t train_set)
> >   	}
> >   }
> >   
> > -void
> > -intel_dp_set_signal_levels(struct intel_dp *intel_dp)
> > +static void
> > +_update_signal_levels(struct intel_dp *intel_dp)
> >   {
> >   	struct intel_digital_port *intel_dig_port =
> > dp_to_dig_port(intel_dp);
> >   	enum port port = intel_dig_port->port;
> >   	struct drm_device *dev = intel_dig_port->base.base.dev;
> > -	struct drm_i915_private *dev_priv = to_i915(dev);
> >   	uint32_t signal_levels, mask = 0;
> >   	uint8_t train_set = intel_dp->train_set[0];
> >   
> > @@ -514,21 +542,66 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
> >   		signal_levels = gen6_edp_signal_levels(train_set);
> >   		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
> >   	} else {
> > -		signal_levels = gen4_signal_levels(train_set);
> > -		mask = DP_VOLTAGE_MASK | DP_PRE_EMPHASIS_MASK;
> > +		WARN(1, "Should be calling intel_dp->signal_levels->set
> > instead.");
> > +		return;
> >   	}
> >   
> >   	if (mask)
> >   		DRM_DEBUG_KMS("Using signal levels %08x\n",
> > signal_levels);
> >   
> > +	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
> > +}
> > +
> > +uint8_t
> > +intel_dp_voltage_max(struct intel_dp *intel_dp)
> > +{
> > +	if (intel_dp->signal_levels)
> > +		return intel_dp->signal_levels->max_voltage;
> > +	else
> > +		return _dp_voltage_max(intel_dp);
> > +}
> > +
> > +uint8_t
> > +intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
> > +{
> > +	if (intel_dp->signal_levels)
> > +		return intel_dp->signal_levels
> > ->max_pre_emph[voltage_swing];
> > +	else
> > +		return _dp_pre_emphasis_max(intel_dp, voltage_swing);
> > +}
> > +
> > +void
> > +intel_dp_set_signal_levels(struct intel_dp *intel_dp)
> > +{
> > +	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> > +	struct drm_i915_private *dev_priv = to_i915(dev);
> > +	uint8_t train_set = intel_dp->train_set[0];
> > +
> > +	if (intel_dp->signal_levels)
> > +		intel_dp->signal_levels->set(intel_dp, train_set);
> > +	else
> > +		_update_signal_levels(intel_dp);
> > +
> >   	DRM_DEBUG_KMS("Using vswing level %d\n",
> >   		train_set & DP_TRAIN_VOLTAGE_SWING_MASK);
> >   	DRM_DEBUG_KMS("Using pre-emphasis level %d\n",
> >   		(train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
> >   			DP_TRAIN_PRE_EMPHASIS_SHIFT);
> >   
> > -	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
> > -
> >   	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
> >   	POSTING_READ(intel_dp->output_reg);
> >   }
> > +
> > +void
> > +intel_dp_init_signal_levels(struct intel_dp *intel_dp)
> > +{
> > +	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> > +	struct intel_digital_port *intel_dig_port =
> > dp_to_dig_port(intel_dp);
> > +	enum port port = intel_dig_port->port;
> > +
> > +	if (port != PORT_A && (IS_IVYBRIDGE(dev) || IS_GEN6(dev)))
> > +		intel_dp->signal_levels = &snb_signal_levels;
> > +
> > +	if (INTEL_INFO(dev)->gen <= 5)
> > +		intel_dp->signal_levels = &gen4_signal_levels;
> > +}
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > b/drivers/gpu/drm/i915/intel_drv.h
> > index d758e94..e00ce6c 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -726,6 +726,14 @@ struct sink_crc {
> >   	int last_count;
> >   };
> >   
> > +struct intel_dp;
> > +struct signal_levels {
> > +	uint8_t max_voltage;
> > +	uint8_t max_pre_emph[4];
> > +
> > +	void (*set)(struct intel_dp *intel_dp, uint8_t train_set);
> > +};
> > +
> >   struct intel_dp {
> >   	uint32_t output_reg;
> >   	uint32_t aux_ch_ctl_reg;
> > @@ -744,6 +752,7 @@ struct intel_dp {
> >   	int sink_rates[DP_MAX_SUPPORTED_RATES];
> >   	struct sink_crc sink_crc;
> >   	struct drm_dp_aux aux;
> > +	const struct signal_levels *signal_levels;
> >   	uint8_t train_set[4];
> >   	int panel_power_up_delay;
> >   	int panel_power_down_delay;
> > @@ -1263,6 +1272,8 @@ bool intel_dp_source_supports_hbr2(struct intel_dp
> > *intel_dp);
> >   bool
> >   intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t
> > link_status[DP_LINK_STATUS_SIZE]);
> >   
> > +void intel_dp_init_signal_levels(struct intel_dp *intel_dp);
> > +
> >   /* intel_dp_mst.c */
> >   int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port,
> > int conn_id);
> >   void intel_dp_mst_encoder_cleanup(struct intel_digital_port
> > *intel_dig_port);
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 07/22] drm/i915: Make intel_dp_source_supports_hbr2() take an intel_dp pointer
  2015-10-25  2:48   ` Thulasimani, Sivakumar
@ 2015-11-05 13:22     ` Ander Conselvan De Oliveira
  0 siblings, 0 replies; 34+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-11-05 13:22 UTC (permalink / raw)
  To: Thulasimani, Sivakumar, intel-gfx, jim.bride

On Sun, 2015-10-25 at 08:18 +0530, Thulasimani, Sivakumar wrote:
> Reviewed-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>

Thanks for reviewing. I pushed the patches up to here.

Ander

> On 10/23/2015 3:31 PM, Ander Conselvan de Oliveira wrote:
> > The function name implies it should get intel_dp, and it mostly used
> > where there is an intel_dp in the context.
> > 
> > Signed-off-by: Ander Conselvan de Oliveira <
> > ander.conselvan.de.oliveira@intel.com>
> > ---
> >   drivers/gpu/drm/i915/intel_dp.c               | 19 +++++++++++--------
> >   drivers/gpu/drm/i915/intel_dp_link_training.c |  4 +---
> >   drivers/gpu/drm/i915/intel_drv.h              |  2 +-
> >   3 files changed, 13 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c
> > b/drivers/gpu/drm/i915/intel_dp.c
> > index 5b04ade..5344de4 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -1189,8 +1189,11 @@ intel_dp_sink_rates(struct intel_dp *intel_dp, const
> > int **sink_rates)
> >   	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
> >   }
> >   
> > -bool intel_dp_source_supports_hbr2(struct drm_device *dev)
> > +bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
> >   {
> > +	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> > +	struct drm_device *dev = dig_port->base.base.dev;
> > +
> >   	/* WaDisableHBR2:skl */
> >   	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
> >   		return false;
> > @@ -1203,8 +1206,10 @@ bool intel_dp_source_supports_hbr2(struct drm_device
> > *dev)
> >   }
> >   
> >   static int
> > -intel_dp_source_rates(struct drm_device *dev, const int **source_rates)
> > +intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
> >   {
> > +	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> > +	struct drm_device *dev = dig_port->base.base.dev;
> >   	int size;
> >   
> >   	if (IS_BROXTON(dev)) {
> > @@ -1219,7 +1224,7 @@ intel_dp_source_rates(struct drm_device *dev, const
> > int **source_rates)
> >   	}
> >   
> >   	/* This depends on the fact that 5.4 is last value in the array */
> > -	if (!intel_dp_source_supports_hbr2(dev))
> > +	if (!intel_dp_source_supports_hbr2(intel_dp))
> >   		size--;
> >   
> >   	return size;
> > @@ -1284,12 +1289,11 @@ static int intersect_rates(const int *source_rates,
> > int source_len,
> >   static int intel_dp_common_rates(struct intel_dp *intel_dp,
> >   				 int *common_rates)
> >   {
> > -	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> >   	const int *source_rates, *sink_rates;
> >   	int source_len, sink_len;
> >   
> >   	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
> > -	source_len = intel_dp_source_rates(dev, &source_rates);
> > +	source_len = intel_dp_source_rates(intel_dp, &source_rates);
> >   
> >   	return intersect_rates(source_rates, source_len,
> >   			       sink_rates, sink_len,
> > @@ -1314,7 +1318,6 @@ static void snprintf_int_array(char *str, size_t len,
> >   
> >   static void intel_dp_print_rates(struct intel_dp *intel_dp)
> >   {
> > -	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> >   	const int *source_rates, *sink_rates;
> >   	int source_len, sink_len, common_len;
> >   	int common_rates[DP_MAX_SUPPORTED_RATES];
> > @@ -1323,7 +1326,7 @@ static void intel_dp_print_rates(struct intel_dp
> > *intel_dp)
> >   	if ((drm_debug & DRM_UT_KMS) == 0)
> >   		return;
> >   
> > -	source_len = intel_dp_source_rates(dev, &source_rates);
> > +	source_len = intel_dp_source_rates(intel_dp, &source_rates);
> >   	snprintf_int_array(str, sizeof(str), source_rates, source_len);
> >   	DRM_DEBUG_KMS("source rates: %s\n", str);
> >   
> > @@ -3711,7 +3714,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
> >   	}
> >   
> >   	DRM_DEBUG_KMS("Display Port TPS3 support: source %s, sink %s\n",
> > -		      yesno(intel_dp_source_supports_hbr2(dev)),
> > +		      yesno(intel_dp_source_supports_hbr2(intel_dp)),
> >   		      yesno(drm_dp_tps3_supported(intel_dp->dpcd)));
> >   
> >   	/* Intermediate frequency support */
> > diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c
> > b/drivers/gpu/drm/i915/intel_dp_link_training.c
> > index bb036d5..8888793 100644
> > --- a/drivers/gpu/drm/i915/intel_dp_link_training.c
> > +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
> > @@ -218,8 +218,6 @@ intel_dp_link_training_clock_recovery(struct intel_dp
> > *intel_dp)
> >   static void
> >   intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
> >   {
> > -	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> > -	struct drm_device *dev = dig_port->base.base.dev;
> >   	bool channel_eq = false;
> >   	int tries, cr_tries;
> >   	uint32_t training_pattern = DP_TRAINING_PATTERN_2;
> > @@ -233,7 +231,7 @@ intel_dp_link_training_channel_equalization(struct
> > intel_dp *intel_dp)
> >   	 * Due to WaDisableHBR2 SKL < B0 is the only exception where TPS3
> > is
> >   	 * supported but still not enabled.
> >   	 */
> > -	if (intel_dp_source_supports_hbr2(dev) &&
> > +	if (intel_dp_source_supports_hbr2(intel_dp) &&
> >   	    drm_dp_tps3_supported(intel_dp->dpcd))
> >   		training_pattern = DP_TRAINING_PATTERN_3;
> >   	else if (intel_dp->link_rate == 540000)
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > b/drivers/gpu/drm/i915/intel_drv.h
> > index 1c2a8ed..3021e40 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1252,7 +1252,7 @@ uint8_t
> >   intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t
> > voltage_swing);
> >   void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
> >   			   uint8_t *link_bw, uint8_t *rate_select);
> > -bool intel_dp_source_supports_hbr2(struct drm_device *dev);
> > +bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
> >   bool
> >   intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t
> > link_status[DP_LINK_STATUS_SIZE]);
> >   
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2015-11-05 13:22 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-23 10:01 [PATCH 00/22] DP refactoring v2 Ander Conselvan de Oliveira
2015-10-23 10:01 ` [PATCH 01/22] drm/i915: Don't pass *DP around to link training functions Ander Conselvan de Oliveira
2015-10-25  2:01   ` Thulasimani, Sivakumar
2015-10-23 10:01 ` [PATCH 02/22] drm/i915: Split write of pattern to DP reg from intel_dp_set_link_train Ander Conselvan de Oliveira
2015-10-25  2:06   ` Thulasimani, Sivakumar
2015-10-23 10:01 ` [PATCH 03/22] drm/i915 Call get_adjust_train() from clock recovery and channel eq Ander Conselvan de Oliveira
2015-10-25  2:11   ` Thulasimani, Sivakumar
2015-10-23 10:01 ` [PATCH 04/22] drm/i915: Move register write into intel_dp_set_signal_levels() Ander Conselvan de Oliveira
2015-10-25  2:28   ` Thulasimani, Sivakumar
2015-10-23 10:01 ` [PATCH 05/22] drm/i915: Move generic link training code to a separate file Ander Conselvan de Oliveira
2015-10-25  2:37   ` Thulasimani, Sivakumar
2015-10-23 10:01 ` [PATCH 06/22] drm/i915: Create intel_dp->prepare_link_retrain() hook Ander Conselvan de Oliveira
2015-10-25  2:40   ` Thulasimani, Sivakumar
2015-10-23 10:01 ` [PATCH 07/22] drm/i915: Make intel_dp_source_supports_hbr2() take an intel_dp pointer Ander Conselvan de Oliveira
2015-10-25  2:48   ` Thulasimani, Sivakumar
2015-11-05 13:22     ` Ander Conselvan De Oliveira
2015-10-23 10:01 ` [PATCH 08/22] drm/i915: Move link training setup code to separate functions (v2) Ander Conselvan de Oliveira
2015-10-23 10:01 ` [PATCH 09/22] drm/i915: Move test for max voltage on all lanes to separate function Ander Conselvan de Oliveira
2015-10-23 10:01 ` [PATCH 10/22] drm/i915: Add function for getting the current link training voltage Ander Conselvan de Oliveira
2015-10-25  3:56   ` Thulasimani, Sivakumar
2015-10-23 10:01 ` [PATCH 11/22] drm/i915: Split full retries loop out of clock recovery code (v2) Ander Conselvan de Oliveira
2015-10-23 10:01 ` [PATCH 12/22] drm/i915: Make the link training test for same voltage smaller Ander Conselvan de Oliveira
2015-10-23 10:01 ` [PATCH 13/22] drm/i915: Move the voltage changed check into intel_get_adjust_train() Ander Conselvan de Oliveira
2015-10-23 10:01 ` [PATCH 14/22] drm/i915: Add missing newline to link training debug message Ander Conselvan de Oliveira
2015-10-23 10:01 ` [PATCH 15/22] drm/i915: Split setting of vswing and pre_emph levels to separate file Ander Conselvan de Oliveira
2015-10-23 10:01 ` [PATCH 16/22] drm/i915: Introduce struct intel_dp_signal_levels Ander Conselvan de Oliveira
2015-10-25  5:24   ` Thulasimani, Sivakumar
2015-10-26  7:22     ` Ander Conselvan De Oliveira
2015-10-23 10:02 ` [PATCH 17/22] drm/i915: Use struct intel_dp_signal_levels for eDP on SNB and IVB Ander Conselvan de Oliveira
2015-10-23 10:02 ` [PATCH 18/22] drm/i915: Use struct intel_dp_signal_levels for VLV Ander Conselvan de Oliveira
2015-10-23 10:02 ` [PATCH 19/22] drm/i915: Use struct intel_dp_signal_levels for CHV Ander Conselvan de Oliveira
2015-10-23 10:02 ` [PATCH 20/22] drm/i915: Use struct intel_dp_signal_levels for DDI platforms Ander Conselvan de Oliveira
2015-10-23 10:02 ` [PATCH 21/22] drm/i915: Remove old functions for maximum DP vswing and pre-emph levels Ander Conselvan de Oliveira
2015-10-23 10:02 ` [PATCH 22/22] drm/i915: Move ddi_signal_levels() to intel_dp_signal_levels.c Ander Conselvan de Oliveira

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.