/*
 * (C) COPYRIGHT 2020 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 * SPDX-License-Identifier: GPL-2.0-only
 */

/****************************************************************************
 * Includes
 ****************************************************************************/

#include "ethosu_buffer.h"

#include "ethosu_device.h"
#include "uapi/ethosu.h"

#include <linux/anon_inodes.h>
#include <linux/dma-mapping.h>
#include <linux/of_address.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

/****************************************************************************
 * Variables
 ****************************************************************************/

static int ethosu_buffer_release(struct inode *inode,
				 struct file *file);

static int ethosu_buffer_mmap(struct file *file,
			      struct vm_area_struct *vma);

static long ethosu_buffer_ioctl(struct file *file,
				unsigned int cmd,
				unsigned long arg);

static const struct file_operations ethosu_buffer_fops = {
	.release        = &ethosu_buffer_release,
	.mmap           = &ethosu_buffer_mmap,
	.unlocked_ioctl = &ethosu_buffer_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl   = &ethosu_buffer_ioctl,
#endif
};

/****************************************************************************
 * Functions
 ****************************************************************************/

/*
 * The 'dma-ranges' device tree property for shared dma memory does not seem
 * to be fully supported for coherent memory. Therefor we apply the DMA range
 * offset ourselves.
 */
static dma_addr_t ethosu_buffer_dma_ranges(struct device *dev,
					   dma_addr_t dma_addr)
{
	struct device_node *node = dev->of_node;
	const __be32 *ranges;
	int len;
	int naddr;
	int nsize;
	int inc;
	int i;

	if (!node)
		return dma_addr;

	/* Get the #address-cells and #size-cells properties */
	naddr = of_n_addr_cells(node);
	nsize = of_n_size_cells(node);

	/* Read the 'dma-ranges' property */
	ranges = of_get_property(node, "dma-ranges", &len);
	if (!ranges || len <= 0)
		return dma_addr;

	dev_dbg(dev, "ranges=%p, len=%d, naddr=%d, nsize=%d\n",
		ranges, len, naddr, nsize);

	len /= sizeof(*ranges);
	inc = naddr + naddr + nsize;

	for (i = 0; (i + inc) <= len; i += inc) {
		dma_addr_t daddr;
		dma_addr_t paddr;
		dma_addr_t size;

		daddr = of_read_number(&ranges[i], naddr);
		paddr = of_read_number(&ranges[i + naddr], naddr);
		size = of_read_number(&ranges[i + naddr + naddr], nsize);

		dev_dbg(dev, "daddr=0x%llx, paddr=0x%llx, size=0x%llx\n",
			daddr, paddr, size);

		if (dma_addr >= paddr && dma_addr < (paddr + size))
			return dma_addr + daddr - paddr;
	}

	return dma_addr;
}

static bool ethosu_buffer_verify(struct file *file)
{
	return file->f_op == &ethosu_buffer_fops;
}

static void ethosu_buffer_destroy(struct kref *kref)
{
	struct ethosu_buffer *buf =
		container_of(kref, struct ethosu_buffer, kref);

	dev_info(buf->edev->dev, "Buffer destroy. handle=0x%pK\n", buf);

	dma_free_coherent(buf->edev->dev, buf->capacity, buf->cpu_addr,
			  buf->dma_addr_orig);
	devm_kfree(buf->edev->dev, buf);
}

static int ethosu_buffer_release(struct inode *inode,
				 struct file *file)
{
	struct ethosu_buffer *buf = file->private_data;

	dev_info(buf->edev->dev, "Buffer release. handle=0x%pK\n", buf);

	ethosu_buffer_put(buf);

	return 0;
}

static int ethosu_buffer_mmap(struct file *file,
			      struct vm_area_struct *vma)
{
	struct ethosu_buffer *buf = file->private_data;
	int ret;

	dev_info(buf->edev->dev, "Buffer mmap. handle=0x%pK\n", buf);

	ret = dma_mmap_coherent(buf->edev->dev, vma, buf->cpu_addr,
				buf->dma_addr_orig,
				buf->capacity);

	return ret;
}

static long ethosu_buffer_ioctl(struct file *file,
				unsigned int cmd,
				unsigned long arg)
{
	struct ethosu_buffer *buf = file->private_data;
	void __user *udata = (void __user *)arg;
	int ret = -EINVAL;

	ret = mutex_lock_interruptible(&buf->edev->mutex);
	if (ret)
		return ret;

	dev_info(buf->edev->dev, "Ioctl. cmd=%u, arg=%lu\n", cmd, arg);

	switch (cmd) {
	case ETHOSU_IOCTL_BUFFER_SET: {
		struct ethosu_uapi_buffer uapi;

		if (copy_from_user(&uapi, udata, sizeof(uapi)))
			break;

		dev_info(buf->edev->dev,
			 "Ioctl: Buffer set. size=%u, offset=%u\n",
			 uapi.size, uapi.offset);

		ret = ethosu_buffer_resize(buf, uapi.size, uapi.offset);
		break;
	}
	case ETHOSU_IOCTL_BUFFER_GET: {
		struct ethosu_uapi_buffer uapi;

		uapi.size = buf->size;
		uapi.offset = buf->offset;

		dev_info(buf->edev->dev,
			 "Ioctl: Buffer get. size=%u, offset=%u\n",
			 uapi.size, uapi.offset);

		if (copy_to_user(udata, &uapi, sizeof(uapi)))
			break;

		ret = 0;
		break;
	}
	default: {
		dev_err(buf->edev->dev, "Invalid ioctl. cmd=%u, arg=%lu",
			cmd, arg);
		break;
	}
	}

	mutex_unlock(&buf->edev->mutex);

	return ret;
}

int ethosu_buffer_create(struct ethosu_device *edev,
			 size_t capacity)
{
	struct ethosu_buffer *buf;
	int ret = -ENOMEM;

	buf = devm_kzalloc(edev->dev, sizeof(*buf), GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	buf->edev = edev;
	buf->capacity = capacity;
	buf->offset = 0;
	buf->size = 0;
	kref_init(&buf->kref);

	buf->cpu_addr = dma_alloc_coherent(buf->edev->dev, capacity,
					   &buf->dma_addr_orig, GFP_KERNEL);
	if (!buf->cpu_addr)
		goto free_buf;

	buf->dma_addr = ethosu_buffer_dma_ranges(buf->edev->dev,
						 buf->dma_addr_orig);

	ret = anon_inode_getfd("ethosu-buffer", &ethosu_buffer_fops, buf,
			       O_RDWR | O_CLOEXEC);
	if (ret < 0)
		goto free_dma;

	buf->file = fget(ret);
	fput(buf->file);

	dev_info(buf->edev->dev,
		 "Buffer create. handle=0x%pK, capacity=%zu, cpu_addr=0x%pK, dma_addr=0x%llx, dma_addr_orig=0x%llx, phys_addr=0x%llx\n",
		 buf, capacity, buf->cpu_addr, buf->dma_addr,
		 buf->dma_addr_orig, virt_to_phys(buf->cpu_addr));

	return ret;

free_dma:
	dma_free_coherent(buf->edev->dev, buf->capacity, buf->cpu_addr,
			  buf->dma_addr_orig);

free_buf:
	devm_kfree(buf->edev->dev, buf);

	return ret;
}

struct ethosu_buffer *ethosu_buffer_get_from_fd(int fd)
{
	struct ethosu_buffer *buf;
	struct file *file;

	file = fget(fd);
	if (!file)
		return ERR_PTR(-EINVAL);

	if (!ethosu_buffer_verify(file)) {
		fput(file);

		return ERR_PTR(-EINVAL);
	}

	buf = file->private_data;
	ethosu_buffer_get(buf);
	fput(file);

	return buf;
}

void ethosu_buffer_get(struct ethosu_buffer *buf)
{
	kref_get(&buf->kref);
}

void ethosu_buffer_put(struct ethosu_buffer *buf)
{
	kref_put(&buf->kref, ethosu_buffer_destroy);
}

int ethosu_buffer_resize(struct ethosu_buffer *buf,
			 size_t size,
			 size_t offset)
{
	if ((size + offset) > buf->capacity)
		return -EINVAL;

	buf->size = size;
	buf->offset = offset;

	return 0;
}
