drm/vc4: Add create and map BO ioctls.
authorEric Anholt <eric@anholt.net>
Sat, 17 Jan 2015 20:33:17 +0000 (09:33 +1300)
committerEric Anholt <eric@anholt.net>
Tue, 8 Dec 2015 04:04:57 +0000 (20:04 -0800)
While there exist dumb APIs for creating and mapping BOs, one of the
rules is that drivers doing 3D acceleration have to provide their own
APIs for buffer allocation (besides, the pitch/height parameters of
the dumb alloc don't really make sense for a lot of 3D allocations).

v2: Use __u32-style types, use "drm.h" instead of <drm/drm.h>.

Signed-off-by: Eric Anholt <eric@anholt.net>
drivers/gpu/drm/vc4/vc4_bo.c
drivers/gpu/drm/vc4/vc4_drv.c
drivers/gpu/drm/vc4/vc4_drv.h
include/uapi/drm/Kbuild
include/uapi/drm/vc4_drm.h [new file with mode: 0644]

index 18faa5ba37b74bf8d507437b7a390bbab52d5866..06cba268e17afa84c43afb964f2eee4e2ea97679 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "vc4_drv.h"
+#include "uapi/drm/vc4_drm.h"
 
 static void vc4_bo_stats_dump(struct vc4_dev *vc4)
 {
@@ -346,6 +347,46 @@ static void vc4_bo_cache_time_timer(unsigned long data)
        schedule_work(&vc4->bo_cache.time_work);
 }
 
+int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
+                       struct drm_file *file_priv)
+{
+       struct drm_vc4_create_bo *args = data;
+       struct vc4_bo *bo = NULL;
+       int ret;
+
+       /*
+        * We can't allocate from the BO cache, because the BOs don't
+        * get zeroed, and that might leak data between users.
+        */
+       bo = vc4_bo_create(dev, args->size, false);
+       if (!bo)
+               return -ENOMEM;
+
+       ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
+       drm_gem_object_unreference_unlocked(&bo->base.base);
+
+       return ret;
+}
+
+int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
+                     struct drm_file *file_priv)
+{
+       struct drm_vc4_mmap_bo *args = data;
+       struct drm_gem_object *gem_obj;
+
+       gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+       if (!gem_obj) {
+               DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
+               return -EINVAL;
+       }
+
+       /* The mmap offset was set up at BO allocation time. */
+       args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
+
+       drm_gem_object_unreference_unlocked(gem_obj);
+       return 0;
+}
+
 void vc4_bo_cache_init(struct drm_device *dev)
 {
        struct vc4_dev *vc4 = to_vc4_dev(dev);
index da041fac0731126f2744feda1cff2f850291f4f2..5fa468864ec8f606f63284d9e13e82e0d9eb2984 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include "drm_fb_cma_helper.h"
 
+#include "uapi/drm/vc4_drm.h"
 #include "vc4_drv.h"
 #include "vc4_regs.h"
 
@@ -73,6 +74,8 @@ static const struct file_operations vc4_drm_fops = {
 };
 
 static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
+       DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0),
+       DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0),
 };
 
 static struct drm_driver vc4_drm_driver = {
index 39a1ff5c8f28dbcf1c9c824b4f1a822eaebb9e4e..fddb0a06ed3a415cff2a86d1534c7188f9a7a607 100644 (file)
@@ -155,6 +155,10 @@ int vc4_dumb_create(struct drm_file *file_priv,
                    struct drm_mode_create_dumb *args);
 struct dma_buf *vc4_prime_export(struct drm_device *dev,
                                 struct drm_gem_object *obj, int flags);
+int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
+                       struct drm_file *file_priv);
+int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
+                     struct drm_file *file_priv);
 void vc4_bo_cache_init(struct drm_device *dev);
 void vc4_bo_cache_destroy(struct drm_device *dev);
 int vc4_bo_stats_debugfs(struct seq_file *m, void *arg);
index 38d437096c358c884a403e4f3f5be5fb86f21d3b..974fcd54e36f4acd77878504eec16145f9c6ed85 100644 (file)
@@ -17,4 +17,5 @@ header-y += tegra_drm.h
 header-y += via_drm.h
 header-y += vmwgfx_drm.h
 header-y += msm_drm.h
+header-y += vc4_drm.h
 header-y += virtgpu_drm.h
diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h
new file mode 100644 (file)
index 0000000..219d34c
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright © 2014-2015 Broadcom
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef _UAPI_VC4_DRM_H_
+#define _UAPI_VC4_DRM_H_
+
+#include "drm.h"
+
+#define DRM_VC4_CREATE_BO                         0x03
+#define DRM_VC4_MMAP_BO                           0x04
+
+#define DRM_IOCTL_VC4_CREATE_BO           DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_BO, struct drm_vc4_create_bo)
+#define DRM_IOCTL_VC4_MMAP_BO             DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_MMAP_BO, struct drm_vc4_mmap_bo)
+
+/**
+ * struct drm_vc4_create_bo - ioctl argument for creating VC4 BOs.
+ *
+ * There are currently no values for the flags argument, but it may be
+ * used in a future extension.
+ */
+struct drm_vc4_create_bo {
+       __u32 size;
+       __u32 flags;
+       /** Returned GEM handle for the BO. */
+       __u32 handle;
+       __u32 pad;
+};
+
+/**
+ * struct drm_vc4_mmap_bo - ioctl argument for mapping VC4 BOs.
+ *
+ * This doesn't actually perform an mmap.  Instead, it returns the
+ * offset you need to use in an mmap on the DRM device node.  This
+ * means that tools like valgrind end up knowing about the mapped
+ * memory.
+ *
+ * There are currently no values for the flags argument, but it may be
+ * used in a future extension.
+ */
+struct drm_vc4_mmap_bo {
+       /** Handle for the object being mapped. */
+       __u32 handle;
+       __u32 flags;
+       /** offset into the drm node to use for subsequent mmap call. */
+       __u64 offset;
+};
+
+#endif /* _UAPI_VC4_DRM_H_ */