Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Kunal Joshi <kunal1.joshi@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: Kunal Joshi <kunal1.joshi@intel.com>, Sowmiya S <sowmiya.s@intel.com>
Subject: [PATCH i-g-t 12/13] lib/igt_dp: add DPCD link status and channel coding checks
Date: Thu,  1 Oct 2026 13:07:02 +0530	[thread overview]
Message-ID: <20261001073703.5067-13-kunal1.joshi@intel.com> (raw)
In-Reply-To: <20261001073703.5067-1-kunal1.joshi@intel.com>

Add igt_dp_link_status_ok() for checking from the sink's DPCD that all
the lanes in use are locked and aligned. 128b/132b has no clock
recovery, and has a separate bit for training failure, so handle both
channel codings, similar to drm_dp_channel_eq_ok() and the
drm_dp_128b132b_*() helpers in the kernel.

Add igt_dp_channel_coding_ok() for checking that
MAIN_LINK_CHANNEL_CODING_SET matches the expected channel coding.

Both return 1 or 0, or a negative error code if the DPCD can't be read,
so the callers can tell a failed check from a failed read.

Assisted-by: GitHub_Copilot:claude-opus-5
Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
Reviewed-by: Sowmiya S <sowmiya.s@intel.com>
---
 lib/igt_dp.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_dp.h |   4 ++
 2 files changed, 107 insertions(+)

diff --git a/lib/igt_dp.c b/lib/igt_dp.c
index 0b1fe73de..a7d9f1e77 100644
--- a/lib/igt_dp.c
+++ b/lib/igt_dp.c
@@ -281,3 +281,106 @@ int igt_dp_dpcd_read_byte(int aux_fd, unsigned int offset, uint8_t *val)
 
 	return ret == 1 ? 0 : -EIO;
 }
+
+/*
+ * DPCD registers and bits used by the sink side link checks, mirroring the
+ * kernel's include/drm/display/drm_dp.h.
+ */
+#define DPCD_MAIN_LINK_CHANNEL_CODING_SET	0x108
+#define  DPCD_SET_ANSI_8B10B			(1 << 0)
+#define  DPCD_SET_ANSI_128B132B			(1 << 1)
+
+#define DPCD_LANE0_1_STATUS			0x202
+#define DPCD_LINK_STATUS_SIZE			6
+#define  DPCD_LANE_CR_DONE			(1 << 0)
+#define  DPCD_LANE_CHANNEL_EQ_DONE		(1 << 1)
+#define  DPCD_LANE_SYMBOL_LOCKED		(1 << 2)
+
+/* DP_LANE_ALIGN_STATUS_UPDATED, the third byte of the status block. */
+#define  DPCD_INTERLANE_ALIGN_DONE		(1 << 0)
+#define  DPCD_128B132B_LT_FAILED		(1 << 4)
+
+static uint8_t dpcd_lane_status(const uint8_t link_status[DPCD_LINK_STATUS_SIZE],
+				int lane)
+{
+	return (link_status[lane / 2] >> (4 * (lane % 2))) & 0xf;
+}
+
+/**
+ * igt_dp_channel_coding_ok: Check the channel coding the sink was told to use
+ * @aux_fd:	AUX channel device file descriptor from igt_dp_aux_open()
+ * @uhbr:	Whether 128b/132b is expected
+ *
+ * Read MAIN_LINK_CHANNEL_CODING_SET and check that it selects the encoding the
+ * link rate implies. This is the only direct evidence that the coding a UHBR
+ * rate implies is the coding that reached the wire.
+ *
+ * Returns:
+ * 1 when the expected coding is selected, 0 when it is not, or a negative
+ * error code when the DPCD could not be read.
+ */
+int igt_dp_channel_coding_ok(int aux_fd, bool uhbr)
+{
+	uint8_t coding;
+	int ret;
+
+	ret = igt_dp_dpcd_read_byte(aux_fd, DPCD_MAIN_LINK_CHANNEL_CODING_SET,
+				    &coding);
+	if (ret < 0)
+		return ret;
+
+	return !!(coding & (uhbr ? DPCD_SET_ANSI_128B132B : DPCD_SET_ANSI_8B10B));
+}
+
+/**
+ * igt_dp_link_status_ok: Check the sink considers the link trained
+ * @aux_fd:	AUX channel device file descriptor from igt_dp_aux_open()
+ * @lane_count:	Number of lanes in use
+ * @uhbr:	Whether the link runs at a UHBR rate, i.e. uses 128b/132b
+ *
+ * Read the link status block at DP_LANE0_1_STATUS and check that every lane in
+ * use is locked and the lanes are aligned.
+ *
+ * 128b/132b reports this differently from 8b/10b: there is no clock recovery
+ * bit, and a training failure has its own bit in
+ * DP_LANE_ALIGN_STATUS_UPDATED. Mirrors drm_dp_channel_eq_ok() and the
+ * drm_dp_128b132b_* predicates.
+ *
+ * Returns:
+ * 1 when the sink considers the link trained, 0 when it does not, or a
+ * negative error code when the DPCD could not be read.
+ */
+int igt_dp_link_status_ok(int aux_fd, int lane_count, bool uhbr)
+{
+	uint8_t link_status[DPCD_LINK_STATUS_SIZE];
+	uint8_t lane_mask;
+	uint8_t align;
+	int ret;
+	int lane;
+
+	ret = igt_dp_dpcd_read(aux_fd, DPCD_LANE0_1_STATUS, link_status,
+			       sizeof(link_status));
+	if (ret < 0)
+		return ret;
+	if (ret != sizeof(link_status))
+		return -EIO;
+
+	align = link_status[2];
+
+	if (uhbr && (align & DPCD_128B132B_LT_FAILED))
+		return 0;
+
+	if (!(align & DPCD_INTERLANE_ALIGN_DONE))
+		return 0;
+
+	/* 128b/132b has no clock recovery phase, so no CR_DONE bit. */
+	lane_mask = DPCD_LANE_CHANNEL_EQ_DONE | DPCD_LANE_SYMBOL_LOCKED;
+	if (!uhbr)
+		lane_mask |= DPCD_LANE_CR_DONE;
+
+	for (lane = 0; lane < lane_count; lane++)
+		if ((dpcd_lane_status(link_status, lane) & lane_mask) != lane_mask)
+			return 0;
+
+	return 1;
+}
diff --git a/lib/igt_dp.h b/lib/igt_dp.h
index 44f3b11a1..332656aae 100644
--- a/lib/igt_dp.h
+++ b/lib/igt_dp.h
@@ -36,4 +36,8 @@ int igt_dp_dpcd_read(int aux_fd, unsigned int offset, void *buf, size_t size);
 
 int igt_dp_dpcd_read_byte(int aux_fd, unsigned int offset, uint8_t *val);
 
+int igt_dp_channel_coding_ok(int aux_fd, bool uhbr);
+
+int igt_dp_link_status_ok(int aux_fd, int lane_count, bool uhbr);
+
 #endif
-- 
2.25.1


  parent reply	other threads:[~2026-10-01  7:23 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-01  7:36 [PATCH i-g-t 00/13] Expand kms_dp_link_training coverage Kunal Joshi
2026-10-01  7:36 ` [PATCH i-g-t 01/13] lib/i915/i915_dp: add helpers for the allowed link configs debugfs Kunal Joshi
2026-10-01  7:36 ` [PATCH i-g-t 02/13] tests/intel/kms_dp_link_training: use i915_dp_is_uhbr_rate() Kunal Joshi
2026-10-01  7:36 ` [PATCH i-g-t 03/13] tests/intel/kms_dp_link_training: extract train_link_config() Kunal Joshi
2026-10-01  7:36 ` [PATCH i-g-t 04/13] tests/intel/kms_dp_link_training: detect links that failed training Kunal Joshi
2026-10-01  9:05   ` S, Sowmiya
2026-10-01  7:36 ` [PATCH i-g-t 05/13] tests/intel/kms_dp_link_training: use the lowest pixel clock mode Kunal Joshi
2026-10-01  7:36 ` [PATCH i-g-t 06/13] tests/intel/kms_dp_link_training: train all allowed link configs Kunal Joshi
2026-10-01  9:05   ` S, Sowmiya
2026-10-01  7:36 ` [PATCH i-g-t 07/13] lib/i915/i915_dp: add i915_dp_get_tc_mode() Kunal Joshi
2026-10-01  7:36 ` [PATCH i-g-t 08/13] tests/intel/kms_dp_link_training: log the DP link inventory Kunal Joshi
2026-10-01  7:36 ` [PATCH i-g-t 09/13] tests/intel/kms_dp_link_training: train each MST topology only once Kunal Joshi
2026-10-01  7:37 ` [PATCH i-g-t 10/13] tests/intel/kms_dp_link_training: add tbt-alt and direct link subtests Kunal Joshi
2026-10-01  7:37 ` [PATCH i-g-t 11/13] lib/igt_dp: add DPCD read helpers Kunal Joshi
2026-10-01  7:37 ` Kunal Joshi [this message]
2026-10-01  7:37 ` [PATCH i-g-t 13/13] tests/intel/kms_dp_link_training: check the link from the sink side Kunal Joshi
2026-10-01 13:13 ` ✓ i915.CI.BAT: success for Expand kms_dp_link_training coverage (rev2) Patchwork
2026-10-01 16:42 ` ✓ Xe.CI.BAT: " Patchwork
2026-10-01 21:02 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-10-05 16:06   ` Joshi, Kunal1
2026-10-02 17:18 ` ✗ i915.CI.Full: " Patchwork
2026-10-05 16:04   ` Joshi, Kunal1

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=20261001073703.5067-13-kunal1.joshi@intel.com \
    --to=kunal1.joshi@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=sowmiya.s@intel.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox