These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / 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         /* set memory type and cache attribute from user side. */
249         exynos_gem->flags = flags;
250
251         ret = exynos_drm_alloc_buf(exynos_gem);
252         if (ret < 0) {
253                 drm_gem_object_release(&exynos_gem->base);
254                 kfree(exynos_gem);
255                 return ERR_PTR(ret);
256         }
257
258         return exynos_gem;
259 }
260
261 int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
262                                 struct drm_file *file_priv)
263 {
264         struct drm_exynos_gem_create *args = data;
265         struct exynos_drm_gem *exynos_gem;
266         int ret;
267
268         exynos_gem = exynos_drm_gem_create(dev, args->flags, args->size);
269         if (IS_ERR(exynos_gem))
270                 return PTR_ERR(exynos_gem);
271
272         ret = exynos_drm_gem_handle_create(&exynos_gem->base, file_priv,
273                                            &args->handle);
274         if (ret) {
275                 exynos_drm_gem_destroy(exynos_gem);
276                 return ret;
277         }
278
279         return 0;
280 }
281
282 dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
283                                         unsigned int gem_handle,
284                                         struct drm_file *filp)
285 {
286         struct exynos_drm_gem *exynos_gem;
287         struct drm_gem_object *obj;
288
289         obj = drm_gem_object_lookup(dev, filp, gem_handle);
290         if (!obj) {
291                 DRM_ERROR("failed to lookup gem object.\n");
292                 return ERR_PTR(-EINVAL);
293         }
294
295         exynos_gem = to_exynos_gem(obj);
296
297         return &exynos_gem->dma_addr;
298 }
299
300 void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
301                                         unsigned int gem_handle,
302                                         struct drm_file *filp)
303 {
304         struct drm_gem_object *obj;
305
306         obj = drm_gem_object_lookup(dev, filp, gem_handle);
307         if (!obj) {
308                 DRM_ERROR("failed to lookup gem object.\n");
309                 return;
310         }
311
312         drm_gem_object_unreference_unlocked(obj);
313
314         /*
315          * decrease obj->refcount one more time because we has already
316          * increased it at exynos_drm_gem_get_dma_addr().
317          */
318         drm_gem_object_unreference_unlocked(obj);
319 }
320
321 static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
322                                       struct vm_area_struct *vma)
323 {
324         struct drm_device *drm_dev = exynos_gem->base.dev;
325         unsigned long vm_size;
326         int ret;
327
328         vma->vm_flags &= ~VM_PFNMAP;
329         vma->vm_pgoff = 0;
330
331         vm_size = vma->vm_end - vma->vm_start;
332
333         /* check if user-requested size is valid. */
334         if (vm_size > exynos_gem->size)
335                 return -EINVAL;
336
337         ret = dma_mmap_attrs(drm_dev->dev, vma, exynos_gem->pages,
338                              exynos_gem->dma_addr, exynos_gem->size,
339                              &exynos_gem->dma_attrs);
340         if (ret < 0) {
341                 DRM_ERROR("failed to mmap.\n");
342                 return ret;
343         }
344
345         return 0;
346 }
347
348 int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
349                                       struct drm_file *file_priv)
350 {
351         struct exynos_drm_gem *exynos_gem;
352         struct drm_exynos_gem_info *args = data;
353         struct drm_gem_object *obj;
354
355         mutex_lock(&dev->struct_mutex);
356
357         obj = drm_gem_object_lookup(dev, file_priv, args->handle);
358         if (!obj) {
359                 DRM_ERROR("failed to lookup gem object.\n");
360                 mutex_unlock(&dev->struct_mutex);
361                 return -EINVAL;
362         }
363
364         exynos_gem = to_exynos_gem(obj);
365
366         args->flags = exynos_gem->flags;
367         args->size = exynos_gem->size;
368
369         drm_gem_object_unreference(obj);
370         mutex_unlock(&dev->struct_mutex);
371
372         return 0;
373 }
374
375 int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
376                                 struct sg_table *sgt,
377                                 enum dma_data_direction dir)
378 {
379         int nents;
380
381         mutex_lock(&drm_dev->struct_mutex);
382
383         nents = dma_map_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
384         if (!nents) {
385                 DRM_ERROR("failed to map sgl with dma.\n");
386                 mutex_unlock(&drm_dev->struct_mutex);
387                 return nents;
388         }
389
390         mutex_unlock(&drm_dev->struct_mutex);
391         return 0;
392 }
393
394 void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
395                                 struct sg_table *sgt,
396                                 enum dma_data_direction dir)
397 {
398         dma_unmap_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
399 }
400
401 void exynos_drm_gem_free_object(struct drm_gem_object *obj)
402 {
403         exynos_drm_gem_destroy(to_exynos_gem(obj));
404 }
405
406 int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
407                                struct drm_device *dev,
408                                struct drm_mode_create_dumb *args)
409 {
410         struct exynos_drm_gem *exynos_gem;
411         unsigned int flags;
412         int ret;
413
414         /*
415          * allocate memory to be used for framebuffer.
416          * - this callback would be called by user application
417          *      with DRM_IOCTL_MODE_CREATE_DUMB command.
418          */
419
420         args->pitch = args->width * ((args->bpp + 7) / 8);
421         args->size = args->pitch * args->height;
422
423         if (is_drm_iommu_supported(dev))
424                 flags = EXYNOS_BO_NONCONTIG | EXYNOS_BO_WC;
425         else
426                 flags = EXYNOS_BO_CONTIG | EXYNOS_BO_WC;
427
428         exynos_gem = exynos_drm_gem_create(dev, flags, args->size);
429         if (IS_ERR(exynos_gem)) {
430                 dev_warn(dev->dev, "FB allocation failed.\n");
431                 return PTR_ERR(exynos_gem);
432         }
433
434         ret = exynos_drm_gem_handle_create(&exynos_gem->base, file_priv,
435                                            &args->handle);
436         if (ret) {
437                 exynos_drm_gem_destroy(exynos_gem);
438                 return ret;
439         }
440
441         return 0;
442 }
443
444 int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
445                                    struct drm_device *dev, uint32_t handle,
446                                    uint64_t *offset)
447 {
448         struct drm_gem_object *obj;
449         int ret = 0;
450
451         mutex_lock(&dev->struct_mutex);
452
453         /*
454          * get offset of memory allocated for drm framebuffer.
455          * - this callback would be called by user application
456          *      with DRM_IOCTL_MODE_MAP_DUMB command.
457          */
458
459         obj = drm_gem_object_lookup(dev, file_priv, handle);
460         if (!obj) {
461                 DRM_ERROR("failed to lookup gem object.\n");
462                 ret = -EINVAL;
463                 goto unlock;
464         }
465
466         *offset = drm_vma_node_offset_addr(&obj->vma_node);
467         DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset);
468
469         drm_gem_object_unreference(obj);
470 unlock:
471         mutex_unlock(&dev->struct_mutex);
472         return ret;
473 }
474
475 int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
476 {
477         struct drm_gem_object *obj = vma->vm_private_data;
478         struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj);
479         unsigned long pfn;
480         pgoff_t page_offset;
481         int ret;
482
483         page_offset = ((unsigned long)vmf->virtual_address -
484                         vma->vm_start) >> PAGE_SHIFT;
485
486         if (page_offset >= (exynos_gem->size >> PAGE_SHIFT)) {
487                 DRM_ERROR("invalid page offset\n");
488                 ret = -EINVAL;
489                 goto out;
490         }
491
492         pfn = page_to_pfn(exynos_gem->pages[page_offset]);
493         ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn);
494
495 out:
496         switch (ret) {
497         case 0:
498         case -ERESTARTSYS:
499         case -EINTR:
500                 return VM_FAULT_NOPAGE;
501         case -ENOMEM:
502                 return VM_FAULT_OOM;
503         default:
504                 return VM_FAULT_SIGBUS;
505         }
506 }
507
508 int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
509 {
510         struct exynos_drm_gem *exynos_gem;
511         struct drm_gem_object *obj;
512         int ret;
513
514         /* set vm_area_struct. */
515         ret = drm_gem_mmap(filp, vma);
516         if (ret < 0) {
517                 DRM_ERROR("failed to mmap.\n");
518                 return ret;
519         }
520
521         obj = vma->vm_private_data;
522         exynos_gem = to_exynos_gem(obj);
523
524         DRM_DEBUG_KMS("flags = 0x%x\n", exynos_gem->flags);
525
526         /* non-cachable as default. */
527         if (exynos_gem->flags & EXYNOS_BO_CACHABLE)
528                 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
529         else if (exynos_gem->flags & EXYNOS_BO_WC)
530                 vma->vm_page_prot =
531                         pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
532         else
533                 vma->vm_page_prot =
534                         pgprot_noncached(vm_get_page_prot(vma->vm_flags));
535
536         ret = exynos_drm_gem_mmap_buffer(exynos_gem, vma);
537         if (ret)
538                 goto err_close_vm;
539
540         return ret;
541
542 err_close_vm:
543         drm_gem_vm_close(vma);
544
545         return ret;
546 }
547
548 /* low-level interface prime helpers */
549 struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj)
550 {
551         struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj);
552         int npages;
553
554         npages = exynos_gem->size >> PAGE_SHIFT;
555
556         return drm_prime_pages_to_sg(exynos_gem->pages, npages);
557 }
558
559 struct drm_gem_object *
560 exynos_drm_gem_prime_import_sg_table(struct drm_device *dev,
561                                      struct dma_buf_attachment *attach,
562                                      struct sg_table *sgt)
563 {
564         struct exynos_drm_gem *exynos_gem;
565         int npages;
566         int ret;
567
568         exynos_gem = exynos_drm_gem_init(dev, attach->dmabuf->size);
569         if (IS_ERR(exynos_gem)) {
570                 ret = PTR_ERR(exynos_gem);
571                 return ERR_PTR(ret);
572         }
573
574         exynos_gem->dma_addr = sg_dma_address(sgt->sgl);
575
576         npages = exynos_gem->size >> PAGE_SHIFT;
577         exynos_gem->pages = drm_malloc_ab(npages, sizeof(struct page *));
578         if (!exynos_gem->pages) {
579                 ret = -ENOMEM;
580                 goto err;
581         }
582
583         ret = drm_prime_sg_to_page_addr_arrays(sgt, exynos_gem->pages, NULL,
584                                                npages);
585         if (ret < 0)
586                 goto err_free_large;
587
588         exynos_gem->sgt = sgt;
589
590         if (sgt->nents == 1) {
591                 /* always physically continuous memory if sgt->nents is 1. */
592                 exynos_gem->flags |= EXYNOS_BO_CONTIG;
593         } else {
594                 /*
595                  * this case could be CONTIG or NONCONTIG type but for now
596                  * sets NONCONTIG.
597                  * TODO. we have to find a way that exporter can notify
598                  * the type of its own buffer to importer.
599                  */
600                 exynos_gem->flags |= EXYNOS_BO_NONCONTIG;
601         }
602
603         return &exynos_gem->base;
604
605 err_free_large:
606         drm_free_large(exynos_gem->pages);
607 err:
608         drm_gem_object_release(&exynos_gem->base);
609         kfree(exynos_gem);
610         return ERR_PTR(ret);
611 }
612
613 void *exynos_drm_gem_prime_vmap(struct drm_gem_object *obj)
614 {
615         return NULL;
616 }
617
618 void exynos_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
619 {
620         /* Nothing to do */
621 }