aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-09-05 11:00:57 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-09-14 15:10:30 -0400
commitc855e25090cdafffb87119028eb018030a46dd9e (patch)
tree237c294ebfb71d5971e60f15cda0c007dd46d30b
parent71c76a086f04055e2da8d7d71c77e0b37ac310a2 (diff)
drm/amdgpu: bind GTT on demand
We don't really need the GTT table any more most of the time. So bind it only on demand. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Acked-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c34
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c33
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c3
8 files changed, 84 insertions, 7 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 717c3b4e1d54..2e8f469159c5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -2521,6 +2521,7 @@ static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { }
2521struct amdgpu_bo_va_mapping * 2521struct amdgpu_bo_va_mapping *
2522amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser, 2522amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
2523 uint64_t addr, struct amdgpu_bo **bo); 2523 uint64_t addr, struct amdgpu_bo **bo);
2524int amdgpu_cs_sysvm_access_required(struct amdgpu_cs_parser *parser);
2524 2525
2525#include "amdgpu_object.h" 2526#include "amdgpu_object.h"
2526#endif 2527#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 61b7e25535bf..f7dccb10d965 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -639,8 +639,12 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
639 } 639 }
640 } 640 }
641 641
642 if (p->uf_entry.robj) 642 if (!r && p->uf_entry.robj) {
643 p->job->uf_addr += amdgpu_bo_gpu_offset(p->uf_entry.robj); 643 struct amdgpu_bo *uf = p->uf_entry.robj;
644
645 r = amdgpu_ttm_bind(uf->tbo.ttm, &uf->tbo.mem);
646 p->job->uf_addr += amdgpu_bo_gpu_offset(uf);
647 }
644 648
645error_validate: 649error_validate:
646 if (r) { 650 if (r) {
@@ -1163,3 +1167,29 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
1163 1167
1164 return NULL; 1168 return NULL;
1165} 1169}
1170
1171/**
1172 * amdgpu_cs_sysvm_access_required - make BOs accessible by the system VM
1173 *
1174 * @parser: command submission parser context
1175 *
1176 * Helper for UVD/VCE VM emulation, make sure BOs are accessible by the system VM.
1177 */
1178int amdgpu_cs_sysvm_access_required(struct amdgpu_cs_parser *parser)
1179{
1180 unsigned i;
1181 int r;
1182
1183 if (!parser->bo_list)
1184 return 0;
1185
1186 for (i = 0; i < parser->bo_list->num_entries; i++) {
1187 struct amdgpu_bo *bo = parser->bo_list->array[i].robj;
1188
1189 r = amdgpu_ttm_bind(bo->tbo.ttm, &bo->tbo.mem);
1190 if (unlikely(r))
1191 return r;
1192 }
1193
1194 return 0;
1195}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 162411bd8145..5a6216c9c007 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -675,6 +675,11 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
675 dev_err(bo->adev->dev, "%p pin failed\n", bo); 675 dev_err(bo->adev->dev, "%p pin failed\n", bo);
676 goto error; 676 goto error;
677 } 677 }
678 r = amdgpu_ttm_bind(bo->tbo.ttm, &bo->tbo.mem);
679 if (unlikely(r)) {
680 dev_err(bo->adev->dev, "%p bind failed\n", bo);
681 goto error;
682 }
678 683
679 bo->pin_count = 1; 684 bo->pin_count = 1;
680 if (gpu_addr != NULL) 685 if (gpu_addr != NULL)
@@ -947,6 +952,8 @@ void amdgpu_bo_fence(struct amdgpu_bo *bo, struct fence *fence,
947u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) 952u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
948{ 953{
949 WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM); 954 WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM);
955 WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_TT &&
956 !amdgpu_ttm_is_bound(bo->tbo.ttm));
950 WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) && 957 WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) &&
951 !bo->pin_count); 958 !bo->pin_count);
952 959
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index a4914b788517..73298fadd7f3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -256,8 +256,12 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
256 new_start = new_mem->start << PAGE_SHIFT; 256 new_start = new_mem->start << PAGE_SHIFT;
257 257
258 switch (old_mem->mem_type) { 258 switch (old_mem->mem_type) {
259 case TTM_PL_VRAM:
260 case TTM_PL_TT: 259 case TTM_PL_TT:
260 r = amdgpu_ttm_bind(bo->ttm, old_mem);
261 if (r)
262 return r;
263
264 case TTM_PL_VRAM:
261 old_start += bo->bdev->man[old_mem->mem_type].gpu_offset; 265 old_start += bo->bdev->man[old_mem->mem_type].gpu_offset;
262 break; 266 break;
263 default: 267 default:
@@ -265,8 +269,12 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
265 return -EINVAL; 269 return -EINVAL;
266 } 270 }
267 switch (new_mem->mem_type) { 271 switch (new_mem->mem_type) {
268 case TTM_PL_VRAM:
269 case TTM_PL_TT: 272 case TTM_PL_TT:
273 r = amdgpu_ttm_bind(bo->ttm, new_mem);
274 if (r)
275 return r;
276
277 case TTM_PL_VRAM:
270 new_start += bo->bdev->man[new_mem->mem_type].gpu_offset; 278 new_start += bo->bdev->man[new_mem->mem_type].gpu_offset;
271 break; 279 break;
272 default: 280 default:
@@ -638,7 +646,6 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
638 struct ttm_mem_reg *bo_mem) 646 struct ttm_mem_reg *bo_mem)
639{ 647{
640 struct amdgpu_ttm_tt *gtt = (void*)ttm; 648 struct amdgpu_ttm_tt *gtt = (void*)ttm;
641 uint32_t flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem);
642 int r; 649 int r;
643 650
644 if (gtt->userptr) { 651 if (gtt->userptr) {
@@ -659,6 +666,26 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
659 bo_mem->mem_type == AMDGPU_PL_OA) 666 bo_mem->mem_type == AMDGPU_PL_OA)
660 return -EINVAL; 667 return -EINVAL;
661 668
669 return 0;
670}
671
672bool amdgpu_ttm_is_bound(struct ttm_tt *ttm)
673{
674 struct amdgpu_ttm_tt *gtt = (void *)ttm;
675
676 return gtt && !list_empty(&gtt->list);
677}
678
679int amdgpu_ttm_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
680{
681 struct amdgpu_ttm_tt *gtt = (void *)ttm;
682 uint32_t flags;
683 int r;
684
685 if (!ttm || amdgpu_ttm_is_bound(ttm))
686 return 0;
687
688 flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem);
662 r = amdgpu_gart_bind(gtt->adev, gtt->offset, ttm->num_pages, 689 r = amdgpu_gart_bind(gtt->adev, gtt->offset, ttm->num_pages,
663 ttm->pages, gtt->ttm.dma_address, flags); 690 ttm->pages, gtt->ttm.dma_address, flags);
664 691
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index 72f6bfc15d8f..214bae965fc6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -77,4 +77,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
77 struct fence **fence); 77 struct fence **fence);
78 78
79int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma); 79int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma);
80bool amdgpu_ttm_is_bound(struct ttm_tt *ttm);
81int amdgpu_ttm_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem);
82
80#endif 83#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index a71efeb5083b..25dd58a65905 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -882,6 +882,10 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx)
882 return -EINVAL; 882 return -EINVAL;
883 } 883 }
884 884
885 r = amdgpu_cs_sysvm_access_required(parser);
886 if (r)
887 return r;
888
885 ctx.parser = parser; 889 ctx.parser = parser;
886 ctx.buf_sizes = buf_sizes; 890 ctx.buf_sizes = buf_sizes;
887 ctx.ib_idx = ib_idx; 891 ctx.ib_idx = ib_idx;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index 9b71d6c2a968..b0c670294e2f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -634,7 +634,11 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
634 uint32_t allocated = 0; 634 uint32_t allocated = 0;
635 uint32_t tmp, handle = 0; 635 uint32_t tmp, handle = 0;
636 uint32_t *size = &tmp; 636 uint32_t *size = &tmp;
637 int i, r = 0, idx = 0; 637 int i, r, idx = 0;
638
639 r = amdgpu_cs_sysvm_access_required(p);
640 if (r)
641 return r;
638 642
639 while (idx < ib->length_dw) { 643 while (idx < ib->length_dw) {
640 uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx); 644 uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index bf56f1814437..bd5af328154f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -1163,7 +1163,8 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
1163 } 1163 }
1164 1164
1165 flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem); 1165 flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem);
1166 gtt_flags = (adev == bo_va->bo->adev) ? flags : 0; 1166 gtt_flags = (amdgpu_ttm_is_bound(bo_va->bo->tbo.ttm) &&
1167 adev == bo_va->bo->adev) ? flags : 0;
1167 1168
1168 spin_lock(&vm->status_lock); 1169 spin_lock(&vm->status_lock);
1169 if (!list_empty(&bo_va->vm_status)) 1170 if (!list_empty(&bo_va->vm_status))