// SPDX-License-Identifier: GPL-2.0-only
/* Copyright 2021 NXP */

#include <dt-bindings/firmware/imx/rsrc.h>
#include <linux/arm-smccc.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/firmware.h>
#include <linux/firmware/imx/sci.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mailbox_client.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/remoteproc.h>
#include <linux/slab.h>

#include "imx_rproc.h"
#include "remoteproc_elf_helpers.h"
#include "remoteproc_internal.h"

#define DSP_RPROC_CLK_MAX			5

#define REMOTE_IS_READY				BIT(0)
#define REMOTE_READY_WAIT_MAX_RETRIES		500

/* att flags */
/* DSP own area */
#define ATT_OWN					BIT(31)
/* DSP instruction area */
#define ATT_IRAM				BIT(30)

/* Definitions for i.MX8MP */
/* DAP registers */
#define IMX8M_DAP_DEBUG				0x28800000
#define IMX8M_DAP_DEBUG_SIZE			(64 * 1024)
#define IMX8M_DAP_PWRCTL			(0x4000 + 0x3020)
#define IMX8M_PWRCTL_CORERESET			BIT(16)

/* DSP audio mix registers */
#define IMX8M_AudioDSP_REG0			0x100
#define IMX8M_AudioDSP_REG1			0x104
#define IMX8M_AudioDSP_REG2			0x108
#define IMX8M_AudioDSP_REG3			0x10c

#define IMX8M_AudioDSP_REG2_RUNSTALL		BIT(5)
#define IMX8M_AudioDSP_REG2_PWAITMODE		BIT(1)

/* Definitions for i.MX8ULP */
#define IMX8ULP_SIM_LPAV_REG_SYSCTRL0		0x8
#define IMX8ULP_SYSCTRL0_DSP_DBG_RST		BIT(25)
#define IMX8ULP_SYSCTRL0_DSP_PLAT_CLK_EN	BIT(19)
#define IMX8ULP_SYSCTRL0_DSP_PBCLK_EN		BIT(18)
#define IMX8ULP_SYSCTRL0_DSP_CLK_EN		BIT(17)
#define IMX8ULP_SYSCTRL0_DSP_RST		BIT(16)
#define IMX8ULP_SYSCTRL0_DSP_OCD_HALT		BIT(14)
#define IMX8ULP_SYSCTRL0_DSP_STALL		BIT(13)

#define IMX8ULP_SIP_HIFI_XRDC			0xc200000e

/*
 * enum - Predefined Mailbox Messages
 *
 * @RP_MBOX_SUSPEND_SYSTEM: system suspend request for the remote processor
 *
 * @RP_MBOX_SUSPEND_ACK: successful response from remote processor for a
 * suspend request
 *
 * @RP_MBOX_RESUME_SYSTEM: system resume request for the remote processor
 *
 * @RP_MBOX_RESUME_ACK: successful response from remote processor for a
 * resume request
 */
enum imx_dsp_rp_mbox_messages {
	RP_MBOX_SUSPEND_SYSTEM			= 0xFF11,
	RP_MBOX_SUSPEND_ACK			= 0xFF12,
	RP_MBOX_RESUME_SYSTEM			= 0xFF13,
	RP_MBOX_RESUME_ACK			= 0xFF14,
};

/**
 * struct imx_dsp_rproc - DSP remote processor state
 * @regmap: regmap handler
 * @rproc: rproc handler
 * @dsp_dcfg: device configuration pointer
 * @clks: clocks needed by this device
 * @cl: mailbox client to request the mailbox channel
 * @cl_rxdb: mailbox client to request the mailbox channel for doorbell
 * @tx_ch: mailbox tx channel handle
 * @rx_ch: mailbox rx channel handle
 * @rxdb_ch: mailbox rx doorbell channel handle
 * @pd_dev: power domain device
 * @pd_dev_link: power domain device link
 * @ipc_handle: System Control Unit ipc handle
 * @rproc_work: work for processing virtio interrupts
 * @pm_comp: completion primitive to sync for suspend response
 * @num_domains: power domain number
 * @flags: control flags
 */
struct imx_dsp_rproc {
	struct regmap				*regmap;
	struct rproc				*rproc;
	const struct imx_dsp_rproc_dcfg		*dsp_dcfg;
	struct clk_bulk_data			clks[DSP_RPROC_CLK_MAX];
	struct mbox_client			cl;
	struct mbox_client			cl_rxdb;
	struct mbox_chan			*tx_ch;
	struct mbox_chan			*rx_ch;
	struct mbox_chan			*rxdb_ch;
	struct device				**pd_dev;
	struct device_link			**pd_dev_link;
	struct imx_sc_ipc			*ipc_handle;
	struct work_struct			rproc_work;
	struct completion			pm_comp;
	int					num_domains;
	u32					flags;
};

/**
 * struct imx_dsp_rproc_dcfg - DSP remote processor configuration
 * @dcfg: imx_rproc_dcfg handler
 * @reset: reset callback function
 */
struct imx_dsp_rproc_dcfg {
	const struct imx_rproc_dcfg		*dcfg;
	int (*reset)(struct imx_dsp_rproc *priv);
};

static const struct imx_rproc_att imx_dsp_rproc_att_imx8qm[] = {
	/* dev addr , sys addr  , size	    , flags */
	{ 0x596e8000, 0x556e8000, 0x00008000, ATT_OWN },
	{ 0x596f0000, 0x556f0000, 0x00008000, ATT_OWN },
	{ 0x596f8000, 0x556f8000, 0x00000800, ATT_OWN | ATT_IRAM},
	{ 0x55700000, 0x55700000, 0x00070000, ATT_OWN },
	/* DDR (Data) */
	{ 0x80000000, 0x80000000, 0x60000000, 0},
};

static const struct imx_rproc_att imx_dsp_rproc_att_imx8qxp[] = {
	/* dev addr , sys addr  , size	    , flags */
	{ 0x596e8000, 0x596e8000, 0x00008000, ATT_OWN },
	{ 0x596f0000, 0x596f0000, 0x00008000, ATT_OWN },
	{ 0x596f8000, 0x596f8000, 0x00000800, ATT_OWN | ATT_IRAM},
	{ 0x59700000, 0x59700000, 0x00070000, ATT_OWN },
	/* DDR (Data) */
	{ 0x80000000, 0x80000000, 0x60000000, 0},
};

static const struct imx_rproc_att imx_dsp_rproc_att_imx8mp[] = {
	/* dev addr , sys addr  , size	    , flags */
	{ 0x3b6e8000, 0x3b6e8000, 0x00008000, ATT_OWN },
	{ 0x3b6f0000, 0x3b6f0000, 0x00008000, ATT_OWN },
	{ 0x3b6f8000, 0x3b6f8000, 0x00000800, ATT_OWN | ATT_IRAM},
	{ 0x3b700000, 0x3b700000, 0x00040000, ATT_OWN },
	/* DDR (Data) */
	{ 0x40000000, 0x40000000, 0x80000000, 0},
};

static const struct imx_rproc_att imx_dsp_rproc_att_imx8ulp[] = {
	/* dev addr , sys addr  , size	    , flags */
	{ 0x21170000, 0x21170000, 0x00010000, ATT_OWN | ATT_IRAM},
	{ 0x21180000, 0x21180000, 0x00010000, ATT_OWN },
	/* DDR (Data) */
	{ 0x0c000000, 0x80000000, 0x10000000, 0},
	{ 0x30000000, 0x90000000, 0x10000000, 0},
};

/* Reset function for DSP on i.MX8MP */
static int imx8mp_dsp_reset(struct imx_dsp_rproc *priv)
{
	void __iomem *dap = ioremap_wc(IMX8M_DAP_DEBUG, IMX8M_DAP_DEBUG_SIZE);
	int pwrctl;

	/* Put DSP into reset and stall */
	pwrctl = readl(dap + IMX8M_DAP_PWRCTL);
	pwrctl |= IMX8M_PWRCTL_CORERESET;
	writel(pwrctl, dap + IMX8M_DAP_PWRCTL);

	/* Keep reset asserted for 10 cycles */
	usleep_range(1, 2);

	regmap_update_bits(priv->regmap, IMX8M_AudioDSP_REG2,
			   IMX8M_AudioDSP_REG2_RUNSTALL,
			   IMX8M_AudioDSP_REG2_RUNSTALL);

	/* Take the DSP out of reset and keep stalled for FW loading */
	pwrctl = readl(dap + IMX8M_DAP_PWRCTL);
	pwrctl &= ~IMX8M_PWRCTL_CORERESET;
	writel(pwrctl, dap + IMX8M_DAP_PWRCTL);

	iounmap(dap);
	return 0;
}

/* Reset function for DSP on i.MX8ULP */
static int imx8ulp_dsp_reset(struct imx_dsp_rproc *priv)
{
	struct arm_smccc_res res;

	/* Put DSP into reset and stall */
	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
			   IMX8ULP_SYSCTRL0_DSP_RST, IMX8ULP_SYSCTRL0_DSP_RST);
	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
			   IMX8ULP_SYSCTRL0_DSP_STALL,
			   IMX8ULP_SYSCTRL0_DSP_STALL);

	/* Configure resources of DSP through TFA */
	arm_smccc_smc(IMX8ULP_SIP_HIFI_XRDC, 0, 0, 0, 0, 0, 0, 0, &res);

	/* Take the DSP out of reset and keep stalled for FW loading */
	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
			   IMX8ULP_SYSCTRL0_DSP_RST, 0);
	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
			   IMX8ULP_SYSCTRL0_DSP_DBG_RST, 0);

	return 0;
}

/* Specific configuration for i.MX8MP */
static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8mp = {
	.src_reg	= IMX8M_AudioDSP_REG2,
	.src_mask	= IMX8M_AudioDSP_REG2_RUNSTALL,
	.src_start	= 0,
	.src_stop	= IMX8M_AudioDSP_REG2_RUNSTALL,
	.att		= imx_dsp_rproc_att_imx8mp,
	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8mp),
	.method		= IMX_RPROC_MMIO,
};

static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8mp = {
	.dcfg		= &dsp_rproc_cfg_imx8mp,
	.reset          = imx8mp_dsp_reset,
};

/* Specific configuration for i.MX8ULP */
static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8ulp = {
	.src_reg	= IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
	.src_mask	= IMX8ULP_SYSCTRL0_DSP_STALL,
	.src_start	= 0,
	.src_stop	= IMX8ULP_SYSCTRL0_DSP_STALL,
	.att		= imx_dsp_rproc_att_imx8ulp,
	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8ulp),
	.method		= IMX_RPROC_MMIO,
};

static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8ulp = {
	.dcfg		= &dsp_rproc_cfg_imx8ulp,
	.reset          = imx8ulp_dsp_reset,
};

/* Specific configuration for i.MX8QXP */
static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8qxp = {
	.att		= imx_dsp_rproc_att_imx8qxp,
	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8qxp),
	.method		= IMX_RPROC_SCU_API,
};

static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qxp = {
	.dcfg		= &dsp_rproc_cfg_imx8qxp,
};

/* Specific configuration for i.MX8QM */
static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8qm = {
	.att		= imx_dsp_rproc_att_imx8qm,
	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8qm),
	.method		= IMX_RPROC_SCU_API,
};

static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qm = {
	.dcfg		= &dsp_rproc_cfg_imx8qm,
};

static int imx_dsp_rproc_ready(struct rproc *rproc)
{
	struct imx_dsp_rproc *priv = rproc->priv;
	int i;

	if (!priv->rxdb_ch)
		return 0;

	for (i = 0; i < REMOTE_READY_WAIT_MAX_RETRIES; i++) {
		if (priv->flags & REMOTE_IS_READY)
			return 0;
		usleep_range(100, 200);
	}

	return -ETIMEDOUT;
}

/*
 * Start function for rproc_ops
 *
 * There is a handshake for start procedure: when DSP starts, it
 * will send a doorbell message to this driver, then the
 * REMOTE_IS_READY flags is set, then driver will kick
 * a message to DSP.
 */
static int imx_dsp_rproc_start(struct rproc *rproc)
{
	struct imx_dsp_rproc *priv = rproc->priv;
	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
	const struct imx_rproc_dcfg *dcfg = dsp_dcfg->dcfg;
	struct device *dev = rproc->dev.parent;
	int ret;

	switch (dcfg->method) {
	case IMX_RPROC_MMIO:
		ret = regmap_update_bits(priv->regmap,
					 dcfg->src_reg,
					 dcfg->src_mask,
					 dcfg->src_start);
		break;
	case IMX_RPROC_SCU_API:
		ret = imx_sc_pm_cpu_start(priv->ipc_handle,
					  IMX_SC_R_DSP,
					  true,
					  rproc->bootaddr);
		break;
	default:
		return -EOPNOTSUPP;
	}

	if (ret)
		dev_err(dev, "Failed to enable remote core!\n");
	else
		ret = imx_dsp_rproc_ready(rproc);

	return ret;
}

/*
 * Stop function for rproc_ops
 * It clears the REMOTE_IS_READY flags
 */
static int imx_dsp_rproc_stop(struct rproc *rproc)
{
	struct imx_dsp_rproc *priv = rproc->priv;
	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
	const struct imx_rproc_dcfg *dcfg = dsp_dcfg->dcfg;
	struct device *dev = rproc->dev.parent;
	int ret = 0;

	/* Make sure work is finished */
	flush_work(&priv->rproc_work);

	if (rproc->state == RPROC_CRASHED) {
		priv->flags &= ~REMOTE_IS_READY;
		return 0;
	}

	switch (dcfg->method) {
	case IMX_RPROC_MMIO:
		ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
					 dcfg->src_stop);
		break;
	case IMX_RPROC_SCU_API:
		ret = imx_sc_pm_cpu_start(priv->ipc_handle,
					  IMX_SC_R_DSP,
					  false,
					  rproc->bootaddr);
		break;
	default:
		return -EOPNOTSUPP;
	}

	if (ret)
		dev_err(dev, "Failed to stop remote core\n");
	else
		priv->flags &= ~REMOTE_IS_READY;

	return ret;
}

/**
 * imx_dsp_rproc_sys_to_da() - internal memory translation helper
 * @priv: private data pointer
 * @sys: system address (DDR address)
 * @len: length of the memory buffer
 * @da: device address to translate
 *
 * Convert system address (DDR address) to device address (DSP)
 * for there may be memory remap for device.
 */
static int imx_dsp_rproc_sys_to_da(struct imx_dsp_rproc *priv, u64 sys,
				   size_t len, u64 *da)
{
	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
	const struct imx_rproc_dcfg *dcfg = dsp_dcfg->dcfg;
	int i;

	/* Parse address translation table */
	for (i = 0; i < dcfg->att_size; i++) {
		const struct imx_rproc_att *att = &dcfg->att[i];

		if (sys >= att->sa && sys + len <= att->sa + att->size) {
			unsigned int offset = sys - att->sa;

			*da = att->da + offset;
			return 0;
		}
	}

	return -ENOENT;
}

/* Main virtqueue message work function
 *
 * This function is executed upon scheduling of the i.MX DSP remoteproc
 * driver's workqueue. The workqueue is scheduled by the mailbox rx
 * handler.
 *
 * This work function processes both the Tx and Rx virtqueue indices on
 * every invocation. The rproc_vq_interrupt function can detect if there
 * are new unprocessed messages or not (returns IRQ_NONE vs IRQ_HANDLED),
 * but there is no need to check for these return values. The index 0
 * triggering will process all pending Rx buffers, and the index 1 triggering
 * will process all newly available Tx buffers and will wakeup any potentially
 * blocked senders.
 *
 * NOTE:
 *    The current logic is based on an inherent design assumption of supporting
 *    only 2 vrings, but this can be changed if needed.
 */
static void imx_dsp_rproc_vq_work(struct work_struct *work)
{
	struct imx_dsp_rproc *priv = container_of(work, struct imx_dsp_rproc,
						  rproc_work);

	rproc_vq_interrupt(priv->rproc, 0);
	rproc_vq_interrupt(priv->rproc, 1);
}

/**
 * imx_dsp_rproc_rx_tx_callback() - inbound mailbox message handler
 * @cl: mailbox client pointer used for requesting the mailbox channel
 * @data: mailbox payload
 *
 * This handler is invoked by mailbox driver whenever a mailbox
 * message is received. Usually, the SUSPEND and RESUME related messages
 * are handled in this function, other messages are handled by remoteproc core
 */
static void imx_dsp_rproc_rx_tx_callback(struct mbox_client *cl, void *data)
{
	struct rproc *rproc = dev_get_drvdata(cl->dev);
	struct imx_dsp_rproc *priv = rproc->priv;
	struct device *dev = rproc->dev.parent;
	u32 message = (u32)(*(u32 *)data);

	dev_dbg(dev, "mbox msg: 0x%x\n", message);

	switch (message) {
	case RP_MBOX_SUSPEND_ACK:
		complete(&priv->pm_comp);
		break;
	case RP_MBOX_RESUME_ACK:
		complete(&priv->pm_comp);
		break;
	default:
		schedule_work(&priv->rproc_work);
		break;
	}
}

/**
 * imx_dsp_rproc_rxdb_callback() - inbound mailbox message handler
 * @cl: mailbox client pointer used for requesting the mailbox channel
 * @data: mailbox payload
 *
 * For doorbell, there is no message specified, just set REMOTE_IS_READY
 * flag.
 */
static void imx_dsp_rproc_rxdb_callback(struct mbox_client *cl, void *data)
{
	struct rproc *rproc = dev_get_drvdata(cl->dev);
	struct imx_dsp_rproc *priv = rproc->priv;

	/* Remote is ready after firmware is loaded and running */
	priv->flags |= REMOTE_IS_READY;
}

/**
 * imx_dsp_rproc_mbox_init() - request mailbox channels
 * @priv: private data pointer
 *
 * Request three mailbox channels (tx, rx, rxdb).
 */
static int imx_dsp_rproc_mbox_init(struct imx_dsp_rproc *priv)
{
	struct device *dev = priv->rproc->dev.parent;
	struct mbox_client *cl;
	int ret;

	if (!of_get_property(dev->of_node, "mbox-names", NULL))
		return 0;

	cl = &priv->cl;
	cl->dev = dev;
	cl->tx_block = true;
	cl->tx_tout = 100;
	cl->knows_txdone = false;
	cl->rx_callback = imx_dsp_rproc_rx_tx_callback;

	/* Channel for sending message */
	priv->tx_ch = mbox_request_channel_byname(cl, "tx");
	if (IS_ERR(priv->tx_ch)) {
		ret = PTR_ERR(priv->tx_ch);
		dev_dbg(cl->dev, "failed to request tx mailbox channel: %d\n",
			ret);
		goto err_out;
	}

	/* Channel for receiving message */
	priv->rx_ch = mbox_request_channel_byname(cl, "rx");
	if (IS_ERR(priv->rx_ch)) {
		ret = PTR_ERR(priv->rx_ch);
		dev_dbg(cl->dev, "failed to request rx mailbox channel: %d\n",
			ret);
		goto err_out;
	}

	cl = &priv->cl_rxdb;
	cl->dev = dev;
	cl->rx_callback = imx_dsp_rproc_rxdb_callback;

	/*
	 * RX door bell is used to receive the ready signal from remote
	 * after firmware loaded.
	 */
	priv->rxdb_ch = mbox_request_channel_byname(cl, "rxdb");
	if (IS_ERR(priv->rxdb_ch)) {
		ret = PTR_ERR(priv->rxdb_ch);
		dev_dbg(cl->dev, "failed to request mbox chan rxdb, ret %d\n",
			ret);
		goto err_out;
	}

	return 0;

err_out:
	if (!IS_ERR(priv->tx_ch))
		mbox_free_channel(priv->tx_ch);
	if (!IS_ERR(priv->rx_ch))
		mbox_free_channel(priv->rx_ch);
	if (!IS_ERR(priv->rxdb_ch))
		mbox_free_channel(priv->rxdb_ch);

	return ret;
}

static void imx_dsp_rproc_free_mbox(struct imx_dsp_rproc *priv)
{
	mbox_free_channel(priv->tx_ch);
	mbox_free_channel(priv->rx_ch);
	mbox_free_channel(priv->rxdb_ch);
}

/**
 * imx_dsp_rproc_add_carveout() - request mailbox channels
 * @priv: private data pointer
 *
 * This function registers specified memory entry in @rproc carveouts list
 * The carveouts can help to mapping the memory address for DSP.
 */
static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv)
{
	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
	const struct imx_rproc_dcfg *dcfg = dsp_dcfg->dcfg;
	struct rproc *rproc = priv->rproc;
	struct device *dev = rproc->dev.parent;
	struct device_node *np = dev->of_node;
	struct of_phandle_iterator it;
	struct rproc_mem_entry *mem;
	struct reserved_mem *rmem;
	void __iomem *cpu_addr;
	int a;
	u64 da;

	/* Remap required addresses */
	for (a = 0; a < dcfg->att_size; a++) {
		const struct imx_rproc_att *att = &dcfg->att[a];

		if (!(att->flags & ATT_OWN))
			continue;

		if (imx_dsp_rproc_sys_to_da(priv, att->sa, att->size, &da))
			return -EINVAL;

		cpu_addr = devm_ioremap_wc(dev, att->sa, att->size);
		if (!cpu_addr) {
			dev_err(dev, "failed to map memory %p\n", &att->sa);
			return -ENOMEM;
		}

		/* Register memory region */
		mem = rproc_mem_entry_init(dev, cpu_addr, (dma_addr_t)att->sa,
					   att->size, da, NULL, NULL, "dsp_mem");

		if (mem)
			rproc_coredump_add_segment(rproc, da, att->size);
		else
			return -ENOMEM;

		rproc_add_carveout(rproc, mem);
	}

	of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
	while (of_phandle_iterator_next(&it) == 0) {
		/*
		 * Ignore the first memory region which will be used vdev buffer.
		 * No need to do extra handlings, rproc_add_virtio_dev will handle it.
		 */
		if (!strcmp(it.node->name, "vdev0buffer"))
			continue;

		rmem = of_reserved_mem_lookup(it.node);
		if (!rmem) {
			dev_err(dev, "unable to acquire memory-region\n");
			return -EINVAL;
		}

		if (imx_dsp_rproc_sys_to_da(priv, rmem->base, rmem->size, &da))
			return -EINVAL;

		cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
		if (!cpu_addr) {
			dev_err(dev, "failed to map memory %p\n", &rmem->base);
			return -ENOMEM;
		}

		/* Register memory region */
		mem = rproc_mem_entry_init(dev, cpu_addr, (dma_addr_t)rmem->base,
					   rmem->size, da, NULL, NULL, it.node->name);

		if (mem)
			rproc_coredump_add_segment(rproc, da, rmem->size);
		else
			return -ENOMEM;

		rproc_add_carveout(rproc, mem);
	}

	return 0;
}

/**
 * imx_dsp_rproc_elf_load_segments() - load firmware segments to memory
 * @rproc: remote processor which will be booted using these fw segments
 * @fw: the ELF firmware image
 *
 * This function specially checks if memsz is zero or not, otherwise it
 * is mostly same as rproc_elf_load_segments().
 */
static int imx_dsp_rproc_elf_load_segments(struct rproc *rproc,
					   const struct firmware *fw)
{
	struct device *dev = &rproc->dev;
	u8 class = fw_elf_get_class(fw);
	u32 elf_phdr_get_size = elf_size_of_phdr(class);
	const u8 *elf_data = fw->data;
	const void *ehdr, *phdr;
	int i, ret = 0;
	u16 phnum;

	ehdr = elf_data;
	phnum = elf_hdr_get_e_phnum(class, ehdr);
	phdr = elf_data + elf_hdr_get_e_phoff(class, ehdr);

	/* go through the available ELF segments */
	for (i = 0; i < phnum; i++, phdr += elf_phdr_get_size) {
		u64 da = elf_phdr_get_p_paddr(class, phdr);
		u64 memsz = elf_phdr_get_p_memsz(class, phdr);
		u64 filesz = elf_phdr_get_p_filesz(class, phdr);
		u64 offset = elf_phdr_get_p_offset(class, phdr);
		u32 type = elf_phdr_get_p_type(class, phdr);
		void *ptr;

		/*
		 *  There is a case that with PT_LOAD type, the
		 *  filesz = memsz = 0. If memsz = 0, rproc_da_to_va
		 *  should return NULL ptr, then error is returned.
		 *  So this case should be skipped from the loop.
		 *  Add !memsz checking here.
		 */
		if (type != PT_LOAD || !memsz)
			continue;

		dev_dbg(dev, "phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n",
			type, da, memsz, filesz);

		if (filesz > memsz) {
			dev_err(dev, "bad phdr filesz 0x%llx memsz 0x%llx\n",
				filesz, memsz);
			ret = -EINVAL;
			break;
		}

		if (offset + filesz > fw->size) {
			dev_err(dev, "truncated fw: need 0x%llx avail 0x%zx\n",
				offset + filesz, fw->size);
			ret = -EINVAL;
			break;
		}

		if (!rproc_u64_fit_in_size_t(memsz)) {
			dev_err(dev, "size (%llx) does not fit in size_t type\n",
				memsz);
			ret = -EOVERFLOW;
			break;
		}

		/* grab the kernel address for this device address */
		ptr = rproc_da_to_va(rproc, da, memsz, NULL);
		if (!ptr) {
			dev_err(dev, "bad phdr da 0x%llx mem 0x%llx\n", da,
				memsz);
			ret = -EINVAL;
			break;
		}

		/* put the segment where the remote processor expects it */
		if (filesz)
			memcpy(ptr, elf_data + offset, filesz);

		/*
		 * Zero out remaining memory for this segment.
		 *
		 * This isn't strictly required since dma_alloc_coherent already
		 * did this for us. albeit harmless, we may consider removing
		 * this.
		 */
		if (memsz > filesz)
			memset(ptr + filesz, 0, memsz - filesz);
	}

	return ret;
}

/* Prepare function for rproc_ops */
static int imx_dsp_rproc_prepare(struct rproc *rproc)
{
	struct imx_dsp_rproc *priv = rproc->priv;
	struct device *dev = rproc->dev.parent;
	struct rproc_mem_entry *carveout;
	int ret;

	ret = imx_dsp_rproc_add_carveout(priv);
	if (ret) {
		dev_err(dev, "failed on imx_dsp_rproc_add_carveout\n");
		return ret;
	}

	pm_runtime_get_sync(dev);

	/*
	 * Clear buffers after pm rumtime for internal ocram is not
	 * accessible if power and clock are not enabled.
	 */
	list_for_each_entry(carveout, &rproc->carveouts, node) {
		if (carveout->va)
			memset(carveout->va, 0, carveout->len);
	}

	return  0;
}

/* Unprepare function for rproc_ops */
static int imx_dsp_rproc_unprepare(struct rproc *rproc)
{
	pm_runtime_put_sync(rproc->dev.parent);

	return  0;
}

/* Kick function for rproc_ops */
static void imx_dsp_rproc_kick(struct rproc *rproc, int vqid)
{
	struct imx_dsp_rproc *priv = rproc->priv;
	struct device *dev = rproc->dev.parent;
	int err;
	__u32 mmsg;

	if (!priv->tx_ch) {
		dev_err(dev, "No initialized mbox tx channel\n");
		return;
	}

	/*
	 * Send the index of the triggered virtqueue as the mu payload.
	 * Let remote processor know which virtqueue is used.
	 */
	mmsg = vqid;

	err = mbox_send_message(priv->tx_ch, (void *)&mmsg);
	if (err < 0)
		dev_err(dev, "%s: failed (%d, err:%d)\n", __func__, vqid, err);
}

static const struct rproc_ops imx_dsp_rproc_ops = {
	.prepare	= imx_dsp_rproc_prepare,
	.unprepare	= imx_dsp_rproc_unprepare,
	.start		= imx_dsp_rproc_start,
	.stop		= imx_dsp_rproc_stop,
	.kick		= imx_dsp_rproc_kick,
	.load		= imx_dsp_rproc_elf_load_segments,
	.parse_fw	= rproc_elf_load_rsc_table,
	.sanity_check	= rproc_elf_sanity_check,
	.get_boot_addr	= rproc_elf_get_boot_addr,
};

/**
 * imx_dsp_attach_pm_domains() - attach the power domains
 * @priv: private data pointer
 *
 * On i.MX8QM and i.MX8QXP there is multiple power domains
 * required, so need to link them.
 */
static int imx_dsp_attach_pm_domains(struct imx_dsp_rproc *priv)
{
	struct device *dev = priv->rproc->dev.parent;
	int ret, i;

	priv->num_domains = of_count_phandle_with_args(dev->of_node,
						       "power-domains",
						       "#power-domain-cells");

	/* If only one domain, then no need to link the device */
	if (priv->num_domains <= 1)
		return 0;

	priv->pd_dev = devm_kmalloc_array(dev, priv->num_domains,
					  sizeof(*priv->pd_dev),
					  GFP_KERNEL);
	if (!priv->pd_dev)
		return -ENOMEM;

	priv->pd_dev_link = devm_kmalloc_array(dev, priv->num_domains,
					       sizeof(*priv->pd_dev_link),
					       GFP_KERNEL);
	if (!priv->pd_dev_link)
		return -ENOMEM;

	for (i = 0; i < priv->num_domains; i++) {
		priv->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
		if (IS_ERR(priv->pd_dev[i])) {
			ret = PTR_ERR(priv->pd_dev[i]);
			goto detach_pm;
		}

		/*
		 * device_link_add will check priv->pd_dev[i], if it is
		 * NULL, then will break.
		 */
		priv->pd_dev_link[i] = device_link_add(dev,
						       priv->pd_dev[i],
						       DL_FLAG_STATELESS |
						       DL_FLAG_PM_RUNTIME);
		if (!priv->pd_dev_link[i]) {
			dev_pm_domain_detach(priv->pd_dev[i], false);
			ret = -EINVAL;
			goto detach_pm;
		}
	}

	return 0;

detach_pm:
	while (--i >= 0) {
		device_link_del(priv->pd_dev_link[i]);
		dev_pm_domain_detach(priv->pd_dev[i], false);
	}

	return ret;
}

static int imx_dsp_detach_pm_domains(struct imx_dsp_rproc *priv)
{
	int i;

	if (priv->num_domains <= 1)
		return 0;

	for (i = 0; i < priv->num_domains; i++) {
		device_link_del(priv->pd_dev_link[i]);
		dev_pm_domain_detach(priv->pd_dev[i], false);
	}

	return 0;
}

/**
 * imx_dsp_rproc_detect_mode() - detect DSP control mode
 * @priv: private data pointer
 *
 * Different platform has different control method for DSP, which depends
 * on how the DSP is integrated in platform.
 *
 * For i.MX8QXP and i.MX8QM, DSP should be started and stopped by System
 * Control Unit.
 * For i.MX8MP and i.MX8ULP, DSP should be started and stopped by system
 * integration module.
 */
static int imx_dsp_rproc_detect_mode(struct imx_dsp_rproc *priv)
{
	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
	struct device *dev = priv->rproc->dev.parent;
	struct regmap *regmap;
	int ret = 0;

	switch (dsp_dcfg->dcfg->method) {
	case IMX_RPROC_SCU_API:
		ret = imx_scu_get_handle(&priv->ipc_handle);
		if (ret)
			return ret;
		break;
	case IMX_RPROC_MMIO:
		regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,dsp-ctrl");
		if (IS_ERR(regmap)) {
			dev_err(dev, "failed to find syscon\n");
			return PTR_ERR(regmap);
		}

		priv->regmap = regmap;
		break;
	default:
		ret = -EOPNOTSUPP;
		break;
	}

	return ret;
}

static const char *imx_dsp_clks_names[DSP_RPROC_CLK_MAX] = {
	/* DSP clocks */
	"core", "ocram", "debug", "ipg", "mu",
};

static int imx_dsp_rproc_clk_get(struct imx_dsp_rproc *priv)
{
	struct device *dev = priv->rproc->dev.parent;
	struct clk_bulk_data *clks = priv->clks;
	int i;

	for (i = 0; i < DSP_RPROC_CLK_MAX; i++)
		clks[i].id = imx_dsp_clks_names[i];

	return devm_clk_bulk_get_optional(dev, DSP_RPROC_CLK_MAX, clks);
}

static int imx_dsp_rproc_probe(struct platform_device *pdev)
{
	const struct imx_dsp_rproc_dcfg *dsp_dcfg;
	struct device *dev = &pdev->dev;
	struct imx_dsp_rproc *priv;
	struct rproc *rproc;
	const char *fw_name;
	int ret;

	dsp_dcfg = of_device_get_match_data(dev);
	if (!dsp_dcfg)
		return -ENODEV;

	ret = rproc_of_parse_firmware(dev, 0, &fw_name);
	if (ret) {
		dev_err(dev, "failed to parse firmware-name property, ret = %d\n",
			ret);
		return ret;
	}

	rproc = rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops, fw_name,
			    sizeof(*priv));
	if (!rproc)
		return -ENOMEM;

	priv = rproc->priv;
	priv->rproc = rproc;
	priv->dsp_dcfg = dsp_dcfg;

	dev_set_drvdata(dev, rproc);

	INIT_WORK(&priv->rproc_work, imx_dsp_rproc_vq_work);

	ret = imx_dsp_rproc_detect_mode(priv);
	if (ret) {
		dev_err(dev, "failed on imx_dsp_rproc_detect_mode\n");
		goto err_put_rproc;
	}

	/* There are multiple power domains required by DSP on some platform */
	ret = imx_dsp_attach_pm_domains(priv);
	if (ret) {
		dev_err(dev, "failed on imx_dsp_attach_pm_domains\n");
		goto err_put_rproc;
	}
	/* Get clocks */
	ret = imx_dsp_rproc_clk_get(priv);
	if (ret) {
		dev_err(dev, "failed on imx_dsp_rproc_clk_get\n");
		goto err_detach_domains;
	}

	init_completion(&priv->pm_comp);
	rproc->auto_boot = false;
	ret = rproc_add(rproc);
	if (ret) {
		dev_err(dev, "rproc_add failed\n");
		goto err_detach_domains;
	}

	pm_runtime_enable(dev);

	return 0;

err_detach_domains:
	imx_dsp_detach_pm_domains(priv);
err_put_rproc:
	rproc_free(rproc);

	return ret;
}

static int imx_dsp_rproc_remove(struct platform_device *pdev)
{
	struct rproc *rproc = platform_get_drvdata(pdev);
	struct imx_dsp_rproc *priv = rproc->priv;

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

	return 0;
}

/* pm runtime functions */
static int imx_dsp_runtime_resume(struct device *dev)
{
	struct rproc *rproc = dev_get_drvdata(dev);
	struct imx_dsp_rproc *priv = rproc->priv;
	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
	int ret;

	/*
	 * There is power domain attached with mailbox, if setup mailbox
	 * in probe(), then the power of mailbox is always enabled,
	 * the power can't be saved.
	 * So move setup of mailbox to runtime resume.
	 */
	ret = imx_dsp_rproc_mbox_init(priv);
	if (ret) {
		dev_err(dev, "failed on imx_dsp_rproc_mbox_init\n");
		return ret;
	}

	ret = clk_bulk_prepare_enable(DSP_RPROC_CLK_MAX, priv->clks);
	if (ret) {
		dev_err(dev, "failed on clk_bulk_prepare_enable\n");
		return ret;
	}

	/* Reset DSP if needed */
	if (dsp_dcfg->reset)
		dsp_dcfg->reset(priv);

	return 0;
}

static int imx_dsp_runtime_suspend(struct device *dev)
{
	struct rproc *rproc = dev_get_drvdata(dev);
	struct imx_dsp_rproc *priv = rproc->priv;

	clk_bulk_disable_unprepare(DSP_RPROC_CLK_MAX, priv->clks);

	imx_dsp_rproc_free_mbox(priv);

	return 0;
}

static void imx_dsp_load_firmware(const struct firmware *fw, void *context)
{
	struct rproc *rproc = context;
	int ret;

	/*
	 * Same flow as start procedure.
	 * Load the ELF segments to memory firstly.
	 */
	ret = rproc_load_segments(rproc, fw);
	if (ret)
		goto out;

	/* Start the remote processor */
	ret = rproc->ops->start(rproc);
	if (ret)
		goto out;

	rproc->ops->kick(rproc, 0);

out:
	release_firmware(fw);
}

static __maybe_unused int imx_dsp_suspend(struct device *dev)
{
	struct rproc *rproc = dev_get_drvdata(dev);
	struct imx_dsp_rproc *priv = rproc->priv;
	__u32 mmsg = RP_MBOX_SUSPEND_SYSTEM;
	int ret;

	if (rproc->state != RPROC_RUNNING)
		goto out;

	reinit_completion(&priv->pm_comp);

	/* Tell DSP that suspend is happening */
	ret = mbox_send_message(priv->tx_ch, (void *)&mmsg);
	if (ret < 0) {
		dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
		return ret;
	}

	/*
	 * DSP need to save the context at suspend.
	 * Here waiting the response for DSP, then power can be disabled.
	 */
	if (!wait_for_completion_timeout(&priv->pm_comp, msecs_to_jiffies(100)))
		return -EBUSY;

out:
	/*
	 * The power of DSP is disabled in suspend, so force pm runtime
	 * to be suspend, then we can reenable the power and clocks at
	 * resume stage.
	 */
	return pm_runtime_force_suspend(dev);
}

static __maybe_unused int imx_dsp_resume(struct device *dev)
{
	struct rproc *rproc = dev_get_drvdata(dev);
	int ret = 0;

	ret = pm_runtime_force_resume(dev);
	if (ret)
		return ret;

	if (rproc->state != RPROC_RUNNING)
		return 0;

	/*
	 * The power of DSP is disabled at suspend, the memory of dsp
	 * is reset, the image segments are lost. So need to reload
	 * firmware and restart the DSP if it is in running state.
	 */
	ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
				      rproc->firmware, dev, GFP_KERNEL,
				      rproc, imx_dsp_load_firmware);
	if (ret < 0) {
		dev_err(dev, "load firmware failed: %d\n", ret);
		goto err;
	}

	return 0;

err:
	pm_runtime_force_suspend(dev);

	return ret;
}

static const struct dev_pm_ops imx_dsp_rproc_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(imx_dsp_suspend, imx_dsp_resume)
	SET_RUNTIME_PM_OPS(imx_dsp_runtime_suspend,
			   imx_dsp_runtime_resume, NULL)
};

static const struct of_device_id imx_dsp_rproc_of_match[] = {
	{ .compatible = "fsl,imx8qxp-hifi4", .data = &imx_dsp_rproc_cfg_imx8qxp },
	{ .compatible = "fsl,imx8qm-hifi4",  .data = &imx_dsp_rproc_cfg_imx8qm },
	{ .compatible = "fsl,imx8mp-hifi4",  .data = &imx_dsp_rproc_cfg_imx8mp },
	{ .compatible = "fsl,imx8ulp-hifi4", .data = &imx_dsp_rproc_cfg_imx8ulp },
	{},
};
MODULE_DEVICE_TABLE(of, imx_dsp_rproc_of_match);

static struct platform_driver imx_dsp_rproc_driver = {
	.probe = imx_dsp_rproc_probe,
	.remove = imx_dsp_rproc_remove,
	.driver = {
		.name = "imx-dsp-rproc",
		.of_match_table = imx_dsp_rproc_of_match,
		.pm = &imx_dsp_rproc_pm_ops,
	},
};
module_platform_driver(imx_dsp_rproc_driver);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("i.MX HiFi Core Remote Processor Control Driver");
MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@nxp.com>");
