From 85545c7b30bfb53a6329d6e41447e52b6e5512c2 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 8 Dec 2015 15:09:48 +0100 Subject: [PATCH] Add sun4i drmmode driver Originally-created-by: Maxime Ripard [Icenowy: changed commit message and change README] Signed-off-by: Icenowy Zheng --- README | 1 + src/Makefile.am | 3 +- src/armsoc_driver.c | 1 + src/drmmode_driver.h | 1 + src/drmmode_sun4i/drmmode_sun4i.c | 88 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/drmmode_sun4i/drmmode_sun4i.c diff --git a/README b/README index 707356a..d2ff0de 100644 --- a/README +++ b/README @@ -13,6 +13,7 @@ The currently supported DRM drivers are: - exynos - kirin - sti +- sun4i For other drivers, you will need to implement this support yourself. A template implementation is provided in src/drmmode_template. diff --git a/src/Makefile.am b/src/Makefile.am index 3b26019..ae39d1e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,7 +43,8 @@ armsoc_drv_ladir = @moduledir@/drivers DRMMODE_SRCS = drmmode_exynos/drmmode_exynos.c \ drmmode_pl111/drmmode_pl111.c \ drmmode_kirin/drmmode_kirin.c \ - drmmode_sti/drmmode_sti.c + drmmode_sti/drmmode_sti.c \ + drmmode_sun4i/drmmode_sun4i.c armsoc_drv_la_SOURCES = \ diff --git a/src/armsoc_driver.c b/src/armsoc_driver.c index 83e74a7..abae36c 100644 --- a/src/armsoc_driver.c +++ b/src/armsoc_driver.c @@ -737,6 +737,7 @@ static struct drmmode_interface *get_drmmode_implementation(int drm_fd) &pl111_interface, &kirin_interface, &sti_interface, + &sun4i_interface, }; int i; diff --git a/src/drmmode_driver.h b/src/drmmode_driver.h index 879fc60..1a75cde 100644 --- a/src/drmmode_driver.h +++ b/src/drmmode_driver.h @@ -106,6 +106,7 @@ extern struct drmmode_interface exynos_interface; extern struct drmmode_interface pl111_interface; extern struct drmmode_interface kirin_interface; extern struct drmmode_interface sti_interface; +extern struct drmmode_interface sun4i_interface; #endif diff --git a/src/drmmode_sun4i/drmmode_sun4i.c b/src/drmmode_sun4i/drmmode_sun4i.c new file mode 100644 index 0000000..5513d80 --- /dev/null +++ b/src/drmmode_sun4i/drmmode_sun4i.c @@ -0,0 +1,88 @@ +/* + * Copyright © 2013 ARM Limited. + * + * 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. + * + */ + +#include + +#include "../drmmode_driver.h" + +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) + +#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) +#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) +#define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) + +/* This should be included from uapi headers once the driver is + * mainlined + */ +struct drm_sun4i_gem_create { + uint64_t size; + uint32_t flags; + uint32_t handle; +}; + +#define DRM_SUN4I_GEM_CREATE 0x00 + +#define DRM_IOCTL_SUN4I_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_SUN4I_GEM_CREATE, \ + struct drm_sun4i_gem_create) + +static int create_custom_gem(int fd, struct armsoc_create_gem *create_gem) +{ + struct drm_sun4i_gem_create create_sun4i; + int ret; + unsigned int pitch; + + assert((create_gem->buf_type == ARMSOC_BO_SCANOUT) || + (create_gem->buf_type == ARMSOC_BO_NON_SCANOUT)); + + /* make pitch a multiple of 64 bytes for best performance */ + pitch = DIV_ROUND_UP(create_gem->width * create_gem->bpp, 8); + pitch = ALIGN(pitch, 64); + + memset(&create_sun4i, 0, sizeof(create_sun4i)); + create_sun4i.size = create_gem->height * pitch; + + ret = drmIoctl(fd, DRM_IOCTL_SUN4I_GEM_CREATE, &create_sun4i); + if (ret) + return ret; + + /* Convert custom create_sun4i to generic create_gem */ + create_gem->handle = create_sun4i.handle; + create_gem->pitch = pitch; + create_gem->size = create_sun4i.size; + + return 0; +} + +struct drmmode_interface sun4i_interface = { + "sun4i-drm" /* name of drm driver*/, + 1 /* use_page_flip_events */, + 1 /* use_early_display */, + 0 /* cursor width */, + 0 /* cursor_height */, + 0 /* cursor padding */, + HWCURSOR_API_NONE /* cursor_api */, + NULL /* init_plane_for_cursor */, + 0 /* vblank_query_supported */, + create_custom_gem /* create_custom_gem */, +}; -- 2.12.2