Fixes to Vivante BO on the resource leak and locking issues Fix stuck issue while the app quit with "ctrl+c". Upstream-Status: Pending Signed-off-by: Yong Gan <yong.gan@nxp.com> Signed-off-by: Prabhu Sundararaj <prabhu.sundararaj@nxp.com>
diff --git a/include/drm/vivante_drm.h b/include/drm/vivante_drm.h index 29c7f27..b457372 100644 --- a/include/drm/vivante_drm.h +++ b/include/drm/vivante_drm.h
@@ -1,18 +1,30 @@ -/* - * Copyright © 2017 VIVANTE Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - */ +/**************************************************************************** +* +* Copyright 2012 - 2017 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* 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, sub license, 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 NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE 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 __VIVNATE_DRM_H__ #define __VIVNATE_DRM_H__ @@ -23,23 +35,33 @@ extern "C" { #endif +/* creation flag bits. */ +#define DRM_VIV_GEM_CONTIGUOUS 0x01 +#define DRM_VIV_GEM_CACHED 0x02 +#define DRM_VIV_GEM_SECURE 0x04 + struct drm_viv_gem_create { - __u64 size; /* in */ - __u32 flags; /* in */ - __u32 handle; /* out */ + __u64 size; + __u32 flags; + __u32 handle; }; struct drm_viv_gem_lock { __u32 handle; __u32 cacheable; - __u32 gpu_va; - __u64 cpu_va; + __u64 logical; }; struct drm_viv_gem_unlock { __u32 handle; }; + +#define DRM_VIV_GEM_CLEAN_CACHE 0x01 +#define DRM_VIV_GEM_INVALIDATE_CACHE 0x02 +#define DRM_VIV_GEM_FLUSH_CACHE 0x03 +#define DRM_VIV_GEM_MEMORY_BARRIER 0x04 + struct drm_viv_gem_cache { __u32 handle; __u32 op; @@ -47,24 +69,98 @@ __u64 bytes; }; -struct drm_viv_gem_getinfo { + +#define DRM_VIV_GEM_PARAM_POOL 0x00 +#define DRM_VIV_GEM_PARAM_SIZE 0x01 + +struct drm_viv_gem_query { __u32 handle; __u32 param; __u64 value; }; + +struct drm_viv_gem_timestamp { + __u32 handle; + /* inc count, 0 for query current. */ + __u32 inc; + /* output inc'ed timestamp. */ + __u64 timestamp; +}; + + +/* basic tiling mode. */ +#define DRM_VIV_GEM_TILING_LINEAR 0x01 +#define DRM_VIV_GEM_TILING_TILED 0x02 +#define DRM_VIV_GEM_TILING_SUPERTILED 0x04 +#define DRM_VIV_GEM_TILING_MINORTILED 0x08 + +/* tiling mode modifiers. */ +#define DRM_VIV_GEM_TILING_SPLIT 0x10 +#define DRM_VIV_GEM_TILING_X_MAJOR 0x20 +#define DRM_VIV_GEM_TILING_Y_MAJOR 0x40 +#define DRM_VIV_GEM_TILING_SWAP 0x80 + +/* ts mode. */ +#define DRM_VIV_GEM_TS_NONE 0x00 +#define DRM_VIV_GEM_TS_DISABLED 0x01 +#define DRM_VIV_GEM_TS_NORMAL 0x02 +#define DRM_VIV_GEM_TS_COMPRESSED 0x03 + +struct drm_viv_gem_set_tiling { + __u32 handle; + __u32 tiling_mode; + + __u32 ts_mode; + __u64 clear_value; +}; + +struct drm_viv_gem_get_tiling { + __u32 handle; + __u32 tiling_mode; + + __u32 ts_mode; + __u64 clear_value; +}; + + +struct drm_viv_gem_attach_aux { + __u32 handle; + __u32 ts_handle; +}; + + +struct drm_viv_gem_ref_node { + __u32 handle; + + /* output. */ + __u32 node; + __u32 ts_node; +}; + + #define DRM_VIV_GEM_CREATE 0x00 #define DRM_VIV_GEM_LOCK 0x01 #define DRM_VIV_GEM_UNLOCK 0x02 #define DRM_VIV_GEM_CACHE 0x03 -#define DRM_VIV_GEM_GETINFO 0x04 -#define DRM_VIV_NUM_IOCTLS 0x05 +#define DRM_VIV_GEM_QUERY 0x04 +#define DRM_VIV_GEM_TIMESTAMP 0x05 +#define DRM_VIV_GEM_SET_TILING 0x06 +#define DRM_VIV_GEM_GET_TILING 0x07 +#define DRM_VIV_GEM_ATTACH_AUX 0x08 +#define DRM_VIV_GEM_REF_NODE 0x09 +#define DRM_VIV_NUM_IOCTLS 0x0A -#define DRM_IOCTL_VIV_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_CREATE, struct drm_viv_gem_create) -#define DRM_IOCTL_VIV_GEM_LOCK DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_LOCK, struct drm_viv_gem_lock) -#define DRM_IOCTL_VIV_GEM_UNLOCK DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_UNLOCK, struct drm_viv_gem_unlock) -#define DRM_IOCTL_VIV_GEM_CACHE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_CACHE, struct drm_viv_gem_cache) -#define DRM_IOCTL_VIV_GEM_GETINFO DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_GETINFO, struct drm_viv_gem_getinfo) +#define DRM_IOCTL_VIV_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_CREATE, struct drm_viv_gem_create) +#define DRM_IOCTL_VIV_GEM_LOCK DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_LOCK, struct drm_viv_gem_lock) +#define DRM_IOCTL_VIV_GEM_UNLOCK DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_UNLOCK, struct drm_viv_gem_unlock) +#define DRM_IOCTL_VIV_GEM_CACHE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_CACHE, struct drm_viv_gem_cache) +#define DRM_IOCTL_VIV_GEM_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_QUERY, struct drm_viv_gem_query) +#define DRM_IOCTL_VIV_GEM_TIMESTAMP DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_TIMESTAMP, struct drm_viv_gem_timestamp) +#define DRM_IOCTL_VIV_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_SET_TILING, struct drm_viv_gem_set_tiling) +#define DRM_IOCTL_VIV_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_GET_TILING, struct drm_viv_gem_get_tiling) +#define DRM_IOCTL_VIV_GEM_ATTACH_AUX DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_ATTACH_AUX, struct drm_viv_gem_attach_aux) +#define DRM_IOCTL_VIV_GEM_REF_NODE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_REF_NODE, struct drm_viv_gem_ref_node) #if defined(__cplusplus) }
diff --git a/tests/vivante/Makefile.am b/tests/vivante/Makefile.am index 8a0dedb..693a922 100644 --- a/tests/vivante/Makefile.am +++ b/tests/vivante/Makefile.am
@@ -1,3 +1,29 @@ +############################################################################## +# +# Copyright 2012 - 2017 Vivante Corporation, Santa Clara, California. +# All Rights Reserved. +# +# 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, sub license, 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 NON-INFRINGEMENT. +# IN NO EVENT SHALL VIVANTE 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. +# +############################################################################## AM_CFLAGS = \ -pthread \ $(WARN_CFLAGS) \
diff --git a/tests/vivante/viv_bo_test.c b/tests/vivante/viv_bo_test.c index aa21af3..4e9b066 100644 --- a/tests/vivante/viv_bo_test.c +++ b/tests/vivante/viv_bo_test.c
@@ -1,3 +1,31 @@ +/**************************************************************************** +* +* Copyright 2012 - 2017 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* 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, sub license, 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 NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE 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. +* +*****************************************************************************/ + + /* * Copyright © 2015 Canonical Ltd. (Maarten Lankhorst) * @@ -33,89 +61,97 @@ #include <pthread.h> #include "xf86drm.h" -#include "vivante.h" +#include "vivante_bo.h" -static int import_fd; +static int import_fd = -1; static void * openclose(void *dev) { - int fd = (intptr_t)dev; - uint32_t bo_handle; - int i; + struct drm_vivante *drm = dev; + struct drm_vivante_bo *bo; + int i; - for (i = 0; i < 100000; ++i) { - if (!drmPrimeFDToHandle(fd, import_fd, &bo_handle)) - drm_vivante_bo_destroy(fd, bo_handle); - } - return NULL; + for (i = 0; i < 100000; ++i) { + if (!drm_vivante_bo_import_from_fd(drm, import_fd, &bo)) + drm_vivante_bo_destroy(bo); + } + return NULL; } int main(int argc, char *argv[]) { - drmVersionPtr version; - const char *device = NULL; - int err, fd1, fd2; - uint32_t bo_handle; - pthread_t t1, t2; + drmVersionPtr version; + const char *device = NULL; + int err, fd1, fd2; + struct drm_vivante *drm1, *drm2; + struct drm_vivante_bo *bo; + pthread_t t1, t2; - if (argc < 2) { - fd1 = drmOpenWithType("vivante", NULL, DRM_NODE_RENDER); - if (fd1 >= 0) - fd2 = drmOpenWithType("vivante", NULL, DRM_NODE_RENDER); - } else { - device = argv[1]; + if (argc < 2) { + fd1 = drmOpenWithType("vivante", NULL, DRM_NODE_RENDER); + if (fd1 >= 0) + fd2 = drmOpenWithType("vivante", NULL, DRM_NODE_RENDER); + } else { + device = argv[1]; - fd1 = open(device, O_RDWR); - if (fd1 >= 0) - fd2 = open(device, O_RDWR); - else - fd2 = fd1 = -errno; - } + fd1 = open(device, O_RDWR); + if (fd1 >= 0) + fd2 = open(device, O_RDWR); + else + fd2 = fd1 = -errno; + } - if (fd1 < 0) { - fprintf(stderr, "Opening 1st vivante render node failed with %i\n", fd1); - return device ? -fd1 : 77; - } + if (fd1 < 0) { + fprintf(stderr, "Opening 1st vivante render node failed with %i\n", fd1); + return device ? -fd1 : 77; + } - if (fd2 < 0) { - fprintf(stderr, "Opening 2nd vivante render node failed with %i\n", -errno); - return errno; - } + if (fd2 < 0) { + fprintf(stderr, "Opening 2nd vivante render node failed with %i\n", -errno); + return errno; + } - version = drmGetVersion(fd1); - if (version) { - printf("Version: %d.%d.%d\n", version->version_major, - version->version_minor, version->version_patchlevel); - printf(" Name: %s\n", version->name); - printf(" Date: %s\n", version->date); - printf(" Description: %s\n", version->desc); + version = drmGetVersion(fd1); + if (version) { + printf("Version: %d.%d.%d\n", version->version_major, + version->version_minor, version->version_patchlevel); + printf(" Name: %s\n", version->name); + printf(" Date: %s\n", version->date); + printf(" Description: %s\n", version->desc); - drmFreeVersion(version); - } + drmFreeVersion(version); + } - err = drm_vivante_bo_create(fd2, 0, 4096, &bo_handle); - if (!err) - err = drmPrimeHandleToFD(fd2, bo_handle, DRM_CLOEXEC, &import_fd); + err = drm_vivante_create(fd1, &drm1); + if (!err) + err = drm_vivante_create(fd2, &drm2); + if (err < 0) + return 1; - if (!err) { - pthread_create(&t1, NULL, openclose, (void*)(intptr_t)fd1); - pthread_create(&t2, NULL, openclose, (void*)(intptr_t)fd1); - } + err = drm_vivante_bo_create(drm2, 0, 1920*1080*4, &bo); + if (!err) + err = drm_vivante_bo_export_to_fd(bo, &import_fd); - pthread_join(t1, NULL); - pthread_join(t2, NULL); + if (!err) { + pthread_create(&t1, NULL, openclose, (void*)drm1); + pthread_create(&t2, NULL, openclose, (void*)drm1); + } - close(import_fd); - drm_vivante_bo_destroy(fd2, bo_handle); + pthread_join(t1, NULL); + pthread_join(t2, NULL); - if (device) { - close(fd2); - close(fd1); - } else { - drmClose(fd2); - drmClose(fd1); - } + drm_vivante_bo_destroy(bo); - return 0; + drm_vivante_close(drm2); + drm_vivante_close(drm1); + if (device) { + close(fd2); + close(fd1); + } else { + drmClose(fd2); + drmClose(fd1); + } + + return 0; }
diff --git a/vivante/Android.mk b/vivante/Android.mk index 234028a..ccb9a02 100644 --- a/vivante/Android.mk +++ b/vivante/Android.mk
@@ -1,11 +1,39 @@ +############################################################################## +# +# Copyright 2012 - 2017 Vivante Corporation, Santa Clara, California. +# All Rights Reserved. +# +# 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, sub license, 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 NON-INFRINGEMENT. +# IN NO EVENT SHALL VIVANTE 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. +# +############################################################################## + + LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) -LOCAL_MODULE := libdrm_vivante +LOCAL_SRC_FILES := vivante_bo.c + +LOCAL_CFLAGS := -Wno-unused-parameter LOCAL_SHARED_LIBRARIES := libdrm -LOCAL_SRC_FILES := vivante.c - -include $(LIBDRM_COMMON_MK) +LOCAL_MODULE := libdrm_vivante include $(BUILD_SHARED_LIBRARY)
diff --git a/vivante/Makefile.am b/vivante/Makefile.am index 8963bf0..cd4c73e 100644 --- a/vivante/Makefile.am +++ b/vivante/Makefile.am
@@ -1,3 +1,31 @@ +############################################################################## +# +# Copyright 2012 - 2017 Vivante Corporation, Santa Clara, California. +# All Rights Reserved. +# +# 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, sub license, 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 NON-INFRINGEMENT. +# IN NO EVENT SHALL VIVANTE 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. +# +############################################################################## + + AM_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/include/drm @@ -12,10 +40,10 @@ libdrm_vivante_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@ libdrm_vivante_la_SOURCES = \ - vivante.c + vivante_bo.c libdrm_vivanteincludedir = ${includedir}/libdrm -libdrm_vivanteinclude_HEADERS = vivante.h +libdrm_vivanteinclude_HEADERS = vivante_bo.h pkgconfigdir = @pkgconfigdir@ pkgconfig_DATA = libdrm_vivante.pc
diff --git a/vivante/libdrm_vivante.pc b/vivante/libdrm_vivante.pc new file mode 100644 index 0000000..474a33c --- /dev/null +++ b/vivante/libdrm_vivante.pc
@@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: libdrm_vivante +Description: Userspace interface to Vivante kernel DRM services +Version: 2.4.84 +Libs: -L${libdir} -ldrm_vivante +Cflags: -I${includedir} -I${includedir}/libdrm +Requires.private: libdrm
diff --git a/vivante/vivante-symbol-check b/vivante/vivante-symbol-check index 29c12a0..177bba9 100644 --- a/vivante/vivante-symbol-check +++ b/vivante/vivante-symbol-check
@@ -1,6 +1,6 @@ #!/bin/bash -# The following symbols (past the first nine) are taken from vivante.h. +# The following symbols (past the first nine) are taken from vivante_bo.h. FUNCS=$(nm -D --format=bsd --defined-only ${1-.libs/libdrm_vivante.so} | awk '{print $3}'| while read func; do ( grep -q "^$func$" || echo $func ) <<EOF @@ -14,10 +14,18 @@ _fini _init drm_vivante_bo_create +drm_vivante_bo_create_with_ts +drm_vivante_bo_export_to_fd +drm_vivante_bo_import_from_fd drm_vivante_bo_destroy -drm_vivante_bo_lock -drm_vivante_bo_unlock -drm_vivante_bo_cache -drm_vivante_bo_getinfo +drm_vivante_bo_get_handle +drm_vivante_bo_mmap +drm_vivante_bo_munmap +drm_vivante_bo_query +drm_vivante_bo_set_tiling +drm_vivante_bo_get_tiling +drm_vivante_bo_inc_timestamp +drm_vivante_bo_get_timestamp +drm_vivante_bo_ref_node EOF done)
diff --git a/vivante/vivante.c b/vivante/vivante.c deleted file mode 100644 index b82138c..0000000 --- a/vivante/vivante.c +++ /dev/null
@@ -1,145 +0,0 @@ -/* - * Copyright © 2012, 2013 Thierry Reding - * Copyright © 2013 Erik Faye-Lund - * Copyright © 2014 NVIDIA Corporation - * - * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <errno.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> - -#include <sys/mman.h> - -#include <xf86drm.h> - -#include <vivante_drm.h> - -#include "vivante.h" - -int drm_vivante_bo_create(int fd, uint32_t flags, uint32_t size, uint32_t *handle) -{ - struct drm_viv_gem_create args; - int err = 0; - - if (size == 0 || !handle) - return -EINVAL; - - memset(&args, 0, sizeof(args)); - args.flags = flags; - args.size = size; - - if (drmIoctl(fd, DRM_IOCTL_VIV_GEM_CREATE, &args)) - return -errno; - - *handle = args.handle; - - return 0; -} - -int drm_vivante_bo_destroy(int fd, uint32_t handle) -{ - struct drm_gem_close args; - - if (!handle) - return -EINVAL; - - args.handle = handle; - if (drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &args)) - return -errno; - - return 0; -} - -void* drm_vivante_bo_lock(int fd, uint32_t handle, uint32_t *gpu_va) -{ - struct drm_viv_gem_lock args; - - if (!handle) - return NULL; - - args.handle = handle; - args.cacheable = 0; - if (drmIoctl(fd, DRM_IOCTL_VIV_GEM_LOCK, &args)) - return NULL; - - if (gpu_va) - { - *gpu_va = args.gpu_va; - } - - return (void*)(intptr_t)args.cpu_va; -} - -int drm_vivante_bo_unlock(int fd, uint32_t handle) -{ - struct drm_viv_gem_unlock args; - - if (!handle) - return -EINVAL; - - args.handle = handle; - if (drmIoctl(fd, DRM_IOCTL_VIV_GEM_UNLOCK, &args)) - return -errno; - - return 0; -} - -int drm_vivante_bo_cache(int fd, uint32_t handle, uint32_t op, void* logical, uint32_t bytes) -{ - struct drm_viv_gem_cache args; - - if (!handle) - return -EINVAL; - - args.handle = handle; - args.op = handle; - args.logical = (uintptr_t)logical; - args.bytes = bytes; - if (drmIoctl(fd, DRM_IOCTL_VIV_GEM_CACHE, &args)) - return -errno; - - return 0; -} - -int drm_vivante_bo_getinfo(int fd, uint32_t handle, uint32_t param, uint64_t *value) -{ - struct drm_viv_gem_getinfo args; - - if (!handle) - return -EINVAL; - - args.handle = handle; - args.param = param; - if (drmIoctl(fd, DRM_IOCTL_VIV_GEM_GETINFO, &args)) - return -errno; - - *value = args.value; - - return 0; -} - - -
diff --git a/vivante/vivante.h b/vivante/vivante.h deleted file mode 100644 index 2492e5a..0000000 --- a/vivante/vivante.h +++ /dev/null
@@ -1,50 +0,0 @@ -/* - * Copyright © 2017 VIVANTE Corporation - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __DRM_VIVANTE_H__ -#define __DRM_VIVANTE_H__ 1 - -#include <stdint.h> -#include <stdlib.h> - -enum VIV_CACHE_OP { - VIV_CACHE_CLEAN = 0x01, - VIV_CACHE_INVALIDATE = 0x02, - VIV_CACHE_FLUSH = VIV_CACHE_CLEAN | VIV_CACHE_INVALIDATE, - VIV_CACHE_BARRIER = 0x04 -}; - -enum VIV_GEM_PARAM { - VIV_GEM_PARAM_NODE = 0, - VIV_GEM_PARAM_POOL, - VIV_GEM_PARAM_SIZE, -}; - -int drm_vivante_bo_create(int fd, uint32_t flags, uint32_t size, uint32_t *handle); -int drm_vivante_bo_destroy(int fd, uint32_t handle); -void* drm_vivante_bo_lock(int fd, uint32_t handle, uint32_t *gpu_va); -int drm_vivante_bo_unlock(int fd, uint32_t handle); -int drm_vivante_bo_cache(int fd, uint32_t handle, uint32_t op, void* logical, uint32_t bytes); -int drm_vivante_bo_getinfo(int fd, uint32_t handle, uint32_t param, uint64_t *value); - -#endif /* __DRM_VIVANTE_H__ */
diff --git a/vivante/vivante_bo.c b/vivante/vivante_bo.c new file mode 100644 index 0000000..fe74384 --- /dev/null +++ b/vivante/vivante_bo.c
@@ -0,0 +1,474 @@ +/**************************************************************************** +* +* Copyright 2012 - 2017 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* 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, sub license, 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 NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE 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. +* +*****************************************************************************/ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +#include <sys/mman.h> + +#include <xf86drm.h> + +#include <vivante_drm.h> + +#include "vivante_bo.h" + +struct drm_vivante +{ + /* driver fd. */ + int fd; +}; + +struct drm_vivante_bo +{ + struct drm_vivante *drm; + + uint32_t handle; + + /* export prime fd if any */ + int fd; + + uint32_t flags; + uint32_t size; + + void *vaddr; +}; + +int drm_vivante_create(int fd, struct drm_vivante **drmp) +{ + int supported = 0; + drmVersionPtr version; + struct drm_vivante *drm; + + version = drmGetVersion(fd); + if (!version) + return -ENOMEM; + + if (!strncmp(version->name, "vivante", version->name_len)) + supported = 1; + + drmFreeVersion(version); + + if (!supported) + return -ENOTSUP; + + drm = calloc(1, sizeof(struct drm_vivante)); + if (!drm) + return -ENOMEM; + + drm->fd = fd; + *drmp = drm; + + return 0; +} + +void drm_vivante_close(struct drm_vivante *drm) +{ + free(drm); +} + +static int drm_vivante_bo_init(struct drm_vivante *drm, + struct drm_vivante_bo **bop) +{ + struct drm_vivante_bo *bo; + + bo = calloc(1, sizeof(*bo)); + if (!bo) + return -ENOMEM; + + bo->drm = drm; + bo->fd = -1; + bo->vaddr = NULL; + + *bop = bo; + return 0; +} + +int drm_vivante_bo_create(struct drm_vivante *drm, + uint32_t flags, uint32_t size, struct drm_vivante_bo **bop) +{ + int err = 0; + struct drm_vivante_bo *bo; + struct drm_viv_gem_create args = { + .flags = flags, + .size = size + }; + + if (size == 0) + return -EINVAL; + + if (!drm || !bop) + return -EINVAL; + + err = drm_vivante_bo_init(drm, &bo); + if (err) { + return err; + } + + if (drmIoctl(drm->fd, DRM_IOCTL_VIV_GEM_CREATE, &args)) { + free(bo); + return -errno; + } + bo->handle = args.handle; + bo->flags = flags; + bo->size = size; + + *bop = bo; + return 0; +} + +int drm_vivante_bo_create_with_ts(struct drm_vivante *drm, + uint32_t flags, uint32_t size, struct drm_vivante_bo **bop) +{ + int err = 0; + uint32_t ts_handle = 0; + struct drm_vivante_bo *bo; + struct drm_viv_gem_create args = { + .flags = flags, + .size = size + }; + struct drm_gem_close close_args; + struct drm_viv_gem_attach_aux aux_args; + const uint32_t valid_ts_flags = DRM_VIV_GEM_CONTIGUOUS | DRM_VIV_GEM_SECURE; + + if (size == 0) + return -EINVAL; + + if (!drm || !bop) + return -EINVAL; + + err = drm_vivante_bo_init(drm, &bo); + if (err) + return err; + + if (drmIoctl(drm->fd, DRM_IOCTL_VIV_GEM_CREATE, &args)) { + err = -errno; + goto err_close; + } + bo->handle = args.handle; + + /* alloc ts handle, size is master buffer size / 256, align up to 64B. */ + args.flags = flags & valid_ts_flags; + args.size = ((size >> 8) + 0x3f) & ~0x3f; + if (drmIoctl(drm->fd, DRM_IOCTL_VIV_GEM_CREATE, &args)) { + err = -errno; + goto err_close; + } + ts_handle = args.handle; + + /* ref ts_handle in master handle. */ + aux_args.handle = bo->handle; + aux_args.ts_handle = ts_handle; + if (drmIoctl(drm->fd, DRM_IOCTL_VIV_GEM_ATTACH_AUX, &aux_args)) { + err = -errno; + goto err_close; + } + + /* Now ts was attached to master, destroy it now. */ + close_args.handle = ts_handle; + if (drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &close_args)) { + err = -errno; + goto err_close; + } + ts_handle = 0; + + bo->flags = flags; + bo->size = size; + + *bop = bo; + return 0; + +err_close: + if (bo->handle) { + + if (ts_handle) { + close_args.handle = ts_handle; + drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &close_args); + } + + close_args.handle = bo->handle; + drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &close_args); + } + + free(bo); + return err; +} + +int drm_vivante_bo_export_to_fd(struct drm_vivante_bo *bo, int *pfd) +{ + if (!bo || !pfd) + return -EINVAL; + + if (bo->fd < 0) { + int fd; + if (drmPrimeHandleToFD(bo->drm->fd, bo->handle, O_RDWR, &fd)) + return -errno; + bo->fd = fd; + } + + *pfd = bo->fd; + return 0; +} + +int drm_vivante_bo_import_from_fd(struct drm_vivante *drm, int fd, + struct drm_vivante_bo **bop) +{ + int err; + uint64_t size; + uint32_t handle = 0; + struct drm_vivante_bo *bo = NULL; + + if (!drm || !bop || fd < 0) + return -EINVAL; + + err = drm_vivante_bo_init(drm, &bo); + if (err) + return err; + + if (drmPrimeFDToHandle(drm->fd, fd, &handle)) { + err = -errno; + goto err_close; + } + bo->handle = handle; + + err = drm_vivante_bo_query(bo, DRM_VIV_GEM_PARAM_SIZE, &size); + if (err) + goto err_close; + bo->size = (uint32_t)size; + + *bop = bo; + return 0; + +err_close: + if (handle > 0) { + struct drm_gem_close close_args = { + .handle = handle, + }; + drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &close_args); + } + free(bo); + + return err; +} + +void drm_vivante_bo_destroy(struct drm_vivante_bo *bo) +{ + struct drm_gem_close close_args; + + if (!bo) + return; + + if (bo->vaddr) { + drm_vivante_bo_munmap(bo); + } + + close_args.handle = bo->handle; + drmIoctl(bo->drm->fd, DRM_IOCTL_GEM_CLOSE, &close_args); + + free(bo); +} + +int drm_vivante_bo_get_handle(struct drm_vivante_bo *bo, uint32_t *handle) +{ + if (!bo || !handle) + return -EINVAL; + + *handle = bo->handle; + return 0; +} + +static int clean_bo_cache(struct drm_vivante_bo *bo) +{ + struct drm_viv_gem_cache args = { + .op = DRM_VIV_GEM_CLEAN_CACHE, + .handle = bo->handle, + .logical = (uint64_t)(uintptr_t)bo->vaddr, + .bytes = bo->size + }; + + if (drmIoctl(bo->drm->fd, DRM_IOCTL_VIV_GEM_CACHE, &args)) + return -errno; + + return 0; +} + + +int drm_vivante_bo_mmap(struct drm_vivante_bo *bo, void **vaddr) +{ + struct drm_viv_gem_lock args; + + if (!bo || !vaddr) + return -EINVAL; + + /* already locked */ + if (bo->vaddr) + return -EPERM; + + args.handle = bo->handle; + args.cacheable = (bo->flags & DRM_VIV_GEM_CACHED) ? 1 : 0; + if (drmIoctl(bo->drm->fd, DRM_IOCTL_VIV_GEM_LOCK, &args)) + return -errno; + + bo->vaddr = (void *)(uintptr_t)args.logical; + + *vaddr = bo->vaddr; + return 0; +} + +int drm_vivante_bo_munmap(struct drm_vivante_bo *bo) +{ + struct drm_viv_gem_unlock args; + + if (!bo || !bo->vaddr) + return -EINVAL; + + args.handle = bo->handle; + if (bo->flags & DRM_VIV_GEM_CACHED) { + int err = clean_bo_cache(bo); + if (err) + return err; + } + + if (drmIoctl(bo->drm->fd, DRM_IOCTL_VIV_GEM_UNLOCK, &args)) + return -errno; + + bo->vaddr = NULL; + return 0; +} + +int drm_vivante_bo_query(struct drm_vivante_bo *bo, + uint32_t param, uint64_t *value) +{ + struct drm_viv_gem_query args = { + .param = param, + }; + + if (!bo || !value) + return -EINVAL; + + args.handle = bo->handle; + if (drmIoctl(bo->drm->fd, DRM_IOCTL_VIV_GEM_QUERY, &args)) + return -errno; + + *value = args.value; + return 0; +} + +int drm_vivante_bo_set_tiling(struct drm_vivante_bo *bo, + const struct drm_vivante_bo_tiling *tiling) +{ + struct drm_viv_gem_set_tiling args; + + if (!bo || !tiling) + return -EINVAL; + + args = (struct drm_viv_gem_set_tiling) { + .handle = bo->handle, + .tiling_mode = tiling->tiling_mode, + .ts_mode = tiling->ts_mode, + .clear_value = tiling->clear_value, + }; + + if (drmIoctl(bo->drm->fd, DRM_IOCTL_VIV_GEM_SET_TILING, &args)) + return -errno; + + return 0; +} + +int drm_vivante_bo_get_tiling(struct drm_vivante_bo *bo, + struct drm_vivante_bo_tiling *tiling) +{ + struct drm_viv_gem_get_tiling args; + + if (!bo || !tiling) + return -EINVAL; + + args.handle = bo->handle; + if (drmIoctl(bo->drm->fd, DRM_IOCTL_VIV_GEM_GET_TILING, &args)) + return -errno; + + tiling->tiling_mode = args.tiling_mode; + tiling->ts_mode = args.ts_mode; + tiling->clear_value = args.clear_value; + + return 0; +} + +static inline int inc_bo_timestamp(struct drm_vivante_bo *bo, + uint32_t inc, uint64_t *timestamp) +{ + struct drm_viv_gem_timestamp args = { + .handle = bo->handle, + .inc = inc, + }; + if (drmIoctl(bo->drm->fd, DRM_IOCTL_VIV_GEM_TIMESTAMP, &args)) + return -errno; + + if (timestamp) + *timestamp = args.timestamp; + return 0; +} + +int drm_vivante_bo_inc_timestamp(struct drm_vivante_bo *bo, + uint64_t *timestamp) +{ + if (!bo) + return -EINVAL; + return inc_bo_timestamp(bo, 1, timestamp); +} + +int drm_vivante_bo_get_timestamp(struct drm_vivante_bo *bo, + uint64_t *timestamp) +{ + if (!bo || !timestamp) + return -EINVAL; + return inc_bo_timestamp(bo, 0, timestamp); +} + +int drm_vivante_bo_ref_node(struct drm_vivante_bo *bo, + uint32_t *node, uint32_t *ts_node) +{ + struct drm_viv_gem_ref_node args; + + if (!bo || !node || !ts_node) + return -EINVAL; + + args.handle = bo->handle; + if (drmIoctl(bo->drm->fd, DRM_IOCTL_VIV_GEM_REF_NODE, &args)) + return -errno; + + *node = args.node; + *ts_node = args.ts_node; + return 0; +} +
diff --git a/vivante/vivante_bo.h b/vivante/vivante_bo.h new file mode 100644 index 0000000..a12f2a3 --- /dev/null +++ b/vivante/vivante_bo.h
@@ -0,0 +1,87 @@ +/**************************************************************************** +* +* Copyright 2012 - 2017 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* 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, sub license, 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 NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE 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 __DRM_VIVANTE_H__ +#define __DRM_VIVANTE_H__ + +#include <stdint.h> +#include <stdlib.h> +#include <vivante_drm.h> + +struct drm_vivante_bo; +struct drm_vivante; + +struct drm_vivante_bo_tiling { + uint32_t tiling_mode; + uint32_t ts_mode; + uint64_t clear_value; +}; + +/* caller owns the driver fd. */ +int drm_vivante_create(int fd, struct drm_vivante **drmp); +void drm_vivante_close(struct drm_vivante *drm); + +int drm_vivante_bo_create(struct drm_vivante *drm, + uint32_t flags, uint32_t size, struct drm_vivante_bo **bop); + +/* create bo with auxillary tile-status bo. */ +int drm_vivante_bo_create_with_ts(struct drm_vivante *drm, + uint32_t flags, uint32_t size, struct drm_vivante_bo **bop); + +/* caller owns the fd. */ +int drm_vivante_bo_export_to_fd(struct drm_vivante_bo *bo, int *pfd); +/* caller still owns the fd upon return. */ +int drm_vivante_bo_import_from_fd(struct drm_vivante *drm, int fd, + struct drm_vivante_bo **bop); + +void drm_vivante_bo_destroy(struct drm_vivante_bo *bo); + +/* do not close the handle directly. */ +int drm_vivante_bo_get_handle(struct drm_vivante_bo *bo, uint32_t *handle); + +int drm_vivante_bo_mmap(struct drm_vivante_bo *bo, void **vaddr); +int drm_vivante_bo_munmap(struct drm_vivante_bo *bo); + +int drm_vivante_bo_query(struct drm_vivante_bo *bo, + uint32_t param, uint64_t *value); + +int drm_vivante_bo_set_tiling(struct drm_vivante_bo *bo, + const struct drm_vivante_bo_tiling *tiling); +int drm_vivante_bo_get_tiling(struct drm_vivante_bo *bo, + struct drm_vivante_bo_tiling *tiling); + +/* output inc'ed timestamp, optional. */ +int drm_vivante_bo_inc_timestamp(struct drm_vivante_bo *bo, + uint64_t *timestamp); +int drm_vivante_bo_get_timestamp(struct drm_vivante_bo *bo, + uint64_t *timestamp); + +int drm_vivante_bo_ref_node(struct drm_vivante_bo *bo, + uint32_t *node, uint32_t *ts_node); + +#endif /* __DRM_VIVANTE_H__ */