[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