[PATCH 18/49] drm/amd/display: add KUnit tests for audio component get_eld

Fangzhi Zuo <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.