1 #include <ion/ion.h>
2 #include <linux/ion_4.12.h>
3
4 #include "ion.h"
5
ion_get_heap_id(int ion_fd,uint32_t heap_type)6 int ion_get_heap_id(int ion_fd, uint32_t heap_type)
7 {
8 int heap_count = 0;
9 int ret = -1;
10
11 if (ion_query_heap_cnt(ion_fd, &heap_count))
12 {
13 return -1;
14 }
15
16 struct ion_heap_data *heap_data =
17 malloc(heap_count * sizeof(struct ion_heap_data));
18
19 if (ion_query_get_heaps(ion_fd, heap_count, heap_data))
20 {
21 free(heap_data);
22 return -1;
23 }
24
25 for (struct ion_heap_data *hi = heap_data;
26 (hi - heap_data) < heap_count;
27 ++hi)
28 {
29 if (hi->type == heap_type)
30 {
31 ret = hi->heap_id;
32 break;
33 }
34 }
35
36 free(heap_data);
37
38 return ret;
39 }
40
41 static const int kBitsInAnInt = (sizeof(int) * 8);
42
ion_alloc_one_fd(int ion_fd,size_t size,int heap_id,int * ion_buffer_fd)43 int ion_alloc_one_fd(int ion_fd, size_t size, int heap_id, int *ion_buffer_fd)
44 {
45 if (heap_id < 0 || heap_id >= kBitsInAnInt)
46 {
47 return -1;
48 }
49
50 const int align = 0;
51 const int heap_mask = 1 << heap_id;
52 const int flags = 0;
53
54 return ion_alloc_fd(ion_fd, size, align, heap_mask, flags, ion_buffer_fd);
55 }
56
ion_mmap(void ** ptr,int ion_buffer_fd,size_t size)57 int ion_mmap(void **ptr, int ion_buffer_fd, size_t size)
58 {
59 void *const k_addr = 0;
60 const int k_prot = PROT_READ | PROT_WRITE;
61 const int k_flags = MAP_SHARED;
62
63 void *ret = mmap(k_addr, size, k_prot, k_flags, ion_buffer_fd, 0);
64
65 if (ret == MAP_FAILED)
66 {
67 return -1;
68 }
69
70 *ptr = ret;
71 return 0;
72 }
73
ion_munmap(void * ptr,size_t size)74 int ion_munmap(void *ptr, size_t size)
75 {
76 if (munmap(ptr, size))
77 {
78 return -1;
79 }
80
81 return 0;
82 }
83
drm_check_prime_caps(int drm_fd)84 int drm_check_prime_caps(int drm_fd)
85 {
86 struct drm_get_cap drm_get_cap_arg = {
87 .capability = DRM_CAP_PRIME,
88 .value = 0
89 };
90
91 if (drmIoctl(drm_fd, DRM_IOCTL_GET_CAP, &drm_get_cap_arg))
92 {
93 return -1;
94 }
95
96 if (!(drm_get_cap_arg.value & DRM_PRIME_CAP_IMPORT) ||
97 !(drm_get_cap_arg.value & DRM_PRIME_CAP_EXPORT))
98 {
99 return -1;
100 }
101
102 return 0;
103 }
104
gem_handle_for_ion_buffer(int drm_fd,uint32_t * gem_handle,int ion_buffer_fd)105 int gem_handle_for_ion_buffer(int drm_fd, uint32_t *gem_handle, int ion_buffer_fd)
106 {
107 struct drm_prime_handle drm_prime_fd_to_handle_arg = {
108 .handle = 0,
109 .flags = 0,
110 .fd = ion_buffer_fd
111 };
112
113 if (drmIoctl(drm_fd,
114 DRM_IOCTL_PRIME_FD_TO_HANDLE,
115 &drm_prime_fd_to_handle_arg))
116 {
117 return -1;
118 }
119
120 *gem_handle = drm_prime_fd_to_handle_arg.handle;
121
122 return 0;
123 }
124
ion_fd_for_gem_handle(int drm_fd,int * ion_fd,uint32_t gem_handle)125 int ion_fd_for_gem_handle(int drm_fd, int *ion_fd, uint32_t gem_handle)
126 {
127 struct drm_prime_handle drm_prime_handle_to_fd_arg = {
128 .handle = gem_handle,
129 .flags = 0,
130 .fd = 0
131 };
132
133 if (drmIoctl(drm_fd,
134 DRM_IOCTL_PRIME_HANDLE_TO_FD,
135 &drm_prime_handle_to_fd_arg))
136 {
137 return -1;
138 }
139
140 *ion_fd = drm_prime_handle_to_fd_arg.fd;
141
142 return 0;
143 }
144
drm_fb_for_ion_buffer(int drm_fd,uint32_t * fb_id,int ion_buffer_fd,const struct fb_configuration * fb_config)145 int drm_fb_for_ion_buffer(int drm_fd, uint32_t *fb_id, int ion_buffer_fd,
146 const struct fb_configuration *fb_config)
147 {
148 uint32_t gem_handle = 0;
149
150 if (gem_handle_for_ion_buffer(drm_fd, &gem_handle, ion_buffer_fd))
151 {
152 return -1;
153 }
154
155 int ret = drm_fb_for_gem_handle(drm_fd, fb_id, gem_handle, fb_config);
156
157 gem_release_handle(drm_fd, gem_handle);
158 return ret;
159 }
160
drm_release_fb(int drm_fd,uint32_t fb_id)161 void drm_release_fb(int drm_fd, uint32_t fb_id)
162 {
163 (void)drmIoctl(drm_fd, DRM_IOCTL_MODE_RMFB, &fb_id);
164 }
165
ion_clone_fd_via_gem(int drm_fd,int * cloned_fd,int ion_buffer_fd)166 int ion_clone_fd_via_gem(int drm_fd, int *cloned_fd, int ion_buffer_fd)
167 {
168 uint32_t gem_handle = 0;
169 if (gem_handle_for_ion_buffer(drm_fd, &gem_handle, ion_buffer_fd))
170 {
171 return -1;
172 }
173
174 int ret = ion_fd_for_gem_handle(drm_fd, cloned_fd, gem_handle);
175 gem_release_handle(drm_fd, gem_handle);
176
177 return ret;
178 }
179
180
181