aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_bo.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_bo.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c114
1 files changed, 79 insertions, 35 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 957d17629840..fb164efada3b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -225,7 +225,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
225 225
226 nouveau_bo_placement_set(nvbo, memtype, 0); 226 nouveau_bo_placement_set(nvbo, memtype, 0);
227 227
228 ret = ttm_bo_validate(bo, &nvbo->placement, false, false); 228 ret = ttm_bo_validate(bo, &nvbo->placement, false, false, false);
229 if (ret == 0) { 229 if (ret == 0) {
230 switch (bo->mem.mem_type) { 230 switch (bo->mem.mem_type) {
231 case TTM_PL_VRAM: 231 case TTM_PL_VRAM:
@@ -261,7 +261,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
261 261
262 nouveau_bo_placement_set(nvbo, bo->mem.placement, 0); 262 nouveau_bo_placement_set(nvbo, bo->mem.placement, 0);
263 263
264 ret = ttm_bo_validate(bo, &nvbo->placement, false, false); 264 ret = ttm_bo_validate(bo, &nvbo->placement, false, false, false);
265 if (ret == 0) { 265 if (ret == 0) {
266 switch (bo->mem.mem_type) { 266 switch (bo->mem.mem_type) {
267 case TTM_PL_VRAM: 267 case TTM_PL_VRAM:
@@ -391,25 +391,16 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
391 break; 391 break;
392 case TTM_PL_VRAM: 392 case TTM_PL_VRAM:
393 man->flags = TTM_MEMTYPE_FLAG_FIXED | 393 man->flags = TTM_MEMTYPE_FLAG_FIXED |
394 TTM_MEMTYPE_FLAG_MAPPABLE | 394 TTM_MEMTYPE_FLAG_MAPPABLE;
395 TTM_MEMTYPE_FLAG_NEEDS_IOREMAP;
396 man->available_caching = TTM_PL_FLAG_UNCACHED | 395 man->available_caching = TTM_PL_FLAG_UNCACHED |
397 TTM_PL_FLAG_WC; 396 TTM_PL_FLAG_WC;
398 man->default_caching = TTM_PL_FLAG_WC; 397 man->default_caching = TTM_PL_FLAG_WC;
399
400 man->io_addr = NULL;
401 man->io_offset = drm_get_resource_start(dev, 1);
402 man->io_size = drm_get_resource_len(dev, 1);
403 if (man->io_size > dev_priv->vram_size)
404 man->io_size = dev_priv->vram_size;
405
406 man->gpu_offset = dev_priv->vm_vram_base; 398 man->gpu_offset = dev_priv->vm_vram_base;
407 break; 399 break;
408 case TTM_PL_TT: 400 case TTM_PL_TT:
409 switch (dev_priv->gart_info.type) { 401 switch (dev_priv->gart_info.type) {
410 case NOUVEAU_GART_AGP: 402 case NOUVEAU_GART_AGP:
411 man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | 403 man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
412 TTM_MEMTYPE_FLAG_NEEDS_IOREMAP;
413 man->available_caching = TTM_PL_FLAG_UNCACHED; 404 man->available_caching = TTM_PL_FLAG_UNCACHED;
414 man->default_caching = TTM_PL_FLAG_UNCACHED; 405 man->default_caching = TTM_PL_FLAG_UNCACHED;
415 break; 406 break;
@@ -424,10 +415,6 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
424 dev_priv->gart_info.type); 415 dev_priv->gart_info.type);
425 return -EINVAL; 416 return -EINVAL;
426 } 417 }
427
428 man->io_offset = dev_priv->gart_info.aper_base;
429 man->io_size = dev_priv->gart_info.aper_size;
430 man->io_addr = NULL;
431 man->gpu_offset = dev_priv->vm_gart_base; 418 man->gpu_offset = dev_priv->vm_gart_base;
432 break; 419 break;
433 default: 420 default:
@@ -462,7 +449,8 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
462 449
463static int 450static int
464nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, 451nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan,
465 struct nouveau_bo *nvbo, bool evict, bool no_wait, 452 struct nouveau_bo *nvbo, bool evict,
453 bool no_wait_reserve, bool no_wait_gpu,
466 struct ttm_mem_reg *new_mem) 454 struct ttm_mem_reg *new_mem)
467{ 455{
468 struct nouveau_fence *fence = NULL; 456 struct nouveau_fence *fence = NULL;
@@ -473,7 +461,7 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan,
473 return ret; 461 return ret;
474 462
475 ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL, 463 ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL,
476 evict, no_wait, new_mem); 464 evict, no_wait_reserve, no_wait_gpu, new_mem);
477 if (nvbo->channel && nvbo->channel != chan) 465 if (nvbo->channel && nvbo->channel != chan)
478 ret = nouveau_fence_wait(fence, NULL, false, false); 466 ret = nouveau_fence_wait(fence, NULL, false, false);
479 nouveau_fence_unref((void *)&fence); 467 nouveau_fence_unref((void *)&fence);
@@ -497,7 +485,8 @@ nouveau_bo_mem_ctxdma(struct nouveau_bo *nvbo, struct nouveau_channel *chan,
497 485
498static int 486static int
499nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, 487nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
500 int no_wait, struct ttm_mem_reg *new_mem) 488 bool no_wait_reserve, bool no_wait_gpu,
489 struct ttm_mem_reg *new_mem)
501{ 490{
502 struct nouveau_bo *nvbo = nouveau_bo(bo); 491 struct nouveau_bo *nvbo = nouveau_bo(bo);
503 struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); 492 struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
@@ -575,12 +564,13 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
575 dst_offset += (PAGE_SIZE * line_count); 564 dst_offset += (PAGE_SIZE * line_count);
576 } 565 }
577 566
578 return nouveau_bo_move_accel_cleanup(chan, nvbo, evict, no_wait, new_mem); 567 return nouveau_bo_move_accel_cleanup(chan, nvbo, evict, no_wait_reserve, no_wait_gpu, new_mem);
579} 568}
580 569
581static int 570static int
582nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, 571nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr,
583 bool no_wait, struct ttm_mem_reg *new_mem) 572 bool no_wait_reserve, bool no_wait_gpu,
573 struct ttm_mem_reg *new_mem)
584{ 574{
585 u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; 575 u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
586 struct ttm_placement placement; 576 struct ttm_placement placement;
@@ -593,7 +583,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr,
593 583
594 tmp_mem = *new_mem; 584 tmp_mem = *new_mem;
595 tmp_mem.mm_node = NULL; 585 tmp_mem.mm_node = NULL;
596 ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, intr, no_wait); 586 ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, intr, no_wait_reserve, no_wait_gpu);
597 if (ret) 587 if (ret)
598 return ret; 588 return ret;
599 589
@@ -601,11 +591,11 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr,
601 if (ret) 591 if (ret)
602 goto out; 592 goto out;
603 593
604 ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait, &tmp_mem); 594 ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait_reserve, no_wait_gpu, &tmp_mem);
605 if (ret) 595 if (ret)
606 goto out; 596 goto out;
607 597
608 ret = ttm_bo_move_ttm(bo, evict, no_wait, new_mem); 598 ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, new_mem);
609out: 599out:
610 if (tmp_mem.mm_node) { 600 if (tmp_mem.mm_node) {
611 spin_lock(&bo->bdev->glob->lru_lock); 601 spin_lock(&bo->bdev->glob->lru_lock);
@@ -618,7 +608,8 @@ out:
618 608
619static int 609static int
620nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, 610nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr,
621 bool no_wait, struct ttm_mem_reg *new_mem) 611 bool no_wait_reserve, bool no_wait_gpu,
612 struct ttm_mem_reg *new_mem)
622{ 613{
623 u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; 614 u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
624 struct ttm_placement placement; 615 struct ttm_placement placement;
@@ -631,15 +622,15 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr,
631 622
632 tmp_mem = *new_mem; 623 tmp_mem = *new_mem;
633 tmp_mem.mm_node = NULL; 624 tmp_mem.mm_node = NULL;
634 ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, intr, no_wait); 625 ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, intr, no_wait_reserve, no_wait_gpu);
635 if (ret) 626 if (ret)
636 return ret; 627 return ret;
637 628
638 ret = ttm_bo_move_ttm(bo, evict, no_wait, &tmp_mem); 629 ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, &tmp_mem);
639 if (ret) 630 if (ret)
640 goto out; 631 goto out;
641 632
642 ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait, new_mem); 633 ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait_reserve, no_wait_gpu, new_mem);
643 if (ret) 634 if (ret)
644 goto out; 635 goto out;
645 636
@@ -706,7 +697,8 @@ nouveau_bo_vm_cleanup(struct ttm_buffer_object *bo,
706 697
707static int 698static int
708nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, 699nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
709 bool no_wait, struct ttm_mem_reg *new_mem) 700 bool no_wait_reserve, bool no_wait_gpu,
701 struct ttm_mem_reg *new_mem)
710{ 702{
711 struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); 703 struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
712 struct nouveau_bo *nvbo = nouveau_bo(bo); 704 struct nouveau_bo *nvbo = nouveau_bo(bo);
@@ -721,7 +713,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
721 /* Software copy if the card isn't up and running yet. */ 713 /* Software copy if the card isn't up and running yet. */
722 if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE || 714 if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE ||
723 !dev_priv->channel) { 715 !dev_priv->channel) {
724 ret = ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); 716 ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem);
725 goto out; 717 goto out;
726 } 718 }
727 719
@@ -735,17 +727,17 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
735 727
736 /* Hardware assisted copy. */ 728 /* Hardware assisted copy. */
737 if (new_mem->mem_type == TTM_PL_SYSTEM) 729 if (new_mem->mem_type == TTM_PL_SYSTEM)
738 ret = nouveau_bo_move_flipd(bo, evict, intr, no_wait, new_mem); 730 ret = nouveau_bo_move_flipd(bo, evict, intr, no_wait_reserve, no_wait_gpu, new_mem);
739 else if (old_mem->mem_type == TTM_PL_SYSTEM) 731 else if (old_mem->mem_type == TTM_PL_SYSTEM)
740 ret = nouveau_bo_move_flips(bo, evict, intr, no_wait, new_mem); 732 ret = nouveau_bo_move_flips(bo, evict, intr, no_wait_reserve, no_wait_gpu, new_mem);
741 else 733 else
742 ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait, new_mem); 734 ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait_reserve, no_wait_gpu, new_mem);
743 735
744 if (!ret) 736 if (!ret)
745 goto out; 737 goto out;
746 738
747 /* Fallback to software copy. */ 739 /* Fallback to software copy. */
748 ret = ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); 740 ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem);
749 741
750out: 742out:
751 if (ret) 743 if (ret)
@@ -762,6 +754,55 @@ nouveau_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
762 return 0; 754 return 0;
763} 755}
764 756
757static int
758nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
759{
760 struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
761 struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
762 struct drm_device *dev = dev_priv->dev;
763
764 mem->bus.addr = NULL;
765 mem->bus.offset = 0;
766 mem->bus.size = mem->num_pages << PAGE_SHIFT;
767 mem->bus.base = 0;
768 mem->bus.is_iomem = false;
769 if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
770 return -EINVAL;
771 switch (mem->mem_type) {
772 case TTM_PL_SYSTEM:
773 /* System memory */
774 return 0;
775 case TTM_PL_TT:
776#if __OS_HAS_AGP
777 if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) {
778 mem->bus.offset = mem->mm_node->start << PAGE_SHIFT;
779 mem->bus.base = dev_priv->gart_info.aper_base;
780 mem->bus.is_iomem = true;
781 }
782#endif
783 break;
784 case TTM_PL_VRAM:
785 mem->bus.offset = mem->mm_node->start << PAGE_SHIFT;
786 mem->bus.base = drm_get_resource_start(dev, 1);
787 mem->bus.is_iomem = true;
788 break;
789 default:
790 return -EINVAL;
791 }
792 return 0;
793}
794
795static void
796nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
797{
798}
799
800static int
801nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo)
802{
803 return 0;
804}
805
765struct ttm_bo_driver nouveau_bo_driver = { 806struct ttm_bo_driver nouveau_bo_driver = {
766 .create_ttm_backend_entry = nouveau_bo_create_ttm_backend_entry, 807 .create_ttm_backend_entry = nouveau_bo_create_ttm_backend_entry,
767 .invalidate_caches = nouveau_bo_invalidate_caches, 808 .invalidate_caches = nouveau_bo_invalidate_caches,
@@ -774,5 +815,8 @@ struct ttm_bo_driver nouveau_bo_driver = {
774 .sync_obj_flush = nouveau_fence_flush, 815 .sync_obj_flush = nouveau_fence_flush,
775 .sync_obj_unref = nouveau_fence_unref, 816 .sync_obj_unref = nouveau_fence_unref,
776 .sync_obj_ref = nouveau_fence_ref, 817 .sync_obj_ref = nouveau_fence_ref,
818 .fault_reserve_notify = &nouveau_ttm_fault_reserve_notify,
819 .io_mem_reserve = &nouveau_ttm_io_mem_reserve,
820 .io_mem_free = &nouveau_ttm_io_mem_free,
777}; 821};
778 822