/** * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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() { 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; }