AMD-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Chenyu Chen <chen-yu.chen@amd.com>
To: <amd-gfx@lists.freedesktop.org>
Cc: Harry Wentland <harry.wentland@amd.com>,
	Leo Li <sunpeng.li@amd.com>,
	Aurabindo Pillai <aurabindo.pillai@amd.com>,
	Roman Li <roman.li@amd.com>, Wayne Lin <wayne.lin@amd.com>,
	Tom Chung <chiahsuan.chung@amd.com>,
	"Fangzhi Zuo" <jerry.zuo@amd.com>,
	Dan Wheeler <daniel.wheeler@amd.com>, Ray Wu <Ray.Wu@amd.com>,
	Ivan Lipski <ivan.lipski@amd.com>, Alex Hung <alex.hung@amd.com>,
	James Lin <PingLei.Lin@amd.com>,
	Chenyu Chen <Chen-Yu.Chen@amd.com>,
	Bhawanpreet Lakha <bhawanpreet.lakha@amd.com>,
	"Chenyu Chen" <chen-yu.chen@amd.com>
Subject: [PATCH 22/66] drm/amd/display: Test link bandwidth readback
Date: Tue, 8 Sep 2026 19:31:15 +0800	[thread overview]
Message-ID: <20260908113338.2433445-23-chen-yu.chen@amd.com> (raw)
In-Reply-To: <20260908113338.2433445-1-chen-yu.chen@amd.com>

From: Alex Hung <alex.hung@amd.com>

[WHAT]
Add KUnit tests for dp_get_link_current_set_bw() covering every link
rate the helper knows about, the unknown rate fallback and the DPCD
read error path.

[HOW]
Add a DPCD backing store for the DSC helpers that is addressed
absolutely, because they read offsets spread across the whole map. A
table driven test then programs the link rate and lane count into the
fake DPCD and checks the returned bandwidth, with one entry arming the
AUX transfer to fail.

Assisted-by: Copilot:Claude-Opus-5
Reviewed-by: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Chenyu Chen <chen-yu.chen@amd.com>
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |   3 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.h   |   2 +
 .../tests/amdgpu_dm_mst_types_test.c          | 120 ++++++++++++++++++
 3 files changed, 124 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index f857303fe386..e8f4ca7e1f2a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -1930,7 +1930,7 @@ static bool is_dsc_common_config_possible(struct dc_stream_state *stream,
 #endif
 
 #if defined(CONFIG_DRM_AMD_DC_FP) || IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
-static bool dp_get_link_current_set_bw(struct drm_dp_aux *aux, uint32_t *cur_link_bw)
+STATIC_IFN_KUNIT bool dp_get_link_current_set_bw(struct drm_dp_aux *aux, uint32_t *cur_link_bw)
 {
 	uint32_t total_data_bw_efficiency_x10000 = 0;
 	uint32_t link_rate_per_lane_kbps = 0;
@@ -1985,6 +1985,7 @@ static bool dp_get_link_current_set_bw(struct drm_dp_aux *aux, uint32_t *cur_lin
 	*cur_link_bw = link_rate_per_lane_kbps * lane_count.bits.LANE_COUNT_SET / 10000 * total_data_bw_efficiency_x10000;
 	return true;
 }
+EXPORT_IF_KUNIT(dp_get_link_current_set_bw);
 #endif
 
 enum dc_status dm_dp_mst_is_port_support_mode(
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
index 0e6189219eb2..4af3aac31223 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
@@ -65,6 +65,7 @@ struct dc_state;
 struct dc_stream_state;
 struct dm_atomic_state;
 struct drm_atomic_commit;
+struct drm_dp_aux;
 struct drm_dp_mst_port;
 struct drm_dp_mst_topology_mgr;
 
@@ -104,6 +105,7 @@ enum dc_status dm_dp_mst_is_port_support_mode(
 
 #if IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
 void amdgpu_dm_mst_reset_mst_connector_setting(struct amdgpu_dm_connector *aconnector);
+bool dp_get_link_current_set_bw(struct drm_dp_aux *aux, uint32_t *cur_link_bw);
 bool retrieve_downstream_port_device(struct amdgpu_dm_connector *aconnector);
 bool retrieve_branch_specific_data(struct amdgpu_dm_connector *aconnector);
 ssize_t dm_dp_aux_transfer_result(ssize_t result,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_mst_types_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_mst_types_test.c
index f2bae3a50941..58a4bbb31e79 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_mst_types_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_mst_types_test.c
@@ -2276,6 +2276,124 @@ static void dm_mst_test_sideband_msg_ready_ack_write_fails(struct kunit *test)
 	dm_mst_test_free_armed_sideband_connector(aconnector);
 }
 
+/*
+ * Fake DPCD backing store for the DSC helpers. Unlike the sideband fake above
+ * it is addressed absolutely, because these helpers read offsets spread across
+ * the whole map (0x60 DSC caps, 0x100 link settings, 0x500 branch descriptor).
+ */
+#define DM_MST_TEST_DSC_DPCD_SIZE 0x600
+
+static u8 dm_mst_test_dsc_dpcd[DM_MST_TEST_DSC_DPCD_SIZE];
+static struct drm_dp_aux *dm_mst_test_dsc_aux_fail;
+
+static ssize_t dm_mst_test_dsc_aux_transfer(struct drm_dp_aux *aux,
+					    struct drm_dp_aux_msg *msg)
+{
+	size_t i;
+
+	if (aux == dm_mst_test_dsc_aux_fail)
+		return -EIO;
+
+	if (msg->address + msg->size > DM_MST_TEST_DSC_DPCD_SIZE)
+		return -EINVAL;
+
+	msg->reply = DP_AUX_NATIVE_REPLY_ACK;
+
+	if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_WRITE)
+		return msg->size;
+
+	for (i = 0; i < msg->size; i++)
+		((u8 *)msg->buffer)[i] = dm_mst_test_dsc_dpcd[msg->address + i];
+
+	return msg->size;
+}
+
+/* Clears the shared store; call once per test before initialising any AUX. */
+static void dm_mst_test_reset_dsc_dpcd(void)
+{
+	memset(dm_mst_test_dsc_dpcd, 0, sizeof(dm_mst_test_dsc_dpcd));
+	dm_mst_test_dsc_aux_fail = NULL;
+}
+
+static void dm_mst_test_init_dsc_aux(struct drm_dp_aux *aux, const char *name)
+{
+	aux->name = name;
+	aux->transfer = dm_mst_test_dsc_aux_transfer;
+	drm_dp_aux_init(aux);
+	drm_dp_dpcd_set_probe(aux, false);
+}
+
+static struct drm_dp_aux *dm_mst_test_alloc_dsc_aux(struct kunit *test, const char *name)
+{
+	struct drm_dp_aux *aux = kunit_kzalloc(test, sizeof(*aux), GFP_KERNEL);
+
+	KUNIT_ASSERT_NOT_NULL(test, aux);
+	dm_mst_test_init_dsc_aux(aux, name);
+
+	return aux;
+}
+
+/* Tests for dp_get_link_current_set_bw */
+
+/*
+ * Program DPCD 0x100..0x10f, the 16-byte window the helper reads in one go.
+ * @coding is the raw DP_MAIN_LINK_CHANNEL_CODING_SET byte at 0x108.
+ */
+static void dm_mst_test_set_link_settings(u8 link_bw_set, u8 lane_count, u8 coding)
+{
+	dm_mst_test_dsc_dpcd[DP_LINK_BW_SET] = link_bw_set;
+	dm_mst_test_dsc_dpcd[DP_LANE_COUNT_SET] = lane_count;
+	dm_mst_test_dsc_dpcd[DP_MAIN_LINK_CHANNEL_CODING_SET] = coding;
+}
+
+struct dm_mst_link_bw_param {
+	const char *name;
+	u8 link_bw_set;
+	u8 lane_count;
+	u8 coding;
+	bool aux_fails;
+	bool supported;
+	uint32_t cur_link_bw;
+};
+
+static const struct dm_mst_link_bw_param dm_mst_link_bw_params[] = {
+	{ "hbr2_8b_10b", DP_LINK_BW_5_4, 4, DP_8b_10b_ENCODING, false, true, 16761600 },
+	{ "uhbr10", DP_LINK_BW_10, 4, DP_128b_132b_ENCODING, false, true, 38564000 },
+	{ "uhbr13_5", DP_LINK_BW_13_5, 4, DP_128b_132b_ENCODING, false, true, 52061400 },
+	{ "uhbr20", DP_LINK_BW_20, 4, DP_128b_132b_ENCODING, false, true, 77128000 },
+	{ "unlisted_uhbr_rate", 0x1e, 4, DP_128b_132b_ENCODING, false, false, 0 },
+	{ "unknown_encoding", DP_LINK_BW_5_4, 4, DP_UNKNOWN_ENCODING, false, false, 0 },
+	{ "dpcd_read_error", DP_LINK_BW_5_4, 4, DP_8b_10b_ENCODING, true, false, 0 },
+};
+
+KUNIT_ARRAY_PARAM_DESC(dm_mst_link_bw, dm_mst_link_bw_params, name);
+
+/**
+ * dm_mst_test_link_current_set_bw - the current link settings are priced
+ * @test: KUnit test context
+ *
+ * For 8b/10b the raw DP_LINK_BW_SET byte is the link rate in 27MHz units, so
+ * HBR2 (0x14) yields 20 * 27000 * 10 kbps per lane scaled by the 80% data
+ * efficiency and the 97% FEC efficiency. For 128b/132b the byte instead
+ * selects a UHBR rate scaled by its own efficiency. An unlisted UHBR rate, an
+ * unknown channel coding and a short DPCD read all report no bandwidth.
+ */
+static void dm_mst_test_link_current_set_bw(struct kunit *test)
+{
+	const struct dm_mst_link_bw_param *param = test->param_value;
+	uint32_t cur_link_bw = 0xdeadbeef;
+	struct drm_dp_aux *aux;
+
+	dm_mst_test_reset_dsc_dpcd();
+	aux = dm_mst_test_alloc_dsc_aux(test, "dm_mst_test_link_bw_aux");
+	dm_mst_test_set_link_settings(param->link_bw_set, param->lane_count, param->coding);
+	if (param->aux_fails)
+		dm_mst_test_dsc_aux_fail = aux;
+
+	KUNIT_EXPECT_EQ(test, dp_get_link_current_set_bw(aux, &cur_link_bw), param->supported);
+	KUNIT_EXPECT_EQ(test, cur_link_bw, param->cur_link_bw);
+}
+
 static struct kunit_case dm_mst_types_test_cases[] = {
 	/* needs_dsc_aux_workaround tests */
 	KUNIT_CASE(dm_mst_test_needs_dsc_aux_workaround_match),
@@ -2360,6 +2478,8 @@ static struct kunit_case dm_mst_types_test_cases[] = {
 	/* dm_dp_mst_connector_destroy tests */
 	KUNIT_CASE(dm_mst_test_connector_destroy_no_sink),
 	KUNIT_CASE(dm_mst_test_connector_destroy_releases_sink),
+	/* dp_get_link_current_set_bw tests */
+	KUNIT_CASE_PARAM(dm_mst_test_link_current_set_bw, dm_mst_link_bw_gen_params),
 	{}
 };
 
-- 
2.43.0


  parent reply	other threads:[~2026-09-08 11:37 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-08 11:30 [PATCH 00/66] DC Patches Sep 14 2026 Chenyu Chen
2026-09-08 11:30 ` [PATCH 01/66] drm/amd/display: Decouple cursor offload hwss executors from pipe context Chenyu Chen
2026-09-08 11:30 ` [PATCH 02/66] drm/amd/display: Update LLS and UPSP programming paths Chenyu Chen
2026-09-08 11:30 ` [PATCH 03/66] drm/amd/display: Refactor RMCM into a separate module Chenyu Chen
2026-09-08 11:30 ` [PATCH 04/66] drm/amd/display: Remove SDPIF_PORT_CONTROL programming for DCN31/35/42 Chenyu Chen
2026-09-08 11:30 ` [PATCH 05/66] drm/amd/display: Test sink stream creation Chenyu Chen
2026-09-08 11:30 ` [PATCH 06/66] drm/amd/display: Test connector init helper Chenyu Chen
2026-09-08 11:31 ` [PATCH 07/66] drm/amd/display: Test HDMI connector init Chenyu Chen
2026-09-08 11:31 ` [PATCH 08/66] drm/amd/display: Test FreeSync caps update Chenyu Chen
2026-09-08 11:31 ` [PATCH 09/66] drm/amd/display: Test connector init Chenyu Chen
2026-09-08 11:31 ` [PATCH 10/66] drm/amd/display: Test forced atomic commit Chenyu Chen
2026-09-08 11:31 ` [PATCH 11/66] drm/amd/display: Test DCC reject for multi-plane format Chenyu Chen
2026-09-08 11:31 ` [PATCH 12/66] drm/amd/display: Test modifier list growth failure Chenyu Chen
2026-09-08 11:31 ` [PATCH 13/66] drm/amd/display: Test pre-GFX9 plane buffer attributes Chenyu Chen
2026-09-08 11:31 ` [PATCH 14/66] drm/amd/display: Test accepted plane atomic check Chenyu Chen
2026-09-08 11:31 ` [PATCH 15/66] drm/amd/display: Test cursor update without DC stream Chenyu Chen
2026-09-08 11:31 ` [PATCH 16/66] drm/amd/display: Test panic flush DCC teardown Chenyu Chen
2026-09-08 11:31 ` [PATCH 17/66] drm/amd/display: Test optional plane property creation Chenyu Chen
2026-09-08 11:31 ` [PATCH 18/66] drm/amd/display: Add option for certain panels to disable FEC Chenyu Chen
2026-09-08 11:31 ` [PATCH 19/66] drm/amd/display: Build MST DSC helpers for KUnit Chenyu Chen
2026-09-08 11:31 ` [PATCH 20/66] drm/amd/display: Test oversized AUX transfer Chenyu Chen
2026-09-08 11:31 ` [PATCH 21/66] drm/amd/display: Test MST connector creation Chenyu Chen
2026-09-08 11:31 ` Chenyu Chen [this message]
2026-09-08 11:31 ` [PATCH 23/66] drm/amd/display: Test cascaded Panamera check Chenyu Chen
2026-09-08 11:31 ` [PATCH 24/66] drm/amd/display: Test DSC caps validation Chenyu Chen
2026-09-08 11:31 ` [PATCH 25/66] drm/amd/display: Test MST port mode support Chenyu Chen
2026-09-08 11:31 ` [PATCH 26/66] drm/amd/display: Test FRL bandwidth lookup Chenyu Chen
2026-09-08 11:31 ` [PATCH 27/66] drm/amd/display: Test DSC precompute helpers Chenyu Chen
2026-09-08 11:31 ` [PATCH 28/66] drm/amd/display: Test DSC recompute check Chenyu Chen
2026-09-08 11:31 ` [PATCH 29/66] drm/amd/display: Test DSC config computation Chenyu Chen
2026-09-08 11:31 ` [PATCH 30/66] drm/amd/display: Test per-link DSC configs Chenyu Chen
2026-09-08 11:31 ` [PATCH 31/66] drm/amd/display: Add urgent assertion counter probe Chenyu Chen
2026-09-08 11:31 ` [PATCH 32/66] drm/amd/display: Add debug option to force optional UCLK support Chenyu Chen
2026-09-08 11:31 ` [PATCH 33/66] drm/amd/display: Honor forced RGB pixel encoding Chenyu Chen
2026-09-08 11:31 ` [PATCH 34/66] drm/amd/display: Add Replay cumulative residency query Chenyu Chen
2026-09-08 11:31 ` [PATCH 35/66] drm/amd/display: Force DSC to 8bpp for MST DP tunneling over USB4 Chenyu Chen
2026-09-08 11:31 ` [PATCH 36/66] drm/amd/display: Force DSC to 8bpp for SST " Chenyu Chen
2026-09-08 11:31 ` [PATCH 37/66] drm/amd/display: Fix peak bandwidth measurement sequence Chenyu Chen
2026-09-08 11:31 ` [PATCH 38/66] drm/amd/display: Add instance field to struct mpc Chenyu Chen
2026-09-08 11:31 ` [PATCH 39/66] drm/amd/display: Enable back alt-ch Chenyu Chen
2026-09-08 11:31 ` [PATCH 40/66] drm/amd/display: Decouple HUBP_UPDATE_PLANE_ADDR from pipe_ctx Chenyu Chen
2026-09-08 11:31 ` [PATCH 41/66] drm/amd/display: Cleanup DMUB command submission interfaces Chenyu Chen
2026-09-08 11:31 ` [PATCH 42/66] drm/amd/display: Enable power gating on dcn42b Chenyu Chen
2026-09-08 11:31 ` [PATCH 43/66] drm/amd/display: Bound DSC power gating loop by num_dsc Chenyu Chen
2026-09-08 11:31 ` [PATCH 44/66] drm/amd/display: Add lock-free memory pool Chenyu Chen
2026-09-08 11:31 ` [PATCH 45/66] drm/amd/display: Rename lock_and_validation_needed to needs_dc_state_realloc Chenyu Chen
2026-09-08 11:31 ` [PATCH 46/66] drm/amd/display: Attach only plane updates that actually changed Chenyu Chen
2026-09-08 11:31 ` [PATCH 47/66] drm/amd/display: Request DMUB HW cursor offload Chenyu Chen
2026-09-08 11:31 ` [PATCH 48/66] drm/amd/display: Send stream_update to DC only when it changed Chenyu Chen
2026-09-08 11:31 ` [PATCH 49/66] drm/amd/display: Drop dead update_type param from update_planes_and_stream_adapter Chenyu Chen
2026-09-08 11:31 ` [PATCH 50/66] drm/amd/display: Flush ISM work before releasing the stream Chenyu Chen
2026-09-08 11:31 ` [PATCH 51/66] drm/amd/display: Cap DML2.1 vmin ODM combine at 2:1 for eDP Chenyu Chen
2026-09-08 11:31 ` [PATCH 52/66] drm/amd/display: Add is_odm_enabled callback to skip init_odm on active ODM pipes Chenyu Chen
2026-09-08 11:31 ` [PATCH 53/66] drm/amd/display: Program DCC as part of address update Chenyu Chen
2026-09-08 11:31 ` [PATCH 54/66] drm/amd/display: Add instance field to struct dccg Chenyu Chen
2026-09-08 11:31 ` [PATCH 55/66] drm/amd/display: Add SPDX license identifier to dcn30_dpp_cm.c Chenyu Chen
2026-09-08 11:31 ` [PATCH 56/66] drm/amd/display: Remove MALL capabilities from DCN42B Chenyu Chen
2026-09-08 11:31 ` [PATCH 57/66] drm/amd/display: Remove MALL capabilities from DCN42B bounding box Chenyu Chen
2026-09-08 11:31 ` [PATCH 58/66] drm/amd/display: Atomize IRQ register read/modify/write ops Chenyu Chen
2026-09-08 11:31 ` [PATCH 59/66] drm/amd/display: Return success status from check_mode_supported Chenyu Chen
2026-09-08 11:31 ` [PATCH 60/66] drm/amd/display: Add condition to skip MALL calculations if there is no MALL Chenyu Chen
2026-09-08 11:31 ` [PATCH 61/66] drm/amd/display: Fix HDMI FRL audio enable Chenyu Chen
2026-09-08 11:31 ` [PATCH 62/66] drm/amd/display: Cast DP DTO pixel clock math to avoid overflow and narrowing Chenyu Chen
2026-09-08 11:31 ` [PATCH 63/66] drm/amd/display: Add inbox0 HW lock helpers for DCN35 Chenyu Chen
2026-09-08 11:31 ` [PATCH 64/66] drm/amd/display: Unify fast update classification paths Chenyu Chen
2026-09-08 11:31 ` [PATCH 65/66] drm/amd/display: Use unsigned types for FRL cap check params and HPO read_state Chenyu Chen
2026-09-08 11:31 ` [PATCH 66/66] drm/amd/display: Promote DC to 3.2.398 Chenyu Chen

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=20260908113338.2433445-23-chen-yu.chen@amd.com \
    --to=chen-yu.chen@amd.com \
    --cc=PingLei.Lin@amd.com \
    --cc=Ray.Wu@amd.com \
    --cc=alex.hung@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=aurabindo.pillai@amd.com \
    --cc=bhawanpreet.lakha@amd.com \
    --cc=chiahsuan.chung@amd.com \
    --cc=daniel.wheeler@amd.com \
    --cc=harry.wentland@amd.com \
    --cc=ivan.lipski@amd.com \
    --cc=jerry.zuo@amd.com \
    --cc=roman.li@amd.com \
    --cc=sunpeng.li@amd.com \
    --cc=wayne.lin@amd.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