Skip to content

Instantly share code, notes, and snippets.

@dsd
Last active January 1, 2016 06:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dsd/8fe8b84fe53e2b0688f5 to your computer and use it in GitHub Desktop.
Save dsd/8fe8b84fe53e2b0688f5 to your computer and use it in GitHub Desktop.
Kernel: UMP/exynos-drm integration
From 6ff1d15c9b3c6356976f10674f474040b3b3ed5f Mon Sep 17 00:00:00 2001
From: Daniel Drake <drake@endlessm.com>
Date: Tue, 24 Dec 2013 11:09:37 -0600
Subject: [PATCH] UMP/exynos-drm integration
Add a new exynos ioctl: DRM_IOCTL_EXYNOS_GEM_CREATE2
This behaves exactly like the original CREATE but it also creates
a UMP handle for the allocation, and returns the relevant UMP
secure ID to userspace.
---
drivers/gpu/drm/exynos/exynos_drm_buf.c | 16 ++++++++++++++++
drivers/gpu/drm/exynos/exynos_drm_buf.h | 1 +
drivers/gpu/drm/exynos/exynos_drm_drv.c | 2 ++
drivers/gpu/drm/exynos/exynos_drm_gem.c | 31 +++++++++++++++++++++++++++++++
drivers/gpu/drm/exynos/exynos_drm_gem.h | 5 +++++
include/uapi/drm/exynos_drm.h | 11 +++++++++++
6 files changed, 66 insertions(+)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 3fc524f..1917a05 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -11,6 +11,7 @@
#include <drm/drmP.h>
#include <drm/exynos_drm.h>
+#include <ump/ump_kernel_interface_ref_drv.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_gem.h"
@@ -194,6 +195,21 @@ int exynos_drm_alloc_buf(struct drm_device *dev,
void exynos_drm_free_buf(struct drm_device *dev,
unsigned int flags, struct exynos_drm_gem_buf *buffer)
{
+ if (buffer->ump_handle)
+ ump_dd_reference_release(buffer->ump_handle);
lowlevel_buffer_deallocate(dev, flags, buffer);
}
+
+ump_dd_handle exynos_drm_get_ump_handle(struct exynos_drm_gem_buf *buffer)
+{
+ ump_dd_physical_block ump_mem;
+
+ if (buffer->ump_handle)
+ return buffer->ump_handle;
+
+ ump_mem.addr = buffer->dma_addr;
+ ump_mem.size = buffer->size;
+ buffer->ump_handle = ump_dd_handle_create_from_phys_blocks(&ump_mem, 1);
+ return buffer->ump_handle;
+}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.h b/drivers/gpu/drm/exynos/exynos_drm_buf.h
index a6412f1..6422167 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.h
@@ -30,4 +30,5 @@ void exynos_drm_free_buf(struct drm_device *dev,
unsigned int flags,
struct exynos_drm_gem_buf *buffer);
+ump_dd_handle exynos_drm_get_ump_handle(struct exynos_drm_gem_buf *buffer);
#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 3da5c2d..4d1c902 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -221,6 +221,8 @@ static const struct vm_operations_struct exynos_drm_gem_vm_ops = {
static struct drm_ioctl_desc exynos_ioctls[] = {
DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl,
DRM_UNLOCKED | DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE2, exynos_drm_gem_create2_ioctl,
+ DRM_UNLOCKED | DRM_AUTH),
DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP_OFFSET,
exynos_drm_gem_map_offset_ioctl, DRM_UNLOCKED |
DRM_AUTH),
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 4731807..6c8acdc 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -13,6 +13,7 @@
#include <linux/shmem_fs.h>
#include <drm/exynos_drm.h>
+#include <ump/ump_kernel_interface_ref_drv.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_gem.h"
@@ -263,6 +264,36 @@ int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
return 0;
}
+int exynos_drm_gem_create2_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_exynos_gem_create2 *args = data;
+ struct exynos_drm_gem_obj *exynos_gem_obj;
+ ump_dd_handle ump_handle;
+ int ret;
+
+ DRM_DEBUG_KMS("%s\n", __FILE__);
+
+ exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size);
+ if (IS_ERR(exynos_gem_obj))
+ return PTR_ERR(exynos_gem_obj);
+
+ ret = exynos_drm_gem_handle_create(&exynos_gem_obj->base, file_priv,
+ &args->handle);
+ if (ret) {
+ exynos_drm_gem_destroy(exynos_gem_obj);
+ return ret;
+ }
+
+ ump_handle = exynos_drm_get_ump_handle(exynos_gem_obj->buffer);
+ if (ump_handle != UMP_DD_HANDLE_INVALID)
+ args->name = ump_dd_secure_id_get(ump_handle);
+ else
+ args->name = 0;
+
+ 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 35ebac4..41ce6ff 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -11,6 +11,7 @@
#ifndef _EXYNOS_DRM_GEM_H_
#define _EXYNOS_DRM_GEM_H_
+#include <ump/ump_kernel_interface_ref_drv.h>
#define to_exynos_gem_obj(x) container_of(x,\
struct exynos_drm_gem_obj, base)
@@ -40,6 +41,7 @@ struct exynos_drm_gem_buf {
unsigned int write;
struct page **pages;
struct sg_table *sgt;
+ ump_dd_handle ump_handle;
unsigned long size;
bool pfnmap;
};
@@ -85,6 +87,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
unsigned int flags,
unsigned long size);
+
/*
* request gem object creation and buffer allocation as the size
* that it is calculated with framebuffer information such as width,
@@ -92,6 +95,8 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
*/
int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int exynos_drm_gem_create2_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
diff --git a/include/uapi/drm/exynos_drm.h b/include/uapi/drm/exynos_drm.h
index d584412..8356c5e 100644
--- a/include/uapi/drm/exynos_drm.h
+++ b/include/uapi/drm/exynos_drm.h
@@ -32,6 +32,13 @@ struct drm_exynos_gem_create {
unsigned int handle;
};
+struct drm_exynos_gem_create2 {
+ uint64_t size;
+ unsigned int flags;
+ unsigned int handle;
+ uint32_t name;
+};
+
/**
* A structure for getting buffer offset.
*
@@ -321,6 +328,7 @@ struct drm_exynos_ipp_cmd_ctrl {
/* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */
#define DRM_EXYNOS_GEM_GET 0x04
#define DRM_EXYNOS_VIDI_CONNECTION 0x07
+#define DRM_EXYNOS_GEM_CREATE2 0x0a
/* G2D */
#define DRM_EXYNOS_G2D_GET_VER 0x20
@@ -336,6 +344,9 @@ struct drm_exynos_ipp_cmd_ctrl {
#define DRM_IOCTL_EXYNOS_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create)
+#define DRM_IOCTL_EXYNOS_GEM_CREATE2 DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_EXYNOS_GEM_CREATE2, struct drm_exynos_gem_create2)
+
#define DRM_IOCTL_EXYNOS_GEM_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off)
--
1.8.3.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment