[PATCH 49/59] drm/amd/display: Test SW init and fini

Alex Hung <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
[WHAT]
Add KUnit tests for dm_sw_init() on an ASIC without a DMUB, and for the
DMUB bounding box release in dm_sw_fini().

[HOW]
An ASIC without DMUB support makes dm_dmub_sw_init() return early. The
bounding box allocation is left without a buffer object, which
amdgpu_bo_free_kernel() short-circuits.

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 |  3 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
 .../display/amdgpu_dm/tests/amdgpu_dm_test.c  | 51 +++++++++++++++++++
 3 files changed, 54 insertions(+), 1 deletion(-)

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 128b12a945fc..8b4d01d97ea4 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1079,7 +1079,7 @@ STATIC_IFN_KUNIT int load_dmcu_fw(struct amdgpu_device *adev)
 }
 EXPORT_IF_KUNIT(load_dmcu_fw);
 
-static int dm_sw_init(struct amdgpu_ip_block *ip_block)
+STATIC_IFN_KUNIT int dm_sw_init(struct amdgpu_ip_block *ip_block)
 {
 	struct amdgpu_device *adev = ip_block->adev;
 	int r;
@@ -1100,6 +1100,7 @@ static int dm_sw_init(struct amdgpu_ip_block *ip_block)
 
 	return load_dmcu_fw(adev);
 }
+EXPORT_IF_KUNIT(dm_sw_init);
 
 STATIC_IFN_KUNIT int dm_sw_fini(struct amdgpu_ip_block *ip_block)
 {
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 858fe967046b..80da5a378d73 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -1254,6 +1254,7 @@ void mmhub_read_system_context(struct amdgpu_device *adev,
 			       struct dc_phy_addr_space_config *pa_config);
 int amdgpu_dm_init_power_module(struct amdgpu_display_manager *dm);
 int load_dmcu_fw(struct amdgpu_device *adev);
+int dm_sw_init(struct amdgpu_ip_block *ip_block);
 #endif
 
 #endif /* __AMDGPU_DM_H__ */
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 f0cd2de97faf..8ad6cf0eaa6c 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
@@ -3654,6 +3654,54 @@ static void dm_test_load_dmcu_fw_missing_firmware(struct kunit *test)
 	KUNIT_EXPECT_NULL(test, adev->dm.fw_dmcu);
 }
 
+/* Tests for dm_sw_init() and dm_sw_fini() */
+
+/**
+ * dm_test_sw_init_no_dmub - Test software init on an ASIC without a DMUB
+ * @test: The KUnit test context
+ */
+static void dm_test_sw_init_no_dmub(struct kunit *test)
+{
+	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+	struct amdgpu_ip_block ip_block = { .adev = adev };
+
+	adev->asic_type = CHIP_BONAIRE;
+
+	KUNIT_EXPECT_EQ(test, dm_sw_init(&ip_block), 0);
+	KUNIT_ASSERT_NOT_NULL(test, adev->dm.cgs_device);
+	KUNIT_EXPECT_TRUE(test, list_empty(&adev->dm.da_list));
+
+	/* amdgpu_cgs_destroy_device() is not exported and is a plain kfree(). */
+	kfree(adev->dm.cgs_device);
+}
+
+/**
+ * dm_test_sw_fini_releases_bounding_box - Test the DMUB bounding box is released
+ * @test: The KUnit test context
+ */
+static void dm_test_sw_fini_releases_bounding_box(struct kunit *test)
+{
+	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+	struct amdgpu_ip_block ip_block = { .adev = adev };
+	struct dal_allocation *da;
+	void *bb;
+
+	bb = kunit_kzalloc(test, sizeof(*da), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, bb);
+	/* Freed by dm_sw_fini(), so it must not be KUnit-managed. */
+	da = kzalloc_obj(*da);
+	KUNIT_ASSERT_NOT_NULL(test, da);
+
+	INIT_LIST_HEAD(&adev->dm.da_list);
+	da->cpu_ptr = bb;
+	list_add(&da->list, &adev->dm.da_list);
+	adev->dm.bb_from_dmub = bb;
+
+	KUNIT_EXPECT_EQ(test, dm_sw_fini(&ip_block), 0);
+	KUNIT_EXPECT_NULL(test, adev->dm.bb_from_dmub);
+	KUNIT_EXPECT_TRUE(test, list_empty(&adev->dm.da_list));
+}
+
 static struct kunit_case amdgpu_dm_tests[] = {
 	/* Simple DM callbacks */
 	KUNIT_CASE(dm_test_wait_for_idle),
@@ -3840,6 +3888,9 @@ static struct kunit_case amdgpu_dm_tests[] = {
 	KUNIT_CASE(dm_test_load_dmcu_fw_unsupported),
 	KUNIT_CASE(dm_test_load_dmcu_fw_raven),
 	KUNIT_CASE(dm_test_load_dmcu_fw_missing_firmware),
+	/* dm_sw_init / dm_sw_fini */
+	KUNIT_CASE(dm_test_sw_init_no_dmub),
+	KUNIT_CASE(dm_test_sw_fini_releases_bounding_box),
 	{}
 };
 
-- 
2.43.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.