69700b9966342d5422986810bd005419b5fa73a8
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / rockchip / rockchip_drm_gem.c
1 /*
2  * Copyright (C) ROCKCHIP, Inc.
3  * Author:yzq<yzq@rock-chips.com>
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13 #include <drm/drmP.h>
14
15 #include <linux/shmem_fs.h>
16 #include <drm/rockchip_drm.h>
17
18 #include "rockchip_drm_drv.h"
19 #include "rockchip_drm_gem.h"
20 #include "rockchip_drm_buf.h"
21
22 static unsigned int convert_to_vm_err_msg(int msg)
23 {
24         unsigned int out_msg;
25
26         switch (msg) {
27         case 0:
28         case -ERESTARTSYS:
29         case -EINTR:
30                 out_msg = VM_FAULT_NOPAGE;
31                 break;
32
33         case -ENOMEM:
34                 out_msg = VM_FAULT_OOM;
35                 break;
36
37         default:
38                 out_msg = VM_FAULT_SIGBUS;
39                 break;
40         }
41
42         return out_msg;
43 }
44
45 static int check_gem_flags(unsigned int flags)
46 {
47         if (flags & ~(ROCKCHIP_BO_MASK)) {
48                 DRM_ERROR("invalid flags.\n");
49                 return -EINVAL;
50         }
51
52         return 0;
53 }
54
55 static void update_vm_cache_attr(struct rockchip_drm_gem_obj *obj,
56                                         struct vm_area_struct *vma)
57 {
58         DRM_DEBUG_KMS("flags = 0x%x\n", obj->flags);
59
60         /* non-cachable as default. */
61         if (obj->flags & ROCKCHIP_BO_CACHABLE)
62                 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
63         else if (obj->flags & ROCKCHIP_BO_WC)
64                 vma->vm_page_prot =
65                         pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
66         else
67                 vma->vm_page_prot =
68                         pgprot_noncached(vm_get_page_prot(vma->vm_flags));
69 }
70
71 static unsigned long roundup_gem_size(unsigned long size, unsigned int flags)
72 {
73         /* TODO */
74
75         return roundup(size, PAGE_SIZE);
76 }
77
78 static int rockchip_drm_gem_map_buf(struct drm_gem_object *obj,
79                                         struct vm_area_struct *vma,
80                                         unsigned long f_vaddr,
81                                         pgoff_t page_offset)
82 {
83         struct rockchip_drm_gem_obj *rockchip_gem_obj = to_rockchip_gem_obj(obj);
84         struct rockchip_drm_gem_buf *buf = rockchip_gem_obj->buffer;
85         struct scatterlist *sgl;
86         unsigned long pfn;
87         int i;
88
89         if (!buf->sgt)
90                 return -EINTR;
91
92         if (page_offset >= (buf->size >> PAGE_SHIFT)) {
93                 DRM_ERROR("invalid page offset\n");
94                 return -EINVAL;
95         }
96
97         sgl = buf->sgt->sgl;
98         for_each_sg(buf->sgt->sgl, sgl, buf->sgt->nents, i) {
99                 if (page_offset < (sgl->length >> PAGE_SHIFT))
100                         break;
101                 page_offset -=  (sgl->length >> PAGE_SHIFT);
102         }
103
104         pfn = __phys_to_pfn(sg_phys(sgl)) + page_offset;
105
106         return vm_insert_mixed(vma, f_vaddr, pfn);
107 }
108
109 static int rockchip_drm_gem_handle_create(struct drm_gem_object *obj,
110                                         struct drm_file *file_priv,
111                                         unsigned int *handle)
112 {
113         int ret;
114
115         /*
116          * allocate a id of idr table where the obj is registered
117          * and handle has the id what user can see.
118          */
119         ret = drm_gem_handle_create(file_priv, obj, handle);
120         if (ret)
121                 return ret;
122
123         DRM_DEBUG_KMS("gem handle = 0x%x\n", *handle);
124
125         /* drop reference from allocate - handle holds it now. */
126         drm_gem_object_unreference_unlocked(obj);
127
128         return 0;
129 }
130
131 void rockchip_drm_gem_destroy(struct rockchip_drm_gem_obj *rockchip_gem_obj)
132 {
133         struct drm_gem_object *obj;
134         struct rockchip_drm_gem_buf *buf;
135
136         DRM_DEBUG_KMS("%s\n", __FILE__);
137
138         obj = &rockchip_gem_obj->base;
139         buf = rockchip_gem_obj->buffer;
140
141         DRM_DEBUG_KMS("handle count = %d\n", atomic_read(&obj->handle_count));
142
143         /*
144          * do not release memory region from exporter.
145          *
146          * the region will be released by exporter
147          * once dmabuf's refcount becomes 0.
148          */
149         if (obj->import_attach)
150                 goto out;
151
152         rockchip_drm_free_buf(obj->dev, rockchip_gem_obj->flags, buf);
153
154 out:
155         rockchip_drm_fini_buf(obj->dev, buf);
156         rockchip_gem_obj->buffer = NULL;
157
158         if (obj->map_list.map)
159                 drm_gem_free_mmap_offset(obj);
160
161         /* release file pointer to gem object. */
162         drm_gem_object_release(obj);
163
164         kfree(rockchip_gem_obj);
165         rockchip_gem_obj = NULL;
166 }
167
168 unsigned long rockchip_drm_gem_get_size(struct drm_device *dev,
169                                                 unsigned int gem_handle,
170                                                 struct drm_file *file_priv)
171 {
172         struct rockchip_drm_gem_obj *rockchip_gem_obj;
173         struct drm_gem_object *obj;
174
175         obj = drm_gem_object_lookup(dev, file_priv, gem_handle);
176         if (!obj) {
177                 DRM_ERROR("failed to lookup gem object.\n");
178                 return 0;
179         }
180
181         rockchip_gem_obj = to_rockchip_gem_obj(obj);
182
183         drm_gem_object_unreference_unlocked(obj);
184
185         return rockchip_gem_obj->buffer->size;
186 }
187
188
189 struct rockchip_drm_gem_obj *rockchip_drm_gem_init(struct drm_device *dev,
190                                                       unsigned long size)
191 {
192         struct rockchip_drm_gem_obj *rockchip_gem_obj;
193         struct drm_gem_object *obj;
194         int ret;
195
196         rockchip_gem_obj = kzalloc(sizeof(*rockchip_gem_obj), GFP_KERNEL);
197         if (!rockchip_gem_obj) {
198                 DRM_ERROR("failed to allocate rockchip gem object\n");
199                 return NULL;
200         }
201
202         rockchip_gem_obj->size = size;
203         obj = &rockchip_gem_obj->base;
204
205         ret = drm_gem_object_init(dev, obj, size);
206         if (ret < 0) {
207                 DRM_ERROR("failed to initialize gem object\n");
208                 kfree(rockchip_gem_obj);
209                 return NULL;
210         }
211
212         DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp);
213
214         return rockchip_gem_obj;
215 }
216
217 struct rockchip_drm_gem_obj *rockchip_drm_gem_create(struct drm_device *dev,
218                                                 unsigned int flags,
219                                                 unsigned long size)
220 {
221         struct rockchip_drm_gem_obj *rockchip_gem_obj;
222         struct rockchip_drm_gem_buf *buf;
223         int ret;
224
225         if (!size) {
226                 DRM_ERROR("invalid size.\n");
227                 return ERR_PTR(-EINVAL);
228         }
229
230         size = roundup_gem_size(size, flags);
231         DRM_DEBUG_KMS("%s\n", __FILE__);
232
233         ret = check_gem_flags(flags);
234         if (ret)
235                 return ERR_PTR(ret);
236
237         buf = rockchip_drm_init_buf(dev, size);
238         if (!buf)
239                 return ERR_PTR(-ENOMEM);
240
241         rockchip_gem_obj = rockchip_drm_gem_init(dev, size);
242         if (!rockchip_gem_obj) {
243                 ret = -ENOMEM;
244                 goto err_fini_buf;
245         }
246
247         rockchip_gem_obj->buffer = buf;
248
249         /* set memory type and cache attribute from user side. */
250         rockchip_gem_obj->flags = flags;
251
252         ret = rockchip_drm_alloc_buf(dev, buf, flags);
253         if (ret < 0) {
254                 drm_gem_object_release(&rockchip_gem_obj->base);
255                 goto err_fini_buf;
256         }
257
258         return rockchip_gem_obj;
259
260 err_fini_buf:
261         rockchip_drm_fini_buf(dev, buf);
262         return ERR_PTR(ret);
263 }
264
265 int rockchip_drm_gem_create_ioctl(struct drm_device *dev, void *data,
266                                 struct drm_file *file_priv)
267 {
268         struct drm_rockchip_gem_create *args = data;
269         struct rockchip_drm_gem_obj *rockchip_gem_obj;
270         int ret;
271
272         DRM_DEBUG_KMS("%s\n", __FILE__);
273
274         rockchip_gem_obj = rockchip_drm_gem_create(dev, args->flags, args->size);
275         if (IS_ERR(rockchip_gem_obj))
276                 return PTR_ERR(rockchip_gem_obj);
277
278         ret = rockchip_drm_gem_handle_create(&rockchip_gem_obj->base, file_priv,
279                         &args->handle);
280         if (ret) {
281                 rockchip_drm_gem_destroy(rockchip_gem_obj);
282                 return ret;
283         }
284
285         return 0;
286 }
287
288 dma_addr_t *rockchip_drm_gem_get_dma_addr(struct drm_device *dev,
289                                         unsigned int gem_handle,
290                                         struct drm_file *filp)
291 {
292         struct rockchip_drm_gem_obj *rockchip_gem_obj;
293         struct drm_gem_object *obj;
294
295         obj = drm_gem_object_lookup(dev, filp, gem_handle);
296         if (!obj) {
297                 DRM_ERROR("failed to lookup gem object.\n");
298                 return ERR_PTR(-EINVAL);
299         }
300
301         rockchip_gem_obj = to_rockchip_gem_obj(obj);
302
303         return &rockchip_gem_obj->buffer->dma_addr;
304 }
305
306 void rockchip_drm_gem_put_dma_addr(struct drm_device *dev,
307                                         unsigned int gem_handle,
308                                         struct drm_file *filp)
309 {
310         struct rockchip_drm_gem_obj *rockchip_gem_obj;
311         struct drm_gem_object *obj;
312
313         obj = drm_gem_object_lookup(dev, filp, gem_handle);
314         if (!obj) {
315                 DRM_ERROR("failed to lookup gem object.\n");
316                 return;
317         }
318
319         rockchip_gem_obj = to_rockchip_gem_obj(obj);
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 rockchip_drm_gem_get_dma_addr().
326          */
327         drm_gem_object_unreference_unlocked(obj);
328 }
329
330 int rockchip_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data,
331                                     struct drm_file *file_priv)
332 {
333         struct drm_rockchip_gem_map_off *args = data;
334
335         DRM_DEBUG_KMS("%s\n", __FILE__);
336
337         DRM_DEBUG_KMS("handle = 0x%x, offset = 0x%lx\n",
338                         args->handle, (unsigned long)args->offset);
339
340         if (!(dev->driver->driver_features & DRIVER_GEM)) {
341                 DRM_ERROR("does not support GEM.\n");
342                 return -ENODEV;
343         }
344
345         return rockchip_drm_gem_dumb_map_offset(file_priv, dev, args->handle,
346                         &args->offset);
347 }
348
349 static struct drm_file *rockchip_drm_find_drm_file(struct drm_device *drm_dev,
350                                                         struct file *filp)
351 {
352         struct drm_file *file_priv;
353
354         /* find current process's drm_file from filelist. */
355         list_for_each_entry(file_priv, &drm_dev->filelist, lhead)
356                 if (file_priv->filp == filp)
357                         return file_priv;
358
359         WARN_ON(1);
360
361         return ERR_PTR(-EFAULT);
362 }
363
364 static int rockchip_drm_gem_mmap_buffer(struct file *filp,
365                                       struct vm_area_struct *vma)
366 {
367         struct drm_gem_object *obj = filp->private_data;
368         struct rockchip_drm_gem_obj *rockchip_gem_obj = to_rockchip_gem_obj(obj);
369         struct drm_device *drm_dev = obj->dev;
370         struct rockchip_drm_gem_buf *buffer;
371         struct drm_file *file_priv;
372         unsigned long vm_size;
373         int ret;
374
375         DRM_DEBUG_KMS("%s\n", __FILE__);
376
377         vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
378         vma->vm_private_data = obj;
379         vma->vm_ops = drm_dev->driver->gem_vm_ops;
380
381         /* restore it to driver's fops. */
382         filp->f_op = fops_get(drm_dev->driver->fops);
383
384         file_priv = rockchip_drm_find_drm_file(drm_dev, filp);
385         if (IS_ERR(file_priv))
386                 return PTR_ERR(file_priv);
387
388         /* restore it to drm_file. */
389         filp->private_data = file_priv;
390
391         update_vm_cache_attr(rockchip_gem_obj, vma);
392
393         vm_size = vma->vm_end - vma->vm_start;
394
395         /*
396          * a buffer contains information to physically continuous memory
397          * allocated by user request or at framebuffer creation.
398          */
399         buffer = rockchip_gem_obj->buffer;
400
401         /* check if user-requested size is valid. */
402         if (vm_size > buffer->size)
403                 return -EINVAL;
404
405         ret = dma_mmap_attrs(drm_dev->dev, vma, buffer->pages,
406                                 buffer->dma_addr, buffer->size,
407                                 &buffer->dma_attrs);
408         if (ret < 0) {
409                 DRM_ERROR("failed to mmap.\n");
410                 return ret;
411         }
412
413         /*
414          * take a reference to this mapping of the object. And this reference
415          * is unreferenced by the corresponding vm_close call.
416          */
417         drm_gem_object_reference(obj);
418
419         drm_vm_open_locked(drm_dev, vma);
420
421         return 0;
422 }
423
424 static const struct file_operations rockchip_drm_gem_fops = {
425         .mmap = rockchip_drm_gem_mmap_buffer,
426 };
427
428 int rockchip_drm_gem_mmap_ioctl(struct drm_device *dev, void *data,
429                               struct drm_file *file_priv)
430 {
431         struct drm_rockchip_gem_mmap *args = data;
432         struct drm_gem_object *obj;
433         unsigned int addr;
434
435         DRM_DEBUG_KMS("%s\n", __FILE__);
436
437         if (!(dev->driver->driver_features & DRIVER_GEM)) {
438                 DRM_ERROR("does not support GEM.\n");
439                 return -ENODEV;
440         }
441
442         obj = drm_gem_object_lookup(dev, file_priv, args->handle);
443         if (!obj) {
444                 DRM_ERROR("failed to lookup gem object.\n");
445                 return -EINVAL;
446         }
447
448         /*
449          * We have to use gem object and its fops for specific mmaper,
450          * but vm_mmap() can deliver only filp. So we have to change
451          * filp->f_op and filp->private_data temporarily, then restore
452          * again. So it is important to keep lock until restoration the
453          * settings to prevent others from misuse of filp->f_op or
454          * filp->private_data.
455          */
456         mutex_lock(&dev->struct_mutex);
457
458         /*
459          * Set specific mmper's fops. And it will be restored by
460          * rockchip_drm_gem_mmap_buffer to dev->driver->fops.
461          * This is used to call specific mapper temporarily.
462          */
463         file_priv->filp->f_op = &rockchip_drm_gem_fops;
464
465         /*
466          * Set gem object to private_data so that specific mmaper
467          * can get the gem object. And it will be restored by
468          * rockchip_drm_gem_mmap_buffer to drm_file.
469          */
470         file_priv->filp->private_data = obj;
471
472         addr = vm_mmap(file_priv->filp, 0, args->size,
473                         PROT_READ | PROT_WRITE, MAP_SHARED, 0);
474
475         drm_gem_object_unreference(obj);
476
477         if (IS_ERR((void *)addr)) {
478                 /* check filp->f_op, filp->private_data are restored */
479                 if (file_priv->filp->f_op == &rockchip_drm_gem_fops) {
480                         file_priv->filp->f_op = fops_get(dev->driver->fops);
481                         file_priv->filp->private_data = file_priv;
482                 }
483                 mutex_unlock(&dev->struct_mutex);
484                 return PTR_ERR((void *)addr);
485         }
486
487         mutex_unlock(&dev->struct_mutex);
488
489         args->mapped = addr;
490
491         DRM_DEBUG_KMS("mapped = 0x%lx\n", (unsigned long)args->mapped);
492
493         return 0;
494 }
495
496 int rockchip_drm_gem_get_ioctl(struct drm_device *dev, void *data,
497                                       struct drm_file *file_priv)
498 {       struct rockchip_drm_gem_obj *rockchip_gem_obj;
499         struct drm_rockchip_gem_info *args = data;
500         struct drm_gem_object *obj;
501
502         mutex_lock(&dev->struct_mutex);
503
504         obj = drm_gem_object_lookup(dev, file_priv, args->handle);
505         if (!obj) {
506                 DRM_ERROR("failed to lookup gem object.\n");
507                 mutex_unlock(&dev->struct_mutex);
508                 return -EINVAL;
509         }
510
511         rockchip_gem_obj = to_rockchip_gem_obj(obj);
512
513         args->flags = rockchip_gem_obj->flags;
514         args->size = rockchip_gem_obj->size;
515
516         drm_gem_object_unreference(obj);
517         mutex_unlock(&dev->struct_mutex);
518
519         return 0;
520 }
521
522 struct vm_area_struct *rockchip_gem_get_vma(struct vm_area_struct *vma)
523 {
524         struct vm_area_struct *vma_copy;
525
526         vma_copy = kmalloc(sizeof(*vma_copy), GFP_KERNEL);
527         if (!vma_copy)
528                 return NULL;
529
530         if (vma->vm_ops && vma->vm_ops->open)
531                 vma->vm_ops->open(vma);
532
533         if (vma->vm_file)
534                 get_file(vma->vm_file);
535
536         memcpy(vma_copy, vma, sizeof(*vma));
537
538         vma_copy->vm_mm = NULL;
539         vma_copy->vm_next = NULL;
540         vma_copy->vm_prev = NULL;
541
542         return vma_copy;
543 }
544
545 void rockchip_gem_put_vma(struct vm_area_struct *vma)
546 {
547         if (!vma)
548                 return;
549
550         if (vma->vm_ops && vma->vm_ops->close)
551                 vma->vm_ops->close(vma);
552
553         if (vma->vm_file)
554                 fput(vma->vm_file);
555
556         kfree(vma);
557 }
558
559 int rockchip_gem_get_pages_from_userptr(unsigned long start,
560                                                 unsigned int npages,
561                                                 struct page **pages,
562                                                 struct vm_area_struct *vma)
563 {
564         int get_npages;
565
566         /* the memory region mmaped with VM_PFNMAP. */
567         if (vma_is_io(vma)) {
568                 unsigned int i;
569
570                 for (i = 0; i < npages; ++i, start += PAGE_SIZE) {
571                         unsigned long pfn;
572                         int ret = follow_pfn(vma, start, &pfn);
573                         if (ret)
574                                 return ret;
575
576                         pages[i] = pfn_to_page(pfn);
577                 }
578
579                 if (i != npages) {
580                         DRM_ERROR("failed to get user_pages.\n");
581                         return -EINVAL;
582                 }
583
584                 return 0;
585         }
586
587         get_npages = get_user_pages(current, current->mm, start,
588                                         npages, 1, 1, pages, NULL);
589         get_npages = max(get_npages, 0);
590         if (get_npages != npages) {
591                 DRM_ERROR("failed to get user_pages.\n");
592                 while (get_npages)
593                         put_page(pages[--get_npages]);
594                 return -EFAULT;
595         }
596
597         return 0;
598 }
599
600 void rockchip_gem_put_pages_to_userptr(struct page **pages,
601                                         unsigned int npages,
602                                         struct vm_area_struct *vma)
603 {
604         if (!vma_is_io(vma)) {
605                 unsigned int i;
606
607                 for (i = 0; i < npages; i++) {
608                         set_page_dirty_lock(pages[i]);
609
610                         /*
611                          * undo the reference we took when populating
612                          * the table.
613                          */
614                         put_page(pages[i]);
615                 }
616         }
617 }
618
619 int rockchip_gem_map_sgt_with_dma(struct drm_device *drm_dev,
620                                 struct sg_table *sgt,
621                                 enum dma_data_direction dir)
622 {
623         int nents;
624
625         mutex_lock(&drm_dev->struct_mutex);
626
627         nents = dma_map_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
628         if (!nents) {
629                 DRM_ERROR("failed to map sgl with dma.\n");
630                 mutex_unlock(&drm_dev->struct_mutex);
631                 return nents;
632         }
633
634         mutex_unlock(&drm_dev->struct_mutex);
635         return 0;
636 }
637
638 void rockchip_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
639                                 struct sg_table *sgt,
640                                 enum dma_data_direction dir)
641 {
642         dma_unmap_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
643 }
644
645 int rockchip_drm_gem_init_object(struct drm_gem_object *obj)
646 {
647         DRM_DEBUG_KMS("%s\n", __FILE__);
648
649         return 0;
650 }
651
652 void rockchip_drm_gem_free_object(struct drm_gem_object *obj)
653 {
654         struct rockchip_drm_gem_obj *rockchip_gem_obj;
655         struct rockchip_drm_gem_buf *buf;
656
657         DRM_DEBUG_KMS("%s\n", __FILE__);
658
659         rockchip_gem_obj = to_rockchip_gem_obj(obj);
660         buf = rockchip_gem_obj->buffer;
661
662         if (obj->import_attach)
663                 drm_prime_gem_destroy(obj, buf->sgt);
664
665         rockchip_drm_gem_destroy(to_rockchip_gem_obj(obj));
666 }
667
668 int rockchip_drm_gem_dumb_create(struct drm_file *file_priv,
669                                struct drm_device *dev,
670                                struct drm_mode_create_dumb *args)
671 {
672         struct rockchip_drm_gem_obj *rockchip_gem_obj;
673         int ret;
674
675         DRM_DEBUG_KMS("%s\n", __FILE__);
676
677         /*
678          * alocate memory to be used for framebuffer.
679          * - this callback would be called by user application
680          *      with DRM_IOCTL_MODE_CREATE_DUMB command.
681          */
682
683         args->pitch = args->width * ((args->bpp + 7) / 8);
684         args->size = args->pitch * args->height;
685
686         rockchip_gem_obj = rockchip_drm_gem_create(dev, ROCKCHIP_BO_CONTIG |
687                                                 ROCKCHIP_BO_WC, args->size);
688         if (IS_ERR(rockchip_gem_obj))
689                 return PTR_ERR(rockchip_gem_obj);
690
691         ret = rockchip_drm_gem_handle_create(&rockchip_gem_obj->base, file_priv,
692                         &args->handle);
693         if (ret) {
694                 rockchip_drm_gem_destroy(rockchip_gem_obj);
695                 return ret;
696         }
697
698         return 0;
699 }
700
701 int rockchip_drm_gem_dumb_map_offset(struct drm_file *file_priv,
702                                    struct drm_device *dev, uint32_t handle,
703                                    uint64_t *offset)
704 {
705         struct drm_gem_object *obj;
706         int ret = 0;
707
708         DRM_DEBUG_KMS("%s\n", __FILE__);
709
710         mutex_lock(&dev->struct_mutex);
711
712         /*
713          * get offset of memory allocated for drm framebuffer.
714          * - this callback would be called by user application
715          *      with DRM_IOCTL_MODE_MAP_DUMB command.
716          */
717
718         obj = drm_gem_object_lookup(dev, file_priv, handle);
719         if (!obj) {
720                 DRM_ERROR("failed to lookup gem object.\n");
721                 ret = -EINVAL;
722                 goto unlock;
723         }
724
725         if (!obj->map_list.map) {
726                 ret = drm_gem_create_mmap_offset(obj);
727                 if (ret)
728                         goto out;
729         }
730
731         *offset = (u64)obj->map_list.hash.key << PAGE_SHIFT;
732         DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset);
733
734 out:
735         drm_gem_object_unreference(obj);
736 unlock:
737         mutex_unlock(&dev->struct_mutex);
738         return ret;
739 }
740
741 int rockchip_drm_gem_dumb_destroy(struct drm_file *file_priv,
742                                 struct drm_device *dev,
743                                 unsigned int handle)
744 {
745         int ret;
746
747         DRM_DEBUG_KMS("%s\n", __FILE__);
748
749         /*
750          * obj->refcount and obj->handle_count are decreased and
751          * if both them are 0 then rockchip_drm_gem_free_object()
752          * would be called by callback to release resources.
753          */
754         ret = drm_gem_handle_delete(file_priv, handle);
755         if (ret < 0) {
756                 DRM_ERROR("failed to delete drm_gem_handle.\n");
757                 return ret;
758         }
759
760         return 0;
761 }
762
763 int rockchip_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
764 {
765         struct drm_gem_object *obj = vma->vm_private_data;
766         struct drm_device *dev = obj->dev;
767         unsigned long f_vaddr;
768         pgoff_t page_offset;
769         int ret;
770
771         page_offset = ((unsigned long)vmf->virtual_address -
772                         vma->vm_start) >> PAGE_SHIFT;
773         f_vaddr = (unsigned long)vmf->virtual_address;
774
775         mutex_lock(&dev->struct_mutex);
776
777         ret = rockchip_drm_gem_map_buf(obj, vma, f_vaddr, page_offset);
778         if (ret < 0)
779                 DRM_ERROR("failed to map a buffer with user.\n");
780
781         mutex_unlock(&dev->struct_mutex);
782
783         return convert_to_vm_err_msg(ret);
784 }
785
786 int rockchip_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
787 {
788         struct rockchip_drm_gem_obj *rockchip_gem_obj;
789         struct drm_gem_object *obj;
790         int ret;
791
792         DRM_DEBUG_KMS("%s\n", __FILE__);
793
794         /* set vm_area_struct. */
795         ret = drm_gem_mmap(filp, vma);
796         if (ret < 0) {
797                 DRM_ERROR("failed to mmap.\n");
798                 return ret;
799         }
800
801         obj = vma->vm_private_data;
802         rockchip_gem_obj = to_rockchip_gem_obj(obj);
803
804         ret = check_gem_flags(rockchip_gem_obj->flags);
805         if (ret) {
806                 drm_gem_vm_close(vma);
807                 drm_gem_free_mmap_offset(obj);
808                 return ret;
809         }
810
811         vma->vm_flags &= ~VM_PFNMAP;
812         vma->vm_flags |= VM_MIXEDMAP;
813
814         update_vm_cache_attr(rockchip_gem_obj, vma);
815
816         return ret;
817 }