From: Bhawanpreet Lakha <[email protected]> Split audio init to make the initialization modular
Test the audio pin initialization Assisted-by: Copilot:Claude-Opus-4.8 Reviewed-by: Alex Hung <[email protected]> Signed-off-by: Bhawanpreet Lakha <[email protected]> Signed-off-by: George Zhang <[email protected]> --- .../amd/display/amdgpu_dm/amdgpu_dm_audio.c | 36 ++++-- .../amd/display/amdgpu_dm/amdgpu_dm_audio.h | 2 + .../amdgpu_dm/tests/amdgpu_dm_audio_test.c | 118 ++++++++++++++++++ 3 files changed, 145 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_audio.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_audio.c index 1ae121387297..7bba82ce2182 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_audio.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_audio.c @@ -116,28 +116,42 @@ static const struct component_ops amdgpu_dm_audio_component_bind_ops = { .unbind = amdgpu_dm_audio_component_unbind, }; -int amdgpu_dm_audio_init(struct amdgpu_device *adev) +STATIC_IFN_KUNIT +void amdgpu_dm_audio_init_pins(struct amdgpu_device *adev, int audio_count, + const unsigned int *inst_array) { - int i, ret; + int i; - if (!amdgpu_audio) - return 0; + adev->mode_info.audio.num_pins = audio_count; - adev->mode_info.audio.enabled = true; - - adev->mode_info.audio.num_pins = adev->dm.dc->res_pool->audio_count; - - for (i = 0; i < adev->mode_info.audio.num_pins; i++) { + for (i = 0; i < audio_count; i++) { adev->mode_info.audio.pin[i].channels = -1; adev->mode_info.audio.pin[i].rate = -1; adev->mode_info.audio.pin[i].bits_per_sample = -1; adev->mode_info.audio.pin[i].status_bits = 0; adev->mode_info.audio.pin[i].category_code = 0; adev->mode_info.audio.pin[i].connected = false; - adev->mode_info.audio.pin[i].id = - adev->dm.dc->res_pool->audios[i]->inst; + adev->mode_info.audio.pin[i].id = inst_array[i]; adev->mode_info.audio.pin[i].offset = 0; } +} +EXPORT_IF_KUNIT(amdgpu_dm_audio_init_pins); + +int amdgpu_dm_audio_init(struct amdgpu_device *adev) +{ + unsigned int inst_array[MAX_AUDIOS]; + int audio_count; + int i, ret; + + if (!amdgpu_audio) + return 0; + + adev->mode_info.audio.enabled = true; + + audio_count = adev->dm.dc->res_pool->audio_count; + for (i = 0; i < audio_count; i++) + inst_array[i] = adev->dm.dc->res_pool->audios[i]->inst; + amdgpu_dm_audio_init_pins(adev, audio_count, inst_array); ret = component_add(adev->dev, &amdgpu_dm_audio_component_bind_ops); if (ret < 0) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_audio.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_audio.h index 48391305c3c2..761808b42f3d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_audio.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_audio.h @@ -51,6 +51,8 @@ void amdgpu_dm_audio_component_unbind(struct device *kdev, void amdgpu_dm_audio_eld_notify(struct amdgpu_device *adev, int pin); int amdgpu_dm_audio_get_param(void); void amdgpu_dm_audio_set_param(int val); +void amdgpu_dm_audio_init_pins(struct amdgpu_device *adev, int audio_count, + const unsigned int *inst_array); #endif #endif /* __AMDGPU_DM_AUDIO_H__ */ 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 79ff5d9b3fa5..3f0108e9a951 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 @@ -6,10 +6,13 @@ */ #include <kunit/test.h> +#include <linux/device.h> #include <drm/drm_audio_component.h> #include "dc.h" +#include "dc/inc/core_types.h" +#include "dc/inc/hw/audio.h" #include "amdgpu.h" #include "amdgpu_mode.h" #include "amdgpu_dm.h" @@ -38,6 +41,57 @@ static void dm_test_audio_init_disabled(struct kunit *test) amdgpu_dm_audio_set_param(saved_audio); } +/** + * dm_test_audio_init_enabled_success - Test init deeper path when audio is enabled + * @test: The KUnit test context + */ +static void dm_test_audio_init_enabled_success(struct kunit *test) +{ + struct amdgpu_device *adev; + struct dc *dc; + struct resource_pool *res_pool; + struct audio *audio0; + struct audio *audio1; + struct device *dev; + int saved_audio = amdgpu_dm_audio_get_param(); + + adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL); + dc = kunit_kzalloc(test, sizeof(*dc), GFP_KERNEL); + res_pool = kunit_kzalloc(test, sizeof(*res_pool), GFP_KERNEL); + audio0 = kunit_kzalloc(test, sizeof(*audio0), GFP_KERNEL); + audio1 = kunit_kzalloc(test, sizeof(*audio1), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, res_pool); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, audio0); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, audio1); + + dev = root_device_register("kunit-dm-audio-init"); + KUNIT_ASSERT_FALSE(test, IS_ERR(dev)); + + audio0->inst = 2; + audio1->inst = 6; + res_pool->audio_count = 2; + res_pool->audios[0] = audio0; + res_pool->audios[1] = audio1; + dc->res_pool = res_pool; + adev->dm.dc = dc; + adev->dev = dev; + + amdgpu_dm_audio_set_param(1); + + KUNIT_EXPECT_EQ(test, amdgpu_dm_audio_init(adev), 0); + KUNIT_EXPECT_TRUE(test, adev->mode_info.audio.enabled); + KUNIT_EXPECT_TRUE(test, adev->dm.audio_registered); + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.num_pins, 2); + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.pin[0].id, 2U); + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.pin[1].id, 6U); + + amdgpu_dm_audio_fini(adev); + root_device_unregister(dev); + amdgpu_dm_audio_set_param(saved_audio); +} + /* Tests for amdgpu_dm_audio_fini() */ /** @@ -455,9 +509,73 @@ static void dm_test_eld_notify_null_callback(struct kunit *test) KUNIT_EXPECT_EQ(test, dm_test_eld_notify_count, 0); } +/* Tests for amdgpu_dm_audio_init_pins() */ + +/** + * dm_test_audio_init_pins_sets_defaults - pin entries are initialised to default values + * @test: The KUnit test context + * + * amdgpu_dm_audio_init_pins() must set num_pins from audio_count, reset every + * pin to the sentinel defaults (-1 for rate/channels/bits, 0 for the rest) + * and copy each pin's hardware instance index from res_pool->audios[i]->inst. + */ +static void dm_test_audio_init_pins_sets_defaults(struct kunit *test) +{ + struct amdgpu_device *adev; + const unsigned int inst_array[] = {3, 7}; + int i; + + adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev); + + amdgpu_dm_audio_init_pins(adev, 2, inst_array); + + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.num_pins, 2); + + for (i = 0; i < 2; i++) { + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.pin[i].channels, -1); + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.pin[i].rate, -1); + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.pin[i].bits_per_sample, -1); + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.pin[i].status_bits, 0); + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.pin[i].category_code, 0); + KUNIT_EXPECT_FALSE(test, adev->mode_info.audio.pin[i].connected); + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.pin[i].offset, 0); + } + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.pin[0].id, 3U); + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.pin[1].id, 7U); +} + +/** + * dm_test_audio_init_pins_zero_count - zero audio_count leaves num_pins at zero + * @test: The KUnit test context + * + * When res_pool->audio_count is 0, num_pins must be 0 and no pins touched. + */ +static void dm_test_audio_init_pins_zero_count(struct kunit *test) +{ + struct amdgpu_device *adev; + + adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev); + + /* Pre-fill a sentinel so we can confirm the loop never ran. */ + adev->mode_info.audio.pin[0].channels = 99; + + amdgpu_dm_audio_init_pins(adev, 0, NULL); + + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.num_pins, 0); + KUNIT_EXPECT_EQ(test, adev->mode_info.audio.pin[0].channels, 99); +} + +/* End of tests for amdgpu_dm_audio_init_pins() */ + static struct kunit_case dm_audio_test_cases[] = { /* amdgpu_dm_audio_init */ KUNIT_CASE(dm_test_audio_init_disabled), + KUNIT_CASE(dm_test_audio_init_enabled_success), + /* amdgpu_dm_audio_init_pins */ + KUNIT_CASE(dm_test_audio_init_pins_sets_defaults), + KUNIT_CASE(dm_test_audio_init_pins_zero_count), /* amdgpu_dm_audio_fini */ KUNIT_CASE(dm_test_audio_fini_without_enabled_audio), /* amdgpu_dm_fill_audio_info */ -- 2.55.0
