[PATCH 2/5] drm/amdgpu/gmc9: add separate vmhub flush function
Xiangliang Yu
Xiangliang.Yu at amd.com
Sun Apr 9 12:30:58 UTC 2017
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
More information about the amd-gfx
mailing list