[WHAT]
Add KUnit tests for amdgpu_dm_early_fini() with audio never enabled, for
dm_sw_fini() releasing the DMUB software state, for dm_oem_i2c_hw_init()
when the resource pool has no OEM device, for dm_gpureset_commit_state()
with an empty DC state, and for amdgpu_dm_emulated_link_detect() rejecting
an unknown connector signal.

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 | 15 ++--
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  4 +
 .../display/amdgpu_dm/tests/amdgpu_dm_test.c  | 86 +++++++++++++++++++
 3 files changed, 100 insertions(+), 5 deletions(-)

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 13afd787c1b4..2085625f8509 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -830,7 +830,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
        return -EINVAL;
 }
 
-static int amdgpu_dm_early_fini(struct amdgpu_ip_block *ip_block)
+STATIC_IFN_KUNIT int amdgpu_dm_early_fini(struct amdgpu_ip_block *ip_block)
 {
        struct amdgpu_device *adev = ip_block->adev;
 
@@ -838,6 +838,7 @@ static int amdgpu_dm_early_fini(struct amdgpu_ip_block 
*ip_block)
 
        return 0;
 }
+EXPORT_IF_KUNIT(amdgpu_dm_early_fini);
 
 static void amdgpu_dm_fini(struct amdgpu_device *adev)
 {
@@ -1078,7 +1079,7 @@ static int dm_sw_init(struct amdgpu_ip_block *ip_block)
        return load_dmcu_fw(adev);
 }
 
-static int dm_sw_fini(struct amdgpu_ip_block *ip_block)
+STATIC_IFN_KUNIT int dm_sw_fini(struct amdgpu_ip_block *ip_block)
 {
        struct amdgpu_device *adev = ip_block->adev;
        struct dal_allocation *da;
@@ -1108,6 +1109,7 @@ static int dm_sw_fini(struct amdgpu_ip_block *ip_block)
 
        return 0;
 }
+EXPORT_IF_KUNIT(dm_sw_fini);
 
 
 static void amdgpu_dm_boot_time_crc_init(struct amdgpu_device *adev)
@@ -1302,7 +1304,7 @@ static void s3_handle_mst(struct drm_device *dev, bool 
suspend)
        drm_connector_list_iter_end(&iter);
 }
 
-static int dm_oem_i2c_hw_init(struct amdgpu_device *adev)
+STATIC_IFN_KUNIT int dm_oem_i2c_hw_init(struct amdgpu_device *adev)
 {
        struct amdgpu_display_manager *dm = &adev->dm;
        struct amdgpu_i2c_adapter *oem_i2c;
@@ -1328,6 +1330,7 @@ static int dm_oem_i2c_hw_init(struct amdgpu_device *adev)
 
        return 0;
 }
+EXPORT_IF_KUNIT(dm_oem_i2c_hw_init);
 
 /**
  * dm_hw_init() - Initialize DC device
@@ -1710,9 +1713,10 @@ void amdgpu_dm_emulated_link_detect(struct dc_link *link)
                drm_err(dev, "Failed to read EDID\n");
 
 }
+EXPORT_IF_KUNIT(amdgpu_dm_emulated_link_detect);
 
-static void dm_gpureset_commit_state(struct dc_state *dc_state,
-                                    struct amdgpu_display_manager *dm)
+STATIC_IFN_KUNIT void dm_gpureset_commit_state(struct dc_state *dc_state,
+                                              struct amdgpu_display_manager 
*dm)
 {
        struct {
                struct dc_surface_update surface_updates[MAX_SURFACES];
@@ -1748,6 +1752,7 @@ static void dm_gpureset_commit_state(struct dc_state 
*dc_state,
                                         bundle->surface_updates);
        }
 }
+EXPORT_IF_KUNIT(dm_gpureset_commit_state);
 
 void amdgpu_dm_apply_delay_after_dpcd_poweroff(struct amdgpu_device *adev,
                                                                                
           struct dc_sink *sink)
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 cec86779b959..35b8725a63af 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -1205,6 +1205,10 @@ void amdgpu_dm_dump_links_and_sinks(struct amdgpu_device 
*adev);
 void amdgpu_dm_update_hdcp(struct drm_atomic_commit *state);
 int do_aquire_global_lock(struct drm_device *dev,
                          struct drm_atomic_commit *state);
+int amdgpu_dm_early_fini(struct amdgpu_ip_block *ip_block);
+int dm_sw_fini(struct amdgpu_ip_block *ip_block);
+int dm_oem_i2c_hw_init(struct amdgpu_device *adev);
+void dm_gpureset_commit_state(struct dc_state *dc_state, struct 
amdgpu_display_manager *dm);
 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 f5c054422346..27182f65e5c3 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
@@ -3094,6 +3094,86 @@ static void dm_test_acpi_phy_transition_interlock(struct 
kunit *test)
        dm_acpi_process_phy_transition_interlock(NULL, params);
 }
 
+/**
+ * dm_test_early_fini_audio_disabled - Test early fini with audio never enabled
+ * @test: The KUnit test context
+ */
+static void dm_test_early_fini_audio_disabled(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+       struct amdgpu_ip_block ip_block = { .adev = adev };
+
+       KUNIT_EXPECT_EQ(test, amdgpu_dm_early_fini(&ip_block), 0);
+}
+
+/**
+ * dm_test_sw_fini_releases_state - Test sw fini drops the DMUB software state
+ * @test: The KUnit test context
+ */
+static void dm_test_sw_fini_releases_state(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+       struct amdgpu_ip_block ip_block = { .adev = adev };
+
+       INIT_LIST_HEAD(&adev->dm.da_list);
+       adev->dm.dmub_fb_info = kzalloc_obj(*adev->dm.dmub_fb_info);
+       KUNIT_ASSERT_NOT_NULL(test, adev->dm.dmub_fb_info);
+
+       KUNIT_EXPECT_EQ(test, dm_sw_fini(&ip_block), 0);
+       KUNIT_EXPECT_NULL(test, adev->dm.dmub_fb_info);
+}
+
+/**
+ * dm_test_oem_i2c_hw_init_no_device - Test no OEM I2C device leaves the bus 
unset
+ * @test: The KUnit test context
+ */
+static void dm_test_oem_i2c_hw_init_no_device(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+       struct dc *dc = dm_kunit_alloc_dc_with_ctx(test);
+
+       dc->res_pool = kunit_kzalloc(test, sizeof(*dc->res_pool), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, dc->res_pool);
+       adev->dm.dc = dc;
+
+       KUNIT_EXPECT_EQ(test, dm_oem_i2c_hw_init(adev), 0);
+       KUNIT_EXPECT_NULL(test, adev->dm.oem_i2c);
+}
+
+/**
+ * dm_test_gpureset_commit_state_no_streams - Test an empty DC state programs 
nothing
+ * @test: The KUnit test context
+ */
+static void dm_test_gpureset_commit_state_no_streams(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+       struct dc_state *context = dm_kunit_alloc_dc_state(test);
+
+       KUNIT_ASSERT_NOT_NULL(test, context);
+       adev->dm.ddev = &adev->ddev;
+
+       dm_gpureset_commit_state(context, &adev->dm);
+}
+
+/**
+ * dm_test_emulated_link_detect_bad_signal - Test an unknown connector signal 
is rejected
+ * @test: The KUnit test context
+ */
+static void dm_test_emulated_link_detect_bad_signal(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+       struct dc_link *link = dm_kunit_alloc_link_with_ctx(test);
+
+       link->ctx->driver_context = adev;
+       link->type = dc_connection_single;
+       link->connector_signal = SIGNAL_TYPE_VIRTUAL;
+
+       amdgpu_dm_emulated_link_detect(link);
+
+       KUNIT_EXPECT_EQ(test, (int)link->type, (int)dc_connection_none);
+       KUNIT_EXPECT_NULL(test, link->local_sink);
+}
+
 static struct kunit_case amdgpu_dm_tests[] = {
        /* Simple DM callbacks */
        KUNIT_CASE(dm_test_wait_for_idle),
@@ -3248,6 +3328,12 @@ static struct kunit_case amdgpu_dm_tests[] = {
        KUNIT_CASE(dm_test_trigger_timing_sync_streams),
        /* dm_acpi_process_phy_transition_interlock */
        KUNIT_CASE(dm_test_acpi_phy_transition_interlock),
+       /* IP block lifecycle helpers */
+       KUNIT_CASE(dm_test_early_fini_audio_disabled),
+       KUNIT_CASE(dm_test_sw_fini_releases_state),
+       KUNIT_CASE(dm_test_oem_i2c_hw_init_no_device),
+       KUNIT_CASE(dm_test_gpureset_commit_state_no_streams),
+       KUNIT_CASE(dm_test_emulated_link_detect_bad_signal),
        {}
 };
 
-- 
2.43.0

Reply via email to