// SPDX-License-Identifier: GPL-2.0-only
/*
 * TI AMx3 Wakeup M3 Remote Processor driver
 *
 * Copyright (C) 2014-2015 Texas Instruments, Inc.
 *
 * Dave Gerlach <d-gerlach@ti.com>
 * Suman Anna <s-anna@ti.com>
 */

#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/remoteproc.h>
#include <linux/reset.h>

#include <linux/platform_data/wkup_m3.h>

#include "remoteproc_internal.h"

#define WKUPM3_MEM_MAX	2

/**
 * struct wkup_m3_mem - WkupM3 internal memory structure
 * @cpu_addr: MPU virtual address of the memory region
 * @bus_addr: Bus address used to access the memory region
 * @dev_addr: Device address from Wakeup M3 view
 * @size: Size of the memory region
 */
struct wkup_m3_mem {
	void __iomem *cpu_addr;
	phys_addr_t bus_addr;
	u32 dev_addr;
	size_t size;
};

/**
 * struct wkup_m3_rproc - WkupM3 remote processor state
 * @rproc: rproc handle
 * @pdev: pointer to platform device
 * @mem: WkupM3 memory information
 * @rsts: reset control
 */
struct wkup_m3_rproc {
	struct rproc *rproc;
	struct platform_device *pdev;
	struct wkup_m3_mem mem[WKUPM3_MEM_MAX];
	struct reset_control *rsts;
};

static int wkup_m3_rproc_start(struct rproc *rproc)
{
	struct wkup_m3_rproc *wkupm3 = rproc->priv;
	struct platform_device *pdev = wkupm3->pdev;
	struct device *dev = &pdev->dev;
	struct wkup_m3_platform_data *pdata = dev_get_platdata(dev);
	int error = 0;

	error = reset_control_deassert(wkupm3->rsts);

	if (!wkupm3->rsts && pdata->deassert_reset(pdev, pdata->reset_name)) {
		dev_err(dev, "Unable to reset wkup_m3!\n");
		error = -ENODEV;
	}

	return error;
}

static int wkup_m3_rproc_stop(struct rproc *rproc)
{
	struct wkup_m3_rproc *wkupm3 = rproc->priv;
	struct platform_device *pdev = wkupm3->pdev;
	struct device *dev = &pdev->dev;
	struct wkup_m3_platform_data *pdata = dev_get_platdata(dev);
	int error = 0;

	error = reset_control_assert(wkupm3->rsts);

	if (!wkupm3->rsts && pdata->assert_reset(pdev, pdata->reset_name)) {
		dev_err(dev, "Unable to assert reset of wkup_m3!\n");
		error = -ENODEV;
	}

	return error;
}

static void *wkup_m3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len)
{
	struct wkup_m3_rproc *wkupm3 = rproc->priv;
	void *va = NULL;
	int i;
	u32 offset;

	if (len == 0)
		return NULL;

	for (i = 0; i < WKUPM3_MEM_MAX; i++) {
		if (da >= wkupm3->mem[i].dev_addr && da + len <=
		    wkupm3->mem[i].dev_addr +  wkupm3->mem[i].size) {
			offset = da -  wkupm3->mem[i].dev_addr;
			/* __force to make sparse happy with type conversion */
			va = (__force void *)(wkupm3->mem[i].cpu_addr + offset);
			break;
		}
	}

	return va;
}

static const struct rproc_ops wkup_m3_rproc_ops = {
	.start		= wkup_m3_rproc_start,
	.stop		= wkup_m3_rproc_stop,
	.da_to_va	= wkup_m3_rproc_da_to_va,
};

static const struct of_device_id wkup_m3_rproc_of_match[] = {
	{ .compatible = "ti,am3352-wkup-m3", },
	{ .compatible = "ti,am4372-wkup-m3", },
	{},
};
MODULE_DEVICE_TABLE(of, wkup_m3_rproc_of_match);

static int wkup_m3_rproc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct wkup_m3_platform_data *pdata = dev->platform_data;
	/* umem always needs to be processed first */
	const char *mem_names[WKUPM3_MEM_MAX] = { "umem", "dmem" };
	struct wkup_m3_rproc *wkupm3;
	const char *fw_name;
	struct rproc *rproc;
	struct resource *res;
	const __be32 *addrp;
	u32 l4_offset = 0;
	u64 size;
	int ret;
	int i;

	ret = of_property_read_string(dev->of_node, "ti,pm-firmware",
				      &fw_name);
	if (ret) {
		dev_err(dev, "No firmware filename given\n");
		return -ENODEV;
	}

	pm_runtime_enable(&pdev->dev);
	ret = pm_runtime_get_sync(&pdev->dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n");
		goto err;
	}

	rproc = rproc_alloc(dev, "wkup_m3", &wkup_m3_rproc_ops,
			    fw_name, sizeof(*wkupm3));
	if (!rproc) {
		ret = -ENOMEM;
		goto err;
	}

	rproc->auto_boot = false;

	wkupm3 = rproc->priv;
	wkupm3->rproc = rproc;
	wkupm3->pdev = pdev;

	wkupm3->rsts = devm_reset_control_get_optional_shared(dev, "rstctrl");
	if (IS_ERR(wkupm3->rsts))
		return PTR_ERR(wkupm3->rsts);
	if (!wkupm3->rsts) {
		if (!(pdata && pdata->deassert_reset && pdata->assert_reset &&
		      pdata->reset_name)) {
			dev_err(dev, "Platform data missing!\n");
			ret = -ENODEV;
			goto err_put_rproc;
		}
	}

	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
						   mem_names[i]);
		wkupm3->mem[i].cpu_addr = devm_ioremap_resource(dev, res);
		if (IS_ERR(wkupm3->mem[i].cpu_addr)) {
			dev_err(&pdev->dev, "devm_ioremap_resource failed for resource %d\n",
				i);
			ret = PTR_ERR(wkupm3->mem[i].cpu_addr);
			goto err_put_rproc;
		}
		wkupm3->mem[i].bus_addr = res->start;
		wkupm3->mem[i].size = resource_size(res);
		addrp = of_get_address(dev->of_node, i, &size, NULL);
		/*
		 * The wkupm3 has umem at address 0 in its view, so the device
		 * addresses for each memory region is computed as a relative
		 * offset of the bus address for umem, and therefore needs to be
		 * processed first.
		 */
		if (!strcmp(mem_names[i], "umem"))
			l4_offset = be32_to_cpu(*addrp);
		wkupm3->mem[i].dev_addr = be32_to_cpu(*addrp) - l4_offset;
	}

	dev_set_drvdata(dev, rproc);

	ret = rproc_add(rproc);
	if (ret) {
		dev_err(dev, "rproc_add failed\n");
		goto err_put_rproc;
	}

	return 0;

err_put_rproc:
	rproc_free(rproc);
err:
	pm_runtime_put_noidle(dev);
	pm_runtime_disable(dev);
	return ret;
}

static int wkup_m3_rproc_remove(struct platform_device *pdev)
{
	struct rproc *rproc = platform_get_drvdata(pdev);

	rproc_del(rproc);
	rproc_free(rproc);
	pm_runtime_put_sync(&pdev->dev);
	pm_runtime_disable(&pdev->dev);

	return 0;
}

#ifdef CONFIG_PM
static int wkup_m3_rpm_suspend(struct device *dev)
{
	return -EBUSY;
}

static int wkup_m3_rpm_resume(struct device *dev)
{
	return 0;
}
#endif

static const struct dev_pm_ops wkup_m3_rproc_pm_ops = {
	SET_RUNTIME_PM_OPS(wkup_m3_rpm_suspend, wkup_m3_rpm_resume, NULL)
};

static struct platform_driver wkup_m3_rproc_driver = {
	.probe = wkup_m3_rproc_probe,
	.remove = wkup_m3_rproc_remove,
	.driver = {
		.name = "wkup_m3_rproc",
		.of_match_table = wkup_m3_rproc_of_match,
		.pm = &wkup_m3_rproc_pm_ops,
	},
};

module_platform_driver(wkup_m3_rproc_driver);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("TI Wakeup M3 remote processor control driver");
MODULE_AUTHOR("Dave Gerlach <d-gerlach@ti.com>");
