Add separate vmhub flush function so that other components can reuse it. Signed-off-by: Xiangliang Yu <Xiangliang.Yu at amd.com> Signed-off-by: Frank Min <Frank.Min at amd.com> --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 77 +++++++++++++++++++++-------------- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h | 3 ++ 2 files changed, 49 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 3b045e0..63f7052 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -192,6 +192,49 @@ static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vm_id) return req; } +/* gmc_v9_0_flush_vmhub - flush a VMID in a VMHUB + * + * @adev: amdgpu_device pointer + * @hub: the VMHUB to flush + * @eng: the engine to use + * @vmid: vm instance to flush + * + * Flush the VMID in a VMHUB using the specified engine. + */ +void gmc_v9_0_flush_vmhub(struct amdgpu_device *adev, struct amdgpu_vmhub *hub, + unsigned eng, uint32_t vmid) +{ + u32 tmp; + unsigned j; + + tmp = gmc_v9_0_get_invalidate_req(vmid); + WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); + + /* Busy wait for ACK.*/ + for (j = 0; j < 100; j++) { + tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack + eng); + tmp &= 1 << vmid; + if (tmp) + break; + cpu_relax(); + } + if (j < 100) + return; + + /* Wait for ACK with a delay.*/ + for (j = 0; j < adev->usec_timeout; j++) { + tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack + eng); + tmp &= 1 << vmid; + if (tmp) + break; + udelay(1); + } + if (j < adev->usec_timeout) + return; + + DRM_ERROR("Timeout waiting for VM flush ACK!\n"); +} + /* * GART * VMID 0 is the physical GPU addresses as used by the kernel. @@ -212,43 +255,15 @@ static void gmc_v9_0_gart_flush_gpu_tlb(struct amdgpu_device *adev, { /* Use register 17 for GART */ const unsigned eng = 17; - unsigned i, j; + unsigned i; /* flush hdp cache */ nbio_v6_1_hdp_flush(adev); spin_lock(&adev->mc.invalidate_lock); - for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) { - struct amdgpu_vmhub *hub = &adev->vmhub[i]; - u32 tmp = gmc_v9_0_get_invalidate_req(vmid); - - WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); - - /* Busy wait for ACK.*/ - for (j = 0; j < 100; j++) { - tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack + eng); - tmp &= 1 << vmid; - if (tmp) - break; - cpu_relax(); - } - if (j < 100) - continue; - - /* Wait for ACK with a delay.*/ - for (j = 0; j < adev->usec_timeout; j++) { - tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack + eng); - tmp &= 1 << vmid; - if (tmp) - break; - udelay(1); - } - if (j < adev->usec_timeout) - continue; - - DRM_ERROR("Timeout waiting for VM flush ACK!\n"); - } + for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) + gmc_v9_0_flush_vmhub(adev, &adev->vmhub[i], eng, vmid); spin_unlock(&adev->mc.invalidate_lock); } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h index b030ca5..c89886c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h @@ -27,4 +27,7 @@ extern const struct amd_ip_funcs gmc_v9_0_ip_funcs; extern const struct amdgpu_ip_block_version gmc_v9_0_ip_block; +void gmc_v9_0_flush_vmhub(struct amdgpu_device *adev, struct amdgpu_vmhub *hub, + unsigned eng, uint32_t vmid); + #endif -- 2.7.4