File Index
Files and directories
Sign in
FILE

imx_rproc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/remoteproc/imx_rproc.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2017 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
   4 */
   5
   6#include <dt-bindings/firmware/imx/rsrc.h>
   7#include <linux/arm-smccc.h>
   8#include <linux/clk.h>
   9#include <linux/err.h>
  10#include <linux/firmware/imx/sci.h>
  11#include <linux/interrupt.h>
  12#include <linux/kernel.h>
  13#include <linux/mailbox_client.h>
  14#include <linux/mfd/syscon.h>
  15#include <linux/module.h>
  16#include <linux/of.h>
  17#include <linux/of_address.h>
  18#include <linux/of_reserved_mem.h>
  19#include <linux/platform_device.h>
  20#include <linux/pm_domain.h>
  21#include <linux/pm_runtime.h>
  22#include <linux/reboot.h>
  23#include <linux/regmap.h>
  24#include <linux/remoteproc.h>
  25#include <linux/workqueue.h>
  26
  27#include "imx_rproc.h"
  28#include "remoteproc_internal.h"
  29
  30#define IMX7D_SRC_SCR			0x0C
  31#define IMX7D_ENABLE_M4			BIT(3)
  32#define IMX7D_SW_M4P_RST		BIT(2)
  33#define IMX7D_SW_M4C_RST		BIT(1)
  34#define IMX7D_SW_M4C_NON_SCLR_RST	BIT(0)
  35
  36#define IMX7D_M4_RST_MASK		(IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
  37					 | IMX7D_SW_M4C_RST \
  38					 | IMX7D_SW_M4C_NON_SCLR_RST)
  39
  40#define IMX7D_M4_START			(IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
  41					 | IMX7D_SW_M4C_RST)
  42#define IMX7D_M4_STOP			(IMX7D_ENABLE_M4 | IMX7D_SW_M4C_RST | \
  43					 IMX7D_SW_M4C_NON_SCLR_RST)
  44
  45#define IMX8M_M7_STOP			(IMX7D_ENABLE_M4 | IMX7D_SW_M4C_RST)
  46#define IMX8M_M7_POLL			IMX7D_ENABLE_M4
  47
  48#define IMX8M_GPR22			0x58
  49#define IMX8M_GPR22_CM7_CPUWAIT		BIT(0)
  50
  51/* Address: 0x020D8000 */
  52#define IMX6SX_SRC_SCR			0x00
  53#define IMX6SX_ENABLE_M4		BIT(22)
  54#define IMX6SX_SW_M4P_RST		BIT(12)
  55#define IMX6SX_SW_M4C_NON_SCLR_RST	BIT(4)
  56#define IMX6SX_SW_M4C_RST		BIT(3)
  57
  58#define IMX6SX_M4_START			(IMX6SX_ENABLE_M4 | IMX6SX_SW_M4P_RST \
  59					 | IMX6SX_SW_M4C_RST)
  60#define IMX6SX_M4_STOP			(IMX6SX_ENABLE_M4 | IMX6SX_SW_M4C_RST | \
  61					 IMX6SX_SW_M4C_NON_SCLR_RST)
  62#define IMX6SX_M4_RST_MASK		(IMX6SX_ENABLE_M4 | IMX6SX_SW_M4P_RST \
  63					 | IMX6SX_SW_M4C_NON_SCLR_RST \
  64					 | IMX6SX_SW_M4C_RST)
  65
  66#define IMX_RPROC_MEM_MAX		32
  67
  68#define IMX_SIP_RPROC			0xC2000005
  69#define IMX_SIP_RPROC_START		0x00
  70#define IMX_SIP_RPROC_STARTED		0x01
  71#define IMX_SIP_RPROC_STOP		0x02
  72
  73#define IMX_SC_IRQ_GROUP_REBOOTED	5
  74
  75/**
  76 * struct imx_rproc_mem - slim internal memory structure
  77 * @cpu_addr: MPU virtual address of the memory region
  78 * @sys_addr: Bus address used to access the memory region
  79 * @size: Size of the memory region
  80 */
  81struct imx_rproc_mem {
  82	void __iomem *cpu_addr;
  83	phys_addr_t sys_addr;
  84	size_t size;
  85};
  86
  87/* att flags: lower 16 bits specifying core, higher 16 bits for flags  */
  88/* M4 own area. Can be mapped at probe */
  89#define ATT_OWN         BIT(31)
  90#define ATT_IOMEM       BIT(30)
  91
  92#define ATT_CORE_MASK   0xffff
  93#define ATT_CORE(I)     BIT((I))
  94
  95static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block);
  96static void imx_rproc_free_mbox(void *data);
  97
  98struct imx_rproc {
  99	struct device			*dev;
 100	struct regmap			*regmap;
 101	struct regmap			*gpr;
 102	struct rproc			*rproc;
 103	const struct imx_rproc_dcfg	*dcfg;
 104	struct imx_rproc_mem		mem[IMX_RPROC_MEM_MAX];
 105	struct clk			*clk;
 106	struct mbox_client		cl;
 107	struct mbox_chan		*tx_ch;
 108	struct mbox_chan		*rx_ch;
 109	struct work_struct		rproc_work;
 110	struct workqueue_struct		*workqueue;
 111	void __iomem			*rsc_table;
 112	struct imx_sc_ipc		*ipc_handle;
 113	struct notifier_block		rproc_nb;
 114	u32				rproc_pt;	/* partition id */
 115	u32				rsrc_id;	/* resource id */
 116	u32				entry;		/* cpu start address */
 117	u32				core_index;
 118	struct dev_pm_domain_list	*pd_list;
 119};
 120
 121static const struct imx_rproc_att imx_rproc_att_imx93[] = {
 122	/* dev addr , sys addr  , size	    , flags */
 123	/* TCM CODE NON-SECURE */
 124	{ 0x0FFC0000, 0x201C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
 125
 126	/* TCM CODE SECURE */
 127	{ 0x1FFC0000, 0x201C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
 128
 129	/* TCM SYS NON-SECURE*/
 130	{ 0x20000000, 0x20200000, 0x00040000, ATT_OWN | ATT_IOMEM },
 131
 132	/* TCM SYS SECURE*/
 133	{ 0x30000000, 0x20200000, 0x00040000, ATT_OWN | ATT_IOMEM },
 134
 135	/* DDR */
 136	{ 0x80000000, 0x80000000, 0x10000000, 0 },
 137	{ 0x90000000, 0x80000000, 0x10000000, 0 },
 138
 139	{ 0xC0000000, 0xC0000000, 0x10000000, 0 },
 140	{ 0xD0000000, 0xC0000000, 0x10000000, 0 },
 141};
 142
 143static const struct imx_rproc_att imx_rproc_att_imx8qm[] = {
 144	/* dev addr , sys addr  , size      , flags */
 145	{ 0x08000000, 0x08000000, 0x10000000, 0},
 146	/* TCML */
 147	{ 0x1FFE0000, 0x34FE0000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(0)},
 148	{ 0x1FFE0000, 0x38FE0000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(1)},
 149	/* TCMU */
 150	{ 0x20000000, 0x35000000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(0)},
 151	{ 0x20000000, 0x39000000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(1)},
 152	/* DDR (Data) */
 153	{ 0x80000000, 0x80000000, 0x60000000, 0 },
 154};
 155
 156static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
 157	{ 0x08000000, 0x08000000, 0x10000000, 0 },
 158	/* TCML/U */
 159	{ 0x1FFE0000, 0x34FE0000, 0x00040000, ATT_OWN | ATT_IOMEM },
 160	/* OCRAM(Low 96KB) */
 161	{ 0x21000000, 0x00100000, 0x00018000, 0 },
 162	/* OCRAM */
 163	{ 0x21100000, 0x00100000, 0x00040000, 0 },
 164	/* DDR (Data) */
 165	{ 0x80000000, 0x80000000, 0x60000000, 0 },
 166};
 167
 168static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
 169	/* dev addr , sys addr  , size	    , flags */
 170	/* ITCM   */
 171	{ 0x00000000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
 172	/* OCRAM_S */
 173	{ 0x00180000, 0x00180000, 0x00009000, 0 },
 174	/* OCRAM */
 175	{ 0x00900000, 0x00900000, 0x00020000, 0 },
 176	/* OCRAM */
 177	{ 0x00920000, 0x00920000, 0x00020000, 0 },
 178	/* OCRAM */
 179	{ 0x00940000, 0x00940000, 0x00050000, 0 },
 180	/* QSPI Code - alias */
 181	{ 0x08000000, 0x08000000, 0x08000000, 0 },
 182	/* DDR (Code) - alias */
 183	{ 0x10000000, 0x40000000, 0x0FFE0000, 0 },
 184	/* DTCM */
 185	{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN | ATT_IOMEM },
 186	/* OCRAM_S - alias */
 187	{ 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
 188	/* OCRAM */
 189	{ 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
 190	/* OCRAM */
 191	{ 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
 192	/* OCRAM */
 193	{ 0x20240000, 0x00940000, 0x00040000, ATT_OWN },
 194	/* DDR (Data) */
 195	{ 0x40000000, 0x40000000, 0x80000000, 0 },
 196};
 197
 198static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
 199	/* dev addr , sys addr  , size	    , flags */
 200	/* TCML - alias */
 201	{ 0x00000000, 0x007e0000, 0x00020000, ATT_IOMEM},
 202	/* OCRAM_S */
 203	{ 0x00180000, 0x00180000, 0x00008000, 0 },
 204	/* OCRAM */
 205	{ 0x00900000, 0x00900000, 0x00020000, 0 },
 206	/* OCRAM */
 207	{ 0x00920000, 0x00920000, 0x00020000, 0 },
 208	/* QSPI Code - alias */
 209	{ 0x08000000, 0x08000000, 0x08000000, 0 },
 210	/* DDR (Code) - alias */
 211	{ 0x10000000, 0x40000000, 0x0FFE0000, 0 },
 212	/* TCML/U */
 213	{ 0x1FFE0000, 0x007E0000, 0x00040000, ATT_OWN  | ATT_IOMEM},
 214	/* OCRAM_S */
 215	{ 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
 216	/* OCRAM */
 217	{ 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
 218	/* OCRAM */
 219	{ 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
 220	/* DDR (Data) */
 221	{ 0x40000000, 0x40000000, 0x80000000, 0 },
 222};
 223
 224static const struct imx_rproc_att imx_rproc_att_imx8ulp[] = {
 225	{0x1FFC0000, 0x1FFC0000, 0xC0000, ATT_OWN},
 226	{0x21000000, 0x21000000, 0x10000, ATT_OWN},
 227	{0x80000000, 0x80000000, 0x60000000, 0}
 228};
 229
 230static const struct imx_rproc_att imx_rproc_att_imx7ulp[] = {
 231	{0x1FFD0000, 0x1FFD0000, 0x30000, ATT_OWN},
 232	{0x20000000, 0x20000000, 0x10000, ATT_OWN},
 233	{0x2F000000, 0x2F000000, 0x20000, ATT_OWN},
 234	{0x2F020000, 0x2F020000, 0x20000, ATT_OWN},
 235	{0x60000000, 0x60000000, 0x40000000, 0}
 236};
 237
 238static const struct imx_rproc_att imx_rproc_att_imx7d[] = {
 239	/* dev addr , sys addr  , size	    , flags */
 240	/* OCRAM_S (M4 Boot code) - alias */
 241	{ 0x00000000, 0x00180000, 0x00008000, 0 },
 242	/* OCRAM_S (Code) */
 243	{ 0x00180000, 0x00180000, 0x00008000, ATT_OWN },
 244	/* OCRAM (Code) - alias */
 245	{ 0x00900000, 0x00900000, 0x00020000, 0 },
 246	/* OCRAM_EPDC (Code) - alias */
 247	{ 0x00920000, 0x00920000, 0x00020000, 0 },
 248	/* OCRAM_PXP (Code) - alias */
 249	{ 0x00940000, 0x00940000, 0x00008000, 0 },
 250	/* TCML (Code) */
 251	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
 252	/* DDR (Code) - alias, first part of DDR (Data) */
 253	{ 0x10000000, 0x80000000, 0x0FFF0000, 0 },
 254
 255	/* TCMU (Data) */
 256	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
 257	/* OCRAM (Data) */
 258	{ 0x20200000, 0x00900000, 0x00020000, 0 },
 259	/* OCRAM_EPDC (Data) */
 260	{ 0x20220000, 0x00920000, 0x00020000, 0 },
 261	/* OCRAM_PXP (Data) */
 262	{ 0x20240000, 0x00940000, 0x00008000, 0 },
 263	/* DDR (Data) */
 264	{ 0x80000000, 0x80000000, 0x60000000, 0 },
 265};
 266
 267static const struct imx_rproc_att imx_rproc_att_imx6sx[] = {
 268	/* dev addr , sys addr  , size	    , flags */
 269	/* TCML (M4 Boot Code) - alias */
 270	{ 0x00000000, 0x007F8000, 0x00008000, ATT_IOMEM },
 271	/* OCRAM_S (Code) */
 272	{ 0x00180000, 0x008F8000, 0x00004000, 0 },
 273	/* OCRAM_S (Code) - alias */
 274	{ 0x00180000, 0x008FC000, 0x00004000, 0 },
 275	/* TCML (Code) */
 276	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
 277	/* DDR (Code) - alias, first part of DDR (Data) */
 278	{ 0x10000000, 0x80000000, 0x0FFF8000, 0 },
 279
 280	/* TCMU (Data) */
 281	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
 282	/* OCRAM_S (Data) - alias? */
 283	{ 0x208F8000, 0x008F8000, 0x00004000, 0 },
 284	/* DDR (Data) */
 285	{ 0x80000000, 0x80000000, 0x60000000, 0 },
 286};
 287
 288static int imx_rproc_arm_smc_start(struct rproc *rproc)
 289{
 290	struct arm_smccc_res res;
 291
 292	arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_START, 0, 0, 0, 0, 0, 0, &res);
 293
 294	return res.a0;
 295}
 296
 297static int imx_rproc_mmio_start(struct rproc *rproc)
 298{
 299	struct imx_rproc *priv = rproc->priv;
 300	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 301
 302	if (priv->gpr)
 303		return regmap_clear_bits(priv->gpr, dcfg->gpr_reg, dcfg->gpr_wait);
 304
 305	return regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask, dcfg->src_start);
 306}
 307
 308static int imx_rproc_scu_api_start(struct rproc *rproc)
 309{
 310	struct imx_rproc *priv = rproc->priv;
 311
 312	return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, true, priv->entry);
 313}
 314
 315static int imx_rproc_start(struct rproc *rproc)
 316{
 317	struct imx_rproc *priv = rproc->priv;
 318	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 319	struct device *dev = priv->dev;
 320	int ret;
 321
 322	ret = imx_rproc_xtr_mbox_init(rproc, true);
 323	if (ret)
 324		return ret;
 325
 326	if (!dcfg->ops || !dcfg->ops->start)
 327		return -EOPNOTSUPP;
 328
 329	ret = dcfg->ops->start(rproc);
 330	if (ret)
 331		dev_err(dev, "Failed to enable remote core!\n");
 332
 333	return ret;
 334}
 335
 336static int imx_rproc_arm_smc_stop(struct rproc *rproc)
 337{
 338	struct imx_rproc *priv = rproc->priv;
 339	struct arm_smccc_res res;
 340
 341	arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STOP, 0, 0, 0, 0, 0, 0, &res);
 342	if (res.a1)
 343		dev_info(priv->dev, "Not in wfi, force stopped\n");
 344
 345	return res.a0;
 346}
 347
 348static int imx_rproc_mmio_stop(struct rproc *rproc)
 349{
 350	struct imx_rproc *priv = rproc->priv;
 351	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 352	int ret;
 353
 354	if (priv->gpr) {
 355		ret = regmap_set_bits(priv->gpr, dcfg->gpr_reg, dcfg->gpr_wait);
 356		if (ret) {
 357			dev_err(priv->dev, "Failed to quiescence M4 platform!\n");
 358			return ret;
 359		}
 360	}
 361
 362	return regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask, dcfg->src_stop);
 363}
 364
 365static int imx_rproc_scu_api_stop(struct rproc *rproc)
 366{
 367	struct imx_rproc *priv = rproc->priv;
 368
 369	return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, false, priv->entry);
 370}
 371
 372static int imx_rproc_stop(struct rproc *rproc)
 373{
 374	struct imx_rproc *priv = rproc->priv;
 375	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 376	struct device *dev = priv->dev;
 377	int ret;
 378
 379	if (!dcfg->ops || !dcfg->ops->stop)
 380		return -EOPNOTSUPP;
 381
 382	ret = dcfg->ops->stop(rproc);
 383	if (ret)
 384		dev_err(dev, "Failed to stop remote core\n");
 385	else
 386		imx_rproc_free_mbox(rproc);
 387
 388	return ret;
 389}
 390
 391static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
 392			       size_t len, u64 *sys, bool *is_iomem)
 393{
 394	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 395	int i;
 396
 397	/* parse address translation table */
 398	for (i = 0; i < dcfg->att_size; i++) {
 399		const struct imx_rproc_att *att = &dcfg->att[i];
 400
 401		/*
 402		 * Ignore entries not belong to current core:
 403		 * i.MX8QM has dual general M4_[0,1] cores, M4_0's own entries
 404		 * has "ATT_CORE(0) & BIT(0)" true, M4_1's own entries has
 405		 * "ATT_CORE(1) & BIT(1)" true.
 406		 */
 407		if (att->flags & ATT_CORE_MASK) {
 408			if (!((BIT(priv->core_index)) & (att->flags & ATT_CORE_MASK)))
 409				continue;
 410		}
 411
 412		if (da >= att->da && da + len < att->da + att->size) {
 413			unsigned int offset = da - att->da;
 414
 415			*sys = att->sa + offset;
 416			if (is_iomem)
 417				*is_iomem = att->flags & ATT_IOMEM;
 418			return 0;
 419		}
 420	}
 421
 422	dev_warn(priv->dev, "Translation failed: da = 0x%llx len = 0x%zx\n",
 423		 da, len);
 424	return -ENOENT;
 425}
 426
 427static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
 428{
 429	struct imx_rproc *priv = rproc->priv;
 430	void *va = NULL;
 431	u64 sys;
 432	int i;
 433
 434	if (len == 0)
 435		return NULL;
 436
 437	/*
 438	 * On device side we have many aliases, so we need to convert device
 439	 * address (M4) to system bus address first.
 440	 */
 441	if (imx_rproc_da_to_sys(priv, da, len, &sys, is_iomem))
 442		return NULL;
 443
 444	for (i = 0; i < IMX_RPROC_MEM_MAX; i++) {
 445		if (sys >= priv->mem[i].sys_addr && sys + len <
 446		    priv->mem[i].sys_addr +  priv->mem[i].size) {
 447			unsigned int offset = sys - priv->mem[i].sys_addr;
 448			/* __force to make sparse happy with type conversion */
 449			va = (__force void *)(priv->mem[i].cpu_addr + offset);
 450			break;
 451		}
 452	}
 453
 454	dev_dbg(&rproc->dev, "da = 0x%llx len = 0x%zx va = 0x%p\n",
 455		da, len, va);
 456
 457	return va;
 458}
 459
 460static int imx_rproc_mem_alloc(struct rproc *rproc,
 461			       struct rproc_mem_entry *mem)
 462{
 463	struct device *dev = rproc->dev.parent;
 464	void *va;
 465
 466	dev_dbg(dev, "map memory: %p+%zx\n", &mem->dma, mem->len);
 467	va = ioremap_wc(mem->dma, mem->len);
 468	if (IS_ERR_OR_NULL(va)) {
 469		dev_err(dev, "Unable to map memory region: %p+%zx\n",
 470			&mem->dma, mem->len);
 471		return -ENOMEM;
 472	}
 473
 474	/* Update memory entry va */
 475	mem->va = va;
 476
 477	return 0;
 478}
 479
 480static int imx_rproc_mem_release(struct rproc *rproc,
 481				 struct rproc_mem_entry *mem)
 482{
 483	dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma);
 484	iounmap(mem->va);
 485
 486	return 0;
 487}
 488
 489static int imx_rproc_prepare(struct rproc *rproc)
 490{
 491	struct imx_rproc *priv = rproc->priv;
 492	struct device_node *np = priv->dev->of_node;
 493	struct rproc_mem_entry *mem;
 494	int i = 0;
 495	u32 da;
 496
 497	/* Register associated reserved memory regions */
 498	while (1) {
 499		int err;
 500		struct resource res;
 501
 502		err = of_reserved_mem_region_to_resource(np, i++, &res);
 503		if (err)
 504			return 0;
 505
 506		/*
 507		 * Ignore the first memory region which will be used vdev buffer.
 508		 * No need to do extra handlings, rproc_add_virtio_dev will handle it.
 509		 */
 510		if (strstarts(res.name, "vdev0buffer"))
 511			continue;
 512
 513		if (strstarts(res.name, "rsc-table"))
 514			continue;
 515
 516		/* No need to translate pa to da, i.MX use same map */
 517		da = res.start;
 518
 519		/* Register memory region */
 520		mem = rproc_mem_entry_init(priv->dev, NULL, (dma_addr_t)res.start,
 521					   resource_size(&res), da,
 522					   imx_rproc_mem_alloc, imx_rproc_mem_release,
 523					   "%.*s", strchrnul(res.name, '@') - res.name,
 524					   res.name);
 525		if (!mem)
 526			return -ENOMEM;
 527
 528		rproc_coredump_add_segment(rproc, da, resource_size(&res));
 529		rproc_add_carveout(rproc, mem);
 530	}
 531}
 532
 533static int imx_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
 534{
 535	int ret;
 536
 537	ret = rproc_elf_load_rsc_table(rproc, fw);
 538	if (ret)
 539		dev_info(&rproc->dev, "No resource table in elf\n");
 540
 541	return 0;
 542}
 543
 544static void imx_rproc_kick(struct rproc *rproc, int vqid)
 545{
 546	struct imx_rproc *priv = rproc->priv;
 547	int err;
 548	__u32 mmsg;
 549
 550	if (!priv->tx_ch) {
 551		dev_err(priv->dev, "No initialized mbox tx channel\n");
 552		return;
 553	}
 554
 555	/*
 556	 * Send the index of the triggered virtqueue as the mu payload.
 557	 * Let remote processor know which virtqueue is used.
 558	 */
 559	mmsg = vqid << 16;
 560
 561	err = mbox_send_message(priv->tx_ch, (void *)&mmsg);
 562	if (err < 0)
 563		dev_err(priv->dev, "%s: failed (%d, err:%d)\n",
 564			__func__, vqid, err);
 565}
 566
 567static int imx_rproc_attach(struct rproc *rproc)
 568{
 569	return imx_rproc_xtr_mbox_init(rproc, true);
 570}
 571
 572static int imx_rproc_scu_api_detach(struct rproc *rproc)
 573{
 574	struct imx_rproc *priv = rproc->priv;
 575
 576	if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id))
 577		return -EOPNOTSUPP;
 578
 579	imx_rproc_free_mbox(rproc);
 580
 581	return 0;
 582}
 583
 584static int imx_rproc_detach(struct rproc *rproc)
 585{
 586	struct imx_rproc *priv = rproc->priv;
 587	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 588
 589	if (!dcfg->ops || !dcfg->ops->detach)
 590		return -EOPNOTSUPP;
 591
 592	return dcfg->ops->detach(rproc);
 593}
 594
 595static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
 596{
 597	struct imx_rproc *priv = rproc->priv;
 598
 599	/* The resource table has already been mapped in imx_rproc_addr_init */
 600	if (!priv->rsc_table)
 601		return NULL;
 602
 603	*table_sz = SZ_1K;
 604	return (struct resource_table *)priv->rsc_table;
 605}
 606
 607static struct resource_table *
 608imx_rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
 609{
 610	struct imx_rproc *priv = rproc->priv;
 611
 612	/* No resource table in the firmware */
 613	if (!rproc->table_ptr)
 614		return NULL;
 615
 616	if (priv->rsc_table)
 617		return (struct resource_table *)priv->rsc_table;
 618
 619	return rproc_elf_find_loaded_rsc_table(rproc, fw);
 620}
 621
 622static const struct rproc_ops imx_rproc_ops = {
 623	.prepare	= imx_rproc_prepare,
 624	.attach		= imx_rproc_attach,
 625	.detach		= imx_rproc_detach,
 626	.start		= imx_rproc_start,
 627	.stop		= imx_rproc_stop,
 628	.kick		= imx_rproc_kick,
 629	.da_to_va       = imx_rproc_da_to_va,
 630	.load		= rproc_elf_load_segments,
 631	.parse_fw	= imx_rproc_parse_fw,
 632	.find_loaded_rsc_table = imx_rproc_elf_find_loaded_rsc_table,
 633	.get_loaded_rsc_table = imx_rproc_get_loaded_rsc_table,
 634	.sanity_check	= rproc_elf_sanity_check,
 635	.get_boot_addr	= rproc_elf_get_boot_addr,
 636};
 637
 638static int imx_rproc_addr_init(struct imx_rproc *priv,
 639			       struct platform_device *pdev)
 640{
 641	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 642	struct device *dev = &pdev->dev;
 643	struct device_node *np = dev->of_node;
 644	int a, b = 0, err, nph;
 645
 646	/* remap required addresses */
 647	for (a = 0; a < dcfg->att_size; a++) {
 648		const struct imx_rproc_att *att = &dcfg->att[a];
 649
 650		if (!(att->flags & ATT_OWN))
 651			continue;
 652
 653		if (b >= IMX_RPROC_MEM_MAX)
 654			break;
 655
 656		if (att->flags & ATT_IOMEM)
 657			priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev,
 658							     att->sa, att->size);
 659		else
 660			priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev,
 661								att->sa, att->size);
 662		if (!priv->mem[b].cpu_addr) {
 663			dev_err(dev, "failed to remap %#x bytes from %#x\n", att->size, att->sa);
 664			return -ENOMEM;
 665		}
 666		priv->mem[b].sys_addr = att->sa;
 667		priv->mem[b].size = att->size;
 668		b++;
 669	}
 670
 671	/* memory-region is optional property */
 672	nph = of_reserved_mem_region_count(np);
 673	if (nph <= 0)
 674		return 0;
 675
 676	/* remap optional addresses */
 677	for (a = 0; a < nph; a++) {
 678		struct resource res;
 679
 680		err = of_reserved_mem_region_to_resource(np, a, &res);
 681		if (err) {
 682			dev_err(dev, "unable to resolve memory region\n");
 683			return err;
 684		}
 685
 686		/* Not map vdevbuffer, vdevring region */
 687		if (strstarts(res.name, "vdev"))
 688			continue;
 689
 690		if (b >= IMX_RPROC_MEM_MAX)
 691			break;
 692
 693		/* Not use resource version, because we might share region */
 694		priv->mem[b].cpu_addr = devm_ioremap_resource_wc(&pdev->dev, &res);
 695		if (!priv->mem[b].cpu_addr) {
 696			dev_err(dev, "failed to remap %pr\n", &res);
 697			return -ENOMEM;
 698		}
 699		priv->mem[b].sys_addr = res.start;
 700		priv->mem[b].size = resource_size(&res);
 701		if (strstarts(res.name, "rsc-table"))
 702			priv->rsc_table = priv->mem[b].cpu_addr;
 703		b++;
 704	}
 705
 706	return 0;
 707}
 708
 709static int imx_rproc_notified_idr_cb(int id, void *ptr, void *data)
 710{
 711	struct rproc *rproc = data;
 712
 713	rproc_vq_interrupt(rproc, id);
 714
 715	return 0;
 716}
 717
 718static void imx_rproc_vq_work(struct work_struct *work)
 719{
 720	struct imx_rproc *priv = container_of(work, struct imx_rproc,
 721					      rproc_work);
 722	struct rproc *rproc = priv->rproc;
 723
 724	idr_for_each(&rproc->notifyids, imx_rproc_notified_idr_cb, rproc);
 725}
 726
 727static void imx_rproc_rx_callback(struct mbox_client *cl, void *msg)
 728{
 729	struct rproc *rproc = dev_get_drvdata(cl->dev);
 730	struct imx_rproc *priv = rproc->priv;
 731
 732	queue_work(priv->workqueue, &priv->rproc_work);
 733}
 734
 735static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block)
 736{
 737	struct imx_rproc *priv = rproc->priv;
 738	struct device *dev = priv->dev;
 739	struct mbox_client *cl;
 740
 741	/*
 742	 * stop() and detach() will free the mbox channels, so need
 743	 * to request mbox channels in start() and attach().
 744	 *
 745	 * Because start() and attach() not able to handle mbox defer
 746	 * probe, imx_rproc_xtr_mbox_init is also called in probe().
 747	 * The check is to avoid request mbox again when start() or
 748	 * attach() after probe() returns success.
 749	 */
 750	if (priv->tx_ch && priv->rx_ch)
 751		return 0;
 752
 753	if (!of_property_present(dev->of_node, "mbox-names"))
 754		return 0;
 755
 756	cl = &priv->cl;
 757	cl->dev = dev;
 758	cl->tx_block = tx_block;
 759	cl->tx_tout = 100;
 760	cl->knows_txdone = false;
 761	cl->rx_callback = imx_rproc_rx_callback;
 762
 763	priv->tx_ch = mbox_request_channel_byname(cl, "tx");
 764	if (IS_ERR(priv->tx_ch))
 765		return dev_err_probe(cl->dev, PTR_ERR(priv->tx_ch),
 766				     "failed to request tx mailbox channel\n");
 767
 768	priv->rx_ch = mbox_request_channel_byname(cl, "rx");
 769	if (IS_ERR(priv->rx_ch)) {
 770		mbox_free_channel(priv->tx_ch);
 771		return dev_err_probe(cl->dev, PTR_ERR(priv->rx_ch),
 772				     "failed to request rx mailbox channel\n");
 773	}
 774
 775	return 0;
 776}
 777
 778static void imx_rproc_free_mbox(void *data)
 779{
 780	struct rproc *rproc = data;
 781	struct imx_rproc *priv = rproc->priv;
 782
 783	if (priv->tx_ch) {
 784		mbox_free_channel(priv->tx_ch);
 785		priv->tx_ch = NULL;
 786	}
 787
 788	if (priv->rx_ch) {
 789		mbox_free_channel(priv->rx_ch);
 790		priv->rx_ch = NULL;
 791	}
 792}
 793
 794static void imx_rproc_put_scu(void *data)
 795{
 796	struct imx_rproc *priv = data;
 797
 798	if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) {
 799		dev_pm_domain_detach_list(priv->pd_list);
 800		return;
 801	}
 802
 803	imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt), false);
 804	imx_scu_irq_unregister_notifier(&priv->rproc_nb);
 805}
 806
 807static int imx_rproc_partition_notify(struct notifier_block *nb,
 808				      unsigned long event, void *group)
 809{
 810	struct imx_rproc *priv = container_of(nb, struct imx_rproc, rproc_nb);
 811
 812	/* Ignore other irqs */
 813	if (!((event & BIT(priv->rproc_pt)) && (*(u8 *)group == IMX_SC_IRQ_GROUP_REBOOTED)))
 814		return 0;
 815
 816	rproc_report_crash(priv->rproc, RPROC_WATCHDOG);
 817
 818	pr_info("Partition%d reset!\n", priv->rproc_pt);
 819
 820	return 0;
 821}
 822
 823static int imx_rproc_attach_pd(struct imx_rproc *priv)
 824{
 825	struct device *dev = priv->dev;
 826	int ret, i;
 827	bool detached = true;
 828
 829	/*
 830	 * If there is only one power-domain entry, the platform driver framework
 831	 * will handle it, no need handle it in this driver.
 832	 */
 833	if (dev->pm_domain)
 834		return 0;
 835
 836	ret = dev_pm_domain_attach_list(dev, NULL, &priv->pd_list);
 837	if (ret < 0)
 838		return ret;
 839	/*
 840	 * If all the power domain devices are already turned on, the remote
 841	 * core is already powered up and running when the kernel booted (e.g.,
 842	 * started by U-Boot's bootaux command). In this case attach to it.
 843	 */
 844	for (i = 0; i < ret; i++) {
 845		if (!dev_pm_genpd_is_on(priv->pd_list->pd_devs[i])) {
 846			detached = false;
 847			break;
 848		}
 849	}
 850
 851	if (detached)
 852		priv->rproc->state = RPROC_DETACHED;
 853
 854	return 0;
 855}
 856
 857static int imx_rproc_arm_smc_detect_mode(struct rproc *rproc)
 858{
 859	struct imx_rproc *priv = rproc->priv;
 860	struct arm_smccc_res res;
 861
 862	arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STARTED, 0, 0, 0, 0, 0, 0, &res);
 863	if (res.a0)
 864		priv->rproc->state = RPROC_DETACHED;
 865
 866	return 0;
 867}
 868
 869static int imx_rproc_mmio_detect_mode(struct rproc *rproc)
 870{
 871	const struct regmap_config config = { .name = "imx-rproc" };
 872	struct imx_rproc *priv = rproc->priv;
 873	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 874	struct device *dev = priv->dev;
 875	struct regmap *regmap;
 876	u32 val;
 877	int ret;
 878
 879	priv->gpr = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,iomuxc-gpr");
 880	if (IS_ERR(priv->gpr))
 881		priv->gpr = NULL;
 882
 883	regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
 884	if (IS_ERR(regmap)) {
 885		dev_err(dev, "failed to find syscon\n");
 886		return PTR_ERR(regmap);
 887	}
 888
 889	priv->regmap = regmap;
 890	regmap_attach_dev(dev, regmap, &config);
 891
 892	if (priv->gpr) {
 893		ret = regmap_read(priv->gpr, dcfg->gpr_reg, &val);
 894		if (val & dcfg->gpr_wait) {
 895			/*
 896			 * After cold boot, the CM indicates its in wait
 897			 * state, but not fully powered off. Power it off
 898			 * fully so firmware can be loaded into it.
 899			 */
 900			imx_rproc_stop(priv->rproc);
 901			return 0;
 902		}
 903	}
 904
 905	ret = regmap_read(regmap, dcfg->src_reg, &val);
 906	if (ret) {
 907		dev_err(dev, "Failed to read src\n");
 908		return ret;
 909	}
 910
 911	if ((val & dcfg->src_mask) != dcfg->src_stop)
 912		priv->rproc->state = RPROC_DETACHED;
 913
 914	return 0;
 915}
 916
 917static int imx_rproc_scu_api_detect_mode(struct rproc *rproc)
 918{
 919	struct imx_rproc *priv = rproc->priv;
 920	struct device *dev = priv->dev;
 921	int ret;
 922	u8 pt;
 923
 924	ret = imx_scu_get_handle(&priv->ipc_handle);
 925	if (ret)
 926		return ret;
 927	ret = of_property_read_u32(dev->of_node, "fsl,resource-id", &priv->rsrc_id);
 928	if (ret) {
 929		dev_err(dev, "No fsl,resource-id property\n");
 930		return ret;
 931	}
 932
 933	if (priv->rsrc_id == IMX_SC_R_M4_1_PID0)
 934		priv->core_index = 1;
 935	else
 936		priv->core_index = 0;
 937
 938	ret = devm_add_action_or_reset(dev, imx_rproc_put_scu, priv);
 939	if (ret)
 940		return dev_err_probe(dev, ret, "Failed to add action for put scu\n");
 941
 942	/*
 943	 * If Mcore resource is not owned by Acore partition, It is kicked by ROM,
 944	 * and Linux could only do IPC with Mcore and nothing else.
 945	 */
 946	if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) {
 947		if (of_property_read_u32(dev->of_node, "fsl,entry-address", &priv->entry))
 948			return -EINVAL;
 949
 950		return imx_rproc_attach_pd(priv);
 951	}
 952
 953	priv->rproc->state = RPROC_DETACHED;
 954	priv->rproc->recovery_disabled = false;
 955	rproc_set_feature(priv->rproc, RPROC_FEAT_ATTACH_ON_RECOVERY);
 956
 957	/* Get partition id and enable irq in SCFW */
 958	ret = imx_sc_rm_get_resource_owner(priv->ipc_handle, priv->rsrc_id, &pt);
 959	if (ret) {
 960		dev_err(dev, "not able to get resource owner\n");
 961		return ret;
 962	}
 963
 964	priv->rproc_pt = pt;
 965	priv->rproc_nb.notifier_call = imx_rproc_partition_notify;
 966
 967	ret = imx_scu_irq_register_notifier(&priv->rproc_nb);
 968	if (ret) {
 969		dev_err(dev, "register scu notifier failed, %d\n", ret);
 970		return ret;
 971	}
 972
 973	ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt),
 974				       true);
 975	if (ret) {
 976		imx_scu_irq_unregister_notifier(&priv->rproc_nb);
 977		dev_err(dev, "Enable irq failed, %d\n", ret);
 978		return ret;
 979	}
 980
 981	return 0;
 982}
 983
 984static int imx_rproc_detect_mode(struct imx_rproc *priv)
 985{
 986	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 987
 988	/*
 989	 * To i.MX{7,8} ULP, Linux is under control of RTOS, no need
 990	 * dcfg->ops or dcfg->ops->detect_mode, it is state RPROC_DETACHED.
 991	 */
 992	if (!dcfg->ops || !dcfg->ops->detect_mode) {
 993		priv->rproc->state = RPROC_DETACHED;
 994		return 0;
 995	}
 996
 997	return dcfg->ops->detect_mode(priv->rproc);
 998}
 999
1000static int imx_rproc_sys_off_handler(struct sys_off_data *data)
1001{
1002	struct rproc *rproc = data->cb_data;
1003	int ret;
1004
1005	imx_rproc_free_mbox(rproc);
1006
1007	ret = imx_rproc_xtr_mbox_init(rproc, false);
1008	if (ret) {
1009		dev_err(&rproc->dev, "Failed to request non-blocking mbox\n");
1010		return NOTIFY_BAD;
1011	}
1012
1013	return NOTIFY_DONE;
1014}
1015
1016static void imx_rproc_destroy_workqueue(void *data)
1017{
1018	struct workqueue_struct *workqueue = data;
1019
1020	destroy_workqueue(workqueue);
1021}
1022
1023static int imx_rproc_probe(struct platform_device *pdev)
1024{
1025	struct device *dev = &pdev->dev;
1026	struct device_node *np = dev->of_node;
1027	struct imx_rproc *priv;
1028	struct rproc *rproc;
1029	const struct imx_rproc_dcfg *dcfg;
1030	int ret;
1031
1032	/* set some other name then imx */
1033	rproc = devm_rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
1034				 NULL, sizeof(*priv));
1035	if (!rproc)
1036		return -ENOMEM;
1037
1038	dcfg = of_device_get_match_data(dev);
1039	if (!dcfg)
1040		return -EINVAL;
1041
1042	priv = rproc->priv;
1043	priv->rproc = rproc;
1044	priv->dcfg = dcfg;
1045	priv->dev = dev;
1046
1047	dev_set_drvdata(dev, rproc);
1048	priv->workqueue = create_workqueue(dev_name(dev));
1049	if (!priv->workqueue) {
1050		dev_err(dev, "cannot create workqueue\n");
1051		return -ENOMEM;
1052	}
1053
1054	ret = devm_add_action_or_reset(dev, imx_rproc_destroy_workqueue, priv->workqueue);
1055	if (ret)
1056		return dev_err_probe(dev, ret, "Failed to add devm destroy workqueue action\n");
1057
1058	INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
1059
1060	ret = imx_rproc_xtr_mbox_init(rproc, true);
1061	if (ret)
1062		return ret;
1063
1064	ret = devm_add_action_or_reset(dev, imx_rproc_free_mbox, rproc);
1065	if (ret)
1066		return dev_err_probe(dev, ret,
1067				     "Failed to add devm free mbox action: %d\n", ret);
1068
1069	ret = imx_rproc_addr_init(priv, pdev);
1070	if (ret)
1071		return dev_err_probe(dev, ret, "failed on imx_rproc_addr_init\n");
1072
1073	ret = imx_rproc_detect_mode(priv);
1074	if (ret)
1075		return dev_err_probe(dev, ret, "failed on detect mode\n");
1076
1077	/*
1078	 * Handle clocks when remote core is under control of Linux AND the
1079	 * clocks are not managed by system firmware.
1080	 */
1081	if (dcfg->flags & IMX_RPROC_NEED_CLKS) {
1082		priv->clk = devm_clk_get_enabled(dev, NULL);
1083		if (IS_ERR(priv->clk))
1084			return dev_err_probe(dev, PTR_ERR(priv->clk), "Failed to enable clock\n");
1085	}
1086
1087	if (rproc->state != RPROC_DETACHED)
1088		rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot");
1089
1090	if (dcfg->flags & IMX_RPROC_NEED_SYSTEM_OFF) {
1091		/*
1092		 * setup mailbox to non-blocking mode in
1093		 * [SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_MODE_RESTART_PREPARE]
1094		 * phase before invoking [SYS_OFF_MODE_POWER_OFF, SYS_OFF_MODE_RESTART]
1095		 * atomic chain, see kernel/reboot.c.
1096		 */
1097		ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF_PREPARE,
1098						    SYS_OFF_PRIO_DEFAULT,
1099						    imx_rproc_sys_off_handler, rproc);
1100		if (ret)
1101			return dev_err_probe(dev, ret, "register power off handler failure\n");
1102
1103		ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART_PREPARE,
1104						    SYS_OFF_PRIO_DEFAULT,
1105						    imx_rproc_sys_off_handler, rproc);
1106		if (ret)
1107			return dev_err_probe(dev, ret, "register restart handler failure\n");
1108	}
1109
1110	pm_runtime_enable(dev);
1111	ret = pm_runtime_resume_and_get(dev);
1112	if (ret)
1113		return dev_err_probe(dev, ret, "pm_runtime get failed\n");
1114
1115	ret = devm_rproc_add(dev, rproc);
1116	if (ret) {
1117		dev_err(dev, "rproc_add failed\n");
1118		goto err_put_pm;
1119	}
1120
1121	return 0;
1122
1123err_put_pm:
1124	pm_runtime_disable(dev);
1125	pm_runtime_put_noidle(dev);
1126
1127	return ret;
1128}
1129
1130static void imx_rproc_remove(struct platform_device *pdev)
1131{
1132	struct rproc *rproc = platform_get_drvdata(pdev);
1133	struct imx_rproc *priv = rproc->priv;
1134
1135	pm_runtime_disable(priv->dev);
1136	pm_runtime_put_noidle(priv->dev);
1137}
1138
1139static const struct imx_rproc_plat_ops imx_rproc_ops_arm_smc = {
1140	.start		= imx_rproc_arm_smc_start,
1141	.stop		= imx_rproc_arm_smc_stop,
1142	.detect_mode	= imx_rproc_arm_smc_detect_mode,
1143};
1144
1145static const struct imx_rproc_plat_ops imx_rproc_ops_mmio = {
1146	.start		= imx_rproc_mmio_start,
1147	.stop		= imx_rproc_mmio_stop,
1148	.detect_mode	= imx_rproc_mmio_detect_mode,
1149};
1150
1151static const struct imx_rproc_plat_ops imx_rproc_ops_scu_api = {
1152	.start		= imx_rproc_scu_api_start,
1153	.stop		= imx_rproc_scu_api_stop,
1154	.detach		= imx_rproc_scu_api_detach,
1155	.detect_mode	= imx_rproc_scu_api_detect_mode,
1156};
1157
1158static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn_mmio = {
1159	.src_reg	= IMX7D_SRC_SCR,
1160	.src_mask	= IMX7D_M4_RST_MASK,
1161	.src_start	= IMX7D_M4_START,
1162	.src_stop	= IMX8M_M7_STOP,
1163	.gpr_reg	= IMX8M_GPR22,
1164	.gpr_wait	= IMX8M_GPR22_CM7_CPUWAIT,
1165	.att		= imx_rproc_att_imx8mn,
1166	.att_size	= ARRAY_SIZE(imx_rproc_att_imx8mn),
1167	.ops		= &imx_rproc_ops_mmio,
1168	.flags		= IMX_RPROC_NEED_CLKS,
1169};
1170
1171static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn = {
1172	.att		= imx_rproc_att_imx8mn,
1173	.att_size	= ARRAY_SIZE(imx_rproc_att_imx8mn),
1174	.ops		= &imx_rproc_ops_arm_smc,
1175	.flags		= IMX_RPROC_NEED_CLKS,
1176};
1177
1178static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
1179	.src_reg	= IMX7D_SRC_SCR,
1180	.src_mask	= IMX7D_M4_RST_MASK,
1181	.src_start	= IMX7D_M4_START,
1182	.src_stop	= IMX7D_M4_STOP,
1183	.att		= imx_rproc_att_imx8mq,
1184	.att_size	= ARRAY_SIZE(imx_rproc_att_imx8mq),
1185	.ops		= &imx_rproc_ops_mmio,
1186	.flags		= IMX_RPROC_NEED_CLKS,
1187};
1188
1189static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qm = {
1190	.att            = imx_rproc_att_imx8qm,
1191	.att_size       = ARRAY_SIZE(imx_rproc_att_imx8qm),
1192	.ops		= &imx_rproc_ops_scu_api,
1193};
1194
1195static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
1196	.att		= imx_rproc_att_imx8qxp,
1197	.att_size	= ARRAY_SIZE(imx_rproc_att_imx8qxp),
1198	.ops		= &imx_rproc_ops_scu_api,
1199};
1200
1201static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
1202	.att		= imx_rproc_att_imx8ulp,
1203	.att_size	= ARRAY_SIZE(imx_rproc_att_imx8ulp),
1204};
1205
1206static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = {
1207	.att		= imx_rproc_att_imx7ulp,
1208	.att_size	= ARRAY_SIZE(imx_rproc_att_imx7ulp),
1209	.flags		= IMX_RPROC_NEED_SYSTEM_OFF,
1210};
1211
1212static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = {
1213	.src_reg	= IMX7D_SRC_SCR,
1214	.src_mask	= IMX7D_M4_RST_MASK,
1215	.src_start	= IMX7D_M4_START,
1216	.src_stop	= IMX7D_M4_STOP,
1217	.att		= imx_rproc_att_imx7d,
1218	.att_size	= ARRAY_SIZE(imx_rproc_att_imx7d),
1219	.ops		= &imx_rproc_ops_mmio,
1220	.flags		= IMX_RPROC_NEED_CLKS,
1221};
1222
1223static const struct imx_rproc_dcfg imx_rproc_cfg_imx6sx = {
1224	.src_reg	= IMX6SX_SRC_SCR,
1225	.src_mask	= IMX6SX_M4_RST_MASK,
1226	.src_start	= IMX6SX_M4_START,
1227	.src_stop	= IMX6SX_M4_STOP,
1228	.att		= imx_rproc_att_imx6sx,
1229	.att_size	= ARRAY_SIZE(imx_rproc_att_imx6sx),
1230	.ops		= &imx_rproc_ops_mmio,
1231	.flags		= IMX_RPROC_NEED_CLKS,
1232};
1233
1234static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = {
1235	.att		= imx_rproc_att_imx93,
1236	.att_size	= ARRAY_SIZE(imx_rproc_att_imx93),
1237	.ops		= &imx_rproc_ops_arm_smc,
1238	.flags		= IMX_RPROC_NEED_CLKS,
1239};
1240
1241static const struct of_device_id imx_rproc_of_match[] = {
1242	{ .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp },
1243	{ .compatible = "fsl,imx7d-cm4", .data = &imx_rproc_cfg_imx7d },
1244	{ .compatible = "fsl,imx6sx-cm4", .data = &imx_rproc_cfg_imx6sx },
1245	{ .compatible = "fsl,imx8mq-cm4", .data = &imx_rproc_cfg_imx8mq },
1246	{ .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
1247	{ .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
1248	{ .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
1249	{ .compatible = "fsl,imx8mn-cm7-mmio", .data = &imx_rproc_cfg_imx8mn_mmio },
1250	{ .compatible = "fsl,imx8mp-cm7-mmio", .data = &imx_rproc_cfg_imx8mn_mmio },
1251	{ .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
1252	{ .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },
1253	{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
1254	{ .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 },
1255	{},
1256};
1257MODULE_DEVICE_TABLE(of, imx_rproc_of_match);
1258
1259static struct platform_driver imx_rproc_driver = {
1260	.probe = imx_rproc_probe,
1261	.remove = imx_rproc_remove,
1262	.driver = {
1263		.name = "imx-rproc",
1264		.of_match_table = imx_rproc_of_match,
1265	},
1266};
1267
1268module_platform_driver(imx_rproc_driver);
1269
1270MODULE_LICENSE("GPL v2");
1271MODULE_DESCRIPTION("i.MX remote processor control driver");
1272MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");
~/ Read-only file preview.