[PATCH 32/59] drm/amd/display: Test cursor commit
Alex Hung <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
[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