summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBhawanpreet Lakha <bhawanpreet.lakha@amd.com>2026-06-23 14:41:26 -0400
committerAlex Deucher <alexander.deucher@amd.com>2026-07-15 09:15:40 -0400
commiteff243192f707a079ceee35fa1b06cd3e1c0b0de (patch)
tree1167ebb60481b21f516138529f5a1b79de9045d4 /drivers
parentb23470a026afe64de5c1df4ad181587b49c22923 (diff)
downloadlinux-next-eff243192f707a079ceee35fa1b06cd3e1c0b0de.tar.gz
linux-next-eff243192f707a079ceee35fa1b06cd3e1c0b0de.zip
drm/amd/display: Add MST link detection tests for connector
Add KUnit coverage for amdgpu_dm_detect_mst_link_for_all_connectors() to the amdgpu_dm_connector tests: - No connectors registered: iteration body never runs and the call succeeds. - Writeback connector: hit by the early continue - Non-MST link - MST branch without aux: NULL mst_mgr.aux Assisted-by: Copilot:Claude-Opus-4.8 Reviewed-by: Alex Hung <alex.hung@amd.com> Signed-off-by: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com> Signed-off-by: George Zhang <george.zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c1
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c129
2 files changed, 130 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
index 82eb8b0bcc4b..6ef18b37b634 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
@@ -331,6 +331,7 @@ int amdgpu_dm_detect_mst_link_for_all_connectors(struct drm_device *dev)
return ret;
}
+EXPORT_IF_KUNIT(amdgpu_dm_detect_mst_link_for_all_connectors);
static void hdmi_cec_unset_edid(struct amdgpu_dm_connector *aconnector)
{
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
index aa274f5e4b84..0dcc13e7f0af 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
@@ -2772,6 +2772,130 @@ static void dm_test_fbc_init_no_modes(struct kunit *test)
KUNIT_EXPECT_NULL(test, ctx->adev->dm.compressor.bo_ptr);
}
+/* Tests for amdgpu_dm_detect_mst_link_for_all_connectors() */
+
+/* Allocate a bare drm_device suitable for registering connectors against. */
+static struct drm_device *dm_test_alloc_drm(struct kunit *test)
+{
+ struct device *dev;
+ struct drm_device *drm;
+
+ dev = drm_kunit_helper_alloc_device(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+ drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0,
+ DRIVER_MODESET);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
+
+ return drm;
+}
+
+/*
+ * Allocate an amdgpu_dm_connector and register its embedded drm_connector with
+ * @drm so that drm_for_each_connector_iter() and to_amdgpu_dm_connector() both
+ * resolve to it.
+ */
+static struct amdgpu_dm_connector *dm_test_add_connector(struct kunit *test,
+ struct drm_device *drm, int connector_type)
+{
+ struct amdgpu_dm_connector *aconnector;
+
+ aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, aconnector);
+
+ KUNIT_ASSERT_EQ(test,
+ drmm_connector_init(drm, &aconnector->base,
+ &dm_test_connector_funcs, connector_type,
+ NULL), 0);
+
+ return aconnector;
+}
+
+/**
+ * dm_test_detect_mst_no_connectors - Test the no-op path on an empty device
+ * @test: The KUnit test context
+ */
+static void dm_test_detect_mst_no_connectors(struct kunit *test)
+{
+ struct drm_device *drm = dm_test_alloc_drm(test);
+
+ /* No connectors registered → iteration body never runs */
+ KUNIT_EXPECT_EQ(test,
+ amdgpu_dm_detect_mst_link_for_all_connectors(drm), 0);
+}
+
+/**
+ * dm_test_detect_mst_skips_writeback - Test writeback connectors are skipped
+ * @test: The KUnit test context
+ *
+ * A writeback connector is hit by the early ``continue`` before its dc_link is
+ * ever dereferenced, so leaving dc_link NULL must not crash.
+ */
+static void dm_test_detect_mst_skips_writeback(struct kunit *test)
+{
+ struct drm_device *drm = dm_test_alloc_drm(test);
+ struct amdgpu_dm_connector *aconnector;
+
+ aconnector = dm_test_add_connector(test, drm,
+ DRM_MODE_CONNECTOR_WRITEBACK);
+ /* dc_link intentionally left NULL: it must not be touched */
+ aconnector->dc_link = NULL;
+
+ KUNIT_EXPECT_EQ(test,
+ amdgpu_dm_detect_mst_link_for_all_connectors(drm), 0);
+}
+
+/**
+ * dm_test_detect_mst_non_mst_link - Test a non-MST link starts no topology
+ * @test: The KUnit test context
+ */
+static void dm_test_detect_mst_non_mst_link(struct kunit *test)
+{
+ struct drm_device *drm = dm_test_alloc_drm(test);
+ struct amdgpu_dm_connector *aconnector;
+ struct dc_link *link;
+
+ aconnector = dm_test_add_connector(test, drm,
+ DRM_MODE_CONNECTOR_DisplayPort);
+ link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, link);
+
+ /* Not an MST branch → the topology manager is never started */
+ link->type = dc_connection_single;
+ aconnector->dc_link = link;
+
+ KUNIT_EXPECT_EQ(test,
+ amdgpu_dm_detect_mst_link_for_all_connectors(drm), 0);
+}
+
+/**
+ * dm_test_detect_mst_branch_without_aux - Test an MST branch with no aux is
+ * skipped
+ * @test: The KUnit test context
+ *
+ * The condition short-circuits on a NULL mst_mgr.aux, so the real
+ * drm_dp_mst_topology_mgr_set_mst() path is never reached.
+ */
+static void dm_test_detect_mst_branch_without_aux(struct kunit *test)
+{
+ struct drm_device *drm = dm_test_alloc_drm(test);
+ struct amdgpu_dm_connector *aconnector;
+ struct dc_link *link;
+
+ aconnector = dm_test_add_connector(test, drm,
+ DRM_MODE_CONNECTOR_DisplayPort);
+ link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, link);
+
+ link->type = dc_connection_mst_branch;
+ aconnector->dc_link = link;
+ /* mst_mgr.aux is NULL (kzalloc) → second half of the && is false */
+ KUNIT_ASSERT_NULL(test, aconnector->mst_mgr.aux);
+
+ KUNIT_EXPECT_EQ(test,
+ amdgpu_dm_detect_mst_link_for_all_connectors(drm), 0);
+}
+
static struct kunit_case amdgpu_dm_connector_tests[] = {
/* get_subconnector_type */
KUNIT_CASE(dm_test_subconnector_type_none),
@@ -2934,6 +3058,11 @@ static struct kunit_case amdgpu_dm_connector_tests[] = {
KUNIT_CASE(dm_test_fbc_init_non_edp),
KUNIT_CASE(dm_test_fbc_init_already_allocated),
KUNIT_CASE(dm_test_fbc_init_no_modes),
+ /* amdgpu_dm_detect_mst_link_for_all_connectors */
+ KUNIT_CASE(dm_test_detect_mst_no_connectors),
+ KUNIT_CASE(dm_test_detect_mst_skips_writeback),
+ KUNIT_CASE(dm_test_detect_mst_non_mst_link),
+ KUNIT_CASE(dm_test_detect_mst_branch_without_aux),
{}
};