[PATCH 9/9] drm/exynos: add ioctls for cpu access of gem object from user

Joonyoung Shim jy0922.shim at samsung.com
Tue Oct 13 00:00:54 PDT 2015


This adds necessary two ioctls for cpu access of gem object from user.
It needs to be synced properly in order for the cpu and device if the
buffer of gem object is cachable.

- DRM_IOCTL_EXYNOS_GEM_CPU_PREP
Should be used explicitly before it will be cpu access of gem object
from user.

- DRM_IOCTL_EXYNOS_GEM_CPU_FINI
Should be used explicitly after it is finished cpu access of gem object
from user.

Signed-off-by: Joonyoung Shim <jy0922.shim at samsung.com>
---
This is based on patch of Daniel dropping DRM_UNLOCKED flag on each
drivers[1] and patch that is droped DRM_UNLOCKED flag from my posted
patch[2].

[1] http://lists.freedesktop.org/archives/intel-gfx/2015-September/075368.html
[2] http://www.spinics.net/lists/dri-devel/msg91465.html

 drivers/gpu/drm/exynos/exynos_drm_drv.c |  4 +++
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 48 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_gem.h | 14 ++++++++++
 include/uapi/drm/exynos_drm.h           | 18 ++++++++++++-
 4 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 74bf3afed519..f15945c1c01d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -408,6 +408,10 @@ static const struct drm_ioctl_desc exynos_ioctls[] = {
 			DRM_AUTH | DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP, exynos_drm_gem_map_ioctl,
 			DRM_AUTH | DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CPU_PREP, exynos_drm_gem_cpu_prep_ioctl,
+			DRM_AUTH | DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CPU_FINI, exynos_drm_gem_cpu_fini_ioctl,
+			DRM_AUTH | DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET, exynos_drm_gem_get_ioctl,
 			DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION, vidi_connection_ioctl,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 01c5e0854016..4907ad3994db 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -321,6 +321,54 @@ int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data,
 					      &args->offset);
 }
 
+int exynos_drm_gem_cpu_prep_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file)
+{
+	struct drm_exynos_gem_cpu_access *args = data;
+	struct drm_gem_object *obj;
+	struct exynos_drm_gem *exynos_gem;
+
+	obj = drm_gem_object_lookup(dev, file, args->handle);
+	if (!obj) {
+		DRM_ERROR("Failed to lookup gem object\n");
+		return -EINVAL;
+	}
+
+	exynos_gem = to_exynos_gem(obj);
+
+	if (exynos_gem->flags & EXYNOS_BO_CACHABLE)
+		dma_sync_sg_for_cpu(dev->dev, exynos_gem->sgt->sgl,
+				    exynos_gem->sgt->nents, DMA_FROM_DEVICE);
+
+	drm_gem_object_unreference_unlocked(obj);
+
+	return 0;
+}
+
+int exynos_drm_gem_cpu_fini_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file)
+{
+	struct drm_exynos_gem_cpu_access *args = data;
+	struct drm_gem_object *obj;
+	struct exynos_drm_gem *exynos_gem;
+
+	obj = drm_gem_object_lookup(dev, file, args->handle);
+	if (!obj) {
+		DRM_ERROR("Failed to lookup gem object\n");
+		return -EINVAL;
+	}
+
+	exynos_gem = to_exynos_gem(obj);
+
+	if (exynos_gem->flags & EXYNOS_BO_CACHABLE)
+		dma_sync_sg_for_device(dev->dev, exynos_gem->sgt->sgl,
+				       exynos_gem->sgt->nents, DMA_TO_DEVICE);
+
+	drm_gem_object_unreference_unlocked(obj);
+
+	return 0;
+}
+
 dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
 					unsigned int gem_handle,
 					struct drm_file *filp)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index e9eb5631f322..d5aac38f455a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -74,6 +74,20 @@ int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data,
 			     struct drm_file *file_priv);
 
 /*
+ * Should be used explicitly before it will be cpu access of gem object
+ * from user.
+ */
+int exynos_drm_gem_cpu_prep_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file_priv);
+
+/*
+ * Should be used explicitly after it is finished cpu access of gem
+ * object from user.
+ */
+int exynos_drm_gem_cpu_fini_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file_priv);
+
+/*
  * get dma address from gem handle and this function could be used for
  * other drivers such as 2d/3d acceleration drivers.
  * with this function call, gem object reference count would be increased.
diff --git a/include/uapi/drm/exynos_drm.h b/include/uapi/drm/exynos_drm.h
index 1d7c80734e43..b16a9a9ea34e 100644
--- a/include/uapi/drm/exynos_drm.h
+++ b/include/uapi/drm/exynos_drm.h
@@ -46,6 +46,16 @@ struct drm_exynos_gem_map {
 };
 
 /**
+ * A structure for cpu access of gem object from user.
+ *
+ * @handle: handle of gem object.
+ */
+struct drm_exynos_gem_cpu_access {
+	__u32 handle;
+	__u32 reserved;
+};
+
+/**
  * A structure to gem information.
  *
  * @handle: a handle to gem object created.
@@ -301,8 +311,10 @@ struct drm_exynos_ipp_cmd_ctrl {
 
 #define DRM_EXYNOS_GEM_CREATE		0x00
 #define DRM_EXYNOS_GEM_MAP		0x01
-/* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */
+#define DRM_EXYNOS_GEM_CPU_PREP		0x02
+#define DRM_EXYNOS_GEM_CPU_FINI		0x03
 #define DRM_EXYNOS_GEM_GET		0x04
+/* Reserved 0x05 ~ 0x06 for exynos specific gem ioctl */
 #define DRM_EXYNOS_VIDI_CONNECTION	0x07
 
 /* G2D */
@@ -320,6 +332,10 @@ struct drm_exynos_ipp_cmd_ctrl {
 		DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create)
 #define DRM_IOCTL_EXYNOS_GEM_MAP		DRM_IOWR(DRM_COMMAND_BASE + \
 		DRM_EXYNOS_GEM_MAP, struct drm_exynos_gem_map)
+#define DRM_IOCTL_EXYNOS_GEM_CPU_PREP		DRM_IOWR(DRM_COMMAND_BASE + \
+		DRM_EXYNOS_GEM_CPU_PREP, struct drm_exynos_gem_cpu_access)
+#define DRM_IOCTL_EXYNOS_GEM_CPU_FINI		DRM_IOWR(DRM_COMMAND_BASE + \
+		DRM_EXYNOS_GEM_CPU_FINI, struct drm_exynos_gem_cpu_access)
 #define DRM_IOCTL_EXYNOS_GEM_GET	DRM_IOWR(DRM_COMMAND_BASE + \
 		DRM_EXYNOS_GEM_GET,	struct drm_exynos_gem_info)
 
-- 
1.9.1



More information about the dri-devel mailing list