Home | History | Annotate | Line # | Download | only in ttm
      1 /*	$NetBSD: ttm_bo_util.c,v 1.28 2021/12/19 11:34:29 riastradh Exp $	*/
      2 
      3 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
      4 /**************************************************************************
      5  *
      6  * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
      7  * All Rights Reserved.
      8  *
      9  * Permission is hereby granted, free of charge, to any person obtaining a
     10  * copy of this software and associated documentation files (the
     11  * "Software"), to deal in the Software without restriction, including
     12  * without limitation the rights to use, copy, modify, merge, publish,
     13  * distribute, sub license, and/or sell copies of the Software, and to
     14  * permit persons to whom the Software is furnished to do so, subject to
     15  * the following conditions:
     16  *
     17  * The above copyright notice and this permission notice (including the
     18  * next paragraph) shall be included in all copies or substantial portions
     19  * of the Software.
     20  *
     21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     23  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     24  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
     25  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     26  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     27  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     28  *
     29  **************************************************************************/
     30 /*
     31  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
     32  */
     33 
     34 #include <sys/cdefs.h>
     35 __KERNEL_RCSID(0, "$NetBSD: ttm_bo_util.c,v 1.28 2021/12/19 11:34:29 riastradh Exp $");
     36 
     37 #include <drm/ttm/ttm_bo_driver.h>
     38 #include <drm/ttm/ttm_placement.h>
     39 #include <drm/drm_vma_manager.h>
     40 #include <linux/io.h>
     41 #include <linux/highmem.h>
     42 #include <linux/wait.h>
     43 #include <linux/slab.h>
     44 #include <linux/vmalloc.h>
     45 #include <linux/module.h>
     46 #include <linux/dma-resv.h>
     47 
     48 struct ttm_transfer_obj {
     49 	struct ttm_buffer_object base;
     50 	struct ttm_buffer_object *bo;
     51 };
     52 
     53 #ifdef __NetBSD__		/* PMAP_* caching flags for ttm_io_prot */
     54 #include <uvm/uvm_pmap.h>
     55 #include <linux/nbsd-namespace.h>
     56 #endif
     57 
     58 void ttm_bo_free_old_node(struct ttm_buffer_object *bo)
     59 {
     60 	ttm_bo_mem_put(bo, &bo->mem);
     61 }
     62 
     63 int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
     64 		   struct ttm_operation_ctx *ctx,
     65 		    struct ttm_mem_reg *new_mem)
     66 {
     67 	struct ttm_tt *ttm = bo->ttm;
     68 	struct ttm_mem_reg *old_mem = &bo->mem;
     69 	int ret;
     70 
     71 	if (old_mem->mem_type != TTM_PL_SYSTEM) {
     72 		ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu);
     73 
     74 		if (unlikely(ret != 0)) {
     75 			if (ret != -ERESTARTSYS)
     76 				pr_err("Failed to expire sync object before unbinding TTM\n");
     77 			return ret;
     78 		}
     79 
     80 		ttm_tt_unbind(ttm);
     81 		ttm_bo_free_old_node(bo);
     82 		ttm_flag_masked(&old_mem->placement, TTM_PL_FLAG_SYSTEM,
     83 				TTM_PL_MASK_MEM);
     84 		old_mem->mem_type = TTM_PL_SYSTEM;
     85 	}
     86 
     87 	ret = ttm_tt_set_placement_caching(ttm, new_mem->placement);
     88 	if (unlikely(ret != 0))
     89 		return ret;
     90 
     91 	if (new_mem->mem_type != TTM_PL_SYSTEM) {
     92 		ret = ttm_tt_bind(ttm, new_mem, ctx);
     93 		if (unlikely(ret != 0))
     94 			return ret;
     95 	}
     96 
     97 	*old_mem = *new_mem;
     98 	new_mem->mm_node = NULL;
     99 
    100 	return 0;
    101 }
    102 EXPORT_SYMBOL(ttm_bo_move_ttm);
    103 
    104 int ttm_mem_io_lock(struct ttm_mem_type_manager *man, bool interruptible)
    105 {
    106 	if (likely(man->io_reserve_fastpath))
    107 		return 0;
    108 
    109 	if (interruptible)
    110 		return mutex_lock_interruptible(&man->io_reserve_mutex);
    111 
    112 	mutex_lock(&man->io_reserve_mutex);
    113 	return 0;
    114 }
    115 
    116 void ttm_mem_io_unlock(struct ttm_mem_type_manager *man)
    117 {
    118 	if (likely(man->io_reserve_fastpath))
    119 		return;
    120 
    121 	mutex_unlock(&man->io_reserve_mutex);
    122 }
    123 
    124 static int ttm_mem_io_evict(struct ttm_mem_type_manager *man)
    125 {
    126 	struct ttm_buffer_object *bo;
    127 
    128 	if (!man->use_io_reserve_lru || list_empty(&man->io_reserve_lru))
    129 		return -EAGAIN;
    130 
    131 	bo = list_first_entry(&man->io_reserve_lru,
    132 			      struct ttm_buffer_object,
    133 			      io_reserve_lru);
    134 	list_del_init(&bo->io_reserve_lru);
    135 	ttm_bo_unmap_virtual_locked(bo);
    136 
    137 	return 0;
    138 }
    139 
    140 
    141 int ttm_mem_io_reserve(struct ttm_bo_device *bdev,
    142 		       struct ttm_mem_reg *mem)
    143 {
    144 	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
    145 	int ret = 0;
    146 
    147 	if (!bdev->driver->io_mem_reserve)
    148 		return 0;
    149 	if (likely(man->io_reserve_fastpath))
    150 		return bdev->driver->io_mem_reserve(bdev, mem);
    151 
    152 	if (bdev->driver->io_mem_reserve &&
    153 	    mem->bus.io_reserved_count++ == 0) {
    154 retry:
    155 		ret = bdev->driver->io_mem_reserve(bdev, mem);
    156 		if (ret == -EAGAIN) {
    157 			ret = ttm_mem_io_evict(man);
    158 			if (ret == 0)
    159 				goto retry;
    160 		}
    161 	}
    162 	return ret;
    163 }
    164 
    165 void ttm_mem_io_free(struct ttm_bo_device *bdev,
    166 		     struct ttm_mem_reg *mem)
    167 {
    168 	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
    169 
    170 	if (likely(man->io_reserve_fastpath))
    171 		return;
    172 
    173 	if (bdev->driver->io_mem_reserve &&
    174 	    --mem->bus.io_reserved_count == 0 &&
    175 	    bdev->driver->io_mem_free)
    176 		bdev->driver->io_mem_free(bdev, mem);
    177 
    178 }
    179 
    180 int ttm_mem_io_reserve_vm(struct ttm_buffer_object *bo)
    181 {
    182 	struct ttm_mem_reg *mem = &bo->mem;
    183 	int ret;
    184 
    185 	if (!mem->bus.io_reserved_vm) {
    186 		struct ttm_mem_type_manager *man =
    187 			&bo->bdev->man[mem->mem_type];
    188 
    189 		ret = ttm_mem_io_reserve(bo->bdev, mem);
    190 		if (unlikely(ret != 0))
    191 			return ret;
    192 		mem->bus.io_reserved_vm = true;
    193 		if (man->use_io_reserve_lru)
    194 			list_add_tail(&bo->io_reserve_lru,
    195 				      &man->io_reserve_lru);
    196 	}
    197 	return 0;
    198 }
    199 
    200 void ttm_mem_io_free_vm(struct ttm_buffer_object *bo)
    201 {
    202 	struct ttm_mem_reg *mem = &bo->mem;
    203 
    204 	if (mem->bus.io_reserved_vm) {
    205 		mem->bus.io_reserved_vm = false;
    206 		list_del_init(&bo->io_reserve_lru);
    207 		ttm_mem_io_free(bo->bdev, mem);
    208 	}
    209 }
    210 
    211 static int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem,
    212 			void **virtual)
    213 {
    214 	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
    215 	int ret;
    216 	void *addr;
    217 
    218 	*virtual = NULL;
    219 	(void) ttm_mem_io_lock(man, false);
    220 	ret = ttm_mem_io_reserve(bdev, mem);
    221 	ttm_mem_io_unlock(man);
    222 	if (ret || !mem->bus.is_iomem)
    223 		return ret;
    224 
    225 	if (mem->bus.addr) {
    226 		addr = mem->bus.addr;
    227 	} else {
    228 #ifdef __NetBSD__
    229 		const bus_addr_t bus_addr = (mem->bus.base + mem->bus.offset);
    230 		int flags = BUS_SPACE_MAP_LINEAR;
    231 
    232 		if (ISSET(mem->placement, TTM_PL_FLAG_WC))
    233 			flags |= BUS_SPACE_MAP_PREFETCHABLE;
    234 		/* XXX errno NetBSD->Linux */
    235 		ret = -bus_space_map(bdev->memt, bus_addr, mem->bus.size,
    236 		    flags, &mem->bus.memh);
    237 		if (ret) {
    238 			(void) ttm_mem_io_lock(man, false);
    239 			ttm_mem_io_free(bdev, mem);
    240 			ttm_mem_io_unlock(man);
    241 			return ret;
    242 		}
    243 		addr = bus_space_vaddr(bdev->memt, mem->bus.memh);
    244 #else
    245 		if (mem->placement & TTM_PL_FLAG_WC)
    246 			addr = ioremap_wc(mem->bus.base + mem->bus.offset, mem->bus.size);
    247 		else
    248 			addr = ioremap(mem->bus.base + mem->bus.offset, mem->bus.size);
    249 		if (!addr) {
    250 			(void) ttm_mem_io_lock(man, false);
    251 			ttm_mem_io_free(bdev, mem);
    252 			ttm_mem_io_unlock(man);
    253 			return -ENOMEM;
    254 		}
    255 #endif
    256 	}
    257 	*virtual = addr;
    258 	return 0;
    259 }
    260 
    261 static void ttm_mem_reg_iounmap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem,
    262 			 void *virtual)
    263 {
    264 	struct ttm_mem_type_manager *man;
    265 
    266 	man = &bdev->man[mem->mem_type];
    267 
    268 	if (virtual && mem->bus.addr == NULL)
    269 #ifdef __NetBSD__
    270 		bus_space_unmap(bdev->memt, mem->bus.memh, mem->bus.size);
    271 #else
    272 		iounmap(virtual);
    273 #endif
    274 	(void) ttm_mem_io_lock(man, false);
    275 	ttm_mem_io_free(bdev, mem);
    276 	ttm_mem_io_unlock(man);
    277 }
    278 
    279 #ifdef __NetBSD__
    280 #  define	ioread32	fake_ioread32
    281 #  define	iowrite32	fake_iowrite32
    282 
    283 static inline uint32_t
    284 ioread32(const volatile uint32_t *p)
    285 {
    286 	uint32_t v;
    287 
    288 	v = *p;
    289 	__insn_barrier();	/* XXX ttm io barrier */
    290 
    291 	return v;		/* XXX ttm byte order */
    292 }
    293 
    294 static inline void
    295 iowrite32(uint32_t v, volatile uint32_t *p)
    296 {
    297 
    298 	__insn_barrier();	/* XXX ttm io barrier */
    299 	*p = v;			/* XXX ttm byte order */
    300 }
    301 #endif
    302 
    303 static int ttm_copy_io_page(void *dst, void *src, unsigned long page)
    304 {
    305 	uint32_t *dstP =
    306 	    (uint32_t *) ((unsigned long)dst + (page << PAGE_SHIFT));
    307 	uint32_t *srcP =
    308 	    (uint32_t *) ((unsigned long)src + (page << PAGE_SHIFT));
    309 
    310 	int i;
    311 	for (i = 0; i < PAGE_SIZE / sizeof(uint32_t); ++i)
    312 		iowrite32(ioread32(srcP++), dstP++);
    313 	return 0;
    314 }
    315 
    316 #ifdef __NetBSD__
    317 #  undef	ioread32
    318 #  undef	iowrite32
    319 #endif
    320 
    321 #ifdef CONFIG_X86
    322 #define __ttm_kmap_atomic_prot(__page, __prot) kmap_atomic_prot(__page, __prot)
    323 #define __ttm_kunmap_atomic(__addr) kunmap_atomic(__addr)
    324 #else
    325 #define __ttm_kmap_atomic_prot(__page, __prot) vmap(&__page, 1, 0,  __prot)
    326 #define __ttm_kunmap_atomic(__addr) vunmap(__addr, 1)
    327 #endif
    328 
    329 
    330 /**
    331  * ttm_kmap_atomic_prot - Efficient kernel map of a single page with
    332  * specified page protection.
    333  *
    334  * @page: The page to map.
    335  * @prot: The page protection.
    336  *
    337  * This function maps a TTM page using the kmap_atomic api if available,
    338  * otherwise falls back to vmap. The user must make sure that the
    339  * specified page does not have an aliased mapping with a different caching
    340  * policy unless the architecture explicitly allows it. Also mapping and
    341  * unmapping using this api must be correctly nested. Unmapping should
    342  * occur in the reverse order of mapping.
    343  */
    344 void *ttm_kmap_atomic_prot(struct page *page, pgprot_t prot)
    345 {
    346 	if (pgprot_val(prot) == pgprot_val(PAGE_KERNEL))
    347 		return kmap_atomic(page);
    348 	else
    349 		return __ttm_kmap_atomic_prot(page, prot);
    350 }
    351 EXPORT_SYMBOL(ttm_kmap_atomic_prot);
    352 
    353 /**
    354  * ttm_kunmap_atomic_prot - Unmap a page that was mapped using
    355  * ttm_kmap_atomic_prot.
    356  *
    357  * @addr: The virtual address from the map.
    358  * @prot: The page protection.
    359  */
    360 void ttm_kunmap_atomic_prot(void *addr, pgprot_t prot)
    361 {
    362 	if (pgprot_val(prot) == pgprot_val(PAGE_KERNEL))
    363 		kunmap_atomic(addr);
    364 	else
    365 		__ttm_kunmap_atomic(addr);
    366 }
    367 EXPORT_SYMBOL(ttm_kunmap_atomic_prot);
    368 
    369 static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src,
    370 				unsigned long page,
    371 				pgprot_t prot)
    372 {
    373 	struct page *d = ttm->pages[page];
    374 	void *dst;
    375 
    376 	if (!d)
    377 		return -ENOMEM;
    378 
    379 	src = (void *)((unsigned long)src + (page << PAGE_SHIFT));
    380 	dst = ttm_kmap_atomic_prot(d, prot);
    381 	if (!dst)
    382 		return -ENOMEM;
    383 
    384 	memcpy_fromio(dst, src, PAGE_SIZE);
    385 
    386 	ttm_kunmap_atomic_prot(dst, prot);
    387 
    388 	return 0;
    389 }
    390 
    391 static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst,
    392 				unsigned long page,
    393 				pgprot_t prot)
    394 {
    395 	struct page *s = ttm->pages[page];
    396 	void *src;
    397 
    398 	if (!s)
    399 		return -ENOMEM;
    400 
    401 	dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT));
    402 	src = ttm_kmap_atomic_prot(s, prot);
    403 	if (!src)
    404 		return -ENOMEM;
    405 
    406 	memcpy_toio(dst, src, PAGE_SIZE);
    407 
    408 	ttm_kunmap_atomic_prot(src, prot);
    409 
    410 	return 0;
    411 }
    412 
    413 int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
    414 		       struct ttm_operation_ctx *ctx,
    415 		       struct ttm_mem_reg *new_mem)
    416 {
    417 	struct ttm_bo_device *bdev = bo->bdev;
    418 	struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
    419 	struct ttm_tt *ttm = bo->ttm;
    420 	struct ttm_mem_reg *old_mem = &bo->mem;
    421 	struct ttm_mem_reg old_copy = *old_mem;
    422 	void *old_iomap;
    423 	void *new_iomap;
    424 	int ret;
    425 	unsigned long i;
    426 	unsigned long page;
    427 	unsigned long add = 0;
    428 	int dir;
    429 
    430 	ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu);
    431 	if (ret)
    432 		return ret;
    433 
    434 	ret = ttm_mem_reg_ioremap(bdev, old_mem, &old_iomap);
    435 	if (ret)
    436 		return ret;
    437 	ret = ttm_mem_reg_ioremap(bdev, new_mem, &new_iomap);
    438 	if (ret)
    439 		goto out;
    440 
    441 	/*
    442 	 * Single TTM move. NOP.
    443 	 */
    444 	if (old_iomap == NULL && new_iomap == NULL)
    445 		goto out2;
    446 
    447 	/*
    448 	 * Don't move nonexistent data. Clear destination instead.
    449 	 */
    450 	if (old_iomap == NULL &&
    451 	    (ttm == NULL || (ttm->state == tt_unpopulated &&
    452 			     !(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)))) {
    453 		memset_io(new_iomap, 0, new_mem->num_pages*PAGE_SIZE);
    454 		goto out2;
    455 	}
    456 
    457 	/*
    458 	 * TTM might be null for moves within the same region.
    459 	 */
    460 	if (ttm) {
    461 		ret = ttm_tt_populate(ttm, ctx);
    462 		if (ret)
    463 			goto out1;
    464 	}
    465 
    466 	add = 0;
    467 	dir = 1;
    468 
    469 	if ((old_mem->mem_type == new_mem->mem_type) &&
    470 	    (new_mem->start < old_mem->start + old_mem->size)) {
    471 		dir = -1;
    472 		add = new_mem->num_pages - 1;
    473 	}
    474 
    475 	for (i = 0; i < new_mem->num_pages; ++i) {
    476 		page = i * dir + add;
    477 		if (old_iomap == NULL) {
    478 			pgprot_t prot = ttm_io_prot(old_mem->placement,
    479 						    PAGE_KERNEL);
    480 			ret = ttm_copy_ttm_io_page(ttm, new_iomap, page,
    481 						   prot);
    482 		} else if (new_iomap == NULL) {
    483 			pgprot_t prot = ttm_io_prot(new_mem->placement,
    484 						    PAGE_KERNEL);
    485 			ret = ttm_copy_io_ttm_page(ttm, old_iomap, page,
    486 						   prot);
    487 		} else {
    488 			ret = ttm_copy_io_page(new_iomap, old_iomap, page);
    489 		}
    490 		if (ret)
    491 			goto out1;
    492 	}
    493 	mb();
    494 out2:
    495 	old_copy = *old_mem;
    496 	*old_mem = *new_mem;
    497 	new_mem->mm_node = NULL;
    498 
    499 	if (man->flags & TTM_MEMTYPE_FLAG_FIXED) {
    500 		ttm_tt_destroy(ttm);
    501 		bo->ttm = NULL;
    502 	}
    503 
    504 out1:
    505 	ttm_mem_reg_iounmap(bdev, old_mem, new_iomap);
    506 out:
    507 	ttm_mem_reg_iounmap(bdev, &old_copy, old_iomap);
    508 
    509 	/*
    510 	 * On error, keep the mm node!
    511 	 */
    512 	if (!ret)
    513 		ttm_bo_mem_put(bo, &old_copy);
    514 	return ret;
    515 }
    516 EXPORT_SYMBOL(ttm_bo_move_memcpy);
    517 
    518 static void ttm_transfered_destroy(struct ttm_buffer_object *bo)
    519 {
    520 	struct ttm_transfer_obj *fbo;
    521 
    522 	fbo = container_of(bo, struct ttm_transfer_obj, base);
    523 	ttm_bo_put(fbo->bo);
    524 	dma_resv_fini(&fbo->base.base._resv);
    525 	if (ttm_bo_uses_embedded_gem_object(bo)) {
    526 		/*
    527 		 * Initialization is unconditional, but we don't go
    528 		 * through drm_gem_object_release, and destruction in
    529 		 * ttm_bo_release is conditional, so do this
    530 		 * conditionally with the reverse sense.
    531 		 *
    532 		 * Yes, this is a kludge.
    533 		 */
    534 		drm_vma_node_destroy(&fbo->base.base.vma_node);
    535 	}
    536 	kfree(fbo);
    537 }
    538 
    539 /**
    540  * ttm_buffer_object_transfer
    541  *
    542  * @bo: A pointer to a struct ttm_buffer_object.
    543  * @new_obj: A pointer to a pointer to a newly created ttm_buffer_object,
    544  * holding the data of @bo with the old placement.
    545  *
    546  * This is a utility function that may be called after an accelerated move
    547  * has been scheduled. A new buffer object is created as a placeholder for
    548  * the old data while it's being copied. When that buffer object is idle,
    549  * it can be destroyed, releasing the space of the old placement.
    550  * Returns:
    551  * !0: Failure.
    552  */
    553 
    554 static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
    555 				      struct ttm_buffer_object **new_obj)
    556 {
    557 	struct ttm_transfer_obj *fbo;
    558 	int ret;
    559 
    560 	fbo = kmalloc(sizeof(*fbo), GFP_KERNEL);
    561 	if (!fbo)
    562 		return -ENOMEM;
    563 
    564 	fbo->base = *bo;
    565 	fbo->base.mem.placement |= TTM_PL_FLAG_NO_EVICT;
    566 
    567 	ttm_bo_get(bo);
    568 	fbo->bo = bo;
    569 
    570 	/**
    571 	 * Fix up members that we shouldn't copy directly:
    572 	 * TODO: Explicit member copy would probably be better here.
    573 	 */
    574 
    575 	atomic_inc(&ttm_bo_glob.bo_count);
    576 	INIT_LIST_HEAD(&fbo->base.ddestroy);
    577 	INIT_LIST_HEAD(&fbo->base.lru);
    578 	INIT_LIST_HEAD(&fbo->base.swap);
    579 	INIT_LIST_HEAD(&fbo->base.io_reserve_lru);
    580 	fbo->base.moving = NULL;
    581 #ifdef __NetBSD__
    582 	drm_vma_node_init(&fbo->base.base.vma_node);
    583 	uvm_obj_init(&fbo->base.uvmobj, bo->bdev->driver->ttm_uvm_ops, true, 1);
    584 	rw_obj_hold(bo->uvmobj.vmobjlock);
    585 	uvm_obj_setlock(&fbo->base.uvmobj, bo->uvmobj.vmobjlock);
    586 #else
    587 	drm_vma_node_reset(&fbo->base.base.vma_node);
    588 #endif
    589 
    590 	kref_init(&fbo->base.list_kref);
    591 	kref_init(&fbo->base.kref);
    592 	fbo->base.destroy = &ttm_transfered_destroy;
    593 	fbo->base.acc_size = 0;
    594 	if (bo->base.resv == &bo->base._resv)
    595 		fbo->base.base.resv = &fbo->base.base._resv;
    596 
    597 	dma_resv_init(&fbo->base.base._resv);
    598 	ret = dma_resv_trylock(&fbo->base.base._resv);
    599 	WARN_ON(!ret);
    600 
    601 	*new_obj = &fbo->base;
    602 	return 0;
    603 }
    604 
    605 pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp)
    606 {
    607 	/* Cached mappings need no adjustment */
    608 	if (caching_flags & TTM_PL_FLAG_CACHED)
    609 		return tmp;
    610 
    611 #ifdef __NetBSD__
    612 	tmp &= ~PMAP_CACHE_MASK;
    613 	if (caching_flags & TTM_PL_FLAG_WC)
    614 		return (tmp | PMAP_WRITE_COMBINE);
    615 	else
    616 		return (tmp | PMAP_NOCACHE);
    617 #else
    618 #if defined(__i386__) || defined(__x86_64__)
    619 	if (caching_flags & TTM_PL_FLAG_WC)
    620 		tmp = pgprot_writecombine(tmp);
    621 	else if (boot_cpu_data.x86 > 3)
    622 		tmp = pgprot_noncached(tmp);
    623 #endif
    624 #if defined(__ia64__) || defined(__arm__) || defined(__aarch64__) || \
    625     defined(__powerpc__) || defined(__mips__)
    626 	if (caching_flags & TTM_PL_FLAG_WC)
    627 		tmp = pgprot_writecombine(tmp);
    628 	else
    629 		tmp = pgprot_noncached(tmp);
    630 #endif
    631 #if defined(__sparc__)
    632 	tmp = pgprot_noncached(tmp);
    633 #endif
    634 	return tmp;
    635 #endif
    636 }
    637 EXPORT_SYMBOL(ttm_io_prot);
    638 
    639 static int ttm_bo_ioremap(struct ttm_buffer_object *bo,
    640 			  unsigned long offset,
    641 			  unsigned long size,
    642 			  struct ttm_bo_kmap_obj *map)
    643 {
    644 	struct ttm_mem_reg *mem = &bo->mem;
    645 
    646 	if (bo->mem.bus.addr) {
    647 		map->bo_kmap_type = ttm_bo_map_premapped;
    648 		map->virtual = (void *)(((u8 *)bo->mem.bus.addr) + offset);
    649 	} else {
    650 		map->bo_kmap_type = ttm_bo_map_iomap;
    651 #ifdef __NetBSD__
    652 	    {
    653 		bus_addr_t addr;
    654 		int flags = BUS_SPACE_MAP_LINEAR;
    655 		int ret;
    656 
    657 		addr = (bo->mem.bus.base + bo->mem.bus.offset + offset);
    658 		if (ISSET(mem->placement, TTM_PL_FLAG_WC))
    659 			flags |= BUS_SPACE_MAP_PREFETCHABLE;
    660 		/* XXX errno NetBSD->Linux */
    661 		ret = -bus_space_map(bo->bdev->memt, addr, size, flags,
    662 		    &map->u.io.memh);
    663 		if (ret)
    664 			return ret;
    665 		map->u.io.size = size;
    666 		map->virtual = bus_space_vaddr(bo->bdev->memt, map->u.io.memh);
    667 	    }
    668 #else
    669 		if (mem->placement & TTM_PL_FLAG_WC)
    670 			map->virtual = ioremap_wc(bo->mem.bus.base + bo->mem.bus.offset + offset,
    671 						  size);
    672 		else
    673 			map->virtual = ioremap(bo->mem.bus.base + bo->mem.bus.offset + offset,
    674 						       size);
    675 #endif
    676 	}
    677 	return (!map->virtual) ? -ENOMEM : 0;
    678 }
    679 
    680 static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
    681 			   unsigned long start_page,
    682 			   unsigned long num_pages,
    683 			   struct ttm_bo_kmap_obj *map)
    684 {
    685 	struct ttm_mem_reg *mem = &bo->mem;
    686 	struct ttm_operation_ctx ctx = {
    687 		.interruptible = false,
    688 		.no_wait_gpu = false
    689 	};
    690 	struct ttm_tt *ttm = bo->ttm;
    691 	pgprot_t prot;
    692 	int ret;
    693 
    694 	BUG_ON(!ttm);
    695 
    696 	ret = ttm_tt_populate(ttm, &ctx);
    697 	if (ret)
    698 		return ret;
    699 
    700 	if (num_pages == 1 && (mem->placement & TTM_PL_FLAG_CACHED)) {
    701 		/*
    702 		 * We're mapping a single page, and the desired
    703 		 * page protection is consistent with the bo.
    704 		 */
    705 
    706 		map->bo_kmap_type = ttm_bo_map_kmap;
    707 #ifdef __NetBSD__
    708 		map->u.kmapped.page = ttm->pages[start_page];
    709 		map->virtual = kmap(map->u.kmapped.page);
    710 #else
    711 		map->page = ttm->pages[start_page];
    712 		map->virtual = kmap(map->page);
    713 #endif
    714 	} else {
    715 		/*
    716 		 * We need to use vmap to get the desired page protection
    717 		 * or to make the buffer object look contiguous.
    718 		 */
    719 		prot = ttm_io_prot(mem->placement, PAGE_KERNEL);
    720 		map->bo_kmap_type = ttm_bo_map_vmap;
    721 		map->virtual = vmap(ttm->pages + start_page, num_pages,
    722 				    0, prot);
    723 #ifdef __NetBSD__
    724 		map->u.vmapped.vsize = (vsize_t)num_pages << PAGE_SHIFT;
    725 #endif
    726 	}
    727 	return (!map->virtual) ? -ENOMEM : 0;
    728 }
    729 
    730 int ttm_bo_kmap(struct ttm_buffer_object *bo,
    731 		unsigned long start_page, unsigned long num_pages,
    732 		struct ttm_bo_kmap_obj *map)
    733 {
    734 	struct ttm_mem_type_manager *man =
    735 		&bo->bdev->man[bo->mem.mem_type];
    736 	unsigned long offset, size;
    737 	int ret;
    738 
    739 	map->virtual = NULL;
    740 	map->bo = bo;
    741 	if (num_pages > bo->num_pages)
    742 		return -EINVAL;
    743 	if (start_page > bo->num_pages)
    744 		return -EINVAL;
    745 
    746 	(void) ttm_mem_io_lock(man, false);
    747 	ret = ttm_mem_io_reserve(bo->bdev, &bo->mem);
    748 	ttm_mem_io_unlock(man);
    749 	if (ret)
    750 		return ret;
    751 	if (!bo->mem.bus.is_iomem) {
    752 		return ttm_bo_kmap_ttm(bo, start_page, num_pages, map);
    753 	} else {
    754 		offset = start_page << PAGE_SHIFT;
    755 		size = num_pages << PAGE_SHIFT;
    756 		return ttm_bo_ioremap(bo, offset, size, map);
    757 	}
    758 }
    759 EXPORT_SYMBOL(ttm_bo_kmap);
    760 
    761 void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map)
    762 {
    763 	struct ttm_buffer_object *bo = map->bo;
    764 	struct ttm_mem_type_manager *man =
    765 		&bo->bdev->man[bo->mem.mem_type];
    766 
    767 	if (!map->virtual)
    768 		return;
    769 	switch (map->bo_kmap_type) {
    770 	case ttm_bo_map_iomap:
    771 #ifdef __NetBSD__
    772 		bus_space_unmap(bo->bdev->memt, map->u.io.memh,
    773 		    map->u.io.size);
    774 #else
    775 		iounmap(map->virtual);
    776 #endif
    777 		break;
    778 	case ttm_bo_map_vmap:
    779 #ifdef __NetBSD__
    780 		vunmap(map->virtual, map->u.vmapped.vsize >> PAGE_SHIFT);
    781 #else
    782 		vunmap(map->virtual);
    783 #endif
    784 		break;
    785 	case ttm_bo_map_kmap:
    786 #ifdef __NetBSD__
    787 		kunmap(map->u.kmapped.page);
    788 #else
    789 		kunmap(map->page);
    790 #endif
    791 		break;
    792 	case ttm_bo_map_premapped:
    793 		break;
    794 	default:
    795 		BUG();
    796 	}
    797 	(void) ttm_mem_io_lock(man, false);
    798 	ttm_mem_io_free(map->bo->bdev, &map->bo->mem);
    799 	ttm_mem_io_unlock(man);
    800 	map->virtual = NULL;
    801 #ifndef __NetBSD__
    802 	map->page = NULL;
    803 #endif
    804 }
    805 EXPORT_SYMBOL(ttm_bo_kunmap);
    806 
    807 int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
    808 			      struct dma_fence *fence,
    809 			      bool evict,
    810 			      struct ttm_mem_reg *new_mem)
    811 {
    812 	struct ttm_bo_device *bdev = bo->bdev;
    813 	struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
    814 	struct ttm_mem_reg *old_mem = &bo->mem;
    815 	int ret;
    816 	struct ttm_buffer_object *ghost_obj;
    817 
    818 	dma_resv_add_excl_fence(bo->base.resv, fence);
    819 	if (evict) {
    820 		ret = ttm_bo_wait(bo, false, false);
    821 		if (ret)
    822 			return ret;
    823 
    824 		if (man->flags & TTM_MEMTYPE_FLAG_FIXED) {
    825 			ttm_tt_destroy(bo->ttm);
    826 			bo->ttm = NULL;
    827 		}
    828 		ttm_bo_free_old_node(bo);
    829 	} else {
    830 		/**
    831 		 * This should help pipeline ordinary buffer moves.
    832 		 *
    833 		 * Hang old buffer memory on a new buffer object,
    834 		 * and leave it to be released when the GPU
    835 		 * operation has completed.
    836 		 */
    837 
    838 		dma_fence_put(bo->moving);
    839 		bo->moving = dma_fence_get(fence);
    840 
    841 		ret = ttm_buffer_object_transfer(bo, &ghost_obj);
    842 		if (ret)
    843 			return ret;
    844 
    845 		dma_resv_add_excl_fence(&ghost_obj->base._resv, fence);
    846 
    847 		/**
    848 		 * If we're not moving to fixed memory, the TTM object
    849 		 * needs to stay alive. Otherwhise hang it on the ghost
    850 		 * bo to be unbound and destroyed.
    851 		 */
    852 
    853 		if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED))
    854 			ghost_obj->ttm = NULL;
    855 		else
    856 			bo->ttm = NULL;
    857 
    858 		dma_resv_unlock(&ghost_obj->base._resv);
    859 		ttm_bo_put(ghost_obj);
    860 	}
    861 
    862 	*old_mem = *new_mem;
    863 	new_mem->mm_node = NULL;
    864 
    865 	return 0;
    866 }
    867 EXPORT_SYMBOL(ttm_bo_move_accel_cleanup);
    868 
    869 int ttm_bo_pipeline_move(struct ttm_buffer_object *bo,
    870 			 struct dma_fence *fence, bool evict,
    871 			 struct ttm_mem_reg *new_mem)
    872 {
    873 	struct ttm_bo_device *bdev = bo->bdev;
    874 	struct ttm_mem_reg *old_mem = &bo->mem;
    875 
    876 	struct ttm_mem_type_manager *from = &bdev->man[old_mem->mem_type];
    877 	struct ttm_mem_type_manager *to = &bdev->man[new_mem->mem_type];
    878 
    879 	int ret;
    880 
    881 	dma_resv_add_excl_fence(bo->base.resv, fence);
    882 
    883 	if (!evict) {
    884 		struct ttm_buffer_object *ghost_obj;
    885 
    886 		/**
    887 		 * This should help pipeline ordinary buffer moves.
    888 		 *
    889 		 * Hang old buffer memory on a new buffer object,
    890 		 * and leave it to be released when the GPU
    891 		 * operation has completed.
    892 		 */
    893 
    894 		dma_fence_put(bo->moving);
    895 		bo->moving = dma_fence_get(fence);
    896 
    897 		ret = ttm_buffer_object_transfer(bo, &ghost_obj);
    898 		if (ret)
    899 			return ret;
    900 
    901 		dma_resv_add_excl_fence(&ghost_obj->base._resv, fence);
    902 
    903 		/**
    904 		 * If we're not moving to fixed memory, the TTM object
    905 		 * needs to stay alive. Otherwhise hang it on the ghost
    906 		 * bo to be unbound and destroyed.
    907 		 */
    908 
    909 		if (!(to->flags & TTM_MEMTYPE_FLAG_FIXED))
    910 			ghost_obj->ttm = NULL;
    911 		else
    912 			bo->ttm = NULL;
    913 
    914 		dma_resv_unlock(&ghost_obj->base._resv);
    915 		ttm_bo_put(ghost_obj);
    916 
    917 	} else if (from->flags & TTM_MEMTYPE_FLAG_FIXED) {
    918 
    919 		/**
    920 		 * BO doesn't have a TTM we need to bind/unbind. Just remember
    921 		 * this eviction and free up the allocation
    922 		 */
    923 
    924 		spin_lock(&from->move_lock);
    925 		if (!from->move || dma_fence_is_later(fence, from->move)) {
    926 			dma_fence_put(from->move);
    927 			from->move = dma_fence_get(fence);
    928 		}
    929 		spin_unlock(&from->move_lock);
    930 
    931 		ttm_bo_free_old_node(bo);
    932 
    933 		dma_fence_put(bo->moving);
    934 		bo->moving = dma_fence_get(fence);
    935 
    936 	} else {
    937 		/**
    938 		 * Last resort, wait for the move to be completed.
    939 		 *
    940 		 * Should never happen in pratice.
    941 		 */
    942 
    943 		ret = ttm_bo_wait(bo, false, false);
    944 		if (ret)
    945 			return ret;
    946 
    947 		if (to->flags & TTM_MEMTYPE_FLAG_FIXED) {
    948 			ttm_tt_destroy(bo->ttm);
    949 			bo->ttm = NULL;
    950 		}
    951 		ttm_bo_free_old_node(bo);
    952 	}
    953 
    954 	*old_mem = *new_mem;
    955 	new_mem->mm_node = NULL;
    956 
    957 	return 0;
    958 }
    959 EXPORT_SYMBOL(ttm_bo_pipeline_move);
    960 
    961 int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo)
    962 {
    963 	struct ttm_buffer_object *ghost;
    964 	int ret;
    965 
    966 	ret = ttm_buffer_object_transfer(bo, &ghost);
    967 	if (ret)
    968 		return ret;
    969 
    970 	ret = dma_resv_copy_fences(&ghost->base._resv, bo->base.resv);
    971 	/* Last resort, wait for the BO to be idle when we are OOM */
    972 	if (ret)
    973 		ttm_bo_wait(bo, false, false);
    974 
    975 	memset(&bo->mem, 0, sizeof(bo->mem));
    976 	bo->mem.mem_type = TTM_PL_SYSTEM;
    977 	bo->ttm = NULL;
    978 
    979 	dma_resv_unlock(&ghost->base._resv);
    980 	ttm_bo_put(ghost);
    981 
    982 	return 0;
    983 }
    984