cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

imx_dsp_rproc.c (29669B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* Copyright 2021 NXP */
      3
      4#include <dt-bindings/firmware/imx/rsrc.h>
      5#include <linux/arm-smccc.h>
      6#include <linux/clk.h>
      7#include <linux/err.h>
      8#include <linux/firmware.h>
      9#include <linux/firmware/imx/sci.h>
     10#include <linux/interrupt.h>
     11#include <linux/kernel.h>
     12#include <linux/mailbox_client.h>
     13#include <linux/mfd/syscon.h>
     14#include <linux/module.h>
     15#include <linux/of_address.h>
     16#include <linux/of_device.h>
     17#include <linux/of_reserved_mem.h>
     18#include <linux/platform_device.h>
     19#include <linux/pm_domain.h>
     20#include <linux/pm_runtime.h>
     21#include <linux/regmap.h>
     22#include <linux/remoteproc.h>
     23#include <linux/slab.h>
     24
     25#include "imx_rproc.h"
     26#include "remoteproc_elf_helpers.h"
     27#include "remoteproc_internal.h"
     28
     29#define DSP_RPROC_CLK_MAX			5
     30
     31#define REMOTE_IS_READY				BIT(0)
     32#define REMOTE_READY_WAIT_MAX_RETRIES		500
     33
     34/* att flags */
     35/* DSP own area */
     36#define ATT_OWN					BIT(31)
     37/* DSP instruction area */
     38#define ATT_IRAM				BIT(30)
     39
     40/* Definitions for i.MX8MP */
     41/* DAP registers */
     42#define IMX8M_DAP_DEBUG				0x28800000
     43#define IMX8M_DAP_DEBUG_SIZE			(64 * 1024)
     44#define IMX8M_DAP_PWRCTL			(0x4000 + 0x3020)
     45#define IMX8M_PWRCTL_CORERESET			BIT(16)
     46
     47/* DSP audio mix registers */
     48#define IMX8M_AudioDSP_REG0			0x100
     49#define IMX8M_AudioDSP_REG1			0x104
     50#define IMX8M_AudioDSP_REG2			0x108
     51#define IMX8M_AudioDSP_REG3			0x10c
     52
     53#define IMX8M_AudioDSP_REG2_RUNSTALL		BIT(5)
     54#define IMX8M_AudioDSP_REG2_PWAITMODE		BIT(1)
     55
     56/* Definitions for i.MX8ULP */
     57#define IMX8ULP_SIM_LPAV_REG_SYSCTRL0		0x8
     58#define IMX8ULP_SYSCTRL0_DSP_DBG_RST		BIT(25)
     59#define IMX8ULP_SYSCTRL0_DSP_PLAT_CLK_EN	BIT(19)
     60#define IMX8ULP_SYSCTRL0_DSP_PBCLK_EN		BIT(18)
     61#define IMX8ULP_SYSCTRL0_DSP_CLK_EN		BIT(17)
     62#define IMX8ULP_SYSCTRL0_DSP_RST		BIT(16)
     63#define IMX8ULP_SYSCTRL0_DSP_OCD_HALT		BIT(14)
     64#define IMX8ULP_SYSCTRL0_DSP_STALL		BIT(13)
     65
     66#define IMX8ULP_SIP_HIFI_XRDC			0xc200000e
     67
     68/*
     69 * enum - Predefined Mailbox Messages
     70 *
     71 * @RP_MBOX_SUSPEND_SYSTEM: system suspend request for the remote processor
     72 *
     73 * @RP_MBOX_SUSPEND_ACK: successful response from remote processor for a
     74 * suspend request
     75 *
     76 * @RP_MBOX_RESUME_SYSTEM: system resume request for the remote processor
     77 *
     78 * @RP_MBOX_RESUME_ACK: successful response from remote processor for a
     79 * resume request
     80 */
     81enum imx_dsp_rp_mbox_messages {
     82	RP_MBOX_SUSPEND_SYSTEM			= 0xFF11,
     83	RP_MBOX_SUSPEND_ACK			= 0xFF12,
     84	RP_MBOX_RESUME_SYSTEM			= 0xFF13,
     85	RP_MBOX_RESUME_ACK			= 0xFF14,
     86};
     87
     88/**
     89 * struct imx_dsp_rproc - DSP remote processor state
     90 * @regmap: regmap handler
     91 * @rproc: rproc handler
     92 * @dsp_dcfg: device configuration pointer
     93 * @clks: clocks needed by this device
     94 * @cl: mailbox client to request the mailbox channel
     95 * @cl_rxdb: mailbox client to request the mailbox channel for doorbell
     96 * @tx_ch: mailbox tx channel handle
     97 * @rx_ch: mailbox rx channel handle
     98 * @rxdb_ch: mailbox rx doorbell channel handle
     99 * @pd_dev: power domain device
    100 * @pd_dev_link: power domain device link
    101 * @ipc_handle: System Control Unit ipc handle
    102 * @rproc_work: work for processing virtio interrupts
    103 * @pm_comp: completion primitive to sync for suspend response
    104 * @num_domains: power domain number
    105 * @flags: control flags
    106 */
    107struct imx_dsp_rproc {
    108	struct regmap				*regmap;
    109	struct rproc				*rproc;
    110	const struct imx_dsp_rproc_dcfg		*dsp_dcfg;
    111	struct clk_bulk_data			clks[DSP_RPROC_CLK_MAX];
    112	struct mbox_client			cl;
    113	struct mbox_client			cl_rxdb;
    114	struct mbox_chan			*tx_ch;
    115	struct mbox_chan			*rx_ch;
    116	struct mbox_chan			*rxdb_ch;
    117	struct device				**pd_dev;
    118	struct device_link			**pd_dev_link;
    119	struct imx_sc_ipc			*ipc_handle;
    120	struct work_struct			rproc_work;
    121	struct completion			pm_comp;
    122	int					num_domains;
    123	u32					flags;
    124};
    125
    126/**
    127 * struct imx_dsp_rproc_dcfg - DSP remote processor configuration
    128 * @dcfg: imx_rproc_dcfg handler
    129 * @reset: reset callback function
    130 */
    131struct imx_dsp_rproc_dcfg {
    132	const struct imx_rproc_dcfg		*dcfg;
    133	int (*reset)(struct imx_dsp_rproc *priv);
    134};
    135
    136static const struct imx_rproc_att imx_dsp_rproc_att_imx8qm[] = {
    137	/* dev addr , sys addr  , size	    , flags */
    138	{ 0x596e8000, 0x556e8000, 0x00008000, ATT_OWN },
    139	{ 0x596f0000, 0x556f0000, 0x00008000, ATT_OWN },
    140	{ 0x596f8000, 0x556f8000, 0x00000800, ATT_OWN | ATT_IRAM},
    141	{ 0x55700000, 0x55700000, 0x00070000, ATT_OWN },
    142	/* DDR (Data) */
    143	{ 0x80000000, 0x80000000, 0x60000000, 0},
    144};
    145
    146static const struct imx_rproc_att imx_dsp_rproc_att_imx8qxp[] = {
    147	/* dev addr , sys addr  , size	    , flags */
    148	{ 0x596e8000, 0x596e8000, 0x00008000, ATT_OWN },
    149	{ 0x596f0000, 0x596f0000, 0x00008000, ATT_OWN },
    150	{ 0x596f8000, 0x596f8000, 0x00000800, ATT_OWN | ATT_IRAM},
    151	{ 0x59700000, 0x59700000, 0x00070000, ATT_OWN },
    152	/* DDR (Data) */
    153	{ 0x80000000, 0x80000000, 0x60000000, 0},
    154};
    155
    156static const struct imx_rproc_att imx_dsp_rproc_att_imx8mp[] = {
    157	/* dev addr , sys addr  , size	    , flags */
    158	{ 0x3b6e8000, 0x3b6e8000, 0x00008000, ATT_OWN },
    159	{ 0x3b6f0000, 0x3b6f0000, 0x00008000, ATT_OWN },
    160	{ 0x3b6f8000, 0x3b6f8000, 0x00000800, ATT_OWN | ATT_IRAM},
    161	{ 0x3b700000, 0x3b700000, 0x00040000, ATT_OWN },
    162	/* DDR (Data) */
    163	{ 0x40000000, 0x40000000, 0x80000000, 0},
    164};
    165
    166static const struct imx_rproc_att imx_dsp_rproc_att_imx8ulp[] = {
    167	/* dev addr , sys addr  , size	    , flags */
    168	{ 0x21170000, 0x21170000, 0x00010000, ATT_OWN | ATT_IRAM},
    169	{ 0x21180000, 0x21180000, 0x00010000, ATT_OWN },
    170	/* DDR (Data) */
    171	{ 0x0c000000, 0x80000000, 0x10000000, 0},
    172	{ 0x30000000, 0x90000000, 0x10000000, 0},
    173};
    174
    175/* Reset function for DSP on i.MX8MP */
    176static int imx8mp_dsp_reset(struct imx_dsp_rproc *priv)
    177{
    178	void __iomem *dap = ioremap_wc(IMX8M_DAP_DEBUG, IMX8M_DAP_DEBUG_SIZE);
    179	int pwrctl;
    180
    181	/* Put DSP into reset and stall */
    182	pwrctl = readl(dap + IMX8M_DAP_PWRCTL);
    183	pwrctl |= IMX8M_PWRCTL_CORERESET;
    184	writel(pwrctl, dap + IMX8M_DAP_PWRCTL);
    185
    186	/* Keep reset asserted for 10 cycles */
    187	usleep_range(1, 2);
    188
    189	regmap_update_bits(priv->regmap, IMX8M_AudioDSP_REG2,
    190			   IMX8M_AudioDSP_REG2_RUNSTALL,
    191			   IMX8M_AudioDSP_REG2_RUNSTALL);
    192
    193	/* Take the DSP out of reset and keep stalled for FW loading */
    194	pwrctl = readl(dap + IMX8M_DAP_PWRCTL);
    195	pwrctl &= ~IMX8M_PWRCTL_CORERESET;
    196	writel(pwrctl, dap + IMX8M_DAP_PWRCTL);
    197
    198	iounmap(dap);
    199	return 0;
    200}
    201
    202/* Reset function for DSP on i.MX8ULP */
    203static int imx8ulp_dsp_reset(struct imx_dsp_rproc *priv)
    204{
    205	struct arm_smccc_res res;
    206
    207	/* Put DSP into reset and stall */
    208	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
    209			   IMX8ULP_SYSCTRL0_DSP_RST, IMX8ULP_SYSCTRL0_DSP_RST);
    210	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
    211			   IMX8ULP_SYSCTRL0_DSP_STALL,
    212			   IMX8ULP_SYSCTRL0_DSP_STALL);
    213
    214	/* Configure resources of DSP through TFA */
    215	arm_smccc_smc(IMX8ULP_SIP_HIFI_XRDC, 0, 0, 0, 0, 0, 0, 0, &res);
    216
    217	/* Take the DSP out of reset and keep stalled for FW loading */
    218	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
    219			   IMX8ULP_SYSCTRL0_DSP_RST, 0);
    220	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
    221			   IMX8ULP_SYSCTRL0_DSP_DBG_RST, 0);
    222
    223	return 0;
    224}
    225
    226/* Specific configuration for i.MX8MP */
    227static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8mp = {
    228	.src_reg	= IMX8M_AudioDSP_REG2,
    229	.src_mask	= IMX8M_AudioDSP_REG2_RUNSTALL,
    230	.src_start	= 0,
    231	.src_stop	= IMX8M_AudioDSP_REG2_RUNSTALL,
    232	.att		= imx_dsp_rproc_att_imx8mp,
    233	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8mp),
    234	.method		= IMX_RPROC_MMIO,
    235};
    236
    237static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8mp = {
    238	.dcfg		= &dsp_rproc_cfg_imx8mp,
    239	.reset          = imx8mp_dsp_reset,
    240};
    241
    242/* Specific configuration for i.MX8ULP */
    243static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8ulp = {
    244	.src_reg	= IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
    245	.src_mask	= IMX8ULP_SYSCTRL0_DSP_STALL,
    246	.src_start	= 0,
    247	.src_stop	= IMX8ULP_SYSCTRL0_DSP_STALL,
    248	.att		= imx_dsp_rproc_att_imx8ulp,
    249	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8ulp),
    250	.method		= IMX_RPROC_MMIO,
    251};
    252
    253static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8ulp = {
    254	.dcfg		= &dsp_rproc_cfg_imx8ulp,
    255	.reset          = imx8ulp_dsp_reset,
    256};
    257
    258/* Specific configuration for i.MX8QXP */
    259static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8qxp = {
    260	.att		= imx_dsp_rproc_att_imx8qxp,
    261	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8qxp),
    262	.method		= IMX_RPROC_SCU_API,
    263};
    264
    265static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qxp = {
    266	.dcfg		= &dsp_rproc_cfg_imx8qxp,
    267};
    268
    269/* Specific configuration for i.MX8QM */
    270static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8qm = {
    271	.att		= imx_dsp_rproc_att_imx8qm,
    272	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8qm),
    273	.method		= IMX_RPROC_SCU_API,
    274};
    275
    276static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qm = {
    277	.dcfg		= &dsp_rproc_cfg_imx8qm,
    278};
    279
    280static int imx_dsp_rproc_ready(struct rproc *rproc)
    281{
    282	struct imx_dsp_rproc *priv = rproc->priv;
    283	int i;
    284
    285	if (!priv->rxdb_ch)
    286		return 0;
    287
    288	for (i = 0; i < REMOTE_READY_WAIT_MAX_RETRIES; i++) {
    289		if (priv->flags & REMOTE_IS_READY)
    290			return 0;
    291		usleep_range(100, 200);
    292	}
    293
    294	return -ETIMEDOUT;
    295}
    296
    297/*
    298 * Start function for rproc_ops
    299 *
    300 * There is a handshake for start procedure: when DSP starts, it
    301 * will send a doorbell message to this driver, then the
    302 * REMOTE_IS_READY flags is set, then driver will kick
    303 * a message to DSP.
    304 */
    305static int imx_dsp_rproc_start(struct rproc *rproc)
    306{
    307	struct imx_dsp_rproc *priv = rproc->priv;
    308	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
    309	const struct imx_rproc_dcfg *dcfg = dsp_dcfg->dcfg;
    310	struct device *dev = rproc->dev.parent;
    311	int ret;
    312
    313	switch (dcfg->method) {
    314	case IMX_RPROC_MMIO:
    315		ret = regmap_update_bits(priv->regmap,
    316					 dcfg->src_reg,
    317					 dcfg->src_mask,
    318					 dcfg->src_start);
    319		break;
    320	case IMX_RPROC_SCU_API:
    321		ret = imx_sc_pm_cpu_start(priv->ipc_handle,
    322					  IMX_SC_R_DSP,
    323					  true,
    324					  rproc->bootaddr);
    325		break;
    326	default:
    327		return -EOPNOTSUPP;
    328	}
    329
    330	if (ret)
    331		dev_err(dev, "Failed to enable remote core!\n");
    332	else
    333		ret = imx_dsp_rproc_ready(rproc);
    334
    335	return ret;
    336}
    337
    338/*
    339 * Stop function for rproc_ops
    340 * It clears the REMOTE_IS_READY flags
    341 */
    342static int imx_dsp_rproc_stop(struct rproc *rproc)
    343{
    344	struct imx_dsp_rproc *priv = rproc->priv;
    345	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
    346	const struct imx_rproc_dcfg *dcfg = dsp_dcfg->dcfg;
    347	struct device *dev = rproc->dev.parent;
    348	int ret = 0;
    349
    350	/* Make sure work is finished */
    351	flush_work(&priv->rproc_work);
    352
    353	if (rproc->state == RPROC_CRASHED) {
    354		priv->flags &= ~REMOTE_IS_READY;
    355		return 0;
    356	}
    357
    358	switch (dcfg->method) {
    359	case IMX_RPROC_MMIO:
    360		ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
    361					 dcfg->src_stop);
    362		break;
    363	case IMX_RPROC_SCU_API:
    364		ret = imx_sc_pm_cpu_start(priv->ipc_handle,
    365					  IMX_SC_R_DSP,
    366					  false,
    367					  rproc->bootaddr);
    368		break;
    369	default:
    370		return -EOPNOTSUPP;
    371	}
    372
    373	if (ret)
    374		dev_err(dev, "Failed to stop remote core\n");
    375	else
    376		priv->flags &= ~REMOTE_IS_READY;
    377
    378	return ret;
    379}
    380
    381/**
    382 * imx_dsp_rproc_sys_to_da() - internal memory translation helper
    383 * @priv: private data pointer
    384 * @sys: system address (DDR address)
    385 * @len: length of the memory buffer
    386 * @da: device address to translate
    387 *
    388 * Convert system address (DDR address) to device address (DSP)
    389 * for there may be memory remap for device.
    390 */
    391static int imx_dsp_rproc_sys_to_da(struct imx_dsp_rproc *priv, u64 sys,
    392				   size_t len, u64 *da)
    393{
    394	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
    395	const struct imx_rproc_dcfg *dcfg = dsp_dcfg->dcfg;
    396	int i;
    397
    398	/* Parse address translation table */
    399	for (i = 0; i < dcfg->att_size; i++) {
    400		const struct imx_rproc_att *att = &dcfg->att[i];
    401
    402		if (sys >= att->sa && sys + len <= att->sa + att->size) {
    403			unsigned int offset = sys - att->sa;
    404
    405			*da = att->da + offset;
    406			return 0;
    407		}
    408	}
    409
    410	return -ENOENT;
    411}
    412
    413/* Main virtqueue message work function
    414 *
    415 * This function is executed upon scheduling of the i.MX DSP remoteproc
    416 * driver's workqueue. The workqueue is scheduled by the mailbox rx
    417 * handler.
    418 *
    419 * This work function processes both the Tx and Rx virtqueue indices on
    420 * every invocation. The rproc_vq_interrupt function can detect if there
    421 * are new unprocessed messages or not (returns IRQ_NONE vs IRQ_HANDLED),
    422 * but there is no need to check for these return values. The index 0
    423 * triggering will process all pending Rx buffers, and the index 1 triggering
    424 * will process all newly available Tx buffers and will wakeup any potentially
    425 * blocked senders.
    426 *
    427 * NOTE:
    428 *    The current logic is based on an inherent design assumption of supporting
    429 *    only 2 vrings, but this can be changed if needed.
    430 */
    431static void imx_dsp_rproc_vq_work(struct work_struct *work)
    432{
    433	struct imx_dsp_rproc *priv = container_of(work, struct imx_dsp_rproc,
    434						  rproc_work);
    435
    436	rproc_vq_interrupt(priv->rproc, 0);
    437	rproc_vq_interrupt(priv->rproc, 1);
    438}
    439
    440/**
    441 * imx_dsp_rproc_rx_tx_callback() - inbound mailbox message handler
    442 * @cl: mailbox client pointer used for requesting the mailbox channel
    443 * @data: mailbox payload
    444 *
    445 * This handler is invoked by mailbox driver whenever a mailbox
    446 * message is received. Usually, the SUSPEND and RESUME related messages
    447 * are handled in this function, other messages are handled by remoteproc core
    448 */
    449static void imx_dsp_rproc_rx_tx_callback(struct mbox_client *cl, void *data)
    450{
    451	struct rproc *rproc = dev_get_drvdata(cl->dev);
    452	struct imx_dsp_rproc *priv = rproc->priv;
    453	struct device *dev = rproc->dev.parent;
    454	u32 message = (u32)(*(u32 *)data);
    455
    456	dev_dbg(dev, "mbox msg: 0x%x\n", message);
    457
    458	switch (message) {
    459	case RP_MBOX_SUSPEND_ACK:
    460		complete(&priv->pm_comp);
    461		break;
    462	case RP_MBOX_RESUME_ACK:
    463		complete(&priv->pm_comp);
    464		break;
    465	default:
    466		schedule_work(&priv->rproc_work);
    467		break;
    468	}
    469}
    470
    471/**
    472 * imx_dsp_rproc_rxdb_callback() - inbound mailbox message handler
    473 * @cl: mailbox client pointer used for requesting the mailbox channel
    474 * @data: mailbox payload
    475 *
    476 * For doorbell, there is no message specified, just set REMOTE_IS_READY
    477 * flag.
    478 */
    479static void imx_dsp_rproc_rxdb_callback(struct mbox_client *cl, void *data)
    480{
    481	struct rproc *rproc = dev_get_drvdata(cl->dev);
    482	struct imx_dsp_rproc *priv = rproc->priv;
    483
    484	/* Remote is ready after firmware is loaded and running */
    485	priv->flags |= REMOTE_IS_READY;
    486}
    487
    488/**
    489 * imx_dsp_rproc_mbox_init() - request mailbox channels
    490 * @priv: private data pointer
    491 *
    492 * Request three mailbox channels (tx, rx, rxdb).
    493 */
    494static int imx_dsp_rproc_mbox_init(struct imx_dsp_rproc *priv)
    495{
    496	struct device *dev = priv->rproc->dev.parent;
    497	struct mbox_client *cl;
    498	int ret;
    499
    500	if (!of_get_property(dev->of_node, "mbox-names", NULL))
    501		return 0;
    502
    503	cl = &priv->cl;
    504	cl->dev = dev;
    505	cl->tx_block = true;
    506	cl->tx_tout = 100;
    507	cl->knows_txdone = false;
    508	cl->rx_callback = imx_dsp_rproc_rx_tx_callback;
    509
    510	/* Channel for sending message */
    511	priv->tx_ch = mbox_request_channel_byname(cl, "tx");
    512	if (IS_ERR(priv->tx_ch)) {
    513		ret = PTR_ERR(priv->tx_ch);
    514		dev_dbg(cl->dev, "failed to request tx mailbox channel: %d\n",
    515			ret);
    516		goto err_out;
    517	}
    518
    519	/* Channel for receiving message */
    520	priv->rx_ch = mbox_request_channel_byname(cl, "rx");
    521	if (IS_ERR(priv->rx_ch)) {
    522		ret = PTR_ERR(priv->rx_ch);
    523		dev_dbg(cl->dev, "failed to request rx mailbox channel: %d\n",
    524			ret);
    525		goto err_out;
    526	}
    527
    528	cl = &priv->cl_rxdb;
    529	cl->dev = dev;
    530	cl->rx_callback = imx_dsp_rproc_rxdb_callback;
    531
    532	/*
    533	 * RX door bell is used to receive the ready signal from remote
    534	 * after firmware loaded.
    535	 */
    536	priv->rxdb_ch = mbox_request_channel_byname(cl, "rxdb");
    537	if (IS_ERR(priv->rxdb_ch)) {
    538		ret = PTR_ERR(priv->rxdb_ch);
    539		dev_dbg(cl->dev, "failed to request mbox chan rxdb, ret %d\n",
    540			ret);
    541		goto err_out;
    542	}
    543
    544	return 0;
    545
    546err_out:
    547	if (!IS_ERR(priv->tx_ch))
    548		mbox_free_channel(priv->tx_ch);
    549	if (!IS_ERR(priv->rx_ch))
    550		mbox_free_channel(priv->rx_ch);
    551	if (!IS_ERR(priv->rxdb_ch))
    552		mbox_free_channel(priv->rxdb_ch);
    553
    554	return ret;
    555}
    556
    557static void imx_dsp_rproc_free_mbox(struct imx_dsp_rproc *priv)
    558{
    559	mbox_free_channel(priv->tx_ch);
    560	mbox_free_channel(priv->rx_ch);
    561	mbox_free_channel(priv->rxdb_ch);
    562}
    563
    564/**
    565 * imx_dsp_rproc_add_carveout() - request mailbox channels
    566 * @priv: private data pointer
    567 *
    568 * This function registers specified memory entry in @rproc carveouts list
    569 * The carveouts can help to mapping the memory address for DSP.
    570 */
    571static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv)
    572{
    573	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
    574	const struct imx_rproc_dcfg *dcfg = dsp_dcfg->dcfg;
    575	struct rproc *rproc = priv->rproc;
    576	struct device *dev = rproc->dev.parent;
    577	struct device_node *np = dev->of_node;
    578	struct of_phandle_iterator it;
    579	struct rproc_mem_entry *mem;
    580	struct reserved_mem *rmem;
    581	void __iomem *cpu_addr;
    582	int a;
    583	u64 da;
    584
    585	/* Remap required addresses */
    586	for (a = 0; a < dcfg->att_size; a++) {
    587		const struct imx_rproc_att *att = &dcfg->att[a];
    588
    589		if (!(att->flags & ATT_OWN))
    590			continue;
    591
    592		if (imx_dsp_rproc_sys_to_da(priv, att->sa, att->size, &da))
    593			return -EINVAL;
    594
    595		cpu_addr = devm_ioremap_wc(dev, att->sa, att->size);
    596		if (!cpu_addr) {
    597			dev_err(dev, "failed to map memory %p\n", &att->sa);
    598			return -ENOMEM;
    599		}
    600
    601		/* Register memory region */
    602		mem = rproc_mem_entry_init(dev, cpu_addr, (dma_addr_t)att->sa,
    603					   att->size, da, NULL, NULL, "dsp_mem");
    604
    605		if (mem)
    606			rproc_coredump_add_segment(rproc, da, att->size);
    607		else
    608			return -ENOMEM;
    609
    610		rproc_add_carveout(rproc, mem);
    611	}
    612
    613	of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
    614	while (of_phandle_iterator_next(&it) == 0) {
    615		/*
    616		 * Ignore the first memory region which will be used vdev buffer.
    617		 * No need to do extra handlings, rproc_add_virtio_dev will handle it.
    618		 */
    619		if (!strcmp(it.node->name, "vdev0buffer"))
    620			continue;
    621
    622		rmem = of_reserved_mem_lookup(it.node);
    623		if (!rmem) {
    624			dev_err(dev, "unable to acquire memory-region\n");
    625			return -EINVAL;
    626		}
    627
    628		if (imx_dsp_rproc_sys_to_da(priv, rmem->base, rmem->size, &da))
    629			return -EINVAL;
    630
    631		cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
    632		if (!cpu_addr) {
    633			dev_err(dev, "failed to map memory %p\n", &rmem->base);
    634			return -ENOMEM;
    635		}
    636
    637		/* Register memory region */
    638		mem = rproc_mem_entry_init(dev, cpu_addr, (dma_addr_t)rmem->base,
    639					   rmem->size, da, NULL, NULL, it.node->name);
    640
    641		if (mem)
    642			rproc_coredump_add_segment(rproc, da, rmem->size);
    643		else
    644			return -ENOMEM;
    645
    646		rproc_add_carveout(rproc, mem);
    647	}
    648
    649	return 0;
    650}
    651
    652/* Prepare function for rproc_ops */
    653static int imx_dsp_rproc_prepare(struct rproc *rproc)
    654{
    655	struct imx_dsp_rproc *priv = rproc->priv;
    656	struct device *dev = rproc->dev.parent;
    657	struct rproc_mem_entry *carveout;
    658	int ret;
    659
    660	ret = imx_dsp_rproc_add_carveout(priv);
    661	if (ret) {
    662		dev_err(dev, "failed on imx_dsp_rproc_add_carveout\n");
    663		return ret;
    664	}
    665
    666	pm_runtime_get_sync(dev);
    667
    668	/*
    669	 * Clear buffers after pm rumtime for internal ocram is not
    670	 * accessible if power and clock are not enabled.
    671	 */
    672	list_for_each_entry(carveout, &rproc->carveouts, node) {
    673		if (carveout->va)
    674			memset(carveout->va, 0, carveout->len);
    675	}
    676
    677	return  0;
    678}
    679
    680/* Unprepare function for rproc_ops */
    681static int imx_dsp_rproc_unprepare(struct rproc *rproc)
    682{
    683	pm_runtime_put_sync(rproc->dev.parent);
    684
    685	return  0;
    686}
    687
    688/* Kick function for rproc_ops */
    689static void imx_dsp_rproc_kick(struct rproc *rproc, int vqid)
    690{
    691	struct imx_dsp_rproc *priv = rproc->priv;
    692	struct device *dev = rproc->dev.parent;
    693	int err;
    694	__u32 mmsg;
    695
    696	if (!priv->tx_ch) {
    697		dev_err(dev, "No initialized mbox tx channel\n");
    698		return;
    699	}
    700
    701	/*
    702	 * Send the index of the triggered virtqueue as the mu payload.
    703	 * Let remote processor know which virtqueue is used.
    704	 */
    705	mmsg = vqid;
    706
    707	err = mbox_send_message(priv->tx_ch, (void *)&mmsg);
    708	if (err < 0)
    709		dev_err(dev, "%s: failed (%d, err:%d)\n", __func__, vqid, err);
    710}
    711
    712static int imx_dsp_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
    713{
    714	if (rproc_elf_load_rsc_table(rproc, fw))
    715		dev_warn(&rproc->dev, "no resource table found for this firmware\n");
    716
    717	return 0;
    718}
    719
    720static const struct rproc_ops imx_dsp_rproc_ops = {
    721	.prepare	= imx_dsp_rproc_prepare,
    722	.unprepare	= imx_dsp_rproc_unprepare,
    723	.start		= imx_dsp_rproc_start,
    724	.stop		= imx_dsp_rproc_stop,
    725	.kick		= imx_dsp_rproc_kick,
    726	.load		= rproc_elf_load_segments,
    727	.parse_fw	= imx_dsp_rproc_parse_fw,
    728	.sanity_check	= rproc_elf_sanity_check,
    729	.get_boot_addr	= rproc_elf_get_boot_addr,
    730};
    731
    732/**
    733 * imx_dsp_attach_pm_domains() - attach the power domains
    734 * @priv: private data pointer
    735 *
    736 * On i.MX8QM and i.MX8QXP there is multiple power domains
    737 * required, so need to link them.
    738 */
    739static int imx_dsp_attach_pm_domains(struct imx_dsp_rproc *priv)
    740{
    741	struct device *dev = priv->rproc->dev.parent;
    742	int ret, i;
    743
    744	priv->num_domains = of_count_phandle_with_args(dev->of_node,
    745						       "power-domains",
    746						       "#power-domain-cells");
    747
    748	/* If only one domain, then no need to link the device */
    749	if (priv->num_domains <= 1)
    750		return 0;
    751
    752	priv->pd_dev = devm_kmalloc_array(dev, priv->num_domains,
    753					  sizeof(*priv->pd_dev),
    754					  GFP_KERNEL);
    755	if (!priv->pd_dev)
    756		return -ENOMEM;
    757
    758	priv->pd_dev_link = devm_kmalloc_array(dev, priv->num_domains,
    759					       sizeof(*priv->pd_dev_link),
    760					       GFP_KERNEL);
    761	if (!priv->pd_dev_link)
    762		return -ENOMEM;
    763
    764	for (i = 0; i < priv->num_domains; i++) {
    765		priv->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
    766		if (IS_ERR(priv->pd_dev[i])) {
    767			ret = PTR_ERR(priv->pd_dev[i]);
    768			goto detach_pm;
    769		}
    770
    771		/*
    772		 * device_link_add will check priv->pd_dev[i], if it is
    773		 * NULL, then will break.
    774		 */
    775		priv->pd_dev_link[i] = device_link_add(dev,
    776						       priv->pd_dev[i],
    777						       DL_FLAG_STATELESS |
    778						       DL_FLAG_PM_RUNTIME);
    779		if (!priv->pd_dev_link[i]) {
    780			dev_pm_domain_detach(priv->pd_dev[i], false);
    781			ret = -EINVAL;
    782			goto detach_pm;
    783		}
    784	}
    785
    786	return 0;
    787
    788detach_pm:
    789	while (--i >= 0) {
    790		device_link_del(priv->pd_dev_link[i]);
    791		dev_pm_domain_detach(priv->pd_dev[i], false);
    792	}
    793
    794	return ret;
    795}
    796
    797static int imx_dsp_detach_pm_domains(struct imx_dsp_rproc *priv)
    798{
    799	int i;
    800
    801	if (priv->num_domains <= 1)
    802		return 0;
    803
    804	for (i = 0; i < priv->num_domains; i++) {
    805		device_link_del(priv->pd_dev_link[i]);
    806		dev_pm_domain_detach(priv->pd_dev[i], false);
    807	}
    808
    809	return 0;
    810}
    811
    812/**
    813 * imx_dsp_rproc_detect_mode() - detect DSP control mode
    814 * @priv: private data pointer
    815 *
    816 * Different platform has different control method for DSP, which depends
    817 * on how the DSP is integrated in platform.
    818 *
    819 * For i.MX8QXP and i.MX8QM, DSP should be started and stopped by System
    820 * Control Unit.
    821 * For i.MX8MP and i.MX8ULP, DSP should be started and stopped by system
    822 * integration module.
    823 */
    824static int imx_dsp_rproc_detect_mode(struct imx_dsp_rproc *priv)
    825{
    826	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
    827	struct device *dev = priv->rproc->dev.parent;
    828	struct regmap *regmap;
    829	int ret = 0;
    830
    831	switch (dsp_dcfg->dcfg->method) {
    832	case IMX_RPROC_SCU_API:
    833		ret = imx_scu_get_handle(&priv->ipc_handle);
    834		if (ret)
    835			return ret;
    836		break;
    837	case IMX_RPROC_MMIO:
    838		regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,dsp-ctrl");
    839		if (IS_ERR(regmap)) {
    840			dev_err(dev, "failed to find syscon\n");
    841			return PTR_ERR(regmap);
    842		}
    843
    844		priv->regmap = regmap;
    845		break;
    846	default:
    847		ret = -EOPNOTSUPP;
    848		break;
    849	}
    850
    851	return ret;
    852}
    853
    854static const char *imx_dsp_clks_names[DSP_RPROC_CLK_MAX] = {
    855	/* DSP clocks */
    856	"core", "ocram", "debug", "ipg", "mu",
    857};
    858
    859static int imx_dsp_rproc_clk_get(struct imx_dsp_rproc *priv)
    860{
    861	struct device *dev = priv->rproc->dev.parent;
    862	struct clk_bulk_data *clks = priv->clks;
    863	int i;
    864
    865	for (i = 0; i < DSP_RPROC_CLK_MAX; i++)
    866		clks[i].id = imx_dsp_clks_names[i];
    867
    868	return devm_clk_bulk_get_optional(dev, DSP_RPROC_CLK_MAX, clks);
    869}
    870
    871static int imx_dsp_rproc_probe(struct platform_device *pdev)
    872{
    873	const struct imx_dsp_rproc_dcfg *dsp_dcfg;
    874	struct device *dev = &pdev->dev;
    875	struct imx_dsp_rproc *priv;
    876	struct rproc *rproc;
    877	const char *fw_name;
    878	int ret;
    879
    880	dsp_dcfg = of_device_get_match_data(dev);
    881	if (!dsp_dcfg)
    882		return -ENODEV;
    883
    884	ret = rproc_of_parse_firmware(dev, 0, &fw_name);
    885	if (ret) {
    886		dev_err(dev, "failed to parse firmware-name property, ret = %d\n",
    887			ret);
    888		return ret;
    889	}
    890
    891	rproc = rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops, fw_name,
    892			    sizeof(*priv));
    893	if (!rproc)
    894		return -ENOMEM;
    895
    896	priv = rproc->priv;
    897	priv->rproc = rproc;
    898	priv->dsp_dcfg = dsp_dcfg;
    899
    900	dev_set_drvdata(dev, rproc);
    901
    902	INIT_WORK(&priv->rproc_work, imx_dsp_rproc_vq_work);
    903
    904	ret = imx_dsp_rproc_detect_mode(priv);
    905	if (ret) {
    906		dev_err(dev, "failed on imx_dsp_rproc_detect_mode\n");
    907		goto err_put_rproc;
    908	}
    909
    910	/* There are multiple power domains required by DSP on some platform */
    911	ret = imx_dsp_attach_pm_domains(priv);
    912	if (ret) {
    913		dev_err(dev, "failed on imx_dsp_attach_pm_domains\n");
    914		goto err_put_rproc;
    915	}
    916	/* Get clocks */
    917	ret = imx_dsp_rproc_clk_get(priv);
    918	if (ret) {
    919		dev_err(dev, "failed on imx_dsp_rproc_clk_get\n");
    920		goto err_detach_domains;
    921	}
    922
    923	init_completion(&priv->pm_comp);
    924	rproc->auto_boot = false;
    925	ret = rproc_add(rproc);
    926	if (ret) {
    927		dev_err(dev, "rproc_add failed\n");
    928		goto err_detach_domains;
    929	}
    930
    931	pm_runtime_enable(dev);
    932
    933	return 0;
    934
    935err_detach_domains:
    936	imx_dsp_detach_pm_domains(priv);
    937err_put_rproc:
    938	rproc_free(rproc);
    939
    940	return ret;
    941}
    942
    943static int imx_dsp_rproc_remove(struct platform_device *pdev)
    944{
    945	struct rproc *rproc = platform_get_drvdata(pdev);
    946	struct imx_dsp_rproc *priv = rproc->priv;
    947
    948	pm_runtime_disable(&pdev->dev);
    949	rproc_del(rproc);
    950	imx_dsp_detach_pm_domains(priv);
    951	rproc_free(rproc);
    952
    953	return 0;
    954}
    955
    956/* pm runtime functions */
    957static int imx_dsp_runtime_resume(struct device *dev)
    958{
    959	struct rproc *rproc = dev_get_drvdata(dev);
    960	struct imx_dsp_rproc *priv = rproc->priv;
    961	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
    962	int ret;
    963
    964	/*
    965	 * There is power domain attached with mailbox, if setup mailbox
    966	 * in probe(), then the power of mailbox is always enabled,
    967	 * the power can't be saved.
    968	 * So move setup of mailbox to runtime resume.
    969	 */
    970	ret = imx_dsp_rproc_mbox_init(priv);
    971	if (ret) {
    972		dev_err(dev, "failed on imx_dsp_rproc_mbox_init\n");
    973		return ret;
    974	}
    975
    976	ret = clk_bulk_prepare_enable(DSP_RPROC_CLK_MAX, priv->clks);
    977	if (ret) {
    978		dev_err(dev, "failed on clk_bulk_prepare_enable\n");
    979		return ret;
    980	}
    981
    982	/* Reset DSP if needed */
    983	if (dsp_dcfg->reset)
    984		dsp_dcfg->reset(priv);
    985
    986	return 0;
    987}
    988
    989static int imx_dsp_runtime_suspend(struct device *dev)
    990{
    991	struct rproc *rproc = dev_get_drvdata(dev);
    992	struct imx_dsp_rproc *priv = rproc->priv;
    993
    994	clk_bulk_disable_unprepare(DSP_RPROC_CLK_MAX, priv->clks);
    995
    996	imx_dsp_rproc_free_mbox(priv);
    997
    998	return 0;
    999}
   1000
   1001static void imx_dsp_load_firmware(const struct firmware *fw, void *context)
   1002{
   1003	struct rproc *rproc = context;
   1004	int ret;
   1005
   1006	/*
   1007	 * Same flow as start procedure.
   1008	 * Load the ELF segments to memory firstly.
   1009	 */
   1010	ret = rproc_load_segments(rproc, fw);
   1011	if (ret)
   1012		goto out;
   1013
   1014	/* Start the remote processor */
   1015	ret = rproc->ops->start(rproc);
   1016	if (ret)
   1017		goto out;
   1018
   1019	rproc->ops->kick(rproc, 0);
   1020
   1021out:
   1022	release_firmware(fw);
   1023}
   1024
   1025static __maybe_unused int imx_dsp_suspend(struct device *dev)
   1026{
   1027	struct rproc *rproc = dev_get_drvdata(dev);
   1028	struct imx_dsp_rproc *priv = rproc->priv;
   1029	__u32 mmsg = RP_MBOX_SUSPEND_SYSTEM;
   1030	int ret;
   1031
   1032	if (rproc->state != RPROC_RUNNING)
   1033		goto out;
   1034
   1035	reinit_completion(&priv->pm_comp);
   1036
   1037	/* Tell DSP that suspend is happening */
   1038	ret = mbox_send_message(priv->tx_ch, (void *)&mmsg);
   1039	if (ret < 0) {
   1040		dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
   1041		return ret;
   1042	}
   1043
   1044	/*
   1045	 * DSP need to save the context at suspend.
   1046	 * Here waiting the response for DSP, then power can be disabled.
   1047	 */
   1048	if (!wait_for_completion_timeout(&priv->pm_comp, msecs_to_jiffies(100)))
   1049		return -EBUSY;
   1050
   1051out:
   1052	/*
   1053	 * The power of DSP is disabled in suspend, so force pm runtime
   1054	 * to be suspend, then we can reenable the power and clocks at
   1055	 * resume stage.
   1056	 */
   1057	return pm_runtime_force_suspend(dev);
   1058}
   1059
   1060static __maybe_unused int imx_dsp_resume(struct device *dev)
   1061{
   1062	struct rproc *rproc = dev_get_drvdata(dev);
   1063	int ret = 0;
   1064
   1065	ret = pm_runtime_force_resume(dev);
   1066	if (ret)
   1067		return ret;
   1068
   1069	if (rproc->state != RPROC_RUNNING)
   1070		return 0;
   1071
   1072	/*
   1073	 * The power of DSP is disabled at suspend, the memory of dsp
   1074	 * is reset, the image segments are lost. So need to reload
   1075	 * firmware and restart the DSP if it is in running state.
   1076	 */
   1077	ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
   1078				      rproc->firmware, dev, GFP_KERNEL,
   1079				      rproc, imx_dsp_load_firmware);
   1080	if (ret < 0) {
   1081		dev_err(dev, "load firmware failed: %d\n", ret);
   1082		goto err;
   1083	}
   1084
   1085	return 0;
   1086
   1087err:
   1088	pm_runtime_force_suspend(dev);
   1089
   1090	return ret;
   1091}
   1092
   1093static const struct dev_pm_ops imx_dsp_rproc_pm_ops = {
   1094	SET_SYSTEM_SLEEP_PM_OPS(imx_dsp_suspend, imx_dsp_resume)
   1095	SET_RUNTIME_PM_OPS(imx_dsp_runtime_suspend,
   1096			   imx_dsp_runtime_resume, NULL)
   1097};
   1098
   1099static const struct of_device_id imx_dsp_rproc_of_match[] = {
   1100	{ .compatible = "fsl,imx8qxp-hifi4", .data = &imx_dsp_rproc_cfg_imx8qxp },
   1101	{ .compatible = "fsl,imx8qm-hifi4",  .data = &imx_dsp_rproc_cfg_imx8qm },
   1102	{ .compatible = "fsl,imx8mp-hifi4",  .data = &imx_dsp_rproc_cfg_imx8mp },
   1103	{ .compatible = "fsl,imx8ulp-hifi4", .data = &imx_dsp_rproc_cfg_imx8ulp },
   1104	{},
   1105};
   1106MODULE_DEVICE_TABLE(of, imx_dsp_rproc_of_match);
   1107
   1108static struct platform_driver imx_dsp_rproc_driver = {
   1109	.probe = imx_dsp_rproc_probe,
   1110	.remove = imx_dsp_rproc_remove,
   1111	.driver = {
   1112		.name = "imx-dsp-rproc",
   1113		.of_match_table = imx_dsp_rproc_of_match,
   1114		.pm = &imx_dsp_rproc_pm_ops,
   1115	},
   1116};
   1117module_platform_driver(imx_dsp_rproc_driver);
   1118
   1119MODULE_LICENSE("GPL v2");
   1120MODULE_DESCRIPTION("i.MX HiFi Core Remote Processor Control Driver");
   1121MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@nxp.com>");