All of 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 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.