GNU Linux-libre 4.4.284-gnu1
[releases.git] / drivers / gpu / drm / exynos / exynos_drm_gem.c
1 /* exynos_drm_gem.c
2  *
3  * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4  * Author: Inki Dae <inki.dae@samsung.com>
5  *
6  * This program is free software; you can redistribute  it and/or modify it
7  * under  the terms of  the GNU General  Public License as published by the
8  * Free Software Foundation;  either version 2 of the  License, or (at your
9  * option) any later version.
10  */
11
12 #include <drm/drmP.h>
13 #include <drm/drm_vma_manager.h>
14
15 #include <linux/shmem_fs.h>
16 #include <linux/dma-buf.h>
17 #include <drm/exynos_drm.h>
18
19 #include "exynos_drm_drv.h"
20 #include "exynos_drm_gem.h"
21 #include "exynos_drm_iommu.h"
22
23 static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
24 {
25         struct drm_device *dev = exynos_gem->base.dev;
26         enum dma_attr attr;
27         unsigned int nr_pages;
28         struct sg_table sgt;
29         int ret = -ENOMEM;
30
31         if (exynos_gem->dma_addr) {
32                 DRM_DEBUG_KMS("already allocated.\n");
33                 return 0;
34         }
35
36         init_dma_attrs(&exynos_gem->dma_attrs);
37
38         /*
39          * if EXYNOS_BO_CONTIG, fully physically contiguous memory
40          * region will be allocated else physically contiguous
41          * as possible.
42          */
43         if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
44                 dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &exynos_gem->dma_attrs);
45
46         /*
47          * if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping
48          * else cachable mapping.
49          */
50         if (exynos_gem->flags & EXYNOS_BO_WC ||
51                         !(exynos_gem->flags & EXYNOS_BO_CACHABLE))
52                 attr = DMA_ATTR_WRITE_COMBINE;
53         else
54                 attr = DMA_ATTR_NON_CONSISTENT;
55
56         dma_set_attr(attr, &exynos_gem->dma_attrs);
57         dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &exynos_gem->dma_attrs);
58
59         nr_pages = exynos_gem->size >> PAGE_SHIFT;
60
61         exynos_gem->pages = drm_calloc_large(nr_pages, sizeof(struct page *));
62         if (!exynos_gem->pages) {
63                 DRM_ERROR("failed to allocate pages.\n");
64                 return -ENOMEM;
65         }
66
67         exynos_gem->cookie = dma_alloc_attrs(dev->dev, exynos_gem->size,
68                                              &exynos_gem->dma_addr, GFP_KERNEL,
69                                              &exynos_gem->dma_attrs);
70         if (!exynos_gem->cookie) {
71                 DRM_ERROR("failed to allocate buffer.\n");
72                 goto err_free;
73         }
74
75         ret = dma_get_sgtable_attrs(dev->dev, &sgt, exynos_gem->cookie,
76                                     exynos_gem->dma_addr, exynos_gem->size,
77                                     &exynos_gem->dma_attrs);
78         if (ret < 0) {
79                 DRM_ERROR("failed to get sgtable.\n");
80                 goto err_dma_free;
81         }
82
83         if (drm_prime_sg_to_page_addr_arrays(&sgt, exynos_gem->pages, NULL,
84                                              nr_pages)) {
85                 DRM_ERROR("invalid sgtable.\n");
86                 ret = -EINVAL;
87                 goto err_sgt_free;
88         }
89
90         sg_free_table(&sgt);
91
92         DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
93                         (unsigned long)exynos_gem->dma_addr, exynos_gem->size);
94
95         return 0;
96
97 err_sgt_free:
98         sg_free_table(&sgt);
99 err_dma_free:
100         dma_free_attrs(dev->dev, exynos_gem->size, exynos_gem->cookie,
101                        exynos_gem->dma_addr, &exynos_gem->dma_attrs);
102 err_free:
103         drm_free_large(exynos_gem->pages);
104
105         return ret;
106 }
107
108 static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem)
109 {
110         struct drm_device *dev = exynos_gem->base.dev;
111
112         if (!exynos_gem->dma_addr) {
113                 DRM_DEBUG_KMS("dma_addr is invalid.\n");
114                 return;
115         }
116
117         DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
118                         (unsigned long)exynos_gem->dma_addr, exynos_gem->size);
119
120         dma_free_attrs(dev->dev, exynos_gem->size, exynos_gem->cookie,
121                         (dma_addr_t)exynos_gem->dma_addr,
122                         &exynos_gem->dma_attrs);
123
124         drm_free_large(exynos_gem->pages);
125 }
126
127 static int exynos_drm_gem_handle_create(struct drm_gem_object *obj,
128                                         struct drm_file *file_priv,
129                                         unsigned int *handle)
130 {
131         int ret;
132
133         /*
134          * allocate a id of idr table where the obj is registered
135          * and handle has the id what user can see.
136          */
137         ret = drm_gem_handle_create(file_priv, obj, handle);
138         if (ret)
139                 return ret;
140
141         DRM_DEBUG_KMS("gem handle = 0x%x\n", *handle);
142
143         /* drop reference from allocate - handle holds it now. */
144         drm_gem_object_unreference_unlocked(obj);
145
146         return 0;
147 }
148
149 void exynos_drm_gem_destroy(struct exynos_drm_gem *exynos_gem)
150 {
151         struct drm_gem_object *obj = &exynos_gem->base;
152
153         DRM_DEBUG_KMS("handle count = %d\n", obj->handle_count);
154
155         /*
156          * do not release memory region from exporter.
157          *
158          * the region will be released by exporter
159          * once dmabuf's refcount becomes 0.
160          */
161         if (obj->import_attach)
162                 drm_prime_gem_destroy(obj, exynos_gem->sgt);
163         else
164                 exynos_drm_free_buf(exynos_gem);
165
166         /* release file pointer to gem object. */
167         drm_gem_object_release(obj);
168
169         kfree(exynos_gem);
170 }
171
172 unsigned long exynos_drm_gem_get_size(struct drm_device *dev,
173                                                 unsigned int gem_handle,
174                                                 struct drm_file *file_priv)
175 {
176         struct exynos_drm_gem *exynos_gem;
177         struct drm_gem_object *obj;
178
179         obj = drm_gem_object_lookup(dev, file_priv, gem_handle);
180         if (!obj) {
181                 DRM_ERROR("failed to lookup gem object.\n");
182                 return 0;
183         }
184
185         exynos_gem = to_exynos_gem(obj);
186
187         drm_gem_object_unreference_unlocked(obj);
188
189         return exynos_gem->size;
190 }
191
192 static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev,
193                                                   unsigned long size)
194 {
195         struct exynos_drm_gem *exynos_gem;
196         struct drm_gem_object *obj;
197         int ret;
198
199         exynos_gem = kzalloc(sizeof(*exynos_gem), GFP_KERNEL);
200         if (!exynos_gem)
201                 return ERR_PTR(-ENOMEM);
202
203         exynos_gem->size = size;
204         obj = &exynos_gem->base;
205
206         ret = drm_gem_object_init(dev, obj, size);
207         if (ret < 0) {
208                 DRM_ERROR("failed to initialize gem object\n");
209                 kfree(exynos_gem);
210                 return ERR_PTR(ret);
211         }
212
213         ret = drm_gem_create_mmap_offset(obj);
214         if (ret < 0) {
215                 drm_gem_object_release(obj);
216                 kfree(exynos_gem);
217                 return ERR_PTR(ret);
218         }
219
220         DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp);
221
222         return exynos_gem;
223 }
224
225 struct exynos_drm_gem *exynos_drm_gem_create(struct drm_device *dev,
226                                              unsigned int flags,
227                                              unsigned long size)
228 {
229         struct exynos_drm_gem *exynos_gem;
230         int ret;
231
232         if (flags & ~(EXYNOS_BO_MASK)) {
233                 DRM_ERROR("invalid flags.\n");
234                 return ERR_PTR(-EINVAL);
235         }
236
237         if (!size) {
238                 DRM_ERROR("invalid size.\n");
239                 return ERR_PTR(-EINVAL);
240         }
241
242         size = roundup(size, PAGE_SIZE);
243
244         exynos_gem = exynos_drm_gem_init(dev, size);
245         if (IS_ERR(exynos_gem))
246                 return exynos_gem;
247
248         if (!is_drm_iommu_supported(dev) && (flags & EXYNOS_BO_NONCONTIG)) {
249                 /*
250                  * when no IOMMU is available, all allocated buffers are
251                  * contiguous anyway, so drop EXYNOS_BO_NONCONTIG flag
252                  */
253                 flags &= ~EXYNOS_BO_NONCONTIG;
254                 DRM_WARN("Non-contiguous allocation is not supported without IOMMU, falling back to contiguous buffer\n");
255         }
256
257         /* set memory type and cache attribute from user side. */
258         exynos_gem->flags = flags;
259
260         ret = exynos_drm_alloc_buf(exynos_gem);
261         if (ret < 0) {
262                 drm_gem_object_release(&exynos_gem->base);
263                 kfree(exynos_gem);
264                 return ERR_PTR(ret);
265         }
266
267         return exynos_gem;
268 }
269
270 int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
271                                 struct drm_file *file_priv)
272 {
273         struct drm_exynos_gem_create *args = data;
274         struct exynos_drm_gem *exynos_gem;
275         int ret;
276
277         exynos_gem = exynos_drm_gem_create(dev, args->flags, args->size);
278         if (IS_ERR(exynos_gem))
279                 return PTR_ERR(exynos_gem);
280
281         ret = exynos_drm_gem_handle_create(&exynos_gem->base, file_priv,
282                                            &args->handle);
283         if (ret) {
284                 exynos_drm_gem_destroy(exynos_gem);
285                 return ret;
286         }
287
288         return 0;
289 }
290
291 dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
292                                         unsigned int gem_handle,
293                                         struct drm_file *filp)
294 {
295         struct exynos_drm_gem *exynos_gem;
296         struct drm_gem_object *obj;
297
298         obj = drm_gem_object_lookup(dev, filp, gem_handle);
299         if (!obj) {
300                 DRM_ERROR("failed to lookup gem object.\n");
301                 return ERR_PTR(-EINVAL);
302         }
303
304         exynos_gem = to_exynos_gem(obj);
305
306         return &exynos_gem->dma_addr;
307 }
308
309 void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
310                                         unsigned int gem_handle,
311                                         struct drm_file *filp)
312 {
313         struct drm_gem_object *obj;
314
315         obj = drm_gem_object_lookup(dev, filp, gem_handle);
316         if (!obj) {
317                 DRM_ERROR("failed to lookup gem object.\n");
318                 return;
319         }
320
321         drm_gem_object_unreference_unlocked(obj);
322
323         /*
324          * decrease obj->refcount one more time because we has already
325          * increased it at exynos_drm_gem_get_dma_addr().
326          */
327         drm_gem_object_unreference_unlocked(obj);
328 }
329
330 static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
331                                       struct vm_area_struct *vma)
332 {
333         struct drm_device *drm_dev = exynos_gem->base.dev;
334         unsigned long vm_size;
335         int ret;
336
337         vma->vm_flags &= ~VM_PFNMAP;
338         vma->vm_pgoff = 0;
339
340         vm_size = vma->vm_end - vma->vm_start;
341
342         /* check if user-requested size is valid. */
343         if (vm_size > exynos_gem->size)
344                 return -EINVAL;
345
346         ret = dma_mmap_attrs(drm_dev->dev, vma, exynos_gem->pages,
347                              exynos_gem->dma_addr, exynos_gem->size,
348                              &exynos_gem->dma_attrs);
349         if (ret < 0) {
350                 DRM_ERROR("failed to mmap.\n");
351                 return ret;
352         }
353
354         return 0;
355 }
356
357 int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
358                                       struct drm_file *file_priv)
359 {
360         struct exynos_drm_gem *exynos_gem;
361         struct drm_exynos_gem_info *args = data;
362         struct drm_gem_object *obj;
363
364         mutex_lock(&dev->struct_mutex);
365
366         obj = drm_gem_object_lookup(dev, file_priv, args->handle);
367         if (!obj) {
368                 DRM_ERROR("failed to lookup gem object.\n");
369                 mutex_unlock(&dev->struct_mutex);
370                 return -EINVAL;
371         }
372
373         exynos_gem = to_exynos_gem(obj);
374
375         args->flags = exynos_gem->flags;
376         args->size = exynos_gem->size;
377
378         drm_gem_object_unreference(obj);
379         mutex_unlock(&dev->struct_mutex);
380
381         return 0;
382 }
383
384 int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
385                                 struct sg_table *sgt,
386                                 enum dma_data_direction dir)
387 {
388         int nents;
389
390         mutex_lock(&drm_dev->struct_mutex);
391
392         nents = dma_map_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
393         if (!nents) {
394                 DRM_ERROR("failed to map sgl with dma.\n");
395                 mutex_unlock(&drm_dev->struct_mutex);
396                 return nents;
397         }
398
399         mutex_unlock(&drm_dev->struct_mutex);
400         return 0;
401 }
402
403 void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
404                                 struct sg_table *sgt,
405                                 enum dma_data_direction dir)
406 {
407         dma_unmap_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
408 }
409
410 void exynos_drm_gem_free_object(struct drm_gem_object *obj)
411 {
412         exynos_drm_gem_destroy(to_exynos_gem(obj));
413 }
414
415 int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
416                                struct drm_device *dev,
417                                struct drm_mode_create_dumb *args)
418 {
419         struct exynos_drm_gem *exynos_gem;
420         unsigned int flags;
421         int ret;
422
423         /*
424          * allocate memory to be used for framebuffer.
425          * - this callback would be called by user application
426          *      with DRM_IOCTL_MODE_CREATE_DUMB command.
427          */
428
429         args->pitch = args->width * ((args->bpp + 7) / 8);
430         args->size = args->pitch * args->height;
431
432         if (is_drm_iommu_supported(dev))
433                 flags = EXYNOS_BO_NONCONTIG | EXYNOS_BO_WC;
434         else
435                 flags = EXYNOS_BO_CONTIG | EXYNOS_BO_WC;
436
437         exynos_gem = exynos_drm_gem_create(dev, flags, args->size);
438         if (IS_ERR(exynos_gem)) {
439                 dev_warn(dev->dev, "FB allocation failed.\n");
440                 return PTR_ERR(exynos_gem);
441         }
442
443         ret = exynos_drm_gem_handle_create(&exynos_gem->base, file_priv,
444                                            &args->handle);
445         if (ret) {
446                 exynos_drm_gem_destroy(exynos_gem);
447                 return ret;
448         }
449
450         return 0;
451 }
452
453 int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
454                                    struct drm_device *dev, uint32_t handle,
455                                    uint64_t *offset)
456 {
457         struct drm_gem_object *obj;
458         int ret = 0;
459
460         mutex_lock(&dev->struct_mutex);
461
462         /*
463          * get offset of memory allocated for drm framebuffer.
464          * - this callback would be called by user application
465          *      with DRM_IOCTL_MODE_MAP_DUMB command.
466          */
467
468         obj = drm_gem_object_lookup(dev, file_priv, handle);
469         if (!obj) {
470                 DRM_ERROR("failed to lookup gem object.\n");
471                 ret = -EINVAL;
472                 goto unlock;
473         }
474
475         *offset = drm_vma_node_offset_addr(&obj->vma_node);
476         DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset);
477
478         drm_gem_object_unreference(obj);
479 unlock:
480         mutex_unlock(&dev->struct_mutex);
481         return ret;
482 }
483
484 int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
485 {
486         struct drm_gem_object *obj = vma->vm_private_data;
487         struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj);
488         unsigned long pfn;
489         pgoff_t page_offset;
490         int ret;
491
492         page_offset = ((unsigned long)vmf->virtual_address -
493                         vma->vm_start) >> PAGE_SHIFT;
494
495         if (page_offset >= (exynos_gem->size >> PAGE_SHIFT)) {
496                 DRM_ERROR("invalid page offset\n");
497                 ret = -EINVAL;
498                 goto out;
499         }
500
501         pfn = page_to_pfn(exynos_gem->pages[page_offset]);
502         ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn);
503
504 out:
505         switch (ret) {
506         case 0:
507         case -ERESTARTSYS:
508         case -EINTR:
509                 return VM_FAULT_NOPAGE;
510         case -ENOMEM:
511                 return VM_FAULT_OOM;
512         default:
513                 return VM_FAULT_SIGBUS;
514         }
515 }
516
517 int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
518 {
519         struct exynos_drm_gem *exynos_gem;
520         struct drm_gem_object *obj;
521         int ret;
522
523         /* set vm_area_struct. */
524         ret = drm_gem_mmap(filp, vma);
525         if (ret < 0) {
526                 DRM_ERROR("failed to mmap.\n");
527                 return ret;
528         }
529
530         obj = vma->vm_private_data;
531         exynos_gem = to_exynos_gem(obj);
532
533         DRM_DEBUG_KMS("flags = 0x%x\n", exynos_gem->flags);
534
535         /* non-cachable as default. */
536         if (exynos_gem->flags & EXYNOS_BO_CACHABLE)
537                 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
538         else if (exynos_gem->flags & EXYNOS_BO_WC)
539                 vma->vm_page_prot =
540                         pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
541         else
542                 vma->vm_page_prot =
543                         pgprot_noncached(vm_get_page_prot(vma->vm_flags));
544
545         ret = exynos_drm_gem_mmap_buffer(exynos_gem, vma);
546         if (ret)
547                 goto err_close_vm;
548
549         return ret;
550
551 err_close_vm:
552         drm_gem_vm_close(vma);
553
554         return ret;
555 }
556
557 /* low-level interface prime helpers */
558 struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj)
559 {
560         struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj);
561         int npages;
562
563         npages = exynos_gem->size >> PAGE_SHIFT;
564
565         return drm_prime_pages_to_sg(exynos_gem->pages, npages);
566 }
567
568 struct drm_gem_object *
569 exynos_drm_gem_prime_import_sg_table(struct drm_device *dev,
570                                      struct dma_buf_attachment *attach,
571                                      struct sg_table *sgt)
572 {
573         struct exynos_drm_gem *exynos_gem;
574         int npages;
575         int ret;
576
577         exynos_gem = exynos_drm_gem_init(dev, attach->dmabuf->size);
578         if (IS_ERR(exynos_gem)) {
579                 ret = PTR_ERR(exynos_gem);
580                 return ERR_PTR(ret);
581         }
582
583         exynos_gem->dma_addr = sg_dma_address(sgt->sgl);
584
585         npages = exynos_gem->size >> PAGE_SHIFT;
586         exynos_gem->pages = drm_malloc_ab(npages, sizeof(struct page *));
587         if (!exynos_gem->pages) {
588                 ret = -ENOMEM;
589                 goto err;
590         }
591
592         ret = drm_prime_sg_to_page_addr_arrays(sgt, exynos_gem->pages, NULL,
593                                                npages);
594         if (ret < 0)
595                 goto err_free_large;
596
597         exynos_gem->sgt = sgt;
598
599         if (sgt->nents == 1) {
600                 /* always physically continuous memory if sgt->nents is 1. */
601                 exynos_gem->flags |= EXYNOS_BO_CONTIG;
602         } else {
603                 /*
604                  * this case could be CONTIG or NONCONTIG type but for now
605                  * sets NONCONTIG.
606                  * TODO. we have to find a way that exporter can notify
607                  * the type of its own buffer to importer.
608                  */
609                 exynos_gem->flags |= EXYNOS_BO_NONCONTIG;
610         }
611
612         return &exynos_gem->base;
613
614 err_free_large:
615         drm_free_large(exynos_gem->pages);
616 err:
617         drm_gem_object_release(&exynos_gem->base);
618         kfree(exynos_gem);
619         return ERR_PTR(ret);
620 }
621
622 void *exynos_drm_gem_prime_vmap(struct drm_gem_object *obj)
623 {
624         return NULL;
625 }
626
627 void exynos_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
628 {
629         /* Nothing to do */
630 }