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, &para);
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, &para);
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, &para);
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, &para);
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