[PATCH 42/82] drm/amd/display: Test MST connector register and unregister

<[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
From: Alex Hung <[email protected]>

[WHAT]
Add KUnit tests for amdgpu_dm_mst_connector_late_register() and
amdgpu_dm_mst_connector_early_unregister(), covering the remote AUX bus
registration, the unregister that only resets the MST status when no
remote sink is attached, and the unregister that removes the sink from
the DC link and clears the MST connector state.

[HOW]
The tests reuse the MST downstream connector fixture, which already
provides the kernel device the DRM MST helpers log through and the
modeset lock the unregister path takes.

Assisted-by: Copilot:Claude-Opus-5
Reviewed-by: Bhawanpreet Lakha <[email protected]>
Signed-off-by: Alex Hung <[email protected]>
Signed-off-by: Ivan Lipski <[email protected]>
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  6 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.h   |  2 +
 .../tests/amdgpu_dm_mst_types_test.c          | 79 +++++++++++++++++++
 3 files changed, 85 insertions(+), 2 deletions(-)

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 79e8952edf8c0..693fd782283bc 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
@@ -187,7 +187,7 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector)
 	kfree(aconnector);
 }
 
-static int
+STATIC_IFN_KUNIT int
 amdgpu_dm_mst_connector_late_register(struct drm_connector *connector)
 {
 	struct amdgpu_dm_connector *amdgpu_dm_connector =
@@ -205,6 +205,7 @@ amdgpu_dm_mst_connector_late_register(struct drm_connector *connector)
 
 	return 0;
 }
+EXPORT_IF_KUNIT(amdgpu_dm_mst_connector_late_register);
 
 
 STATIC_IFN_KUNIT void
@@ -218,7 +219,7 @@ amdgpu_dm_mst_reset_mst_connector_setting(struct amdgpu_dm_connector *aconnector
 }
 EXPORT_IF_KUNIT(amdgpu_dm_mst_reset_mst_connector_setting);
 
-static void
+STATIC_IFN_KUNIT void
 amdgpu_dm_mst_connector_early_unregister(struct drm_connector *connector)
 {
 	struct amdgpu_dm_connector *aconnector =
@@ -251,6 +252,7 @@ amdgpu_dm_mst_connector_early_unregister(struct drm_connector *connector)
 	aconnector->mst_status = MST_STATUS_DEFAULT;
 	drm_modeset_unlock(&root->mst_mgr.base.lock);
 }
+EXPORT_IF_KUNIT(amdgpu_dm_mst_connector_early_unregister);
 
 static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
 	.fill_modes = drm_helper_probe_single_connector_modes,
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 406dba95c4aec..63130226e67eb 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
@@ -119,6 +119,8 @@ int dm_dp_mst_atomic_check(struct drm_connector *connector,
 int dm_dp_mst_detect(struct drm_connector *connector,
 			     struct drm_modeset_acquire_ctx *ctx, bool force);
 int dm_dp_mst_get_modes(struct drm_connector *connector);
+int amdgpu_dm_mst_connector_late_register(struct drm_connector *connector);
+void amdgpu_dm_mst_connector_early_unregister(struct drm_connector *connector);
 #endif
 
 #endif
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 6c0d5d233dcf1..6d920bc783d54 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
@@ -1818,6 +1818,80 @@ static void dm_mst_test_detect_disconnect_releases_sink(struct kunit *test)
 	dm_mst_test_fini_child(&child);
 }
 
+/* Tests for amdgpu_dm_mst_connector_late_register */
+
+/**
+ * dm_mst_test_connector_late_register - Test MST connector late registration
+ * @test: KUnit test context
+ *
+ * amdgpu_dm_mst_connector_late_register() must register the port's remote AUX
+ * bus and report success.
+ */
+static void dm_mst_test_connector_late_register(struct kunit *test)
+{
+	struct dm_mst_test_child child;
+
+	dm_mst_test_init_child(test, &child);
+
+	KUNIT_EXPECT_EQ(test, amdgpu_dm_mst_connector_late_register(&child.aconnector->base), 0);
+
+	dm_mst_test_fini_child(&child);
+}
+
+/* Tests for amdgpu_dm_mst_connector_early_unregister */
+
+/**
+ * dm_mst_test_connector_early_unregister_no_sink - Test unregister without sink
+ * @test: KUnit test context
+ *
+ * With no remote sink attached, amdgpu_dm_mst_connector_early_unregister() must
+ * only reset the MST status.
+ */
+static void dm_mst_test_connector_early_unregister_no_sink(struct kunit *test)
+{
+	struct dm_mst_test_child child;
+
+	dm_mst_test_init_child(test, &child);
+	child.aconnector->mst_status = MST_REMOTE_EDID;
+
+	amdgpu_dm_mst_connector_early_unregister(&child.aconnector->base);
+
+	KUNIT_EXPECT_EQ(test, dm_mst_test_remove_remote_sink_calls, 0U);
+	KUNIT_EXPECT_EQ(test, (int)child.aconnector->mst_status, (int)MST_STATUS_DEFAULT);
+
+	dm_mst_test_fini_child(&child);
+}
+
+/**
+ * dm_mst_test_connector_early_unregister_releases_sink - Test sink release
+ * @test: KUnit test context
+ *
+ * When the port leaves the topology, amdgpu_dm_mst_connector_early_unregister()
+ * must remove the remote sink from the link and reset the MST connector state.
+ */
+static void dm_mst_test_connector_early_unregister_releases_sink(struct kunit *test)
+{
+	struct dm_mst_test_child child;
+	struct dc_sink *sink;
+
+	dm_mst_test_init_child(test, &child);
+
+	sink = dm_mst_test_alloc_sink(test);
+	child.aconnector->dc_sink = sink;
+	child.aconnector->vc_full_pbn = 42;
+	child.link->sink_count = 1;
+
+	amdgpu_dm_mst_connector_early_unregister(&child.aconnector->base);
+
+	KUNIT_EXPECT_EQ(test, dm_mst_test_remove_remote_sink_calls, 1U);
+	KUNIT_EXPECT_PTR_EQ(test, dm_mst_test_removed_sink, sink);
+	KUNIT_EXPECT_NULL(test, child.aconnector->dc_sink);
+	KUNIT_EXPECT_EQ(test, child.aconnector->vc_full_pbn, 0U);
+	KUNIT_EXPECT_EQ(test, (int)child.aconnector->mst_status, (int)MST_STATUS_DEFAULT);
+
+	dm_mst_test_fini_child(&child);
+}
+
 /*
  * Sideband connector with a live topology manager and the DOWN_REP ready bit
  * armed, so dm_handle_mst_sideband_msg_ready_event() reaches its ack path.
@@ -1978,6 +2052,11 @@ static struct kunit_case dm_mst_types_test_cases[] = {
 	KUNIT_CASE(dm_mst_test_get_modes_cached_edid_sink_alloc_fails),
 	KUNIT_CASE(dm_mst_test_get_modes_restores_hdcp_properties),
 	KUNIT_CASE(dm_mst_test_get_modes_reads_remote_edid),
+	/* amdgpu_dm_mst_connector_late_register tests */
+	KUNIT_CASE(dm_mst_test_connector_late_register),
+	/* amdgpu_dm_mst_connector_early_unregister tests */
+	KUNIT_CASE(dm_mst_test_connector_early_unregister_no_sink),
+	KUNIT_CASE(dm_mst_test_connector_early_unregister_releases_sink),
 	/* CONFIG_DRM_AMD_DC_FP disabled public paths */
 #if !defined(CONFIG_DRM_AMD_DC_FP)
 	KUNIT_CASE(dm_mst_test_fp_guarded_public_stubs),
-- 
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.