diff options
| author | Alex Hung <alex.hung@amd.com> | 2026-08-13 21:00:45 -0600 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-09-10 11:59:56 -0400 |
| commit | 9f46b2f90f350149b3edfd4af624e507aec84ba7 (patch) | |
| tree | 29941972d1947c37d3e42d2424254a0fc20f04b2 | |
| parent | 519ba75dcd1a4061909d2bf74230b84136dae2cc (diff) | |
| download | linux-next-9f46b2f90f350149b3edfd4af624e507aec84ba7.tar.gz linux-next-9f46b2f90f350149b3edfd4af624e507aec84ba7.zip | |
drm/amd/display: Test GPU reset helpers
[Why]
Add KUnit tests for dm_gpureset_toggle_interrupts() on DCN,
amdgpu_dm_commit_zero_streams() on an already empty DC state, and
dm_destroy_cached_state() without a cached state.
[How]
GRPH_PFLIP is unused on DCN, so only the vupdate interrupt is toggled
and no interrupt service is needed. An unchanged empty stream list makes
dc_commit_streams() return early.
Assisted-by: Copilot:Claude-Opus-5 GPT-5.6 Sol
Reviewed-by: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Ray Wu <ray.wu@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
| -rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c | 63 |
3 files changed, 74 insertions, 5 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 b31f4e090790..13a12f7d1c27 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1425,8 +1425,8 @@ static int dm_hw_fini(struct amdgpu_ip_block *ip_block) } -static void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev, - struct dc_state *state, bool enable) +STATIC_IFN_KUNIT void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev, + struct dc_state *state, bool enable) { enum dc_irq_source irq_source; struct amdgpu_crtc *acrtc; @@ -1477,10 +1477,11 @@ static void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev, } } +EXPORT_IF_KUNIT(dm_gpureset_toggle_interrupts); -DEFINE_FREE(state_release, struct dc_state *, if (_T) dc_state_release(_T)) +DEFINE_FREE(state_release, struct dc_state *, dc_state_release(_T)) -static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc) +STATIC_IFN_KUNIT enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc) { struct dc_state *context __free(state_release) = NULL; int i; @@ -1518,6 +1519,7 @@ static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc) return dc_commit_streams(dc, ¶ms); } +EXPORT_IF_KUNIT(amdgpu_dm_commit_zero_streams); static int dm_cache_state(struct amdgpu_device *adev) { @@ -1532,7 +1534,7 @@ static int dm_cache_state(struct amdgpu_device *adev) return adev->dm.cached_state ? 0 : r; } -static void dm_destroy_cached_state(struct amdgpu_device *adev) +STATIC_IFN_KUNIT void dm_destroy_cached_state(struct amdgpu_device *adev) { struct amdgpu_display_manager *dm = &adev->dm; struct drm_device *ddev = adev_to_drm(adev); @@ -1582,6 +1584,7 @@ static void dm_destroy_cached_state(struct amdgpu_device *adev) dm->cached_state = NULL; } +EXPORT_IF_KUNIT(dm_destroy_cached_state); static int dm_suspend(struct amdgpu_ip_block *ip_block) { 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 9399f71c528e..645b39e4223b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -1257,6 +1257,9 @@ struct dsc_mst_fairness_vars; void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_addr_space_config *pa_config); int amdgpu_dm_init_power_module(struct amdgpu_display_manager *dm); +void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev, struct dc_state *state, bool enable); +enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc); +void dm_destroy_cached_state(struct amdgpu_device *adev); int dm_early_init(struct amdgpu_ip_block *ip_block); int fill_dc_plane_info_and_addr(struct amdgpu_device *adev, const struct drm_plane_state *plane_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 3c975ca2710d..7a79aee057f8 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 @@ -4217,6 +4217,35 @@ static void dm_test_early_init_unsupported_version(struct kunit *test) KUNIT_EXPECT_FALSE(test, adev->dc_enabled); } +/* Tests for the remaining suspend and resume helpers */ + +/** + * dm_test_commit_zero_streams_empty - Test committing an already empty DC state + * @test: The KUnit test context + */ +static void dm_test_commit_zero_streams_empty(struct kunit *test) +{ + struct dc *dc = dm_kunit_alloc_dc_with_ctx(test); + + dc->current_state = dm_kunit_alloc_dc_state(test); + KUNIT_ASSERT_NOT_NULL(test, dc->current_state); + + KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_commit_zero_streams(dc), (int)DC_OK); +} + +/** + * dm_test_destroy_cached_state_none - Test no cached state is a no-op + * @test: The KUnit test context + */ +static void dm_test_destroy_cached_state_none(struct kunit *test) +{ + struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + + dm_destroy_cached_state(adev); + + KUNIT_EXPECT_NULL(test, adev->dm.cached_state); +} + /* Tests for dm_update_mst_vcpi_slots_for_dsc() */ /** @@ -4790,6 +4819,35 @@ static void dm_test_initialize_plane_overlay(struct kunit *test) DRM_PLANE_TYPE_OVERLAY, plane_cap), 0); } +/* Tests for dm_gpureset_toggle_interrupts() */ + +/** + * dm_test_gpureset_toggle_interrupts_dcn - Test DCN only toggles the vupdate IRQ + * @test: The KUnit test context + */ +static void dm_test_gpureset_toggle_interrupts_dcn(struct kunit *test) +{ + struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + struct dc_state *state = dm_kunit_alloc_dc_state(test); + struct amdgpu_crtc *acrtc; + + KUNIT_ASSERT_NOT_NULL(test, state); + acrtc = kunit_kzalloc(test, sizeof(*acrtc), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, acrtc); + + adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 2, 0); + adev->mode_info.num_crtc = 1; + adev->mode_info.crtcs[0] = acrtc; + acrtc->base.dev = &adev->ddev; + acrtc->otg_inst = 0; + state->stream_count = 1; + state->stream_status[0].primary_otg_inst = 0; + state->stream_status[0].plane_count = 1; + + /* GRPH_PFLIP is unused on DCN, so only the vupdate IRQ is touched. */ + dm_gpureset_toggle_interrupts(adev, state, true); +} + static struct kunit_case amdgpu_dm_tests[] = { /* Simple DM callbacks */ KUNIT_CASE(dm_test_wait_for_idle), @@ -4994,6 +5052,9 @@ static struct kunit_case amdgpu_dm_tests[] = { KUNIT_CASE(dm_test_early_init_legacy_asics), KUNIT_CASE(dm_test_early_init_dcn_versions), KUNIT_CASE(dm_test_early_init_unsupported_version), + /* suspend and resume helpers */ + KUNIT_CASE(dm_test_commit_zero_streams_empty), + KUNIT_CASE(dm_test_destroy_cached_state_none), /* dm_update_mst_vcpi_slots_for_dsc */ KUNIT_CASE(dm_test_mst_vcpi_slots_no_connector), KUNIT_CASE(dm_test_mst_vcpi_slots_skips_writeback), @@ -5023,6 +5084,8 @@ static struct kunit_case amdgpu_dm_tests[] = { /* initialize_plane */ KUNIT_CASE(dm_test_initialize_plane_primary), KUNIT_CASE(dm_test_initialize_plane_overlay), + /* dm_gpureset_toggle_interrupts */ + KUNIT_CASE(dm_test_gpureset_toggle_interrupts_dcn), {} }; |
