All of lore.kernel.org
 help / color / mirror / Atom feed
From: Miquel Raynal <miquel.raynal@bootlin.com>
To: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Vinod Koul <vkoul@kernel.org>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	dmaengine <dmaengine@vger.kernel.org>,
	Rob Herring <robh+dt@kernel.org>,
	"open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS" 
	<devicetree@vger.kernel.org>,
	Linux-Renesas <linux-renesas-soc@vger.kernel.org>,
	Magnus Damm <magnus.damm@gmail.com>,
	Gareth Williams <gareth.williams.jx@renesas.com>,
	Phil Edworthy <phil.edworthy@renesas.com>,
	Stephen Boyd <sboyd@kernel.org>,
	Michael Turquette <mturquette@baylibre.com>,
	linux-clk <linux-clk@vger.kernel.org>,
	Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
	Milan Stevanovic <milan.stevanovic@se.com>,
	Jimmy Lalande <jimmy.lalande@se.com>,
	Pascal Eberhard <pascal.eberhard@se.com>
Subject: Re: [PATCH v2 4/8] dma: dmamux: Introduce RZN1 DMA router support
Date: Wed, 23 Feb 2022 17:49:02 +0100	[thread overview]
Message-ID: <20220223174902.3a9b85ea@xps13> (raw)
In-Reply-To: <CAMuHMdWd150q63Nr-=7tn34D3EyiBkAKyuXHm35MM6wci93KZw@mail.gmail.com>

Hi Geert,

geert@linux-m68k.org wrote on Wed, 23 Feb 2022 13:46:11 +0100:

> Hi Miquel,
> 
> On Tue, Feb 22, 2022 at 11:35 AM Miquel Raynal
> <miquel.raynal@bootlin.com> wrote:
> > The Renesas RZN1 DMA IP is a based on a DW core, with eg. an additional
> > dmamux register located in the system control area which can take up to
> > 32 requests (16 per DMA controller). Each DMA channel can be wired to
> > two different peripherals.
> >
> > We need two additional information from the 'dmas' property: the channel
> > (bit in the dmamux register) that must be accessed and the value of the
> > mux for this channel.
> >
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>  
> 
> Thanks for your patch!
> 
> > --- /dev/null
> > +++ b/drivers/dma/dw/dmamux.c  
> 
> rzn1-dmamux.c?

Ok.

> 
> > @@ -0,0 +1,167 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (C) 2022 Schneider-Electric
> > + * Author: Miquel Raynal <miquel.raynal@bootlin.com
> > + * Based on TI crossbar driver written by Peter Ujfalusi <peter.ujfalusi@ti.com>
> > + */
> > +#include <linux/slab.h>
> > +#include <linux/err.h>
> > +#include <linux/init.h>
> > +#include <linux/list.h>
> > +#include <linux/io.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_dma.h>
> > +#include <linux/soc/renesas/r9a06g032-sysctrl.h>
> > +
> > +#define RZN1_DMAMUX_LINES      64  
> 
> Unused. But using it wouldn't hurt, I guess?
> 
> > +static void *rzn1_dmamux_route_allocate(struct of_phandle_args *dma_spec,
> > +                                       struct of_dma *ofdma)
> > +{
> > +       struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
> > +       struct rzn1_dmamux_data *dmamux = platform_get_drvdata(pdev);
> > +       struct rzn1_dmamux_map *map;
> > +       unsigned int master, chan, val;
> > +       u32 mask;
> > +       int ret;
> > +
> > +       map = kzalloc(sizeof(*map), GFP_KERNEL);
> > +       if (!map)
> > +               return ERR_PTR(-ENOMEM);
> > +
> > +       if (dma_spec->args_count != 6)
> > +               return ERR_PTR(-EINVAL);
> > +
> > +       chan = dma_spec->args[0];
> > +       map->req_idx = dma_spec->args[4];
> > +       val = dma_spec->args[5];
> > +       dma_spec->args_count -= 2;
> > +
> > +       if (chan >= dmamux->dmac_requests) {
> > +               dev_err(&pdev->dev, "Invalid DMA request line: %d\n", chan);  
> 
> %u
> 
> > +               return ERR_PTR(-EINVAL);
> > +       }
> > +
> > +       if (map->req_idx >= dmamux->dmamux_requests ||
> > +           map->req_idx % dmamux->dmac_requests != chan) {  
> 
> The reliance on .dmac_requests (i.e. "dma-requests" in the parent
> DMA controller DT node) looks fragile to me.  Currently there are two
> masters, each providing 16 channels, hence using all 2 x 16 =
> 32 bits in the DMAMUX register.
> What if a variant used the same mux, and the same 16/16 split, but
> the parent DMACs don't have all channels available?
> I think it would be safer to hardcode this as 16 (using a #define, ofc).

That's right, I assumed this was safe but indeed it does not work in
all cases. I will change the second condition to:

		map->req_idx % <16> != chan

> 
> > +               dev_err(&pdev->dev, "Invalid MUX request line: %d\n", map->req_idx);  
> 
> %u
> 
> > +               return ERR_PTR(-EINVAL);
> > +       }
> > +
> > +       /* The of_node_put() will be done in the core for the node */
> > +       master = map->req_idx >= dmamux->dmac_requests ? 1 : 0;  
> 
> The name "master" confused me: initially I thought it was used as a
> boolean flag, but it really is the index of the parent DMAC.

I personally prefer using true/false for booleans ;) Whatever, the name
is badly chosen I agree, I'll switch to "dmac_idx" which seems more
accurate.

> 
> > +       dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", master);
> > +       if (!dma_spec->np) {
> > +               dev_err(&pdev->dev, "Can't get DMA master\n");
> > +               return ERR_PTR(-EINVAL);
> > +       }
> > +
> > +       dev_dbg(&pdev->dev, "Mapping DMAMUX request %u to DMAC%u request %u\n",
> > +               map->req_idx, master, chan);
> > +
> > +       mask = BIT(map->req_idx);
> > +       mutex_lock(&dmamux->lock);
> > +       dmamux->used_chans |= mask;
> > +       ret = r9a06g032_sysctrl_set_dmamux(mask, val ? mask : 0);
> > +       mutex_unlock(&dmamux->lock);
> > +       if (ret) {
> > +               rzn1_dmamux_free(&pdev->dev, map);
> > +               return ERR_PTR(ret);
> > +       }
> > +
> > +       return map;
> > +}
> > +
> > +static const struct of_device_id rzn1_dmac_match[] __maybe_unused = {
> > +       { .compatible = "renesas,rzn1-dma" },
> > +       {},
> > +};
> > +
> > +static int rzn1_dmamux_probe(struct platform_device *pdev)
> > +{
> > +       struct device_node *mux_node = pdev->dev.of_node;
> > +       const struct of_device_id *match;
> > +       struct device_node *dmac_node;
> > +       struct rzn1_dmamux_data *dmamux;
> > +
> > +       dmamux = devm_kzalloc(&pdev->dev, sizeof(*dmamux), GFP_KERNEL);
> > +       if (!dmamux)
> > +               return -ENOMEM;
> > +
> > +       mutex_init(&dmamux->lock);
> > +
> > +       dmac_node = of_parse_phandle(mux_node, "dma-masters", 0);
> > +       if (!dmac_node)
> > +               return dev_err_probe(&pdev->dev, -ENODEV, "Can't get DMA master node\n");
> > +
> > +       match = of_match_node(rzn1_dmac_match, dmac_node);
> > +       if (!match) {
> > +               of_node_put(dmac_node);
> > +               return dev_err_probe(&pdev->dev, -EINVAL, "DMA master is not supported\n");
> > +       }
> > +
> > +       if (of_property_read_u32(dmac_node, "dma-requests", &dmamux->dmac_requests)) {
> > +               of_node_put(dmac_node);
> > +               return dev_err_probe(&pdev->dev, -EINVAL, "Missing DMAC requests information\n");
> > +       }
> > +
> > +       of_node_put(dmac_node);  
> 
> When hardcoding dmac_requests to 16, I guess the whole dmac_node
> handling can be removed?

Not really, I think the following checks are still valid and fortunate,
and they need some of_ handling to work properly:
- verify that the chan requested is within the range of dmac_requests
  in the _route_allocate() callback
- ensure the dmamux is wired to a supported DMAC in the DT (this
  condition might be loosen in the future if needed or dropped entirely
  if considered useless)
- I would like to add a check against the number of requests supported
  by the dmamux and the dmac (not done yet).
For the record, I've taken inspiration to write these lines on the other
dma router driver from TI.

Unless, and I know some people think like that, we do not try to
validate the DT and if the DT is wrong that is none of our business.

> 
> > +
> > +       if (of_property_read_u32(mux_node, "dma-requests", &dmamux->dmamux_requests)) {  
> 
> Don't obtain from DT, but fix to 32?

I believe the answer to the previous question should give me a clue
about why you would prefer hardcoding than reading from the DT such
an information. Perhaps I should mention that all these properties are
already part of the bindings, and are not specific to the driver, the
information will be in the DT anyway.

Thanks,
Miquèl

  reply	other threads:[~2022-02-23 16:49 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-22 10:34 [PATCH v2 0/8] RZN1 DMA support Miquel Raynal
2022-02-22 10:34 ` [PATCH v2 1/8] dt-bindings: dma: Introduce RZN1 dmamux bindings Miquel Raynal
2022-02-23 11:27   ` Geert Uytterhoeven
2022-02-22 10:34 ` [PATCH v2 2/8] dt-bindings: dma: Introduce RZN1 DMA compatible Miquel Raynal
2022-02-23 12:21   ` Geert Uytterhoeven
2022-02-23 15:49     ` Miquel Raynal
2022-02-23 16:16       ` Geert Uytterhoeven
2022-02-23 17:10         ` Miquel Raynal
2022-02-22 10:34 ` [PATCH v2 3/8] soc: renesas: rzn1-sysc: Export function to set dmamux Miquel Raynal
2022-02-23 12:28   ` Geert Uytterhoeven
2022-02-23 15:54     ` Miquel Raynal
2022-02-22 10:34 ` [PATCH v2 4/8] dma: dmamux: Introduce RZN1 DMA router support Miquel Raynal
2022-02-22 20:27   ` kernel test robot
2022-02-23  8:26     ` Miquel Raynal
2022-02-23  8:26       ` Miquel Raynal
2022-02-23 10:31   ` Miquel Raynal
2022-02-23 12:46   ` Geert Uytterhoeven
2022-02-23 16:49     ` Miquel Raynal [this message]
2022-02-24  9:14       ` Geert Uytterhoeven
2022-02-24  9:27         ` Miquel Raynal
2022-02-24  9:52           ` Geert Uytterhoeven
2022-02-24 11:36             ` Miquel Raynal
2022-02-24 12:16               ` Geert Uytterhoeven
2022-02-24 15:56                 ` Miquel Raynal
2022-02-22 10:34 ` [PATCH v2 5/8] dma: dw: Avoid partial transfers Miquel Raynal
2022-02-23 13:35   ` Andy Shevchenko
2022-02-24 16:30     ` Miquel Raynal
2022-02-25 20:30       ` Andy Shevchenko
2022-02-22 10:34 ` [PATCH v2 6/8] dma: dw: Add RZN1 compatible Miquel Raynal
2022-02-23 12:50   ` Geert Uytterhoeven
2022-02-22 10:34 ` [PATCH v2 7/8] ARM: dts: r9a06g032: Add the two DMA nodes Miquel Raynal
2022-02-23 12:54   ` Geert Uytterhoeven
2022-02-23 17:14     ` Miquel Raynal
2022-02-24  9:17       ` Geert Uytterhoeven
2022-02-22 10:34 ` [PATCH v2 8/8] ARM: dts: r9a06g032: Describe the DMA router Miquel Raynal

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=20220223174902.3a9b85ea@xps13 \
    --to=miquel.raynal@bootlin.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dmaengine@vger.kernel.org \
    --cc=gareth.williams.jx@renesas.com \
    --cc=geert@linux-m68k.org \
    --cc=jimmy.lalande@se.com \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=magnus.damm@gmail.com \
    --cc=milan.stevanovic@se.com \
    --cc=mturquette@baylibre.com \
    --cc=pascal.eberhard@se.com \
    --cc=phil.edworthy@renesas.com \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@kernel.org \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=vkoul@kernel.org \
    /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.