gralloc: Extend hikey gralloc to use dmabuf heaps am: c3571ac08c am: 33a7181e2c
Change-Id: I01be9989ba5e1c3351818b843f8ed008f7eb5258
diff --git a/gralloc/alloc_device.cpp b/gralloc/alloc_device.cpp
index 44fbf6c..95b1a43 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,13 +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;
-static bool gralloc_legacy_ion;
#endif
#if GRALLOC_SIMULATE_FAILURES
@@ -123,12 +135,57 @@
#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_RDWR);
+ 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 (!gralloc_legacy_ion) {
- /* We only support two heaps, so mapping between CMA/System is simple */
+ 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;
@@ -671,7 +728,7 @@
}
#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;
@@ -718,6 +775,52 @@
}
#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);
@@ -755,30 +858,11 @@
#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;
}
-
- gralloc_legacy_ion = ion_is_legacy(m->ion_client);
-
- if (!gralloc_legacy_ion)
- {
- system_heap_id = find_ion_heap_id(m->ion_client, ION_SYSTEM);
- cma_heap_id = find_ion_heap_id(m->ion_client, ION_CMA);
- if (system_heap_id < 0 || cma_heap_id < 0)
- {
- delete dev;
- ion_close(m->ion_client);
- m->ion_client = -1;
- return -1;
- }
- }
-
#endif
*device = &dev->common;