[WHAT] Add KUnit tests for dm_update_mst_vcpi_slots_for_dsc(), covering an empty commit and the writeback, non-MST and unmatched stream skips.
[HOW] The tests build a commit holding a single connector and vary its type and MST output port so every early-skip branch is reached without an MST topology or a matching DC stream. Assisted-by: Copilot:Claude-Opus-5 GPT-5.6-Sol Reviewed-by: Bhawanpreet Lakha <[email protected]> Signed-off-by: Alex Hung <[email protected]> --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 3 + .../display/amdgpu_dm/tests/amdgpu_dm_test.c | 109 ++++++++++++++++++ 3 files changed, 116 insertions(+), 3 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 a97caf7e1d33..e5c8f8a2ea3e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3296,9 +3296,9 @@ STATIC_IFN_KUNIT void fill_dc_dirty_rects(struct drm_plane *plane, } EXPORT_IF_KUNIT(fill_dc_dirty_rects); -static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_commit *state, - struct dc_state *dc_state, - struct dsc_mst_fairness_vars *vars) +STATIC_IFN_KUNIT int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_commit *state, + struct dc_state *dc_state, + struct dsc_mst_fairness_vars *vars) { struct dc_stream_state *stream = NULL; struct drm_connector *connector; @@ -3372,6 +3372,7 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_commit *state, } return 0; } +EXPORT_IF_KUNIT(dm_update_mst_vcpi_slots_for_dsc); static void manage_dm_interrupts(struct amdgpu_device *adev, struct amdgpu_crtc *acrtc, 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 b1db78e79015..089741ba0619 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -1252,6 +1252,7 @@ struct dc_phy_addr_space_config; struct dc_plane_address; struct dc_plane_cap; struct dc_plane_info; +struct dsc_mst_fairness_vars; void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_addr_space_config *pa_config); @@ -1261,6 +1262,8 @@ int fill_dc_plane_info_and_addr(struct amdgpu_device *adev, const struct drm_plane_state *plane_state, struct dc_plane_info *plane_info, struct dc_plane_address *address, bool tmz_surface); +int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_commit *state, struct dc_state *dc_state, + struct dsc_mst_fairness_vars *vars); int load_dmcu_fw(struct amdgpu_device *adev); int dm_sw_init(struct amdgpu_ip_block *ip_block); int dm_late_init(struct amdgpu_ip_block *ip_block); 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 f8c540a6cdee..a67774e6db36 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 @@ -35,6 +35,7 @@ #include "amdgpu_dm.h" #include "amdgpu_dm_audio.h" #include "amdgpu_dm_hdcp.h" +#include "amdgpu_dm_mst_types.h" #include "amdgpu_dm_kunit_test_helpers.h" /* Tests for simple DM callbacks */ @@ -3964,6 +3965,109 @@ static void dm_test_early_init_unsupported_version(struct kunit *test) KUNIT_EXPECT_FALSE(test, adev->dc_enabled); } +/* Tests for dm_update_mst_vcpi_slots_for_dsc() */ + +/** + * dm_test_mst_vcpi_slots_no_connector - Test an empty commit allocates no slots + * @test: The KUnit test context + */ +static void dm_test_mst_vcpi_slots_no_connector(struct kunit *test) +{ + struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + struct dsc_mst_fairness_vars vars[MAX_PIPES] = {0}; + struct dc_state *dc_state = dm_kunit_alloc_dc_state(test); + + KUNIT_ASSERT_NOT_NULL(test, dc_state); + + KUNIT_EXPECT_EQ(test, + dm_update_mst_vcpi_slots_for_dsc(dm_test_alloc_commit(test, adev), + dc_state, vars), + 0); +} + +/** + * dm_test_mst_vcpi_slots_skips_writeback - Test writeback connectors are skipped + * @test: The KUnit test context + */ +static void dm_test_mst_vcpi_slots_skips_writeback(struct kunit *test) +{ + struct dsc_mst_fairness_vars vars[MAX_PIPES] = {0}; + struct amdgpu_dm_connector *aconnector; + struct dc_state *dc_state; + struct drm_atomic_commit *state; + struct drm_crtc *crtc; + + aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, aconnector); + crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, crtc); + dc_state = dm_kunit_alloc_dc_state(test); + KUNIT_ASSERT_NOT_NULL(test, dc_state); + + aconnector->base.connector_type = DRM_MODE_CONNECTOR_WRITEBACK; + state = dm_test_state_with_connector(test, &aconnector->base, crtc); + + KUNIT_EXPECT_EQ(test, + dm_update_mst_vcpi_slots_for_dsc(state, dc_state, vars), 0); +} + +/** + * dm_test_mst_vcpi_slots_skips_non_mst - Test a connector without an MST port + * @test: The KUnit test context + */ +static void dm_test_mst_vcpi_slots_skips_non_mst(struct kunit *test) +{ + struct dsc_mst_fairness_vars vars[MAX_PIPES] = {0}; + struct amdgpu_dm_connector *aconnector; + struct dc_state *dc_state; + struct drm_atomic_commit *state; + struct drm_crtc *crtc; + + aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, aconnector); + crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, crtc); + dc_state = dm_kunit_alloc_dc_state(test); + KUNIT_ASSERT_NOT_NULL(test, dc_state); + + aconnector->base.connector_type = DRM_MODE_CONNECTOR_DisplayPort; + state = dm_test_state_with_connector(test, &aconnector->base, crtc); + + KUNIT_EXPECT_EQ(test, + dm_update_mst_vcpi_slots_for_dsc(state, dc_state, vars), 0); +} + +/** + * dm_test_mst_vcpi_slots_no_matching_stream - Test a connector with no DC stream + * @test: The KUnit test context + */ +static void dm_test_mst_vcpi_slots_no_matching_stream(struct kunit *test) +{ + struct dsc_mst_fairness_vars vars[MAX_PIPES] = {0}; + struct amdgpu_dm_connector *aconnector; + struct drm_dp_mst_port *port; + struct dc_state *dc_state; + struct drm_atomic_commit *state; + struct drm_crtc *crtc; + + aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, aconnector); + port = kunit_kzalloc(test, sizeof(*port), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, port); + crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, crtc); + dc_state = dm_kunit_alloc_dc_state(test); + KUNIT_ASSERT_NOT_NULL(test, dc_state); + + aconnector->base.connector_type = DRM_MODE_CONNECTOR_DisplayPort; + aconnector->mst_output_port = port; + state = dm_test_state_with_connector(test, &aconnector->base, crtc); + + /* No DC stream references the connector, so the slot update is skipped. */ + KUNIT_EXPECT_EQ(test, + dm_update_mst_vcpi_slots_for_dsc(state, dc_state, vars), 0); +} + /* Tests for fill_dc_plane_attributes() */ struct dm_test_plane_attr_ctx { @@ -4626,6 +4730,11 @@ 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), + /* 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), + KUNIT_CASE(dm_test_mst_vcpi_slots_skips_non_mst), + KUNIT_CASE(dm_test_mst_vcpi_slots_no_matching_stream), /* fill_dc_plane_attributes */ KUNIT_CASE(dm_test_plane_attributes_success), KUNIT_CASE(dm_test_plane_attributes_bad_scaling), -- 2.43.0
