From: Alex Hung <[email protected]> [WHAT] Add KUnit tests for dm_enable_per_frame_crtc_master_sync covering the single-stream no-op, the two-stream master selection with trigger parameters, and the NULL-stream skip path.
Assisted-by: Copilot:Claude-Opus-4.8 Reviewed-by: Bhawanpreet Lakha <[email protected]> Signed-off-by: Alex Hung <[email protected]> Signed-off-by: Wayne Lin <[email protected]> --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 1 + .../display/amdgpu_dm/tests/amdgpu_dm_test.c | 103 ++++++++++++++++++ 3 files changed, 107 insertions(+), 2 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 fa0add5bcabf..8fe7e125e14a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -141,7 +141,7 @@ static void amdgpu_dm_destroy_drm_device(struct amdgpu_display_manager *dm); static int amdgpu_dm_atomic_setup_commit(struct drm_atomic_state *state); static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state); -static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context); +STATIC_IFN_KUNIT void dm_enable_per_frame_crtc_master_sync(struct dc_state *context); static int amdgpu_dm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state); @@ -5342,7 +5342,7 @@ STATIC_IFN_KUNIT void set_master_stream(struct dc_stream_state *stream_set[], } EXPORT_IF_KUNIT(set_master_stream); -static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context) +STATIC_IFN_KUNIT void dm_enable_per_frame_crtc_master_sync(struct dc_state *context) { int i = 0; struct dc_stream_state *stream; @@ -5370,6 +5370,7 @@ static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context) set_multisync_trigger_params(stream); } } +EXPORT_IF_KUNIT(dm_enable_per_frame_crtc_master_sync); /** * amdgpu_dm_atomic_commit_tail() - AMDgpu DM's commit tail implementation. 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 29cefa4d8468..897434504459 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -1181,6 +1181,7 @@ void set_master_stream(struct dc_stream_state *stream_set[], int stream_count); void reset_freesync_config_for_crtc(struct dm_crtc_state *new_crtc_state); void get_freesync_config_for_crtc(struct dm_crtc_state *new_crtc_state, struct dm_connector_state *new_con_state); +void dm_enable_per_frame_crtc_master_sync(struct dc_state *context); struct hdcp_workqueue; bool is_content_protection_different(struct drm_crtc_state *new_crtc_state, struct drm_crtc_state *old_crtc_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 1464eeda704b..b988198418c6 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 @@ -1838,6 +1838,105 @@ static void dm_test_reset_freesync_config(struct kunit *test) KUNIT_EXPECT_FALSE(test, crtc_state->vrr_infopacket.valid); } +/* Tests for dm_enable_per_frame_crtc_master_sync() */ + +/** + * dm_test_per_frame_master_sync_single_stream - Test fewer than two streams is a no-op + * @test: The KUnit test context + */ +static void dm_test_per_frame_master_sync_single_stream(struct kunit *test) +{ + struct dc_state *context; + struct dc_stream_state *stream; + + context = kunit_kzalloc(test, sizeof(*context), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, context); + stream = kunit_kzalloc(test, sizeof(*stream), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, stream); + + stream->triggered_crtc_reset.enabled = true; + context->streams[0] = stream; + context->stream_count = 1; + + dm_enable_per_frame_crtc_master_sync(context); + + /* < 2 streams: early return, event_source stays NULL */ + KUNIT_EXPECT_NULL(test, stream->triggered_crtc_reset.event_source); +} + +/** + * dm_test_per_frame_master_sync_two_streams - Test the master is picked and applied + * @test: The KUnit test context + */ +static void dm_test_per_frame_master_sync_two_streams(struct kunit *test) +{ + struct dc_state *context; + struct dc_stream_state *stream0, *stream1; + + context = kunit_kzalloc(test, sizeof(*context), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, context); + stream0 = kunit_kzalloc(test, sizeof(*stream0), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, stream0); + stream1 = kunit_kzalloc(test, sizeof(*stream1), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, stream1); + + /* stream0 60Hz, stream1 120Hz, both trigger-reset enabled */ + stream0->triggered_crtc_reset.enabled = true; + stream0->timing.pix_clk_100hz = 1485000; + stream0->timing.h_total = 2200; + stream0->timing.v_total = 1125; + stream1->triggered_crtc_reset.enabled = true; + stream1->timing.pix_clk_100hz = 2970000; + stream1->timing.h_total = 2200; + stream1->timing.v_total = 1125; + stream1->timing.flags.VSYNC_POSITIVE_POLARITY = 1; + + context->streams[0] = stream0; + context->streams[1] = stream1; + context->stream_count = 2; + + dm_enable_per_frame_crtc_master_sync(context); + + /* set_master_stream picks the highest refresh (stream1) as event source */ + KUNIT_EXPECT_PTR_EQ(test, stream0->triggered_crtc_reset.event_source, + stream1); + KUNIT_EXPECT_PTR_EQ(test, stream1->triggered_crtc_reset.event_source, + stream1); + /* set_multisync_trigger_params applied to enabled streams */ + KUNIT_EXPECT_EQ(test, (int)stream0->triggered_crtc_reset.event, + (int)CRTC_EVENT_VSYNC_RISING); + KUNIT_EXPECT_EQ(test, (int)stream0->triggered_crtc_reset.delay, + (int)TRIGGER_DELAY_NEXT_PIXEL); +} + +/** + * dm_test_per_frame_master_sync_skips_null_stream - Test NULL stream entries are skipped + * @test: The KUnit test context + */ +static void dm_test_per_frame_master_sync_skips_null_stream(struct kunit *test) +{ + struct dc_state *context; + struct dc_stream_state *stream; + + context = kunit_kzalloc(test, sizeof(*context), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, context); + stream = kunit_kzalloc(test, sizeof(*stream), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, stream); + + stream->triggered_crtc_reset.enabled = true; + stream->timing.pix_clk_100hz = 1485000; + stream->timing.h_total = 2200; + stream->timing.v_total = 1125; + context->streams[0] = stream; + context->streams[1] = NULL; + context->stream_count = 2; + + dm_enable_per_frame_crtc_master_sync(context); + + KUNIT_EXPECT_PTR_EQ(test, stream->triggered_crtc_reset.event_source, + stream); +} + static struct kunit_case amdgpu_dm_tests[] = { /* Simple DM callbacks */ KUNIT_CASE(dm_test_is_idle), @@ -1939,6 +2038,10 @@ static struct kunit_case amdgpu_dm_tests[] = { KUNIT_CASE(dm_test_freesync_config_active_fixed), /* reset_freesync_config_for_crtc */ KUNIT_CASE(dm_test_reset_freesync_config), + /* dm_enable_per_frame_crtc_master_sync */ + KUNIT_CASE(dm_test_per_frame_master_sync_single_stream), + KUNIT_CASE(dm_test_per_frame_master_sync_two_streams), + KUNIT_CASE(dm_test_per_frame_master_sync_skips_null_stream), {} }; -- 2.43.0
