summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2026-06-01 12:38:28 +0300
committerImre Deak <imre.deak@intel.com>2026-06-08 19:50:55 +0300
commit4ba52dc9b4e088ef1eb574ab92565e866f2160c4 (patch)
treeea5d818183588b515dc058bbe20207cf9451bd3f
parent1536edeee040f98455b6117a2f57bf54fab088b3 (diff)
drm/i915/dp_link_training: Track link recovery state with an enum
Replace the sequential link training failure counter with an explicit link recovery state enum. This makes the recovery states and transitions clearer: idle, automatic retraining pending, and automatic retraining disabled. A follow-up change will also move the retrain_disabled flag into this enum. v2: (Jani) - Convert enum intel_dp_link_recovery_state's documentation to be a non kernel-doc comment. - Compare against / set enum values explicitly. Cc: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Mika Kahola <mika.kahola@intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://patch.msgid.link/20260601093836.3057345-16-imre.deak@intel.com
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.c71
1 files changed, 62 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index dc1ad0fc6bd8..7f0918b9b698 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -62,14 +62,54 @@
lt_dbg(_intel_dp, _dp_phy, "Sink disconnected: " _format, ## __VA_ARGS__); \
} while (0)
-#define MAX_SEQ_TRAIN_FAILURES 2
+/*
+ * enum intel_dp_link_recovery_state - LT recovery state
+ * @INTEL_DP_LINK_RECOVERY_IDLE:
+ * No link training failure is currently tracked and no recovery is
+ * in progress. This is the initial state after driver initialization,
+ * power state transitions, sink (re-)connection, or after a successful
+ * link training.
+ *
+ * @INTEL_DP_LINK_RECOVERY_AUTORETRAIN_PENDING:
+ * A first link training failure has been observed and an automatic
+ * retraining attempt with the same link parameters is pending. Exactly
+ * one such attempt is allowed before switching to userspace-driven
+ * recovery.
+ *
+ * @INTEL_DP_LINK_RECOVERY_AUTORETRAIN_DISABLED:
+ * Automatic retraining is no longer possible. At this point, a
+ * fallback selection is made and userspace is notified to take over
+ * recovery, performing modesets with parameters it determines are
+ * required. The driver then selects a link configuration from the
+ * remaining fallback configuration set. Subsequent link training
+ * failures trigger further fallback selections and userspace
+ * notifications.
+ *
+ * Describes the link recovery state used by the Intel DP link recovery
+ * logic.
+ *
+ * See also:
+ * - link_recovery_autoretrain_pending()
+ * - link_recovery_autoretrain_allowed()
+ * - link_recovery_mark_train_failure()
+ * - link_recovery_reset()
+ */
+enum intel_dp_link_recovery_state {
+ /*
+ * Keep the enum values ordered from least to most severe
+ * recovery state; helper logic relies on that ordering.
+ */
+ INTEL_DP_LINK_RECOVERY_IDLE,
+ INTEL_DP_LINK_RECOVERY_AUTORETRAIN_PENDING,
+ INTEL_DP_LINK_RECOVERY_AUTORETRAIN_DISABLED,
+};
struct intel_dp_link_training {
struct intel_dp *dp;
+ enum intel_dp_link_recovery_state recovery_state;
+
bool retrain_disabled;
- /* Sequential link training failures after a passing LT */
- int seq_train_failures;
int force_train_failure;
bool force_retrain;
};
@@ -1267,7 +1307,7 @@ intel_dp_128b132b_intra_hop(struct intel_dp *intel_dp,
static bool
link_recovery_autoretrain_pending(struct intel_dp_link_training *link_training)
{
- return link_training->seq_train_failures == 1;
+ return link_training->recovery_state == INTEL_DP_LINK_RECOVERY_AUTORETRAIN_PENDING;
}
/*
@@ -1289,7 +1329,13 @@ link_recovery_autoretrain_pending(struct intel_dp_link_training *link_training)
static bool
link_recovery_autoretrain_allowed(struct intel_dp_link_training *link_training)
{
- return link_training->seq_train_failures < MAX_SEQ_TRAIN_FAILURES;
+ switch (link_training->recovery_state) {
+ case INTEL_DP_LINK_RECOVERY_IDLE:
+ case INTEL_DP_LINK_RECOVERY_AUTORETRAIN_PENDING:
+ return true;
+ default:
+ return false;
+ }
}
/*
@@ -1307,9 +1353,16 @@ link_recovery_autoretrain_allowed(struct intel_dp_link_training *link_training)
static bool
link_recovery_mark_train_failure(struct intel_dp_link_training *link_training)
{
- if (link_recovery_autoretrain_allowed(link_training))
- /* Move to autoretrain pending or autoretrain disabled state. */
- link_training->seq_train_failures++;
+ switch (link_training->recovery_state) {
+ case INTEL_DP_LINK_RECOVERY_IDLE:
+ link_training->recovery_state = INTEL_DP_LINK_RECOVERY_AUTORETRAIN_PENDING;
+ break;
+ case INTEL_DP_LINK_RECOVERY_AUTORETRAIN_PENDING:
+ link_training->recovery_state = INTEL_DP_LINK_RECOVERY_AUTORETRAIN_DISABLED;
+ break;
+ default:
+ break;
+ }
return link_recovery_autoretrain_allowed(link_training);
}
@@ -1323,7 +1376,7 @@ link_recovery_mark_train_failure(struct intel_dp_link_training *link_training)
*/
static void link_recovery_reset(struct intel_dp_link_training *link_training)
{
- link_training->seq_train_failures = 0;
+ link_training->recovery_state = INTEL_DP_LINK_RECOVERY_IDLE;
}
/**