Rockchip Dev patch fix

A patch that was replaced didn't get removed.
This commit is contained in:
Tonymac32 2017-08-21 23:22:53 -04:00 committed by GitHub
parent c9159db816
commit d5b55fda59

View file

@ -1,389 +0,0 @@
From 24e524279e625a64210165fad83e3a64e8d2f2d7 Mon Sep 17 00:00:00 2001
From: Myy <myy@miouyouyou.fr>
Date: Sun, 12 Mar 2017 17:49:55 +0000
Subject: [PATCH 01/12] Readaptation of Rockchip DRM patches provided by ARM
engineers
These patches aim to add some of the GEM API that is completely
missing from the mainline Rockchip DRM drivers, for reasons I do
not comprehend.
What the point of DRM drivers if there's no User API header ?
This also add the FBIOGET_DMABUF, in order to enable cooperation
between the Mali Userspace binary driver and the Framebuffer.
Details here :
https://www.community.arm.com/graphics/b/blog/posts/improving-arm-mali-drivers-on-fbdev
Signed-off-by: Myy <myy@miouyouyou.fr>
---
drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 10 +++++
drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 21 ++++++++++
drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 51 ++++++++++++++++++++++--
drivers/gpu/drm/rockchip/rockchip_drm_gem.h | 9 ++++-
drivers/video/fbdev/core/fbmem.c | 31 +++++++++++++++
include/linux/fb.h | 2 +
include/uapi/drm/rockchip_drm.h | 57 +++++++++++++++++++++++++++
include/uapi/linux/fb.h | 6 +++
8 files changed, 182 insertions(+), 5 deletions(-)
create mode 100644 include/uapi/drm/rockchip_drm.h
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index b360e62..0f4ba05 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -19,6 +19,7 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_of.h>
+#include <drm/rockchip_drm.h>
#include <linux/dma-mapping.h>
#include <linux/dma-iommu.h>
#include <linux/pm_runtime.h>
@@ -262,6 +263,12 @@ static void rockchip_drm_lastclose(struct drm_device *dev)
drm_fb_helper_restore_fbdev_mode_unlocked(&priv->fbdev_helper);
}
+static const struct drm_ioctl_desc rockchip_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(ROCKCHIP_GEM_CREATE, rockchip_gem_create_ioctl,
+ DRM_UNLOCKED | DRM_AUTH),
+};
+
+
static const struct file_operations rockchip_drm_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
@@ -287,12 +294,15 @@ static struct drm_driver rockchip_drm_driver = {
.dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_import_sg_table = rockchip_gem_prime_import_sg_table,
.gem_prime_import = drm_gem_prime_import,
.gem_prime_export = drm_gem_prime_export,
.gem_prime_get_sg_table = rockchip_gem_prime_get_sg_table,
.gem_prime_vmap = rockchip_gem_prime_vmap,
.gem_prime_vunmap = rockchip_gem_prime_vunmap,
.gem_prime_mmap = rockchip_gem_mmap_buf,
+ .ioctls = rockchip_ioctls,
+ .num_ioctls = ARRAY_SIZE(rockchip_ioctls),
.fops = &rockchip_drm_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
index 70ad50d..5578958 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
@@ -35,6 +35,26 @@ static int rockchip_fbdev_mmap(struct fb_info *info,
return rockchip_gem_mmap_buf(private->fbdev_bo, vma);
}
+/* Mali driver specific API :
+ https://www.community.arm.com/graphics/b/blog/posts/improving-arm-mali-drivers-on-fbdev
+ I wonder if this problem isn't already solved in another way...
+ */
+static struct dma_buf *rockchip_fbdev_get_dma_buf(struct fb_info *info) {
+ struct dma_buf *buf = NULL;
+ struct drm_fb_helper *helper = info->par;
+ struct rockchip_drm_private *private = to_drm_private(helper);
+ struct drm_device *dev = helper->dev;
+
+ if (dev->driver->gem_prime_export) {
+ buf = dev->driver->gem_prime_export(dev, private->fbdev_bo, O_RDWR);
+ if (buf)
+ drm_gem_object_reference(private->fbdev_bo);
+ }
+
+ return buf;
+}
+
+
static struct fb_ops rockchip_drm_fbdev_ops = {
.owner = THIS_MODULE,
DRM_FB_HELPER_DEFAULT_OPS,
@@ -42,6 +62,7 @@ static struct fb_ops rockchip_drm_fbdev_ops = {
.fb_fillrect = drm_fb_helper_cfb_fillrect,
.fb_copyarea = drm_fb_helper_cfb_copyarea,
.fb_imageblit = drm_fb_helper_cfb_imageblit,
+ .fb_dmabuf_export = rockchip_fbdev_get_dma_buf
};
static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index df9e570..e018e59 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -16,7 +16,12 @@
#include <drm/drmP.h>
#include <drm/drm_gem.h>
#include <drm/drm_vma_manager.h>
+#include <drm/rockchip_drm.h>
+
#include <linux/iommu.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-buf.h>
+
#include "rockchip_drm_drv.h"
#include "rockchip_drm_gem.h"
@@ -307,6 +312,31 @@ static void rockchip_gem_release_object(struct rockchip_gem_object *rk_obj)
kfree(rk_obj);
}
+struct drm_gem_object *
+rockchip_gem_prime_import_sg_table(struct drm_device *drm,
+ struct dma_buf_attachment *attach,
+ struct sg_table *sgt) {
+ struct rockchip_gem_object *rk_obj;
+ struct drm_gem_object *obj;
+
+ if (sgt->nents != 1)
+ return ERR_PTR(-EINVAL);
+
+ rk_obj = kzalloc(sizeof(*rk_obj), GFP_KERNEL);
+ if (!rk_obj)
+ return ERR_PTR(-ENOMEM);
+
+ obj = &rk_obj->base;
+
+ drm_gem_private_object_init(drm, obj, attach->dmabuf->size);
+
+ rk_obj->dma_addr = sg_dma_address(sgt->sgl);
+ rk_obj->sgt = sgt;
+ obj->size = sg_dma_len(sgt->sgl);
+
+ return obj;
+}
+
struct rockchip_gem_object *
rockchip_gem_create_object(struct drm_device *drm, unsigned int size,
bool alloc_kmap)
@@ -343,12 +373,17 @@ struct rockchip_gem_object *
void rockchip_gem_free_object(struct drm_gem_object *obj)
{
struct rockchip_gem_object *rk_obj;
+ if (obj->import_attach)
+ drm_prime_gem_destroy(obj, rk_obj->sgt);
+ else {
+ drm_gem_free_mmap_offset(obj);
- rk_obj = to_rockchip_obj(obj);
+ rk_obj = to_rockchip_obj(obj);
- rockchip_gem_free_buf(rk_obj);
+ rockchip_gem_free_buf(rk_obj);
- rockchip_gem_release_object(rk_obj);
+ rockchip_gem_release_object(rk_obj);
+ }
}
/*
@@ -444,6 +479,16 @@ int rockchip_gem_dumb_create(struct drm_file *file_priv,
return PTR_ERR_OR_ZERO(rk_obj);
}
+int rockchip_gem_create_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv) {
+ struct drm_rockchip_gem_create *args = data;
+ struct rockchip_gem_object *rk_obj;
+
+ rk_obj = rockchip_gem_create_with_handle(file_priv, dev, args->size,
+ &args->handle);
+ return PTR_ERR_OR_ZERO(rk_obj);
+}
+
/*
* Allocate a sg_table for this GEM object.
* Note: Both the table's contents, and the sg_table itself must be freed by
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h b/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
index 3f6ea4d..b8fed4d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
@@ -36,8 +36,9 @@ struct rockchip_gem_object {
struct sg_table *rockchip_gem_prime_get_sg_table(struct drm_gem_object *obj);
struct drm_gem_object *
-rockchip_gem_prime_import_sg_table(struct drm_device *dev, size_t size,
- struct sg_table *sgt);
+rockchip_gem_prime_import_sg_table(struct drm_device *dev,
+ struct dma_buf_attachment *attach,
+ struct sg_table *sgt);
void *rockchip_gem_prime_vmap(struct drm_gem_object *obj);
void rockchip_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
@@ -57,6 +58,10 @@ void rockchip_gem_free_object(struct drm_gem_object *obj);
int rockchip_gem_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
+int rockchip_gem_create_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int rockchip_gem_map_offset_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
int rockchip_gem_dumb_map_offset(struct drm_file *file_priv,
struct drm_device *dev, uint32_t handle,
uint64_t *offset);
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index 069fe79..d19e98a 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -31,6 +31,7 @@
#include <linux/err.h>
#include <linux/device.h>
#include <linux/efi.h>
+#include <linux/dma-buf.h> // Mali specific
#include <linux/fb.h>
#include <asm/fb.h>
@@ -1084,6 +1085,21 @@ fb_blank(struct fb_info *info, int blank)
}
EXPORT_SYMBOL(fb_blank);
+/* Mali specific */
+int fb_get_dmabuf(struct fb_info *info, int flags)
+{
+ struct dma_buf *dmabuf;
+
+ if (info->fbops->fb_dmabuf_export == NULL)
+ return -ENOTTY;
+
+ dmabuf = info->fbops->fb_dmabuf_export(info);
+ if (IS_ERR(dmabuf))
+ return PTR_ERR(dmabuf);
+
+ return dma_buf_fd(dmabuf, flags);
+}
+
static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg)
{
@@ -1094,6 +1110,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
struct fb_cmap cmap_from;
struct fb_cmap_user cmap;
struct fb_event event;
+ struct fb_dmabuf_export dmaexp;
void __user *argp = (void __user *)arg;
long ret = 0;
@@ -1199,6 +1216,20 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
unlock_fb_info(info);
console_unlock();
break;
+ case FBIOGET_DMABUF: /* Mali specific */
+ if (copy_from_user(&dmaexp, argp, sizeof(dmaexp)))
+ return -EFAULT;
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ dmaexp.fd = fb_get_dmabuf(info, dmaexp.flags);
+ unlock_fb_info(info);
+
+ if (dmaexp.fd < 0)
+ return dmaexp.fd;
+
+ ret = copy_to_user(argp, &dmaexp, sizeof(dmaexp))
+ ? -EFAULT : 0;
+ break;
case FBIOBLANK:
console_lock();
if (!lock_fb_info(info)) {
diff --git a/include/linux/fb.h b/include/linux/fb.h
index a964d07..58c9d08 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -320,6 +320,8 @@ struct fb_ops {
/* called at KDB enter and leave time to prepare the console */
int (*fb_debug_enter)(struct fb_info *info);
int (*fb_debug_leave)(struct fb_info *info);
+
+ struct dma_buf *(*fb_dmabuf_export)(struct fb_info *info);
};
#ifdef CONFIG_FB_TILEBLITTING
diff --git a/include/uapi/drm/rockchip_drm.h b/include/uapi/drm/rockchip_drm.h
new file mode 100644
index 0000000..c521e5a
--- /dev/null
+++ b/include/uapi/drm/rockchip_drm.h
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright (c) Fuzhou Rockchip Electronics Co.Ltd
+ * Authors:
+ * Mark Yao <yzq@rock-chips.com>
+ *
+ * base on exynos_drm.h
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef _UAPI_ROCKCHIP_DRM_H
+#define _UAPI_ROCKCHIP_DRM_H
+
+#include <drm/drm.h>
+
+/**
+ * User-desired buffer creation information structure.
+ *
+ * @size: user-desired memory allocation size.
+ * @flags: user request for setting memory type or cache attributes.
+ * @handle: returned a handle to created gem object.
+ * - this handle will be set by gem module of kernel side.
+ */
+struct drm_rockchip_gem_create {
+ uint64_t size;
+ uint32_t flags;
+ uint32_t handle;
+};
+
+/**
+ * A structure for getting buffer offset.
+ *
+ * @handle: a pointer to gem object created.
+ * @pad: just padding to be 64-bit aligned.
+ * @offset: relatived offset value of the memory region allocated.
+ * - this value should be set by user.
+ */
+struct drm_rockchip_gem_map_off {
+ uint32_t handle;
+ uint32_t pad;
+ uint64_t offset;
+};
+
+#define DRM_ROCKCHIP_GEM_CREATE 0x00
+#define DRM_ROCKCHIP_GEM_MAP_OFFSET 0x01
+
+#define DRM_IOCTL_ROCKCHIP_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_ROCKCHIP_GEM_CREATE, struct drm_rockchip_gem_create)
+
+#define DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_ROCKCHIP_GEM_MAP_OFFSET, struct drm_rockchip_gem_map_off)
+
+#endif /* _UAPI_ROCKCHIP_DRM_H */
diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h
index fb795c3..c279b04 100644
--- a/include/uapi/linux/fb.h
+++ b/include/uapi/linux/fb.h
@@ -34,6 +34,8 @@
#define FBIOPUT_MODEINFO 0x4617
#define FBIOGET_DISPINFO 0x4618
#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
+/* Mali specific */
+#define FBIOGET_DMABUF _IOR('F', 0x21, struct fb_dmabuf_export)
#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
#define FB_TYPE_PLANES 1 /* Non interleaved planes */
@@ -398,5 +400,9 @@ struct fb_cursor {
#define FB_BACKLIGHT_MAX 0xFF
#endif
+struct fb_dmabuf_export { /* Mali specific */
+ __u32 fd;
+ __u32 flags;
+};
#endif /* _UAPI_LINUX_FB_H */
--
2.10.2