8389972a1ed6f87510075bd85384ff2c913e7224
[linux-2.6-microblaze.git] / drivers / gpu / drm / ttm / ttm_bo_util.c
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(bo, ctx->interruptible, ctx->no_wait_gpu);
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_tt_unbind(bo->bdev, ttm);
71                 ttm_bo_free_old_node(bo);
72                 old_mem->mem_type = TTM_PL_SYSTEM;
73         }
74
75         ret = ttm_tt_set_placement_caching(ttm, new_mem->placement);
76         if (unlikely(ret != 0))
77                 return ret;
78
79         if (new_mem->mem_type != TTM_PL_SYSTEM) {
80                 ret = ttm_tt_bind(bo->bdev, ttm, new_mem, ctx);
81                 if (unlikely(ret != 0))
82                         return ret;
83         }
84
85         *old_mem = *new_mem;
86         new_mem->mm_node = NULL;
87
88         return 0;
89 }
90 EXPORT_SYMBOL(ttm_bo_move_ttm);
91
92 int ttm_mem_io_reserve(struct ttm_bo_device *bdev,
93                        struct ttm_resource *mem)
94 {
95         if (mem->bus.offset || mem->bus.addr)
96                 return 0;
97
98         mem->bus.is_iomem = false;
99         if (!bdev->driver->io_mem_reserve)
100                 return 0;
101
102         return bdev->driver->io_mem_reserve(bdev, mem);
103 }
104
105 void ttm_mem_io_free(struct ttm_bo_device *bdev,
106                      struct ttm_resource *mem)
107 {
108         if (!mem->bus.offset && !mem->bus.addr)
109                 return;
110
111         if (bdev->driver->io_mem_free)
112                 bdev->driver->io_mem_free(bdev, mem);
113
114         mem->bus.offset = 0;
115         mem->bus.addr = NULL;
116 }
117
118 static int ttm_resource_ioremap(struct ttm_bo_device *bdev,
119                                struct ttm_resource *mem,
120                                void **virtual)
121 {
122         int ret;
123         void *addr;
124
125         *virtual = NULL;
126         ret = ttm_mem_io_reserve(bdev, mem);
127         if (ret || !mem->bus.is_iomem)
128                 return ret;
129
130         if (mem->bus.addr) {
131                 addr = mem->bus.addr;
132         } else {
133                 size_t bus_size = (size_t)mem->num_pages << PAGE_SHIFT;
134
135                 if (mem->placement & TTM_PL_FLAG_WC)
136                         addr = ioremap_wc(mem->bus.offset, bus_size);
137                 else
138                         addr = ioremap(mem->bus.offset, bus_size);
139                 if (!addr) {
140                         ttm_mem_io_free(bdev, mem);
141                         return -ENOMEM;
142                 }
143         }
144         *virtual = addr;
145         return 0;
146 }
147
148 static void ttm_resource_iounmap(struct ttm_bo_device *bdev,
149                                 struct ttm_resource *mem,
150                                 void *virtual)
151 {
152         if (virtual && mem->bus.addr == NULL)
153                 iounmap(virtual);
154         ttm_mem_io_free(bdev, mem);
155 }
156
157 static int ttm_copy_io_page(void *dst, void *src, unsigned long page)
158 {
159         uint32_t *dstP =
160             (uint32_t *) ((unsigned long)dst + (page << PAGE_SHIFT));
161         uint32_t *srcP =
162             (uint32_t *) ((unsigned long)src + (page << PAGE_SHIFT));
163
164         int i;
165         for (i = 0; i < PAGE_SIZE / sizeof(uint32_t); ++i)
166                 iowrite32(ioread32(srcP++), dstP++);
167         return 0;
168 }
169
170 static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src,
171                                 unsigned long page,
172                                 pgprot_t prot)
173 {
174         struct page *d = ttm->pages[page];
175         void *dst;
176
177         if (!d)
178                 return -ENOMEM;
179
180         src = (void *)((unsigned long)src + (page << PAGE_SHIFT));
181         dst = kmap_atomic_prot(d, prot);
182         if (!dst)
183                 return -ENOMEM;
184
185         memcpy_fromio(dst, src, PAGE_SIZE);
186
187         kunmap_atomic(dst);
188
189         return 0;
190 }
191
192 static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst,
193                                 unsigned long page,
194                                 pgprot_t prot)
195 {
196         struct page *s = ttm->pages[page];
197         void *src;
198
199         if (!s)
200                 return -ENOMEM;
201
202         dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT));
203         src = kmap_atomic_prot(s, prot);
204         if (!src)
205                 return -ENOMEM;
206
207         memcpy_toio(dst, src, PAGE_SIZE);
208
209         kunmap_atomic(src);
210
211         return 0;
212 }
213
214 int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
215                        struct ttm_operation_ctx *ctx,
216                        struct ttm_resource *new_mem)
217 {
218         struct ttm_bo_device *bdev = bo->bdev;
219         struct ttm_resource_manager *man = ttm_manager_type(bdev, new_mem->mem_type);
220         struct ttm_tt *ttm = bo->ttm;
221         struct ttm_resource *old_mem = &bo->mem;
222         struct ttm_resource old_copy = *old_mem;
223         void *old_iomap;
224         void *new_iomap;
225         int ret;
226         unsigned long i;
227         unsigned long page;
228         unsigned long add = 0;
229         int dir;
230
231         ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu);
232         if (ret)
233                 return ret;
234
235         ret = ttm_resource_ioremap(bdev, old_mem, &old_iomap);
236         if (ret)
237                 return ret;
238         ret = ttm_resource_ioremap(bdev, new_mem, &new_iomap);
239         if (ret)
240                 goto out;
241
242         /*
243          * Single TTM move. NOP.
244          */
245         if (old_iomap == NULL && new_iomap == NULL)
246                 goto out2;
247
248         /*
249          * Don't move nonexistent data. Clear destination instead.
250          */
251         if (old_iomap == NULL &&
252             (ttm == NULL || (!ttm_tt_is_populated(ttm) &&
253                              !(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)))) {
254                 memset_io(new_iomap, 0, new_mem->num_pages*PAGE_SIZE);
255                 goto out2;
256         }
257
258         /*
259          * TTM might be null for moves within the same region.
260          */
261         if (ttm) {
262                 ret = ttm_tt_populate(bdev, ttm, ctx);
263                 if (ret)
264                         goto out1;
265         }
266
267         add = 0;
268         dir = 1;
269
270         if ((old_mem->mem_type == new_mem->mem_type) &&
271             (new_mem->start < old_mem->start + old_mem->size)) {
272                 dir = -1;
273                 add = new_mem->num_pages - 1;
274         }
275
276         for (i = 0; i < new_mem->num_pages; ++i) {
277                 page = i * dir + add;
278                 if (old_iomap == NULL) {
279                         pgprot_t prot = ttm_io_prot(old_mem->placement,
280                                                     PAGE_KERNEL);
281                         ret = ttm_copy_ttm_io_page(ttm, new_iomap, page,
282                                                    prot);
283                 } else if (new_iomap == NULL) {
284                         pgprot_t prot = ttm_io_prot(new_mem->placement,
285                                                     PAGE_KERNEL);
286                         ret = ttm_copy_io_ttm_page(ttm, old_iomap, page,
287                                                    prot);
288                 } else {
289                         ret = ttm_copy_io_page(new_iomap, old_iomap, page);
290                 }
291                 if (ret)
292                         goto out1;
293         }
294         mb();
295 out2:
296         old_copy = *old_mem;
297         *old_mem = *new_mem;
298         new_mem->mm_node = NULL;
299
300         if (!man->use_tt)
301                 ttm_bo_tt_destroy(bo);
302
303 out1:
304         ttm_resource_iounmap(bdev, old_mem, new_iomap);
305 out:
306         ttm_resource_iounmap(bdev, &old_copy, old_iomap);
307
308         /*
309          * On error, keep the mm node!
310          */
311         if (!ret)
312                 ttm_resource_free(bo, &old_copy);
313         return ret;
314 }
315 EXPORT_SYMBOL(ttm_bo_move_memcpy);
316
317 static void ttm_transfered_destroy(struct ttm_buffer_object *bo)
318 {
319         struct ttm_transfer_obj *fbo;
320
321         fbo = container_of(bo, struct ttm_transfer_obj, base);
322         ttm_bo_put(fbo->bo);
323         kfree(fbo);
324 }
325
326 /**
327  * ttm_buffer_object_transfer
328  *
329  * @bo: A pointer to a struct ttm_buffer_object.
330  * @new_obj: A pointer to a pointer to a newly created ttm_buffer_object,
331  * holding the data of @bo with the old placement.
332  *
333  * This is a utility function that may be called after an accelerated move
334  * has been scheduled. A new buffer object is created as a placeholder for
335  * the old data while it's being copied. When that buffer object is idle,
336  * it can be destroyed, releasing the space of the old placement.
337  * Returns:
338  * !0: Failure.
339  */
340
341 static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
342                                       struct ttm_buffer_object **new_obj)
343 {
344         struct ttm_transfer_obj *fbo;
345         int ret;
346
347         fbo = kmalloc(sizeof(*fbo), GFP_KERNEL);
348         if (!fbo)
349                 return -ENOMEM;
350
351         fbo->base = *bo;
352         fbo->base.mem.placement |= TTM_PL_FLAG_NO_EVICT;
353
354         ttm_bo_get(bo);
355         fbo->bo = bo;
356
357         /**
358          * Fix up members that we shouldn't copy directly:
359          * TODO: Explicit member copy would probably be better here.
360          */
361
362         atomic_inc(&ttm_bo_glob.bo_count);
363         INIT_LIST_HEAD(&fbo->base.ddestroy);
364         INIT_LIST_HEAD(&fbo->base.lru);
365         INIT_LIST_HEAD(&fbo->base.swap);
366         fbo->base.moving = NULL;
367         drm_vma_node_reset(&fbo->base.base.vma_node);
368
369         kref_init(&fbo->base.kref);
370         fbo->base.destroy = &ttm_transfered_destroy;
371         fbo->base.acc_size = 0;
372         if (bo->type != ttm_bo_type_sg)
373                 fbo->base.base.resv = &fbo->base.base._resv;
374
375         dma_resv_init(&fbo->base.base._resv);
376         fbo->base.base.dev = NULL;
377         ret = dma_resv_trylock(&fbo->base.base._resv);
378         WARN_ON(!ret);
379
380         *new_obj = &fbo->base;
381         return 0;
382 }
383
384 pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp)
385 {
386         /* Cached mappings need no adjustment */
387         if (caching_flags & TTM_PL_FLAG_CACHED)
388                 return tmp;
389
390 #if defined(__i386__) || defined(__x86_64__)
391         if (caching_flags & TTM_PL_FLAG_WC)
392                 tmp = pgprot_writecombine(tmp);
393         else if (boot_cpu_data.x86 > 3)
394                 tmp = pgprot_noncached(tmp);
395 #endif
396 #if defined(__ia64__) || defined(__arm__) || defined(__aarch64__) || \
397     defined(__powerpc__) || defined(__mips__)
398         if (caching_flags & TTM_PL_FLAG_WC)
399                 tmp = pgprot_writecombine(tmp);
400         else
401                 tmp = pgprot_noncached(tmp);
402 #endif
403 #if defined(__sparc__)
404         tmp = pgprot_noncached(tmp);
405 #endif
406         return tmp;
407 }
408 EXPORT_SYMBOL(ttm_io_prot);
409
410 static int ttm_bo_ioremap(struct ttm_buffer_object *bo,
411                           unsigned long offset,
412                           unsigned long size,
413                           struct ttm_bo_kmap_obj *map)
414 {
415         struct ttm_resource *mem = &bo->mem;
416
417         if (bo->mem.bus.addr) {
418                 map->bo_kmap_type = ttm_bo_map_premapped;
419                 map->virtual = (void *)(((u8 *)bo->mem.bus.addr) + offset);
420         } else {
421                 map->bo_kmap_type = ttm_bo_map_iomap;
422                 if (mem->placement & TTM_PL_FLAG_WC)
423                         map->virtual = ioremap_wc(bo->mem.bus.offset + offset,
424                                                   size);
425                 else
426                         map->virtual = ioremap(bo->mem.bus.offset + offset,
427                                                size);
428         }
429         return (!map->virtual) ? -ENOMEM : 0;
430 }
431
432 static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
433                            unsigned long start_page,
434                            unsigned long num_pages,
435                            struct ttm_bo_kmap_obj *map)
436 {
437         struct ttm_resource *mem = &bo->mem;
438         struct ttm_operation_ctx ctx = {
439                 .interruptible = false,
440                 .no_wait_gpu = false
441         };
442         struct ttm_tt *ttm = bo->ttm;
443         pgprot_t prot;
444         int ret;
445
446         BUG_ON(!ttm);
447
448         ret = ttm_tt_populate(bo->bdev, ttm, &ctx);
449         if (ret)
450                 return ret;
451
452         if (num_pages == 1 && (mem->placement & TTM_PL_FLAG_CACHED)) {
453                 /*
454                  * We're mapping a single page, and the desired
455                  * page protection is consistent with the bo.
456                  */
457
458                 map->bo_kmap_type = ttm_bo_map_kmap;
459                 map->page = ttm->pages[start_page];
460                 map->virtual = kmap(map->page);
461         } else {
462                 /*
463                  * We need to use vmap to get the desired page protection
464                  * or to make the buffer object look contiguous.
465                  */
466                 prot = ttm_io_prot(mem->placement, PAGE_KERNEL);
467                 map->bo_kmap_type = ttm_bo_map_vmap;
468                 map->virtual = vmap(ttm->pages + start_page, num_pages,
469                                     0, prot);
470         }
471         return (!map->virtual) ? -ENOMEM : 0;
472 }
473
474 int ttm_bo_kmap(struct ttm_buffer_object *bo,
475                 unsigned long start_page, unsigned long num_pages,
476                 struct ttm_bo_kmap_obj *map)
477 {
478         unsigned long offset, size;
479         int ret;
480
481         map->virtual = NULL;
482         map->bo = bo;
483         if (num_pages > bo->num_pages)
484                 return -EINVAL;
485         if (start_page > bo->num_pages)
486                 return -EINVAL;
487
488         ret = ttm_mem_io_reserve(bo->bdev, &bo->mem);
489         if (ret)
490                 return ret;
491         if (!bo->mem.bus.is_iomem) {
492                 return ttm_bo_kmap_ttm(bo, start_page, num_pages, map);
493         } else {
494                 offset = start_page << PAGE_SHIFT;
495                 size = num_pages << PAGE_SHIFT;
496                 return ttm_bo_ioremap(bo, offset, size, map);
497         }
498 }
499 EXPORT_SYMBOL(ttm_bo_kmap);
500
501 void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map)
502 {
503         if (!map->virtual)
504                 return;
505         switch (map->bo_kmap_type) {
506         case ttm_bo_map_iomap:
507                 iounmap(map->virtual);
508                 break;
509         case ttm_bo_map_vmap:
510                 vunmap(map->virtual);
511                 break;
512         case ttm_bo_map_kmap:
513                 kunmap(map->page);
514                 break;
515         case ttm_bo_map_premapped:
516                 break;
517         default:
518                 BUG();
519         }
520         ttm_mem_io_free(map->bo->bdev, &map->bo->mem);
521         map->virtual = NULL;
522         map->page = NULL;
523 }
524 EXPORT_SYMBOL(ttm_bo_kunmap);
525
526 int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
527                               struct dma_fence *fence,
528                               bool evict,
529                               struct ttm_resource *new_mem)
530 {
531         struct ttm_bo_device *bdev = bo->bdev;
532         struct ttm_resource_manager *man = ttm_manager_type(bdev, new_mem->mem_type);
533         struct ttm_resource *old_mem = &bo->mem;
534         int ret;
535         struct ttm_buffer_object *ghost_obj;
536
537         dma_resv_add_excl_fence(bo->base.resv, fence);
538         if (evict) {
539                 ret = ttm_bo_wait(bo, false, false);
540                 if (ret)
541                         return ret;
542
543                 if (!man->use_tt)
544                         ttm_bo_tt_destroy(bo);
545                 ttm_bo_free_old_node(bo);
546         } else {
547                 /**
548                  * This should help pipeline ordinary buffer moves.
549                  *
550                  * Hang old buffer memory on a new buffer object,
551                  * and leave it to be released when the GPU
552                  * operation has completed.
553                  */
554
555                 dma_fence_put(bo->moving);
556                 bo->moving = dma_fence_get(fence);
557
558                 ret = ttm_buffer_object_transfer(bo, &ghost_obj);
559                 if (ret)
560                         return ret;
561
562                 dma_resv_add_excl_fence(&ghost_obj->base._resv, fence);
563
564                 /**
565                  * If we're not moving to fixed memory, the TTM object
566                  * needs to stay alive. Otherwhise hang it on the ghost
567                  * bo to be unbound and destroyed.
568                  */
569
570                 if (man->use_tt)
571                         ghost_obj->ttm = NULL;
572                 else
573                         bo->ttm = NULL;
574
575                 dma_resv_unlock(&ghost_obj->base._resv);
576                 ttm_bo_put(ghost_obj);
577         }
578
579         *old_mem = *new_mem;
580         new_mem->mm_node = NULL;
581
582         return 0;
583 }
584 EXPORT_SYMBOL(ttm_bo_move_accel_cleanup);
585
586 int ttm_bo_pipeline_move(struct ttm_buffer_object *bo,
587                          struct dma_fence *fence, bool evict,
588                          struct ttm_resource *new_mem)
589 {
590         struct ttm_bo_device *bdev = bo->bdev;
591         struct ttm_resource *old_mem = &bo->mem;
592
593         struct ttm_resource_manager *from = ttm_manager_type(bdev, old_mem->mem_type);
594         struct ttm_resource_manager *to = ttm_manager_type(bdev, new_mem->mem_type);
595
596         int ret;
597
598         dma_resv_add_excl_fence(bo->base.resv, fence);
599
600         if (!evict) {
601                 struct ttm_buffer_object *ghost_obj;
602
603                 /**
604                  * This should help pipeline ordinary buffer moves.
605                  *
606                  * Hang old buffer memory on a new buffer object,
607                  * and leave it to be released when the GPU
608                  * operation has completed.
609                  */
610
611                 dma_fence_put(bo->moving);
612                 bo->moving = dma_fence_get(fence);
613
614                 ret = ttm_buffer_object_transfer(bo, &ghost_obj);
615                 if (ret)
616                         return ret;
617
618                 dma_resv_add_excl_fence(&ghost_obj->base._resv, fence);
619
620                 /**
621                  * If we're not moving to fixed memory, the TTM object
622                  * needs to stay alive. Otherwhise hang it on the ghost
623                  * bo to be unbound and destroyed.
624                  */
625
626                 if (to->use_tt)
627                         ghost_obj->ttm = NULL;
628                 else
629                         bo->ttm = NULL;
630
631                 dma_resv_unlock(&ghost_obj->base._resv);
632                 ttm_bo_put(ghost_obj);
633
634         } else if (!from->use_tt) {
635
636                 /**
637                  * BO doesn't have a TTM we need to bind/unbind. Just remember
638                  * this eviction and free up the allocation
639                  */
640
641                 spin_lock(&from->move_lock);
642                 if (!from->move || dma_fence_is_later(fence, from->move)) {
643                         dma_fence_put(from->move);
644                         from->move = dma_fence_get(fence);
645                 }
646                 spin_unlock(&from->move_lock);
647
648                 ttm_bo_free_old_node(bo);
649
650                 dma_fence_put(bo->moving);
651                 bo->moving = dma_fence_get(fence);
652
653         } else {
654                 /**
655                  * Last resort, wait for the move to be completed.
656                  *
657                  * Should never happen in pratice.
658                  */
659
660                 ret = ttm_bo_wait(bo, false, false);
661                 if (ret)
662                         return ret;
663
664                 if (!to->use_tt)
665                         ttm_bo_tt_destroy(bo);
666                 ttm_bo_free_old_node(bo);
667         }
668
669         *old_mem = *new_mem;
670         new_mem->mm_node = NULL;
671
672         return 0;
673 }
674 EXPORT_SYMBOL(ttm_bo_pipeline_move);
675
676 int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo)
677 {
678         struct ttm_buffer_object *ghost;
679         int ret;
680
681         ret = ttm_buffer_object_transfer(bo, &ghost);
682         if (ret)
683                 return ret;
684
685         ret = dma_resv_copy_fences(&ghost->base._resv, bo->base.resv);
686         /* Last resort, wait for the BO to be idle when we are OOM */
687         if (ret)
688                 ttm_bo_wait(bo, false, false);
689
690         memset(&bo->mem, 0, sizeof(bo->mem));
691         bo->mem.mem_type = TTM_PL_SYSTEM;
692         bo->ttm = NULL;
693
694         dma_resv_unlock(&ghost->base._resv);
695         ttm_bo_put(ghost);
696
697         return 0;
698 }
699