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

Change-Id: Ib2beae9cea1ad1314c57f0fcdcc254816f39b9b2
Signed-off-by: Chunming Zhou <david1.z...@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

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to