diff options
author | Aurabindo Pillai <aurabindo.pillai@amd.com> | 2022-02-21 15:33:05 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2022-06-03 16:43:38 -0400 |
commit | 543036a2de71f14f8ad566c858e5e9ff61736a86 (patch) | |
tree | 65783ad16fcb2058635c9e1b18f6f07fa9519824 /drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | |
parent | 49401d3a5c86f5ead12ea7cbe98031edb512b13a (diff) | |
download | lwn-543036a2de71f14f8ad566c858e5e9ff61736a86.tar.gz lwn-543036a2de71f14f8ad566c858e5e9ff61736a86.zip |
drm/amd: Add GFX11 modifiers support to AMDGPU (v3)
GFX11 IP introduces new tiling mode. Various combinations of DCC
settings are possible and the most preferred settings must be exposed
for optimal use of the hardware.
add_gfx11_modifiers() is based on recommendation from Marek for the
preferred tiling modifier that are most efficient for the hardware.
v2: microtiling fix noticed by Marek
v3: keep Z tiling check
Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_display.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 17c9bbe0cbc5..8ef489fad707 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -30,6 +30,9 @@ #include "atom.h" #include "amdgpu_connectors.h" #include "amdgpu_display.h" +#include "soc15_common.h" +#include "gc/gc_11_0_0_offset.h" +#include "gc/gc_11_0_0_sh_mask.h" #include <asm/div64.h> #include <linux/pci.h> @@ -663,6 +666,11 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb) { struct amdgpu_device *adev = drm_to_adev(afb->base.dev); uint64_t modifier = 0; + int num_pipes = 0; + int num_pkrs = 0; + + num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs; + num_pipes = adev->gfx.config.gb_addr_config_fields.num_pipes; if (!afb->tiling_flags || !AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) { modifier = DRM_FORMAT_MOD_LINEAR; @@ -675,7 +683,7 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb) int bank_xor_bits = 0; int packers = 0; int rb = 0; - int pipes = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes); + int pipes = ilog2(num_pipes); uint32_t dcc_offset = AMDGPU_TILING_GET(afb->tiling_flags, DCC_OFFSET_256B); switch (swizzle >> 2) { @@ -691,12 +699,17 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb) case 6: /* 64 KiB _X */ block_size_bits = 16; break; + case 7: /* 256 KiB */ + block_size_bits = 18; + break; default: /* RESERVED or VAR */ return -EINVAL; } - if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0)) + if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(11, 0, 0)) + version = AMD_FMT_MOD_TILE_VER_GFX11; + else if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0)) version = AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS; else if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 0, 0)) version = AMD_FMT_MOD_TILE_VER_GFX10; @@ -707,19 +720,33 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb) case 0: /* Z microtiling */ return -EINVAL; case 1: /* S microtiling */ - if (!has_xor) - version = AMD_FMT_MOD_TILE_VER_GFX9; + if (adev->ip_versions[GC_HWIP][0] < IP_VERSION(11, 0, 0)) { + if (!has_xor) + version = AMD_FMT_MOD_TILE_VER_GFX9; + } break; case 2: - if (!has_xor && afb->base.format->cpp[0] != 4) - version = AMD_FMT_MOD_TILE_VER_GFX9; + if (adev->ip_versions[GC_HWIP][0] < IP_VERSION(11, 0, 0)) { + if (!has_xor && afb->base.format->cpp[0] != 4) + version = AMD_FMT_MOD_TILE_VER_GFX9; + } break; case 3: break; } if (has_xor) { + if (num_pipes == num_pkrs && num_pkrs == 0) { + DRM_ERROR("invalid number of pipes and packers\n"); + return -EINVAL; + } + 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)); + break; case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS: pipe_xor_bits = min(block_size_bits - 8, pipes); packers = min(block_size_bits - 8 - pipe_xor_bits, @@ -753,9 +780,10 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb) u64 render_dcc_offset; /* Enable constant encode on RAVEN2 and later. */ - bool dcc_constant_encode = adev->asic_type > CHIP_RAVEN || + bool dcc_constant_encode = (adev->asic_type > CHIP_RAVEN || (adev->asic_type == CHIP_RAVEN && - adev->external_rev_id >= 0x81); + adev->external_rev_id >= 0x81)) && + adev->ip_versions[GC_HWIP][0] < IP_VERSION(11, 0, 0); int max_cblock_size = dcc_i64b ? AMD_FMT_MOD_DCC_BLOCK_64B : dcc_i128b ? AMD_FMT_MOD_DCC_BLOCK_128B : @@ -870,10 +898,11 @@ static unsigned int get_dcc_block_size(uint64_t modifier, bool rb_aligned, return max(10 + (rb_aligned ? (int)AMD_FMT_MOD_GET(RB, modifier) : 0), 12); } case AMD_FMT_MOD_TILE_VER_GFX10: - case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS: { + case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS: + case AMD_FMT_MOD_TILE_VER_GFX11: { int pipes_log2 = AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier); - if (ver == AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS && pipes_log2 > 1 && + if (ver >= AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS && pipes_log2 > 1 && AMD_FMT_MOD_GET(PACKERS, modifier) == pipes_log2) ++pipes_log2; @@ -966,6 +995,9 @@ static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb) case DC_SW_64KB_S_X: block_size_log2 = 16; break; + case DC_SW_VAR_S_X: + block_size_log2 = 18; + break; default: drm_dbg_kms(rfb->base.dev, "Swizzle mode with unknown block size: %d\n", swizzle); |