0001
0002
0003
0004 #include <dt-bindings/firmware/imx/rsrc.h>
0005 #include <linux/arm-smccc.h>
0006 #include <linux/clk.h>
0007 #include <linux/err.h>
0008 #include <linux/firmware.h>
0009 #include <linux/firmware/imx/sci.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/kernel.h>
0012 #include <linux/mailbox_client.h>
0013 #include <linux/mfd/syscon.h>
0014 #include <linux/module.h>
0015 #include <linux/of_address.h>
0016 #include <linux/of_device.h>
0017 #include <linux/of_reserved_mem.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/pm_domain.h>
0020 #include <linux/pm_runtime.h>
0021 #include <linux/regmap.h>
0022 #include <linux/remoteproc.h>
0023 #include <linux/slab.h>
0024
0025 #include "imx_rproc.h"
0026 #include "remoteproc_elf_helpers.h"
0027 #include "remoteproc_internal.h"
0028
0029 #define DSP_RPROC_CLK_MAX 5
0030
0031 #define REMOTE_IS_READY BIT(0)
0032 #define REMOTE_READY_WAIT_MAX_RETRIES 500
0033
0034
0035
0036 #define ATT_OWN BIT(31)
0037
0038 #define ATT_IRAM BIT(30)
0039
0040
0041
0042 #define IMX8M_DAP_DEBUG 0x28800000
0043 #define IMX8M_DAP_DEBUG_SIZE (64 * 1024)
0044 #define IMX8M_DAP_PWRCTL (0x4000 + 0x3020)
0045 #define IMX8M_PWRCTL_CORERESET BIT(16)
0046
0047
0048 #define IMX8M_AudioDSP_REG0 0x100
0049 #define IMX8M_AudioDSP_REG1 0x104
0050 #define IMX8M_AudioDSP_REG2 0x108
0051 #define IMX8M_AudioDSP_REG3 0x10c
0052
0053 #define IMX8M_AudioDSP_REG2_RUNSTALL BIT(5)
0054 #define IMX8M_AudioDSP_REG2_PWAITMODE BIT(1)
0055
0056
0057 #define IMX8ULP_SIM_LPAV_REG_SYSCTRL0 0x8
0058 #define IMX8ULP_SYSCTRL0_DSP_DBG_RST BIT(25)
0059 #define IMX8ULP_SYSCTRL0_DSP_PLAT_CLK_EN BIT(19)
0060 #define IMX8ULP_SYSCTRL0_DSP_PBCLK_EN BIT(18)
0061 #define IMX8ULP_SYSCTRL0_DSP_CLK_EN BIT(17)
0062 #define IMX8ULP_SYSCTRL0_DSP_RST BIT(16)
0063 #define IMX8ULP_SYSCTRL0_DSP_OCD_HALT BIT(14)
0064 #define IMX8ULP_SYSCTRL0_DSP_STALL BIT(13)
0065
0066 #define IMX8ULP_SIP_HIFI_XRDC 0xc200000e
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 enum imx_dsp_rp_mbox_messages {
0082 RP_MBOX_SUSPEND_SYSTEM = 0xFF11,
0083 RP_MBOX_SUSPEND_ACK = 0xFF12,
0084 RP_MBOX_RESUME_SYSTEM = 0xFF13,
0085 RP_MBOX_RESUME_ACK = 0xFF14,
0086 };
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 struct imx_dsp_rproc {
0108 struct regmap *regmap;
0109 struct rproc *rproc;
0110 const struct imx_dsp_rproc_dcfg *dsp_dcfg;
0111 struct clk_bulk_data clks[DSP_RPROC_CLK_MAX];
0112 struct mbox_client cl;
0113 struct mbox_client cl_rxdb;
0114 struct mbox_chan *tx_ch;
0115 struct mbox_chan *rx_ch;
0116 struct mbox_chan *rxdb_ch;
0117 struct device **pd_dev;
0118 struct device_link **pd_dev_link;
0119 struct imx_sc_ipc *ipc_handle;
0120 struct work_struct rproc_work;
0121 struct completion pm_comp;
0122 int num_domains;
0123 u32 flags;
0124 };
0125
0126
0127
0128
0129
0130
0131 struct imx_dsp_rproc_dcfg {
0132 const struct imx_rproc_dcfg *dcfg;
0133 int (*reset)(struct imx_dsp_rproc *priv);
0134 };
0135
0136 static const struct imx_rproc_att imx_dsp_rproc_att_imx8qm[] = {
0137
0138 { 0x596e8000, 0x556e8000, 0x00008000, ATT_OWN },
0139 { 0x596f0000, 0x556f0000, 0x00008000, ATT_OWN },
0140 { 0x596f8000, 0x556f8000, 0x00000800, ATT_OWN | ATT_IRAM},
0141 { 0x55700000, 0x55700000, 0x00070000, ATT_OWN },
0142
0143 { 0x80000000, 0x80000000, 0x60000000, 0},
0144 };
0145
0146 static const struct imx_rproc_att imx_dsp_rproc_att_imx8qxp[] = {
0147
0148 { 0x596e8000, 0x596e8000, 0x00008000, ATT_OWN },
0149 { 0x596f0000, 0x596f0000, 0x00008000, ATT_OWN },
0150 { 0x596f8000, 0x596f8000, 0x00000800, ATT_OWN | ATT_IRAM},
0151 { 0x59700000, 0x59700000, 0x00070000, ATT_OWN },
0152
0153 { 0x80000000, 0x80000000, 0x60000000, 0},
0154 };
0155
0156 static const struct imx_rproc_att imx_dsp_rproc_att_imx8mp[] = {
0157
0158 { 0x3b6e8000, 0x3b6e8000, 0x00008000, ATT_OWN },
0159 { 0x3b6f0000, 0x3b6f0000, 0x00008000, ATT_OWN },
0160 { 0x3b6f8000, 0x3b6f8000, 0x00000800, ATT_OWN | ATT_IRAM},
0161 { 0x3b700000, 0x3b700000, 0x00040000, ATT_OWN },
0162
0163 { 0x40000000, 0x40000000, 0x80000000, 0},
0164 };
0165
0166 static const struct imx_rproc_att imx_dsp_rproc_att_imx8ulp[] = {
0167
0168 { 0x21170000, 0x21170000, 0x00010000, ATT_OWN | ATT_IRAM},
0169 { 0x21180000, 0x21180000, 0x00010000, ATT_OWN },
0170
0171 { 0x0c000000, 0x80000000, 0x10000000, 0},
0172 { 0x30000000, 0x90000000, 0x10000000, 0},
0173 };
0174
0175
0176 static int imx8mp_dsp_reset(struct imx_dsp_rproc *priv)
0177 {
0178 void __iomem *dap = ioremap_wc(IMX8M_DAP_DEBUG, IMX8M_DAP_DEBUG_SIZE);
0179 int pwrctl;
0180
0181
0182 pwrctl = readl(dap + IMX8M_DAP_PWRCTL);
0183 pwrctl |= IMX8M_PWRCTL_CORERESET;
0184 writel(pwrctl, dap + IMX8M_DAP_PWRCTL);
0185
0186
0187 usleep_range(1, 2);
0188
0189 regmap_update_bits(priv->regmap, IMX8M_AudioDSP_REG2,
0190 IMX8M_AudioDSP_REG2_RUNSTALL,
0191 IMX8M_AudioDSP_REG2_RUNSTALL);
0192
0193
0194 pwrctl = readl(dap + IMX8M_DAP_PWRCTL);
0195 pwrctl &= ~IMX8M_PWRCTL_CORERESET;
0196 writel(pwrctl, dap + IMX8M_DAP_PWRCTL);
0197
0198 iounmap(dap);
0199 return 0;
0200 }
0201
0202
0203 static int imx8ulp_dsp_reset(struct imx_dsp_rproc *priv)
0204 {
0205 struct arm_smccc_res res;
0206
0207
0208 regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
0209 IMX8ULP_SYSCTRL0_DSP_RST, IMX8ULP_SYSCTRL0_DSP_RST);
0210 regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
0211 IMX8ULP_SYSCTRL0_DSP_STALL,
0212 IMX8ULP_SYSCTRL0_DSP_STALL);
0213
0214
0215 arm_smccc_smc(IMX8ULP_SIP_HIFI_XRDC, 0, 0, 0, 0, 0, 0, 0, &res);
0216
0217
0218 regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
0219 IMX8ULP_SYSCTRL0_DSP_RST, 0);
0220 regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
0221 IMX8ULP_SYSCTRL0_DSP_DBG_RST, 0);
0222
0223 return 0;
0224 }
0225
0226
0227 static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8mp = {
0228 .src_reg = IMX8M_AudioDSP_REG2,
0229 .src_mask = IMX8M_AudioDSP_REG2_RUNSTALL,
0230 .src_start = 0,
0231 .src_stop = IMX8M_AudioDSP_REG2_RUNSTALL,
0232 .att = imx_dsp_rproc_att_imx8mp,
0233 .att_size = ARRAY_SIZE(imx_dsp_rproc_att_imx8mp),
0234 .method = IMX_RPROC_MMIO,
0235 };
0236
0237 static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8mp = {
0238 .dcfg = &dsp_rproc_cfg_imx8mp,
0239 .reset = imx8mp_dsp_reset,
0240 };
0241
0242
0243 static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8ulp = {
0244 .src_reg = IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
0245 .src_mask = IMX8ULP_SYSCTRL0_DSP_STALL,
0246 .src_start = 0,
0247 .src_stop = IMX8ULP_SYSCTRL0_DSP_STALL,
0248 .att = imx_dsp_rproc_att_imx8ulp,
0249 .att_size = ARRAY_SIZE(imx_dsp_rproc_att_imx8ulp),
0250 .method = IMX_RPROC_MMIO,
0251 };
0252
0253 static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8ulp = {
0254 .dcfg = &dsp_rproc_cfg_imx8ulp,
0255 .reset = imx8ulp_dsp_reset,
0256 };
0257
0258
0259 static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8qxp = {
0260 .att = imx_dsp_rproc_att_imx8qxp,
0261 .att_size = ARRAY_SIZE(imx_dsp_rproc_att_imx8qxp),
0262 .method = IMX_RPROC_SCU_API,
0263 };
0264
0265 static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qxp = {
0266 .dcfg = &dsp_rproc_cfg_imx8qxp,
0267 };
0268
0269
0270 static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8qm = {
0271 .att = imx_dsp_rproc_att_imx8qm,
0272 .att_size = ARRAY_SIZE(imx_dsp_rproc_att_imx8qm),
0273 .method = IMX_RPROC_SCU_API,
0274 };
0275
0276 static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qm = {
0277 .dcfg = &dsp_rproc_cfg_imx8qm,
0278 };
0279
0280 static int imx_dsp_rproc_ready(struct rproc *rproc)
0281 {
0282 struct imx_dsp_rproc *priv = rproc->priv;
0283 int i;
0284
0285 if (!priv->rxdb_ch)
0286 return 0;
0287
0288 for (i = 0; i < REMOTE_READY_WAIT_MAX_RETRIES; i++) {
0289 if (priv->flags & REMOTE_IS_READY)
0290 return 0;
0291 usleep_range(100, 200);
0292 }
0293
0294 return -ETIMEDOUT;
0295 }
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 static int imx_dsp_rproc_start(struct rproc *rproc)
0306 {
0307 struct imx_dsp_rproc *priv = rproc->priv;
0308 const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
0309 const struct imx_rproc_dcfg *dcfg = dsp_dcfg->dcfg;
0310 struct device *dev = rproc->dev.parent;
0311 int ret;
0312
0313 switch (dcfg->method) {
0314 case IMX_RPROC_MMIO:
0315 ret = regmap_update_bits(priv->regmap,
0316 dcfg->src_reg,
0317 dcfg->src_mask,
0318 dcfg->src_start);
0319 break;
0320 case IMX_RPROC_SCU_API:
0321 ret = imx_sc_pm_cpu_start(priv->ipc_handle,
0322 IMX_SC_R_DSP,
0323 true,
0324 rproc->bootaddr);
0325 break;
0326 default:
0327 return -EOPNOTSUPP;
0328 }
0329
0330 if (ret)
0331 dev_err(dev, "Failed to enable remote core!\n");
0332 else
0333 ret = imx_dsp_rproc_ready(rproc);
0334
0335 return ret;
0336 }
0337
0338
0339
0340
0341
0342 static int imx_dsp_rproc_stop(struct rproc *rproc)
0343 {
0344 struct imx_dsp_rproc *priv = rproc->priv;
0345 const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
0346 const struct imx_rproc_dcfg *dcfg = dsp_dcfg->dcfg;
0347 struct device *dev = rproc->dev.parent;
0348 int ret = 0;
0349
0350
0351 flush_work(&priv->rproc_work);
0352
0353 if (rproc->state == RPROC_CRASHED) {
0354 priv->flags &= ~REMOTE_IS_READY;
0355 return 0;
0356 }
0357
0358 switch (dcfg->method) {
0359 case IMX_RPROC_MMIO:
0360 ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
0361 dcfg->src_stop);
0362 break;
0363 case IMX_RPROC_SCU_API:
0364 ret = imx_sc_pm_cpu_start(priv->ipc_handle,
0365 IMX_SC_R_DSP,
0366 false,
0367 rproc->bootaddr);
0368 break;
0369 default:
0370 return -EOPNOTSUPP;
0371 }
0372
0373 if (ret)
0374 dev_err(dev, "Failed to stop remote core\n");
0375 else
0376 priv->flags &= ~REMOTE_IS_READY;
0377
0378 return ret;
0379 }
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391 static int imx_dsp_rproc_sys_to_da(struct imx_dsp_rproc *priv, u64 sys,
0392 size_t len, u64 *da)
0393 {
0394 const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
0395 const struct imx_rproc_dcfg *dcfg = dsp_dcfg->dcfg;
0396 int i;
0397
0398
0399 for (i = 0; i < dcfg->att_size; i++) {
0400 const struct imx_rproc_att *att = &dcfg->att[i];
0401
0402 if (sys >= att->sa && sys + len <= att->sa + att->size) {
0403 unsigned int offset = sys - att->sa;
0404
0405 *da = att->da + offset;
0406 return 0;
0407 }
0408 }
0409
0410 return -ENOENT;
0411 }
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431 static void imx_dsp_rproc_vq_work(struct work_struct *work)
0432 {
0433 struct imx_dsp_rproc *priv = container_of(work, struct imx_dsp_rproc,
0434 rproc_work);
0435
0436 rproc_vq_interrupt(priv->rproc, 0);
0437 rproc_vq_interrupt(priv->rproc, 1);
0438 }
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449 static void imx_dsp_rproc_rx_tx_callback(struct mbox_client *cl, void *data)
0450 {
0451 struct rproc *rproc = dev_get_drvdata(cl->dev);
0452 struct imx_dsp_rproc *priv = rproc->priv;
0453 struct device *dev = rproc->dev.parent;
0454 u32 message = (u32)(*(u32 *)data);
0455
0456 dev_dbg(dev, "mbox msg: 0x%x\n", message);
0457
0458 switch (message) {
0459 case RP_MBOX_SUSPEND_ACK:
0460 complete(&priv->pm_comp);
0461 break;
0462 case RP_MBOX_RESUME_ACK:
0463 complete(&priv->pm_comp);
0464 break;
0465 default:
0466 schedule_work(&priv->rproc_work);
0467 break;
0468 }
0469 }
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479 static void imx_dsp_rproc_rxdb_callback(struct mbox_client *cl, void *data)
0480 {
0481 struct rproc *rproc = dev_get_drvdata(cl->dev);
0482 struct imx_dsp_rproc *priv = rproc->priv;
0483
0484
0485 priv->flags |= REMOTE_IS_READY;
0486 }
0487
0488
0489
0490
0491
0492
0493
0494 static int imx_dsp_rproc_mbox_init(struct imx_dsp_rproc *priv)
0495 {
0496 struct device *dev = priv->rproc->dev.parent;
0497 struct mbox_client *cl;
0498 int ret;
0499
0500 if (!of_get_property(dev->of_node, "mbox-names", NULL))
0501 return 0;
0502
0503 cl = &priv->cl;
0504 cl->dev = dev;
0505 cl->tx_block = true;
0506 cl->tx_tout = 100;
0507 cl->knows_txdone = false;
0508 cl->rx_callback = imx_dsp_rproc_rx_tx_callback;
0509
0510
0511 priv->tx_ch = mbox_request_channel_byname(cl, "tx");
0512 if (IS_ERR(priv->tx_ch)) {
0513 ret = PTR_ERR(priv->tx_ch);
0514 dev_dbg(cl->dev, "failed to request tx mailbox channel: %d\n",
0515 ret);
0516 goto err_out;
0517 }
0518
0519
0520 priv->rx_ch = mbox_request_channel_byname(cl, "rx");
0521 if (IS_ERR(priv->rx_ch)) {
0522 ret = PTR_ERR(priv->rx_ch);
0523 dev_dbg(cl->dev, "failed to request rx mailbox channel: %d\n",
0524 ret);
0525 goto err_out;
0526 }
0527
0528 cl = &priv->cl_rxdb;
0529 cl->dev = dev;
0530 cl->rx_callback = imx_dsp_rproc_rxdb_callback;
0531
0532
0533
0534
0535
0536 priv->rxdb_ch = mbox_request_channel_byname(cl, "rxdb");
0537 if (IS_ERR(priv->rxdb_ch)) {
0538 ret = PTR_ERR(priv->rxdb_ch);
0539 dev_dbg(cl->dev, "failed to request mbox chan rxdb, ret %d\n",
0540 ret);
0541 goto err_out;
0542 }
0543
0544 return 0;
0545
0546 err_out:
0547 if (!IS_ERR(priv->tx_ch))
0548 mbox_free_channel(priv->tx_ch);
0549 if (!IS_ERR(priv->rx_ch))
0550 mbox_free_channel(priv->rx_ch);
0551 if (!IS_ERR(priv->rxdb_ch))
0552 mbox_free_channel(priv->rxdb_ch);
0553
0554 return ret;
0555 }
0556
0557 static void imx_dsp_rproc_free_mbox(struct imx_dsp_rproc *priv)
0558 {
0559 mbox_free_channel(priv->tx_ch);
0560 mbox_free_channel(priv->rx_ch);
0561 mbox_free_channel(priv->rxdb_ch);
0562 }
0563
0564
0565
0566
0567
0568
0569
0570
0571 static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv)
0572 {
0573 const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
0574 const struct imx_rproc_dcfg *dcfg = dsp_dcfg->dcfg;
0575 struct rproc *rproc = priv->rproc;
0576 struct device *dev = rproc->dev.parent;
0577 struct device_node *np = dev->of_node;
0578 struct of_phandle_iterator it;
0579 struct rproc_mem_entry *mem;
0580 struct reserved_mem *rmem;
0581 void __iomem *cpu_addr;
0582 int a;
0583 u64 da;
0584
0585
0586 for (a = 0; a < dcfg->att_size; a++) {
0587 const struct imx_rproc_att *att = &dcfg->att[a];
0588
0589 if (!(att->flags & ATT_OWN))
0590 continue;
0591
0592 if (imx_dsp_rproc_sys_to_da(priv, att->sa, att->size, &da))
0593 return -EINVAL;
0594
0595 cpu_addr = devm_ioremap_wc(dev, att->sa, att->size);
0596 if (!cpu_addr) {
0597 dev_err(dev, "failed to map memory %p\n", &att->sa);
0598 return -ENOMEM;
0599 }
0600
0601
0602 mem = rproc_mem_entry_init(dev, cpu_addr, (dma_addr_t)att->sa,
0603 att->size, da, NULL, NULL, "dsp_mem");
0604
0605 if (mem)
0606 rproc_coredump_add_segment(rproc, da, att->size);
0607 else
0608 return -ENOMEM;
0609
0610 rproc_add_carveout(rproc, mem);
0611 }
0612
0613 of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
0614 while (of_phandle_iterator_next(&it) == 0) {
0615
0616
0617
0618
0619 if (!strcmp(it.node->name, "vdev0buffer"))
0620 continue;
0621
0622 rmem = of_reserved_mem_lookup(it.node);
0623 if (!rmem) {
0624 dev_err(dev, "unable to acquire memory-region\n");
0625 return -EINVAL;
0626 }
0627
0628 if (imx_dsp_rproc_sys_to_da(priv, rmem->base, rmem->size, &da))
0629 return -EINVAL;
0630
0631 cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
0632 if (!cpu_addr) {
0633 dev_err(dev, "failed to map memory %p\n", &rmem->base);
0634 return -ENOMEM;
0635 }
0636
0637
0638 mem = rproc_mem_entry_init(dev, cpu_addr, (dma_addr_t)rmem->base,
0639 rmem->size, da, NULL, NULL, it.node->name);
0640
0641 if (mem)
0642 rproc_coredump_add_segment(rproc, da, rmem->size);
0643 else
0644 return -ENOMEM;
0645
0646 rproc_add_carveout(rproc, mem);
0647 }
0648
0649 return 0;
0650 }
0651
0652
0653 static int imx_dsp_rproc_prepare(struct rproc *rproc)
0654 {
0655 struct imx_dsp_rproc *priv = rproc->priv;
0656 struct device *dev = rproc->dev.parent;
0657 struct rproc_mem_entry *carveout;
0658 int ret;
0659
0660 ret = imx_dsp_rproc_add_carveout(priv);
0661 if (ret) {
0662 dev_err(dev, "failed on imx_dsp_rproc_add_carveout\n");
0663 return ret;
0664 }
0665
0666 pm_runtime_get_sync(dev);
0667
0668
0669
0670
0671
0672 list_for_each_entry(carveout, &rproc->carveouts, node) {
0673 if (carveout->va)
0674 memset(carveout->va, 0, carveout->len);
0675 }
0676
0677 return 0;
0678 }
0679
0680
0681 static int imx_dsp_rproc_unprepare(struct rproc *rproc)
0682 {
0683 pm_runtime_put_sync(rproc->dev.parent);
0684
0685 return 0;
0686 }
0687
0688
0689 static void imx_dsp_rproc_kick(struct rproc *rproc, int vqid)
0690 {
0691 struct imx_dsp_rproc *priv = rproc->priv;
0692 struct device *dev = rproc->dev.parent;
0693 int err;
0694 __u32 mmsg;
0695
0696 if (!priv->tx_ch) {
0697 dev_err(dev, "No initialized mbox tx channel\n");
0698 return;
0699 }
0700
0701
0702
0703
0704
0705 mmsg = vqid;
0706
0707 err = mbox_send_message(priv->tx_ch, (void *)&mmsg);
0708 if (err < 0)
0709 dev_err(dev, "%s: failed (%d, err:%d)\n", __func__, vqid, err);
0710 }
0711
0712 static int imx_dsp_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
0713 {
0714 if (rproc_elf_load_rsc_table(rproc, fw))
0715 dev_warn(&rproc->dev, "no resource table found for this firmware\n");
0716
0717 return 0;
0718 }
0719
0720 static const struct rproc_ops imx_dsp_rproc_ops = {
0721 .prepare = imx_dsp_rproc_prepare,
0722 .unprepare = imx_dsp_rproc_unprepare,
0723 .start = imx_dsp_rproc_start,
0724 .stop = imx_dsp_rproc_stop,
0725 .kick = imx_dsp_rproc_kick,
0726 .load = rproc_elf_load_segments,
0727 .parse_fw = imx_dsp_rproc_parse_fw,
0728 .sanity_check = rproc_elf_sanity_check,
0729 .get_boot_addr = rproc_elf_get_boot_addr,
0730 };
0731
0732
0733
0734
0735
0736
0737
0738
0739 static int imx_dsp_attach_pm_domains(struct imx_dsp_rproc *priv)
0740 {
0741 struct device *dev = priv->rproc->dev.parent;
0742 int ret, i;
0743
0744 priv->num_domains = of_count_phandle_with_args(dev->of_node,
0745 "power-domains",
0746 "#power-domain-cells");
0747
0748
0749 if (priv->num_domains <= 1)
0750 return 0;
0751
0752 priv->pd_dev = devm_kmalloc_array(dev, priv->num_domains,
0753 sizeof(*priv->pd_dev),
0754 GFP_KERNEL);
0755 if (!priv->pd_dev)
0756 return -ENOMEM;
0757
0758 priv->pd_dev_link = devm_kmalloc_array(dev, priv->num_domains,
0759 sizeof(*priv->pd_dev_link),
0760 GFP_KERNEL);
0761 if (!priv->pd_dev_link)
0762 return -ENOMEM;
0763
0764 for (i = 0; i < priv->num_domains; i++) {
0765 priv->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
0766 if (IS_ERR(priv->pd_dev[i])) {
0767 ret = PTR_ERR(priv->pd_dev[i]);
0768 goto detach_pm;
0769 }
0770
0771
0772
0773
0774
0775 priv->pd_dev_link[i] = device_link_add(dev,
0776 priv->pd_dev[i],
0777 DL_FLAG_STATELESS |
0778 DL_FLAG_PM_RUNTIME);
0779 if (!priv->pd_dev_link[i]) {
0780 dev_pm_domain_detach(priv->pd_dev[i], false);
0781 ret = -EINVAL;
0782 goto detach_pm;
0783 }
0784 }
0785
0786 return 0;
0787
0788 detach_pm:
0789 while (--i >= 0) {
0790 device_link_del(priv->pd_dev_link[i]);
0791 dev_pm_domain_detach(priv->pd_dev[i], false);
0792 }
0793
0794 return ret;
0795 }
0796
0797 static int imx_dsp_detach_pm_domains(struct imx_dsp_rproc *priv)
0798 {
0799 int i;
0800
0801 if (priv->num_domains <= 1)
0802 return 0;
0803
0804 for (i = 0; i < priv->num_domains; i++) {
0805 device_link_del(priv->pd_dev_link[i]);
0806 dev_pm_domain_detach(priv->pd_dev[i], false);
0807 }
0808
0809 return 0;
0810 }
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824 static int imx_dsp_rproc_detect_mode(struct imx_dsp_rproc *priv)
0825 {
0826 const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
0827 struct device *dev = priv->rproc->dev.parent;
0828 struct regmap *regmap;
0829 int ret = 0;
0830
0831 switch (dsp_dcfg->dcfg->method) {
0832 case IMX_RPROC_SCU_API:
0833 ret = imx_scu_get_handle(&priv->ipc_handle);
0834 if (ret)
0835 return ret;
0836 break;
0837 case IMX_RPROC_MMIO:
0838 regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,dsp-ctrl");
0839 if (IS_ERR(regmap)) {
0840 dev_err(dev, "failed to find syscon\n");
0841 return PTR_ERR(regmap);
0842 }
0843
0844 priv->regmap = regmap;
0845 break;
0846 default:
0847 ret = -EOPNOTSUPP;
0848 break;
0849 }
0850
0851 return ret;
0852 }
0853
0854 static const char *imx_dsp_clks_names[DSP_RPROC_CLK_MAX] = {
0855
0856 "core", "ocram", "debug", "ipg", "mu",
0857 };
0858
0859 static int imx_dsp_rproc_clk_get(struct imx_dsp_rproc *priv)
0860 {
0861 struct device *dev = priv->rproc->dev.parent;
0862 struct clk_bulk_data *clks = priv->clks;
0863 int i;
0864
0865 for (i = 0; i < DSP_RPROC_CLK_MAX; i++)
0866 clks[i].id = imx_dsp_clks_names[i];
0867
0868 return devm_clk_bulk_get_optional(dev, DSP_RPROC_CLK_MAX, clks);
0869 }
0870
0871 static int imx_dsp_rproc_probe(struct platform_device *pdev)
0872 {
0873 const struct imx_dsp_rproc_dcfg *dsp_dcfg;
0874 struct device *dev = &pdev->dev;
0875 struct imx_dsp_rproc *priv;
0876 struct rproc *rproc;
0877 const char *fw_name;
0878 int ret;
0879
0880 dsp_dcfg = of_device_get_match_data(dev);
0881 if (!dsp_dcfg)
0882 return -ENODEV;
0883
0884 ret = rproc_of_parse_firmware(dev, 0, &fw_name);
0885 if (ret) {
0886 dev_err(dev, "failed to parse firmware-name property, ret = %d\n",
0887 ret);
0888 return ret;
0889 }
0890
0891 rproc = rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops, fw_name,
0892 sizeof(*priv));
0893 if (!rproc)
0894 return -ENOMEM;
0895
0896 priv = rproc->priv;
0897 priv->rproc = rproc;
0898 priv->dsp_dcfg = dsp_dcfg;
0899
0900 dev_set_drvdata(dev, rproc);
0901
0902 INIT_WORK(&priv->rproc_work, imx_dsp_rproc_vq_work);
0903
0904 ret = imx_dsp_rproc_detect_mode(priv);
0905 if (ret) {
0906 dev_err(dev, "failed on imx_dsp_rproc_detect_mode\n");
0907 goto err_put_rproc;
0908 }
0909
0910
0911 ret = imx_dsp_attach_pm_domains(priv);
0912 if (ret) {
0913 dev_err(dev, "failed on imx_dsp_attach_pm_domains\n");
0914 goto err_put_rproc;
0915 }
0916
0917 ret = imx_dsp_rproc_clk_get(priv);
0918 if (ret) {
0919 dev_err(dev, "failed on imx_dsp_rproc_clk_get\n");
0920 goto err_detach_domains;
0921 }
0922
0923 init_completion(&priv->pm_comp);
0924 rproc->auto_boot = false;
0925 ret = rproc_add(rproc);
0926 if (ret) {
0927 dev_err(dev, "rproc_add failed\n");
0928 goto err_detach_domains;
0929 }
0930
0931 pm_runtime_enable(dev);
0932
0933 return 0;
0934
0935 err_detach_domains:
0936 imx_dsp_detach_pm_domains(priv);
0937 err_put_rproc:
0938 rproc_free(rproc);
0939
0940 return ret;
0941 }
0942
0943 static int imx_dsp_rproc_remove(struct platform_device *pdev)
0944 {
0945 struct rproc *rproc = platform_get_drvdata(pdev);
0946 struct imx_dsp_rproc *priv = rproc->priv;
0947
0948 pm_runtime_disable(&pdev->dev);
0949 rproc_del(rproc);
0950 imx_dsp_detach_pm_domains(priv);
0951 rproc_free(rproc);
0952
0953 return 0;
0954 }
0955
0956
0957 static int imx_dsp_runtime_resume(struct device *dev)
0958 {
0959 struct rproc *rproc = dev_get_drvdata(dev);
0960 struct imx_dsp_rproc *priv = rproc->priv;
0961 const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
0962 int ret;
0963
0964
0965
0966
0967
0968
0969
0970 ret = imx_dsp_rproc_mbox_init(priv);
0971 if (ret) {
0972 dev_err(dev, "failed on imx_dsp_rproc_mbox_init\n");
0973 return ret;
0974 }
0975
0976 ret = clk_bulk_prepare_enable(DSP_RPROC_CLK_MAX, priv->clks);
0977 if (ret) {
0978 dev_err(dev, "failed on clk_bulk_prepare_enable\n");
0979 return ret;
0980 }
0981
0982
0983 if (dsp_dcfg->reset)
0984 dsp_dcfg->reset(priv);
0985
0986 return 0;
0987 }
0988
0989 static int imx_dsp_runtime_suspend(struct device *dev)
0990 {
0991 struct rproc *rproc = dev_get_drvdata(dev);
0992 struct imx_dsp_rproc *priv = rproc->priv;
0993
0994 clk_bulk_disable_unprepare(DSP_RPROC_CLK_MAX, priv->clks);
0995
0996 imx_dsp_rproc_free_mbox(priv);
0997
0998 return 0;
0999 }
1000
1001 static void imx_dsp_load_firmware(const struct firmware *fw, void *context)
1002 {
1003 struct rproc *rproc = context;
1004 int ret;
1005
1006
1007
1008
1009
1010 ret = rproc_load_segments(rproc, fw);
1011 if (ret)
1012 goto out;
1013
1014
1015 ret = rproc->ops->start(rproc);
1016 if (ret)
1017 goto out;
1018
1019 rproc->ops->kick(rproc, 0);
1020
1021 out:
1022 release_firmware(fw);
1023 }
1024
1025 static __maybe_unused int imx_dsp_suspend(struct device *dev)
1026 {
1027 struct rproc *rproc = dev_get_drvdata(dev);
1028 struct imx_dsp_rproc *priv = rproc->priv;
1029 __u32 mmsg = RP_MBOX_SUSPEND_SYSTEM;
1030 int ret;
1031
1032 if (rproc->state != RPROC_RUNNING)
1033 goto out;
1034
1035 reinit_completion(&priv->pm_comp);
1036
1037
1038 ret = mbox_send_message(priv->tx_ch, (void *)&mmsg);
1039 if (ret < 0) {
1040 dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
1041 return ret;
1042 }
1043
1044
1045
1046
1047
1048 if (!wait_for_completion_timeout(&priv->pm_comp, msecs_to_jiffies(100)))
1049 return -EBUSY;
1050
1051 out:
1052
1053
1054
1055
1056
1057 return pm_runtime_force_suspend(dev);
1058 }
1059
1060 static __maybe_unused int imx_dsp_resume(struct device *dev)
1061 {
1062 struct rproc *rproc = dev_get_drvdata(dev);
1063 int ret = 0;
1064
1065 ret = pm_runtime_force_resume(dev);
1066 if (ret)
1067 return ret;
1068
1069 if (rproc->state != RPROC_RUNNING)
1070 return 0;
1071
1072
1073
1074
1075
1076
1077 ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
1078 rproc->firmware, dev, GFP_KERNEL,
1079 rproc, imx_dsp_load_firmware);
1080 if (ret < 0) {
1081 dev_err(dev, "load firmware failed: %d\n", ret);
1082 goto err;
1083 }
1084
1085 return 0;
1086
1087 err:
1088 pm_runtime_force_suspend(dev);
1089
1090 return ret;
1091 }
1092
1093 static const struct dev_pm_ops imx_dsp_rproc_pm_ops = {
1094 SET_SYSTEM_SLEEP_PM_OPS(imx_dsp_suspend, imx_dsp_resume)
1095 SET_RUNTIME_PM_OPS(imx_dsp_runtime_suspend,
1096 imx_dsp_runtime_resume, NULL)
1097 };
1098
1099 static const struct of_device_id imx_dsp_rproc_of_match[] = {
1100 { .compatible = "fsl,imx8qxp-hifi4", .data = &imx_dsp_rproc_cfg_imx8qxp },
1101 { .compatible = "fsl,imx8qm-hifi4", .data = &imx_dsp_rproc_cfg_imx8qm },
1102 { .compatible = "fsl,imx8mp-hifi4", .data = &imx_dsp_rproc_cfg_imx8mp },
1103 { .compatible = "fsl,imx8ulp-hifi4", .data = &imx_dsp_rproc_cfg_imx8ulp },
1104 {},
1105 };
1106 MODULE_DEVICE_TABLE(of, imx_dsp_rproc_of_match);
1107
1108 static struct platform_driver imx_dsp_rproc_driver = {
1109 .probe = imx_dsp_rproc_probe,
1110 .remove = imx_dsp_rproc_remove,
1111 .driver = {
1112 .name = "imx-dsp-rproc",
1113 .of_match_table = imx_dsp_rproc_of_match,
1114 .pm = &imx_dsp_rproc_pm_ops,
1115 },
1116 };
1117 module_platform_driver(imx_dsp_rproc_driver);
1118
1119 MODULE_LICENSE("GPL v2");
1120 MODULE_DESCRIPTION("i.MX HiFi Core Remote Processor Control Driver");
1121 MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@nxp.com>");