DMA Engine development
 help / color / mirror / Atom feed
* Re: [PATCH v3 0/7] Allwinner H6 DMA support
From: Maxime Ripard @ 2019-05-28 11:10 UTC (permalink / raw)
  To: Clément Péron
  Cc: Vinod Koul, Rob Herring, Mark Rutland, Chen-Yu Tsai, Dan Williams,
	dmaengine, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20190527201459.20130-1-peron.clem@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 954 bytes --]

On Mon, May 27, 2019 at 10:14:52PM +0200, Clément Péron wrote:
> Hi,
>
> This series has been first proposed by Jernej Skrabec[1].
> As this series is mandatory for SPDIF/I2S support and because he is
> busy on Cedrus stuff. I asked him to make the minor change requested
> and repost it.
> Authorship remains to him.
>
> I have tested this series with SPDIF driver and added a patch to enable
> DMA_SUN6I_CONFIG for arm64.
>
> Original Post:
> "
> DMA engine engine on H6 almost the same as on older SoCs. The biggest
> difference is that it has slightly rearranged bits in registers and
> it needs additional clock, probably due to iommu.
>
> These patches were tested with I2S connected to HDMI. I2S needs
> additional patches which will be sent later.

For the whole series,
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [EXT] Re: [V3 1/2] dmaengine: fsl-dpaa2-qdma: Add the DPDMAI(Data Path DMA Interface) support
From: Joe Perches @ 2019-05-28  9:46 UTC (permalink / raw)
  To: Peng Ma, Vinod Koul
  Cc: dan.j.williams@intel.com, Leo Li, linux-kernel@vger.kernel.org,
	dmaengine@vger.kernel.org
In-Reply-To: <VI1PR04MB44314E4B35FA0C7E850CD512ED1E0@VI1PR04MB4431.eurprd04.prod.outlook.com>

On Tue, 2019-05-28 at 04:47 +0000, Peng Ma wrote:
> -----Original Message-----
> > From: Vinod Koul <vkoul@kernel.org>
[]
> > > diff --git a/drivers/dma/fsl-dpaa2-qdma/dpdmai.h
> > > b/drivers/dma/fsl-dpaa2-qdma/dpdmai.h
> > > new file mode 100644
> > > index 0000000..c8a7b7f
> > > --- /dev/null
> > > +++ b/drivers/dma/fsl-dpaa2-qdma/dpdmai.h
> > > @@ -0,0 +1,524 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/* Copyright 2014-2018 NXP */
> > > +
> > > +/*
> > > + * Redistribution and use in source and binary forms, with or without
> > > + * modification, are permitted provided that the following conditions are
> > met:
> > > + * * Redistributions of source code must retain the above copyright
> > > + * notice, this list of conditions and the following disclaimer.
> > > + * * Redistributions in binary form must reproduce the above
> > > +copyright
> > > + * notice, this list of conditions and the following disclaimer in
> > > +the
> > > + * documentation and/or other materials provided with the distribution.
> > > + * * Neither the name of the above-listed copyright holders nor the
> > > + * names of any contributors may be used to endorse or promote
> > > +products
> > > + * derived from this software without specific prior written permission.
> > > + *
> > > + *
> > > + * ALTERNATIVELY, this software may be distributed under the terms of
> > > +the
> > > + * GNU General Public License ("GPL") as published by the Free
> > > +Software
> > > + * Foundation, either version 2 of that License or (at your option)
> > > +any
> > > + * later version.
> > > + *
> > > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> > CONTRIBUTORS "AS IS"
> > > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > LIMITED
> > > +TO, THE
> > > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> > PARTICULAR
> > > +PURPOSE
> > > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
> > > +CONTRIBUTORS BE
> > > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
> > > +OR
> > > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> > PROCUREMENT
> > > +OF
> > > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> > > +BUSINESS
> > > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> > > +WHETHER IN
> > > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> > > +OTHERWISE)
> > > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> > > +ADVISED OF THE
> > > + * POSSIBILITY OF SUCH DAMAGE.
> > > + */
> > 
> > we have SiPDX tag, why do you need ths here!
> > 
> [Peng Ma] It is my mistake. I will fixe it.

Please have your company review which licenses you are
intending to use as the SPDX tag does not match the
licenses shown in the text.



^ permalink raw reply

* RE: [EXT] Re: [V3 1/2] dmaengine: fsl-dpaa2-qdma: Add the DPDMAI(Data Path DMA Interface) support
From: Peng Ma @ 2019-05-28  4:47 UTC (permalink / raw)
  To: Vinod Koul
  Cc: dan.j.williams@intel.com, Leo Li, linux-kernel@vger.kernel.org,
	dmaengine@vger.kernel.org
In-Reply-To: <20190426124550.GE28103@vkoul-mobl>

Hi Vinod

Sorry to replay so late.
The dpaa2 qdma driver is based on FSL_MC_BUS and FSL_MC_DPIO, so It will used those two drivers
Functions or structs. This patch provides some necessary functions and structs for qdma driver(next patch: dpaa2-qdma.c)
The dpaa2 driver is not only to write some register on driver side but also need enable FSL_MC_BUS and FSL_MC_DPIO to
call some functions provided by them. Such as: mc_encode_cmd_header, mc_send_command etc. I will clear up this driver
again. And send V4 to review, thanks for your review.

Best Regards,
Peng
>-----Original Message-----
>From: Vinod Koul <vkoul@kernel.org>
>Sent: 2019年4月26日 20:46
>To: Peng Ma <peng.ma@nxp.com>
>Cc: dan.j.williams@intel.com; Leo Li <leoyang.li@nxp.com>;
>linux-kernel@vger.kernel.org; dmaengine@vger.kernel.org
>Subject: [EXT] Re: [V3 1/2] dmaengine: fsl-dpaa2-qdma: Add the DPDMAI(Data
>Path DMA Interface) support
>
>Caution: EXT Email
>
>On 09-04-19, 15:22, Peng Ma wrote:
>
>Subject missed PATCH tag!
>
>> The MC exports the DPDMAI object as an interface to operate the DPAA2
>> QDMA
>
>whats MC, DPDMAI, DPAA2
>
[Peng Ma] MC: Management Complex
DPDMAI: Data Path DMA Interface
DPAA2: Data Path Acceleration Architecture, Second Generation
I will explain them on next version.
>> Engine. The DPDMAI enables sending frame-based requests to QDMA and
>> receiving back confirmation response on transaction completion,
>> utilizing the DPAA2 QBMan infrastructure. DPDMAI object provides up to
>> two priorities for processing QDMA requests.
>
>> +int dpdmai_open(struct fsl_mc_io *mc_io,
>> +             u32 cmd_flags,
>> +             int dpdmai_id,
>> +             u16 *token)
>
>could be written as:
>
>int dpdmai_open(struct fsl_mc_io *mc_io, u32 cmd_flags,
>                int dpdmai_id, u16 *token)
>
>Looks neater, right? It would be to reread coding guidelines and run checkpatch
>with --strict on this
>
[Peng Ma] Ok, got it.
>
>> +{
>> +     struct fsl_mc_command cmd = { 0 };
>
>where is this defined?
[Peng Ma] include/linux/fsl/mc.h
>
>> +     struct dpdmai_cmd_open *cmd_params;
>> +     int err;
>> +
>> +     /* prepare command */
>> +     cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_OPEN,
>> +                                       cmd_flags,
>> +                                       0);
>> +
>> +     cmd_params = (struct dpdmai_cmd_open *)cmd.params;
>
>I dont like casts, can you explain
[Peng Ma] If I didn't use the casts, There are two case:
1: struct fsl_mc_command cmd_org = { 0 };
  Struct fsl_mc_command *cmd = &cmd_org;
  In this case, we will define one more temporary variable in the stack.
2: Struct fsl_mc_command *cmd = kmalloc();
  In this case, we will alloc some memory, It may be produce memory
Fragmentation. Those functions will be called on driver init It is not necessary 
use this case to those function.
>
>> +     cmd_params->dpdmai_id = cpu_to_le32(dpdmai_id);
>> +
>> +     /* send command to mc*/
>> +     err = mc_send_command(mc_io, &cmd);
>> +     if (err)
>> +             return err;
>> +
>> +     /* retrieve response parameters */
>> +     *token = mc_cmd_hdr_read_token(&cmd);
>> +     return 0;
>> +}
>
>who will call this API?
>
[Peng Ma] This file is not a driver, some of functions define in this file, the dma driver(dpaa2-qdma.c) will call some of those API and I will
delete unuseless API in the future.
>> +int dpdmai_create(struct fsl_mc_io *mc_io,
>> +               u32 cmd_flags,
>> +               const struct dpdmai_cfg *cfg,
>> +               u16 *token)
>> +{
>> +     struct fsl_mc_command cmd = { 0 };
>> +     int err;
>> +
>> +     /* prepare command */
>> +     cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CREATE,
>> +                                       cmd_flags,
>> +                                       0);
>
>why waste a line, last arg can be in previous line!
>
[Peng Ma] sorry, I will remove it.
>> +int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io,
>> +                     u32 cmd_flags,
>> +                     u16 token,
>> +                     u8 priority,
>> +                     struct dpdmai_tx_queue_attr *attr) {
>> +     struct fsl_mc_command cmd = { 0 };
>> +     struct dpdmai_cmd_queue *cmd_params;
>> +     struct dpdmai_rsp_get_tx_queue *rsp_params;
>> +     int err;
>> +
>> +     /* prepare command */
>> +     cmd.header =
>mc_encode_cmd_header(DPDMAI_CMDID_GET_TX_QUEUE,
>> +                                       cmd_flags,
>> +                                       token);
>> +
>> +     cmd_params = (struct dpdmai_cmd_queue *)cmd.params;
>> +     cmd_params->queue = priority;
>> +
>> +     /* send command to mc*/
>> +     err = mc_send_command(mc_io, &cmd);
>> +     if (err)
>> +             return err;
>> +
>> +     /* retrieve response parameters */
>> +
>> +     rsp_params = (struct dpdmai_rsp_get_tx_queue *)cmd.params;
>> +     attr->fqid = le32_to_cpu(rsp_params->fqid);
>> +
>> +     return 0;
>> +}
>
>Okay this file does not use any of dmaengine apis, is this a dmaengine driver?
[Peng Ma] please the previous comment.
>
>> diff --git a/drivers/dma/fsl-dpaa2-qdma/dpdmai.h
>> b/drivers/dma/fsl-dpaa2-qdma/dpdmai.h
>> new file mode 100644
>> index 0000000..c8a7b7f
>> --- /dev/null
>> +++ b/drivers/dma/fsl-dpaa2-qdma/dpdmai.h
>> @@ -0,0 +1,524 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright 2014-2018 NXP */
>> +
>> +/*
>> + * Redistribution and use in source and binary forms, with or without
>> + * modification, are permitted provided that the following conditions are
>met:
>> + * * Redistributions of source code must retain the above copyright
>> + * notice, this list of conditions and the following disclaimer.
>> + * * Redistributions in binary form must reproduce the above
>> +copyright
>> + * notice, this list of conditions and the following disclaimer in
>> +the
>> + * documentation and/or other materials provided with the distribution.
>> + * * Neither the name of the above-listed copyright holders nor the
>> + * names of any contributors may be used to endorse or promote
>> +products
>> + * derived from this software without specific prior written permission.
>> + *
>> + *
>> + * ALTERNATIVELY, this software may be distributed under the terms of
>> +the
>> + * GNU General Public License ("GPL") as published by the Free
>> +Software
>> + * Foundation, either version 2 of that License or (at your option)
>> +any
>> + * later version.
>> + *
>> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
>CONTRIBUTORS "AS IS"
>> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>LIMITED
>> +TO, THE
>> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
>PARTICULAR
>> +PURPOSE
>> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
>> +CONTRIBUTORS BE
>> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
>> +OR
>> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
>PROCUREMENT
>> +OF
>> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
>> +BUSINESS
>> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
>> +WHETHER IN
>> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
>> +OTHERWISE)
>> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
>> +ADVISED OF THE
>> + * POSSIBILITY OF SUCH DAMAGE.
>> + */
>
>we have SiPDX tag, why do you need ths here!
>
[Peng Ma] It is my mistake. I will fixe it.
>--
>~Vinod

^ permalink raw reply

* [PATCH v3 0/7] Allwinner H6 DMA support
From: Clément Péron @ 2019-05-27 20:14 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Mark Rutland, Maxime Ripard,
	Chen-Yu Tsai, Dan Williams
  Cc: dmaengine, devicetree, linux-arm-kernel, linux-kernel,
	Clément Péron

Hi,

This series has been first proposed by Jernej Skrabec[1].
As this series is mandatory for SPDIF/I2S support and because he is
busy on Cedrus stuff. I asked him to make the minor change requested
and repost it.
Authorship remains to him.

I have tested this series with SPDIF driver and added a patch to enable
DMA_SUN6I_CONFIG for arm64.

Original Post:
"
DMA engine engine on H6 almost the same as on older SoCs. The biggest
difference is that it has slightly rearranged bits in registers and
it needs additional clock, probably due to iommu.

These patches were tested with I2S connected to HDMI. I2S needs
additional patches which will be sent later.

Please take a look.

Best regards,
Jernej
"

Thanks,
Clément

Changes since v2:
 - Drop the change of "dma-request" default value

Changes since v1:
 - Enable DMA_SUN6I in arm64 defconfig
 - Change mbus_clk to has_mbus_clk
 - Collect Rob H. reviewed-by

Clément Péron (1):
  arm64: defconfig: enable Allwinner DMA drivers

Jernej Skrabec (6):
  dt-bindings: arm64: allwinner: h6: Add binding for DMA controller
  dmaengine: sun6i: Add a quirk for additional mbus clock
  dmaengine: sun6i: Add a quirk for setting DRQ fields
  dmaengine: sun6i: Add a quirk for setting mode fields
  dmaengine: sun6i: Add support for H6 DMA
  arm64: dts: allwinner: h6: Add DMA node

 .../devicetree/bindings/dma/sun6i-dma.txt     |   9 +-
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  |  12 ++
 arch/arm64/configs/defconfig                  |   1 +
 drivers/dma/sun6i-dma.c                       | 147 +++++++++++++-----
 4 files changed, 132 insertions(+), 37 deletions(-)

-- 
2.20.1


^ permalink raw reply

* [PATCH v3 1/7] dt-bindings: arm64: allwinner: h6: Add binding for DMA controller
From: Clément Péron @ 2019-05-27 20:14 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Mark Rutland, Maxime Ripard,
	Chen-Yu Tsai, Dan Williams
  Cc: dmaengine, devicetree, linux-arm-kernel, linux-kernel,
	Jernej Skrabec, Rob Herring, Clément Péron
In-Reply-To: <20190527201459.20130-1-peron.clem@gmail.com>

From: Jernej Skrabec <jernej.skrabec@siol.net>

DMA in H6 is similar to other DMA controller, except it is first which
supports more than 32 request sources and has 16 channels. It also needs
additional clock to be enabled.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
---
 Documentation/devicetree/bindings/dma/sun6i-dma.txt | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/sun6i-dma.txt b/Documentation/devicetree/bindings/dma/sun6i-dma.txt
index 7fccc20d8331..cae31f4e77ba 100644
--- a/Documentation/devicetree/bindings/dma/sun6i-dma.txt
+++ b/Documentation/devicetree/bindings/dma/sun6i-dma.txt
@@ -28,12 +28,17 @@ Example:
 	};
 
 ------------------------------------------------------------------------------
-For A64 DMA controller:
+For A64 and H6 DMA controller:
 
 Required properties:
-- compatible:	"allwinner,sun50i-a64-dma"
+- compatible:	Must be one of
+		  "allwinner,sun50i-a64-dma"
+		  "allwinner,sun50i-h6-dma"
 - dma-channels: Number of DMA channels supported by the controller.
 		Refer to Documentation/devicetree/bindings/dma/dma.txt
+- clocks:	In addition to parent AHB clock, it should also contain mbus
+		clock (H6 only)
+- clock-names:	Should contain "bus" and "mbus" (H6 only)
 - all properties above, i.e. reg, interrupts, clocks, resets and #dma-cells
 
 Optional properties:
-- 
2.20.1


^ permalink raw reply related

* [PATCH v3 2/7] dmaengine: sun6i: Add a quirk for additional mbus clock
From: Clément Péron @ 2019-05-27 20:14 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Mark Rutland, Maxime Ripard,
	Chen-Yu Tsai, Dan Williams
  Cc: dmaengine, devicetree, linux-arm-kernel, linux-kernel,
	Jernej Skrabec, Clément Péron
In-Reply-To: <20190527201459.20130-1-peron.clem@gmail.com>

From: Jernej Skrabec <jernej.skrabec@siol.net>

H6 DMA controller needs additional mbus clock to be enabled.

Add a quirk for it and handle it accordingly.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
---
 drivers/dma/sun6i-dma.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 0cd13f17fc11..7d9606997251 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -129,6 +129,7 @@ struct sun6i_dma_config {
 	u32 dst_burst_lengths;
 	u32 src_addr_widths;
 	u32 dst_addr_widths;
+	bool has_mbus_clk;
 };
 
 /*
@@ -182,6 +183,7 @@ struct sun6i_dma_dev {
 	struct dma_device	slave;
 	void __iomem		*base;
 	struct clk		*clk;
+	struct clk		*clk_mbus;
 	int			irq;
 	spinlock_t		lock;
 	struct reset_control	*rstc;
@@ -1208,6 +1210,14 @@ static int sun6i_dma_probe(struct platform_device *pdev)
 		return PTR_ERR(sdc->clk);
 	}
 
+	if (sdc->cfg->has_mbus_clk) {
+		sdc->clk_mbus = devm_clk_get(&pdev->dev, "mbus");
+		if (IS_ERR(sdc->clk_mbus)) {
+			dev_err(&pdev->dev, "No mbus clock specified\n");
+			return PTR_ERR(sdc->clk_mbus);
+		}
+	}
+
 	sdc->rstc = devm_reset_control_get(&pdev->dev, NULL);
 	if (IS_ERR(sdc->rstc)) {
 		dev_err(&pdev->dev, "No reset controller specified\n");
@@ -1312,11 +1322,19 @@ static int sun6i_dma_probe(struct platform_device *pdev)
 		goto err_reset_assert;
 	}
 
+	if (sdc->cfg->has_mbus_clk) {
+		ret = clk_prepare_enable(sdc->clk_mbus);
+		if (ret) {
+			dev_err(&pdev->dev, "Couldn't enable mbus clock\n");
+			goto err_clk_disable;
+		}
+	}
+
 	ret = devm_request_irq(&pdev->dev, sdc->irq, sun6i_dma_interrupt, 0,
 			       dev_name(&pdev->dev), sdc);
 	if (ret) {
 		dev_err(&pdev->dev, "Cannot request IRQ\n");
-		goto err_clk_disable;
+		goto err_mbus_clk_disable;
 	}
 
 	ret = dma_async_device_register(&sdc->slave);
@@ -1341,6 +1359,8 @@ static int sun6i_dma_probe(struct platform_device *pdev)
 	dma_async_device_unregister(&sdc->slave);
 err_irq_disable:
 	sun6i_kill_tasklet(sdc);
+err_mbus_clk_disable:
+	clk_disable_unprepare(sdc->clk_mbus);
 err_clk_disable:
 	clk_disable_unprepare(sdc->clk);
 err_reset_assert:
@@ -1359,6 +1379,7 @@ static int sun6i_dma_remove(struct platform_device *pdev)
 
 	sun6i_kill_tasklet(sdc);
 
+	clk_disable_unprepare(sdc->clk_mbus);
 	clk_disable_unprepare(sdc->clk);
 	reset_control_assert(sdc->rstc);
 
-- 
2.20.1


^ permalink raw reply related

* [PATCH v3 3/7] dmaengine: sun6i: Add a quirk for setting DRQ fields
From: Clément Péron @ 2019-05-27 20:14 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Mark Rutland, Maxime Ripard,
	Chen-Yu Tsai, Dan Williams
  Cc: dmaengine, devicetree, linux-arm-kernel, linux-kernel,
	Jernej Skrabec, Clément Péron
In-Reply-To: <20190527201459.20130-1-peron.clem@gmail.com>

From: Jernej Skrabec <jernej.skrabec@siol.net>

H6 DMA has more than 32 possible DRQs. That means that current maximum
of 31 DRQs is not enough anymore.

Add a quirk which will set source and destination DRQ number.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
---
 drivers/dma/sun6i-dma.c | 48 ++++++++++++++++++++++++-----------------
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 7d9606997251..f725b93fd21a 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -68,15 +68,15 @@
 #define DMA_CHAN_LLI_ADDR	0x08
 
 #define DMA_CHAN_CUR_CFG	0x0c
-#define DMA_CHAN_MAX_DRQ		0x1f
-#define DMA_CHAN_CFG_SRC_DRQ(x)		((x) & DMA_CHAN_MAX_DRQ)
+#define DMA_CHAN_MAX_DRQ_A31		0x1f
+#define DMA_CHAN_CFG_SRC_DRQ_A31(x)	((x) & DMA_CHAN_MAX_DRQ_A31)
 #define DMA_CHAN_CFG_SRC_IO_MODE	BIT(5)
 #define DMA_CHAN_CFG_SRC_LINEAR_MODE	(0 << 5)
 #define DMA_CHAN_CFG_SRC_BURST_A31(x)	(((x) & 0x3) << 7)
 #define DMA_CHAN_CFG_SRC_BURST_H3(x)	(((x) & 0x3) << 6)
 #define DMA_CHAN_CFG_SRC_WIDTH(x)	(((x) & 0x3) << 9)
 
-#define DMA_CHAN_CFG_DST_DRQ(x)		(DMA_CHAN_CFG_SRC_DRQ(x) << 16)
+#define DMA_CHAN_CFG_DST_DRQ_A31(x)	(DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16)
 #define DMA_CHAN_CFG_DST_IO_MODE	(DMA_CHAN_CFG_SRC_IO_MODE << 16)
 #define DMA_CHAN_CFG_DST_LINEAR_MODE	(DMA_CHAN_CFG_SRC_LINEAR_MODE << 16)
 #define DMA_CHAN_CFG_DST_BURST_A31(x)	(DMA_CHAN_CFG_SRC_BURST_A31(x) << 16)
@@ -125,6 +125,7 @@ struct sun6i_dma_config {
 	 */
 	void (*clock_autogate_enable)(struct sun6i_dma_dev *);
 	void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst);
+	void (*set_drq)(u32 *p_cfg, s8 src_drq, s8 dst_drq);
 	u32 src_burst_lengths;
 	u32 dst_burst_lengths;
 	u32 src_addr_widths;
@@ -311,6 +312,12 @@ static void sun6i_set_burst_length_h3(u32 *p_cfg, s8 src_burst, s8 dst_burst)
 		  DMA_CHAN_CFG_DST_BURST_H3(dst_burst);
 }
 
+static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq)
+{
+	*p_cfg |= DMA_CHAN_CFG_SRC_DRQ_A31(src_drq) |
+		  DMA_CHAN_CFG_DST_DRQ_A31(dst_drq);
+}
+
 static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan)
 {
 	struct sun6i_desc *txd = pchan->desc;
@@ -634,14 +641,13 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
 
 	burst = convert_burst(8);
 	width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES);
-	v_lli->cfg = DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) |
-		DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) |
-		DMA_CHAN_CFG_DST_LINEAR_MODE |
+	v_lli->cfg = DMA_CHAN_CFG_DST_LINEAR_MODE |
 		DMA_CHAN_CFG_SRC_LINEAR_MODE |
 		DMA_CHAN_CFG_SRC_WIDTH(width) |
 		DMA_CHAN_CFG_DST_WIDTH(width);
 
 	sdev->cfg->set_burst_length(&v_lli->cfg, burst, burst);
+	sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, DRQ_SDRAM);
 
 	sun6i_dma_lli_add(NULL, v_lli, p_lli, txd);
 
@@ -695,9 +701,8 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 			v_lli->dst = sconfig->dst_addr;
 			v_lli->cfg = lli_cfg |
 				DMA_CHAN_CFG_DST_IO_MODE |
-				DMA_CHAN_CFG_SRC_LINEAR_MODE |
-				DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) |
-				DMA_CHAN_CFG_DST_DRQ(vchan->port);
+				DMA_CHAN_CFG_SRC_LINEAR_MODE;
+			sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port);
 
 			dev_dbg(chan2dev(chan),
 				"%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n",
@@ -710,9 +715,8 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 			v_lli->dst = sg_dma_address(sg);
 			v_lli->cfg = lli_cfg |
 				DMA_CHAN_CFG_DST_LINEAR_MODE |
-				DMA_CHAN_CFG_SRC_IO_MODE |
-				DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) |
-				DMA_CHAN_CFG_SRC_DRQ(vchan->port);
+				DMA_CHAN_CFG_SRC_IO_MODE;
+			sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM);
 
 			dev_dbg(chan2dev(chan),
 				"%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n",
@@ -780,17 +784,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
 			v_lli->dst = sconfig->dst_addr;
 			v_lli->cfg = lli_cfg |
 				DMA_CHAN_CFG_DST_IO_MODE |
-				DMA_CHAN_CFG_SRC_LINEAR_MODE |
-				DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) |
-				DMA_CHAN_CFG_DST_DRQ(vchan->port);
+				DMA_CHAN_CFG_SRC_LINEAR_MODE;
+			sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port);
 		} else {
 			v_lli->src = sconfig->src_addr;
 			v_lli->dst = buf_addr + period_len * i;
 			v_lli->cfg = lli_cfg |
 				DMA_CHAN_CFG_DST_LINEAR_MODE |
-				DMA_CHAN_CFG_SRC_IO_MODE |
-				DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) |
-				DMA_CHAN_CFG_SRC_DRQ(vchan->port);
+				DMA_CHAN_CFG_SRC_IO_MODE;
+			sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM);
 		}
 
 		prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd);
@@ -1055,6 +1057,7 @@ static struct sun6i_dma_config sun6i_a31_dma_cfg = {
 	.nr_max_requests = 30,
 	.nr_max_vchans   = 53,
 	.set_burst_length = sun6i_set_burst_length_a31,
+	.set_drq          = sun6i_set_drq_a31,
 	.src_burst_lengths = BIT(1) | BIT(8),
 	.dst_burst_lengths = BIT(1) | BIT(8),
 	.src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
@@ -1076,6 +1079,7 @@ static struct sun6i_dma_config sun8i_a23_dma_cfg = {
 	.nr_max_vchans   = 37,
 	.clock_autogate_enable = sun6i_enable_clock_autogate_a23,
 	.set_burst_length = sun6i_set_burst_length_a31,
+	.set_drq          = sun6i_set_drq_a31,
 	.src_burst_lengths = BIT(1) | BIT(8),
 	.dst_burst_lengths = BIT(1) | BIT(8),
 	.src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
@@ -1092,6 +1096,7 @@ static struct sun6i_dma_config sun8i_a83t_dma_cfg = {
 	.nr_max_vchans   = 39,
 	.clock_autogate_enable = sun6i_enable_clock_autogate_a23,
 	.set_burst_length = sun6i_set_burst_length_a31,
+	.set_drq          = sun6i_set_drq_a31,
 	.src_burst_lengths = BIT(1) | BIT(8),
 	.dst_burst_lengths = BIT(1) | BIT(8),
 	.src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
@@ -1115,6 +1120,7 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = {
 	.nr_max_vchans   = 34,
 	.clock_autogate_enable = sun6i_enable_clock_autogate_h3,
 	.set_burst_length = sun6i_set_burst_length_h3,
+	.set_drq          = sun6i_set_drq_a31,
 	.src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
 	.dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
 	.src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
@@ -1134,6 +1140,7 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = {
 static struct sun6i_dma_config sun50i_a64_dma_cfg = {
 	.clock_autogate_enable = sun6i_enable_clock_autogate_h3,
 	.set_burst_length = sun6i_set_burst_length_h3,
+	.set_drq          = sun6i_set_drq_a31,
 	.src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
 	.dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
 	.src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
@@ -1157,6 +1164,7 @@ static struct sun6i_dma_config sun8i_v3s_dma_cfg = {
 	.nr_max_vchans   = 24,
 	.clock_autogate_enable = sun6i_enable_clock_autogate_a23,
 	.set_burst_length = sun6i_set_burst_length_a31,
+	.set_drq          = sun6i_set_drq_a31,
 	.src_burst_lengths = BIT(1) | BIT(8),
 	.dst_burst_lengths = BIT(1) | BIT(8),
 	.src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
@@ -1272,8 +1280,8 @@ static int sun6i_dma_probe(struct platform_device *pdev)
 	ret = of_property_read_u32(np, "dma-requests", &sdc->max_request);
 	if (ret && !sdc->max_request) {
 		dev_info(&pdev->dev, "Missing dma-requests, using %u.\n",
-			 DMA_CHAN_MAX_DRQ);
-		sdc->max_request = DMA_CHAN_MAX_DRQ;
+			 DMA_CHAN_MAX_DRQ_A31);
+		sdc->max_request = DMA_CHAN_MAX_DRQ_A31;
 	}
 
 	/*
-- 
2.20.1


^ permalink raw reply related

* [PATCH v3 4/7] dmaengine: sun6i: Add a quirk for setting mode fields
From: Clément Péron @ 2019-05-27 20:14 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Mark Rutland, Maxime Ripard,
	Chen-Yu Tsai, Dan Williams
  Cc: dmaengine, devicetree, linux-arm-kernel, linux-kernel,
	Jernej Skrabec, Clément Péron
In-Reply-To: <20190527201459.20130-1-peron.clem@gmail.com>

From: Jernej Skrabec <jernej.skrabec@siol.net>

H6 DMA has mode fields in different position than any other currently
supported DMA controller.

Add a quirk for that.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
---
 drivers/dma/sun6i-dma.c | 46 ++++++++++++++++++++++++-----------------
 1 file changed, 27 insertions(+), 19 deletions(-)

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index f725b93fd21a..f5cb5e89bf7b 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -70,15 +70,13 @@
 #define DMA_CHAN_CUR_CFG	0x0c
 #define DMA_CHAN_MAX_DRQ_A31		0x1f
 #define DMA_CHAN_CFG_SRC_DRQ_A31(x)	((x) & DMA_CHAN_MAX_DRQ_A31)
-#define DMA_CHAN_CFG_SRC_IO_MODE	BIT(5)
-#define DMA_CHAN_CFG_SRC_LINEAR_MODE	(0 << 5)
+#define DMA_CHAN_CFG_SRC_MODE_A31(x)	(((x) & 0x1) << 5)
 #define DMA_CHAN_CFG_SRC_BURST_A31(x)	(((x) & 0x3) << 7)
 #define DMA_CHAN_CFG_SRC_BURST_H3(x)	(((x) & 0x3) << 6)
 #define DMA_CHAN_CFG_SRC_WIDTH(x)	(((x) & 0x3) << 9)
 
 #define DMA_CHAN_CFG_DST_DRQ_A31(x)	(DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16)
-#define DMA_CHAN_CFG_DST_IO_MODE	(DMA_CHAN_CFG_SRC_IO_MODE << 16)
-#define DMA_CHAN_CFG_DST_LINEAR_MODE	(DMA_CHAN_CFG_SRC_LINEAR_MODE << 16)
+#define DMA_CHAN_CFG_DST_MODE_A31(x)	(DMA_CHAN_CFG_SRC_MODE_A31(x) << 16)
 #define DMA_CHAN_CFG_DST_BURST_A31(x)	(DMA_CHAN_CFG_SRC_BURST_A31(x) << 16)
 #define DMA_CHAN_CFG_DST_BURST_H3(x)	(DMA_CHAN_CFG_SRC_BURST_H3(x) << 16)
 #define DMA_CHAN_CFG_DST_WIDTH(x)	(DMA_CHAN_CFG_SRC_WIDTH(x) << 16)
@@ -98,6 +96,8 @@
 #define LLI_LAST_ITEM	0xfffff800
 #define NORMAL_WAIT	8
 #define DRQ_SDRAM	1
+#define LINEAR_MODE     0
+#define IO_MODE         1
 
 /* forward declaration */
 struct sun6i_dma_dev;
@@ -126,6 +126,7 @@ struct sun6i_dma_config {
 	void (*clock_autogate_enable)(struct sun6i_dma_dev *);
 	void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst);
 	void (*set_drq)(u32 *p_cfg, s8 src_drq, s8 dst_drq);
+	void (*set_mode)(u32 *p_cfg, s8 src_mode, s8 dst_mode);
 	u32 src_burst_lengths;
 	u32 dst_burst_lengths;
 	u32 src_addr_widths;
@@ -318,6 +319,12 @@ static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq)
 		  DMA_CHAN_CFG_DST_DRQ_A31(dst_drq);
 }
 
+static void sun6i_set_mode_a31(u32 *p_cfg, s8 src_mode, s8 dst_mode)
+{
+	*p_cfg |= DMA_CHAN_CFG_SRC_MODE_A31(src_mode) |
+		  DMA_CHAN_CFG_DST_MODE_A31(dst_mode);
+}
+
 static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan)
 {
 	struct sun6i_desc *txd = pchan->desc;
@@ -641,13 +648,12 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
 
 	burst = convert_burst(8);
 	width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES);
-	v_lli->cfg = DMA_CHAN_CFG_DST_LINEAR_MODE |
-		DMA_CHAN_CFG_SRC_LINEAR_MODE |
-		DMA_CHAN_CFG_SRC_WIDTH(width) |
+	v_lli->cfg = DMA_CHAN_CFG_SRC_WIDTH(width) |
 		DMA_CHAN_CFG_DST_WIDTH(width);
 
 	sdev->cfg->set_burst_length(&v_lli->cfg, burst, burst);
 	sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, DRQ_SDRAM);
+	sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, LINEAR_MODE);
 
 	sun6i_dma_lli_add(NULL, v_lli, p_lli, txd);
 
@@ -699,10 +705,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 		if (dir == DMA_MEM_TO_DEV) {
 			v_lli->src = sg_dma_address(sg);
 			v_lli->dst = sconfig->dst_addr;
-			v_lli->cfg = lli_cfg |
-				DMA_CHAN_CFG_DST_IO_MODE |
-				DMA_CHAN_CFG_SRC_LINEAR_MODE;
+			v_lli->cfg = lli_cfg;
 			sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port);
+			sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE);
 
 			dev_dbg(chan2dev(chan),
 				"%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n",
@@ -713,10 +718,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 		} else {
 			v_lli->src = sconfig->src_addr;
 			v_lli->dst = sg_dma_address(sg);
-			v_lli->cfg = lli_cfg |
-				DMA_CHAN_CFG_DST_LINEAR_MODE |
-				DMA_CHAN_CFG_SRC_IO_MODE;
+			v_lli->cfg = lli_cfg;
 			sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM);
+			sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE);
 
 			dev_dbg(chan2dev(chan),
 				"%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n",
@@ -782,17 +786,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
 		if (dir == DMA_MEM_TO_DEV) {
 			v_lli->src = buf_addr + period_len * i;
 			v_lli->dst = sconfig->dst_addr;
-			v_lli->cfg = lli_cfg |
-				DMA_CHAN_CFG_DST_IO_MODE |
-				DMA_CHAN_CFG_SRC_LINEAR_MODE;
+			v_lli->cfg = lli_cfg;
 			sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port);
+			sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE);
 		} else {
 			v_lli->src = sconfig->src_addr;
 			v_lli->dst = buf_addr + period_len * i;
-			v_lli->cfg = lli_cfg |
-				DMA_CHAN_CFG_DST_LINEAR_MODE |
-				DMA_CHAN_CFG_SRC_IO_MODE;
+			v_lli->cfg = lli_cfg;
 			sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM);
+			sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE);
 		}
 
 		prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd);
@@ -1058,6 +1060,7 @@ static struct sun6i_dma_config sun6i_a31_dma_cfg = {
 	.nr_max_vchans   = 53,
 	.set_burst_length = sun6i_set_burst_length_a31,
 	.set_drq          = sun6i_set_drq_a31,
+	.set_mode         = sun6i_set_mode_a31,
 	.src_burst_lengths = BIT(1) | BIT(8),
 	.dst_burst_lengths = BIT(1) | BIT(8),
 	.src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
@@ -1080,6 +1083,7 @@ static struct sun6i_dma_config sun8i_a23_dma_cfg = {
 	.clock_autogate_enable = sun6i_enable_clock_autogate_a23,
 	.set_burst_length = sun6i_set_burst_length_a31,
 	.set_drq          = sun6i_set_drq_a31,
+	.set_mode         = sun6i_set_mode_a31,
 	.src_burst_lengths = BIT(1) | BIT(8),
 	.dst_burst_lengths = BIT(1) | BIT(8),
 	.src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
@@ -1097,6 +1101,7 @@ static struct sun6i_dma_config sun8i_a83t_dma_cfg = {
 	.clock_autogate_enable = sun6i_enable_clock_autogate_a23,
 	.set_burst_length = sun6i_set_burst_length_a31,
 	.set_drq          = sun6i_set_drq_a31,
+	.set_mode         = sun6i_set_mode_a31,
 	.src_burst_lengths = BIT(1) | BIT(8),
 	.dst_burst_lengths = BIT(1) | BIT(8),
 	.src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
@@ -1121,6 +1126,7 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = {
 	.clock_autogate_enable = sun6i_enable_clock_autogate_h3,
 	.set_burst_length = sun6i_set_burst_length_h3,
 	.set_drq          = sun6i_set_drq_a31,
+	.set_mode         = sun6i_set_mode_a31,
 	.src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
 	.dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
 	.src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
@@ -1141,6 +1147,7 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = {
 	.clock_autogate_enable = sun6i_enable_clock_autogate_h3,
 	.set_burst_length = sun6i_set_burst_length_h3,
 	.set_drq          = sun6i_set_drq_a31,
+	.set_mode         = sun6i_set_mode_a31,
 	.src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
 	.dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
 	.src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
@@ -1165,6 +1172,7 @@ static struct sun6i_dma_config sun8i_v3s_dma_cfg = {
 	.clock_autogate_enable = sun6i_enable_clock_autogate_a23,
 	.set_burst_length = sun6i_set_burst_length_a31,
 	.set_drq          = sun6i_set_drq_a31,
+	.set_mode         = sun6i_set_mode_a31,
 	.src_burst_lengths = BIT(1) | BIT(8),
 	.dst_burst_lengths = BIT(1) | BIT(8),
 	.src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
-- 
2.20.1


^ permalink raw reply related

* [PATCH v3 6/7] arm64: dts: allwinner: h6: Add DMA node
From: Clément Péron @ 2019-05-27 20:14 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Mark Rutland, Maxime Ripard,
	Chen-Yu Tsai, Dan Williams
  Cc: dmaengine, devicetree, linux-arm-kernel, linux-kernel,
	Jernej Skrabec, Clément Péron
In-Reply-To: <20190527201459.20130-1-peron.clem@gmail.com>

From: Jernej Skrabec <jernej.skrabec@siol.net>

H6 has DMA controller which supports 16 channels.

Add a node for it.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 16c5c3d0fd81..f4ea596c82ce 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -208,6 +208,18 @@
 			reg = <0x03006000 0x400>;
 		};
 
+		dma: dma-controller@3002000 {
+			compatible = "allwinner,sun50i-h6-dma";
+			reg = <0x03002000 0x1000>;
+			interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_DMA>, <&ccu CLK_MBUS_DMA>;
+			clock-names = "bus", "mbus";
+			dma-channels = <16>;
+			dma-requests = <46>;
+			resets = <&ccu RST_BUS_DMA>;
+			#dma-cells = <1>;
+		};
+
 		pio: pinctrl@300b000 {
 			compatible = "allwinner,sun50i-h6-pinctrl";
 			reg = <0x0300b000 0x400>;
-- 
2.20.1


^ permalink raw reply related

* [PATCH v3 5/7] dmaengine: sun6i: Add support for H6 DMA
From: Clément Péron @ 2019-05-27 20:14 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Mark Rutland, Maxime Ripard,
	Chen-Yu Tsai, Dan Williams
  Cc: dmaengine, devicetree, linux-arm-kernel, linux-kernel,
	Jernej Skrabec, Clément Péron
In-Reply-To: <20190527201459.20130-1-peron.clem@gmail.com>

From: Jernej Skrabec <jernej.skrabec@siol.net>

H6 DMA has more than 32 supported DRQs, which means that configuration
register is slightly rearranged. It also needs additional clock to be
enabled.

Add support for it.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
---
 drivers/dma/sun6i-dma.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index f5cb5e89bf7b..ddef87ebdfdb 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -69,14 +69,19 @@
 
 #define DMA_CHAN_CUR_CFG	0x0c
 #define DMA_CHAN_MAX_DRQ_A31		0x1f
+#define DMA_CHAN_MAX_DRQ_H6		0x3f
 #define DMA_CHAN_CFG_SRC_DRQ_A31(x)	((x) & DMA_CHAN_MAX_DRQ_A31)
+#define DMA_CHAN_CFG_SRC_DRQ_H6(x)	((x) & DMA_CHAN_MAX_DRQ_H6)
 #define DMA_CHAN_CFG_SRC_MODE_A31(x)	(((x) & 0x1) << 5)
+#define DMA_CHAN_CFG_SRC_MODE_H6(x)	(((x) & 0x1) << 8)
 #define DMA_CHAN_CFG_SRC_BURST_A31(x)	(((x) & 0x3) << 7)
 #define DMA_CHAN_CFG_SRC_BURST_H3(x)	(((x) & 0x3) << 6)
 #define DMA_CHAN_CFG_SRC_WIDTH(x)	(((x) & 0x3) << 9)
 
 #define DMA_CHAN_CFG_DST_DRQ_A31(x)	(DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16)
+#define DMA_CHAN_CFG_DST_DRQ_H6(x)	(DMA_CHAN_CFG_SRC_DRQ_H6(x) << 16)
 #define DMA_CHAN_CFG_DST_MODE_A31(x)	(DMA_CHAN_CFG_SRC_MODE_A31(x) << 16)
+#define DMA_CHAN_CFG_DST_MODE_H6(x)	(DMA_CHAN_CFG_SRC_MODE_H6(x) << 16)
 #define DMA_CHAN_CFG_DST_BURST_A31(x)	(DMA_CHAN_CFG_SRC_BURST_A31(x) << 16)
 #define DMA_CHAN_CFG_DST_BURST_H3(x)	(DMA_CHAN_CFG_SRC_BURST_H3(x) << 16)
 #define DMA_CHAN_CFG_DST_WIDTH(x)	(DMA_CHAN_CFG_SRC_WIDTH(x) << 16)
@@ -319,12 +324,24 @@ static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq)
 		  DMA_CHAN_CFG_DST_DRQ_A31(dst_drq);
 }
 
+static void sun6i_set_drq_h6(u32 *p_cfg, s8 src_drq, s8 dst_drq)
+{
+	*p_cfg |= DMA_CHAN_CFG_SRC_DRQ_H6(src_drq) |
+		  DMA_CHAN_CFG_DST_DRQ_H6(dst_drq);
+}
+
 static void sun6i_set_mode_a31(u32 *p_cfg, s8 src_mode, s8 dst_mode)
 {
 	*p_cfg |= DMA_CHAN_CFG_SRC_MODE_A31(src_mode) |
 		  DMA_CHAN_CFG_DST_MODE_A31(dst_mode);
 }
 
+static void sun6i_set_mode_h6(u32 *p_cfg, s8 src_mode, s8 dst_mode)
+{
+	*p_cfg |= DMA_CHAN_CFG_SRC_MODE_H6(src_mode) |
+		  DMA_CHAN_CFG_DST_MODE_H6(dst_mode);
+}
+
 static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan)
 {
 	struct sun6i_desc *txd = pchan->desc;
@@ -1160,6 +1177,28 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = {
 			     BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
 };
 
+/*
+ * The H6 binding uses the number of dma channels from the
+ * device tree node.
+ */
+static struct sun6i_dma_config sun50i_h6_dma_cfg = {
+	.clock_autogate_enable = sun6i_enable_clock_autogate_h3,
+	.set_burst_length = sun6i_set_burst_length_h3,
+	.set_drq          = sun6i_set_drq_h6,
+	.set_mode         = sun6i_set_mode_h6,
+	.src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
+	.dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
+	.src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
+			     BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
+			     BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
+			     BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
+	.dst_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
+			     BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
+			     BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
+			     BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
+	.has_mbus_clk = true,
+};
+
 /*
  * The V3s have only 8 physical channels, a maximum DRQ port id of 23,
  * and a total of 24 usable source and destination endpoints.
@@ -1190,6 +1229,7 @@ static const struct of_device_id sun6i_dma_match[] = {
 	{ .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg },
 	{ .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg },
 	{ .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg },
+	{ .compatible = "allwinner,sun50i-h6-dma", .data = &sun50i_h6_dma_cfg },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sun6i_dma_match);
-- 
2.20.1


^ permalink raw reply related

* [PATCH v3 7/7] arm64: defconfig: enable Allwinner DMA drivers
From: Clément Péron @ 2019-05-27 20:14 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Mark Rutland, Maxime Ripard,
	Chen-Yu Tsai, Dan Williams
  Cc: dmaengine, devicetree, linux-arm-kernel, linux-kernel,
	Clément Péron
In-Reply-To: <20190527201459.20130-1-peron.clem@gmail.com>

Allwinner sun6i DMA drivers is used on A64 and H6 boards.

Enable it as a module.

Signed-off-by: Clément Péron <peron.clem@gmail.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 4d583514258c..b535f0f412cc 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -614,6 +614,7 @@ CONFIG_RTC_DRV_IMX_SC=m
 CONFIG_RTC_DRV_XGENE=y
 CONFIG_DMADEVICES=y
 CONFIG_DMA_BCM2835=m
+CONFIG_DMA_SUN6I=m
 CONFIG_K3_DMA=y
 CONFIG_MV_XOR=y
 CONFIG_MV_XOR_V2=y
-- 
2.20.1


^ permalink raw reply related

* Re: [PATCH] dmaengine: use to_platform_device()
From: Vinod Koul @ 2019-05-27 13:27 UTC (permalink / raw)
  To: Weitao Hou
  Cc: dan.j.williams, mcoquelin.stm32, alexandre.torgue, dmaengine,
	linux-stm32, linux-arm-kernel, linux-kernel
In-Reply-To: <CAK98mP9teTxZn9mMZ_yXSmC7h8gimgN14kX=GT0Q43O58zC-rw@mail.gmail.com>

Hi Weitao,

On 27-05-19, 21:10, Weitao Hou wrote:
> Hi,Vinod
>     Need I add the stm32 driver tag and resend v2 patch?

Please do not top post!

As below says, the patch is applied and I corrected the tag and added
stm32 while applying, so no change or v2 required.

> Vinod Koul <vkoul@kernel.org> 于2019年5月27日周一 下午2:43写道:
> 
> > On 26-05-19, 15:13, Weitao Hou wrote:
> > > Use to_platform_device() instead of open-coding it.
> >
> > Applied after adding stm32 driver tag, thanks
> >
> > --
> > ~Vinod
> >

-- 
~Vinod

^ permalink raw reply

* Re: [PATCH v2 5/7] dmaengine: sun6i: Add support for H6 DMA
From: Maxime Ripard @ 2019-05-27 12:49 UTC (permalink / raw)
  To: Clément Péron
  Cc: Vinod Koul, Rob Herring, Mark Rutland, Chen-Yu Tsai, Dan Williams,
	dmaengine, devicetree, linux-arm-kernel, linux-kernel,
	Jernej Skrabec
In-Reply-To: <CAJiuCcfe7LHehZTzGvW+0LzqvDRs4dSjmGhRxkDHgbHrD2+MKA@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 6192 bytes --]

On Sun, May 26, 2019 at 09:12:36PM +0200, Clément Péron wrote:
> Hi Maxime,
>
> On Sun, 26 May 2019 at 20:34, Maxime Ripard <maxime.ripard@bootlin.com> wrote:
> >
> > On Sat, May 25, 2019 at 06:38:17PM +0200, Clément Péron wrote:
> > > From: Jernej Skrabec <jernej.skrabec@siol.net>
> > >
> > > H6 DMA has more than 32 supported DRQs, which means that configuration
> > > register is slightly rearranged. It also needs additional clock to be
> > > enabled.
> > >
> > > Add support for it.
> > >
> > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > Signed-off-by: Clément Péron <peron.clem@gmail.com>
> > > ---
> > >  drivers/dma/sun6i-dma.c | 44 +++++++++++++++++++++++++++++++++++++++--
> > >  1 file changed, 42 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > index f5cb5e89bf7b..8d44ddae926a 100644
> > > --- a/drivers/dma/sun6i-dma.c
> > > +++ b/drivers/dma/sun6i-dma.c
> > > @@ -69,14 +69,19 @@
> > >
> > >  #define DMA_CHAN_CUR_CFG     0x0c
> > >  #define DMA_CHAN_MAX_DRQ_A31         0x1f
> > > +#define DMA_CHAN_MAX_DRQ_H6          0x3f
> > >  #define DMA_CHAN_CFG_SRC_DRQ_A31(x)  ((x) & DMA_CHAN_MAX_DRQ_A31)
> > > +#define DMA_CHAN_CFG_SRC_DRQ_H6(x)   ((x) & DMA_CHAN_MAX_DRQ_H6)
> > >  #define DMA_CHAN_CFG_SRC_MODE_A31(x) (((x) & 0x1) << 5)
> > > +#define DMA_CHAN_CFG_SRC_MODE_H6(x)  (((x) & 0x1) << 8)
> > >  #define DMA_CHAN_CFG_SRC_BURST_A31(x)        (((x) & 0x3) << 7)
> > >  #define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6)
> > >  #define DMA_CHAN_CFG_SRC_WIDTH(x)    (((x) & 0x3) << 9)
> > >
> > >  #define DMA_CHAN_CFG_DST_DRQ_A31(x)  (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16)
> > > +#define DMA_CHAN_CFG_DST_DRQ_H6(x)   (DMA_CHAN_CFG_SRC_DRQ_H6(x) << 16)
> > >  #define DMA_CHAN_CFG_DST_MODE_A31(x) (DMA_CHAN_CFG_SRC_MODE_A31(x) << 16)
> > > +#define DMA_CHAN_CFG_DST_MODE_H6(x)  (DMA_CHAN_CFG_SRC_MODE_H6(x) << 16)
> > >  #define DMA_CHAN_CFG_DST_BURST_A31(x)        (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16)
> > >  #define DMA_CHAN_CFG_DST_BURST_H3(x) (DMA_CHAN_CFG_SRC_BURST_H3(x) << 16)
> > >  #define DMA_CHAN_CFG_DST_WIDTH(x)    (DMA_CHAN_CFG_SRC_WIDTH(x) << 16)
> > > @@ -319,12 +324,24 @@ static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq)
> > >                 DMA_CHAN_CFG_DST_DRQ_A31(dst_drq);
> > >  }
> > >
> > > +static void sun6i_set_drq_h6(u32 *p_cfg, s8 src_drq, s8 dst_drq)
> > > +{
> > > +     *p_cfg |= DMA_CHAN_CFG_SRC_DRQ_H6(src_drq) |
> > > +               DMA_CHAN_CFG_DST_DRQ_H6(dst_drq);
> > > +}
> > > +
> > >  static void sun6i_set_mode_a31(u32 *p_cfg, s8 src_mode, s8 dst_mode)
> > >  {
> > >       *p_cfg |= DMA_CHAN_CFG_SRC_MODE_A31(src_mode) |
> > >                 DMA_CHAN_CFG_DST_MODE_A31(dst_mode);
> > >  }
> > >
> > > +static void sun6i_set_mode_h6(u32 *p_cfg, s8 src_mode, s8 dst_mode)
> > > +{
> > > +     *p_cfg |= DMA_CHAN_CFG_SRC_MODE_H6(src_mode) |
> > > +               DMA_CHAN_CFG_DST_MODE_H6(dst_mode);
> > > +}
> > > +
> > >  static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan)
> > >  {
> > >       struct sun6i_desc *txd = pchan->desc;
> > > @@ -1160,6 +1177,28 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = {
> > >                            BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
> > >  };
> > >
> > > +/*
> > > + * The H6 binding uses the number of dma channels from the
> > > + * device tree node.
> > > + */
> > > +static struct sun6i_dma_config sun50i_h6_dma_cfg = {
> > > +     .clock_autogate_enable = sun6i_enable_clock_autogate_h3,
> > > +     .set_burst_length = sun6i_set_burst_length_h3,
> > > +     .set_drq          = sun6i_set_drq_h6,
> > > +     .set_mode         = sun6i_set_mode_h6,
> > > +     .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
> > > +     .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
> > > +     .src_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> > > +                          BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> > > +                          BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
> > > +                          BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
> > > +     .dst_addr_widths   = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> > > +                          BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> > > +                          BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
> > > +                          BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
> > > +     .has_mbus_clk = true,
> > > +};
> > > +
> > >  /*
> > >   * The V3s have only 8 physical channels, a maximum DRQ port id of 23,
> > >   * and a total of 24 usable source and destination endpoints.
> > > @@ -1190,6 +1229,7 @@ static const struct of_device_id sun6i_dma_match[] = {
> > >       { .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg },
> > >       { .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg },
> > >       { .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg },
> > > +     { .compatible = "allwinner,sun50i-h6-dma", .data = &sun50i_h6_dma_cfg },
> > >       { /* sentinel */ }
> > >  };
> > >  MODULE_DEVICE_TABLE(of, sun6i_dma_match);
> > > @@ -1288,8 +1328,8 @@ static int sun6i_dma_probe(struct platform_device *pdev)
> > >       ret = of_property_read_u32(np, "dma-requests", &sdc->max_request);
> > >       if (ret && !sdc->max_request) {
> > >               dev_info(&pdev->dev, "Missing dma-requests, using %u.\n",
> > > -                      DMA_CHAN_MAX_DRQ_A31);
> > > -             sdc->max_request = DMA_CHAN_MAX_DRQ_A31;
> > > +                      DMA_CHAN_MAX_DRQ_H6);
> > > +             sdc->max_request = DMA_CHAN_MAX_DRQ_H6;
> >
> > This is changing the binding though, since we're changing the
> > default. This should be reflected in the binding, and we should keep
> > the same default in the device tree binding.
>
> Agree, H6 device-tree will have the "dma-request" property.
> As this modification is not mandatory, we can drop it to avoid
> bindings modification.
>
> What do you think?

That works for me

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH v2 6/7] dmaengine: fsl-edma: add i.mx7ulp edma2 version support
From: Vinod Koul @ 2019-05-27 10:10 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: yibin.gong, robh, shawnguo, festevam, mark.rutland,
	dan.j.williams, devicetree, linux-kernel, linux-imx, kernel,
	dmaengine, linux-arm-kernel
In-Reply-To: <20190527090553.lek7tm3lyst3bhrd@pengutronix.de>

On 27-05-19, 11:05, Sascha Hauer wrote:
> On Mon, May 27, 2019 at 04:51:17PM +0800, yibin.gong@nxp.com wrote:
> > From: Robin Gong <yibin.gong@nxp.com>
> > 
> > +static const struct of_device_id fsl_edma_dt_ids[] = {
> > +	{ .compatible = "fsl,vf610-edma", .data = (void *)v1 },
> > +	{ .compatible = "fsl,imx7ulp-edma", .data = (void *)v3 },
> > +	{ /* sentinel */ }
> 
> Please put a struct type behind the .data pointer so that you can
> configure...

Yeah that was the idea behind the suggestion in previous version.

Something like 

struct fsl_edma_driver_data {
        unsigned int channels;
        ...
};

and then you have

const struct fsl_edma_driver_data v1_data {
        .channels = 1;
        ...
};

> 
> > +};
> > +MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
> > +
> > @@ -218,6 +272,22 @@ static int fsl_edma_probe(struct platform_device *pdev)
> >  	fsl_edma_setup_regs(fsl_edma);
> >  	regs = &fsl_edma->regs;
> >  
> > +	if (fsl_edma->version == v3) {
> > +		fsl_edma->dmamux_nr = 1;

You can store the struct in driver context or store the values, so here
it becomes

        driver->data->channel;

and so on for other data, you can also point function pointers (hint
edma/2_irq_init)

> 
> ...things like this...
> 
> > @@ -264,7 +334,11 @@ static int fsl_edma_probe(struct platform_device *pdev)
> >  	}
> >  
> >  	edma_writel(fsl_edma, ~0, regs->intl);
> > -	ret = fsl_edma_irq_init(pdev, fsl_edma);
> > +
> > +	if (fsl_edma->version == v3)
> > +		ret = fsl_edma2_irq_init(pdev, fsl_edma);
> > +	else
> > +		ret = fsl_edma_irq_init(pdev, fsl_edma);
> 
> ...and this one in that struct rather than littering the code more and
> more with such version tests.
> 
> Sascha
> 
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

-- 
~Vinod

^ permalink raw reply

* Re: [PATCH v2 6/7] dmaengine: fsl-edma: add i.mx7ulp edma2 version support
From: Robin Gong @ 2019-05-27 10:04 UTC (permalink / raw)
  To: s.hauer@pengutronix.de
  Cc: dl-linux-imx, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org, festevam@gmail.com,
	dan.j.williams@intel.com, mark.rutland@arm.com,
	dmaengine@vger.kernel.org, robh@kernel.org, shawnguo@kernel.org,
	linux-arm-kernel@lists.infradead.org, vkoul@kernel.org,
	kernel@pengutronix.de
In-Reply-To: <20190527090553.lek7tm3lyst3bhrd@pengutronix.de>

On 2019-05-27 at 11:05 +0200, Sascha Hauer wrote:
> On Mon, May 27, 2019 at 04:51:17PM +0800, yibin.gong@nxp.com wrote:
> > 
> > From: Robin Gong <yibin.gong@nxp.com>
> > 
> > +static const struct of_device_id fsl_edma_dt_ids[] = {
> > +	{ .compatible = "fsl,vf610-edma", .data = (void *)v1 },
> > +	{ .compatible = "fsl,imx7ulp-edma", .data = (void *)v3 },
> > +	{ /* sentinel */ }
> Please put a struct type behind the .data pointer so that you can
> configure...
But current only version needed, so I give up struct define....
> 
> > 
> > +};
> > +MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
> > +
> > @@ -218,6 +272,22 @@ static int fsl_edma_probe(struct
> > platform_device *pdev)
> >  	fsl_edma_setup_regs(fsl_edma);
> >  	regs = &fsl_edma->regs;
> >  
> > +	if (fsl_edma->version == v3) {
> > +		fsl_edma->dmamux_nr = 1;
> ...things like this...
Yes, dmamux_nr could be moved to struct at least.
> 
> > 
> > @@ -264,7 +334,11 @@ static int fsl_edma_probe(struct
> > platform_device *pdev)
> >  	}
> >  
> >  	edma_writel(fsl_edma, ~0, regs->intl);
> > -	ret = fsl_edma_irq_init(pdev, fsl_edma);
> > +
> > +	if (fsl_edma->version == v3)
> > +		ret = fsl_edma2_irq_init(pdev, fsl_edma);
> > +	else
> > +		ret = fsl_edma_irq_init(pdev, fsl_edma);
> ...and this one in that struct rather than littering the code more
> and
> more with such version tests.
Yes, such irq setup function could be moved to struct, thus, no version
test in this file. Will refine it in v3.
> 
> Sascha
> 

^ permalink raw reply

* Re: [PATCH v2 4/7] dmaengine: fsl-edma-common: version check for v2 instead
From: Robin Gong @ 2019-05-27  9:52 UTC (permalink / raw)
  To: s.hauer@pengutronix.de
  Cc: dl-linux-imx, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org, festevam@gmail.com,
	dan.j.williams@intel.com, mark.rutland@arm.com,
	dmaengine@vger.kernel.org, robh@kernel.org, shawnguo@kernel.org,
	linux-arm-kernel@lists.infradead.org, vkoul@kernel.org,
	kernel@pengutronix.de
In-Reply-To: <20190527090814.qfjiksqi24x2jrs3@pengutronix.de>

On 2019-05-27 at 09:08 +0000, Sascha Hauer wrote:
> On Mon, May 27, 2019 at 04:51:15PM +0800, yibin.gong@nxp.com wrote:
> > 
> > From: Robin Gong <yibin.gong@nxp.com>
> > 
> > The next v3 i.mx7ulp edma is based on v1, so change version
> > check logic for v2 instead.
> > 
> > Signed-off-by: Robin Gong <yibin.gong@nxp.com>
> > ---
> >  drivers/dma/fsl-edma-common.c | 40 ++++++++++++++++++++-----------
> > ---------
> >  1 file changed, 20 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-
> > common.c
> > index bb24251..45d70d3 100644
> > --- a/drivers/dma/fsl-edma-common.c
> > +++ b/drivers/dma/fsl-edma-common.c
> > @@ -657,26 +657,26 @@ void fsl_edma_setup_regs(struct
> > fsl_edma_engine *edma)
> >  	edma->regs.erql = edma->membase + EDMA_ERQ;
> >  	edma->regs.eeil = edma->membase + EDMA_EEI;
> >  
> > -	edma->regs.serq = edma->membase + ((edma->version == v1) ?
> > -			EDMA_SERQ : EDMA64_SERQ);
> > -	edma->regs.cerq = edma->membase + ((edma->version == v1) ?
> > -			EDMA_CERQ : EDMA64_CERQ);
> > -	edma->regs.seei = edma->membase + ((edma->version == v1) ?
> > -			EDMA_SEEI : EDMA64_SEEI);
> > -	edma->regs.ceei = edma->membase + ((edma->version == v1) ?
> > -			EDMA_CEEI : EDMA64_CEEI);
> > -	edma->regs.cint = edma->membase + ((edma->version == v1) ?
> > -			EDMA_CINT : EDMA64_CINT);
> > -	edma->regs.cerr = edma->membase + ((edma->version == v1) ?
> > -			EDMA_CERR : EDMA64_CERR);
> > -	edma->regs.ssrt = edma->membase + ((edma->version == v1) ?
> > -			EDMA_SSRT : EDMA64_SSRT);
> > -	edma->regs.cdne = edma->membase + ((edma->version == v1) ?
> > -			EDMA_CDNE : EDMA64_CDNE);
> > -	edma->regs.intl = edma->membase + ((edma->version == v1) ?
> > -			EDMA_INTR : EDMA64_INTL);
> > -	edma->regs.errl = edma->membase + ((edma->version == v1) ?
> > -			EDMA_ERR : EDMA64_ERRL);
> > +	edma->regs.serq = edma->membase + ((edma->version == v2) ?
> > +			EDMA64_SERQ : EDMA_SERQ);
> > +	edma->regs.cerq = edma->membase + ((edma->version == v2) ?
> > +			EDMA64_CERQ : EDMA_CERQ);
> > +	edma->regs.seei = edma->membase + ((edma->version == v2) ?
> > +			EDMA64_SEEI : EDMA_SEEI);
> > +	edma->regs.ceei = edma->membase + ((edma->version == v2) ?
> > +			EDMA64_CEEI : EDMA_CEEI);
> > +	edma->regs.cint = edma->membase + ((edma->version == v2) ?
> > +			EDMA64_CINT : EDMA_CINT);
> > +	edma->regs.cerr = edma->membase + ((edma->version == v2) ?
> > +			EDMA64_CERR : EDMA_CERR);
> > +	edma->regs.ssrt = edma->membase + ((edma->version == v2) ?
> > +			EDMA64_SSRT : EDMA_SSRT);
> > +	edma->regs.cdne = edma->membase + ((edma->version == v2) ?
> > +			EDMA64_CDNE : EDMA_CDNE);
> > +	edma->regs.intl = edma->membase + ((edma->version == v2) ?
> > +			EDMA64_INTL : EDMA_INTR);
> > +	edma->regs.errl = edma->membase + ((edma->version == v2) ?
> > +			EDMA64_ERRL : EDMA_ERR);
> Following to what I have said to 6/7 you can put the register offsets
> into that new struct aswell.
> 
> Sascha
Understood your point, but the logic of fsl-edma-common.c is the common
functions array provided to be called in fsl-edma.c or mcf-edma.c, not
different specific functions in fsl-edma.c or mcf-edma.c.   
> 

^ permalink raw reply

* Re: [PATCH v2 4/7] dmaengine: fsl-edma-common: version check for v2 instead
From: Sascha Hauer @ 2019-05-27  9:08 UTC (permalink / raw)
  To: yibin.gong
  Cc: robh, shawnguo, festevam, mark.rutland, vkoul, dan.j.williams,
	linux-imx, linux-arm-kernel, linux-kernel, dmaengine, devicetree,
	kernel
In-Reply-To: <20190527085118.40423-5-yibin.gong@nxp.com>

On Mon, May 27, 2019 at 04:51:15PM +0800, yibin.gong@nxp.com wrote:
> From: Robin Gong <yibin.gong@nxp.com>
> 
> The next v3 i.mx7ulp edma is based on v1, so change version
> check logic for v2 instead.
> 
> Signed-off-by: Robin Gong <yibin.gong@nxp.com>
> ---
>  drivers/dma/fsl-edma-common.c | 40 ++++++++++++++++++++--------------------
>  1 file changed, 20 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
> index bb24251..45d70d3 100644
> --- a/drivers/dma/fsl-edma-common.c
> +++ b/drivers/dma/fsl-edma-common.c
> @@ -657,26 +657,26 @@ void fsl_edma_setup_regs(struct fsl_edma_engine *edma)
>  	edma->regs.erql = edma->membase + EDMA_ERQ;
>  	edma->regs.eeil = edma->membase + EDMA_EEI;
>  
> -	edma->regs.serq = edma->membase + ((edma->version == v1) ?
> -			EDMA_SERQ : EDMA64_SERQ);
> -	edma->regs.cerq = edma->membase + ((edma->version == v1) ?
> -			EDMA_CERQ : EDMA64_CERQ);
> -	edma->regs.seei = edma->membase + ((edma->version == v1) ?
> -			EDMA_SEEI : EDMA64_SEEI);
> -	edma->regs.ceei = edma->membase + ((edma->version == v1) ?
> -			EDMA_CEEI : EDMA64_CEEI);
> -	edma->regs.cint = edma->membase + ((edma->version == v1) ?
> -			EDMA_CINT : EDMA64_CINT);
> -	edma->regs.cerr = edma->membase + ((edma->version == v1) ?
> -			EDMA_CERR : EDMA64_CERR);
> -	edma->regs.ssrt = edma->membase + ((edma->version == v1) ?
> -			EDMA_SSRT : EDMA64_SSRT);
> -	edma->regs.cdne = edma->membase + ((edma->version == v1) ?
> -			EDMA_CDNE : EDMA64_CDNE);
> -	edma->regs.intl = edma->membase + ((edma->version == v1) ?
> -			EDMA_INTR : EDMA64_INTL);
> -	edma->regs.errl = edma->membase + ((edma->version == v1) ?
> -			EDMA_ERR : EDMA64_ERRL);
> +	edma->regs.serq = edma->membase + ((edma->version == v2) ?
> +			EDMA64_SERQ : EDMA_SERQ);
> +	edma->regs.cerq = edma->membase + ((edma->version == v2) ?
> +			EDMA64_CERQ : EDMA_CERQ);
> +	edma->regs.seei = edma->membase + ((edma->version == v2) ?
> +			EDMA64_SEEI : EDMA_SEEI);
> +	edma->regs.ceei = edma->membase + ((edma->version == v2) ?
> +			EDMA64_CEEI : EDMA_CEEI);
> +	edma->regs.cint = edma->membase + ((edma->version == v2) ?
> +			EDMA64_CINT : EDMA_CINT);
> +	edma->regs.cerr = edma->membase + ((edma->version == v2) ?
> +			EDMA64_CERR : EDMA_CERR);
> +	edma->regs.ssrt = edma->membase + ((edma->version == v2) ?
> +			EDMA64_SSRT : EDMA_SSRT);
> +	edma->regs.cdne = edma->membase + ((edma->version == v2) ?
> +			EDMA64_CDNE : EDMA_CDNE);
> +	edma->regs.intl = edma->membase + ((edma->version == v2) ?
> +			EDMA64_INTL : EDMA_INTR);
> +	edma->regs.errl = edma->membase + ((edma->version == v2) ?
> +			EDMA64_ERRL : EDMA_ERR);

Following to what I have said to 6/7 you can put the register offsets
into that new struct aswell.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* Re: [PATCH v2 6/7] dmaengine: fsl-edma: add i.mx7ulp edma2 version support
From: Sascha Hauer @ 2019-05-27  9:05 UTC (permalink / raw)
  To: yibin.gong
  Cc: robh, shawnguo, festevam, mark.rutland, vkoul, dan.j.williams,
	devicetree, linux-kernel, linux-imx, kernel, dmaengine,
	linux-arm-kernel
In-Reply-To: <20190527085118.40423-7-yibin.gong@nxp.com>

On Mon, May 27, 2019 at 04:51:17PM +0800, yibin.gong@nxp.com wrote:
> From: Robin Gong <yibin.gong@nxp.com>
> 
> +static const struct of_device_id fsl_edma_dt_ids[] = {
> +	{ .compatible = "fsl,vf610-edma", .data = (void *)v1 },
> +	{ .compatible = "fsl,imx7ulp-edma", .data = (void *)v3 },
> +	{ /* sentinel */ }

Please put a struct type behind the .data pointer so that you can
configure...

> +};
> +MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
> +
> @@ -218,6 +272,22 @@ static int fsl_edma_probe(struct platform_device *pdev)
>  	fsl_edma_setup_regs(fsl_edma);
>  	regs = &fsl_edma->regs;
>  
> +	if (fsl_edma->version == v3) {
> +		fsl_edma->dmamux_nr = 1;

...things like this...

> @@ -264,7 +334,11 @@ static int fsl_edma_probe(struct platform_device *pdev)
>  	}
>  
>  	edma_writel(fsl_edma, ~0, regs->intl);
> -	ret = fsl_edma_irq_init(pdev, fsl_edma);
> +
> +	if (fsl_edma->version == v3)
> +		ret = fsl_edma2_irq_init(pdev, fsl_edma);
> +	else
> +		ret = fsl_edma_irq_init(pdev, fsl_edma);

...and this one in that struct rather than littering the code more and
more with such version tests.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* [PATCH v2 1/7] dmaengine: fsl-edma: add dmamux_nr for next version
From: yibin.gong @ 2019-05-27  8:51 UTC (permalink / raw)
  To: robh, shawnguo, s.hauer, festevam, mark.rutland, vkoul,
	dan.j.williams
  Cc: linux-imx, linux-arm-kernel, linux-kernel, dmaengine, devicetree,
	kernel
In-Reply-To: <20190527085118.40423-1-yibin.gong@nxp.com>

From: Robin Gong <yibin.gong@nxp.com>

Next version of edma such as edmav2 on i.mx7ulp has only one dmamux.
Add dmamux_nr instead of static macro define 'DMAMUX_NR'. No any
function change here.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
---
 drivers/dma/fsl-edma-common.h |  1 +
 drivers/dma/fsl-edma.c        | 11 ++++++-----
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h
index c53f76e..21a9cfd 100644
--- a/drivers/dma/fsl-edma-common.h
+++ b/drivers/dma/fsl-edma-common.h
@@ -145,6 +145,7 @@ struct fsl_edma_engine {
 	void __iomem		*membase;
 	void __iomem		*muxbase[DMAMUX_NR];
 	struct clk		*muxclk[DMAMUX_NR];
+	u32			dmamux_nr;
 	struct mutex		fsl_edma_mutex;
 	u32			n_chans;
 	int			txirq;
diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
index d641ef8..7b65ef4 100644
--- a/drivers/dma/fsl-edma.c
+++ b/drivers/dma/fsl-edma.c
@@ -96,7 +96,7 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
 	struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
 	struct dma_chan *chan, *_chan;
 	struct fsl_edma_chan *fsl_chan;
-	unsigned long chans_per_mux = fsl_edma->n_chans / DMAMUX_NR;
+	unsigned long chans_per_mux = fsl_edma->n_chans / fsl_edma->dmamux_nr;
 
 	if (dma_spec->args_count != 2)
 		return NULL;
@@ -206,6 +206,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	fsl_edma->version = v1;
+	fsl_edma->dmamux_nr = DMAMUX_NR;
 	fsl_edma->n_chans = chans;
 	mutex_init(&fsl_edma->fsl_edma_mutex);
 
@@ -217,7 +218,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
 	fsl_edma_setup_regs(fsl_edma);
 	regs = &fsl_edma->regs;
 
-	for (i = 0; i < DMAMUX_NR; i++) {
+	for (i = 0; i < fsl_edma->dmamux_nr; i++) {
 		char clkname[32];
 
 		res = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i);
@@ -295,7 +296,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
 	if (ret) {
 		dev_err(&pdev->dev,
 			"Can't register Freescale eDMA engine. (%d)\n", ret);
-		fsl_disable_clocks(fsl_edma, DMAMUX_NR);
+		fsl_disable_clocks(fsl_edma, fsl_edma->dmamux_nr);
 		return ret;
 	}
 
@@ -304,7 +305,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev,
 			"Can't register Freescale eDMA of_dma. (%d)\n", ret);
 		dma_async_device_unregister(&fsl_edma->dma_dev);
-		fsl_disable_clocks(fsl_edma, DMAMUX_NR);
+		fsl_disable_clocks(fsl_edma, fsl_edma->dmamux_nr);
 		return ret;
 	}
 
@@ -323,7 +324,7 @@ static int fsl_edma_remove(struct platform_device *pdev)
 	fsl_edma_cleanup_vchan(&fsl_edma->dma_dev);
 	of_dma_controller_free(np);
 	dma_async_device_unregister(&fsl_edma->dma_dev);
-	fsl_disable_clocks(fsl_edma, DMAMUX_NR);
+	fsl_disable_clocks(fsl_edma, fsl_edma->dmamux_nr);
 
 	return 0;
 }
-- 
2.7.4


^ permalink raw reply related

* [PATCH v2 2/7] dmaengine: mcf-edma: update to 'dmamux_nr'
From: yibin.gong @ 2019-05-27  8:51 UTC (permalink / raw)
  To: robh, shawnguo, s.hauer, festevam, mark.rutland, vkoul,
	dan.j.williams
  Cc: linux-imx, linux-arm-kernel, linux-kernel, dmaengine, devicetree,
	kernel
In-Reply-To: <20190527085118.40423-1-yibin.gong@nxp.com>

From: Robin Gong <yibin.gong@nxp.com>

Update to 'dmamux_nr' instead of static macro DMAMUX_NR since
new version edma only has one dmamux.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
---
 drivers/dma/fsl-edma-common.c | 2 +-
 drivers/dma/mcf-edma.c        | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
index 680b2a0..c9a17fc 100644
--- a/drivers/dma/fsl-edma-common.c
+++ b/drivers/dma/fsl-edma-common.c
@@ -84,7 +84,7 @@ void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan,
 	void __iomem *muxaddr;
 	unsigned int chans_per_mux, ch_off;
 
-	chans_per_mux = fsl_chan->edma->n_chans / DMAMUX_NR;
+	chans_per_mux = fsl_chan->edma->n_chans / fsl_chan->edma->dmamux_nr;
 	ch_off = fsl_chan->vchan.chan.chan_id % chans_per_mux;
 	muxaddr = fsl_chan->edma->muxbase[ch / chans_per_mux];
 	slot = EDMAMUX_CHCFG_SOURCE(slot);
diff --git a/drivers/dma/mcf-edma.c b/drivers/dma/mcf-edma.c
index 7de54b2f..4484190 100644
--- a/drivers/dma/mcf-edma.c
+++ b/drivers/dma/mcf-edma.c
@@ -189,6 +189,7 @@ static int mcf_edma_probe(struct platform_device *pdev)
 
 	/* Set up version for ColdFire edma */
 	mcf_edma->version = v2;
+	mcf_edma->dmamux_nr = DMAMUX_NR;
 	mcf_edma->big_endian = 1;
 
 	if (!mcf_edma->n_chans) {
-- 
2.7.4


^ permalink raw reply related

* [PATCH v2 4/7] dmaengine: fsl-edma-common: version check for v2 instead
From: yibin.gong @ 2019-05-27  8:51 UTC (permalink / raw)
  To: robh, shawnguo, s.hauer, festevam, mark.rutland, vkoul,
	dan.j.williams
  Cc: linux-imx, linux-arm-kernel, linux-kernel, dmaengine, devicetree,
	kernel
In-Reply-To: <20190527085118.40423-1-yibin.gong@nxp.com>

From: Robin Gong <yibin.gong@nxp.com>

The next v3 i.mx7ulp edma is based on v1, so change version
check logic for v2 instead.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
---
 drivers/dma/fsl-edma-common.c | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
index bb24251..45d70d3 100644
--- a/drivers/dma/fsl-edma-common.c
+++ b/drivers/dma/fsl-edma-common.c
@@ -657,26 +657,26 @@ void fsl_edma_setup_regs(struct fsl_edma_engine *edma)
 	edma->regs.erql = edma->membase + EDMA_ERQ;
 	edma->regs.eeil = edma->membase + EDMA_EEI;
 
-	edma->regs.serq = edma->membase + ((edma->version == v1) ?
-			EDMA_SERQ : EDMA64_SERQ);
-	edma->regs.cerq = edma->membase + ((edma->version == v1) ?
-			EDMA_CERQ : EDMA64_CERQ);
-	edma->regs.seei = edma->membase + ((edma->version == v1) ?
-			EDMA_SEEI : EDMA64_SEEI);
-	edma->regs.ceei = edma->membase + ((edma->version == v1) ?
-			EDMA_CEEI : EDMA64_CEEI);
-	edma->regs.cint = edma->membase + ((edma->version == v1) ?
-			EDMA_CINT : EDMA64_CINT);
-	edma->regs.cerr = edma->membase + ((edma->version == v1) ?
-			EDMA_CERR : EDMA64_CERR);
-	edma->regs.ssrt = edma->membase + ((edma->version == v1) ?
-			EDMA_SSRT : EDMA64_SSRT);
-	edma->regs.cdne = edma->membase + ((edma->version == v1) ?
-			EDMA_CDNE : EDMA64_CDNE);
-	edma->regs.intl = edma->membase + ((edma->version == v1) ?
-			EDMA_INTR : EDMA64_INTL);
-	edma->regs.errl = edma->membase + ((edma->version == v1) ?
-			EDMA_ERR : EDMA64_ERRL);
+	edma->regs.serq = edma->membase + ((edma->version == v2) ?
+			EDMA64_SERQ : EDMA_SERQ);
+	edma->regs.cerq = edma->membase + ((edma->version == v2) ?
+			EDMA64_CERQ : EDMA_CERQ);
+	edma->regs.seei = edma->membase + ((edma->version == v2) ?
+			EDMA64_SEEI : EDMA_SEEI);
+	edma->regs.ceei = edma->membase + ((edma->version == v2) ?
+			EDMA64_CEEI : EDMA_CEEI);
+	edma->regs.cint = edma->membase + ((edma->version == v2) ?
+			EDMA64_CINT : EDMA_CINT);
+	edma->regs.cerr = edma->membase + ((edma->version == v2) ?
+			EDMA64_CERR : EDMA_CERR);
+	edma->regs.ssrt = edma->membase + ((edma->version == v2) ?
+			EDMA64_SSRT : EDMA_SSRT);
+	edma->regs.cdne = edma->membase + ((edma->version == v2) ?
+			EDMA64_CDNE : EDMA_CDNE);
+	edma->regs.intl = edma->membase + ((edma->version == v2) ?
+			EDMA64_INTL : EDMA_INTR);
+	edma->regs.errl = edma->membase + ((edma->version == v2) ?
+			EDMA64_ERRL : EDMA_ERR);
 
 	if (edma->version == v2) {
 		edma->regs.erqh = edma->membase + EDMA64_ERQH;
-- 
2.7.4


^ permalink raw reply related

* [PATCH v2 3/7] dmaengine: fsl-edma-common: move dmamux register to another single function
From: yibin.gong @ 2019-05-27  8:51 UTC (permalink / raw)
  To: robh, shawnguo, s.hauer, festevam, mark.rutland, vkoul,
	dan.j.williams
  Cc: linux-imx, linux-arm-kernel, linux-kernel, dmaengine, devicetree,
	kernel
In-Reply-To: <20190527085118.40423-1-yibin.gong@nxp.com>

From: Robin Gong <yibin.gong@nxp.com>

Prepare for edmav2 on i.mx7ulp whose dmamux register is 32bit. No function
impacted.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
---
 drivers/dma/fsl-edma-common.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
index c9a17fc..bb24251 100644
--- a/drivers/dma/fsl-edma-common.c
+++ b/drivers/dma/fsl-edma-common.c
@@ -77,6 +77,19 @@ void fsl_edma_disable_request(struct fsl_edma_chan *fsl_chan)
 }
 EXPORT_SYMBOL_GPL(fsl_edma_disable_request);
 
+static void mux_configure8(struct fsl_edma_chan *fsl_chan, void __iomem *addr,
+			   u32 off, u32 slot, bool enable)
+{
+	u8 val8;
+
+	if (enable)
+		val8 = EDMAMUX_CHCFG_ENBL | slot;
+	else
+		val8 = EDMAMUX_CHCFG_DIS;
+
+	iowrite8(val8, addr + off);
+}
+
 void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan,
 			unsigned int slot, bool enable)
 {
@@ -89,10 +102,7 @@ void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan,
 	muxaddr = fsl_chan->edma->muxbase[ch / chans_per_mux];
 	slot = EDMAMUX_CHCFG_SOURCE(slot);
 
-	if (enable)
-		iowrite8(EDMAMUX_CHCFG_ENBL | slot, muxaddr + ch_off);
-	else
-		iowrite8(EDMAMUX_CHCFG_DIS, muxaddr + ch_off);
+	mux_configure8(fsl_chan, muxaddr, ch_off, slot, enable);
 }
 EXPORT_SYMBOL_GPL(fsl_edma_chan_mux);
 
-- 
2.7.4


^ permalink raw reply related

* [PATCH v2 6/7] dmaengine: fsl-edma: add i.mx7ulp edma2 version support
From: yibin.gong @ 2019-05-27  8:51 UTC (permalink / raw)
  To: robh, shawnguo, s.hauer, festevam, mark.rutland, vkoul,
	dan.j.williams
  Cc: linux-imx, linux-arm-kernel, linux-kernel, dmaengine, devicetree,
	kernel
In-Reply-To: <20190527085118.40423-1-yibin.gong@nxp.com>

From: Robin Gong <yibin.gong@nxp.com>

  Add edma2 for i.mx7ulp by version v3, since v2 has already
been used by mcf-edma.
The big changes based on v1 are belows:
1. only one dmamux.
2. another clock dma_clk except dmamux clk.
3. 16 independent interrupts instead of only one interrupt for
all channels.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
---
 drivers/dma/fsl-edma-common.c | 18 +++++++++-
 drivers/dma/fsl-edma-common.h |  3 ++
 drivers/dma/fsl-edma.c        | 84 ++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
index 45d70d3..0d9915c 100644
--- a/drivers/dma/fsl-edma-common.c
+++ b/drivers/dma/fsl-edma-common.c
@@ -90,6 +90,19 @@ static void mux_configure8(struct fsl_edma_chan *fsl_chan, void __iomem *addr,
 	iowrite8(val8, addr + off);
 }
 
+void mux_configure32(struct fsl_edma_chan *fsl_chan, void __iomem *addr,
+		     u32 off, u32 slot, bool enable)
+{
+	u32 val;
+
+	if (enable)
+		val = EDMAMUX_CHCFG_ENBL << 24 | slot;
+	else
+		val = EDMAMUX_CHCFG_DIS;
+
+	iowrite32(val, addr + off * 4);
+}
+
 void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan,
 			unsigned int slot, bool enable)
 {
@@ -102,7 +115,10 @@ void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan,
 	muxaddr = fsl_chan->edma->muxbase[ch / chans_per_mux];
 	slot = EDMAMUX_CHCFG_SOURCE(slot);
 
-	mux_configure8(fsl_chan, muxaddr, ch_off, slot, enable);
+	if (fsl_chan->edma->version == v3)
+		mux_configure32(fsl_chan, muxaddr, ch_off, slot, enable);
+	else
+		mux_configure8(fsl_chan, muxaddr, ch_off, slot, enable);
 }
 EXPORT_SYMBOL_GPL(fsl_edma_chan_mux);
 
diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h
index 21a9cfd..2b0cc8e 100644
--- a/drivers/dma/fsl-edma-common.h
+++ b/drivers/dma/fsl-edma-common.h
@@ -124,6 +124,7 @@ struct fsl_edma_chan {
 	dma_addr_t			dma_dev_addr;
 	u32				dma_dev_size;
 	enum dma_data_direction		dma_dir;
+	char				chan_name[16];
 };
 
 struct fsl_edma_desc {
@@ -138,6 +139,7 @@ struct fsl_edma_desc {
 enum edma_version {
 	v1, /* 32ch, Vybrid, mpc57x, etc */
 	v2, /* 64ch Coldfire */
+	v3, /* 32ch, i.mx7ulp */
 };
 
 struct fsl_edma_engine {
@@ -145,6 +147,7 @@ struct fsl_edma_engine {
 	void __iomem		*membase;
 	void __iomem		*muxbase[DMAMUX_NR];
 	struct clk		*muxclk[DMAMUX_NR];
+	struct clk		*dmaclk;
 	u32			dmamux_nr;
 	struct mutex		fsl_edma_mutex;
 	u32			n_chans;
diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
index 7b65ef4..055f430 100644
--- a/drivers/dma/fsl-edma.c
+++ b/drivers/dma/fsl-edma.c
@@ -165,6 +165,51 @@ fsl_edma_irq_init(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma
 	return 0;
 }
 
+static int
+fsl_edma2_irq_init(struct platform_device *pdev,
+		   struct fsl_edma_engine *fsl_edma)
+{
+	struct device_node *np = pdev->dev.of_node;
+	int i, ret, irq;
+	int count = 0;
+
+	count = of_irq_count(np);
+	dev_info(&pdev->dev, "%s Found %d interrupts\r\n", __func__, count);
+	if (count <= 2) {
+		dev_err(&pdev->dev, "Interrupts in DTS not correct.\n");
+		return -EINVAL;
+	}
+	/*
+	 * 16 channel independent interrupts + 1 error interrupt on i.mx7ulp.
+	 * 2 channel share one interrupt, for example, ch0/ch16, ch1/ch17...
+	 * For now, just simply request irq without IRQF_SHARED flag, since 16
+	 * channels are enough on i.mx7ulp whose M4 domain own some peripherals.
+	 */
+	for (i = 0; i < count; i++) {
+		irq = platform_get_irq(pdev, i);
+		if (irq < 0)
+			return -ENXIO;
+
+		sprintf(fsl_edma->chans[i].chan_name, "eDMA2-CH%02d", i);
+
+		/* The last IRQ is for eDMA err */
+		if (i == count - 1)
+			ret = devm_request_irq(&pdev->dev, irq,
+						fsl_edma_err_handler,
+						0, "eDMA2-ERR", fsl_edma);
+		else
+
+			ret = devm_request_irq(&pdev->dev, irq,
+						fsl_edma_tx_handler, 0,
+						fsl_edma->chans[i].chan_name,
+						fsl_edma);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static void fsl_edma_irq_exit(
 		struct platform_device *pdev, struct fsl_edma_engine *fsl_edma)
 {
@@ -184,8 +229,17 @@ static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma, int nr_clocks)
 		clk_disable_unprepare(fsl_edma->muxclk[i]);
 }
 
+static const struct of_device_id fsl_edma_dt_ids[] = {
+	{ .compatible = "fsl,vf610-edma", .data = (void *)v1 },
+	{ .compatible = "fsl,imx7ulp-edma", .data = (void *)v3 },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
+
 static int fsl_edma_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *of_id =
+			of_match_device(fsl_edma_dt_ids, &pdev->dev);
 	struct device_node *np = pdev->dev.of_node;
 	struct fsl_edma_engine *fsl_edma;
 	struct fsl_edma_chan *fsl_chan;
@@ -205,7 +259,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
 	if (!fsl_edma)
 		return -ENOMEM;
 
-	fsl_edma->version = v1;
+	fsl_edma->version = (enum edma_version)of_id->data;
 	fsl_edma->dmamux_nr = DMAMUX_NR;
 	fsl_edma->n_chans = chans;
 	mutex_init(&fsl_edma->fsl_edma_mutex);
@@ -218,6 +272,22 @@ static int fsl_edma_probe(struct platform_device *pdev)
 	fsl_edma_setup_regs(fsl_edma);
 	regs = &fsl_edma->regs;
 
+	if (fsl_edma->version == v3) {
+		fsl_edma->dmamux_nr = 1;
+
+		fsl_edma->dmaclk = devm_clk_get(&pdev->dev, "dma");
+		if (IS_ERR(fsl_edma->dmaclk)) {
+			dev_err(&pdev->dev, "Missing DMA block clock.\n");
+			return PTR_ERR(fsl_edma->dmaclk);
+		}
+
+		ret = clk_prepare_enable(fsl_edma->dmaclk);
+		if (ret) {
+			dev_err(&pdev->dev, "DMA clk block failed.\n");
+			return ret;
+		}
+	}
+
 	for (i = 0; i < fsl_edma->dmamux_nr; i++) {
 		char clkname[32];
 
@@ -264,7 +334,11 @@ static int fsl_edma_probe(struct platform_device *pdev)
 	}
 
 	edma_writel(fsl_edma, ~0, regs->intl);
-	ret = fsl_edma_irq_init(pdev, fsl_edma);
+
+	if (fsl_edma->version == v3)
+		ret = fsl_edma2_irq_init(pdev, fsl_edma);
+	else
+		ret = fsl_edma_irq_init(pdev, fsl_edma);
 	if (ret)
 		return ret;
 
@@ -383,12 +457,6 @@ static const struct dev_pm_ops fsl_edma_pm_ops = {
 	.resume_early   = fsl_edma_resume_early,
 };
 
-static const struct of_device_id fsl_edma_dt_ids[] = {
-	{ .compatible = "fsl,vf610-edma", },
-	{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
-
 static struct platform_driver fsl_edma_driver = {
 	.driver		= {
 		.name	= "fsl-edma",
-- 
2.7.4


^ permalink raw reply related

* [PATCH v2 7/7] ARM: dts: imx7ulp: add edma device node
From: yibin.gong @ 2019-05-27  8:51 UTC (permalink / raw)
  To: robh, shawnguo, s.hauer, festevam, mark.rutland, vkoul,
	dan.j.williams
  Cc: linux-imx, linux-arm-kernel, linux-kernel, dmaengine, devicetree,
	kernel
In-Reply-To: <20190527085118.40423-1-yibin.gong@nxp.com>

From: Robin Gong <yibin.gong@nxp.com>

Add edma device node in dts.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
---
 arch/arm/boot/dts/imx7ulp.dtsi | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm/boot/dts/imx7ulp.dtsi b/arch/arm/boot/dts/imx7ulp.dtsi
index d6b7110..b4f7adf 100644
--- a/arch/arm/boot/dts/imx7ulp.dtsi
+++ b/arch/arm/boot/dts/imx7ulp.dtsi
@@ -100,6 +100,34 @@
 		reg = <0x40000000 0x800000>;
 		ranges;
 
+		edma1: dma-controller@40080000 {
+			#dma-cells = <2>;
+			compatible = "fsl,imx7ulp-edma";
+			reg = <0x40080000 0x2000>,
+				<0x40210000 0x1000>;
+			dma-channels = <32>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+			clock-names = "dma", "dmamux0";
+			clocks = <&pcc2 IMX7ULP_CLK_DMA1>,
+				 <&pcc2 IMX7ULP_CLK_DMA_MUX1>;
+		};
+
 		lpuart4: serial@402d0000 {
 			compatible = "fsl,imx7ulp-lpuart";
 			reg = <0x402d0000 0x1000>;
-- 
2.7.4


^ permalink raw reply related

* [PATCH v2 5/7] dt-bindings: dma: fsl-edma: add new i.mx7ulp-edma
From: yibin.gong @ 2019-05-27  8:51 UTC (permalink / raw)
  To: robh, shawnguo, s.hauer, festevam, mark.rutland, vkoul,
	dan.j.williams
  Cc: linux-imx, linux-arm-kernel, linux-kernel, dmaengine, devicetree,
	kernel
In-Reply-To: <20190527085118.40423-1-yibin.gong@nxp.com>

From: Robin Gong <yibin.gong@nxp.com>

More channel interrupts, one more clock, and only one
dmamux on i.mx7ulp-edma.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
---
 Documentation/devicetree/bindings/dma/fsl-edma.txt | 44 +++++++++++++++++++---
 1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/fsl-edma.txt b/Documentation/devicetree/bindings/dma/fsl-edma.txt
index 97e213e..29dd3cc 100644
--- a/Documentation/devicetree/bindings/dma/fsl-edma.txt
+++ b/Documentation/devicetree/bindings/dma/fsl-edma.txt
@@ -9,15 +9,16 @@ group, DMAMUX0 or DMAMUX1, but not both.
 Required properties:
 - compatible :
 	- "fsl,vf610-edma" for eDMA used similar to that on Vybrid vf610 SoC
+	- "fsl,imx7ulp-edma" for eDMA2 used similar to that on i.mx7ulp
 - reg : Specifies base physical address(s) and size of the eDMA registers.
 	The 1st region is eDMA control register's address and size.
 	The 2nd and the 3rd regions are programmable channel multiplexing
 	control register's address and size.
 - interrupts : A list of interrupt-specifiers, one for each entry in
-	interrupt-names.
-- interrupt-names : Should contain:
-	"edma-tx" - the transmission interrupt
-	"edma-err" - the error interrupt
+	interrupt-names on vf610 similar SoC. But for i.mx7ulp per channel
+	per transmission interrupt, total 16 channel interrupt and 1
+	error interrupt(located in the last), no interrupt-names list on
+	i.mx7ulp for clean on dts.
 - #dma-cells : Must be <2>.
 	The 1st cell specifies the DMAMUX(0 for DMAMUX0 and 1 for DMAMUX1).
 	Specific request source can only be multiplexed by specific channels
@@ -28,6 +29,7 @@ Required properties:
 - clock-names : A list of channel group clock names. Should contain:
 	"dmamux0" - clock name of mux0 group
 	"dmamux1" - clock name of mux1 group
+	Note: No dmamux0 on i.mx7ulp, but another 'dma' clk added on i.mx7ulp.
 - clocks : A list of phandle and clock-specifier pairs, one for each entry in
 	clock-names.
 
@@ -35,6 +37,10 @@ Optional properties:
 - big-endian: If present registers and hardware scatter/gather descriptors
 	of the eDMA are implemented in big endian mode, otherwise in little
 	mode.
+- interrupt-names : Should contain the below on vf610 similar SoC but not used
+	on i.mx7ulp similar SoC:
+	"edma-tx" - the transmission interrupt
+	"edma-err" - the error interrupt
 
 
 Examples:
@@ -52,8 +58,36 @@ edma0: dma-controller@40018000 {
 	clock-names = "dmamux0", "dmamux1";
 	clocks = <&clks VF610_CLK_DMAMUX0>,
 		<&clks VF610_CLK_DMAMUX1>;
-};
+}; /* vf610 */
 
+edma1: dma-controller@40080000 {
+	#dma-cells = <2>;
+	compatible = "fsl,imx7ulp-edma";
+	reg = <0x40080000 0x2000>,
+		<0x40210000 0x1000>;
+	dma-channels = <32>;
+	interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+		     /* last is eDMA2-ERR interrupt */
+		     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+	clock-names = "dma", "dmamux0";
+	clocks = <&pcc2 IMX7ULP_CLK_DMA1>,
+		 <&pcc2 IMX7ULP_CLK_DMA_MUX1>;
+}; /* i.mx7ulp */
 
 * DMA clients
 DMA client drivers that uses the DMA function must use the format described
-- 
2.7.4


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox