]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/tegra/gem.c
gpu: host1x: Support DMA mapping of buffers
[linux.git] / drivers / gpu / drm / tegra / gem.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * NVIDIA Tegra DRM GEM helper functions
4  *
5  * Copyright (C) 2012 Sascha Hauer, Pengutronix
6  * Copyright (C) 2013-2015 NVIDIA CORPORATION, All rights reserved.
7  *
8  * Based on the GEM/CMA helpers
9  *
10  * Copyright (c) 2011 Samsung Electronics Co., Ltd.
11  */
12
13 #include <linux/dma-buf.h>
14 #include <linux/iommu.h>
15
16 #include <drm/drm_drv.h>
17 #include <drm/drm_prime.h>
18 #include <drm/tegra_drm.h>
19
20 #include "drm.h"
21 #include "gem.h"
22
23 static void tegra_bo_put(struct host1x_bo *bo)
24 {
25         struct tegra_bo *obj = host1x_to_tegra_bo(bo);
26
27         drm_gem_object_put_unlocked(&obj->gem);
28 }
29
30 static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
31                                      dma_addr_t *phys)
32 {
33         struct tegra_bo *obj = host1x_to_tegra_bo(bo);
34         struct sg_table *sgt;
35         int err;
36
37         /*
38          * If we've manually mapped the buffer object through the IOMMU, make
39          * sure to return the IOVA address of our mapping.
40          */
41         if (phys && obj->mm) {
42                 *phys = obj->iova;
43                 return NULL;
44         }
45
46         /*
47          * If we don't have a mapping for this buffer yet, return an SG table
48          * so that host1x can do the mapping for us via the DMA API.
49          */
50         sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
51         if (!sgt)
52                 return ERR_PTR(-ENOMEM);
53
54         if (obj->pages) {
55                 err = sg_alloc_table_from_pages(sgt, obj->pages, obj->num_pages,
56                                                 0, obj->gem.size, GFP_KERNEL);
57                 if (err < 0)
58                         goto free;
59         } else {
60                 err = dma_get_sgtable(dev, sgt, obj->vaddr, obj->iova,
61                                       obj->gem.size);
62                 if (err < 0)
63                         goto free;
64         }
65
66         return sgt;
67
68 free:
69         kfree(sgt);
70         return ERR_PTR(err);
71 }
72
73 static void tegra_bo_unpin(struct device *dev, struct sg_table *sgt)
74 {
75         if (sgt) {
76                 sg_free_table(sgt);
77                 kfree(sgt);
78         }
79 }
80
81 static void *tegra_bo_mmap(struct host1x_bo *bo)
82 {
83         struct tegra_bo *obj = host1x_to_tegra_bo(bo);
84
85         if (obj->vaddr)
86                 return obj->vaddr;
87         else if (obj->gem.import_attach)
88                 return dma_buf_vmap(obj->gem.import_attach->dmabuf);
89         else
90                 return vmap(obj->pages, obj->num_pages, VM_MAP,
91                             pgprot_writecombine(PAGE_KERNEL));
92 }
93
94 static void tegra_bo_munmap(struct host1x_bo *bo, void *addr)
95 {
96         struct tegra_bo *obj = host1x_to_tegra_bo(bo);
97
98         if (obj->vaddr)
99                 return;
100         else if (obj->gem.import_attach)
101                 dma_buf_vunmap(obj->gem.import_attach->dmabuf, addr);
102         else
103                 vunmap(addr);
104 }
105
106 static void *tegra_bo_kmap(struct host1x_bo *bo, unsigned int page)
107 {
108         struct tegra_bo *obj = host1x_to_tegra_bo(bo);
109
110         if (obj->vaddr)
111                 return obj->vaddr + page * PAGE_SIZE;
112         else if (obj->gem.import_attach)
113                 return dma_buf_kmap(obj->gem.import_attach->dmabuf, page);
114         else
115                 return vmap(obj->pages + page, 1, VM_MAP,
116                             pgprot_writecombine(PAGE_KERNEL));
117 }
118
119 static void tegra_bo_kunmap(struct host1x_bo *bo, unsigned int page,
120                             void *addr)
121 {
122         struct tegra_bo *obj = host1x_to_tegra_bo(bo);
123
124         if (obj->vaddr)
125                 return;
126         else if (obj->gem.import_attach)
127                 dma_buf_kunmap(obj->gem.import_attach->dmabuf, page, addr);
128         else
129                 vunmap(addr);
130 }
131
132 static struct host1x_bo *tegra_bo_get(struct host1x_bo *bo)
133 {
134         struct tegra_bo *obj = host1x_to_tegra_bo(bo);
135
136         drm_gem_object_get(&obj->gem);
137
138         return bo;
139 }
140
141 static const struct host1x_bo_ops tegra_bo_ops = {
142         .get = tegra_bo_get,
143         .put = tegra_bo_put,
144         .pin = tegra_bo_pin,
145         .unpin = tegra_bo_unpin,
146         .mmap = tegra_bo_mmap,
147         .munmap = tegra_bo_munmap,
148         .kmap = tegra_bo_kmap,
149         .kunmap = tegra_bo_kunmap,
150 };
151
152 static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo)
153 {
154         int prot = IOMMU_READ | IOMMU_WRITE;
155         int err;
156
157         if (bo->mm)
158                 return -EBUSY;
159
160         bo->mm = kzalloc(sizeof(*bo->mm), GFP_KERNEL);
161         if (!bo->mm)
162                 return -ENOMEM;
163
164         mutex_lock(&tegra->mm_lock);
165
166         err = drm_mm_insert_node_generic(&tegra->mm,
167                                          bo->mm, bo->gem.size, PAGE_SIZE, 0, 0);
168         if (err < 0) {
169                 dev_err(tegra->drm->dev, "out of I/O virtual memory: %d\n",
170                         err);
171                 goto unlock;
172         }
173
174         bo->iova = bo->mm->start;
175
176         bo->size = iommu_map_sg(tegra->domain, bo->iova, bo->sgt->sgl,
177                                 bo->sgt->nents, prot);
178         if (!bo->size) {
179                 dev_err(tegra->drm->dev, "failed to map buffer\n");
180                 err = -ENOMEM;
181                 goto remove;
182         }
183
184         mutex_unlock(&tegra->mm_lock);
185
186         return 0;
187
188 remove:
189         drm_mm_remove_node(bo->mm);
190 unlock:
191         mutex_unlock(&tegra->mm_lock);
192         kfree(bo->mm);
193         return err;
194 }
195
196 static int tegra_bo_iommu_unmap(struct tegra_drm *tegra, struct tegra_bo *bo)
197 {
198         if (!bo->mm)
199                 return 0;
200
201         mutex_lock(&tegra->mm_lock);
202         iommu_unmap(tegra->domain, bo->iova, bo->size);
203         drm_mm_remove_node(bo->mm);
204         mutex_unlock(&tegra->mm_lock);
205
206         kfree(bo->mm);
207
208         return 0;
209 }
210
211 static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm,
212                                               size_t size)
213 {
214         struct tegra_bo *bo;
215         int err;
216
217         bo = kzalloc(sizeof(*bo), GFP_KERNEL);
218         if (!bo)
219                 return ERR_PTR(-ENOMEM);
220
221         host1x_bo_init(&bo->base, &tegra_bo_ops);
222         size = round_up(size, PAGE_SIZE);
223
224         err = drm_gem_object_init(drm, &bo->gem, size);
225         if (err < 0)
226                 goto free;
227
228         err = drm_gem_create_mmap_offset(&bo->gem);
229         if (err < 0)
230                 goto release;
231
232         return bo;
233
234 release:
235         drm_gem_object_release(&bo->gem);
236 free:
237         kfree(bo);
238         return ERR_PTR(err);
239 }
240
241 static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo)
242 {
243         if (bo->pages) {
244                 dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
245                              DMA_FROM_DEVICE);
246                 drm_gem_put_pages(&bo->gem, bo->pages, true, true);
247                 sg_free_table(bo->sgt);
248                 kfree(bo->sgt);
249         } else if (bo->vaddr) {
250                 dma_free_wc(drm->dev, bo->gem.size, bo->vaddr, bo->iova);
251         }
252 }
253
254 static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
255 {
256         int err;
257
258         bo->pages = drm_gem_get_pages(&bo->gem);
259         if (IS_ERR(bo->pages))
260                 return PTR_ERR(bo->pages);
261
262         bo->num_pages = bo->gem.size >> PAGE_SHIFT;
263
264         bo->sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages);
265         if (IS_ERR(bo->sgt)) {
266                 err = PTR_ERR(bo->sgt);
267                 goto put_pages;
268         }
269
270         err = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
271                          DMA_FROM_DEVICE);
272         if (err == 0) {
273                 err = -EFAULT;
274                 goto free_sgt;
275         }
276
277         return 0;
278
279 free_sgt:
280         sg_free_table(bo->sgt);
281         kfree(bo->sgt);
282 put_pages:
283         drm_gem_put_pages(&bo->gem, bo->pages, false, false);
284         return err;
285 }
286
287 static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo)
288 {
289         struct tegra_drm *tegra = drm->dev_private;
290         int err;
291
292         if (tegra->domain) {
293                 err = tegra_bo_get_pages(drm, bo);
294                 if (err < 0)
295                         return err;
296
297                 err = tegra_bo_iommu_map(tegra, bo);
298                 if (err < 0) {
299                         tegra_bo_free(drm, bo);
300                         return err;
301                 }
302         } else {
303                 size_t size = bo->gem.size;
304
305                 bo->vaddr = dma_alloc_wc(drm->dev, size, &bo->iova,
306                                          GFP_KERNEL | __GFP_NOWARN);
307                 if (!bo->vaddr) {
308                         dev_err(drm->dev,
309                                 "failed to allocate buffer of size %zu\n",
310                                 size);
311                         return -ENOMEM;
312                 }
313         }
314
315         return 0;
316 }
317
318 struct tegra_bo *tegra_bo_create(struct drm_device *drm, size_t size,
319                                  unsigned long flags)
320 {
321         struct tegra_bo *bo;
322         int err;
323
324         bo = tegra_bo_alloc_object(drm, size);
325         if (IS_ERR(bo))
326                 return bo;
327
328         err = tegra_bo_alloc(drm, bo);
329         if (err < 0)
330                 goto release;
331
332         if (flags & DRM_TEGRA_GEM_CREATE_TILED)
333                 bo->tiling.mode = TEGRA_BO_TILING_MODE_TILED;
334
335         if (flags & DRM_TEGRA_GEM_CREATE_BOTTOM_UP)
336                 bo->flags |= TEGRA_BO_BOTTOM_UP;
337
338         return bo;
339
340 release:
341         drm_gem_object_release(&bo->gem);
342         kfree(bo);
343         return ERR_PTR(err);
344 }
345
346 struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file,
347                                              struct drm_device *drm,
348                                              size_t size,
349                                              unsigned long flags,
350                                              u32 *handle)
351 {
352         struct tegra_bo *bo;
353         int err;
354
355         bo = tegra_bo_create(drm, size, flags);
356         if (IS_ERR(bo))
357                 return bo;
358
359         err = drm_gem_handle_create(file, &bo->gem, handle);
360         if (err) {
361                 tegra_bo_free_object(&bo->gem);
362                 return ERR_PTR(err);
363         }
364
365         drm_gem_object_put_unlocked(&bo->gem);
366
367         return bo;
368 }
369
370 static struct tegra_bo *tegra_bo_import(struct drm_device *drm,
371                                         struct dma_buf *buf)
372 {
373         struct tegra_drm *tegra = drm->dev_private;
374         struct dma_buf_attachment *attach;
375         struct tegra_bo *bo;
376         int err;
377
378         bo = tegra_bo_alloc_object(drm, buf->size);
379         if (IS_ERR(bo))
380                 return bo;
381
382         attach = dma_buf_attach(buf, drm->dev);
383         if (IS_ERR(attach)) {
384                 err = PTR_ERR(attach);
385                 goto free;
386         }
387
388         get_dma_buf(buf);
389
390         bo->sgt = dma_buf_map_attachment(attach, DMA_TO_DEVICE);
391         if (IS_ERR(bo->sgt)) {
392                 err = PTR_ERR(bo->sgt);
393                 goto detach;
394         }
395
396         if (tegra->domain) {
397                 err = tegra_bo_iommu_map(tegra, bo);
398                 if (err < 0)
399                         goto detach;
400         } else {
401                 if (bo->sgt->nents > 1) {
402                         err = -EINVAL;
403                         goto detach;
404                 }
405
406                 bo->iova = sg_dma_address(bo->sgt->sgl);
407         }
408
409         bo->gem.import_attach = attach;
410
411         return bo;
412
413 detach:
414         if (!IS_ERR_OR_NULL(bo->sgt))
415                 dma_buf_unmap_attachment(attach, bo->sgt, DMA_TO_DEVICE);
416
417         dma_buf_detach(buf, attach);
418         dma_buf_put(buf);
419 free:
420         drm_gem_object_release(&bo->gem);
421         kfree(bo);
422         return ERR_PTR(err);
423 }
424
425 void tegra_bo_free_object(struct drm_gem_object *gem)
426 {
427         struct tegra_drm *tegra = gem->dev->dev_private;
428         struct tegra_bo *bo = to_tegra_bo(gem);
429
430         if (tegra->domain)
431                 tegra_bo_iommu_unmap(tegra, bo);
432
433         if (gem->import_attach) {
434                 dma_buf_unmap_attachment(gem->import_attach, bo->sgt,
435                                          DMA_TO_DEVICE);
436                 drm_prime_gem_destroy(gem, NULL);
437         } else {
438                 tegra_bo_free(gem->dev, bo);
439         }
440
441         drm_gem_object_release(gem);
442         kfree(bo);
443 }
444
445 int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
446                          struct drm_mode_create_dumb *args)
447 {
448         unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
449         struct tegra_drm *tegra = drm->dev_private;
450         struct tegra_bo *bo;
451
452         args->pitch = round_up(min_pitch, tegra->pitch_align);
453         args->size = args->pitch * args->height;
454
455         bo = tegra_bo_create_with_handle(file, drm, args->size, 0,
456                                          &args->handle);
457         if (IS_ERR(bo))
458                 return PTR_ERR(bo);
459
460         return 0;
461 }
462
463 static vm_fault_t tegra_bo_fault(struct vm_fault *vmf)
464 {
465         struct vm_area_struct *vma = vmf->vma;
466         struct drm_gem_object *gem = vma->vm_private_data;
467         struct tegra_bo *bo = to_tegra_bo(gem);
468         struct page *page;
469         pgoff_t offset;
470
471         if (!bo->pages)
472                 return VM_FAULT_SIGBUS;
473
474         offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
475         page = bo->pages[offset];
476
477         return vmf_insert_page(vma, vmf->address, page);
478 }
479
480 const struct vm_operations_struct tegra_bo_vm_ops = {
481         .fault = tegra_bo_fault,
482         .open = drm_gem_vm_open,
483         .close = drm_gem_vm_close,
484 };
485
486 int __tegra_gem_mmap(struct drm_gem_object *gem, struct vm_area_struct *vma)
487 {
488         struct tegra_bo *bo = to_tegra_bo(gem);
489
490         if (!bo->pages) {
491                 unsigned long vm_pgoff = vma->vm_pgoff;
492                 int err;
493
494                 /*
495                  * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(),
496                  * and set the vm_pgoff (used as a fake buffer offset by DRM)
497                  * to 0 as we want to map the whole buffer.
498                  */
499                 vma->vm_flags &= ~VM_PFNMAP;
500                 vma->vm_pgoff = 0;
501
502                 err = dma_mmap_wc(gem->dev->dev, vma, bo->vaddr, bo->iova,
503                                   gem->size);
504                 if (err < 0) {
505                         drm_gem_vm_close(vma);
506                         return err;
507                 }
508
509                 vma->vm_pgoff = vm_pgoff;
510         } else {
511                 pgprot_t prot = vm_get_page_prot(vma->vm_flags);
512
513                 vma->vm_flags |= VM_MIXEDMAP;
514                 vma->vm_flags &= ~VM_PFNMAP;
515
516                 vma->vm_page_prot = pgprot_writecombine(prot);
517         }
518
519         return 0;
520 }
521
522 int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
523 {
524         struct drm_gem_object *gem;
525         int err;
526
527         err = drm_gem_mmap(file, vma);
528         if (err < 0)
529                 return err;
530
531         gem = vma->vm_private_data;
532
533         return __tegra_gem_mmap(gem, vma);
534 }
535
536 static struct sg_table *
537 tegra_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
538                             enum dma_data_direction dir)
539 {
540         struct drm_gem_object *gem = attach->dmabuf->priv;
541         struct tegra_bo *bo = to_tegra_bo(gem);
542         struct sg_table *sgt;
543
544         sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
545         if (!sgt)
546                 return NULL;
547
548         if (bo->pages) {
549                 if (sg_alloc_table_from_pages(sgt, bo->pages, bo->num_pages,
550                                               0, gem->size, GFP_KERNEL) < 0)
551                         goto free;
552         } else {
553                 if (dma_get_sgtable(attach->dev, sgt, bo->vaddr, bo->iova,
554                                     gem->size) < 0)
555                         goto free;
556         }
557
558         if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
559                 goto free;
560
561         return sgt;
562
563 free:
564         sg_free_table(sgt);
565         kfree(sgt);
566         return NULL;
567 }
568
569 static void tegra_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
570                                           struct sg_table *sgt,
571                                           enum dma_data_direction dir)
572 {
573         struct drm_gem_object *gem = attach->dmabuf->priv;
574         struct tegra_bo *bo = to_tegra_bo(gem);
575
576         if (bo->pages)
577                 dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
578
579         sg_free_table(sgt);
580         kfree(sgt);
581 }
582
583 static void tegra_gem_prime_release(struct dma_buf *buf)
584 {
585         drm_gem_dmabuf_release(buf);
586 }
587
588 static int tegra_gem_prime_begin_cpu_access(struct dma_buf *buf,
589                                             enum dma_data_direction direction)
590 {
591         struct drm_gem_object *gem = buf->priv;
592         struct tegra_bo *bo = to_tegra_bo(gem);
593         struct drm_device *drm = gem->dev;
594
595         if (bo->pages)
596                 dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->nents,
597                                     DMA_FROM_DEVICE);
598
599         return 0;
600 }
601
602 static int tegra_gem_prime_end_cpu_access(struct dma_buf *buf,
603                                           enum dma_data_direction direction)
604 {
605         struct drm_gem_object *gem = buf->priv;
606         struct tegra_bo *bo = to_tegra_bo(gem);
607         struct drm_device *drm = gem->dev;
608
609         if (bo->pages)
610                 dma_sync_sg_for_device(drm->dev, bo->sgt->sgl, bo->sgt->nents,
611                                        DMA_TO_DEVICE);
612
613         return 0;
614 }
615
616 static void *tegra_gem_prime_kmap(struct dma_buf *buf, unsigned long page)
617 {
618         return NULL;
619 }
620
621 static void tegra_gem_prime_kunmap(struct dma_buf *buf, unsigned long page,
622                                    void *addr)
623 {
624 }
625
626 static int tegra_gem_prime_mmap(struct dma_buf *buf, struct vm_area_struct *vma)
627 {
628         struct drm_gem_object *gem = buf->priv;
629         int err;
630
631         err = drm_gem_mmap_obj(gem, gem->size, vma);
632         if (err < 0)
633                 return err;
634
635         return __tegra_gem_mmap(gem, vma);
636 }
637
638 static void *tegra_gem_prime_vmap(struct dma_buf *buf)
639 {
640         struct drm_gem_object *gem = buf->priv;
641         struct tegra_bo *bo = to_tegra_bo(gem);
642
643         return bo->vaddr;
644 }
645
646 static void tegra_gem_prime_vunmap(struct dma_buf *buf, void *vaddr)
647 {
648 }
649
650 static const struct dma_buf_ops tegra_gem_prime_dmabuf_ops = {
651         .map_dma_buf = tegra_gem_prime_map_dma_buf,
652         .unmap_dma_buf = tegra_gem_prime_unmap_dma_buf,
653         .release = tegra_gem_prime_release,
654         .begin_cpu_access = tegra_gem_prime_begin_cpu_access,
655         .end_cpu_access = tegra_gem_prime_end_cpu_access,
656         .map = tegra_gem_prime_kmap,
657         .unmap = tegra_gem_prime_kunmap,
658         .mmap = tegra_gem_prime_mmap,
659         .vmap = tegra_gem_prime_vmap,
660         .vunmap = tegra_gem_prime_vunmap,
661 };
662
663 struct dma_buf *tegra_gem_prime_export(struct drm_gem_object *gem,
664                                        int flags)
665 {
666         DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
667
668         exp_info.exp_name = KBUILD_MODNAME;
669         exp_info.owner = gem->dev->driver->fops->owner;
670         exp_info.ops = &tegra_gem_prime_dmabuf_ops;
671         exp_info.size = gem->size;
672         exp_info.flags = flags;
673         exp_info.priv = gem;
674
675         return drm_gem_dmabuf_export(gem->dev, &exp_info);
676 }
677
678 struct drm_gem_object *tegra_gem_prime_import(struct drm_device *drm,
679                                               struct dma_buf *buf)
680 {
681         struct tegra_bo *bo;
682
683         if (buf->ops == &tegra_gem_prime_dmabuf_ops) {
684                 struct drm_gem_object *gem = buf->priv;
685
686                 if (gem->dev == drm) {
687                         drm_gem_object_get(gem);
688                         return gem;
689                 }
690         }
691
692         bo = tegra_bo_import(drm, buf);
693         if (IS_ERR(bo))
694                 return ERR_CAST(bo);
695
696         return &bo->gem;
697 }