[RESEND PATCH v2] remoteproc/mediatek: read IPI buffer offset from FW

Mathieu Poirier mathieu.poirier at linaro.org
Fri Nov 27 11:11:19 EST 2020


On Fri, 27 Nov 2020 at 02:30, Tzung-Bi Shih <tzungbi at google.com> wrote:
>
> Reads the IPI buffer offset from the FW binary.  The information resides
> in addr of .ipi_buffer section.
>
> Moves scp_ipi_init() to scp_load() phase.  The IPI buffer can be
> initialized only if the offset is clear.
>
> Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
> ---
> The patch bases on https://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc.git/log/?h=for-next
>
> The first 2 patches in the series
> https://patchwork.kernel.org/project/linux-remoteproc/cover/20201116084413.3312631-1-tzungbi@google.com/
> have been merged to remoteproc for-next branch.
>
> Follow up the discussion in
> https://patchwork.kernel.org/project/linux-remoteproc/patch/20201116084413.3312631-4-tzungbi@google.com/#23784483
>
> The patch breaks MTK SCP when working with legacy SCP firmware.  We're
> aware of it and will upgrade the devices' kernel and SCP firmware
> carefully.  Other than that, AFAICT, no other devices in the wild are
> using this driver.
>
>  drivers/remoteproc/mtk_scp.c | 73 ++++++++++++++++++++++++------------
>  1 file changed, 49 insertions(+), 24 deletions(-)

This is the exact same patch that you sent here [1], that I commented
on, and that you agreed with my assessment.

What do you want me to do here?  What am I missing?

[1]. https://patchwork.kernel.org/project/linux-remoteproc/patch/20201116084413.3312631-4-tzungbi@google.com/

>
> diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
> index 7e0f1e1a335b..4467ed646bb1 100644
> --- a/drivers/remoteproc/mtk_scp.c
> +++ b/drivers/remoteproc/mtk_scp.c
> @@ -21,7 +21,7 @@
>  #include "remoteproc_internal.h"
>
>  #define MAX_CODE_SIZE 0x500000
> -#define SCP_FW_END 0x7C000
> +#define SECTION_NAME_IPI_BUFFER ".ipi_buffer"
>
>  /**
>   * scp_get() - get a reference to SCP.
> @@ -119,16 +119,24 @@ static void scp_ipi_handler(struct mtk_scp *scp)
>         wake_up(&scp->ack_wq);
>  }
>
> -static int scp_ipi_init(struct mtk_scp *scp)
> +static int scp_elf_read_ipi_buf_addr(struct mtk_scp *scp,
> +                                    const struct firmware *fw,
> +                                    size_t *offset);
> +
> +static int scp_ipi_init(struct mtk_scp *scp, const struct firmware *fw)
>  {
> -       size_t send_offset = SCP_FW_END - sizeof(struct mtk_share_obj);
> -       size_t recv_offset = send_offset - sizeof(struct mtk_share_obj);
> +       int ret;
> +       size_t offset;
> +
> +       ret = scp_elf_read_ipi_buf_addr(scp, fw, &offset);
> +       if (ret)
> +               return ret;
> +       dev_info(scp->dev, "IPI buf addr %#010zx\n", offset);
>
> -       /* shared buffer initialization */
> -       scp->recv_buf =
> -               (struct mtk_share_obj __iomem *)(scp->sram_base + recv_offset);
> -       scp->send_buf =
> -               (struct mtk_share_obj __iomem *)(scp->sram_base + send_offset);
> +       scp->recv_buf = (struct mtk_share_obj __iomem *)
> +                       (scp->sram_base + offset);
> +       scp->send_buf = (struct mtk_share_obj __iomem *)
> +                       (scp->sram_base + offset + sizeof(*scp->recv_buf));
>         memset_io(scp->recv_buf, 0, sizeof(*scp->recv_buf));
>         memset_io(scp->send_buf, 0, sizeof(*scp->send_buf));
>
> @@ -271,6 +279,32 @@ static int scp_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
>         return ret;
>  }
>
> +static int scp_elf_read_ipi_buf_addr(struct mtk_scp *scp,
> +                                    const struct firmware *fw,
> +                                    size_t *offset)
> +{
> +       struct elf32_hdr *ehdr;
> +       struct elf32_shdr *shdr, *shdr_strtab;
> +       int i;
> +       const u8 *elf_data = fw->data;
> +       const char *strtab;
> +
> +       ehdr = (struct elf32_hdr *)elf_data;
> +       shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff);
> +       shdr_strtab = shdr + ehdr->e_shstrndx;
> +       strtab = (const char *)(elf_data + shdr_strtab->sh_offset);
> +
> +       for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
> +               if (strcmp(strtab + shdr->sh_name,
> +                          SECTION_NAME_IPI_BUFFER) == 0) {
> +                       *offset = shdr->sh_addr;
> +                       return 0;
> +               }
> +       }
> +
> +       return -ENOENT;
> +}
> +
>  static int mt8183_scp_before_load(struct mtk_scp *scp)
>  {
>         /* Clear SCP to host interrupt */
> @@ -350,11 +384,15 @@ static int scp_load(struct rproc *rproc, const struct firmware *fw)
>
>         ret = scp->data->scp_before_load(scp);
>         if (ret < 0)
> -               return ret;
> +               goto leave;
>
>         ret = scp_elf_load_segments(rproc, fw);
> -       clk_disable_unprepare(scp->clk);
> +       if (ret)
> +               goto leave;
>
> +       ret = scp_ipi_init(scp, fw);
> +leave:
> +       clk_disable_unprepare(scp->clk);
>         return ret;
>  }
>
> @@ -680,19 +718,6 @@ static int scp_probe(struct platform_device *pdev)
>                 goto release_dev_mem;
>         }
>
> -       ret = clk_prepare_enable(scp->clk);
> -       if (ret) {
> -               dev_err(dev, "failed to enable clocks\n");
> -               goto release_dev_mem;
> -       }
> -
> -       ret = scp_ipi_init(scp);
> -       clk_disable_unprepare(scp->clk);
> -       if (ret) {
> -               dev_err(dev, "Failed to init ipi\n");
> -               goto release_dev_mem;
> -       }
> -
>         /* register SCP initialization IPI */
>         ret = scp_ipi_register(scp, SCP_IPI_INIT, scp_init_ipi_handler, scp);
>         if (ret) {
> --
> 2.29.2.454.gaff20da3a2-goog
>



More information about the Linux-mediatek mailing list