[PATCH 42/59] drm/amd/display: Test IP block teardown and link emulation
Alex Hung <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
[WHAT] Add KUnit tests for amdgpu_dm_early_fini() with audio never enabled, for dm_sw_fini() releasing the DMUB software state, for dm_oem_i2c_hw_init() when the resource pool has no OEM device, for dm_gpureset_commit_state() with an empty DC state, and for amdgpu_dm_emulated_link_detect() rejecting an unknown connector signal. 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 | 15 ++-- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 4 + .../display/amdgpu_dm/tests/amdgpu_dm_test.c | 86 +++++++++++++++++++ 3 files changed, 100 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 13afd787c1b4..2085625f8509 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -830,7 +830,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) return -EINVAL; } -static int amdgpu_dm_early_fini(struct amdgpu_ip_block *ip_block) +STATIC_IFN_KUNIT int amdgpu_dm_early_fini(struct amdgpu_ip_block *ip_block) { struct amdgpu_device *adev = ip_block->adev; @@ -838,6 +838,7 @@ static int amdgpu_dm_early_fini(struct amdgpu_ip_block *ip_block) return 0; } +EXPORT_IF_KUNIT(amdgpu_dm_early_fini); static void amdgpu_dm_fini(struct amdgpu_device *adev) { @@ -1078,7 +1079,7 @@ static int dm_sw_init(struct amdgpu_ip_block *ip_block) return load_dmcu_fw(adev); } -static int dm_sw_fini(struct amdgpu_ip_block *ip_block) +STATIC_IFN_KUNIT int dm_sw_fini(struct amdgpu_ip_block *ip_block) { struct amdgpu_device *adev = ip_block->adev; struct dal_allocation *da; @@ -1108,6 +1109,7 @@ static int dm_sw_fini(struct amdgpu_ip_block *ip_block) return 0; } +EXPORT_IF_KUNIT(dm_sw_fini); static void amdgpu_dm_boot_time_crc_init(struct amdgpu_device *adev) @@ -1302,7 +1304,7 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend) drm_connector_list_iter_end(&iter); } -static int dm_oem_i2c_hw_init(struct amdgpu_device *adev) +STATIC_IFN_KUNIT int dm_oem_i2c_hw_init(struct amdgpu_device *adev) { struct amdgpu_display_manager *dm = &adev->dm; struct amdgpu_i2c_adapter *oem_i2c; @@ -1328,6 +1330,7 @@ static int dm_oem_i2c_hw_init(struct amdgpu_device *adev) return 0; } +EXPORT_IF_KUNIT(dm_oem_i2c_hw_init); /** * dm_hw_init() - Initialize DC device @@ -1710,9 +1713,10 @@ void amdgpu_dm_emulated_link_detect(struct dc_link *link) drm_err(dev, "Failed to read EDID\n"); } +EXPORT_IF_KUNIT(amdgpu_dm_emulated_link_detect); -static void dm_gpureset_commit_state(struct dc_state *dc_state, - struct amdgpu_display_manager *dm) +STATIC_IFN_KUNIT void dm_gpureset_commit_state(struct dc_state *dc_state, + struct amdgpu_display_manager *dm) { struct { struct dc_surface_update surface_updates[MAX_SURFACES]; @@ -1748,6 +1752,7 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, bundle->surface_updates); } } +EXPORT_IF_KUNIT(dm_gpureset_commit_state); void amdgpu_dm_apply_delay_after_dpcd_poweroff(struct amdgpu_device *adev, struct dc_sink *sink) 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 cec86779b959..35b8725a63af 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -1205,6 +1205,10 @@ void amdgpu_dm_dump_links_and_sinks(struct amdgpu_device *adev); void amdgpu_dm_update_hdcp(struct drm_atomic_commit *state); int do_aquire_global_lock(struct drm_device *dev, struct drm_atomic_commit *state); +int amdgpu_dm_early_fini(struct amdgpu_ip_block *ip_block); +int dm_sw_fini(struct amdgpu_ip_block *ip_block); +int dm_oem_i2c_hw_init(struct amdgpu_device *adev); +void dm_gpureset_commit_state(struct dc_state *dc_state, struct amdgpu_display_manager *dm); int dm_plane_layer_index_cmp(const void *a, const void *b); int fill_plane_color_attributes(const struct drm_plane_state *plane_state, const enum surface_pixel_format format, 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 f5c054422346..27182f65e5c3 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 @@ -3094,6 +3094,86 @@ static void dm_test_acpi_phy_transition_interlock(struct kunit *test) dm_acpi_process_phy_transition_interlock(NULL, params); } +/** + * dm_test_early_fini_audio_disabled - Test early fini with audio never enabled + * @test: The KUnit test context + */ +static void dm_test_early_fini_audio_disabled(struct kunit *test) +{ + struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + struct amdgpu_ip_block ip_block = { .adev = adev }; + + KUNIT_EXPECT_EQ(test, amdgpu_dm_early_fini(&ip_block), 0); +} + +/** + * dm_test_sw_fini_releases_state - Test sw fini drops the DMUB software state + * @test: The KUnit test context + */ +static void dm_test_sw_fini_releases_state(struct kunit *test) +{ + struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + struct amdgpu_ip_block ip_block = { .adev = adev }; + + INIT_LIST_HEAD(&adev->dm.da_list); + adev->dm.dmub_fb_info = kzalloc_obj(*adev->dm.dmub_fb_info); + KUNIT_ASSERT_NOT_NULL(test, adev->dm.dmub_fb_info); + + KUNIT_EXPECT_EQ(test, dm_sw_fini(&ip_block), 0); + KUNIT_EXPECT_NULL(test, adev->dm.dmub_fb_info); +} + +/** + * dm_test_oem_i2c_hw_init_no_device - Test no OEM I2C device leaves the bus unset + * @test: The KUnit test context + */ +static void dm_test_oem_i2c_hw_init_no_device(struct kunit *test) +{ + struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + struct dc *dc = dm_kunit_alloc_dc_with_ctx(test); + + dc->res_pool = kunit_kzalloc(test, sizeof(*dc->res_pool), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, dc->res_pool); + adev->dm.dc = dc; + + KUNIT_EXPECT_EQ(test, dm_oem_i2c_hw_init(adev), 0); + KUNIT_EXPECT_NULL(test, adev->dm.oem_i2c); +} + +/** + * dm_test_gpureset_commit_state_no_streams - Test an empty DC state programs nothing + * @test: The KUnit test context + */ +static void dm_test_gpureset_commit_state_no_streams(struct kunit *test) +{ + struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + struct dc_state *context = dm_kunit_alloc_dc_state(test); + + KUNIT_ASSERT_NOT_NULL(test, context); + adev->dm.ddev = &adev->ddev; + + dm_gpureset_commit_state(context, &adev->dm); +} + +/** + * dm_test_emulated_link_detect_bad_signal - Test an unknown connector signal is rejected + * @test: The KUnit test context + */ +static void dm_test_emulated_link_detect_bad_signal(struct kunit *test) +{ + struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + struct dc_link *link = dm_kunit_alloc_link_with_ctx(test); + + link->ctx->driver_context = adev; + link->type = dc_connection_single; + link->connector_signal = SIGNAL_TYPE_VIRTUAL; + + amdgpu_dm_emulated_link_detect(link); + + KUNIT_EXPECT_EQ(test, (int)link->type, (int)dc_connection_none); + KUNIT_EXPECT_NULL(test, link->local_sink); +} + static struct kunit_case amdgpu_dm_tests[] = { /* Simple DM callbacks */ KUNIT_CASE(dm_test_wait_for_idle), @@ -3248,6 +3328,12 @@ static struct kunit_case amdgpu_dm_tests[] = { KUNIT_CASE(dm_test_trigger_timing_sync_streams), /* dm_acpi_process_phy_transition_interlock */ KUNIT_CASE(dm_test_acpi_phy_transition_interlock), + /* IP block lifecycle helpers */ + KUNIT_CASE(dm_test_early_fini_audio_disabled), + KUNIT_CASE(dm_test_sw_fini_releases_state), + KUNIT_CASE(dm_test_oem_i2c_hw_init_no_device), + KUNIT_CASE(dm_test_gpureset_commit_state_no_streams), + KUNIT_CASE(dm_test_emulated_link_detect_bad_signal), {} }; -- 2.43.0