/*
 * SPDX-FileCopyrightText: Copyright 2021-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
 * SPDX-License-Identifier: GPL-2.0-only
 *
 * 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.
 */

#include <linux/dma-mapping.h>
#include <linux/dma-direct.h>
#include <linux/firmware.h>
#include <linux/io.h>
#include <linux/irqreturn.h>
#include <linux/kernel.h>
#include <linux/mailbox_client.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/remoteproc.h>
#include <linux/reset.h>
#include <linux/version.h>
#include <linux/workqueue.h>

/****************************************************************************
 * Defines
 ****************************************************************************/

#define DMA_ADDR_BITS 32 /* Number of address bits */

#define ETHOSU_RPROC_DRIVER_VERSION "0.0.1"

#define DEFAULT_FW_FILE "arm-ethos-u65.fw"
#define DEFAULT_AUTO_BOOT false

/* firmware naming module parameter */
static char fw_filename_param[256] = DEFAULT_FW_FILE;

/* As the remoteproc is setup at probe, just allow the filename readonly */
module_param_string(filename, fw_filename_param, sizeof(fw_filename_param),
		    0444);
MODULE_PARM_DESC(filename,
		 "Filename for firmware image for Ethos-U remoteproc");

static bool auto_boot = DEFAULT_AUTO_BOOT;
module_param(auto_boot, bool, 0);
MODULE_PARM_DESC(auto_boot, "Set to one to auto boot at load.");

#define RSC_MAPPING RSC_VENDOR_START + 1

/**
 * struct fw_rsc_map_range - memory map range
 * @da:		Start device address of the memory address range
 * @pa:		Start physical address of the memory address range
 * @len:	length of memory address range
 *
 * Memory range to translate between physical and device addresses.
 */
struct fw_rsc_map_range {
	uint32_t da;
	uint32_t pa;
	uint32_t len;
} __packed;

/**
 * struct fw_rsc_mapping - memory map for address translation
 * @num_ranges:	Number of ranges in the memory map
 * @range:	Array of the ranges in the memory map
 *
 * This resource entry requests the host to provide information for how to
 * translate between physical and device addresses.
 */
struct fw_rsc_mapping {
	uint8_t                 num_ranges;
	struct fw_rsc_map_range range[0];
} __packed;

struct ethosu_rproc {
	struct device           *dev;
	struct reset_control    *rstc;
	struct mbox_client      mbox_client;
	struct mbox_chan        *ch_rx;
	struct mbox_chan        *ch_tx;
	struct workqueue_struct *wq;
	struct work_struct      work;
};

/* declaration is in remoteproc_internal.h */
extern irqreturn_t rproc_vq_interrupt(struct rproc *rproc,
				      int vq_id);

static void ethosu_mbox_bottom(struct work_struct *work)
{
	struct ethosu_rproc *erproc = container_of(
		work, struct ethosu_rproc, work);
	struct rproc *rproc = dev_get_drvdata(erproc->dev);

	dev_dbg(&rproc->dev, "Handle interrupt");

	rproc_vq_interrupt(rproc, 0);
}

static void ethosu_mbox_top(struct mbox_client *client,
			    void *message)
{
	struct ethosu_rproc *erproc = container_of(
		client, struct ethosu_rproc, mbox_client);

	queue_work(erproc->wq, &erproc->work);
}

static int ethosu_add_carveout(struct rproc *rproc,
			       const phys_addr_t pa,
			       const size_t size,
			       const char *name)
{
	struct device *dev = rproc->dev.parent;
	dma_addr_t da;
	void __iomem *va;
	struct rproc_mem_entry *mem;

	da = translate_phys_to_dma(dev, pa);
	dev_dbg(dev, "PA to DA. pa=0x%pa, da=0x%pad", &pa, &da);
	if (da == DMA_MAPPING_ERROR) {
		dev_err(dev, "No mapping found for PA. pa=%pa, size=%zu", &pa,
			size);

		return -ENOMEM;
	}

	va = devm_ioremap_wc(dev, pa, size);
	if (!va) {
		dev_err(dev, "Failed to remap address. pa=%pa, len=%zu", &pa,
			size);

		return -ENOMEM;
	}

	mem = rproc_mem_entry_init(dev, va, pa, size, da, NULL, NULL, name);
	if (!mem)
		return -ENOMEM;

	dev_info(dev, "Add carveout mapping. dma=%pad, da=%x, va=%p, len=%zu",
		 &mem->dma, mem->da, mem->va, mem->len);

	rproc_add_carveout(rproc, mem);

	return 0;
}

static int ethosu_rproc_prepare(struct rproc *rproc)
{
	struct device *dev = rproc->dev.parent;
	struct device_node *np = dev->of_node;
	struct of_phandle_iterator it;
	struct resource res;
	int i;
	int ret;

	dev_info(dev, "Preparing Ethos-U");

	/* Add carveout for each 'reg' device tree entry */
	for (i = 0; of_address_to_resource(np, i, &res) == 0; i++) {
		dev_info(dev, "Found resource. start=%llx, size=%llx",
			 res.start, resource_size(&res));

		ret = ethosu_add_carveout(rproc, res.start,
					  resource_size(&res), res.name);
		if (ret)
			return ret;
	}

	of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
	while (of_phandle_iterator_next(&it) == 0) {
		struct reserved_mem *res_mem = of_reserved_mem_lookup(it.node);

		if (!res_mem) {
			dev_err(dev, "Failed to look up memory region. node=%p",
				it.node);

			return -EINVAL;
		}

		dev_info(dev,
			 "Found memory region. pa=%llx, size=%llu, name=%s",
			 res_mem->base, res_mem->size, it.node->name);

		ret = ethosu_add_carveout(rproc, res_mem->base, res_mem->size,
					  it.node->name);
		if (ret)
			return ret;
	}

	return 0;
}

static int ethosu_rproc_start(struct rproc *rproc)
{
	struct ethosu_rproc *erproc = (struct ethosu_rproc *)rproc->priv;
	struct device *dev = erproc->dev;

	dev_info(dev, "Starting up Ethos-U subsystem CPU");

	return reset_control_deassert(erproc->rstc);
}

static int ethosu_rproc_stop(struct rproc *rproc)
{
	struct ethosu_rproc *erproc = (struct ethosu_rproc *)rproc->priv;
	struct device *dev = erproc->dev;

	dev_info(dev, "Stopping Ethos-U subsystem CPU");

	return reset_control_assert(erproc->rstc);
}

static void ethosu_rproc_kick(struct rproc *rproc,
			      int vqid)
{
	struct ethosu_rproc *erproc = (struct ethosu_rproc *)rproc->priv;

	dev_dbg(&rproc->dev, "Kicking Ethos-U remoteproc vqid: %d!", vqid);

	mbox_send_message(erproc->ch_tx, (void *)&vqid);
}

static int ethosu_rproc_handle_rsc(struct rproc *rproc,
				   u32 rsc_type,
				   void *rsc,
				   int offset,
				   int avail)
{
	struct ethosu_rproc *erproc = (struct ethosu_rproc *)rproc->priv;
	struct device *dev = erproc->dev;
	struct fw_rsc_mapping *mapping = rsc;
	const struct bus_dma_region *map;
	size_t num_ranges = 0U;
	size_t i;

	if (rsc_type != RSC_MAPPING)
		return RSC_IGNORED;

	if (struct_size(mapping, range, mapping->num_ranges) > avail) {
		dev_err(dev, "mapping rsc is truncated\n");

		return -EINVAL;
	}

	for (map = dev->dma_range_map; map->size; ++map)
		num_ranges++;

	if (num_ranges > mapping->num_ranges) {
		dev_err(dev,
			"Mapping rsc doesn't have enough room for DMA ranges\n");

		return -EINVAL;
	}

	for (i = 0U; i < num_ranges; ++i) {
		struct fw_rsc_map_range *range = &mapping->range[i];
		map = &dev->dma_range_map[i];

		range->da = map->dma_start;
		range->pa = map->cpu_start;
		range->len = map->size;
	}

	dev_dbg(dev, "handle_rsc: Mapping rsc setup");

	return RSC_HANDLED;
}

static const struct rproc_ops ethosu_rproc_ops = {
	.prepare    = &ethosu_rproc_prepare,
	.start      = &ethosu_rproc_start,
	.stop       = &ethosu_rproc_stop,
	.kick       = &ethosu_rproc_kick,
	.handle_rsc = &ethosu_rproc_handle_rsc,
};

static int ethosu_mailbox_init(struct ethosu_rproc *erproc)
{
	struct device *dev = erproc->dev;
	struct mbox_client *cl = &erproc->mbox_client;

	INIT_WORK(&erproc->work, ethosu_mbox_bottom);

	erproc->wq = create_singlethread_workqueue("ethosu_rproc_wq");
	if (!erproc->wq) {
		dev_err(dev, "Failed to create work queue");

		return -EINVAL;
	}

	cl->dev = dev;
	cl->rx_callback = ethosu_mbox_top;
	cl->tx_prepare = NULL;
	cl->tx_done = NULL;
	cl->tx_block = true;
	cl->knows_txdone = false;
	cl->tx_tout = 500;

	erproc->ch_rx = mbox_request_channel_byname(cl, "rx");
	if (IS_ERR(erproc->ch_rx)) {
		dev_err(dev, "Failed to request mbox chan rx");

		return PTR_ERR(erproc->ch_rx);
	}

	erproc->ch_tx = mbox_request_channel_byname(cl, "tx");
	if (IS_ERR(erproc->ch_tx)) {
		dev_info(dev, "Using same channel for RX and TX");
		erproc->ch_tx = erproc->ch_rx;
	}

	return 0;
}

static const struct of_device_id ethosu_rproc_match[] = {
	{ .compatible = "arm,ethosu-rproc" },
	{ /* sentinel */ },
};

static int ethosu_rproc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct ethosu_rproc *erproc;
	struct rproc *rproc;
	int ret;

	/* map the first 'memory-region' for DMA-mapping */
	ret = of_reserved_mem_device_init(dev);
	if (ret)
		return ret;

	dma_set_mask_and_coherent(dev, DMA_BIT_MASK(DMA_ADDR_BITS));

	rproc = devm_rproc_alloc(dev, np->name, &ethosu_rproc_ops,
				 fw_filename_param,
				 sizeof(*erproc));
	if (!rproc)
		return -ENOMEM;

	platform_set_drvdata(pdev, rproc);

	/* Configure rproc */
	rproc->has_iommu = false;
	rproc->auto_boot = auto_boot;

	/* Configure Ethos-U rproc */
	erproc = rproc->priv;
	erproc->dev = dev;

	/* Get the reset handler for the subsystem */
	erproc->rstc = devm_reset_control_get_exclusive_by_index(dev, 0);
	if (IS_ERR(erproc->rstc)) {
		dev_err(&pdev->dev, "Failed to get reset controller.");

		return PTR_ERR(erproc->rstc);
	}

	/* Allocate and initialize mailbox client */
	ret = ethosu_mailbox_init(erproc);
	if (ret)
		return ret;

	ret = rproc_add(rproc);
	if (ret) {
		dev_err(dev, "Failed to add rproc");
		goto free_mbox;
	}

	return 0;

free_mbox:
	if (erproc->wq)
		destroy_workqueue(erproc->wq);

	mbox_free_channel(erproc->ch_rx);

	if (erproc->ch_tx != erproc->ch_rx)
		mbox_free_channel(erproc->ch_tx);

	return ret;
}

static int ethosu_rproc_remove(struct platform_device *pdev)
{
	struct rproc *rproc = platform_get_drvdata(pdev);
	struct ethosu_rproc *erproc = rproc->priv;

	if (erproc->wq)
		destroy_workqueue(erproc->wq);

	if (erproc->ch_tx != erproc->ch_rx)
		mbox_free_channel(erproc->ch_tx);

	mbox_free_channel(erproc->ch_rx);

	rproc_del(rproc);

	return 0;
}

static struct platform_driver ethosu_rproc_driver = {
	.probe                  = ethosu_rproc_probe,
	.remove                 = ethosu_rproc_remove,
	.driver                 = {
		.name           = "ethosu-rproc",
		.of_match_table = of_match_ptr(ethosu_rproc_match),
	},
};

module_platform_driver(ethosu_rproc_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Arm Ltd");
MODULE_DESCRIPTION("Arm Ethos-U NPU RemoteProc Driver");
MODULE_VERSION(ETHOSU_RPROC_DRIVER_VERSION);
