FILE
imx_rproc.c
File preview with syntax highlighting.
linux-6.19.14/drivers/remoteproc/imx_rproc.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.