aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
diff options
context:
space:
mode:
authorChunming Zhou <david1.zhou@amd.com>2015-08-25 05:23:45 -0400
committerAlex Deucher <alexander.deucher@amd.com>2015-08-26 17:50:42 -0400
commitc7ae72c01be10f539f385f624713f8ba0aa11a8f (patch)
treec523633396afdeede8a47c386436bf0dd4e541ac /drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
parent113cd9dacbad4906e1c8db09233b9fdcb002f80d (diff)
drm/amdgpu: use IB for copy buffer of eviction
This aids handling buffers moves with the scheduler. Signed-off-by: Chunming Zhou <david1.zhou@amd.com> Reviewed-by: Christian K?nig <christian.koenig@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c77
1 files changed, 40 insertions, 37 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 4cb81320b045..399143541d8a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -228,7 +228,7 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
228 struct amdgpu_device *adev; 228 struct amdgpu_device *adev;
229 struct amdgpu_ring *ring; 229 struct amdgpu_ring *ring;
230 uint64_t old_start, new_start; 230 uint64_t old_start, new_start;
231 struct amdgpu_fence *fence; 231 struct fence *fence;
232 int r; 232 int r;
233 233
234 adev = amdgpu_get_adev(bo->bdev); 234 adev = amdgpu_get_adev(bo->bdev);
@@ -269,9 +269,9 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
269 new_mem->num_pages * PAGE_SIZE, /* bytes */ 269 new_mem->num_pages * PAGE_SIZE, /* bytes */
270 bo->resv, &fence); 270 bo->resv, &fence);
271 /* FIXME: handle copy error */ 271 /* FIXME: handle copy error */
272 r = ttm_bo_move_accel_cleanup(bo, &fence->base, 272 r = ttm_bo_move_accel_cleanup(bo, fence,
273 evict, no_wait_gpu, new_mem); 273 evict, no_wait_gpu, new_mem);
274 amdgpu_fence_unref(&fence); 274 fence_put(fence);
275 return r; 275 return r;
276} 276}
277 277
@@ -987,52 +987,48 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring,
987 uint64_t dst_offset, 987 uint64_t dst_offset,
988 uint32_t byte_count, 988 uint32_t byte_count,
989 struct reservation_object *resv, 989 struct reservation_object *resv,
990 struct amdgpu_fence **fence) 990 struct fence **fence)
991{ 991{
992 struct amdgpu_device *adev = ring->adev; 992 struct amdgpu_device *adev = ring->adev;
993 struct amdgpu_sync sync;
994 uint32_t max_bytes; 993 uint32_t max_bytes;
995 unsigned num_loops, num_dw; 994 unsigned num_loops, num_dw;
995 struct amdgpu_ib *ib;
996 unsigned i; 996 unsigned i;
997 int r; 997 int r;
998 998
999 /* sync other rings */
1000 amdgpu_sync_create(&sync);
1001 if (resv) {
1002 r = amdgpu_sync_resv(adev, &sync, resv, false);
1003 if (r) {
1004 DRM_ERROR("sync failed (%d).\n", r);
1005 amdgpu_sync_free(adev, &sync, NULL);
1006 return r;
1007 }
1008 }
1009
1010 max_bytes = adev->mman.buffer_funcs->copy_max_bytes; 999 max_bytes = adev->mman.buffer_funcs->copy_max_bytes;
1011 num_loops = DIV_ROUND_UP(byte_count, max_bytes); 1000 num_loops = DIV_ROUND_UP(byte_count, max_bytes);
1012 num_dw = num_loops * adev->mman.buffer_funcs->copy_num_dw; 1001 num_dw = num_loops * adev->mman.buffer_funcs->copy_num_dw;
1013 1002
1014 /* for fence and sync */ 1003 /* for IB padding */
1015 num_dw += 64 + AMDGPU_NUM_SYNCS * 8; 1004 while (num_dw & 0x7)
1005 num_dw++;
1006
1007 ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL);
1008 if (!ib)
1009 return -ENOMEM;
1016 1010
1017 r = amdgpu_sync_wait(&sync); 1011 r = amdgpu_ib_get(ring, NULL, num_dw * 4, ib);
1018 if (r) { 1012 if (r) {
1019 DRM_ERROR("sync wait failed (%d).\n", r); 1013 kfree(ib);
1020 amdgpu_sync_free(adev, &sync, NULL);
1021 return r; 1014 return r;
1022 } 1015 }
1023 1016
1024 r = amdgpu_ring_lock(ring, num_dw); 1017 ib->length_dw = 0;
1025 if (r) { 1018
1026 DRM_ERROR("ring lock failed (%d).\n", r); 1019 if (resv) {
1027 amdgpu_sync_free(adev, &sync, NULL); 1020 r = amdgpu_sync_resv(adev, &ib->sync, resv,
1028 return r; 1021 AMDGPU_FENCE_OWNER_UNDEFINED);
1022 if (r) {
1023 DRM_ERROR("sync failed (%d).\n", r);
1024 goto error_free;
1025 }
1029 } 1026 }
1030 amdgpu_sync_rings(&sync, ring);
1031 1027
1032 for (i = 0; i < num_loops; i++) { 1028 for (i = 0; i < num_loops; i++) {
1033 uint32_t cur_size_in_bytes = min(byte_count, max_bytes); 1029 uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
1034 1030
1035 amdgpu_emit_copy_buffer(adev, ring, src_offset, dst_offset, 1031 amdgpu_emit_copy_buffer(adev, ib, src_offset, dst_offset,
1036 cur_size_in_bytes); 1032 cur_size_in_bytes);
1037 1033
1038 src_offset += cur_size_in_bytes; 1034 src_offset += cur_size_in_bytes;
@@ -1040,17 +1036,24 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring,
1040 byte_count -= cur_size_in_bytes; 1036 byte_count -= cur_size_in_bytes;
1041 } 1037 }
1042 1038
1043 r = amdgpu_fence_emit(ring, AMDGPU_FENCE_OWNER_MOVE, fence); 1039 amdgpu_vm_pad_ib(adev, ib);
1044 if (r) { 1040 WARN_ON(ib->length_dw > num_dw);
1045 amdgpu_ring_unlock_undo(ring); 1041 r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1,
1046 amdgpu_sync_free(adev, &sync, NULL); 1042 &amdgpu_vm_free_job,
1047 return r; 1043 AMDGPU_FENCE_OWNER_MOVE,
1048 } 1044 fence);
1049 1045 if (r)
1050 amdgpu_ring_unlock_commit(ring); 1046 goto error_free;
1051 amdgpu_sync_free(adev, &sync, &(*fence)->base);
1052 1047
1048 if (!amdgpu_enable_scheduler) {
1049 amdgpu_ib_free(adev, ib);
1050 kfree(ib);
1051 }
1053 return 0; 1052 return 0;
1053error_free:
1054 amdgpu_ib_free(adev, ib);
1055 kfree(ib);
1056 return r;
1054} 1057}
1055 1058
1056#if defined(CONFIG_DEBUG_FS) 1059#if defined(CONFIG_DEBUG_FS)