aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-11-25 10:21:02 -0500
committerDave Airlie <airlied@redhat.com>2012-03-30 06:52:44 -0400
commit3248877ea1796915419fba7c89315fdbf00cb56a (patch)
tree4fab8743212004bc033e71e02a2e051b64001606
parentf52b69f86e27903d6896ed5fa7cd280fec8de532 (diff)
drm: base prime/dma-buf support (v5)
This adds the basic drm dma-buf interface layer, called PRIME. This commit doesn't add any driver support, it is simply and agreed upon starting point so we can work towards merging driver support for the next merge window. Current drivers with work done are nouveau, i915, udl, exynos and omap. The main APIs exposed to userspace allow translating a 32-bit object handle to a file descriptor, and a file descriptor to a 32-bit object handle. The flags value is currently limited to O_CLOEXEC. Acknowledgements: Daniel Vetter: lots of review Rob Clark: cleaned up lots of the internals and did lifetime review. v2: rename some functions after Chris preferred a green shed fix IS_ERR_OR_NULL -> IS_ERR v3: Fix Ville pointed out using buffer + kmalloc v4: add locking as per ickle review v5: allow re-exporting the original dma-buf (Daniel) Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Rob Clark <rob.clark@linaro.org> Reviewed-by: Sumit Semwal <sumit.semwal@linaro.org> Reviewed-by: Inki Dae <inki.dae@samsung.com> Acked-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/Kconfig1
-rw-r--r--drivers/gpu/drm/Makefile2
-rw-r--r--drivers/gpu/drm/drm_drv.c4
-rw-r--r--drivers/gpu/drm/drm_fops.c7
-rw-r--r--drivers/gpu/drm/drm_gem.c9
-rw-r--r--drivers/gpu/drm/drm_prime.c304
-rw-r--r--include/drm/drm.h14
-rw-r--r--include/drm/drmP.h62
8 files changed, 401 insertions, 2 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index cc1148837e24..e354bc0b052a 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -9,6 +9,7 @@ menuconfig DRM
9 depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU 9 depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU
10 select I2C 10 select I2C
11 select I2C_ALGOBIT 11 select I2C_ALGOBIT
12 select DMA_SHARED_BUFFER
12 help 13 help
13 Kernel-level support for the Direct Rendering Infrastructure (DRI) 14 Kernel-level support for the Direct Rendering Infrastructure (DRI)
14 introduced in XFree86 4.0. If you say Y here, you need to select 15 introduced in XFree86 4.0. If you say Y here, you need to select
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index a858532806ae..c20da5bda355 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -12,7 +12,7 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
12 drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ 12 drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
13 drm_crtc.o drm_modes.o drm_edid.o \ 13 drm_crtc.o drm_modes.o drm_edid.o \
14 drm_info.o drm_debugfs.o drm_encoder_slave.o \ 14 drm_info.o drm_debugfs.o drm_encoder_slave.o \
15 drm_trace_points.o drm_global.o 15 drm_trace_points.o drm_global.o drm_prime.o
16 16
17drm-$(CONFIG_COMPAT) += drm_ioc32.o 17drm-$(CONFIG_COMPAT) += drm_ioc32.o
18 18
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 0b65fbc8a630..6116e3b75393 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -136,6 +136,10 @@ static struct drm_ioctl_desc drm_ioctls[] = {
136 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), 136 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
137 137
138 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 138 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
139
140 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED),
141 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED),
142
139 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 143 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
140 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED), 144 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
141 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 145 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 7348a3dab250..cdfbf27b2b3c 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -271,6 +271,9 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
271 if (dev->driver->driver_features & DRIVER_GEM) 271 if (dev->driver->driver_features & DRIVER_GEM)
272 drm_gem_open(dev, priv); 272 drm_gem_open(dev, priv);
273 273
274 if (drm_core_check_feature(dev, DRIVER_PRIME))
275 drm_prime_init_file_private(&priv->prime);
276
274 if (dev->driver->open) { 277 if (dev->driver->open) {
275 ret = dev->driver->open(dev, priv); 278 ret = dev->driver->open(dev, priv);
276 if (ret < 0) 279 if (ret < 0)
@@ -571,6 +574,10 @@ int drm_release(struct inode *inode, struct file *filp)
571 574
572 if (dev->driver->postclose) 575 if (dev->driver->postclose)
573 dev->driver->postclose(dev, file_priv); 576 dev->driver->postclose(dev, file_priv);
577
578 if (drm_core_check_feature(dev, DRIVER_PRIME))
579 drm_prime_destroy_file_private(&file_priv->prime);
580
574 kfree(file_priv); 581 kfree(file_priv);
575 582
576 /* ======================================================== 583 /* ========================================================
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 0ef358e53245..83114b5e3cee 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -35,6 +35,7 @@
35#include <linux/mman.h> 35#include <linux/mman.h>
36#include <linux/pagemap.h> 36#include <linux/pagemap.h>
37#include <linux/shmem_fs.h> 37#include <linux/shmem_fs.h>
38#include <linux/dma-buf.h>
38#include "drmP.h" 39#include "drmP.h"
39 40
40/** @file drm_gem.c 41/** @file drm_gem.c
@@ -232,6 +233,10 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
232 idr_remove(&filp->object_idr, handle); 233 idr_remove(&filp->object_idr, handle);
233 spin_unlock(&filp->table_lock); 234 spin_unlock(&filp->table_lock);
234 235
236 if (obj->import_attach)
237 drm_prime_remove_imported_buf_handle(&filp->prime,
238 obj->import_attach->dmabuf);
239
235 if (dev->driver->gem_close_object) 240 if (dev->driver->gem_close_object)
236 dev->driver->gem_close_object(obj, filp); 241 dev->driver->gem_close_object(obj, filp);
237 drm_gem_object_handle_unreference_unlocked(obj); 242 drm_gem_object_handle_unreference_unlocked(obj);
@@ -527,6 +532,10 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
527 struct drm_gem_object *obj = ptr; 532 struct drm_gem_object *obj = ptr;
528 struct drm_device *dev = obj->dev; 533 struct drm_device *dev = obj->dev;
529 534
535 if (obj->import_attach)
536 drm_prime_remove_imported_buf_handle(&file_priv->prime,
537 obj->import_attach->dmabuf);
538
530 if (dev->driver->gem_close_object) 539 if (dev->driver->gem_close_object)
531 dev->driver->gem_close_object(obj, file_priv); 540 dev->driver->gem_close_object(obj, file_priv);
532 541
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
new file mode 100644
index 000000000000..1bdf2b54eaf6
--- /dev/null
+++ b/drivers/gpu/drm/drm_prime.c
@@ -0,0 +1,304 @@
1/*
2 * Copyright © 2012 Red Hat
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 DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Dave Airlie <airlied@redhat.com>
25 * Rob Clark <rob.clark@linaro.org>
26 *
27 */
28
29#include <linux/export.h>
30#include <linux/dma-buf.h>
31#include "drmP.h"
32
33/*
34 * DMA-BUF/GEM Object references and lifetime overview:
35 *
36 * On the export the dma_buf holds a reference to the exporting GEM
37 * object. It takes this reference in handle_to_fd_ioctl, when it
38 * first calls .prime_export and stores the exporting GEM object in
39 * the dma_buf priv. This reference is released when the dma_buf
40 * object goes away in the driver .release function.
41 *
42 * On the import the importing GEM object holds a reference to the
43 * dma_buf (which in turn holds a ref to the exporting GEM object).
44 * It takes that reference in the fd_to_handle ioctl.
45 * It calls dma_buf_get, creates an attachment to it and stores the
46 * attachment in the GEM object. When this attachment is destroyed
47 * when the imported object is destroyed, we remove the attachment
48 * and drop the reference to the dma_buf.
49 *
50 * Thus the chain of references always flows in one direction
51 * (avoiding loops): importing_gem -> dmabuf -> exporting_gem
52 *
53 * Self-importing: if userspace is using PRIME as a replacement for flink
54 * then it will get a fd->handle request for a GEM object that it created.
55 * Drivers should detect this situation and return back the gem object
56 * from the dma-buf private.
57 */
58
59struct drm_prime_member {
60 struct list_head entry;
61 struct dma_buf *dma_buf;
62 uint32_t handle;
63};
64
65int drm_gem_prime_handle_to_fd(struct drm_device *dev,
66 struct drm_file *file_priv, uint32_t handle, uint32_t flags,
67 int *prime_fd)
68{
69 struct drm_gem_object *obj;
70 void *buf;
71
72 obj = drm_gem_object_lookup(dev, file_priv, handle);
73 if (!obj)
74 return -ENOENT;
75
76 mutex_lock(&file_priv->prime.lock);
77 /* re-export the original imported object */
78 if (obj->import_attach) {
79 get_dma_buf(obj->import_attach->dmabuf);
80 *prime_fd = dma_buf_fd(obj->import_attach->dmabuf, flags);
81 drm_gem_object_unreference_unlocked(obj);
82 mutex_unlock(&file_priv->prime.lock);
83 return 0;
84 }
85
86 if (obj->export_dma_buf) {
87 get_dma_buf(obj->export_dma_buf);
88 *prime_fd = dma_buf_fd(obj->export_dma_buf, flags);
89 drm_gem_object_unreference_unlocked(obj);
90 } else {
91 buf = dev->driver->gem_prime_export(dev, obj, flags);
92 if (IS_ERR(buf)) {
93 /* normally the created dma-buf takes ownership of the ref,
94 * but if that fails then drop the ref
95 */
96 drm_gem_object_unreference_unlocked(obj);
97 mutex_unlock(&file_priv->prime.lock);
98 return PTR_ERR(buf);
99 }
100 obj->export_dma_buf = buf;
101 *prime_fd = dma_buf_fd(buf, flags);
102 }
103 mutex_unlock(&file_priv->prime.lock);
104 return 0;
105}
106EXPORT_SYMBOL(drm_gem_prime_handle_to_fd);
107
108int drm_gem_prime_fd_to_handle(struct drm_device *dev,
109 struct drm_file *file_priv, int prime_fd, uint32_t *handle)
110{
111 struct dma_buf *dma_buf;
112 struct drm_gem_object *obj;
113 int ret;
114
115 dma_buf = dma_buf_get(prime_fd);
116 if (IS_ERR(dma_buf))
117 return PTR_ERR(dma_buf);
118
119 mutex_lock(&file_priv->prime.lock);
120
121 ret = drm_prime_lookup_imported_buf_handle(&file_priv->prime,
122 dma_buf, handle);
123 if (!ret) {
124 ret = 0;
125 goto out_put;
126 }
127
128 /* never seen this one, need to import */
129 obj = dev->driver->gem_prime_import(dev, dma_buf);
130 if (IS_ERR(obj)) {
131 ret = PTR_ERR(obj);
132 goto out_put;
133 }
134
135 ret = drm_gem_handle_create(file_priv, obj, handle);
136 drm_gem_object_unreference_unlocked(obj);
137 if (ret)
138 goto out_put;
139
140 ret = drm_prime_add_imported_buf_handle(&file_priv->prime,
141 dma_buf, *handle);
142 if (ret)
143 goto fail;
144
145 mutex_unlock(&file_priv->prime.lock);
146 return 0;
147
148fail:
149 /* hmm, if driver attached, we are relying on the free-object path
150 * to detach.. which seems ok..
151 */
152 drm_gem_object_handle_unreference_unlocked(obj);
153out_put:
154 dma_buf_put(dma_buf);
155 mutex_unlock(&file_priv->prime.lock);
156 return ret;
157}
158EXPORT_SYMBOL(drm_gem_prime_fd_to_handle);
159
160int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
161 struct drm_file *file_priv)
162{
163 struct drm_prime_handle *args = data;
164 uint32_t flags;
165
166 if (!drm_core_check_feature(dev, DRIVER_PRIME))
167 return -EINVAL;
168
169 if (!dev->driver->prime_handle_to_fd)
170 return -ENOSYS;
171
172 /* check flags are valid */
173 if (args->flags & ~DRM_CLOEXEC)
174 return -EINVAL;
175
176 /* we only want to pass DRM_CLOEXEC which is == O_CLOEXEC */
177 flags = args->flags & DRM_CLOEXEC;
178
179 return dev->driver->prime_handle_to_fd(dev, file_priv,
180 args->handle, flags, &args->fd);
181}
182
183int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data,
184 struct drm_file *file_priv)
185{
186 struct drm_prime_handle *args = data;
187
188 if (!drm_core_check_feature(dev, DRIVER_PRIME))
189 return -EINVAL;
190
191 if (!dev->driver->prime_fd_to_handle)
192 return -ENOSYS;
193
194 return dev->driver->prime_fd_to_handle(dev, file_priv,
195 args->fd, &args->handle);
196}
197
198/*
199 * drm_prime_pages_to_sg
200 *
201 * this helper creates an sg table object from a set of pages
202 * the driver is responsible for mapping the pages into the
203 * importers address space
204 */
205struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages)
206{
207 struct sg_table *sg = NULL;
208 struct scatterlist *iter;
209 int i;
210 int ret;
211
212 sg = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
213 if (!sg)
214 goto out;
215
216 ret = sg_alloc_table(sg, nr_pages, GFP_KERNEL);
217 if (ret)
218 goto out;
219
220 for_each_sg(sg->sgl, iter, nr_pages, i)
221 sg_set_page(iter, pages[i], PAGE_SIZE, 0);
222
223 return sg;
224out:
225 kfree(sg);
226 return NULL;
227}
228EXPORT_SYMBOL(drm_prime_pages_to_sg);
229
230/* helper function to cleanup a GEM/prime object */
231void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg)
232{
233 struct dma_buf_attachment *attach;
234 struct dma_buf *dma_buf;
235 attach = obj->import_attach;
236 if (sg)
237 dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL);
238 dma_buf = attach->dmabuf;
239 dma_buf_detach(attach->dmabuf, attach);
240 /* remove the reference */
241 dma_buf_put(dma_buf);
242}
243EXPORT_SYMBOL(drm_prime_gem_destroy);
244
245void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv)
246{
247 INIT_LIST_HEAD(&prime_fpriv->head);
248 mutex_init(&prime_fpriv->lock);
249}
250EXPORT_SYMBOL(drm_prime_init_file_private);
251
252void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv)
253{
254 struct drm_prime_member *member, *safe;
255 list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) {
256 list_del(&member->entry);
257 kfree(member);
258 }
259}
260EXPORT_SYMBOL(drm_prime_destroy_file_private);
261
262int drm_prime_add_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle)
263{
264 struct drm_prime_member *member;
265
266 member = kmalloc(sizeof(*member), GFP_KERNEL);
267 if (!member)
268 return -ENOMEM;
269
270 member->dma_buf = dma_buf;
271 member->handle = handle;
272 list_add(&member->entry, &prime_fpriv->head);
273 return 0;
274}
275EXPORT_SYMBOL(drm_prime_add_imported_buf_handle);
276
277int drm_prime_lookup_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle)
278{
279 struct drm_prime_member *member;
280
281 list_for_each_entry(member, &prime_fpriv->head, entry) {
282 if (member->dma_buf == dma_buf) {
283 *handle = member->handle;
284 return 0;
285 }
286 }
287 return -ENOENT;
288}
289EXPORT_SYMBOL(drm_prime_lookup_imported_buf_handle);
290
291void drm_prime_remove_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf)
292{
293 struct drm_prime_member *member, *safe;
294
295 mutex_lock(&prime_fpriv->lock);
296 list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) {
297 if (member->dma_buf == dma_buf) {
298 list_del(&member->entry);
299 kfree(member);
300 }
301 }
302 mutex_unlock(&prime_fpriv->lock);
303}
304EXPORT_SYMBOL(drm_prime_remove_imported_buf_handle);
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 34a7b89fd006..64ff02d5b730 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -617,6 +617,17 @@ struct drm_get_cap {
617 __u64 value; 617 __u64 value;
618}; 618};
619 619
620#define DRM_CLOEXEC O_CLOEXEC
621struct drm_prime_handle {
622 __u32 handle;
623
624 /** Flags.. only applicable for handle->fd */
625 __u32 flags;
626
627 /** Returned dmabuf file descriptor */
628 __s32 fd;
629};
630
620#include "drm_mode.h" 631#include "drm_mode.h"
621 632
622#define DRM_IOCTL_BASE 'd' 633#define DRM_IOCTL_BASE 'd'
@@ -673,7 +684,8 @@ struct drm_get_cap {
673#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock) 684#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock)
674#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock) 685#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock)
675 686
676#define DRM_IOCTL_GEM_PRIME_OPEN DRM_IOWR(0x2e, struct drm_gem_open) 687#define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle)
688#define DRM_IOCTL_PRIME_FD_TO_HANDLE DRM_IOWR(0x2e, struct drm_prime_handle)
677 689
678#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) 690#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
679#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) 691#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 574bd1c81ebd..dd731043fecd 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -91,6 +91,7 @@ struct drm_device;
91#define DRM_UT_CORE 0x01 91#define DRM_UT_CORE 0x01
92#define DRM_UT_DRIVER 0x02 92#define DRM_UT_DRIVER 0x02
93#define DRM_UT_KMS 0x04 93#define DRM_UT_KMS 0x04
94#define DRM_UT_PRIME 0x08
94/* 95/*
95 * Three debug levels are defined. 96 * Three debug levels are defined.
96 * drm_core, drm_driver, drm_kms 97 * drm_core, drm_driver, drm_kms
@@ -150,6 +151,7 @@ int drm_err(const char *func, const char *format, ...);
150#define DRIVER_IRQ_VBL2 0x800 151#define DRIVER_IRQ_VBL2 0x800
151#define DRIVER_GEM 0x1000 152#define DRIVER_GEM 0x1000
152#define DRIVER_MODESET 0x2000 153#define DRIVER_MODESET 0x2000
154#define DRIVER_PRIME 0x4000
153 155
154#define DRIVER_BUS_PCI 0x1 156#define DRIVER_BUS_PCI 0x1
155#define DRIVER_BUS_PLATFORM 0x2 157#define DRIVER_BUS_PLATFORM 0x2
@@ -215,6 +217,11 @@ int drm_err(const char *func, const char *format, ...);
215 drm_ut_debug_printk(DRM_UT_KMS, DRM_NAME, \ 217 drm_ut_debug_printk(DRM_UT_KMS, DRM_NAME, \
216 __func__, fmt, ##args); \ 218 __func__, fmt, ##args); \
217 } while (0) 219 } while (0)
220#define DRM_DEBUG_PRIME(fmt, args...) \
221 do { \
222 drm_ut_debug_printk(DRM_UT_PRIME, DRM_NAME, \
223 __func__, fmt, ##args); \
224 } while (0)
218#define DRM_LOG(fmt, args...) \ 225#define DRM_LOG(fmt, args...) \
219 do { \ 226 do { \
220 drm_ut_debug_printk(DRM_UT_CORE, NULL, \ 227 drm_ut_debug_printk(DRM_UT_CORE, NULL, \
@@ -238,6 +245,7 @@ int drm_err(const char *func, const char *format, ...);
238#else 245#else
239#define DRM_DEBUG_DRIVER(fmt, args...) do { } while (0) 246#define DRM_DEBUG_DRIVER(fmt, args...) do { } while (0)
240#define DRM_DEBUG_KMS(fmt, args...) do { } while (0) 247#define DRM_DEBUG_KMS(fmt, args...) do { } while (0)
248#define DRM_DEBUG_PRIME(fmt, args...) do { } while (0)
241#define DRM_DEBUG(fmt, arg...) do { } while (0) 249#define DRM_DEBUG(fmt, arg...) do { } while (0)
242#define DRM_LOG(fmt, arg...) do { } while (0) 250#define DRM_LOG(fmt, arg...) do { } while (0)
243#define DRM_LOG_KMS(fmt, args...) do { } while (0) 251#define DRM_LOG_KMS(fmt, args...) do { } while (0)
@@ -410,6 +418,12 @@ struct drm_pending_event {
410 void (*destroy)(struct drm_pending_event *event); 418 void (*destroy)(struct drm_pending_event *event);
411}; 419};
412 420
421/* initial implementaton using a linked list - todo hashtab */
422struct drm_prime_file_private {
423 struct list_head head;
424 struct mutex lock;
425};
426
413/** File private data */ 427/** File private data */
414struct drm_file { 428struct drm_file {
415 int authenticated; 429 int authenticated;
@@ -437,6 +451,8 @@ struct drm_file {
437 wait_queue_head_t event_wait; 451 wait_queue_head_t event_wait;
438 struct list_head event_list; 452 struct list_head event_list;
439 int event_space; 453 int event_space;
454
455 struct drm_prime_file_private prime;
440}; 456};
441 457
442/** Wait queue */ 458/** Wait queue */
@@ -652,6 +668,12 @@ struct drm_gem_object {
652 uint32_t pending_write_domain; 668 uint32_t pending_write_domain;
653 669
654 void *driver_private; 670 void *driver_private;
671
672 /* dma buf exported from this GEM object */
673 struct dma_buf *export_dma_buf;
674
675 /* dma buf attachment backing this object */
676 struct dma_buf_attachment *import_attach;
655}; 677};
656 678
657#include "drm_crtc.h" 679#include "drm_crtc.h"
@@ -890,6 +912,20 @@ struct drm_driver {
890 int (*gem_open_object) (struct drm_gem_object *, struct drm_file *); 912 int (*gem_open_object) (struct drm_gem_object *, struct drm_file *);
891 void (*gem_close_object) (struct drm_gem_object *, struct drm_file *); 913 void (*gem_close_object) (struct drm_gem_object *, struct drm_file *);
892 914
915 /* prime: */
916 /* export handle -> fd (see drm_gem_prime_handle_to_fd() helper) */
917 int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv,
918 uint32_t handle, uint32_t flags, int *prime_fd);
919 /* import fd -> handle (see drm_gem_prime_fd_to_handle() helper) */
920 int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv,
921 int prime_fd, uint32_t *handle);
922 /* export GEM -> dmabuf */
923 struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
924 struct drm_gem_object *obj, int flags);
925 /* import dmabuf -> GEM */
926 struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
927 struct dma_buf *dma_buf);
928
893 /* vga arb irq handler */ 929 /* vga arb irq handler */
894 void (*vgaarb_irq)(struct drm_device *dev, bool state); 930 void (*vgaarb_irq)(struct drm_device *dev, bool state);
895 931
@@ -1509,6 +1545,32 @@ extern int drm_vblank_info(struct seq_file *m, void *data);
1509extern int drm_clients_info(struct seq_file *m, void* data); 1545extern int drm_clients_info(struct seq_file *m, void* data);
1510extern int drm_gem_name_info(struct seq_file *m, void *data); 1546extern int drm_gem_name_info(struct seq_file *m, void *data);
1511 1547
1548
1549extern int drm_gem_prime_handle_to_fd(struct drm_device *dev,
1550 struct drm_file *file_priv, uint32_t handle, uint32_t flags,
1551 int *prime_fd);
1552extern int drm_gem_prime_fd_to_handle(struct drm_device *dev,
1553 struct drm_file *file_priv, int prime_fd, uint32_t *handle);
1554
1555extern int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
1556 struct drm_file *file_priv);
1557extern int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data,
1558 struct drm_file *file_priv);
1559
1560extern struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages);
1561extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg);
1562
1563
1564void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv);
1565void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv);
1566int drm_prime_add_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle);
1567int drm_prime_lookup_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle);
1568void drm_prime_remove_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf);
1569
1570int drm_prime_add_dma_buf(struct drm_device *dev, struct drm_gem_object *obj);
1571int drm_prime_lookup_obj(struct drm_device *dev, struct dma_buf *buf,
1572 struct drm_gem_object **obj);
1573
1512#if DRM_DEBUG_CODE 1574#if DRM_DEBUG_CODE
1513extern int drm_vma_info(struct seq_file *m, void *data); 1575extern int drm_vma_info(struct seq_file *m, void *data);
1514#endif 1576#endif