[PATCH 27/41] drm/amd/display: Cover crtc vblank IPS self-refresh restore
<[email protected]> Fri, 31 Jul 2026 17:12:48 -0400
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
From: Bhawanpreet Lakha <[email protected]> Add dm_test_crtc_enable_vblank_ips_restore to cover the IPS/self-refresh branch of amdgpu_dm_crtc_set_vblank() that calls drm_crtc_vblank_restore(). The test primes the DC with ips_support set and IPS not fully disabled, a supported PSR version (self-refresh supported) and an immediate-disable vblank config, so all four conditions gating the restore hold. A stub get_vblank_timestamp hook is installed on the CRTC so the restore helper passes its sanity check, and the enable path then runs to completion. Assisted-by: Copilot:Claude-Opus-4.8 Reviewed-by: Alex Hung <[email protected]> Signed-off-by: Bhawanpreet Lakha <[email protected]> Signed-off-by: Roman Li <[email protected]> --- .../amdgpu_dm/tests/amdgpu_dm_crtc_test.c | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c index 74d72289dff6..b64660064902 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c @@ -858,6 +858,24 @@ static const struct amdgpu_irq_src_funcs dm_test_crtc_irq_src_funcs = { .set = dm_test_crtc_irq_src_set, }; +/* + * Stub get_vblank_timestamp so drm_crtc_vblank_restore() finds a non-NULL hook. + * The CRTC is not registered on the device, so drm_crtc_from_index() returns + * NULL and this callback is never actually invoked; it only satisfies the + * WARN_ON_ONCE(!crtc->funcs->get_vblank_timestamp) sanity check. + */ +static bool dm_test_crtc_get_vblank_timestamp(struct drm_crtc *crtc, + int *max_error, + ktime_t *vblank_time, + bool in_vblank_irq) +{ + return false; +} + +static const struct drm_crtc_funcs dm_test_crtc_funcs = { + .get_vblank_timestamp = dm_test_crtc_get_vblank_timestamp, +}; + /* * dm_test_crtc_arm_irq_src - Prime an IRQ source so get()/put() short-circuit. * @test: The KUnit test context @@ -1107,6 +1125,53 @@ static void dm_test_crtc_enable_vblank_queues_work(struct kunit *test) KUNIT_EXPECT_EQ(test, adev->dm.active_vblank_irq_count, 1); } +/** + * dm_test_crtc_enable_vblank_ips_restore - Test IPS/self-refresh vblank restore + * @test: The KUnit test context + * + * When the DC advertises IPS support with IPS not fully disabled, self-refresh + * is supported and immediate vblank disable is configured, the enable path must + * call drm_crtc_vblank_restore() to estimate missed vblanks before arming the + * IRQs. The enable path then runs to completion. + */ +static void dm_test_crtc_enable_vblank_ips_restore(struct kunit *test) +{ + struct dm_crtc_state *acrtc_state; + struct drm_vblank_crtc *vblank; + struct amdgpu_device *adev; + struct amdgpu_crtc *acrtc; + struct dc_link *link; + + /* DCE_VERSION_8_0 supports VRR -> the vupdate-irq branch is walked. */ + acrtc = dm_test_crtc_setup_enable(test, &adev, DCE_VERSION_8_0); + + /* OTG unassigned -> amdgpu_dm_crtc_set_vupdate_irq() returns 0 early. */ + acrtc->otg_inst = -1; + acrtc_state = to_dm_crtc_state(acrtc->base.state); + acrtc_state->freesync_config.state = VRR_STATE_ACTIVE_VARIABLE; + + /* Non-NULL get_vblank_timestamp keeps drm_crtc_vblank_restore() quiet. */ + acrtc->base.funcs = &dm_test_crtc_funcs; + + /* IPS enabled and not fully disabled -> first restore condition holds. */ + adev->dm.dc->caps.ips_support = true; + adev->dm.dc->config.disable_ips = DMUB_IPS_ENABLE; + + /* Supported PSR version makes self-refresh supported. */ + link = acrtc_state->stream->link; + link->psr_settings.psr_version = DC_PSR_VERSION_1; + + /* Immediate vblank disable is the last condition gating the restore. */ + vblank = drm_crtc_vblank_crtc(&acrtc->base); + vblank->config.disable_immediate = true; + + adev->irq.installed = true; + dm_test_crtc_arm_irq_src(test, &adev->crtc_irq, 1); + dm_test_crtc_arm_irq_src(test, &adev->pageflip_irq, 1); + + KUNIT_EXPECT_EQ(test, amdgpu_dm_crtc_enable_vblank(&acrtc->base), 0); +} + /* Tests for amdgpu_dm_crtc_update_crtc_active_planes() */ /** @@ -1748,6 +1813,7 @@ static struct kunit_case amdgpu_dm_crtc_tests[] = { KUNIT_CASE(dm_test_crtc_enable_vblank_crtc_irq_error), KUNIT_CASE(dm_test_crtc_enable_vblank_in_reset), KUNIT_CASE(dm_test_crtc_enable_vblank_queues_work), + KUNIT_CASE(dm_test_crtc_enable_vblank_ips_restore), /* amdgpu_dm_crtc_update_crtc_active_planes */ KUNIT_CASE(dm_test_crtc_update_active_planes_no_stream), /* amdgpu_dm_crtc_count_crtc_active_planes */ -- 2.34.1