drm/i915: Make DP link training channel equalization DP 1.2 Spec compliant

Fix the number of tries in channel euqalization link training sequence
according to DP 1.2 Spec. It returns a boolean depending on channel
equalization pass or failure.

Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
This commit is contained in:
Navare, Manasi D 2016-09-01 15:08:15 -07:00 committed by Rodrigo Vivi
parent 13b1996e84
commit c92bd2fa33
2 changed files with 22 additions and 36 deletions

View file

@ -244,12 +244,12 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
return training_pattern; return training_pattern;
} }
static void static bool
intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
{ {
bool channel_eq = false; int tries;
int tries, cr_tries;
u32 training_pattern; u32 training_pattern;
uint8_t link_status[DP_LINK_STATUS_SIZE];
training_pattern = intel_dp_training_pattern(intel_dp); training_pattern = intel_dp_training_pattern(intel_dp);
@ -258,20 +258,11 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
training_pattern | training_pattern |
DP_LINK_SCRAMBLING_DISABLE)) { DP_LINK_SCRAMBLING_DISABLE)) {
DRM_ERROR("failed to start channel equalization\n"); DRM_ERROR("failed to start channel equalization\n");
return; return false;
} }
tries = 0; intel_dp->channel_eq_status = false;
cr_tries = 0; for (tries = 0; tries < 5; tries++) {
channel_eq = false;
for (;;) {
uint8_t link_status[DP_LINK_STATUS_SIZE];
if (cr_tries > 5) {
DRM_ERROR("failed to train DP, aborting\n");
intel_dp_dump_link_status(link_status);
break;
}
drm_dp_link_train_channel_eq_delay(intel_dp->dpcd); drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
if (!intel_dp_get_link_status(intel_dp, link_status)) { if (!intel_dp_get_link_status(intel_dp, link_status)) {
@ -282,44 +273,38 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
/* Make sure clock is still ok */ /* Make sure clock is still ok */
if (!drm_dp_clock_recovery_ok(link_status, if (!drm_dp_clock_recovery_ok(link_status,
intel_dp->lane_count)) { intel_dp->lane_count)) {
intel_dp_link_training_clock_recovery(intel_dp); intel_dp_dump_link_status(link_status);
intel_dp_set_link_train(intel_dp, DRM_DEBUG_KMS("Clock recovery check failed, cannot "
training_pattern | "continue channel equalization\n");
DP_LINK_SCRAMBLING_DISABLE); break;
cr_tries++;
continue;
} }
if (drm_dp_channel_eq_ok(link_status, if (drm_dp_channel_eq_ok(link_status,
intel_dp->lane_count)) { intel_dp->lane_count)) {
channel_eq = true; intel_dp->channel_eq_status = true;
DRM_DEBUG_KMS("Channel EQ done. DP Training "
"successful\n");
break; break;
} }
/* Try 5 times, then try clock recovery if that fails */
if (tries > 5) {
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 */ /* Update training set as requested by target */
intel_get_adjust_train(intel_dp, link_status); intel_get_adjust_train(intel_dp, link_status);
if (!intel_dp_update_link_train(intel_dp)) { if (!intel_dp_update_link_train(intel_dp)) {
DRM_ERROR("failed to update link training\n"); DRM_ERROR("failed to update link training\n");
break; break;
} }
++tries; }
/* Try 5 times, else fail and try at lower BW */
if (tries == 5) {
intel_dp_dump_link_status(link_status);
DRM_DEBUG_KMS("Channel equalization failed 5 times\n");
} }
intel_dp_set_idle_link_train(intel_dp); intel_dp_set_idle_link_train(intel_dp);
if (channel_eq) return intel_dp->channel_eq_status;
DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
} }
void intel_dp_stop_link_train(struct intel_dp *intel_dp) void intel_dp_stop_link_train(struct intel_dp *intel_dp)

View file

@ -878,6 +878,7 @@ struct intel_dp {
bool link_mst; bool link_mst;
bool has_audio; bool has_audio;
bool detect_done; bool detect_done;
bool channel_eq_status;
enum hdmi_force_audio force_audio; enum hdmi_force_audio force_audio;
bool limited_color_range; bool limited_color_range;
bool color_range_auto; bool color_range_auto;