@@ -4748,6 +4748,7 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
intel_dp->reset_link_params = false;
+ intel_dp->train_set_valid = false;
}
intel_dp_print_rates(intel_dp);
@@ -6017,6 +6018,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
intel_dp_set_source_rates(intel_dp);
intel_dp->reset_link_params = true;
+ intel_dp->train_set_valid = false;
intel_dp->pps_pipe = INVALID_PIPE;
intel_dp->active_pipe = INVALID_PIPE;
@@ -94,7 +94,8 @@ static bool
intel_dp_reset_link_train(struct intel_dp *intel_dp,
uint8_t dp_train_pat)
{
- memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
+ 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);
}
@@ -162,9 +163,18 @@ 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");
+ intel_dp->train_set_valid = false;
return false;
}
+ /*
+ * The initial set of link parameters are set by this point, so go
+ * ahead and set intel_dp->train_set_valid to false in case any of
+ * the succeeding steps fail. It will be set back to true if we were
+ * able to achieve clock recovery in the specified configuration.
+ */
+ intel_dp->train_set_valid = false;
+
voltage_tries = 1;
max_vswing_tries = 0;
for (;;) {
@@ -179,6 +189,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
DRM_DEBUG_KMS("clock recovery OK\n");
+ intel_dp->train_set_valid = intel_dp_is_edp(intel_dp);
return true;
}
@@ -256,6 +267,7 @@ 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");
+ intel_dp->train_set_valid = false;
return false;
}
@@ -296,6 +308,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
/* Try 5 times, else fail and try at lower BW */
if (tries == 5) {
intel_dp_dump_link_status(link_status);
+ intel_dp->train_set_valid = false;
DRM_DEBUG_KMS("Channel equalization failed 5 times\n");
}
@@ -987,6 +987,7 @@ struct intel_dp {
struct drm_dp_aux aux;
enum intel_display_power_domain aux_power_domain;
uint8_t train_set[4];
+ bool train_set_valid;
int panel_power_up_delay;
int panel_power_down_delay;
int panel_power_cycle_delay;