aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_cs.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c83
1 files changed, 29 insertions, 54 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index 891fff52ab65..cb7b7c062fef 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -32,7 +32,7 @@
32void r100_cs_dump_packet(struct radeon_cs_parser *p, 32void r100_cs_dump_packet(struct radeon_cs_parser *p,
33 struct radeon_cs_packet *pkt); 33 struct radeon_cs_packet *pkt);
34 34
35int radeon_cs_parser_relocs(struct radeon_cs_parser *p) 35static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
36{ 36{
37 struct drm_device *ddev = p->rdev->ddev; 37 struct drm_device *ddev = p->rdev->ddev;
38 struct radeon_cs_chunk *chunk; 38 struct radeon_cs_chunk *chunk;
@@ -115,19 +115,27 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority
115 return 0; 115 return 0;
116} 116}
117 117
118static void radeon_cs_sync_to(struct radeon_cs_parser *p,
119 struct radeon_fence *fence)
120{
121 struct radeon_fence *other;
122
123 if (!fence)
124 return;
125
126 other = p->ib.sync_to[fence->ring];
127 p->ib.sync_to[fence->ring] = radeon_fence_later(fence, other);
128}
129
118static void radeon_cs_sync_rings(struct radeon_cs_parser *p) 130static void radeon_cs_sync_rings(struct radeon_cs_parser *p)
119{ 131{
120 int i; 132 int i;
121 133
122 for (i = 0; i < p->nrelocs; i++) { 134 for (i = 0; i < p->nrelocs; i++) {
123 struct radeon_fence *a, *b; 135 if (!p->relocs[i].robj)
124
125 if (!p->relocs[i].robj || !p->relocs[i].robj->tbo.sync_obj)
126 continue; 136 continue;
127 137
128 a = p->relocs[i].robj->tbo.sync_obj; 138 radeon_cs_sync_to(p, p->relocs[i].robj->tbo.sync_obj);
129 b = p->ib.sync_to[a->ring];
130 p->ib.sync_to[a->ring] = radeon_fence_later(a, b);
131 } 139 }
132} 140}
133 141
@@ -278,30 +286,6 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
278 return 0; 286 return 0;
279} 287}
280 288
281static void radeon_bo_vm_fence_va(struct radeon_cs_parser *parser,
282 struct radeon_fence *fence)
283{
284 struct radeon_fpriv *fpriv = parser->filp->driver_priv;
285 struct radeon_vm *vm = &fpriv->vm;
286 struct radeon_bo_list *lobj;
287
288 if (parser->chunk_ib_idx == -1) {
289 return;
290 }
291 if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) {
292 return;
293 }
294
295 list_for_each_entry(lobj, &parser->validated, tv.head) {
296 struct radeon_bo_va *bo_va;
297 struct radeon_bo *rbo = lobj->bo;
298
299 bo_va = radeon_bo_va(rbo, vm);
300 radeon_fence_unref(&bo_va->fence);
301 bo_va->fence = radeon_fence_ref(fence);
302 }
303}
304
305/** 289/**
306 * cs_parser_fini() - clean parser states 290 * cs_parser_fini() - clean parser states
307 * @parser: parser structure holding parsing context. 291 * @parser: parser structure holding parsing context.
@@ -315,8 +299,6 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
315 unsigned i; 299 unsigned i;
316 300
317 if (!error) { 301 if (!error) {
318 /* fence all bo va before ttm_eu_fence_buffer_objects so bo are still reserved */
319 radeon_bo_vm_fence_va(parser, parser->ib.fence);
320 ttm_eu_fence_buffer_objects(&parser->validated, 302 ttm_eu_fence_buffer_objects(&parser->validated,
321 parser->ib.fence); 303 parser->ib.fence);
322 } else { 304 } else {
@@ -363,7 +345,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
363 * uncached). 345 * uncached).
364 */ 346 */
365 r = radeon_ib_get(rdev, parser->ring, &parser->ib, 347 r = radeon_ib_get(rdev, parser->ring, &parser->ib,
366 ib_chunk->length_dw * 4); 348 NULL, ib_chunk->length_dw * 4);
367 if (r) { 349 if (r) {
368 DRM_ERROR("Failed to get ib !\n"); 350 DRM_ERROR("Failed to get ib !\n");
369 return r; 351 return r;
@@ -380,7 +362,6 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
380 return r; 362 return r;
381 } 363 }
382 radeon_cs_sync_rings(parser); 364 radeon_cs_sync_rings(parser);
383 parser->ib.vm_id = 0;
384 r = radeon_ib_schedule(rdev, &parser->ib, NULL); 365 r = radeon_ib_schedule(rdev, &parser->ib, NULL);
385 if (r) { 366 if (r) {
386 DRM_ERROR("Failed to schedule IB !\n"); 367 DRM_ERROR("Failed to schedule IB !\n");
@@ -391,10 +372,15 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
391static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser, 372static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser,
392 struct radeon_vm *vm) 373 struct radeon_vm *vm)
393{ 374{
375 struct radeon_device *rdev = parser->rdev;
394 struct radeon_bo_list *lobj; 376 struct radeon_bo_list *lobj;
395 struct radeon_bo *bo; 377 struct radeon_bo *bo;
396 int r; 378 int r;
397 379
380 r = radeon_vm_bo_update_pte(rdev, vm, rdev->ring_tmp_bo.bo, &rdev->ring_tmp_bo.bo->tbo.mem);
381 if (r) {
382 return r;
383 }
398 list_for_each_entry(lobj, &parser->validated, tv.head) { 384 list_for_each_entry(lobj, &parser->validated, tv.head) {
399 bo = lobj->bo; 385 bo = lobj->bo;
400 r = radeon_vm_bo_update_pte(parser->rdev, vm, bo, &bo->tbo.mem); 386 r = radeon_vm_bo_update_pte(parser->rdev, vm, bo, &bo->tbo.mem);
@@ -426,7 +412,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
426 return -EINVAL; 412 return -EINVAL;
427 } 413 }
428 r = radeon_ib_get(rdev, parser->ring, &parser->const_ib, 414 r = radeon_ib_get(rdev, parser->ring, &parser->const_ib,
429 ib_chunk->length_dw * 4); 415 vm, ib_chunk->length_dw * 4);
430 if (r) { 416 if (r) {
431 DRM_ERROR("Failed to get const ib !\n"); 417 DRM_ERROR("Failed to get const ib !\n");
432 return r; 418 return r;
@@ -450,7 +436,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
450 return -EINVAL; 436 return -EINVAL;
451 } 437 }
452 r = radeon_ib_get(rdev, parser->ring, &parser->ib, 438 r = radeon_ib_get(rdev, parser->ring, &parser->ib,
453 ib_chunk->length_dw * 4); 439 vm, ib_chunk->length_dw * 4);
454 if (r) { 440 if (r) {
455 DRM_ERROR("Failed to get ib !\n"); 441 DRM_ERROR("Failed to get ib !\n");
456 return r; 442 return r;
@@ -468,7 +454,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
468 454
469 mutex_lock(&rdev->vm_manager.lock); 455 mutex_lock(&rdev->vm_manager.lock);
470 mutex_lock(&vm->mutex); 456 mutex_lock(&vm->mutex);
471 r = radeon_vm_bind(rdev, vm); 457 r = radeon_vm_alloc_pt(rdev, vm);
472 if (r) { 458 if (r) {
473 goto out; 459 goto out;
474 } 460 }
@@ -477,32 +463,21 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
477 goto out; 463 goto out;
478 } 464 }
479 radeon_cs_sync_rings(parser); 465 radeon_cs_sync_rings(parser);
480 466 radeon_cs_sync_to(parser, vm->fence);
481 parser->ib.vm_id = vm->id; 467 radeon_cs_sync_to(parser, radeon_vm_grab_id(rdev, vm, parser->ring));
482 /* ib pool is bind at 0 in virtual address space,
483 * so gpu_addr is the offset inside the pool bo
484 */
485 parser->ib.gpu_addr = parser->ib.sa_bo->soffset;
486 468
487 if ((rdev->family >= CHIP_TAHITI) && 469 if ((rdev->family >= CHIP_TAHITI) &&
488 (parser->chunk_const_ib_idx != -1)) { 470 (parser->chunk_const_ib_idx != -1)) {
489 parser->const_ib.vm_id = vm->id;
490 /* ib pool is bind at 0 in virtual address space,
491 * so gpu_addr is the offset inside the pool bo
492 */
493 parser->const_ib.gpu_addr = parser->const_ib.sa_bo->soffset;
494 r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib); 471 r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib);
495 } else { 472 } else {
496 r = radeon_ib_schedule(rdev, &parser->ib, NULL); 473 r = radeon_ib_schedule(rdev, &parser->ib, NULL);
497 } 474 }
498 475
499out:
500 if (!r) { 476 if (!r) {
501 if (vm->fence) { 477 radeon_vm_fence(rdev, vm, parser->ib.fence);
502 radeon_fence_unref(&vm->fence);
503 }
504 vm->fence = radeon_fence_ref(parser->ib.fence);
505 } 478 }
479
480out:
506 mutex_unlock(&vm->mutex); 481 mutex_unlock(&vm->mutex);
507 mutex_unlock(&rdev->vm_manager.lock); 482 mutex_unlock(&rdev->vm_manager.lock);
508 return r; 483 return r;