lkml.org 
[lkml]   [2020]   [Apr]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH v2 1/3] remoteproc: imx_rproc: set pc on start
    On Fri, 17 Apr 2020 11:01:22 -0600
    Mathieu Poirier <mathieu.poirier@linaro.org> wrote:

    > On Thu, 16 Apr 2020 at 23:40, <nikita.shubin@maquefel.me> wrote:
    > >
    > > Hi Mathieue,
    > >
    > > Hi Nikita,
    > >
    > > On Mon, Apr 06, 2020 at 02:33:08PM +0300, nikita.shubin@maquefel.me
    > > wrote:
    > >
    > > In case elf file interrupt vector is not supposed to be at OCRAM_S,
    > > it is needed to write elf entry point to OCRAM_S + 0x4, to boot M4
    > > firmware.
    > >
    > > Otherwise firmware located anywhere besides OCRAM_S won't boot.
    > >
    > > The firmware must set stack poiner as first instruction:
    > >
    > > Reset_Handler:
    > > ldr sp, = __stack /* set stack pointer */
    > >
    > > Signed-off-by: Nikita Shubin <NShubin@topcon.com>
    > >
    > >
    > > The address in the SoB has to match what is found in the "From:"
    > > field of the email header. Checkpatch is complaining about that,
    > > something I would have expected to be fixed before sending this set
    > > out.
    > >
    > > Noted and will be fixed.
    > >
    > > ---
    > > drivers/remoteproc/imx_rproc.c | 16 +++++++++++++++-
    > > 1 file changed, 15 insertions(+), 1 deletion(-)
    > >
    > > diff --git a/drivers/remoteproc/imx_rproc.c
    > > b/drivers/remoteproc/imx_rproc.c index 3e72b6f38d4b..bebc58d0f711
    > > 100644 --- a/drivers/remoteproc/imx_rproc.c
    > > +++ b/drivers/remoteproc/imx_rproc.c
    > > @@ -45,6 +45,8 @@
    > >
    > > #define IMX7D_RPROC_MEM_MAX 8
    > >
    > > +#define IMX_BOOT_PC 0x4
    > > +
    > > /**
    > > * struct imx_rproc_mem - slim internal memory structure
    > > * @cpu_addr: MPU virtual address of the memory region
    > > @@ -85,6 +87,7 @@ struct imx_rproc {
    > > const struct imx_rproc_dcfg *dcfg;
    > > struct imx_rproc_mem mem[IMX7D_RPROC_MEM_MAX];
    > > struct clk *clk;
    > > + void __iomem *bootreg;
    > > };
    > >
    > > static const struct imx_rproc_att imx_rproc_att_imx7d[] = {
    > > @@ -162,11 +165,16 @@ static int imx_rproc_start(struct rproc
    > > *rproc) struct device *dev = priv->dev;
    > > int ret;
    > >
    > > + /* write entry point to program counter */
    > > + writel(rproc->bootaddr, priv->bootreg);
    > >
    > >
    > > What happens on all the other IMX systems where this fix is not
    > > needed? Will they continue to work properly?
    > >
    > > Yes, my bad, it is also needed for IMX6 (but even so i need to
    > > study this topic more carefully), this should be applied
    > > exclusively for imx7d for now, and if will be needed someone with
    > > imx6 hardware to test on can extend this on imx6 also.
    > >
    > >
    > >
    > >
    > > +
    > > ret = regmap_update_bits(priv->regmap, dcfg->src_reg,
    > > dcfg->src_mask, dcfg->src_start);
    > > if (ret)
    > > dev_err(dev, "Failed to enable M4!\n");
    > >
    > > + dev_info(&rproc->dev, "Started from 0x%x\n", rproc->bootaddr);
    > > +
    > > return ret;
    > > }
    > >
    > > @@ -182,6 +190,9 @@ static int imx_rproc_stop(struct rproc *rproc)
    > > if (ret)
    > > dev_err(dev, "Failed to stop M4!\n");
    > >
    > > + /* clear entry points */
    > > + writel(0, priv->bootreg);
    > > +
    > > return ret;
    > > }
    > >
    > > @@ -243,7 +254,8 @@ static void *imx_rproc_da_to_va(struct rproc
    > > *rproc, u64 da, int len) static const struct rproc_ops
    > > imx_rproc_ops = { .start = imx_rproc_start,
    > > .stop = imx_rproc_stop,
    > > - .da_to_va = imx_rproc_da_to_va,
    > > + .da_to_va = imx_rproc_da_to_va,
    > > + .get_boot_addr = rproc_elf_get_boot_addr,
    > >
    > >
    > > How is this useful? Sure it will set rproc->bootaddr in
    > > rproc_fw_boot() but what good does that do when it is invariably
    > > set again in imx_rproc_start() ?
    > >
    > > The priv->bootreg is the address where we are writing Entry Point
    > > and it is fixed, 0x04 address is translated to 0x00180004, so don't
    > > quite understand you we are writing rproc->bootaddr into
    > > priv->bootreg, not wiseversa.
    > >
    >
    > What is your reason to set ops->get_boot_addr ? How does that help
    > the work done in this patch?

    The reason is the following :

    remoteproc_core.c:
    | rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
    | rproc->bootaddr = rproc_get_boot_addr(rproc, fw);

    remoteproc_internal.h
    | static inline
    | u32 rproc_get_boot_addr(struct rproc *rproc, const struct firmware
    *fw) | {
    | if (rproc->ops->get_boot_addr)
    | return rproc->ops->get_boot_addr(rproc, fw);
    |
    | return 0;
    | }

    >
    > >
    > > };
    > >
    > > static int imx_rproc_addr_init(struct imx_rproc *priv,
    > > @@ -360,6 +372,8 @@ static int imx_rproc_probe(struct
    > > platform_device *pdev) goto err_put_rproc;
    > > }
    > >
    > > + priv->bootreg = imx_rproc_da_to_va(rproc, IMX_BOOT_PC,
    > > sizeof(u32)); +
    > > /*
    > > * clk for M4 block including memory. Should be
    > > * enabled before .start for FW transfer.
    > > --
    > > 2.25.1
    > >

    \
     
     \ /
      Last update: 2020-04-17 19:29    [W:3.005 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site