[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