[PATCH 05/10] drm/amdgpu: shadow gart table support
Chunming Zhou
David1.Zhou at amd.com
Tue Aug 2 08:00:35 UTC 2016
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
More information about the amd-gfx
mailing list