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