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;