18c2ecf20Sopenharmony_ci#include <errno.h>
28c2ecf20Sopenharmony_ci#include <fcntl.h>
38c2ecf20Sopenharmony_ci#include <stdio.h>
48c2ecf20Sopenharmony_ci#include <stdint.h>
58c2ecf20Sopenharmony_ci#include <string.h>
68c2ecf20Sopenharmony_ci#include <unistd.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <sys/ioctl.h>
98c2ecf20Sopenharmony_ci#include <sys/types.h>
108c2ecf20Sopenharmony_ci#include <sys/stat.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/dma-buf.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <drm/drm.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include "ion.h"
178c2ecf20Sopenharmony_ci#include "ionutils.h"
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ciint check_vgem(int fd)
208c2ecf20Sopenharmony_ci{
218c2ecf20Sopenharmony_ci	drm_version_t version = { 0 };
228c2ecf20Sopenharmony_ci	char name[5];
238c2ecf20Sopenharmony_ci	int ret;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	version.name_len = 4;
268c2ecf20Sopenharmony_ci	version.name = name;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	ret = ioctl(fd, DRM_IOCTL_VERSION, &version);
298c2ecf20Sopenharmony_ci	if (ret)
308c2ecf20Sopenharmony_ci		return 1;
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	return strcmp(name, "vgem");
338c2ecf20Sopenharmony_ci}
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ciint open_vgem(void)
368c2ecf20Sopenharmony_ci{
378c2ecf20Sopenharmony_ci	int i, fd;
388c2ecf20Sopenharmony_ci	const char *drmstr = "/dev/dri/card";
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	fd = -1;
418c2ecf20Sopenharmony_ci	for (i = 0; i < 16; i++) {
428c2ecf20Sopenharmony_ci		char name[80];
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci		sprintf(name, "%s%u", drmstr, i);
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci		fd = open(name, O_RDWR);
478c2ecf20Sopenharmony_ci		if (fd < 0)
488c2ecf20Sopenharmony_ci			continue;
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci		if (check_vgem(fd)) {
518c2ecf20Sopenharmony_ci			close(fd);
528c2ecf20Sopenharmony_ci			continue;
538c2ecf20Sopenharmony_ci		} else {
548c2ecf20Sopenharmony_ci			break;
558c2ecf20Sopenharmony_ci		}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci	}
588c2ecf20Sopenharmony_ci	return fd;
598c2ecf20Sopenharmony_ci}
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ciint import_vgem_fd(int vgem_fd, int dma_buf_fd, uint32_t *handle)
628c2ecf20Sopenharmony_ci{
638c2ecf20Sopenharmony_ci	struct drm_prime_handle import_handle = { 0 };
648c2ecf20Sopenharmony_ci	int ret;
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	import_handle.fd = dma_buf_fd;
678c2ecf20Sopenharmony_ci	import_handle.flags = 0;
688c2ecf20Sopenharmony_ci	import_handle.handle = 0;
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	ret = ioctl(vgem_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &import_handle);
718c2ecf20Sopenharmony_ci	if (ret == 0)
728c2ecf20Sopenharmony_ci		*handle = import_handle.handle;
738c2ecf20Sopenharmony_ci	return ret;
748c2ecf20Sopenharmony_ci}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_civoid close_handle(int vgem_fd, uint32_t handle)
778c2ecf20Sopenharmony_ci{
788c2ecf20Sopenharmony_ci	struct drm_gem_close close = { 0 };
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	close.handle = handle;
818c2ecf20Sopenharmony_ci	ioctl(vgem_fd, DRM_IOCTL_GEM_CLOSE, &close);
828c2ecf20Sopenharmony_ci}
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ciint main()
858c2ecf20Sopenharmony_ci{
868c2ecf20Sopenharmony_ci	int ret, vgem_fd;
878c2ecf20Sopenharmony_ci	struct ion_buffer_info info;
888c2ecf20Sopenharmony_ci	uint32_t handle = 0;
898c2ecf20Sopenharmony_ci	struct dma_buf_sync sync = { 0 };
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci	info.heap_type = ION_HEAP_TYPE_SYSTEM;
928c2ecf20Sopenharmony_ci	info.heap_size = 4096;
938c2ecf20Sopenharmony_ci	info.flag_type = ION_FLAG_CACHED;
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci	ret = ion_export_buffer_fd(&info);
968c2ecf20Sopenharmony_ci	if (ret < 0) {
978c2ecf20Sopenharmony_ci		printf("ion buffer alloc failed\n");
988c2ecf20Sopenharmony_ci		return -1;
998c2ecf20Sopenharmony_ci	}
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci	vgem_fd = open_vgem();
1028c2ecf20Sopenharmony_ci	if (vgem_fd < 0) {
1038c2ecf20Sopenharmony_ci		ret = vgem_fd;
1048c2ecf20Sopenharmony_ci		printf("Failed to open vgem\n");
1058c2ecf20Sopenharmony_ci		goto out_ion;
1068c2ecf20Sopenharmony_ci	}
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci	ret = import_vgem_fd(vgem_fd, info.buffd, &handle);
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	if (ret < 0) {
1118c2ecf20Sopenharmony_ci		printf("Failed to import buffer\n");
1128c2ecf20Sopenharmony_ci		goto out_vgem;
1138c2ecf20Sopenharmony_ci	}
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
1168c2ecf20Sopenharmony_ci	ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync);
1178c2ecf20Sopenharmony_ci	if (ret)
1188c2ecf20Sopenharmony_ci		printf("sync start failed %d\n", errno);
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	memset(info.buffer, 0xff, 4096);
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
1238c2ecf20Sopenharmony_ci	ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync);
1248c2ecf20Sopenharmony_ci	if (ret)
1258c2ecf20Sopenharmony_ci		printf("sync end failed %d\n", errno);
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	close_handle(vgem_fd, handle);
1288c2ecf20Sopenharmony_ci	ret = 0;
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ciout_vgem:
1318c2ecf20Sopenharmony_ci	close(vgem_fd);
1328c2ecf20Sopenharmony_ciout_ion:
1338c2ecf20Sopenharmony_ci	ion_close_buffer_fd(&info);
1348c2ecf20Sopenharmony_ci	printf("done.\n");
1358c2ecf20Sopenharmony_ci	return ret;
1368c2ecf20Sopenharmony_ci}
137