From: Alex Hung <[email protected]> [WHAT] Add KUnit coverage for amdgpu_dm_audio_component_get_eld(), one of the functions reported as untested by gcov.
The tests use the standard DRM KUnit device plus drm_connector_init() to build a real connector list, then invoke the bound audio component get_eld callback. They cover the matching-connector ELD copy path, the writeback-connector skip, and the no-match (disabled) path. A shared connector funcs table and cleanup action back the fixtures. Reviewed-by: Bhawanpreet Lakha <[email protected]> Signed-off-by: Alex Hung <[email protected]> Signed-off-by: Fangzhi Zuo <[email protected]> Tested-by: Dan Wheeler <[email protected]> --- .../amdgpu_dm/tests/amdgpu_dm_audio_test.c | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_audio_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_audio_test.c index 3f0108e9a951..d30b7f644f97 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_audio_test.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_audio_test.c @@ -8,7 +8,12 @@ #include <kunit/test.h> #include <linux/device.h> +#include <drm/drm_atomic_helper.h> #include <drm/drm_audio_component.h> +#include <drm/drm_connector.h> +#include <drm/drm_eld.h> +#include <drm/drm_kunit_helpers.h> +#include <drm/drm_probe_helper.h> #include "dc.h" #include "dc/inc/core_types.h" @@ -17,6 +22,20 @@ #include "amdgpu_mode.h" #include "amdgpu_dm.h" #include "amdgpu_dm_audio.h" +#include "amdgpu_dm_kunit_test_helpers.h" + +static const struct drm_connector_funcs dm_test_audio_connector_funcs = { + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, +}; + +static void dm_test_audio_connector_cleanup(void *data) +{ + drm_connector_cleanup(data); +} /* Tests for amdgpu_dm_audio_init() */ @@ -569,6 +588,103 @@ static void dm_test_audio_init_pins_zero_count(struct kunit *test) /* End of tests for amdgpu_dm_audio_init_pins() */ +/* Tests for amdgpu_dm_audio_component_get_eld() */ + +/** + * dm_test_audio_component_get_eld_copies_matching_connector - Test ELD lookup + * @test: The KUnit test context + * + * The bound component callback should find the connector whose audio instance + * matches the requested port, report it enabled, and copy the connector ELD. + */ +static void dm_test_audio_component_get_eld_copies_matching_connector(struct kunit *test) +{ + struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + struct amdgpu_dm_connector *aconnector; + struct drm_connector *wb_connector; + struct drm_audio_component *acomp; + struct device *kdev; + unsigned char buf[DRM_ELD_HEADER_BLOCK_SIZE + 8] = {0}; + bool enabled = false; + int ret; + + kdev = adev->ddev.dev; + KUNIT_ASSERT_NOT_NULL(test, kdev); + acomp = kunit_kzalloc(test, sizeof(*acomp), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, acomp); + wb_connector = kunit_kzalloc(test, sizeof(*wb_connector), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, wb_connector); + KUNIT_ASSERT_EQ(test, drm_connector_init(&adev->ddev, wb_connector, + &dm_test_audio_connector_funcs, + DRM_MODE_CONNECTOR_WRITEBACK), 0); + KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, + dm_test_audio_connector_cleanup, wb_connector), 0); + + aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, aconnector); + KUNIT_ASSERT_EQ(test, drm_connector_init(&adev->ddev, &aconnector->base, + &dm_test_audio_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA), 0); + KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, + dm_test_audio_connector_cleanup, &aconnector->base), 0); + + mutex_init(&adev->dm.audio_lock); + aconnector->audio_inst = 3; + aconnector->base.eld[DRM_ELD_BASELINE_ELD_LEN] = 2; + aconnector->base.eld[DRM_ELD_VER] = DRM_ELD_VER_CEA861D; + aconnector->base.eld[DRM_ELD_SPEAKER] = DRM_ELD_SPEAKER_FLR; + dev_set_drvdata(kdev, &adev->ddev); + + KUNIT_ASSERT_EQ(test, amdgpu_dm_audio_component_bind(kdev, NULL, acomp), 0); + ret = acomp->ops->get_eld(kdev, 3, 0, &enabled, buf, sizeof(buf)); + + KUNIT_EXPECT_EQ(test, ret, DRM_ELD_HEADER_BLOCK_SIZE + 8); + KUNIT_EXPECT_TRUE(test, enabled); + KUNIT_EXPECT_EQ(test, memcmp(buf, aconnector->base.eld, ret), 0); +} + +/** + * dm_test_audio_component_get_eld_no_match - Test ELD lookup miss + * @test: The KUnit test context + * + * A non-matching connector should leave the audio port disabled and return an + * empty ELD size without copying data. + */ +static void dm_test_audio_component_get_eld_no_match(struct kunit *test) +{ + struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + struct amdgpu_dm_connector *aconnector; + struct drm_audio_component *acomp; + struct device *kdev; + unsigned char buf[DRM_ELD_HEADER_BLOCK_SIZE] = {0x5a}; + bool enabled = true; + int ret; + + kdev = adev->ddev.dev; + KUNIT_ASSERT_NOT_NULL(test, kdev); + acomp = kunit_kzalloc(test, sizeof(*acomp), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, acomp); + + aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, aconnector); + KUNIT_ASSERT_EQ(test, drm_connector_init(&adev->ddev, &aconnector->base, + &dm_test_audio_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA), 0); + KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, + dm_test_audio_connector_cleanup, &aconnector->base), 0); + + mutex_init(&adev->dm.audio_lock); + aconnector->audio_inst = 4; + dev_set_drvdata(kdev, &adev->ddev); + + KUNIT_ASSERT_EQ(test, amdgpu_dm_audio_component_bind(kdev, NULL, acomp), 0); + ret = acomp->ops->get_eld(kdev, 3, 0, &enabled, buf, sizeof(buf)); + + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_FALSE(test, enabled); + KUNIT_EXPECT_EQ(test, buf[0], 0x5a); +} + static struct kunit_case dm_audio_test_cases[] = { /* amdgpu_dm_audio_init */ KUNIT_CASE(dm_test_audio_init_disabled), @@ -593,6 +709,9 @@ static struct kunit_case dm_audio_test_cases[] = { KUNIT_CASE(dm_test_eld_notify_no_component), KUNIT_CASE(dm_test_eld_notify_null_audio_ops), KUNIT_CASE(dm_test_eld_notify_null_callback), + /* amdgpu_dm_audio_component_get_eld */ + KUNIT_CASE(dm_test_audio_component_get_eld_copies_matching_connector), + KUNIT_CASE(dm_test_audio_component_get_eld_no_match), {} }; -- 2.53.0
