lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 28 Jul 2015 12:03:27 -0400
From:	Benjamin Tissoires <benjamin.tissoires@...hat.com>
To:	Daniel Vetter <daniel.vetter@...el.com>
Cc:	Stéphane Marchesin <marcheu@...omium.org>,
	Todd Broch <tbroch@...omium.org>,
	intel-gfx@...ts.freedesktop.org, linux-kernel@...r.kernel.org,
	Benjamin Tissoires <benjamin.tissoires@...hat.com>
Subject: [PATCH 1/3] drm/i915: add parameters to dp_start_link_train and dp_complete_link_train

In order to detect if the Display Port is reversed or not (when connected
to a USC type-C connector), we need to probe the training with one lane
to check if the polarity is correct.
Factor out the code that we need later on.

This commit has no functional change

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@...hat.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 75 ++++++++++++++++++++++++++---------------
 1 file changed, 47 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f1b9f93..f2352d8 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3566,15 +3566,15 @@ static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
 }
 
 /* Enable corresponding port and start training pattern 1 */
-void
-intel_dp_start_link_train(struct intel_dp *intel_dp)
+static bool
+_intel_dp_start_link_train(struct intel_dp *intel_dp, uint8_t lane_count,
+			   uint32_t *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;
-	uint32_t DP = intel_dp->DP;
 	uint8_t link_config[2];
 
 	if (HAS_DDI(dev))
@@ -3582,7 +3582,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 
 	/* Write the link configuration data */
 	link_config[0] = intel_dp->link_bw;
-	link_config[1] = intel_dp->lane_count;
+	link_config[1] = 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);
@@ -3594,14 +3594,14 @@ intel_dp_start_link_train(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;
+	*DP |= DP_PORT_EN;
 
 	/* clock recovery */
-	if (!intel_dp_reset_link_train(intel_dp, &DP,
+	if (!intel_dp_reset_link_train(intel_dp, DP,
 				       DP_TRAINING_PATTERN_1 |
 				       DP_LINK_SCRAMBLING_DISABLE)) {
 		DRM_ERROR("failed to enable link training\n");
-		return;
+		return false;
 	}
 
 	voltage = 0xff;
@@ -3616,7 +3616,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 			break;
 		}
 
-		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
+		if (drm_dp_clock_recovery_ok(link_status, lane_count)) {
 			DRM_DEBUG_KMS("clock recovery OK\n");
 			break;
 		}
@@ -3629,26 +3629,26 @@ intel_dp_start_link_train(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,
 						       DP_TRAINING_PATTERN_1 |
 						       DP_LINK_SCRAMBLING_DISABLE)) {
 				DRM_ERROR("failed to enable link training\n");
-				return;
+				return false;
 			}
 			continue;
 		}
 
 		/* Check to see if we've tried the max voltage */
-		for (i = 0; i < intel_dp->lane_count; i++)
+		for (i = 0; i < lane_count; i++)
 			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
 				break;
-		if (i == intel_dp->lane_count) {
+		if (i == 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,
+			intel_dp_reset_link_train(intel_dp, DP,
 						  DP_TRAINING_PATTERN_1 |
 						  DP_LINK_SCRAMBLING_DISABLE);
 			voltage_tries = 0;
@@ -3667,21 +3667,31 @@ intel_dp_start_link_train(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, DP, link_status)) {
 			DRM_ERROR("failed to update link training\n");
 			break;
 		}
 	}
 
-	intel_dp->DP = DP;
+	return true;
 }
 
+/* Enable corresponding port and start training pattern 1 */
 void
-intel_dp_complete_link_train(struct intel_dp *intel_dp)
+intel_dp_start_link_train(struct intel_dp *intel_dp)
+{
+	uint32_t DP = intel_dp->DP;
+
+	if (_intel_dp_start_link_train(intel_dp, intel_dp->lane_count, &DP))
+		intel_dp->DP = DP;
+}
+
+static bool
+_intel_dp_complete_link_train(struct intel_dp *intel_dp, uint8_t lane_count,
+			      uint32_t *DP)
 {
 	bool channel_eq = false;
 	int tries, cr_tries;
-	uint32_t DP = intel_dp->DP;
 	uint32_t training_pattern = DP_TRAINING_PATTERN_2;
 
 	/* Training Pattern 3 for HBR2 ot 1.2 devices that support it*/
@@ -3689,11 +3699,11 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 		training_pattern = DP_TRAINING_PATTERN_3;
 
 	/* channel equalization */
-	if (!intel_dp_set_link_train(intel_dp, &DP,
+	if (!intel_dp_set_link_train(intel_dp, DP,
 				     training_pattern |
 				     DP_LINK_SCRAMBLING_DISABLE)) {
 		DRM_ERROR("failed to start channel equalization\n");
-		return;
+		return false;
 	}
 
 	tries = 0;
@@ -3714,17 +3724,17 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 		}
 
 		/* Make sure clock is still ok */
-		if (!drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
+		if (!drm_dp_clock_recovery_ok(link_status, lane_count)) {
 			intel_dp->train_set_valid = false;
-			intel_dp_start_link_train(intel_dp);
-			intel_dp_set_link_train(intel_dp, &DP,
+			_intel_dp_start_link_train(intel_dp, lane_count, DP);
+			intel_dp_set_link_train(intel_dp, DP,
 						training_pattern |
 						DP_LINK_SCRAMBLING_DISABLE);
 			cr_tries++;
 			continue;
 		}
 
-		if (drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) {
+		if (drm_dp_channel_eq_ok(link_status, lane_count)) {
 			channel_eq = true;
 			break;
 		}
@@ -3732,8 +3742,8 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 		/* Try 5 times, then try clock recovery if that fails */
 		if (tries > 5) {
 			intel_dp->train_set_valid = false;
-			intel_dp_start_link_train(intel_dp);
-			intel_dp_set_link_train(intel_dp, &DP,
+			_intel_dp_start_link_train(intel_dp);
+			intel_dp_set_link_train(intel_dp, DP,
 						training_pattern |
 						DP_LINK_SCRAMBLING_DISABLE);
 			tries = 0;
@@ -3742,7 +3752,7 @@ intel_dp_complete_link_train(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, DP, link_status)) {
 			DRM_ERROR("failed to update link training\n");
 			break;
 		}
@@ -3751,12 +3761,21 @@ intel_dp_complete_link_train(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");
 	}
+
+	return channel_eq;
+}
+
+void
+intel_dp_complete_link_train(struct intel_dp *intel_dp)
+{
+	uint32_t DP = intel_dp->DP;
+
+	if (_intel_dp_complete_link_train(intel_dp, intel_dp->lane_count, &DP))
+		intel_dp->DP = DP;
 }
 
 void intel_dp_stop_link_train(struct intel_dp *intel_dp)
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ