Commit 3248877ea1796915419fba7c89315fdbf00cb56a

Authored by Dave Airlie
1 parent f52b69f86e

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>

Showing 8 changed files with 401 additions and 2 deletions Side-by-side Diff

drivers/gpu/drm/Kconfig
... ... @@ -9,6 +9,7 @@
9 9 depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU
10 10 select I2C
11 11 select I2C_ALGOBIT
  12 + select DMA_SHARED_BUFFER
12 13 help
13 14 Kernel-level support for the Direct Rendering Infrastructure (DRI)
14 15 introduced in XFree86 4.0. If you say Y here, you need to select
drivers/gpu/drm/Makefile
... ... @@ -12,7 +12,7 @@
12 12 drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
13 13 drm_crtc.o drm_modes.o drm_edid.o \
14 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  
17 17 drm-$(CONFIG_COMPAT) += drm_ioc32.o
18 18  
drivers/gpu/drm/drm_drv.c
... ... @@ -136,6 +136,10 @@
136 136 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
137 137  
138 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 143 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
140 144 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
141 145 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
drivers/gpu/drm/drm_fops.c
... ... @@ -271,6 +271,9 @@
271 271 if (dev->driver->driver_features & DRIVER_GEM)
272 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 277 if (dev->driver->open) {
275 278 ret = dev->driver->open(dev, priv);
276 279 if (ret < 0)
... ... @@ -571,6 +574,10 @@
571 574  
572 575 if (dev->driver->postclose)
573 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 581 kfree(file_priv);
575 582  
576 583 /* ========================================================
drivers/gpu/drm/drm_gem.c
... ... @@ -35,6 +35,7 @@
35 35 #include <linux/mman.h>
36 36 #include <linux/pagemap.h>
37 37 #include <linux/shmem_fs.h>
  38 +#include <linux/dma-buf.h>
38 39 #include "drmP.h"
39 40  
40 41 /** @file drm_gem.c
... ... @@ -232,6 +233,10 @@
232 233 idr_remove(&filp->object_idr, handle);
233 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 240 if (dev->driver->gem_close_object)
236 241 dev->driver->gem_close_object(obj, filp);
237 242 drm_gem_object_handle_unreference_unlocked(obj);
... ... @@ -526,6 +531,10 @@
526 531 struct drm_file *file_priv = data;
527 532 struct drm_gem_object *obj = ptr;
528 533 struct drm_device *dev = obj->dev;
  534 +
  535 + if (obj->import_attach)
  536 + drm_prime_remove_imported_buf_handle(&file_priv->prime,
  537 + obj->import_attach->dmabuf);
529 538  
530 539 if (dev->driver->gem_close_object)
531 540 dev->driver->gem_close_object(obj, file_priv);
drivers/gpu/drm/drm_prime.c
  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 +
  59 +struct drm_prime_member {
  60 + struct list_head entry;
  61 + struct dma_buf *dma_buf;
  62 + uint32_t handle;
  63 +};
  64 +
  65 +int 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 +}
  106 +EXPORT_SYMBOL(drm_gem_prime_handle_to_fd);
  107 +
  108 +int 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 +
  148 +fail:
  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);
  153 +out_put:
  154 + dma_buf_put(dma_buf);
  155 + mutex_unlock(&file_priv->prime.lock);
  156 + return ret;
  157 +}
  158 +EXPORT_SYMBOL(drm_gem_prime_fd_to_handle);
  159 +
  160 +int 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 +
  183 +int 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 + */
  205 +struct 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;
  224 +out:
  225 + kfree(sg);
  226 + return NULL;
  227 +}
  228 +EXPORT_SYMBOL(drm_prime_pages_to_sg);
  229 +
  230 +/* helper function to cleanup a GEM/prime object */
  231 +void 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 +}
  243 +EXPORT_SYMBOL(drm_prime_gem_destroy);
  244 +
  245 +void 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 +}
  250 +EXPORT_SYMBOL(drm_prime_init_file_private);
  251 +
  252 +void 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 +}
  260 +EXPORT_SYMBOL(drm_prime_destroy_file_private);
  261 +
  262 +int 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 +}
  275 +EXPORT_SYMBOL(drm_prime_add_imported_buf_handle);
  276 +
  277 +int 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 +}
  289 +EXPORT_SYMBOL(drm_prime_lookup_imported_buf_handle);
  290 +
  291 +void 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 +}
  304 +EXPORT_SYMBOL(drm_prime_remove_imported_buf_handle);
... ... @@ -617,6 +617,17 @@
617 617 __u64 value;
618 618 };
619 619  
  620 +#define DRM_CLOEXEC O_CLOEXEC
  621 +struct 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 631 #include "drm_mode.h"
621 632  
622 633 #define DRM_IOCTL_BASE 'd'
... ... @@ -673,7 +684,8 @@
673 684 #define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock)
674 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 690 #define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
679 691 #define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
... ... @@ -91,6 +91,7 @@
91 91 #define DRM_UT_CORE 0x01
92 92 #define DRM_UT_DRIVER 0x02
93 93 #define DRM_UT_KMS 0x04
  94 +#define DRM_UT_PRIME 0x08
94 95 /*
95 96 * Three debug levels are defined.
96 97 * drm_core, drm_driver, drm_kms
... ... @@ -150,6 +151,7 @@
150 151 #define DRIVER_IRQ_VBL2 0x800
151 152 #define DRIVER_GEM 0x1000
152 153 #define DRIVER_MODESET 0x2000
  154 +#define DRIVER_PRIME 0x4000
153 155  
154 156 #define DRIVER_BUS_PCI 0x1
155 157 #define DRIVER_BUS_PLATFORM 0x2
... ... @@ -215,6 +217,11 @@
215 217 drm_ut_debug_printk(DRM_UT_KMS, DRM_NAME, \
216 218 __func__, fmt, ##args); \
217 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 225 #define DRM_LOG(fmt, args...) \
219 226 do { \
220 227 drm_ut_debug_printk(DRM_UT_CORE, NULL, \
... ... @@ -238,6 +245,7 @@
238 245 #else
239 246 #define DRM_DEBUG_DRIVER(fmt, args...) do { } while (0)
240 247 #define DRM_DEBUG_KMS(fmt, args...) do { } while (0)
  248 +#define DRM_DEBUG_PRIME(fmt, args...) do { } while (0)
241 249 #define DRM_DEBUG(fmt, arg...) do { } while (0)
242 250 #define DRM_LOG(fmt, arg...) do { } while (0)
243 251 #define DRM_LOG_KMS(fmt, args...) do { } while (0)
... ... @@ -410,6 +418,12 @@
410 418 void (*destroy)(struct drm_pending_event *event);
411 419 };
412 420  
  421 +/* initial implementaton using a linked list - todo hashtab */
  422 +struct drm_prime_file_private {
  423 + struct list_head head;
  424 + struct mutex lock;
  425 +};
  426 +
413 427 /** File private data */
414 428 struct drm_file {
415 429 int authenticated;
... ... @@ -437,6 +451,8 @@
437 451 wait_queue_head_t event_wait;
438 452 struct list_head event_list;
439 453 int event_space;
  454 +
  455 + struct drm_prime_file_private prime;
440 456 };
441 457  
442 458 /** Wait queue */
... ... @@ -652,6 +668,12 @@
652 668 uint32_t pending_write_domain;
653 669  
654 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 679 #include "drm_crtc.h"
... ... @@ -890,6 +912,20 @@
890 912 int (*gem_open_object) (struct drm_gem_object *, struct drm_file *);
891 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 929 /* vga arb irq handler */
894 930 void (*vgaarb_irq)(struct drm_device *dev, bool state);
895 931  
... ... @@ -1508,6 +1544,32 @@
1508 1544 extern int drm_vblank_info(struct seq_file *m, void *data);
1509 1545 extern int drm_clients_info(struct seq_file *m, void* data);
1510 1546 extern int drm_gem_name_info(struct seq_file *m, void *data);
  1547 +
  1548 +
  1549 +extern 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);
  1552 +extern int drm_gem_prime_fd_to_handle(struct drm_device *dev,
  1553 + struct drm_file *file_priv, int prime_fd, uint32_t *handle);
  1554 +
  1555 +extern int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
  1556 + struct drm_file *file_priv);
  1557 +extern int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data,
  1558 + struct drm_file *file_priv);
  1559 +
  1560 +extern struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages);
  1561 +extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg);
  1562 +
  1563 +
  1564 +void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv);
  1565 +void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv);
  1566 +int drm_prime_add_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle);
  1567 +int drm_prime_lookup_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle);
  1568 +void drm_prime_remove_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf);
  1569 +
  1570 +int drm_prime_add_dma_buf(struct drm_device *dev, struct drm_gem_object *obj);
  1571 +int drm_prime_lookup_obj(struct drm_device *dev, struct dma_buf *buf,
  1572 + struct drm_gem_object **obj);
1511 1573  
1512 1574 #if DRM_DEBUG_CODE
1513 1575 extern int drm_vma_info(struct seq_file *m, void *data);