at master 34 kB view raw
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 if (priv->rsc_table) 613 return (struct resource_table *)priv->rsc_table; 614 615 return rproc_elf_find_loaded_rsc_table(rproc, fw); 616} 617 618static const struct rproc_ops imx_rproc_ops = { 619 .prepare = imx_rproc_prepare, 620 .attach = imx_rproc_attach, 621 .detach = imx_rproc_detach, 622 .start = imx_rproc_start, 623 .stop = imx_rproc_stop, 624 .kick = imx_rproc_kick, 625 .da_to_va = imx_rproc_da_to_va, 626 .load = rproc_elf_load_segments, 627 .parse_fw = imx_rproc_parse_fw, 628 .find_loaded_rsc_table = imx_rproc_elf_find_loaded_rsc_table, 629 .get_loaded_rsc_table = imx_rproc_get_loaded_rsc_table, 630 .sanity_check = rproc_elf_sanity_check, 631 .get_boot_addr = rproc_elf_get_boot_addr, 632}; 633 634static int imx_rproc_addr_init(struct imx_rproc *priv, 635 struct platform_device *pdev) 636{ 637 const struct imx_rproc_dcfg *dcfg = priv->dcfg; 638 struct device *dev = &pdev->dev; 639 struct device_node *np = dev->of_node; 640 int a, b = 0, err, nph; 641 642 /* remap required addresses */ 643 for (a = 0; a < dcfg->att_size; a++) { 644 const struct imx_rproc_att *att = &dcfg->att[a]; 645 646 if (!(att->flags & ATT_OWN)) 647 continue; 648 649 if (b >= IMX_RPROC_MEM_MAX) 650 break; 651 652 if (att->flags & ATT_IOMEM) 653 priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev, 654 att->sa, att->size); 655 else 656 priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev, 657 att->sa, att->size); 658 if (!priv->mem[b].cpu_addr) { 659 dev_err(dev, "failed to remap %#x bytes from %#x\n", att->size, att->sa); 660 return -ENOMEM; 661 } 662 priv->mem[b].sys_addr = att->sa; 663 priv->mem[b].size = att->size; 664 b++; 665 } 666 667 /* memory-region is optional property */ 668 nph = of_reserved_mem_region_count(np); 669 if (nph <= 0) 670 return 0; 671 672 /* remap optional addresses */ 673 for (a = 0; a < nph; a++) { 674 struct resource res; 675 676 err = of_reserved_mem_region_to_resource(np, a, &res); 677 if (err) { 678 dev_err(dev, "unable to resolve memory region\n"); 679 return err; 680 } 681 682 /* Not map vdevbuffer, vdevring region */ 683 if (strstarts(res.name, "vdev")) 684 continue; 685 686 if (b >= IMX_RPROC_MEM_MAX) 687 break; 688 689 /* Not use resource version, because we might share region */ 690 priv->mem[b].cpu_addr = devm_ioremap_resource_wc(&pdev->dev, &res); 691 if (!priv->mem[b].cpu_addr) { 692 dev_err(dev, "failed to remap %pr\n", &res); 693 return -ENOMEM; 694 } 695 priv->mem[b].sys_addr = res.start; 696 priv->mem[b].size = resource_size(&res); 697 if (!strcmp(res.name, "rsc-table")) 698 priv->rsc_table = priv->mem[b].cpu_addr; 699 b++; 700 } 701 702 return 0; 703} 704 705static int imx_rproc_notified_idr_cb(int id, void *ptr, void *data) 706{ 707 struct rproc *rproc = data; 708 709 rproc_vq_interrupt(rproc, id); 710 711 return 0; 712} 713 714static void imx_rproc_vq_work(struct work_struct *work) 715{ 716 struct imx_rproc *priv = container_of(work, struct imx_rproc, 717 rproc_work); 718 struct rproc *rproc = priv->rproc; 719 720 idr_for_each(&rproc->notifyids, imx_rproc_notified_idr_cb, rproc); 721} 722 723static void imx_rproc_rx_callback(struct mbox_client *cl, void *msg) 724{ 725 struct rproc *rproc = dev_get_drvdata(cl->dev); 726 struct imx_rproc *priv = rproc->priv; 727 728 queue_work(priv->workqueue, &priv->rproc_work); 729} 730 731static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block) 732{ 733 struct imx_rproc *priv = rproc->priv; 734 struct device *dev = priv->dev; 735 struct mbox_client *cl; 736 737 /* 738 * stop() and detach() will free the mbox channels, so need 739 * to request mbox channels in start() and attach(). 740 * 741 * Because start() and attach() not able to handle mbox defer 742 * probe, imx_rproc_xtr_mbox_init is also called in probe(). 743 * The check is to avoid request mbox again when start() or 744 * attach() after probe() returns success. 745 */ 746 if (priv->tx_ch && priv->rx_ch) 747 return 0; 748 749 if (!of_property_present(dev->of_node, "mbox-names")) 750 return 0; 751 752 cl = &priv->cl; 753 cl->dev = dev; 754 cl->tx_block = tx_block; 755 cl->tx_tout = 100; 756 cl->knows_txdone = false; 757 cl->rx_callback = imx_rproc_rx_callback; 758 759 priv->tx_ch = mbox_request_channel_byname(cl, "tx"); 760 if (IS_ERR(priv->tx_ch)) 761 return dev_err_probe(cl->dev, PTR_ERR(priv->tx_ch), 762 "failed to request tx mailbox channel\n"); 763 764 priv->rx_ch = mbox_request_channel_byname(cl, "rx"); 765 if (IS_ERR(priv->rx_ch)) { 766 mbox_free_channel(priv->tx_ch); 767 return dev_err_probe(cl->dev, PTR_ERR(priv->rx_ch), 768 "failed to request rx mailbox channel\n"); 769 } 770 771 return 0; 772} 773 774static void imx_rproc_free_mbox(void *data) 775{ 776 struct rproc *rproc = data; 777 struct imx_rproc *priv = rproc->priv; 778 779 if (priv->tx_ch) { 780 mbox_free_channel(priv->tx_ch); 781 priv->tx_ch = NULL; 782 } 783 784 if (priv->rx_ch) { 785 mbox_free_channel(priv->rx_ch); 786 priv->rx_ch = NULL; 787 } 788} 789 790static void imx_rproc_put_scu(void *data) 791{ 792 struct imx_rproc *priv = data; 793 794 if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) { 795 dev_pm_domain_detach_list(priv->pd_list); 796 return; 797 } 798 799 imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt), false); 800 imx_scu_irq_unregister_notifier(&priv->rproc_nb); 801} 802 803static int imx_rproc_partition_notify(struct notifier_block *nb, 804 unsigned long event, void *group) 805{ 806 struct imx_rproc *priv = container_of(nb, struct imx_rproc, rproc_nb); 807 808 /* Ignore other irqs */ 809 if (!((event & BIT(priv->rproc_pt)) && (*(u8 *)group == IMX_SC_IRQ_GROUP_REBOOTED))) 810 return 0; 811 812 rproc_report_crash(priv->rproc, RPROC_WATCHDOG); 813 814 pr_info("Partition%d reset!\n", priv->rproc_pt); 815 816 return 0; 817} 818 819static int imx_rproc_attach_pd(struct imx_rproc *priv) 820{ 821 struct device *dev = priv->dev; 822 int ret, i; 823 bool detached = true; 824 825 /* 826 * If there is only one power-domain entry, the platform driver framework 827 * will handle it, no need handle it in this driver. 828 */ 829 if (dev->pm_domain) 830 return 0; 831 832 ret = dev_pm_domain_attach_list(dev, NULL, &priv->pd_list); 833 if (ret < 0) 834 return ret; 835 /* 836 * If all the power domain devices are already turned on, the remote 837 * core is already powered up and running when the kernel booted (e.g., 838 * started by U-Boot's bootaux command). In this case attach to it. 839 */ 840 for (i = 0; i < ret; i++) { 841 if (!dev_pm_genpd_is_on(priv->pd_list->pd_devs[i])) { 842 detached = false; 843 break; 844 } 845 } 846 847 if (detached) 848 priv->rproc->state = RPROC_DETACHED; 849 850 return 0; 851} 852 853static int imx_rproc_arm_smc_detect_mode(struct rproc *rproc) 854{ 855 struct imx_rproc *priv = rproc->priv; 856 struct arm_smccc_res res; 857 858 arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STARTED, 0, 0, 0, 0, 0, 0, &res); 859 if (res.a0) 860 priv->rproc->state = RPROC_DETACHED; 861 862 return 0; 863} 864 865static int imx_rproc_mmio_detect_mode(struct rproc *rproc) 866{ 867 const struct regmap_config config = { .name = "imx-rproc" }; 868 struct imx_rproc *priv = rproc->priv; 869 const struct imx_rproc_dcfg *dcfg = priv->dcfg; 870 struct device *dev = priv->dev; 871 struct regmap *regmap; 872 u32 val; 873 int ret; 874 875 priv->gpr = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,iomuxc-gpr"); 876 if (IS_ERR(priv->gpr)) 877 priv->gpr = NULL; 878 879 regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); 880 if (IS_ERR(regmap)) { 881 dev_err(dev, "failed to find syscon\n"); 882 return PTR_ERR(regmap); 883 } 884 885 priv->regmap = regmap; 886 regmap_attach_dev(dev, regmap, &config); 887 888 if (priv->gpr) { 889 ret = regmap_read(priv->gpr, dcfg->gpr_reg, &val); 890 if (val & dcfg->gpr_wait) { 891 /* 892 * After cold boot, the CM indicates its in wait 893 * state, but not fully powered off. Power it off 894 * fully so firmware can be loaded into it. 895 */ 896 imx_rproc_stop(priv->rproc); 897 return 0; 898 } 899 } 900 901 ret = regmap_read(regmap, dcfg->src_reg, &val); 902 if (ret) { 903 dev_err(dev, "Failed to read src\n"); 904 return ret; 905 } 906 907 if ((val & dcfg->src_mask) != dcfg->src_stop) 908 priv->rproc->state = RPROC_DETACHED; 909 910 return 0; 911} 912 913static int imx_rproc_scu_api_detect_mode(struct rproc *rproc) 914{ 915 struct imx_rproc *priv = rproc->priv; 916 struct device *dev = priv->dev; 917 int ret; 918 u8 pt; 919 920 ret = imx_scu_get_handle(&priv->ipc_handle); 921 if (ret) 922 return ret; 923 ret = of_property_read_u32(dev->of_node, "fsl,resource-id", &priv->rsrc_id); 924 if (ret) { 925 dev_err(dev, "No fsl,resource-id property\n"); 926 return ret; 927 } 928 929 if (priv->rsrc_id == IMX_SC_R_M4_1_PID0) 930 priv->core_index = 1; 931 else 932 priv->core_index = 0; 933 934 ret = devm_add_action_or_reset(dev, imx_rproc_put_scu, priv); 935 if (ret) 936 return dev_err_probe(dev, ret, "Failed to add action for put scu\n"); 937 938 /* 939 * If Mcore resource is not owned by Acore partition, It is kicked by ROM, 940 * and Linux could only do IPC with Mcore and nothing else. 941 */ 942 if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) { 943 if (of_property_read_u32(dev->of_node, "fsl,entry-address", &priv->entry)) 944 return -EINVAL; 945 946 return imx_rproc_attach_pd(priv); 947 } 948 949 priv->rproc->state = RPROC_DETACHED; 950 priv->rproc->recovery_disabled = false; 951 rproc_set_feature(priv->rproc, RPROC_FEAT_ATTACH_ON_RECOVERY); 952 953 /* Get partition id and enable irq in SCFW */ 954 ret = imx_sc_rm_get_resource_owner(priv->ipc_handle, priv->rsrc_id, &pt); 955 if (ret) { 956 dev_err(dev, "not able to get resource owner\n"); 957 return ret; 958 } 959 960 priv->rproc_pt = pt; 961 priv->rproc_nb.notifier_call = imx_rproc_partition_notify; 962 963 ret = imx_scu_irq_register_notifier(&priv->rproc_nb); 964 if (ret) { 965 dev_err(dev, "register scu notifier failed, %d\n", ret); 966 return ret; 967 } 968 969 ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt), 970 true); 971 if (ret) { 972 imx_scu_irq_unregister_notifier(&priv->rproc_nb); 973 dev_err(dev, "Enable irq failed, %d\n", ret); 974 return ret; 975 } 976 977 return 0; 978} 979 980static int imx_rproc_detect_mode(struct imx_rproc *priv) 981{ 982 const struct imx_rproc_dcfg *dcfg = priv->dcfg; 983 984 /* 985 * To i.MX{7,8} ULP, Linux is under control of RTOS, no need 986 * dcfg->ops or dcfg->ops->detect_mode, it is state RPROC_DETACHED. 987 */ 988 if (!dcfg->ops || !dcfg->ops->detect_mode) { 989 priv->rproc->state = RPROC_DETACHED; 990 return 0; 991 } 992 993 return dcfg->ops->detect_mode(priv->rproc); 994} 995 996static int imx_rproc_sys_off_handler(struct sys_off_data *data) 997{ 998 struct rproc *rproc = data->cb_data; 999 int ret; 1000 1001 imx_rproc_free_mbox(rproc); 1002 1003 ret = imx_rproc_xtr_mbox_init(rproc, false); 1004 if (ret) { 1005 dev_err(&rproc->dev, "Failed to request non-blocking mbox\n"); 1006 return NOTIFY_BAD; 1007 } 1008 1009 return NOTIFY_DONE; 1010} 1011 1012static void imx_rproc_destroy_workqueue(void *data) 1013{ 1014 struct workqueue_struct *workqueue = data; 1015 1016 destroy_workqueue(workqueue); 1017} 1018 1019static int imx_rproc_probe(struct platform_device *pdev) 1020{ 1021 struct device *dev = &pdev->dev; 1022 struct device_node *np = dev->of_node; 1023 struct imx_rproc *priv; 1024 struct rproc *rproc; 1025 const struct imx_rproc_dcfg *dcfg; 1026 int ret; 1027 1028 /* set some other name then imx */ 1029 rproc = devm_rproc_alloc(dev, "imx-rproc", &imx_rproc_ops, 1030 NULL, sizeof(*priv)); 1031 if (!rproc) 1032 return -ENOMEM; 1033 1034 dcfg = of_device_get_match_data(dev); 1035 if (!dcfg) 1036 return -EINVAL; 1037 1038 priv = rproc->priv; 1039 priv->rproc = rproc; 1040 priv->dcfg = dcfg; 1041 priv->dev = dev; 1042 1043 dev_set_drvdata(dev, rproc); 1044 priv->workqueue = create_workqueue(dev_name(dev)); 1045 if (!priv->workqueue) { 1046 dev_err(dev, "cannot create workqueue\n"); 1047 return -ENOMEM; 1048 } 1049 1050 ret = devm_add_action_or_reset(dev, imx_rproc_destroy_workqueue, priv->workqueue); 1051 if (ret) 1052 return dev_err_probe(dev, ret, "Failed to add devm destroy workqueue action\n"); 1053 1054 INIT_WORK(&priv->rproc_work, imx_rproc_vq_work); 1055 1056 ret = imx_rproc_xtr_mbox_init(rproc, true); 1057 if (ret) 1058 return ret; 1059 1060 ret = devm_add_action_or_reset(dev, imx_rproc_free_mbox, rproc); 1061 if (ret) 1062 return dev_err_probe(dev, ret, 1063 "Failed to add devm free mbox action: %d\n", ret); 1064 1065 ret = imx_rproc_addr_init(priv, pdev); 1066 if (ret) 1067 return dev_err_probe(dev, ret, "failed on imx_rproc_addr_init\n"); 1068 1069 ret = imx_rproc_detect_mode(priv); 1070 if (ret) 1071 return dev_err_probe(dev, ret, "failed on detect mode\n"); 1072 1073 /* 1074 * Handle clocks when remote core is under control of Linux AND the 1075 * clocks are not managed by system firmware. 1076 */ 1077 if (dcfg->flags & IMX_RPROC_NEED_CLKS) { 1078 priv->clk = devm_clk_get_enabled(dev, NULL); 1079 if (IS_ERR(priv->clk)) 1080 return dev_err_probe(dev, PTR_ERR(priv->clk), "Failed to enable clock\n"); 1081 } 1082 1083 if (rproc->state != RPROC_DETACHED) 1084 rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot"); 1085 1086 if (dcfg->flags & IMX_RPROC_NEED_SYSTEM_OFF) { 1087 /* 1088 * setup mailbox to non-blocking mode in 1089 * [SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_MODE_RESTART_PREPARE] 1090 * phase before invoking [SYS_OFF_MODE_POWER_OFF, SYS_OFF_MODE_RESTART] 1091 * atomic chain, see kernel/reboot.c. 1092 */ 1093 ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF_PREPARE, 1094 SYS_OFF_PRIO_DEFAULT, 1095 imx_rproc_sys_off_handler, rproc); 1096 if (ret) 1097 return dev_err_probe(dev, ret, "register power off handler failure\n"); 1098 1099 ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART_PREPARE, 1100 SYS_OFF_PRIO_DEFAULT, 1101 imx_rproc_sys_off_handler, rproc); 1102 if (ret) 1103 return dev_err_probe(dev, ret, "register restart handler failure\n"); 1104 } 1105 1106 pm_runtime_enable(dev); 1107 ret = pm_runtime_resume_and_get(dev); 1108 if (ret) 1109 return dev_err_probe(dev, ret, "pm_runtime get failed\n"); 1110 1111 ret = devm_rproc_add(dev, rproc); 1112 if (ret) { 1113 dev_err(dev, "rproc_add failed\n"); 1114 goto err_put_pm; 1115 } 1116 1117 return 0; 1118 1119err_put_pm: 1120 pm_runtime_disable(dev); 1121 pm_runtime_put_noidle(dev); 1122 1123 return ret; 1124} 1125 1126static void imx_rproc_remove(struct platform_device *pdev) 1127{ 1128 struct rproc *rproc = platform_get_drvdata(pdev); 1129 struct imx_rproc *priv = rproc->priv; 1130 1131 pm_runtime_disable(priv->dev); 1132 pm_runtime_put_noidle(priv->dev); 1133} 1134 1135static const struct imx_rproc_plat_ops imx_rproc_ops_arm_smc = { 1136 .start = imx_rproc_arm_smc_start, 1137 .stop = imx_rproc_arm_smc_stop, 1138 .detect_mode = imx_rproc_arm_smc_detect_mode, 1139}; 1140 1141static const struct imx_rproc_plat_ops imx_rproc_ops_mmio = { 1142 .start = imx_rproc_mmio_start, 1143 .stop = imx_rproc_mmio_stop, 1144 .detect_mode = imx_rproc_mmio_detect_mode, 1145}; 1146 1147static const struct imx_rproc_plat_ops imx_rproc_ops_scu_api = { 1148 .start = imx_rproc_scu_api_start, 1149 .stop = imx_rproc_scu_api_stop, 1150 .detach = imx_rproc_scu_api_detach, 1151 .detect_mode = imx_rproc_scu_api_detect_mode, 1152}; 1153 1154static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn_mmio = { 1155 .src_reg = IMX7D_SRC_SCR, 1156 .src_mask = IMX7D_M4_RST_MASK, 1157 .src_start = IMX7D_M4_START, 1158 .src_stop = IMX8M_M7_STOP, 1159 .gpr_reg = IMX8M_GPR22, 1160 .gpr_wait = IMX8M_GPR22_CM7_CPUWAIT, 1161 .att = imx_rproc_att_imx8mn, 1162 .att_size = ARRAY_SIZE(imx_rproc_att_imx8mn), 1163 .ops = &imx_rproc_ops_mmio, 1164 .flags = IMX_RPROC_NEED_CLKS, 1165}; 1166 1167static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn = { 1168 .att = imx_rproc_att_imx8mn, 1169 .att_size = ARRAY_SIZE(imx_rproc_att_imx8mn), 1170 .ops = &imx_rproc_ops_arm_smc, 1171 .flags = IMX_RPROC_NEED_CLKS, 1172}; 1173 1174static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = { 1175 .src_reg = IMX7D_SRC_SCR, 1176 .src_mask = IMX7D_M4_RST_MASK, 1177 .src_start = IMX7D_M4_START, 1178 .src_stop = IMX7D_M4_STOP, 1179 .att = imx_rproc_att_imx8mq, 1180 .att_size = ARRAY_SIZE(imx_rproc_att_imx8mq), 1181 .ops = &imx_rproc_ops_mmio, 1182 .flags = IMX_RPROC_NEED_CLKS, 1183}; 1184 1185static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qm = { 1186 .att = imx_rproc_att_imx8qm, 1187 .att_size = ARRAY_SIZE(imx_rproc_att_imx8qm), 1188 .ops = &imx_rproc_ops_scu_api, 1189}; 1190 1191static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = { 1192 .att = imx_rproc_att_imx8qxp, 1193 .att_size = ARRAY_SIZE(imx_rproc_att_imx8qxp), 1194 .ops = &imx_rproc_ops_scu_api, 1195}; 1196 1197static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = { 1198 .att = imx_rproc_att_imx8ulp, 1199 .att_size = ARRAY_SIZE(imx_rproc_att_imx8ulp), 1200}; 1201 1202static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = { 1203 .att = imx_rproc_att_imx7ulp, 1204 .att_size = ARRAY_SIZE(imx_rproc_att_imx7ulp), 1205 .flags = IMX_RPROC_NEED_SYSTEM_OFF, 1206}; 1207 1208static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = { 1209 .src_reg = IMX7D_SRC_SCR, 1210 .src_mask = IMX7D_M4_RST_MASK, 1211 .src_start = IMX7D_M4_START, 1212 .src_stop = IMX7D_M4_STOP, 1213 .att = imx_rproc_att_imx7d, 1214 .att_size = ARRAY_SIZE(imx_rproc_att_imx7d), 1215 .ops = &imx_rproc_ops_mmio, 1216 .flags = IMX_RPROC_NEED_CLKS, 1217}; 1218 1219static const struct imx_rproc_dcfg imx_rproc_cfg_imx6sx = { 1220 .src_reg = IMX6SX_SRC_SCR, 1221 .src_mask = IMX6SX_M4_RST_MASK, 1222 .src_start = IMX6SX_M4_START, 1223 .src_stop = IMX6SX_M4_STOP, 1224 .att = imx_rproc_att_imx6sx, 1225 .att_size = ARRAY_SIZE(imx_rproc_att_imx6sx), 1226 .ops = &imx_rproc_ops_mmio, 1227 .flags = IMX_RPROC_NEED_CLKS, 1228}; 1229 1230static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = { 1231 .att = imx_rproc_att_imx93, 1232 .att_size = ARRAY_SIZE(imx_rproc_att_imx93), 1233 .ops = &imx_rproc_ops_arm_smc, 1234 .flags = IMX_RPROC_NEED_CLKS, 1235}; 1236 1237static const struct of_device_id imx_rproc_of_match[] = { 1238 { .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp }, 1239 { .compatible = "fsl,imx7d-cm4", .data = &imx_rproc_cfg_imx7d }, 1240 { .compatible = "fsl,imx6sx-cm4", .data = &imx_rproc_cfg_imx6sx }, 1241 { .compatible = "fsl,imx8mq-cm4", .data = &imx_rproc_cfg_imx8mq }, 1242 { .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq }, 1243 { .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn }, 1244 { .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn }, 1245 { .compatible = "fsl,imx8mn-cm7-mmio", .data = &imx_rproc_cfg_imx8mn_mmio }, 1246 { .compatible = "fsl,imx8mp-cm7-mmio", .data = &imx_rproc_cfg_imx8mn_mmio }, 1247 { .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp }, 1248 { .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm }, 1249 { .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp }, 1250 { .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 }, 1251 {}, 1252}; 1253MODULE_DEVICE_TABLE(of, imx_rproc_of_match); 1254 1255static struct platform_driver imx_rproc_driver = { 1256 .probe = imx_rproc_probe, 1257 .remove = imx_rproc_remove, 1258 .driver = { 1259 .name = "imx-rproc", 1260 .of_match_table = imx_rproc_of_match, 1261 }, 1262}; 1263 1264module_platform_driver(imx_rproc_driver); 1265 1266MODULE_LICENSE("GPL v2"); 1267MODULE_DESCRIPTION("i.MX remote processor control driver"); 1268MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");