drm/amd/display: Test GFX9/GFX10 plane modifiers

[WHAT]
Add KUnit tests for amdgpu_dm_plane_get_plane_modifiers() on GFX9,
Raven, Raven constant-encode, GFX10.1 and GFX10.3 devices.

Introduce the dm_test_expect_mods_terminated(), dm_test_mods_contain()
and dm_test_get_primary_mods() helpers used to validate the generated
modifier lists.

Assisted-by: Copilot:Claude-Opus-4.8 GPT-5.5
Reviewed-by: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: George Zhang <george.zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Alex Hung 2026-06-26 17:35:52 -06:00 committed by Alex Deucher
parent da2fe19f1b
commit 05b3588830

View File

@ -1226,6 +1226,48 @@ static void dm_test_fill_blending_global_alpha_dcn42(struct kunit *test)
KUNIT_EXPECT_EQ(test, global_alpha_value, 0x800);
}
static void dm_test_expect_mods_terminated(struct kunit *test, struct amdgpu_device *adev)
{
u64 *mods = NULL;
int ret;
int i;
ret = amdgpu_dm_plane_get_plane_modifiers(adev, DRM_PLANE_TYPE_PRIMARY, &mods);
KUNIT_ASSERT_EQ(test, ret, 0);
KUNIT_ASSERT_NOT_NULL(test, mods);
for (i = 0; mods[i] != DRM_FORMAT_MOD_INVALID; i++)
;
KUNIT_EXPECT_GT(test, i, 0);
KUNIT_EXPECT_EQ(test, mods[i - 1], DRM_FORMAT_MOD_LINEAR);
kfree(mods);
}
static bool dm_test_mods_contain(const u64 *mods, u64 expected)
{
int i;
for (i = 0; mods[i] != DRM_FORMAT_MOD_INVALID; i++) {
if (mods[i] == expected)
return true;
}
return false;
}
static u64 *dm_test_get_primary_mods(struct kunit *test, struct amdgpu_device *adev)
{
u64 *mods = NULL;
int ret;
ret = amdgpu_dm_plane_get_plane_modifiers(adev, DRM_PLANE_TYPE_PRIMARY, &mods);
KUNIT_ASSERT_EQ(test, ret, 0);
KUNIT_ASSERT_NOT_NULL(test, mods);
return mods;
}
/**
* dm_test_get_plane_formats_overlay_universal_cap() - Verify universal overlay.
* @test: KUnit test context.
@ -1252,6 +1294,178 @@ static void dm_test_get_plane_formats_overlay_universal_cap(struct kunit *test)
14);
}
/**
* dm_test_get_plane_modifiers_gfx9() - Verify GFX9 modifier list generation.
* @test: KUnit test context.
*
* Verify if the GFX9 family produces a non-empty modifier list terminated by
* LINEAR and INVALID entries.
*/
static void dm_test_get_plane_modifiers_gfx9(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_AI;
adev->gfx.config.gb_addr_config_fields.num_pipes = 4;
adev->gfx.config.gb_addr_config_fields.num_banks = 8;
adev->gfx.config.gb_addr_config_fields.num_se = 2;
adev->gfx.config.gb_addr_config_fields.num_rb_per_se = 2;
dm_test_expect_mods_terminated(test, adev);
}
/**
* dm_test_get_plane_modifiers_rv() - Verify RV modifier list generation.
* @test: KUnit test context.
*
* Verify if pre-Raven2 RV devices add RV-specific S-swizzle modifiers and
* non-constant-encode DCC modifiers.
*/
static void dm_test_get_plane_modifiers_rv(struct kunit *test)
{
struct amdgpu_device *adev;
u64 *mods;
u64 dcc_mod;
u64 s_x_mod;
u64 s_mod;
int pipes = 2;
int pipe_xor_bits = 3;
int bank_xor_bits = 2;
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, adev);
adev->family = AMDGPU_FAMILY_RV;
adev->asic_type = CHIP_RAVEN;
adev->external_rev_id = 0x80;
adev->gfx.config.gb_addr_config_fields.num_pipes = 4;
adev->gfx.config.gb_addr_config_fields.num_banks = 4;
adev->gfx.config.gb_addr_config_fields.num_se = 2;
adev->gfx.config.gb_addr_config_fields.num_rb_per_se = 2;
mods = dm_test_get_primary_mods(test, adev);
dcc_mod = AMD_FMT_MOD |
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
AMD_FMT_MOD_SET(DCC, 1) |
AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 0);
s_x_mod = AMD_FMT_MOD |
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits);
s_mod = AMD_FMT_MOD |
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) |
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9);
KUNIT_EXPECT_TRUE(test, dm_test_mods_contain(mods, dcc_mod));
KUNIT_EXPECT_TRUE(test, dm_test_mods_contain(mods, dcc_mod |
AMD_FMT_MOD_SET(DCC_RETILE, 1) |
AMD_FMT_MOD_SET(RB, 2) |
AMD_FMT_MOD_SET(PIPE, pipes)));
KUNIT_EXPECT_TRUE(test, dm_test_mods_contain(mods, s_x_mod));
KUNIT_EXPECT_TRUE(test, dm_test_mods_contain(mods, s_mod));
kfree(mods);
}
/**
* dm_test_get_plane_modifiers_rv_constant_encode() - Verify Raven2+ modifiers.
* @test: KUnit test context.
*
* Verify if Raven2 and later RV devices add the constant-encode modifier
* variants.
*/
static void dm_test_get_plane_modifiers_rv_constant_encode(struct kunit *test)
{
struct amdgpu_device *adev;
u64 *mods;
u64 dcc_mod;
int pipes = 2;
int pipe_xor_bits = 3;
int bank_xor_bits = 2;
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, adev);
adev->family = AMDGPU_FAMILY_RV;
adev->asic_type = CHIP_RAVEN;
adev->external_rev_id = 0x81;
adev->gfx.config.gb_addr_config_fields.num_pipes = 4;
adev->gfx.config.gb_addr_config_fields.num_banks = 4;
adev->gfx.config.gb_addr_config_fields.num_se = 2;
adev->gfx.config.gb_addr_config_fields.num_rb_per_se = 2;
mods = dm_test_get_primary_mods(test, adev);
dcc_mod = AMD_FMT_MOD |
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
AMD_FMT_MOD_SET(DCC, 1) |
AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1);
KUNIT_EXPECT_TRUE(test, dm_test_mods_contain(mods, dcc_mod));
KUNIT_EXPECT_TRUE(test, dm_test_mods_contain(mods, dcc_mod |
AMD_FMT_MOD_SET(DCC_RETILE, 1) |
AMD_FMT_MOD_SET(RB, 2) |
AMD_FMT_MOD_SET(PIPE, pipes)));
kfree(mods);
}
/**
* dm_test_get_plane_modifiers_gfx10_1() - Verify GFX10.1 modifier list generation.
* @test: KUnit test context.
*
* Verify if a pre-10.3 NV family device dispatches to the GFX10.1 modifier
* builder and produces a terminated list.
*/
static void dm_test_get_plane_modifiers_gfx10_1(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_NV;
adev->gfx.config.gb_addr_config_fields.num_pipes = 4;
adev->ip_versions[GC_HWIP][0] = IP_VERSION(10, 1, 0);
dm_test_expect_mods_terminated(test, adev);
}
/**
* dm_test_get_plane_modifiers_gfx10_3() - Verify GFX10.3 modifier list generation.
* @test: KUnit test context.
*
* Verify if a 10.3+ NV family device dispatches to the GFX10.3 modifier
* builder and produces a terminated list.
*/
static void dm_test_get_plane_modifiers_gfx10_3(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_NV;
adev->gfx.config.gb_addr_config_fields.num_pipes = 4;
adev->gfx.config.gb_addr_config_fields.num_pkrs = 2;
adev->ip_versions[GC_HWIP][0] = IP_VERSION(10, 3, 0);
dm_test_expect_mods_terminated(test, adev);
}
/**
* dm_test_format_mod_supported_d_swizzle_reject() - Verify D swizzle rejection.
* @test: KUnit test context.
@ -1303,6 +1517,11 @@ static struct kunit_case amdgpu_dm_plane_test_cases[] = {
KUNIT_CASE(dm_test_get_plane_formats_overlay_universal_cap),
/* amdgpu_dm_plane_get_plane_modifiers() */
KUNIT_CASE(dm_test_get_plane_modifiers),
KUNIT_CASE(dm_test_get_plane_modifiers_gfx9),
KUNIT_CASE(dm_test_get_plane_modifiers_rv),
KUNIT_CASE(dm_test_get_plane_modifiers_rv_constant_encode),
KUNIT_CASE(dm_test_get_plane_modifiers_gfx10_1),
KUNIT_CASE(dm_test_get_plane_modifiers_gfx10_3),
/* amdgpu_dm_plane_fill_dc_scaling_info() */
KUNIT_CASE(dm_test_fill_dc_scaling_info),
/* amdgpu_dm_plane_get_min_max_dc_plane_scaling() */