xref: /linux/drivers/gpu/drm/ttm/ttm_bo_util.c (revision 2277ab4a1df50e05bc732fe9488d4e902bb8399a)
1 /**************************************************************************
2  *
3  * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 /*
28  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
29  */
30 
31 #include "ttm/ttm_bo_driver.h"
32 #include "ttm/ttm_placement.h"
33 #include <linux/io.h>
34 #include <linux/highmem.h>
35 #include <linux/wait.h>
36 #include <linux/vmalloc.h>
37 #include <linux/module.h>
38 
39 void ttm_bo_free_old_node(struct ttm_buffer_object *bo)
40 {
41 	struct ttm_mem_reg *old_mem = &bo->mem;
42 
43 	if (old_mem->mm_node) {
44 		spin_lock(&bo->bdev->lru_lock);
45 		drm_mm_put_block(old_mem->mm_node);
46 		spin_unlock(&bo->bdev->lru_lock);
47 	}
48 	old_mem->mm_node = NULL;
49 }
50 
51 int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
52 		    bool evict, bool no_wait, struct ttm_mem_reg *new_mem)
53 {
54 	struct ttm_tt *ttm = bo->ttm;
55 	struct ttm_mem_reg *old_mem = &bo->mem;
56 	uint32_t save_flags = old_mem->placement;
57 	int ret;
58 
59 	if (old_mem->mem_type != TTM_PL_SYSTEM) {
60 		ttm_tt_unbind(ttm);
61 		ttm_bo_free_old_node(bo);
62 		ttm_flag_masked(&old_mem->placement, TTM_PL_FLAG_SYSTEM,
63 				TTM_PL_MASK_MEM);
64 		old_mem->mem_type = TTM_PL_SYSTEM;
65 		save_flags = old_mem->placement;
66 	}
67 
68 	ret = ttm_tt_set_placement_caching(ttm, new_mem->placement);
69 	if (unlikely(ret != 0))
70 		return ret;
71 
72 	if (new_mem->mem_type != TTM_PL_SYSTEM) {
73 		ret = ttm_tt_bind(ttm, new_mem);
74 		if (unlikely(ret != 0))
75 			return ret;
76 	}
77 
78 	*old_mem = *new_mem;
79 	new_mem->mm_node = NULL;
80 	ttm_flag_masked(&save_flags, new_mem->placement, TTM_PL_MASK_MEMTYPE);
81 	return 0;
82 }
83 EXPORT_SYMBOL(ttm_bo_move_ttm);
84 
85 int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem,
86 			void **virtual)
87 {
88 	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
89 	unsigned long bus_offset;
90 	unsigned long bus_size;
91 	unsigned long bus_base;
92 	int ret;
93 	void *addr;
94 
95 	*virtual = NULL;
96 	ret = ttm_bo_pci_offset(bdev, mem, &bus_base, &bus_offset, &bus_size);
97 	if (ret || bus_size == 0)
98 		return ret;
99 
100 	if (!(man->flags & TTM_MEMTYPE_FLAG_NEEDS_IOREMAP))
101 		addr = (void *)(((u8 *) man->io_addr) + bus_offset);
102 	else {
103 		if (mem->placement & TTM_PL_FLAG_WC)
104 			addr = ioremap_wc(bus_base + bus_offset, bus_size);
105 		else
106 			addr = ioremap_nocache(bus_base + bus_offset, bus_size);
107 		if (!addr)
108 			return -ENOMEM;
109 	}
110 	*virtual = addr;
111 	return 0;
112 }
113 
114 void ttm_mem_reg_iounmap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem,
115 			 void *virtual)
116 {
117 	struct ttm_mem_type_manager *man;
118 
119 	man = &bdev->man[mem->mem_type];
120 
121 	if (virtual && (man->flags & TTM_MEMTYPE_FLAG_NEEDS_IOREMAP))
122 		iounmap(virtual);
123 }
124 
125 static int ttm_copy_io_page(void *dst, void *src, unsigned long page)
126 {
127 	uint32_t *dstP =
128 	    (uint32_t *) ((unsigned long)dst + (page << PAGE_SHIFT));
129 	uint32_t *srcP =
130 	    (uint32_t *) ((unsigned long)src + (page << PAGE_SHIFT));
131 
132 	int i;
133 	for (i = 0; i < PAGE_SIZE / sizeof(uint32_t); ++i)
134 		iowrite32(ioread32(srcP++), dstP++);
135 	return 0;
136 }
137 
138 static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src,
139 				unsigned long page)
140 {
141 	struct page *d = ttm_tt_get_page(ttm, page);
142 	void *dst;
143 
144 	if (!d)
145 		return -ENOMEM;
146 
147 	src = (void *)((unsigned long)src + (page << PAGE_SHIFT));
148 	dst = kmap(d);
149 	if (!dst)
150 		return -ENOMEM;
151 
152 	memcpy_fromio(dst, src, PAGE_SIZE);
153 	kunmap(d);
154 	return 0;
155 }
156 
157 static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst,
158 				unsigned long page)
159 {
160 	struct page *s = ttm_tt_get_page(ttm, page);
161 	void *src;
162 
163 	if (!s)
164 		return -ENOMEM;
165 
166 	dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT));
167 	src = kmap(s);
168 	if (!src)
169 		return -ENOMEM;
170 
171 	memcpy_toio(dst, src, PAGE_SIZE);
172 	kunmap(s);
173 	return 0;
174 }
175 
176 int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
177 		       bool evict, bool no_wait, struct ttm_mem_reg *new_mem)
178 {
179 	struct ttm_bo_device *bdev = bo->bdev;
180 	struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
181 	struct ttm_tt *ttm = bo->ttm;
182 	struct ttm_mem_reg *old_mem = &bo->mem;
183 	struct ttm_mem_reg old_copy = *old_mem;
184 	void *old_iomap;
185 	void *new_iomap;
186 	int ret;
187 	uint32_t save_flags = old_mem->placement;
188 	unsigned long i;
189 	unsigned long page;
190 	unsigned long add = 0;
191 	int dir;
192 
193 	ret = ttm_mem_reg_ioremap(bdev, old_mem, &old_iomap);
194 	if (ret)
195 		return ret;
196 	ret = ttm_mem_reg_ioremap(bdev, new_mem, &new_iomap);
197 	if (ret)
198 		goto out;
199 
200 	if (old_iomap == NULL && new_iomap == NULL)
201 		goto out2;
202 	if (old_iomap == NULL && ttm == NULL)
203 		goto out2;
204 
205 	add = 0;
206 	dir = 1;
207 
208 	if ((old_mem->mem_type == new_mem->mem_type) &&
209 	    (new_mem->mm_node->start <
210 	     old_mem->mm_node->start + old_mem->mm_node->size)) {
211 		dir = -1;
212 		add = new_mem->num_pages - 1;
213 	}
214 
215 	for (i = 0; i < new_mem->num_pages; ++i) {
216 		page = i * dir + add;
217 		if (old_iomap == NULL)
218 			ret = ttm_copy_ttm_io_page(ttm, new_iomap, page);
219 		else if (new_iomap == NULL)
220 			ret = ttm_copy_io_ttm_page(ttm, old_iomap, page);
221 		else
222 			ret = ttm_copy_io_page(new_iomap, old_iomap, page);
223 		if (ret)
224 			goto out1;
225 	}
226 	mb();
227 out2:
228 	ttm_bo_free_old_node(bo);
229 
230 	*old_mem = *new_mem;
231 	new_mem->mm_node = NULL;
232 	ttm_flag_masked(&save_flags, new_mem->placement, TTM_PL_MASK_MEMTYPE);
233 
234 	if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && (ttm != NULL)) {
235 		ttm_tt_unbind(ttm);
236 		ttm_tt_destroy(ttm);
237 		bo->ttm = NULL;
238 	}
239 
240 out1:
241 	ttm_mem_reg_iounmap(bdev, new_mem, new_iomap);
242 out:
243 	ttm_mem_reg_iounmap(bdev, &old_copy, old_iomap);
244 	return ret;
245 }
246 EXPORT_SYMBOL(ttm_bo_move_memcpy);
247 
248 static void ttm_transfered_destroy(struct ttm_buffer_object *bo)
249 {
250 	kfree(bo);
251 }
252 
253 /**
254  * ttm_buffer_object_transfer
255  *
256  * @bo: A pointer to a struct ttm_buffer_object.
257  * @new_obj: A pointer to a pointer to a newly created ttm_buffer_object,
258  * holding the data of @bo with the old placement.
259  *
260  * This is a utility function that may be called after an accelerated move
261  * has been scheduled. A new buffer object is created as a placeholder for
262  * the old data while it's being copied. When that buffer object is idle,
263  * it can be destroyed, releasing the space of the old placement.
264  * Returns:
265  * !0: Failure.
266  */
267 
268 static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
269 				      struct ttm_buffer_object **new_obj)
270 {
271 	struct ttm_buffer_object *fbo;
272 	struct ttm_bo_device *bdev = bo->bdev;
273 	struct ttm_bo_driver *driver = bdev->driver;
274 
275 	fbo = kzalloc(sizeof(*fbo), GFP_KERNEL);
276 	if (!fbo)
277 		return -ENOMEM;
278 
279 	*fbo = *bo;
280 
281 	/**
282 	 * Fix up members that we shouldn't copy directly:
283 	 * TODO: Explicit member copy would probably be better here.
284 	 */
285 
286 	spin_lock_init(&fbo->lock);
287 	init_waitqueue_head(&fbo->event_queue);
288 	INIT_LIST_HEAD(&fbo->ddestroy);
289 	INIT_LIST_HEAD(&fbo->lru);
290 	INIT_LIST_HEAD(&fbo->swap);
291 	fbo->vm_node = NULL;
292 
293 	fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
294 	if (fbo->mem.mm_node)
295 		fbo->mem.mm_node->private = (void *)fbo;
296 	kref_init(&fbo->list_kref);
297 	kref_init(&fbo->kref);
298 	fbo->destroy = &ttm_transfered_destroy;
299 
300 	*new_obj = fbo;
301 	return 0;
302 }
303 
304 pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp)
305 {
306 #if defined(__i386__) || defined(__x86_64__)
307 	if (caching_flags & TTM_PL_FLAG_WC)
308 		tmp = pgprot_writecombine(tmp);
309 	else if (boot_cpu_data.x86 > 3)
310 		tmp = pgprot_noncached(tmp);
311 
312 #elif defined(__powerpc__)
313 	if (!(caching_flags & TTM_PL_FLAG_CACHED)) {
314 		pgprot_val(tmp) |= _PAGE_NO_CACHE;
315 		if (caching_flags & TTM_PL_FLAG_UNCACHED)
316 			pgprot_val(tmp) |= _PAGE_GUARDED;
317 	}
318 #endif
319 #if defined(__ia64__)
320 	if (caching_flags & TTM_PL_FLAG_WC)
321 		tmp = pgprot_writecombine(tmp);
322 	else
323 		tmp = pgprot_noncached(tmp);
324 #endif
325 #if defined(__sparc__)
326 	if (!(caching_flags & TTM_PL_FLAG_CACHED))
327 		tmp = pgprot_noncached(tmp);
328 #endif
329 	return tmp;
330 }
331 
332 static int ttm_bo_ioremap(struct ttm_buffer_object *bo,
333 			  unsigned long bus_base,
334 			  unsigned long bus_offset,
335 			  unsigned long bus_size,
336 			  struct ttm_bo_kmap_obj *map)
337 {
338 	struct ttm_bo_device *bdev = bo->bdev;
339 	struct ttm_mem_reg *mem = &bo->mem;
340 	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
341 
342 	if (!(man->flags & TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) {
343 		map->bo_kmap_type = ttm_bo_map_premapped;
344 		map->virtual = (void *)(((u8 *) man->io_addr) + bus_offset);
345 	} else {
346 		map->bo_kmap_type = ttm_bo_map_iomap;
347 		if (mem->placement & TTM_PL_FLAG_WC)
348 			map->virtual = ioremap_wc(bus_base + bus_offset,
349 						  bus_size);
350 		else
351 			map->virtual = ioremap_nocache(bus_base + bus_offset,
352 						       bus_size);
353 	}
354 	return (!map->virtual) ? -ENOMEM : 0;
355 }
356 
357 static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
358 			   unsigned long start_page,
359 			   unsigned long num_pages,
360 			   struct ttm_bo_kmap_obj *map)
361 {
362 	struct ttm_mem_reg *mem = &bo->mem; pgprot_t prot;
363 	struct ttm_tt *ttm = bo->ttm;
364 	struct page *d;
365 	int i;
366 
367 	BUG_ON(!ttm);
368 	if (num_pages == 1 && (mem->placement & TTM_PL_FLAG_CACHED)) {
369 		/*
370 		 * We're mapping a single page, and the desired
371 		 * page protection is consistent with the bo.
372 		 */
373 
374 		map->bo_kmap_type = ttm_bo_map_kmap;
375 		map->page = ttm_tt_get_page(ttm, start_page);
376 		map->virtual = kmap(map->page);
377 	} else {
378 	    /*
379 	     * Populate the part we're mapping;
380 	     */
381 		for (i = start_page; i < start_page + num_pages; ++i) {
382 			d = ttm_tt_get_page(ttm, i);
383 			if (!d)
384 				return -ENOMEM;
385 		}
386 
387 		/*
388 		 * We need to use vmap to get the desired page protection
389 		 * or to make the buffer object look contigous.
390 		 */
391 		prot = (mem->placement & TTM_PL_FLAG_CACHED) ?
392 			PAGE_KERNEL :
393 			ttm_io_prot(mem->placement, PAGE_KERNEL);
394 		map->bo_kmap_type = ttm_bo_map_vmap;
395 		map->virtual = vmap(ttm->pages + start_page, num_pages,
396 				    0, prot);
397 	}
398 	return (!map->virtual) ? -ENOMEM : 0;
399 }
400 
401 int ttm_bo_kmap(struct ttm_buffer_object *bo,
402 		unsigned long start_page, unsigned long num_pages,
403 		struct ttm_bo_kmap_obj *map)
404 {
405 	int ret;
406 	unsigned long bus_base;
407 	unsigned long bus_offset;
408 	unsigned long bus_size;
409 
410 	BUG_ON(!list_empty(&bo->swap));
411 	map->virtual = NULL;
412 	if (num_pages > bo->num_pages)
413 		return -EINVAL;
414 	if (start_page > bo->num_pages)
415 		return -EINVAL;
416 #if 0
417 	if (num_pages > 1 && !DRM_SUSER(DRM_CURPROC))
418 		return -EPERM;
419 #endif
420 	ret = ttm_bo_pci_offset(bo->bdev, &bo->mem, &bus_base,
421 				&bus_offset, &bus_size);
422 	if (ret)
423 		return ret;
424 	if (bus_size == 0) {
425 		return ttm_bo_kmap_ttm(bo, start_page, num_pages, map);
426 	} else {
427 		bus_offset += start_page << PAGE_SHIFT;
428 		bus_size = num_pages << PAGE_SHIFT;
429 		return ttm_bo_ioremap(bo, bus_base, bus_offset, bus_size, map);
430 	}
431 }
432 EXPORT_SYMBOL(ttm_bo_kmap);
433 
434 void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map)
435 {
436 	if (!map->virtual)
437 		return;
438 	switch (map->bo_kmap_type) {
439 	case ttm_bo_map_iomap:
440 		iounmap(map->virtual);
441 		break;
442 	case ttm_bo_map_vmap:
443 		vunmap(map->virtual);
444 		break;
445 	case ttm_bo_map_kmap:
446 		kunmap(map->page);
447 		break;
448 	case ttm_bo_map_premapped:
449 		break;
450 	default:
451 		BUG();
452 	}
453 	map->virtual = NULL;
454 	map->page = NULL;
455 }
456 EXPORT_SYMBOL(ttm_bo_kunmap);
457 
458 int ttm_bo_pfn_prot(struct ttm_buffer_object *bo,
459 		    unsigned long dst_offset,
460 		    unsigned long *pfn, pgprot_t *prot)
461 {
462 	struct ttm_mem_reg *mem = &bo->mem;
463 	struct ttm_bo_device *bdev = bo->bdev;
464 	unsigned long bus_offset;
465 	unsigned long bus_size;
466 	unsigned long bus_base;
467 	int ret;
468 	ret = ttm_bo_pci_offset(bdev, mem, &bus_base, &bus_offset,
469 			&bus_size);
470 	if (ret)
471 		return -EINVAL;
472 	if (bus_size != 0)
473 		*pfn = (bus_base + bus_offset + dst_offset) >> PAGE_SHIFT;
474 	else
475 		if (!bo->ttm)
476 			return -EINVAL;
477 		else
478 			*pfn = page_to_pfn(ttm_tt_get_page(bo->ttm,
479 							   dst_offset >>
480 							   PAGE_SHIFT));
481 	*prot = (mem->placement & TTM_PL_FLAG_CACHED) ?
482 		PAGE_KERNEL : ttm_io_prot(mem->placement, PAGE_KERNEL);
483 
484 	return 0;
485 }
486 
487 int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
488 			      void *sync_obj,
489 			      void *sync_obj_arg,
490 			      bool evict, bool no_wait,
491 			      struct ttm_mem_reg *new_mem)
492 {
493 	struct ttm_bo_device *bdev = bo->bdev;
494 	struct ttm_bo_driver *driver = bdev->driver;
495 	struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
496 	struct ttm_mem_reg *old_mem = &bo->mem;
497 	int ret;
498 	uint32_t save_flags = old_mem->placement;
499 	struct ttm_buffer_object *ghost_obj;
500 	void *tmp_obj = NULL;
501 
502 	spin_lock(&bo->lock);
503 	if (bo->sync_obj) {
504 		tmp_obj = bo->sync_obj;
505 		bo->sync_obj = NULL;
506 	}
507 	bo->sync_obj = driver->sync_obj_ref(sync_obj);
508 	bo->sync_obj_arg = sync_obj_arg;
509 	if (evict) {
510 		ret = ttm_bo_wait(bo, false, false, false);
511 		spin_unlock(&bo->lock);
512 		driver->sync_obj_unref(&bo->sync_obj);
513 
514 		if (ret)
515 			return ret;
516 
517 		ttm_bo_free_old_node(bo);
518 		if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
519 		    (bo->ttm != NULL)) {
520 			ttm_tt_unbind(bo->ttm);
521 			ttm_tt_destroy(bo->ttm);
522 			bo->ttm = NULL;
523 		}
524 	} else {
525 		/**
526 		 * This should help pipeline ordinary buffer moves.
527 		 *
528 		 * Hang old buffer memory on a new buffer object,
529 		 * and leave it to be released when the GPU
530 		 * operation has completed.
531 		 */
532 
533 		set_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags);
534 		spin_unlock(&bo->lock);
535 
536 		ret = ttm_buffer_object_transfer(bo, &ghost_obj);
537 		if (ret)
538 			return ret;
539 
540 		/**
541 		 * If we're not moving to fixed memory, the TTM object
542 		 * needs to stay alive. Otherwhise hang it on the ghost
543 		 * bo to be unbound and destroyed.
544 		 */
545 
546 		if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED))
547 			ghost_obj->ttm = NULL;
548 		else
549 			bo->ttm = NULL;
550 
551 		ttm_bo_unreserve(ghost_obj);
552 		ttm_bo_unref(&ghost_obj);
553 	}
554 
555 	*old_mem = *new_mem;
556 	new_mem->mm_node = NULL;
557 	ttm_flag_masked(&save_flags, new_mem->placement, TTM_PL_MASK_MEMTYPE);
558 	return 0;
559 }
560 EXPORT_SYMBOL(ttm_bo_move_accel_cleanup);
561