From: Alex Hung <[email protected]>

[Why]
Add KUnit tests for dm_gpureset_toggle_interrupts() on DCN,
amdgpu_dm_commit_zero_streams() on an already empty DC state, and
dm_destroy_cached_state() without a cached state.

[How]
GRPH_PFLIP is unused on DCN, so only the vupdate interrupt is toggled
and no interrupt service is needed. An unchanged empty stream list makes
dc_commit_streams() return early.

Assisted-by: Copilot:Claude-Opus-5 GPT-5.6 Sol
Reviewed-by: Bhawanpreet Lakha <[email protected]>
Signed-off-by: Alex Hung <[email protected]>
Signed-off-by: Ray Wu <[email protected]>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 13 ++--
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  3 +
 .../display/amdgpu_dm/tests/amdgpu_dm_test.c  | 63 +++++++++++++++++++
 3 files changed, 74 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 7a06486cec9e..bd087155aac2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1425,8 +1425,8 @@ static int dm_hw_fini(struct amdgpu_ip_block *ip_block)
 }
 
 
-static void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev,
-                                struct dc_state *state, bool enable)
+STATIC_IFN_KUNIT void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev,
+                                                   struct dc_state *state, 
bool enable)
 {
        enum dc_irq_source irq_source;
        struct amdgpu_crtc *acrtc;
@@ -1477,10 +1477,11 @@ static void dm_gpureset_toggle_interrupts(struct 
amdgpu_device *adev,
        }
 
 }
+EXPORT_IF_KUNIT(dm_gpureset_toggle_interrupts);
 
-DEFINE_FREE(state_release, struct dc_state *, if (_T) dc_state_release(_T))
+DEFINE_FREE(state_release, struct dc_state *, dc_state_release(_T))
 
-static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc)
+STATIC_IFN_KUNIT enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc)
 {
        struct dc_state *context __free(state_release) = NULL;
        int i;
@@ -1518,6 +1519,7 @@ static enum dc_status 
amdgpu_dm_commit_zero_streams(struct dc *dc)
 
        return dc_commit_streams(dc, &params);
 }
+EXPORT_IF_KUNIT(amdgpu_dm_commit_zero_streams);
 
 static int dm_cache_state(struct amdgpu_device *adev)
 {
@@ -1532,7 +1534,7 @@ static int dm_cache_state(struct amdgpu_device *adev)
        return adev->dm.cached_state ? 0 : r;
 }
 
-static void dm_destroy_cached_state(struct amdgpu_device *adev)
+STATIC_IFN_KUNIT void dm_destroy_cached_state(struct amdgpu_device *adev)
 {
        struct amdgpu_display_manager *dm = &adev->dm;
        struct drm_device *ddev = adev_to_drm(adev);
@@ -1582,6 +1584,7 @@ static void dm_destroy_cached_state(struct amdgpu_device 
*adev)
 
        dm->cached_state = NULL;
 }
+EXPORT_IF_KUNIT(dm_destroy_cached_state);
 
 static int dm_suspend(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 9399f71c528e..645b39e4223b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -1257,6 +1257,9 @@ struct dsc_mst_fairness_vars;
 void mmhub_read_system_context(struct amdgpu_device *adev,
                               struct dc_phy_addr_space_config *pa_config);
 int amdgpu_dm_init_power_module(struct amdgpu_display_manager *dm);
+void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev, struct dc_state 
*state, bool enable);
+enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc);
+void dm_destroy_cached_state(struct amdgpu_device *adev);
 int dm_early_init(struct amdgpu_ip_block *ip_block);
 int fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
                                const struct drm_plane_state *plane_state,
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 3c975ca2710d..7a79aee057f8 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
@@ -4217,6 +4217,35 @@ static void 
dm_test_early_init_unsupported_version(struct kunit *test)
        KUNIT_EXPECT_FALSE(test, adev->dc_enabled);
 }
 
+/* Tests for the remaining suspend and resume helpers */
+
+/**
+ * dm_test_commit_zero_streams_empty - Test committing an already empty DC 
state
+ * @test: The KUnit test context
+ */
+static void dm_test_commit_zero_streams_empty(struct kunit *test)
+{
+       struct dc *dc = dm_kunit_alloc_dc_with_ctx(test);
+
+       dc->current_state = dm_kunit_alloc_dc_state(test);
+       KUNIT_ASSERT_NOT_NULL(test, dc->current_state);
+
+       KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_commit_zero_streams(dc), 
(int)DC_OK);
+}
+
+/**
+ * dm_test_destroy_cached_state_none - Test no cached state is a no-op
+ * @test: The KUnit test context
+ */
+static void dm_test_destroy_cached_state_none(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+
+       dm_destroy_cached_state(adev);
+
+       KUNIT_EXPECT_NULL(test, adev->dm.cached_state);
+}
+
 /* Tests for dm_update_mst_vcpi_slots_for_dsc() */
 
 /**
@@ -4790,6 +4819,35 @@ static void dm_test_initialize_plane_overlay(struct 
kunit *test)
                                               DRM_PLANE_TYPE_OVERLAY, 
plane_cap), 0);
 }
 
+/* Tests for dm_gpureset_toggle_interrupts() */
+
+/**
+ * dm_test_gpureset_toggle_interrupts_dcn - Test DCN only toggles the vupdate 
IRQ
+ * @test: The KUnit test context
+ */
+static void dm_test_gpureset_toggle_interrupts_dcn(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+       struct dc_state *state = dm_kunit_alloc_dc_state(test);
+       struct amdgpu_crtc *acrtc;
+
+       KUNIT_ASSERT_NOT_NULL(test, state);
+       acrtc = kunit_kzalloc(test, sizeof(*acrtc), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, acrtc);
+
+       adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 2, 0);
+       adev->mode_info.num_crtc = 1;
+       adev->mode_info.crtcs[0] = acrtc;
+       acrtc->base.dev = &adev->ddev;
+       acrtc->otg_inst = 0;
+       state->stream_count = 1;
+       state->stream_status[0].primary_otg_inst = 0;
+       state->stream_status[0].plane_count = 1;
+
+       /* GRPH_PFLIP is unused on DCN, so only the vupdate IRQ is touched. */
+       dm_gpureset_toggle_interrupts(adev, state, true);
+}
+
 static struct kunit_case amdgpu_dm_tests[] = {
        /* Simple DM callbacks */
        KUNIT_CASE(dm_test_wait_for_idle),
@@ -4994,6 +5052,9 @@ static struct kunit_case amdgpu_dm_tests[] = {
        KUNIT_CASE(dm_test_early_init_legacy_asics),
        KUNIT_CASE(dm_test_early_init_dcn_versions),
        KUNIT_CASE(dm_test_early_init_unsupported_version),
+       /* suspend and resume helpers */
+       KUNIT_CASE(dm_test_commit_zero_streams_empty),
+       KUNIT_CASE(dm_test_destroy_cached_state_none),
        /* dm_update_mst_vcpi_slots_for_dsc */
        KUNIT_CASE(dm_test_mst_vcpi_slots_no_connector),
        KUNIT_CASE(dm_test_mst_vcpi_slots_skips_writeback),
@@ -5023,6 +5084,8 @@ static struct kunit_case amdgpu_dm_tests[] = {
        /* initialize_plane */
        KUNIT_CASE(dm_test_initialize_plane_primary),
        KUNIT_CASE(dm_test_initialize_plane_overlay),
+       /* dm_gpureset_toggle_interrupts */
+       KUNIT_CASE(dm_test_gpureset_toggle_interrupts_dcn),
        {}
 };
 
-- 
2.43.0

Reply via email to