Each vmhub has it's own vmid to pasid mapping, but the code was assuming that a gfxhub vmid would also apply to mmhub and flushing mmhub using the gfxhub vmids.
Instead we need to find the vmid mapping for each hub individually and flush with that. Signed-off-by: Benjamin Cheng <[email protected]> --- drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c | 47 ++++++++++++++++---------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c index cd276a138e10..b6b815d939e3 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c @@ -200,10 +200,25 @@ static bool gmc_v12_0_use_invalidate_semaphore(struct amdgpu_device *adev, static bool gmc_v12_0_get_vmid_pasid_mapping_info( struct amdgpu_device *adev, - uint8_t vmid, uint16_t *p_pasid) + uint32_t vmhub, uint8_t vmid, + uint16_t *p_pasid) { - *p_pasid = RREG32(SOC15_REG_OFFSET(OSSSYS, 0, regIH_VMID_0_LUT) + vmid) & 0xffff; + int reg; + switch (vmhub) { + case AMDGPU_GFXHUB(0): + reg = SOC15_REG_OFFSET(OSSSYS, 0, regIH_VMID_0_LUT); + break; + case AMDGPU_MMHUB0(0): + reg = SOC15_REG_OFFSET(OSSSYS, 0, regIH_VMID_0_LUT_MM); + break; + default: + /* There shouldn't be any other VMHUB. */ + WARN_ON_ONCE(true); + return false; + } + + *p_pasid = RREG32(reg + vmid) & 0xffff; return !!(*p_pasid); } @@ -351,7 +366,7 @@ static void gmc_v12_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev, bool all_hub, uint32_t inst) { uint16_t queried; - int vmid, i; + int vmid, hub; if (adev->enable_uni_mes && adev->mes.ring[AMDGPU_MES_SCHED_PIPE].sched.ready && (adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x84) { @@ -369,22 +384,20 @@ static void gmc_v12_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev, return; } - for (vmid = 1; vmid < 16; vmid++) { - bool valid; - - valid = gmc_v12_0_get_vmid_pasid_mapping_info(adev, vmid, - &queried); - if (!valid || queried != pasid) + for_each_set_bit(hub, adev->vmhubs_mask, AMDGPU_MAX_VMHUBS) { + if (!all_hub && hub != AMDGPU_GFXHUB(0)) continue; - if (all_hub) { - for_each_set_bit(i, adev->vmhubs_mask, - AMDGPU_MAX_VMHUBS) - gmc_v12_0_flush_gpu_tlb(adev, vmid, i, - flush_type); - } else { - gmc_v12_0_flush_gpu_tlb(adev, vmid, AMDGPU_GFXHUB(0), - flush_type); + for (vmid = 1; vmid < 16; vmid++) { + bool valid; + + valid = gmc_v12_0_get_vmid_pasid_mapping_info(adev, hub, + vmid, + &queried); + if (!valid || queried != pasid) + continue; + + gmc_v12_0_flush_gpu_tlb(adev, vmid, hub, flush_type); } } } -- 2.55.0
