xref: /openbmc/linux/drivers/gpu/drm/ttm/ttm_bo_util.c (revision 9aab6601)
1 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
2 /**************************************************************************
3  *
4  * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sub license, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice (including the
16  * next paragraph) shall be included in all copies or substantial portions
17  * of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
23  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25  * USE OR OTHER DEALINGS IN THE SOFTWARE.
26  *
27  **************************************************************************/
28 /*
29  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
30  */
31 
32 #include <drm/ttm/ttm_bo_driver.h>
33 #include <drm/ttm/ttm_placement.h>
34 #include <drm/drm_vma_manager.h>
35 #include <linux/io.h>
36 #include <linux/highmem.h>
37 #include <linux/wait.h>
38 #include <linux/slab.h>
39 #include <linux/vmalloc.h>
40 #include <linux/module.h>
41 #include <linux/dma-resv.h>
42 
43 struct ttm_transfer_obj {
44 	struct ttm_buffer_object base;
45 	struct ttm_buffer_object *bo;
46 };
47 
48 void ttm_bo_free_old_node(struct ttm_buffer_object *bo)
49 {
50 	ttm_resource_free(bo, &bo->mem);
51 }
52 
53 int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
54 		   struct ttm_operation_ctx *ctx,
55 		    struct ttm_resource *new_mem)
56 {
57 	struct ttm_tt *ttm = bo->ttm;
58 	struct ttm_resource *old_mem = &bo->mem;
59 	int ret;
60 
61 	if (old_mem->mem_type != TTM_PL_SYSTEM) {
62 		ret = ttm_bo_wait_ctx(bo, ctx);
63 
64 		if (unlikely(ret != 0)) {
65 			if (ret != -ERESTARTSYS)
66 				pr_err("Failed to expire sync object before unbinding TTM\n");
67 			return ret;
68 		}
69 
70 		ttm_bo_tt_unbind(bo);
71 		ttm_bo_free_old_node(bo);
72 		old_mem->mem_type = TTM_PL_SYSTEM;
73 	}
74 
75 	if (new_mem->mem_type != TTM_PL_SYSTEM) {
76 
77 		ret = ttm_tt_populate(bo->bdev, ttm, ctx);
78 		if (unlikely(ret != 0))
79 			return ret;
80 
81 		ret = ttm_bo_tt_bind(bo, new_mem);
82 		if (unlikely(ret != 0))
83 			return ret;
84 	}
85 
86 	ttm_bo_assign_mem(bo, new_mem);
87 	return 0;
88 }
89 EXPORT_SYMBOL(ttm_bo_move_ttm);
90 
91 int ttm_mem_io_reserve(struct ttm_bo_device *bdev,
92 		       struct ttm_resource *mem)
93 {
94 	if (mem->bus.offset || mem->bus.addr)
95 		return 0;
96 
97 	mem->bus.is_iomem = false;
98 	if (!bdev->driver->io_mem_reserve)
99 		return 0;
100 
101 	return bdev->driver->io_mem_reserve(bdev, mem);
102 }
103 
104 void ttm_mem_io_free(struct ttm_bo_device *bdev,
105 		     struct ttm_resource *mem)
106 {
107 	if (!mem->bus.offset && !mem->bus.addr)
108 		return;
109 
110 	if (bdev->driver->io_mem_free)
111 		bdev->driver->io_mem_free(bdev, mem);
112 
113 	mem->bus.offset = 0;
114 	mem->bus.addr = NULL;
115 }
116 
117 static int ttm_resource_ioremap(struct ttm_bo_device *bdev,
118 			       struct ttm_resource *mem,
119 			       void **virtual)
120 {
121 	int ret;
122 	void *addr;
123 
124 	*virtual = NULL;
125 	ret = ttm_mem_io_reserve(bdev, mem);
126 	if (ret || !mem->bus.is_iomem)
127 		return ret;
128 
129 	if (mem->bus.addr) {
130 		addr = mem->bus.addr;
131 	} else {
132 		size_t bus_size = (size_t)mem->num_pages << PAGE_SHIFT;
133 
134 		if (mem->bus.caching == ttm_write_combined)
135 			addr = ioremap_wc(mem->bus.offset, bus_size);
136 		else
137 			addr = ioremap(mem->bus.offset, bus_size);
138 		if (!addr) {
139 			ttm_mem_io_free(bdev, mem);
140 			return -ENOMEM;
141 		}
142 	}
143 	*virtual = addr;
144 	return 0;
145 }
146 
147 static void ttm_resource_iounmap(struct ttm_bo_device *bdev,
148 				struct ttm_resource *mem,
149 				void *virtual)
150 {
151 	if (virtual && mem->bus.addr == NULL)
152 		iounmap(virtual);
153 	ttm_mem_io_free(bdev, mem);
154 }
155 
156 static int ttm_copy_io_page(void *dst, void *src, unsigned long page)
157 {
158 	uint32_t *dstP =
159 	    (uint32_t *) ((unsigned long)dst + (page << PAGE_SHIFT));
160 	uint32_t *srcP =
161 	    (uint32_t *) ((unsigned long)src + (page << PAGE_SHIFT));
162 
163 	int i;
164 	for (i = 0; i < PAGE_SIZE / sizeof(uint32_t); ++i)
165 		iowrite32(ioread32(srcP++), dstP++);
166 	return 0;
167 }
168 
169 static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src,
170 				unsigned long page,
171 				pgprot_t prot)
172 {
173 	struct page *d = ttm->pages[page];
174 	void *dst;
175 
176 	if (!d)
177 		return -ENOMEM;
178 
179 	src = (void *)((unsigned long)src + (page << PAGE_SHIFT));
180 	dst = kmap_atomic_prot(d, prot);
181 	if (!dst)
182 		return -ENOMEM;
183 
184 	memcpy_fromio(dst, src, PAGE_SIZE);
185 
186 	kunmap_atomic(dst);
187 
188 	return 0;
189 }
190 
191 static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst,
192 				unsigned long page,
193 				pgprot_t prot)
194 {
195 	struct page *s = ttm->pages[page];
196 	void *src;
197 
198 	if (!s)
199 		return -ENOMEM;
200 
201 	dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT));
202 	src = kmap_atomic_prot(s, prot);
203 	if (!src)
204 		return -ENOMEM;
205 
206 	memcpy_toio(dst, src, PAGE_SIZE);
207 
208 	kunmap_atomic(src);
209 
210 	return 0;
211 }
212 
213 int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
214 		       struct ttm_operation_ctx *ctx,
215 		       struct ttm_resource *new_mem)
216 {
217 	struct ttm_bo_device *bdev = bo->bdev;
218 	struct ttm_resource_manager *man = ttm_manager_type(bdev, new_mem->mem_type);
219 	struct ttm_tt *ttm = bo->ttm;
220 	struct ttm_resource *old_mem = &bo->mem;
221 	struct ttm_resource old_copy = *old_mem;
222 	void *old_iomap;
223 	void *new_iomap;
224 	int ret;
225 	unsigned long i;
226 	unsigned long page;
227 	unsigned long add = 0;
228 	int dir;
229 
230 	ret = ttm_bo_wait_ctx(bo, ctx);
231 	if (ret)
232 		return ret;
233 
234 	ret = ttm_resource_ioremap(bdev, old_mem, &old_iomap);
235 	if (ret)
236 		return ret;
237 	ret = ttm_resource_ioremap(bdev, new_mem, &new_iomap);
238 	if (ret)
239 		goto out;
240 
241 	/*
242 	 * Single TTM move. NOP.
243 	 */
244 	if (old_iomap == NULL && new_iomap == NULL)
245 		goto out2;
246 
247 	/*
248 	 * Don't move nonexistent data. Clear destination instead.
249 	 */
250 	if (old_iomap == NULL &&
251 	    (ttm == NULL || (!ttm_tt_is_populated(ttm) &&
252 			     !(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)))) {
253 		memset_io(new_iomap, 0, new_mem->num_pages*PAGE_SIZE);
254 		goto out2;
255 	}
256 
257 	/*
258 	 * TTM might be null for moves within the same region.
259 	 */
260 	if (ttm) {
261 		ret = ttm_tt_populate(bdev, ttm, ctx);
262 		if (ret)
263 			goto out1;
264 	}
265 
266 	add = 0;
267 	dir = 1;
268 
269 	if ((old_mem->mem_type == new_mem->mem_type) &&
270 	    (new_mem->start < old_mem->start + old_mem->size)) {
271 		dir = -1;
272 		add = new_mem->num_pages - 1;
273 	}
274 
275 	for (i = 0; i < new_mem->num_pages; ++i) {
276 		page = i * dir + add;
277 		if (old_iomap == NULL) {
278 			pgprot_t prot = ttm_io_prot(bo, old_mem, PAGE_KERNEL);
279 			ret = ttm_copy_ttm_io_page(ttm, new_iomap, page,
280 						   prot);
281 		} else if (new_iomap == NULL) {
282 			pgprot_t prot = ttm_io_prot(bo, new_mem, PAGE_KERNEL);
283 			ret = ttm_copy_io_ttm_page(ttm, old_iomap, page,
284 						   prot);
285 		} else {
286 			ret = ttm_copy_io_page(new_iomap, old_iomap, page);
287 		}
288 		if (ret)
289 			goto out1;
290 	}
291 	mb();
292 out2:
293 	old_copy = *old_mem;
294 
295 	ttm_bo_assign_mem(bo, new_mem);
296 
297 	if (!man->use_tt)
298 		ttm_bo_tt_destroy(bo);
299 
300 out1:
301 	ttm_resource_iounmap(bdev, old_mem, new_iomap);
302 out:
303 	ttm_resource_iounmap(bdev, &old_copy, old_iomap);
304 
305 	/*
306 	 * On error, keep the mm node!
307 	 */
308 	if (!ret)
309 		ttm_resource_free(bo, &old_copy);
310 	return ret;
311 }
312 EXPORT_SYMBOL(ttm_bo_move_memcpy);
313 
314 static void ttm_transfered_destroy(struct ttm_buffer_object *bo)
315 {
316 	struct ttm_transfer_obj *fbo;
317 
318 	fbo = container_of(bo, struct ttm_transfer_obj, base);
319 	ttm_bo_put(fbo->bo);
320 	kfree(fbo);
321 }
322 
323 /**
324  * ttm_buffer_object_transfer
325  *
326  * @bo: A pointer to a struct ttm_buffer_object.
327  * @new_obj: A pointer to a pointer to a newly created ttm_buffer_object,
328  * holding the data of @bo with the old placement.
329  *
330  * This is a utility function that may be called after an accelerated move
331  * has been scheduled. A new buffer object is created as a placeholder for
332  * the old data while it's being copied. When that buffer object is idle,
333  * it can be destroyed, releasing the space of the old placement.
334  * Returns:
335  * !0: Failure.
336  */
337 
338 static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
339 				      struct ttm_buffer_object **new_obj)
340 {
341 	struct ttm_transfer_obj *fbo;
342 	int ret;
343 
344 	fbo = kmalloc(sizeof(*fbo), GFP_KERNEL);
345 	if (!fbo)
346 		return -ENOMEM;
347 
348 	fbo->base = *bo;
349 
350 	ttm_bo_get(bo);
351 	fbo->bo = bo;
352 
353 	/**
354 	 * Fix up members that we shouldn't copy directly:
355 	 * TODO: Explicit member copy would probably be better here.
356 	 */
357 
358 	atomic_inc(&ttm_bo_glob.bo_count);
359 	INIT_LIST_HEAD(&fbo->base.ddestroy);
360 	INIT_LIST_HEAD(&fbo->base.lru);
361 	INIT_LIST_HEAD(&fbo->base.swap);
362 	fbo->base.moving = NULL;
363 	drm_vma_node_reset(&fbo->base.base.vma_node);
364 
365 	kref_init(&fbo->base.kref);
366 	fbo->base.destroy = &ttm_transfered_destroy;
367 	fbo->base.acc_size = 0;
368 	fbo->base.pin_count = 1;
369 	if (bo->type != ttm_bo_type_sg)
370 		fbo->base.base.resv = &fbo->base.base._resv;
371 
372 	dma_resv_init(&fbo->base.base._resv);
373 	fbo->base.base.dev = NULL;
374 	ret = dma_resv_trylock(&fbo->base.base._resv);
375 	WARN_ON(!ret);
376 
377 	*new_obj = &fbo->base;
378 	return 0;
379 }
380 
381 pgprot_t ttm_io_prot(struct ttm_buffer_object *bo, struct ttm_resource *res,
382 		     pgprot_t tmp)
383 {
384 	struct ttm_resource_manager *man;
385 	enum ttm_caching caching;
386 
387 	man = ttm_manager_type(bo->bdev, res->mem_type);
388 	caching = man->use_tt ? bo->ttm->caching : res->bus.caching;
389 
390 	/* Cached mappings need no adjustment */
391 	if (caching == ttm_cached)
392 		return tmp;
393 
394 #if defined(__i386__) || defined(__x86_64__)
395 	if (caching == ttm_write_combined)
396 		tmp = pgprot_writecombine(tmp);
397 	else if (boot_cpu_data.x86 > 3)
398 		tmp = pgprot_noncached(tmp);
399 #endif
400 #if defined(__ia64__) || defined(__arm__) || defined(__aarch64__) || \
401     defined(__powerpc__) || defined(__mips__)
402 	if (caching == ttm_write_combined)
403 		tmp = pgprot_writecombine(tmp);
404 	else
405 		tmp = pgprot_noncached(tmp);
406 #endif
407 #if defined(__sparc__)
408 	tmp = pgprot_noncached(tmp);
409 #endif
410 	return tmp;
411 }
412 EXPORT_SYMBOL(ttm_io_prot);
413 
414 static int ttm_bo_ioremap(struct ttm_buffer_object *bo,
415 			  unsigned long offset,
416 			  unsigned long size,
417 			  struct ttm_bo_kmap_obj *map)
418 {
419 	struct ttm_resource *mem = &bo->mem;
420 
421 	if (bo->mem.bus.addr) {
422 		map->bo_kmap_type = ttm_bo_map_premapped;
423 		map->virtual = (void *)(((u8 *)bo->mem.bus.addr) + offset);
424 	} else {
425 		map->bo_kmap_type = ttm_bo_map_iomap;
426 		if (mem->bus.caching == ttm_write_combined)
427 			map->virtual = ioremap_wc(bo->mem.bus.offset + offset,
428 						  size);
429 		else
430 			map->virtual = ioremap(bo->mem.bus.offset + offset,
431 					       size);
432 	}
433 	return (!map->virtual) ? -ENOMEM : 0;
434 }
435 
436 static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
437 			   unsigned long start_page,
438 			   unsigned long num_pages,
439 			   struct ttm_bo_kmap_obj *map)
440 {
441 	struct ttm_resource *mem = &bo->mem;
442 	struct ttm_operation_ctx ctx = {
443 		.interruptible = false,
444 		.no_wait_gpu = false
445 	};
446 	struct ttm_tt *ttm = bo->ttm;
447 	pgprot_t prot;
448 	int ret;
449 
450 	BUG_ON(!ttm);
451 
452 	ret = ttm_tt_populate(bo->bdev, ttm, &ctx);
453 	if (ret)
454 		return ret;
455 
456 	if (num_pages == 1 && ttm->caching == ttm_cached) {
457 		/*
458 		 * We're mapping a single page, and the desired
459 		 * page protection is consistent with the bo.
460 		 */
461 
462 		map->bo_kmap_type = ttm_bo_map_kmap;
463 		map->page = ttm->pages[start_page];
464 		map->virtual = kmap(map->page);
465 	} else {
466 		/*
467 		 * We need to use vmap to get the desired page protection
468 		 * or to make the buffer object look contiguous.
469 		 */
470 		prot = ttm_io_prot(bo, mem, PAGE_KERNEL);
471 		map->bo_kmap_type = ttm_bo_map_vmap;
472 		map->virtual = vmap(ttm->pages + start_page, num_pages,
473 				    0, prot);
474 	}
475 	return (!map->virtual) ? -ENOMEM : 0;
476 }
477 
478 int ttm_bo_kmap(struct ttm_buffer_object *bo,
479 		unsigned long start_page, unsigned long num_pages,
480 		struct ttm_bo_kmap_obj *map)
481 {
482 	unsigned long offset, size;
483 	int ret;
484 
485 	map->virtual = NULL;
486 	map->bo = bo;
487 	if (num_pages > bo->num_pages)
488 		return -EINVAL;
489 	if (start_page > bo->num_pages)
490 		return -EINVAL;
491 
492 	ret = ttm_mem_io_reserve(bo->bdev, &bo->mem);
493 	if (ret)
494 		return ret;
495 	if (!bo->mem.bus.is_iomem) {
496 		return ttm_bo_kmap_ttm(bo, start_page, num_pages, map);
497 	} else {
498 		offset = start_page << PAGE_SHIFT;
499 		size = num_pages << PAGE_SHIFT;
500 		return ttm_bo_ioremap(bo, offset, size, map);
501 	}
502 }
503 EXPORT_SYMBOL(ttm_bo_kmap);
504 
505 void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map)
506 {
507 	if (!map->virtual)
508 		return;
509 	switch (map->bo_kmap_type) {
510 	case ttm_bo_map_iomap:
511 		iounmap(map->virtual);
512 		break;
513 	case ttm_bo_map_vmap:
514 		vunmap(map->virtual);
515 		break;
516 	case ttm_bo_map_kmap:
517 		kunmap(map->page);
518 		break;
519 	case ttm_bo_map_premapped:
520 		break;
521 	default:
522 		BUG();
523 	}
524 	ttm_mem_io_free(map->bo->bdev, &map->bo->mem);
525 	map->virtual = NULL;
526 	map->page = NULL;
527 }
528 EXPORT_SYMBOL(ttm_bo_kunmap);
529 
530 static int ttm_bo_wait_free_node(struct ttm_buffer_object *bo,
531 				 bool dst_use_tt)
532 {
533 	int ret;
534 	ret = ttm_bo_wait(bo, false, false);
535 	if (ret)
536 		return ret;
537 
538 	if (!dst_use_tt)
539 		ttm_bo_tt_destroy(bo);
540 	ttm_bo_free_old_node(bo);
541 	return 0;
542 }
543 
544 static int ttm_bo_move_to_ghost(struct ttm_buffer_object *bo,
545 				struct dma_fence *fence,
546 				bool dst_use_tt)
547 {
548 	struct ttm_buffer_object *ghost_obj;
549 	int ret;
550 
551 	/**
552 	 * This should help pipeline ordinary buffer moves.
553 	 *
554 	 * Hang old buffer memory on a new buffer object,
555 	 * and leave it to be released when the GPU
556 	 * operation has completed.
557 	 */
558 
559 	dma_fence_put(bo->moving);
560 	bo->moving = dma_fence_get(fence);
561 
562 	ret = ttm_buffer_object_transfer(bo, &ghost_obj);
563 	if (ret)
564 		return ret;
565 
566 	dma_resv_add_excl_fence(&ghost_obj->base._resv, fence);
567 
568 	/**
569 	 * If we're not moving to fixed memory, the TTM object
570 	 * needs to stay alive. Otherwhise hang it on the ghost
571 	 * bo to be unbound and destroyed.
572 	 */
573 
574 	if (dst_use_tt)
575 		ghost_obj->ttm = NULL;
576 	else
577 		bo->ttm = NULL;
578 
579 	dma_resv_unlock(&ghost_obj->base._resv);
580 	ttm_bo_put(ghost_obj);
581 	return 0;
582 }
583 
584 static void ttm_bo_move_pipeline_evict(struct ttm_buffer_object *bo,
585 				       struct dma_fence *fence)
586 {
587 	struct ttm_bo_device *bdev = bo->bdev;
588 	struct ttm_resource_manager *from = ttm_manager_type(bdev, bo->mem.mem_type);
589 
590 	/**
591 	 * BO doesn't have a TTM we need to bind/unbind. Just remember
592 	 * this eviction and free up the allocation
593 	 */
594 	spin_lock(&from->move_lock);
595 	if (!from->move || dma_fence_is_later(fence, from->move)) {
596 		dma_fence_put(from->move);
597 		from->move = dma_fence_get(fence);
598 	}
599 	spin_unlock(&from->move_lock);
600 
601 	ttm_bo_free_old_node(bo);
602 
603 	dma_fence_put(bo->moving);
604 	bo->moving = dma_fence_get(fence);
605 }
606 
607 int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
608 			      struct dma_fence *fence,
609 			      bool evict,
610 			      bool pipeline,
611 			      struct ttm_resource *new_mem)
612 {
613 	struct ttm_bo_device *bdev = bo->bdev;
614 	struct ttm_resource_manager *from = ttm_manager_type(bdev, bo->mem.mem_type);
615 	struct ttm_resource_manager *man = ttm_manager_type(bdev, new_mem->mem_type);
616 	int ret = 0;
617 
618 	dma_resv_add_excl_fence(bo->base.resv, fence);
619 	if (!evict)
620 		ret = ttm_bo_move_to_ghost(bo, fence, man->use_tt);
621 	else if (!from->use_tt && pipeline)
622 		ttm_bo_move_pipeline_evict(bo, fence);
623 	else
624 		ret = ttm_bo_wait_free_node(bo, man->use_tt);
625 
626 	if (ret)
627 		return ret;
628 
629 	ttm_bo_assign_mem(bo, new_mem);
630 
631 	return 0;
632 }
633 EXPORT_SYMBOL(ttm_bo_move_accel_cleanup);
634 
635 int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo)
636 {
637 	struct ttm_buffer_object *ghost;
638 	int ret;
639 
640 	ret = ttm_buffer_object_transfer(bo, &ghost);
641 	if (ret)
642 		return ret;
643 
644 	ret = dma_resv_copy_fences(&ghost->base._resv, bo->base.resv);
645 	/* Last resort, wait for the BO to be idle when we are OOM */
646 	if (ret)
647 		ttm_bo_wait(bo, false, false);
648 
649 	memset(&bo->mem, 0, sizeof(bo->mem));
650 	bo->mem.mem_type = TTM_PL_SYSTEM;
651 	bo->ttm = NULL;
652 
653 	dma_resv_unlock(&ghost->base._resv);
654 	ttm_bo_put(ghost);
655 
656 	return 0;
657 }
658