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