On Wed, May 25, 2022 at 12:20 PM Alex Deucher <alexander.deuc...@amd.com> wrote:
> From: Aurabindo Pillai <aurabindo.pil...@amd.com> > > 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. > > Signed-off-by: Aurabindo Pillai <aurabindo.pil...@amd.com> > Acked-by: Alex Deucher <alexander.deuc...@amd.com> > Signed-off-by: Alex Deucher <alexander.deuc...@amd.com> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 40 ++++++++-- > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 74 ++++++++++++++++++- > include/uapi/drm/drm_fourcc.h | 2 + > 3 files changed, 108 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c > index ec395fe427f2..a54081a89282 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> > @@ -662,6 +665,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; > @@ -674,7 +682,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) { > @@ -690,12 +698,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; > @@ -718,7 +731,17 @@ static int convert_tiling_flags_to_modifier(struct > amdgpu_framebuffer *afb) > } > The switch statement right above this that is not in this patch and changes "version" should be skipped on >= gfx11. Under no circumstances should the version be changed on gfx11. Marek > > 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, > @@ -752,9 +775,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 : > @@ -869,10 +893,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; > > @@ -965,6 +990,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); > 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 a93affc37c53..badd136f5686 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -88,10 +88,14 @@ > #include "dcn/dcn_1_0_offset.h" > #include "dcn/dcn_1_0_sh_mask.h" > #include "soc15_hw_ip.h" > +#include "soc15_common.h" > #include "vega10_ip_offset.h" > > #include "soc15_common.h" > > +#include "gc/gc_11_0_0_offset.h" > +#include "gc/gc_11_0_0_sh_mask.h" > + > #include "modules/inc/mod_freesync.h" > #include "modules/power/power_helpers.h" > #include "modules/inc/mod_info_packet.h" > @@ -4885,7 +4889,9 @@ fill_gfx9_tiling_info_from_modifier(const struct > amdgpu_device *adev, > unsigned int mod_bank_xor_bits = AMD_FMT_MOD_GET(BANK_XOR_BITS, > modifier); > unsigned int mod_pipe_xor_bits = AMD_FMT_MOD_GET(PIPE_XOR_BITS, > modifier); > unsigned int pkrs_log2 = AMD_FMT_MOD_GET(PACKERS, modifier); > - unsigned int pipes_log2 = min(4u, mod_pipe_xor_bits); > + unsigned int pipes_log2; > + > + pipes_log2 = min(5u, mod_pipe_xor_bits); > > fill_gfx9_tiling_info_from_device(adev, tiling_info); > > @@ -5221,6 +5227,67 @@ add_gfx10_3_modifiers(const struct amdgpu_device > *adev, > AMD_FMT_MOD_SET(TILE_VERSION, > AMD_FMT_MOD_TILE_VER_GFX9)); > } > > +static void > +add_gfx11_modifiers(const struct amdgpu_device *adev, > + uint64_t **mods, uint64_t *size, uint64_t *capacity) > +{ > + int num_pipes = 0; > + int pipe_xor_bits = 0; > + int num_pkrs = 0; > + int pkrs = 0; > + u32 gb_addr_config; > + unsigned swizzle_r_x; > + uint64_t modifier_r_x; > + uint64_t modifier_dcc_best; > + uint64_t modifier_dcc_4k; > + > + /* TODO: GFX11 IP HW init hasnt finish and we get zero if we read > from > + * adev->gfx.config.gb_addr_config_fields.num_{pkrs,pipes} */ > + gb_addr_config = RREG32_SOC15(GC, 0, regGB_ADDR_CONFIG); > + ASSERT(gb_addr_config != 0); > + > + num_pkrs = 1 << REG_GET_FIELD(gb_addr_config, GB_ADDR_CONFIG, > NUM_PKRS); > + pkrs = ilog2(num_pkrs); > + 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); > + > + add_modifier(mods, size, capacity, AMD_FMT_MOD | > + AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX11) | > + AMD_FMT_MOD_SET(TILE, > AMD_FMT_MOD_TILE_GFX9_64K_D)); > +} > + > static int > get_plane_modifiers(const struct amdgpu_device *adev, unsigned int > plane_type, uint64_t **mods) > { > @@ -5254,6 +5321,9 @@ get_plane_modifiers(const struct amdgpu_device > *adev, unsigned int plane_type, u > else > add_gfx10_1_modifiers(adev, mods, &size, > &capacity); > break; > + case AMDGPU_FAMILY_GC_11_0_0: > + add_gfx11_modifiers(adev, mods, &size, &capacity); > + break; > } > > add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR); > @@ -5292,7 +5362,7 @@ fill_gfx9_plane_attributes_from_modifiers(struct > amdgpu_device *adev, > dcc->enable = 1; > dcc->meta_pitch = afb->base.pitches[1]; > dcc->independent_64b_blks = independent_64b_blks; > - if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == > AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) { > + if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) >= > AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) { > if (independent_64b_blks && independent_128b_blks) > dcc->dcc_ind_blk = > hubp_ind_block_64b_no_128bcl; > else if (independent_128b_blks) > diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h > index fc0c1454d275..14cb2dafb0fa 100644 > --- a/include/uapi/drm/drm_fourcc.h > +++ b/include/uapi/drm/drm_fourcc.h > @@ -1294,6 +1294,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 > modifier) > #define AMD_FMT_MOD_TILE_VER_GFX9 1 > #define AMD_FMT_MOD_TILE_VER_GFX10 2 > #define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3 > +#define AMD_FMT_MOD_TILE_VER_GFX11 4 > > /* > * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as > canonical > @@ -1309,6 +1310,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 > modifier) > #define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25 > #define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26 > #define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27 > +#define AMD_FMT_MOD_TILE_GFX11_256K_R_X 31 > > #define AMD_FMT_MOD_DCC_BLOCK_64B 0 > #define AMD_FMT_MOD_DCC_BLOCK_128B 1 > -- > 2.35.3 > >