[WHAT]
Add KUnit tests for amdgpu_dm_commit_cursors() covering an empty commit,
a non-cursor plane, and a cursor update, and for amdgpu_dm_update_cursor()
covering missing framebuffers and removal of an active stream cursor.

[HOW]
Reuse the single-plane commit fixture. The disable path uses the real
state-only DC cursor position setter without 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]>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  10 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   5 +
 .../display/amdgpu_dm/tests/amdgpu_dm_test.c  | 140 ++++++++++++++++++
 3 files changed, 151 insertions(+), 4 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 9d233b18f2df..08f2cc7fec68 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3587,7 +3587,7 @@ static void remove_stream(struct amdgpu_device *adev,
        acrtc->enabled = false;
 }
 
-static void amdgpu_dm_commit_cursors(struct drm_atomic_commit *state)
+STATIC_IFN_KUNIT void amdgpu_dm_commit_cursors(struct drm_atomic_commit *state)
 {
        struct drm_plane *plane;
        struct drm_plane_state *old_plane_state;
@@ -3601,6 +3601,7 @@ static void amdgpu_dm_commit_cursors(struct 
drm_atomic_commit *state)
                if (plane->type == DRM_PLANE_TYPE_CURSOR)
                        amdgpu_dm_plane_handle_cursor_update(plane, 
old_plane_state);
 }
+EXPORT_IF_KUNIT(amdgpu_dm_commit_cursors);
 
 static inline uint32_t get_mem_type(struct drm_framebuffer *fb)
 {
@@ -3609,9 +3610,9 @@ static inline uint32_t get_mem_type(struct 
drm_framebuffer *fb)
        return abo->tbo.resource ? abo->tbo.resource->mem_type : 0;
 }
 
-static void amdgpu_dm_update_cursor(struct drm_plane *plane,
-                                   struct drm_plane_state *old_plane_state,
-                                   struct dc_stream_update *update)
+STATIC_IFN_KUNIT void amdgpu_dm_update_cursor(struct drm_plane *plane,
+                                             struct drm_plane_state 
*old_plane_state,
+                                             struct dc_stream_update *update)
 {
        struct amdgpu_device *adev = drm_to_adev(plane->dev);
        struct amdgpu_framebuffer *afb = 
to_amdgpu_framebuffer(plane->state->fb);
@@ -3680,6 +3681,7 @@ static void amdgpu_dm_update_cursor(struct drm_plane 
*plane,
                update->cursor_position = &crtc_state->stream->cursor_position;
        }
 }
+EXPORT_IF_KUNIT(amdgpu_dm_update_cursor);
 
 static void amdgpu_dm_enable_self_refresh(struct amdgpu_display_manager *dm,
                                          struct amdgpu_crtc *acrtc_attach,
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 a48154ea62ae..ed2341b387d9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -86,6 +86,7 @@ struct dc;
 struct amdgpu_bo;
 struct dmub_srv;
 struct dc_plane_state;
+struct dc_stream_update;
 struct dmub_notification;
 struct dmub_cmd_fused_request;
 
@@ -1171,6 +1172,10 @@ struct dm_atomic_state *dm_atomic_get_new_state(struct 
drm_atomic_commit *state)
 struct drm_private_state *dm_atomic_duplicate_state(struct drm_private_obj 
*obj);
 void dm_atomic_destroy_state(struct drm_private_obj *obj,
                             struct drm_private_state *state);
+void amdgpu_dm_commit_cursors(struct drm_atomic_commit *state);
+void amdgpu_dm_update_cursor(struct drm_plane *plane,
+                            struct drm_plane_state *old_plane_state,
+                            struct dc_stream_update *update);
 int add_affected_mst_dsc_crtcs(struct drm_atomic_commit *state,
                               struct drm_crtc *crtc);
 int dm_plane_layer_index_cmp(const void *a, const void *b);
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 2afa73a07ebd..a2671ad90bfe 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
@@ -1418,6 +1418,140 @@ static void 
dm_test_add_affected_mst_dsc_crtcs_disabled(struct kunit *test)
        KUNIT_EXPECT_EQ(test, add_affected_mst_dsc_crtcs(state, crtc), 0);
 }
 
+/* Tests for amdgpu_dm_commit_cursors() */
+
+/**
+ * dm_test_commit_cursors_no_planes - Test an empty plane set is a no-op
+ * @test: The KUnit test context
+ */
+static void dm_test_commit_cursors_no_planes(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+
+       amdgpu_dm_commit_cursors(dm_test_alloc_commit(test, adev));
+}
+
+/*
+ * Build a commit holding a single plane of @type with empty old and new plane
+ * states.
+ */
+static struct drm_atomic_commit *
+dm_test_commit_with_plane(struct kunit *test, struct amdgpu_device *adev,
+                         enum drm_plane_type type)
+{
+       struct drm_atomic_commit *state = dm_test_alloc_commit(test, adev);
+       struct drm_plane_state *old_state, *new_state;
+       struct drm_plane *plane;
+
+       plane = kunit_kzalloc(test, sizeof(*plane), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, plane);
+       old_state = kunit_kzalloc(test, sizeof(*old_state), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, old_state);
+       new_state = kunit_kzalloc(test, sizeof(*new_state), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, new_state);
+       state->planes = kunit_kzalloc(test, sizeof(*state->planes), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, state->planes);
+
+       plane->type = type;
+       plane->dev = &adev->ddev;
+       plane->state = new_state;
+       adev->ddev.mode_config.num_total_plane = 1;
+       state->planes[0].ptr = plane;
+       state->planes[0].old_state = old_state;
+
+       return state;
+}
+
+/**
+ * dm_test_commit_cursors_skips_non_cursor - Test non-cursor planes are skipped
+ * @test: The KUnit test context
+ */
+static void dm_test_commit_cursors_skips_non_cursor(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+
+       amdgpu_dm_commit_cursors(dm_test_commit_with_plane(test, adev,
+                                                          
DRM_PLANE_TYPE_PRIMARY));
+}
+
+/**
+ * dm_test_commit_cursors_updates_cursor - Test cursor planes reach the cursor 
update
+ * @test: The KUnit test context
+ */
+static void dm_test_commit_cursors_updates_cursor(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+
+       amdgpu_dm_commit_cursors(dm_test_commit_with_plane(test, adev,
+                                                          
DRM_PLANE_TYPE_CURSOR));
+}
+
+/**
+ * dm_test_update_cursor_no_framebuffer - Test missing framebuffers leave the 
update untouched
+ * @test: The KUnit test context
+ */
+static void dm_test_update_cursor_no_framebuffer(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+       struct drm_atomic_commit *state;
+       struct dc_stream_update *update;
+       struct drm_plane *plane;
+
+       state = dm_test_commit_with_plane(test, adev, DRM_PLANE_TYPE_CURSOR);
+       plane = state->planes[0].ptr;
+       update = kunit_kzalloc(test, sizeof(*update), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, update);
+
+       update->cursor_attributes = (void *)1;
+       update->cursor_position = (void *)1;
+
+       amdgpu_dm_update_cursor(plane, state->planes[0].old_state, update);
+
+       KUNIT_EXPECT_PTR_EQ(test, update->cursor_attributes, (void *)1);
+       KUNIT_EXPECT_PTR_EQ(test, update->cursor_position, (void *)1);
+}
+
+/**
+ * dm_test_update_cursor_disables_stream - Test removing the framebuffer 
disables the cursor
+ * @test: The KUnit test context
+ */
+static void dm_test_update_cursor_disables_stream(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+       struct drm_atomic_commit *state;
+       struct dc_stream_update *update;
+       struct drm_plane_state *old_plane_state;
+       struct dm_crtc_state *crtc_state;
+       struct amdgpu_framebuffer *afb;
+       struct amdgpu_crtc *acrtc;
+       struct drm_plane *plane;
+
+       state = dm_test_commit_with_plane(test, adev, DRM_PLANE_TYPE_CURSOR);
+       plane = state->planes[0].ptr;
+       old_plane_state = state->planes[0].old_state;
+       crtc_state = kunit_kzalloc(test, sizeof(*crtc_state), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, crtc_state);
+       afb = kunit_kzalloc(test, sizeof(*afb), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, afb);
+       acrtc = kunit_kzalloc(test, sizeof(*acrtc), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, acrtc);
+       update = kunit_kzalloc(test, sizeof(*update), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, update);
+
+       old_plane_state->fb = &afb->base;
+       old_plane_state->crtc = &acrtc->base;
+       acrtc->base.state = &crtc_state->base;
+       crtc_state->stream = dm_kunit_alloc_stream(test, NULL);
+       crtc_state->stream->cursor_position.enable = true;
+
+       amdgpu_dm_update_cursor(plane, old_plane_state, update);
+
+       KUNIT_EXPECT_FALSE(test, crtc_state->stream->cursor_position.enable);
+       KUNIT_EXPECT_PTR_EQ(test, update->cursor_position,
+                           &crtc_state->stream->cursor_position);
+       KUNIT_EXPECT_NULL(test, update->cursor_attributes);
+}
+
 static struct kunit_case amdgpu_dm_tests[] = {
        /* Simple DM callbacks */
        KUNIT_CASE(dm_test_wait_for_idle),
@@ -1497,6 +1631,12 @@ static struct kunit_case amdgpu_dm_tests[] = {
        KUNIT_CASE(dm_test_add_affected_mst_dsc_crtcs_not_mst),
        KUNIT_CASE(dm_test_add_affected_mst_dsc_crtcs_other_crtc),
        KUNIT_CASE(dm_test_add_affected_mst_dsc_crtcs_disabled),
+       /* amdgpu_dm_commit_cursors */
+       KUNIT_CASE(dm_test_commit_cursors_no_planes),
+       KUNIT_CASE(dm_test_commit_cursors_skips_non_cursor),
+       KUNIT_CASE(dm_test_commit_cursors_updates_cursor),
+       KUNIT_CASE(dm_test_update_cursor_no_framebuffer),
+       KUNIT_CASE(dm_test_update_cursor_disables_stream),
        {}
 };
 
-- 
2.43.0

Reply via email to