devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support
@ 2021-12-27 12:05 Stefan Wahren
  2021-12-27 12:05 ` [PATCH RFC 01/11] ARM: dts: bcm283x: Update DMA node name per DT schema Stefan Wahren
                   ` (10 more replies)
  0 siblings, 11 replies; 15+ messages in thread
From: Stefan Wahren @ 2021-12-27 12:05 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Florian Fainelli, Nicolas Saenz Julienne
  Cc: Ray Jui, Scott Branden, bcm-kernel-feedback-list, dmaengine,
	Phil Elwell, devicetree, linux-arm-kernel, Lukas Wunner,
	linux-rpi-kernel, Stefan Wahren

The BCM2711 has 4 DMA channels with a 40-bit address range, allowing them
to access the full 4GB of memory on a Pi 4. This patch series serves as a
basis for a discussion (just compile tested, so don't expect anything working)
which include the following points:

* correct DT binding and representation for BCM2711

According to the vendor DTS [1] the 4 DMA channels are connected to SCB.
I'm not sure how this is properly adapted to the mainline DT.

* general implementation approach

The vendor approach mapped all the BCM2835 control block bits to the BCM2711
layout and the rest of the differences are handled by a lot of is_40bit_channel
conditions. An advantage of this is the small amount of changes to the driver.
But on the down side the code is now much harder to understand and maintain.

This series tries to implement this feature in a more cleaner way
while keeping it in the bcm2835-dma driver. Before this series the driver
has ~ 1000 lines and after that ~ 1500 lines.

So the question is this approach acceptable?

Patches 1 - 3 are just clean-ups.

Disclaimer: my knowledge about the DMA controller is very limited

More information:

https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf

[1] - https://github.com/raspberrypi/linux/blob/561deffcf471ba0f7bd48541d06a79d5aa38d297/arch/arm/boot/dts/bcm2711-rpi-ds.dtsi#L47
[2] - https://github.com/raspberrypi/linux/commit/44364bd140b0bc9187c881fbdc4ee358961059d5

Stefan Wahren (11):
  ARM: dts: bcm283x: Update DMA node name per DT schema
  dt-bindings: dma: Convert brcm,bcm2835-dma to json-schema
  dmaengine: bcm2835: Support common dma-channel-mask
  dmaengine: bcm2835: move CB info generation into separate function
  dmaengine: bcm2835: move CB final extra info generation into function
  dmaengine: bcm2835: make address increment platform independent
  dmaengine: bcm2385: drop info parameters
  dmaengine: bcm2835: pass dma_chan to generic functions
  dmaengine: bcm2835: introduce multi platform support
  dmaengine: bcm2835: add BCM2711 40-bit DMA support
  ARM: dts: bcm2711: add bcm2711-dma node

 .../devicetree/bindings/dma/brcm,bcm2835-dma.txt   |  83 ---
 .../devicetree/bindings/dma/brcm,bcm2835-dma.yaml  | 107 +++
 arch/arm/boot/dts/bcm2711.dtsi                     |  18 +-
 arch/arm/boot/dts/bcm2835-common.dtsi              |   2 +-
 drivers/dma/bcm2835-dma.c                          | 745 +++++++++++++++++----
 5 files changed, 734 insertions(+), 221 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
 create mode 100644 Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml

-- 
2.7.4


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH RFC 01/11] ARM: dts: bcm283x: Update DMA node name per DT schema
  2021-12-27 12:05 [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
@ 2021-12-27 12:05 ` Stefan Wahren
  2021-12-27 12:05 ` [PATCH RFC 02/11] dt-bindings: dma: Convert brcm,bcm2835-dma to json-schema Stefan Wahren
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Stefan Wahren @ 2021-12-27 12:05 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Florian Fainelli, Nicolas Saenz Julienne
  Cc: Ray Jui, Scott Branden, bcm-kernel-feedback-list, dmaengine,
	Phil Elwell, devicetree, linux-arm-kernel, Lukas Wunner,
	linux-rpi-kernel, Stefan Wahren

Follow dma-controller.yaml schema to use 'dma-controller' as node name
for BCM2835 DMA controller.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 arch/arm/boot/dts/bcm2711.dtsi        | 2 +-
 arch/arm/boot/dts/bcm2835-common.dtsi | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
index b8a4096..590068b 100644
--- a/arch/arm/boot/dts/bcm2711.dtsi
+++ b/arch/arm/boot/dts/bcm2711.dtsi
@@ -76,7 +76,7 @@
 			};
 		};
 
-		dma: dma@7e007000 {
+		dma: dma-controller@7e007000 {
 			compatible = "brcm,bcm2835-dma";
 			reg = <0x7e007000 0xb00>;
 			interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm/boot/dts/bcm2835-common.dtsi b/arch/arm/boot/dts/bcm2835-common.dtsi
index 4119271..f540140 100644
--- a/arch/arm/boot/dts/bcm2835-common.dtsi
+++ b/arch/arm/boot/dts/bcm2835-common.dtsi
@@ -8,7 +8,7 @@
 	interrupt-parent = <&intc>;
 
 	soc {
-		dma: dma@7e007000 {
+		dma: dma-controller@7e007000 {
 			compatible = "brcm,bcm2835-dma";
 			reg = <0x7e007000 0xf00>;
 			interrupts = <1 16>,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH RFC 02/11] dt-bindings: dma: Convert brcm,bcm2835-dma to json-schema
  2021-12-27 12:05 [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
  2021-12-27 12:05 ` [PATCH RFC 01/11] ARM: dts: bcm283x: Update DMA node name per DT schema Stefan Wahren
@ 2021-12-27 12:05 ` Stefan Wahren
  2022-01-04 22:50   ` Rob Herring
  2021-12-27 12:05 ` [PATCH RFC 03/11] dmaengine: bcm2835: Support common dma-channel-mask Stefan Wahren
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 15+ messages in thread
From: Stefan Wahren @ 2021-12-27 12:05 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Florian Fainelli, Nicolas Saenz Julienne
  Cc: Ray Jui, Scott Branden, bcm-kernel-feedback-list, dmaengine,
	Phil Elwell, devicetree, linux-arm-kernel, Lukas Wunner,
	linux-rpi-kernel, Stefan Wahren

This convert the BCM2835 DMA bindings to YAML format.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 .../devicetree/bindings/dma/brcm,bcm2835-dma.txt   |  83 ----------------
 .../devicetree/bindings/dma/brcm,bcm2835-dma.yaml  | 107 +++++++++++++++++++++
 2 files changed, 107 insertions(+), 83 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
 create mode 100644 Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml

diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
deleted file mode 100644
index b6a8cc0..0000000
--- a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-* BCM2835 DMA controller
-
-The BCM2835 DMA controller has 16 channels in total.
-Only the lower 13 channels have an associated IRQ.
-Some arbitrary channels are used by the firmware
-(1,3,6,7 in the current firmware version).
-The channels 0,2 and 3 have special functionality
-and should not be used by the driver.
-
-Required properties:
-- compatible: Should be "brcm,bcm2835-dma".
-- reg: Should contain DMA registers location and length.
-- interrupts: Should contain the DMA interrupts associated
-		to the DMA channels in ascending order.
-- interrupt-names: Should contain the names of the interrupt
-		   in the form "dmaXX".
-		   Use "dma-shared-all" for the common interrupt line
-		   that is shared by all dma channels.
-- #dma-cells: Must be <1>, the cell in the dmas property of the
-		client device represents the DREQ number.
-- brcm,dma-channel-mask: Bit mask representing the channels
-			 not used by the firmware in ascending order,
-			 i.e. first channel corresponds to LSB.
-
-Example:
-
-dma: dma@7e007000 {
-	compatible = "brcm,bcm2835-dma";
-	reg = <0x7e007000 0xf00>;
-	interrupts = <1 16>,
-		     <1 17>,
-		     <1 18>,
-		     <1 19>,
-		     <1 20>,
-		     <1 21>,
-		     <1 22>,
-		     <1 23>,
-		     <1 24>,
-		     <1 25>,
-		     <1 26>,
-		     /* dma channel 11-14 share one irq */
-		     <1 27>,
-		     <1 27>,
-		     <1 27>,
-		     <1 27>,
-		     /* unused shared irq for all channels */
-		     <1 28>;
-	interrupt-names = "dma0",
-			  "dma1",
-			  "dma2",
-			  "dma3",
-			  "dma4",
-			  "dma5",
-			  "dma6",
-			  "dma7",
-			  "dma8",
-			  "dma9",
-			  "dma10",
-			  "dma11",
-			  "dma12",
-			  "dma13",
-			  "dma14",
-			  "dma-shared-all";
-
-	#dma-cells = <1>;
-	brcm,dma-channel-mask = <0x7f35>;
-};
-
-
-DMA clients connected to the BCM2835 DMA controller must use the format
-described in the dma.txt file, using a two-cell specifier for each channel.
-
-Example:
-
-bcm2835_i2s: i2s@7e203000 {
-	compatible = "brcm,bcm2835-i2s";
-	reg = <	0x7e203000 0x24>;
-	clocks = <&clocks BCM2835_CLOCK_PCM>;
-
-	dmas = <&dma 2>,
-	       <&dma 3>;
-	dma-names = "tx", "rx";
-};
diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml
new file mode 100644
index 0000000..44cb83f
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/brcm,bcm2835-dma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: BCM2835 DMA controller
+
+maintainers:
+  - Nicolas Saenz Julienne <nsaenz@kernel.org>
+
+description: |
+  The BCM2835 DMA controller has 16 channels in total.
+  Only the lower 13 channels have an associated IRQ.
+  Some arbitrary channels are used by the firmware
+  (1,3,6,7 in the current firmware version).
+  The channels 0,2 and 3 have special functionality
+  and should not be used by the driver.
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+  compatible:
+    const: brcm,bcm2835-dma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    description:
+      Should contain the DMA interrupts associated to the DMA channels in
+      ascending order.
+    minItems: 1
+    maxItems: 16
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 16
+
+  "#dma-cells":
+    const: 1
+    description: >
+      DMA clients must use the format described in dma.txt, giving a phandle
+      to the DMA controller while the second cell in the dmas property of the
+      client device represents the DREQ number.
+
+  brcm,dma-channel-mask:
+    description:
+      Bit mask representing the channels not used by the firmware in
+      ascending order, i.e. first channel corresponds to LSB.
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - "#dma-cells"
+  - brcm,dma-channel-mask
+
+additionalProperties: false
+
+examples:
+  - |
+    dma: dma-controller@7e007000 {
+      compatible = "brcm,bcm2835-dma";
+      reg = <0x7e007000 0xf00>;
+      interrupts = <1 16>,
+                   <1 17>,
+                   <1 18>,
+                   <1 19>,
+                   <1 20>,
+                   <1 21>,
+                   <1 22>,
+                   <1 23>,
+                   <1 24>,
+                   <1 25>,
+                   <1 26>,
+                   /* dma channel 11-14 share one irq */
+                   <1 27>,
+                   <1 27>,
+                   <1 27>,
+                   <1 27>,
+                   /* unused shared irq for all channels */
+                   <1 28>;
+      interrupt-names = "dma0",
+                        "dma1",
+                        "dma2",
+                        "dma3",
+                        "dma4",
+                        "dma5",
+                        "dma6",
+                        "dma7",
+                        "dma8",
+                        "dma9",
+                        "dma10",
+                        "dma11",
+                        "dma12",
+                        "dma13",
+                        "dma14",
+                        "dma-shared-all";
+        #dma-cells = <1>;
+        brcm,dma-channel-mask = <0x7f35>;
+    };
+
+...
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH RFC 03/11] dmaengine: bcm2835: Support common dma-channel-mask
  2021-12-27 12:05 [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
  2021-12-27 12:05 ` [PATCH RFC 01/11] ARM: dts: bcm283x: Update DMA node name per DT schema Stefan Wahren
  2021-12-27 12:05 ` [PATCH RFC 02/11] dt-bindings: dma: Convert brcm,bcm2835-dma to json-schema Stefan Wahren
@ 2021-12-27 12:05 ` Stefan Wahren
  2021-12-27 12:05 ` [PATCH RFC 04/11] dmaengine: bcm2835: move CB info generation into separate function Stefan Wahren
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Stefan Wahren @ 2021-12-27 12:05 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Florian Fainelli, Nicolas Saenz Julienne
  Cc: Ray Jui, Scott Branden, bcm-kernel-feedback-list, dmaengine,
	Phil Elwell, devicetree, linux-arm-kernel, Lukas Wunner,
	linux-rpi-kernel, Stefan Wahren

Nowadays there is a generic property for dma-channel-mask in the DMA
controller binding. So prefer this one instead of the old vendor specific
one. Print a warning in case the old one is used. Btw use the result of
of_property_read_u32() as return code in error case.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/dma/bcm2835-dma.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 630dfbb..adfe6bc 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -943,12 +943,19 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
 	}
 
 	/* Request DMA channel mask from device tree */
-	if (of_property_read_u32(pdev->dev.of_node,
-			"brcm,dma-channel-mask",
-			&chans_available)) {
-		dev_err(&pdev->dev, "Failed to get channel mask\n");
-		rc = -EINVAL;
-		goto err_no_dma;
+	rc = of_property_read_u32(pdev->dev.of_node, "dma-channel-mask",
+				  &chans_available);
+
+	if (rc) {
+		/* Try deprecated property */
+		if (of_property_read_u32(pdev->dev.of_node,
+					 "brcm,dma-channel-mask",
+					 &chans_available)) {
+			dev_err(&pdev->dev, "Failed to get channel mask\n");
+			goto err_no_dma;
+		}
+
+		dev_warn(&pdev->dev, "Please update DT blob\n");
 	}
 
 	/* get irqs for each channel that we support */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH RFC 04/11] dmaengine: bcm2835: move CB info generation into separate function
  2021-12-27 12:05 [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
                   ` (2 preceding siblings ...)
  2021-12-27 12:05 ` [PATCH RFC 03/11] dmaengine: bcm2835: Support common dma-channel-mask Stefan Wahren
@ 2021-12-27 12:05 ` Stefan Wahren
  2021-12-27 12:05 ` [PATCH RFC 05/11] dmaengine: bcm2835: move CB final extra info generation into function Stefan Wahren
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Stefan Wahren @ 2021-12-27 12:05 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Florian Fainelli, Nicolas Saenz Julienne
  Cc: Ray Jui, Scott Branden, bcm-kernel-feedback-list, dmaengine,
	Phil Elwell, devicetree, linux-arm-kernel, Lukas Wunner,
	linux-rpi-kernel, Stefan Wahren

Actually the generation of the Control Block info follows some simple
rules. So handle this with a separate function to avoid open coding
for every DMA operation. Another advantage is that we can easier
introduce other platforms with different info bits.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/dma/bcm2835-dma.c | 51 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 18 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index adfe6bc..10c9ba2 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -201,6 +201,35 @@ static inline struct bcm2835_desc *to_bcm2835_dma_desc(
 	return container_of(t, struct bcm2835_desc, vd.tx);
 }
 
+static u32 bcm2835_dma_prepare_cb_info(struct bcm2835_chan *c,
+				       enum dma_transfer_direction direction,
+				       bool zero_page)
+{
+	u32 result;
+
+	if (direction == DMA_MEM_TO_MEM)
+		return BCM2835_DMA_D_INC | BCM2835_DMA_S_INC;
+
+	result = BCM2835_DMA_WAIT_RESP;
+
+	/* Setup DREQ channel */
+	if (c->dreq != 0)
+		result |= BCM2835_DMA_PER_MAP(c->dreq);
+
+	if (direction == DMA_DEV_TO_MEM) {
+		result |= BCM2835_DMA_S_DREQ | BCM2835_DMA_D_INC;
+	} else {
+		result |= BCM2835_DMA_D_DREQ | BCM2835_DMA_S_INC;
+
+		/* non-lite channels can write zeroes w/o accessing memory */
+		if (zero_page && !c->is_lite_channel) {
+			result |= BCM2835_DMA_S_IGNORE;
+		}
+	}
+
+	return result;
+}
+
 static void bcm2835_dma_free_cb_chain(struct bcm2835_desc *desc)
 {
 	size_t i;
@@ -615,7 +644,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_memcpy(
 {
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
-	u32 info = BCM2835_DMA_D_INC | BCM2835_DMA_S_INC;
+	u32 info = bcm2835_dma_prepare_cb_info(c, DMA_MEM_TO_MEM, false);
 	u32 extra = BCM2835_DMA_INT_EN | BCM2835_DMA_WAIT_RESP;
 	size_t max_len = bcm2835_dma_max_frame_length(c);
 	size_t frames;
@@ -646,7 +675,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	dma_addr_t src = 0, dst = 0;
-	u32 info = BCM2835_DMA_WAIT_RESP;
+	u32 info = bcm2835_dma_prepare_cb_info(c, direction, false);
 	u32 extra = BCM2835_DMA_INT_EN;
 	size_t frames;
 
@@ -656,19 +685,14 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
 		return NULL;
 	}
 
-	if (c->dreq != 0)
-		info |= BCM2835_DMA_PER_MAP(c->dreq);
-
 	if (direction == DMA_DEV_TO_MEM) {
 		if (c->cfg.src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
 		src = c->cfg.src_addr;
-		info |= BCM2835_DMA_S_DREQ | BCM2835_DMA_D_INC;
 	} else {
 		if (c->cfg.dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
 		dst = c->cfg.dst_addr;
-		info |= BCM2835_DMA_D_DREQ | BCM2835_DMA_S_INC;
 	}
 
 	/* count frames in sg list */
@@ -698,7 +722,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	dma_addr_t src, dst;
-	u32 info = BCM2835_DMA_WAIT_RESP;
+	u32 info = bcm2835_dma_prepare_cb_info(c, direction,
+					       buf_addr == od->zero_page);
 	u32 extra = 0;
 	size_t max_len = bcm2835_dma_max_frame_length(c);
 	size_t frames;
@@ -729,26 +754,16 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 			      "%s: buffer_length (%zd) is not a multiple of period_len (%zd)\n",
 			      __func__, buf_len, period_len);
 
-	/* Setup DREQ channel */
-	if (c->dreq != 0)
-		info |= BCM2835_DMA_PER_MAP(c->dreq);
-
 	if (direction == DMA_DEV_TO_MEM) {
 		if (c->cfg.src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
 		src = c->cfg.src_addr;
 		dst = buf_addr;
-		info |= BCM2835_DMA_S_DREQ | BCM2835_DMA_D_INC;
 	} else {
 		if (c->cfg.dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
 		dst = c->cfg.dst_addr;
 		src = buf_addr;
-		info |= BCM2835_DMA_D_DREQ | BCM2835_DMA_S_INC;
-
-		/* non-lite channels can write zeroes w/o accessing memory */
-		if (buf_addr == od->zero_page && !c->is_lite_channel)
-			info |= BCM2835_DMA_S_IGNORE;
 	}
 
 	/* calculate number of frames */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH RFC 05/11] dmaengine: bcm2835: move CB final extra info generation into function
  2021-12-27 12:05 [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
                   ` (3 preceding siblings ...)
  2021-12-27 12:05 ` [PATCH RFC 04/11] dmaengine: bcm2835: move CB info generation into separate function Stefan Wahren
@ 2021-12-27 12:05 ` Stefan Wahren
  2021-12-27 12:05 ` [PATCH RFC 06/11] dmaengine: bcm2835: make address increment platform independent Stefan Wahren
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Stefan Wahren @ 2021-12-27 12:05 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Florian Fainelli, Nicolas Saenz Julienne
  Cc: Ray Jui, Scott Branden, bcm-kernel-feedback-list, dmaengine,
	Phil Elwell, devicetree, linux-arm-kernel, Lukas Wunner,
	linux-rpi-kernel, Stefan Wahren

Similar to the info generation, generate the final extra info with a
separate function. This is necessary to introduce other platforms
with different info bits.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/dma/bcm2835-dma.c | 34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 10c9ba2..863792e 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -230,6 +230,29 @@ static u32 bcm2835_dma_prepare_cb_info(struct bcm2835_chan *c,
 	return result;
 }
 
+static u32 bcm2835_dma_prepare_cb_extra(struct bcm2835_chan *c,
+					enum dma_transfer_direction direction,
+					bool cyclic, bool final,
+					unsigned long flags)
+{
+	u32 result = 0;
+
+	if (cyclic) {
+		if (flags & DMA_PREP_INTERRUPT)
+			result |= BCM2835_DMA_INT_EN;
+	} else {
+		if (!final)
+			return 0;
+
+		result |= BCM2835_DMA_INT_EN;
+
+		if (direction == DMA_MEM_TO_MEM)
+			result |= BCM2835_DMA_WAIT_RESP;
+	}
+
+	return result;
+}
+
 static void bcm2835_dma_free_cb_chain(struct bcm2835_desc *desc)
 {
 	size_t i;
@@ -645,7 +668,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_memcpy(
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	u32 info = bcm2835_dma_prepare_cb_info(c, DMA_MEM_TO_MEM, false);
-	u32 extra = BCM2835_DMA_INT_EN | BCM2835_DMA_WAIT_RESP;
+	u32 extra = bcm2835_dma_prepare_cb_extra(c, DMA_MEM_TO_MEM, false,
+						 true, 0);
 	size_t max_len = bcm2835_dma_max_frame_length(c);
 	size_t frames;
 
@@ -676,7 +700,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
 	struct bcm2835_desc *d;
 	dma_addr_t src = 0, dst = 0;
 	u32 info = bcm2835_dma_prepare_cb_info(c, direction, false);
-	u32 extra = BCM2835_DMA_INT_EN;
+	u32 extra = bcm2835_dma_prepare_cb_extra(c, direction, false, true, 0);
 	size_t frames;
 
 	if (!is_slave_direction(direction)) {
@@ -724,7 +748,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 	dma_addr_t src, dst;
 	u32 info = bcm2835_dma_prepare_cb_info(c, direction,
 					       buf_addr == od->zero_page);
-	u32 extra = 0;
+	u32 extra = bcm2835_dma_prepare_cb_extra(c, direction, true, true, 0);
 	size_t max_len = bcm2835_dma_max_frame_length(c);
 	size_t frames;
 
@@ -740,9 +764,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 		return NULL;
 	}
 
-	if (flags & DMA_PREP_INTERRUPT)
-		extra |= BCM2835_DMA_INT_EN;
-	else
+	if (!(flags & DMA_PREP_INTERRUPT))
 		period_len = buf_len;
 
 	/*
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH RFC 06/11] dmaengine: bcm2835: make address increment platform independent
  2021-12-27 12:05 [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
                   ` (4 preceding siblings ...)
  2021-12-27 12:05 ` [PATCH RFC 05/11] dmaengine: bcm2835: move CB final extra info generation into function Stefan Wahren
@ 2021-12-27 12:05 ` Stefan Wahren
  2021-12-27 12:05 ` [PATCH RFC 07/11] dmaengine: bcm2385: drop info parameters Stefan Wahren
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Stefan Wahren @ 2021-12-27 12:05 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Florian Fainelli, Nicolas Saenz Julienne
  Cc: Ray Jui, Scott Branden, bcm-kernel-feedback-list, dmaengine,
	Phil Elwell, devicetree, linux-arm-kernel, Lukas Wunner,
	linux-rpi-kernel, Stefan Wahren

Actually the criteria to increment source & destination address doesn't
based on platform specific bits. It's just the DMA transfer direction which
is translated into the info bits. So introduce two new helper functions
and get the rid of these platform specifics.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/dma/bcm2835-dma.c | 28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 863792e..a7b9f88 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -253,6 +253,24 @@ static u32 bcm2835_dma_prepare_cb_extra(struct bcm2835_chan *c,
 	return result;
 }
 
+static inline bool need_src_incr(enum dma_transfer_direction direction)
+{
+	return direction != DMA_DEV_TO_MEM;
+}
+
+static inline bool need_dst_incr(enum dma_transfer_direction direction)
+{
+	switch (direction) {
+	case DMA_MEM_TO_MEM:
+	case DMA_DEV_TO_MEM:
+		return true;
+	default:
+		break;
+	}
+
+	return false;
+}
+
 static void bcm2835_dma_free_cb_chain(struct bcm2835_desc *desc)
 {
 	size_t i;
@@ -337,10 +355,8 @@ static inline size_t bcm2835_dma_count_frames_for_sg(
  * @cyclic:         it is a cyclic transfer
  * @info:           the default info bits to apply per controlblock
  * @frames:         number of controlblocks to allocate
- * @src:            the src address to assign (if the S_INC bit is set
- *                  in @info, then it gets incremented)
- * @dst:            the dst address to assign (if the D_INC bit is set
- *                  in @info, then it gets incremented)
+ * @src:            the src address to assign
+ * @dst:            the dst address to assign
  * @buf_len:        the full buffer length (may also be 0)
  * @period_len:     the period length when to apply @finalextrainfo
  *                  in addition to the last transfer
@@ -409,9 +425,9 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 			d->cb_list[frame - 1].cb->next = cb_entry->paddr;
 
 		/* update src and dst and length */
-		if (src && (info & BCM2835_DMA_S_INC))
+		if (src && need_src_incr(direction))
 			src += control_block->length;
-		if (dst && (info & BCM2835_DMA_D_INC))
+		if (dst && need_dst_incr(direction))
 			dst += control_block->length;
 
 		/* Length of total transfer */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH RFC 07/11] dmaengine: bcm2385: drop info parameters
  2021-12-27 12:05 [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
                   ` (5 preceding siblings ...)
  2021-12-27 12:05 ` [PATCH RFC 06/11] dmaengine: bcm2835: make address increment platform independent Stefan Wahren
@ 2021-12-27 12:05 ` Stefan Wahren
  2021-12-27 12:05 ` [PATCH RFC 08/11] dmaengine: bcm2835: pass dma_chan to generic functions Stefan Wahren
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Stefan Wahren @ 2021-12-27 12:05 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Florian Fainelli, Nicolas Saenz Julienne
  Cc: Ray Jui, Scott Branden, bcm-kernel-feedback-list, dmaengine,
	Phil Elwell, devicetree, linux-arm-kernel, Lukas Wunner,
	linux-rpi-kernel, Stefan Wahren

The parameters info and finalextrainfo are platform specific. So drop
them by generating them within bcm2835_dma_create_cb_chain().

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/dma/bcm2835-dma.c | 75 +++++++++++++++++++++++------------------------
 1 file changed, 37 insertions(+), 38 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index a7b9f88..997fe6e 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -288,13 +288,12 @@ static void bcm2835_dma_desc_free(struct virt_dma_desc *vd)
 		container_of(vd, struct bcm2835_desc, vd));
 }
 
-static void bcm2835_dma_create_cb_set_length(
+static bool bcm2835_dma_create_cb_set_length(
 	struct bcm2835_chan *chan,
 	struct bcm2835_dma_cb *control_block,
 	size_t len,
 	size_t period_len,
-	size_t *total_len,
-	u32 finalextrainfo)
+	size_t *total_len)
 {
 	size_t max_len = bcm2835_dma_max_frame_length(chan);
 
@@ -303,7 +302,7 @@ static void bcm2835_dma_create_cb_set_length(
 
 	/* finished if we have no period_length */
 	if (!period_len)
-		return;
+		return false;
 
 	/*
 	 * period_len means: that we need to generate
@@ -317,7 +316,7 @@ static void bcm2835_dma_create_cb_set_length(
 	if (*total_len + control_block->length < period_len) {
 		/* update number of bytes in this period so far */
 		*total_len += control_block->length;
-		return;
+		return false;
 	}
 
 	/* calculate the length that remains to reach period_length */
@@ -326,8 +325,7 @@ static void bcm2835_dma_create_cb_set_length(
 	/* reset total_length for next period */
 	*total_len = 0;
 
-	/* add extrainfo bits in info */
-	control_block->info |= finalextrainfo;
+	return true;
 }
 
 static inline size_t bcm2835_dma_count_frames_for_sg(
@@ -353,7 +351,6 @@ static inline size_t bcm2835_dma_count_frames_for_sg(
  * @chan:           the @dma_chan for which we run this
  * @direction:      the direction in which we transfer
  * @cyclic:         it is a cyclic transfer
- * @info:           the default info bits to apply per controlblock
  * @frames:         number of controlblocks to allocate
  * @src:            the src address to assign
  * @dst:            the dst address to assign
@@ -361,22 +358,24 @@ static inline size_t bcm2835_dma_count_frames_for_sg(
  * @period_len:     the period length when to apply @finalextrainfo
  *                  in addition to the last transfer
  *                  this will also break some control-blocks early
- * @finalextrainfo: additional bits in last controlblock
- *                  (or when period_len is reached in case of cyclic)
  * @gfp:            the GFP flag to use for allocation
+ * @flags
  */
 static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 	struct dma_chan *chan, enum dma_transfer_direction direction,
-	bool cyclic, u32 info, u32 finalextrainfo, size_t frames,
-	dma_addr_t src, dma_addr_t dst, size_t buf_len,
-	size_t period_len, gfp_t gfp)
+	bool cyclic, size_t frames, dma_addr_t src, dma_addr_t dst,
+	size_t buf_len,	size_t period_len, gfp_t gfp, unsigned long flags)
 {
+	struct bcm2835_dmadev *od = to_bcm2835_dma_dev(chan->device);
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	size_t len = buf_len, total_len;
 	size_t frame;
 	struct bcm2835_desc *d;
 	struct bcm2835_cb_entry *cb_entry;
 	struct bcm2835_dma_cb *control_block;
+	u32 extrainfo = bcm2835_dma_prepare_cb_extra(c, direction, cyclic,
+						     false, flags);
+	bool zero_page = false;
 
 	if (!frames)
 		return NULL;
@@ -390,6 +389,15 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 	d->dir = direction;
 	d->cyclic = cyclic;
 
+	switch (direction) {
+	case DMA_MEM_TO_MEM:
+	case DMA_DEV_TO_MEM:
+		break;
+	default:
+		zero_page = src == od->zero_page;
+	}
+
+
 	/*
 	 * Iterate over all frames, create a control block
 	 * for each frame and link them together.
@@ -403,7 +411,8 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 
 		/* fill in the control block */
 		control_block = cb_entry->cb;
-		control_block->info = info;
+		control_block->info = bcm2835_dma_prepare_cb_info(c, direction,
+								  zero_page);
 		control_block->src = src;
 		control_block->dst = dst;
 		control_block->stride = 0;
@@ -411,10 +420,12 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 		/* set up length in control_block if requested */
 		if (buf_len) {
 			/* calculate length honoring period_length */
-			bcm2835_dma_create_cb_set_length(
+			if (bcm2835_dma_create_cb_set_length(
 				c, control_block,
-				len, period_len, &total_len,
-				cyclic ? finalextrainfo : 0);
+				len, period_len, &total_len)) {
+				/* add extrainfo bits in info */
+				control_block->info |= extrainfo;
+			}
 
 			/* calculate new remaining length */
 			len -= control_block->length;
@@ -435,7 +446,9 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 	}
 
 	/* the last frame requires extra flags */
-	d->cb_list[d->frames - 1].cb->info |= finalextrainfo;
+	extrainfo = bcm2835_dma_prepare_cb_extra(c, direction, cyclic, true,
+						 flags);
+	d->cb_list[d->frames - 1].cb->info |= extrainfo;
 
 	/* detect a size missmatch */
 	if (buf_len && (d->size != buf_len))
@@ -683,9 +696,6 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_memcpy(
 {
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
-	u32 info = bcm2835_dma_prepare_cb_info(c, DMA_MEM_TO_MEM, false);
-	u32 extra = bcm2835_dma_prepare_cb_extra(c, DMA_MEM_TO_MEM, false,
-						 true, 0);
 	size_t max_len = bcm2835_dma_max_frame_length(c);
 	size_t frames;
 
@@ -697,9 +707,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_memcpy(
 	frames = bcm2835_dma_frames_for_length(len, max_len);
 
 	/* allocate the CB chain - this also fills in the pointers */
-	d = bcm2835_dma_create_cb_chain(chan, DMA_MEM_TO_MEM, false,
-					info, extra, frames,
-					src, dst, len, 0, GFP_KERNEL);
+	d = bcm2835_dma_create_cb_chain(chan, DMA_MEM_TO_MEM, false, frames,
+					src, dst, len, 0, GFP_KERNEL, 0);
 	if (!d)
 		return NULL;
 
@@ -715,8 +724,6 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	dma_addr_t src = 0, dst = 0;
-	u32 info = bcm2835_dma_prepare_cb_info(c, direction, false);
-	u32 extra = bcm2835_dma_prepare_cb_extra(c, direction, false, true, 0);
 	size_t frames;
 
 	if (!is_slave_direction(direction)) {
@@ -739,10 +746,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
 	frames = bcm2835_dma_count_frames_for_sg(c, sgl, sg_len);
 
 	/* allocate the CB chain */
-	d = bcm2835_dma_create_cb_chain(chan, direction, false,
-					info, extra,
-					frames, src, dst, 0, 0,
-					GFP_NOWAIT);
+	d = bcm2835_dma_create_cb_chain(chan, direction, false, frames, src,
+					dst, 0, 0, GFP_NOWAIT, 0);
 	if (!d)
 		return NULL;
 
@@ -758,13 +763,9 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 	size_t period_len, enum dma_transfer_direction direction,
 	unsigned long flags)
 {
-	struct bcm2835_dmadev *od = to_bcm2835_dma_dev(chan->device);
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	dma_addr_t src, dst;
-	u32 info = bcm2835_dma_prepare_cb_info(c, direction,
-					       buf_addr == od->zero_page);
-	u32 extra = bcm2835_dma_prepare_cb_extra(c, direction, true, true, 0);
 	size_t max_len = bcm2835_dma_max_frame_length(c);
 	size_t frames;
 
@@ -815,10 +816,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 	 * note that we need to use GFP_NOWAIT, as the ALSA i2s dmaengine
 	 * implementation calls prep_dma_cyclic with interrupts disabled.
 	 */
-	d = bcm2835_dma_create_cb_chain(chan, direction, true,
-					info, extra,
-					frames, src, dst, buf_len,
-					period_len, GFP_NOWAIT);
+	d = bcm2835_dma_create_cb_chain(chan, direction, true, frames, src, dst,
+					buf_len, period_len, GFP_NOWAIT, flags);
 	if (!d)
 		return NULL;
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH RFC 08/11] dmaengine: bcm2835: pass dma_chan to generic functions
  2021-12-27 12:05 [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
                   ` (6 preceding siblings ...)
  2021-12-27 12:05 ` [PATCH RFC 07/11] dmaengine: bcm2385: drop info parameters Stefan Wahren
@ 2021-12-27 12:05 ` Stefan Wahren
  2021-12-27 12:05 ` [PATCH RFC 09/11] dmaengine: bcm2835: introduce multi platform support Stefan Wahren
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Stefan Wahren @ 2021-12-27 12:05 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Florian Fainelli, Nicolas Saenz Julienne
  Cc: Ray Jui, Scott Branden, bcm-kernel-feedback-list, dmaengine,
	Phil Elwell, devicetree, linux-arm-kernel, Lukas Wunner,
	linux-rpi-kernel, Stefan Wahren

In preparation to support more platforms pass the dma_chan to the
generic functions. This provides access to the DMA device and possible
platform specific data.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/dma/bcm2835-dma.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 997fe6e..0933404 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -289,13 +289,14 @@ static void bcm2835_dma_desc_free(struct virt_dma_desc *vd)
 }
 
 static bool bcm2835_dma_create_cb_set_length(
-	struct bcm2835_chan *chan,
+	struct dma_chan *chan,
 	struct bcm2835_dma_cb *control_block,
 	size_t len,
 	size_t period_len,
 	size_t *total_len)
 {
-	size_t max_len = bcm2835_dma_max_frame_length(chan);
+	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
+	size_t max_len = bcm2835_dma_max_frame_length(c);
 
 	/* set the length taking lite-channel limitations into account */
 	control_block->length = min_t(u32, len, max_len);
@@ -421,7 +422,7 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 		if (buf_len) {
 			/* calculate length honoring period_length */
 			if (bcm2835_dma_create_cb_set_length(
-				c, control_block,
+				chan, control_block,
 				len, period_len, &total_len)) {
 				/* add extrainfo bits in info */
 				control_block->info |= extrainfo;
@@ -488,8 +489,9 @@ static void bcm2835_dma_fill_cb_chain_with_sg(
 	}
 }
 
-static void bcm2835_dma_abort(struct bcm2835_chan *c)
+static void bcm2835_dma_abort(struct dma_chan *chan)
 {
+	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	void __iomem *chan_base = c->chan_base;
 	long int timeout = 10000;
 
@@ -516,8 +518,9 @@ static void bcm2835_dma_abort(struct bcm2835_chan *c)
 	writel(BCM2835_DMA_RESET, chan_base + BCM2835_DMA_CS);
 }
 
-static void bcm2835_dma_start_desc(struct bcm2835_chan *c)
+static void bcm2835_dma_start_desc(struct dma_chan *chan)
 {
+	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
 	struct bcm2835_desc *d;
 
@@ -536,7 +539,8 @@ static void bcm2835_dma_start_desc(struct bcm2835_chan *c)
 
 static irqreturn_t bcm2835_dma_callback(int irq, void *data)
 {
-	struct bcm2835_chan *c = data;
+	struct dma_chan *chan = data;
+	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	unsigned long flags;
 
@@ -569,7 +573,7 @@ static irqreturn_t bcm2835_dma_callback(int irq, void *data)
 			vchan_cyclic_callback(&d->vd);
 		} else if (!readl(c->chan_base + BCM2835_DMA_ADDR)) {
 			vchan_cookie_complete(&c->desc->vd);
-			bcm2835_dma_start_desc(c);
+			bcm2835_dma_start_desc(chan);
 		}
 	}
 
@@ -597,7 +601,7 @@ static int bcm2835_dma_alloc_chan_resources(struct dma_chan *chan)
 	}
 
 	return request_irq(c->irq_number, bcm2835_dma_callback,
-			   c->irq_flags, "DMA IRQ", c);
+			   c->irq_flags, "DMA IRQ", chan);
 }
 
 static void bcm2835_dma_free_chan_resources(struct dma_chan *chan)
@@ -685,7 +689,7 @@ static void bcm2835_dma_issue_pending(struct dma_chan *chan)
 
 	spin_lock_irqsave(&c->vc.lock, flags);
 	if (vchan_issue_pending(&c->vc) && !c->desc)
-		bcm2835_dma_start_desc(c);
+		bcm2835_dma_start_desc(chan);
 
 	spin_unlock_irqrestore(&c->vc.lock, flags);
 }
@@ -849,7 +853,7 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan)
 	if (c->desc) {
 		vchan_terminate_vdesc(&c->desc->vd);
 		c->desc = NULL;
-		bcm2835_dma_abort(c);
+		bcm2835_dma_abort(chan);
 	}
 
 	vchan_get_all_descriptors(&c->vc, &head);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH RFC 09/11] dmaengine: bcm2835: introduce multi platform support
  2021-12-27 12:05 [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
                   ` (7 preceding siblings ...)
  2021-12-27 12:05 ` [PATCH RFC 08/11] dmaengine: bcm2835: pass dma_chan to generic functions Stefan Wahren
@ 2021-12-27 12:05 ` Stefan Wahren
  2022-01-23 14:08 ` [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
  2023-06-18 19:43 ` Shengyu Qu
  10 siblings, 0 replies; 15+ messages in thread
From: Stefan Wahren @ 2021-12-27 12:05 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Florian Fainelli, Nicolas Saenz Julienne
  Cc: Ray Jui, Scott Branden, bcm-kernel-feedback-list, dmaengine,
	Phil Elwell, devicetree, linux-arm-kernel, Lukas Wunner,
	linux-rpi-kernel, Stefan Wahren

This finally moves all platform specific stuff into a separate structure,
which is initialized on the OF compatible during probing. Since the DMA
control block is different on the BCM2711 platform, we introduce a common
control block to reserve the necessary space and adequate methods for
access.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/dma/bcm2835-dma.c | 303 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 235 insertions(+), 68 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 0933404..7159fa2 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -48,6 +48,11 @@ struct bcm2835_dmadev {
 	struct dma_device ddev;
 	void __iomem *base;
 	dma_addr_t zero_page;
+	const struct bcm2835_dma_cfg *cfg;
+};
+
+struct bcm_dma_cb {
+	uint32_t rsvd[8];
 };
 
 struct bcm2835_dma_cb {
@@ -61,7 +66,7 @@ struct bcm2835_dma_cb {
 };
 
 struct bcm2835_cb_entry {
-	struct bcm2835_dma_cb *cb;
+	struct bcm_dma_cb *cb;
 	dma_addr_t paddr;
 };
 
@@ -82,6 +87,38 @@ struct bcm2835_chan {
 	bool is_lite_channel;
 };
 
+struct bcm2835_dma_cfg {
+	dma_addr_t addr_offset;
+	u32 cs_reg;
+	u32 cb_reg;
+
+	u32 wait_mask;
+	u32 reset_mask;
+	u32 int_mask;
+	u32 active_mask;
+
+	u32 (*cb_get_length)(void *data);
+	dma_addr_t (*cb_get_addr)(void *data, enum dma_transfer_direction);
+
+	void (*cb_init)(void *data, struct bcm2835_chan *c,
+			enum dma_transfer_direction, u32 src, u32 dst,
+			bool zero_page);
+	void (*cb_set_src)(void *data, enum dma_transfer_direction, u32 src);
+	void (*cb_set_dst)(void *data, enum dma_transfer_direction, u32 dst);
+	void (*cb_set_next)(void *data, u32 next);
+	void (*cb_set_length)(void *data, u32 length);
+	void (*cb_append_extra)(void *data,
+				struct bcm2835_chan *c,
+				enum dma_transfer_direction direction,
+				bool cyclic, bool final, unsigned long flags);
+
+	u32 (*to_cb_addr)(dma_addr_t addr);
+
+	void (*chan_plat_init)(struct bcm2835_chan *c);
+	dma_addr_t (*read_addr)(struct bcm2835_chan *c,
+				enum dma_transfer_direction);
+};
+
 struct bcm2835_desc {
 	struct bcm2835_chan *c;
 	struct virt_dma_desc vd;
@@ -190,6 +227,13 @@ static inline struct bcm2835_dmadev *to_bcm2835_dma_dev(struct dma_device *d)
 	return container_of(d, struct bcm2835_dmadev, ddev);
 }
 
+static inline const struct bcm2835_dma_cfg *to_bcm2835_cfg(struct dma_device *d)
+{
+	struct bcm2835_dmadev *od = container_of(d, struct bcm2835_dmadev, ddev);
+
+	return od->cfg;
+}
+
 static inline struct bcm2835_chan *to_bcm2835_dma_chan(struct dma_chan *c)
 {
 	return container_of(c, struct bcm2835_chan, vc.chan);
@@ -271,6 +315,104 @@ static inline bool need_dst_incr(enum dma_transfer_direction direction)
 	return false;
 }
 
+static inline u32 bcm2835_dma_cb_get_length(void *data)
+{
+	struct bcm2835_dma_cb *cb = data;
+
+	return cb->length;
+}
+
+static inline dma_addr_t
+bcm2835_dma_cb_get_addr(void *data, enum dma_transfer_direction direction)
+{
+	struct bcm2835_dma_cb *cb = data;
+
+	if (direction == DMA_DEV_TO_MEM)
+		return cb->dst;
+
+	return cb->src;
+}
+
+static inline void
+bcm2835_dma_cb_init(void *data, struct bcm2835_chan *c,
+		    enum dma_transfer_direction direction, u32 src, u32 dst,
+		    bool zero_page)
+{
+	struct bcm2835_dma_cb *cb = data;
+
+	cb->info = bcm2835_dma_prepare_cb_info(c, direction, zero_page);
+	cb->src = src;
+	cb->dst = dst;
+	cb->stride = 0;
+	cb->next = 0;
+}
+
+static inline void
+bcm2835_dma_cb_set_src(void *data, enum dma_transfer_direction direction,
+		       u32 src)
+{
+	struct bcm2835_dma_cb *cb = data;
+
+	cb->src = src;
+}
+
+static inline void
+bcm2835_dma_cb_set_dst(void *data, enum dma_transfer_direction direction,
+		       u32 dst)
+{
+	struct bcm2835_dma_cb *cb = data;
+
+	cb->dst = dst;
+}
+
+static inline void bcm2835_dma_cb_set_next(void *data, u32 next)
+{
+	struct bcm2835_dma_cb *cb = data;
+
+	cb->next = next;
+}
+
+static inline void bcm2835_dma_cb_set_length(void *data, u32 length)
+{
+	struct bcm2835_dma_cb *cb = data;
+
+	cb->length = length;
+}
+
+static inline void
+bcm2835_dma_cb_append_extra(void *data, struct bcm2835_chan *c,
+			    enum dma_transfer_direction direction,
+			    bool cyclic, bool final, unsigned long flags)
+{
+	struct bcm2835_dma_cb *cb = data;
+
+	cb->info |= bcm2835_dma_prepare_cb_extra(c, direction, cyclic, final,
+						 flags);
+}
+
+static inline dma_addr_t bcm2835_dma_to_cb_addr(dma_addr_t addr)
+{
+	return addr;
+}
+
+static void bcm2835_dma_chan_plat_init(struct bcm2835_chan *c)
+{
+	/* check in DEBUG register if this is a LITE channel */
+	if (readl(c->chan_base + BCM2835_DMA_DEBUG) & BCM2835_DMA_DEBUG_LITE)
+		c->is_lite_channel = true;
+}
+
+static dma_addr_t bcm2835_dma_read_addr(struct bcm2835_chan *c,
+					enum dma_transfer_direction direction)
+{
+	if (direction == DMA_MEM_TO_DEV)
+		return readl(c->chan_base + BCM2835_DMA_SOURCE_AD);
+	else if (direction == DMA_DEV_TO_MEM)
+		return readl(c->chan_base + BCM2835_DMA_DEST_AD);
+
+	return 0;
+}
+
 static void bcm2835_dma_free_cb_chain(struct bcm2835_desc *desc)
 {
 	size_t i;
@@ -290,16 +432,19 @@ static void bcm2835_dma_desc_free(struct virt_dma_desc *vd)
 
 static bool bcm2835_dma_create_cb_set_length(
 	struct dma_chan *chan,
-	struct bcm2835_dma_cb *control_block,
+	void *data,
 	size_t len,
 	size_t period_len,
 	size_t *total_len)
 {
+	const struct bcm2835_dma_cfg *cfg = to_bcm2835_cfg(chan->device);
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	size_t max_len = bcm2835_dma_max_frame_length(c);
 
 	/* set the length taking lite-channel limitations into account */
-	control_block->length = min_t(u32, len, max_len);
+	u32 length = min_t(u32, len, max_len);
+
+	cfg->cb_set_length(data, length);
 
 	/* finished if we have no period_length */
 	if (!period_len)
@@ -314,14 +459,14 @@ static bool bcm2835_dma_create_cb_set_length(
 	 */
 
 	/* have we filled in period_length yet? */
-	if (*total_len + control_block->length < period_len) {
+	if (*total_len + length < period_len) {
 		/* update number of bytes in this period so far */
-		*total_len += control_block->length;
+		*total_len += length;
 		return false;
 	}
 
 	/* calculate the length that remains to reach period_length */
-	control_block->length = period_len - *total_len;
+	cfg->cb_set_length(data, period_len - *total_len);
 
 	/* reset total_length for next period */
 	*total_len = 0;
@@ -367,15 +512,14 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 	bool cyclic, size_t frames, dma_addr_t src, dma_addr_t dst,
 	size_t buf_len,	size_t period_len, gfp_t gfp, unsigned long flags)
 {
+	const struct bcm2835_dma_cfg *cfg = to_bcm2835_cfg(chan->device);
 	struct bcm2835_dmadev *od = to_bcm2835_dma_dev(chan->device);
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	size_t len = buf_len, total_len;
 	size_t frame;
 	struct bcm2835_desc *d;
 	struct bcm2835_cb_entry *cb_entry;
-	struct bcm2835_dma_cb *control_block;
-	u32 extrainfo = bcm2835_dma_prepare_cb_extra(c, direction, cyclic,
-						     false, flags);
+	struct bcm_dma_cb *control_block;
 	bool zero_page = false;
 
 	if (!frames)
@@ -412,12 +556,7 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 
 		/* fill in the control block */
 		control_block = cb_entry->cb;
-		control_block->info = bcm2835_dma_prepare_cb_info(c, direction,
-								  zero_page);
-		control_block->src = src;
-		control_block->dst = dst;
-		control_block->stride = 0;
-		control_block->next = 0;
+		cfg->cb_init(control_block, c, src, dst, direction, zero_page);
 		/* set up length in control_block if requested */
 		if (buf_len) {
 			/* calculate length honoring period_length */
@@ -425,31 +564,33 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 				chan, control_block,
 				len, period_len, &total_len)) {
 				/* add extrainfo bits in info */
-				control_block->info |= extrainfo;
+				bcm2835_dma_cb_append_extra(control_block, c,
+							    direction, cyclic,
+							    false, flags);
 			}
 
 			/* calculate new remaining length */
-			len -= control_block->length;
+			len -= cfg->cb_get_length(control_block);
 		}
 
 		/* link this the last controlblock */
 		if (frame)
-			d->cb_list[frame - 1].cb->next = cb_entry->paddr;
+			cfg->cb_set_next(d->cb_list[frame - 1].cb,
+					 cb_entry->paddr);
 
 		/* update src and dst and length */
 		if (src && need_src_incr(direction))
-			src += control_block->length;
+			src += cfg->cb_get_length(control_block);
 		if (dst && need_dst_incr(direction))
-			dst += control_block->length;
+			dst += cfg->cb_get_length(control_block);
 
 		/* Length of total transfer */
-		d->size += control_block->length;
+		d->size += cfg->cb_get_length(control_block);
 	}
 
 	/* the last frame requires extra flags */
-	extrainfo = bcm2835_dma_prepare_cb_extra(c, direction, cyclic, true,
-						 flags);
-	d->cb_list[d->frames - 1].cb->info |= extrainfo;
+	cfg->cb_append_extra(d->cb_list[d->frames - 1].cb, c, direction, cyclic,
+			     true, flags);
 
 	/* detect a size missmatch */
 	if (buf_len && (d->size != buf_len))
@@ -469,6 +610,7 @@ static void bcm2835_dma_fill_cb_chain_with_sg(
 	struct scatterlist *sgl,
 	unsigned int sg_len)
 {
+	const struct bcm2835_dma_cfg *cfg = to_bcm2835_cfg(chan->device);
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	size_t len, max_len;
 	unsigned int i;
@@ -479,18 +621,19 @@ static void bcm2835_dma_fill_cb_chain_with_sg(
 	for_each_sg(sgl, sgent, sg_len, i) {
 		for (addr = sg_dma_address(sgent), len = sg_dma_len(sgent);
 		     len > 0;
-		     addr += cb->cb->length, len -= cb->cb->length, cb++) {
+		     addr += cfg->cb_get_length(cb->cb), len -= cfg->cb_get_length(cb->cb), cb++) {
 			if (direction == DMA_DEV_TO_MEM)
-				cb->cb->dst = addr;
+				cfg->cb_set_dst(cb->cb, direction, addr);
 			else
-				cb->cb->src = addr;
-			cb->cb->length = min(len, max_len);
+				cfg->cb_set_src(cb->cb, direction, addr);
+			cfg->cb_set_length(cb->cb, min(len, max_len));
 		}
 	}
 }
 
 static void bcm2835_dma_abort(struct dma_chan *chan)
 {
+	const struct bcm2835_dma_cfg *cfg = to_bcm2835_cfg(chan->device);
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	void __iomem *chan_base = c->chan_base;
 	long int timeout = 10000;
@@ -499,15 +642,15 @@ static void bcm2835_dma_abort(struct dma_chan *chan)
 	 * A zero control block address means the channel is idle.
 	 * (The ACTIVE flag in the CS register is not a reliable indicator.)
 	 */
-	if (!readl(chan_base + BCM2835_DMA_ADDR))
+	if (!readl(chan_base + cfg->cb_reg))
 		return;
 
 	/* Write 0 to the active bit - Pause the DMA */
-	writel(0, chan_base + BCM2835_DMA_CS);
+	writel(0, chan_base + cfg->cs_reg);
 
 	/* Wait for any current AXI transfer to complete */
-	while ((readl(chan_base + BCM2835_DMA_CS) &
-		BCM2835_DMA_WAITING_FOR_WRITES) && --timeout)
+	while ((readl(chan_base + cfg->cs_reg) & cfg->wait_mask) &&
+	       --timeout)
 		cpu_relax();
 
 	/* Peripheral might be stuck and fail to signal AXI write responses */
@@ -515,11 +658,12 @@ static void bcm2835_dma_abort(struct dma_chan *chan)
 		dev_err(c->vc.chan.device->dev,
 			"failed to complete outstanding writes\n");
 
-	writel(BCM2835_DMA_RESET, chan_base + BCM2835_DMA_CS);
+	writel(cfg->reset_mask, chan_base + cfg->cs_reg);
 }
 
 static void bcm2835_dma_start_desc(struct dma_chan *chan)
 {
+	const struct bcm2835_dma_cfg *cfg = to_bcm2835_cfg(chan->device);
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
 	struct bcm2835_desc *d;
@@ -533,13 +677,14 @@ static void bcm2835_dma_start_desc(struct dma_chan *chan)
 
 	c->desc = d = to_bcm2835_dma_desc(&vd->tx);
 
-	writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR);
-	writel(BCM2835_DMA_ACTIVE, c->chan_base + BCM2835_DMA_CS);
+	writel(cfg->to_cb_addr(d->cb_list[0].paddr), c->chan_base + cfg->cb_reg);
+	writel(cfg->active_mask, c->chan_base + cfg->cs_reg);
 }
 
 static irqreturn_t bcm2835_dma_callback(int irq, void *data)
 {
 	struct dma_chan *chan = data;
+	const struct bcm2835_dma_cfg *cfg = to_bcm2835_cfg(chan->device);
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	unsigned long flags;
@@ -547,9 +692,9 @@ static irqreturn_t bcm2835_dma_callback(int irq, void *data)
 	/* check the shared interrupt */
 	if (c->irq_flags & IRQF_SHARED) {
 		/* check if the interrupt is enabled */
-		flags = readl(c->chan_base + BCM2835_DMA_CS);
+		flags = readl(c->chan_base + cfg->cs_reg);
 		/* if not set then we are not the reason for the irq */
-		if (!(flags & BCM2835_DMA_INT))
+		if (!(flags & cfg->int_mask))
 			return IRQ_NONE;
 	}
 
@@ -562,8 +707,7 @@ static irqreturn_t bcm2835_dma_callback(int irq, void *data)
 	 * if this IRQ handler is threaded.) If the channel is finished, it
 	 * will remain idle despite the ACTIVE flag being set.
 	 */
-	writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE,
-	       c->chan_base + BCM2835_DMA_CS);
+	writel(cfg->int_mask | cfg->active_mask, c->chan_base + cfg->cs_reg);
 
 	d = c->desc;
 
@@ -571,7 +715,7 @@ static irqreturn_t bcm2835_dma_callback(int irq, void *data)
 		if (d->cyclic) {
 			/* call the cyclic callback */
 			vchan_cyclic_callback(&d->vd);
-		} else if (!readl(c->chan_base + BCM2835_DMA_ADDR)) {
+		} else if (!readl(c->chan_base + cfg->cb_reg)) {
 			vchan_cookie_complete(&c->desc->vd);
 			bcm2835_dma_start_desc(chan);
 		}
@@ -594,7 +738,7 @@ static int bcm2835_dma_alloc_chan_resources(struct dma_chan *chan)
 	 * (32 byte) aligned address (BCM2835 ARM Peripherals, sec. 4.2.1.1).
 	 */
 	c->cb_pool = dma_pool_create(dev_name(dev), dev,
-				     sizeof(struct bcm2835_dma_cb), 32, 0);
+				     sizeof(struct bcm_dma_cb), 32, 0);
 	if (!c->cb_pool) {
 		dev_err(dev, "unable to allocate descriptor pool\n");
 		return -ENOMEM;
@@ -620,20 +764,16 @@ static size_t bcm2835_dma_desc_size(struct bcm2835_desc *d)
 	return d->size;
 }
 
-static size_t bcm2835_dma_desc_size_pos(struct bcm2835_desc *d, dma_addr_t addr)
+static size_t bcm2835_dma_desc_size_pos(const struct bcm2835_dma_cfg *cfg,
+					struct bcm2835_desc *d, dma_addr_t addr)
 {
 	unsigned int i;
 	size_t size;
 
 	for (size = i = 0; i < d->frames; i++) {
-		struct bcm2835_dma_cb *control_block = d->cb_list[i].cb;
-		size_t this_size = control_block->length;
-		dma_addr_t dma;
-
-		if (d->dir == DMA_DEV_TO_MEM)
-			dma = control_block->dst;
-		else
-			dma = control_block->src;
+		struct bcm_dma_cb *control_block = d->cb_list[i].cb;
+		size_t this_size = cfg->cb_get_length(control_block);
+		dma_addr_t dma = cfg->cb_get_addr(control_block, d->dir);
 
 		if (size)
 			size += this_size;
@@ -647,6 +787,7 @@ static size_t bcm2835_dma_desc_size_pos(struct bcm2835_desc *d, dma_addr_t addr)
 static enum dma_status bcm2835_dma_tx_status(struct dma_chan *chan,
 	dma_cookie_t cookie, struct dma_tx_state *txstate)
 {
+	const struct bcm2835_dma_cfg *cfg = to_bcm2835_cfg(chan->device);
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct virt_dma_desc *vd;
 	enum dma_status ret;
@@ -665,14 +806,8 @@ static enum dma_status bcm2835_dma_tx_status(struct dma_chan *chan,
 		struct bcm2835_desc *d = c->desc;
 		dma_addr_t pos;
 
-		if (d->dir == DMA_MEM_TO_DEV)
-			pos = readl(c->chan_base + BCM2835_DMA_SOURCE_AD);
-		else if (d->dir == DMA_DEV_TO_MEM)
-			pos = readl(c->chan_base + BCM2835_DMA_DEST_AD);
-		else
-			pos = 0;
-
-		txstate->residue = bcm2835_dma_desc_size_pos(d, pos);
+		pos = cfg->read_addr(c, d->dir);
+		txstate->residue = bcm2835_dma_desc_size_pos(cfg, d, pos);
 	} else {
 		txstate->residue = 0;
 	}
@@ -725,6 +860,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
 	enum dma_transfer_direction direction,
 	unsigned long flags, void *context)
 {
+	const struct bcm2835_dma_cfg *cfg = to_bcm2835_cfg(chan->device);
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	dma_addr_t src = 0, dst = 0;
@@ -739,11 +875,11 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
 	if (direction == DMA_DEV_TO_MEM) {
 		if (c->cfg.src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
-		src = c->cfg.src_addr;
+		src = cfg->addr_offset + c->cfg.src_addr;
 	} else {
 		if (c->cfg.dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
-		dst = c->cfg.dst_addr;
+		dst = cfg->addr_offset + c->cfg.dst_addr;
 	}
 
 	/* count frames in sg list */
@@ -767,6 +903,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 	size_t period_len, enum dma_transfer_direction direction,
 	unsigned long flags)
 {
+	const struct bcm2835_dma_cfg *cfg = to_bcm2835_cfg(chan->device);
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	dma_addr_t src, dst;
@@ -800,12 +937,12 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 	if (direction == DMA_DEV_TO_MEM) {
 		if (c->cfg.src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
-		src = c->cfg.src_addr;
+		src = cfg->addr_offset + c->cfg.src_addr;
 		dst = buf_addr;
 	} else {
 		if (c->cfg.dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
-		dst = c->cfg.dst_addr;
+		dst = cfg->addr_offset + c->cfg.dst_addr;
 		src = buf_addr;
 	}
 
@@ -826,7 +963,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 		return NULL;
 
 	/* wrap around into a loop */
-	d->cb_list[d->frames - 1].cb->next = d->cb_list[0].paddr;
+	cfg->cb_set_next(d->cb_list[d->frames - 1].cb,
+			 cfg->to_cb_addr(d->cb_list[0].paddr));
 
 	return vchan_tx_prep(&c->vc, &d->vd, flags);
 }
@@ -887,10 +1025,7 @@ static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id,
 	c->irq_number = irq;
 	c->irq_flags = irq_flags;
 
-	/* check in DEBUG register if this is a LITE channel */
-	if (readl(c->chan_base + BCM2835_DMA_DEBUG) &
-		BCM2835_DMA_DEBUG_LITE)
-		c->is_lite_channel = true;
+	d->cfg->chan_plat_init(c);
 
 	return 0;
 }
@@ -909,8 +1044,34 @@ static void bcm2835_dma_free(struct bcm2835_dmadev *od)
 			     DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
 }
 
+static const struct bcm2835_dma_cfg bcm2835_data = {
+	.addr_offset = 0,
+
+	.cs_reg = BCM2835_DMA_CS,
+	.cb_reg = BCM2835_DMA_ADDR,
+
+	.wait_mask = BCM2835_DMA_WAITING_FOR_WRITES,
+	.reset_mask = BCM2835_DMA_RESET,
+	.int_mask = BCM2835_DMA_INT,
+	.active_mask = BCM2835_DMA_ACTIVE,
+
+	.cb_get_length = bcm2835_dma_cb_get_length,
+	.cb_get_addr = bcm2835_dma_cb_get_addr,
+	.cb_init = bcm2835_dma_cb_init,
+	.cb_set_src = bcm2835_dma_cb_set_src,
+	.cb_set_dst = bcm2835_dma_cb_set_dst,
+	.cb_set_next = bcm2835_dma_cb_set_next,
+	.cb_set_length = bcm2835_dma_cb_set_length,
+	.cb_append_extra = bcm2835_dma_cb_append_extra,
+
+	.to_cb_addr = bcm2835_dma_to_cb_addr,
+
+	.chan_plat_init = bcm2835_dma_chan_plat_init,
+	.read_addr = bcm2835_dma_read_addr,
+};
+
 static const struct of_device_id bcm2835_dma_of_match[] = {
-	{ .compatible = "brcm,bcm2835-dma", },
+	{ .compatible = "brcm,bcm2835-dma", .data = &bcm2835_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, bcm2835_dma_of_match);
@@ -933,6 +1094,7 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
 
 static int bcm2835_dma_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *of_id;
 	struct bcm2835_dmadev *od;
 	struct resource *res;
 	void __iomem *base;
@@ -943,6 +1105,10 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
 	uint32_t chans_available;
 	char chan_name[BCM2835_DMA_CHAN_NAME_SIZE];
 
+	of_id = of_match_node(bcm2835_dma_of_match, pdev->dev.of_node);
+	if (!of_id)
+		return -EINVAL;
+
 	if (!pdev->dev.dma_mask)
 		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
 
@@ -964,6 +1130,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
 		return PTR_ERR(base);
 
 	od->base = base;
+	od->cfg = of_id->data;
 
 	dma_cap_set(DMA_SLAVE, od->ddev.cap_mask);
 	dma_cap_set(DMA_PRIVATE, od->ddev.cap_mask);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH RFC 02/11] dt-bindings: dma: Convert brcm,bcm2835-dma to json-schema
  2021-12-27 12:05 ` [PATCH RFC 02/11] dt-bindings: dma: Convert brcm,bcm2835-dma to json-schema Stefan Wahren
@ 2022-01-04 22:50   ` Rob Herring
  0 siblings, 0 replies; 15+ messages in thread
From: Rob Herring @ 2022-01-04 22:50 UTC (permalink / raw)
  To: Stefan Wahren
  Cc: Vinod Koul, Florian Fainelli, Nicolas Saenz Julienne, Ray Jui,
	Scott Branden, bcm-kernel-feedback-list, dmaengine, Phil Elwell,
	devicetree, linux-arm-kernel, Lukas Wunner, linux-rpi-kernel

On Mon, Dec 27, 2021 at 01:05:36PM +0100, Stefan Wahren wrote:
> This convert the BCM2835 DMA bindings to YAML format.
> 
> Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
> ---
>  .../devicetree/bindings/dma/brcm,bcm2835-dma.txt   |  83 ----------------
>  .../devicetree/bindings/dma/brcm,bcm2835-dma.yaml  | 107 +++++++++++++++++++++
>  2 files changed, 107 insertions(+), 83 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
>  create mode 100644 Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml
> 
> diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
> deleted file mode 100644
> index b6a8cc0..0000000
> --- a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
> +++ /dev/null
> @@ -1,83 +0,0 @@
> -* BCM2835 DMA controller
> -
> -The BCM2835 DMA controller has 16 channels in total.
> -Only the lower 13 channels have an associated IRQ.
> -Some arbitrary channels are used by the firmware
> -(1,3,6,7 in the current firmware version).
> -The channels 0,2 and 3 have special functionality
> -and should not be used by the driver.
> -
> -Required properties:
> -- compatible: Should be "brcm,bcm2835-dma".
> -- reg: Should contain DMA registers location and length.
> -- interrupts: Should contain the DMA interrupts associated
> -		to the DMA channels in ascending order.
> -- interrupt-names: Should contain the names of the interrupt
> -		   in the form "dmaXX".
> -		   Use "dma-shared-all" for the common interrupt line
> -		   that is shared by all dma channels.
> -- #dma-cells: Must be <1>, the cell in the dmas property of the
> -		client device represents the DREQ number.
> -- brcm,dma-channel-mask: Bit mask representing the channels
> -			 not used by the firmware in ascending order,
> -			 i.e. first channel corresponds to LSB.
> -
> -Example:
> -
> -dma: dma@7e007000 {
> -	compatible = "brcm,bcm2835-dma";
> -	reg = <0x7e007000 0xf00>;
> -	interrupts = <1 16>,
> -		     <1 17>,
> -		     <1 18>,
> -		     <1 19>,
> -		     <1 20>,
> -		     <1 21>,
> -		     <1 22>,
> -		     <1 23>,
> -		     <1 24>,
> -		     <1 25>,
> -		     <1 26>,
> -		     /* dma channel 11-14 share one irq */
> -		     <1 27>,
> -		     <1 27>,
> -		     <1 27>,
> -		     <1 27>,
> -		     /* unused shared irq for all channels */
> -		     <1 28>;
> -	interrupt-names = "dma0",
> -			  "dma1",
> -			  "dma2",
> -			  "dma3",
> -			  "dma4",
> -			  "dma5",
> -			  "dma6",
> -			  "dma7",
> -			  "dma8",
> -			  "dma9",
> -			  "dma10",
> -			  "dma11",
> -			  "dma12",
> -			  "dma13",
> -			  "dma14",
> -			  "dma-shared-all";
> -
> -	#dma-cells = <1>;
> -	brcm,dma-channel-mask = <0x7f35>;
> -};
> -
> -
> -DMA clients connected to the BCM2835 DMA controller must use the format
> -described in the dma.txt file, using a two-cell specifier for each channel.
> -
> -Example:
> -
> -bcm2835_i2s: i2s@7e203000 {
> -	compatible = "brcm,bcm2835-i2s";
> -	reg = <	0x7e203000 0x24>;
> -	clocks = <&clocks BCM2835_CLOCK_PCM>;
> -
> -	dmas = <&dma 2>,
> -	       <&dma 3>;
> -	dma-names = "tx", "rx";
> -};
> diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml
> new file mode 100644
> index 0000000..44cb83f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml
> @@ -0,0 +1,107 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/dma/brcm,bcm2835-dma.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: BCM2835 DMA controller
> +
> +maintainers:
> +  - Nicolas Saenz Julienne <nsaenz@kernel.org>
> +
> +description: |

Don't need '|' unless there is formatting to preserve.

> +  The BCM2835 DMA controller has 16 channels in total.
> +  Only the lower 13 channels have an associated IRQ.
> +  Some arbitrary channels are used by the firmware
> +  (1,3,6,7 in the current firmware version).
> +  The channels 0,2 and 3 have special functionality
> +  and should not be used by the driver.

Re-wrap the lines.

> +
> +allOf:
> +  - $ref: "dma-controller.yaml#"
> +
> +properties:
> +  compatible:
> +    const: brcm,bcm2835-dma
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    description:
> +      Should contain the DMA interrupts associated to the DMA channels in
> +      ascending order.
> +    minItems: 1
> +    maxItems: 16
> +
> +  interrupt-names:
> +    minItems: 1
> +    maxItems: 16

The names must be defined. You can do:

items:
  pattern: ...

> +
> +  "#dma-cells":
> +    const: 1
> +    description: >
> +      DMA clients must use the format described in dma.txt, giving a phandle

Please read dma.txt.

> +      to the DMA controller while the second cell in the dmas property of the

Cells don't include the phandle, so 'second cell' is odd. Reword all 
this to be just what is specific to this binding.

> +      client device represents the DREQ number.
> +
> +  brcm,dma-channel-mask:
> +    description:
> +      Bit mask representing the channels not used by the firmware in
> +      ascending order, i.e. first channel corresponds to LSB.
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - "#dma-cells"
> +  - brcm,dma-channel-mask
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    dma: dma-controller@7e007000 {
> +      compatible = "brcm,bcm2835-dma";
> +      reg = <0x7e007000 0xf00>;
> +      interrupts = <1 16>,
> +                   <1 17>,
> +                   <1 18>,
> +                   <1 19>,
> +                   <1 20>,
> +                   <1 21>,
> +                   <1 22>,
> +                   <1 23>,
> +                   <1 24>,
> +                   <1 25>,
> +                   <1 26>,
> +                   /* dma channel 11-14 share one irq */
> +                   <1 27>,
> +                   <1 27>,
> +                   <1 27>,
> +                   <1 27>,
> +                   /* unused shared irq for all channels */
> +                   <1 28>;
> +      interrupt-names = "dma0",
> +                        "dma1",
> +                        "dma2",
> +                        "dma3",
> +                        "dma4",
> +                        "dma5",
> +                        "dma6",
> +                        "dma7",
> +                        "dma8",
> +                        "dma9",
> +                        "dma10",
> +                        "dma11",
> +                        "dma12",
> +                        "dma13",
> +                        "dma14",
> +                        "dma-shared-all";
> +        #dma-cells = <1>;
> +        brcm,dma-channel-mask = <0x7f35>;
> +    };
> +
> +...
> -- 
> 2.7.4
> 
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support
  2021-12-27 12:05 [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
                   ` (8 preceding siblings ...)
  2021-12-27 12:05 ` [PATCH RFC 09/11] dmaengine: bcm2835: introduce multi platform support Stefan Wahren
@ 2022-01-23 14:08 ` Stefan Wahren
  2022-02-15 11:20   ` Vinod Koul
  2023-06-18 19:43 ` Shengyu Qu
  10 siblings, 1 reply; 15+ messages in thread
From: Stefan Wahren @ 2022-01-23 14:08 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Florian Fainelli, Nicolas Saenz Julienne
  Cc: Ray Jui, Scott Branden, bcm-kernel-feedback-list, dmaengine,
	Phil Elwell, devicetree, linux-arm-kernel, Lukas Wunner,
	linux-rpi-kernel

Hi,

Am 27.12.21 um 13:05 schrieb Stefan Wahren:
> The BCM2711 has 4 DMA channels with a 40-bit address range, allowing them
> to access the full 4GB of memory on a Pi 4. This patch series serves as a
> basis for a discussion (just compile tested, so don't expect anything working)
> which include the following points:
>
> * correct DT binding and representation for BCM2711
>
> According to the vendor DTS [1] the 4 DMA channels are connected to SCB.
> I'm not sure how this is properly adapted to the mainline DT.
>
> * general implementation approach
>
> The vendor approach mapped all the BCM2835 control block bits to the BCM2711
> layout and the rest of the differences are handled by a lot of is_40bit_channel
> conditions. An advantage of this is the small amount of changes to the driver.
> But on the down side the code is now much harder to understand and maintain.
>
> This series tries to implement this feature in a more cleaner way
> while keeping it in the bcm2835-dma driver. Before this series the driver
> has ~ 1000 lines and after that ~ 1500 lines.
>
> So the question is this approach acceptable?
>
> Patches 1 - 3 are just clean-ups.
>
> Disclaimer: my knowledge about the DMA controller is very limited
>
> More information:
>
> https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf
>
> [1] - https://github.com/raspberrypi/linux/blob/561deffcf471ba0f7bd48541d06a79d5aa38d297/arch/arm/boot/dts/bcm2711-rpi-ds.dtsi#L47
> [2] - https://github.com/raspberrypi/linux/commit/44364bd140b0bc9187c881fbdc4ee358961059d5
would be nice to get some input aka gentle ping.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support
  2022-01-23 14:08 ` [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
@ 2022-02-15 11:20   ` Vinod Koul
  0 siblings, 0 replies; 15+ messages in thread
From: Vinod Koul @ 2022-02-15 11:20 UTC (permalink / raw)
  To: Stefan Wahren
  Cc: Rob Herring, Florian Fainelli, Nicolas Saenz Julienne, Ray Jui,
	Scott Branden, bcm-kernel-feedback-list, dmaengine, Phil Elwell,
	devicetree, linux-arm-kernel, Lukas Wunner, linux-rpi-kernel

On 23-01-22, 15:08, Stefan Wahren wrote:
> Hi,
> 
> Am 27.12.21 um 13:05 schrieb Stefan Wahren:
> > The BCM2711 has 4 DMA channels with a 40-bit address range, allowing them
> > to access the full 4GB of memory on a Pi 4. This patch series serves as a
> > basis for a discussion (just compile tested, so don't expect anything working)
> > which include the following points:
> >
> > * correct DT binding and representation for BCM2711
> >
> > According to the vendor DTS [1] the 4 DMA channels are connected to SCB.
> > I'm not sure how this is properly adapted to the mainline DT.
> >
> > * general implementation approach
> >
> > The vendor approach mapped all the BCM2835 control block bits to the BCM2711
> > layout and the rest of the differences are handled by a lot of is_40bit_channel
> > conditions. An advantage of this is the small amount of changes to the driver.
> > But on the down side the code is now much harder to understand and maintain.
> >
> > This series tries to implement this feature in a more cleaner way
> > while keeping it in the bcm2835-dma driver. Before this series the driver
> > has ~ 1000 lines and after that ~ 1500 lines.
> >
> > So the question is this approach acceptable?
> >
> > Patches 1 - 3 are just clean-ups.
> >
> > Disclaimer: my knowledge about the DMA controller is very limited
> >
> > More information:
> >
> > https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf
> >
> > [1] - https://github.com/raspberrypi/linux/blob/561deffcf471ba0f7bd48541d06a79d5aa38d297/arch/arm/boot/dts/bcm2711-rpi-ds.dtsi#L47
> > [2] - https://github.com/raspberrypi/linux/commit/44364bd140b0bc9187c881fbdc4ee358961059d5
> would be nice to get some input aka gentle ping.

Somehow patch 10/11 is appearing split from rest of the series. The
series looks fairly okay, dts needs more polishing as Rob indicated

-- 
~Vinod

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support
  2021-12-27 12:05 [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
                   ` (9 preceding siblings ...)
  2022-01-23 14:08 ` [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
@ 2023-06-18 19:43 ` Shengyu Qu
  2023-06-18 21:14   ` Stefan Wahren
  10 siblings, 1 reply; 15+ messages in thread
From: Shengyu Qu @ 2023-06-18 19:43 UTC (permalink / raw)
  To: Stefan Wahren, Vinod Koul, Rob Herring, Florian Fainelli,
	Nicolas Saenz Julienne
  Cc: wiagn233, Ray Jui, Scott Branden, bcm-kernel-feedback-list,
	dmaengine, Phil Elwell, devicetree, linux-arm-kernel,
	Lukas Wunner, linux-rpi-kernel


[-- Attachment #1.1.1: Type: text/plain, Size: 2935 bytes --]

Hello Stefan,

Sorry to reply to this old series, but I wonder what happens to this 
series?

Best regards,

Shengyu

> The BCM2711 has 4 DMA channels with a 40-bit address range, allowing them
> to access the full 4GB of memory on a Pi 4. This patch series serves as a
> basis for a discussion (just compile tested, so don't expect anything working)
> which include the following points:
>
> * correct DT binding and representation for BCM2711
>
> According to the vendor DTS [1] the 4 DMA channels are connected to SCB.
> I'm not sure how this is properly adapted to the mainline DT.
>
> * general implementation approach
>
> The vendor approach mapped all the BCM2835 control block bits to the BCM2711
> layout and the rest of the differences are handled by a lot of is_40bit_channel
> conditions. An advantage of this is the small amount of changes to the driver.
> But on the down side the code is now much harder to understand and maintain.
>
> This series tries to implement this feature in a more cleaner way
> while keeping it in the bcm2835-dma driver. Before this series the driver
> has ~ 1000 lines and after that ~ 1500 lines.
>
> So the question is this approach acceptable?
>
> Patches 1 - 3 are just clean-ups.
>
> Disclaimer: my knowledge about the DMA controller is very limited
>
> More information:
>
> https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf
>
> [1] - https://github.com/raspberrypi/linux/blob/561deffcf471ba0f7bd48541d06a79d5aa38d297/arch/arm/boot/dts/bcm2711-rpi-ds.dtsi#L47
> [2] - https://github.com/raspberrypi/linux/commit/44364bd140b0bc9187c881fbdc4ee358961059d5
>
> Stefan Wahren (11):
>    ARM: dts: bcm283x: Update DMA node name per DT schema
>    dt-bindings: dma: Convert brcm,bcm2835-dma to json-schema
>    dmaengine: bcm2835: Support common dma-channel-mask
>    dmaengine: bcm2835: move CB info generation into separate function
>    dmaengine: bcm2835: move CB final extra info generation into function
>    dmaengine: bcm2835: make address increment platform independent
>    dmaengine: bcm2385: drop info parameters
>    dmaengine: bcm2835: pass dma_chan to generic functions
>    dmaengine: bcm2835: introduce multi platform support
>    dmaengine: bcm2835: add BCM2711 40-bit DMA support
>    ARM: dts: bcm2711: add bcm2711-dma node
>
>   .../devicetree/bindings/dma/brcm,bcm2835-dma.txt   |  83 ---
>   .../devicetree/bindings/dma/brcm,bcm2835-dma.yaml  | 107 +++
>   arch/arm/boot/dts/bcm2711.dtsi                     |  18 +-
>   arch/arm/boot/dts/bcm2835-common.dtsi              |   2 +-
>   drivers/dma/bcm2835-dma.c                          | 745 +++++++++++++++++----
>   5 files changed, 734 insertions(+), 221 deletions(-)
>   delete mode 100644 Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
>   create mode 100644 Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml
>

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 6977 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support
  2023-06-18 19:43 ` Shengyu Qu
@ 2023-06-18 21:14   ` Stefan Wahren
  0 siblings, 0 replies; 15+ messages in thread
From: Stefan Wahren @ 2023-06-18 21:14 UTC (permalink / raw)
  To: Shengyu Qu, Vinod Koul, Rob Herring, Florian Fainelli,
	Nicolas Saenz Julienne
  Cc: Ray Jui, Scott Branden, bcm-kernel-feedback-list, dmaengine,
	Phil Elwell, devicetree, linux-arm-kernel, Lukas Wunner,
	linux-rpi-kernel

Hi Sengyu,

Am 18.06.23 um 21:43 schrieb Shengyu Qu:
> Hello Stefan,
> 
> Sorry to reply to this old series, but I wonder what happens to this 
> series?

i never found the time to prepare a newer version. Unfortunately the 
downstream kernel had a lot of changes regarding this feature recently.

> 
> Best regards,
> 
> Shengyu
> 
>> The BCM2711 has 4 DMA channels with a 40-bit address range, allowing them
>> to access the full 4GB of memory on a Pi 4. This patch series serves as a
>> basis for a discussion (just compile tested, so don't expect anything 
>> working)
>> which include the following points:
>>
>> * correct DT binding and representation for BCM2711
>>
>> According to the vendor DTS [1] the 4 DMA channels are connected to SCB.
>> I'm not sure how this is properly adapted to the mainline DT.
>>
>> * general implementation approach
>>
>> The vendor approach mapped all the BCM2835 control block bits to the 
>> BCM2711
>> layout and the rest of the differences are handled by a lot of 
>> is_40bit_channel
>> conditions. An advantage of this is the small amount of changes to the 
>> driver.
>> But on the down side the code is now much harder to understand and 
>> maintain.
>>
>> This series tries to implement this feature in a more cleaner way
>> while keeping it in the bcm2835-dma driver. Before this series the driver
>> has ~ 1000 lines and after that ~ 1500 lines.
>>
>> So the question is this approach acceptable?
>>
>> Patches 1 - 3 are just clean-ups.
>>
>> Disclaimer: my knowledge about the DMA controller is very limited
>>
>> More information:
>>
>> https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf
>>
>> [1] - 
>> https://github.com/raspberrypi/linux/blob/561deffcf471ba0f7bd48541d06a79d5aa38d297/arch/arm/boot/dts/bcm2711-rpi-ds.dtsi#L47
>> [2] - 
>> https://github.com/raspberrypi/linux/commit/44364bd140b0bc9187c881fbdc4ee358961059d5
>>
>> Stefan Wahren (11):
>>    ARM: dts: bcm283x: Update DMA node name per DT schema
>>    dt-bindings: dma: Convert brcm,bcm2835-dma to json-schema
>>    dmaengine: bcm2835: Support common dma-channel-mask
>>    dmaengine: bcm2835: move CB info generation into separate function
>>    dmaengine: bcm2835: move CB final extra info generation into function
>>    dmaengine: bcm2835: make address increment platform independent
>>    dmaengine: bcm2385: drop info parameters
>>    dmaengine: bcm2835: pass dma_chan to generic functions
>>    dmaengine: bcm2835: introduce multi platform support
>>    dmaengine: bcm2835: add BCM2711 40-bit DMA support
>>    ARM: dts: bcm2711: add bcm2711-dma node
>>
>>   .../devicetree/bindings/dma/brcm,bcm2835-dma.txt   |  83 ---
>>   .../devicetree/bindings/dma/brcm,bcm2835-dma.yaml  | 107 +++
>>   arch/arm/boot/dts/bcm2711.dtsi                     |  18 +-
>>   arch/arm/boot/dts/bcm2835-common.dtsi              |   2 +-
>>   drivers/dma/bcm2835-dma.c                          | 745 
>> +++++++++++++++++----
>>   5 files changed, 734 insertions(+), 221 deletions(-)
>>   delete mode 100644 
>> Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
>>   create mode 100644 
>> Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml
>>

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2023-06-18 21:15 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-27 12:05 [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
2021-12-27 12:05 ` [PATCH RFC 01/11] ARM: dts: bcm283x: Update DMA node name per DT schema Stefan Wahren
2021-12-27 12:05 ` [PATCH RFC 02/11] dt-bindings: dma: Convert brcm,bcm2835-dma to json-schema Stefan Wahren
2022-01-04 22:50   ` Rob Herring
2021-12-27 12:05 ` [PATCH RFC 03/11] dmaengine: bcm2835: Support common dma-channel-mask Stefan Wahren
2021-12-27 12:05 ` [PATCH RFC 04/11] dmaengine: bcm2835: move CB info generation into separate function Stefan Wahren
2021-12-27 12:05 ` [PATCH RFC 05/11] dmaengine: bcm2835: move CB final extra info generation into function Stefan Wahren
2021-12-27 12:05 ` [PATCH RFC 06/11] dmaengine: bcm2835: make address increment platform independent Stefan Wahren
2021-12-27 12:05 ` [PATCH RFC 07/11] dmaengine: bcm2385: drop info parameters Stefan Wahren
2021-12-27 12:05 ` [PATCH RFC 08/11] dmaengine: bcm2835: pass dma_chan to generic functions Stefan Wahren
2021-12-27 12:05 ` [PATCH RFC 09/11] dmaengine: bcm2835: introduce multi platform support Stefan Wahren
2022-01-23 14:08 ` [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA support Stefan Wahren
2022-02-15 11:20   ` Vinod Koul
2023-06-18 19:43 ` Shengyu Qu
2023-06-18 21:14   ` Stefan Wahren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).