Merge changes I1c0be5f8,Id837c19a
* changes:
gralloc960: Extend gralloc to use dmabuf heaps
hikey/hikey960: Add userland support for dmabuf heap dev dir
diff --git a/gralloc960/dma-heap.h b/gralloc960/dma-heap.h
new file mode 100644
index 0000000..6f84fa0
--- /dev/null
+++ b/gralloc960/dma-heap.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * DMABUF Heaps Userspace API
+ *
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2019 Linaro Ltd.
+ */
+#ifndef _UAPI_LINUX_DMABUF_POOL_H
+#define _UAPI_LINUX_DMABUF_POOL_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/**
+ * DOC: DMABUF Heaps Userspace API
+ */
+
+/* Valid FD_FLAGS are O_CLOEXEC, O_RDONLY, O_WRONLY, O_RDWR */
+#define DMA_HEAP_VALID_FD_FLAGS (O_CLOEXEC | O_ACCMODE)
+
+/* Currently no heap flags */
+#define DMA_HEAP_VALID_HEAP_FLAGS (0)
+
+/**
+ * struct dma_heap_allocation_data - metadata passed from userspace for
+ * allocations
+ * @len: size of the allocation
+ * @fd: will be populated with a fd which provides the
+ * handle to the allocated dma-buf
+ * @fd_flags: file descriptor flags used when allocating
+ * @heap_flags: flags passed to heap
+ *
+ * Provided by userspace as an argument to the ioctl
+ */
+struct dma_heap_allocation_data {
+ __u64 len;
+ __u32 fd;
+ __u32 fd_flags;
+ __u64 heap_flags;
+};
+
+#define DMA_HEAP_IOC_MAGIC 'H'
+
+/**
+ * DOC: DMA_HEAP_IOCTL_ALLOC - allocate memory from pool
+ *
+ * Takes a dma_heap_allocation_data struct and returns it with the fd field
+ * populated with the dmabuf handle of the allocation.
+ */
+#define DMA_HEAP_IOCTL_ALLOC _IOWR(DMA_HEAP_IOC_MAGIC, 0x0,\
+ struct dma_heap_allocation_data)
+
+#endif /* _UAPI_LINUX_DMABUF_POOL_H */
diff --git a/gralloc960/mali_gralloc_ion.cpp b/gralloc960/mali_gralloc_ion.cpp
index 5fb5179..d688de1 100644
--- a/gralloc960/mali_gralloc_ion.cpp
+++ b/gralloc960/mali_gralloc_ion.cpp
@@ -45,12 +45,21 @@
#include "mali_gralloc_usages.h"
#include "mali_gralloc_bufferdescriptor.h"
#include "ion_4.12.h"
-
+#include "dma-heap.h"
#define ION_SYSTEM (char*)"ion_system_heap"
#define ION_CMA (char*)"linux,cma"
-static bool gralloc_legacy_ion;
+
+#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;
@@ -150,18 +159,63 @@
return heap_id;
}
+#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) {
+ 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);
}
@@ -170,10 +224,11 @@
ion_user_handle_t ion_hnd = -1;
int shared_fd, ret;
- if ((ion_fd < 0) || (size <= 0) || (heap_mask == 0) || (min_pgsz == NULL))
- {
+ if ((interface_ver != INTERFACE_DMABUF_HEAPS) && (ion_fd < 0))
return -1;
- }
+
+ if ((size <= 0) || (heap_mask == 0) || (min_pgsz == NULL))
+ return -1;
ret = alloc_ion_fd(ion_fd, size, heap_mask, flags, &(shared_fd));
if (ret < 0)
@@ -378,6 +433,55 @@
return max_buffer_index;
}
+
+
+static int initialize_interface(mali_gralloc_module *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 mali_gralloc_ion_allocate(mali_gralloc_module *m, const gralloc_buffer_descriptor_t *descriptors,
uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend)
{
@@ -389,33 +493,17 @@
int shared_fd, ret, ion_flags = 0;
int min_pgsz = 0;
- if (m->ion_client < 0)
- {
- m->ion_client = ion_open();
+ ret = initialize_interface(m);
+ if (ret)
+ return ret;
- if (m->ion_client < 0)
- {
+ /* we may need to reopen the /dev/ion device */
+ if ((interface_ver != INTERFACE_DMABUF_HEAPS) && (m->ion_client < 0)) {
+ m->ion_client = ion_open();
+ if (m->ion_client < 0) {
AERR("ion_open failed with %s", strerror(errno));
return -1;
}
-
- gralloc_legacy_ion = ion_is_legacy(m->ion_client);
- if (!gralloc_legacy_ion)
- {
- 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;
- }
- }
}
*shared_backend = check_buffers_sharable(descriptors, numDescriptors);
@@ -603,7 +691,7 @@
void mali_gralloc_ion_sync(const mali_gralloc_module *m, private_handle_t *hnd)
{
- if (!gralloc_legacy_ion)
+ if (interface_ver != INTERFACE_ION_LEGACY)
return;
if (m != NULL && hnd != NULL)
@@ -644,23 +732,6 @@
break;
}
- /* the test condition is set to m->ion_client <= 0 here, because:
- * 1) module structure are initialized to 0 if no initial value is applied
- * 2) a second user process should get a ion fd greater than 0.
- */
- if (m->ion_client <= 0)
- {
- /* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/
- m->ion_client = ion_open();
-
- if (m->ion_client < 0)
- {
- AERR("Could not open ion device for handle: %p", hnd);
- retval = -errno;
- break;
- }
- }
-
mappedAddress = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_fd, 0);
if (MAP_FAILED == mappedAddress)
diff --git a/sepolicy/file_contexts b/sepolicy/file_contexts
index 5c010f0..0fb634c 100644
--- a/sepolicy/file_contexts
+++ b/sepolicy/file_contexts
@@ -13,7 +13,7 @@
/dev/hifi_misc u:object_r:audio_device:s0
/dev/hi_vdec u:object_r:video_device:s0
/dev/hi_venc u:object_r:video_device:s0
-
+/dev/dma_heap(/.*)? u:object_r:graphics_device:s0
/dev/graphics/fb0 u:object_r:graphics_device:s0
# files in /vendor
diff --git a/ueventd.common.rc b/ueventd.common.rc
index b7dd505..7f37c25 100644
--- a/ueventd.common.rc
+++ b/ueventd.common.rc
@@ -1,5 +1,9 @@
modalias_handling enabled
+subsystem dma_heap
+ devname uevent_devpath
+ dirname /dev/dma_heap
+
subsystem usbmisc
devname uevent_devname
@@ -14,6 +18,8 @@
/dev/hi_vdec 0660 system camera
/dev/hi_venc 0660 system camera
/dev/ion 0666 system graphics
+/dev/dma_heap/system 0666 system graphics
+/dev/dma_heap/linux,cma 0666 system graphics
/dev/graphics/fb0 0666 system graphics
/sys/devices/platform/ddr_devfreq/devfreq/ddr_devfreq min_freq 0644 system system