summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAurabindo Pillai <aurabindo.pillai@amd.com>2022-06-28 16:25:28 -0400
committerAlex Deucher <alexander.deucher@amd.com>2022-06-29 17:12:18 -0400
commitff15cea338d2c78e0086d55c8a9dd637a5dd3ccc (patch)
tree538e5646b18ab2e7f2c4e11264feffc1732bdd2c
parent7268f0a9e842c52fa73b9f5afc1bebcf9f7d48b7 (diff)
downloadlinux-ff15cea338d2c78e0086d55c8a9dd637a5dd3ccc.tar.bz2
drm/amd/display: expose additional modifier for DCN32/321
[Why&How] Some userspace expect a backwards compatible modifier on DCN32/321. For hardware with num_pipes more than 16, we expose the most efficient modifier first. As a fall back method, we need to expose slightly inefficient modifier AMD_FMT_MOD_TILE_GFX9_64K_R_X after the best option. Also set the number of packers to fixed value as required per hardware documentation. This value is cached during hardware initialization and can be read through the base driver. Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_display.c3
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c66
2 files changed, 36 insertions, 33 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 8ef489fad707..97fff4727724 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -744,8 +744,7 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
switch (version) {
case AMD_FMT_MOD_TILE_VER_GFX11:
pipe_xor_bits = min(block_size_bits - 8, pipes);
- packers = min(block_size_bits - 8 - pipe_xor_bits,
- ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs));
+ packers = ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs);
break;
case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
pipe_xor_bits = min(block_size_bits - 8, pipes);
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 9195d6a8a51f..1bd65b41ba4d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5203,6 +5203,7 @@ add_gfx11_modifiers(struct amdgpu_device *adev,
int num_pkrs = 0;
int pkrs = 0;
u32 gb_addr_config;
+ u8 i = 0;
unsigned swizzle_r_x;
uint64_t modifier_r_x;
uint64_t modifier_dcc_best;
@@ -5218,37 +5219,40 @@ add_gfx11_modifiers(struct amdgpu_device *adev,
num_pipes = 1 << REG_GET_FIELD(gb_addr_config, GB_ADDR_CONFIG, NUM_PIPES);
pipe_xor_bits = ilog2(num_pipes);
- /* R_X swizzle modes are the best for rendering and DCC requires them. */
- swizzle_r_x = num_pipes > 16 ? AMD_FMT_MOD_TILE_GFX11_256K_R_X :
- AMD_FMT_MOD_TILE_GFX9_64K_R_X;
-
- modifier_r_x = AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX11) |
- AMD_FMT_MOD_SET(TILE, swizzle_r_x) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(PACKERS, pkrs);
-
- /* DCC_CONSTANT_ENCODE is not set because it can't vary with gfx11 (it's implied to be 1). */
- modifier_dcc_best = modifier_r_x |
- AMD_FMT_MOD_SET(DCC, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 0) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
- AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B);
-
- /* DCC settings for 4K and greater resolutions. (required by display hw) */
- modifier_dcc_4k = modifier_r_x |
- AMD_FMT_MOD_SET(DCC, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
- AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B);
-
- add_modifier(mods, size, capacity, modifier_dcc_best);
- add_modifier(mods, size, capacity, modifier_dcc_4k);
-
- add_modifier(mods, size, capacity, modifier_dcc_best | AMD_FMT_MOD_SET(DCC_RETILE, 1));
- add_modifier(mods, size, capacity, modifier_dcc_4k | AMD_FMT_MOD_SET(DCC_RETILE, 1));
-
- add_modifier(mods, size, capacity, modifier_r_x);
+ for (i = 0; i < 2; i++) {
+ /* Insert the best one first. */
+ /* R_X swizzle modes are the best for rendering and DCC requires them. */
+ if (num_pipes > 16)
+ swizzle_r_x = !i ? AMD_FMT_MOD_TILE_GFX11_256K_R_X : AMD_FMT_MOD_TILE_GFX9_64K_R_X;
+ else
+ swizzle_r_x = !i ? AMD_FMT_MOD_TILE_GFX9_64K_R_X : AMD_FMT_MOD_TILE_GFX11_256K_R_X;
+
+ modifier_r_x = AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX11) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(TILE, swizzle_r_x) |
+ AMD_FMT_MOD_SET(PACKERS, pkrs);
+
+ /* DCC_CONSTANT_ENCODE is not set because it can't vary with gfx11 (it's implied to be 1). */
+ modifier_dcc_best = modifier_r_x | AMD_FMT_MOD_SET(DCC, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 0) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
+ AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B);
+
+ /* DCC settings for 4K and greater resolutions. (required by display hw) */
+ modifier_dcc_4k = modifier_r_x | AMD_FMT_MOD_SET(DCC, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
+ AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B);
+
+ add_modifier(mods, size, capacity, modifier_dcc_best);
+ add_modifier(mods, size, capacity, modifier_dcc_4k);
+
+ add_modifier(mods, size, capacity, modifier_dcc_best | AMD_FMT_MOD_SET(DCC_RETILE, 1));
+ add_modifier(mods, size, capacity, modifier_dcc_4k | AMD_FMT_MOD_SET(DCC_RETILE, 1));
+
+ add_modifier(mods, size, capacity, modifier_r_x);
+ }
add_modifier(mods, size, capacity, AMD_FMT_MOD |
AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX11) |