this patch adds libdrm_exynos helper layer that inclues some intefaces for exynos specific gem and virtual display driver and also adds exynos module name to modtest and vbltest.
this patch is based on a link below: git://anongit.freedesktop.org/mesa/drm commit id: e057a56448e2e785f74bc13dbd6ead8572ebed91
Signed-off-by: Inki Dae inki.dae@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com --- Makefile.am | 6 +- configure.ac | 13 ++ exynos/Makefile.am | 22 +++ exynos/exynos_drm.c | 324 ++++++++++++++++++++++++++++++++++++++++++++ exynos/exynos_drm.h | 127 +++++++++++++++++ exynos/exynos_drmif.h | 60 ++++++++ exynos/libdrm_exynos.pc.in | 11 ++ tests/modetest/modetest.c | 2 +- tests/vbltest/vbltest.c | 2 +- 9 files changed, 564 insertions(+), 3 deletions(-) create mode 100644 exynos/Makefile.am create mode 100644 exynos/exynos_drm.c create mode 100644 exynos/exynos_drm.h create mode 100644 exynos/exynos_drmif.h create mode 100644 exynos/libdrm_exynos.pc.in
diff --git a/Makefile.am b/Makefile.am index 4f625a1..256a8cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,7 +45,11 @@ if HAVE_OMAP OMAP_SUBDIR = omap endif
-SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) tests include +if HAVE_EXYNOS +EXYNOS_SUBDIR = exynos +endif + +SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include
libdrm_la_LTLIBRARIES = libdrm.la libdrm_ladir = $(libdir) diff --git a/configure.ac b/configure.ac index 1ba7eba..ae84817 100644 --- a/configure.ac +++ b/configure.ac @@ -88,6 +88,11 @@ AC_ARG_ENABLE(omap-experimental-api, [Enable support for OMAP's experimental API (default: disabled)]), [OMAP=$enableval], [OMAP=no])
+AC_ARG_ENABLE(exynos-experimental-api, + AS_HELP_STRING([--enable-exynos-experimental-api], + [Enable support for EXYNOS's experimental API (default: disabled)]), + [EXYNOS=$enableval], [EXYNOS=no]) + dnl =========================================================================== dnl check compiler flags AC_DEFUN([LIBDRM_CC_TRY_FLAG], [ @@ -191,6 +196,11 @@ if test "x$OMAP" = xyes; then AC_DEFINE(HAVE_OMAP, 1, [Have OMAP support]) fi
+AM_CONDITIONAL(HAVE_EXYNOS, [test "x$EXYNOS" = xyes]) +if test "x$EXYNOS" = xyes; then + AC_DEFINE(HAVE_EXYNOS, 1, [Have EXYNOS support]) +fi + PKG_CHECK_MODULES(CAIRO, cairo, [HAVE_CAIRO=yes], [HAVE_CAIRO=no]) if test "x$HAVE_CAIRO" = xyes; then AC_DEFINE(HAVE_CAIRO, 1, [Have cairo support]) @@ -302,6 +312,8 @@ AC_CONFIG_FILES([ nouveau/libdrm_nouveau.pc omap/Makefile omap/libdrm_omap.pc + exynos/Makefile + exynos/libdrm_exynos.pc tests/Makefile tests/modeprint/Makefile tests/modetest/Makefile @@ -322,4 +334,5 @@ echo " vmwgfx API $VMWGFX" echo " Radeon API $RADEON" echo " Nouveau API $NOUVEAU" echo " OMAP API $OMAP" +echo " EXYNOS API $EXYNOS" echo "" diff --git a/exynos/Makefile.am b/exynos/Makefile.am new file mode 100644 index 0000000..e782d34 --- /dev/null +++ b/exynos/Makefile.am @@ -0,0 +1,22 @@ +AM_CFLAGS = \ + $(WARN_CFLAGS) \ + -I$(top_srcdir) \ + -I$(top_srcdir)/exynos \ + $(PTHREADSTUBS_CFLAGS) \ + -I$(top_srcdir)/include/drm + +libdrm_exynos_la_LTLIBRARIES = libdrm_exynos.la +libdrm_exynos_ladir = $(libdir) +libdrm_exynos_la_LDFLAGS = -version-number 1:0:0 -no-undefined +libdrm_exynos_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@ + +libdrm_exynos_la_SOURCES = exynos_drm.c + +libdrm_exynoscommonincludedir = ${includedir}/exynos +libdrm_exynoscommoninclude_HEADERS = exynos_drm.h + +libdrm_exynosincludedir = ${includedir}/libdrm +libdrm_exynosinclude_HEADERS = exynos_drmif.h + +pkgconfigdir = @pkgconfigdir@ +pkgconfig_DATA = libdrm_exynos.pc diff --git a/exynos/exynos_drm.c b/exynos/exynos_drm.c new file mode 100644 index 0000000..778321a --- /dev/null +++ b/exynos/exynos_drm.c @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co., Ltd. + * + * 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. + * + * Authors: + * Inki Dae inki.dae@samsung.com + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include <sys/mman.h> +#include <linux/stddef.h> + +#include <xf86drm.h> + +#include "exynos_drm.h" +#include "exynos_drmif.h" + +struct exynos_device { + int fd; +}; + +/* + * Exynos Buffer Object structure. + * + * @dev: exynos device object allocated. + * @handle: a gem handle to gem object created. + * @size: size to the buffer created. + * @map: user pointer to a gem buffer mmaped. + * @name: a gem global handle from flink request. + */ +struct exynos_bo { + struct exynos_device *dev; + uint32_t handle; + size_t size; + void *map; + uint32_t name; +}; + +/* + * Create exynos drm device object. + * + * @fd: file descriptor to exynos drm driver opened. + * + * if true, return the device object else NULL. + */ +struct exynos_device * exynos_device_create(int fd) +{ + struct exynos_device *dev; + + dev = calloc(sizeof(*dev), 1); + if (!dev) { + fprintf(stderr, "failed to create device[%s].\n", + strerror(errno)); + return NULL; + } + + dev->fd = fd; + + return dev; +} + +/* + * Destroy exynos drm device object + * + * @dev: exynos drm device object. + */ +void exynos_device_destroy(struct exynos_device *dev) +{ + free(dev); +} + +/* + * Create a exynos buffer object to exynos drm device. + * + * @dev: exynos drm device object. + * @size: user-desired size. + * flags: user-desired memory type. + * user can set one or more types among EXYNOS_BO_NONCONTIG and + * EXYNOS_BO_CONTIG and it would be used for EXYNOS_BO_NONCONTIG + * as default. + * + * EXYNOS_BO_NONCONTIG: Physically Non-continuous Memory type. + * EXYNOS_BO_CONTIG: Physically Continuous Memory type. + * + * if true, return a exynos buffer object else NULL. + */ +struct exynos_bo * exynos_bo_create(struct exynos_device *dev, + size_t size, uint32_t flags) +{ + struct exynos_bo *bo; + struct drm_exynos_gem_create req = { + .size = size, + .flags = flags, + }; + + if (size == 0) { + fprintf(stderr, "invalid size.\n"); + goto fail; + } + + bo = calloc(sizeof(*bo), 1); + if (!bo) { + fprintf(stderr, "failed to create bo[%s].\n", + strerror(errno)); + goto err_free_bo; + } + + bo->dev = dev; + + if (drmCommandWriteRead(dev->fd, DRM_EXYNOS_GEM_CREATE, &req, + sizeof(req))) { + fprintf(stderr, "failed to create gem object[%s].\n", + strerror(errno)); + goto err_free_bo; + } + + bo->handle = req.handle; + + return bo; + +err_free_bo: + free(bo); +fail: + return NULL; +} + +/* + * Destroy a exynos buffer object. + * + * @bo: a exynos buffer object to be destroyed. + */ +void exynos_bo_destroy(struct exynos_bo *bo) +{ + if (!bo) + return; + + if (bo->map) + munmap(bo->map, bo->size); + + if (bo->handle) { + struct drm_gem_close req = { + .handle = bo->handle, + }; + + drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req); + } + + free(bo); +} + + +/* + * Get a exynos buffer object from a gem global object name. + * + * @dev: a exynos device object. + * @name: a gem global object name exported by another process. + * + * this interface is used to get a exynos buffer object from a gem + * global object name sent by another process for buffer sharing. + * + * if true, return a exynos buffer object else NULL. + * + */ +struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name) +{ + struct exynos_bo *bo; + struct drm_gem_open req = { + .name = name, + }; + + bo = calloc(sizeof(*bo), 1); + if (!bo) { + fprintf(stderr, "failed to allocate bo[%s].\n", + strerror(errno)); + return NULL; + } + + if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) { + fprintf(stderr, "failed to open gem object[%s].\n", + strerror(errno)); + goto err_free_bo; + } + + bo->dev = dev; + bo->name = name; + bo->handle = req.handle; + + return bo; + +err_free_bo: + free(bo); + return NULL; +} + +/* + * Get a gem global object name from a gem object handle. + * + * @bo: a exynos buffer object including gem handle. + * @name: a gem global object name to be got by kernel driver. + * + * this interface is used to get a gem global object name from a gem object + * handle to a buffer that wants to share it with another process. + * + * if true, return 0 else negative. + */ +int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name) +{ + if (!bo->name) { + struct drm_gem_flink req = { + .handle = bo->handle, + }; + int ret; + + ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req); + if (ret) { + fprintf(stderr, "failed to get gem global name[%s].\n", + strerror(errno)); + return ret; + } + + bo->name = req.name; + } + + *name = bo->name; + + return 0; +} + +uint32_t exynos_bo_handle(struct exynos_bo *bo) +{ + return bo->handle; +} + +/* + * Mmap a buffer to user space. + * + * @bo: a exynos buffer object including a gem object handle to be mmapped + * to user space. + * + * if true, user pointer mmaped else NULL. + */ +void *exynos_bo_map(struct exynos_bo *bo) +{ + if (!bo->map) { + struct exynos_device *dev = bo->dev; + struct drm_exynos_gem_mmap req = { + .handle = bo->handle, + .size = bo->size, + }; + int ret; + + ret = drmCommandWriteRead(dev->fd, DRM_EXYNOS_GEM_MMAP, &req, + sizeof(req)); + if (ret) { + fprintf(stderr, "failed to mmap[%s].\n", + strerror(errno)); + return NULL; + } + } + + return bo->map; +} + +/* + * Request Wireless Display connection or disconnection. + * + * @dev: a exynos device object. + * @connect: indicate whether connectoin or disconnection request. + * @ext: indicate whether edid data includes extentions data or not. + * @edid: a pointer to edid data from Wireless Display device. + * + * this interface is used to request Virtual Display driver connection or + * disconnection. for this, user should get a edid data from the Wireless + * Display device and then send that data to kernel driver with connection + * request + * + * if true, return 0 else negative. + */ +int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect, + uint32_t ext, void *edid) +{ + struct drm_exynos_vidi_connection req = { + .connection = connect, + .extensions = ext, + .edid = edid, + }; + int ret; + + ret = drmCommandWriteRead(dev->fd, DRM_EXYNOS_VIDI_CONNECTION, &req, + sizeof(req)); + if (ret) { + fprintf(stderr, "failed to request vidi connection[%s].\n", + strerror(errno)); + return ret; + } + + return 0; +} diff --git a/exynos/exynos_drm.h b/exynos/exynos_drm.h new file mode 100644 index 0000000..09f8723 --- /dev/null +++ b/exynos/exynos_drm.h @@ -0,0 +1,127 @@ +/* exynos_drm.h + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * Authors: + * Inki Dae inki.dae@samsung.com + * Joonyoung Shim jy0922.shim@samsung.com + * Seung-Woo Kim sw0312.kim@samsung.com + * + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 _EXYNOS_DRM_H_ +#define _EXYNOS_DRM_H_ + +/** + * User-desired buffer creation information structure. + * + * @size: user-desired memory allocation size. + * - this size value would be page-aligned internally. + * @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_exynos_gem_create { + uint64_t size; + unsigned int flags; + unsigned int 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_exynos_gem_map_off { + unsigned int handle; + unsigned int pad; + uint64_t offset; +}; + +/** + * A structure for mapping buffer. + * + * @handle: a handle to gem object created. + * @size: memory size to be mapped. + * @mapped: having user virtual address mmaped. + * - this variable would be filled by exynos gem module + * of kernel side with user virtual address which is allocated + * by do_mmap(). + */ +struct drm_exynos_gem_mmap { + unsigned int handle; + unsigned int size; + uint64_t mapped; +}; + +/** + * A structure for user connection request of virtual display. + * + * @connection: indicate whether doing connetion or not by user. + * @extensions: if this value is 1 then the vidi driver would need additional + * 128bytes edid data. + * @edid: the edid data pointer from user side. + */ +struct drm_exynos_vidi_connection { + unsigned int connection; + unsigned int extensions; + uint64_t *edid; +}; + +struct drm_exynos_plane_set_zpos { + __u32 plane_id; + __s32 zpos; +}; + +/* memory type definitions. */ +enum e_drm_exynos_gem_mem_type { + /* Physically Continuous memory and used as default. */ + EXYNOS_BO_CONTIG = 0 << 0, + /* Physically Non-Continuous memory. */ + EXYNOS_BO_NONCONTIG = 1 << 0, + EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG +}; + +#define DRM_EXYNOS_GEM_CREATE 0x00 +#define DRM_EXYNOS_GEM_MAP_OFFSET 0x01 +#define DRM_EXYNOS_GEM_MMAP 0x02 +/* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */ +#define DRM_EXYNOS_PLANE_SET_ZPOS 0x06 +#define DRM_EXYNOS_VIDI_CONNECTION 0x07 + +#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_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off) + +#define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap) + +#define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos) + +#define DRM_IOCTL_EXYNOS_VIDI_CONNECTION DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection) + +#endif diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h new file mode 100644 index 0000000..0f58083 --- /dev/null +++ b/exynos/exynos_drmif.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co., Ltd. + * + * 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. + * + * Authors: + * Inki Dae inki.dae@samsung.com + */ + +#ifndef EXYNOS_DRMIF_H_ +#define EXYNOS_DRMIF_H_ + +#include <xf86drm.h> +#include <stdint.h> +#include "exynos_drm.h" + +struct exynos_bo; +struct exynos_device; + +/* + * device related functions: + */ +struct exynos_device * exynos_device_create(int fd); +void exynos_device_destroy(struct exynos_device *dev); + +/* + * buffer-object related functions: + */ +struct exynos_bo * exynos_bo_create(struct exynos_device *dev, + uint32_t size, uint32_t flags); +void exynos_bo_destroy(struct exynos_bo *bo); +struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name); +int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name); +uint32_t exynos_bo_handle(struct exynos_bo *bo); +void * exynos_bo_map(struct exynos_bo *bo); + +/* + * Virtual Display related functions: + */ +int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect, + uint32_t ext, void *edid); + +#endif /* EXYNOS_DRMIF_H_ */ diff --git a/exynos/libdrm_exynos.pc.in b/exynos/libdrm_exynos.pc.in new file mode 100644 index 0000000..5ce9118 --- /dev/null +++ b/exynos/libdrm_exynos.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libdrm_exynos +Description: Userspace interface to exynos kernel DRM services +Version: 0.6 +Libs: -L${libdir} -ldrm_exynos +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos +Requires.private: libdrm diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 1e4ec91..c5aa194 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -721,7 +721,7 @@ int main(int argc, char **argv) int c; int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0; int test_vsync = 0; - char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm" }; + char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" }; char *modeset = NULL; int i, count = 0; struct connector con_args[2]; diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c index 903ca0f..4fccd59 100644 --- a/tests/vbltest/vbltest.c +++ b/tests/vbltest/vbltest.c @@ -103,7 +103,7 @@ static void usage(char *name) int main(int argc, char **argv) { int i, c, fd, ret; - char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx" }; + char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos" }; drmVBlank vbl; drmEventContext evctx; struct vbl_info handler_info;
Please, give me any comments and I hope this patch would be applied to libdrm if there is any problem.
Thanks, Inki Dae.
2012년 4월 2일 오후 9:08, Inki Dae inki.dae@samsung.com님의 말:
this patch adds libdrm_exynos helper layer that inclues some intefaces for exynos specific gem and virtual display driver and also adds exynos module name to modtest and vbltest.
this patch is based on a link below: git://anongit.freedesktop.org/mesa/drm commit id: e057a56448e2e785f74bc13dbd6ead8572ebed91
Signed-off-by: Inki Dae inki.dae@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com
Makefile.am | 6 +- configure.ac | 13 ++ exynos/Makefile.am | 22 +++ exynos/exynos_drm.c | 324 ++++++++++++++++++++++++++++++++++++++++++++ exynos/exynos_drm.h | 127 +++++++++++++++++ exynos/exynos_drmif.h | 60 ++++++++ exynos/libdrm_exynos.pc.in | 11 ++ tests/modetest/modetest.c | 2 +- tests/vbltest/vbltest.c | 2 +- 9 files changed, 564 insertions(+), 3 deletions(-) create mode 100644 exynos/Makefile.am create mode 100644 exynos/exynos_drm.c create mode 100644 exynos/exynos_drm.h create mode 100644 exynos/exynos_drmif.h create mode 100644 exynos/libdrm_exynos.pc.in
diff --git a/Makefile.am b/Makefile.am index 4f625a1..256a8cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,7 +45,11 @@ if HAVE_OMAP OMAP_SUBDIR = omap endif
-SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) tests include +if HAVE_EXYNOS +EXYNOS_SUBDIR = exynos +endif
+SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include
libdrm_la_LTLIBRARIES = libdrm.la libdrm_ladir = $(libdir) diff --git a/configure.ac b/configure.ac index 1ba7eba..ae84817 100644 --- a/configure.ac +++ b/configure.ac @@ -88,6 +88,11 @@ AC_ARG_ENABLE(omap-experimental-api, [Enable support for OMAP's experimental API (default: disabled)]), [OMAP=$enableval], [OMAP=no])
+AC_ARG_ENABLE(exynos-experimental-api,
AS_HELP_STRING([--enable-exynos-experimental-api],
[Enable support for EXYNOS's experimental API (default: disabled)]),
[EXYNOS=$enableval], [EXYNOS=no])
dnl =========================================================================== dnl check compiler flags AC_DEFUN([LIBDRM_CC_TRY_FLAG], [ @@ -191,6 +196,11 @@ if test "x$OMAP" = xyes; then AC_DEFINE(HAVE_OMAP, 1, [Have OMAP support]) fi
+AM_CONDITIONAL(HAVE_EXYNOS, [test "x$EXYNOS" = xyes]) +if test "x$EXYNOS" = xyes; then
AC_DEFINE(HAVE_EXYNOS, 1, [Have EXYNOS support])
+fi
PKG_CHECK_MODULES(CAIRO, cairo, [HAVE_CAIRO=yes], [HAVE_CAIRO=no]) if test "x$HAVE_CAIRO" = xyes; then AC_DEFINE(HAVE_CAIRO, 1, [Have cairo support]) @@ -302,6 +312,8 @@ AC_CONFIG_FILES([ nouveau/libdrm_nouveau.pc omap/Makefile omap/libdrm_omap.pc
exynos/Makefile
exynos/libdrm_exynos.pc tests/Makefile tests/modeprint/Makefile tests/modetest/Makefile
@@ -322,4 +334,5 @@ echo " vmwgfx API $VMWGFX" echo " Radeon API $RADEON" echo " Nouveau API $NOUVEAU" echo " OMAP API $OMAP" +echo " EXYNOS API $EXYNOS" echo "" diff --git a/exynos/Makefile.am b/exynos/Makefile.am new file mode 100644 index 0000000..e782d34 --- /dev/null +++ b/exynos/Makefile.am @@ -0,0 +1,22 @@ +AM_CFLAGS = \
$(WARN_CFLAGS) \
-I$(top_srcdir) \
-I$(top_srcdir)/exynos \
$(PTHREADSTUBS_CFLAGS) \
-I$(top_srcdir)/include/drm
+libdrm_exynos_la_LTLIBRARIES = libdrm_exynos.la +libdrm_exynos_ladir = $(libdir) +libdrm_exynos_la_LDFLAGS = -version-number 1:0:0 -no-undefined +libdrm_exynos_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
+libdrm_exynos_la_SOURCES = exynos_drm.c
+libdrm_exynoscommonincludedir = ${includedir}/exynos +libdrm_exynoscommoninclude_HEADERS = exynos_drm.h
+libdrm_exynosincludedir = ${includedir}/libdrm +libdrm_exynosinclude_HEADERS = exynos_drmif.h
+pkgconfigdir = @pkgconfigdir@ +pkgconfig_DATA = libdrm_exynos.pc diff --git a/exynos/exynos_drm.c b/exynos/exynos_drm.c new file mode 100644 index 0000000..778321a --- /dev/null +++ b/exynos/exynos_drm.c @@ -0,0 +1,324 @@ +/*
- Copyright (C) 2012 Samsung Electronics Co., Ltd.
- 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.
- Authors:
- Inki Dae inki.dae@samsung.com
- */
+#ifdef HAVE_CONFIG_H +#include "config.h" +#endif
+#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h>
+#include <sys/mman.h> +#include <linux/stddef.h>
+#include <xf86drm.h>
+#include "exynos_drm.h" +#include "exynos_drmif.h"
+struct exynos_device {
int fd;
+};
+/*
- Exynos Buffer Object structure.
- @dev: exynos device object allocated.
- @handle: a gem handle to gem object created.
- @size: size to the buffer created.
- @map: user pointer to a gem buffer mmaped.
- @name: a gem global handle from flink request.
- */
+struct exynos_bo {
struct exynos_device *dev;
uint32_t handle;
size_t size;
void *map;
uint32_t name;
+};
+/*
- Create exynos drm device object.
- @fd: file descriptor to exynos drm driver opened.
- if true, return the device object else NULL.
- */
+struct exynos_device * exynos_device_create(int fd) +{
struct exynos_device *dev;
dev = calloc(sizeof(*dev), 1);
if (!dev) {
fprintf(stderr, "failed to create device[%s].\n",
strerror(errno));
return NULL;
}
dev->fd = fd;
return dev;
+}
+/*
- Destroy exynos drm device object
- @dev: exynos drm device object.
- */
+void exynos_device_destroy(struct exynos_device *dev) +{
free(dev);
+}
+/*
- Create a exynos buffer object to exynos drm device.
- @dev: exynos drm device object.
- @size: user-desired size.
- flags: user-desired memory type.
user can set one or more types among EXYNOS_BO_NONCONTIG and
EXYNOS_BO_CONTIG and it would be used for EXYNOS_BO_NONCONTIG
as default.
EXYNOS_BO_NONCONTIG: Physically Non-continuous Memory type.
EXYNOS_BO_CONTIG: Physically Continuous Memory type.
- if true, return a exynos buffer object else NULL.
- */
+struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
size_t size, uint32_t flags)
+{
struct exynos_bo *bo;
struct drm_exynos_gem_create req = {
.size = size,
.flags = flags,
};
if (size == 0) {
fprintf(stderr, "invalid size.\n");
goto fail;
}
bo = calloc(sizeof(*bo), 1);
if (!bo) {
fprintf(stderr, "failed to create bo[%s].\n",
strerror(errno));
goto err_free_bo;
}
bo->dev = dev;
if (drmCommandWriteRead(dev->fd, DRM_EXYNOS_GEM_CREATE, &req,
sizeof(req))) {
fprintf(stderr, "failed to create gem object[%s].\n",
strerror(errno));
goto err_free_bo;
}
bo->handle = req.handle;
return bo;
+err_free_bo:
free(bo);
+fail:
return NULL;
+}
+/*
- Destroy a exynos buffer object.
- @bo: a exynos buffer object to be destroyed.
- */
+void exynos_bo_destroy(struct exynos_bo *bo) +{
if (!bo)
return;
if (bo->map)
munmap(bo->map, bo->size);
if (bo->handle) {
struct drm_gem_close req = {
.handle = bo->handle,
};
drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
}
free(bo);
+}
+/*
- Get a exynos buffer object from a gem global object name.
- @dev: a exynos device object.
- @name: a gem global object name exported by another process.
- this interface is used to get a exynos buffer object from a gem
- global object name sent by another process for buffer sharing.
- if true, return a exynos buffer object else NULL.
- */
+struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name) +{
struct exynos_bo *bo;
struct drm_gem_open req = {
.name = name,
};
bo = calloc(sizeof(*bo), 1);
if (!bo) {
fprintf(stderr, "failed to allocate bo[%s].\n",
strerror(errno));
return NULL;
}
if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) {
fprintf(stderr, "failed to open gem object[%s].\n",
strerror(errno));
goto err_free_bo;
}
bo->dev = dev;
bo->name = name;
bo->handle = req.handle;
return bo;
+err_free_bo:
free(bo);
return NULL;
+}
+/*
- Get a gem global object name from a gem object handle.
- @bo: a exynos buffer object including gem handle.
- @name: a gem global object name to be got by kernel driver.
- this interface is used to get a gem global object name from a gem object
- handle to a buffer that wants to share it with another process.
- if true, return 0 else negative.
- */
+int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name) +{
if (!bo->name) {
struct drm_gem_flink req = {
.handle = bo->handle,
};
int ret;
ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
if (ret) {
fprintf(stderr, "failed to get gem global name[%s].\n",
strerror(errno));
return ret;
}
bo->name = req.name;
}
*name = bo->name;
return 0;
+}
+uint32_t exynos_bo_handle(struct exynos_bo *bo) +{
return bo->handle;
+}
+/*
- Mmap a buffer to user space.
- @bo: a exynos buffer object including a gem object handle to be mmapped
to user space.
- if true, user pointer mmaped else NULL.
- */
+void *exynos_bo_map(struct exynos_bo *bo) +{
if (!bo->map) {
struct exynos_device *dev = bo->dev;
struct drm_exynos_gem_mmap req = {
.handle = bo->handle,
.size = bo->size,
};
int ret;
ret = drmCommandWriteRead(dev->fd, DRM_EXYNOS_GEM_MMAP, &req,
sizeof(req));
if (ret) {
fprintf(stderr, "failed to mmap[%s].\n",
strerror(errno));
return NULL;
}
}
return bo->map;
+}
+/*
- Request Wireless Display connection or disconnection.
- @dev: a exynos device object.
- @connect: indicate whether connectoin or disconnection request.
- @ext: indicate whether edid data includes extentions data or not.
- @edid: a pointer to edid data from Wireless Display device.
- this interface is used to request Virtual Display driver connection or
- disconnection. for this, user should get a edid data from the Wireless
- Display device and then send that data to kernel driver with connection
- request
- if true, return 0 else negative.
- */
+int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
uint32_t ext, void *edid)
+{
struct drm_exynos_vidi_connection req = {
.connection = connect,
.extensions = ext,
.edid = edid,
};
int ret;
ret = drmCommandWriteRead(dev->fd, DRM_EXYNOS_VIDI_CONNECTION, &req,
sizeof(req));
if (ret) {
fprintf(stderr, "failed to request vidi connection[%s].\n",
strerror(errno));
return ret;
}
return 0;
+} diff --git a/exynos/exynos_drm.h b/exynos/exynos_drm.h new file mode 100644 index 0000000..09f8723 --- /dev/null +++ b/exynos/exynos_drm.h @@ -0,0 +1,127 @@ +/* exynos_drm.h
- Copyright (c) 2011 Samsung Electronics Co., Ltd.
- Authors:
Inki Dae <inki.dae@samsung.com>
Joonyoung Shim <jy0922.shim@samsung.com>
Seung-Woo Kim <sw0312.kim@samsung.com>
- 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
- VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 _EXYNOS_DRM_H_ +#define _EXYNOS_DRM_H_
+/**
- User-desired buffer creation information structure.
- @size: user-desired memory allocation size.
- this size value would be page-aligned internally.
- @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_exynos_gem_create {
uint64_t size;
unsigned int flags;
unsigned int 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_exynos_gem_map_off {
unsigned int handle;
unsigned int pad;
uint64_t offset;
+};
+/**
- A structure for mapping buffer.
- @handle: a handle to gem object created.
- @size: memory size to be mapped.
- @mapped: having user virtual address mmaped.
- this variable would be filled by exynos gem module
of kernel side with user virtual address which is allocated
by do_mmap().
- */
+struct drm_exynos_gem_mmap {
unsigned int handle;
unsigned int size;
uint64_t mapped;
+};
+/**
- A structure for user connection request of virtual display.
- @connection: indicate whether doing connetion or not by user.
- @extensions: if this value is 1 then the vidi driver would need additional
128bytes edid data.
- @edid: the edid data pointer from user side.
- */
+struct drm_exynos_vidi_connection {
unsigned int connection;
unsigned int extensions;
uint64_t *edid;
+};
+struct drm_exynos_plane_set_zpos {
__u32 plane_id;
__s32 zpos;
+};
+/* memory type definitions. */ +enum e_drm_exynos_gem_mem_type {
/* Physically Continuous memory and used as default. */
EXYNOS_BO_CONTIG = 0 << 0,
/* Physically Non-Continuous memory. */
EXYNOS_BO_NONCONTIG = 1 << 0,
EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG
+};
+#define DRM_EXYNOS_GEM_CREATE 0x00 +#define DRM_EXYNOS_GEM_MAP_OFFSET 0x01 +#define DRM_EXYNOS_GEM_MMAP 0x02 +/* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */ +#define DRM_EXYNOS_PLANE_SET_ZPOS 0x06 +#define DRM_EXYNOS_VIDI_CONNECTION 0x07
+#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_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off)
+#define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap)
+#define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos)
+#define DRM_IOCTL_EXYNOS_VIDI_CONNECTION DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection)
+#endif diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h new file mode 100644 index 0000000..0f58083 --- /dev/null +++ b/exynos/exynos_drmif.h @@ -0,0 +1,60 @@ +/*
- Copyright (C) 2012 Samsung Electronics Co., Ltd.
- 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.
- Authors:
- Inki Dae inki.dae@samsung.com
- */
+#ifndef EXYNOS_DRMIF_H_ +#define EXYNOS_DRMIF_H_
+#include <xf86drm.h> +#include <stdint.h> +#include "exynos_drm.h"
+struct exynos_bo; +struct exynos_device;
+/*
- device related functions:
- */
+struct exynos_device * exynos_device_create(int fd); +void exynos_device_destroy(struct exynos_device *dev);
+/*
- buffer-object related functions:
- */
+struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
uint32_t size, uint32_t flags);
+void exynos_bo_destroy(struct exynos_bo *bo); +struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name); +int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name); +uint32_t exynos_bo_handle(struct exynos_bo *bo); +void * exynos_bo_map(struct exynos_bo *bo);
+/*
- Virtual Display related functions:
- */
+int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
uint32_t ext, void *edid);
+#endif /* EXYNOS_DRMIF_H_ */ diff --git a/exynos/libdrm_exynos.pc.in b/exynos/libdrm_exynos.pc.in new file mode 100644 index 0000000..5ce9118 --- /dev/null +++ b/exynos/libdrm_exynos.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@
+Name: libdrm_exynos +Description: Userspace interface to exynos kernel DRM services +Version: 0.6 +Libs: -L${libdir} -ldrm_exynos +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos +Requires.private: libdrm diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 1e4ec91..c5aa194 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -721,7 +721,7 @@ int main(int argc, char **argv) int c; int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0; int test_vsync = 0;
char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm" };
char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" }; char *modeset = NULL; int i, count = 0; struct connector con_args[2];
diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c index 903ca0f..4fccd59 100644 --- a/tests/vbltest/vbltest.c +++ b/tests/vbltest/vbltest.c @@ -103,7 +103,7 @@ static void usage(char *name) int main(int argc, char **argv) { int i, c, fd, ret;
char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx" };
char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos" }; drmVBlank vbl; drmEventContext evctx; struct vbl_info handler_info;
-- 1.7.4.1
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
2012/4/12 InKi Dae daeinki@gmail.com:
Please, give me any comments and I hope this patch would be applied to libdrm if there is any problem.
Looks good to me.
Reviewed-by: Alex Deucher alexander.deucher@amd.com
If you need an fdo account, you can request one here: http://www.freedesktop.org/wiki/AccountRequests
Alex
Thanks, Inki Dae.
2012년 4월 2일 오후 9:08, Inki Dae inki.dae@samsung.com님의 말:
this patch adds libdrm_exynos helper layer that inclues some intefaces for exynos specific gem and virtual display driver and also adds exynos module name to modtest and vbltest.
this patch is based on a link below: git://anongit.freedesktop.org/mesa/drm commit id: e057a56448e2e785f74bc13dbd6ead8572ebed91
Signed-off-by: Inki Dae inki.dae@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com
Makefile.am | 6 +- configure.ac | 13 ++ exynos/Makefile.am | 22 +++ exynos/exynos_drm.c | 324 ++++++++++++++++++++++++++++++++++++++++++++ exynos/exynos_drm.h | 127 +++++++++++++++++ exynos/exynos_drmif.h | 60 ++++++++ exynos/libdrm_exynos.pc.in | 11 ++ tests/modetest/modetest.c | 2 +- tests/vbltest/vbltest.c | 2 +- 9 files changed, 564 insertions(+), 3 deletions(-) create mode 100644 exynos/Makefile.am create mode 100644 exynos/exynos_drm.c create mode 100644 exynos/exynos_drm.h create mode 100644 exynos/exynos_drmif.h create mode 100644 exynos/libdrm_exynos.pc.in
diff --git a/Makefile.am b/Makefile.am index 4f625a1..256a8cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,7 +45,11 @@ if HAVE_OMAP OMAP_SUBDIR = omap endif
-SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) tests include +if HAVE_EXYNOS +EXYNOS_SUBDIR = exynos +endif
+SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include
libdrm_la_LTLIBRARIES = libdrm.la libdrm_ladir = $(libdir) diff --git a/configure.ac b/configure.ac index 1ba7eba..ae84817 100644 --- a/configure.ac +++ b/configure.ac @@ -88,6 +88,11 @@ AC_ARG_ENABLE(omap-experimental-api, [Enable support for OMAP's experimental API (default: disabled)]), [OMAP=$enableval], [OMAP=no])
+AC_ARG_ENABLE(exynos-experimental-api,
AS_HELP_STRING([--enable-exynos-experimental-api],
[Enable support for EXYNOS's experimental API (default: disabled)]),
[EXYNOS=$enableval], [EXYNOS=no])
dnl =========================================================================== dnl check compiler flags AC_DEFUN([LIBDRM_CC_TRY_FLAG], [ @@ -191,6 +196,11 @@ if test "x$OMAP" = xyes; then AC_DEFINE(HAVE_OMAP, 1, [Have OMAP support]) fi
+AM_CONDITIONAL(HAVE_EXYNOS, [test "x$EXYNOS" = xyes]) +if test "x$EXYNOS" = xyes; then
AC_DEFINE(HAVE_EXYNOS, 1, [Have EXYNOS support])
+fi
PKG_CHECK_MODULES(CAIRO, cairo, [HAVE_CAIRO=yes], [HAVE_CAIRO=no]) if test "x$HAVE_CAIRO" = xyes; then AC_DEFINE(HAVE_CAIRO, 1, [Have cairo support]) @@ -302,6 +312,8 @@ AC_CONFIG_FILES([ nouveau/libdrm_nouveau.pc omap/Makefile omap/libdrm_omap.pc
exynos/Makefile
exynos/libdrm_exynos.pc tests/Makefile tests/modeprint/Makefile tests/modetest/Makefile
@@ -322,4 +334,5 @@ echo " vmwgfx API $VMWGFX" echo " Radeon API $RADEON" echo " Nouveau API $NOUVEAU" echo " OMAP API $OMAP" +echo " EXYNOS API $EXYNOS" echo "" diff --git a/exynos/Makefile.am b/exynos/Makefile.am new file mode 100644 index 0000000..e782d34 --- /dev/null +++ b/exynos/Makefile.am @@ -0,0 +1,22 @@ +AM_CFLAGS = \
$(WARN_CFLAGS) \
-I$(top_srcdir) \
-I$(top_srcdir)/exynos \
$(PTHREADSTUBS_CFLAGS) \
-I$(top_srcdir)/include/drm
+libdrm_exynos_la_LTLIBRARIES = libdrm_exynos.la +libdrm_exynos_ladir = $(libdir) +libdrm_exynos_la_LDFLAGS = -version-number 1:0:0 -no-undefined +libdrm_exynos_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
+libdrm_exynos_la_SOURCES = exynos_drm.c
+libdrm_exynoscommonincludedir = ${includedir}/exynos +libdrm_exynoscommoninclude_HEADERS = exynos_drm.h
+libdrm_exynosincludedir = ${includedir}/libdrm +libdrm_exynosinclude_HEADERS = exynos_drmif.h
+pkgconfigdir = @pkgconfigdir@ +pkgconfig_DATA = libdrm_exynos.pc diff --git a/exynos/exynos_drm.c b/exynos/exynos_drm.c new file mode 100644 index 0000000..778321a --- /dev/null +++ b/exynos/exynos_drm.c @@ -0,0 +1,324 @@ +/*
- Copyright (C) 2012 Samsung Electronics Co., Ltd.
- 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.
- Authors:
- Inki Dae inki.dae@samsung.com
- */
+#ifdef HAVE_CONFIG_H +#include "config.h" +#endif
+#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h>
+#include <sys/mman.h> +#include <linux/stddef.h>
+#include <xf86drm.h>
+#include "exynos_drm.h" +#include "exynos_drmif.h"
+struct exynos_device {
int fd;
+};
+/*
- Exynos Buffer Object structure.
- @dev: exynos device object allocated.
- @handle: a gem handle to gem object created.
- @size: size to the buffer created.
- @map: user pointer to a gem buffer mmaped.
- @name: a gem global handle from flink request.
- */
+struct exynos_bo {
struct exynos_device *dev;
uint32_t handle;
size_t size;
void *map;
uint32_t name;
+};
+/*
- Create exynos drm device object.
- @fd: file descriptor to exynos drm driver opened.
- if true, return the device object else NULL.
- */
+struct exynos_device * exynos_device_create(int fd) +{
struct exynos_device *dev;
dev = calloc(sizeof(*dev), 1);
if (!dev) {
fprintf(stderr, "failed to create device[%s].\n",
strerror(errno));
return NULL;
}
dev->fd = fd;
return dev;
+}
+/*
- Destroy exynos drm device object
- @dev: exynos drm device object.
- */
+void exynos_device_destroy(struct exynos_device *dev) +{
free(dev);
+}
+/*
- Create a exynos buffer object to exynos drm device.
- @dev: exynos drm device object.
- @size: user-desired size.
- flags: user-desired memory type.
user can set one or more types among EXYNOS_BO_NONCONTIG and
EXYNOS_BO_CONTIG and it would be used for EXYNOS_BO_NONCONTIG
as default.
EXYNOS_BO_NONCONTIG: Physically Non-continuous Memory type.
EXYNOS_BO_CONTIG: Physically Continuous Memory type.
- if true, return a exynos buffer object else NULL.
- */
+struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
size_t size, uint32_t flags)
+{
struct exynos_bo *bo;
struct drm_exynos_gem_create req = {
.size = size,
.flags = flags,
};
if (size == 0) {
fprintf(stderr, "invalid size.\n");
goto fail;
}
bo = calloc(sizeof(*bo), 1);
if (!bo) {
fprintf(stderr, "failed to create bo[%s].\n",
strerror(errno));
goto err_free_bo;
}
bo->dev = dev;
if (drmCommandWriteRead(dev->fd, DRM_EXYNOS_GEM_CREATE, &req,
sizeof(req))) {
fprintf(stderr, "failed to create gem object[%s].\n",
strerror(errno));
goto err_free_bo;
}
bo->handle = req.handle;
return bo;
+err_free_bo:
free(bo);
+fail:
return NULL;
+}
+/*
- Destroy a exynos buffer object.
- @bo: a exynos buffer object to be destroyed.
- */
+void exynos_bo_destroy(struct exynos_bo *bo) +{
if (!bo)
return;
if (bo->map)
munmap(bo->map, bo->size);
if (bo->handle) {
struct drm_gem_close req = {
.handle = bo->handle,
};
drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
}
free(bo);
+}
+/*
- Get a exynos buffer object from a gem global object name.
- @dev: a exynos device object.
- @name: a gem global object name exported by another process.
- this interface is used to get a exynos buffer object from a gem
- global object name sent by another process for buffer sharing.
- if true, return a exynos buffer object else NULL.
- */
+struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name) +{
struct exynos_bo *bo;
struct drm_gem_open req = {
.name = name,
};
bo = calloc(sizeof(*bo), 1);
if (!bo) {
fprintf(stderr, "failed to allocate bo[%s].\n",
strerror(errno));
return NULL;
}
if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) {
fprintf(stderr, "failed to open gem object[%s].\n",
strerror(errno));
goto err_free_bo;
}
bo->dev = dev;
bo->name = name;
bo->handle = req.handle;
return bo;
+err_free_bo:
free(bo);
return NULL;
+}
+/*
- Get a gem global object name from a gem object handle.
- @bo: a exynos buffer object including gem handle.
- @name: a gem global object name to be got by kernel driver.
- this interface is used to get a gem global object name from a gem object
- handle to a buffer that wants to share it with another process.
- if true, return 0 else negative.
- */
+int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name) +{
if (!bo->name) {
struct drm_gem_flink req = {
.handle = bo->handle,
};
int ret;
ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
if (ret) {
fprintf(stderr, "failed to get gem global name[%s].\n",
strerror(errno));
return ret;
}
bo->name = req.name;
}
*name = bo->name;
return 0;
+}
+uint32_t exynos_bo_handle(struct exynos_bo *bo) +{
return bo->handle;
+}
+/*
- Mmap a buffer to user space.
- @bo: a exynos buffer object including a gem object handle to be mmapped
to user space.
- if true, user pointer mmaped else NULL.
- */
+void *exynos_bo_map(struct exynos_bo *bo) +{
if (!bo->map) {
struct exynos_device *dev = bo->dev;
struct drm_exynos_gem_mmap req = {
.handle = bo->handle,
.size = bo->size,
};
int ret;
ret = drmCommandWriteRead(dev->fd, DRM_EXYNOS_GEM_MMAP, &req,
sizeof(req));
if (ret) {
fprintf(stderr, "failed to mmap[%s].\n",
strerror(errno));
return NULL;
}
}
return bo->map;
+}
+/*
- Request Wireless Display connection or disconnection.
- @dev: a exynos device object.
- @connect: indicate whether connectoin or disconnection request.
- @ext: indicate whether edid data includes extentions data or not.
- @edid: a pointer to edid data from Wireless Display device.
- this interface is used to request Virtual Display driver connection or
- disconnection. for this, user should get a edid data from the Wireless
- Display device and then send that data to kernel driver with connection
- request
- if true, return 0 else negative.
- */
+int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
uint32_t ext, void *edid)
+{
struct drm_exynos_vidi_connection req = {
.connection = connect,
.extensions = ext,
.edid = edid,
};
int ret;
ret = drmCommandWriteRead(dev->fd, DRM_EXYNOS_VIDI_CONNECTION, &req,
sizeof(req));
if (ret) {
fprintf(stderr, "failed to request vidi connection[%s].\n",
strerror(errno));
return ret;
}
return 0;
+} diff --git a/exynos/exynos_drm.h b/exynos/exynos_drm.h new file mode 100644 index 0000000..09f8723 --- /dev/null +++ b/exynos/exynos_drm.h @@ -0,0 +1,127 @@ +/* exynos_drm.h
- Copyright (c) 2011 Samsung Electronics Co., Ltd.
- Authors:
Inki Dae <inki.dae@samsung.com>
Joonyoung Shim <jy0922.shim@samsung.com>
Seung-Woo Kim <sw0312.kim@samsung.com>
- 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
- VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 _EXYNOS_DRM_H_ +#define _EXYNOS_DRM_H_
+/**
- User-desired buffer creation information structure.
- @size: user-desired memory allocation size.
- this size value would be page-aligned internally.
- @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_exynos_gem_create {
uint64_t size;
unsigned int flags;
unsigned int 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_exynos_gem_map_off {
unsigned int handle;
unsigned int pad;
uint64_t offset;
+};
+/**
- A structure for mapping buffer.
- @handle: a handle to gem object created.
- @size: memory size to be mapped.
- @mapped: having user virtual address mmaped.
- this variable would be filled by exynos gem module
of kernel side with user virtual address which is allocated
by do_mmap().
- */
+struct drm_exynos_gem_mmap {
unsigned int handle;
unsigned int size;
uint64_t mapped;
+};
+/**
- A structure for user connection request of virtual display.
- @connection: indicate whether doing connetion or not by user.
- @extensions: if this value is 1 then the vidi driver would need additional
128bytes edid data.
- @edid: the edid data pointer from user side.
- */
+struct drm_exynos_vidi_connection {
unsigned int connection;
unsigned int extensions;
uint64_t *edid;
+};
+struct drm_exynos_plane_set_zpos {
__u32 plane_id;
__s32 zpos;
+};
+/* memory type definitions. */ +enum e_drm_exynos_gem_mem_type {
/* Physically Continuous memory and used as default. */
EXYNOS_BO_CONTIG = 0 << 0,
/* Physically Non-Continuous memory. */
EXYNOS_BO_NONCONTIG = 1 << 0,
EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG
+};
+#define DRM_EXYNOS_GEM_CREATE 0x00 +#define DRM_EXYNOS_GEM_MAP_OFFSET 0x01 +#define DRM_EXYNOS_GEM_MMAP 0x02 +/* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */ +#define DRM_EXYNOS_PLANE_SET_ZPOS 0x06 +#define DRM_EXYNOS_VIDI_CONNECTION 0x07
+#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_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off)
+#define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap)
+#define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos)
+#define DRM_IOCTL_EXYNOS_VIDI_CONNECTION DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection)
+#endif diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h new file mode 100644 index 0000000..0f58083 --- /dev/null +++ b/exynos/exynos_drmif.h @@ -0,0 +1,60 @@ +/*
- Copyright (C) 2012 Samsung Electronics Co., Ltd.
- 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.
- Authors:
- Inki Dae inki.dae@samsung.com
- */
+#ifndef EXYNOS_DRMIF_H_ +#define EXYNOS_DRMIF_H_
+#include <xf86drm.h> +#include <stdint.h> +#include "exynos_drm.h"
+struct exynos_bo; +struct exynos_device;
+/*
- device related functions:
- */
+struct exynos_device * exynos_device_create(int fd); +void exynos_device_destroy(struct exynos_device *dev);
+/*
- buffer-object related functions:
- */
+struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
uint32_t size, uint32_t flags);
+void exynos_bo_destroy(struct exynos_bo *bo); +struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name); +int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name); +uint32_t exynos_bo_handle(struct exynos_bo *bo); +void * exynos_bo_map(struct exynos_bo *bo);
+/*
- Virtual Display related functions:
- */
+int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
uint32_t ext, void *edid);
+#endif /* EXYNOS_DRMIF_H_ */ diff --git a/exynos/libdrm_exynos.pc.in b/exynos/libdrm_exynos.pc.in new file mode 100644 index 0000000..5ce9118 --- /dev/null +++ b/exynos/libdrm_exynos.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@
+Name: libdrm_exynos +Description: Userspace interface to exynos kernel DRM services +Version: 0.6 +Libs: -L${libdir} -ldrm_exynos +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos +Requires.private: libdrm diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 1e4ec91..c5aa194 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -721,7 +721,7 @@ int main(int argc, char **argv) int c; int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0; int test_vsync = 0;
char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm" };
char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" }; char *modeset = NULL; int i, count = 0; struct connector con_args[2];
diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c index 903ca0f..4fccd59 100644 --- a/tests/vbltest/vbltest.c +++ b/tests/vbltest/vbltest.c @@ -103,7 +103,7 @@ static void usage(char *name) int main(int argc, char **argv) { int i, c, fd, ret;
char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx" };
char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos" }; drmVBlank vbl; drmEventContext evctx; struct vbl_info handler_info;
-- 1.7.4.1
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
On Mon, Apr 2, 2012 at 7:08 AM, Inki Dae inki.dae@samsung.com wrote:
this patch adds libdrm_exynos helper layer that inclues some intefaces for exynos specific gem and virtual display driver and also adds exynos module name to modtest and vbltest.
this patch is based on a link below: git://anongit.freedesktop.org/mesa/drm commit id: e057a56448e2e785f74bc13dbd6ead8572ebed91
Reviewed-by: Rob Clark <rob@.ti.com>
Signed-off-by: Inki Dae inki.dae@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com
Makefile.am | 6 +- configure.ac | 13 ++ exynos/Makefile.am | 22 +++ exynos/exynos_drm.c | 324 ++++++++++++++++++++++++++++++++++++++++++++ exynos/exynos_drm.h | 127 +++++++++++++++++ exynos/exynos_drmif.h | 60 ++++++++ exynos/libdrm_exynos.pc.in | 11 ++ tests/modetest/modetest.c | 2 +- tests/vbltest/vbltest.c | 2 +- 9 files changed, 564 insertions(+), 3 deletions(-) create mode 100644 exynos/Makefile.am create mode 100644 exynos/exynos_drm.c create mode 100644 exynos/exynos_drm.h create mode 100644 exynos/exynos_drmif.h create mode 100644 exynos/libdrm_exynos.pc.in
diff --git a/Makefile.am b/Makefile.am index 4f625a1..256a8cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,7 +45,11 @@ if HAVE_OMAP OMAP_SUBDIR = omap endif
-SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) tests include +if HAVE_EXYNOS +EXYNOS_SUBDIR = exynos +endif
+SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include
libdrm_la_LTLIBRARIES = libdrm.la libdrm_ladir = $(libdir) diff --git a/configure.ac b/configure.ac index 1ba7eba..ae84817 100644 --- a/configure.ac +++ b/configure.ac @@ -88,6 +88,11 @@ AC_ARG_ENABLE(omap-experimental-api, [Enable support for OMAP's experimental API (default: disabled)]), [OMAP=$enableval], [OMAP=no])
+AC_ARG_ENABLE(exynos-experimental-api,
- AS_HELP_STRING([--enable-exynos-experimental-api],
- [Enable support for EXYNOS's experimental API (default: disabled)]),
- [EXYNOS=$enableval], [EXYNOS=no])
dnl =========================================================================== dnl check compiler flags AC_DEFUN([LIBDRM_CC_TRY_FLAG], [ @@ -191,6 +196,11 @@ if test "x$OMAP" = xyes; then AC_DEFINE(HAVE_OMAP, 1, [Have OMAP support]) fi
+AM_CONDITIONAL(HAVE_EXYNOS, [test "x$EXYNOS" = xyes]) +if test "x$EXYNOS" = xyes; then
- AC_DEFINE(HAVE_EXYNOS, 1, [Have EXYNOS support])
+fi
PKG_CHECK_MODULES(CAIRO, cairo, [HAVE_CAIRO=yes], [HAVE_CAIRO=no]) if test "x$HAVE_CAIRO" = xyes; then AC_DEFINE(HAVE_CAIRO, 1, [Have cairo support]) @@ -302,6 +312,8 @@ AC_CONFIG_FILES([ nouveau/libdrm_nouveau.pc omap/Makefile omap/libdrm_omap.pc
- exynos/Makefile
- exynos/libdrm_exynos.pc
tests/Makefile tests/modeprint/Makefile tests/modetest/Makefile @@ -322,4 +334,5 @@ echo " vmwgfx API $VMWGFX" echo " Radeon API $RADEON" echo " Nouveau API $NOUVEAU" echo " OMAP API $OMAP" +echo " EXYNOS API $EXYNOS" echo "" diff --git a/exynos/Makefile.am b/exynos/Makefile.am new file mode 100644 index 0000000..e782d34 --- /dev/null +++ b/exynos/Makefile.am @@ -0,0 +1,22 @@ +AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -I$(top_srcdir) \
- -I$(top_srcdir)/exynos \
- $(PTHREADSTUBS_CFLAGS) \
- -I$(top_srcdir)/include/drm
+libdrm_exynos_la_LTLIBRARIES = libdrm_exynos.la +libdrm_exynos_ladir = $(libdir) +libdrm_exynos_la_LDFLAGS = -version-number 1:0:0 -no-undefined +libdrm_exynos_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
+libdrm_exynos_la_SOURCES = exynos_drm.c
+libdrm_exynoscommonincludedir = ${includedir}/exynos +libdrm_exynoscommoninclude_HEADERS = exynos_drm.h
+libdrm_exynosincludedir = ${includedir}/libdrm +libdrm_exynosinclude_HEADERS = exynos_drmif.h
+pkgconfigdir = @pkgconfigdir@ +pkgconfig_DATA = libdrm_exynos.pc diff --git a/exynos/exynos_drm.c b/exynos/exynos_drm.c new file mode 100644 index 0000000..778321a --- /dev/null +++ b/exynos/exynos_drm.c @@ -0,0 +1,324 @@ +/*
- Copyright (C) 2012 Samsung Electronics Co., Ltd.
- 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.
- Authors:
- Inki Dae inki.dae@samsung.com
- */
+#ifdef HAVE_CONFIG_H +#include "config.h" +#endif
+#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h>
+#include <sys/mman.h> +#include <linux/stddef.h>
+#include <xf86drm.h>
+#include "exynos_drm.h" +#include "exynos_drmif.h"
+struct exynos_device {
- int fd;
+};
+/*
- Exynos Buffer Object structure.
- @dev: exynos device object allocated.
- @handle: a gem handle to gem object created.
- @size: size to the buffer created.
- @map: user pointer to a gem buffer mmaped.
- @name: a gem global handle from flink request.
- */
+struct exynos_bo {
- struct exynos_device *dev;
- uint32_t handle;
- size_t size;
- void *map;
- uint32_t name;
+};
+/*
- Create exynos drm device object.
- @fd: file descriptor to exynos drm driver opened.
- if true, return the device object else NULL.
- */
+struct exynos_device * exynos_device_create(int fd) +{
- struct exynos_device *dev;
- dev = calloc(sizeof(*dev), 1);
- if (!dev) {
- fprintf(stderr, "failed to create device[%s].\n",
- strerror(errno));
- return NULL;
- }
- dev->fd = fd;
- return dev;
+}
+/*
- Destroy exynos drm device object
- @dev: exynos drm device object.
- */
+void exynos_device_destroy(struct exynos_device *dev) +{
- free(dev);
+}
+/*
- Create a exynos buffer object to exynos drm device.
- @dev: exynos drm device object.
- @size: user-desired size.
- flags: user-desired memory type.
- user can set one or more types among EXYNOS_BO_NONCONTIG and
- EXYNOS_BO_CONTIG and it would be used for EXYNOS_BO_NONCONTIG
- as default.
- EXYNOS_BO_NONCONTIG: Physically Non-continuous Memory type.
- EXYNOS_BO_CONTIG: Physically Continuous Memory type.
- if true, return a exynos buffer object else NULL.
- */
+struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
- size_t size, uint32_t flags)
+{
- struct exynos_bo *bo;
- struct drm_exynos_gem_create req = {
- .size = size,
- .flags = flags,
- };
- if (size == 0) {
- fprintf(stderr, "invalid size.\n");
- goto fail;
- }
- bo = calloc(sizeof(*bo), 1);
- if (!bo) {
- fprintf(stderr, "failed to create bo[%s].\n",
- strerror(errno));
- goto err_free_bo;
- }
- bo->dev = dev;
- if (drmCommandWriteRead(dev->fd, DRM_EXYNOS_GEM_CREATE, &req,
- sizeof(req))) {
- fprintf(stderr, "failed to create gem object[%s].\n",
- strerror(errno));
- goto err_free_bo;
- }
- bo->handle = req.handle;
- return bo;
+err_free_bo:
- free(bo);
+fail:
- return NULL;
+}
+/*
- Destroy a exynos buffer object.
- @bo: a exynos buffer object to be destroyed.
- */
+void exynos_bo_destroy(struct exynos_bo *bo) +{
- if (!bo)
- return;
- if (bo->map)
- munmap(bo->map, bo->size);
- if (bo->handle) {
- struct drm_gem_close req = {
- .handle = bo->handle,
- };
- drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
- }
- free(bo);
+}
+/*
- Get a exynos buffer object from a gem global object name.
- @dev: a exynos device object.
- @name: a gem global object name exported by another process.
- this interface is used to get a exynos buffer object from a gem
- global object name sent by another process for buffer sharing.
- if true, return a exynos buffer object else NULL.
- */
+struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name) +{
- struct exynos_bo *bo;
- struct drm_gem_open req = {
- .name = name,
- };
- bo = calloc(sizeof(*bo), 1);
- if (!bo) {
- fprintf(stderr, "failed to allocate bo[%s].\n",
- strerror(errno));
- return NULL;
- }
- if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) {
- fprintf(stderr, "failed to open gem object[%s].\n",
- strerror(errno));
- goto err_free_bo;
- }
- bo->dev = dev;
- bo->name = name;
- bo->handle = req.handle;
- return bo;
+err_free_bo:
- free(bo);
- return NULL;
+}
+/*
- Get a gem global object name from a gem object handle.
- @bo: a exynos buffer object including gem handle.
- @name: a gem global object name to be got by kernel driver.
- this interface is used to get a gem global object name from a gem object
- handle to a buffer that wants to share it with another process.
- if true, return 0 else negative.
- */
+int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name) +{
- if (!bo->name) {
- struct drm_gem_flink req = {
- .handle = bo->handle,
- };
- int ret;
- ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
- if (ret) {
- fprintf(stderr, "failed to get gem global name[%s].\n",
- strerror(errno));
- return ret;
- }
- bo->name = req.name;
- }
- *name = bo->name;
- return 0;
+}
+uint32_t exynos_bo_handle(struct exynos_bo *bo) +{
- return bo->handle;
+}
+/*
- Mmap a buffer to user space.
- @bo: a exynos buffer object including a gem object handle to be mmapped
- to user space.
- if true, user pointer mmaped else NULL.
- */
+void *exynos_bo_map(struct exynos_bo *bo) +{
- if (!bo->map) {
- struct exynos_device *dev = bo->dev;
- struct drm_exynos_gem_mmap req = {
- .handle = bo->handle,
- .size = bo->size,
- };
- int ret;
- ret = drmCommandWriteRead(dev->fd, DRM_EXYNOS_GEM_MMAP, &req,
- sizeof(req));
- if (ret) {
- fprintf(stderr, "failed to mmap[%s].\n",
- strerror(errno));
- return NULL;
- }
- }
- return bo->map;
+}
+/*
- Request Wireless Display connection or disconnection.
- @dev: a exynos device object.
- @connect: indicate whether connectoin or disconnection request.
- @ext: indicate whether edid data includes extentions data or not.
- @edid: a pointer to edid data from Wireless Display device.
- this interface is used to request Virtual Display driver connection or
- disconnection. for this, user should get a edid data from the Wireless
- Display device and then send that data to kernel driver with connection
- request
- if true, return 0 else negative.
- */
+int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
- uint32_t ext, void *edid)
+{
- struct drm_exynos_vidi_connection req = {
- .connection = connect,
- .extensions = ext,
- .edid = edid,
- };
- int ret;
- ret = drmCommandWriteRead(dev->fd, DRM_EXYNOS_VIDI_CONNECTION, &req,
- sizeof(req));
- if (ret) {
- fprintf(stderr, "failed to request vidi connection[%s].\n",
- strerror(errno));
- return ret;
- }
- return 0;
+} diff --git a/exynos/exynos_drm.h b/exynos/exynos_drm.h new file mode 100644 index 0000000..09f8723 --- /dev/null +++ b/exynos/exynos_drm.h @@ -0,0 +1,127 @@ +/* exynos_drm.h
- Copyright (c) 2011 Samsung Electronics Co., Ltd.
- Authors:
- Inki Dae inki.dae@samsung.com
- Joonyoung Shim jy0922.shim@samsung.com
- Seung-Woo Kim sw0312.kim@samsung.com
- 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
- VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 _EXYNOS_DRM_H_ +#define _EXYNOS_DRM_H_
+/**
- User-desired buffer creation information structure.
- @size: user-desired memory allocation size.
- - this size value would be page-aligned internally.
- @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_exynos_gem_create {
- uint64_t size;
- unsigned int flags;
- unsigned int 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_exynos_gem_map_off {
- unsigned int handle;
- unsigned int pad;
- uint64_t offset;
+};
+/**
- A structure for mapping buffer.
- @handle: a handle to gem object created.
- @size: memory size to be mapped.
- @mapped: having user virtual address mmaped.
- - this variable would be filled by exynos gem module
- of kernel side with user virtual address which is allocated
- by do_mmap().
- */
+struct drm_exynos_gem_mmap {
- unsigned int handle;
- unsigned int size;
- uint64_t mapped;
+};
+/**
- A structure for user connection request of virtual display.
- @connection: indicate whether doing connetion or not by user.
- @extensions: if this value is 1 then the vidi driver would need additional
- 128bytes edid data.
- @edid: the edid data pointer from user side.
- */
+struct drm_exynos_vidi_connection {
- unsigned int connection;
- unsigned int extensions;
- uint64_t *edid;
+};
+struct drm_exynos_plane_set_zpos {
- __u32 plane_id;
- __s32 zpos;
+};
+/* memory type definitions. */ +enum e_drm_exynos_gem_mem_type {
- /* Physically Continuous memory and used as default. */
- EXYNOS_BO_CONTIG = 0 << 0,
- /* Physically Non-Continuous memory. */
- EXYNOS_BO_NONCONTIG = 1 << 0,
- EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG
+};
+#define DRM_EXYNOS_GEM_CREATE 0x00 +#define DRM_EXYNOS_GEM_MAP_OFFSET 0x01 +#define DRM_EXYNOS_GEM_MMAP 0x02 +/* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */ +#define DRM_EXYNOS_PLANE_SET_ZPOS 0x06 +#define DRM_EXYNOS_VIDI_CONNECTION 0x07
+#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_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off)
+#define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap)
+#define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos)
+#define DRM_IOCTL_EXYNOS_VIDI_CONNECTION DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection)
+#endif diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h new file mode 100644 index 0000000..0f58083 --- /dev/null +++ b/exynos/exynos_drmif.h @@ -0,0 +1,60 @@ +/*
- Copyright (C) 2012 Samsung Electronics Co., Ltd.
- 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.
- Authors:
- Inki Dae inki.dae@samsung.com
- */
+#ifndef EXYNOS_DRMIF_H_ +#define EXYNOS_DRMIF_H_
+#include <xf86drm.h> +#include <stdint.h> +#include "exynos_drm.h"
+struct exynos_bo; +struct exynos_device;
+/*
- device related functions:
- */
+struct exynos_device * exynos_device_create(int fd); +void exynos_device_destroy(struct exynos_device *dev);
+/*
- buffer-object related functions:
- */
+struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
- uint32_t size, uint32_t flags);
+void exynos_bo_destroy(struct exynos_bo *bo); +struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name); +int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name); +uint32_t exynos_bo_handle(struct exynos_bo *bo); +void * exynos_bo_map(struct exynos_bo *bo);
+/*
- Virtual Display related functions:
- */
+int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
- uint32_t ext, void *edid);
+#endif /* EXYNOS_DRMIF_H_ */ diff --git a/exynos/libdrm_exynos.pc.in b/exynos/libdrm_exynos.pc.in new file mode 100644 index 0000000..5ce9118 --- /dev/null +++ b/exynos/libdrm_exynos.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@
+Name: libdrm_exynos +Description: Userspace interface to exynos kernel DRM services +Version: 0.6 +Libs: -L${libdir} -ldrm_exynos +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos +Requires.private: libdrm diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 1e4ec91..c5aa194 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -721,7 +721,7 @@ int main(int argc, char **argv) int c; int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0; int test_vsync = 0;
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm" };
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" };
char *modeset = NULL; int i, count = 0; struct connector con_args[2]; diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c index 903ca0f..4fccd59 100644 --- a/tests/vbltest/vbltest.c +++ b/tests/vbltest/vbltest.c @@ -103,7 +103,7 @@ static void usage(char *name) int main(int argc, char **argv) { int i, c, fd, ret;
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx" };
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos" };
drmVBlank vbl; drmEventContext evctx; struct vbl_info handler_info; -- 1.7.4.1
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
this patch adds libdrm_exynos helper layer that inclues some intefaces for exynos specific gem and virtual display driver and also adds exynos module name to modtest and vbltest.
Changelog v2: - fixed exynos broken ioctl. the pointer of uint64_t *edid should be removed. - removed unnecessary definitions. - added drm prime interfaces. this feature is used to share a buffer between drivers or memory managers and for this, please, refer to below links: http://www.mjmwired.net/kernel/Documentation/dma-buf-sharing.txt http://lwn.net/Articles/488664/
this patch is based on a link below: git://anongit.freedesktop.org/mesa/drm commit id: d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22
Reviewed-by: Rob Clark rob@ti.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Inki Dae inki.dae@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com --- Makefile.am | 6 +- configure.ac | 13 ++ exynos/Makefile.am | 22 +++ exynos/exynos_drm.c | 396 ++++++++++++++++++++++++++++++++++++++++++++ exynos/exynos_drm.h | 149 +++++++++++++++++ exynos/exynos_drmif.h | 88 ++++++++++ exynos/libdrm_exynos.pc | 11 ++ exynos/libdrm_exynos.pc.in | 11 ++ tests/modetest/modetest.c | 2 +- tests/vbltest/vbltest.c | 2 +- 10 files changed, 697 insertions(+), 3 deletions(-) create mode 100644 exynos/Makefile.am create mode 100644 exynos/exynos_drm.c create mode 100644 exynos/exynos_drm.h create mode 100644 exynos/exynos_drmif.h create mode 100644 exynos/libdrm_exynos.pc create mode 100644 exynos/libdrm_exynos.pc.in
diff --git a/Makefile.am b/Makefile.am index 4f625a1..256a8cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,7 +45,11 @@ if HAVE_OMAP OMAP_SUBDIR = omap endif
-SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) tests include +if HAVE_EXYNOS +EXYNOS_SUBDIR = exynos +endif + +SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include
libdrm_la_LTLIBRARIES = libdrm.la libdrm_ladir = $(libdir) diff --git a/configure.ac b/configure.ac index 6a1d98e..f832201 100644 --- a/configure.ac +++ b/configure.ac @@ -88,6 +88,11 @@ AC_ARG_ENABLE(omap-experimental-api, [Enable support for OMAP's experimental API (default: disabled)]), [OMAP=$enableval], [OMAP=no])
+AC_ARG_ENABLE(exynos-experimental-api, + AS_HELP_STRING([--enable-exynos-experimental-api], + [Enable support for EXYNOS's experimental API (default: disabled)]), + [EXYNOS=$enableval], [EXYNOS=no]) + dnl =========================================================================== dnl check compiler flags AC_DEFUN([LIBDRM_CC_TRY_FLAG], [ @@ -191,6 +196,11 @@ if test "x$OMAP" = xyes; then AC_DEFINE(HAVE_OMAP, 1, [Have OMAP support]) fi
+AM_CONDITIONAL(HAVE_EXYNOS, [test "x$EXYNOS" = xyes]) +if test "x$EXYNOS" = xyes; then + AC_DEFINE(HAVE_EXYNOS, 1, [Have EXYNOS support]) +fi + PKG_CHECK_MODULES(CAIRO, cairo, [HAVE_CAIRO=yes], [HAVE_CAIRO=no]) if test "x$HAVE_CAIRO" = xyes; then AC_DEFINE(HAVE_CAIRO, 1, [Have cairo support]) @@ -313,6 +323,8 @@ AC_CONFIG_FILES([ nouveau/libdrm_nouveau.pc omap/Makefile omap/libdrm_omap.pc + exynos/Makefile + exynos/libdrm_exynos.pc tests/Makefile tests/modeprint/Makefile tests/modetest/Makefile @@ -333,4 +345,5 @@ echo " vmwgfx API $VMWGFX" echo " Radeon API $RADEON" echo " Nouveau API $NOUVEAU" echo " OMAP API $OMAP" +echo " EXYNOS API $EXYNOS" echo "" diff --git a/exynos/Makefile.am b/exynos/Makefile.am new file mode 100644 index 0000000..e782d34 --- /dev/null +++ b/exynos/Makefile.am @@ -0,0 +1,22 @@ +AM_CFLAGS = \ + $(WARN_CFLAGS) \ + -I$(top_srcdir) \ + -I$(top_srcdir)/exynos \ + $(PTHREADSTUBS_CFLAGS) \ + -I$(top_srcdir)/include/drm + +libdrm_exynos_la_LTLIBRARIES = libdrm_exynos.la +libdrm_exynos_ladir = $(libdir) +libdrm_exynos_la_LDFLAGS = -version-number 1:0:0 -no-undefined +libdrm_exynos_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@ + +libdrm_exynos_la_SOURCES = exynos_drm.c + +libdrm_exynoscommonincludedir = ${includedir}/exynos +libdrm_exynoscommoninclude_HEADERS = exynos_drm.h + +libdrm_exynosincludedir = ${includedir}/libdrm +libdrm_exynosinclude_HEADERS = exynos_drmif.h + +pkgconfigdir = @pkgconfigdir@ +pkgconfig_DATA = libdrm_exynos.pc diff --git a/exynos/exynos_drm.c b/exynos/exynos_drm.c new file mode 100644 index 0000000..4db755e --- /dev/null +++ b/exynos/exynos_drm.c @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co., Ltd. + * + * 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. + * + * Authors: + * Inki Dae inki.dae@samsung.com + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include <sys/mman.h> +#include <linux/stddef.h> + +#include <xf86drm.h> + +#include "exynos_drm.h" +#include "exynos_drmif.h" + +/* + * Create exynos drm device object. + * + * @fd: file descriptor to exynos drm driver opened. + * + * if true, return the device object else NULL. + */ +struct exynos_device * exynos_device_create(int fd) +{ + struct exynos_device *dev; + + dev = calloc(sizeof(*dev), 1); + if (!dev) { + fprintf(stderr, "failed to create device[%s].\n", + strerror(errno)); + return NULL; + } + + dev->fd = fd; + + return dev; +} + +/* + * Destroy exynos drm device object + * + * @dev: exynos drm device object. + */ +void exynos_device_destroy(struct exynos_device *dev) +{ + free(dev); +} + +/* + * Create a exynos buffer object to exynos drm device. + * + * @dev: exynos drm device object. + * @size: user-desired size. + * flags: user-desired memory type. + * user can set one or more types among several types to memory + * allocation and cache attribute types. and as default, + * EXYNOS_BO_NONCONTIG and EXYNOS-BO_NONCACHABLE types would + * be used. + * + * if true, return a exynos buffer object else NULL. + */ +struct exynos_bo * exynos_bo_create(struct exynos_device *dev, + size_t size, uint32_t flags) +{ + struct exynos_bo *bo; + struct drm_exynos_gem_create req = { + .size = size, + .flags = flags, + }; + + if (size == 0) { + fprintf(stderr, "invalid size.\n"); + goto fail; + } + + bo = calloc(sizeof(*bo), 1); + if (!bo) { + fprintf(stderr, "failed to create bo[%s].\n", + strerror(errno)); + goto err_free_bo; + } + + bo->dev = dev; + + if (drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_CREATE, &req)){ + fprintf(stderr, "failed to create gem object[%s].\n", + strerror(errno)); + goto err_free_bo; + } + + bo->handle = req.handle; + bo->size = size; + bo->flags = flags; + + return bo; + +err_free_bo: + free(bo); +fail: + return NULL; +} + +/* + * Get information to gem region allocated. + * + * @dev: exynos drm device object. + * @handle: gem handle to request gem info. + * @size: size to gem object and returned by kernel side. + * @flags: gem flags to gem object and returned by kernel side. + * + * with this function call, you can get flags and size to gem handle + * through bo object. + * + * if true, return 0 else negative. + */ +int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle, + size_t *size, uint32_t *flags) +{ + int ret; + struct drm_exynos_gem_info req = { + .handle = handle, + }; + + ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_GET, &req); + if (ret < 0) { + fprintf(stderr, "failed to get gem object information[%s].\n", + strerror(errno)); + return ret; + } + + *size = req.size; + *flags = req.flags; + + return 0; +} + +/* + * Destroy a exynos buffer object. + * + * @bo: a exynos buffer object to be destroyed. + */ +void exynos_bo_destroy(struct exynos_bo *bo) +{ + if (!bo) + return; + + if (bo->vaddr) + munmap(bo->vaddr, bo->size); + + if (bo->handle) { + struct drm_gem_close req = { + .handle = bo->handle, + }; + + drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req); + } + + free(bo); +} + + +/* + * Get a exynos buffer object from a gem global object name. + * + * @dev: a exynos device object. + * @name: a gem global object name exported by another process. + * + * this interface is used to get a exynos buffer object from a gem + * global object name sent by another process for buffer sharing. + * + * if true, return a exynos buffer object else NULL. + * + */ +struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name) +{ + struct exynos_bo *bo; + struct drm_gem_open req = { + .name = name, + }; + + bo = calloc(sizeof(*bo), 1); + if (!bo) { + fprintf(stderr, "failed to allocate bo[%s].\n", + strerror(errno)); + return NULL; + } + + if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) { + fprintf(stderr, "failed to open gem object[%s].\n", + strerror(errno)); + goto err_free_bo; + } + + bo->dev = dev; + bo->name = name; + bo->handle = req.handle; + + return bo; + +err_free_bo: + free(bo); + return NULL; +} + +/* + * Get a gem global object name from a gem object handle. + * + * @bo: a exynos buffer object including gem handle. + * @name: a gem global object name to be got by kernel driver. + * + * this interface is used to get a gem global object name from a gem object + * handle to a buffer that wants to share it with another process. + * + * if true, return 0 else negative. + */ +int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name) +{ + if (!bo->name) { + struct drm_gem_flink req = { + .handle = bo->handle, + }; + int ret; + + ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req); + if (ret) { + fprintf(stderr, "failed to get gem global name[%s].\n", + strerror(errno)); + return ret; + } + + bo->name = req.name; + } + + *name = bo->name; + + return 0; +} + +uint32_t exynos_bo_handle(struct exynos_bo *bo) +{ + return bo->handle; +} + +/* + * Mmap a buffer to user space. + * + * @bo: a exynos buffer object including a gem object handle to be mmapped + * to user space. + * + * if true, user pointer mmaped else NULL. + */ +void *exynos_bo_map(struct exynos_bo *bo) +{ + if (!bo->vaddr) { + struct exynos_device *dev = bo->dev; + struct drm_exynos_gem_mmap req = { + .handle = bo->handle, + .size = bo->size, + }; + int ret; + + ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_MMAP, &req); + if (ret) { + fprintf(stderr, "failed to mmap[%s].\n", + strerror(errno)); + return NULL; + } + + bo->vaddr = req.mapped; + } + + return bo->vaddr; +} + +/* + * Export gem object to dmabuf as file descriptor. + * + * @dev: a exynos device object. + * @handle: gem handle to be exported into dmabuf as file descriptor. + * @fd: file descriptor to dmabuf exported from gem handle and + * returned by kernel side. + * + * if true, return 0 else negative. + */ +int exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle, + int *fd) +{ + int ret; + struct drm_prime_handle req = { + .handle = handle, + }; + + ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req); + if (ret) { + fprintf(stderr, "failed to mmap[%s].\n", + strerror(errno)); + return ret; + } + + *fd = req.fd; + return 0; +} + +/* + * Import file descriptor into gem handle. + * + * @dev: a exynos device object. + * @fd: file descriptor exported into dmabuf. + * @handle: gem handle to gem object imported from file descriptor + * and returned by kernel side. + * + * if true, return 0 else negative. + */ +int exynos_prime_fd_to_handle(struct exynos_device *dev, int fd, + uint32_t *handle) +{ + int ret; + struct drm_prime_handle req = { + .fd = fd, + }; + + ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &req); + if (ret) { + fprintf(stderr, "failed to mmap[%s].\n", + strerror(errno)); + return ret; + } + + *handle = req.handle; + return 0; +} + + + +/* + * Request Wireless Display connection or disconnection. + * + * @dev: a exynos device object. + * @connect: indicate whether connectoin or disconnection request. + * @ext: indicate whether edid data includes extentions data or not. + * @edid: a pointer to edid data from Wireless Display device. + * + * this interface is used to request Virtual Display driver connection or + * disconnection. for this, user should get a edid data from the Wireless + * Display device and then send that data to kernel driver with connection + * request + * + * if true, return 0 else negative. + */ +int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect, + uint32_t ext, void *edid) +{ + struct drm_exynos_vidi_connection req = { + .connection = connect, + .extensions = ext, + .edid = edid, + }; + int ret; + + ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_VIDI_CONNECTION, &req); + if (ret) { + fprintf(stderr, "failed to request vidi connection[%s].\n", + strerror(errno)); + return ret; + } + + return 0; +} diff --git a/exynos/exynos_drm.h b/exynos/exynos_drm.h new file mode 100644 index 0000000..8786b92 --- /dev/null +++ b/exynos/exynos_drm.h @@ -0,0 +1,149 @@ +/* exynos_drm.h + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * Authors: + * Inki Dae inki.dae@samsung.com + * Joonyoung Shim jy0922.shim@samsung.com + * Seung-Woo Kim sw0312.kim@samsung.com + * + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 _EXYNOS_DRM_H_ +#define _EXYNOS_DRM_H_ + +#include "drm.h" + +/** + * User-desired buffer creation information structure. + * + * @size: user-desired memory allocation size. + * - this size value would be page-aligned internally. + * @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_exynos_gem_create { + uint64_t size; + unsigned int flags; + unsigned int 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_exynos_gem_map_off { + unsigned int handle; + unsigned int pad; + uint64_t offset; +}; + +/** + * A structure for mapping buffer. + * + * @handle: a handle to gem object created. + * @size: memory size to be mapped. + * @mapped: having user virtual address mmaped. + * - this variable would be filled by exynos gem module + * of kernel side with user virtual address which is allocated + * by do_mmap(). + */ +struct drm_exynos_gem_mmap { + unsigned int handle; + unsigned int size; + uint64_t mapped; +}; + +/** + * A structure to gem information. + * + * @handle: a handle to gem object created. + * @flags: flag value including memory type and cache attribute and + * this value would be set by driver. + * @size: size to memory region allocated by gem and this size would + * be set by driver. + */ +struct drm_exynos_gem_info { + unsigned int handle; + unsigned int flags; + uint64_t size; +}; + +/** + * A structure for user connection request of virtual display. + * + * @connection: indicate whether doing connetion or not by user. + * @extensions: if this value is 1 then the vidi driver would need additional + * 128bytes edid data. + * @edid: the edid data pointer from user side. + */ +struct drm_exynos_vidi_connection { + unsigned int connection; + unsigned int extensions; + uint64_t edid; +}; + +/* memory type definitions. */ +enum e_drm_exynos_gem_mem_type { + /* Physically Continuous memory and used as default. */ + EXYNOS_BO_CONTIG = 0 << 0, + /* Physically Non-Continuous memory. */ + EXYNOS_BO_NONCONTIG = 1 << 0, + /* non-cachable mapping and used as default. */ + EXYNOS_BO_NONCACHABLE = 0 << 1, + /* cachable mapping. */ + EXYNOS_BO_CACHABLE = 1 << 1, + /* write-combine mapping. */ + EXYNOS_BO_WC = 1 << 2, + EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG | EXYNOS_BO_CACHABLE | + EXYNOS_BO_WC +}; + +#define DRM_EXYNOS_GEM_CREATE 0x00 +#define DRM_EXYNOS_GEM_MAP_OFFSET 0x01 +#define DRM_EXYNOS_GEM_MMAP 0x02 +/* Reserved 0x04 ~ 0x05 for exynos specific gem ioctl */ +#define DRM_EXYNOS_GEM_GET 0x04 +#define DRM_EXYNOS_VIDI_CONNECTION 0x07 + +#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_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off) + +#define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap) + +#define DRM_IOCTL_EXYNOS_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_EXYNOS_GEM_USERPTR, struct drm_exynos_gem_userptr) + +#define DRM_IOCTL_EXYNOS_GEM_GET DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_EXYNOS_GEM_GET, struct drm_exynos_gem_info) + +#define DRM_IOCTL_EXYNOS_VIDI_CONNECTION DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection) + +#endif diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h new file mode 100644 index 0000000..7e8347a --- /dev/null +++ b/exynos/exynos_drmif.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co., Ltd. + * + * 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. + * + * Authors: + * Inki Dae inki.dae@samsung.com + */ + +#ifndef EXYNOS_DRMIF_H_ +#define EXYNOS_DRMIF_H_ + +#include <xf86drm.h> +#include <stdint.h> +#include "exynos_drm.h" + +struct exynos_device { + int fd; +}; + +/* + * Exynos Buffer Object structure. + * + * @dev: exynos device object allocated. + * @handle: a gem handle to gem object created. + * @flags: indicate memory allocation and cache attribute types. + * @fd: file descriptor exported into dmabuf. + * @size: size to the buffer created. + * @vaddr: user space address to a gem buffer mmaped. + * @name: a gem global handle from flink request. + */ +struct exynos_bo { + struct exynos_device *dev; + uint32_t handle; + uint32_t flags; + int fd; + size_t size; + void *vaddr; + uint32_t name; +}; + +/* + * device related functions: + */ +struct exynos_device * exynos_device_create(int fd); +void exynos_device_destroy(struct exynos_device *dev); + +/* + * buffer-object related functions: + */ +struct exynos_bo * exynos_bo_create(struct exynos_device *dev, + uint32_t size, uint32_t flags); +int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle, + size_t *size, uint32_t *flags); +void exynos_bo_destroy(struct exynos_bo *bo); +struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name); +int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name); +uint32_t exynos_bo_handle(struct exynos_bo *bo); +void * exynos_bo_map(struct exynos_bo *bo); +int exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle, + int *fd); +int exynos_prime_fd_to_handle(struct exynos_device *dev, int fd, + uint32_t *handle); + +/* + * Virtual Display related functions: + */ +int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect, + uint32_t ext, void *edid); + +#endif /* EXYNOS_DRMIF_H_ */ diff --git a/exynos/libdrm_exynos.pc b/exynos/libdrm_exynos.pc new file mode 100644 index 0000000..434dc3f --- /dev/null +++ b/exynos/libdrm_exynos.pc @@ -0,0 +1,11 @@ +prefix=/home/daeinki/project/share +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: libdrm_exynos +Description: Userspace interface to exynos kernel DRM services +Version: 0.6 +Libs: -L${libdir} -ldrm_exynos +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos +Requires.private: libdrm diff --git a/exynos/libdrm_exynos.pc.in b/exynos/libdrm_exynos.pc.in new file mode 100644 index 0000000..5ce9118 --- /dev/null +++ b/exynos/libdrm_exynos.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libdrm_exynos +Description: Userspace interface to exynos kernel DRM services +Version: 0.6 +Libs: -L${libdir} -ldrm_exynos +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos +Requires.private: libdrm diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 5784622..8012ecc 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -1099,7 +1099,7 @@ int main(int argc, char **argv) int c; int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0; int test_vsync = 0; - char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm" }; + char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" }; unsigned int i; int count = 0, plane_count = 0; struct connector con_args[2]; diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c index 903ca0f..4fccd59 100644 --- a/tests/vbltest/vbltest.c +++ b/tests/vbltest/vbltest.c @@ -103,7 +103,7 @@ static void usage(char *name) int main(int argc, char **argv) { int i, c, fd, ret; - char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx" }; + char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos" }; drmVBlank vbl; drmEventContext evctx; struct vbl_info handler_info;
Hi,
we had posted this patch and we hope this patch is applied to libdrm so that we can go ahead next work. as you may know, exynos drm driver have already been merged to mainline.
please, let me know if there is any problem.
Thanks, Inki Dae
2012/5/4 Inki Dae inki.dae@samsung.com:
this patch adds libdrm_exynos helper layer that inclues some intefaces for exynos specific gem and virtual display driver and also adds exynos module name to modtest and vbltest.
Changelog v2:
- fixed exynos broken ioctl.
the pointer of uint64_t *edid should be removed.
- removed unnecessary definitions.
- added drm prime interfaces.
this feature is used to share a buffer between drivers or memory managers and for this, please, refer to below links: http://www.mjmwired.net/kernel/Documentation/dma-buf-sharing.txt http://lwn.net/Articles/488664/
this patch is based on a link below: git://anongit.freedesktop.org/mesa/drm commit id: d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22
Reviewed-by: Rob Clark rob@ti.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Inki Dae inki.dae@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com
Makefile.am | 6 +- configure.ac | 13 ++ exynos/Makefile.am | 22 +++ exynos/exynos_drm.c | 396 ++++++++++++++++++++++++++++++++++++++++++++ exynos/exynos_drm.h | 149 +++++++++++++++++ exynos/exynos_drmif.h | 88 ++++++++++ exynos/libdrm_exynos.pc | 11 ++ exynos/libdrm_exynos.pc.in | 11 ++ tests/modetest/modetest.c | 2 +- tests/vbltest/vbltest.c | 2 +- 10 files changed, 697 insertions(+), 3 deletions(-) create mode 100644 exynos/Makefile.am create mode 100644 exynos/exynos_drm.c create mode 100644 exynos/exynos_drm.h create mode 100644 exynos/exynos_drmif.h create mode 100644 exynos/libdrm_exynos.pc create mode 100644 exynos/libdrm_exynos.pc.in
diff --git a/Makefile.am b/Makefile.am index 4f625a1..256a8cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,7 +45,11 @@ if HAVE_OMAP OMAP_SUBDIR = omap endif
-SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) tests include +if HAVE_EXYNOS +EXYNOS_SUBDIR = exynos +endif
+SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include
libdrm_la_LTLIBRARIES = libdrm.la libdrm_ladir = $(libdir) diff --git a/configure.ac b/configure.ac index 6a1d98e..f832201 100644 --- a/configure.ac +++ b/configure.ac @@ -88,6 +88,11 @@ AC_ARG_ENABLE(omap-experimental-api, [Enable support for OMAP's experimental API (default: disabled)]), [OMAP=$enableval], [OMAP=no])
+AC_ARG_ENABLE(exynos-experimental-api,
- AS_HELP_STRING([--enable-exynos-experimental-api],
- [Enable support for EXYNOS's experimental API (default: disabled)]),
- [EXYNOS=$enableval], [EXYNOS=no])
dnl =========================================================================== dnl check compiler flags AC_DEFUN([LIBDRM_CC_TRY_FLAG], [ @@ -191,6 +196,11 @@ if test "x$OMAP" = xyes; then AC_DEFINE(HAVE_OMAP, 1, [Have OMAP support]) fi
+AM_CONDITIONAL(HAVE_EXYNOS, [test "x$EXYNOS" = xyes]) +if test "x$EXYNOS" = xyes; then
- AC_DEFINE(HAVE_EXYNOS, 1, [Have EXYNOS support])
+fi
PKG_CHECK_MODULES(CAIRO, cairo, [HAVE_CAIRO=yes], [HAVE_CAIRO=no]) if test "x$HAVE_CAIRO" = xyes; then AC_DEFINE(HAVE_CAIRO, 1, [Have cairo support]) @@ -313,6 +323,8 @@ AC_CONFIG_FILES([ nouveau/libdrm_nouveau.pc omap/Makefile omap/libdrm_omap.pc
- exynos/Makefile
- exynos/libdrm_exynos.pc
tests/Makefile tests/modeprint/Makefile tests/modetest/Makefile @@ -333,4 +345,5 @@ echo " vmwgfx API $VMWGFX" echo " Radeon API $RADEON" echo " Nouveau API $NOUVEAU" echo " OMAP API $OMAP" +echo " EXYNOS API $EXYNOS" echo "" diff --git a/exynos/Makefile.am b/exynos/Makefile.am new file mode 100644 index 0000000..e782d34 --- /dev/null +++ b/exynos/Makefile.am @@ -0,0 +1,22 @@ +AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -I$(top_srcdir) \
- -I$(top_srcdir)/exynos \
- $(PTHREADSTUBS_CFLAGS) \
- -I$(top_srcdir)/include/drm
+libdrm_exynos_la_LTLIBRARIES = libdrm_exynos.la +libdrm_exynos_ladir = $(libdir) +libdrm_exynos_la_LDFLAGS = -version-number 1:0:0 -no-undefined +libdrm_exynos_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
+libdrm_exynos_la_SOURCES = exynos_drm.c
+libdrm_exynoscommonincludedir = ${includedir}/exynos +libdrm_exynoscommoninclude_HEADERS = exynos_drm.h
+libdrm_exynosincludedir = ${includedir}/libdrm +libdrm_exynosinclude_HEADERS = exynos_drmif.h
+pkgconfigdir = @pkgconfigdir@ +pkgconfig_DATA = libdrm_exynos.pc diff --git a/exynos/exynos_drm.c b/exynos/exynos_drm.c new file mode 100644 index 0000000..4db755e --- /dev/null +++ b/exynos/exynos_drm.c @@ -0,0 +1,396 @@ +/*
- Copyright (C) 2012 Samsung Electronics Co., Ltd.
- 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.
- Authors:
- Inki Dae inki.dae@samsung.com
- */
+#ifdef HAVE_CONFIG_H +#include "config.h" +#endif
+#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h>
+#include <sys/mman.h> +#include <linux/stddef.h>
+#include <xf86drm.h>
+#include "exynos_drm.h" +#include "exynos_drmif.h"
+/*
- Create exynos drm device object.
- @fd: file descriptor to exynos drm driver opened.
- if true, return the device object else NULL.
- */
+struct exynos_device * exynos_device_create(int fd) +{
- struct exynos_device *dev;
- dev = calloc(sizeof(*dev), 1);
- if (!dev) {
- fprintf(stderr, "failed to create device[%s].\n",
- strerror(errno));
- return NULL;
- }
- dev->fd = fd;
- return dev;
+}
+/*
- Destroy exynos drm device object
- @dev: exynos drm device object.
- */
+void exynos_device_destroy(struct exynos_device *dev) +{
- free(dev);
+}
+/*
- Create a exynos buffer object to exynos drm device.
- @dev: exynos drm device object.
- @size: user-desired size.
- flags: user-desired memory type.
- user can set one or more types among several types to memory
- allocation and cache attribute types. and as default,
- EXYNOS_BO_NONCONTIG and EXYNOS-BO_NONCACHABLE types would
- be used.
- if true, return a exynos buffer object else NULL.
- */
+struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
- size_t size, uint32_t flags)
+{
- struct exynos_bo *bo;
- struct drm_exynos_gem_create req = {
- .size = size,
- .flags = flags,
- };
- if (size == 0) {
- fprintf(stderr, "invalid size.\n");
- goto fail;
- }
- bo = calloc(sizeof(*bo), 1);
- if (!bo) {
- fprintf(stderr, "failed to create bo[%s].\n",
- strerror(errno));
- goto err_free_bo;
- }
- bo->dev = dev;
- if (drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_CREATE, &req)){
- fprintf(stderr, "failed to create gem object[%s].\n",
- strerror(errno));
- goto err_free_bo;
- }
- bo->handle = req.handle;
- bo->size = size;
- bo->flags = flags;
- return bo;
+err_free_bo:
- free(bo);
+fail:
- return NULL;
+}
+/*
- Get information to gem region allocated.
- @dev: exynos drm device object.
- @handle: gem handle to request gem info.
- @size: size to gem object and returned by kernel side.
- @flags: gem flags to gem object and returned by kernel side.
- with this function call, you can get flags and size to gem handle
- through bo object.
- if true, return 0 else negative.
- */
+int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle,
- size_t *size, uint32_t *flags)
+{
- int ret;
- struct drm_exynos_gem_info req = {
- .handle = handle,
- };
- ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_GET, &req);
- if (ret < 0) {
- fprintf(stderr, "failed to get gem object information[%s].\n",
- strerror(errno));
- return ret;
- }
- *size = req.size;
- *flags = req.flags;
- return 0;
+}
+/*
- Destroy a exynos buffer object.
- @bo: a exynos buffer object to be destroyed.
- */
+void exynos_bo_destroy(struct exynos_bo *bo) +{
- if (!bo)
- return;
- if (bo->vaddr)
- munmap(bo->vaddr, bo->size);
- if (bo->handle) {
- struct drm_gem_close req = {
- .handle = bo->handle,
- };
- drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
- }
- free(bo);
+}
+/*
- Get a exynos buffer object from a gem global object name.
- @dev: a exynos device object.
- @name: a gem global object name exported by another process.
- this interface is used to get a exynos buffer object from a gem
- global object name sent by another process for buffer sharing.
- if true, return a exynos buffer object else NULL.
- */
+struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name) +{
- struct exynos_bo *bo;
- struct drm_gem_open req = {
- .name = name,
- };
- bo = calloc(sizeof(*bo), 1);
- if (!bo) {
- fprintf(stderr, "failed to allocate bo[%s].\n",
- strerror(errno));
- return NULL;
- }
- if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) {
- fprintf(stderr, "failed to open gem object[%s].\n",
- strerror(errno));
- goto err_free_bo;
- }
- bo->dev = dev;
- bo->name = name;
- bo->handle = req.handle;
- return bo;
+err_free_bo:
- free(bo);
- return NULL;
+}
+/*
- Get a gem global object name from a gem object handle.
- @bo: a exynos buffer object including gem handle.
- @name: a gem global object name to be got by kernel driver.
- this interface is used to get a gem global object name from a gem object
- handle to a buffer that wants to share it with another process.
- if true, return 0 else negative.
- */
+int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name) +{
- if (!bo->name) {
- struct drm_gem_flink req = {
- .handle = bo->handle,
- };
- int ret;
- ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
- if (ret) {
- fprintf(stderr, "failed to get gem global name[%s].\n",
- strerror(errno));
- return ret;
- }
- bo->name = req.name;
- }
- *name = bo->name;
- return 0;
+}
+uint32_t exynos_bo_handle(struct exynos_bo *bo) +{
- return bo->handle;
+}
+/*
- Mmap a buffer to user space.
- @bo: a exynos buffer object including a gem object handle to be mmapped
- to user space.
- if true, user pointer mmaped else NULL.
- */
+void *exynos_bo_map(struct exynos_bo *bo) +{
- if (!bo->vaddr) {
- struct exynos_device *dev = bo->dev;
- struct drm_exynos_gem_mmap req = {
- .handle = bo->handle,
- .size = bo->size,
- };
- int ret;
- ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_MMAP, &req);
- if (ret) {
- fprintf(stderr, "failed to mmap[%s].\n",
- strerror(errno));
- return NULL;
- }
- bo->vaddr = req.mapped;
- }
- return bo->vaddr;
+}
+/*
- Export gem object to dmabuf as file descriptor.
- @dev: a exynos device object.
- @handle: gem handle to be exported into dmabuf as file descriptor.
- @fd: file descriptor to dmabuf exported from gem handle and
- returned by kernel side.
- if true, return 0 else negative.
- */
+int exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle,
- int *fd)
+{
- int ret;
- struct drm_prime_handle req = {
- .handle = handle,
- };
- ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req);
- if (ret) {
- fprintf(stderr, "failed to mmap[%s].\n",
- strerror(errno));
- return ret;
- }
- *fd = req.fd;
- return 0;
+}
+/*
- Import file descriptor into gem handle.
- @dev: a exynos device object.
- @fd: file descriptor exported into dmabuf.
- @handle: gem handle to gem object imported from file descriptor
- and returned by kernel side.
- if true, return 0 else negative.
- */
+int exynos_prime_fd_to_handle(struct exynos_device *dev, int fd,
- uint32_t *handle)
+{
- int ret;
- struct drm_prime_handle req = {
- .fd = fd,
- };
- ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &req);
- if (ret) {
- fprintf(stderr, "failed to mmap[%s].\n",
- strerror(errno));
- return ret;
- }
- *handle = req.handle;
- return 0;
+}
+/*
- Request Wireless Display connection or disconnection.
- @dev: a exynos device object.
- @connect: indicate whether connectoin or disconnection request.
- @ext: indicate whether edid data includes extentions data or not.
- @edid: a pointer to edid data from Wireless Display device.
- this interface is used to request Virtual Display driver connection or
- disconnection. for this, user should get a edid data from the Wireless
- Display device and then send that data to kernel driver with connection
- request
- if true, return 0 else negative.
- */
+int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
- uint32_t ext, void *edid)
+{
- struct drm_exynos_vidi_connection req = {
- .connection = connect,
- .extensions = ext,
- .edid = edid,
- };
- int ret;
- ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_VIDI_CONNECTION, &req);
- if (ret) {
- fprintf(stderr, "failed to request vidi connection[%s].\n",
- strerror(errno));
- return ret;
- }
- return 0;
+} diff --git a/exynos/exynos_drm.h b/exynos/exynos_drm.h new file mode 100644 index 0000000..8786b92 --- /dev/null +++ b/exynos/exynos_drm.h @@ -0,0 +1,149 @@ +/* exynos_drm.h
- Copyright (c) 2011 Samsung Electronics Co., Ltd.
- Authors:
- Inki Dae inki.dae@samsung.com
- Joonyoung Shim jy0922.shim@samsung.com
- Seung-Woo Kim sw0312.kim@samsung.com
- 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
- VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 _EXYNOS_DRM_H_ +#define _EXYNOS_DRM_H_
+#include "drm.h"
+/**
- User-desired buffer creation information structure.
- @size: user-desired memory allocation size.
- - this size value would be page-aligned internally.
- @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_exynos_gem_create {
- uint64_t size;
- unsigned int flags;
- unsigned int 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_exynos_gem_map_off {
- unsigned int handle;
- unsigned int pad;
- uint64_t offset;
+};
+/**
- A structure for mapping buffer.
- @handle: a handle to gem object created.
- @size: memory size to be mapped.
- @mapped: having user virtual address mmaped.
- - this variable would be filled by exynos gem module
- of kernel side with user virtual address which is allocated
- by do_mmap().
- */
+struct drm_exynos_gem_mmap {
- unsigned int handle;
- unsigned int size;
- uint64_t mapped;
+};
+/**
- A structure to gem information.
- @handle: a handle to gem object created.
- @flags: flag value including memory type and cache attribute and
- this value would be set by driver.
- @size: size to memory region allocated by gem and this size would
- be set by driver.
- */
+struct drm_exynos_gem_info {
- unsigned int handle;
- unsigned int flags;
- uint64_t size;
+};
+/**
- A structure for user connection request of virtual display.
- @connection: indicate whether doing connetion or not by user.
- @extensions: if this value is 1 then the vidi driver would need additional
- 128bytes edid data.
- @edid: the edid data pointer from user side.
- */
+struct drm_exynos_vidi_connection {
- unsigned int connection;
- unsigned int extensions;
- uint64_t edid;
+};
+/* memory type definitions. */ +enum e_drm_exynos_gem_mem_type {
- /* Physically Continuous memory and used as default. */
- EXYNOS_BO_CONTIG = 0 << 0,
- /* Physically Non-Continuous memory. */
- EXYNOS_BO_NONCONTIG = 1 << 0,
- /* non-cachable mapping and used as default. */
- EXYNOS_BO_NONCACHABLE = 0 << 1,
- /* cachable mapping. */
- EXYNOS_BO_CACHABLE = 1 << 1,
- /* write-combine mapping. */
- EXYNOS_BO_WC = 1 << 2,
- EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG | EXYNOS_BO_CACHABLE |
- EXYNOS_BO_WC
+};
+#define DRM_EXYNOS_GEM_CREATE 0x00 +#define DRM_EXYNOS_GEM_MAP_OFFSET 0x01 +#define DRM_EXYNOS_GEM_MMAP 0x02 +/* Reserved 0x04 ~ 0x05 for exynos specific gem ioctl */ +#define DRM_EXYNOS_GEM_GET 0x04 +#define DRM_EXYNOS_VIDI_CONNECTION 0x07
+#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_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off)
+#define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap)
+#define DRM_IOCTL_EXYNOS_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_USERPTR, struct drm_exynos_gem_userptr)
+#define DRM_IOCTL_EXYNOS_GEM_GET DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_GET, struct drm_exynos_gem_info)
+#define DRM_IOCTL_EXYNOS_VIDI_CONNECTION DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection)
+#endif diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h new file mode 100644 index 0000000..7e8347a --- /dev/null +++ b/exynos/exynos_drmif.h @@ -0,0 +1,88 @@ +/*
- Copyright (C) 2012 Samsung Electronics Co., Ltd.
- 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.
- Authors:
- Inki Dae inki.dae@samsung.com
- */
+#ifndef EXYNOS_DRMIF_H_ +#define EXYNOS_DRMIF_H_
+#include <xf86drm.h> +#include <stdint.h> +#include "exynos_drm.h"
+struct exynos_device {
- int fd;
+};
+/*
- Exynos Buffer Object structure.
- @dev: exynos device object allocated.
- @handle: a gem handle to gem object created.
- @flags: indicate memory allocation and cache attribute types.
- @fd: file descriptor exported into dmabuf.
- @size: size to the buffer created.
- @vaddr: user space address to a gem buffer mmaped.
- @name: a gem global handle from flink request.
- */
+struct exynos_bo {
- struct exynos_device *dev;
- uint32_t handle;
- uint32_t flags;
- int fd;
- size_t size;
- void *vaddr;
- uint32_t name;
+};
+/*
- device related functions:
- */
+struct exynos_device * exynos_device_create(int fd); +void exynos_device_destroy(struct exynos_device *dev);
+/*
- buffer-object related functions:
- */
+struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
- uint32_t size, uint32_t flags);
+int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle,
- size_t *size, uint32_t *flags);
+void exynos_bo_destroy(struct exynos_bo *bo); +struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name); +int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name); +uint32_t exynos_bo_handle(struct exynos_bo *bo); +void * exynos_bo_map(struct exynos_bo *bo); +int exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle,
- int *fd);
+int exynos_prime_fd_to_handle(struct exynos_device *dev, int fd,
- uint32_t *handle);
+/*
- Virtual Display related functions:
- */
+int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
- uint32_t ext, void *edid);
+#endif /* EXYNOS_DRMIF_H_ */ diff --git a/exynos/libdrm_exynos.pc b/exynos/libdrm_exynos.pc new file mode 100644 index 0000000..434dc3f --- /dev/null +++ b/exynos/libdrm_exynos.pc @@ -0,0 +1,11 @@ +prefix=/home/daeinki/project/share +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include
+Name: libdrm_exynos +Description: Userspace interface to exynos kernel DRM services +Version: 0.6 +Libs: -L${libdir} -ldrm_exynos +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos +Requires.private: libdrm diff --git a/exynos/libdrm_exynos.pc.in b/exynos/libdrm_exynos.pc.in new file mode 100644 index 0000000..5ce9118 --- /dev/null +++ b/exynos/libdrm_exynos.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@
+Name: libdrm_exynos +Description: Userspace interface to exynos kernel DRM services +Version: 0.6 +Libs: -L${libdir} -ldrm_exynos +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos +Requires.private: libdrm diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 5784622..8012ecc 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -1099,7 +1099,7 @@ int main(int argc, char **argv) int c; int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0; int test_vsync = 0;
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm" };
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" };
unsigned int i; int count = 0, plane_count = 0; struct connector con_args[2]; diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c index 903ca0f..4fccd59 100644 --- a/tests/vbltest/vbltest.c +++ b/tests/vbltest/vbltest.c @@ -103,7 +103,7 @@ static void usage(char *name) int main(int argc, char **argv) { int i, c, fd, ret;
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx" };
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos" };
drmVBlank vbl; drmEventContext evctx; struct vbl_info handler_info; -- 1.7.4.1
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Ok, I've pushed this with a couple minor cleanups:
1) remove .pc file (which is generated from .pc.in file) 2) below patch to fix a compile error (maybe not seen w/ older gcc?) 3) remove DRM_IOCTL_EXYNOS_GEM_USERPTR because I think that part is still being debated on kernel side.. it can be added back in another patch once there is a conclusion on the kernel side
--------- diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h index 7e8347a..92f613e 100644 --- a/exynos/exynos_drmif.h +++ b/exynos/exynos_drmif.h @@ -66,7 +66,7 @@ void exynos_device_destroy(struct exynos_device *dev); * buffer-object related functions: */ struct exynos_bo * exynos_bo_create(struct exynos_device *dev, - uint32_t size, uint32_t flags); + size_t size, uint32_t flags); int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle, size_t *size, uint32_t *flags); void exynos_bo_destroy(struct exynos_bo *bo); ---------
BR, -R
On Fri, May 4, 2012 at 5:13 AM, Inki Dae inki.dae@samsung.com wrote:
this patch adds libdrm_exynos helper layer that inclues some intefaces for exynos specific gem and virtual display driver and also adds exynos module name to modtest and vbltest.
Changelog v2:
- fixed exynos broken ioctl.
the pointer of uint64_t *edid should be removed.
- removed unnecessary definitions.
- added drm prime interfaces.
this feature is used to share a buffer between drivers or memory managers and for this, please, refer to below links: http://www.mjmwired.net/kernel/Documentation/dma-buf-sharing.txt http://lwn.net/Articles/488664/
this patch is based on a link below: git://anongit.freedesktop.org/mesa/drm commit id: d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22
Reviewed-by: Rob Clark rob@ti.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Inki Dae inki.dae@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com
Makefile.am | 6 +- configure.ac | 13 ++ exynos/Makefile.am | 22 +++ exynos/exynos_drm.c | 396 ++++++++++++++++++++++++++++++++++++++++++++ exynos/exynos_drm.h | 149 +++++++++++++++++ exynos/exynos_drmif.h | 88 ++++++++++ exynos/libdrm_exynos.pc | 11 ++ exynos/libdrm_exynos.pc.in | 11 ++ tests/modetest/modetest.c | 2 +- tests/vbltest/vbltest.c | 2 +- 10 files changed, 697 insertions(+), 3 deletions(-) create mode 100644 exynos/Makefile.am create mode 100644 exynos/exynos_drm.c create mode 100644 exynos/exynos_drm.h create mode 100644 exynos/exynos_drmif.h create mode 100644 exynos/libdrm_exynos.pc create mode 100644 exynos/libdrm_exynos.pc.in
diff --git a/Makefile.am b/Makefile.am index 4f625a1..256a8cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,7 +45,11 @@ if HAVE_OMAP OMAP_SUBDIR = omap endif
-SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) tests include +if HAVE_EXYNOS +EXYNOS_SUBDIR = exynos +endif
+SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include
libdrm_la_LTLIBRARIES = libdrm.la libdrm_ladir = $(libdir) diff --git a/configure.ac b/configure.ac index 6a1d98e..f832201 100644 --- a/configure.ac +++ b/configure.ac @@ -88,6 +88,11 @@ AC_ARG_ENABLE(omap-experimental-api, [Enable support for OMAP's experimental API (default: disabled)]), [OMAP=$enableval], [OMAP=no])
+AC_ARG_ENABLE(exynos-experimental-api,
- AS_HELP_STRING([--enable-exynos-experimental-api],
- [Enable support for EXYNOS's experimental API (default: disabled)]),
- [EXYNOS=$enableval], [EXYNOS=no])
dnl =========================================================================== dnl check compiler flags AC_DEFUN([LIBDRM_CC_TRY_FLAG], [ @@ -191,6 +196,11 @@ if test "x$OMAP" = xyes; then AC_DEFINE(HAVE_OMAP, 1, [Have OMAP support]) fi
+AM_CONDITIONAL(HAVE_EXYNOS, [test "x$EXYNOS" = xyes]) +if test "x$EXYNOS" = xyes; then
- AC_DEFINE(HAVE_EXYNOS, 1, [Have EXYNOS support])
+fi
PKG_CHECK_MODULES(CAIRO, cairo, [HAVE_CAIRO=yes], [HAVE_CAIRO=no]) if test "x$HAVE_CAIRO" = xyes; then AC_DEFINE(HAVE_CAIRO, 1, [Have cairo support]) @@ -313,6 +323,8 @@ AC_CONFIG_FILES([ nouveau/libdrm_nouveau.pc omap/Makefile omap/libdrm_omap.pc
- exynos/Makefile
- exynos/libdrm_exynos.pc
tests/Makefile tests/modeprint/Makefile tests/modetest/Makefile @@ -333,4 +345,5 @@ echo " vmwgfx API $VMWGFX" echo " Radeon API $RADEON" echo " Nouveau API $NOUVEAU" echo " OMAP API $OMAP" +echo " EXYNOS API $EXYNOS" echo "" diff --git a/exynos/Makefile.am b/exynos/Makefile.am new file mode 100644 index 0000000..e782d34 --- /dev/null +++ b/exynos/Makefile.am @@ -0,0 +1,22 @@ +AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -I$(top_srcdir) \
- -I$(top_srcdir)/exynos \
- $(PTHREADSTUBS_CFLAGS) \
- -I$(top_srcdir)/include/drm
+libdrm_exynos_la_LTLIBRARIES = libdrm_exynos.la +libdrm_exynos_ladir = $(libdir) +libdrm_exynos_la_LDFLAGS = -version-number 1:0:0 -no-undefined +libdrm_exynos_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
+libdrm_exynos_la_SOURCES = exynos_drm.c
+libdrm_exynoscommonincludedir = ${includedir}/exynos +libdrm_exynoscommoninclude_HEADERS = exynos_drm.h
+libdrm_exynosincludedir = ${includedir}/libdrm +libdrm_exynosinclude_HEADERS = exynos_drmif.h
+pkgconfigdir = @pkgconfigdir@ +pkgconfig_DATA = libdrm_exynos.pc diff --git a/exynos/exynos_drm.c b/exynos/exynos_drm.c new file mode 100644 index 0000000..4db755e --- /dev/null +++ b/exynos/exynos_drm.c @@ -0,0 +1,396 @@ +/*
- Copyright (C) 2012 Samsung Electronics Co., Ltd.
- 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.
- Authors:
- Inki Dae inki.dae@samsung.com
- */
+#ifdef HAVE_CONFIG_H +#include "config.h" +#endif
+#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h>
+#include <sys/mman.h> +#include <linux/stddef.h>
+#include <xf86drm.h>
+#include "exynos_drm.h" +#include "exynos_drmif.h"
+/*
- Create exynos drm device object.
- @fd: file descriptor to exynos drm driver opened.
- if true, return the device object else NULL.
- */
+struct exynos_device * exynos_device_create(int fd) +{
- struct exynos_device *dev;
- dev = calloc(sizeof(*dev), 1);
- if (!dev) {
- fprintf(stderr, "failed to create device[%s].\n",
- strerror(errno));
- return NULL;
- }
- dev->fd = fd;
- return dev;
+}
+/*
- Destroy exynos drm device object
- @dev: exynos drm device object.
- */
+void exynos_device_destroy(struct exynos_device *dev) +{
- free(dev);
+}
+/*
- Create a exynos buffer object to exynos drm device.
- @dev: exynos drm device object.
- @size: user-desired size.
- flags: user-desired memory type.
- user can set one or more types among several types to memory
- allocation and cache attribute types. and as default,
- EXYNOS_BO_NONCONTIG and EXYNOS-BO_NONCACHABLE types would
- be used.
- if true, return a exynos buffer object else NULL.
- */
+struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
- size_t size, uint32_t flags)
+{
- struct exynos_bo *bo;
- struct drm_exynos_gem_create req = {
- .size = size,
- .flags = flags,
- };
- if (size == 0) {
- fprintf(stderr, "invalid size.\n");
- goto fail;
- }
- bo = calloc(sizeof(*bo), 1);
- if (!bo) {
- fprintf(stderr, "failed to create bo[%s].\n",
- strerror(errno));
- goto err_free_bo;
- }
- bo->dev = dev;
- if (drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_CREATE, &req)){
- fprintf(stderr, "failed to create gem object[%s].\n",
- strerror(errno));
- goto err_free_bo;
- }
- bo->handle = req.handle;
- bo->size = size;
- bo->flags = flags;
- return bo;
+err_free_bo:
- free(bo);
+fail:
- return NULL;
+}
+/*
- Get information to gem region allocated.
- @dev: exynos drm device object.
- @handle: gem handle to request gem info.
- @size: size to gem object and returned by kernel side.
- @flags: gem flags to gem object and returned by kernel side.
- with this function call, you can get flags and size to gem handle
- through bo object.
- if true, return 0 else negative.
- */
+int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle,
- size_t *size, uint32_t *flags)
+{
- int ret;
- struct drm_exynos_gem_info req = {
- .handle = handle,
- };
- ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_GET, &req);
- if (ret < 0) {
- fprintf(stderr, "failed to get gem object information[%s].\n",
- strerror(errno));
- return ret;
- }
- *size = req.size;
- *flags = req.flags;
- return 0;
+}
+/*
- Destroy a exynos buffer object.
- @bo: a exynos buffer object to be destroyed.
- */
+void exynos_bo_destroy(struct exynos_bo *bo) +{
- if (!bo)
- return;
- if (bo->vaddr)
- munmap(bo->vaddr, bo->size);
- if (bo->handle) {
- struct drm_gem_close req = {
- .handle = bo->handle,
- };
- drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
- }
- free(bo);
+}
+/*
- Get a exynos buffer object from a gem global object name.
- @dev: a exynos device object.
- @name: a gem global object name exported by another process.
- this interface is used to get a exynos buffer object from a gem
- global object name sent by another process for buffer sharing.
- if true, return a exynos buffer object else NULL.
- */
+struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name) +{
- struct exynos_bo *bo;
- struct drm_gem_open req = {
- .name = name,
- };
- bo = calloc(sizeof(*bo), 1);
- if (!bo) {
- fprintf(stderr, "failed to allocate bo[%s].\n",
- strerror(errno));
- return NULL;
- }
- if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) {
- fprintf(stderr, "failed to open gem object[%s].\n",
- strerror(errno));
- goto err_free_bo;
- }
- bo->dev = dev;
- bo->name = name;
- bo->handle = req.handle;
- return bo;
+err_free_bo:
- free(bo);
- return NULL;
+}
+/*
- Get a gem global object name from a gem object handle.
- @bo: a exynos buffer object including gem handle.
- @name: a gem global object name to be got by kernel driver.
- this interface is used to get a gem global object name from a gem object
- handle to a buffer that wants to share it with another process.
- if true, return 0 else negative.
- */
+int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name) +{
- if (!bo->name) {
- struct drm_gem_flink req = {
- .handle = bo->handle,
- };
- int ret;
- ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
- if (ret) {
- fprintf(stderr, "failed to get gem global name[%s].\n",
- strerror(errno));
- return ret;
- }
- bo->name = req.name;
- }
- *name = bo->name;
- return 0;
+}
+uint32_t exynos_bo_handle(struct exynos_bo *bo) +{
- return bo->handle;
+}
+/*
- Mmap a buffer to user space.
- @bo: a exynos buffer object including a gem object handle to be mmapped
- to user space.
- if true, user pointer mmaped else NULL.
- */
+void *exynos_bo_map(struct exynos_bo *bo) +{
- if (!bo->vaddr) {
- struct exynos_device *dev = bo->dev;
- struct drm_exynos_gem_mmap req = {
- .handle = bo->handle,
- .size = bo->size,
- };
- int ret;
- ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_MMAP, &req);
- if (ret) {
- fprintf(stderr, "failed to mmap[%s].\n",
- strerror(errno));
- return NULL;
- }
- bo->vaddr = req.mapped;
- }
- return bo->vaddr;
+}
+/*
- Export gem object to dmabuf as file descriptor.
- @dev: a exynos device object.
- @handle: gem handle to be exported into dmabuf as file descriptor.
- @fd: file descriptor to dmabuf exported from gem handle and
- returned by kernel side.
- if true, return 0 else negative.
- */
+int exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle,
- int *fd)
+{
- int ret;
- struct drm_prime_handle req = {
- .handle = handle,
- };
- ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req);
- if (ret) {
- fprintf(stderr, "failed to mmap[%s].\n",
- strerror(errno));
- return ret;
- }
- *fd = req.fd;
- return 0;
+}
+/*
- Import file descriptor into gem handle.
- @dev: a exynos device object.
- @fd: file descriptor exported into dmabuf.
- @handle: gem handle to gem object imported from file descriptor
- and returned by kernel side.
- if true, return 0 else negative.
- */
+int exynos_prime_fd_to_handle(struct exynos_device *dev, int fd,
- uint32_t *handle)
+{
- int ret;
- struct drm_prime_handle req = {
- .fd = fd,
- };
- ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &req);
- if (ret) {
- fprintf(stderr, "failed to mmap[%s].\n",
- strerror(errno));
- return ret;
- }
- *handle = req.handle;
- return 0;
+}
+/*
- Request Wireless Display connection or disconnection.
- @dev: a exynos device object.
- @connect: indicate whether connectoin or disconnection request.
- @ext: indicate whether edid data includes extentions data or not.
- @edid: a pointer to edid data from Wireless Display device.
- this interface is used to request Virtual Display driver connection or
- disconnection. for this, user should get a edid data from the Wireless
- Display device and then send that data to kernel driver with connection
- request
- if true, return 0 else negative.
- */
+int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
- uint32_t ext, void *edid)
+{
- struct drm_exynos_vidi_connection req = {
- .connection = connect,
- .extensions = ext,
- .edid = edid,
- };
- int ret;
- ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_VIDI_CONNECTION, &req);
- if (ret) {
- fprintf(stderr, "failed to request vidi connection[%s].\n",
- strerror(errno));
- return ret;
- }
- return 0;
+} diff --git a/exynos/exynos_drm.h b/exynos/exynos_drm.h new file mode 100644 index 0000000..8786b92 --- /dev/null +++ b/exynos/exynos_drm.h @@ -0,0 +1,149 @@ +/* exynos_drm.h
- Copyright (c) 2011 Samsung Electronics Co., Ltd.
- Authors:
- Inki Dae inki.dae@samsung.com
- Joonyoung Shim jy0922.shim@samsung.com
- Seung-Woo Kim sw0312.kim@samsung.com
- 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
- VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 _EXYNOS_DRM_H_ +#define _EXYNOS_DRM_H_
+#include "drm.h"
+/**
- User-desired buffer creation information structure.
- @size: user-desired memory allocation size.
- - this size value would be page-aligned internally.
- @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_exynos_gem_create {
- uint64_t size;
- unsigned int flags;
- unsigned int 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_exynos_gem_map_off {
- unsigned int handle;
- unsigned int pad;
- uint64_t offset;
+};
+/**
- A structure for mapping buffer.
- @handle: a handle to gem object created.
- @size: memory size to be mapped.
- @mapped: having user virtual address mmaped.
- - this variable would be filled by exynos gem module
- of kernel side with user virtual address which is allocated
- by do_mmap().
- */
+struct drm_exynos_gem_mmap {
- unsigned int handle;
- unsigned int size;
- uint64_t mapped;
+};
+/**
- A structure to gem information.
- @handle: a handle to gem object created.
- @flags: flag value including memory type and cache attribute and
- this value would be set by driver.
- @size: size to memory region allocated by gem and this size would
- be set by driver.
- */
+struct drm_exynos_gem_info {
- unsigned int handle;
- unsigned int flags;
- uint64_t size;
+};
+/**
- A structure for user connection request of virtual display.
- @connection: indicate whether doing connetion or not by user.
- @extensions: if this value is 1 then the vidi driver would need additional
- 128bytes edid data.
- @edid: the edid data pointer from user side.
- */
+struct drm_exynos_vidi_connection {
- unsigned int connection;
- unsigned int extensions;
- uint64_t edid;
+};
+/* memory type definitions. */ +enum e_drm_exynos_gem_mem_type {
- /* Physically Continuous memory and used as default. */
- EXYNOS_BO_CONTIG = 0 << 0,
- /* Physically Non-Continuous memory. */
- EXYNOS_BO_NONCONTIG = 1 << 0,
- /* non-cachable mapping and used as default. */
- EXYNOS_BO_NONCACHABLE = 0 << 1,
- /* cachable mapping. */
- EXYNOS_BO_CACHABLE = 1 << 1,
- /* write-combine mapping. */
- EXYNOS_BO_WC = 1 << 2,
- EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG | EXYNOS_BO_CACHABLE |
- EXYNOS_BO_WC
+};
+#define DRM_EXYNOS_GEM_CREATE 0x00 +#define DRM_EXYNOS_GEM_MAP_OFFSET 0x01 +#define DRM_EXYNOS_GEM_MMAP 0x02 +/* Reserved 0x04 ~ 0x05 for exynos specific gem ioctl */ +#define DRM_EXYNOS_GEM_GET 0x04 +#define DRM_EXYNOS_VIDI_CONNECTION 0x07
+#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_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off)
+#define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap)
+#define DRM_IOCTL_EXYNOS_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_USERPTR, struct drm_exynos_gem_userptr)
+#define DRM_IOCTL_EXYNOS_GEM_GET DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_GET, struct drm_exynos_gem_info)
+#define DRM_IOCTL_EXYNOS_VIDI_CONNECTION DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection)
+#endif diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h new file mode 100644 index 0000000..7e8347a --- /dev/null +++ b/exynos/exynos_drmif.h @@ -0,0 +1,88 @@ +/*
- Copyright (C) 2012 Samsung Electronics Co., Ltd.
- 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.
- Authors:
- Inki Dae inki.dae@samsung.com
- */
+#ifndef EXYNOS_DRMIF_H_ +#define EXYNOS_DRMIF_H_
+#include <xf86drm.h> +#include <stdint.h> +#include "exynos_drm.h"
+struct exynos_device {
- int fd;
+};
+/*
- Exynos Buffer Object structure.
- @dev: exynos device object allocated.
- @handle: a gem handle to gem object created.
- @flags: indicate memory allocation and cache attribute types.
- @fd: file descriptor exported into dmabuf.
- @size: size to the buffer created.
- @vaddr: user space address to a gem buffer mmaped.
- @name: a gem global handle from flink request.
- */
+struct exynos_bo {
- struct exynos_device *dev;
- uint32_t handle;
- uint32_t flags;
- int fd;
- size_t size;
- void *vaddr;
- uint32_t name;
+};
+/*
- device related functions:
- */
+struct exynos_device * exynos_device_create(int fd); +void exynos_device_destroy(struct exynos_device *dev);
+/*
- buffer-object related functions:
- */
+struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
- uint32_t size, uint32_t flags);
+int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle,
- size_t *size, uint32_t *flags);
+void exynos_bo_destroy(struct exynos_bo *bo); +struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name); +int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name); +uint32_t exynos_bo_handle(struct exynos_bo *bo); +void * exynos_bo_map(struct exynos_bo *bo); +int exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle,
- int *fd);
+int exynos_prime_fd_to_handle(struct exynos_device *dev, int fd,
- uint32_t *handle);
+/*
- Virtual Display related functions:
- */
+int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
- uint32_t ext, void *edid);
+#endif /* EXYNOS_DRMIF_H_ */ diff --git a/exynos/libdrm_exynos.pc b/exynos/libdrm_exynos.pc new file mode 100644 index 0000000..434dc3f --- /dev/null +++ b/exynos/libdrm_exynos.pc @@ -0,0 +1,11 @@ +prefix=/home/daeinki/project/share +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include
+Name: libdrm_exynos +Description: Userspace interface to exynos kernel DRM services +Version: 0.6 +Libs: -L${libdir} -ldrm_exynos +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos +Requires.private: libdrm diff --git a/exynos/libdrm_exynos.pc.in b/exynos/libdrm_exynos.pc.in new file mode 100644 index 0000000..5ce9118 --- /dev/null +++ b/exynos/libdrm_exynos.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@
+Name: libdrm_exynos +Description: Userspace interface to exynos kernel DRM services +Version: 0.6 +Libs: -L${libdir} -ldrm_exynos +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos +Requires.private: libdrm diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 5784622..8012ecc 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -1099,7 +1099,7 @@ int main(int argc, char **argv) int c; int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0; int test_vsync = 0;
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm" };
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" };
unsigned int i; int count = 0, plane_count = 0; struct connector con_args[2]; diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c index 903ca0f..4fccd59 100644 --- a/tests/vbltest/vbltest.c +++ b/tests/vbltest/vbltest.c @@ -103,7 +103,7 @@ static void usage(char *name) int main(int argc, char **argv) { int i, c, fd, ret;
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx" };
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos" };
drmVBlank vbl; drmEventContext evctx; struct vbl_info handler_info; -- 1.7.4.1
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
2012. 5. 13. 오전 12:05 Rob Clark rob.clark@linaro.org 작성:
Ok, I've pushed this with a couple minor cleanups:
- remove .pc file (which is generated from .pc.in file)
- below patch to fix a compile error (maybe not seen w/ older gcc?)
- remove DRM_IOCTL_EXYNOS_GEM_USERPTR because I think that part is
still being debated on kernel side.. it can be added back in another patch once there is a conclusion on the kernel side
yes, right. I should have removed USERPTR ioctl but I missed it and also thank you for cleanup.
Thanks, Inki Dae
diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h index 7e8347a..92f613e 100644 --- a/exynos/exynos_drmif.h +++ b/exynos/exynos_drmif.h @@ -66,7 +66,7 @@ void exynos_device_destroy(struct exynos_device *dev);
- buffer-object related functions:
*/ struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
uint32_t size, uint32_t flags);
size_t size, uint32_t flags);
int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle, size_t *size, uint32_t *flags); void exynos_bo_destroy(struct exynos_bo *bo);
BR, -R
On Fri, May 4, 2012 at 5:13 AM, Inki Dae inki.dae@samsung.com wrote:
this patch adds libdrm_exynos helper layer that inclues some intefaces for exynos specific gem and virtual display driver and also adds exynos module name to modtest and vbltest.
Changelog v2:
- fixed exynos broken ioctl.
the pointer of uint64_t *edid should be removed.
- removed unnecessary definitions.
- added drm prime interfaces.
this feature is used to share a buffer between drivers or memory managers and for this, please, refer to below links: http://www.mjmwired.net/kernel/Documentation/dma-buf-sharing.txt http://lwn.net/Articles/488664/
this patch is based on a link below: git://anongit.freedesktop.org/mesa/drm commit id: d72a44c7c4f5eea9c1e5bb0c36cb9e0224b9ca22
Reviewed-by: Rob Clark rob@ti.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Inki Dae inki.dae@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@samsung.com
Makefile.am | 6 +- configure.ac | 13 ++ exynos/Makefile.am | 22 +++ exynos/exynos_drm.c | 396 ++++++++++++++++++++++++++++++++++++++++++++ exynos/exynos_drm.h | 149 +++++++++++++++++ exynos/exynos_drmif.h | 88 ++++++++++ exynos/libdrm_exynos.pc | 11 ++ exynos/libdrm_exynos.pc.in | 11 ++ tests/modetest/modetest.c | 2 +- tests/vbltest/vbltest.c | 2 +- 10 files changed, 697 insertions(+), 3 deletions(-) create mode 100644 exynos/Makefile.am create mode 100644 exynos/exynos_drm.c create mode 100644 exynos/exynos_drm.h create mode 100644 exynos/exynos_drmif.h create mode 100644 exynos/libdrm_exynos.pc create mode 100644 exynos/libdrm_exynos.pc.in
diff --git a/Makefile.am b/Makefile.am index 4f625a1..256a8cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,7 +45,11 @@ if HAVE_OMAP OMAP_SUBDIR = omap endif
-SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) tests include +if HAVE_EXYNOS +EXYNOS_SUBDIR = exynos +endif
+SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include
libdrm_la_LTLIBRARIES = libdrm.la libdrm_ladir = $(libdir) diff --git a/configure.ac b/configure.ac index 6a1d98e..f832201 100644 --- a/configure.ac +++ b/configure.ac @@ -88,6 +88,11 @@ AC_ARG_ENABLE(omap-experimental-api, [Enable support for OMAP's experimental API (default: disabled)]), [OMAP=$enableval], [OMAP=no])
+AC_ARG_ENABLE(exynos-experimental-api,
AS_HELP_STRING([--enable-exynos-experimental-api],
[Enable support for EXYNOS's experimental API (default: disabled)]),
[EXYNOS=$enableval], [EXYNOS=no])
dnl =========================================================================== dnl check compiler flags AC_DEFUN([LIBDRM_CC_TRY_FLAG], [ @@ -191,6 +196,11 @@ if test "x$OMAP" = xyes; then AC_DEFINE(HAVE_OMAP, 1, [Have OMAP support]) fi
+AM_CONDITIONAL(HAVE_EXYNOS, [test "x$EXYNOS" = xyes]) +if test "x$EXYNOS" = xyes; then
AC_DEFINE(HAVE_EXYNOS, 1, [Have EXYNOS support])
+fi
PKG_CHECK_MODULES(CAIRO, cairo, [HAVE_CAIRO=yes], [HAVE_CAIRO=no]) if test "x$HAVE_CAIRO" = xyes; then AC_DEFINE(HAVE_CAIRO, 1, [Have cairo support]) @@ -313,6 +323,8 @@ AC_CONFIG_FILES([ nouveau/libdrm_nouveau.pc omap/Makefile omap/libdrm_omap.pc
exynos/Makefile
exynos/libdrm_exynos.pc tests/Makefile tests/modeprint/Makefile tests/modetest/Makefile
@@ -333,4 +345,5 @@ echo " vmwgfx API $VMWGFX" echo " Radeon API $RADEON" echo " Nouveau API $NOUVEAU" echo " OMAP API $OMAP" +echo " EXYNOS API $EXYNOS" echo "" diff --git a/exynos/Makefile.am b/exynos/Makefile.am new file mode 100644 index 0000000..e782d34 --- /dev/null +++ b/exynos/Makefile.am @@ -0,0 +1,22 @@ +AM_CFLAGS = \
$(WARN_CFLAGS) \
-I$(top_srcdir) \
-I$(top_srcdir)/exynos \
$(PTHREADSTUBS_CFLAGS) \
-I$(top_srcdir)/include/drm
+libdrm_exynos_la_LTLIBRARIES = libdrm_exynos.la +libdrm_exynos_ladir = $(libdir) +libdrm_exynos_la_LDFLAGS = -version-number 1:0:0 -no-undefined +libdrm_exynos_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
+libdrm_exynos_la_SOURCES = exynos_drm.c
+libdrm_exynoscommonincludedir = ${includedir}/exynos +libdrm_exynoscommoninclude_HEADERS = exynos_drm.h
+libdrm_exynosincludedir = ${includedir}/libdrm +libdrm_exynosinclude_HEADERS = exynos_drmif.h
+pkgconfigdir = @pkgconfigdir@ +pkgconfig_DATA = libdrm_exynos.pc diff --git a/exynos/exynos_drm.c b/exynos/exynos_drm.c new file mode 100644 index 0000000..4db755e --- /dev/null +++ b/exynos/exynos_drm.c @@ -0,0 +1,396 @@ +/*
- Copyright (C) 2012 Samsung Electronics Co., Ltd.
- 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.
- Authors:
- Inki Dae inki.dae@samsung.com
- */
+#ifdef HAVE_CONFIG_H +#include "config.h" +#endif
+#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h>
+#include <sys/mman.h> +#include <linux/stddef.h>
+#include <xf86drm.h>
+#include "exynos_drm.h" +#include "exynos_drmif.h"
+/*
- Create exynos drm device object.
- @fd: file descriptor to exynos drm driver opened.
- if true, return the device object else NULL.
- */
+struct exynos_device * exynos_device_create(int fd) +{
struct exynos_device *dev;
dev = calloc(sizeof(*dev), 1);
if (!dev) {
fprintf(stderr, "failed to create device[%s].\n",
strerror(errno));
return NULL;
}
dev->fd = fd;
return dev;
+}
+/*
- Destroy exynos drm device object
- @dev: exynos drm device object.
- */
+void exynos_device_destroy(struct exynos_device *dev) +{
free(dev);
+}
+/*
- Create a exynos buffer object to exynos drm device.
- @dev: exynos drm device object.
- @size: user-desired size.
- flags: user-desired memory type.
user can set one or more types among several types to memory
allocation and cache attribute types. and as default,
EXYNOS_BO_NONCONTIG and EXYNOS-BO_NONCACHABLE types would
be used.
- if true, return a exynos buffer object else NULL.
- */
+struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
size_t size, uint32_t flags)
+{
struct exynos_bo *bo;
struct drm_exynos_gem_create req = {
.size = size,
.flags = flags,
};
if (size == 0) {
fprintf(stderr, "invalid size.\n");
goto fail;
}
bo = calloc(sizeof(*bo), 1);
if (!bo) {
fprintf(stderr, "failed to create bo[%s].\n",
strerror(errno));
goto err_free_bo;
}
bo->dev = dev;
if (drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_CREATE, &req)){
fprintf(stderr, "failed to create gem object[%s].\n",
strerror(errno));
goto err_free_bo;
}
bo->handle = req.handle;
bo->size = size;
bo->flags = flags;
return bo;
+err_free_bo:
free(bo);
+fail:
return NULL;
+}
+/*
- Get information to gem region allocated.
- @dev: exynos drm device object.
- @handle: gem handle to request gem info.
- @size: size to gem object and returned by kernel side.
- @flags: gem flags to gem object and returned by kernel side.
- with this function call, you can get flags and size to gem handle
- through bo object.
- if true, return 0 else negative.
- */
+int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle,
size_t *size, uint32_t *flags)
+{
int ret;
struct drm_exynos_gem_info req = {
.handle = handle,
};
ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_GET, &req);
if (ret < 0) {
fprintf(stderr, "failed to get gem object information[%s].\n",
strerror(errno));
return ret;
}
*size = req.size;
*flags = req.flags;
return 0;
+}
+/*
- Destroy a exynos buffer object.
- @bo: a exynos buffer object to be destroyed.
- */
+void exynos_bo_destroy(struct exynos_bo *bo) +{
if (!bo)
return;
if (bo->vaddr)
munmap(bo->vaddr, bo->size);
if (bo->handle) {
struct drm_gem_close req = {
.handle = bo->handle,
};
drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
}
free(bo);
+}
+/*
- Get a exynos buffer object from a gem global object name.
- @dev: a exynos device object.
- @name: a gem global object name exported by another process.
- this interface is used to get a exynos buffer object from a gem
- global object name sent by another process for buffer sharing.
- if true, return a exynos buffer object else NULL.
- */
+struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name) +{
struct exynos_bo *bo;
struct drm_gem_open req = {
.name = name,
};
bo = calloc(sizeof(*bo), 1);
if (!bo) {
fprintf(stderr, "failed to allocate bo[%s].\n",
strerror(errno));
return NULL;
}
if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) {
fprintf(stderr, "failed to open gem object[%s].\n",
strerror(errno));
goto err_free_bo;
}
bo->dev = dev;
bo->name = name;
bo->handle = req.handle;
return bo;
+err_free_bo:
free(bo);
return NULL;
+}
+/*
- Get a gem global object name from a gem object handle.
- @bo: a exynos buffer object including gem handle.
- @name: a gem global object name to be got by kernel driver.
- this interface is used to get a gem global object name from a gem object
- handle to a buffer that wants to share it with another process.
- if true, return 0 else negative.
- */
+int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name) +{
if (!bo->name) {
struct drm_gem_flink req = {
.handle = bo->handle,
};
int ret;
ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
if (ret) {
fprintf(stderr, "failed to get gem global name[%s].\n",
strerror(errno));
return ret;
}
bo->name = req.name;
}
*name = bo->name;
return 0;
+}
+uint32_t exynos_bo_handle(struct exynos_bo *bo) +{
return bo->handle;
+}
+/*
- Mmap a buffer to user space.
- @bo: a exynos buffer object including a gem object handle to be mmapped
to user space.
- if true, user pointer mmaped else NULL.
- */
+void *exynos_bo_map(struct exynos_bo *bo) +{
if (!bo->vaddr) {
struct exynos_device *dev = bo->dev;
struct drm_exynos_gem_mmap req = {
.handle = bo->handle,
.size = bo->size,
};
int ret;
ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_MMAP, &req);
if (ret) {
fprintf(stderr, "failed to mmap[%s].\n",
strerror(errno));
return NULL;
}
bo->vaddr = req.mapped;
}
return bo->vaddr;
+}
+/*
- Export gem object to dmabuf as file descriptor.
- @dev: a exynos device object.
- @handle: gem handle to be exported into dmabuf as file descriptor.
- @fd: file descriptor to dmabuf exported from gem handle and
returned by kernel side.
- if true, return 0 else negative.
- */
+int exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle,
int *fd)
+{
int ret;
struct drm_prime_handle req = {
.handle = handle,
};
ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req);
if (ret) {
fprintf(stderr, "failed to mmap[%s].\n",
strerror(errno));
return ret;
}
*fd = req.fd;
return 0;
+}
+/*
- Import file descriptor into gem handle.
- @dev: a exynos device object.
- @fd: file descriptor exported into dmabuf.
- @handle: gem handle to gem object imported from file descriptor
and returned by kernel side.
- if true, return 0 else negative.
- */
+int exynos_prime_fd_to_handle(struct exynos_device *dev, int fd,
uint32_t *handle)
+{
int ret;
struct drm_prime_handle req = {
.fd = fd,
};
ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &req);
if (ret) {
fprintf(stderr, "failed to mmap[%s].\n",
strerror(errno));
return ret;
}
*handle = req.handle;
return 0;
+}
+/*
- Request Wireless Display connection or disconnection.
- @dev: a exynos device object.
- @connect: indicate whether connectoin or disconnection request.
- @ext: indicate whether edid data includes extentions data or not.
- @edid: a pointer to edid data from Wireless Display device.
- this interface is used to request Virtual Display driver connection or
- disconnection. for this, user should get a edid data from the Wireless
- Display device and then send that data to kernel driver with connection
- request
- if true, return 0 else negative.
- */
+int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
uint32_t ext, void *edid)
+{
struct drm_exynos_vidi_connection req = {
.connection = connect,
.extensions = ext,
.edid = edid,
};
int ret;
ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_VIDI_CONNECTION, &req);
if (ret) {
fprintf(stderr, "failed to request vidi connection[%s].\n",
strerror(errno));
return ret;
}
return 0;
+} diff --git a/exynos/exynos_drm.h b/exynos/exynos_drm.h new file mode 100644 index 0000000..8786b92 --- /dev/null +++ b/exynos/exynos_drm.h @@ -0,0 +1,149 @@ +/* exynos_drm.h
- Copyright (c) 2011 Samsung Electronics Co., Ltd.
- Authors:
Inki Dae <inki.dae@samsung.com>
Joonyoung Shim <jy0922.shim@samsung.com>
Seung-Woo Kim <sw0312.kim@samsung.com>
- 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
- VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 _EXYNOS_DRM_H_ +#define _EXYNOS_DRM_H_
+#include "drm.h"
+/**
- User-desired buffer creation information structure.
- @size: user-desired memory allocation size.
- this size value would be page-aligned internally.
- @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_exynos_gem_create {
uint64_t size;
unsigned int flags;
unsigned int 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_exynos_gem_map_off {
unsigned int handle;
unsigned int pad;
uint64_t offset;
+};
+/**
- A structure for mapping buffer.
- @handle: a handle to gem object created.
- @size: memory size to be mapped.
- @mapped: having user virtual address mmaped.
- this variable would be filled by exynos gem module
of kernel side with user virtual address which is allocated
by do_mmap().
- */
+struct drm_exynos_gem_mmap {
unsigned int handle;
unsigned int size;
uint64_t mapped;
+};
+/**
- A structure to gem information.
- @handle: a handle to gem object created.
- @flags: flag value including memory type and cache attribute and
this value would be set by driver.
- @size: size to memory region allocated by gem and this size would
be set by driver.
- */
+struct drm_exynos_gem_info {
unsigned int handle;
unsigned int flags;
uint64_t size;
+};
+/**
- A structure for user connection request of virtual display.
- @connection: indicate whether doing connetion or not by user.
- @extensions: if this value is 1 then the vidi driver would need additional
128bytes edid data.
- @edid: the edid data pointer from user side.
- */
+struct drm_exynos_vidi_connection {
unsigned int connection;
unsigned int extensions;
uint64_t edid;
+};
+/* memory type definitions. */ +enum e_drm_exynos_gem_mem_type {
/* Physically Continuous memory and used as default. */
EXYNOS_BO_CONTIG = 0 << 0,
/* Physically Non-Continuous memory. */
EXYNOS_BO_NONCONTIG = 1 << 0,
/* non-cachable mapping and used as default. */
EXYNOS_BO_NONCACHABLE = 0 << 1,
/* cachable mapping. */
EXYNOS_BO_CACHABLE = 1 << 1,
/* write-combine mapping. */
EXYNOS_BO_WC = 1 << 2,
EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG | EXYNOS_BO_CACHABLE |
EXYNOS_BO_WC
+};
+#define DRM_EXYNOS_GEM_CREATE 0x00 +#define DRM_EXYNOS_GEM_MAP_OFFSET 0x01 +#define DRM_EXYNOS_GEM_MMAP 0x02 +/* Reserved 0x04 ~ 0x05 for exynos specific gem ioctl */ +#define DRM_EXYNOS_GEM_GET 0x04 +#define DRM_EXYNOS_VIDI_CONNECTION 0x07
+#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_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off)
+#define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap)
+#define DRM_IOCTL_EXYNOS_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_GEM_USERPTR, struct drm_exynos_gem_userptr)
+#define DRM_IOCTL_EXYNOS_GEM_GET DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_GEM_GET, struct drm_exynos_gem_info)
+#define DRM_IOCTL_EXYNOS_VIDI_CONNECTION DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection)
+#endif diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h new file mode 100644 index 0000000..7e8347a --- /dev/null +++ b/exynos/exynos_drmif.h @@ -0,0 +1,88 @@ +/*
- Copyright (C) 2012 Samsung Electronics Co., Ltd.
- 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.
- Authors:
- Inki Dae inki.dae@samsung.com
- */
+#ifndef EXYNOS_DRMIF_H_ +#define EXYNOS_DRMIF_H_
+#include <xf86drm.h> +#include <stdint.h> +#include "exynos_drm.h"
+struct exynos_device {
int fd;
+};
+/*
- Exynos Buffer Object structure.
- @dev: exynos device object allocated.
- @handle: a gem handle to gem object created.
- @flags: indicate memory allocation and cache attribute types.
- @fd: file descriptor exported into dmabuf.
- @size: size to the buffer created.
- @vaddr: user space address to a gem buffer mmaped.
- @name: a gem global handle from flink request.
- */
+struct exynos_bo {
struct exynos_device *dev;
uint32_t handle;
uint32_t flags;
int fd;
size_t size;
void *vaddr;
uint32_t name;
+};
+/*
- device related functions:
- */
+struct exynos_device * exynos_device_create(int fd); +void exynos_device_destroy(struct exynos_device *dev);
+/*
- buffer-object related functions:
- */
+struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
uint32_t size, uint32_t flags);
+int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle,
size_t *size, uint32_t *flags);
+void exynos_bo_destroy(struct exynos_bo *bo); +struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t name); +int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name); +uint32_t exynos_bo_handle(struct exynos_bo *bo); +void * exynos_bo_map(struct exynos_bo *bo); +int exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle,
int *fd);
+int exynos_prime_fd_to_handle(struct exynos_device *dev, int fd,
uint32_t *handle);
+/*
- Virtual Display related functions:
- */
+int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
uint32_t ext, void *edid);
+#endif /* EXYNOS_DRMIF_H_ */ diff --git a/exynos/libdrm_exynos.pc b/exynos/libdrm_exynos.pc new file mode 100644 index 0000000..434dc3f --- /dev/null +++ b/exynos/libdrm_exynos.pc @@ -0,0 +1,11 @@ +prefix=/home/daeinki/project/share +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include
+Name: libdrm_exynos +Description: Userspace interface to exynos kernel DRM services +Version: 0.6 +Libs: -L${libdir} -ldrm_exynos +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos +Requires.private: libdrm diff --git a/exynos/libdrm_exynos.pc.in b/exynos/libdrm_exynos.pc.in new file mode 100644 index 0000000..5ce9118 --- /dev/null +++ b/exynos/libdrm_exynos.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@
+Name: libdrm_exynos +Description: Userspace interface to exynos kernel DRM services +Version: 0.6 +Libs: -L${libdir} -ldrm_exynos +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/exynos +Requires.private: libdrm diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 5784622..8012ecc 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -1099,7 +1099,7 @@ int main(int argc, char **argv) int c; int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0; int test_vsync = 0;
char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm" };
char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" }; unsigned int i; int count = 0, plane_count = 0; struct connector con_args[2];
diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c index 903ca0f..4fccd59 100644 --- a/tests/vbltest/vbltest.c +++ b/tests/vbltest/vbltest.c @@ -103,7 +103,7 @@ static void usage(char *name) int main(int argc, char **argv) { int i, c, fd, ret;
char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx" };
char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos" }; drmVBlank vbl; drmEventContext evctx; struct vbl_info handler_info;
-- 1.7.4.1
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
dri-devel@lists.freedesktop.org