1*4882a593Smuzhiyun #include <errno.h>
2*4882a593Smuzhiyun #include <fcntl.h>
3*4882a593Smuzhiyun #include <stdio.h>
4*4882a593Smuzhiyun #include <stdint.h>
5*4882a593Smuzhiyun #include <string.h>
6*4882a593Smuzhiyun #include <unistd.h>
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <sys/ioctl.h>
9*4882a593Smuzhiyun #include <sys/types.h>
10*4882a593Smuzhiyun #include <sys/stat.h>
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <linux/dma-buf.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #include <drm/drm.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include "ion.h"
17*4882a593Smuzhiyun #include "ionutils.h"
18*4882a593Smuzhiyun
check_vgem(int fd)19*4882a593Smuzhiyun int check_vgem(int fd)
20*4882a593Smuzhiyun {
21*4882a593Smuzhiyun drm_version_t version = { 0 };
22*4882a593Smuzhiyun char name[5];
23*4882a593Smuzhiyun int ret;
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun version.name_len = 4;
26*4882a593Smuzhiyun version.name = name;
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun ret = ioctl(fd, DRM_IOCTL_VERSION, &version);
29*4882a593Smuzhiyun if (ret)
30*4882a593Smuzhiyun return 1;
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun return strcmp(name, "vgem");
33*4882a593Smuzhiyun }
34*4882a593Smuzhiyun
open_vgem(void)35*4882a593Smuzhiyun int open_vgem(void)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun int i, fd;
38*4882a593Smuzhiyun const char *drmstr = "/dev/dri/card";
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun fd = -1;
41*4882a593Smuzhiyun for (i = 0; i < 16; i++) {
42*4882a593Smuzhiyun char name[80];
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun sprintf(name, "%s%u", drmstr, i);
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun fd = open(name, O_RDWR);
47*4882a593Smuzhiyun if (fd < 0)
48*4882a593Smuzhiyun continue;
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun if (check_vgem(fd)) {
51*4882a593Smuzhiyun close(fd);
52*4882a593Smuzhiyun continue;
53*4882a593Smuzhiyun } else {
54*4882a593Smuzhiyun break;
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun return fd;
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun
import_vgem_fd(int vgem_fd,int dma_buf_fd,uint32_t * handle)61*4882a593Smuzhiyun int import_vgem_fd(int vgem_fd, int dma_buf_fd, uint32_t *handle)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun struct drm_prime_handle import_handle = { 0 };
64*4882a593Smuzhiyun int ret;
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun import_handle.fd = dma_buf_fd;
67*4882a593Smuzhiyun import_handle.flags = 0;
68*4882a593Smuzhiyun import_handle.handle = 0;
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun ret = ioctl(vgem_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &import_handle);
71*4882a593Smuzhiyun if (ret == 0)
72*4882a593Smuzhiyun *handle = import_handle.handle;
73*4882a593Smuzhiyun return ret;
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun
close_handle(int vgem_fd,uint32_t handle)76*4882a593Smuzhiyun void close_handle(int vgem_fd, uint32_t handle)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun struct drm_gem_close close = { 0 };
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun close.handle = handle;
81*4882a593Smuzhiyun ioctl(vgem_fd, DRM_IOCTL_GEM_CLOSE, &close);
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun
main()84*4882a593Smuzhiyun int main()
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun int ret, vgem_fd;
87*4882a593Smuzhiyun struct ion_buffer_info info;
88*4882a593Smuzhiyun uint32_t handle = 0;
89*4882a593Smuzhiyun struct dma_buf_sync sync = { 0 };
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun info.heap_type = ION_HEAP_TYPE_SYSTEM;
92*4882a593Smuzhiyun info.heap_size = 4096;
93*4882a593Smuzhiyun info.flag_type = ION_FLAG_CACHED;
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun ret = ion_export_buffer_fd(&info);
96*4882a593Smuzhiyun if (ret < 0) {
97*4882a593Smuzhiyun printf("ion buffer alloc failed\n");
98*4882a593Smuzhiyun return -1;
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun vgem_fd = open_vgem();
102*4882a593Smuzhiyun if (vgem_fd < 0) {
103*4882a593Smuzhiyun ret = vgem_fd;
104*4882a593Smuzhiyun printf("Failed to open vgem\n");
105*4882a593Smuzhiyun goto out_ion;
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun ret = import_vgem_fd(vgem_fd, info.buffd, &handle);
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun if (ret < 0) {
111*4882a593Smuzhiyun printf("Failed to import buffer\n");
112*4882a593Smuzhiyun goto out_vgem;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
116*4882a593Smuzhiyun ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync);
117*4882a593Smuzhiyun if (ret)
118*4882a593Smuzhiyun printf("sync start failed %d\n", errno);
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun memset(info.buffer, 0xff, 4096);
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
123*4882a593Smuzhiyun ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync);
124*4882a593Smuzhiyun if (ret)
125*4882a593Smuzhiyun printf("sync end failed %d\n", errno);
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun close_handle(vgem_fd, handle);
128*4882a593Smuzhiyun ret = 0;
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun out_vgem:
131*4882a593Smuzhiyun close(vgem_fd);
132*4882a593Smuzhiyun out_ion:
133*4882a593Smuzhiyun ion_close_buffer_fd(&info);
134*4882a593Smuzhiyun printf("done.\n");
135*4882a593Smuzhiyun return ret;
136*4882a593Smuzhiyun }
137