mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 10:29:37 +00:00
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:
parent
13b1996e84
commit
c92bd2fa33
2 changed files with 22 additions and 36 deletions
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue