aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-11-17 06:06:38 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-11-23 15:08:44 -0500
commitf29224a6197dc71a7f3c557f41ae56c58192c345 (patch)
tree488feb44c7e16a065ca1c355a74642c6bb036091 /drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
parent3b1c9036a678e917c2df6ed12cb96681b7dd92b4 (diff)
drm/amdgpu: fix amdgpu_fill_buffer (v2)
The mem start is relative to the domain in the address space, so this worked only when VRAM was mapped at offset 0. It also didn't handled multiple drm_mm_nodes for split VRAM. v2: rebase on dma_fence renaming Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c69
1 files changed, 48 insertions, 21 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 1821c05484d0..8f18b8ed2b3a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1382,28 +1382,40 @@ error_free:
1382} 1382}
1383 1383
1384int amdgpu_fill_buffer(struct amdgpu_bo *bo, 1384int amdgpu_fill_buffer(struct amdgpu_bo *bo,
1385 uint32_t src_data, 1385 uint32_t src_data,
1386 struct reservation_object *resv, 1386 struct reservation_object *resv,
1387 struct dma_fence **fence) 1387 struct dma_fence **fence)
1388{ 1388{
1389 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 1389 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
1390 struct amdgpu_job *job; 1390 uint32_t max_bytes = adev->mman.buffer_funcs->fill_max_bytes;
1391 struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; 1391 struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
1392 1392
1393 uint32_t max_bytes, byte_count; 1393 struct drm_mm_node *mm_node;
1394 uint64_t dst_offset; 1394 unsigned long num_pages;
1395 unsigned int num_loops, num_dw; 1395 unsigned int num_loops, num_dw;
1396 unsigned int i; 1396
1397 struct amdgpu_job *job;
1397 int r; 1398 int r;
1398 1399
1399 byte_count = bo->tbo.num_pages << PAGE_SHIFT; 1400 if (!ring->ready) {
1400 max_bytes = adev->mman.buffer_funcs->fill_max_bytes; 1401 DRM_ERROR("Trying to clear memory with ring turned off.\n");
1401 num_loops = DIV_ROUND_UP(byte_count, max_bytes); 1402 return -EINVAL;
1403 }
1404
1405 num_pages = bo->tbo.num_pages;
1406 mm_node = bo->tbo.mem.mm_node;
1407 num_loops = 0;
1408 while (num_pages) {
1409 uint32_t byte_count = mm_node->size << PAGE_SHIFT;
1410
1411 num_loops += DIV_ROUND_UP(byte_count, max_bytes);
1412 num_pages -= mm_node->size;
1413 ++mm_node;
1414 }
1402 num_dw = num_loops * adev->mman.buffer_funcs->fill_num_dw; 1415 num_dw = num_loops * adev->mman.buffer_funcs->fill_num_dw;
1403 1416
1404 /* for IB padding */ 1417 /* for IB padding */
1405 while (num_dw & 0x7) 1418 num_dw += 64;
1406 num_dw++;
1407 1419
1408 r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job); 1420 r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job);
1409 if (r) 1421 if (r)
@@ -1411,28 +1423,43 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
1411 1423
1412 if (resv) { 1424 if (resv) {
1413 r = amdgpu_sync_resv(adev, &job->sync, resv, 1425 r = amdgpu_sync_resv(adev, &job->sync, resv,
1414 AMDGPU_FENCE_OWNER_UNDEFINED); 1426 AMDGPU_FENCE_OWNER_UNDEFINED);
1415 if (r) { 1427 if (r) {
1416 DRM_ERROR("sync failed (%d).\n", r); 1428 DRM_ERROR("sync failed (%d).\n", r);
1417 goto error_free; 1429 goto error_free;
1418 } 1430 }
1419 } 1431 }
1420 1432
1421 dst_offset = bo->tbo.mem.start << PAGE_SHIFT; 1433 num_pages = bo->tbo.num_pages;
1422 for (i = 0; i < num_loops; i++) { 1434 mm_node = bo->tbo.mem.mm_node;
1423 uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
1424 1435
1425 amdgpu_emit_fill_buffer(adev, &job->ibs[0], src_data, 1436 while (num_pages) {
1426 dst_offset, cur_size_in_bytes); 1437 uint32_t byte_count = mm_node->size << PAGE_SHIFT;
1438 uint64_t dst_addr;
1427 1439
1428 dst_offset += cur_size_in_bytes; 1440 r = amdgpu_mm_node_addr(&bo->tbo, mm_node,
1429 byte_count -= cur_size_in_bytes; 1441 &bo->tbo.mem, &dst_addr);
1442 if (r)
1443 return r;
1444
1445 while (byte_count) {
1446 uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
1447
1448 amdgpu_emit_fill_buffer(adev, &job->ibs[0], src_data,
1449 dst_addr, cur_size_in_bytes);
1450
1451 dst_addr += cur_size_in_bytes;
1452 byte_count -= cur_size_in_bytes;
1453 }
1454
1455 num_pages -= mm_node->size;
1456 ++mm_node;
1430 } 1457 }
1431 1458
1432 amdgpu_ring_pad_ib(ring, &job->ibs[0]); 1459 amdgpu_ring_pad_ib(ring, &job->ibs[0]);
1433 WARN_ON(job->ibs[0].length_dw > num_dw); 1460 WARN_ON(job->ibs[0].length_dw > num_dw);
1434 r = amdgpu_job_submit(job, ring, &adev->mman.entity, 1461 r = amdgpu_job_submit(job, ring, &adev->mman.entity,
1435 AMDGPU_FENCE_OWNER_UNDEFINED, fence); 1462 AMDGPU_FENCE_OWNER_UNDEFINED, fence);
1436 if (r) 1463 if (r)
1437 goto error_free; 1464 goto error_free;
1438 1465