[PATCH] drm/amdgpu: Add indirect L1_TLB_CNTL reg programming for VFs

Luo, Zhigang Zhigang.Luo at amd.com
Fri Mar 28 15:47:48 UTC 2025


[AMD Official Use Only - AMD Internal Distribution Only]

> -----Original Message-----
> From: Skvortsov, Victor <Victor.Skvortsov at amd.com>
> Sent: Thursday, March 27, 2025 11:58 AM
> To: amd-gfx at lists.freedesktop.org
> Cc: Rehman, Ahmad <Ahmad.Rehman at amd.com>; Chan, Hing Pong
> <Jeffrey.Chan at amd.com>; Luo, Zhigang <Zhigang.Luo at amd.com>; Skvortsov,
> Victor <Victor.Skvortsov at amd.com>
> Subject: [PATCH] drm/amdgpu: Add indirect L1_TLB_CNTL reg programming for
> VFs
>
> VFs on some IP verions are unable to access this register directly.
>
> This register must be programmed before PSP ring is setup, so use PSP VF mailbox
> directly.
>
> Signed-off-by: Victor Skvortsov <victor.skvortsov at amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h     | 10 ++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h    | 12 +++-
>  drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h |  9 +--
>  drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c     | 63 ++++++++++++++++-----
>  drivers/gpu/drm/amd/amdgpu/psp_v13_0.c      | 20 +++++++
>  5 files changed, 93 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
> index 8d5acc415d38..dcf5e8e0b9e3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
> @@ -107,6 +107,7 @@ enum psp_reg_prog_id {
>       PSP_REG_IH_RB_CNTL        = 0,  /* register IH_RB_CNTL */
>       PSP_REG_IH_RB_CNTL_RING1  = 1,  /* register IH_RB_CNTL_RING1 */
>       PSP_REG_IH_RB_CNTL_RING2  = 2,  /* register IH_RB_CNTL_RING2 */
> +     PSP_REG_MMHUB_L1_TLB_CNTL = 25,
>       PSP_REG_LAST
>  };
>
> @@ -142,6 +143,8 @@ struct psp_funcs {
>       bool (*get_ras_capability)(struct psp_context *psp);
>       bool (*is_aux_sos_load_required)(struct psp_context *psp);
>       bool (*is_reload_needed)(struct psp_context *psp);
> +     int (*reg_program_no_ring)(struct psp_context *psp, uint32_t val,
> +                                enum psp_reg_prog_id id);
>  };
>
>  struct ta_funcs {
> @@ -475,6 +478,10 @@ struct amdgpu_psp_funcs {  #define
> psp_is_aux_sos_load_required(psp) \
>       ((psp)->funcs->is_aux_sos_load_required ? (psp)->funcs-
> >is_aux_sos_load_required((psp)) : 0)
>
> +#define psp_reg_program_no_ring(psp, val, id) \
> +     ((psp)->funcs->reg_program_no_ring ? \
> +     (psp)->funcs->reg_program_no_ring((psp), val, id) : -EINVAL)
> +
>  extern const struct amd_ip_funcs psp_ip_funcs;
>
>  extern const struct amdgpu_ip_block_version psp_v3_1_ip_block; @@ -569,5
> +576,8 @@ bool amdgpu_psp_get_ras_capability(struct psp_context *psp);  int
> psp_config_sq_perfmon(struct psp_context *psp, uint32_t xcp_id,
>       bool core_override_enable, bool reg_override_enable, bool
> perfmon_override_enable);  bool amdgpu_psp_tos_reload_needed(struct
> amdgpu_device *adev);
> +int amdgpu_psp_reg_program_no_ring(struct psp_context *psp, uint32_t val,
> +                                enum psp_reg_prog_id id);
> +
>
>  #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> index df03dba67ab8..b6ec6b7969f0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> @@ -146,11 +146,13 @@ enum AMDGIM_FEATURE_FLAG {
>
>  enum AMDGIM_REG_ACCESS_FLAG {
>       /* Use PSP to program IH_RB_CNTL */
> -     AMDGIM_FEATURE_IH_REG_PSP_EN     = (1 << 0),
> +     AMDGIM_FEATURE_IH_REG_PSP_EN      = (1 << 0),
>       /* Use RLC to program MMHUB regs */
> -     AMDGIM_FEATURE_MMHUB_REG_RLC_EN  = (1 << 1),
> +     AMDGIM_FEATURE_MMHUB_REG_RLC_EN   = (1 << 1),
>       /* Use RLC to program GC regs */
> -     AMDGIM_FEATURE_GC_REG_RLC_EN     = (1 << 2),
> +     AMDGIM_FEATURE_GC_REG_RLC_EN      = (1 << 2),
> +     /* Use PSP to program L1_TLB_CNTL*/
> +     AMDGIM_FEATURE_L1_TLB_CNTL_PSP_EN = (1 << 3),
>  };
>
>  struct amdgim_pf2vf_info_v1 {
> @@ -330,6 +332,10 @@ struct amdgpu_video_codec_info;
>  (amdgpu_sriov_vf((adev)) && \
>       ((adev)->virt.reg_access & (AMDGIM_FEATURE_GC_REG_RLC_EN)))
>
> +#define amdgpu_sriov_reg_indirect_l1_tlb_cntl(adev) \
> +(amdgpu_sriov_vf((adev)) && \
> +     ((adev)->virt.reg_access &
> (AMDGIM_FEATURE_L1_TLB_CNTL_PSP_EN)))
> +
>  #define amdgpu_sriov_rlcg_error_report_enabled(adev) \
>          (amdgpu_sriov_reg_indirect_mmhub(adev) ||
> amdgpu_sriov_reg_indirect_gc(adev))
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> index d6ac2652f0ac..bea724981309 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> @@ -109,10 +109,11 @@ union amd_sriov_msg_feature_flags {
>
>  union amd_sriov_reg_access_flags {
>       struct {
> -             uint32_t vf_reg_access_ih       : 1;
> -             uint32_t vf_reg_access_mmhub    : 1;
> -             uint32_t vf_reg_access_gc       : 1;
> -             uint32_t reserved               : 29;
> +             uint32_t vf_reg_access_ih               : 1;
> +             uint32_t vf_reg_access_mmhub            : 1;
> +             uint32_t vf_reg_access_gc               : 1;
> +             uint32_t vf_reg_access_l1_tlb_cntl      : 1;
> +             uint32_t reserved                       : 28;
>       } flags;
>       uint32_t all;
>  };
> diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c
> b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c
> index 84cde1239ee4..cc218f6e37c2 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c
> @@ -30,6 +30,7 @@
>  #include "soc15_common.h"
>  #include "soc15.h"
>  #include "amdgpu_ras.h"
> +#include "amdgpu_psp.h"
>
>  #define regVM_L2_CNTL3_DEFAULT       0x80100007
>  #define regVM_L2_CNTL4_DEFAULT       0x000000c1
> @@ -192,10 +193,8 @@ static void mmhub_v1_8_init_tlb_regs(struct
> amdgpu_device *adev)
>       uint32_t tmp, inst_mask;
>       int i;
>
> -     /* Setup TLB control */
> -     inst_mask = adev->aid_mask;
> -     for_each_inst(i, inst_mask) {
> -             tmp = RREG32_SOC15(MMHUB, i,
> regMC_VM_MX_L1_TLB_CNTL);
> +     if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_l1_tlb_cntl(adev))

[Luo, Zhigang] amdgpu_sriov_vf() checking can be removed as amdgpu_sriov_reg_indirect_l1_tlb_cntl already has the checking.
With this change, this patch is reviewed by Zhigang Luo <Zhigang.luo at amd.com>

> {
> +             tmp = RREG32_SOC15(MMHUB, 0,
> regMC_VM_MX_L1_TLB_CNTL);
>
>               tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> ENABLE_L1_TLB,
>                                   1);
> @@ -209,7 +208,26 @@ static void mmhub_v1_8_init_tlb_regs(struct
> amdgpu_device *adev)
>                                   MTYPE, MTYPE_UC);/* XXX for emulation. */
>               tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> ATC_EN, 1);
>
> -             WREG32_SOC15(MMHUB, i, regMC_VM_MX_L1_TLB_CNTL, tmp);
> +             psp_reg_program_no_ring(&adev->psp, tmp,
> PSP_REG_MMHUB_L1_TLB_CNTL);
> +     } else {
> +             inst_mask = adev->aid_mask;
> +             for_each_inst(i, inst_mask) {
> +                     tmp = RREG32_SOC15(MMHUB, i,
> regMC_VM_MX_L1_TLB_CNTL);
> +
> +                     tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> ENABLE_L1_TLB,
> +                                         1);
> +                     tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> +                                         SYSTEM_ACCESS_MODE, 3);
> +                     tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> +                                         ENABLE_ADVANCED_DRIVER_MODEL,
> 1);
> +                     tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> +
> SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
> +                     tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> +                                         MTYPE, MTYPE_UC);/* XXX for emulation.
> */
> +                     tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> ATC_EN, 1);
> +
> +                     WREG32_SOC15(MMHUB, i,
> regMC_VM_MX_L1_TLB_CNTL, tmp);
> +             }
>       }
>  }
>
> @@ -454,6 +472,30 @@ static int mmhub_v1_8_gart_enable(struct amdgpu_device
> *adev)
>       return 0;
>  }
>
> +static void mmhub_v1_8_disable_l1_tlb(struct amdgpu_device *adev) {
> +     u32 tmp;
> +     u32 i, inst_mask;
> +
> +     if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_l1_tlb_cntl(adev))
> {
> +             tmp = RREG32_SOC15(MMHUB, 0,
> regMC_VM_MX_L1_TLB_CNTL);
> +             tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> ENABLE_L1_TLB, 0);
> +             tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> +                                 ENABLE_ADVANCED_DRIVER_MODEL, 0);
> +             psp_reg_program_no_ring(&adev->psp, tmp,
> PSP_REG_MMHUB_L1_TLB_CNTL);
> +     } else {
> +             inst_mask = adev->aid_mask;
> +             for_each_inst(i, inst_mask) {
> +                     tmp = RREG32_SOC15(MMHUB, i,
> regMC_VM_MX_L1_TLB_CNTL);
> +                     tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> ENABLE_L1_TLB,
> +                                         0);
> +                     tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> +                                         ENABLE_ADVANCED_DRIVER_MODEL,
> 0);
> +                     WREG32_SOC15(MMHUB, i,
> regMC_VM_MX_L1_TLB_CNTL, tmp);
> +             }
> +     }
> +}
> +
>  static void mmhub_v1_8_gart_disable(struct amdgpu_device *adev)  {
>       struct amdgpu_vmhub *hub;
> @@ -467,15 +509,6 @@ static void mmhub_v1_8_gart_disable(struct
> amdgpu_device *adev)
>               for (i = 0; i < 16; i++)
>                       WREG32_SOC15_OFFSET(MMHUB, j,
> regVM_CONTEXT0_CNTL,
>                                           i * hub->ctx_distance, 0);
> -
> -             /* Setup TLB control */
> -             tmp = RREG32_SOC15(MMHUB, j,
> regMC_VM_MX_L1_TLB_CNTL);
> -             tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> ENABLE_L1_TLB,
> -                                 0);
> -             tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL,
> -                                 ENABLE_ADVANCED_DRIVER_MODEL, 0);
> -             WREG32_SOC15(MMHUB, j, regMC_VM_MX_L1_TLB_CNTL, tmp);
> -
>               if (!amdgpu_sriov_vf(adev)) {
>                       /* Setup L2 cache */
>                       tmp = RREG32_SOC15(MMHUB, j, regVM_L2_CNTL); @@ -
> 485,6 +518,8 @@ static void mmhub_v1_8_gart_disable(struct amdgpu_device
> *adev)
>                       WREG32_SOC15(MMHUB, j, regVM_L2_CNTL3, 0);
>               }
>       }
> +
> +     mmhub_v1_8_disable_l1_tlb(adev);
>  }
>
>  /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
> b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
> index cc621064610f..17f1ccd8bd53 100644
> --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
> @@ -858,6 +858,25 @@ static bool psp_v13_0_is_reload_needed(struct
> psp_context *psp)
>       return false;
>  }
>
> +static int psp_v13_0_reg_program_no_ring(struct psp_context *psp, uint32_t val,
> +                                      enum psp_reg_prog_id id)
> +{
> +     struct amdgpu_device *adev = psp->adev;
> +     int ret = -EOPNOTSUPP;
> +
> +     /* PSP will broadcast the value to all instances */
> +     if (amdgpu_sriov_vf(adev)) {
> +             WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_101,
> GFX_CTRL_CMD_ID_GBR_IH_SET);
> +             WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_102, id);
> +             WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_103, val);
> +
> +             ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0,
> regMP0_SMN_C2PMSG_101),
> +                                0x80000000, 0x80000000, false);
> +     }
> +
> +     return ret;
> +}
> +
>  static const struct psp_funcs psp_v13_0_funcs = {
>       .init_microcode = psp_v13_0_init_microcode,
>       .wait_for_bootloader = psp_v13_0_wait_for_bootloader_steady_state,
> @@ -884,6 +903,7 @@ static const struct psp_funcs psp_v13_0_funcs = {
>       .get_ras_capability = psp_v13_0_get_ras_capability,
>       .is_aux_sos_load_required = psp_v13_0_is_aux_sos_load_required,
>       .is_reload_needed = psp_v13_0_is_reload_needed,
> +     .reg_program_no_ring = psp_v13_0_reg_program_no_ring,
>  };
>
>  void psp_v13_0_set_psp_funcs(struct psp_context *psp)
> --
> 2.34.1



More information about the amd-gfx mailing list