Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* Copyright 2021 NXP */
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 /* att flags */
0035 /* DSP own area */
0036 #define ATT_OWN                 BIT(31)
0037 /* DSP instruction area */
0038 #define ATT_IRAM                BIT(30)
0039 
0040 /* Definitions for i.MX8MP */
0041 /* DAP registers */
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 /* DSP audio mix registers */
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 /* Definitions for i.MX8ULP */
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  * enum - Predefined Mailbox Messages
0070  *
0071  * @RP_MBOX_SUSPEND_SYSTEM: system suspend request for the remote processor
0072  *
0073  * @RP_MBOX_SUSPEND_ACK: successful response from remote processor for a
0074  * suspend request
0075  *
0076  * @RP_MBOX_RESUME_SYSTEM: system resume request for the remote processor
0077  *
0078  * @RP_MBOX_RESUME_ACK: successful response from remote processor for a
0079  * resume request
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  * struct imx_dsp_rproc - DSP remote processor state
0090  * @regmap: regmap handler
0091  * @rproc: rproc handler
0092  * @dsp_dcfg: device configuration pointer
0093  * @clks: clocks needed by this device
0094  * @cl: mailbox client to request the mailbox channel
0095  * @cl_rxdb: mailbox client to request the mailbox channel for doorbell
0096  * @tx_ch: mailbox tx channel handle
0097  * @rx_ch: mailbox rx channel handle
0098  * @rxdb_ch: mailbox rx doorbell channel handle
0099  * @pd_dev: power domain device
0100  * @pd_dev_link: power domain device link
0101  * @ipc_handle: System Control Unit ipc handle
0102  * @rproc_work: work for processing virtio interrupts
0103  * @pm_comp: completion primitive to sync for suspend response
0104  * @num_domains: power domain number
0105  * @flags: control flags
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  * struct imx_dsp_rproc_dcfg - DSP remote processor configuration
0128  * @dcfg: imx_rproc_dcfg handler
0129  * @reset: reset callback function
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     /* dev addr , sys addr  , size      , flags */
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     /* DDR (Data) */
0143     { 0x80000000, 0x80000000, 0x60000000, 0},
0144 };
0145 
0146 static const struct imx_rproc_att imx_dsp_rproc_att_imx8qxp[] = {
0147     /* dev addr , sys addr  , size      , flags */
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     /* DDR (Data) */
0153     { 0x80000000, 0x80000000, 0x60000000, 0},
0154 };
0155 
0156 static const struct imx_rproc_att imx_dsp_rproc_att_imx8mp[] = {
0157     /* dev addr , sys addr  , size      , flags */
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     /* DDR (Data) */
0163     { 0x40000000, 0x40000000, 0x80000000, 0},
0164 };
0165 
0166 static const struct imx_rproc_att imx_dsp_rproc_att_imx8ulp[] = {
0167     /* dev addr , sys addr  , size      , flags */
0168     { 0x21170000, 0x21170000, 0x00010000, ATT_OWN | ATT_IRAM},
0169     { 0x21180000, 0x21180000, 0x00010000, ATT_OWN },
0170     /* DDR (Data) */
0171     { 0x0c000000, 0x80000000, 0x10000000, 0},
0172     { 0x30000000, 0x90000000, 0x10000000, 0},
0173 };
0174 
0175 /* Reset function for DSP on i.MX8MP */
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     /* Put DSP into reset and stall */
0182     pwrctl = readl(dap + IMX8M_DAP_PWRCTL);
0183     pwrctl |= IMX8M_PWRCTL_CORERESET;
0184     writel(pwrctl, dap + IMX8M_DAP_PWRCTL);
0185 
0186     /* Keep reset asserted for 10 cycles */
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     /* Take the DSP out of reset and keep stalled for FW loading */
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 /* Reset function for DSP on i.MX8ULP */
0203 static int imx8ulp_dsp_reset(struct imx_dsp_rproc *priv)
0204 {
0205     struct arm_smccc_res res;
0206 
0207     /* Put DSP into reset and stall */
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     /* Configure resources of DSP through TFA */
0215     arm_smccc_smc(IMX8ULP_SIP_HIFI_XRDC, 0, 0, 0, 0, 0, 0, 0, &res);
0216 
0217     /* Take the DSP out of reset and keep stalled for FW loading */
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 /* Specific configuration for i.MX8MP */
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 /* Specific configuration for i.MX8ULP */
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 /* Specific configuration for i.MX8QXP */
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 /* Specific configuration for i.MX8QM */
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  * Start function for rproc_ops
0299  *
0300  * There is a handshake for start procedure: when DSP starts, it
0301  * will send a doorbell message to this driver, then the
0302  * REMOTE_IS_READY flags is set, then driver will kick
0303  * a message to DSP.
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  * Stop function for rproc_ops
0340  * It clears the REMOTE_IS_READY flags
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     /* Make sure work is finished */
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  * imx_dsp_rproc_sys_to_da() - internal memory translation helper
0383  * @priv: private data pointer
0384  * @sys: system address (DDR address)
0385  * @len: length of the memory buffer
0386  * @da: device address to translate
0387  *
0388  * Convert system address (DDR address) to device address (DSP)
0389  * for there may be memory remap for device.
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     /* Parse address translation table */
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 /* Main virtqueue message work function
0414  *
0415  * This function is executed upon scheduling of the i.MX DSP remoteproc
0416  * driver's workqueue. The workqueue is scheduled by the mailbox rx
0417  * handler.
0418  *
0419  * This work function processes both the Tx and Rx virtqueue indices on
0420  * every invocation. The rproc_vq_interrupt function can detect if there
0421  * are new unprocessed messages or not (returns IRQ_NONE vs IRQ_HANDLED),
0422  * but there is no need to check for these return values. The index 0
0423  * triggering will process all pending Rx buffers, and the index 1 triggering
0424  * will process all newly available Tx buffers and will wakeup any potentially
0425  * blocked senders.
0426  *
0427  * NOTE:
0428  *    The current logic is based on an inherent design assumption of supporting
0429  *    only 2 vrings, but this can be changed if needed.
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  * imx_dsp_rproc_rx_tx_callback() - inbound mailbox message handler
0442  * @cl: mailbox client pointer used for requesting the mailbox channel
0443  * @data: mailbox payload
0444  *
0445  * This handler is invoked by mailbox driver whenever a mailbox
0446  * message is received. Usually, the SUSPEND and RESUME related messages
0447  * are handled in this function, other messages are handled by remoteproc core
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  * imx_dsp_rproc_rxdb_callback() - inbound mailbox message handler
0473  * @cl: mailbox client pointer used for requesting the mailbox channel
0474  * @data: mailbox payload
0475  *
0476  * For doorbell, there is no message specified, just set REMOTE_IS_READY
0477  * flag.
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     /* Remote is ready after firmware is loaded and running */
0485     priv->flags |= REMOTE_IS_READY;
0486 }
0487 
0488 /**
0489  * imx_dsp_rproc_mbox_init() - request mailbox channels
0490  * @priv: private data pointer
0491  *
0492  * Request three mailbox channels (tx, rx, rxdb).
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     /* Channel for sending message */
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     /* Channel for receiving message */
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      * RX door bell is used to receive the ready signal from remote
0534      * after firmware loaded.
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  * imx_dsp_rproc_add_carveout() - request mailbox channels
0566  * @priv: private data pointer
0567  *
0568  * This function registers specified memory entry in @rproc carveouts list
0569  * The carveouts can help to mapping the memory address for DSP.
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     /* Remap required addresses */
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         /* Register memory region */
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          * Ignore the first memory region which will be used vdev buffer.
0617          * No need to do extra handlings, rproc_add_virtio_dev will handle it.
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         /* Register memory region */
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 /* Prepare function for rproc_ops */
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      * Clear buffers after pm rumtime for internal ocram is not
0670      * accessible if power and clock are not enabled.
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 /* Unprepare function for rproc_ops */
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 /* Kick function for rproc_ops */
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      * Send the index of the triggered virtqueue as the mu payload.
0703      * Let remote processor know which virtqueue is used.
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  * imx_dsp_attach_pm_domains() - attach the power domains
0734  * @priv: private data pointer
0735  *
0736  * On i.MX8QM and i.MX8QXP there is multiple power domains
0737  * required, so need to link them.
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     /* If only one domain, then no need to link the device */
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          * device_link_add will check priv->pd_dev[i], if it is
0773          * NULL, then will break.
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  * imx_dsp_rproc_detect_mode() - detect DSP control mode
0814  * @priv: private data pointer
0815  *
0816  * Different platform has different control method for DSP, which depends
0817  * on how the DSP is integrated in platform.
0818  *
0819  * For i.MX8QXP and i.MX8QM, DSP should be started and stopped by System
0820  * Control Unit.
0821  * For i.MX8MP and i.MX8ULP, DSP should be started and stopped by system
0822  * integration module.
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     /* DSP clocks */
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     /* There are multiple power domains required by DSP on some platform */
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     /* Get clocks */
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 /* pm runtime functions */
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      * There is power domain attached with mailbox, if setup mailbox
0966      * in probe(), then the power of mailbox is always enabled,
0967      * the power can't be saved.
0968      * So move setup of mailbox to runtime resume.
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     /* Reset DSP if needed */
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      * Same flow as start procedure.
1008      * Load the ELF segments to memory firstly.
1009      */
1010     ret = rproc_load_segments(rproc, fw);
1011     if (ret)
1012         goto out;
1013 
1014     /* Start the remote processor */
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     /* Tell DSP that suspend is happening */
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      * DSP need to save the context at suspend.
1046      * Here waiting the response for DSP, then power can be disabled.
1047      */
1048     if (!wait_for_completion_timeout(&priv->pm_comp, msecs_to_jiffies(100)))
1049         return -EBUSY;
1050 
1051 out:
1052     /*
1053      * The power of DSP is disabled in suspend, so force pm runtime
1054      * to be suspend, then we can reenable the power and clocks at
1055      * resume stage.
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      * The power of DSP is disabled at suspend, the memory of dsp
1074      * is reset, the image segments are lost. So need to reload
1075      * firmware and restart the DSP if it is in running state.
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>");