From: Alex Hung <[email protected]>

[Why]
Add KUnit tests for an empty amdgpu_dm_atomic_check(), an unchanged
CRTC update, and a detached plane update.

[How]
Use standard DRM KUnit objects and existing state fixtures so each
helper reaches its software-only early return without DC hardware
programming.

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 | 40 +++++-----
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 17 +++++
 .../display/amdgpu_dm/tests/amdgpu_dm_test.c  | 76 +++++++++++++++++++
 3 files changed, 116 insertions(+), 17 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 d94d18e884ef..9f64bea15ea1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -145,8 +145,10 @@ STATIC_IFN_KUNIT int amdgpu_dm_atomic_setup_commit(struct 
drm_atomic_commit *sta
 static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_commit *state);
 STATIC_IFN_KUNIT void dm_enable_per_frame_crtc_master_sync(struct dc_state 
*context);
 
+#if !IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
 static int amdgpu_dm_atomic_check(struct drm_device *dev,
                                  struct drm_atomic_commit *state);
+#endif
 
 static inline void amdgpu_dm_exit_ips_for_hw_access(struct dc *dc)
 {
@@ -5428,13 +5430,13 @@ STATIC_IFN_KUNIT int do_aquire_global_lock(struct 
drm_device *dev,
 }
 EXPORT_IF_KUNIT(do_aquire_global_lock);
 
-static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
-                        struct drm_atomic_commit *state,
-                        struct drm_crtc *crtc,
-                        struct drm_crtc_state *old_crtc_state,
-                        struct drm_crtc_state *new_crtc_state,
-                        bool enable,
-                        bool *lock_and_validation_needed)
+STATIC_IFN_KUNIT int dm_update_crtc_state(struct amdgpu_display_manager *dm,
+                                         struct drm_atomic_commit *state,
+                                         struct drm_crtc *crtc,
+                                         struct drm_crtc_state *old_crtc_state,
+                                         struct drm_crtc_state *new_crtc_state,
+                                         bool enable,
+                                         bool *lock_and_validation_needed)
 {
        struct dm_atomic_state *dm_state = NULL;
        struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state;
@@ -5703,6 +5705,7 @@ static int dm_update_crtc_state(struct 
amdgpu_display_manager *dm,
                dc_stream_release(new_stream);
        return ret;
 }
+EXPORT_IF_KUNIT(dm_update_crtc_state);
 
 STATIC_IFN_KUNIT bool should_reset_plane(struct drm_atomic_commit *state,
                                         struct drm_plane *plane,
@@ -5869,14 +5872,15 @@ STATIC_IFN_KUNIT bool should_reset_plane(struct 
drm_atomic_commit *state,
 }
 EXPORT_IF_KUNIT(should_reset_plane);
 
-static int dm_update_plane_state(struct dc *dc,
-                                struct drm_atomic_commit *state,
-                                struct drm_plane *plane,
-                                struct drm_plane_state *old_plane_state,
-                                struct drm_plane_state *new_plane_state,
-                                bool enable,
-                                bool *lock_and_validation_needed,
-                                bool *is_top_most_overlay)
+STATIC_IFN_KUNIT int
+dm_update_plane_state(struct dc *dc,
+                     struct drm_atomic_commit *state,
+                     struct drm_plane *plane,
+                     struct drm_plane_state *old_plane_state,
+                     struct drm_plane_state *new_plane_state,
+                     bool enable,
+                     bool *lock_and_validation_needed,
+                     bool *is_top_most_overlay)
 {
 
        struct dm_atomic_state *dm_state = NULL;
@@ -6040,6 +6044,7 @@ static int dm_update_plane_state(struct dc *dc,
 
        return ret;
 }
+EXPORT_IF_KUNIT(dm_update_plane_state);
 
 /*
  * The normalized_zpos value cannot be used by this iterator directly. It's 
only
@@ -6166,8 +6171,8 @@ EXPORT_IF_KUNIT(amdgpu_dm_crtc_mem_type_changed);
  *
  * Return: -Error code if validation failed.
  */
-static int amdgpu_dm_atomic_check(struct drm_device *dev,
-                                 struct drm_atomic_commit *state)
+STATIC_IFN_KUNIT int amdgpu_dm_atomic_check(struct drm_device *dev,
+                                           struct drm_atomic_commit *state)
 {
        struct amdgpu_device *adev = drm_to_adev(dev);
        struct dm_atomic_state *dm_state = NULL;
@@ -6678,6 +6683,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 
        return ret;
 }
+EXPORT_IF_KUNIT(amdgpu_dm_atomic_check);
 
 void amdgpu_dm_trigger_timing_sync(struct drm_device *dev)
 {
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 3c63dfcc2343..c99a84bb040e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -1208,6 +1208,23 @@ void amdgpu_dm_update_hdcp(struct drm_atomic_commit 
*state);
 int amdgpu_dm_atomic_setup_commit(struct drm_atomic_commit *state);
 int do_aquire_global_lock(struct drm_device *dev,
                          struct drm_atomic_commit *state);
+int dm_update_crtc_state(struct amdgpu_display_manager *dm,
+                        struct drm_atomic_commit *state,
+                        struct drm_crtc *crtc,
+                        struct drm_crtc_state *old_crtc_state,
+                        struct drm_crtc_state *new_crtc_state,
+                        bool enable,
+                        bool *lock_and_validation_needed);
+int dm_update_plane_state(struct dc *dc,
+                         struct drm_atomic_commit *state,
+                         struct drm_plane *plane,
+                         struct drm_plane_state *old_plane_state,
+                         struct drm_plane_state *new_plane_state,
+                         bool enable,
+                         bool *lock_and_validation_needed,
+                         bool *is_top_most_overlay);
+int amdgpu_dm_atomic_check(struct drm_device *dev,
+                          struct drm_atomic_commit *state);
 void amdgpu_dm_mod_power_update_streams(struct drm_atomic_commit *state,
                                        struct amdgpu_display_manager *dm);
 void amdgpu_dm_mod_power_setup_streams(struct drm_atomic_commit *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 3209608a41b8..6335fc23e977 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
@@ -2990,6 +2990,21 @@ static void dm_test_atomic_setup_commit_empty(struct 
kunit *test)
                        0);
 }
 
+/**
+ * dm_test_atomic_check_empty - Test an empty atomic commit needs no DC 
validation
+ * @test: The KUnit test context
+ */
+static void dm_test_atomic_check_empty(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+       struct drm_atomic_commit *state = dm_test_alloc_commit(test, adev);
+
+       adev->dm.dc = dm_kunit_alloc_dc_with_ctx(test);
+
+       KUNIT_EXPECT_EQ(test, amdgpu_dm_atomic_check(&adev->ddev, state), 0);
+       KUNIT_EXPECT_EQ(test, state->num_private_objs, 0U);
+}
+
 /*
  * A commit with one connector of @type bound to a CRTC that keeps its stream.
  * The content protection state is unchanged, so amdgpu_dm_update_hdcp() walks
@@ -3172,6 +3187,64 @@ static void 
dm_test_aquire_global_lock_waits_commit(struct kunit *test)
        KUNIT_EXPECT_EQ(test, ret, 0);
 }
 
+/**
+ * dm_test_update_crtc_state_unchanged - Test unchanged state needs no 
validation
+ * @test: The KUnit test context
+ */
+static void dm_test_update_crtc_state_unchanged(struct kunit *test)
+{
+       struct dm_test_reset_plane_ctx *ctx = 
dm_test_reset_plane_ctx_alloc(test);
+       bool lock_and_validation_needed = false;
+
+       ctx->adev->dm.adev = ctx->adev;
+       KUNIT_EXPECT_EQ(test,
+                       dm_update_crtc_state(&ctx->adev->dm, ctx->state, 
ctx->crtc,
+                                            &ctx->old_crtc_state->base,
+                                            &ctx->new_crtc_state->base, true,
+                                            &lock_and_validation_needed),
+                       0);
+       KUNIT_EXPECT_FALSE(test, lock_and_validation_needed);
+       KUNIT_EXPECT_NULL(test, ctx->new_crtc_state->stream);
+}
+
+/**
+ * dm_test_update_plane_state_detached - Test a detached plane needs no DC 
update
+ * @test: The KUnit test context
+ */
+static void dm_test_update_plane_state_detached(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+       struct dm_plane_state *old_plane_state;
+       struct dm_plane_state *new_plane_state;
+       struct drm_plane *plane;
+       bool lock_and_validation_needed = false;
+       bool is_top_most_overlay = true;
+
+       old_plane_state = kunit_kzalloc(test, sizeof(*old_plane_state), 
GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, old_plane_state);
+       new_plane_state = kunit_kzalloc(test, sizeof(*new_plane_state), 
GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, new_plane_state);
+       plane = kunit_kzalloc(test, sizeof(*plane), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, plane);
+       adev->reset_domain = kunit_kzalloc(test, sizeof(*adev->reset_domain), 
GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, adev->reset_domain);
+
+       adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 2, 0);
+       plane->dev = &adev->ddev;
+       plane->type = DRM_PLANE_TYPE_PRIMARY;
+
+       KUNIT_EXPECT_EQ(test,
+                       dm_update_plane_state(NULL, dm_test_alloc_commit(test, 
adev), plane,
+                                             &old_plane_state->base,
+                                             &new_plane_state->base, false,
+                                             &lock_and_validation_needed,
+                                             &is_top_most_overlay),
+                       0);
+       KUNIT_EXPECT_FALSE(test, lock_and_validation_needed);
+       KUNIT_EXPECT_TRUE(test, is_top_most_overlay);
+       KUNIT_EXPECT_NULL(test, new_plane_state->dc_state);
+}
+
 /**
  * dm_test_mod_power_update_streams_empty - Test an empty commit updates no 
streams
  * @test: The KUnit test context
@@ -5251,9 +5324,12 @@ static struct kunit_case amdgpu_dm_tests[] = {
        KUNIT_CASE(dm_test_atomic_setup_commit_color_mgmt),
        KUNIT_CASE(dm_test_atomic_setup_commit_modeset),
        KUNIT_CASE(dm_test_atomic_setup_commit_bad_lut),
+       KUNIT_CASE(dm_test_atomic_check_empty),
        KUNIT_CASE(dm_test_aquire_global_lock_no_crtc),
        KUNIT_CASE(dm_test_aquire_global_lock_no_commit),
        KUNIT_CASE(dm_test_aquire_global_lock_waits_commit),
+       KUNIT_CASE(dm_test_update_crtc_state_unchanged),
+       KUNIT_CASE(dm_test_update_plane_state_detached),
        KUNIT_CASE(dm_test_mod_power_update_streams_empty),
        KUNIT_CASE(dm_test_mod_power_update_streams_no_modeset),
        KUNIT_CASE(dm_test_mod_power_update_streams_enable),
-- 
2.43.0

Reply via email to