[PATCH v2 2/2] remoteproc: imx_dsp_rproc: add remoteproc driver for dsp on i.MX

Shengjiu Wang shengjiu.wang at gmail.com
Wed Sep 1 18:46:04 PDT 2021


On Wed, Sep 1, 2021 at 11:50 PM Mathieu Poirier
<mathieu.poirier at linaro.org> wrote:
>
> [...]
>
> >
> > >
> > > > +
> > > > +/* address translation table */
> > > > +struct imx_dsp_rproc_att {
> > > > +     u32 da; /* device address (From Cortex M4 view)*/
> > > > +     u32 sa; /* system bus address */
> > > > +     u32 size; /* size of reg range */
> > > > +     int flags;
> > > > +};
> > >
> > > This is already defined in imx_rproc.c - why do we need another definition here?
> >
> > I just want to avoid to modify imx_rproc.c driver.
> > So with this comments, should I add imx_rproc.h for extracting the common
> > structure in it?
> >
>
> Yes, that is probably the best way to proceed.

Ok, I will do it in the next version.

>
> > >
> > > > +
> > > > +/* Remote core start/stop method */
> > > > +enum imx_dsp_rproc_method {
> > > > +     /* Through syscon regmap */
> > > > +     IMX_DSP_MMIO,
> > > > +     IMX_DSP_SCU_API,
> > > > +};
> > >
> > > From where I stand it would be worth merging the above with imx_rproc_method
> > > found in imx_rproc.c.  I don't see a need for duplication.
> >
> > Should I add imx_rproc.h for extracting the common structure in it?
> >
>
> See my comment above.
>
> > >
> > > > +
> > > > +struct imx_dsp_rproc {
> > > > +     struct device                   *dev;
> > > > +     struct regmap                   *regmap;
> > > > +     struct rproc                    *rproc;
> > > > +     const struct imx_dsp_rproc_dcfg *dcfg;
> > > > +     struct clk                      *clks[DSP_RPROC_CLK_MAX];
> > > > +     struct mbox_client              cl;
> > > > +     struct mbox_client              cl_rxdb;
> > > > +     struct mbox_chan                *tx_ch;
> > > > +     struct mbox_chan                *rx_ch;
> > > > +     struct mbox_chan                *rxdb_ch;
> > > > +     struct device                   **pd_dev;
> > > > +     struct device_link              **pd_dev_link;
> > > > +     struct imx_sc_ipc               *ipc_handle;
> > > > +     struct work_struct              rproc_work;
> > > > +     struct workqueue_struct         *workqueue;
> > > > +     struct completion               pm_comp;
> > > > +     spinlock_t                      mbox_lock;    /* lock for mbox */
> > > > +     int                             num_domains;
> > > > +     u32                             flags;
> > > > +};
> > > > +
> > > > +struct imx_dsp_rproc_dcfg {
> > > > +     u32                             src_reg;
> > > > +     u32                             src_mask;
> > > > +     u32                             src_start;
> > > > +     u32                             src_stop;
> > > > +     const struct imx_dsp_rproc_att  *att;
> > > > +     size_t                          att_size;
> > > > +     enum imx_dsp_rproc_method       method;
> > >
> > > The above is similar to imx_rproc_cfg.  As such:
> > >
> > > struct imx_dsp_rproc_dcfg {
> > >         struct imx_rproc_cfg            *dcfg;
> > >         int (*reset)(struct imx_dsp_rproc *priv);
> > > };
> > >
> >
> > Yes, seems need to add imx_rproc.h header file.
> >
>
> [...]
>
> > > > +
> > > > +/* pm runtime */
> > > > +static int imx_dsp_runtime_resume(struct device *dev)
> > > > +{
> > > > +     struct rproc *rproc = dev_get_drvdata(dev);
> > > > +     struct imx_dsp_rproc *priv = rproc->priv;
> > > > +     const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
> > > > +     int ret;
> > > > +
> > > > +     ret = imx_dsp_rproc_mbox_init(priv);
> > >
> > > Why is the mailbox setup and destroyed with every PM cycle?  I find an overall
> > > lack of comments makes this driver difficult to review, resulting in having to
> > > spend more time to look at and understand the code.  I will have to continue
> > > tomorrow because, well, I ran out of time.
> > >
> > > Mathieu
> > >
> >
> > There is power domain attached with mailbox, if request the mailbox
> > channel, the power is enabled. so if setup mailbox in probe(), then
> > the power is enabled always which is no benefit for saving power.
> > so setup mailbox in pm_runtime_resume().
>
> This is the kind of very useful information that should be in comments.

All right,  I will add it in the next version.

>
> >
> > Sorry for lack of comments, I will add more in next version.
>
> That will be much appreciated.
>
> >
> > Again, Thanks your time for reviewing this patch.
>
> More comments to come in a minute...
>
> >
> > Best regards
> > Wang shengjiu
> >
> > > > +     if (ret) {
> > > > +             dev_err(dev, "failed on imx_dsp_rproc_mbox_init\n");
> > > > +             return ret;
> > > > +     }
> > > > +
> > > > +     ret = imx_dsp_rproc_clk_enable(priv);
> > > > +     if (ret) {
> > > > +             dev_err(dev, "failed on imx_dsp_rproc_clk_enable\n");
> > > > +             return ret;
> > > > +     }
> > > > +
> > > > +     /* reset DSP if needed */
> > > > +     if (dcfg->reset)
> > > > +             dcfg->reset(priv);
> > > > +
> > > > +     return 0;
> > > > +}
> > > > +
> > > > +static int imx_dsp_runtime_suspend(struct device *dev)
> > > > +{
> > > > +     struct rproc *rproc = dev_get_drvdata(dev);
> > > > +     struct imx_dsp_rproc *priv = rproc->priv;
> > > > +
> > > > +     imx_dsp_rproc_clk_disable(priv);
> > > > +
> > > > +     imx_dsp_rproc_free_mbox(priv);
> > > > +
> > > > +     return 0;
> > > > +}
> > > > +
> > > > +static void imx_dsp_load_firmware(const struct firmware *fw, void *context)
> > > > +{
> > > > +     struct rproc *rproc = context;
> > > > +     int ret;
> > > > +
> > > > +     /* load the ELF segments to memory */
> > > > +     ret = rproc_load_segments(rproc, fw);
> > > > +     if (ret)
> > > > +             goto out;
> > > > +
> > > > +     /* power up the remote processor */
> > > > +     ret = rproc->ops->start(rproc);
> > > > +     if (ret)
> > > > +             goto out;
> > > > +
> > > > +     /* same flow as first start */
> > > > +     rproc->ops->kick(rproc, 0);
> > > > +
> > > > +out:
> > > > +     release_firmware(fw);
> > > > +}
> > > > +
> > > > +static int imx_dsp_suspend(struct device *dev)
> > > > +{
> > > > +     struct rproc *rproc = dev_get_drvdata(dev);
> > > > +     struct imx_dsp_rproc *priv = rproc->priv;
> > > > +     __u32 mmsg = RP_MBOX_SUSPEND_SYSTEM;
> > > > +     int ret;
> > > > +
> > > > +     if (rproc->state == RPROC_RUNNING) {
> > > > +             reinit_completion(&priv->pm_comp);
> > > > +
> > > > +             ret = mbox_send_message(priv->tx_ch, (void *)&mmsg);
> > > > +             if (ret < 0) {
> > > > +                     dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
> > > > +                     return ret;
> > > > +             }
> > > > +
> > > > +             if (!wait_for_completion_timeout(&priv->pm_comp, msecs_to_jiffies(100)))
> > > > +                     return -EBUSY;
> > > > +     }
> > > > +
> > > > +     return pm_runtime_force_suspend(dev);
> > > > +}
> > > > +
> > > > +static int imx_dsp_resume(struct device *dev)
> > > > +{
> > > > +     struct rproc *rproc = dev_get_drvdata(dev);
> > > > +     int ret = 0;
> > > > +
> > > > +     ret = pm_runtime_force_resume(dev);
> > > > +     if (ret)
> > > > +             return ret;
> > > > +
> > > > +     if (rproc->state == RPROC_RUNNING) {
> > > > +             /*TODO: load firmware and start */
> > > > +             ret = request_firmware_nowait(THIS_MODULE,
> > > > +                                           FW_ACTION_UEVENT,
> > > > +                                           rproc->firmware,
> > > > +                                           dev,
> > > > +                                           GFP_KERNEL,
> > > > +                                           rproc,
> > > > +                                           imx_dsp_load_firmware);
> > > > +             if (ret < 0) {
> > > > +                     dev_err(dev, "load firmware failed: %d\n", ret);
> > > > +                     goto err;
> > > > +             }
> > > > +     }
> > > > +
> > > > +     return 0;
> > > > +
> > > > +err:
> > > > +     pm_runtime_force_suspend(dev);
> > > > +
> > > > +     return ret;
> > > > +}
> > > > +
> > > > +static const struct dev_pm_ops imx_dsp_rproc_pm_ops = {
> > > > +     SET_SYSTEM_SLEEP_PM_OPS(imx_dsp_suspend, imx_dsp_resume)
> > > > +     SET_RUNTIME_PM_OPS(imx_dsp_runtime_suspend,
> > > > +                        imx_dsp_runtime_resume, NULL)
> > > > +};
> > > > +
> > > > +static const struct of_device_id imx_dsp_rproc_of_match[] = {
> > > > +     { .compatible = "fsl,imx8qxp-hifi4", .data = &imx_dsp_rproc_cfg_imx8qxp },
> > > > +     { .compatible = "fsl,imx8qm-hifi4",  .data = &imx_dsp_rproc_cfg_imx8qm },
> > > > +     { .compatible = "fsl,imx8mp-hifi4",  .data = &imx_dsp_rproc_cfg_imx8mp },
> > > > +     { .compatible = "fsl,imx8ulp-hifi4", .data = &imx_dsp_rproc_cfg_imx8ulp },
> > > > +     {},
> > > > +};
> > > > +MODULE_DEVICE_TABLE(of, imx_dsp_rproc_of_match);
> > > > +
> > > > +static struct platform_driver imx_dsp_rproc_driver = {
> > > > +     .probe = imx_dsp_rproc_probe,
> > > > +     .remove = imx_dsp_rproc_remove,
> > > > +     .driver = {
> > > > +             .name = "imx-dsp-rproc",
> > > > +             .of_match_table = imx_dsp_rproc_of_match,
> > > > +             .pm = &imx_dsp_rproc_pm_ops,
> > > > +     },
> > > > +};
> > > > +module_platform_driver(imx_dsp_rproc_driver);
> > > > +
> > > > +MODULE_LICENSE("GPL v2");
> > > > +MODULE_DESCRIPTION("i.MX HiFi Core Remote Processor Control Driver");
> > > > +MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang at nxp.com>");
> > > > --
> > > > 2.17.1
> > > >



More information about the linux-arm-kernel mailing list