All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] Add DMAC support to the RZ/V2H(P)
@ 2025-02-12 22:12 Fabrizio Castro
  2025-02-12 22:12 ` [PATCH v2 1/7] clk: renesas: r9a09g057: Add entries for the DMACs Fabrizio Castro
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: Fabrizio Castro @ 2025-02-12 22:12 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Michael Turquette, Stephen Boyd, Thomas Gleixner,
	Geert Uytterhoeven
  Cc: Fabrizio Castro, Magnus Damm, Philipp Zabel, Wolfram Sang,
	Biju Das, Uwe Kleine-König, dmaengine, devicetree,
	linux-kernel, linux-renesas-soc, linux-clk, Lad Prabhakar

Dear All,

This series adds DMAC support to the Renesas RZ/V2H(P).

Cheers,
Fab

v1->v2:
* Improved macros in ICU driver
* Shared new macros between ICU driver and DMAC driver
* Improved dt-bindings

Fabrizio Castro (7):
  clk: renesas: r9a09g057: Add entries for the DMACs
  dt-bindings: dma: rz-dmac: Restrict properties for RZ/A1H
  dt-bindings: dma: rz-dmac: Document RZ/V2H(P) family of SoCs
  irqchip/renesas-rzv2h: Add rzv2h_icu_register_dma_req_ack
  dmaengine: sh: rz-dmac: Allow for multiple DMACs
  dmaengine: sh: rz-dmac: Add RZ/V2H(P) support
  arm64: dts: renesas: r9a09g057: Add DMAC nodes

 .../bindings/dma/renesas,rz-dmac.yaml         | 113 ++++++++++--
 arch/arm64/boot/dts/renesas/r9a09g057.dtsi    | 165 +++++++++++++++++
 drivers/clk/renesas/r9a09g057-cpg.c           |  24 +++
 drivers/clk/renesas/rzv2h-cpg.h               |   2 +
 drivers/dma/sh/Kconfig                        |   1 +
 drivers/dma/sh/rz-dmac.c                      | 167 ++++++++++++++++--
 drivers/irqchip/irq-renesas-rzv2h.c           |  56 ++++++
 include/linux/irqchip/irq-renesas-rzv2h.h     |  21 +++
 8 files changed, 516 insertions(+), 33 deletions(-)
 create mode 100644 include/linux/irqchip/irq-renesas-rzv2h.h

-- 
2.34.1


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

* [PATCH v2 1/7] clk: renesas: r9a09g057: Add entries for the DMACs
  2025-02-12 22:12 [PATCH v2 0/7] Add DMAC support to the RZ/V2H(P) Fabrizio Castro
@ 2025-02-12 22:12 ` Fabrizio Castro
  2025-02-12 22:13 ` [PATCH v2 2/7] dt-bindings: dma: rz-dmac: Restrict properties for RZ/A1H Fabrizio Castro
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Fabrizio Castro @ 2025-02-12 22:12 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Geert Uytterhoeven
  Cc: Fabrizio Castro, linux-renesas-soc, linux-clk, linux-kernel,
	Biju Das, Lad Prabhakar

Add clock and reset entries for the Renesas RZ/V2H(P) DMAC IPs.

Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
v1->v2:
* No change.
---
 drivers/clk/renesas/r9a09g057-cpg.c | 24 ++++++++++++++++++++++++
 drivers/clk/renesas/rzv2h-cpg.h     |  2 ++
 2 files changed, 26 insertions(+)

diff --git a/drivers/clk/renesas/r9a09g057-cpg.c b/drivers/clk/renesas/r9a09g057-cpg.c
index 3705e18f66ad..d63eafbca780 100644
--- a/drivers/clk/renesas/r9a09g057-cpg.c
+++ b/drivers/clk/renesas/r9a09g057-cpg.c
@@ -31,6 +31,8 @@ enum clk_ids {
 	CLK_PLLVDO,
 
 	/* Internal Core Clocks */
+	CLK_PLLCM33_DIV4,
+	CLK_PLLCM33_DIV4_PLLCM33,
 	CLK_PLLCM33_DIV16,
 	CLK_PLLCLN_DIV2,
 	CLK_PLLCLN_DIV8,
@@ -39,6 +41,8 @@ enum clk_ids {
 	CLK_PLLDTY_ACPU_DIV2,
 	CLK_PLLDTY_ACPU_DIV4,
 	CLK_PLLDTY_DIV16,
+	CLK_PLLDTY_RCPU,
+	CLK_PLLDTY_RCPU_DIV4,
 	CLK_PLLVDO_CRU0,
 	CLK_PLLVDO_CRU1,
 	CLK_PLLVDO_CRU2,
@@ -85,6 +89,9 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = {
 	DEF_FIXED(".pllvdo", CLK_PLLVDO, CLK_QEXTAL, 105, 2),
 
 	/* Internal Core Clocks */
+	DEF_FIXED(".pllcm33_div4", CLK_PLLCM33_DIV4, CLK_PLLCM33, 1, 4),
+	DEF_DDIV(".pllcm33_div4_pllcm33", CLK_PLLCM33_DIV4_PLLCM33,
+		 CLK_PLLCM33_DIV4, CDDIV0_DIVCTL1, dtable_2_64),
 	DEF_FIXED(".pllcm33_div16", CLK_PLLCM33_DIV16, CLK_PLLCM33, 1, 16),
 
 	DEF_FIXED(".pllcln_div2", CLK_PLLCLN_DIV2, CLK_PLLCLN, 1, 2),
@@ -95,6 +102,8 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = {
 	DEF_FIXED(".plldty_acpu_div2", CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU, 1, 2),
 	DEF_FIXED(".plldty_acpu_div4", CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_ACPU, 1, 4),
 	DEF_FIXED(".plldty_div16", CLK_PLLDTY_DIV16, CLK_PLLDTY, 1, 16),
+	DEF_DDIV(".plldty_rcpu", CLK_PLLDTY_RCPU, CLK_PLLDTY, CDDIV3_DIVCTL2, dtable_2_64),
+	DEF_FIXED(".plldty_rcpu_div4", CLK_PLLDTY_RCPU_DIV4, CLK_PLLDTY_RCPU, 1, 4),
 
 	DEF_DDIV(".pllvdo_cru0", CLK_PLLVDO_CRU0, CLK_PLLVDO, CDDIV3_DIVCTL3, dtable_2_4),
 	DEF_DDIV(".pllvdo_cru1", CLK_PLLVDO_CRU1, CLK_PLLVDO, CDDIV4_DIVCTL0, dtable_2_4),
@@ -115,6 +124,16 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = {
 };
 
 static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = {
+	DEF_MOD("dmac_0_aclk",			CLK_PLLCM33_DIV4_PLLCM33, 0, 0, 0, 0,
+						BUS_MSTOP(5, BIT(9))),
+	DEF_MOD("dmac_1_aclk",			CLK_PLLDTY_ACPU_DIV2, 0, 1, 0, 1,
+						BUS_MSTOP(3, BIT(2))),
+	DEF_MOD("dmac_2_aclk",			CLK_PLLDTY_ACPU_DIV2, 0, 2, 0, 2,
+						BUS_MSTOP(3, BIT(3))),
+	DEF_MOD("dmac_3_aclk",			CLK_PLLDTY_RCPU_DIV4, 0, 3, 0, 3,
+						BUS_MSTOP(10, BIT(11))),
+	DEF_MOD("dmac_4_aclk",			CLK_PLLDTY_RCPU_DIV4, 0, 4, 0, 4,
+						BUS_MSTOP(10, BIT(12))),
 	DEF_MOD_CRITICAL("icu_0_pclk_i",	CLK_PLLCM33_DIV16, 0, 5, 0, 5,
 						BUS_MSTOP_NONE),
 	DEF_MOD_CRITICAL("gic_0_gicclk",	CLK_PLLDTY_ACPU_DIV4, 1, 3, 0, 19,
@@ -223,6 +242,11 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = {
 
 static const struct rzv2h_reset r9a09g057_resets[] __initconst = {
 	DEF_RST(3, 0, 1, 1),		/* SYS_0_PRESETN */
+	DEF_RST(3, 1, 1, 2),		/* DMAC_0_ARESETN */
+	DEF_RST(3, 2, 1, 3),		/* DMAC_1_ARESETN */
+	DEF_RST(3, 3, 1, 4),		/* DMAC_2_ARESETN */
+	DEF_RST(3, 4, 1, 5),		/* DMAC_3_ARESETN */
+	DEF_RST(3, 5, 1, 6),		/* DMAC_4_ARESETN */
 	DEF_RST(3, 6, 1, 7),		/* ICU_0_PRESETN_I */
 	DEF_RST(3, 8, 1, 9),		/* GIC_0_GICRESET_N */
 	DEF_RST(3, 9, 1, 10),		/* GIC_0_DBG_GICRESET_N */
diff --git a/drivers/clk/renesas/rzv2h-cpg.h b/drivers/clk/renesas/rzv2h-cpg.h
index fd8eb985c75b..576a070763cb 100644
--- a/drivers/clk/renesas/rzv2h-cpg.h
+++ b/drivers/clk/renesas/rzv2h-cpg.h
@@ -38,11 +38,13 @@ struct ddiv {
 #define CPG_CDDIV3		(0x40C)
 #define CPG_CDDIV4		(0x410)
 
+#define CDDIV0_DIVCTL1	DDIV_PACK(CPG_CDDIV0, 4, 3, 1)
 #define CDDIV0_DIVCTL2	DDIV_PACK(CPG_CDDIV0, 8, 3, 2)
 #define CDDIV1_DIVCTL0	DDIV_PACK(CPG_CDDIV1, 0, 2, 4)
 #define CDDIV1_DIVCTL1	DDIV_PACK(CPG_CDDIV1, 4, 2, 5)
 #define CDDIV1_DIVCTL2	DDIV_PACK(CPG_CDDIV1, 8, 2, 6)
 #define CDDIV1_DIVCTL3	DDIV_PACK(CPG_CDDIV1, 12, 2, 7)
+#define CDDIV3_DIVCTL2	DDIV_PACK(CPG_CDDIV3, 8, 3, 14)
 #define CDDIV3_DIVCTL3	DDIV_PACK(CPG_CDDIV3, 12, 1, 15)
 #define CDDIV4_DIVCTL0	DDIV_PACK(CPG_CDDIV4, 0, 1, 16)
 #define CDDIV4_DIVCTL1	DDIV_PACK(CPG_CDDIV4, 4, 1, 17)
-- 
2.34.1


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

* [PATCH v2 2/7] dt-bindings: dma: rz-dmac: Restrict properties for RZ/A1H
  2025-02-12 22:12 [PATCH v2 0/7] Add DMAC support to the RZ/V2H(P) Fabrizio Castro
  2025-02-12 22:12 ` [PATCH v2 1/7] clk: renesas: r9a09g057: Add entries for the DMACs Fabrizio Castro
@ 2025-02-12 22:13 ` Fabrizio Castro
  2025-02-12 22:13 ` [PATCH v2 3/7] dt-bindings: dma: rz-dmac: Document RZ/V2H(P) family of SoCs Fabrizio Castro
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Fabrizio Castro @ 2025-02-12 22:13 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven
  Cc: Fabrizio Castro, Magnus Damm, Biju Das, Wolfram Sang, dmaengine,
	devicetree, linux-kernel, linux-renesas-soc, Lad Prabhakar

Make sure we don't allow for the clocks, clock-names, resets,
reset-names. and power-domains properties for the Renesas
RZ/A1H SoC because its DMAC doesn't have clocks, resets,
and power domains.

Fixes: 209efec19c4c ("dt-bindings: dma: rz-dmac: Document RZ/A1H SoC")
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
v1->v2:
* No change.
---
 .../devicetree/bindings/dma/renesas,rz-dmac.yaml          | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml b/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml
index b356251de5a8..82de3b927479 100644
--- a/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml
+++ b/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml
@@ -112,6 +112,14 @@ allOf:
         - resets
         - reset-names
 
+    else:
+      properties:
+        clocks: false
+        clock-names: false
+        power-domains: false
+        resets: false
+        reset-names: false
+
 additionalProperties: false
 
 examples:
-- 
2.34.1


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

* [PATCH v2 3/7] dt-bindings: dma: rz-dmac: Document RZ/V2H(P) family of SoCs
  2025-02-12 22:12 [PATCH v2 0/7] Add DMAC support to the RZ/V2H(P) Fabrizio Castro
  2025-02-12 22:12 ` [PATCH v2 1/7] clk: renesas: r9a09g057: Add entries for the DMACs Fabrizio Castro
  2025-02-12 22:13 ` [PATCH v2 2/7] dt-bindings: dma: rz-dmac: Restrict properties for RZ/A1H Fabrizio Castro
@ 2025-02-12 22:13 ` Fabrizio Castro
  2025-02-12 22:13 ` [PATCH v2 4/7] irqchip/renesas-rzv2h: Add rzv2h_icu_register_dma_req_ack Fabrizio Castro
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Fabrizio Castro @ 2025-02-12 22:13 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven
  Cc: Fabrizio Castro, Magnus Damm, Biju Das, dmaengine, devicetree,
	linux-kernel, linux-renesas-soc, Lad Prabhakar

Document the Renesas RZ/V2H(P) family of SoCs DMAC block.
The Renesas RZ/V2H(P) DMAC is very similar to the one found on the
Renesas RZ/G2L family of SoCs, but there are some differences:
* It only uses one register area
* It only uses one clock
* It only uses one reset
* Instead of using MID/IRD it uses REQ NO/ACK NO
* It is connected to the Interrupt Control Unit (ICU)

Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
v1->v2:
* Removed RZ/V2H DMAC example.
* Improved the readability of the `if` statement.
---
 .../bindings/dma/renesas,rz-dmac.yaml         | 107 +++++++++++++++---
 1 file changed, 89 insertions(+), 18 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml b/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml
index 82de3b927479..4b89d199c022 100644
--- a/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml
+++ b/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml
@@ -11,19 +11,23 @@ maintainers:
 
 properties:
   compatible:
-    items:
-      - enum:
-          - renesas,r7s72100-dmac # RZ/A1H
-          - renesas,r9a07g043-dmac # RZ/G2UL and RZ/Five
-          - renesas,r9a07g044-dmac # RZ/G2{L,LC}
-          - renesas,r9a07g054-dmac # RZ/V2L
-          - renesas,r9a08g045-dmac # RZ/G3S
-      - const: renesas,rz-dmac
+    oneOf:
+      - items:
+          - enum:
+              - renesas,r7s72100-dmac # RZ/A1H
+              - renesas,r9a07g043-dmac # RZ/G2UL and RZ/Five
+              - renesas,r9a07g044-dmac # RZ/G2{L,LC}
+              - renesas,r9a07g054-dmac # RZ/V2L
+              - renesas,r9a08g045-dmac # RZ/G3S
+          - const: renesas,rz-dmac
+
+      - const: renesas,r9a09g057-dmac # RZ/V2H(P)
 
   reg:
     items:
       - description: Control and channel register block
       - description: DMA extended resource selector block
+    minItems: 1
 
   interrupts:
     maxItems: 17
@@ -52,6 +56,7 @@ properties:
     items:
       - description: DMA main clock
       - description: DMA register access clock
+    minItems: 1
 
   clock-names:
     items:
@@ -61,14 +66,22 @@ properties:
   '#dma-cells':
     const: 1
     description:
-      The cell specifies the encoded MID/RID values of the DMAC port
-      connected to the DMA client and the slave channel configuration
-      parameters.
+      For the RZ/A1H, RZ/Five, RZ/G2{L,LC,UL}, RZ/V2L, and RZ/G3S SoCs, the cell
+      specifies the encoded MID/RID values of the DMAC port connected to the
+      DMA client and the slave channel configuration parameters.
       bits[0:9] - Specifies MID/RID value
       bit[10] - Specifies DMA request high enable (HIEN)
       bit[11] - Specifies DMA request detection type (LVL)
       bits[12:14] - Specifies DMAACK output mode (AM)
       bit[15] - Specifies Transfer Mode (TM)
+      For the RZ/V2H(P) SoC the cell specifies the REQ NO, the ACK NO, and the
+      slave channel configuration parameters.
+      bits[0:9] - Specifies the REQ NO
+      bits[10:16] - Specifies the ACK NO
+      bit[17] - Specifies DMA request high enable (HIEN)
+      bit[18] - Specifies DMA request detection type (LVL)
+      bits[19:21] - Specifies DMAACK output mode (AM)
+      bit[22] - Specifies Transfer Mode (TM)
 
   dma-channels:
     const: 16
@@ -80,12 +93,29 @@ properties:
     items:
       - description: Reset for DMA ARESETN reset terminal
       - description: Reset for DMA RST_ASYNC reset terminal
+    minItems: 1
 
   reset-names:
     items:
       - const: arst
       - const: rst_async
 
+  renesas,icu:
+    description:
+      On the RZ/V2H(P) SoC configures the ICU to which the DMAC is connected to.
+      It must contain the phandle to the ICU, and the index of the DMAC as seen
+      from the ICU (e.g. parameter k from register ICU_DMkSELy).
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: phandle to the ICU node.
+          - description: The DMAC index.
+              4 for DMAC0
+              0 for DMAC1
+              1 for DMAC2
+              2 for DMAC3
+              3 for DMAC4
+
 required:
   - compatible
   - reg
@@ -98,13 +128,25 @@ allOf:
   - $ref: dma-controller.yaml#
 
   - if:
-      not:
-        properties:
-          compatible:
-            contains:
-              enum:
-                - renesas,r7s72100-dmac
+      properties:
+        compatible:
+          contains:
+            enum:
+              - renesas,r9a07g043-dmac
+              - renesas,r9a07g044-dmac
+              - renesas,r9a07g054-dmac
+              - renesas,r9a08g045-dmac
     then:
+      properties:
+        reg:
+          minItems: 2
+        clocks:
+          minItems: 2
+        resets:
+          minItems: 2
+
+        renesas,icu: false
+
       required:
         - clocks
         - clock-names
@@ -112,13 +154,42 @@ allOf:
         - resets
         - reset-names
 
-    else:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: renesas,r7s72100-dmac
+    then:
       properties:
         clocks: false
         clock-names: false
         power-domains: false
         resets: false
         reset-names: false
+        renesas,icu: false
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: renesas,r9a09g057-dmac
+    then:
+      properties:
+        reg:
+          maxItems: 1
+        clocks:
+          maxItems: 1
+        resets:
+          maxItems: 1
+
+        clock-names: false
+        reset-names: false
+
+      required:
+        - clocks
+        - power-domains
+        - renesas,icu
+        - resets
 
 additionalProperties: false
 
-- 
2.34.1


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

* [PATCH v2 4/7] irqchip/renesas-rzv2h: Add rzv2h_icu_register_dma_req_ack
  2025-02-12 22:12 [PATCH v2 0/7] Add DMAC support to the RZ/V2H(P) Fabrizio Castro
                   ` (2 preceding siblings ...)
  2025-02-12 22:13 ` [PATCH v2 3/7] dt-bindings: dma: rz-dmac: Document RZ/V2H(P) family of SoCs Fabrizio Castro
@ 2025-02-12 22:13 ` Fabrizio Castro
  2025-02-18  8:00   ` Thomas Gleixner
  2025-02-12 22:13 ` [PATCH v2 5/7] dmaengine: sh: rz-dmac: Allow for multiple DMACs Fabrizio Castro
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Fabrizio Castro @ 2025-02-12 22:13 UTC (permalink / raw)
  To: Thomas Gleixner, Geert Uytterhoeven
  Cc: Fabrizio Castro, linux-kernel, Biju Das, Lad Prabhakar,
	linux-renesas-soc

On the Renesas RZ/V2H(P) family of SoCs, DMAC IPs are connected
to the Interrupt Control Unit (ICU).
For DMA transfers, a request number and an ack number must be
registered with the ICU, which means that the DMAC driver has
to be able to instruct the ICU driver with the registration of
such ids.

Export rzv2h_icu_register_dma_req_ack so that the DMA driver
can register both ids in one go.

Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
v1->v2:
* Improved macros.
* Shared new macros for minimum values.
---
 drivers/irqchip/irq-renesas-rzv2h.c       | 56 +++++++++++++++++++++++
 include/linux/irqchip/irq-renesas-rzv2h.h | 21 +++++++++
 2 files changed, 77 insertions(+)
 create mode 100644 include/linux/irqchip/irq-renesas-rzv2h.h

diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index fe2d29e91026..a8e9feda73b0 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -15,6 +15,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/irqchip.h>
+#include <linux/irqchip/irq-renesas-rzv2h.h>
 #include <linux/irqdomain.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
@@ -41,6 +42,8 @@
 #define ICU_TSCLR				0x24
 #define ICU_TITSR(k)				(0x28 + (k) * 4)
 #define ICU_TSSR(k)				(0x30 + (k) * 4)
+#define ICU_DMkSELy(k, y)			(0x420 + (k) * 0x20 + (y) * 4)
+#define ICU_DMACKSELk(k)			(0x500 + (k) * 4)
 
 /* NMI */
 #define ICU_NMI_EDGE_FALLING			0
@@ -80,6 +83,19 @@
 #define ICU_TINT_EXTRACT_GPIOINT(x)		FIELD_GET(GENMASK(31, 16), (x))
 #define ICU_PB5_TINT				0x55
 
+/* DMAC */
+#define ICU_DMAC_DkRQ_SEL_MASK			GENMASK(9, 0)
+
+#define ICU_DMAC_DMAREQ_SHIFT(up)		((up) * 16)
+#define ICU_DMAC_DMAREQ_MASK(up)		(ICU_DMAC_DkRQ_SEL_MASK \
+						 << ICU_DMAC_DMAREQ_SHIFT(up))
+#define ICU_DMAC_PREP_DMAREQ(sel, up)		(FIELD_PREP(ICU_DMAC_DkRQ_SEL_MASK, (sel)) \
+						 << ICU_DMAC_DMAREQ_SHIFT(up))
+
+#define ICU_DMAC_DACK_SEL_SHIFT(field_no)	((field_no) * 8)
+#define ICU_DMAC_DACK_SEL_MASK(field_no)	(GENMASK(6, 0) << ICU_DMAC_DACK_SEL_SHIFT(field_no))
+#define ICU_DMAC_PREP_DACK_SEL(sel, field_no)	((sel) << ICU_DMAC_DACK_SEL_SHIFT(field_no))
+
 /**
  * struct rzv2h_icu_priv - Interrupt Control Unit controller private data structure.
  * @base:	Controller's base address
@@ -94,6 +110,45 @@ struct rzv2h_icu_priv {
 	raw_spinlock_t			lock;
 };
 
+void rzv2h_icu_register_dma_req_ack(struct platform_device *icu_dev, u8 dmac_index, u8 dmac_channel,
+				    u16 req_no, u8 ack_no)
+{
+	struct rzv2h_icu_priv *priv = platform_get_drvdata(icu_dev);
+	u32 icu_dmackselk, dmaack, dmaack_mask;
+	u32 icu_dmksely, dmareq, dmareq_mask;
+	u8 k, field_no;
+	u8 y, upper;
+
+	if (req_no >= RZV2H_ICU_DMAC_REQ_NO_MIN_FIX_OUTPUT)
+		req_no = RZV2H_ICU_DMAC_REQ_NO_DEFAULT;
+
+	if (ack_no >= RZV2H_ICU_DMAC_ACK_NO_MIN_FIX_OUTPUT)
+		ack_no = RZV2H_ICU_DMAC_ACK_NO_DEFAULT;
+
+	y = dmac_channel / 2;
+	upper = dmac_channel % 2;
+
+	dmareq = ICU_DMAC_PREP_DMAREQ(req_no, upper);
+	dmareq_mask = ICU_DMAC_DMAREQ_MASK(upper);
+
+	k  = ack_no / 4;
+	field_no = ack_no % 4;
+
+	dmaack_mask = ICU_DMAC_DACK_SEL_MASK(field_no);
+	dmaack = ICU_DMAC_PREP_DACK_SEL(ack_no, field_no);
+
+	guard(raw_spinlock_irqsave)(&priv->lock);
+
+	icu_dmksely = readl(priv->base + ICU_DMkSELy(dmac_index, y));
+	icu_dmksely = (icu_dmksely & ~dmareq_mask) | dmareq;
+	writel(icu_dmksely, priv->base + ICU_DMkSELy(dmac_index, y));
+
+	icu_dmackselk = readl(priv->base + ICU_DMACKSELk(k));
+	icu_dmackselk = (icu_dmackselk & ~dmaack_mask) | dmaack;
+	writel(icu_dmackselk, priv->base + ICU_DMACKSELk(k));
+}
+EXPORT_SYMBOL_GPL(rzv2h_icu_register_dma_req_ack);
+
 static inline struct rzv2h_icu_priv *irq_data_to_priv(struct irq_data *data)
 {
 	return data->domain->host_data;
@@ -446,6 +501,7 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
 		goto put_dev;
 	}
 
+	platform_set_drvdata(pdev, rzv2h_icu_data);
 	rzv2h_icu_data->irqchip = &rzv2h_icu_chip;
 
 	rzv2h_icu_data->base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL);
diff --git a/include/linux/irqchip/irq-renesas-rzv2h.h b/include/linux/irqchip/irq-renesas-rzv2h.h
new file mode 100644
index 000000000000..9d47a64d5f74
--- /dev/null
+++ b/include/linux/irqchip/irq-renesas-rzv2h.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Renesas RZ/V2H(P) Interrupt Control Unit (ICU)
+ *
+ * Copyright (C) 2025 Renesas Electronics Corporation.
+ */
+
+#ifndef __LINUX_IRQ_RENESAS_RZV2H
+#define __LINUX_IRQ_RENESAS_RZV2H
+
+#include <linux/platform_device.h>
+
+#define RZV2H_ICU_DMAC_REQ_NO_DEFAULT		0x3ff
+#define RZV2H_ICU_DMAC_ACK_NO_DEFAULT		0x7f
+#define RZV2H_ICU_DMAC_REQ_NO_MIN_FIX_OUTPUT	0x1b5
+#define RZV2H_ICU_DMAC_ACK_NO_MIN_FIX_OUTPUT	0x50
+
+void rzv2h_icu_register_dma_req_ack(struct platform_device *icu_dev, u8 dmac_index, u8 dmac_channel,
+				    u16 req_no, u8 ack_no);
+
+#endif
-- 
2.34.1


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

* [PATCH v2 5/7] dmaengine: sh: rz-dmac: Allow for multiple DMACs
  2025-02-12 22:12 [PATCH v2 0/7] Add DMAC support to the RZ/V2H(P) Fabrizio Castro
                   ` (3 preceding siblings ...)
  2025-02-12 22:13 ` [PATCH v2 4/7] irqchip/renesas-rzv2h: Add rzv2h_icu_register_dma_req_ack Fabrizio Castro
@ 2025-02-12 22:13 ` Fabrizio Castro
  2025-02-12 22:13 ` [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support Fabrizio Castro
  2025-02-12 22:13 ` [PATCH v2 7/7] arm64: dts: renesas: r9a09g057: Add DMAC nodes Fabrizio Castro
  6 siblings, 0 replies; 15+ messages in thread
From: Fabrizio Castro @ 2025-02-12 22:13 UTC (permalink / raw)
  To: Vinod Koul, Geert Uytterhoeven
  Cc: Fabrizio Castro, Wolfram Sang, Biju Das, Uwe Kleine-König,
	dmaengine, linux-kernel, Lad Prabhakar, linux-renesas-soc

dma_request_channel calls into __dma_request_channel with NULL
as value for np, which won't allow for the selection of the
correct DMAC when multiple DMACs are available.

Switch to using __dma_request_channel directly so that we can
choose the desired DMA for the channel. This is in preparation
of adding DMAC support for the Renesas RZ/V2H(P) and similar SoCs.

Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
v1->v2:
* No change.
---
 drivers/dma/sh/rz-dmac.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c
index 9235db551026..d7a4ce28040b 100644
--- a/drivers/dma/sh/rz-dmac.c
+++ b/drivers/dma/sh/rz-dmac.c
@@ -748,7 +748,8 @@ static struct dma_chan *rz_dmac_of_xlate(struct of_phandle_args *dma_spec,
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 
-	return dma_request_channel(mask, rz_dmac_chan_filter, dma_spec);
+	return __dma_request_channel(&mask, rz_dmac_chan_filter, dma_spec,
+				     ofdma->of_node);
 }
 
 /*
-- 
2.34.1


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

* [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support
  2025-02-12 22:12 [PATCH v2 0/7] Add DMAC support to the RZ/V2H(P) Fabrizio Castro
                   ` (4 preceding siblings ...)
  2025-02-12 22:13 ` [PATCH v2 5/7] dmaengine: sh: rz-dmac: Allow for multiple DMACs Fabrizio Castro
@ 2025-02-12 22:13 ` Fabrizio Castro
  2025-02-13 13:24   ` kernel test robot
  2025-02-13 14:19   ` Geert Uytterhoeven
  2025-02-12 22:13 ` [PATCH v2 7/7] arm64: dts: renesas: r9a09g057: Add DMAC nodes Fabrizio Castro
  6 siblings, 2 replies; 15+ messages in thread
From: Fabrizio Castro @ 2025-02-12 22:13 UTC (permalink / raw)
  To: Vinod Koul, Geert Uytterhoeven
  Cc: Fabrizio Castro, Magnus Damm, Philipp Zabel, Wolfram Sang,
	Biju Das, Uwe Kleine-König, dmaengine, linux-kernel,
	linux-renesas-soc, Lad Prabhakar

The DMAC IP found on the Renesas RZ/V2H(P) family of SoCs is
similar to the version found on the Renesas RZ/G2L family of
SoCs, but there are some differences:
* It only uses one register area
* It only uses one clock
* It only uses one reset
* Instead of using MID/IRD it uses REQ NO/ACK NO
* It is connected to the Interrupt Control Unit (ICU)
* On the RZ/G2L there is only 1 DMAC, on the RZ/V2H(P) there are 5

Add specific support for the Renesas RZ/V2H(P) family of SoC by
tackling the aforementioned differences.

Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
v1->v2:
* Switched to new macros for minimum values.
---
 drivers/dma/sh/Kconfig   |   1 +
 drivers/dma/sh/rz-dmac.c | 164 +++++++++++++++++++++++++++++++++++----
 2 files changed, 150 insertions(+), 15 deletions(-)

diff --git a/drivers/dma/sh/Kconfig b/drivers/dma/sh/Kconfig
index 6ea5a880b433..020cf941abc7 100644
--- a/drivers/dma/sh/Kconfig
+++ b/drivers/dma/sh/Kconfig
@@ -53,6 +53,7 @@ config RZ_DMAC
 	depends on ARCH_R7S72100 || ARCH_RZG2L || COMPILE_TEST
 	select RENESAS_DMA
 	select DMA_VIRTUAL_CHANNELS
+	select RENESAS_RZV2H_ICU
 	help
 	  This driver supports the general purpose DMA controller typically
 	  found in the Renesas RZ SoC variants.
diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c
index d7a4ce28040b..24a8c6a337d5 100644
--- a/drivers/dma/sh/rz-dmac.c
+++ b/drivers/dma/sh/rz-dmac.c
@@ -14,6 +14,7 @@
 #include <linux/dmaengine.h>
 #include <linux/interrupt.h>
 #include <linux/iopoll.h>
+#include <linux/irqchip/irq-renesas-rzv2h.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -28,6 +29,11 @@
 #include "../dmaengine.h"
 #include "../virt-dma.h"
 
+enum rz_dmac_type {
+	RZ_DMAC_RZG2L,
+	RZ_DMAC_RZV2H,
+};
+
 enum  rz_dmac_prep_type {
 	RZ_DMAC_DESC_MEMCPY,
 	RZ_DMAC_DESC_SLAVE_SG,
@@ -85,20 +91,32 @@ struct rz_dmac_chan {
 		struct rz_lmdesc *tail;
 		dma_addr_t base_dma;
 	} lmdesc;
+
+	/* RZ/V2H ICU related signals */
+	u16 req_no;
+	u8 ack_no;
 };
 
 #define to_rz_dmac_chan(c)	container_of(c, struct rz_dmac_chan, vc.chan)
 
+struct rz_dmac_icu {
+	struct platform_device *pdev;
+	u8 dmac_index;
+};
+
 struct rz_dmac {
 	struct dma_device engine;
 	struct device *dev;
 	struct reset_control *rstc;
+	struct rz_dmac_icu icu;
 	void __iomem *base;
 	void __iomem *ext_base;
 
 	unsigned int n_channels;
 	struct rz_dmac_chan *channels;
 
+	enum rz_dmac_type type;
+
 	DECLARE_BITMAP(modules, 1024);
 };
 
@@ -167,6 +185,22 @@ struct rz_dmac {
 #define RZ_DMAC_MAX_CHANNELS		16
 #define DMAC_NR_LMDESC			64
 
+/* RZ/V2H ICU related */
+#define RZV2H_REQ_NO_MASK		GENMASK(9, 0)
+#define RZV2H_ACK_NO_MASK		GENMASK(16, 10)
+#define RZV2H_HIEN_MASK			BIT(17)
+#define RZV2H_LVL_MASK			BIT(18)
+#define RZV2H_AM_MASK			GENMASK(21, 19)
+#define RZV2H_TM_MASK			BIT(22)
+#define RZV2H_EXTRACT_REQ_NO(x)		FIELD_GET(RZV2H_REQ_NO_MASK, (x))
+#define RZV2H_EXTRACT_ACK_NO(x)		FIELD_GET(RZV2H_ACK_NO_MASK, (x))
+#define RZVH2_EXTRACT_CHCFG(x)		((FIELD_GET(RZV2H_HIEN_MASK, (x)) << 5) | \
+					 (FIELD_GET(RZV2H_LVL_MASK, (x))  << 6) | \
+					 (FIELD_GET(RZV2H_AM_MASK, (x))   << 8) | \
+					 (FIELD_GET(RZV2H_TM_MASK, (x))   << 22))
+
+#define RZV2H_MAX_DMAC_INDEX		4
+
 /*
  * -----------------------------------------------------------------------------
  * Device access
@@ -324,7 +358,15 @@ static void rz_dmac_prepare_desc_for_memcpy(struct rz_dmac_chan *channel)
 	lmdesc->chext = 0;
 	lmdesc->header = HEADER_LV;
 
-	rz_dmac_set_dmars_register(dmac, channel->index, 0);
+	if (dmac->type == RZ_DMAC_RZG2L) {
+		rz_dmac_set_dmars_register(dmac, channel->index, 0);
+	} else {
+		rzv2h_icu_register_dma_req_ack(dmac->icu.pdev,
+					       dmac->icu.dmac_index,
+					       channel->index,
+					       RZV2H_ICU_DMAC_REQ_NO_DEFAULT,
+					       RZV2H_ICU_DMAC_ACK_NO_DEFAULT);
+	}
 
 	channel->chcfg = chcfg;
 	channel->chctrl = CHCTRL_STG | CHCTRL_SETEN;
@@ -375,7 +417,15 @@ static void rz_dmac_prepare_descs_for_slave_sg(struct rz_dmac_chan *channel)
 
 	channel->lmdesc.tail = lmdesc;
 
-	rz_dmac_set_dmars_register(dmac, channel->index, channel->mid_rid);
+	if (dmac->type == RZ_DMAC_RZG2L) {
+		rz_dmac_set_dmars_register(dmac, channel->index, channel->mid_rid);
+	} else {
+		rzv2h_icu_register_dma_req_ack(dmac->icu.pdev,
+					       dmac->icu.dmac_index,
+					       channel->index, channel->req_no,
+					       channel->ack_no);
+	}
+
 	channel->chctrl = CHCTRL_SETEN;
 }
 
@@ -452,9 +502,15 @@ static void rz_dmac_free_chan_resources(struct dma_chan *chan)
 	list_splice_tail_init(&channel->ld_active, &channel->ld_free);
 	list_splice_tail_init(&channel->ld_queue, &channel->ld_free);
 
-	if (channel->mid_rid >= 0) {
-		clear_bit(channel->mid_rid, dmac->modules);
-		channel->mid_rid = -EINVAL;
+	if (dmac->type == RZ_DMAC_RZG2L) {
+		if (channel->mid_rid >= 0) {
+			clear_bit(channel->mid_rid, dmac->modules);
+			channel->mid_rid = -EINVAL;
+		}
+	} else {
+		clear_bit(channel->req_no, dmac->modules);
+		channel->req_no = RZV2H_ICU_DMAC_REQ_NO_DEFAULT;
+		channel->ack_no = RZV2H_ICU_DMAC_ACK_NO_DEFAULT;
 	}
 
 	spin_unlock_irqrestore(&channel->vc.lock, flags);
@@ -647,7 +703,15 @@ static void rz_dmac_device_synchronize(struct dma_chan *chan)
 	if (ret < 0)
 		dev_warn(dmac->dev, "DMA Timeout");
 
-	rz_dmac_set_dmars_register(dmac, channel->index, 0);
+	if (dmac->type == RZ_DMAC_RZG2L) {
+		rz_dmac_set_dmars_register(dmac, channel->index, 0);
+	} else {
+		rzv2h_icu_register_dma_req_ack(dmac->icu.pdev,
+					       dmac->icu.dmac_index,
+					       channel->index,
+					       RZV2H_ICU_DMAC_REQ_NO_DEFAULT,
+					       RZV2H_ICU_DMAC_ACK_NO_DEFAULT);
+	}
 }
 
 /*
@@ -727,13 +791,30 @@ static bool rz_dmac_chan_filter(struct dma_chan *chan, void *arg)
 	struct rz_dmac *dmac = to_rz_dmac(chan->device);
 	struct of_phandle_args *dma_spec = arg;
 	u32 ch_cfg;
+	u16 req_no;
+
+	if (dmac->type == RZ_DMAC_RZG2L) {
+		channel->mid_rid = dma_spec->args[0] & MID_RID_MASK;
+		ch_cfg = (dma_spec->args[0] & CHCFG_MASK) >> 10;
+		channel->chcfg = CHCFG_FILL_TM(ch_cfg) | CHCFG_FILL_AM(ch_cfg) |
+				 CHCFG_FILL_LVL(ch_cfg) | CHCFG_FILL_HIEN(ch_cfg);
+
+		return !test_and_set_bit(channel->mid_rid, dmac->modules);
+	}
+
+	req_no = RZV2H_EXTRACT_REQ_NO(dma_spec->args[0]);
+	if (req_no >= RZV2H_ICU_DMAC_REQ_NO_MIN_FIX_OUTPUT)
+		return false;
+
+	channel->req_no = req_no;
+
+	channel->ack_no = RZV2H_EXTRACT_ACK_NO(dma_spec->args[0]);
+	if (channel->ack_no >= RZV2H_ICU_DMAC_ACK_NO_MIN_FIX_OUTPUT)
+		channel->ack_no = RZV2H_ICU_DMAC_ACK_NO_DEFAULT;
 
-	channel->mid_rid = dma_spec->args[0] & MID_RID_MASK;
-	ch_cfg = (dma_spec->args[0] & CHCFG_MASK) >> 10;
-	channel->chcfg = CHCFG_FILL_TM(ch_cfg) | CHCFG_FILL_AM(ch_cfg) |
-			 CHCFG_FILL_LVL(ch_cfg) | CHCFG_FILL_HIEN(ch_cfg);
+	channel->chcfg = RZVH2_EXTRACT_CHCFG(dma_spec->args[0]);
 
-	return !test_and_set_bit(channel->mid_rid, dmac->modules);
+	return !test_and_set_bit(channel->req_no, dmac->modules);
 }
 
 static struct dma_chan *rz_dmac_of_xlate(struct of_phandle_args *dma_spec,
@@ -769,6 +850,8 @@ static int rz_dmac_chan_probe(struct rz_dmac *dmac,
 
 	channel->index = index;
 	channel->mid_rid = -EINVAL;
+	channel->req_no = RZV2H_ICU_DMAC_REQ_NO_DEFAULT;
+	channel->ack_no = RZV2H_ICU_DMAC_ACK_NO_DEFAULT;
 
 	/* Request the channel interrupt. */
 	scnprintf(pdev_irqname, sizeof(pdev_irqname), "ch%u", index);
@@ -824,6 +907,40 @@ static int rz_dmac_chan_probe(struct rz_dmac *dmac,
 	return 0;
 }
 
+static int rz_dmac_parse_of_icu(struct device *dev, struct rz_dmac *dmac)
+{
+	struct device_node *icu_np, *np = dev->of_node;
+	struct of_phandle_args args;
+	uint32_t dmac_index;
+	int ret;
+
+	ret = of_parse_phandle_with_fixed_args(np, "renesas,icu", 1, 0, &args);
+	if (ret)
+		return ret;
+
+	icu_np = args.np;
+	dmac_index = args.args[0];
+
+	if (dmac_index > RZV2H_MAX_DMAC_INDEX) {
+		dev_err(dev, "DMAC index %u invalid.\n", dmac_index);
+		ret = -EINVAL;
+		goto free_icu_np;
+	}
+
+	dmac->icu.pdev = of_find_device_by_node(icu_np);
+	if (!dmac->icu.pdev) {
+		ret = -ENODEV;
+		goto free_icu_np;
+	}
+
+	dmac->icu.dmac_index = dmac_index;
+
+free_icu_np:
+	of_node_put(icu_np);
+
+	return ret;
+}
+
 static int rz_dmac_parse_of(struct device *dev, struct rz_dmac *dmac)
 {
 	struct device_node *np = dev->of_node;
@@ -859,6 +976,7 @@ static int rz_dmac_probe(struct platform_device *pdev)
 
 	dmac->dev = &pdev->dev;
 	platform_set_drvdata(pdev, dmac);
+	dmac->type = (enum rz_dmac_type)of_device_get_match_data(dmac->dev);
 
 	ret = rz_dmac_parse_of(&pdev->dev, dmac);
 	if (ret < 0)
@@ -874,9 +992,15 @@ static int rz_dmac_probe(struct platform_device *pdev)
 	if (IS_ERR(dmac->base))
 		return PTR_ERR(dmac->base);
 
-	dmac->ext_base = devm_platform_ioremap_resource(pdev, 1);
-	if (IS_ERR(dmac->ext_base))
-		return PTR_ERR(dmac->ext_base);
+	if (dmac->type == RZ_DMAC_RZG2L) {
+		dmac->ext_base = devm_platform_ioremap_resource(pdev, 1);
+		if (IS_ERR(dmac->ext_base))
+			return PTR_ERR(dmac->ext_base);
+	} else {
+		ret = rz_dmac_parse_of_icu(&pdev->dev, dmac);
+		if (ret)
+			return ret;
+	}
 
 	/* Register interrupt handler for error */
 	irq = platform_get_irq_byname(pdev, irqname);
@@ -991,10 +1115,20 @@ static void rz_dmac_remove(struct platform_device *pdev)
 	reset_control_assert(dmac->rstc);
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
+
+	if (dmac->type == RZ_DMAC_RZV2H)
+		platform_device_put(dmac->icu.pdev);
 }
 
 static const struct of_device_id of_rz_dmac_match[] = {
-	{ .compatible = "renesas,rz-dmac", },
+	{
+		.compatible	= "renesas,r9a09g057-dmac",
+		.data		= (void *) RZ_DMAC_RZV2H
+	},
+	{
+		.compatible	= "renesas,rz-dmac",
+		.data		= (void *) RZ_DMAC_RZG2L
+	},
 	{ /* Sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, of_rz_dmac_match);
-- 
2.34.1


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

* [PATCH v2 7/7] arm64: dts: renesas: r9a09g057: Add DMAC nodes
  2025-02-12 22:12 [PATCH v2 0/7] Add DMAC support to the RZ/V2H(P) Fabrizio Castro
                   ` (5 preceding siblings ...)
  2025-02-12 22:13 ` [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support Fabrizio Castro
@ 2025-02-12 22:13 ` Fabrizio Castro
  6 siblings, 0 replies; 15+ messages in thread
From: Fabrizio Castro @ 2025-02-12 22:13 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Geert Uytterhoeven
  Cc: Fabrizio Castro, Magnus Damm, linux-renesas-soc, devicetree,
	linux-kernel, Biju Das, Lad Prabhakar

Add nodes for the DMAC IPs found on the Renesas RZ/V2H(P) SoC.

Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
v1->v2:
* No change.
---
 arch/arm64/boot/dts/renesas/r9a09g057.dtsi | 165 +++++++++++++++++++++
 1 file changed, 165 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r9a09g057.dtsi b/arch/arm64/boot/dts/renesas/r9a09g057.dtsi
index 1c550b22b164..0a7d0c801e32 100644
--- a/arch/arm64/boot/dts/renesas/r9a09g057.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a09g057.dtsi
@@ -252,6 +252,171 @@ sys: system-controller@10430000 {
 			status = "disabled";
 		};
 
+		dmac0: dma-controller@11400000 {
+			compatible = "renesas,r9a09g057-dmac";
+			reg = <0 0x11400000 0 0x10000>;
+			interrupts = <GIC_SPI 499 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 89  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 90  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 91  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 92  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 93  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 94  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 95  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 96  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 97  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 98  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 99  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 100 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 101 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 102 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 103 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 104 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 0x0>;
+			power-domains = <&cpg>;
+			resets = <&cpg 0x31>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+			renesas,icu = <&icu 4>;
+		};
+
+		dmac1: dma-controller@14830000 {
+			compatible = "renesas,r9a09g057-dmac";
+			reg = <0 0x14830000 0 0x10000>;
+			interrupts = <GIC_SPI 495 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 25  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 26  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 27  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 28  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 29  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 30  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 31  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 32  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 33  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 34  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 35  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 36  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 37  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 38  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 39  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 40  IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 0x1>;
+			power-domains = <&cpg>;
+			resets = <&cpg 0x32>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+			renesas,icu = <&icu 0>;
+		};
+
+		dmac2: dma-controller@14840000 {
+			compatible = "renesas,r9a09g057-dmac";
+			reg = <0 0x14840000 0 0x10000>;
+			interrupts = <GIC_SPI 496 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 41  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 42  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 43  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 44  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 45  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 46  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 47  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 48  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 49  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 50  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 51  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 52  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 53  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 54  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 55  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 56  IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 0x2>;
+			power-domains = <&cpg>;
+			resets = <&cpg 0x33>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+			renesas,icu = <&icu 1>;
+		};
+
+		dmac3: dma-controller@12000000 {
+			compatible = "renesas,r9a09g057-dmac";
+			reg = <0 0x12000000 0 0x10000>;
+			interrupts = <GIC_SPI 497 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 57  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 58  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 59  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 60  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 61  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 62  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 63  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 64  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 65  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 66  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 67  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 68  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 69  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 70  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 71  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 72  IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 0x3>;
+			power-domains = <&cpg>;
+			resets = <&cpg 0x34>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+			renesas,icu = <&icu 2>;
+		};
+
+		dmac4: dma-controller@12010000 {
+			compatible = "renesas,r9a09g057-dmac";
+			reg = <0 0x12010000 0 0x10000>;
+			interrupts = <GIC_SPI 498 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 73  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 74  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 75  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 76  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 77  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 78  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 79  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 80  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 81  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 82  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 83  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 84  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 85  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 86  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 87  IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 88  IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 0x4>;
+			power-domains = <&cpg>;
+			resets = <&cpg 0x35>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+			renesas,icu = <&icu 3>;
+		};
+
 		ostm0: timer@11800000 {
 			compatible = "renesas,r9a09g057-ostm", "renesas,ostm";
 			reg = <0x0 0x11800000 0x0 0x1000>;
-- 
2.34.1


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

* Re: [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support
  2025-02-12 22:13 ` [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support Fabrizio Castro
@ 2025-02-13 13:24   ` kernel test robot
  2025-02-13 14:19   ` Geert Uytterhoeven
  1 sibling, 0 replies; 15+ messages in thread
From: kernel test robot @ 2025-02-13 13:24 UTC (permalink / raw)
  To: Fabrizio Castro, Vinod Koul, Geert Uytterhoeven
  Cc: llvm, oe-kbuild-all, Fabrizio Castro, Magnus Damm, Philipp Zabel,
	Wolfram Sang, Biju Das, Uwe Kleine-König, dmaengine,
	linux-kernel, linux-renesas-soc, Lad Prabhakar

Hi Fabrizio,

kernel test robot noticed the following build warnings:

[auto build test WARNING on vkoul-dmaengine/next]
[also build test WARNING on geert-renesas-drivers/renesas-clk robh/for-next linus/master v6.14-rc2 next-20250213]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Fabrizio-Castro/clk-renesas-r9a09g057-Add-entries-for-the-DMACs/20250213-061714
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git next
patch link:    https://lore.kernel.org/r/20250212221305.431716-7-fabrizio.castro.jz%40renesas.com
patch subject: [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support
config: powerpc64-randconfig-001-20250213 (https://download.01.org/0day-ci/archive/20250213/202502132123.1ePmN98r-lkp@intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250213/202502132123.1ePmN98r-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202502132123.1ePmN98r-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/dma/sh/rz-dmac.c:979:15: warning: cast to smaller integer type 'enum rz_dmac_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
     979 |         dmac->type = (enum rz_dmac_type)of_device_get_match_data(dmac->dev);
         |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 warning generated.


vim +979 drivers/dma/sh/rz-dmac.c

   962	
   963	static int rz_dmac_probe(struct platform_device *pdev)
   964	{
   965		const char *irqname = "error";
   966		struct dma_device *engine;
   967		struct rz_dmac *dmac;
   968		int channel_num;
   969		int ret;
   970		int irq;
   971		u8 i;
   972	
   973		dmac = devm_kzalloc(&pdev->dev, sizeof(*dmac), GFP_KERNEL);
   974		if (!dmac)
   975			return -ENOMEM;
   976	
   977		dmac->dev = &pdev->dev;
   978		platform_set_drvdata(pdev, dmac);
 > 979		dmac->type = (enum rz_dmac_type)of_device_get_match_data(dmac->dev);
   980	
   981		ret = rz_dmac_parse_of(&pdev->dev, dmac);
   982		if (ret < 0)
   983			return ret;
   984	
   985		dmac->channels = devm_kcalloc(&pdev->dev, dmac->n_channels,
   986					      sizeof(*dmac->channels), GFP_KERNEL);
   987		if (!dmac->channels)
   988			return -ENOMEM;
   989	
   990		/* Request resources */
   991		dmac->base = devm_platform_ioremap_resource(pdev, 0);
   992		if (IS_ERR(dmac->base))
   993			return PTR_ERR(dmac->base);
   994	
   995		if (dmac->type == RZ_DMAC_RZG2L) {
   996			dmac->ext_base = devm_platform_ioremap_resource(pdev, 1);
   997			if (IS_ERR(dmac->ext_base))
   998				return PTR_ERR(dmac->ext_base);
   999		} else {
  1000			ret = rz_dmac_parse_of_icu(&pdev->dev, dmac);
  1001			if (ret)
  1002				return ret;
  1003		}
  1004	
  1005		/* Register interrupt handler for error */
  1006		irq = platform_get_irq_byname(pdev, irqname);
  1007		if (irq < 0)
  1008			return irq;
  1009	
  1010		ret = devm_request_irq(&pdev->dev, irq, rz_dmac_irq_handler, 0,
  1011				       irqname, NULL);
  1012		if (ret) {
  1013			dev_err(&pdev->dev, "failed to request IRQ %u (%d)\n",
  1014				irq, ret);
  1015			return ret;
  1016		}
  1017	
  1018		/* Initialize the channels. */
  1019		INIT_LIST_HEAD(&dmac->engine.channels);
  1020	
  1021		dmac->rstc = devm_reset_control_array_get_optional_exclusive(&pdev->dev);
  1022		if (IS_ERR(dmac->rstc))
  1023			return dev_err_probe(&pdev->dev, PTR_ERR(dmac->rstc),
  1024					     "failed to get resets\n");
  1025	
  1026		pm_runtime_enable(&pdev->dev);
  1027		ret = pm_runtime_resume_and_get(&pdev->dev);
  1028		if (ret < 0) {
  1029			dev_err(&pdev->dev, "pm_runtime_resume_and_get failed\n");
  1030			goto err_pm_disable;
  1031		}
  1032	
  1033		ret = reset_control_deassert(dmac->rstc);
  1034		if (ret)
  1035			goto err_pm_runtime_put;
  1036	
  1037		for (i = 0; i < dmac->n_channels; i++) {
  1038			ret = rz_dmac_chan_probe(dmac, &dmac->channels[i], i);
  1039			if (ret < 0)
  1040				goto err;
  1041		}
  1042	
  1043		/* Register the DMAC as a DMA provider for DT. */
  1044		ret = of_dma_controller_register(pdev->dev.of_node, rz_dmac_of_xlate,
  1045						 NULL);
  1046		if (ret < 0)
  1047			goto err;
  1048	
  1049		/* Register the DMA engine device. */
  1050		engine = &dmac->engine;
  1051		dma_cap_set(DMA_SLAVE, engine->cap_mask);
  1052		dma_cap_set(DMA_MEMCPY, engine->cap_mask);
  1053		rz_dmac_writel(dmac, DCTRL_DEFAULT, CHANNEL_0_7_COMMON_BASE + DCTRL);
  1054		rz_dmac_writel(dmac, DCTRL_DEFAULT, CHANNEL_8_15_COMMON_BASE + DCTRL);
  1055	
  1056		engine->dev = &pdev->dev;
  1057	
  1058		engine->device_alloc_chan_resources = rz_dmac_alloc_chan_resources;
  1059		engine->device_free_chan_resources = rz_dmac_free_chan_resources;
  1060		engine->device_tx_status = dma_cookie_status;
  1061		engine->device_prep_slave_sg = rz_dmac_prep_slave_sg;
  1062		engine->device_prep_dma_memcpy = rz_dmac_prep_dma_memcpy;
  1063		engine->device_config = rz_dmac_config;
  1064		engine->device_terminate_all = rz_dmac_terminate_all;
  1065		engine->device_issue_pending = rz_dmac_issue_pending;
  1066		engine->device_synchronize = rz_dmac_device_synchronize;
  1067	
  1068		engine->copy_align = DMAENGINE_ALIGN_1_BYTE;
  1069		dma_set_max_seg_size(engine->dev, U32_MAX);
  1070	
  1071		ret = dma_async_device_register(engine);
  1072		if (ret < 0) {
  1073			dev_err(&pdev->dev, "unable to register\n");
  1074			goto dma_register_err;
  1075		}
  1076		return 0;
  1077	
  1078	dma_register_err:
  1079		of_dma_controller_free(pdev->dev.of_node);
  1080	err:
  1081		channel_num = i ? i - 1 : 0;
  1082		for (i = 0; i < channel_num; i++) {
  1083			struct rz_dmac_chan *channel = &dmac->channels[i];
  1084	
  1085			dma_free_coherent(&pdev->dev,
  1086					  sizeof(struct rz_lmdesc) * DMAC_NR_LMDESC,
  1087					  channel->lmdesc.base,
  1088					  channel->lmdesc.base_dma);
  1089		}
  1090	
  1091		reset_control_assert(dmac->rstc);
  1092	err_pm_runtime_put:
  1093		pm_runtime_put(&pdev->dev);
  1094	err_pm_disable:
  1095		pm_runtime_disable(&pdev->dev);
  1096	
  1097		return ret;
  1098	}
  1099	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support
  2025-02-12 22:13 ` [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support Fabrizio Castro
  2025-02-13 13:24   ` kernel test robot
@ 2025-02-13 14:19   ` Geert Uytterhoeven
  2025-02-13 14:23     ` Geert Uytterhoeven
  2025-02-18 20:39     ` Fabrizio Castro
  1 sibling, 2 replies; 15+ messages in thread
From: Geert Uytterhoeven @ 2025-02-13 14:19 UTC (permalink / raw)
  To: Fabrizio Castro
  Cc: Vinod Koul, Magnus Damm, Philipp Zabel, Wolfram Sang, Biju Das,
	Uwe Kleine-König, dmaengine, linux-kernel, linux-renesas-soc,
	Lad Prabhakar

Hi Fabrizio,

On Wed, 12 Feb 2025 at 23:13, Fabrizio Castro
<fabrizio.castro.jz@renesas.com> wrote:
> The DMAC IP found on the Renesas RZ/V2H(P) family of SoCs is
> similar to the version found on the Renesas RZ/G2L family of
> SoCs, but there are some differences:
> * It only uses one register area
> * It only uses one clock
> * It only uses one reset
> * Instead of using MID/IRD it uses REQ NO/ACK NO
> * It is connected to the Interrupt Control Unit (ICU)
> * On the RZ/G2L there is only 1 DMAC, on the RZ/V2H(P) there are 5
>
> Add specific support for the Renesas RZ/V2H(P) family of SoC by
> tackling the aforementioned differences.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> ---
> v1->v2:
> * Switched to new macros for minimum values.

Thanks for the update!

> --- a/drivers/dma/sh/Kconfig
> +++ b/drivers/dma/sh/Kconfig
> @@ -53,6 +53,7 @@ config RZ_DMAC
>         depends on ARCH_R7S72100 || ARCH_RZG2L || COMPILE_TEST
>         select RENESAS_DMA
>         select DMA_VIRTUAL_CHANNELS
> +       select RENESAS_RZV2H_ICU

This enables RENESAS_RZV2H_ICU unconditionally, while it is only
really needed on RZ/V2H, and not on other arm64 SoCs, or on arm32
or riscv SoCs.

>         help
>           This driver supports the general purpose DMA controller typically
>           found in the Renesas RZ SoC variants.
> diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c
> index d7a4ce28040b..24a8c6a337d5 100644
> --- a/drivers/dma/sh/rz-dmac.c
> +++ b/drivers/dma/sh/rz-dmac.c
> @@ -14,6 +14,7 @@
>  #include <linux/dmaengine.h>
>  #include <linux/interrupt.h>
>  #include <linux/iopoll.h>
> +#include <linux/irqchip/irq-renesas-rzv2h.h>
>  #include <linux/list.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> @@ -28,6 +29,11 @@
>  #include "../dmaengine.h"
>  #include "../virt-dma.h"
>
> +enum rz_dmac_type {
> +       RZ_DMAC_RZG2L,
> +       RZ_DMAC_RZV2H,

So basically these mean !has_icu respectively has_icu (more below)...

> +};
> +
>  enum  rz_dmac_prep_type {
>         RZ_DMAC_DESC_MEMCPY,
>         RZ_DMAC_DESC_SLAVE_SG,
> @@ -85,20 +91,32 @@ struct rz_dmac_chan {
>                 struct rz_lmdesc *tail;
>                 dma_addr_t base_dma;
>         } lmdesc;
> +
> +       /* RZ/V2H ICU related signals */
> +       u16 req_no;
> +       u8 ack_no;

This could be an anonymous union with mid_rid, as mid_rid is
mutually-exclusive with req_no and ack_no.

>  };

> @@ -824,6 +907,40 @@ static int rz_dmac_chan_probe(struct rz_dmac *dmac,
>         return 0;
>  }
>
> +static int rz_dmac_parse_of_icu(struct device *dev, struct rz_dmac *dmac)
> +{
> +       struct device_node *icu_np, *np = dev->of_node;
> +       struct of_phandle_args args;
> +       uint32_t dmac_index;
> +       int ret;
> +
> +       ret = of_parse_phandle_with_fixed_args(np, "renesas,icu", 1, 0, &args);
> +       if (ret)
> +               return ret;
> +
> +       icu_np = args.np;
> +       dmac_index = args.args[0];
> +
> +       if (dmac_index > RZV2H_MAX_DMAC_INDEX) {
> +               dev_err(dev, "DMAC index %u invalid.\n", dmac_index);
> +               ret = -EINVAL;
> +               goto free_icu_np;
> +       }
> +
> +       dmac->icu.pdev = of_find_device_by_node(icu_np);

What if the DMAC is probed before the ICU?
Is the returned pdev valid?
Will rzv2h_icu_register_dma_req_ack() crash when dereferencing priv?

> +       if (!dmac->icu.pdev) {
> +               ret = -ENODEV;
> +               goto free_icu_np;
> +       }
> +
> +       dmac->icu.dmac_index = dmac_index;
> +
> +free_icu_np:
> +       of_node_put(icu_np);
> +
> +       return ret;
> +}
> +
>  static int rz_dmac_parse_of(struct device *dev, struct rz_dmac *dmac)
>  {
>         struct device_node *np = dev->of_node;
> @@ -859,6 +976,7 @@ static int rz_dmac_probe(struct platform_device *pdev)
>
>         dmac->dev = &pdev->dev;
>         platform_set_drvdata(pdev, dmac);
> +       dmac->type = (enum rz_dmac_type)of_device_get_match_data(dmac->dev);

(uintptr_t)

But as "renesas,icu" is a required property for RZ/V2H, perhaps you
can devise the has_icu flag at runtime?

>
>         ret = rz_dmac_parse_of(&pdev->dev, dmac);
>         if (ret < 0)

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support
  2025-02-13 14:19   ` Geert Uytterhoeven
@ 2025-02-13 14:23     ` Geert Uytterhoeven
  2025-02-18 20:40       ` Fabrizio Castro
  2025-02-18 20:39     ` Fabrizio Castro
  1 sibling, 1 reply; 15+ messages in thread
From: Geert Uytterhoeven @ 2025-02-13 14:23 UTC (permalink / raw)
  To: Fabrizio Castro
  Cc: Vinod Koul, Magnus Damm, Philipp Zabel, Wolfram Sang, Biju Das,
	Uwe Kleine-König, dmaengine, linux-kernel, linux-renesas-soc,
	Lad Prabhakar

Hi Fabrizio,

On Thu, 13 Feb 2025 at 15:19, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> On Wed, 12 Feb 2025 at 23:13, Fabrizio Castro
> <fabrizio.castro.jz@renesas.com> wrote:
> > The DMAC IP found on the Renesas RZ/V2H(P) family of SoCs is
> > similar to the version found on the Renesas RZ/G2L family of
> > SoCs, but there are some differences:
> > * It only uses one register area
> > * It only uses one clock
> > * It only uses one reset
> > * Instead of using MID/IRD it uses REQ NO/ACK NO
> > * It is connected to the Interrupt Control Unit (ICU)
> > * On the RZ/G2L there is only 1 DMAC, on the RZ/V2H(P) there are 5
> >
> > Add specific support for the Renesas RZ/V2H(P) family of SoC by
> > tackling the aforementioned differences.
> >
> > Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> > ---
> > v1->v2:
> > * Switched to new macros for minimum values.
>
> Thanks for the update!
>
> > --- a/drivers/dma/sh/Kconfig
> > +++ b/drivers/dma/sh/Kconfig
> > @@ -53,6 +53,7 @@ config RZ_DMAC
> >         depends on ARCH_R7S72100 || ARCH_RZG2L || COMPILE_TEST
> >         select RENESAS_DMA
> >         select DMA_VIRTUAL_CHANNELS
> > +       select RENESAS_RZV2H_ICU
>
> This enables RENESAS_RZV2H_ICU unconditionally, while it is only
> really needed on RZ/V2H, and not on other arm64 SoCs, or on arm32
> or riscv SoCs.

As ARCH_R9A09G057 already selects RENESAS_RZV2H_ICU, you could provide
a dummy rzv2h_icu_register_dma_req_ack() for the !RENESAS_RZV2H_ICU
case, or even disable all ICU-related code when it is not needed.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v2 4/7] irqchip/renesas-rzv2h: Add rzv2h_icu_register_dma_req_ack
  2025-02-12 22:13 ` [PATCH v2 4/7] irqchip/renesas-rzv2h: Add rzv2h_icu_register_dma_req_ack Fabrizio Castro
@ 2025-02-18  8:00   ` Thomas Gleixner
  2025-02-18 22:10     ` Fabrizio Castro
  0 siblings, 1 reply; 15+ messages in thread
From: Thomas Gleixner @ 2025-02-18  8:00 UTC (permalink / raw)
  To: Fabrizio Castro, Geert Uytterhoeven
  Cc: Fabrizio Castro, linux-kernel, Biju Das, Lad Prabhakar,
	linux-renesas-soc

On Wed, Feb 12 2025 at 22:13, Fabrizio Castro wrote:
> On the Renesas RZ/V2H(P) family of SoCs, DMAC IPs are connected
> to the Interrupt Control Unit (ICU).
> For DMA transfers, a request number and an ack number must be
> registered with the ICU, which means that the DMAC driver has
> to be able to instruct the ICU driver with the registration of
> such ids.
>
> Export rzv2h_icu_register_dma_req_ack so that the DMA driver
> can register both ids in one go.

Please denote functions in the subject and change log body as fun()
according to documentation:

https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#function-references-in-changelogs

With that fixed:

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

under the assumption that this will be merged via the dmaengine tree.

Thanks,

        tglx

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

* RE: [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support
  2025-02-13 14:19   ` Geert Uytterhoeven
  2025-02-13 14:23     ` Geert Uytterhoeven
@ 2025-02-18 20:39     ` Fabrizio Castro
  1 sibling, 0 replies; 15+ messages in thread
From: Fabrizio Castro @ 2025-02-18 20:39 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Vinod Koul, Magnus Damm, Philipp Zabel, Wolfram Sang, Biju Das,
	Uwe Kleine-König, dmaengine@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
	Prabhakar Mahadev Lad

Hi Geert,

Thanks for your feedback!

> From: Geert Uytterhoeven <geert@linux-m68k.org>
> Sent: 13 February 2025 14:20
> Subject: Re: [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support
> 
> Hi Fabrizio,
> 
> On Wed, 12 Feb 2025 at 23:13, Fabrizio Castro
> <fabrizio.castro.jz@renesas.com> wrote:
> > The DMAC IP found on the Renesas RZ/V2H(P) family of SoCs is
> > similar to the version found on the Renesas RZ/G2L family of
> > SoCs, but there are some differences:
> > * It only uses one register area
> > * It only uses one clock
> > * It only uses one reset
> > * Instead of using MID/IRD it uses REQ NO/ACK NO
> > * It is connected to the Interrupt Control Unit (ICU)
> > * On the RZ/G2L there is only 1 DMAC, on the RZ/V2H(P) there are 5
> >
> > Add specific support for the Renesas RZ/V2H(P) family of SoC by
> > tackling the aforementioned differences.
> >
> > Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> > ---
> > v1->v2:
> > * Switched to new macros for minimum values.
> 
> Thanks for the update!
> 
> > --- a/drivers/dma/sh/Kconfig
> > +++ b/drivers/dma/sh/Kconfig
> > @@ -53,6 +53,7 @@ config RZ_DMAC
> >         depends on ARCH_R7S72100 || ARCH_RZG2L || COMPILE_TEST
> >         select RENESAS_DMA
> >         select DMA_VIRTUAL_CHANNELS
> > +       select RENESAS_RZV2H_ICU
> 
> This enables RENESAS_RZV2H_ICU unconditionally, while it is only
> really needed on RZ/V2H, and not on other arm64 SoCs, or on arm32
> or riscv SoCs.

Good point, I'll follow up on this on your other email.

> 
> >         help
> >           This driver supports the general purpose DMA controller typically
> >           found in the Renesas RZ SoC variants.
> > diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c
> > index d7a4ce28040b..24a8c6a337d5 100644
> > --- a/drivers/dma/sh/rz-dmac.c
> > +++ b/drivers/dma/sh/rz-dmac.c
> > @@ -14,6 +14,7 @@
> >  #include <linux/dmaengine.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/iopoll.h>
> > +#include <linux/irqchip/irq-renesas-rzv2h.h>
> >  #include <linux/list.h>
> >  #include <linux/module.h>
> >  #include <linux/of.h>
> > @@ -28,6 +29,11 @@
> >  #include "../dmaengine.h"
> >  #include "../virt-dma.h"
> >
> > +enum rz_dmac_type {
> > +       RZ_DMAC_RZG2L,
> > +       RZ_DMAC_RZV2H,
> 
> So basically these mean !has_icu respectively has_icu (more below)...

Yes.

> 
> > +};
> > +
> >  enum  rz_dmac_prep_type {
> >         RZ_DMAC_DESC_MEMCPY,
> >         RZ_DMAC_DESC_SLAVE_SG,
> > @@ -85,20 +91,32 @@ struct rz_dmac_chan {
> >                 struct rz_lmdesc *tail;
> >                 dma_addr_t base_dma;
> >         } lmdesc;
> > +
> > +       /* RZ/V2H ICU related signals */
> > +       u16 req_no;
> > +       u8 ack_no;
> 
> This could be an anonymous union with mid_rid, as mid_rid is
> mutually-exclusive with req_no and ack_no.

Indeed, I'll adjust accordingly.

> 
> >  };
> 
> > @@ -824,6 +907,40 @@ static int rz_dmac_chan_probe(struct rz_dmac *dmac,
> >         return 0;
> >  }
> >
> > +static int rz_dmac_parse_of_icu(struct device *dev, struct rz_dmac *dmac)
> > +{
> > +       struct device_node *icu_np, *np = dev->of_node;
> > +       struct of_phandle_args args;
> > +       uint32_t dmac_index;
> > +       int ret;
> > +
> > +       ret = of_parse_phandle_with_fixed_args(np, "renesas,icu", 1, 0, &args);
> > +       if (ret)
> > +               return ret;
> > +
> > +       icu_np = args.np;
> > +       dmac_index = args.args[0];
> > +
> > +       if (dmac_index > RZV2H_MAX_DMAC_INDEX) {
> > +               dev_err(dev, "DMAC index %u invalid.\n", dmac_index);
> > +               ret = -EINVAL;
> > +               goto free_icu_np;
> > +       }
> > +
> > +       dmac->icu.pdev = of_find_device_by_node(icu_np);
> 
> What if the DMAC is probed before the ICU?

This doesn't look like a possible scenario, as irqchips are initialized very early.

> Is the returned pdev valid?
> Will rzv2h_icu_register_dma_req_ack() crash when dereferencing priv?

Even though it doesn't seem possible for the ICU driver to get probed after the DMAC
driver, I have still looked into possible ways your comment could apply, and I have
found one, although it can't really happen in practice, as the system will hang before
getting there.

If the probing of the ICU driver _fails_, then of_find_device_by_node() returns a valid
pointer. At some point we call into rzv2h_icu_register_dma_req_ack(), and the first time
we do anything with `priv` we deal with a NULL pointer.

However, if the probing of the ICU driver fails, the system hangs very early on because
the ICU is the interrupt parent of the pintctrl node.

In order to see the failure I have described I had to take `interrupt-parent = <&icu>;`
out of the pinctrl node, on top of manually make the ICU driver fail.

If the ICU driver fails its initialization the system is gone, and not because of DMAC,
therefore I'll leave this bit unchanged for the next version of the series.

> 
> > +       if (!dmac->icu.pdev) {
> > +               ret = -ENODEV;
> > +               goto free_icu_np;
> > +       }
> > +
> > +       dmac->icu.dmac_index = dmac_index;
> > +
> > +free_icu_np:
> > +       of_node_put(icu_np);
> > +
> > +       return ret;
> > +}
> > +
> >  static int rz_dmac_parse_of(struct device *dev, struct rz_dmac *dmac)
> >  {
> >         struct device_node *np = dev->of_node;
> > @@ -859,6 +976,7 @@ static int rz_dmac_probe(struct platform_device *pdev)
> >
> >         dmac->dev = &pdev->dev;
> >         platform_set_drvdata(pdev, dmac);
> > +       dmac->type = (enum rz_dmac_type)of_device_get_match_data(dmac->dev);
> 
> (uintptr_t)
> 
> But as "renesas,icu" is a required property for RZ/V2H, perhaps you
> can devise the has_icu flag at runtime?

I'll switch to using the has_icu flag at runtime.

Thanks!

Cheers,
Fab

> 
> >
> >         ret = rz_dmac_parse_of(&pdev->dev, dmac);
> >         if (ret < 0)
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds

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

* RE: [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support
  2025-02-13 14:23     ` Geert Uytterhoeven
@ 2025-02-18 20:40       ` Fabrizio Castro
  0 siblings, 0 replies; 15+ messages in thread
From: Fabrizio Castro @ 2025-02-18 20:40 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Vinod Koul, Magnus Damm, Philipp Zabel, Wolfram Sang, Biju Das,
	Uwe Kleine-König, dmaengine@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
	Prabhakar Mahadev Lad

Hi Geert,

Thanks for your feedback!

> From: Geert Uytterhoeven <geert@linux-m68k.org>
> Sent: 13 February 2025 14:23
> Subject: Re: [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support
> 
> Hi Fabrizio,
> 
> On Thu, 13 Feb 2025 at 15:19, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> > On Wed, 12 Feb 2025 at 23:13, Fabrizio Castro
> > <fabrizio.castro.jz@renesas.com> wrote:
> > > The DMAC IP found on the Renesas RZ/V2H(P) family of SoCs is
> > > similar to the version found on the Renesas RZ/G2L family of
> > > SoCs, but there are some differences:
> > > * It only uses one register area
> > > * It only uses one clock
> > > * It only uses one reset
> > > * Instead of using MID/IRD it uses REQ NO/ACK NO
> > > * It is connected to the Interrupt Control Unit (ICU)
> > > * On the RZ/G2L there is only 1 DMAC, on the RZ/V2H(P) there are 5
> > >
> > > Add specific support for the Renesas RZ/V2H(P) family of SoC by
> > > tackling the aforementioned differences.
> > >
> > > Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> > > ---
> > > v1->v2:
> > > * Switched to new macros for minimum values.
> >
> > Thanks for the update!
> >
> > > --- a/drivers/dma/sh/Kconfig
> > > +++ b/drivers/dma/sh/Kconfig
> > > @@ -53,6 +53,7 @@ config RZ_DMAC
> > >         depends on ARCH_R7S72100 || ARCH_RZG2L || COMPILE_TEST
> > >         select RENESAS_DMA
> > >         select DMA_VIRTUAL_CHANNELS
> > > +       select RENESAS_RZV2H_ICU
> >
> > This enables RENESAS_RZV2H_ICU unconditionally, while it is only
> > really needed on RZ/V2H, and not on other arm64 SoCs, or on arm32
> > or riscv SoCs.
> 
> As ARCH_R9A09G057 already selects RENESAS_RZV2H_ICU, you could provide
> a dummy rzv2h_icu_register_dma_req_ack() for the !RENESAS_RZV2H_ICU
> case, or even disable all ICU-related code when it is not needed.

A dummy rzv2h_icu_register_dma_req_ack() sounds good, I'll include that
in the next version of the series.

Thanks!

Cheers,
Fab

> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds

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

* RE: [PATCH v2 4/7] irqchip/renesas-rzv2h: Add rzv2h_icu_register_dma_req_ack
  2025-02-18  8:00   ` Thomas Gleixner
@ 2025-02-18 22:10     ` Fabrizio Castro
  0 siblings, 0 replies; 15+ messages in thread
From: Fabrizio Castro @ 2025-02-18 22:10 UTC (permalink / raw)
  To: Thomas Gleixner, Geert Uytterhoeven
  Cc: linux-kernel@vger.kernel.org, Biju Das, Prabhakar Mahadev Lad,
	linux-renesas-soc@vger.kernel.org

Hi Thomas,

Thanks for your feedback!

> From: Thomas Gleixner <tglx@linutronix.de>
> Sent: 18 February 2025 08:00
> Subject: Re: [PATCH v2 4/7] irqchip/renesas-rzv2h: Add rzv2h_icu_register_dma_req_ack
> 
> On Wed, Feb 12 2025 at 22:13, Fabrizio Castro wrote:
> > On the Renesas RZ/V2H(P) family of SoCs, DMAC IPs are connected
> > to the Interrupt Control Unit (ICU).
> > For DMA transfers, a request number and an ack number must be
> > registered with the ICU, which means that the DMAC driver has
> > to be able to instruct the ICU driver with the registration of
> > such ids.
> >
> > Export rzv2h_icu_register_dma_req_ack so that the DMA driver
> > can register both ids in one go.
> 
> Please denote functions in the subject and change log body as fun()
> according to documentation:

Thanks for pointing this out. I'll address it in the next version.

Cheers,
Fab

> 
> https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#function-references-in-changelogs
> 
> With that fixed:
> 
> Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
> 
> under the assumption that this will be merged via the dmaengine tree.
> 
> Thanks,
> 
>         tglx

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

end of thread, other threads:[~2025-02-18 22:10 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-12 22:12 [PATCH v2 0/7] Add DMAC support to the RZ/V2H(P) Fabrizio Castro
2025-02-12 22:12 ` [PATCH v2 1/7] clk: renesas: r9a09g057: Add entries for the DMACs Fabrizio Castro
2025-02-12 22:13 ` [PATCH v2 2/7] dt-bindings: dma: rz-dmac: Restrict properties for RZ/A1H Fabrizio Castro
2025-02-12 22:13 ` [PATCH v2 3/7] dt-bindings: dma: rz-dmac: Document RZ/V2H(P) family of SoCs Fabrizio Castro
2025-02-12 22:13 ` [PATCH v2 4/7] irqchip/renesas-rzv2h: Add rzv2h_icu_register_dma_req_ack Fabrizio Castro
2025-02-18  8:00   ` Thomas Gleixner
2025-02-18 22:10     ` Fabrizio Castro
2025-02-12 22:13 ` [PATCH v2 5/7] dmaengine: sh: rz-dmac: Allow for multiple DMACs Fabrizio Castro
2025-02-12 22:13 ` [PATCH v2 6/7] dmaengine: sh: rz-dmac: Add RZ/V2H(P) support Fabrizio Castro
2025-02-13 13:24   ` kernel test robot
2025-02-13 14:19   ` Geert Uytterhoeven
2025-02-13 14:23     ` Geert Uytterhoeven
2025-02-18 20:40       ` Fabrizio Castro
2025-02-18 20:39     ` Fabrizio Castro
2025-02-12 22:13 ` [PATCH v2 7/7] arm64: dts: renesas: r9a09g057: Add DMAC nodes Fabrizio Castro

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.