[PATCH 14/43] drm/amd: Add GFX11 modifiers support to AMDGPU
Marek Olšák
maraeo at gmail.com
Wed May 25 19:27:28 UTC 2022
On Wed, May 25, 2022 at 12:20 PM Alex Deucher <alexander.deucher at amd.com>
wrote:
> From: Aurabindo Pillai <aurabindo.pillai at 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.pillai at amd.com>
> Acked-by: Alex Deucher <alexander.deucher at amd.com>
> Signed-off-by: Alex Deucher <alexander.deucher at 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/amd-gfx/attachments/20220525/36b9ab4d/attachment-0001.htm>
More information about the amd-gfx
mailing list