drm/rockchip: gem: add get phys ioctl
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / rockchip / rockchip_drm_gem.c
1 /*
2  * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
3  * Author:Mark Yao <mark.yao@rock-chips.com>
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #include <drm/drm.h>
16 #include <drm/drmP.h>
17 #include <drm/drm_gem.h>
18 #include <drm/drm_sync_helper.h>
19 #include <drm/drm_vma_manager.h>
20 #include <drm/rockchip_drm.h>
21
22 #include <linux/completion.h>
23 #include <linux/dma-attrs.h>
24 #include <linux/dma-buf.h>
25 #include <linux/reservation.h>
26 #include <linux/iommu.h>
27 #include <linux/pagemap.h>
28
29 #include "rockchip_drm_drv.h"
30 #include "rockchip_drm_gem.h"
31
32 struct page_info {
33         struct page *page;
34         struct list_head list;
35 };
36
37 #define PG_ROUND        8
38
39 static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
40 {
41         struct drm_device *drm = rk_obj->base.dev;
42         struct rockchip_drm_private *private = drm->dev_private;
43         int prot = IOMMU_READ | IOMMU_WRITE;
44         ssize_t ret;
45
46         mutex_lock(&private->mm_lock);
47
48         ret = drm_mm_insert_node_generic(&private->mm, &rk_obj->mm,
49                                          rk_obj->base.size, PAGE_SIZE,
50                                          0, 0, 0);
51
52         mutex_unlock(&private->mm_lock);
53         if (ret < 0) {
54                 DRM_ERROR("out of I/O virtual memory: %zd\n", ret);
55                 return ret;
56         }
57
58         rk_obj->dma_addr = rk_obj->mm.start;
59
60         ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
61                            rk_obj->sgt->nents, prot);
62         if (ret < rk_obj->base.size) {
63                 DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n",
64                           ret, rk_obj->base.size);
65                 ret = -ENOMEM;
66                 goto err_remove_node;
67         }
68
69         rk_obj->size = ret;
70
71         return 0;
72
73 err_remove_node:
74         drm_mm_remove_node(&rk_obj->mm);
75
76         return ret;
77 }
78
79 static int rockchip_gem_iommu_unmap(struct rockchip_gem_object *rk_obj)
80 {
81         struct drm_device *drm = rk_obj->base.dev;
82         struct rockchip_drm_private *private = drm->dev_private;
83
84         iommu_unmap(private->domain, rk_obj->dma_addr, rk_obj->size);
85
86         mutex_lock(&private->mm_lock);
87
88         drm_mm_remove_node(&rk_obj->mm);
89
90         mutex_unlock(&private->mm_lock);
91
92         return 0;
93 }
94
95 static void rockchip_gem_free_list(struct list_head lists[])
96 {
97         struct page_info *info, *tmp_info;
98         int i;
99
100         for (i = 0; i < PG_ROUND; i++) {
101                 list_for_each_entry_safe(info, tmp_info, &lists[i], list) {
102                         list_del(&info->list);
103                         kfree(info);
104                 }
105         }
106 }
107
108 static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
109 {
110         struct drm_device *drm = rk_obj->base.dev;
111         int ret, i;
112         struct scatterlist *s;
113         unsigned int cur_page;
114         struct page **pages, **dst_pages;
115         int j;
116         int n_pages;
117         unsigned long chunk_pages;
118         unsigned long remain;
119         struct list_head lists[PG_ROUND];
120         dma_addr_t phys;
121         int end = 0;
122         unsigned int bit12_14;
123         unsigned int block_index[PG_ROUND] = {0};
124         struct page_info *info;
125         unsigned int maximum;
126
127         for (i = 0; i < PG_ROUND; i++)
128                 INIT_LIST_HEAD(&lists[i]);
129
130         pages = drm_gem_get_pages(&rk_obj->base);
131         if (IS_ERR(pages))
132                 return PTR_ERR(pages);
133
134         rk_obj->pages = pages;
135
136         rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
137
138         n_pages = rk_obj->num_pages;
139
140         dst_pages = drm_malloc_ab(n_pages, sizeof(struct page *));
141         if (!dst_pages) {
142                 ret = -ENOMEM;
143                 goto err_put_pages;
144         }
145
146         cur_page = 0;
147         remain = n_pages;
148         /* look for the end of the current chunk */
149         while (remain) {
150                 for (j = cur_page + 1; j < n_pages; ++j) {
151                         if (page_to_pfn(pages[j]) !=
152                                 page_to_pfn(pages[j - 1]) + 1)
153                         break;
154                 }
155
156                 chunk_pages = j - cur_page;
157
158                 if (chunk_pages > 7) {
159                         for (i = 0; i < chunk_pages; i++)
160                                 dst_pages[end + i] = pages[cur_page + i];
161                         end += chunk_pages;
162                 } else {
163                         for (i = 0; i < chunk_pages; i++) {
164                                 info = kmalloc(sizeof(*info), GFP_KERNEL);
165                                 if (!info) {
166                                         ret = -ENOMEM;
167                                         goto err_put_list;
168                                 }
169
170                                 INIT_LIST_HEAD(&info->list);
171                                 info->page = pages[cur_page + i];
172                                 phys = page_to_phys(info->page);
173                                 bit12_14 = (phys >> 12) & 0x7;
174                                 list_add_tail(&info->list, &lists[bit12_14]);
175                                 block_index[bit12_14]++;
176                         }
177                 }
178
179                 cur_page = j;
180                 remain -= chunk_pages;
181         }
182
183         maximum = block_index[0];
184         for (i = 1; i < PG_ROUND; i++)
185                 maximum = max(maximum, block_index[i]);
186
187         for (i = 0; i < maximum; i++) {
188                 for (j = 0; j < PG_ROUND; j++) {
189                         if (!list_empty(&lists[j])) {
190                                 struct page_info *info;
191
192                                 info = list_first_entry(&lists[j],
193                                                       struct page_info, list);
194                                 dst_pages[end++] = info->page;
195                                 list_del(&info->list);
196                                 kfree(info);
197                         }
198                 }
199         }
200
201         DRM_DEBUG_KMS("%s, %d, end = %d, n_pages = %d\n", __func__, __LINE__,
202                  end, n_pages);
203
204         rk_obj->sgt = drm_prime_pages_to_sg(dst_pages, rk_obj->num_pages);
205         if (IS_ERR(rk_obj->sgt)) {
206                 ret = PTR_ERR(rk_obj->sgt);
207                 goto err_put_list;
208         }
209
210         rk_obj->pages = dst_pages;
211
212         /*
213          * Fake up the SG table so that dma_sync_sg_for_device() can be used
214          * to flush the pages associated with it.
215          *
216          * TODO: Replace this by drm_clflush_sg() once it can be implemented
217          * without relying on symbols that are not exported.
218          */
219         for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i)
220                 sg_dma_address(s) = sg_phys(s);
221
222         dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents,
223                                DMA_TO_DEVICE);
224
225         drm_free_large(pages);
226
227         return 0;
228
229 err_put_list:
230         rockchip_gem_free_list(lists);
231         drm_free_large(dst_pages);
232 err_put_pages:
233         drm_gem_put_pages(&rk_obj->base, rk_obj->pages, false, false);
234         return ret;
235 }
236
237 static void rockchip_gem_put_pages(struct rockchip_gem_object *rk_obj)
238 {
239         sg_free_table(rk_obj->sgt);
240         kfree(rk_obj->sgt);
241         drm_gem_put_pages(&rk_obj->base, rk_obj->pages, true, true);
242 }
243
244 static int rockchip_gem_alloc_cma(struct rockchip_gem_object *rk_obj)
245 {
246         struct drm_gem_object *obj = &rk_obj->base;
247         struct drm_device *drm = obj->dev;
248         struct sg_table *sgt;
249         int ret;
250
251         init_dma_attrs(&rk_obj->dma_attrs);
252         dma_set_attr(DMA_ATTR_WRITE_COMBINE, &rk_obj->dma_attrs);
253         dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &rk_obj->dma_attrs);
254
255         rk_obj->cookie = dma_alloc_attrs(drm->dev, obj->size,
256                                          &rk_obj->dma_handle, GFP_KERNEL,
257                                          &rk_obj->dma_attrs);
258         if (!rk_obj->cookie) {
259                 DRM_ERROR("failed to allocate %zu byte dma buffer", obj->size);
260                 return -ENOMEM;
261         }
262
263         sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
264         if (!sgt) {
265                 ret = -ENOMEM;
266                 goto err_dma_free;
267         }
268
269         ret = dma_get_sgtable_attrs(drm->dev, sgt, rk_obj->cookie,
270                                     rk_obj->dma_handle, obj->size,
271                                     &rk_obj->dma_attrs);
272         if (ret) {
273                 DRM_ERROR("failed to allocate sgt, %d\n", ret);
274                 goto err_sgt_free;
275         }
276
277         rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT;
278
279         rk_obj->pages = drm_calloc_large(rk_obj->num_pages,
280                                          sizeof(*rk_obj->pages));
281         if (!rk_obj->pages) {
282                 DRM_ERROR("failed to allocate pages.\n");
283                 goto err_sg_table_free;
284         }
285
286         if (drm_prime_sg_to_page_addr_arrays(sgt, rk_obj->pages, NULL,
287                                              rk_obj->num_pages)) {
288                 DRM_ERROR("invalid sgtable.\n");
289                 ret = -EINVAL;
290                 goto err_page_free;
291         }
292
293         rk_obj->sgt = sgt;
294
295         return 0;
296
297 err_page_free:
298         drm_free_large(rk_obj->pages);
299 err_sg_table_free:
300         sg_free_table(sgt);
301 err_sgt_free:
302         kfree(sgt);
303 err_dma_free:
304         dma_free_attrs(drm->dev, obj->size, rk_obj->cookie,
305                        rk_obj->dma_addr, &rk_obj->dma_attrs);
306
307         return ret;
308 }
309
310 static void rockchip_gem_free_cma(struct rockchip_gem_object *rk_obj)
311 {
312         struct drm_gem_object *obj = &rk_obj->base;
313         struct drm_device *drm = obj->dev;
314
315         drm_free_large(rk_obj->pages);
316         sg_free_table(rk_obj->sgt);
317         kfree(rk_obj->sgt);
318         dma_free_attrs(drm->dev, obj->size, rk_obj->cookie,
319                        rk_obj->dma_addr, &rk_obj->dma_attrs);
320 }
321
322 static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj,
323                                   bool alloc_kmap)
324 {
325         struct drm_gem_object *obj = &rk_obj->base;
326         struct drm_device *drm = obj->dev;
327         struct rockchip_drm_private *private = drm->dev_private;
328         int ret;
329
330         if (!private->domain)
331                 rk_obj->flags |= ROCKCHIP_BO_CONTIG;
332
333         if (rk_obj->flags & ROCKCHIP_BO_CONTIG) {
334                 rk_obj->buf_type = ROCKCHIP_GEM_BUF_TYPE_CMA;
335                 ret = rockchip_gem_alloc_cma(rk_obj);
336                 if (ret < 0)
337                         return ret;
338         } else {
339                 rk_obj->buf_type = ROCKCHIP_GEM_BUF_TYPE_SHMEM;
340                 ret = rockchip_gem_get_pages(rk_obj);
341                 if (ret < 0)
342                         return ret;
343         }
344
345         if (private->domain) {
346                 ret = rockchip_gem_iommu_map(rk_obj);
347                 if (ret < 0)
348                         goto err_free;
349         } else {
350                 WARN_ON(!rk_obj->dma_handle);
351                 rk_obj->dma_addr = rk_obj->dma_handle;
352         }
353
354         if (alloc_kmap) {
355                 rk_obj->kvaddr = vmap(rk_obj->pages, rk_obj->num_pages, VM_MAP,
356                                       pgprot_writecombine(PAGE_KERNEL));
357                 if (!rk_obj->kvaddr) {
358                         DRM_ERROR("failed to vmap() buffer\n");
359                         ret = -ENOMEM;
360                         goto err_iommu_free;
361                 }
362         }
363
364         return 0;
365
366 err_iommu_free:
367         if (private->domain)
368                 rockchip_gem_iommu_unmap(rk_obj);
369 err_free:
370         if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_CMA)
371                 rockchip_gem_free_cma(rk_obj);
372         else
373                 rockchip_gem_put_pages(rk_obj);
374         return ret;
375 }
376
377 static void rockchip_gem_free_buf(struct rockchip_gem_object *rk_obj)
378 {
379         struct drm_device *drm = rk_obj->base.dev;
380         struct rockchip_drm_private *private = drm->dev_private;
381
382         if (private->domain)
383                 rockchip_gem_iommu_unmap(rk_obj);
384
385         vunmap(rk_obj->kvaddr);
386
387         if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_SHMEM) {
388                 rockchip_gem_put_pages(rk_obj);
389         } else {
390                 rockchip_gem_free_cma(rk_obj);
391         }
392 }
393
394 static int rockchip_drm_gem_object_mmap_shm(struct drm_gem_object *obj,
395                                             struct vm_area_struct *vma)
396 {
397         struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
398         unsigned int i, count = obj->size >> PAGE_SHIFT;
399         unsigned long user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
400         unsigned long uaddr = vma->vm_start;
401         unsigned long offset = vma->vm_pgoff;
402         unsigned long end = user_count + offset;
403         int ret;
404
405         if (user_count == 0)
406                 return -ENXIO;
407         if (end > count)
408                 return -ENXIO;
409
410         for (i = offset; i < end; i++) {
411                 ret = vm_insert_page(vma, uaddr, rk_obj->pages[i]);
412                 if (ret)
413                         return ret;
414                 uaddr += PAGE_SIZE;
415         }
416
417         return 0;
418 }
419
420 static int rockchip_drm_gem_object_mmap_cma(struct drm_gem_object *obj,
421                                             struct vm_area_struct *vma)
422 {
423         struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
424         struct drm_device *drm = obj->dev;
425
426         return dma_mmap_attrs(drm->dev, vma, rk_obj->cookie, rk_obj->dma_handle,
427                               obj->size, &rk_obj->dma_attrs);
428 }
429
430 static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj,
431                                         struct vm_area_struct *vma)
432 {
433         int ret;
434         struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
435
436         /* default is wc. */
437         if (rk_obj->flags & ROCKCHIP_BO_CACHABLE)
438                 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
439
440         /*
441          * We allocated a struct page table for rk_obj, so clear
442          * VM_PFNMAP flag that was set by drm_gem_mmap_obj()/drm_gem_mmap().
443          */
444         vma->vm_flags &= ~VM_PFNMAP;
445
446         if (rk_obj->buf_type == ROCKCHIP_GEM_BUF_TYPE_SHMEM)
447                 ret = rockchip_drm_gem_object_mmap_shm(obj, vma);
448         else
449                 ret = rockchip_drm_gem_object_mmap_cma(obj, vma);
450
451         if (ret)
452                 drm_gem_vm_close(vma);
453
454         return ret;
455 }
456
457 int rockchip_gem_mmap_buf(struct drm_gem_object *obj,
458                           struct vm_area_struct *vma)
459 {
460         int ret;
461
462         ret = drm_gem_mmap_obj(obj, obj->size, vma);
463         if (ret)
464                 return ret;
465
466         return rockchip_drm_gem_object_mmap(obj, vma);
467 }
468
469 /* drm driver mmap file operations */
470 int rockchip_gem_mmap(struct file *filp, struct vm_area_struct *vma)
471 {
472         struct drm_gem_object *obj;
473         int ret;
474
475         ret = drm_gem_mmap(filp, vma);
476         if (ret)
477                 return ret;
478
479         /*
480          * Set vm_pgoff (used as a fake buffer offset by DRM) to 0 and map the
481          * whole buffer from the start.
482          */
483         vma->vm_pgoff = 0;
484
485         obj = vma->vm_private_data;
486
487         return rockchip_drm_gem_object_mmap(obj, vma);
488 }
489
490 static struct rockchip_gem_object *
491 rockchip_gem_alloc_object(struct drm_device *drm, unsigned int size)
492 {
493         struct address_space *mapping;
494         struct rockchip_gem_object *rk_obj;
495         struct drm_gem_object *obj;
496
497         size = round_up(size, PAGE_SIZE);
498
499         rk_obj = kzalloc(sizeof(*rk_obj), GFP_KERNEL);
500         if (!rk_obj)
501                 return ERR_PTR(-ENOMEM);
502
503         obj = &rk_obj->base;
504
505         drm_gem_object_init(drm, obj, size);
506
507         if (IS_ENABLED(CONFIG_ARM_LPAE)) {
508                 mapping = file_inode(obj->filp)->i_mapping;
509                 mapping_set_gfp_mask(mapping,
510                                      mapping_gfp_mask(mapping) | __GFP_DMA32);
511         }
512
513         return rk_obj;
514 }
515
516 static void rockchip_gem_release_object(struct rockchip_gem_object *rk_obj)
517 {
518         drm_gem_object_release(&rk_obj->base);
519         kfree(rk_obj);
520 }
521
522 struct rockchip_gem_object *
523 rockchip_gem_create_object(struct drm_device *drm, unsigned int size,
524                            bool alloc_kmap, unsigned int flags)
525 {
526         struct rockchip_gem_object *rk_obj;
527         int ret;
528
529         rk_obj = rockchip_gem_alloc_object(drm, size);
530         if (IS_ERR(rk_obj))
531                 return rk_obj;
532         rk_obj->flags = flags;
533
534         ret = rockchip_gem_alloc_buf(rk_obj, alloc_kmap);
535         if (ret)
536                 goto err_free_rk_obj;
537
538         return rk_obj;
539
540 err_free_rk_obj:
541         rockchip_gem_release_object(rk_obj);
542         return ERR_PTR(ret);
543 }
544
545 /*
546  * rockchip_gem_free_object - (struct drm_driver)->gem_free_object callback
547  * function
548  */
549 void rockchip_gem_free_object(struct drm_gem_object *obj)
550 {
551         struct drm_device *drm = obj->dev;
552         struct rockchip_drm_private *private = drm->dev_private;
553         struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
554
555         if (obj->import_attach) {
556                 if (private->domain) {
557                         rockchip_gem_iommu_unmap(rk_obj);
558                 } else {
559                         dma_unmap_sg(drm->dev, rk_obj->sgt->sgl,
560                                      rk_obj->sgt->nents, DMA_BIDIRECTIONAL);
561                 }
562         } else {
563                 rockchip_gem_free_buf(rk_obj);
564         }
565
566 #ifdef CONFIG_DRM_DMA_SYNC
567         drm_fence_signal_and_put(&rk_obj->acquire_fence);
568 #endif
569
570         rockchip_gem_release_object(rk_obj);
571 }
572
573 /*
574  * rockchip_gem_create_with_handle - allocate an object with the given
575  * size and create a gem handle on it
576  *
577  * returns a struct rockchip_gem_object* on success or ERR_PTR values
578  * on failure.
579  */
580 static struct rockchip_gem_object *
581 rockchip_gem_create_with_handle(struct drm_file *file_priv,
582                                 struct drm_device *drm, unsigned int size,
583                                 unsigned int *handle, unsigned int flags)
584 {
585         struct rockchip_gem_object *rk_obj;
586         struct drm_gem_object *obj;
587         int ret;
588
589         rk_obj = rockchip_gem_create_object(drm, size, false, flags);
590         if (IS_ERR(rk_obj))
591                 return ERR_CAST(rk_obj);
592
593         obj = &rk_obj->base;
594
595         /*
596          * allocate a id of idr table where the obj is registered
597          * and handle has the id what user can see.
598          */
599         ret = drm_gem_handle_create(file_priv, obj, handle);
600         if (ret)
601                 goto err_handle_create;
602
603         /* drop reference from allocate - handle holds it now. */
604         drm_gem_object_unreference_unlocked(obj);
605
606         return rk_obj;
607
608 err_handle_create:
609         rockchip_gem_free_object(obj);
610
611         return ERR_PTR(ret);
612 }
613
614 int rockchip_gem_dumb_map_offset(struct drm_file *file_priv,
615                                  struct drm_device *dev, uint32_t handle,
616                                  uint64_t *offset)
617 {
618         struct drm_gem_object *obj;
619         int ret;
620
621         obj = drm_gem_object_lookup(dev, file_priv, handle);
622         if (!obj) {
623                 DRM_ERROR("failed to lookup gem object.\n");
624                 return -EINVAL;
625         }
626
627         ret = drm_gem_create_mmap_offset(obj);
628         if (ret)
629                 goto out;
630
631         *offset = drm_vma_node_offset_addr(&obj->vma_node);
632         DRM_DEBUG_KMS("offset = 0x%llx\n", *offset);
633
634 out:
635         drm_gem_object_unreference_unlocked(obj);
636
637         return 0;
638 }
639
640 /*
641  * rockchip_gem_dumb_create - (struct drm_driver)->dumb_create callback
642  * function
643  *
644  * This aligns the pitch and size arguments to the minimum required. wrap
645  * this into your own function if you need bigger alignment.
646  */
647 int rockchip_gem_dumb_create(struct drm_file *file_priv,
648                              struct drm_device *dev,
649                              struct drm_mode_create_dumb *args)
650 {
651         struct rockchip_gem_object *rk_obj;
652         int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
653
654         /*
655          * align to 64 bytes since Mali requires it.
656          */
657         args->pitch = ALIGN(min_pitch, 64);
658         args->size = args->pitch * args->height;
659
660         rk_obj = rockchip_gem_create_with_handle(file_priv, dev, args->size,
661                                                  &args->handle, args->flags);
662
663         return PTR_ERR_OR_ZERO(rk_obj);
664 }
665
666 int rockchip_gem_map_offset_ioctl(struct drm_device *drm, void *data,
667                                   struct drm_file *file_priv)
668 {
669         struct drm_rockchip_gem_map_off *args = data;
670
671         return rockchip_gem_dumb_map_offset(file_priv, drm, args->handle,
672                                             &args->offset);
673 }
674
675 int rockchip_gem_get_phys_ioctl(struct drm_device *dev, void *data,
676                                 struct drm_file *file_priv)
677 {
678         struct drm_rockchip_gem_phys *args = data;
679         struct rockchip_gem_object *rk_obj;
680         struct drm_gem_object *obj;
681
682         obj = drm_gem_object_lookup(dev, file_priv, args->handle);
683         if (!obj) {
684                 DRM_ERROR("failed to lookup gem object.\n");
685                 return -EINVAL;
686         }
687         rk_obj = to_rockchip_obj(obj);
688
689         if (!(rk_obj->flags & ROCKCHIP_BO_CONTIG)) {
690                 DRM_ERROR("Can't get phys address from non-continus buf.\n");
691                 return -EINVAL;
692         }
693
694         args->phy_addr = page_to_phys(rk_obj->pages[0]);
695
696         return 0;
697 }
698
699 int rockchip_gem_create_ioctl(struct drm_device *dev, void *data,
700                               struct drm_file *file_priv)
701 {
702         struct drm_rockchip_gem_create *args = data;
703         struct rockchip_gem_object *rk_obj;
704
705         rk_obj = rockchip_gem_create_with_handle(file_priv, dev, args->size,
706                                                  &args->handle, args->flags);
707         return PTR_ERR_OR_ZERO(rk_obj);
708 }
709
710 static struct reservation_object *drm_gem_get_resv(struct drm_gem_object *gem)
711 {
712         struct dma_buf *dma_buf = gem->dma_buf;
713         return dma_buf ? dma_buf->resv : NULL;
714 }
715
716 #ifdef CONFIG_DRM_DMA_SYNC
717 static void rockchip_gem_acquire_complete(struct drm_reservation_cb *rcb,
718                                         void *context)
719 {
720         struct completion *compl = context;
721         complete(compl);
722 }
723
724 static int rockchip_gem_acquire(struct drm_device *dev,
725                                 struct rockchip_gem_object *rockchip_gem_obj,
726                                 bool exclusive)
727 {
728         struct fence *fence;
729         struct rockchip_drm_private *dev_priv = dev->dev_private;
730         struct reservation_object *resv =
731                 drm_gem_get_resv(&rockchip_gem_obj->base);
732         int ret = 0;
733         struct drm_reservation_cb rcb;
734         DECLARE_COMPLETION_ONSTACK(compl);
735
736         if (!resv)
737                 return ret;
738
739         if (!exclusive &&
740             !rockchip_gem_obj->acquire_exclusive &&
741             rockchip_gem_obj->acquire_fence) {
742                 atomic_inc(&rockchip_gem_obj->acquire_shared_count);
743                 return ret;
744         }
745
746         fence = drm_sw_fence_new(dev_priv->cpu_fence_context,
747                         atomic_add_return(1, &dev_priv->cpu_fence_seqno));
748         if (IS_ERR(fence)) {
749                 ret = PTR_ERR(fence);
750                 DRM_ERROR("Failed to create acquire fence %d.\n", ret);
751                 return ret;
752         }
753         ww_mutex_lock(&resv->lock, NULL);
754         if (!exclusive) {
755                 ret = reservation_object_reserve_shared(resv);
756                 if (ret < 0) {
757                         DRM_ERROR("Failed to reserve space for shared fence %d.\n",
758                                   ret);
759                         goto resv_unlock;
760                 }
761         }
762         drm_reservation_cb_init(&rcb, rockchip_gem_acquire_complete, &compl);
763         ret = drm_reservation_cb_add(&rcb, resv, exclusive);
764         if (ret < 0) {
765                 DRM_ERROR("Failed to add reservation to callback %d.\n", ret);
766                 goto resv_unlock;
767         }
768         drm_reservation_cb_done(&rcb);
769         if (exclusive)
770                 reservation_object_add_excl_fence(resv, fence);
771         else
772                 reservation_object_add_shared_fence(resv, fence);
773
774         ww_mutex_unlock(&resv->lock);
775         mutex_unlock(&dev->struct_mutex);
776         ret = wait_for_completion_interruptible(&compl);
777         mutex_lock(&dev->struct_mutex);
778         if (ret < 0) {
779                 DRM_ERROR("Failed wait for reservation callback %d.\n", ret);
780                 drm_reservation_cb_fini(&rcb);
781                 /* somebody else may be already waiting on it */
782                 drm_fence_signal_and_put(&fence);
783                 return ret;
784         }
785         rockchip_gem_obj->acquire_fence = fence;
786         rockchip_gem_obj->acquire_exclusive = exclusive;
787         atomic_set(&rockchip_gem_obj->acquire_shared_count, 1);
788         return ret;
789
790 resv_unlock:
791         ww_mutex_unlock(&resv->lock);
792         fence_put(fence);
793         return ret;
794 }
795
796 static void rockchip_gem_release(struct rockchip_gem_object *rockchip_gem_obj)
797 {
798         BUG_ON(!rockchip_gem_obj->acquire_fence);
799         if (atomic_sub_and_test(1,
800                         &rockchip_gem_obj->acquire_shared_count))
801                 drm_fence_signal_and_put(&rockchip_gem_obj->acquire_fence);
802 }
803 #endif
804
805 int rockchip_gem_cpu_acquire_ioctl(struct drm_device *dev, void *data,
806                                    struct drm_file *file)
807 {
808         struct drm_rockchip_gem_cpu_acquire *args = data;
809         struct rockchip_drm_file_private *file_priv = file->driver_priv;
810         struct drm_gem_object *obj;
811         struct rockchip_gem_object *rockchip_gem_obj;
812         struct rockchip_gem_object_node *gem_node;
813         int ret = 0;
814
815         DRM_DEBUG_KMS("[BO:%u] flags: 0x%x\n", args->handle, args->flags);
816
817         mutex_lock(&dev->struct_mutex);
818
819         obj = drm_gem_object_lookup(dev, file, args->handle);
820         if (!obj) {
821                 DRM_ERROR("failed to lookup gem object.\n");
822                 ret = -EINVAL;
823                 goto unlock;
824         }
825
826         rockchip_gem_obj = to_rockchip_obj(obj);
827
828         if (!drm_gem_get_resv(&rockchip_gem_obj->base)) {
829                 /* If there is no reservation object present, there is no
830                  * cross-process/cross-device sharing and sync is unnecessary.
831                  */
832                 ret = 0;
833                 goto unref_obj;
834         }
835
836 #ifdef CONFIG_DRM_DMA_SYNC
837         ret = rockchip_gem_acquire(dev, rockchip_gem_obj,
838                         args->flags & DRM_ROCKCHIP_GEM_CPU_ACQUIRE_EXCLUSIVE);
839         if (ret < 0)
840                 goto unref_obj;
841 #endif
842
843         gem_node = kzalloc(sizeof(*gem_node), GFP_KERNEL);
844         if (!gem_node) {
845                 DRM_ERROR("Failed to allocate rockchip_drm_gem_obj_node.\n");
846                 ret = -ENOMEM;
847                 goto release_sync;
848         }
849
850         gem_node->rockchip_gem_obj = rockchip_gem_obj;
851         list_add(&gem_node->list, &file_priv->gem_cpu_acquire_list);
852         mutex_unlock(&dev->struct_mutex);
853         return 0;
854
855 release_sync:
856 #ifdef CONFIG_DRM_DMA_SYNC
857         rockchip_gem_release(rockchip_gem_obj);
858 #endif
859 unref_obj:
860         drm_gem_object_unreference(obj);
861
862 unlock:
863         mutex_unlock(&dev->struct_mutex);
864         return ret;
865 }
866
867 int rockchip_gem_cpu_release_ioctl(struct drm_device *dev, void *data,
868                                    struct drm_file *file)
869 {
870         struct drm_rockchip_gem_cpu_release *args = data;
871         struct rockchip_drm_file_private *file_priv = file->driver_priv;
872         struct drm_gem_object *obj;
873         struct rockchip_gem_object *rockchip_gem_obj;
874         struct list_head *cur;
875         int ret = 0;
876
877         DRM_DEBUG_KMS("[BO:%u]\n", args->handle);
878
879         mutex_lock(&dev->struct_mutex);
880
881         obj = drm_gem_object_lookup(dev, file, args->handle);
882         if (!obj) {
883                 DRM_ERROR("failed to lookup gem object.\n");
884                 ret = -EINVAL;
885                 goto unlock;
886         }
887
888         rockchip_gem_obj = to_rockchip_obj(obj);
889
890         if (!drm_gem_get_resv(&rockchip_gem_obj->base)) {
891                 /* If there is no reservation object present, there is no
892                  * cross-process/cross-device sharing and sync is unnecessary.
893                  */
894                 ret = 0;
895                 goto unref_obj;
896         }
897
898         list_for_each(cur, &file_priv->gem_cpu_acquire_list) {
899                 struct rockchip_gem_object_node *node = list_entry(
900                                 cur, struct rockchip_gem_object_node, list);
901                 if (node->rockchip_gem_obj == rockchip_gem_obj)
902                         break;
903         }
904         if (cur == &file_priv->gem_cpu_acquire_list) {
905                 DRM_ERROR("gem object not acquired for current process.\n");
906                 ret = -EINVAL;
907                 goto unref_obj;
908         }
909
910 #ifdef CONFIG_DRM_DMA_SYNC
911         rockchip_gem_release(rockchip_gem_obj);
912 #endif
913
914         list_del(cur);
915         kfree(list_entry(cur, struct rockchip_gem_object_node, list));
916         /* unreference for the reference held since cpu_acquire_ioctl */
917         drm_gem_object_unreference(obj);
918         ret = 0;
919
920 unref_obj:
921         /* unreference for the reference from drm_gem_object_lookup() */
922         drm_gem_object_unreference(obj);
923
924 unlock:
925         mutex_unlock(&dev->struct_mutex);
926         return ret;
927 }
928
929 /*
930  * Allocate a sg_table for this GEM object.
931  * Note: Both the table's contents, and the sg_table itself must be freed by
932  *       the caller.
933  * Returns a pointer to the newly allocated sg_table, or an ERR_PTR() error.
934  */
935 struct sg_table *rockchip_gem_prime_get_sg_table(struct drm_gem_object *obj)
936 {
937         struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
938
939         WARN_ON(!rk_obj->pages);
940
941         return drm_prime_pages_to_sg(rk_obj->pages, rk_obj->num_pages);
942 }
943
944 static unsigned long rockchip_sg_get_contiguous_size(struct sg_table *sgt,
945                                                      int count)
946 {
947         struct scatterlist *s;
948         dma_addr_t expected = sg_dma_address(sgt->sgl);
949         unsigned int i;
950         unsigned long size = 0;
951
952         for_each_sg(sgt->sgl, s, count, i) {
953                 if (sg_dma_address(s) != expected)
954                         break;
955                 expected = sg_dma_address(s) + sg_dma_len(s);
956                 size += sg_dma_len(s);
957         }
958         return size;
959 }
960
961 static int
962 rockchip_gem_iommu_map_sg(struct drm_device *drm,
963                           struct dma_buf_attachment *attach,
964                           struct sg_table *sg,
965                           struct rockchip_gem_object *rk_obj)
966 {
967         rk_obj->sgt = sg;
968         return rockchip_gem_iommu_map(rk_obj);
969 }
970
971 static int
972 rockchip_gem_dma_map_sg(struct drm_device *drm,
973                         struct dma_buf_attachment *attach,
974                         struct sg_table *sg,
975                         struct rockchip_gem_object *rk_obj)
976 {
977         int count = dma_map_sg(drm->dev, sg->sgl, sg->nents,
978                                DMA_BIDIRECTIONAL);
979         if (!count)
980                 return -EINVAL;
981
982         if (rockchip_sg_get_contiguous_size(sg, count) < attach->dmabuf->size) {
983                 DRM_ERROR("failed to map sg_table to contiguous linear address.\n");
984                 dma_unmap_sg(drm->dev, sg->sgl, sg->nents,
985                              DMA_BIDIRECTIONAL);
986                 return -EINVAL;
987         }
988
989         rk_obj->dma_addr = sg_dma_address(sg->sgl);
990         rk_obj->sgt = sg;
991         return 0;
992 }
993
994 struct drm_gem_object *
995 rockchip_gem_prime_import_sg_table(struct drm_device *drm,
996                                    struct dma_buf_attachment *attach,
997                                    struct sg_table *sg)
998 {
999         struct rockchip_drm_private *private = drm->dev_private;
1000         struct rockchip_gem_object *rk_obj;
1001         int ret;
1002
1003         rk_obj = rockchip_gem_alloc_object(drm, attach->dmabuf->size);
1004         if (IS_ERR(rk_obj))
1005                 return ERR_CAST(rk_obj);
1006
1007         if (private->domain)
1008                 ret = rockchip_gem_iommu_map_sg(drm, attach, sg, rk_obj);
1009         else
1010                 ret = rockchip_gem_dma_map_sg(drm, attach, sg, rk_obj);
1011
1012         if (ret < 0) {
1013                 DRM_ERROR("failed to import sg table: %d\n", ret);
1014                 goto err_free_rk_obj;
1015         }
1016
1017         return &rk_obj->base;
1018
1019 err_free_rk_obj:
1020         rockchip_gem_release_object(rk_obj);
1021         return ERR_PTR(ret);
1022 }
1023
1024 void *rockchip_gem_prime_vmap(struct drm_gem_object *obj)
1025 {
1026         struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
1027
1028         if (rk_obj->kvaddr)
1029                 return rk_obj->kvaddr;
1030
1031         rk_obj->kvaddr = vmap(rk_obj->pages, rk_obj->num_pages, VM_MAP,
1032                               pgprot_writecombine(PAGE_KERNEL));
1033
1034         return rk_obj->kvaddr;
1035 }
1036
1037 void rockchip_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
1038 {
1039         /* Unmap buffer on buffer destroy. */
1040 }
1041
1042 int rockchip_gem_prime_begin_cpu_access(struct drm_gem_object *obj,
1043                                         size_t start, size_t len,
1044                                         enum dma_data_direction dir)
1045 {
1046         struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
1047         struct drm_device *drm = obj->dev;
1048
1049         if (!rk_obj->sgt)
1050                 return 0;
1051
1052         dma_sync_sg_for_cpu(drm->dev, rk_obj->sgt->sgl,
1053                             rk_obj->sgt->nents, dir);
1054         return 0;
1055 }
1056
1057 void rockchip_gem_prime_end_cpu_access(struct drm_gem_object *obj,
1058                                    size_t start, size_t len,
1059                                    enum dma_data_direction dir)
1060 {
1061         struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
1062         struct drm_device *drm = obj->dev;
1063
1064         if (!rk_obj->sgt)
1065                 return;
1066
1067         dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl,
1068                                rk_obj->sgt->nents, dir);
1069 }