diff options
| author | Mark Brown <broonie@kernel.org> | 2020-12-28 17:20:00 +0300 | 
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2020-12-28 17:20:00 +0300 | 
| commit | 2ae6f64ce1ce304b502461fdfe0b96c8171ae2cc (patch) | |
| tree | 88e987c447daf2c29e2d4c15e58d1029b0cc78c2 /drivers/gpu/drm/ttm/ttm_bo_util.c | |
| parent | 3b66e4a8e58a85af3212c7117d7a29c9ef6679a2 (diff) | |
| parent | 5c8fe583cce542aa0b84adc939ce85293de36e5e (diff) | |
| download | linux-2ae6f64ce1ce304b502461fdfe0b96c8171ae2cc.tar.xz | |
Merge tag 'v5.11-rc1' into regulator-5.11
Linux 5.11-rc1
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_bo_util.c')
| -rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo_util.c | 175 | 
1 files changed, 96 insertions, 79 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index fb2a25f8408f..7ccb2295cac1 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -32,6 +32,7 @@  #include <drm/ttm/ttm_bo_driver.h>  #include <drm/ttm/ttm_placement.h>  #include <drm/drm_vma_manager.h> +#include <linux/dma-buf-map.h>  #include <linux/io.h>  #include <linux/highmem.h>  #include <linux/wait.h> @@ -45,53 +46,6 @@ struct ttm_transfer_obj {  	struct ttm_buffer_object *bo;  }; -void ttm_bo_free_old_node(struct ttm_buffer_object *bo) -{ -	ttm_resource_free(bo, &bo->mem); -} - -int ttm_bo_move_ttm(struct ttm_buffer_object *bo, -		   struct ttm_operation_ctx *ctx, -		    struct ttm_resource *new_mem) -{ -	struct ttm_tt *ttm = bo->ttm; -	struct ttm_resource *old_mem = &bo->mem; -	int ret; - -	if (old_mem->mem_type != TTM_PL_SYSTEM) { -		ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); - -		if (unlikely(ret != 0)) { -			if (ret != -ERESTARTSYS) -				pr_err("Failed to expire sync object before unbinding TTM\n"); -			return ret; -		} - -		ttm_bo_tt_unbind(bo); -		ttm_bo_free_old_node(bo); -		old_mem->mem_type = TTM_PL_SYSTEM; -	} - -	ret = ttm_tt_set_placement_caching(ttm, new_mem->placement); -	if (unlikely(ret != 0)) -		return ret; - -	if (new_mem->mem_type != TTM_PL_SYSTEM) { - -		ret = ttm_tt_populate(bo->bdev, ttm, ctx); -		if (unlikely(ret != 0)) -			return ret; - -		ret = ttm_bo_tt_bind(bo, new_mem); -		if (unlikely(ret != 0)) -			return ret; -	} - -	ttm_bo_assign_mem(bo, new_mem); -	return 0; -} -EXPORT_SYMBOL(ttm_bo_move_ttm); -  int ttm_mem_io_reserve(struct ttm_bo_device *bdev,  		       struct ttm_resource *mem)  { @@ -135,7 +89,7 @@ static int ttm_resource_ioremap(struct ttm_bo_device *bdev,  	} else {  		size_t bus_size = (size_t)mem->num_pages << PAGE_SHIFT; -		if (mem->placement & TTM_PL_FLAG_WC) +		if (mem->bus.caching == ttm_write_combined)  			addr = ioremap_wc(mem->bus.offset, bus_size);  		else  			addr = ioremap(mem->bus.offset, bus_size); @@ -227,11 +181,8 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,  	void *new_iomap;  	int ret;  	unsigned long i; -	unsigned long page; -	unsigned long add = 0; -	int dir; -	ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); +	ret = ttm_bo_wait_ctx(bo, ctx);  	if (ret)  		return ret; @@ -267,29 +218,17 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,  			goto out1;  	} -	add = 0; -	dir = 1; - -	if ((old_mem->mem_type == new_mem->mem_type) && -	    (new_mem->start < old_mem->start + old_mem->size)) { -		dir = -1; -		add = new_mem->num_pages - 1; -	} -  	for (i = 0; i < new_mem->num_pages; ++i) { -		page = i * dir + add;  		if (old_iomap == NULL) { -			pgprot_t prot = ttm_io_prot(old_mem->placement, -						    PAGE_KERNEL); -			ret = ttm_copy_ttm_io_page(ttm, new_iomap, page, +			pgprot_t prot = ttm_io_prot(bo, old_mem, PAGE_KERNEL); +			ret = ttm_copy_ttm_io_page(ttm, new_iomap, i,  						   prot);  		} else if (new_iomap == NULL) { -			pgprot_t prot = ttm_io_prot(new_mem->placement, -						    PAGE_KERNEL); -			ret = ttm_copy_io_ttm_page(ttm, old_iomap, page, +			pgprot_t prot = ttm_io_prot(bo, new_mem, PAGE_KERNEL); +			ret = ttm_copy_io_ttm_page(ttm, old_iomap, i,  						   prot);  		} else { -			ret = ttm_copy_io_page(new_iomap, old_iomap, page); +			ret = ttm_copy_io_page(new_iomap, old_iomap, i);  		}  		if (ret)  			goto out1; @@ -352,7 +291,6 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,  		return -ENOMEM;  	fbo->base = *bo; -	fbo->base.mem.placement |= TTM_PL_FLAG_NO_EVICT;  	ttm_bo_get(bo);  	fbo->bo = bo; @@ -372,6 +310,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,  	kref_init(&fbo->base.kref);  	fbo->base.destroy = &ttm_transfered_destroy;  	fbo->base.acc_size = 0; +	fbo->base.pin_count = 1;  	if (bo->type != ttm_bo_type_sg)  		fbo->base.base.resv = &fbo->base.base._resv; @@ -384,21 +323,28 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,  	return 0;  } -pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp) +pgprot_t ttm_io_prot(struct ttm_buffer_object *bo, struct ttm_resource *res, +		     pgprot_t tmp)  { +	struct ttm_resource_manager *man; +	enum ttm_caching caching; + +	man = ttm_manager_type(bo->bdev, res->mem_type); +	caching = man->use_tt ? bo->ttm->caching : res->bus.caching; +  	/* Cached mappings need no adjustment */ -	if (caching_flags & TTM_PL_FLAG_CACHED) +	if (caching == ttm_cached)  		return tmp;  #if defined(__i386__) || defined(__x86_64__) -	if (caching_flags & TTM_PL_FLAG_WC) +	if (caching == ttm_write_combined)  		tmp = pgprot_writecombine(tmp);  	else if (boot_cpu_data.x86 > 3)  		tmp = pgprot_noncached(tmp);  #endif  #if defined(__ia64__) || defined(__arm__) || defined(__aarch64__) || \      defined(__powerpc__) || defined(__mips__) -	if (caching_flags & TTM_PL_FLAG_WC) +	if (caching == ttm_write_combined)  		tmp = pgprot_writecombine(tmp);  	else  		tmp = pgprot_noncached(tmp); @@ -422,7 +368,7 @@ static int ttm_bo_ioremap(struct ttm_buffer_object *bo,  		map->virtual = (void *)(((u8 *)bo->mem.bus.addr) + offset);  	} else {  		map->bo_kmap_type = ttm_bo_map_iomap; -		if (mem->placement & TTM_PL_FLAG_WC) +		if (mem->bus.caching == ttm_write_combined)  			map->virtual = ioremap_wc(bo->mem.bus.offset + offset,  						  size);  		else @@ -452,7 +398,7 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,  	if (ret)  		return ret; -	if (num_pages == 1 && (mem->placement & TTM_PL_FLAG_CACHED)) { +	if (num_pages == 1 && ttm->caching == ttm_cached) {  		/*  		 * We're mapping a single page, and the desired  		 * page protection is consistent with the bo. @@ -466,7 +412,7 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,  		 * We need to use vmap to get the desired page protection  		 * or to make the buffer object look contiguous.  		 */ -		prot = ttm_io_prot(mem->placement, PAGE_KERNEL); +		prot = ttm_io_prot(bo, mem, PAGE_KERNEL);  		map->bo_kmap_type = ttm_bo_map_vmap;  		map->virtual = vmap(ttm->pages + start_page, num_pages,  				    0, prot); @@ -526,6 +472,77 @@ void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map)  }  EXPORT_SYMBOL(ttm_bo_kunmap); +int ttm_bo_vmap(struct ttm_buffer_object *bo, struct dma_buf_map *map) +{ +	struct ttm_resource *mem = &bo->mem; +	int ret; + +	ret = ttm_mem_io_reserve(bo->bdev, mem); +	if (ret) +		return ret; + +	if (mem->bus.is_iomem) { +		void __iomem *vaddr_iomem; +		size_t size = bo->num_pages << PAGE_SHIFT; + +		if (mem->bus.addr) +			vaddr_iomem = (void __iomem *)mem->bus.addr; +		else if (mem->bus.caching == ttm_write_combined) +			vaddr_iomem = ioremap_wc(mem->bus.offset, size); +		else +			vaddr_iomem = ioremap(mem->bus.offset, size); + +		if (!vaddr_iomem) +			return -ENOMEM; + +		dma_buf_map_set_vaddr_iomem(map, vaddr_iomem); + +	} else { +		struct ttm_operation_ctx ctx = { +			.interruptible = false, +			.no_wait_gpu = false +		}; +		struct ttm_tt *ttm = bo->ttm; +		pgprot_t prot; +		void *vaddr; + +		ret = ttm_tt_populate(bo->bdev, ttm, &ctx); +		if (ret) +			return ret; + +		/* +		 * We need to use vmap to get the desired page protection +		 * or to make the buffer object look contiguous. +		 */ +		prot = ttm_io_prot(bo, mem, PAGE_KERNEL); +		vaddr = vmap(ttm->pages, bo->num_pages, 0, prot); +		if (!vaddr) +			return -ENOMEM; + +		dma_buf_map_set_vaddr(map, vaddr); +	} + +	return 0; +} +EXPORT_SYMBOL(ttm_bo_vmap); + +void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct dma_buf_map *map) +{ +	struct ttm_resource *mem = &bo->mem; + +	if (dma_buf_map_is_null(map)) +		return; + +	if (!map->is_iomem) +		vunmap(map->vaddr); +	else if (!mem->bus.addr) +		iounmap(map->vaddr_iomem); +	dma_buf_map_clear(map); + +	ttm_mem_io_free(bo->bdev, &bo->mem); +} +EXPORT_SYMBOL(ttm_bo_vunmap); +  static int ttm_bo_wait_free_node(struct ttm_buffer_object *bo,  				 bool dst_use_tt)  { @@ -536,7 +553,7 @@ static int ttm_bo_wait_free_node(struct ttm_buffer_object *bo,  	if (!dst_use_tt)  		ttm_bo_tt_destroy(bo); -	ttm_bo_free_old_node(bo); +	ttm_resource_free(bo, &bo->mem);  	return 0;  } @@ -597,7 +614,7 @@ static void ttm_bo_move_pipeline_evict(struct ttm_buffer_object *bo,  	}  	spin_unlock(&from->move_lock); -	ttm_bo_free_old_node(bo); +	ttm_resource_free(bo, &bo->mem);  	dma_fence_put(bo->moving);  	bo->moving = dma_fence_get(fence);  | 
