From: Kunal Joshi <kunal1.joshi@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: Kunal Joshi <kunal1.joshi@intel.com>
Subject: [PATCH i-g-t 04/13] tests/intel/kms_dp_link_training: Check the config survived training
Date: Wed, 16 Sep 2026 10:17:52 +0530 [thread overview]
Message-ID: <20260916044801.1279102-5-kunal1.joshi@intel.com> (raw)
In-Reply-To: <20260916044801.1279102-1-kunal1.joshi@intel.com>
The test asserts that the current link rate equals the rate it forced.
Both values come from the same debugfs file, which the kernel prints
from intel_dp->link_rate, the rate the driver asked the sink for, not
the rate the link ended up running at. A link that failed training and
fell back still reads back the forced value, so the assertion passes on
a link that never trained. The FIXME in the test says as much.
link-status does not close the gap either. With both the rate and the
lane count forced there is nothing to fall back to, so the driver never
reaches intel_dp_queue_modeset_retry_for_link() and link-status stays
GOOD on a link that failed for good. What it does instead is mark
retraining disabled, which i915_dp_link_retrain_disabled exposes. Assert
on that.
Wait for the verdict rather than reading it once. The driver clears the
forced retrain flag when the retrain modeset starts and only then queues
its automatic retrain, so when the test's poll for the flag completes
the first failure is still in flight. Recovery ends either with a
trained link or with retraining disabled, so poll for the whole recovery
timeout before calling the link trained.
Read the state before the next force: forcing a rate or a lane count
runs intel_dp_reset_link_params(), which resets the recovery state and
would mask the failure.
Drop the FIXME.
Note this can newly fail a link whose advertised maximum never trained.
That is the bug the FIXME was placed for.
Assisted-by: GitHub_Copilot:claude-opus-5
Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
---
tests/intel/kms_dp_link_training.c | 57 ++++++++++++++++++++++++++++--
1 file changed, 55 insertions(+), 2 deletions(-)
diff --git a/tests/intel/kms_dp_link_training.c b/tests/intel/kms_dp_link_training.c
index 595d78d98..b2d686f28 100644
--- a/tests/intel/kms_dp_link_training.c
+++ b/tests/intel/kms_dp_link_training.c
@@ -29,6 +29,13 @@
#define RETRAIN_COUNT 1
+/*
+ * How long the driver's link recovery is given to reach a verdict, in seconds.
+ * The automatic retrain is queued without a delay, so this only has to cover
+ * one retrain and the fallback selection that follows it.
+ */
+#define LINK_RECOVERY_TIMEOUT 5.0
+
typedef struct {
int drm_fd;
uint32_t devid;
@@ -99,9 +106,46 @@ static void assert_link_status_good(data_t *data, bool mst)
}
}
+/*
+ * assert_link_recovery_idle - Let the driver's link recovery reach a verdict
+ * and check it had nothing to recover.
+ *
+ * A failed training is not visible the moment the forced retrain flag clears:
+ * the driver clears that flag when the retrain modeset starts and only then
+ * queues its automatic retrain, so the first failure is still in flight. Once
+ * the automatic retrain is used up the driver looks for a configuration to
+ * fall back to, and with both the rate and the lane count forced there is
+ * none. It then marks retraining disabled, which is the one place a link that
+ * failed for good becomes visible.
+ *
+ * Poll for that verdict rather than reading it once, and give recovery the
+ * full timeout to reach it before calling the link trained.
+ */
+static void assert_link_recovery_idle(data_t *data,
+ const struct i915_dp_link_config *config)
+{
+ struct timespec start, now;
+ double elapsed;
+
+ clock_gettime(CLOCK_MONOTONIC, &start);
+
+ do {
+ igt_assert_f(!i915_dp_get_link_retrain_disabled(data->drm_fd,
+ data->output),
+ "Link training at %d lanes, rate %d was given up on.\n",
+ config->lane_count, config->link_rate);
+
+ usleep(200 * 1000);
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ elapsed = (now.tv_sec - start.tv_sec) +
+ (now.tv_nsec - start.tv_nsec) / 1e9;
+ } while (elapsed < LINK_RECOVERY_TIMEOUT);
+}
+
/*
* train_link_config - Force one link configuration, re-establish the link and
- * check that the configuration took effect.
+ * check that the configuration took effect and survived training.
*/
static void train_link_config(data_t *data, bool mst,
const struct i915_dp_link_config *config)
@@ -127,6 +171,16 @@ static void train_link_config(data_t *data, bool mst,
igt_info("Current link rate is %d\n", current_link_rate);
igt_assert_f(current_link_rate == config->link_rate,
"Link training did not succeed at the forced link rate.\n");
+
+ /*
+ * The link parameters read back above are the ones the driver asked
+ * the sink for, not the ones the link ended up running at, so ask the
+ * driver whether it had to recover the link after training it.
+ *
+ * This has to happen before the next force: forcing a rate or a lane
+ * count resets the recovery state, which would mask the failure.
+ */
+ assert_link_recovery_idle(data, config);
}
/*
@@ -222,7 +276,6 @@ static bool run_link_rate_test(data_t *data, bool mst, bool uhbr)
1.0, 20.0), 0);
assert_link_status_good(data, mst);
- /* FIXME : Driver may lie max link rate or max lane count */
/* Read max_link_rate and max_lane_count */
config.link_rate = i915_dp_get_max_link_rate(data->drm_fd, data->output);
config.lane_count = i915_dp_get_max_lane_count(data->drm_fd, data->output);
--
2.25.1
next prev parent reply other threads:[~2026-09-16 4:29 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-16 4:47 [PATCH i-g-t 00/13] Expand kms_dp_link_training coverage Kunal Joshi
2026-09-16 4:47 ` [PATCH i-g-t 01/13] lib/i915/i915_dp: Add helpers for the allowed link configs debugfs Kunal Joshi
2026-09-21 8:37 ` S, Sowmiya
2026-09-16 4:47 ` [PATCH i-g-t 02/13] tests/intel/kms_dp_link_training: Use the UHBR helpers from lib Kunal Joshi
2026-09-21 8:38 ` S, Sowmiya
2026-09-16 4:47 ` [PATCH i-g-t 03/13] tests/intel/kms_dp_link_training: Extract train_link_config() Kunal Joshi
2026-09-22 11:51 ` S, Sowmiya
2026-09-16 4:47 ` Kunal Joshi [this message]
2026-09-22 5:25 ` [PATCH i-g-t 04/13] tests/intel/kms_dp_link_training: Check the config survived training S, Sowmiya
2026-09-16 4:47 ` [PATCH i-g-t 05/13] tests/intel/kms_dp_link_training: Drive the smallest mode the sink offers Kunal Joshi
2026-09-22 11:59 ` S, Sowmiya
2026-09-16 4:47 ` [PATCH i-g-t 06/13] tests/intel/kms_dp_link_training: Train every allowed link config Kunal Joshi
2026-09-22 13:51 ` S, Sowmiya
2026-09-16 4:47 ` [PATCH i-g-t 07/13] lib/i915/i915_dp: Add a Type-C port mode query Kunal Joshi
2026-09-22 14:55 ` S, Sowmiya
2026-09-16 4:47 ` [PATCH i-g-t 08/13] tests/intel/kms_dp_link_training: Log the DP link inventory in the fixture Kunal Joshi
2026-09-23 12:46 ` S, Sowmiya
2026-09-16 4:47 ` [PATCH i-g-t 09/13] tests/intel/kms_dp_link_training: Group the outputs into links Kunal Joshi
2026-09-23 13:10 ` S, Sowmiya
2026-09-16 4:47 ` [PATCH i-g-t 10/13] tests/intel/kms_dp_link_training: Add per connector mode subtests Kunal Joshi
2026-09-23 13:29 ` S, Sowmiya
2026-09-16 4:47 ` [PATCH i-g-t 11/13] lib/igt_dp: Add DPCD read helpers Kunal Joshi
2026-09-23 13:34 ` S, Sowmiya
2026-09-16 4:48 ` [PATCH i-g-t 12/13] lib/igt_dp: Add link status predicates for both channel codings Kunal Joshi
2026-09-23 13:55 ` S, Sowmiya
2026-09-16 4:48 ` [PATCH i-g-t 13/13] tests/intel/kms_dp_link_training: Verify the trained link from the sink side Kunal Joshi
2026-09-23 14:00 ` S, Sowmiya
2026-09-16 5:08 ` ✓ Xe.CI.BAT: success for Expand kms_dp_link_training coverage Patchwork
2026-09-16 5:25 ` ✓ i915.CI.BAT: " Patchwork
2026-09-16 6:15 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-09-16 11:59 ` ✗ i915.CI.Full: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260916044801.1279102-5-kunal1.joshi@intel.com \
--to=kunal1.joshi@intel.com \
--cc=igt-dev@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.