Skip to content

Commit

Permalink
drm/amdgpu: Add indirect L1_TLB_CNTL reg programming for VFs
Browse files Browse the repository at this point in the history
VFs on some IP versions are unable to access this register directly.

This register must be programmed before PSP ring is setup,
so use PSP VF mailbox directly. PSP will broadcast the register
value to all VF assigned instances.

Signed-off-by: Victor Skvortsov <victor.skvortsov@amd.com>
Reviewed-by: Zhigang Luo <Zhigang.luo@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  • Loading branch information
Victor Skvortsov authored and Alex Deucher committed Apr 7, 2025
1 parent 4aa8de3 commit 0c6e39c
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 21 deletions.
10 changes: 10 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
12 changes: 9 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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))

Expand Down
9 changes: 5 additions & 4 deletions drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down
63 changes: 49 additions & 14 deletions drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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_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,
1);
Expand All @@ -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);
}
}
}

Expand Down Expand Up @@ -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_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;
Expand All @@ -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);
Expand All @@ -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);
}

/**
Expand Down
20 changes: 20 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand Down

0 comments on commit 0c6e39c

Please sign in to comment.