[PATCH 38/59] drm/amd/display: Test link and sink dump

Alex Hung <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
[WHAT]
Add KUnit tests for amdgpu_dm_dump_links_and_sinks() covering a device
without DC, a DC without links, named local and remote sinks, and missing
or unnamed sinks.

[HOW]
Build lightweight DC link and sink objects so the dump walks each naming
and skip path without display hardware.

Assisted-by: Copilot:Claude-Opus-5 GPT-5.6-Sol
Reviewed-by: Bhawanpreet Lakha <[email protected]>
Signed-off-by: Alex Hung <[email protected]>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  3 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
 .../display/amdgpu_dm/tests/amdgpu_dm_test.c  | 92 +++++++++++++++++++
 3 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 8db18d7cf49f..fc03fcca4c6a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1776,7 +1776,7 @@ EXPORT_IF_KUNIT(amdgpu_dm_apply_delay_after_dpcd_poweroff);
  * (MST) sinks. Should be called after connector detection is complete to see
  * the final state of all links.
  */
-static void amdgpu_dm_dump_links_and_sinks(struct amdgpu_device *adev)
+STATIC_IFN_KUNIT void amdgpu_dm_dump_links_and_sinks(struct amdgpu_device *adev)
 {
 	struct dc *dc = adev->dm.dc;
 	struct drm_device *dev = adev_to_drm(adev);
@@ -1828,6 +1828,7 @@ static void amdgpu_dm_dump_links_and_sinks(struct amdgpu_device *adev)
 		}
 	}
 }
+EXPORT_IF_KUNIT(amdgpu_dm_dump_links_and_sinks);
 
 static int dm_resume(struct amdgpu_ip_block *ip_block)
 {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 0151913336b7..7cb22915d18b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -1201,6 +1201,7 @@ int add_affected_mst_dsc_crtcs(struct drm_atomic_commit *state,
 bool amdgpu_dm_crtc_mem_type_changed(struct drm_device *dev,
 				     struct drm_atomic_commit *state,
 				     struct drm_crtc_state *crtc_state);
+void amdgpu_dm_dump_links_and_sinks(struct amdgpu_device *adev);
 int dm_plane_layer_index_cmp(const void *a, const void *b);
 int fill_plane_color_attributes(const struct drm_plane_state *plane_state,
 				const enum surface_pixel_format format,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
index 799cd3867a77..63d43f917273 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
@@ -2759,6 +2759,93 @@ static void dm_test_reset_plane_other_modifier(struct kunit *test)
 	KUNIT_EXPECT_TRUE(test, dm_test_should_reset_plane(ctx));
 }
 
+/* Tests for amdgpu_dm_dump_links_and_sinks() */
+
+/**
+ * dm_test_dump_links_no_dc - Test a device without DC dumps nothing
+ * @test: The KUnit test context
+ */
+static void dm_test_dump_links_no_dc(struct kunit *test)
+{
+	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+
+	amdgpu_dm_dump_links_and_sinks(adev);
+}
+
+/**
+ * dm_test_dump_links_no_links - Test a DC without links dumps nothing
+ * @test: The KUnit test context
+ */
+static void dm_test_dump_links_no_links(struct kunit *test)
+{
+	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+
+	adev->dm.dc = dm_kunit_alloc_dc_with_ctx(test);
+
+	amdgpu_dm_dump_links_and_sinks(adev);
+}
+
+/*
+ * Attach a single DC link to @adev so amdgpu_dm_dump_links_and_sinks() walks it.
+ */
+static struct dc_link *dm_test_dc_with_link(struct kunit *test,
+					   struct amdgpu_device *adev)
+{
+	struct dc *dc = dm_kunit_alloc_dc_with_ctx(test);
+	struct dc_link *link = dm_kunit_alloc_link(test);
+
+	dc->links[0] = link;
+	dc->link_count = 1;
+	adev->dm.dc = dc;
+
+	return link;
+}
+
+/**
+ * dm_test_dump_links_with_sinks - Test local and remote sinks are walked
+ * @test: The KUnit test context
+ */
+static void dm_test_dump_links_with_sinks(struct kunit *test)
+{
+	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+	struct dc_link *link = dm_test_dc_with_link(test, adev);
+	struct dc_sink *local_sink, *remote_sink;
+
+	local_sink = kunit_kzalloc(test, sizeof(*local_sink), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, local_sink);
+	remote_sink = kunit_kzalloc(test, sizeof(*remote_sink), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, remote_sink);
+
+	strscpy(local_sink->edid_caps.display_name, "local");
+	strscpy(remote_sink->edid_caps.display_name, "remote");
+	link->local_sink = local_sink;
+	link->sink_count = 1;
+	link->remote_sinks[0] = remote_sink;
+	adev->dm.dc->link_count = 2;
+
+	amdgpu_dm_dump_links_and_sinks(adev);
+}
+
+/**
+ * dm_test_dump_links_unnamed_sinks - Test links without a sink or EDID name
+ * @test: The KUnit test context
+ */
+static void dm_test_dump_links_unnamed_sinks(struct kunit *test)
+{
+	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+	struct dc_link *link = dm_test_dc_with_link(test, adev);
+	struct dc_sink *remote_sink;
+
+	remote_sink = kunit_kzalloc(test, sizeof(*remote_sink), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, remote_sink);
+
+	link->sink_count = 2;
+	link->remote_sinks[0] = NULL;
+	link->remote_sinks[1] = remote_sink;
+
+	amdgpu_dm_dump_links_and_sinks(adev);
+}
+
 static struct kunit_case amdgpu_dm_tests[] = {
 	/* Simple DM callbacks */
 	KUNIT_CASE(dm_test_wait_for_idle),
@@ -2896,6 +2983,11 @@ static struct kunit_case amdgpu_dm_tests[] = {
 	KUNIT_CASE(dm_test_reset_plane_other_no_fb),
 	KUNIT_CASE(dm_test_reset_plane_other_format),
 	KUNIT_CASE(dm_test_reset_plane_other_modifier),
+	/* amdgpu_dm_dump_links_and_sinks */
+	KUNIT_CASE(dm_test_dump_links_no_dc),
+	KUNIT_CASE(dm_test_dump_links_no_links),
+	KUNIT_CASE(dm_test_dump_links_with_sinks),
+	KUNIT_CASE(dm_test_dump_links_unnamed_sinks),
 	{}
 };
 
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.