From: Mathieu Poirier <mathieu.poirier@linaro.org>
To: Tanmay Shah <tanmay.shah@amd.com>
Cc: andersson@kernel.org, linux-remoteproc@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2] remoteproc: xlnx: add sram support
Date: Mon, 22 Jul 2024 10:39:19 -0600 [thread overview]
Message-ID: <Zp6LNyyuzskj+UBH@p14s> (raw)
In-Reply-To: <20240716013953.1715134-1-tanmay.shah@amd.com>
Good morning,
On Mon, Jul 15, 2024 at 06:39:54PM -0700, Tanmay Shah wrote:
> AMD-Xilinx zynqmp platform contains on-chip sram memory (OCM).
> R5 cores can access OCM and access is faster than DDR memory but slower
> than TCM memories available. Sram region can have optional multiple
> power-domains. Platform management firmware is responsible
> to operate these power-domains.
>
> Signed-off-by: Tanmay Shah <tanmay.shah@amd.com>
> ---
>
> Changes in v2:
> - Expand commit message with power-domains related information.
>
> drivers/remoteproc/xlnx_r5_remoteproc.c | 131 ++++++++++++++++++++++++
> 1 file changed, 131 insertions(+)
>
> diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
> index 596f3ffb8935..52ddd42b09e0 100644
> --- a/drivers/remoteproc/xlnx_r5_remoteproc.c
> +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
> @@ -56,6 +56,17 @@ struct mem_bank_data {
> char *bank_name;
> };
>
> +/**
> + * struct zynqmp_sram_bank - sram bank description
> + *
> + * @sram_res: sram address region information
> + * @da: device address of sram
> + */
> +struct zynqmp_sram_bank {
> + struct resource sram_res;
> + u32 da;
> +};
> +
> /**
> * struct mbox_info
> *
> @@ -120,6 +131,8 @@ static const struct mem_bank_data zynqmp_tcm_banks_lockstep[] = {
> * struct zynqmp_r5_core
> *
> * @rsc_tbl_va: resource table virtual address
> + * @sram: Array of sram memories assigned to this core
> + * @num_sram: number of sram for this core
> * @dev: device of RPU instance
> * @np: device node of RPU instance
> * @tcm_bank_count: number TCM banks accessible to this RPU
> @@ -131,6 +144,8 @@ static const struct mem_bank_data zynqmp_tcm_banks_lockstep[] = {
> */
> struct zynqmp_r5_core {
> void __iomem *rsc_tbl_va;
> + struct zynqmp_sram_bank **sram;
I suggest making @sram an array rather than an array of pointers - it would
simplify function zynqmp_r5_get_sram_banks().
> + int num_sram;
> struct device *dev;
> struct device_node *np;
> int tcm_bank_count;
> @@ -494,6 +509,40 @@ static int add_mem_regions_carveout(struct rproc *rproc)
> return 0;
> }
>
> +static int add_sram_carveouts(struct rproc *rproc)
> +{
> + struct zynqmp_r5_core *r5_core = rproc->priv;
> + struct rproc_mem_entry *rproc_mem;
> + struct zynqmp_sram_bank *sram;
> + dma_addr_t dma_addr;
> + size_t len;
> + int da, i;
> +
> + for (i = 0; i < r5_core->num_sram; i++) {
> + sram = r5_core->sram[i];
> +
> + dma_addr = (dma_addr_t)sram->sram_res.start;
> + len = resource_size(&sram->sram_res);
> + da = sram->da;
> +
> + /* Register associated reserved memory regions */
> + rproc_mem = rproc_mem_entry_init(&rproc->dev, NULL,
> + (dma_addr_t)dma_addr,
> + len, da,
> + zynqmp_r5_mem_region_map,
> + zynqmp_r5_mem_region_unmap,
> + sram->sram_res.name);
> +
> + rproc_add_carveout(rproc, rproc_mem);
> + rproc_coredump_add_segment(rproc, da, len);
> +
> + dev_dbg(&rproc->dev, "sram carveout %s addr=%llx, da=0x%x, size=0x%lx",
> + sram->sram_res.name, dma_addr, da, len);
> + }
> +
> + return 0;
> +}
> +
> /*
> * tcm_mem_unmap()
> * @rproc: single R5 core's corresponding rproc instance
> @@ -669,6 +718,12 @@ static int zynqmp_r5_rproc_prepare(struct rproc *rproc)
> return ret;
> }
>
> + ret = add_sram_carveouts(rproc);
> + if (ret) {
> + dev_err(&rproc->dev, "failed to get sram carveout %d\n", ret);
> + return ret;
> + }
> +
> return 0;
> }
>
> @@ -881,6 +936,78 @@ static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev)
> return ERR_PTR(ret);
> }
>
> +static int zynqmp_r5_get_sram_banks(struct zynqmp_r5_core *r5_core)
> +{
> + struct zynqmp_sram_bank **sram, *sram_data;
> + struct device_node *np = r5_core->np;
> + struct device *dev = r5_core->dev;
> + struct device_node *sram_np;
> + int num_sram, i, ret;
> + u64 abs_addr, size;
> +
> + /* "sram" is optional proprty. Do not fail, if unavailable. */
s/proprty/property
> + if (!of_find_property(r5_core->np, "sram", NULL))
> + return 0;
> +
> + num_sram = of_property_count_elems_of_size(np, "sram", sizeof(phandle));
> + if (num_sram <= 0) {
Any reason this is "<" rather than "<=" ?
> + dev_err(dev, "Invalid sram property, ret = %d\n",
> + num_sram);
> + return -EINVAL;
> + }
> +
> + sram = devm_kcalloc(dev, num_sram,
> + sizeof(struct zynqmp_sram_bank *), GFP_KERNEL);
> + if (!sram)
> + return -ENOMEM;
> +
> + for (i = 0; i < num_sram; i++) {
> + sram_data = devm_kzalloc(dev, sizeof(struct zynqmp_sram_bank),
> + GFP_KERNEL);
> + if (!sram_data)
> + return -ENOMEM;
> +
> + sram_np = of_parse_phandle(np, "sram", i);
> + if (!sram_np) {
> + dev_err(dev, "failed to get sram %d phandle\n", i);
> + return -EINVAL;
> + }
> +
> + if (!of_device_is_available(sram_np)) {
> + of_node_put(sram_np);
> + dev_err(dev, "sram device not available\n");
> + return -EINVAL;
> + }
> +
> + ret = of_address_to_resource(sram_np, 0, &sram_data->sram_res);
> + of_node_put(sram_np);
Why calling this here when sram_np is used below?
> + if (ret) {
> + dev_err(dev, "addr to res failed\n");
> + return ret;
> + }
> +
> + /* Get SRAM device address */
> + ret = of_property_read_reg(sram_np, i, &abs_addr, &size);
> + if (ret) {
> + dev_err(dev, "failed to get reg property\n");
> + return ret;
> + }
> +
> + sram_data->da = (u32)abs_addr;
> +
> + sram[i] = sram_data;
> +
> + dev_dbg(dev, "sram %d: name=%s, addr=0x%llx, da=0x%x, size=0x%llx\n",
> + i, sram[i]->sram_res.name, sram[i]->sram_res.start,
> + sram[i]->da, resource_size(&sram[i]->sram_res));
> + }
> +
> + r5_core->sram = sram;
> + r5_core->num_sram = num_sram;
> +
> + return 0;
> +}
> +
> static int zynqmp_r5_get_tcm_node_from_dt(struct zynqmp_r5_cluster *cluster)
> {
> int i, j, tcm_bank_count, ret, tcm_pd_idx, pd_count;
> @@ -1095,6 +1222,10 @@ static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster,
> return ret;
> }
> }
> +
> + ret = zynqmp_r5_get_sram_banks(r5_core);
> + if (ret)
> + return ret;
> }
Thanks,
Mathieu
>
> return 0;
>
> base-commit: d87dbfd31796f810ed777aee4919f211b4a6c7fb
> --
> 2.25.1
>
next prev parent reply other threads:[~2024-07-22 16:39 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-16 1:39 [PATCH v2] remoteproc: xlnx: add sram support Tanmay Shah
2024-07-22 16:39 ` Mathieu Poirier [this message]
2024-07-24 22:04 ` Tanmay Shah
2024-07-25 14:42 ` Mathieu Poirier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Zp6LNyyuzskj+UBH@p14s \
--to=mathieu.poirier@linaro.org \
--cc=andersson@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-remoteproc@vger.kernel.org \
--cc=tanmay.shah@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.