Merge tag 'v4.6-rc3' into drm-intel-next-queued
[cascardo/linux.git] / drivers / gpu / drm / i915 / i915_gem_dmabuf.c
1 /*
2  * Copyright 2012 Red Hat Inc
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *      Dave Airlie <airlied@redhat.com>
25  */
26 #include <drm/drmP.h>
27 #include "i915_drv.h"
28 #include <linux/dma-buf.h>
29
30 static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf *buf)
31 {
32         return to_intel_bo(buf->priv);
33 }
34
35 static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachment,
36                                              enum dma_data_direction dir)
37 {
38         struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
39         struct sg_table *st;
40         struct scatterlist *src, *dst;
41         int ret, i;
42
43         ret = i915_mutex_lock_interruptible(obj->base.dev);
44         if (ret)
45                 goto err;
46
47         ret = i915_gem_object_get_pages(obj);
48         if (ret)
49                 goto err_unlock;
50
51         i915_gem_object_pin_pages(obj);
52
53         /* Copy sg so that we make an independent mapping */
54         st = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
55         if (st == NULL) {
56                 ret = -ENOMEM;
57                 goto err_unpin;
58         }
59
60         ret = sg_alloc_table(st, obj->pages->nents, GFP_KERNEL);
61         if (ret)
62                 goto err_free;
63
64         src = obj->pages->sgl;
65         dst = st->sgl;
66         for (i = 0; i < obj->pages->nents; i++) {
67                 sg_set_page(dst, sg_page(src), src->length, 0);
68                 dst = sg_next(dst);
69                 src = sg_next(src);
70         }
71
72         if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
73                 ret =-ENOMEM;
74                 goto err_free_sg;
75         }
76
77         mutex_unlock(&obj->base.dev->struct_mutex);
78         return st;
79
80 err_free_sg:
81         sg_free_table(st);
82 err_free:
83         kfree(st);
84 err_unpin:
85         i915_gem_object_unpin_pages(obj);
86 err_unlock:
87         mutex_unlock(&obj->base.dev->struct_mutex);
88 err:
89         return ERR_PTR(ret);
90 }
91
92 static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
93                                    struct sg_table *sg,
94                                    enum dma_data_direction dir)
95 {
96         struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
97
98         dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir);
99         sg_free_table(sg);
100         kfree(sg);
101
102         mutex_lock(&obj->base.dev->struct_mutex);
103         i915_gem_object_unpin_pages(obj);
104         mutex_unlock(&obj->base.dev->struct_mutex);
105 }
106
107 static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
108 {
109         struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
110         struct drm_device *dev = obj->base.dev;
111         void *addr;
112         int ret;
113
114         ret = i915_mutex_lock_interruptible(dev);
115         if (ret)
116                 return ERR_PTR(ret);
117
118         addr = i915_gem_object_pin_map(obj);
119         mutex_unlock(&dev->struct_mutex);
120
121         return addr;
122 }
123
124 static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
125 {
126         struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
127         struct drm_device *dev = obj->base.dev;
128
129         mutex_lock(&dev->struct_mutex);
130         i915_gem_object_unpin_map(obj);
131         mutex_unlock(&dev->struct_mutex);
132 }
133
134 static void *i915_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num)
135 {
136         return NULL;
137 }
138
139 static void i915_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
140 {
141
142 }
143 static void *i915_gem_dmabuf_kmap(struct dma_buf *dma_buf, unsigned long page_num)
144 {
145         return NULL;
146 }
147
148 static void i915_gem_dmabuf_kunmap(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
149 {
150
151 }
152
153 static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
154 {
155         struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
156         int ret;
157
158         if (obj->base.size < vma->vm_end - vma->vm_start)
159                 return -EINVAL;
160
161         if (!obj->base.filp)
162                 return -ENODEV;
163
164         ret = obj->base.filp->f_op->mmap(obj->base.filp, vma);
165         if (ret)
166                 return ret;
167
168         fput(vma->vm_file);
169         vma->vm_file = get_file(obj->base.filp);
170
171         return 0;
172 }
173
174 static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction)
175 {
176         struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
177         struct drm_device *dev = obj->base.dev;
178         int ret;
179         bool write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE);
180
181         ret = i915_mutex_lock_interruptible(dev);
182         if (ret)
183                 return ret;
184
185         ret = i915_gem_object_set_to_cpu_domain(obj, write);
186         mutex_unlock(&dev->struct_mutex);
187         return ret;
188 }
189
190 static int i915_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction)
191 {
192         struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
193         struct drm_device *dev = obj->base.dev;
194         int ret;
195
196         ret = i915_mutex_lock_interruptible(dev);
197         if (ret)
198                 return ret;
199
200         ret = i915_gem_object_set_to_gtt_domain(obj, false);
201         mutex_unlock(&dev->struct_mutex);
202
203         return ret;
204 }
205
206 static const struct dma_buf_ops i915_dmabuf_ops =  {
207         .map_dma_buf = i915_gem_map_dma_buf,
208         .unmap_dma_buf = i915_gem_unmap_dma_buf,
209         .release = drm_gem_dmabuf_release,
210         .kmap = i915_gem_dmabuf_kmap,
211         .kmap_atomic = i915_gem_dmabuf_kmap_atomic,
212         .kunmap = i915_gem_dmabuf_kunmap,
213         .kunmap_atomic = i915_gem_dmabuf_kunmap_atomic,
214         .mmap = i915_gem_dmabuf_mmap,
215         .vmap = i915_gem_dmabuf_vmap,
216         .vunmap = i915_gem_dmabuf_vunmap,
217         .begin_cpu_access = i915_gem_begin_cpu_access,
218         .end_cpu_access = i915_gem_end_cpu_access,
219 };
220
221 struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
222                                       struct drm_gem_object *gem_obj, int flags)
223 {
224         struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
225         DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
226
227         exp_info.ops = &i915_dmabuf_ops;
228         exp_info.size = gem_obj->size;
229         exp_info.flags = flags;
230         exp_info.priv = gem_obj;
231
232
233         if (obj->ops->dmabuf_export) {
234                 int ret = obj->ops->dmabuf_export(obj);
235                 if (ret)
236                         return ERR_PTR(ret);
237         }
238
239         return dma_buf_export(&exp_info);
240 }
241
242 static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
243 {
244         struct sg_table *sg;
245
246         sg = dma_buf_map_attachment(obj->base.import_attach, DMA_BIDIRECTIONAL);
247         if (IS_ERR(sg))
248                 return PTR_ERR(sg);
249
250         obj->pages = sg;
251         return 0;
252 }
253
254 static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj)
255 {
256         dma_buf_unmap_attachment(obj->base.import_attach,
257                                  obj->pages, DMA_BIDIRECTIONAL);
258 }
259
260 static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = {
261         .get_pages = i915_gem_object_get_pages_dmabuf,
262         .put_pages = i915_gem_object_put_pages_dmabuf,
263 };
264
265 struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
266                                              struct dma_buf *dma_buf)
267 {
268         struct dma_buf_attachment *attach;
269         struct drm_i915_gem_object *obj;
270         int ret;
271
272         /* is this one of own objects? */
273         if (dma_buf->ops == &i915_dmabuf_ops) {
274                 obj = dma_buf_to_obj(dma_buf);
275                 /* is it from our device? */
276                 if (obj->base.dev == dev) {
277                         /*
278                          * Importing dmabuf exported from out own gem increases
279                          * refcount on gem itself instead of f_count of dmabuf.
280                          */
281                         drm_gem_object_reference(&obj->base);
282                         return &obj->base;
283                 }
284         }
285
286         /* need to attach */
287         attach = dma_buf_attach(dma_buf, dev->dev);
288         if (IS_ERR(attach))
289                 return ERR_CAST(attach);
290
291         get_dma_buf(dma_buf);
292
293         obj = i915_gem_object_alloc(dev);
294         if (obj == NULL) {
295                 ret = -ENOMEM;
296                 goto fail_detach;
297         }
298
299         drm_gem_private_object_init(dev, &obj->base, dma_buf->size);
300         i915_gem_object_init(obj, &i915_gem_object_dmabuf_ops);
301         obj->base.import_attach = attach;
302
303         return &obj->base;
304
305 fail_detach:
306         dma_buf_detach(dma_buf, attach);
307         dma_buf_put(dma_buf);
308
309         return ERR_PTR(ret);
310 }