/* * Copyright (c) 2008-2016 Allwinner Technology Co. Ltd. * All rights reserved. * * File : cdcionUtil.c * Description : get phy addr for android * (it is only work in android, do not compile in LINUX) * History : * Comment : * * */ #include #include #include #include #include #include #include #include #include #ifdef __ANDROID__ #include #endif #include "log.h" #include "CdcUtil.h" int CdcIonGetMemType() { MEMORY_TYPE eMemoryType; #ifdef __ANDROID__ char prop_value[512]; property_get("ro.kernel.iomem.type", prop_value, "0xaf01"); logv("++++ prop_value: %s", prop_value); if(strcmp(prop_value, "0xaf10")==0) { eMemoryType = MEMORY_IOMMU; } else eMemoryType = MEMORY_NORMAL; #else #ifdef CONF_KERNEL_IOMMU eMemoryType = MEMORY_IOMMU; #else eMemoryType = MEMORY_NORMAL; #endif #endif return eMemoryType; } unsigned long CdcIonGetPhyAdr(int fd, uintptr_t handle) { if(CdcIonGetMemType() == MEMORY_IOMMU) { return 1; } else { int ret = 0; ion_custom_data_t custom_data; cdc_sunxi_phys_data phys_data; memset(&phys_data, 0, sizeof(cdc_sunxi_phys_data)); CEDARC_UNUSE(phys_data.size); custom_data.aw_cmd = ION_IOC_SUNXI_PHYS_ADDR; phys_data.handle = (aw_ion_user_handle_t)handle; custom_data.aw_arg = (unsigned long)&phys_data; ret = ioctl(fd, AW_MEM_ION_IOC_CUSTOM, &custom_data); if(ret < 0) { loge("CdcIonGetPhyAdr AW_MEM_ION_IOC_CUSTOM error\n"); return 0; } return phys_data.phys_addr; } } int CdcIonGetFd(int fd, uintptr_t handle) { int ret; ion_fd_data_t fd_data; fd_data.handle = (aw_ion_user_handle_t)handle; ret = ioctl(fd, AW_MEM_ION_IOC_MAP, &fd_data); if(ret) { loge("CdcIonGetFd map other dev's handle err, ret %d, dmabuf fd 0x%08x\n", ret, fd_data.aw_fd); return -1; } return fd_data.aw_fd; } int CdcIonImport(int fd, int share_fd, aw_ion_user_handle_t *ion_handle) { int ret; ion_fd_data_t fd_data; memset(&fd_data, 0, sizeof(ion_fd_data_t)); fd_data.aw_fd = share_fd; ret = ioctl(fd, AW_MEM_ION_IOC_IMPORT, &fd_data); if(ret) { loge("CdcIonImport get ion_handle err, ret %d\n",ret); return -1; } *ion_handle = fd_data.handle; return 0; } int CdcIonFree(int fd, aw_ion_user_handle_t ion_handle) { int ret; ion_handle_data_t sIonHandleData; memset(&sIonHandleData, 0, sizeof(ion_handle_data_t)); sIonHandleData.handle = ion_handle; ret = ioctl(fd, AW_MEM_ION_IOC_FREE, &sIonHandleData); if(ret) { loge("CdcIonFree free ion_handle err, ret %d\n",ret); return -1; } return 0; } int CdcIonOpen(void) { int fd = open("/dev/ion", O_RDWR); if (fd < 0) loge("open /dev/ion failed!\n"); return fd; } int CdcIonClose(int fd) { int ret = close(fd); if (ret < 0) { loge("CdcIonClose failed with code %d: %s\n", ret, strerror(errno)); return -errno; } return ret; } int CdcIonMmap(int buf_fd, size_t len, unsigned char **pVirAddr) { CEDARC_UNUSE(CdcIonMmap); /* mmap to user */ *pVirAddr = mmap(NULL, len, \ PROT_READ|PROT_WRITE, MAP_SHARED, buf_fd, 0); if(MAP_FAILED == pVirAddr) { loge("CdcIonMmap failed: %s\n", strerror(errno)); return -errno; } return 0; } int CdcIonUnmap(size_t len, unsigned char *pVirAddr) { CEDARC_UNUSE(CdcIonUnmap); int ret; ret = munmap((void*)pVirAddr, len); if(ret) { loge("CdcIonUnmap failed: %s\n", strerror(errno)); return -errno; } return 0; }