diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_bo.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bo.c | 114 |
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 | ||
463 | static int | 450 | static int |
464 | nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, | 451 | nouveau_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 | ||
498 | static int | 486 | static int |
499 | nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, | 487 | nouveau_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 | ||
581 | static int | 570 | static int |
582 | nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, | 571 | nouveau_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); |
609 | out: | 599 | out: |
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 | ||
619 | static int | 609 | static int |
620 | nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, | 610 | nouveau_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 | ||
707 | static int | 698 | static int |
708 | nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, | 699 | nouveau_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 | ||
750 | out: | 742 | out: |
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 | ||
757 | static int | ||
758 | nouveau_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 | |||
795 | static void | ||
796 | nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) | ||
797 | { | ||
798 | } | ||
799 | |||
800 | static int | ||
801 | nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) | ||
802 | { | ||
803 | return 0; | ||
804 | } | ||
805 | |||
765 | struct ttm_bo_driver nouveau_bo_driver = { | 806 | struct 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 | ||