Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2017 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
0004  */
0005 
0006 #include <linux/arm-smccc.h>
0007 #include <linux/clk.h>
0008 #include <linux/err.h>
0009 #include <linux/interrupt.h>
0010 #include <linux/kernel.h>
0011 #include <linux/mailbox_client.h>
0012 #include <linux/mfd/syscon.h>
0013 #include <linux/module.h>
0014 #include <linux/of_address.h>
0015 #include <linux/of_reserved_mem.h>
0016 #include <linux/of_device.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/regmap.h>
0019 #include <linux/remoteproc.h>
0020 #include <linux/workqueue.h>
0021 
0022 #include "imx_rproc.h"
0023 #include "remoteproc_internal.h"
0024 
0025 #define IMX7D_SRC_SCR           0x0C
0026 #define IMX7D_ENABLE_M4         BIT(3)
0027 #define IMX7D_SW_M4P_RST        BIT(2)
0028 #define IMX7D_SW_M4C_RST        BIT(1)
0029 #define IMX7D_SW_M4C_NON_SCLR_RST   BIT(0)
0030 
0031 #define IMX7D_M4_RST_MASK       (IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
0032                      | IMX7D_SW_M4C_RST \
0033                      | IMX7D_SW_M4C_NON_SCLR_RST)
0034 
0035 #define IMX7D_M4_START          (IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
0036                      | IMX7D_SW_M4C_RST)
0037 #define IMX7D_M4_STOP           (IMX7D_ENABLE_M4 | IMX7D_SW_M4C_RST | \
0038                      IMX7D_SW_M4C_NON_SCLR_RST)
0039 
0040 /* Address: 0x020D8000 */
0041 #define IMX6SX_SRC_SCR          0x00
0042 #define IMX6SX_ENABLE_M4        BIT(22)
0043 #define IMX6SX_SW_M4P_RST       BIT(12)
0044 #define IMX6SX_SW_M4C_NON_SCLR_RST  BIT(4)
0045 #define IMX6SX_SW_M4C_RST       BIT(3)
0046 
0047 #define IMX6SX_M4_START         (IMX6SX_ENABLE_M4 | IMX6SX_SW_M4P_RST \
0048                      | IMX6SX_SW_M4C_RST)
0049 #define IMX6SX_M4_STOP          (IMX6SX_ENABLE_M4 | IMX6SX_SW_M4C_RST | \
0050                      IMX6SX_SW_M4C_NON_SCLR_RST)
0051 #define IMX6SX_M4_RST_MASK      (IMX6SX_ENABLE_M4 | IMX6SX_SW_M4P_RST \
0052                      | IMX6SX_SW_M4C_NON_SCLR_RST \
0053                      | IMX6SX_SW_M4C_RST)
0054 
0055 #define IMX_RPROC_MEM_MAX       32
0056 
0057 #define IMX_SIP_RPROC           0xC2000005
0058 #define IMX_SIP_RPROC_START     0x00
0059 #define IMX_SIP_RPROC_STARTED       0x01
0060 #define IMX_SIP_RPROC_STOP      0x02
0061 
0062 /**
0063  * struct imx_rproc_mem - slim internal memory structure
0064  * @cpu_addr: MPU virtual address of the memory region
0065  * @sys_addr: Bus address used to access the memory region
0066  * @size: Size of the memory region
0067  */
0068 struct imx_rproc_mem {
0069     void __iomem *cpu_addr;
0070     phys_addr_t sys_addr;
0071     size_t size;
0072 };
0073 
0074 /* att flags */
0075 /* M4 own area. Can be mapped at probe */
0076 #define ATT_OWN     BIT(1)
0077 #define ATT_IOMEM   BIT(2)
0078 
0079 struct imx_rproc {
0080     struct device           *dev;
0081     struct regmap           *regmap;
0082     struct rproc            *rproc;
0083     const struct imx_rproc_dcfg *dcfg;
0084     struct imx_rproc_mem        mem[IMX_RPROC_MEM_MAX];
0085     struct clk          *clk;
0086     struct mbox_client      cl;
0087     struct mbox_chan        *tx_ch;
0088     struct mbox_chan        *rx_ch;
0089     struct work_struct      rproc_work;
0090     struct workqueue_struct     *workqueue;
0091     void __iomem            *rsc_table;
0092 };
0093 
0094 static const struct imx_rproc_att imx_rproc_att_imx93[] = {
0095     /* dev addr , sys addr  , size      , flags */
0096     /* TCM CODE NON-SECURE */
0097     { 0x0FFC0000, 0x201C0000, 0x00020000, ATT_OWN | ATT_IOMEM },
0098     { 0x0FFE0000, 0x201E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
0099 
0100     /* TCM CODE SECURE */
0101     { 0x1FFC0000, 0x201C0000, 0x00020000, ATT_OWN | ATT_IOMEM },
0102     { 0x1FFE0000, 0x201E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
0103 
0104     /* TCM SYS NON-SECURE*/
0105     { 0x20000000, 0x20200000, 0x00020000, ATT_OWN | ATT_IOMEM },
0106     { 0x20020000, 0x20220000, 0x00020000, ATT_OWN | ATT_IOMEM },
0107 
0108     /* TCM SYS SECURE*/
0109     { 0x30000000, 0x20200000, 0x00020000, ATT_OWN | ATT_IOMEM },
0110     { 0x30020000, 0x20220000, 0x00020000, ATT_OWN | ATT_IOMEM },
0111 
0112     /* DDR */
0113     { 0x80000000, 0x80000000, 0x10000000, 0 },
0114     { 0x90000000, 0x80000000, 0x10000000, 0 },
0115 
0116     { 0xC0000000, 0xa0000000, 0x10000000, 0 },
0117     { 0xD0000000, 0xa0000000, 0x10000000, 0 },
0118 };
0119 
0120 static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
0121     /* dev addr , sys addr  , size      , flags */
0122     /* ITCM   */
0123     { 0x00000000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
0124     /* OCRAM_S */
0125     { 0x00180000, 0x00180000, 0x00009000, 0 },
0126     /* OCRAM */
0127     { 0x00900000, 0x00900000, 0x00020000, 0 },
0128     /* OCRAM */
0129     { 0x00920000, 0x00920000, 0x00020000, 0 },
0130     /* OCRAM */
0131     { 0x00940000, 0x00940000, 0x00050000, 0 },
0132     /* QSPI Code - alias */
0133     { 0x08000000, 0x08000000, 0x08000000, 0 },
0134     /* DDR (Code) - alias */
0135     { 0x10000000, 0x40000000, 0x0FFE0000, 0 },
0136     /* DTCM */
0137     { 0x20000000, 0x00800000, 0x00020000, ATT_OWN | ATT_IOMEM },
0138     /* OCRAM_S - alias */
0139     { 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
0140     /* OCRAM */
0141     { 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
0142     /* OCRAM */
0143     { 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
0144     /* OCRAM */
0145     { 0x20240000, 0x00940000, 0x00040000, ATT_OWN },
0146     /* DDR (Data) */
0147     { 0x40000000, 0x40000000, 0x80000000, 0 },
0148 };
0149 
0150 static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
0151     /* dev addr , sys addr  , size      , flags */
0152     /* TCML - alias */
0153     { 0x00000000, 0x007e0000, 0x00020000, ATT_IOMEM},
0154     /* OCRAM_S */
0155     { 0x00180000, 0x00180000, 0x00008000, 0 },
0156     /* OCRAM */
0157     { 0x00900000, 0x00900000, 0x00020000, 0 },
0158     /* OCRAM */
0159     { 0x00920000, 0x00920000, 0x00020000, 0 },
0160     /* QSPI Code - alias */
0161     { 0x08000000, 0x08000000, 0x08000000, 0 },
0162     /* DDR (Code) - alias */
0163     { 0x10000000, 0x80000000, 0x0FFE0000, 0 },
0164     /* TCML */
0165     { 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN  | ATT_IOMEM},
0166     /* TCMU */
0167     { 0x20000000, 0x00800000, 0x00020000, ATT_OWN  | ATT_IOMEM},
0168     /* OCRAM_S */
0169     { 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
0170     /* OCRAM */
0171     { 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
0172     /* OCRAM */
0173     { 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
0174     /* DDR (Data) */
0175     { 0x40000000, 0x40000000, 0x80000000, 0 },
0176 };
0177 
0178 static const struct imx_rproc_att imx_rproc_att_imx8ulp[] = {
0179     {0x1FFC0000, 0x1FFC0000, 0xC0000, ATT_OWN},
0180     {0x21000000, 0x21000000, 0x10000, ATT_OWN},
0181     {0x80000000, 0x80000000, 0x60000000, 0}
0182 };
0183 
0184 static const struct imx_rproc_att imx_rproc_att_imx7ulp[] = {
0185     {0x1FFD0000, 0x1FFD0000, 0x30000, ATT_OWN},
0186     {0x20000000, 0x20000000, 0x10000, ATT_OWN},
0187     {0x2F000000, 0x2F000000, 0x20000, ATT_OWN},
0188     {0x2F020000, 0x2F020000, 0x20000, ATT_OWN},
0189     {0x60000000, 0x60000000, 0x40000000, 0}
0190 };
0191 
0192 static const struct imx_rproc_att imx_rproc_att_imx7d[] = {
0193     /* dev addr , sys addr  , size      , flags */
0194     /* OCRAM_S (M4 Boot code) - alias */
0195     { 0x00000000, 0x00180000, 0x00008000, 0 },
0196     /* OCRAM_S (Code) */
0197     { 0x00180000, 0x00180000, 0x00008000, ATT_OWN },
0198     /* OCRAM (Code) - alias */
0199     { 0x00900000, 0x00900000, 0x00020000, 0 },
0200     /* OCRAM_EPDC (Code) - alias */
0201     { 0x00920000, 0x00920000, 0x00020000, 0 },
0202     /* OCRAM_PXP (Code) - alias */
0203     { 0x00940000, 0x00940000, 0x00008000, 0 },
0204     /* TCML (Code) */
0205     { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
0206     /* DDR (Code) - alias, first part of DDR (Data) */
0207     { 0x10000000, 0x80000000, 0x0FFF0000, 0 },
0208 
0209     /* TCMU (Data) */
0210     { 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
0211     /* OCRAM (Data) */
0212     { 0x20200000, 0x00900000, 0x00020000, 0 },
0213     /* OCRAM_EPDC (Data) */
0214     { 0x20220000, 0x00920000, 0x00020000, 0 },
0215     /* OCRAM_PXP (Data) */
0216     { 0x20240000, 0x00940000, 0x00008000, 0 },
0217     /* DDR (Data) */
0218     { 0x80000000, 0x80000000, 0x60000000, 0 },
0219 };
0220 
0221 static const struct imx_rproc_att imx_rproc_att_imx6sx[] = {
0222     /* dev addr , sys addr  , size      , flags */
0223     /* TCML (M4 Boot Code) - alias */
0224     { 0x00000000, 0x007F8000, 0x00008000, ATT_IOMEM },
0225     /* OCRAM_S (Code) */
0226     { 0x00180000, 0x008F8000, 0x00004000, 0 },
0227     /* OCRAM_S (Code) - alias */
0228     { 0x00180000, 0x008FC000, 0x00004000, 0 },
0229     /* TCML (Code) */
0230     { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
0231     /* DDR (Code) - alias, first part of DDR (Data) */
0232     { 0x10000000, 0x80000000, 0x0FFF8000, 0 },
0233 
0234     /* TCMU (Data) */
0235     { 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
0236     /* OCRAM_S (Data) - alias? */
0237     { 0x208F8000, 0x008F8000, 0x00004000, 0 },
0238     /* DDR (Data) */
0239     { 0x80000000, 0x80000000, 0x60000000, 0 },
0240 };
0241 
0242 static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn = {
0243     .att        = imx_rproc_att_imx8mn,
0244     .att_size   = ARRAY_SIZE(imx_rproc_att_imx8mn),
0245     .method     = IMX_RPROC_SMC,
0246 };
0247 
0248 static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
0249     .src_reg    = IMX7D_SRC_SCR,
0250     .src_mask   = IMX7D_M4_RST_MASK,
0251     .src_start  = IMX7D_M4_START,
0252     .src_stop   = IMX7D_M4_STOP,
0253     .att        = imx_rproc_att_imx8mq,
0254     .att_size   = ARRAY_SIZE(imx_rproc_att_imx8mq),
0255     .method     = IMX_RPROC_MMIO,
0256 };
0257 
0258 static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
0259     .att        = imx_rproc_att_imx8ulp,
0260     .att_size   = ARRAY_SIZE(imx_rproc_att_imx8ulp),
0261     .method     = IMX_RPROC_NONE,
0262 };
0263 
0264 static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = {
0265     .att        = imx_rproc_att_imx7ulp,
0266     .att_size   = ARRAY_SIZE(imx_rproc_att_imx7ulp),
0267     .method     = IMX_RPROC_NONE,
0268 };
0269 
0270 static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = {
0271     .src_reg    = IMX7D_SRC_SCR,
0272     .src_mask   = IMX7D_M4_RST_MASK,
0273     .src_start  = IMX7D_M4_START,
0274     .src_stop   = IMX7D_M4_STOP,
0275     .att        = imx_rproc_att_imx7d,
0276     .att_size   = ARRAY_SIZE(imx_rproc_att_imx7d),
0277     .method     = IMX_RPROC_MMIO,
0278 };
0279 
0280 static const struct imx_rproc_dcfg imx_rproc_cfg_imx6sx = {
0281     .src_reg    = IMX6SX_SRC_SCR,
0282     .src_mask   = IMX6SX_M4_RST_MASK,
0283     .src_start  = IMX6SX_M4_START,
0284     .src_stop   = IMX6SX_M4_STOP,
0285     .att        = imx_rproc_att_imx6sx,
0286     .att_size   = ARRAY_SIZE(imx_rproc_att_imx6sx),
0287     .method     = IMX_RPROC_MMIO,
0288 };
0289 
0290 static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = {
0291     .att        = imx_rproc_att_imx93,
0292     .att_size   = ARRAY_SIZE(imx_rproc_att_imx93),
0293     .method     = IMX_RPROC_SMC,
0294 };
0295 
0296 static int imx_rproc_start(struct rproc *rproc)
0297 {
0298     struct imx_rproc *priv = rproc->priv;
0299     const struct imx_rproc_dcfg *dcfg = priv->dcfg;
0300     struct device *dev = priv->dev;
0301     struct arm_smccc_res res;
0302     int ret;
0303 
0304     switch (dcfg->method) {
0305     case IMX_RPROC_MMIO:
0306         ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
0307                      dcfg->src_start);
0308         break;
0309     case IMX_RPROC_SMC:
0310         arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_START, 0, 0, 0, 0, 0, 0, &res);
0311         ret = res.a0;
0312         break;
0313     default:
0314         return -EOPNOTSUPP;
0315     }
0316 
0317     if (ret)
0318         dev_err(dev, "Failed to enable remote core!\n");
0319 
0320     return ret;
0321 }
0322 
0323 static int imx_rproc_stop(struct rproc *rproc)
0324 {
0325     struct imx_rproc *priv = rproc->priv;
0326     const struct imx_rproc_dcfg *dcfg = priv->dcfg;
0327     struct device *dev = priv->dev;
0328     struct arm_smccc_res res;
0329     int ret;
0330 
0331     switch (dcfg->method) {
0332     case IMX_RPROC_MMIO:
0333         ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
0334                      dcfg->src_stop);
0335         break;
0336     case IMX_RPROC_SMC:
0337         arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STOP, 0, 0, 0, 0, 0, 0, &res);
0338         ret = res.a0;
0339         if (res.a1)
0340             dev_info(dev, "Not in wfi, force stopped\n");
0341         break;
0342     default:
0343         return -EOPNOTSUPP;
0344     }
0345 
0346     if (ret)
0347         dev_err(dev, "Failed to stop remote core\n");
0348 
0349     return ret;
0350 }
0351 
0352 static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
0353                    size_t len, u64 *sys, bool *is_iomem)
0354 {
0355     const struct imx_rproc_dcfg *dcfg = priv->dcfg;
0356     int i;
0357 
0358     /* parse address translation table */
0359     for (i = 0; i < dcfg->att_size; i++) {
0360         const struct imx_rproc_att *att = &dcfg->att[i];
0361 
0362         if (da >= att->da && da + len < att->da + att->size) {
0363             unsigned int offset = da - att->da;
0364 
0365             *sys = att->sa + offset;
0366             if (is_iomem)
0367                 *is_iomem = att->flags & ATT_IOMEM;
0368             return 0;
0369         }
0370     }
0371 
0372     dev_warn(priv->dev, "Translation failed: da = 0x%llx len = 0x%zx\n",
0373          da, len);
0374     return -ENOENT;
0375 }
0376 
0377 static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
0378 {
0379     struct imx_rproc *priv = rproc->priv;
0380     void *va = NULL;
0381     u64 sys;
0382     int i;
0383 
0384     if (len == 0)
0385         return NULL;
0386 
0387     /*
0388      * On device side we have many aliases, so we need to convert device
0389      * address (M4) to system bus address first.
0390      */
0391     if (imx_rproc_da_to_sys(priv, da, len, &sys, is_iomem))
0392         return NULL;
0393 
0394     for (i = 0; i < IMX_RPROC_MEM_MAX; i++) {
0395         if (sys >= priv->mem[i].sys_addr && sys + len <
0396             priv->mem[i].sys_addr +  priv->mem[i].size) {
0397             unsigned int offset = sys - priv->mem[i].sys_addr;
0398             /* __force to make sparse happy with type conversion */
0399             va = (__force void *)(priv->mem[i].cpu_addr + offset);
0400             break;
0401         }
0402     }
0403 
0404     dev_dbg(&rproc->dev, "da = 0x%llx len = 0x%zx va = 0x%p\n",
0405         da, len, va);
0406 
0407     return va;
0408 }
0409 
0410 static int imx_rproc_mem_alloc(struct rproc *rproc,
0411                    struct rproc_mem_entry *mem)
0412 {
0413     struct device *dev = rproc->dev.parent;
0414     void *va;
0415 
0416     dev_dbg(dev, "map memory: %p+%zx\n", &mem->dma, mem->len);
0417     va = ioremap_wc(mem->dma, mem->len);
0418     if (IS_ERR_OR_NULL(va)) {
0419         dev_err(dev, "Unable to map memory region: %p+%zx\n",
0420             &mem->dma, mem->len);
0421         return -ENOMEM;
0422     }
0423 
0424     /* Update memory entry va */
0425     mem->va = va;
0426 
0427     return 0;
0428 }
0429 
0430 static int imx_rproc_mem_release(struct rproc *rproc,
0431                  struct rproc_mem_entry *mem)
0432 {
0433     dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma);
0434     iounmap(mem->va);
0435 
0436     return 0;
0437 }
0438 
0439 static int imx_rproc_prepare(struct rproc *rproc)
0440 {
0441     struct imx_rproc *priv = rproc->priv;
0442     struct device_node *np = priv->dev->of_node;
0443     struct of_phandle_iterator it;
0444     struct rproc_mem_entry *mem;
0445     struct reserved_mem *rmem;
0446     u32 da;
0447 
0448     /* Register associated reserved memory regions */
0449     of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
0450     while (of_phandle_iterator_next(&it) == 0) {
0451         /*
0452          * Ignore the first memory region which will be used vdev buffer.
0453          * No need to do extra handlings, rproc_add_virtio_dev will handle it.
0454          */
0455         if (!strcmp(it.node->name, "vdev0buffer"))
0456             continue;
0457 
0458         if (!strcmp(it.node->name, "rsc-table"))
0459             continue;
0460 
0461         rmem = of_reserved_mem_lookup(it.node);
0462         if (!rmem) {
0463             dev_err(priv->dev, "unable to acquire memory-region\n");
0464             return -EINVAL;
0465         }
0466 
0467         /* No need to translate pa to da, i.MX use same map */
0468         da = rmem->base;
0469 
0470         /* Register memory region */
0471         mem = rproc_mem_entry_init(priv->dev, NULL, (dma_addr_t)rmem->base, rmem->size, da,
0472                        imx_rproc_mem_alloc, imx_rproc_mem_release,
0473                        it.node->name);
0474 
0475         if (mem)
0476             rproc_coredump_add_segment(rproc, da, rmem->size);
0477         else
0478             return -ENOMEM;
0479 
0480         rproc_add_carveout(rproc, mem);
0481     }
0482 
0483     return  0;
0484 }
0485 
0486 static int imx_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
0487 {
0488     int ret;
0489 
0490     ret = rproc_elf_load_rsc_table(rproc, fw);
0491     if (ret)
0492         dev_info(&rproc->dev, "No resource table in elf\n");
0493 
0494     return 0;
0495 }
0496 
0497 static void imx_rproc_kick(struct rproc *rproc, int vqid)
0498 {
0499     struct imx_rproc *priv = rproc->priv;
0500     int err;
0501     __u32 mmsg;
0502 
0503     if (!priv->tx_ch) {
0504         dev_err(priv->dev, "No initialized mbox tx channel\n");
0505         return;
0506     }
0507 
0508     /*
0509      * Send the index of the triggered virtqueue as the mu payload.
0510      * Let remote processor know which virtqueue is used.
0511      */
0512     mmsg = vqid << 16;
0513 
0514     err = mbox_send_message(priv->tx_ch, (void *)&mmsg);
0515     if (err < 0)
0516         dev_err(priv->dev, "%s: failed (%d, err:%d)\n",
0517             __func__, vqid, err);
0518 }
0519 
0520 static int imx_rproc_attach(struct rproc *rproc)
0521 {
0522     return 0;
0523 }
0524 
0525 static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
0526 {
0527     struct imx_rproc *priv = rproc->priv;
0528 
0529     /* The resource table has already been mapped in imx_rproc_addr_init */
0530     if (!priv->rsc_table)
0531         return NULL;
0532 
0533     *table_sz = SZ_1K;
0534     return (struct resource_table *)priv->rsc_table;
0535 }
0536 
0537 static const struct rproc_ops imx_rproc_ops = {
0538     .prepare    = imx_rproc_prepare,
0539     .attach     = imx_rproc_attach,
0540     .start      = imx_rproc_start,
0541     .stop       = imx_rproc_stop,
0542     .kick       = imx_rproc_kick,
0543     .da_to_va       = imx_rproc_da_to_va,
0544     .load       = rproc_elf_load_segments,
0545     .parse_fw   = imx_rproc_parse_fw,
0546     .find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
0547     .get_loaded_rsc_table = imx_rproc_get_loaded_rsc_table,
0548     .sanity_check   = rproc_elf_sanity_check,
0549     .get_boot_addr  = rproc_elf_get_boot_addr,
0550 };
0551 
0552 static int imx_rproc_addr_init(struct imx_rproc *priv,
0553                    struct platform_device *pdev)
0554 {
0555     const struct imx_rproc_dcfg *dcfg = priv->dcfg;
0556     struct device *dev = &pdev->dev;
0557     struct device_node *np = dev->of_node;
0558     int a, b = 0, err, nph;
0559 
0560     /* remap required addresses */
0561     for (a = 0; a < dcfg->att_size; a++) {
0562         const struct imx_rproc_att *att = &dcfg->att[a];
0563 
0564         if (!(att->flags & ATT_OWN))
0565             continue;
0566 
0567         if (b >= IMX_RPROC_MEM_MAX)
0568             break;
0569 
0570         if (att->flags & ATT_IOMEM)
0571             priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev,
0572                                  att->sa, att->size);
0573         else
0574             priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev,
0575                                 att->sa, att->size);
0576         if (!priv->mem[b].cpu_addr) {
0577             dev_err(dev, "failed to remap %#x bytes from %#x\n", att->size, att->sa);
0578             return -ENOMEM;
0579         }
0580         priv->mem[b].sys_addr = att->sa;
0581         priv->mem[b].size = att->size;
0582         b++;
0583     }
0584 
0585     /* memory-region is optional property */
0586     nph = of_count_phandle_with_args(np, "memory-region", NULL);
0587     if (nph <= 0)
0588         return 0;
0589 
0590     /* remap optional addresses */
0591     for (a = 0; a < nph; a++) {
0592         struct device_node *node;
0593         struct resource res;
0594 
0595         node = of_parse_phandle(np, "memory-region", a);
0596         /* Not map vdevbuffer, vdevring region */
0597         if (!strncmp(node->name, "vdev", strlen("vdev"))) {
0598             of_node_put(node);
0599             continue;
0600         }
0601         err = of_address_to_resource(node, 0, &res);
0602         of_node_put(node);
0603         if (err) {
0604             dev_err(dev, "unable to resolve memory region\n");
0605             return err;
0606         }
0607 
0608         if (b >= IMX_RPROC_MEM_MAX)
0609             break;
0610 
0611         /* Not use resource version, because we might share region */
0612         priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev, res.start, resource_size(&res));
0613         if (!priv->mem[b].cpu_addr) {
0614             dev_err(dev, "failed to remap %pr\n", &res);
0615             return -ENOMEM;
0616         }
0617         priv->mem[b].sys_addr = res.start;
0618         priv->mem[b].size = resource_size(&res);
0619         if (!strcmp(node->name, "rsc-table"))
0620             priv->rsc_table = priv->mem[b].cpu_addr;
0621         b++;
0622     }
0623 
0624     return 0;
0625 }
0626 
0627 static void imx_rproc_vq_work(struct work_struct *work)
0628 {
0629     struct imx_rproc *priv = container_of(work, struct imx_rproc,
0630                           rproc_work);
0631 
0632     rproc_vq_interrupt(priv->rproc, 0);
0633     rproc_vq_interrupt(priv->rproc, 1);
0634 }
0635 
0636 static void imx_rproc_rx_callback(struct mbox_client *cl, void *msg)
0637 {
0638     struct rproc *rproc = dev_get_drvdata(cl->dev);
0639     struct imx_rproc *priv = rproc->priv;
0640 
0641     queue_work(priv->workqueue, &priv->rproc_work);
0642 }
0643 
0644 static int imx_rproc_xtr_mbox_init(struct rproc *rproc)
0645 {
0646     struct imx_rproc *priv = rproc->priv;
0647     struct device *dev = priv->dev;
0648     struct mbox_client *cl;
0649     int ret;
0650 
0651     if (!of_get_property(dev->of_node, "mbox-names", NULL))
0652         return 0;
0653 
0654     cl = &priv->cl;
0655     cl->dev = dev;
0656     cl->tx_block = true;
0657     cl->tx_tout = 100;
0658     cl->knows_txdone = false;
0659     cl->rx_callback = imx_rproc_rx_callback;
0660 
0661     priv->tx_ch = mbox_request_channel_byname(cl, "tx");
0662     if (IS_ERR(priv->tx_ch)) {
0663         ret = PTR_ERR(priv->tx_ch);
0664         return dev_err_probe(cl->dev, ret,
0665                      "failed to request tx mailbox channel: %d\n", ret);
0666     }
0667 
0668     priv->rx_ch = mbox_request_channel_byname(cl, "rx");
0669     if (IS_ERR(priv->rx_ch)) {
0670         mbox_free_channel(priv->tx_ch);
0671         ret = PTR_ERR(priv->rx_ch);
0672         return dev_err_probe(cl->dev, ret,
0673                      "failed to request rx mailbox channel: %d\n", ret);
0674     }
0675 
0676     return 0;
0677 }
0678 
0679 static void imx_rproc_free_mbox(struct rproc *rproc)
0680 {
0681     struct imx_rproc *priv = rproc->priv;
0682 
0683     mbox_free_channel(priv->tx_ch);
0684     mbox_free_channel(priv->rx_ch);
0685 }
0686 
0687 static int imx_rproc_detect_mode(struct imx_rproc *priv)
0688 {
0689     struct regmap_config config = { .name = "imx-rproc" };
0690     const struct imx_rproc_dcfg *dcfg = priv->dcfg;
0691     struct device *dev = priv->dev;
0692     struct regmap *regmap;
0693     struct arm_smccc_res res;
0694     int ret;
0695     u32 val;
0696 
0697     switch (dcfg->method) {
0698     case IMX_RPROC_NONE:
0699         priv->rproc->state = RPROC_DETACHED;
0700         return 0;
0701     case IMX_RPROC_SMC:
0702         arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STARTED, 0, 0, 0, 0, 0, 0, &res);
0703         if (res.a0)
0704             priv->rproc->state = RPROC_DETACHED;
0705         return 0;
0706     default:
0707         break;
0708     }
0709 
0710     regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
0711     if (IS_ERR(regmap)) {
0712         dev_err(dev, "failed to find syscon\n");
0713         return PTR_ERR(regmap);
0714     }
0715 
0716     priv->regmap = regmap;
0717     regmap_attach_dev(dev, regmap, &config);
0718 
0719     ret = regmap_read(regmap, dcfg->src_reg, &val);
0720     if (ret) {
0721         dev_err(dev, "Failed to read src\n");
0722         return ret;
0723     }
0724 
0725     if ((val & dcfg->src_mask) != dcfg->src_stop)
0726         priv->rproc->state = RPROC_DETACHED;
0727 
0728     return 0;
0729 }
0730 
0731 static int imx_rproc_clk_enable(struct imx_rproc *priv)
0732 {
0733     const struct imx_rproc_dcfg *dcfg = priv->dcfg;
0734     struct device *dev = priv->dev;
0735     int ret;
0736 
0737     /* Remote core is not under control of Linux */
0738     if (dcfg->method == IMX_RPROC_NONE)
0739         return 0;
0740 
0741     priv->clk = devm_clk_get(dev, NULL);
0742     if (IS_ERR(priv->clk)) {
0743         dev_err(dev, "Failed to get clock\n");
0744         return PTR_ERR(priv->clk);
0745     }
0746 
0747     /*
0748      * clk for M4 block including memory. Should be
0749      * enabled before .start for FW transfer.
0750      */
0751     ret = clk_prepare_enable(priv->clk);
0752     if (ret) {
0753         dev_err(dev, "Failed to enable clock\n");
0754         return ret;
0755     }
0756 
0757     return 0;
0758 }
0759 
0760 static int imx_rproc_probe(struct platform_device *pdev)
0761 {
0762     struct device *dev = &pdev->dev;
0763     struct device_node *np = dev->of_node;
0764     struct imx_rproc *priv;
0765     struct rproc *rproc;
0766     const struct imx_rproc_dcfg *dcfg;
0767     int ret;
0768 
0769     /* set some other name then imx */
0770     rproc = rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
0771                 NULL, sizeof(*priv));
0772     if (!rproc)
0773         return -ENOMEM;
0774 
0775     dcfg = of_device_get_match_data(dev);
0776     if (!dcfg) {
0777         ret = -EINVAL;
0778         goto err_put_rproc;
0779     }
0780 
0781     priv = rproc->priv;
0782     priv->rproc = rproc;
0783     priv->dcfg = dcfg;
0784     priv->dev = dev;
0785 
0786     dev_set_drvdata(dev, rproc);
0787     priv->workqueue = create_workqueue(dev_name(dev));
0788     if (!priv->workqueue) {
0789         dev_err(dev, "cannot create workqueue\n");
0790         ret = -ENOMEM;
0791         goto err_put_rproc;
0792     }
0793 
0794     ret = imx_rproc_xtr_mbox_init(rproc);
0795     if (ret)
0796         goto err_put_wkq;
0797 
0798     ret = imx_rproc_addr_init(priv, pdev);
0799     if (ret) {
0800         dev_err(dev, "failed on imx_rproc_addr_init\n");
0801         goto err_put_mbox;
0802     }
0803 
0804     ret = imx_rproc_detect_mode(priv);
0805     if (ret)
0806         goto err_put_mbox;
0807 
0808     ret = imx_rproc_clk_enable(priv);
0809     if (ret)
0810         goto err_put_mbox;
0811 
0812     INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
0813 
0814     if (rproc->state != RPROC_DETACHED)
0815         rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot");
0816 
0817     ret = rproc_add(rproc);
0818     if (ret) {
0819         dev_err(dev, "rproc_add failed\n");
0820         goto err_put_clk;
0821     }
0822 
0823     return 0;
0824 
0825 err_put_clk:
0826     clk_disable_unprepare(priv->clk);
0827 err_put_mbox:
0828     imx_rproc_free_mbox(rproc);
0829 err_put_wkq:
0830     destroy_workqueue(priv->workqueue);
0831 err_put_rproc:
0832     rproc_free(rproc);
0833 
0834     return ret;
0835 }
0836 
0837 static int imx_rproc_remove(struct platform_device *pdev)
0838 {
0839     struct rproc *rproc = platform_get_drvdata(pdev);
0840     struct imx_rproc *priv = rproc->priv;
0841 
0842     clk_disable_unprepare(priv->clk);
0843     rproc_del(rproc);
0844     imx_rproc_free_mbox(rproc);
0845     destroy_workqueue(priv->workqueue);
0846     rproc_free(rproc);
0847 
0848     return 0;
0849 }
0850 
0851 static const struct of_device_id imx_rproc_of_match[] = {
0852     { .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp },
0853     { .compatible = "fsl,imx7d-cm4", .data = &imx_rproc_cfg_imx7d },
0854     { .compatible = "fsl,imx6sx-cm4", .data = &imx_rproc_cfg_imx6sx },
0855     { .compatible = "fsl,imx8mq-cm4", .data = &imx_rproc_cfg_imx8mq },
0856     { .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
0857     { .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
0858     { .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
0859     { .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
0860     { .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 },
0861     {},
0862 };
0863 MODULE_DEVICE_TABLE(of, imx_rproc_of_match);
0864 
0865 static struct platform_driver imx_rproc_driver = {
0866     .probe = imx_rproc_probe,
0867     .remove = imx_rproc_remove,
0868     .driver = {
0869         .name = "imx-rproc",
0870         .of_match_table = imx_rproc_of_match,
0871     },
0872 };
0873 
0874 module_platform_driver(imx_rproc_driver);
0875 
0876 MODULE_LICENSE("GPL v2");
0877 MODULE_DESCRIPTION("i.MX remote processor control driver");
0878 MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");