summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Hung <alex.hung@amd.com>2026-08-13 21:00:45 -0600
committerAlex Deucher <alexander.deucher@amd.com>2026-09-10 11:59:56 -0400
commit9f46b2f90f350149b3edfd4af624e507aec84ba7 (patch)
tree29941972d1947c37d3e42d2424254a0fc20f04b2
parent519ba75dcd1a4061909d2bf74230b84136dae2cc (diff)
downloadlinux-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.c13
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h3
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c63
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, &params);
}
+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),
{}
};