[PATCH 45/59] drm/amd/display: Test MMHUB config read

Alex Hung <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
[WHAT]
Add KUnit tests for the system aperture and GART configuration built by
mmhub_read_system_context(), covering the enabled and disabled AGP
aperture branches, the Raven2 and Renoir aperture workarounds, and the
GPUVM support flag.

[HOW]
Add struct amdgpu_dm_kunit_ops, a KUnit-only indirection table for
amdgpu_gmc_pd_addr(), which walks a live TTM buffer object back to its
device. Tests install a stub returning a fixed page directory address,
which makes the arithmetic reachable in the UML test environment. The
default table points at the existing AMDGPU function, so no test-only
wrapper is introduced.

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 |  24 +++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  11 ++
 .../display/amdgpu_dm/tests/amdgpu_dm_test.c  | 128 ++++++++++++++++++
 3 files changed, 161 insertions(+), 2 deletions(-)

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 71fe85498766..ffc5cea6b6df 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -309,8 +309,27 @@ EXPORT_IF_KUNIT(dm_set_powergating_state);
 /* Prototypes of private functions */
 static int dm_early_init(struct amdgpu_ip_block *ip_block);
 
+#if IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
+static const struct amdgpu_dm_kunit_ops amdgpu_dm_default_ops = {
+	.gmc_pd_addr = amdgpu_gmc_pd_addr,
+};
+
+static const struct amdgpu_dm_kunit_ops *amdgpu_dm_ops = &amdgpu_dm_default_ops;
+
+void amdgpu_dm_kunit_set_ops(const struct amdgpu_dm_kunit_ops *ops)
+{
+	amdgpu_dm_ops = ops ? ops : &amdgpu_dm_default_ops;
+}
+EXPORT_IF_KUNIT(amdgpu_dm_kunit_set_ops);
+
+#define dm_gmc_pd_addr		amdgpu_dm_ops->gmc_pd_addr
+#else
+#define dm_gmc_pd_addr		amdgpu_gmc_pd_addr
+#endif
+
 /* Allocate memory for FBC compressed data  */
-static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_addr_space_config *pa_config)
+STATIC_IFN_KUNIT void mmhub_read_system_context(struct amdgpu_device *adev,
+						struct dc_phy_addr_space_config *pa_config)
 {
 	u64 pt_base;
 	u32 logical_addr_low;
@@ -355,7 +374,7 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_
 			logical_addr_high = max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18;
 	}
 
-	pt_base = amdgpu_gmc_pd_addr(adev->gart.bo);
+	pt_base = dm_gmc_pd_addr(adev->gart.bo);
 
 	page_table_start.high_part = upper_32_bits(adev->gmc.gart_start >>
 						   AMDGPU_GPU_PAGE_SHIFT);
@@ -386,6 +405,7 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_
 	pa_config->is_hvm_enabled = adev->mode_info.gpu_vm_support;
 
 }
+EXPORT_IF_KUNIT(mmhub_read_system_context);
 
 static int amdgpu_dm_init_power_module(struct amdgpu_display_manager *dm)
 {
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 5ffaca8a6efe..a53246040948 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -1241,6 +1241,17 @@ struct amdgpu_dm_services_kunit_ops {
 };
 
 void amdgpu_dm_services_kunit_set_ops(const struct amdgpu_dm_services_kunit_ops *ops);
+
+struct amdgpu_dm_kunit_ops {
+	uint64_t (*gmc_pd_addr)(struct amdgpu_bo *bo);
+};
+
+void amdgpu_dm_kunit_set_ops(const struct amdgpu_dm_kunit_ops *ops);
+
+struct dc_phy_addr_space_config;
+
+void mmhub_read_system_context(struct amdgpu_device *adev,
+			       struct dc_phy_addr_space_config *pa_config);
 #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 a8140747c25d..bb52da037e69 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
@@ -3399,6 +3399,129 @@ static void dm_test_atomic_setup_commit_bad_lut(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, amdgpu_dm_atomic_setup_commit(ctx->state), -EINVAL);
 }
 
+/* Tests for mmhub_read_system_context() */
+
+#define DM_TEST_PD_ADDR		0x1234000ULL
+
+/*
+ * Stub for the page directory address read: amdgpu_gmc_pd_addr() walks a live
+ * TTM buffer object back to its device, so return a fixed address instead.
+ */
+static uint64_t dm_test_gmc_pd_addr(struct amdgpu_bo *bo)
+{
+	return DM_TEST_PD_ADDR;
+}
+
+static const struct amdgpu_dm_kunit_ops dm_test_dm_ops = {
+	.gmc_pd_addr = dm_test_gmc_pd_addr,
+};
+
+static void dm_test_restore_dm_ops(void *ctx)
+{
+	amdgpu_dm_kunit_set_ops(NULL);
+}
+
+/*
+ * A device whose AGP aperture is disabled (bot above top), so the frame buffer
+ * alone decides the logical address range.
+ */
+static struct amdgpu_device *dm_test_mmhub_adev(struct kunit *test)
+{
+	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+
+	amdgpu_dm_kunit_set_ops(&dm_test_dm_ops);
+	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, dm_test_restore_dm_ops, NULL), 0);
+
+	adev->gmc.agp_start = 0x2000000;
+	adev->gmc.agp_end = 0x1000000;
+	adev->gmc.fb_start = 0x40000000;
+	adev->gmc.fb_end = 0x7fffffff;
+	adev->gmc.gart_start = 0x100000000ULL;
+	adev->gmc.gart_end = 0x1ffffffffULL;
+	adev->vm_manager.vram_base_offset = 0x800000;
+
+	return adev;
+}
+
+/**
+ * dm_test_mmhub_agp_disabled - Test a disabled AGP aperture uses the frame buffer
+ * @test: The KUnit test context
+ */
+static void dm_test_mmhub_agp_disabled(struct kunit *test)
+{
+	struct amdgpu_device *adev = dm_test_mmhub_adev(test);
+	struct dc_phy_addr_space_config pa_config;
+
+	mmhub_read_system_context(adev, &pa_config);
+
+	KUNIT_EXPECT_EQ(test, pa_config.system_aperture.start_addr, 0x40000000ULL);
+	KUNIT_EXPECT_EQ(test, pa_config.system_aperture.end_addr, 0x7ffc0000ULL);
+	KUNIT_EXPECT_EQ(test, pa_config.system_aperture.agp_base, 0ULL);
+	KUNIT_EXPECT_EQ(test, pa_config.system_aperture.agp_bot, 0x2000000ULL);
+	KUNIT_EXPECT_EQ(test, pa_config.system_aperture.agp_top, 0x1000000ULL);
+	KUNIT_EXPECT_EQ(test, pa_config.system_aperture.fb_base, 0x40000000ULL);
+	KUNIT_EXPECT_EQ(test, pa_config.system_aperture.fb_offset, 0x800000ULL);
+	KUNIT_EXPECT_EQ(test, pa_config.system_aperture.fb_top, 0x7fffffffULL);
+	KUNIT_EXPECT_EQ(test, pa_config.gart_config.page_table_start_addr, 0x100000000ULL);
+	KUNIT_EXPECT_EQ(test, pa_config.gart_config.page_table_end_addr, 0x1fffff000ULL);
+	KUNIT_EXPECT_EQ(test, pa_config.gart_config.page_table_base_addr, DM_TEST_PD_ADDR);
+	KUNIT_EXPECT_FALSE(test, pa_config.is_hvm_enabled);
+}
+
+/**
+ * dm_test_mmhub_agp_disabled_raven2 - Test the Raven2 aperture workaround
+ * @test: The KUnit test context
+ */
+static void dm_test_mmhub_agp_disabled_raven2(struct kunit *test)
+{
+	struct amdgpu_device *adev = dm_test_mmhub_adev(test);
+	struct dc_phy_addr_space_config pa_config;
+
+	adev->apu_flags = AMD_APU_IS_RAVEN2;
+
+	mmhub_read_system_context(adev, &pa_config);
+
+	KUNIT_EXPECT_EQ(test, pa_config.system_aperture.end_addr, 0x80000000ULL);
+}
+
+/**
+ * dm_test_mmhub_agp_enabled - Test an enabled AGP aperture widens the range
+ * @test: The KUnit test context
+ */
+static void dm_test_mmhub_agp_enabled(struct kunit *test)
+{
+	struct amdgpu_device *adev = dm_test_mmhub_adev(test);
+	struct dc_phy_addr_space_config pa_config;
+
+	adev->gmc.agp_start = 0x1000000;
+	adev->gmc.agp_end = 0x2000000;
+	adev->mode_info.gpu_vm_support = true;
+
+	mmhub_read_system_context(adev, &pa_config);
+
+	KUNIT_EXPECT_EQ(test, pa_config.system_aperture.start_addr, 0x1000000ULL);
+	KUNIT_EXPECT_EQ(test, pa_config.system_aperture.end_addr, 0x7ffc0000ULL);
+	KUNIT_EXPECT_TRUE(test, pa_config.is_hvm_enabled);
+}
+
+/**
+ * dm_test_mmhub_agp_enabled_renoir - Test the Renoir aperture workaround
+ * @test: The KUnit test context
+ */
+static void dm_test_mmhub_agp_enabled_renoir(struct kunit *test)
+{
+	struct amdgpu_device *adev = dm_test_mmhub_adev(test);
+	struct dc_phy_addr_space_config pa_config;
+
+	adev->gmc.agp_start = 0x1000000;
+	adev->gmc.agp_end = 0x2000000;
+	adev->apu_flags = AMD_APU_IS_RENOIR;
+
+	mmhub_read_system_context(adev, &pa_config);
+
+	KUNIT_EXPECT_EQ(test, pa_config.system_aperture.end_addr, 0x80000000ULL);
+}
+
 static struct kunit_case amdgpu_dm_tests[] = {
 	/* Simple DM callbacks */
 	KUNIT_CASE(dm_test_wait_for_idle),
@@ -3571,6 +3694,11 @@ static struct kunit_case amdgpu_dm_tests[] = {
 	KUNIT_CASE(dm_test_oem_i2c_hw_init_no_device),
 	KUNIT_CASE(dm_test_gpureset_commit_state_no_streams),
 	KUNIT_CASE(dm_test_emulated_link_detect_bad_signal),
+	/* mmhub_read_system_context */
+	KUNIT_CASE(dm_test_mmhub_agp_disabled),
+	KUNIT_CASE(dm_test_mmhub_agp_disabled_raven2),
+	KUNIT_CASE(dm_test_mmhub_agp_enabled),
+	KUNIT_CASE(dm_test_mmhub_agp_enabled_renoir),
 	{}
 };
 
-- 
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.