diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_cs.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_cs.c | 83 |
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 @@ | |||
32 | void r100_cs_dump_packet(struct radeon_cs_parser *p, | 32 | void r100_cs_dump_packet(struct radeon_cs_parser *p, |
33 | struct radeon_cs_packet *pkt); | 33 | struct radeon_cs_packet *pkt); |
34 | 34 | ||
35 | int radeon_cs_parser_relocs(struct radeon_cs_parser *p) | 35 | static 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 | ||
118 | static 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 | |||
118 | static void radeon_cs_sync_rings(struct radeon_cs_parser *p) | 130 | static 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 | ||
281 | static 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, | |||
391 | static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser, | 372 | static 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 | ||
499 | out: | ||
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 | |||
480 | out: | ||
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; |