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