[PATCH 1/3] drm/i915: add parameters to dp_start_link_train and dp_complete_link_train

From: Benjamin Tissoires
Date: Tue Jul 28 2015 - 12:04:58 EST


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@xxxxxxxxxx>
---
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@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/