[PATCH 05/10] drm/amdgpu: shadow gart table support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



allocate gart shadow bo, and using shadow bo to backup gart table.

Change-Id: Ib2beae9cea1ad1314c57f0fcdcc254816f39b9b2
Signed-off-by: Chunming Zhou <David1.Zhou at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h      |  3 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 47 +++++++++++++++++++++++++++++++-
 drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c    | 15 ++++++++++
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c    | 16 +++++++++++
 4 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 419a33b..2985578d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -638,6 +638,7 @@ struct amdgpu_gart {
 	dma_addr_t			table_addr;
 	struct amdgpu_bo		*robj;
 	void				*ptr;
+	void				*shadow_ptr;
 	unsigned			num_gpu_pages;
 	unsigned			num_cpu_pages;
 	unsigned			table_size;
@@ -655,6 +656,8 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev);
 void amdgpu_gart_table_vram_free(struct amdgpu_device *adev);
 int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev);
 void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev);
+int amdgpu_gart_table_vram_shadow_pin(struct amdgpu_device *adev);
+void amdgpu_gart_table_vram_shadow_unpin(struct amdgpu_device *adev);
 int amdgpu_gart_init(struct amdgpu_device *adev);
 void amdgpu_gart_fini(struct amdgpu_device *adev);
 int amdgpu_gart_late_init(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
index c1f226b..b306684 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
@@ -248,6 +248,9 @@ void amdgpu_gart_unbind(struct amdgpu_device *adev, unsigned offset,
 		for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) {
 			amdgpu_gart_set_pte_pde(adev, adev->gart.ptr,
 						t, page_base, flags);
+			if (amdgpu_vm_need_backup(adev) && adev->gart.robj->shadow)
+				amdgpu_gart_set_pte_pde(adev, adev->gart.shadow_ptr,
+							t, page_base, flags);
 			page_base += AMDGPU_GPU_PAGE_SIZE;
 		}
 	}
@@ -293,6 +296,9 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, unsigned offset,
 			page_base = dma_addr[i];
 			for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) {
 				amdgpu_gart_set_pte_pde(adev, adev->gart.ptr, t, page_base, flags);
+				if (amdgpu_vm_need_backup(adev) && adev->gart.robj->shadow)
+					amdgpu_gart_set_pte_pde(adev, adev->gart.shadow_ptr,
+								t, page_base, flags);
 				page_base += AMDGPU_GPU_PAGE_SIZE;
 			}
 		}
@@ -364,6 +370,46 @@ void amdgpu_gart_fini(struct amdgpu_device *adev)
 	amdgpu_dummy_page_fini(adev);
 }
 
+int amdgpu_gart_table_vram_shadow_pin(struct amdgpu_device *adev)
+{
+	uint64_t gpu_addr;
+	int r;
+
+	if (!adev->gart.robj->shadow)
+		return -EINVAL;
+
+	r = amdgpu_bo_reserve(adev->gart.robj->shadow, false);
+	if (unlikely(r != 0))
+		return r;
+	r = amdgpu_bo_pin(adev->gart.robj->shadow,
+				AMDGPU_GEM_DOMAIN_GTT, &gpu_addr);
+	if (r) {
+		amdgpu_bo_unreserve(adev->gart.robj->shadow);
+		return r;
+	}
+	r = amdgpu_bo_kmap(adev->gart.robj->shadow, &adev->gart.shadow_ptr);
+	if (r)
+		amdgpu_bo_unpin(adev->gart.robj->shadow);
+	amdgpu_bo_unreserve(adev->gart.robj->shadow);
+	return r;
+}
+
+void amdgpu_gart_table_vram_shadow_unpin(struct amdgpu_device *adev)
+{
+	int r;
+
+	if (adev->gart.robj->shadow == NULL)
+		return;
+
+	r = amdgpu_bo_reserve(adev->gart.robj->shadow, false);
+	if (likely(r == 0)) {
+		amdgpu_bo_kunmap(adev->gart.robj->shadow);
+		amdgpu_bo_unpin(adev->gart.robj->shadow);
+		amdgpu_bo_unreserve(adev->gart.robj->shadow);
+		adev->gart.shadow_ptr = NULL;
+	}
+}
+
 int amdgpu_gart_late_init(struct amdgpu_device *adev)
 {
 	struct amd_sched_rq *rq;
@@ -372,7 +418,6 @@ int amdgpu_gart_late_init(struct amdgpu_device *adev)
 	rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_RECOVER];
 	return amd_sched_entity_init(&ring->sched, &adev->gart.recover_entity,
 				     rq, amdgpu_sched_jobs);
-
 }
 
 void amdgpu_gart_late_fini(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index 0771c04..5470a28 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -589,7 +589,21 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
 		 (unsigned)(adev->mc.gtt_size >> 20),
 		 (unsigned long long)adev->gart.table_addr);
 	adev->gart.ready = true;
+	if (amdgpu_vm_need_backup(adev) && adev->gart.robj) {
+		r = amdgpu_bo_create_shadow(adev, adev->gart.table_size,
+					    PAGE_SIZE, adev->gart.robj);
+		if (r)
+			goto err;
+		r = amdgpu_gart_table_vram_shadow_pin(adev);
+		if (r)
+			goto err;
+	}
+
 	return 0;
+err:
+	amdgpu_gart_table_vram_unpin(adev);
+
+	return r;
 }
 
 static int gmc_v7_0_gart_init(struct amdgpu_device *adev)
@@ -634,6 +648,7 @@ static void gmc_v7_0_gart_disable(struct amdgpu_device *adev)
 	WREG32(mmVM_L2_CNTL, tmp);
 	WREG32(mmVM_L2_CNTL2, 0);
 	amdgpu_gart_table_vram_unpin(adev);
+	amdgpu_gart_table_vram_shadow_unpin(adev);
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index c26bee9..6c2b5de 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -704,7 +704,22 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
 		 (unsigned)(adev->mc.gtt_size >> 20),
 		 (unsigned long long)adev->gart.table_addr);
 	adev->gart.ready = true;
+
+	if (amdgpu_vm_need_backup(adev) && adev->gart.robj) {
+		r = amdgpu_bo_create_shadow(adev, adev->gart.table_size,
+					    PAGE_SIZE, adev->gart.robj);
+		if (r)
+			goto err;
+		r = amdgpu_gart_table_vram_shadow_pin(adev);
+		if (r)
+			goto err;
+	}
+
 	return 0;
+err:
+	amdgpu_gart_table_vram_unpin(adev);
+
+	return r;
 }
 
 static int gmc_v8_0_gart_init(struct amdgpu_device *adev)
@@ -749,6 +764,7 @@ static void gmc_v8_0_gart_disable(struct amdgpu_device *adev)
 	WREG32(mmVM_L2_CNTL, tmp);
 	WREG32(mmVM_L2_CNTL2, 0);
 	amdgpu_gart_table_vram_unpin(adev);
+	amdgpu_gart_table_vram_shadow_unpin(adev);
 }
 
 /**
-- 
1.9.1



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux