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

Reply via email to