diff options
Diffstat (limited to 'gralloc/alloc_device.cpp')
-rw-r--r-- | gralloc/alloc_device.cpp | 206 |
1 files changed, 134 insertions, 72 deletions
diff --git a/gralloc/alloc_device.cpp b/gralloc/alloc_device.cpp index b6bd69ea..f458a624 100644 --- a/gralloc/alloc_device.cpp +++ b/gralloc/alloc_device.cpp @@ -20,6 +20,9 @@ #include <string.h> #include <errno.h> #include <pthread.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #include <cutils/log.h> #include <cutils/atomic.h> @@ -41,10 +44,22 @@ #if GRALLOC_ARM_DMA_BUF_MODULE #include <ion/ion.h> #include "ion_4.12.h" +#include "dma-heap.h" #define ION_SYSTEM (char*)"ion_system_heap" #define ION_CMA (char*)"linux,cma" +#define DMABUF_SYSTEM (char*)"system" +#define DMABUF_CMA (char*)"linux,cma" +static enum { + INTERFACE_UNKNOWN, + INTERFACE_ION_LEGACY, + INTERFACE_ION_MODERN, + INTERFACE_DMABUF_HEAPS +} interface_ver; + +static int system_heap_id; +static int cma_heap_id; #endif #if GRALLOC_SIMULATE_FAILURES @@ -119,12 +134,73 @@ static int fb_get_framebuffer_dmabuf(private_module_t *m, private_handle_t *hnd) } #endif +#if GRALLOC_ARM_DMA_BUF_MODULE +#define DEVPATH "/dev/dma_heap" +int dma_heap_open(const char* name) +{ + int ret, fd; + char buf[256]; + + ret = sprintf(buf, "%s/%s", DEVPATH, name); + if (ret < 0) { + AERR("sprintf failed!\n"); + return ret; + } + + fd = open(buf, O_RDONLY); + if (fd < 0) + AERR("open %s failed!\n", buf); + return fd; +} + +int dma_heap_alloc(int fd, size_t len, unsigned int flags, int *dmabuf_fd) +{ + struct dma_heap_allocation_data data = { + .len = len, + .fd_flags = O_RDWR | O_CLOEXEC, + .heap_flags = flags, + }; + int ret; + + if (dmabuf_fd == NULL) + return -EINVAL; + + ret = ioctl(fd, DMA_HEAP_IOCTL_ALLOC, &data); + if (ret < 0) + return ret; + *dmabuf_fd = (int)data.fd; + return ret; +} + +static int alloc_ion_fd(int ion_fd, size_t size, unsigned int heap_mask, unsigned int flags, int *shared_fd) +{ + int heap; + + if (interface_ver == INTERFACE_DMABUF_HEAPS) { + int fd = system_heap_id; + unsigned long flg = 0; + if (heap_mask == ION_HEAP_TYPE_DMA_MASK) + fd = cma_heap_id; + + return dma_heap_alloc(fd, size, flg, shared_fd); + } + + if (interface_ver == INTERFACE_ION_MODERN) { + heap = 1 << system_heap_id; + if (heap_mask == ION_HEAP_TYPE_DMA_MASK) + heap = 1 << cma_heap_id; + } else { + heap = heap_mask; + } + return ion_alloc_fd(ion_fd, size, 0, heap, flags, shared_fd); +} +#endif + static int gralloc_alloc_buffer(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle) { #if GRALLOC_ARM_DMA_BUF_MODULE { private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); - ion_user_handle_t ion_hnd; void *cpu_ptr = MAP_FAILED; int shared_fd; int ret; @@ -132,8 +208,7 @@ static int gralloc_alloc_buffer(alloc_device_t *dev, size_t size, int usage, buf int lock_state = 0; int map_mask = 0; - if (usage & GRALLOC_USAGE_PROTECTED) - { + if (usage & GRALLOC_USAGE_PROTECTED) { #if defined(ION_HEAP_SECURE_MASK) heap_mask = ION_HEAP_SECURE_MASK; #else @@ -141,57 +216,17 @@ static int gralloc_alloc_buffer(alloc_device_t *dev, size_t size, int usage, buf return -1; #endif } - else - { - heap_mask = ION_HEAP_SYSTEM_MASK; + else if (usage & GRALLOC_USAGE_HW_FB) { + heap_mask = ION_HEAP_TYPE_DMA_MASK; } - - if (m->gralloc_legacy_ion) - { - if (usage & GRALLOC_USAGE_HW_FB) - ret = ion_alloc(m->ion_client, size, 0, ION_HEAP_TYPE_DMA_MASK, 0, &(ion_hnd)); - else - ret = ion_alloc(m->ion_client, size, 0, ION_HEAP_SYSTEM_MASK, 0, &(ion_hnd)); - - if (ret != 0) - { - AERR("Failed to ion_alloc from ion_client:%d", m->ion_client); - return -1; - } - - ret = ion_share(m->ion_client, ion_hnd, &shared_fd); - - if (ret != 0) - { - AERR("ion_share( %d ) failed", m->ion_client); - - if (0 != ion_free(m->ion_client, ion_hnd)) - { - AERR("ion_free( %d ) failed", m->ion_client); - } - - return -1; - } - - // we do not need ion_hnd once we have shared_fd - if (0 != ion_free(m->ion_client, ion_hnd)) - { - AWAR("ion_free( %d ) failed", m->ion_client); - } - ion_hnd = ION_INVALID_HANDLE; + else { + heap_mask = ION_HEAP_SYSTEM_MASK; } - else - { - if (usage & GRALLOC_USAGE_HW_FB) - ret = ion_alloc_fd(m->ion_client, size, 0, 1 << m->cma_heap_id, 0, &(shared_fd)); - else - ret = ion_alloc_fd(m->ion_client, size, 0, 1 << m->system_heap_id, 0, &(shared_fd)); - if (ret != 0) - { - AERR("Failed to ion_alloc_fd from ion_client:%d", m->ion_client); - return -1; - } + ret = alloc_ion_fd(m->ion_client, size, heap_mask, 0, &shared_fd); + if (ret != 0) { + AERR("Failed to ion_alloc_fd from ion_client:%d", m->ion_client); + return -1; } if (!(usage & GRALLOC_USAGE_PROTECTED)) @@ -693,7 +728,7 @@ static int alloc_device_close(struct hw_device_t *device) } #if GRALLOC_ARM_DMA_BUF_MODULE -static int find_ion_heap_id(int ion_client, char* name) +static int find_heap_id(int ion_client, char* name) { int i, ret, cnt, heap_id = -1; struct ion_heap_data *data; @@ -740,6 +775,52 @@ static int find_ion_heap_id(int ion_client, char* name) } #endif +static int initialize_interface(private_module_t *m) +{ + int fd; + + if (interface_ver != INTERFACE_UNKNOWN) + return 0; + + /* test for dma-heaps*/ + fd = dma_heap_open(DMABUF_SYSTEM); + if (fd >= 0) { + AINF("Using DMA-BUF Heaps.\n"); + interface_ver = INTERFACE_DMABUF_HEAPS; + system_heap_id = fd; + cma_heap_id = dma_heap_open(DMABUF_CMA); + /* Open other dma heaps here */ + return 0; + } + + /* test for modern vs legacy ION */ + m->ion_client = ion_open(); + if (m->ion_client < 0) { + AERR("ion_open failed with %s", strerror(errno)); + return -1; + } + if (!ion_is_legacy(m->ion_client)) { + system_heap_id = find_heap_id(m->ion_client, ION_SYSTEM); + cma_heap_id = find_heap_id(m->ion_client, ION_CMA); + if (system_heap_id < 0) { + ion_close(m->ion_client); + m->ion_client = -1; + AERR( "ion_open failed: no system heap found" ); + return -1; + } + if (cma_heap_id < 0) { + AERR("No cma heap found, falling back to system"); + cma_heap_id = system_heap_id; + } + AINF("Using ION Modern interface.\n"); + interface_ver = INTERFACE_ION_MODERN; + } else { + AINF("Using ION Legacy interface.\n"); + interface_ver = INTERFACE_ION_LEGACY; + } + return 0; +} + int alloc_device_open(hw_module_t const *module, const char *name, hw_device_t **device) { MALI_IGNORE(name); @@ -777,30 +858,11 @@ int alloc_device_open(hw_module_t const *module, const char *name, hw_device_t * #if GRALLOC_ARM_DMA_BUF_MODULE private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); - m->ion_client = ion_open(); - if (m->ion_client < 0) - { - AERR("ion_open failed with %s", strerror(errno)); + if (initialize_interface(m) < 0) { delete dev; return -1; } - - m->gralloc_legacy_ion = ion_is_legacy(m->ion_client); - - if (!m->gralloc_legacy_ion) - { - m->system_heap_id = find_ion_heap_id(m->ion_client, ION_SYSTEM); - m->cma_heap_id = find_ion_heap_id(m->ion_client, ION_CMA); - if (m->system_heap_id < 0 || m->cma_heap_id < 0) - { - delete dev; - ion_close(m->ion_client); - m->ion_client = -1; - return -1; - } - } - #endif *device = &dev->common; |