[PATCH 48/82] drm/amd/display: Test GFX6-8 modifier calculation
<
[email protected] >
Tue, 18 Aug 2026 16:15:40 -0400
Newsgroups
org.freedesktop.lists.amd-gfx
Message-ID
<[email protected] >
From: Alex Hung <[email protected] >
[WHAT]
Add KUnit tests for amdgpu_dm_plane_calc_gfx6_mod() and
amdgpu_dm_plane_gfx6_format_mod_supported() covering the micro tiled
early return, the GFX7-8 macro tile mode table lookup, the GFX6 tile
mode register fields, and the rejection of foreign, DCC, newer tile
version, GFX9+ and non-displayable modifiers.
Assisted-by: Copilot:Claude-Opus-5
Reviewed-by: Bhawanpreet Lakha <[email protected] >
Signed-off-by: Alex Hung <[email protected] >
Signed-off-by: Ivan Lipski <[email protected] >
---
.../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 14 +-
.../amd/display/amdgpu_dm/amdgpu_dm_plane.h | 4 +
.../amdgpu_dm/tests/amdgpu_dm_plane_test.c | 146 ++++++++++++++++++
3 files changed, 158 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index d6b80c380db85..b736cd13baaeb 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -597,9 +597,9 @@ EXPORT_IF_KUNIT(amdgpu_dm_plane_get_gfx7_macro_tile_idx);
* Select suitable micro and macro tile modes for the given bits per pixel,
* and calculate the corresponding DRM format modifier.
*/
-static u64 amdgpu_dm_plane_calc_gfx6_mod(const struct amdgpu_device *adev,
- const u32 bpp,
- const enum array_mode_values arr)
+STATIC_IFN_KUNIT u64 amdgpu_dm_plane_calc_gfx6_mod(const struct amdgpu_device *adev,
+ const u32 bpp,
+ const enum array_mode_values arr)
{
u32 array_mode, micro_tile_mode, tile_split_bytes;
u32 gb_macrotile_mode, macrotile_idx;
@@ -649,6 +649,7 @@ static u64 amdgpu_dm_plane_calc_gfx6_mod(const struct amdgpu_device *adev,
AMD_FMT_MOD_SET(MACRO_TILE_ASPECT, (gb_macrotile_mode >> 4) & 0x3) |
AMD_FMT_MOD_SET(NUM_BANKS, (gb_macrotile_mode >> 6) & 0x3);
}
+EXPORT_IF_KUNIT(amdgpu_dm_plane_calc_gfx6_mod);
/**
* amdgpu_dm_plane_gfx6_format_mod_supported() - Check if a modifier is supported on GFX6-8
@@ -660,9 +661,9 @@ static u64 amdgpu_dm_plane_calc_gfx6_mod(const struct amdgpu_device *adev,
* On GFX6-8, not all DRM format modifier can be used with all image formats.
* Check whether the specified modifier is supported with the given bits per pixel value.
*/
-static bool amdgpu_dm_plane_gfx6_format_mod_supported(const struct amdgpu_device *adev,
- const u32 bpp,
- const u64 modifier)
+STATIC_IFN_KUNIT bool amdgpu_dm_plane_gfx6_format_mod_supported(const struct amdgpu_device *adev,
+ const u32 bpp,
+ const u64 modifier)
{
const u32 array_mode = AMD_FMT_MOD_GET(TILE, modifier);
const u32 micro_tile_mode = AMD_FMT_MOD_GET(MICROTILE, modifier);
@@ -701,6 +702,7 @@ static bool amdgpu_dm_plane_gfx6_format_mod_supported(const struct amdgpu_device
/* Verify that the modifier is the same that we'd expose for this bpp */
return amdgpu_dm_plane_calc_gfx6_mod(adev, bpp, array_mode) == modifier;
}
+EXPORT_IF_KUNIT(amdgpu_dm_plane_gfx6_format_mod_supported);
/**
* amdgpu_dm_plane_add_gfx6_modifiers() - Expose modifiers for GFX6-8
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
index 7c5d0a7dadb1d..b396b3ea78bae 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
@@ -130,5 +130,9 @@ u32 amdgpu_dm_plane_get_gfx6_tile_idx(const struct amdgpu_device *adev, const u3
u32 amdgpu_dm_plane_calc_gfx7_tile_split(const struct amdgpu_device *adev, const u32 bpp,
const u32 gb_tile_mode);
u32 amdgpu_dm_plane_get_gfx7_macro_tile_idx(const u32 bpp, const u32 tile_split_bytes);
+u64 amdgpu_dm_plane_calc_gfx6_mod(const struct amdgpu_device *adev, const u32 bpp,
+ const enum array_mode_values arr);
+bool amdgpu_dm_plane_gfx6_format_mod_supported(const struct amdgpu_device *adev, const u32 bpp,
+ const u64 modifier);
#endif
#endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
index 420b053d2e3dc..312fe34eb7105 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
@@ -3277,6 +3277,44 @@ static void dm_test_fill_gfx6_tiling_info_2d(struct kunit *test)
KUNIT_EXPECT_EQ(test, tiling_info.gfx8.num_banks, 2U);
}
+static u64 dm_test_gfx6_mod(u32 tile, u32 pipe_config, u32 tile_split, u32 bank_width,
+ u32 bank_height, u32 aspect, u32 num_banks)
+{
+ return AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX6) |
+ AMD_FMT_MOD_SET(TILE, tile) |
+ AMD_FMT_MOD_SET(MICROTILE, AMD_FMT_MOD_MICROTILE_DISPLAY) |
+ AMD_FMT_MOD_SET(PIPE_CONFIG, pipe_config) |
+ AMD_FMT_MOD_SET(TILE_SPLIT, tile_split) |
+ AMD_FMT_MOD_SET(BANK_WIDTH, bank_width) |
+ AMD_FMT_MOD_SET(BANK_HEIGHT, bank_height) |
+ AMD_FMT_MOD_SET(MACRO_TILE_ASPECT, aspect) |
+ AMD_FMT_MOD_SET(NUM_BANKS, num_banks);
+}
+
+static struct amdgpu_device *dm_test_alloc_gfx7_device(struct kunit *test)
+{
+ struct amdgpu_device *adev;
+
+ adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, adev);
+
+ adev->family = AMDGPU_FAMILY_VI;
+ adev->gfx.config.mem_row_size_in_kb = 4;
+ /* 2D_TILED_THIN1 array mode (bits 5:2) and pipe config 2 (bits 10:6). */
+ adev->gfx.config.tile_mode_array[10] = (4u << 2) | (2u << 6);
+ /*
+ * Bank width (bits 1:0), bank height (bits 3:2), macro tile aspect
+ * (bits 5:4) and num banks (bits 7:6). Entries 1 and 2 are identical so
+ * the 16 and 32 bpp modifiers collide and the dedup path is taken.
+ */
+ adev->gfx.config.macrotile_mode_array[1] = 0xb9u;
+ adev->gfx.config.macrotile_mode_array[2] = 0xb9u;
+ adev->gfx.config.macrotile_mode_array[3] = 0x2au;
+
+ return adev;
+}
+
/**
* dm_test_get_gfx6_tile_idx() - Verify GFX6-8 tile mode index selection.
* @test: KUnit test context.
@@ -3352,6 +3390,108 @@ static void dm_test_get_gfx7_macro_tile_idx(struct kunit *test)
KUNIT_EXPECT_EQ(test, amdgpu_dm_plane_get_gfx7_macro_tile_idx(64, 256), 2U);
}
+/**
+ * dm_test_calc_gfx6_mod_1d() - Verify the micro tiled GFX6-8 modifier.
+ * @test: KUnit test context.
+ *
+ * Verify if a micro tiled array mode returns early with only the base modifier
+ * fields set.
+ */
+static void dm_test_calc_gfx6_mod_1d(struct kunit *test)
+{
+ struct amdgpu_device *adev = dm_test_alloc_gfx7_device(test);
+ u64 expected = AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX6) |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX6_1D_TILED_THIN1) |
+ AMD_FMT_MOD_SET(MICROTILE, AMD_FMT_MOD_MICROTILE_DISPLAY);
+
+ KUNIT_EXPECT_EQ(test,
+ amdgpu_dm_plane_calc_gfx6_mod(adev, 0, DC_ARRAY_1D_TILED_THIN1),
+ expected);
+}
+
+/**
+ * dm_test_calc_gfx6_mod_gfx7() - Verify the macro tiled GFX7-8 modifier.
+ * @test: KUnit test context.
+ *
+ * Verify if the modifier combines the tile mode pipe config and computed tile
+ * split with the bank fields taken from the macro tile mode table.
+ */
+static void dm_test_calc_gfx6_mod_gfx7(struct kunit *test)
+{
+ struct amdgpu_device *adev = dm_test_alloc_gfx7_device(test);
+
+ /* 32 bpp: 256 byte tile split (log2 of 4 units), macro tile mode 2. */
+ KUNIT_EXPECT_EQ(test,
+ amdgpu_dm_plane_calc_gfx6_mod(adev, 32, DC_ARRAY_2D_TILED_THIN1),
+ dm_test_gfx6_mod(AMD_FMT_MOD_TILE_GFX6_2D_TILED_THIN1, 2, 2, 1, 2, 3, 2));
+
+ /* 64 bpp: 512 byte tile split (log2 of 8 units), macro tile mode 3. */
+ KUNIT_EXPECT_EQ(test,
+ amdgpu_dm_plane_calc_gfx6_mod(adev, 64, DC_ARRAY_2D_TILED_THIN1),
+ dm_test_gfx6_mod(AMD_FMT_MOD_TILE_GFX6_2D_TILED_THIN1, 2, 3, 2, 2, 2, 0));
+}
+
+/**
+ * dm_test_calc_gfx6_mod_si() - Verify the macro tiled GFX6 modifier.
+ * @test: KUnit test context.
+ *
+ * Verify if GFX6 takes the tile split and bank fields directly from the tile
+ * mode register instead of the macro tile mode table.
+ */
+static void dm_test_calc_gfx6_mod_si(struct kunit *test)
+{
+ struct amdgpu_device *adev;
+
+ adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, adev);
+
+ adev->family = AMDGPU_FAMILY_SI;
+ /* 2D_TILED_THIN1, pipe config 3, 256 byte tile split, banks 1/2/3/1. */
+ adev->gfx.config.tile_mode_array[12] = (4u << 2) | (3u << 6) | (2u << 11) |
+ (1u << 14) | (2u << 16) | (3u << 18) |
+ (1u << 20);
+
+ KUNIT_EXPECT_EQ(test,
+ amdgpu_dm_plane_calc_gfx6_mod(adev, 32, DC_ARRAY_2D_TILED_THIN1),
+ dm_test_gfx6_mod(AMD_FMT_MOD_TILE_GFX6_2D_TILED_THIN1, 3, 2, 1, 2, 3, 1));
+}
+
+/**
+ * dm_test_gfx6_format_mod_supported() - Verify GFX6-8 modifier support checks.
+ * @test: KUnit test context.
+ *
+ * Verify if only the canonical modifier for a given bits per pixel is accepted,
+ * and that non-AMD modifiers, newer tile versions, GFX9+ devices, DCC, and
+ * non-displayable tile modes are rejected.
+ */
+static void dm_test_gfx6_format_mod_supported(struct kunit *test)
+{
+ struct amdgpu_device *adev = dm_test_alloc_gfx7_device(test);
+ u64 modifier = amdgpu_dm_plane_calc_gfx6_mod(adev, 32, DC_ARRAY_2D_TILED_THIN1);
+ u64 gfx9_mod = AMD_FMT_MOD | AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9);
+ /* Neither 1D nor 2D THIN array mode. */
+ u64 bad_tile_mod = AMD_FMT_MOD | AMD_FMT_MOD_SET(TILE, 3);
+ /* Non-displayable micro tile mode. */
+ u64 bad_micro_mod = AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX6_2D_TILED_THIN1) |
+ AMD_FMT_MOD_SET(MICROTILE, AMD_FMT_MOD_MICROTILE_THIN);
+ u64 not_amd_mod = DRM_FORMAT_MOD_VENDOR_AMD;
+ u64 dcc_mod = modifier | AMD_FMT_MOD_SET(DCC, 1);
+
+ KUNIT_EXPECT_TRUE(test, amdgpu_dm_plane_gfx6_format_mod_supported(adev, 32, modifier));
+
+ KUNIT_EXPECT_FALSE(test, amdgpu_dm_plane_gfx6_format_mod_supported(adev, 64, modifier));
+ KUNIT_EXPECT_FALSE(test, amdgpu_dm_plane_gfx6_format_mod_supported(adev, 32, not_amd_mod));
+ KUNIT_EXPECT_FALSE(test, amdgpu_dm_plane_gfx6_format_mod_supported(adev, 32, gfx9_mod));
+ KUNIT_EXPECT_FALSE(test, amdgpu_dm_plane_gfx6_format_mod_supported(adev, 32, dcc_mod));
+ KUNIT_EXPECT_FALSE(test, amdgpu_dm_plane_gfx6_format_mod_supported(adev, 32, bad_tile_mod));
+ KUNIT_EXPECT_FALSE(test, amdgpu_dm_plane_gfx6_format_mod_supported(adev, 32, bad_micro_mod));
+
+ adev->family = AMDGPU_FAMILY_AI;
+ KUNIT_EXPECT_FALSE(test, amdgpu_dm_plane_gfx6_format_mod_supported(adev, 32, modifier));
+}
+
static struct kunit_case amdgpu_dm_plane_test_cases[] = {
/* amdgpu_dm_plane_is_video_format() */
KUNIT_CASE(dm_test_plane_is_video_format_known_video),
@@ -3452,6 +3592,12 @@ static struct kunit_case amdgpu_dm_plane_test_cases[] = {
KUNIT_CASE(dm_test_calc_gfx7_tile_split),
/* amdgpu_dm_plane_get_gfx7_macro_tile_idx() */
KUNIT_CASE(dm_test_get_gfx7_macro_tile_idx),
+ /* amdgpu_dm_plane_calc_gfx6_mod() */
+ KUNIT_CASE(dm_test_calc_gfx6_mod_1d),
+ KUNIT_CASE(dm_test_calc_gfx6_mod_gfx7),
+ KUNIT_CASE(dm_test_calc_gfx6_mod_si),
+ /* amdgpu_dm_plane_gfx6_format_mod_supported() */
+ KUNIT_CASE(dm_test_gfx6_format_mod_supported),
/* amdgpu_dm_plane_fill_gfx9_tiling_info_from_device() */
KUNIT_CASE(dm_test_fill_gfx9_tiling_info_from_device_pre_10_3),
KUNIT_CASE(dm_test_fill_gfx9_tiling_info_from_device_10_3_plus),
--
2.43.0