From: Vinod Koul <vkoul@kernel.org>
To: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com>
Cc: Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
"J.M.B. Downing" <jonathan.downing@nautel.com>,
Vladimir Zapolskiy <vz@mleia.com>,
Liam Girdwood <lgirdwood@gmail.com>,
Mark Brown <broonie@kernel.org>,
Russell King <linux@armlinux.org.uk>,
Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@kernel.org>,
Andi Shyti <andi.shyti@kernel.org>,
Miquel Raynal <miquel.raynal@bootlin.com>,
Richard Weinberger <richard@nod.at>,
Vignesh Raghavendra <vigneshr@ti.com>,
Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
Yangtao Li <frank.li@vivo.com>, Arnd Bergmann <arnd@arndb.de>,
Li Zetao <lizetao1@huawei.com>, Chancel Liu <chancel.liu@nxp.com>,
Michael Ellerman <mpe@ellerman.id.au>,
dmaengine@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
alsa-devel@alsa-project.org, linuxppc-dev@lists.ozlabs.org,
linux-sound@vger.kernel.org, linux-clk@vger.kernel.org,
linux-i2c@vger.kernel.org, linux-mtd@lists.infradead.org,
Markus Elfring <Markus.Elfring@web.de>
Subject: Re: [Patch v4 06/10] dmaengine: Add dma router for pl08x in LPC32XX SoC
Date: Mon, 24 Jun 2024 11:08:59 +0530 [thread overview]
Message-ID: <ZnkGcwd8M1QFfmxl@matsya> (raw)
In-Reply-To: <20240620175657.358273-7-piotr.wojtaszczyk@timesys.com>
Hi Piotr,
Any reason why dmaengine parts cant be sent separately, why are they
clubbed together, I dont see any obvious dependencies...
On 20-06-24, 19:56, Piotr Wojtaszczyk wrote:
> LPC32XX connects few of its peripherals to pl08x DMA thru a multiplexer,
> this driver allows to route a signal request line thru the multiplexer for
> given peripheral.
What is the difference b/w this and lpc18xx driver, why not reuse that
one?
>
> Signed-off-by: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com>
> ---
> Changes for v4:
> - This patch is new in v4
>
> MAINTAINERS | 1 +
> drivers/dma/Kconfig | 9 ++
> drivers/dma/Makefile | 1 +
> drivers/dma/lpc32xx-dmamux.c | 195 +++++++++++++++++++++++++++++++++++
> 4 files changed, 206 insertions(+)
> create mode 100644 drivers/dma/lpc32xx-dmamux.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fadf1baafd89..5ffe988ee282 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2403,6 +2403,7 @@ R: Vladimir Zapolskiy <vz@mleia.com>
> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
> S: Maintained
> F: Documentation/devicetree/bindings/dma/nxp,lpc3220-dmamux.yaml
> +F: drivers/dma/lpc32xx-dmamux.c
> N: lpc32xx
>
> ARM/Marvell Dove/MV78xx0/Orion SOC support
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 002a5ec80620..aeace3d7e066 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -378,6 +378,15 @@ config LPC18XX_DMAMUX
> Enable support for DMA on NXP LPC18xx/43xx platforms
> with PL080 and multiplexed DMA request lines.
>
> +config LPC32XX_DMAMUX
> + bool "NXP LPC32xx DMA MUX for PL080"
> + depends on ARCH_LPC32XX || COMPILE_TEST
> + depends on OF && AMBA_PL08X
> + select MFD_SYSCON
> + help
> + Support for PL080 multiplexed DMA request lines on
> + LPC32XX platrofm.
> +
> config LS2X_APB_DMA
> tristate "Loongson LS2X APB DMA support"
> depends on LOONGARCH || COMPILE_TEST
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index 802ca916f05f..6f1350b62e7f 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -50,6 +50,7 @@ obj-$(CONFIG_INTEL_IOATDMA) += ioat/
> obj-y += idxd/
> obj-$(CONFIG_K3_DMA) += k3dma.o
> obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
> +obj-$(CONFIG_LPC32XX_DMAMUX) += lpc32xx-dmamux.o
> obj-$(CONFIG_LS2X_APB_DMA) += ls2x-apb-dma.o
> obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
> obj-$(CONFIG_MILBEAUT_XDMAC) += milbeaut-xdmac.o
> diff --git a/drivers/dma/lpc32xx-dmamux.c b/drivers/dma/lpc32xx-dmamux.c
> new file mode 100644
> index 000000000000..4e6ce6026164
> --- /dev/null
> +++ b/drivers/dma/lpc32xx-dmamux.c
> @@ -0,0 +1,195 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +//
> +// Copyright 2024 Timesys Corporation <piotr.wojtaszczyk@timesys.com>
> +//
> +// Based on TI DMA Crossbar driver by:
> +// Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
> +// Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
> +
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/of_dma.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/spinlock.h>
> +
> +#define LPC32XX_SSP_CLK_CTRL 0x78
> +#define LPC32XX_I2S_CLK_CTRL 0x7c
> +
> +struct lpc32xx_dmamux {
> + int signal;
> + char *name_sel0;
> + char *name_sel1;
> + int muxval;
> + int muxreg;
> + int bit;
> + bool busy;
> +};
> +
> +/* From LPC32x0 User manual "3.2.1 DMA request signals" */
> +static struct lpc32xx_dmamux lpc32xx_muxes[] = {
> + {
> + .signal = 3,
> + .name_sel0 = "spi2-rx-tx",
> + .name_sel1 = "ssp1-rx",
> + .muxreg = LPC32XX_SSP_CLK_CTRL,
> + .bit = 5,
> + },
> + {
> + .signal = 10,
> + .name_sel0 = "uart7-rx",
> + .name_sel1 = "i2s1-dma1",
> + .muxreg = LPC32XX_I2S_CLK_CTRL,
> + .bit = 4,
> + },
> + {
> + .signal = 11,
> + .name_sel0 = "spi1-rx-tx",
> + .name_sel1 = "ssp1-tx",
> + .muxreg = LPC32XX_SSP_CLK_CTRL,
> + .bit = 4,
> + },
> + {
> + .signal = 14,
> + .name_sel0 = "none",
> + .name_sel1 = "ssp0-rx",
> + .muxreg = LPC32XX_SSP_CLK_CTRL,
> + .bit = 3,
> + },
> + {
> + .signal = 15,
> + .name_sel0 = "none",
> + .name_sel1 = "ssp0-tx",
> + .muxreg = LPC32XX_SSP_CLK_CTRL,
> + .bit = 2,
> + },
> +};
> +
> +struct lpc32xx_dmamux_data {
> + struct dma_router dmarouter;
> + struct regmap *reg;
> + spinlock_t lock; /* protects busy status flag */
> +};
> +
> +static void lpc32xx_dmamux_release(struct device *dev, void *route_data)
> +{
> + struct lpc32xx_dmamux_data *dmamux = dev_get_drvdata(dev);
> + struct lpc32xx_dmamux *mux = route_data;
> + unsigned long flags;
> +
> + dev_dbg(dev, "releasing dma request signal %d routed to %s\n",
> + mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1);
> +
> + guard(spinlock)(&dmamux->lock);
> +
> + mux->busy = false;
> +}
> +
> +static void *lpc32xx_dmamux_reserve(struct of_phandle_args *dma_spec,
> + struct of_dma *ofdma)
> +{
> + struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
> + struct device *dev = &pdev->dev;
> + struct lpc32xx_dmamux_data *dmamux = platform_get_drvdata(pdev);
> + unsigned long flags;
> + struct lpc32xx_dmamux *mux = NULL;
> + int i;
> +
> + if (dma_spec->args_count != 3) {
> + dev_err(&pdev->dev, "invalid number of dma mux args\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + for (i = 0; i < ARRAY_SIZE(lpc32xx_muxes); i++) {
> + if (lpc32xx_muxes[i].signal == dma_spec->args[0])
> + mux = &lpc32xx_muxes[i];
> + }
> + if (!mux) {
> + dev_err(&pdev->dev, "invalid mux request number: %d\n",
> + dma_spec->args[0]);
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (dma_spec->args[2] > 1) {
> + dev_err(&pdev->dev, "invalid dma mux value: %d\n",
> + dma_spec->args[1]);
> + return ERR_PTR(-EINVAL);
> + }
> +
> + /* The of_node_put() will be done in the core for the node */
> + dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
> + if (!dma_spec->np) {
> + dev_err(&pdev->dev, "can't get dma master\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + spin_lock_irqsave(&dmamux->lock, flags);
> + if (mux->busy) {
> + spin_unlock_irqrestore(&dmamux->lock, flags);
> + dev_err(dev, "dma request signal %d busy, routed to %s\n",
> + mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1);
> + of_node_put(dma_spec->np);
> + return ERR_PTR(-EBUSY);
> + }
> +
> + mux->busy = true;
> + mux->muxval = dma_spec->args[2] ? BIT(mux->bit) : 0;
> +
> + regmap_update_bits(dmamux->reg, mux->muxreg, BIT(mux->bit), mux->muxval);
> + spin_unlock_irqrestore(&dmamux->lock, flags);
> +
> + dma_spec->args[2] = 0;
> + dma_spec->args_count = 2;
> +
> + dev_dbg(dev, "dma request signal %d routed to %s\n",
> + mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1);
> +
> + return mux;
> +}
> +
> +static int lpc32xx_dmamux_probe(struct platform_device *pdev)
> +{
> + struct device_node *np = pdev->dev.of_node;
> + struct lpc32xx_dmamux_data *dmamux;
> + int ret;
> +
> + dmamux = devm_kzalloc(&pdev->dev, sizeof(*dmamux), GFP_KERNEL);
> + if (!dmamux)
> + return -ENOMEM;
> +
> + dmamux->reg = syscon_node_to_regmap(np->parent);
> + if (IS_ERR(dmamux->reg)) {
> + dev_err(&pdev->dev, "syscon lookup failed\n");
> + return PTR_ERR(dmamux->reg);
> + }
> +
> + spin_lock_init(&dmamux->lock);
> + platform_set_drvdata(pdev, dmamux);
> + dmamux->dmarouter.dev = &pdev->dev;
> + dmamux->dmarouter.route_free = lpc32xx_dmamux_release;
> +
> + return of_dma_router_register(np, lpc32xx_dmamux_reserve,
> + &dmamux->dmarouter);
> +}
> +
> +static const struct of_device_id lpc32xx_dmamux_match[] = {
> + { .compatible = "nxp,lpc3220-dmamux" },
> + {},
> +};
> +
> +static struct platform_driver lpc32xx_dmamux_driver = {
> + .probe = lpc32xx_dmamux_probe,
> + .driver = {
> + .name = "lpc32xx-dmamux",
> + .of_match_table = lpc32xx_dmamux_match,
> + },
> +};
> +
> +static int __init lpc32xx_dmamux_init(void)
> +{
> + return platform_driver_register(&lpc32xx_dmamux_driver);
> +}
> +arch_initcall(lpc32xx_dmamux_init);
> --
> 2.25.1
--
~Vinod
WARNING: multiple messages have this Message-ID (diff)
From: Vinod Koul <vkoul@kernel.org>
To: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com>
Cc: Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
"J.M.B. Downing" <jonathan.downing@nautel.com>,
Vladimir Zapolskiy <vz@mleia.com>,
Liam Girdwood <lgirdwood@gmail.com>,
Mark Brown <broonie@kernel.org>,
Russell King <linux@armlinux.org.uk>,
Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@kernel.org>,
Andi Shyti <andi.shyti@kernel.org>,
Miquel Raynal <miquel.raynal@bootlin.com>,
Richard Weinberger <richard@nod.at>,
Vignesh Raghavendra <vigneshr@ti.com>,
Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
Yangtao Li <frank.li@vivo.com>, Arnd Bergmann <arnd@arndb.de>,
Li Zetao <lizetao1@huawei.com>, Chancel Liu <chancel.liu@nxp.com>,
Michael Ellerman <mpe@ellerman.id.au>,
dmaengine@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
alsa-devel@alsa-project.org, linuxppc-dev@lists.ozlabs.org,
linux-sound@vger.kernel.org, linux-clk@vger.kernel.org,
linux-i2c@vger.kernel.org, linux-mtd@lists.infradead.org,
Markus Elfring <Markus.Elfring@web.de>
Subject: Re: [Patch v4 06/10] dmaengine: Add dma router for pl08x in LPC32XX SoC
Date: Mon, 24 Jun 2024 11:08:59 +0530 [thread overview]
Message-ID: <ZnkGcwd8M1QFfmxl@matsya> (raw)
In-Reply-To: <20240620175657.358273-7-piotr.wojtaszczyk@timesys.com>
Hi Piotr,
Any reason why dmaengine parts cant be sent separately, why are they
clubbed together, I dont see any obvious dependencies...
On 20-06-24, 19:56, Piotr Wojtaszczyk wrote:
> LPC32XX connects few of its peripherals to pl08x DMA thru a multiplexer,
> this driver allows to route a signal request line thru the multiplexer for
> given peripheral.
What is the difference b/w this and lpc18xx driver, why not reuse that
one?
>
> Signed-off-by: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com>
> ---
> Changes for v4:
> - This patch is new in v4
>
> MAINTAINERS | 1 +
> drivers/dma/Kconfig | 9 ++
> drivers/dma/Makefile | 1 +
> drivers/dma/lpc32xx-dmamux.c | 195 +++++++++++++++++++++++++++++++++++
> 4 files changed, 206 insertions(+)
> create mode 100644 drivers/dma/lpc32xx-dmamux.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fadf1baafd89..5ffe988ee282 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2403,6 +2403,7 @@ R: Vladimir Zapolskiy <vz@mleia.com>
> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
> S: Maintained
> F: Documentation/devicetree/bindings/dma/nxp,lpc3220-dmamux.yaml
> +F: drivers/dma/lpc32xx-dmamux.c
> N: lpc32xx
>
> ARM/Marvell Dove/MV78xx0/Orion SOC support
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 002a5ec80620..aeace3d7e066 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -378,6 +378,15 @@ config LPC18XX_DMAMUX
> Enable support for DMA on NXP LPC18xx/43xx platforms
> with PL080 and multiplexed DMA request lines.
>
> +config LPC32XX_DMAMUX
> + bool "NXP LPC32xx DMA MUX for PL080"
> + depends on ARCH_LPC32XX || COMPILE_TEST
> + depends on OF && AMBA_PL08X
> + select MFD_SYSCON
> + help
> + Support for PL080 multiplexed DMA request lines on
> + LPC32XX platrofm.
> +
> config LS2X_APB_DMA
> tristate "Loongson LS2X APB DMA support"
> depends on LOONGARCH || COMPILE_TEST
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index 802ca916f05f..6f1350b62e7f 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -50,6 +50,7 @@ obj-$(CONFIG_INTEL_IOATDMA) += ioat/
> obj-y += idxd/
> obj-$(CONFIG_K3_DMA) += k3dma.o
> obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
> +obj-$(CONFIG_LPC32XX_DMAMUX) += lpc32xx-dmamux.o
> obj-$(CONFIG_LS2X_APB_DMA) += ls2x-apb-dma.o
> obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
> obj-$(CONFIG_MILBEAUT_XDMAC) += milbeaut-xdmac.o
> diff --git a/drivers/dma/lpc32xx-dmamux.c b/drivers/dma/lpc32xx-dmamux.c
> new file mode 100644
> index 000000000000..4e6ce6026164
> --- /dev/null
> +++ b/drivers/dma/lpc32xx-dmamux.c
> @@ -0,0 +1,195 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +//
> +// Copyright 2024 Timesys Corporation <piotr.wojtaszczyk@timesys.com>
> +//
> +// Based on TI DMA Crossbar driver by:
> +// Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
> +// Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
> +
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/of_dma.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/spinlock.h>
> +
> +#define LPC32XX_SSP_CLK_CTRL 0x78
> +#define LPC32XX_I2S_CLK_CTRL 0x7c
> +
> +struct lpc32xx_dmamux {
> + int signal;
> + char *name_sel0;
> + char *name_sel1;
> + int muxval;
> + int muxreg;
> + int bit;
> + bool busy;
> +};
> +
> +/* From LPC32x0 User manual "3.2.1 DMA request signals" */
> +static struct lpc32xx_dmamux lpc32xx_muxes[] = {
> + {
> + .signal = 3,
> + .name_sel0 = "spi2-rx-tx",
> + .name_sel1 = "ssp1-rx",
> + .muxreg = LPC32XX_SSP_CLK_CTRL,
> + .bit = 5,
> + },
> + {
> + .signal = 10,
> + .name_sel0 = "uart7-rx",
> + .name_sel1 = "i2s1-dma1",
> + .muxreg = LPC32XX_I2S_CLK_CTRL,
> + .bit = 4,
> + },
> + {
> + .signal = 11,
> + .name_sel0 = "spi1-rx-tx",
> + .name_sel1 = "ssp1-tx",
> + .muxreg = LPC32XX_SSP_CLK_CTRL,
> + .bit = 4,
> + },
> + {
> + .signal = 14,
> + .name_sel0 = "none",
> + .name_sel1 = "ssp0-rx",
> + .muxreg = LPC32XX_SSP_CLK_CTRL,
> + .bit = 3,
> + },
> + {
> + .signal = 15,
> + .name_sel0 = "none",
> + .name_sel1 = "ssp0-tx",
> + .muxreg = LPC32XX_SSP_CLK_CTRL,
> + .bit = 2,
> + },
> +};
> +
> +struct lpc32xx_dmamux_data {
> + struct dma_router dmarouter;
> + struct regmap *reg;
> + spinlock_t lock; /* protects busy status flag */
> +};
> +
> +static void lpc32xx_dmamux_release(struct device *dev, void *route_data)
> +{
> + struct lpc32xx_dmamux_data *dmamux = dev_get_drvdata(dev);
> + struct lpc32xx_dmamux *mux = route_data;
> + unsigned long flags;
> +
> + dev_dbg(dev, "releasing dma request signal %d routed to %s\n",
> + mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1);
> +
> + guard(spinlock)(&dmamux->lock);
> +
> + mux->busy = false;
> +}
> +
> +static void *lpc32xx_dmamux_reserve(struct of_phandle_args *dma_spec,
> + struct of_dma *ofdma)
> +{
> + struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
> + struct device *dev = &pdev->dev;
> + struct lpc32xx_dmamux_data *dmamux = platform_get_drvdata(pdev);
> + unsigned long flags;
> + struct lpc32xx_dmamux *mux = NULL;
> + int i;
> +
> + if (dma_spec->args_count != 3) {
> + dev_err(&pdev->dev, "invalid number of dma mux args\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + for (i = 0; i < ARRAY_SIZE(lpc32xx_muxes); i++) {
> + if (lpc32xx_muxes[i].signal == dma_spec->args[0])
> + mux = &lpc32xx_muxes[i];
> + }
> + if (!mux) {
> + dev_err(&pdev->dev, "invalid mux request number: %d\n",
> + dma_spec->args[0]);
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (dma_spec->args[2] > 1) {
> + dev_err(&pdev->dev, "invalid dma mux value: %d\n",
> + dma_spec->args[1]);
> + return ERR_PTR(-EINVAL);
> + }
> +
> + /* The of_node_put() will be done in the core for the node */
> + dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
> + if (!dma_spec->np) {
> + dev_err(&pdev->dev, "can't get dma master\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + spin_lock_irqsave(&dmamux->lock, flags);
> + if (mux->busy) {
> + spin_unlock_irqrestore(&dmamux->lock, flags);
> + dev_err(dev, "dma request signal %d busy, routed to %s\n",
> + mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1);
> + of_node_put(dma_spec->np);
> + return ERR_PTR(-EBUSY);
> + }
> +
> + mux->busy = true;
> + mux->muxval = dma_spec->args[2] ? BIT(mux->bit) : 0;
> +
> + regmap_update_bits(dmamux->reg, mux->muxreg, BIT(mux->bit), mux->muxval);
> + spin_unlock_irqrestore(&dmamux->lock, flags);
> +
> + dma_spec->args[2] = 0;
> + dma_spec->args_count = 2;
> +
> + dev_dbg(dev, "dma request signal %d routed to %s\n",
> + mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1);
> +
> + return mux;
> +}
> +
> +static int lpc32xx_dmamux_probe(struct platform_device *pdev)
> +{
> + struct device_node *np = pdev->dev.of_node;
> + struct lpc32xx_dmamux_data *dmamux;
> + int ret;
> +
> + dmamux = devm_kzalloc(&pdev->dev, sizeof(*dmamux), GFP_KERNEL);
> + if (!dmamux)
> + return -ENOMEM;
> +
> + dmamux->reg = syscon_node_to_regmap(np->parent);
> + if (IS_ERR(dmamux->reg)) {
> + dev_err(&pdev->dev, "syscon lookup failed\n");
> + return PTR_ERR(dmamux->reg);
> + }
> +
> + spin_lock_init(&dmamux->lock);
> + platform_set_drvdata(pdev, dmamux);
> + dmamux->dmarouter.dev = &pdev->dev;
> + dmamux->dmarouter.route_free = lpc32xx_dmamux_release;
> +
> + return of_dma_router_register(np, lpc32xx_dmamux_reserve,
> + &dmamux->dmarouter);
> +}
> +
> +static const struct of_device_id lpc32xx_dmamux_match[] = {
> + { .compatible = "nxp,lpc3220-dmamux" },
> + {},
> +};
> +
> +static struct platform_driver lpc32xx_dmamux_driver = {
> + .probe = lpc32xx_dmamux_probe,
> + .driver = {
> + .name = "lpc32xx-dmamux",
> + .of_match_table = lpc32xx_dmamux_match,
> + },
> +};
> +
> +static int __init lpc32xx_dmamux_init(void)
> +{
> + return platform_driver_register(&lpc32xx_dmamux_driver);
> +}
> +arch_initcall(lpc32xx_dmamux_init);
> --
> 2.25.1
--
~Vinod
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
WARNING: multiple messages have this Message-ID (diff)
From: Vinod Koul <vkoul@kernel.org>
To: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com>
Cc: alsa-devel@alsa-project.org,
Vignesh Raghavendra <vigneshr@ti.com>,
Michael Turquette <mturquette@baylibre.com>,
Li Zetao <lizetao1@huawei.com>,
Liam Girdwood <lgirdwood@gmail.com>,
linux-mtd@lists.infradead.org, linux-i2c@vger.kernel.org,
Miquel Raynal <miquel.raynal@bootlin.com>,
linux-clk@vger.kernel.org, Rob Herring <robh@kernel.org>,
Richard Weinberger <richard@nod.at>,
Russell King <linux@armlinux.org.uk>,
"J.M.B. Downing" <jonathan.downing@nautel.com>,
Markus Elfring <Markus.Elfring@web.de>,
devicetree@vger.kernel.org, Conor Dooley <conor+dt@kernel.org>,
Andi Shyti <andi.shyti@kernel.org>, Arnd Bergmann <arnd@arndb.de>,
Yangtao Li <frank.li@vivo.com>,
linux-sound@vger.kernel.org, Vladimir Zapolskiy <vz@mleia.com>,
Mark Brown <broonie@kernel.org>, Jaroslav Kysela <perex@perex.cz>,
linux-arm-kernel@lists.infradead.org,
Stephen Boyd <sboyd@kernel.org>, Takashi Iwai <tiwai@suse.com>,
linux-kernel@vger.kernel.org, Chancel Liu <chancel.liu@nxp.com>,
dmaengine@vger.kernel.org,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
linuxppc-dev@lists.ozlabs.org
Subject: Re: [Patch v4 06/10] dmaengine: Add dma router for pl08x in LPC32XX SoC
Date: Mon, 24 Jun 2024 11:08:59 +0530 [thread overview]
Message-ID: <ZnkGcwd8M1QFfmxl@matsya> (raw)
In-Reply-To: <20240620175657.358273-7-piotr.wojtaszczyk@timesys.com>
Hi Piotr,
Any reason why dmaengine parts cant be sent separately, why are they
clubbed together, I dont see any obvious dependencies...
On 20-06-24, 19:56, Piotr Wojtaszczyk wrote:
> LPC32XX connects few of its peripherals to pl08x DMA thru a multiplexer,
> this driver allows to route a signal request line thru the multiplexer for
> given peripheral.
What is the difference b/w this and lpc18xx driver, why not reuse that
one?
>
> Signed-off-by: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com>
> ---
> Changes for v4:
> - This patch is new in v4
>
> MAINTAINERS | 1 +
> drivers/dma/Kconfig | 9 ++
> drivers/dma/Makefile | 1 +
> drivers/dma/lpc32xx-dmamux.c | 195 +++++++++++++++++++++++++++++++++++
> 4 files changed, 206 insertions(+)
> create mode 100644 drivers/dma/lpc32xx-dmamux.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fadf1baafd89..5ffe988ee282 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2403,6 +2403,7 @@ R: Vladimir Zapolskiy <vz@mleia.com>
> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
> S: Maintained
> F: Documentation/devicetree/bindings/dma/nxp,lpc3220-dmamux.yaml
> +F: drivers/dma/lpc32xx-dmamux.c
> N: lpc32xx
>
> ARM/Marvell Dove/MV78xx0/Orion SOC support
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 002a5ec80620..aeace3d7e066 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -378,6 +378,15 @@ config LPC18XX_DMAMUX
> Enable support for DMA on NXP LPC18xx/43xx platforms
> with PL080 and multiplexed DMA request lines.
>
> +config LPC32XX_DMAMUX
> + bool "NXP LPC32xx DMA MUX for PL080"
> + depends on ARCH_LPC32XX || COMPILE_TEST
> + depends on OF && AMBA_PL08X
> + select MFD_SYSCON
> + help
> + Support for PL080 multiplexed DMA request lines on
> + LPC32XX platrofm.
> +
> config LS2X_APB_DMA
> tristate "Loongson LS2X APB DMA support"
> depends on LOONGARCH || COMPILE_TEST
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index 802ca916f05f..6f1350b62e7f 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -50,6 +50,7 @@ obj-$(CONFIG_INTEL_IOATDMA) += ioat/
> obj-y += idxd/
> obj-$(CONFIG_K3_DMA) += k3dma.o
> obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
> +obj-$(CONFIG_LPC32XX_DMAMUX) += lpc32xx-dmamux.o
> obj-$(CONFIG_LS2X_APB_DMA) += ls2x-apb-dma.o
> obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
> obj-$(CONFIG_MILBEAUT_XDMAC) += milbeaut-xdmac.o
> diff --git a/drivers/dma/lpc32xx-dmamux.c b/drivers/dma/lpc32xx-dmamux.c
> new file mode 100644
> index 000000000000..4e6ce6026164
> --- /dev/null
> +++ b/drivers/dma/lpc32xx-dmamux.c
> @@ -0,0 +1,195 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +//
> +// Copyright 2024 Timesys Corporation <piotr.wojtaszczyk@timesys.com>
> +//
> +// Based on TI DMA Crossbar driver by:
> +// Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
> +// Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
> +
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/of_dma.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/spinlock.h>
> +
> +#define LPC32XX_SSP_CLK_CTRL 0x78
> +#define LPC32XX_I2S_CLK_CTRL 0x7c
> +
> +struct lpc32xx_dmamux {
> + int signal;
> + char *name_sel0;
> + char *name_sel1;
> + int muxval;
> + int muxreg;
> + int bit;
> + bool busy;
> +};
> +
> +/* From LPC32x0 User manual "3.2.1 DMA request signals" */
> +static struct lpc32xx_dmamux lpc32xx_muxes[] = {
> + {
> + .signal = 3,
> + .name_sel0 = "spi2-rx-tx",
> + .name_sel1 = "ssp1-rx",
> + .muxreg = LPC32XX_SSP_CLK_CTRL,
> + .bit = 5,
> + },
> + {
> + .signal = 10,
> + .name_sel0 = "uart7-rx",
> + .name_sel1 = "i2s1-dma1",
> + .muxreg = LPC32XX_I2S_CLK_CTRL,
> + .bit = 4,
> + },
> + {
> + .signal = 11,
> + .name_sel0 = "spi1-rx-tx",
> + .name_sel1 = "ssp1-tx",
> + .muxreg = LPC32XX_SSP_CLK_CTRL,
> + .bit = 4,
> + },
> + {
> + .signal = 14,
> + .name_sel0 = "none",
> + .name_sel1 = "ssp0-rx",
> + .muxreg = LPC32XX_SSP_CLK_CTRL,
> + .bit = 3,
> + },
> + {
> + .signal = 15,
> + .name_sel0 = "none",
> + .name_sel1 = "ssp0-tx",
> + .muxreg = LPC32XX_SSP_CLK_CTRL,
> + .bit = 2,
> + },
> +};
> +
> +struct lpc32xx_dmamux_data {
> + struct dma_router dmarouter;
> + struct regmap *reg;
> + spinlock_t lock; /* protects busy status flag */
> +};
> +
> +static void lpc32xx_dmamux_release(struct device *dev, void *route_data)
> +{
> + struct lpc32xx_dmamux_data *dmamux = dev_get_drvdata(dev);
> + struct lpc32xx_dmamux *mux = route_data;
> + unsigned long flags;
> +
> + dev_dbg(dev, "releasing dma request signal %d routed to %s\n",
> + mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1);
> +
> + guard(spinlock)(&dmamux->lock);
> +
> + mux->busy = false;
> +}
> +
> +static void *lpc32xx_dmamux_reserve(struct of_phandle_args *dma_spec,
> + struct of_dma *ofdma)
> +{
> + struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
> + struct device *dev = &pdev->dev;
> + struct lpc32xx_dmamux_data *dmamux = platform_get_drvdata(pdev);
> + unsigned long flags;
> + struct lpc32xx_dmamux *mux = NULL;
> + int i;
> +
> + if (dma_spec->args_count != 3) {
> + dev_err(&pdev->dev, "invalid number of dma mux args\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + for (i = 0; i < ARRAY_SIZE(lpc32xx_muxes); i++) {
> + if (lpc32xx_muxes[i].signal == dma_spec->args[0])
> + mux = &lpc32xx_muxes[i];
> + }
> + if (!mux) {
> + dev_err(&pdev->dev, "invalid mux request number: %d\n",
> + dma_spec->args[0]);
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (dma_spec->args[2] > 1) {
> + dev_err(&pdev->dev, "invalid dma mux value: %d\n",
> + dma_spec->args[1]);
> + return ERR_PTR(-EINVAL);
> + }
> +
> + /* The of_node_put() will be done in the core for the node */
> + dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
> + if (!dma_spec->np) {
> + dev_err(&pdev->dev, "can't get dma master\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + spin_lock_irqsave(&dmamux->lock, flags);
> + if (mux->busy) {
> + spin_unlock_irqrestore(&dmamux->lock, flags);
> + dev_err(dev, "dma request signal %d busy, routed to %s\n",
> + mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1);
> + of_node_put(dma_spec->np);
> + return ERR_PTR(-EBUSY);
> + }
> +
> + mux->busy = true;
> + mux->muxval = dma_spec->args[2] ? BIT(mux->bit) : 0;
> +
> + regmap_update_bits(dmamux->reg, mux->muxreg, BIT(mux->bit), mux->muxval);
> + spin_unlock_irqrestore(&dmamux->lock, flags);
> +
> + dma_spec->args[2] = 0;
> + dma_spec->args_count = 2;
> +
> + dev_dbg(dev, "dma request signal %d routed to %s\n",
> + mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1);
> +
> + return mux;
> +}
> +
> +static int lpc32xx_dmamux_probe(struct platform_device *pdev)
> +{
> + struct device_node *np = pdev->dev.of_node;
> + struct lpc32xx_dmamux_data *dmamux;
> + int ret;
> +
> + dmamux = devm_kzalloc(&pdev->dev, sizeof(*dmamux), GFP_KERNEL);
> + if (!dmamux)
> + return -ENOMEM;
> +
> + dmamux->reg = syscon_node_to_regmap(np->parent);
> + if (IS_ERR(dmamux->reg)) {
> + dev_err(&pdev->dev, "syscon lookup failed\n");
> + return PTR_ERR(dmamux->reg);
> + }
> +
> + spin_lock_init(&dmamux->lock);
> + platform_set_drvdata(pdev, dmamux);
> + dmamux->dmarouter.dev = &pdev->dev;
> + dmamux->dmarouter.route_free = lpc32xx_dmamux_release;
> +
> + return of_dma_router_register(np, lpc32xx_dmamux_reserve,
> + &dmamux->dmarouter);
> +}
> +
> +static const struct of_device_id lpc32xx_dmamux_match[] = {
> + { .compatible = "nxp,lpc3220-dmamux" },
> + {},
> +};
> +
> +static struct platform_driver lpc32xx_dmamux_driver = {
> + .probe = lpc32xx_dmamux_probe,
> + .driver = {
> + .name = "lpc32xx-dmamux",
> + .of_match_table = lpc32xx_dmamux_match,
> + },
> +};
> +
> +static int __init lpc32xx_dmamux_init(void)
> +{
> + return platform_driver_register(&lpc32xx_dmamux_driver);
> +}
> +arch_initcall(lpc32xx_dmamux_init);
> --
> 2.25.1
--
~Vinod
next prev parent reply other threads:[~2024-06-24 5:43 UTC|newest]
Thread overview: 80+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-20 17:56 [Patch v4 00/10] Add audio support for LPC32XX CPUs Piotr Wojtaszczyk
2024-06-20 17:56 ` Piotr Wojtaszczyk
2024-06-20 17:56 ` [Patch v4 01/10] dt-bindings: dma: pl08x: Add dma-cells description Piotr Wojtaszczyk
2024-06-20 17:56 ` Piotr Wojtaszczyk
2024-06-21 6:12 ` Krzysztof Kozlowski
2024-06-21 6:12 ` Krzysztof Kozlowski
2024-06-20 17:56 ` [Patch v4 02/10] dt-bindings: dma: Add lpc32xx DMA mux binding Piotr Wojtaszczyk
2024-06-20 17:56 ` Piotr Wojtaszczyk
2024-06-20 19:47 ` Rob Herring (Arm)
2024-06-20 19:47 ` Rob Herring (Arm)
2024-06-20 19:47 ` Rob Herring (Arm)
2024-06-21 6:17 ` Krzysztof Kozlowski
2024-06-21 6:17 ` Krzysztof Kozlowski
2024-06-20 17:56 ` [Patch v4 03/10] ASoC: dt-bindings: lpc32xx: Add lpc32xx i2s DT binding Piotr Wojtaszczyk
2024-06-20 17:56 ` Piotr Wojtaszczyk
2024-06-21 6:18 ` Krzysztof Kozlowski
2024-06-21 6:18 ` Krzysztof Kozlowski
2024-06-20 17:56 ` [Patch v4 04/10] ARM: dts: lpc32xx: Add missing dma and i2s properties Piotr Wojtaszczyk
2024-06-20 17:56 ` Piotr Wojtaszczyk
2024-06-21 5:36 ` Markus Elfring
2024-06-21 5:36 ` Markus Elfring
2024-06-21 6:20 ` Krzysztof Kozlowski
2024-06-21 6:20 ` Krzysztof Kozlowski
2024-06-20 17:56 ` [Patch v4 05/10] clk: lpc32xx: initialize regmap using parent syscon Piotr Wojtaszczyk
2024-06-20 17:56 ` Piotr Wojtaszczyk
2024-06-21 5:45 ` Markus Elfring
2024-06-21 5:45 ` Markus Elfring
2024-06-21 6:21 ` Krzysztof Kozlowski
2024-06-21 6:21 ` Krzysztof Kozlowski
2024-06-20 17:56 ` [Patch v4 06/10] dmaengine: Add dma router for pl08x in LPC32XX SoC Piotr Wojtaszczyk
2024-06-20 17:56 ` Piotr Wojtaszczyk
2024-06-21 5:51 ` Markus Elfring
2024-06-21 5:51 ` Markus Elfring
2024-06-21 6:24 ` Krzysztof Kozlowski
2024-06-21 6:24 ` Krzysztof Kozlowski
2024-06-24 5:38 ` Vinod Koul [this message]
2024-06-24 5:38 ` Vinod Koul
2024-06-24 5:38 ` Vinod Koul
2024-06-24 8:59 ` Piotr Wojtaszczyk
2024-06-24 8:59 ` Piotr Wojtaszczyk
2024-06-24 8:59 ` Piotr Wojtaszczyk
2024-07-02 4:18 ` kernel test robot
2024-06-20 17:56 ` [Patch v4 07/10] ARM: lpc32xx: Remove pl08x platform data in favor for device tree Piotr Wojtaszczyk
2024-06-20 17:56 ` Piotr Wojtaszczyk
2024-06-21 5:56 ` Markus Elfring
2024-06-21 5:56 ` Markus Elfring
2024-06-21 6:25 ` Krzysztof Kozlowski
2024-06-21 6:25 ` Krzysztof Kozlowski
2024-06-20 17:56 ` [Patch v4 08/10] mtd: rawnand: lpx32xx: Request DMA channels using DT entries Piotr Wojtaszczyk
2024-06-20 17:56 ` Piotr Wojtaszczyk
2024-06-21 8:30 ` Miquel Raynal
2024-06-21 8:30 ` Miquel Raynal
2024-06-21 8:30 ` Miquel Raynal
2024-06-21 12:44 ` Piotr Wojtaszczyk
2024-06-21 12:44 ` Piotr Wojtaszczyk
2024-06-21 12:44 ` Piotr Wojtaszczyk
2024-06-24 6:39 ` Miquel Raynal
2024-06-24 6:39 ` Miquel Raynal
2024-06-24 6:39 ` Miquel Raynal
2024-06-28 9:48 ` Piotr Wojtaszczyk
2024-06-28 9:48 ` Piotr Wojtaszczyk
2024-06-28 9:48 ` Piotr Wojtaszczyk
2024-07-02 0:37 ` kernel test robot
2024-06-20 17:56 ` [Patch v4 09/10] ASoC: fsl: Add i2s and pcm drivers for LPC32xx CPUs Piotr Wojtaszczyk
2024-06-20 17:56 ` Piotr Wojtaszczyk
2024-07-02 2:43 ` kernel test robot
2024-06-20 17:56 ` [Patch v4 10/10] i2x: pnx: Use threaded irq to fix warning from del_timer_sync() Piotr Wojtaszczyk
2024-06-20 17:56 ` Piotr Wojtaszczyk
2024-06-20 22:57 ` Andi Shyti
2024-06-20 22:57 ` Andi Shyti
2024-06-20 22:57 ` Andi Shyti
2024-06-21 12:08 ` Piotr Wojtaszczyk
2024-06-21 12:08 ` Piotr Wojtaszczyk
2024-06-21 12:08 ` Piotr Wojtaszczyk
2024-06-25 21:12 ` Andi Shyti
2024-06-25 21:12 ` Andi Shyti
2024-06-25 21:12 ` Andi Shyti
2024-06-27 11:05 ` Piotr Wojtaszczyk
2024-06-27 11:05 ` Piotr Wojtaszczyk
2024-06-27 11:05 ` Piotr Wojtaszczyk
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=ZnkGcwd8M1QFfmxl@matsya \
--to=vkoul@kernel.org \
--cc=Markus.Elfring@web.de \
--cc=alsa-devel@alsa-project.org \
--cc=andi.shyti@kernel.org \
--cc=arnd@arndb.de \
--cc=broonie@kernel.org \
--cc=chancel.liu@nxp.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=frank.li@vivo.com \
--cc=jonathan.downing@nautel.com \
--cc=krzk+dt@kernel.org \
--cc=lgirdwood@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=linux-sound@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=lizetao1@huawei.com \
--cc=miquel.raynal@bootlin.com \
--cc=mpe@ellerman.id.au \
--cc=mturquette@baylibre.com \
--cc=perex@perex.cz \
--cc=piotr.wojtaszczyk@timesys.com \
--cc=richard@nod.at \
--cc=robh@kernel.org \
--cc=sboyd@kernel.org \
--cc=tiwai@suse.com \
--cc=vigneshr@ti.com \
--cc=vz@mleia.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.