From: Alex Hung <[email protected]>

[WHAT]
Add KUnit tests for amdgpu_dm_plane_helper_prepare_fb() and
amdgpu_dm_plane_helper_cleanup_fb() covering the early return taken when
the plane state carries no framebuffer, so no buffer object is pinned or
unpinned.

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]>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 10 +++--
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |  2 +
 .../amdgpu_dm/tests/amdgpu_dm_plane_test.c    | 40 +++++++++++++++++++
 3 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index b736cd13baaeb..096e1a5e37ad0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1223,8 +1223,8 @@ int amdgpu_dm_plane_fill_plane_buffer_attributes(struct 
amdgpu_device *adev,
 }
 EXPORT_IF_KUNIT(amdgpu_dm_plane_fill_plane_buffer_attributes);
 
-static int amdgpu_dm_plane_helper_prepare_fb(struct drm_plane *plane,
-                                            struct drm_plane_state *new_state)
+STATIC_IFN_KUNIT int amdgpu_dm_plane_helper_prepare_fb(struct drm_plane *plane,
+                                                      struct drm_plane_state 
*new_state)
 {
        struct amdgpu_framebuffer *afb;
        struct drm_gem_object *obj;
@@ -1321,9 +1321,10 @@ static int amdgpu_dm_plane_helper_prepare_fb(struct 
drm_plane *plane,
        amdgpu_bo_unreserve(rbo);
        return r;
 }
+EXPORT_IF_KUNIT(amdgpu_dm_plane_helper_prepare_fb);
 
-static void amdgpu_dm_plane_helper_cleanup_fb(struct drm_plane *plane,
-                                             struct drm_plane_state *old_state)
+STATIC_IFN_KUNIT void amdgpu_dm_plane_helper_cleanup_fb(struct drm_plane 
*plane,
+                                                       struct drm_plane_state 
*old_state)
 {
        struct amdgpu_bo *rbo;
        int r;
@@ -1342,6 +1343,7 @@ static void amdgpu_dm_plane_helper_cleanup_fb(struct 
drm_plane *plane,
        amdgpu_bo_unreserve(rbo);
        amdgpu_bo_unref(&rbo);
 }
+EXPORT_IF_KUNIT(amdgpu_dm_plane_helper_cleanup_fb);
 
 STATIC_IFN_KUNIT void amdgpu_dm_plane_get_min_max_dc_plane_scaling(struct 
drm_device *dev,
                                                                   struct 
drm_framebuffer *fb,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
index b396b3ea78bae..d8ebe48abc9fa 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
@@ -134,5 +134,7 @@ u64 amdgpu_dm_plane_calc_gfx6_mod(const struct 
amdgpu_device *adev, const u32 bp
                                  const enum array_mode_values arr);
 bool amdgpu_dm_plane_gfx6_format_mod_supported(const struct amdgpu_device 
*adev, const u32 bpp,
                                               const u64 modifier);
+int amdgpu_dm_plane_helper_prepare_fb(struct drm_plane *plane, struct 
drm_plane_state *new_state);
+void amdgpu_dm_plane_helper_cleanup_fb(struct drm_plane *plane, struct 
drm_plane_state *old_state);
 #endif
 #endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
index a0e7d012ccbab..7b3f0759cc1f9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
@@ -3559,6 +3559,42 @@ static void dm_test_format_mod_supported_gfx6(struct 
kunit *test)
                                                                listed_mod));
 }
 
+/**
+ * dm_test_helper_prepare_fb_no_fb() - Verify prepare_fb without a framebuffer.
+ * @test: KUnit test context.
+ *
+ * Verify if prepare_fb succeeds without touching any buffer object when the 
new
+ * plane state has no framebuffer bound.
+ */
+static void dm_test_helper_prepare_fb_no_fb(struct kunit *test)
+{
+       struct drm_plane_state state = {0};
+       struct drm_plane *plane;
+
+       plane = kunit_kzalloc(test, sizeof(*plane), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, plane);
+
+       KUNIT_EXPECT_EQ(test, amdgpu_dm_plane_helper_prepare_fb(plane, &state), 
0);
+}
+
+/**
+ * dm_test_helper_cleanup_fb_no_fb() - Verify cleanup_fb without a framebuffer.
+ * @test: KUnit test context.
+ *
+ * Verify if cleanup_fb returns without unpinning anything when the old plane
+ * state has no framebuffer bound.
+ */
+static void dm_test_helper_cleanup_fb_no_fb(struct kunit *test)
+{
+       struct drm_plane_state state = {0};
+       struct drm_plane *plane;
+
+       plane = kunit_kzalloc(test, sizeof(*plane), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, plane);
+
+       amdgpu_dm_plane_helper_cleanup_fb(plane, &state);
+}
+
 static struct kunit_case amdgpu_dm_plane_test_cases[] = {
        /* amdgpu_dm_plane_is_video_format() */
        KUNIT_CASE(dm_test_plane_is_video_format_known_video),
@@ -3624,6 +3660,10 @@ static struct kunit_case amdgpu_dm_plane_test_cases[] = {
        KUNIT_CASE(dm_test_helper_check_state_small_viewport_height),
        KUNIT_CASE(dm_test_helper_check_state_bottom_clipped_height),
        KUNIT_CASE(dm_test_helper_check_state_scaling_caps),
+       /* amdgpu_dm_plane_helper_prepare_fb() */
+       KUNIT_CASE(dm_test_helper_prepare_fb_no_fb),
+       /* amdgpu_dm_plane_helper_cleanup_fb() */
+       KUNIT_CASE(dm_test_helper_cleanup_fb_no_fb),
        /* amdgpu_dm_plane_atomic_async_check() */
        KUNIT_CASE(dm_test_atomic_async_check_rejects),
        KUNIT_CASE(dm_test_atomic_async_check_overlay_cursor),
-- 
2.43.0

Reply via email to