[PATCH 35/59] drm/amd/display: Test CRTC memory domain change detection
Alex Hung <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
[WHAT] Add KUnit tests for amdgpu_dm_crtc_mem_type_changed() covering an empty plane mask, a plane missing one of its states, framebuffers in the same memory domain, and a framebuffer migrated between domains. [HOW] Back the framebuffers with fake buffer objects carrying a TTM resource, so get_mem_type() resolves a memory domain without a live TTM device. 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 | 7 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 3 + .../display/amdgpu_dm/tests/amdgpu_dm_test.c | 138 ++++++++++++++++++ 3 files changed, 145 insertions(+), 3 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 4650b5f09c08..70f50fa17366 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6044,9 +6044,9 @@ STATIC_IFN_KUNIT int add_affected_mst_dsc_crtcs(struct drm_atomic_commit *state, } EXPORT_IF_KUNIT(add_affected_mst_dsc_crtcs); -static bool amdgpu_dm_crtc_mem_type_changed(struct drm_device *dev, - struct drm_atomic_commit *state, - struct drm_crtc_state *crtc_state) +STATIC_IFN_KUNIT bool amdgpu_dm_crtc_mem_type_changed(struct drm_device *dev, + struct drm_atomic_commit *state, + struct drm_crtc_state *crtc_state) { struct drm_plane *plane; struct drm_plane_state *new_plane_state, *old_plane_state; @@ -6065,6 +6065,7 @@ static bool amdgpu_dm_crtc_mem_type_changed(struct drm_device *dev, return false; } +EXPORT_IF_KUNIT(amdgpu_dm_crtc_mem_type_changed); /** * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM. 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 c22266f534e3..ca19977cf788 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -1186,6 +1186,9 @@ void dm_arm_vblank_event_pre_programming(struct amdgpu_crtc *acrtc, bool pflip_update, bool cursor_update); int add_affected_mst_dsc_crtcs(struct drm_atomic_commit *state, struct drm_crtc *crtc); +bool amdgpu_dm_crtc_mem_type_changed(struct drm_device *dev, + struct drm_atomic_commit *state, + struct drm_crtc_state *crtc_state); int dm_plane_layer_index_cmp(const void *a, const void *b); int fill_plane_color_attributes(const struct drm_plane_state *plane_state, const enum surface_pixel_format format, 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 845638fed223..0c57b3cc47fe 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 @@ -1804,6 +1804,139 @@ static void dm_test_update_pflip_irq_state_dce(struct kunit *test) (int)AMDGPU_IRQ_STATE_DISABLE); } +/* Tests for amdgpu_dm_crtc_mem_type_changed() */ + +struct dm_test_mem_type_ctx { + struct amdgpu_device *adev; + struct drm_atomic_commit *state; + struct drm_crtc_state *crtc_state; + struct drm_plane *plane; + struct drm_plane_state *old_plane_state; + struct drm_plane_state *new_plane_state; +}; + +/* + * Register a single plane on the CRTC's plane mask. get_mem_type() walks + * fb->obj[0] back to an amdgpu_bo, so the framebuffers are backed by fake + * buffer objects with a TTM resource instead of a live TTM device. + */ +static struct drm_framebuffer *dm_test_alloc_fb(struct kunit *test, + u32 mem_type) +{ + struct drm_framebuffer *fb; + struct ttm_resource *res; + struct amdgpu_bo *abo; + + fb = kunit_kzalloc(test, sizeof(*fb), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, fb); + abo = kunit_kzalloc(test, sizeof(*abo), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, abo); + res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, res); + + res->mem_type = mem_type; + abo->tbo.resource = res; + fb->obj[0] = &abo->tbo.base; + + return fb; +} + +static struct dm_test_mem_type_ctx *dm_test_mem_type_ctx_alloc(struct kunit *test) +{ + struct dm_test_mem_type_ctx *ctx; + + ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, ctx); + + ctx->adev = dm_kunit_alloc_adev(test); + ctx->state = dm_test_alloc_commit(test, ctx->adev); + ctx->crtc_state = kunit_kzalloc(test, sizeof(*ctx->crtc_state), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, ctx->crtc_state); + ctx->plane = drm_kunit_helper_create_primary_plane(test, &ctx->adev->ddev, + NULL, NULL, NULL, 0, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->plane); + ctx->old_plane_state = kunit_kzalloc(test, sizeof(*ctx->old_plane_state), + GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, ctx->old_plane_state); + ctx->new_plane_state = kunit_kzalloc(test, sizeof(*ctx->new_plane_state), + GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, ctx->new_plane_state); + ctx->state->planes = kunit_kcalloc(test, ctx->plane->index + 1, + sizeof(*ctx->state->planes), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, ctx->state->planes); + + ctx->crtc_state->plane_mask = drm_plane_mask(ctx->plane); + ctx->state->planes[ctx->plane->index].ptr = ctx->plane; + + return ctx; +} + +/** + * dm_test_mem_type_changed_no_planes - Test an empty plane mask reports no change + * @test: The KUnit test context + */ +static void dm_test_mem_type_changed_no_planes(struct kunit *test) +{ + struct dm_test_mem_type_ctx *ctx = dm_test_mem_type_ctx_alloc(test); + + ctx->crtc_state->plane_mask = 0; + + KUNIT_EXPECT_FALSE(test, amdgpu_dm_crtc_mem_type_changed(&ctx->adev->ddev, + ctx->state, + ctx->crtc_state)); +} + +/** + * dm_test_mem_type_changed_missing_state - Test a plane without both states is skipped + * @test: The KUnit test context + */ +static void dm_test_mem_type_changed_missing_state(struct kunit *test) +{ + struct dm_test_mem_type_ctx *ctx = dm_test_mem_type_ctx_alloc(test); + + ctx->state->planes[ctx->plane->index].new_state = ctx->new_plane_state; + + KUNIT_EXPECT_FALSE(test, amdgpu_dm_crtc_mem_type_changed(&ctx->adev->ddev, + ctx->state, + ctx->crtc_state)); +} + +/** + * dm_test_mem_type_changed_same_domain - Test identical memory domains report no change + * @test: The KUnit test context + */ +static void dm_test_mem_type_changed_same_domain(struct kunit *test) +{ + struct dm_test_mem_type_ctx *ctx = dm_test_mem_type_ctx_alloc(test); + + ctx->old_plane_state->fb = dm_test_alloc_fb(test, TTM_PL_VRAM); + ctx->new_plane_state->fb = dm_test_alloc_fb(test, TTM_PL_VRAM); + ctx->state->planes[ctx->plane->index].old_state = ctx->old_plane_state; + ctx->state->planes[ctx->plane->index].new_state = ctx->new_plane_state; + + KUNIT_EXPECT_FALSE(test, amdgpu_dm_crtc_mem_type_changed(&ctx->adev->ddev, + ctx->state, + ctx->crtc_state)); +} + +/** + * dm_test_mem_type_changed_different_domain - Test a domain migration is detected + * @test: The KUnit test context + */ +static void dm_test_mem_type_changed_different_domain(struct kunit *test) +{ + struct dm_test_mem_type_ctx *ctx = dm_test_mem_type_ctx_alloc(test); + + ctx->old_plane_state->fb = dm_test_alloc_fb(test, TTM_PL_TT); + ctx->new_plane_state->fb = dm_test_alloc_fb(test, TTM_PL_VRAM); + ctx->state->planes[ctx->plane->index].old_state = ctx->old_plane_state; + ctx->state->planes[ctx->plane->index].new_state = ctx->new_plane_state; + + KUNIT_EXPECT_TRUE(test, amdgpu_dm_crtc_mem_type_changed(&ctx->adev->ddev, + ctx->state, + ctx->crtc_state)); +} + static struct kunit_case amdgpu_dm_tests[] = { /* Simple DM callbacks */ KUNIT_CASE(dm_test_wait_for_idle), @@ -1900,6 +2033,11 @@ static struct kunit_case amdgpu_dm_tests[] = { /* dm_update_pflip_irq_state */ KUNIT_CASE(dm_test_update_pflip_irq_state_dcn), KUNIT_CASE(dm_test_update_pflip_irq_state_dce), + /* amdgpu_dm_crtc_mem_type_changed */ + KUNIT_CASE(dm_test_mem_type_changed_no_planes), + KUNIT_CASE(dm_test_mem_type_changed_missing_state), + KUNIT_CASE(dm_test_mem_type_changed_same_domain), + KUNIT_CASE(dm_test_mem_type_changed_different_domain), {} }; -- 2.43.0