[PATCH 29/59] drm/amd/display: Test vblank counter and scanout position
Alex Hung <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
[WHAT] Add KUnit tests for dm_vblank_get_counter() and dm_crtc_get_scanoutpos() covering a CRTC whose stream is not owned by any pipe in the resource context, and the branch that disables idle optimizations before reading the scanout position. [HOW] Wire a DC context, a current DC state and a logger to the device so both callbacks walk the resource context instead of returning early. Assisted-by: Copilot:Claude-Opus-5 GPT-5.6-Sol Reviewed-by: Bhawanpreet Lakha <[email protected]> Signed-off-by: Alex Hung <[email protected]> --- .../display/amdgpu_dm/tests/amdgpu_dm_test.c | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) 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 a0f90b0bd74a..33cca3f01b5b 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 @@ -8,13 +8,23 @@ #include <kunit/test.h> #include <linux/pci.h> #include <drm/drm_atomic.h> +#include <drm/drm_blend.h> #include <drm/drm_connector.h> #include <drm/drm_crtc.h> +#include <drm/drm_framebuffer.h> +#include <drm/drm_kunit_helpers.h> #include <drm/drm_modes.h> +#include <drm/drm_modeset_lock.h> +#include <drm/drm_plane.h> +#include <drm/drm_property.h> +#include <drm/drm_vblank.h> #include <drm/drm_writeback.h> #include "dc.h" +#include "dm_services_types.h" +#include "dmub/dmub_srv.h" #include "inc/core_types.h" +#include "logger_types.h" #include "amd_shared.h" #include "amdgpu.h" #include "amdgpu_mode.h" @@ -1141,6 +1151,87 @@ static void dm_test_apply_delay_nonzero_wait(struct kunit *test) amdgpu_dm_apply_delay_after_dpcd_poweroff(adev, sink); } +/* + * Attach a DC stream to CRTC 0 of @adev so the scanout helpers walk the DC + * resource context instead of bailing out early. + */ +static void dm_test_crtc_with_stream(struct kunit *test, + struct amdgpu_device *adev, struct dc *dc) +{ + struct dc_stream_state *stream; + struct amdgpu_crtc *acrtc; + struct dal_logger *logger; + + acrtc = kunit_kzalloc(test, sizeof(*acrtc), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, acrtc); + + logger = kunit_kzalloc(test, sizeof(*logger), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, logger); + logger->dev = &adev->ddev; + dc->ctx->logger = logger; + + dc->current_state = dm_kunit_alloc_dc_state(test); + KUNIT_ASSERT_NOT_NULL(test, dc->current_state); + + stream = dm_kunit_alloc_stream(test, NULL); + stream->ctx = dc->ctx; + + adev->dm.dc = dc; + adev->mode_info.num_crtc = 1; + adev->mode_info.crtcs[0] = acrtc; + acrtc->dm_irq_params.stream = stream; +} + +/** + * dm_test_vblank_get_counter_unmapped_stream - Test a stream without a pipe returns zero + * @test: The KUnit test context + */ +static void dm_test_vblank_get_counter_unmapped_stream(struct kunit *test) +{ + struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + struct dc *dc = dm_kunit_alloc_dc_with_ctx(test); + + dm_test_crtc_with_stream(test, adev, dc); + + KUNIT_EXPECT_EQ(test, dm_vblank_get_counter(adev, 0), 0U); +} + +/** + * dm_test_crtc_get_scanoutpos_unmapped_stream - Test scanout position for an unmapped stream + * @test: The KUnit test context + */ +static void dm_test_crtc_get_scanoutpos_unmapped_stream(struct kunit *test) +{ + struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + struct dc *dc = dm_kunit_alloc_dc_with_ctx(test); + u32 vbl = 0xdeadbeef; + u32 position = 0xdeadbeef; + + dm_test_crtc_with_stream(test, adev, dc); + + KUNIT_EXPECT_EQ(test, dm_crtc_get_scanoutpos(adev, 0, &vbl, &position), 0); + KUNIT_EXPECT_EQ(test, vbl, 0U); + KUNIT_EXPECT_EQ(test, position, 0U); +} + +/** + * dm_test_crtc_get_scanoutpos_exits_idle - Test idle optimizations are disabled first + * @test: The KUnit test context + */ +static void dm_test_crtc_get_scanoutpos_exits_idle(struct kunit *test) +{ + struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + struct dc *dc = dm_kunit_alloc_dc_with_ctx(test); + u32 vbl = 0; + u32 position = 0; + + dm_test_crtc_with_stream(test, adev, dc); + dc->caps.ips_support = true; + dc->idle_optimizations_allowed = true; + + KUNIT_EXPECT_EQ(test, dm_crtc_get_scanoutpos(adev, 0, &vbl, &position), 0); +} + static struct kunit_case amdgpu_dm_tests[] = { /* Simple DM callbacks */ KUNIT_CASE(dm_test_wait_for_idle), @@ -1207,6 +1298,10 @@ static struct kunit_case amdgpu_dm_tests[] = { KUNIT_CASE(dm_test_apply_delay_null_sink), KUNIT_CASE(dm_test_apply_delay_zero_wait), KUNIT_CASE(dm_test_apply_delay_nonzero_wait), + /* dm_vblank_get_counter / dm_crtc_get_scanoutpos with a stream */ + KUNIT_CASE(dm_test_vblank_get_counter_unmapped_stream), + KUNIT_CASE(dm_test_crtc_get_scanoutpos_unmapped_stream), + KUNIT_CASE(dm_test_crtc_get_scanoutpos_exits_idle), {} }; -- 2.43.0