Commit e8ef3b22 authored by John Stultz's avatar John Stultz Committed by Automerger Merge Worker
Browse files

yukawa: gralloc: Add dmabuf heap support am: 97ab2b29

Original change: https://android-review.googlesource.com/c/device/amlogic/yukawa/+/1720231

Change-Id: I7f2b305816af1e5af525e0318c8a18c93d884793
parents bfbdd985 97ab2b29
/* 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 */
......@@ -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 @@ static int find_heap_id(int ion_client, char *name)
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_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 (!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 @@ static int alloc_from_ion_heap(int ion_fd, size_t size, unsigned int heap_mask,
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 @@ static int get_max_buffer_descriptor_index(const gralloc_buffer_descriptor_t *de
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 mali_gralloc_ion_allocate(mali_gralloc_module *m, const gralloc_buffer_descr
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);
......@@ -604,7 +692,7 @@ static void mali_gralloc_ion_free_internal(buffer_handle_t *pHandle, uint32_t nu
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)
......@@ -645,23 +733,6 @@ int mali_gralloc_ion_map(private_handle_t *hnd)
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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment