| /** |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <dirent.h> |
| #include <dlfcn.h> |
| #include <fcntl.h> |
| #include <linux/sched.h> |
| #include <pthread.h> |
| #include <sched.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <sys/ioctl.h> |
| #include <sys/mman.h> |
| #include <sys/resource.h> |
| #include <sys/stat.h> |
| #include <sys/syscall.h> |
| #include <sys/time.h> |
| #include <unistd.h> |
| #include <unistd.h> |
| |
| #define DRM_TEGRA_GEM_CREATE 0x00 |
| #define DRM_TEGRA_GEM_MMAP 0x01 |
| #define DRM_TEGRA_SYNCPT_READ 0x02 |
| #define DRM_TEGRA_SYNCPT_INCR 0x03 |
| #define DRM_TEGRA_SYNCPT_WAIT 0x04 |
| #define DRM_TEGRA_OPEN_CHANNEL 0x05 |
| #define DRM_TEGRA_CLOSE_CHANNEL 0x06 |
| #define DRM_TEGRA_GET_SYNCPT 0x07 |
| #define DRM_TEGRA_SUBMIT 0x08 |
| #define DRM_TEGRA_GET_SYNCPT_BASE 0x09 |
| #define DRM_TEGRA_GEM_SET_TILING 0x0a |
| #define DRM_TEGRA_GEM_GET_TILING 0x0b |
| #define DRM_TEGRA_GEM_SET_FLAGS 0x0c |
| #define DRM_TEGRA_GEM_GET_FLAGS 0x0d |
| #define DRM_TEGRA_GET_CLK_RATE 0x0e |
| #define DRM_TEGRA_SET_CLK_RATE 0x0f |
| #define DRM_TEGRA_START_KEEPON 0x10 |
| #define DRM_TEGRA_STOP_KEEPON 0x11 |
| #define DRM_TEGRA_GET_CLK_CONSTRAINT 0x12 |
| #define DRM_TEGRA_SET_CLK_CONSTRAINT 0x13 |
| |
| struct drm_tegra_gem_create { |
| __u64 size; |
| __u32 flags; |
| __u32 handle; |
| }; |
| struct drm_tegra_open_channel { |
| __u32 client; |
| __u32 pad; |
| __u64 context; |
| }; |
| struct drm_tegra_constraint { |
| /* channel context (from opening a channel) */ |
| __u64 context; |
| /* index identifying the clock. One of HOST1X_CLOCK_INDEX_* */ |
| __u32 index; |
| /* constraint type. One of HOST1X_USER_CONSTRAINT_TYPE_* */ |
| __u32 type; |
| /* numeric value for type */ |
| __u32 rate; |
| __u32 pad; |
| }; |
| struct drm_prime_handle { |
| __u32 handle; |
| |
| /** Flags.. only applicable for handle->fd */ |
| __u32 flags; |
| |
| /** Returned dmabuf file descriptor */ |
| __s32 fd; |
| }; |
| |
| #define DRM_COMMAND_BASE 0x40 |
| #define DRM_COMMAND_END 0xA0 |
| #define DRM_IOCTL_BASE 'd' |
| #define DRM_IO(nr) _IO(DRM_IOCTL_BASE, nr) |
| #define DRM_IOR(nr, type) _IOR(DRM_IOCTL_BASE, nr, type) |
| #define DRM_IOW(nr, type) _IOW(DRM_IOCTL_BASE, nr, type) |
| #define DRM_IOWR(nr, type) _IOWR(DRM_IOCTL_BASE, nr, type) |
| #define DRM_IOCTL_TEGRA_GEM_CREATE \ |
| DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_CREATE, struct drm_tegra_gem_create) |
| #define DRM_IOCTL_TEGRA_OPEN_CHANNEL \ |
| DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_OPEN_CHANNEL, \ |
| struct drm_tegra_open_channel) |
| #define DRM_IOCTL_TEGRA_GET_CLK_CONSTRAINT \ |
| DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GET_CLK_CONSTRAINT, \ |
| struct drm_tegra_constraint) |
| #define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle) |
| |
| int g_fd = -1; |
| int g_ion_fd = -1; |
| enum host1x_class { |
| HOST1X_CLASS_HOST1X = 0x1, |
| HOST1X_CLASS_NVENC = 0x21, |
| HOST1X_CLASS_VI = 0x30, |
| HOST1X_CLASS_ISPA = 0x32, |
| HOST1X_CLASS_ISPB = 0x34, |
| HOST1X_CLASS_GR2D = 0x51, |
| HOST1X_CLASS_GR2D_SB = 0x52, |
| HOST1X_CLASS_VIC = 0x5D, |
| HOST1X_CLASS_GR3D = 0x60, |
| HOST1X_CLASS_NVJPG = 0xC0, |
| HOST1X_CLASS_NVDEC = 0xF0, |
| }; |
| int classes[] = {HOST1X_CLASS_HOST1X, HOST1X_CLASS_NVENC, HOST1X_CLASS_VI, |
| HOST1X_CLASS_ISPA, HOST1X_CLASS_ISPB, HOST1X_CLASS_GR2D, |
| HOST1X_CLASS_GR2D_SB, HOST1X_CLASS_VIC, HOST1X_CLASS_GR3D, |
| HOST1X_CLASS_NVJPG, HOST1X_CLASS_NVDEC}; |
| #define ION_IOC_MAGIC 'I' |
| #define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data) |
| #define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) |
| struct ion_fd_data { |
| int handle; |
| int fd; |
| }; |
| struct ion_handle_data { |
| int handle; |
| }; |
| |
| int open_driver(void); |
| void gem_create(void); |
| void handle_to_fd(void); |
| void ion_import(void); |
| void ion_handle_free(void); |
| |
| int open_driver(void) { |
| const char* dev_path = "/dev/dri/renderD129"; |
| g_fd = open(dev_path, O_RDONLY); |
| if (g_fd < 0) { |
| return g_fd; |
| } |
| |
| dev_path = "/dev/ion"; |
| g_ion_fd = open(dev_path, O_RDONLY); |
| if (g_ion_fd < 0) { |
| return g_ion_fd; |
| } |
| return 1; |
| } |
| |
| char* g_buf = NULL; |
| void* g_context = NULL; |
| int g_gem_handle = -1; |
| int g_dmabuf_fd = -1; |
| int g_ion_handle = -1; |
| |
| void gem_create(void) { |
| struct drm_tegra_gem_create para = {0, 0, 0}; |
| para.size = 1024; |
| ioctl(g_fd, DRM_IOCTL_TEGRA_GEM_CREATE, ¶); |
| g_gem_handle = para.handle; |
| } |
| void handle_to_fd(void) { |
| struct drm_prime_handle para = {0, 0, 0}; |
| para.handle = g_gem_handle; |
| ioctl(g_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, ¶); |
| g_dmabuf_fd = para.fd; |
| } |
| void ion_import(void) { |
| struct ion_fd_data para = {0, 0}; |
| para.fd = g_dmabuf_fd; |
| ioctl(g_ion_fd, ION_IOC_IMPORT, ¶); |
| g_ion_handle = para.handle; |
| } |
| void ion_handle_free(void) { |
| struct ion_handle_data para = {0}; |
| para.handle = g_ion_handle; |
| ioctl(g_ion_fd, ION_IOC_FREE, ¶); |
| } |
| |
| int main(void) { |
| if (open_driver() < 0) { |
| return -1; |
| } |
| gem_create(); |
| handle_to_fd(); |
| ion_import(); |
| ion_handle_free(); |
| close(g_fd); |
| close(g_dmabuf_fd); |
| return 0; |
| } |