* [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support
@ 2026-05-12 18:26 John Madieu
2026-05-12 18:26 ` [PATCH v6 01/16] ASoC: dt-bindings: sound: Add DT binding for RZ/G3E sound John Madieu
` (15 more replies)
0 siblings, 16 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
Add audio support for the Renesas RZ/G3E SoC to the R-Car Sound
driver. The RZ/G3E audio subsystem is based on R-Car Sound IP but
has several differences requiring dedicated handling:
- SSI operates exclusively in BUSIF mode (no PIO)
- 2-4 BUSIF channels per SSI (layout differs from R-Car)
- Separate register regions for SCU, ADG, SSIU, SSI accessed by name
- Per-SSI ADG and SSIF supply clocks
- Dedicated audmacpp clock/reset for Audio DMAC peri-peri
- Per-SSI and per-module reset controllers via CPG
- Unprefixed DT sub-node names (ssi, ssiu, src, ...) instead of
rcar_sound,xxx
- Hyphenated indexed clock/reset names (ssi-0, src-0, adg-ssi-0,
audio-clka, ...) instead of the legacy dotted form
Link to v5 at [1].
Changes:
v6:
- Rename all indexed clock-names and reset-names from the dotted form
("ssi.0", "src.0", "adg.ssi.0", "clk_a", ...) to the hyphenated form
("ssi-0", "src-0", "adg-ssi-0", "audio-clka", ...).
- DT binding: tighten #sound-dai-cells to const: 1, drop the unused
clock-frequency and clkout-lr-asynchronous properties.
- Add a new preparatory patch to handle the hyphenated DT name first and
fall back to the legacy dotted form, so existing R-Car DTs keep
working unchanged while new bindings can use the hyphenated convention.
- Convert the SSI, SRC, CTU, DVC and MIX probes to the helpers and drop
the per-module name buffers and NAME_SIZE defines.
- Add a new patch adding a third clkin name table for RZ/G3E and
dispatching to it in the same style as the existing Gen4
branch. CLKA/B/C/I enum values, the clkin[] array and the
BRGA/BRGB derivation are unchanged; only the DT lookup names
differ and use the hyphenated form.
- audmacpp: enable the clock before deasserting the reset so the
block sees a stable clock on the way out of reset (and mirror
the ordering on suspend/resume).
- SRC: use devm_clk_get_optional_enabled() for scu_supply and drop
the manual prepare/enable in rsnd_src_init()/rsnd_src_quit(),
so scu_supply has the same lifetime as scu/scu_x2.
- adg: simplify the per-SSI ADG and SSIF supply clock
- Strip out the "rcar_sound," from binding, DT, and add corresponding
code support.
- suspend/resume: respect the probe ordering in
rsnd_dma_suspend()/_resume() (assert reset before disabling
clock on suspend; enable clock before deasserting reset on
resume)
- Guard rsnd_src_suspend()/_resume() so platforms without SRC are safe.
v5:
- Drop the rsnd.yaml binding split (patches 01/12 and 02/12 from v4).
- Extract RSND_SOC_MASK fix as a standalone bug-fix patch (was
previously embedded in patch 04) per Kuninori's request.
- Split the DMA refactor out of patch 06/12 into its own
preparatory patch, so the struct/lookup introduction and the
RZ/G3E address tables are in separate commits.
- Add new patch "Support unprefixed DT node names for RZ/G3E"
converting rsnd_parse_of_node() to a function that tries the
legacy rcar_sound, prefix first, then falls back to the bare
name.
- Simplify flags layout comment per Kuninori's feedback.
- Add comment clarifying that clock/reset acquisition is optional
and no-error when absent from DT, and drop spurious blank line
in rsnd.h.
- Move RZ/G3E DMA address comment to rsnd_rzg3e_dma_addr(), not
the shared header. Separate the line-wrap-only change in
rsnd_gen2_dma_addr() into the preparatory patch only.
v4:
- Add reset_control_assert() in rsnd_mod_quit() for symmetry with
deassert in rsnd_mod_init() (Mark Brown)
- Fix RSND_SOC_MASK to (0xF << 4) to avoid overlap with
RSND_RZ_MASK. Add nibble layout comment documenting the flag
bit allocation.
- Move audmapp_clk and audmapp_rstc from struct rsnd_priv into
struct rsnd_dma_ctrl.
- Replace raw [3][2][3] DMA address array with named structs
(rsnd_dma_addr_dir, rsnd_dma_addr_map) for self-documenting
table initializers.
- Move busif_status_count from file-static into new
struct rsnd_ssiu_ctrl, following the rsnd_dma_ctrl pattern.
Remove duplicate priv variable. Properly propagate reset errors
via dev_err_probe().
- Clarify commit message regarding PIO mode still being available
on R-Car.
- Collapse dev_err_probe() and rsnd_mod_init() calls to single
lines.
- Move per-SSI ADG and SSIF supply clock prepare/unprepare into
rsnd_adg_clk_control() instead of separate functions.
- Move shared SCU clocks from file-statics into new
struct rsnd_src_ctrl.
- Merge rsnd_adg_mod_get() helper directly into the suspend/resume
patch.
- Drop former patch 12/14 "Add rsnd_adg_mod_get() for PM support".
- Drop former patch 13/14 "Export rsnd_ssiu_mod_get() for PM
support".
v3:
- Split out from v2 series [2] to ASoC-specific patchset.
v2:
- Split of rsnd.yaml into common and R-Car-specific schemas.
- Introduce RZ/G3E sound binding as a standalone schema.
- Addressed Kuninori's comments (details in individual patches).
[1] https://lore.kernel.org/all/20260415124731.3684773-1-john.madieu.xa@bp.renesas.com/
[2] https://lore.kernel.org/all/20260402090524.9137-1-john.madieu.xa@bp.renesas.com/
John Madieu (16):
ASoC: dt-bindings: sound: Add DT binding for RZ/G3E sound
ASoC: rsnd: Fix RSND_SOC_MASK width to single nibble
ASoC: rsnd: Add reset controller support to rsnd_mod
ASoC: rsnd: Support hyphen or dot in indexed clock and reset names
ASoC: rsnd: Add RZ/G3E SoC probing and register map
ASoC: rsnd: Add audmacpp clock and reset support for RZ/G3E
ASoC: rsnd: Refactor DMA address tables with named structs
ASoC: rsnd: Add RZ/G3E DMA address calculation support
ASoC: rsnd: ssui: Add RZ/G3E SSIU BUSIF support
ASoC: rsnd: Add SSI reset support for RZ/G3E platform
ASoC: rsnd: Add ADG reset support for RZ/G3E
ASoC: rsnd: adg: Add per-SSI ADG and SSIF supply clock management
ASoC: rsnd: adg: Look up RZ/G3E clkin under audio-clk{a,b,c,i}
ASoC: rsnd: src: Add SRC reset and clock support for RZ/G3E
ASoC: rsnd: Support unprefixed DT node names for RZ/G3E
ASoC: rsnd: Add system suspend/resume support
.../sound/renesas,r9a09g047-sound.yaml | 743 ++++++++++++++++++
sound/soc/renesas/rcar/adg.c | 130 ++-
sound/soc/renesas/rcar/cmd.c | 2 +-
sound/soc/renesas/rcar/core.c | 162 +++-
sound/soc/renesas/rcar/ctu.c | 29 +-
sound/soc/renesas/rcar/dma.c | 280 +++++--
sound/soc/renesas/rcar/dvc.c | 29 +-
sound/soc/renesas/rcar/gen.c | 180 +++++
sound/soc/renesas/rcar/mix.c | 29 +-
sound/soc/renesas/rcar/rsnd.h | 73 +-
sound/soc/renesas/rcar/src.c | 91 ++-
sound/soc/renesas/rcar/ssi.c | 49 +-
sound/soc/renesas/rcar/ssiu.c | 91 ++-
13 files changed, 1763 insertions(+), 125 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/renesas,r9a09g047-sound.yaml
--
2.25.1
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v6 01/16] ASoC: dt-bindings: sound: Add DT binding for RZ/G3E sound
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 02/16] ASoC: rsnd: Fix RSND_SOC_MASK width to single nibble John Madieu
` (14 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
Add a standalone device tree binding for the Renesas RZ/G3E (R9A09G047)
sound controller.
The RZ/G3E sound IP is based on R-Car Sound but differs in several ways:
- Uses unprefixed sub-node names (ssi, ssiu, src, dvc, mix, ctu) instead
of R-Car's rcar_sound,xxx prefixed names.
- Supports up to 5 DMA controllers per direction, allowing multiple DMA
entries with repeated channel names in SSIU, SRC and DVC sub-nodes.
- Has 47 clocks including per-SSI ADG clocks (adg-ssi-[0-9]), SCU clocks
(scu, scu_x2, scu_supply), SSIF supply clock, AUDMAC peri-peri clock,
and ADG clock.
- Has 14 reset lines including SCU, ADG and AUDMAC peri-peri resets.
- SSI operates exclusively in BUSIF mode.
These differences make the RZ/G3E binding incompatible with the existing
renesas,rsnd.yaml, so it is added as a separate standalone binding with
its own $ref to dai-common.yaml.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6:
- Rename all indexed clock-names and reset-names from the dotted
form (ssi.0, src.0, adg.ssi.0, clk_a, clk_b, clk_c, clk_i) to
the hyphenated form (ssi-0, src-0, adg-ssi-0, audio-clka,
audio-clkb, audio-clkc, audio-clki) so the new binding follows
the standard DT naming convention.
- Tighten #sound-dai-cells to const: 1.
- Drop unused properties: clock-frequency, clkout-lr-asynchronous.
- Simplify the ports/endpoint schema (single ports object with
port@N children referencing audio-graph-port.yaml), drop the
separate top-level dai patternProperties block.
- Move additionalProperties: false to the top of each sub-object
(dvc, mix, ctu, src, ssiu, ssi).
- Reorder example clocks/resets to match the new ordinal-ascending
name order.
v5:
- Drop the two-patch rsnd.yaml split approach from v4. Replace
with a single self-contained standalone binding that does not
touch renesas,rsnd.yaml at all.
- Remove select: false, redundant blanket properties
(compatible: true, reg: true, etc.) and pointless
patternProperties per Krzysztof's review.
- Add missing #clock-cells and #sound-dai-cells constraints.
- Add hardware description text instead of "Binding for ..."
phrasing.
- Move G3E-specific DMA comment into the binding itself rather
than relying on a shared schema.
- Use unprefixed sub-node names (ssi, ssiu, src, dvc, mix, ctu)
to reflect the actual RZ/G3E DT binding.
v4: No changes
v3: No changes
v2:
- Introduce RZ/G3E sound binding as a standalone schema.
.../sound/renesas,r9a09g047-sound.yaml | 743 ++++++++++++++++++
1 file changed, 743 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/renesas,r9a09g047-sound.yaml
diff --git a/Documentation/devicetree/bindings/sound/renesas,r9a09g047-sound.yaml b/Documentation/devicetree/bindings/sound/renesas,r9a09g047-sound.yaml
new file mode 100644
index 000000000000..0b651214bd61
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/renesas,r9a09g047-sound.yaml
@@ -0,0 +1,743 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/renesas,r9a09g047-sound.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/G3E Sound Controller
+
+maintainers:
+ - Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ - John Madieu <john.madieu.xa@bp.renesas.com>
+
+description:
+ The RZ/G3E (R9A09G047) sound controller is based on R-Car Sound IP
+ with extended DMA channel support (up to 5 DMACs per direction),
+ additional clock domains (47 clocks including per-SSI ADG clocks),
+ and additional reset lines (14 including SCU, ADG and Audio DMAC
+ peri-peri resets). SSI operates exclusively in BUSIF mode with
+ 2-4 BUSIF channels per SSI.
+
+allOf:
+ - $ref: dai-common.yaml#
+
+properties:
+ compatible:
+ const: renesas,r9a09g047-sound
+
+ reg:
+ maxItems: 5
+
+ reg-names:
+ items:
+ - const: scu
+ - const: adg
+ - const: ssiu
+ - const: ssi
+ - const: audmapp
+
+ "#sound-dai-cells":
+ const: 1
+
+ "#clock-cells":
+ const: 0
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ clocks:
+ maxItems: 47
+
+ clock-names:
+ items:
+ - const: ssi-all
+ - const: ssi-0
+ - const: ssi-1
+ - const: ssi-2
+ - const: ssi-3
+ - const: ssi-4
+ - const: ssi-5
+ - const: ssi-6
+ - const: ssi-7
+ - const: ssi-8
+ - const: ssi-9
+ - const: src-0
+ - const: src-1
+ - const: src-2
+ - const: src-3
+ - const: src-4
+ - const: src-5
+ - const: src-6
+ - const: src-7
+ - const: src-8
+ - const: src-9
+ - const: mix-0
+ - const: mix-1
+ - const: ctu-0
+ - const: ctu-1
+ - const: dvc-0
+ - const: dvc-1
+ - const: audio-clka
+ - const: audio-clkb
+ - const: audio-clkc
+ - const: audio-clki
+ - const: ssif_supply
+ - const: scu
+ - const: scu_x2
+ - const: scu_supply
+ - const: adg-ssi-0
+ - const: adg-ssi-1
+ - const: adg-ssi-2
+ - const: adg-ssi-3
+ - const: adg-ssi-4
+ - const: adg-ssi-5
+ - const: adg-ssi-6
+ - const: adg-ssi-7
+ - const: adg-ssi-8
+ - const: adg-ssi-9
+ - const: audmapp
+ - const: adg
+
+ power-domains:
+ maxItems: 1
+
+ resets:
+ maxItems: 14
+
+ reset-names:
+ items:
+ - const: ssi-all
+ - const: ssi-0
+ - const: ssi-1
+ - const: ssi-2
+ - const: ssi-3
+ - const: ssi-4
+ - const: ssi-5
+ - const: ssi-6
+ - const: ssi-7
+ - const: ssi-8
+ - const: ssi-9
+ - const: scu
+ - const: adg
+ - const: audmapp
+
+ dvc:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^dvc-[0-1]$":
+ type: object
+ additionalProperties: false
+ properties:
+ dmas:
+ maxItems: 5
+ dma-names:
+ maxItems: 5
+ allOf:
+ - items:
+ enum:
+ - tx
+ required:
+ - dmas
+ - dma-names
+
+ mix:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^mix-[0-1]$":
+ type: object
+ additionalProperties: false
+
+ ctu:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^ctu-[0-7]$":
+ type: object
+ additionalProperties: false
+
+ src:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^src-[0-9]$":
+ type: object
+ additionalProperties: false
+ properties:
+ interrupts:
+ maxItems: 1
+ dmas:
+ maxItems: 10
+ dma-names:
+ maxItems: 10
+ allOf:
+ - items:
+ enum:
+ - tx
+ - rx
+
+ ssiu:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^ssiu-[0-9]+$":
+ type: object
+ additionalProperties: false
+ properties:
+ dmas:
+ maxItems: 10
+ dma-names:
+ maxItems: 10
+ allOf:
+ - items:
+ enum:
+ - tx
+ - rx
+ required:
+ - dmas
+ - dma-names
+
+ ssi:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^ssi-[0-9]$":
+ type: object
+ additionalProperties: false
+ properties:
+ interrupts:
+ maxItems: 1
+ dmas: true
+ dma-names: true
+ shared-pin:
+ description: Shared clock pin.
+ $ref: /schemas/types.yaml#/definitions/flag
+ required:
+ - interrupts
+
+ ports:
+ $ref: audio-graph-port.yaml#/definitions/port-base
+ unevaluatedProperties: false
+ patternProperties:
+ '^port@[0-9a-f]+$':
+ $ref: audio-graph-port.yaml#/definitions/port-base
+ unevaluatedProperties: false
+ properties:
+ reg:
+ maxItems: 1
+ endpoint:
+ $ref: audio-graph-port.yaml#/definitions/endpoint-base
+ unevaluatedProperties: false
+ properties:
+ playback:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ capture:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ sound@13c00000 {
+ #sound-dai-cells = <1>;
+ #clock-cells = <0>;
+ compatible = "renesas,r9a09g047-sound";
+ reg = <0x13c00000 0x10000>,
+ <0x13c20000 0x10000>,
+ <0x13c30000 0x1000>,
+ <0x13c31000 0x1f000>,
+ <0x13c50000 0x10000>;
+ reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+ clocks = <&cpg 245>,
+ <&cpg 385>, <&cpg 386>,
+ <&cpg 387>, <&cpg 388>,
+ <&cpg 389>, <&cpg 390>,
+ <&cpg 391>, <&cpg 392>,
+ <&cpg 393>, <&cpg 394>,
+ <&cpg 372>, <&cpg 373>,
+ <&cpg 374>, <&cpg 375>,
+ <&cpg 376>, <&cpg 377>,
+ <&cpg 378>, <&cpg 379>,
+ <&cpg 380>, <&cpg 381>,
+ <&cpg 370>, <&cpg 371>,
+ <&cpg 370>, <&cpg 371>,
+ <&cpg 368>, <&cpg 369>,
+ <&cpg 251>, <&cpg 252>,
+ <&cpg 253>, <&cpg 250>,
+ <&cpg 384>,
+ <&cpg 246>, <&cpg 247>,
+ <&cpg 382>,
+ <&cpg 352>, <&cpg 353>,
+ <&cpg 354>, <&cpg 355>,
+ <&cpg 356>, <&cpg 357>,
+ <&cpg 358>, <&cpg 359>,
+ <&cpg 360>, <&cpg 361>,
+ <&cpg 248>, <&cpg 249>;
+ clock-names = "ssi-all",
+ "ssi-0", "ssi-1",
+ "ssi-2", "ssi-3",
+ "ssi-4", "ssi-5",
+ "ssi-6", "ssi-7",
+ "ssi-8", "ssi-9",
+ "src-0", "src-1",
+ "src-2", "src-3",
+ "src-4", "src-5",
+ "src-6", "src-7",
+ "src-8", "src-9",
+ "mix-0", "mix-1",
+ "ctu-0", "ctu-1",
+ "dvc-0", "dvc-1",
+ "audio-clka", "audio-clkb",
+ "audio-clkc", "audio-clki",
+ "ssif_supply",
+ "scu", "scu_x2",
+ "scu_supply",
+ "adg-ssi-0", "adg-ssi-1",
+ "adg-ssi-2", "adg-ssi-3",
+ "adg-ssi-4", "adg-ssi-5",
+ "adg-ssi-6", "adg-ssi-7",
+ "adg-ssi-8", "adg-ssi-9",
+ "audmapp", "adg";
+ power-domains = <&cpg>;
+ resets = <&cpg 225>,
+ <&cpg 226>, <&cpg 227>,
+ <&cpg 228>, <&cpg 229>,
+ <&cpg 230>, <&cpg 231>,
+ <&cpg 232>, <&cpg 233>,
+ <&cpg 234>, <&cpg 235>,
+ <&cpg 236>, <&cpg 238>, <&cpg 237>;
+ reset-names = "ssi-all",
+ "ssi-0", "ssi-1",
+ "ssi-2", "ssi-3",
+ "ssi-4", "ssi-5",
+ "ssi-6", "ssi-7",
+ "ssi-8", "ssi-9",
+ "scu", "adg",
+ "audmapp";
+
+ ctu {
+ ctu-0 { };
+ ctu-1 { };
+ ctu-2 { };
+ ctu-3 { };
+ ctu-4 { };
+ ctu-5 { };
+ ctu-6 { };
+ ctu-7 { };
+ };
+
+ dvc {
+ dvc-0 {
+ dmas = <&dmac0 0x1db3>, <&dmac1 0x1db3>,
+ <&dmac2 0x1db3>, <&dmac3 0x1db3>,
+ <&dmac4 0x1db3>;
+ dma-names = "tx", "tx", "tx", "tx", "tx";
+ };
+ dvc-1 {
+ dmas = <&dmac0 0x1db4>, <&dmac1 0x1db4>,
+ <&dmac2 0x1db4>, <&dmac3 0x1db4>,
+ <&dmac4 0x1db4>;
+ dma-names = "tx", "tx", "tx", "tx", "tx";
+ };
+ };
+
+ mix {
+ mix-0 { };
+ mix-1 { };
+ };
+
+ src {
+ src-0 {
+ interrupts = <GIC_SPI 902 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac0 0x1d9f>, <&dmac0 0x1da9>,
+ <&dmac1 0x1d9f>, <&dmac1 0x1da9>,
+ <&dmac2 0x1d9f>, <&dmac2 0x1da9>,
+ <&dmac3 0x1d9f>, <&dmac3 0x1da9>,
+ <&dmac4 0x1d9f>, <&dmac4 0x1da9>;
+ dma-names = "rx", "tx", "rx", "tx", "rx", "tx",
+ "rx", "tx", "rx", "tx";
+ };
+ src-1 {
+ interrupts = <GIC_SPI 903 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac0 0x1da0>, <&dmac0 0x1daa>,
+ <&dmac1 0x1da0>, <&dmac1 0x1daa>,
+ <&dmac2 0x1da0>, <&dmac2 0x1daa>,
+ <&dmac3 0x1da0>, <&dmac3 0x1daa>,
+ <&dmac4 0x1da0>, <&dmac4 0x1daa>;
+ dma-names = "rx", "tx", "rx", "tx", "rx", "tx",
+ "rx", "tx", "rx", "tx";
+ };
+ src-2 {
+ interrupts = <GIC_SPI 904 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac0 0x1da1>, <&dmac0 0x1dab>,
+ <&dmac1 0x1da1>, <&dmac1 0x1dab>,
+ <&dmac2 0x1da1>, <&dmac2 0x1dab>,
+ <&dmac3 0x1da1>, <&dmac3 0x1dab>,
+ <&dmac4 0x1da1>, <&dmac4 0x1dab>;
+ dma-names = "rx", "tx", "rx", "tx", "rx", "tx",
+ "rx", "tx", "rx", "tx";
+ };
+ src-3 {
+ interrupts = <GIC_SPI 905 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac0 0x1da2>, <&dmac0 0x1dac>,
+ <&dmac1 0x1da2>, <&dmac1 0x1dac>,
+ <&dmac2 0x1da2>, <&dmac2 0x1dac>,
+ <&dmac3 0x1da2>, <&dmac3 0x1dac>,
+ <&dmac4 0x1da2>, <&dmac4 0x1dac>;
+ dma-names = "rx", "tx", "rx", "tx", "rx", "tx",
+ "rx", "tx", "rx", "tx";
+ };
+ src-4 {
+ interrupts = <GIC_SPI 906 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac0 0x1da3>, <&dmac0 0x1dad>,
+ <&dmac1 0x1da3>, <&dmac1 0x1dad>,
+ <&dmac2 0x1da3>, <&dmac2 0x1dad>,
+ <&dmac3 0x1da3>, <&dmac3 0x1dad>,
+ <&dmac4 0x1da3>, <&dmac4 0x1dad>;
+ dma-names = "rx", "tx", "rx", "tx", "rx", "tx",
+ "rx", "tx", "rx", "tx";
+ };
+ src-5 {
+ interrupts = <GIC_SPI 907 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac0 0x1da4>, <&dmac0 0x1dae>,
+ <&dmac1 0x1da4>, <&dmac1 0x1dae>,
+ <&dmac2 0x1da4>, <&dmac2 0x1dae>,
+ <&dmac3 0x1da4>, <&dmac3 0x1dae>,
+ <&dmac4 0x1da4>, <&dmac4 0x1dae>;
+ dma-names = "rx", "tx", "rx", "tx", "rx", "tx",
+ "rx", "tx", "rx", "tx";
+ };
+ src-6 {
+ interrupts = <GIC_SPI 908 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac0 0x1da5>, <&dmac0 0x1daf>,
+ <&dmac1 0x1da5>, <&dmac1 0x1daf>,
+ <&dmac2 0x1da5>, <&dmac2 0x1daf>,
+ <&dmac3 0x1da5>, <&dmac3 0x1daf>,
+ <&dmac4 0x1da5>, <&dmac4 0x1daf>;
+ dma-names = "rx", "tx", "rx", "tx", "rx", "tx",
+ "rx", "tx", "rx", "tx";
+ };
+ src-7 {
+ interrupts = <GIC_SPI 909 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac0 0x1da6>, <&dmac0 0x1db0>,
+ <&dmac1 0x1da6>, <&dmac1 0x1db0>,
+ <&dmac2 0x1da6>, <&dmac2 0x1db0>,
+ <&dmac3 0x1da6>, <&dmac3 0x1db0>,
+ <&dmac4 0x1da6>, <&dmac4 0x1db0>;
+ dma-names = "rx", "tx", "rx", "tx", "rx", "tx",
+ "rx", "tx", "rx", "tx";
+ };
+ src-8 {
+ interrupts = <GIC_SPI 910 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac0 0x1da7>, <&dmac0 0x1db1>,
+ <&dmac1 0x1da7>, <&dmac1 0x1db1>,
+ <&dmac2 0x1da7>, <&dmac2 0x1db1>,
+ <&dmac3 0x1da7>, <&dmac3 0x1db1>,
+ <&dmac4 0x1da7>, <&dmac4 0x1db1>;
+ dma-names = "rx", "tx", "rx", "tx", "rx", "tx",
+ "rx", "tx", "rx", "tx";
+ };
+ src-9 {
+ interrupts = <GIC_SPI 911 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmac0 0x1da8>, <&dmac0 0x1db2>,
+ <&dmac1 0x1da8>, <&dmac1 0x1db2>,
+ <&dmac2 0x1da8>, <&dmac2 0x1db2>,
+ <&dmac3 0x1da8>, <&dmac3 0x1db2>,
+ <&dmac4 0x1da8>, <&dmac4 0x1db2>;
+ dma-names = "rx", "tx", "rx", "tx", "rx", "tx",
+ "rx", "tx", "rx", "tx";
+ };
+ };
+
+ ssi {
+ ssi-0 {
+ interrupts = <GIC_SPI 889 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ ssi-1 {
+ interrupts = <GIC_SPI 890 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ ssi-2 {
+ interrupts = <GIC_SPI 891 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ ssi-3 {
+ interrupts = <GIC_SPI 892 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ ssi-4 {
+ interrupts = <GIC_SPI 893 IRQ_TYPE_LEVEL_HIGH>;
+ shared-pin;
+ };
+ ssi-5 {
+ interrupts = <GIC_SPI 894 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ ssi-6 {
+ interrupts = <GIC_SPI 895 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ ssi-7 {
+ interrupts = <GIC_SPI 896 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ ssi-8 {
+ interrupts = <GIC_SPI 897 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ ssi-9 {
+ interrupts = <GIC_SPI 898 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ ssiu {
+ ssiu-0 {
+ dmas = <&dmac0 0x1d61>, <&dmac0 0x1d62>,
+ <&dmac1 0x1d61>, <&dmac1 0x1d62>,
+ <&dmac2 0x1d61>, <&dmac2 0x1d62>,
+ <&dmac3 0x1d61>, <&dmac3 0x1d62>,
+ <&dmac4 0x1d61>, <&dmac4 0x1d62>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-1 {
+ dmas = <&dmac0 0x1d63>, <&dmac0 0x1d64>,
+ <&dmac1 0x1d63>, <&dmac1 0x1d64>,
+ <&dmac2 0x1d63>, <&dmac2 0x1d64>,
+ <&dmac3 0x1d63>, <&dmac3 0x1d64>,
+ <&dmac4 0x1d63>, <&dmac4 0x1d64>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-2 {
+ dmas = <&dmac0 0x1d65>, <&dmac0 0x1d66>,
+ <&dmac1 0x1d65>, <&dmac1 0x1d66>,
+ <&dmac2 0x1d65>, <&dmac2 0x1d66>,
+ <&dmac3 0x1d65>, <&dmac3 0x1d66>,
+ <&dmac4 0x1d65>, <&dmac4 0x1d66>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-3 {
+ dmas = <&dmac0 0x1d67>, <&dmac0 0x1d68>,
+ <&dmac1 0x1d67>, <&dmac1 0x1d68>,
+ <&dmac2 0x1d67>, <&dmac2 0x1d68>,
+ <&dmac3 0x1d67>, <&dmac3 0x1d68>,
+ <&dmac4 0x1d67>, <&dmac4 0x1d68>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-4 {
+ dmas = <&dmac0 0x1d69>, <&dmac0 0x1d6a>,
+ <&dmac1 0x1d69>, <&dmac1 0x1d6a>,
+ <&dmac2 0x1d69>, <&dmac2 0x1d6a>,
+ <&dmac3 0x1d69>, <&dmac3 0x1d6a>,
+ <&dmac4 0x1d69>, <&dmac4 0x1d6a>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-5 {
+ dmas = <&dmac0 0x1d6b>, <&dmac0 0x1d6c>,
+ <&dmac1 0x1d6b>, <&dmac1 0x1d6c>,
+ <&dmac2 0x1d6b>, <&dmac2 0x1d6c>,
+ <&dmac3 0x1d6b>, <&dmac3 0x1d6c>,
+ <&dmac4 0x1d6b>, <&dmac4 0x1d6c>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-6 {
+ dmas = <&dmac0 0x1d6d>, <&dmac0 0x1d6e>,
+ <&dmac1 0x1d6d>, <&dmac1 0x1d6e>,
+ <&dmac2 0x1d6d>, <&dmac2 0x1d6e>,
+ <&dmac3 0x1d6d>, <&dmac3 0x1d6e>,
+ <&dmac4 0x1d6d>, <&dmac4 0x1d6e>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-7 {
+ dmas = <&dmac0 0x1d6f>, <&dmac0 0x1d70>,
+ <&dmac1 0x1d6f>, <&dmac1 0x1d70>,
+ <&dmac2 0x1d6f>, <&dmac2 0x1d70>,
+ <&dmac3 0x1d6f>, <&dmac3 0x1d70>,
+ <&dmac4 0x1d6f>, <&dmac4 0x1d70>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-8 {
+ dmas = <&dmac0 0x1d71>, <&dmac0 0x1d72>,
+ <&dmac1 0x1d71>, <&dmac1 0x1d72>,
+ <&dmac2 0x1d71>, <&dmac2 0x1d72>,
+ <&dmac3 0x1d71>, <&dmac3 0x1d72>,
+ <&dmac4 0x1d71>, <&dmac4 0x1d72>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-9 {
+ dmas = <&dmac0 0x1d73>, <&dmac0 0x1d74>,
+ <&dmac1 0x1d73>, <&dmac1 0x1d74>,
+ <&dmac2 0x1d73>, <&dmac2 0x1d74>,
+ <&dmac3 0x1d73>, <&dmac3 0x1d74>,
+ <&dmac4 0x1d73>, <&dmac4 0x1d74>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-10 {
+ dmas = <&dmac0 0x1d75>, <&dmac0 0x1d76>,
+ <&dmac1 0x1d75>, <&dmac1 0x1d76>,
+ <&dmac2 0x1d75>, <&dmac2 0x1d76>,
+ <&dmac3 0x1d75>, <&dmac3 0x1d76>,
+ <&dmac4 0x1d75>, <&dmac4 0x1d76>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-11 {
+ dmas = <&dmac0 0x1d77>, <&dmac0 0x1d78>,
+ <&dmac1 0x1d77>, <&dmac1 0x1d78>,
+ <&dmac2 0x1d77>, <&dmac2 0x1d78>,
+ <&dmac3 0x1d77>, <&dmac3 0x1d78>,
+ <&dmac4 0x1d77>, <&dmac4 0x1d78>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-12 {
+ dmas = <&dmac0 0x1d79>, <&dmac0 0x1d7a>,
+ <&dmac1 0x1d79>, <&dmac1 0x1d7a>,
+ <&dmac2 0x1d79>, <&dmac2 0x1d7a>,
+ <&dmac3 0x1d79>, <&dmac3 0x1d7a>,
+ <&dmac4 0x1d79>, <&dmac4 0x1d7a>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-13 {
+ dmas = <&dmac0 0x1d7b>, <&dmac0 0x1d7c>,
+ <&dmac1 0x1d7b>, <&dmac1 0x1d7c>,
+ <&dmac2 0x1d7b>, <&dmac2 0x1d7c>,
+ <&dmac3 0x1d7b>, <&dmac3 0x1d7c>,
+ <&dmac4 0x1d7b>, <&dmac4 0x1d7c>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-14 {
+ dmas = <&dmac0 0x1d7d>, <&dmac0 0x1d7e>,
+ <&dmac1 0x1d7d>, <&dmac1 0x1d7e>,
+ <&dmac2 0x1d7d>, <&dmac2 0x1d7e>,
+ <&dmac3 0x1d7d>, <&dmac3 0x1d7e>,
+ <&dmac4 0x1d7d>, <&dmac4 0x1d7e>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-15 {
+ dmas = <&dmac0 0x1d7f>, <&dmac0 0x1d80>,
+ <&dmac1 0x1d7f>, <&dmac1 0x1d80>,
+ <&dmac2 0x1d7f>, <&dmac2 0x1d80>,
+ <&dmac3 0x1d7f>, <&dmac3 0x1d80>,
+ <&dmac4 0x1d7f>, <&dmac4 0x1d80>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-16 {
+ dmas = <&dmac0 0x1d81>, <&dmac0 0x1d82>,
+ <&dmac1 0x1d81>, <&dmac1 0x1d82>,
+ <&dmac2 0x1d81>, <&dmac2 0x1d82>,
+ <&dmac3 0x1d81>, <&dmac3 0x1d82>,
+ <&dmac4 0x1d81>, <&dmac4 0x1d82>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-17 {
+ dmas = <&dmac0 0x1d83>, <&dmac0 0x1d84>,
+ <&dmac1 0x1d83>, <&dmac1 0x1d84>,
+ <&dmac2 0x1d83>, <&dmac2 0x1d84>,
+ <&dmac3 0x1d83>, <&dmac3 0x1d84>,
+ <&dmac4 0x1d83>, <&dmac4 0x1d84>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-18 {
+ dmas = <&dmac0 0x1d85>, <&dmac0 0x1d86>,
+ <&dmac1 0x1d85>, <&dmac1 0x1d86>,
+ <&dmac2 0x1d85>, <&dmac2 0x1d86>,
+ <&dmac3 0x1d85>, <&dmac3 0x1d86>,
+ <&dmac4 0x1d85>, <&dmac4 0x1d86>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-19 {
+ dmas = <&dmac0 0x1d87>, <&dmac0 0x1d88>,
+ <&dmac1 0x1d87>, <&dmac1 0x1d88>,
+ <&dmac2 0x1d87>, <&dmac2 0x1d88>,
+ <&dmac3 0x1d87>, <&dmac3 0x1d88>,
+ <&dmac4 0x1d87>, <&dmac4 0x1d88>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-20 {
+ dmas = <&dmac0 0x1d89>, <&dmac0 0x1d8a>,
+ <&dmac1 0x1d89>, <&dmac1 0x1d8a>,
+ <&dmac2 0x1d89>, <&dmac2 0x1d8a>,
+ <&dmac3 0x1d89>, <&dmac3 0x1d8a>,
+ <&dmac4 0x1d89>, <&dmac4 0x1d8a>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-21 {
+ dmas = <&dmac0 0x1d8b>, <&dmac0 0x1d8c>,
+ <&dmac1 0x1d8b>, <&dmac1 0x1d8c>,
+ <&dmac2 0x1d8b>, <&dmac2 0x1d8c>,
+ <&dmac3 0x1d8b>, <&dmac3 0x1d8c>,
+ <&dmac4 0x1d8b>, <&dmac4 0x1d8c>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-22 {
+ dmas = <&dmac0 0x1d8d>, <&dmac0 0x1d8e>,
+ <&dmac1 0x1d8d>, <&dmac1 0x1d8e>,
+ <&dmac2 0x1d8d>, <&dmac2 0x1d8e>,
+ <&dmac3 0x1d8d>, <&dmac3 0x1d8e>,
+ <&dmac4 0x1d8d>, <&dmac4 0x1d8e>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-23 {
+ dmas = <&dmac0 0x1d8f>, <&dmac0 0x1d90>,
+ <&dmac1 0x1d8f>, <&dmac1 0x1d90>,
+ <&dmac2 0x1d8f>, <&dmac2 0x1d90>,
+ <&dmac3 0x1d8f>, <&dmac3 0x1d90>,
+ <&dmac4 0x1d8f>, <&dmac4 0x1d90>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-24 {
+ dmas = <&dmac0 0x1d91>, <&dmac0 0x1d92>,
+ <&dmac1 0x1d91>, <&dmac1 0x1d92>,
+ <&dmac2 0x1d91>, <&dmac2 0x1d92>,
+ <&dmac3 0x1d91>, <&dmac3 0x1d92>,
+ <&dmac4 0x1d91>, <&dmac4 0x1d92>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-25 {
+ dmas = <&dmac0 0x1d93>, <&dmac0 0x1d94>,
+ <&dmac1 0x1d93>, <&dmac1 0x1d94>,
+ <&dmac2 0x1d93>, <&dmac2 0x1d94>,
+ <&dmac3 0x1d93>, <&dmac3 0x1d94>,
+ <&dmac4 0x1d93>, <&dmac4 0x1d94>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-26 {
+ dmas = <&dmac0 0x1d95>, <&dmac0 0x1d96>,
+ <&dmac1 0x1d95>, <&dmac1 0x1d96>,
+ <&dmac2 0x1d95>, <&dmac2 0x1d96>,
+ <&dmac3 0x1d95>, <&dmac3 0x1d96>,
+ <&dmac4 0x1d95>, <&dmac4 0x1d96>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ ssiu-27 {
+ dmas = <&dmac0 0x1d97>, <&dmac0 0x1d98>,
+ <&dmac1 0x1d97>, <&dmac1 0x1d98>,
+ <&dmac2 0x1d97>, <&dmac2 0x1d98>,
+ <&dmac3 0x1d97>, <&dmac3 0x1d98>,
+ <&dmac4 0x1d97>, <&dmac4 0x1d98>;
+ dma-names = "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx", "tx", "rx";
+ };
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ rsnd_endpoint0: endpoint {
+ remote-endpoint = <&codec_endpoint>;
+ dai-format = "i2s";
+ bitclock-master = <&rsnd_endpoint0>;
+ frame-master = <&rsnd_endpoint0>;
+ playback = <&ssi3>, <&src1>, <&dvc1>;
+ capture = <&ssi4>, <&src0>, <&dvc0>;
+ };
+ };
+ };
+ };
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 02/16] ASoC: rsnd: Fix RSND_SOC_MASK width to single nibble
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
2026-05-12 18:26 ` [PATCH v6 01/16] ASoC: dt-bindings: sound: Add DT binding for RZ/G3E sound John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 03/16] ASoC: rsnd: Add reset controller support to rsnd_mod John Madieu
` (13 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
RSND_SOC_MASK was defined as (0xFF << 4), spanning bits 4-11. This is
wider than needed since only nibble B (bits 7:4) is used for SoC
identifiers. Narrow it to (0xF << 4) to match the intended single-nibble
allocation and prevent overlap with bits 8-11 which will be used by
upcoming RZ series flags.
No functional change, since the only current user (RSND_SOC_E) fits
within a single nibble.
Fixes: ba164a49f8f7 ("ASoC: rsnd: src: Avoid a potential deadlock")
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6: No changes
v5:
- New patch. Extracted as a standalone bug-fix patch per
Kuninori's request (previously embedded in patch 04/12 of v4).
- Add Fixes: tag referencing the commit that introduced the mask.
sound/soc/renesas/rcar/rsnd.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/renesas/rcar/rsnd.h b/sound/soc/renesas/rcar/rsnd.h
index 04c70690f7a2..3e666125959b 100644
--- a/sound/soc/renesas/rcar/rsnd.h
+++ b/sound/soc/renesas/rcar/rsnd.h
@@ -624,7 +624,7 @@ struct rsnd_priv {
#define RSND_GEN2 (2 << 0)
#define RSND_GEN3 (3 << 0)
#define RSND_GEN4 (4 << 0)
-#define RSND_SOC_MASK (0xFF << 4)
+#define RSND_SOC_MASK (0xF << 4)
#define RSND_SOC_E (1 << 4) /* E1/E2/E3 */
/*
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 03/16] ASoC: rsnd: Add reset controller support to rsnd_mod
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
2026-05-12 18:26 ` [PATCH v6 01/16] ASoC: dt-bindings: sound: Add DT binding for RZ/G3E sound John Madieu
2026-05-12 18:26 ` [PATCH v6 02/16] ASoC: rsnd: Fix RSND_SOC_MASK width to single nibble John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 04/16] ASoC: rsnd: Support hyphen or dot in indexed clock and reset names John Madieu
` (12 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
The RZ/G3E SoC requires per-module reset control for the audio subsystem.
Add reset controller support to struct rsnd_mod and update rsnd_mod_init()
to accept and handle a reset_control parameter and mirror it in
rsnd_mod_quit().
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6: No changes
v5: No changes
v4:
- Add reset_control_assert() in rsnd_mod_quit() for symmetry with
deassert in rsnd_mod_init().
v3: No changes
v2: No changes
sound/soc/renesas/rcar/adg.c | 2 +-
sound/soc/renesas/rcar/cmd.c | 2 +-
sound/soc/renesas/rcar/core.c | 16 +++++++++++++++-
sound/soc/renesas/rcar/ctu.c | 2 +-
sound/soc/renesas/rcar/dma.c | 4 ++--
sound/soc/renesas/rcar/dvc.c | 2 +-
sound/soc/renesas/rcar/mix.c | 2 +-
sound/soc/renesas/rcar/rsnd.h | 3 +++
sound/soc/renesas/rcar/src.c | 2 +-
sound/soc/renesas/rcar/ssi.c | 2 +-
sound/soc/renesas/rcar/ssiu.c | 2 +-
11 files changed, 28 insertions(+), 11 deletions(-)
diff --git a/sound/soc/renesas/rcar/adg.c b/sound/soc/renesas/rcar/adg.c
index 8641b73d1f77..0105c60a144e 100644
--- a/sound/soc/renesas/rcar/adg.c
+++ b/sound/soc/renesas/rcar/adg.c
@@ -780,7 +780,7 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
return -ENOMEM;
ret = rsnd_mod_init(priv, &adg->mod, &adg_ops,
- NULL, 0, 0);
+ NULL, NULL, 0, 0);
if (ret)
return ret;
diff --git a/sound/soc/renesas/rcar/cmd.c b/sound/soc/renesas/rcar/cmd.c
index 8d9a1e345a22..13beef389797 100644
--- a/sound/soc/renesas/rcar/cmd.c
+++ b/sound/soc/renesas/rcar/cmd.c
@@ -171,7 +171,7 @@ int rsnd_cmd_probe(struct rsnd_priv *priv)
for_each_rsnd_cmd(cmd, priv, i) {
int ret = rsnd_mod_init(priv, rsnd_mod_get(cmd),
- &rsnd_cmd_ops, NULL,
+ &rsnd_cmd_ops, NULL, NULL,
RSND_MOD_CMD, i);
if (ret)
return ret;
diff --git a/sound/soc/renesas/rcar/core.c b/sound/soc/renesas/rcar/core.c
index 2dc078358612..c3c139a6fc60 100644
--- a/sound/soc/renesas/rcar/core.c
+++ b/sound/soc/renesas/rcar/core.c
@@ -90,6 +90,7 @@
*
*/
+#include <linux/delay.h>
#include <linux/pm_runtime.h>
#include <linux/of_graph.h>
#include "rsnd.h"
@@ -196,18 +197,29 @@ int rsnd_mod_init(struct rsnd_priv *priv,
struct rsnd_mod *mod,
struct rsnd_mod_ops *ops,
struct clk *clk,
+ struct reset_control *rstc,
enum rsnd_mod_type type,
int id)
{
- int ret = clk_prepare(clk);
+ int ret;
+ ret = clk_prepare_enable(clk);
if (ret)
return ret;
+ ret = reset_control_deassert(rstc);
+ if (ret) {
+ clk_disable_unprepare(clk);
+ return ret;
+ }
+
+ clk_disable(clk);
+
mod->id = id;
mod->ops = ops;
mod->type = type;
mod->clk = clk;
+ mod->rstc = rstc;
mod->priv = priv;
return 0;
@@ -217,6 +229,8 @@ void rsnd_mod_quit(struct rsnd_mod *mod)
{
clk_unprepare(mod->clk);
mod->clk = NULL;
+ reset_control_assert(mod->rstc);
+ mod->rstc = NULL;
}
void rsnd_mod_interrupt(struct rsnd_mod *mod,
diff --git a/sound/soc/renesas/rcar/ctu.c b/sound/soc/renesas/rcar/ctu.c
index bd4c61f9fb3c..81bba6a1af6e 100644
--- a/sound/soc/renesas/rcar/ctu.c
+++ b/sound/soc/renesas/rcar/ctu.c
@@ -360,7 +360,7 @@ int rsnd_ctu_probe(struct rsnd_priv *priv)
}
ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops,
- clk, RSND_MOD_CTU, i);
+ clk, NULL, RSND_MOD_CTU, i);
if (ret)
goto rsnd_ctu_probe_done;
diff --git a/sound/soc/renesas/rcar/dma.c b/sound/soc/renesas/rcar/dma.c
index 2035ce06fe4c..68c859897e68 100644
--- a/sound/soc/renesas/rcar/dma.c
+++ b/sound/soc/renesas/rcar/dma.c
@@ -803,7 +803,7 @@ static int rsnd_dma_alloc(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
*dma_mod = rsnd_mod_get(dma);
- ret = rsnd_mod_init(priv, *dma_mod, ops, NULL,
+ ret = rsnd_mod_init(priv, *dma_mod, ops, NULL, NULL,
type, dma_id);
if (ret < 0)
return ret;
@@ -879,5 +879,5 @@ int rsnd_dma_probe(struct rsnd_priv *priv)
priv->dma = dmac;
/* dummy mem mod for debug */
- return rsnd_mod_init(NULL, &mem, &mem_ops, NULL, 0, 0);
+ return rsnd_mod_init(NULL, &mem, &mem_ops, NULL, NULL, 0, 0);
}
diff --git a/sound/soc/renesas/rcar/dvc.c b/sound/soc/renesas/rcar/dvc.c
index 988cbddbc611..bf7146ceb5f6 100644
--- a/sound/soc/renesas/rcar/dvc.c
+++ b/sound/soc/renesas/rcar/dvc.c
@@ -364,7 +364,7 @@ int rsnd_dvc_probe(struct rsnd_priv *priv)
}
ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
- clk, RSND_MOD_DVC, i);
+ clk, NULL, RSND_MOD_DVC, i);
if (ret)
goto rsnd_dvc_probe_done;
diff --git a/sound/soc/renesas/rcar/mix.c b/sound/soc/renesas/rcar/mix.c
index aea74e703305..566e9b2a488c 100644
--- a/sound/soc/renesas/rcar/mix.c
+++ b/sound/soc/renesas/rcar/mix.c
@@ -328,7 +328,7 @@ int rsnd_mix_probe(struct rsnd_priv *priv)
}
ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops,
- clk, RSND_MOD_MIX, i);
+ clk, NULL, RSND_MOD_MIX, i);
if (ret)
goto rsnd_mix_probe_done;
diff --git a/sound/soc/renesas/rcar/rsnd.h b/sound/soc/renesas/rcar/rsnd.h
index 3e666125959b..3d419b31cf40 100644
--- a/sound/soc/renesas/rcar/rsnd.h
+++ b/sound/soc/renesas/rcar/rsnd.h
@@ -15,6 +15,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/reset.h>
#include <linux/sh_dma.h>
#include <linux/workqueue.h>
#include <sound/soc.h>
@@ -353,6 +354,7 @@ struct rsnd_mod {
struct rsnd_mod_ops *ops;
struct rsnd_priv *priv;
struct clk *clk;
+ struct reset_control *rstc;
u32 status;
};
/*
@@ -420,6 +422,7 @@ int rsnd_mod_init(struct rsnd_priv *priv,
struct rsnd_mod *mod,
struct rsnd_mod_ops *ops,
struct clk *clk,
+ struct reset_control *rstc,
enum rsnd_mod_type type,
int id);
void rsnd_mod_quit(struct rsnd_mod *mod);
diff --git a/sound/soc/renesas/rcar/src.c b/sound/soc/renesas/rcar/src.c
index 6a3dbc84f474..8b58cc20e7a8 100644
--- a/sound/soc/renesas/rcar/src.c
+++ b/sound/soc/renesas/rcar/src.c
@@ -766,7 +766,7 @@ int rsnd_src_probe(struct rsnd_priv *priv)
}
ret = rsnd_mod_init(priv, rsnd_mod_get(src),
- &rsnd_src_ops, clk, RSND_MOD_SRC, i);
+ &rsnd_src_ops, clk, NULL, RSND_MOD_SRC, i);
if (ret)
goto rsnd_src_probe_done;
diff --git a/sound/soc/renesas/rcar/ssi.c b/sound/soc/renesas/rcar/ssi.c
index 0420041e282c..c06cebb36170 100644
--- a/sound/soc/renesas/rcar/ssi.c
+++ b/sound/soc/renesas/rcar/ssi.c
@@ -1225,7 +1225,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
ops = &rsnd_ssi_dma_ops;
ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk,
- RSND_MOD_SSI, i);
+ NULL, RSND_MOD_SSI, i);
if (ret)
goto rsnd_ssi_probe_done;
diff --git a/sound/soc/renesas/rcar/ssiu.c b/sound/soc/renesas/rcar/ssiu.c
index 244fb833292a..0cfa84fe5ea8 100644
--- a/sound/soc/renesas/rcar/ssiu.c
+++ b/sound/soc/renesas/rcar/ssiu.c
@@ -586,7 +586,7 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)
}
ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu),
- ops, NULL, RSND_MOD_SSIU, i);
+ ops, NULL, NULL, RSND_MOD_SSIU, i);
if (ret)
return ret;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 04/16] ASoC: rsnd: Support hyphen or dot in indexed clock and reset names
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
` (2 preceding siblings ...)
2026-05-12 18:26 ` [PATCH v6 03/16] ASoC: rsnd: Add reset controller support to rsnd_mod John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 05/16] ASoC: rsnd: Add RZ/G3E SoC probing and register map John Madieu
` (11 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
The rsnd driver historically looks up per-instance clocks and resets
using dot-separated names matching the ones declared in R-Car device
tree bindings ("ssi.0", "src.0", "adg.ssi.0", ...). The dot separator
is unusual for device tree clock-names / reset-names and newer
Renesas SoC bindings (RZ/G3E and later) use the more standard hyphen
form ("ssi-0", "src-0", ...).
Rather than force every existing R-Car user to rename their DT entries,
add a small set of helpers that try the hyphen form first and fall
back to the dot form. While at it, convert the existing indexed
devm_clk_get() call sites in the SSI, SRC, CTU, DVC and MIX probes to use
the new helpers and drop the now unused per-module name buffers and
NAME_SIZE defines.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6: New patch
sound/soc/renesas/rcar/core.c | 67 +++++++++++++++++++++++++++++++++++
sound/soc/renesas/rcar/ctu.c | 7 +---
sound/soc/renesas/rcar/dvc.c | 7 +---
sound/soc/renesas/rcar/mix.c | 7 +---
sound/soc/renesas/rcar/rsnd.h | 19 ++++++++++
sound/soc/renesas/rcar/src.c | 7 +---
sound/soc/renesas/rcar/ssi.c | 7 +---
7 files changed, 91 insertions(+), 30 deletions(-)
diff --git a/sound/soc/renesas/rcar/core.c b/sound/soc/renesas/rcar/core.c
index c3c139a6fc60..5f3841565d49 100644
--- a/sound/soc/renesas/rcar/core.c
+++ b/sound/soc/renesas/rcar/core.c
@@ -1233,6 +1233,73 @@ int rsnd_node_count(struct rsnd_priv *priv, struct device_node *node, char *name
return i;
}
+/*
+ * Build "<base>-<index>" or "<base>.<index>" and try the hyphen form first,
+ * falling back to the dot form if the hyphen form is not present. This lets
+ * the driver accept both the new DT convention ("ssi-0", "src-0", ...) and
+ * the legacy R-Car convention ("ssi.0", "src.0", ...) transparently.
+ *
+ * @base: name prefix ("ssi", "src", "ctu", "mix", "dvc", "adg.ssi", ...)
+ * @index: integer suffix
+ *
+ * On ENODEV from the hyphen form, the dot form is tried. All other errors
+ * (including -EPROBE_DEFER) are returned to the caller unchanged, so
+ * behaviour against the clock and reset frameworks is preserved.
+ */
+#define RSND_INDEXED_NAME_MAX 32
+
+static void rsnd_format_indexed_name(char *buf, size_t buflen, char sep,
+ const char *base, int index)
+{
+ snprintf(buf, buflen, "%s%c%d", base, sep, index);
+}
+
+struct clk *rsnd_devm_clk_get_indexed(struct device *dev,
+ const char *base, int index)
+{
+ char name[RSND_INDEXED_NAME_MAX];
+ struct clk *clk;
+
+ rsnd_format_indexed_name(name, sizeof(name), '-', base, index);
+ clk = devm_clk_get(dev, name);
+ if (!IS_ERR(clk) || PTR_ERR(clk) != -ENOENT)
+ return clk;
+
+ rsnd_format_indexed_name(name, sizeof(name), '.', base, index);
+ return devm_clk_get(dev, name);
+}
+
+struct clk *rsnd_devm_clk_get_optional_indexed(struct device *dev,
+ const char *base, int index)
+{
+ char name[RSND_INDEXED_NAME_MAX];
+ struct clk *clk;
+
+ rsnd_format_indexed_name(name, sizeof(name), '-', base, index);
+ clk = devm_clk_get_optional(dev, name);
+ if (IS_ERR(clk) || clk)
+ return clk;
+
+ rsnd_format_indexed_name(name, sizeof(name), '.', base, index);
+ return devm_clk_get_optional(dev, name);
+}
+
+struct reset_control *
+rsnd_devm_reset_control_get_optional_indexed(struct device *dev,
+ const char *base, int index)
+{
+ char name[RSND_INDEXED_NAME_MAX];
+ struct reset_control *rstc;
+
+ rsnd_format_indexed_name(name, sizeof(name), '-', base, index);
+ rstc = devm_reset_control_get_optional(dev, name);
+ if (IS_ERR(rstc) || rstc)
+ return rstc;
+
+ rsnd_format_indexed_name(name, sizeof(name), '.', base, index);
+ return devm_reset_control_get_optional(dev, name);
+}
+
static struct device_node*
rsnd_pick_endpoint_node_for_ports(struct device_node *e_ports,
struct device_node *e_port)
diff --git a/sound/soc/renesas/rcar/ctu.c b/sound/soc/renesas/rcar/ctu.c
index 81bba6a1af6e..293b0eec1ded 100644
--- a/sound/soc/renesas/rcar/ctu.c
+++ b/sound/soc/renesas/rcar/ctu.c
@@ -6,7 +6,6 @@
#include "rsnd.h"
-#define CTU_NAME_SIZE 16
#define CTU_NAME "ctu"
/*
@@ -319,7 +318,6 @@ int rsnd_ctu_probe(struct rsnd_priv *priv)
struct device *dev = rsnd_priv_to_dev(priv);
struct rsnd_ctu *ctu;
struct clk *clk;
- char name[CTU_NAME_SIZE];
int i, nr, ret;
node = rsnd_ctu_of_node(priv);
@@ -350,10 +348,7 @@ int rsnd_ctu_probe(struct rsnd_priv *priv)
* CTU00, CTU01, CTU02, CTU03 => CTU0
* CTU10, CTU11, CTU12, CTU13 => CTU1
*/
- snprintf(name, CTU_NAME_SIZE, "%s.%d",
- CTU_NAME, i / 4);
-
- clk = devm_clk_get(dev, name);
+ clk = rsnd_devm_clk_get_indexed(dev, CTU_NAME, i / 4);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
goto rsnd_ctu_probe_done;
diff --git a/sound/soc/renesas/rcar/dvc.c b/sound/soc/renesas/rcar/dvc.c
index bf7146ceb5f6..26f80d542da8 100644
--- a/sound/soc/renesas/rcar/dvc.c
+++ b/sound/soc/renesas/rcar/dvc.c
@@ -29,7 +29,6 @@
#include "rsnd.h"
-#define RSND_DVC_NAME_SIZE 16
#define DVC_NAME "dvc"
@@ -327,7 +326,6 @@ int rsnd_dvc_probe(struct rsnd_priv *priv)
struct device *dev = rsnd_priv_to_dev(priv);
struct rsnd_dvc *dvc;
struct clk *clk;
- char name[RSND_DVC_NAME_SIZE];
int i, nr, ret;
node = rsnd_dvc_of_node(priv);
@@ -354,10 +352,7 @@ int rsnd_dvc_probe(struct rsnd_priv *priv)
for_each_child_of_node_scoped(node, np) {
dvc = rsnd_dvc_get(priv, i);
- snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d",
- DVC_NAME, i);
-
- clk = devm_clk_get(dev, name);
+ clk = rsnd_devm_clk_get_indexed(dev, DVC_NAME, i);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
goto rsnd_dvc_probe_done;
diff --git a/sound/soc/renesas/rcar/mix.c b/sound/soc/renesas/rcar/mix.c
index 566e9b2a488c..9ffa591aa4a4 100644
--- a/sound/soc/renesas/rcar/mix.c
+++ b/sound/soc/renesas/rcar/mix.c
@@ -32,7 +32,6 @@
#include "rsnd.h"
-#define MIX_NAME_SIZE 16
#define MIX_NAME "mix"
struct rsnd_mix {
@@ -291,7 +290,6 @@ int rsnd_mix_probe(struct rsnd_priv *priv)
struct device *dev = rsnd_priv_to_dev(priv);
struct rsnd_mix *mix;
struct clk *clk;
- char name[MIX_NAME_SIZE];
int i, nr, ret;
node = rsnd_mix_of_node(priv);
@@ -318,10 +316,7 @@ int rsnd_mix_probe(struct rsnd_priv *priv)
for_each_child_of_node_scoped(node, np) {
mix = rsnd_mix_get(priv, i);
- snprintf(name, MIX_NAME_SIZE, "%s.%d",
- MIX_NAME, i);
-
- clk = devm_clk_get(dev, name);
+ clk = rsnd_devm_clk_get_indexed(dev, MIX_NAME, i);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
goto rsnd_mix_probe_done;
diff --git a/sound/soc/renesas/rcar/rsnd.h b/sound/soc/renesas/rcar/rsnd.h
index 3d419b31cf40..f3f1ad1180f8 100644
--- a/sound/soc/renesas/rcar/rsnd.h
+++ b/sound/soc/renesas/rcar/rsnd.h
@@ -476,6 +476,25 @@ int rsnd_runtime_is_multi_ssi(struct rsnd_dai_stream *io);
int rsnd_runtime_is_tdm(struct rsnd_dai_stream *io);
int rsnd_runtime_is_tdm_split(struct rsnd_dai_stream *io);
+/*
+ * Indexed clock and reset name helpers.
+ *
+ * Historically the rsnd driver has looked up per-instance clocks and
+ * resets using dot-separated names (e.g. "ssi.0", "src.0", "adg.ssi.0").
+ * Newer Renesas SoC bindings (RZ/G3E and later) use hyphen-separated
+ * names ("ssi-0", "src-0", ...) to follow the standard Device Tree
+ * naming convention. These helpers look up the hyphenated name first
+ * and transparently fall back to the dotted name, so a single driver
+ * build supports both conventions.
+ */
+struct clk *rsnd_devm_clk_get_indexed(struct device *dev,
+ const char *base, int index);
+struct clk *rsnd_devm_clk_get_optional_indexed(struct device *dev,
+ const char *base, int index);
+struct reset_control *
+rsnd_devm_reset_control_get_optional_indexed(struct device *dev,
+ const char *base, int index);
+
/*
* DT
*/
diff --git a/sound/soc/renesas/rcar/src.c b/sound/soc/renesas/rcar/src.c
index 8b58cc20e7a8..43abe13137bf 100644
--- a/sound/soc/renesas/rcar/src.c
+++ b/sound/soc/renesas/rcar/src.c
@@ -39,7 +39,6 @@ struct rsnd_src {
int irq;
};
-#define RSND_SRC_NAME_SIZE 16
#define rsnd_src_get(priv, id) ((struct rsnd_src *)(priv->src) + id)
#define rsnd_src_nr(priv) ((priv)->src_nr)
@@ -715,7 +714,6 @@ int rsnd_src_probe(struct rsnd_priv *priv)
struct device *dev = rsnd_priv_to_dev(priv);
struct rsnd_src *src;
struct clk *clk;
- char name[RSND_SRC_NAME_SIZE];
int i, nr, ret;
node = rsnd_src_of_node(priv);
@@ -750,16 +748,13 @@ int rsnd_src_probe(struct rsnd_priv *priv)
src = rsnd_src_get(priv, i);
- snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d",
- SRC_NAME, i);
-
src->irq = irq_of_parse_and_map(np, 0);
if (!src->irq) {
ret = -EINVAL;
goto rsnd_src_probe_done;
}
- clk = devm_clk_get(dev, name);
+ clk = rsnd_devm_clk_get_indexed(dev, SRC_NAME, i);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
goto rsnd_src_probe_done;
diff --git a/sound/soc/renesas/rcar/ssi.c b/sound/soc/renesas/rcar/ssi.c
index c06cebb36170..cf98cc9ee44c 100644
--- a/sound/soc/renesas/rcar/ssi.c
+++ b/sound/soc/renesas/rcar/ssi.c
@@ -21,7 +21,6 @@
#include <linux/of_irq.h>
#include <linux/delay.h>
#include "rsnd.h"
-#define RSND_SSI_NAME_SIZE 16
/*
* SSICR
@@ -1163,7 +1162,6 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
struct rsnd_mod_ops *ops;
struct clk *clk;
struct rsnd_ssi *ssi;
- char name[RSND_SSI_NAME_SIZE];
int i, nr, ret;
node = rsnd_ssi_of_node(priv);
@@ -1198,10 +1196,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
ssi = rsnd_ssi_get(priv, i);
- snprintf(name, RSND_SSI_NAME_SIZE, "%s.%d",
- SSI_NAME, i);
-
- clk = devm_clk_get(dev, name);
+ clk = rsnd_devm_clk_get_indexed(dev, SSI_NAME, i);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
goto rsnd_ssi_probe_done;
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 05/16] ASoC: rsnd: Add RZ/G3E SoC probing and register map
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
` (3 preceding siblings ...)
2026-05-12 18:26 ` [PATCH v6 04/16] ASoC: rsnd: Support hyphen or dot in indexed clock and reset names John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 06/16] ASoC: rsnd: Add audmacpp clock and reset support for RZ/G3E John Madieu
` (10 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
RZ/G3E audio subsystem has a different register layout compared to
R-Car Gen2/Gen3/Gen4, as described below:
- Different base address organization (SCU, ADG, SSIU, SSI as
separate regions accessed by name)
- Additional registers: AUDIO_CLK_SEL3, SSI_MODE3, SSI_CONTROL2
- Different register offsets within each region
Add RZ/G3E SoC's audio subsystem register layouts and probe support.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6: No changes
v5:
- Simplify flags layout comment per Kuninori's feedback.
- RSND_SOC_MASK fix moved to dedicated patch 02/14.
v4:
- Fix RSND_SOC_MASK to (0xF << 4) to avoid overlap with
RSND_RZ_MASK.
- Add comment documenting flag nibble layout.
v3: No changes
v2: No changes
sound/soc/renesas/rcar/core.c | 1 +
sound/soc/renesas/rcar/gen.c | 180 ++++++++++++++++++++++++++++++++++
sound/soc/renesas/rcar/rsnd.h | 26 ++++-
3 files changed, 204 insertions(+), 3 deletions(-)
diff --git a/sound/soc/renesas/rcar/core.c b/sound/soc/renesas/rcar/core.c
index 5f3841565d49..fa6a12571198 100644
--- a/sound/soc/renesas/rcar/core.c
+++ b/sound/soc/renesas/rcar/core.c
@@ -107,6 +107,7 @@ static const struct of_device_id rsnd_of_match[] = {
{ .compatible = "renesas,rcar_sound-gen4", .data = (void *)RSND_GEN4 },
/* Special Handling */
{ .compatible = "renesas,rcar_sound-r8a77990", .data = (void *)(RSND_GEN3 | RSND_SOC_E) },
+ { .compatible = "renesas,r9a09g047-sound", .data = (void *)(RSND_RZ3 | RSND_RZG3E) },
{},
};
MODULE_DEVICE_TABLE(of, rsnd_of_match);
diff --git a/sound/soc/renesas/rcar/gen.c b/sound/soc/renesas/rcar/gen.c
index d1f20cde66be..05d5f656fb01 100644
--- a/sound/soc/renesas/rcar/gen.c
+++ b/sound/soc/renesas/rcar/gen.c
@@ -464,6 +464,184 @@ static int rsnd_gen1_probe(struct rsnd_priv *priv)
return ret_adg | ret_ssi;
}
+/*
+ * RZ/G3E Generation
+ */
+static int rsnd_rzg3e_probe(struct rsnd_priv *priv)
+{
+ static const struct rsnd_regmap_field_conf conf_ssiu[] = {
+ RSND_GEN_S_REG(SSI_MODE1, 0x804),
+ RSND_GEN_S_REG(SSI_MODE2, 0x808),
+ RSND_GEN_S_REG(SSI_MODE3, 0x80c),
+ RSND_GEN_S_REG(SSI_CONTROL, 0x810),
+ RSND_GEN_S_REG(SSI_CONTROL2, 0x814),
+ RSND_GEN_S_REG(SSI_SYS_STATUS0, 0x840),
+ RSND_GEN_S_REG(SSI_SYS_STATUS1, 0x844),
+ RSND_GEN_S_REG(SSI_SYS_STATUS2, 0x848),
+ RSND_GEN_S_REG(SSI_SYS_STATUS3, 0x84c),
+ RSND_GEN_S_REG(SSI_SYS_INT_ENABLE0, 0x850),
+ RSND_GEN_S_REG(SSI_SYS_INT_ENABLE1, 0x854),
+ RSND_GEN_S_REG(SSI_SYS_INT_ENABLE2, 0x858),
+ RSND_GEN_S_REG(SSI_SYS_INT_ENABLE3, 0x85c),
+ RSND_GEN_M_REG(SSI_BUSIF0_MODE, 0x0, 0x80),
+ RSND_GEN_M_REG(SSI_BUSIF0_ADINR, 0x4, 0x80),
+ RSND_GEN_M_REG(SSI_BUSIF0_DALIGN, 0x8, 0x80),
+ RSND_GEN_M_REG(SSI_BUSIF1_MODE, 0x20, 0x80),
+ RSND_GEN_M_REG(SSI_BUSIF1_ADINR, 0x24, 0x80),
+ RSND_GEN_M_REG(SSI_BUSIF1_DALIGN, 0x28, 0x80),
+ RSND_GEN_M_REG(SSI_BUSIF2_MODE, 0x40, 0x80),
+ RSND_GEN_M_REG(SSI_BUSIF2_ADINR, 0x44, 0x80),
+ RSND_GEN_M_REG(SSI_BUSIF2_DALIGN, 0x48, 0x80),
+ RSND_GEN_M_REG(SSI_BUSIF3_MODE, 0x60, 0x80),
+ RSND_GEN_M_REG(SSI_BUSIF3_ADINR, 0x64, 0x80),
+ RSND_GEN_M_REG(SSI_BUSIF3_DALIGN, 0x68, 0x80),
+ RSND_GEN_M_REG(SSI_MODE, 0xc, 0x80),
+ RSND_GEN_M_REG(SSI_CTRL, 0x10, 0x80),
+ RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80),
+ RSND_GEN_S_REG(SSI9_BUSIF0_MODE, 0x480),
+ RSND_GEN_S_REG(SSI9_BUSIF0_ADINR, 0x484),
+ RSND_GEN_S_REG(SSI9_BUSIF0_DALIGN, 0x488),
+ RSND_GEN_S_REG(SSI9_BUSIF1_MODE, 0x4a0),
+ RSND_GEN_S_REG(SSI9_BUSIF1_ADINR, 0x4a4),
+ RSND_GEN_S_REG(SSI9_BUSIF1_DALIGN, 0x4a8),
+ RSND_GEN_S_REG(SSI9_BUSIF2_MODE, 0x4c0),
+ RSND_GEN_S_REG(SSI9_BUSIF2_ADINR, 0x4c4),
+ RSND_GEN_S_REG(SSI9_BUSIF2_DALIGN, 0x4c8),
+ RSND_GEN_S_REG(SSI9_BUSIF3_MODE, 0x4e0),
+ RSND_GEN_S_REG(SSI9_BUSIF3_ADINR, 0x4e4),
+ RSND_GEN_S_REG(SSI9_BUSIF3_DALIGN, 0x4e8),
+ };
+ static const struct rsnd_regmap_field_conf conf_scu[] = {
+ RSND_GEN_M_REG(SRC_I_BUSIF_MODE, 0x0, 0x20),
+ RSND_GEN_M_REG(SRC_O_BUSIF_MODE, 0x4, 0x20),
+ RSND_GEN_M_REG(SRC_BUSIF_DALIGN, 0x8, 0x20),
+ RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20),
+ RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20),
+ RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20),
+ RSND_GEN_M_REG(CMD_BUSIF_MODE, 0x184, 0x20),
+ RSND_GEN_M_REG(CMD_BUSIF_DALIGN, 0x188, 0x20),
+ RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20),
+ RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20),
+ RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8),
+ RSND_GEN_S_REG(SCU_SYS_INT_EN0, 0x1cc),
+ RSND_GEN_S_REG(SCU_SYS_STATUS1, 0x1d0),
+ RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1d4),
+ RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40),
+ RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40),
+ RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40),
+ RSND_GEN_M_REG(SRC_IFSCR, 0x21c, 0x40),
+ RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40),
+ RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40),
+ RSND_GEN_M_REG(SRC_BSDSR, 0x22c, 0x40),
+ RSND_GEN_M_REG(SRC_BSISR, 0x238, 0x40),
+ RSND_GEN_M_REG(CTU_SWRSR, 0x500, 0x100),
+ RSND_GEN_M_REG(CTU_CTUIR, 0x504, 0x100),
+ RSND_GEN_M_REG(CTU_ADINR, 0x508, 0x100),
+ RSND_GEN_M_REG(CTU_CPMDR, 0x510, 0x100),
+ RSND_GEN_M_REG(CTU_SCMDR, 0x514, 0x100),
+ RSND_GEN_M_REG(CTU_SV00R, 0x518, 0x100),
+ RSND_GEN_M_REG(CTU_SV01R, 0x51c, 0x100),
+ RSND_GEN_M_REG(CTU_SV02R, 0x520, 0x100),
+ RSND_GEN_M_REG(CTU_SV03R, 0x524, 0x100),
+ RSND_GEN_M_REG(CTU_SV04R, 0x528, 0x100),
+ RSND_GEN_M_REG(CTU_SV05R, 0x52c, 0x100),
+ RSND_GEN_M_REG(CTU_SV06R, 0x530, 0x100),
+ RSND_GEN_M_REG(CTU_SV07R, 0x534, 0x100),
+ RSND_GEN_M_REG(CTU_SV10R, 0x538, 0x100),
+ RSND_GEN_M_REG(CTU_SV11R, 0x53c, 0x100),
+ RSND_GEN_M_REG(CTU_SV12R, 0x540, 0x100),
+ RSND_GEN_M_REG(CTU_SV13R, 0x544, 0x100),
+ RSND_GEN_M_REG(CTU_SV14R, 0x548, 0x100),
+ RSND_GEN_M_REG(CTU_SV15R, 0x54c, 0x100),
+ RSND_GEN_M_REG(CTU_SV16R, 0x550, 0x100),
+ RSND_GEN_M_REG(CTU_SV17R, 0x554, 0x100),
+ RSND_GEN_M_REG(CTU_SV20R, 0x558, 0x100),
+ RSND_GEN_M_REG(CTU_SV21R, 0x55c, 0x100),
+ RSND_GEN_M_REG(CTU_SV22R, 0x560, 0x100),
+ RSND_GEN_M_REG(CTU_SV23R, 0x564, 0x100),
+ RSND_GEN_M_REG(CTU_SV24R, 0x568, 0x100),
+ RSND_GEN_M_REG(CTU_SV25R, 0x56c, 0x100),
+ RSND_GEN_M_REG(CTU_SV26R, 0x570, 0x100),
+ RSND_GEN_M_REG(CTU_SV27R, 0x574, 0x100),
+ RSND_GEN_M_REG(CTU_SV30R, 0x578, 0x100),
+ RSND_GEN_M_REG(CTU_SV31R, 0x57c, 0x100),
+ RSND_GEN_M_REG(CTU_SV32R, 0x580, 0x100),
+ RSND_GEN_M_REG(CTU_SV33R, 0x584, 0x100),
+ RSND_GEN_M_REG(CTU_SV34R, 0x588, 0x100),
+ RSND_GEN_M_REG(CTU_SV35R, 0x58c, 0x100),
+ RSND_GEN_M_REG(CTU_SV36R, 0x590, 0x100),
+ RSND_GEN_M_REG(CTU_SV37R, 0x594, 0x100),
+ RSND_GEN_M_REG(MIX_SWRSR, 0xd00, 0x40),
+ RSND_GEN_M_REG(MIX_MIXIR, 0xd04, 0x40),
+ RSND_GEN_M_REG(MIX_ADINR, 0xd08, 0x40),
+ RSND_GEN_M_REG(MIX_MIXMR, 0xd10, 0x40),
+ RSND_GEN_M_REG(MIX_MVPDR, 0xd14, 0x40),
+ RSND_GEN_M_REG(MIX_MDBAR, 0xd18, 0x40),
+ RSND_GEN_M_REG(MIX_MDBBR, 0xd1c, 0x40),
+ RSND_GEN_M_REG(MIX_MDBCR, 0xd20, 0x40),
+ RSND_GEN_M_REG(MIX_MDBDR, 0xd24, 0x40),
+ RSND_GEN_M_REG(MIX_MDBER, 0xd28, 0x40),
+ RSND_GEN_M_REG(DVC_SWRSR, 0xe00, 0x100),
+ RSND_GEN_M_REG(DVC_DVUIR, 0xe04, 0x100),
+ RSND_GEN_M_REG(DVC_ADINR, 0xe08, 0x100),
+ RSND_GEN_M_REG(DVC_DVUCR, 0xe10, 0x100),
+ RSND_GEN_M_REG(DVC_ZCMCR, 0xe14, 0x100),
+ RSND_GEN_M_REG(DVC_VRCTR, 0xe18, 0x100),
+ RSND_GEN_M_REG(DVC_VRPDR, 0xe1c, 0x100),
+ RSND_GEN_M_REG(DVC_VRDBR, 0xe20, 0x100),
+ RSND_GEN_M_REG(DVC_VOL0R, 0xe28, 0x100),
+ RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100),
+ RSND_GEN_M_REG(DVC_VOL2R, 0xe30, 0x100),
+ RSND_GEN_M_REG(DVC_VOL3R, 0xe34, 0x100),
+ RSND_GEN_M_REG(DVC_VOL4R, 0xe38, 0x100),
+ RSND_GEN_M_REG(DVC_VOL5R, 0xe3c, 0x100),
+ RSND_GEN_M_REG(DVC_VOL6R, 0xe40, 0x100),
+ RSND_GEN_M_REG(DVC_VOL7R, 0xe44, 0x100),
+ RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100),
+ };
+ static const struct rsnd_regmap_field_conf conf_adg[] = {
+ RSND_GEN_S_REG(BRRA, 0x00),
+ RSND_GEN_S_REG(BRRB, 0x04),
+ RSND_GEN_S_REG(BRGCKR, 0x08),
+ RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c),
+ RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10),
+ RSND_GEN_S_REG(AUDIO_CLK_SEL2, 0x14),
+ RSND_GEN_S_REG(AUDIO_CLK_SEL3, 0x18),
+ RSND_GEN_S_REG(DIV_EN, 0x30),
+ RSND_GEN_S_REG(SRCIN_TIMSEL0, 0x34),
+ RSND_GEN_S_REG(SRCIN_TIMSEL1, 0x38),
+ RSND_GEN_S_REG(SRCIN_TIMSEL2, 0x3c),
+ RSND_GEN_S_REG(SRCIN_TIMSEL3, 0x40),
+ RSND_GEN_S_REG(SRCIN_TIMSEL4, 0x44),
+ RSND_GEN_S_REG(SRCOUT_TIMSEL0, 0x48),
+ RSND_GEN_S_REG(SRCOUT_TIMSEL1, 0x4c),
+ RSND_GEN_S_REG(SRCOUT_TIMSEL2, 0x50),
+ RSND_GEN_S_REG(SRCOUT_TIMSEL3, 0x54),
+ RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58),
+ RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c),
+ };
+ static const struct rsnd_regmap_field_conf conf_ssi[] = {
+ RSND_GEN_M_REG(SSICR, 0x00, 0x40),
+ RSND_GEN_M_REG(SSISR, 0x04, 0x40),
+ RSND_GEN_M_REG(SSIWSR, 0x20, 0x40),
+ };
+ int ret;
+
+ ret = rsnd_gen_regmap_init(priv, 10, RSND_BASE_SCU, "scu", conf_scu);
+ if (ret < 0)
+ return ret;
+
+ ret = rsnd_gen_regmap_init(priv, 1, RSND_BASE_ADG, "adg", conf_adg);
+ if (ret < 0)
+ return ret;
+
+ ret = rsnd_gen_regmap_init(priv, 10, RSND_BASE_SSIU, "ssiu", conf_ssiu);
+ if (ret < 0)
+ return ret;
+
+ return rsnd_gen_regmap_init(priv, 10, RSND_BASE_SSI, "ssi", conf_ssi);
+}
+
/*
* Gen
*/
@@ -487,6 +665,8 @@ int rsnd_gen_probe(struct rsnd_priv *priv)
ret = rsnd_gen2_probe(priv);
else if (rsnd_is_gen4(priv))
ret = rsnd_gen4_probe(priv);
+ else if (rsnd_is_rzg3e(priv))
+ ret = rsnd_rzg3e_probe(priv);
if (ret < 0)
dev_err(dev, "unknown generation R-Car sound device\n");
diff --git a/sound/soc/renesas/rcar/rsnd.h b/sound/soc/renesas/rcar/rsnd.h
index f3f1ad1180f8..e917aa12fa80 100644
--- a/sound/soc/renesas/rcar/rsnd.h
+++ b/sound/soc/renesas/rcar/rsnd.h
@@ -143,13 +143,16 @@ enum rsnd_reg {
AUDIO_CLK_SEL0,
AUDIO_CLK_SEL1,
AUDIO_CLK_SEL2,
+ AUDIO_CLK_SEL3,
/* SSIU */
SSI_MODE,
SSI_MODE0,
SSI_MODE1,
SSI_MODE2,
+ SSI_MODE3,
SSI_CONTROL,
+ SSI_CONTROL2,
SSI_CTRL,
SSI_BUSIF0_MODE,
SSI_BUSIF1_MODE,
@@ -641,14 +644,28 @@ struct rsnd_priv {
struct platform_device *pdev;
spinlock_t lock;
unsigned long flags;
+
+ /*
+ * Flags layout: 0xDCBA
+ *
+ * A: R-Car generation (Gen1/Gen2/Gen3/Gen4)
+ * B: R-Car SoC variant (e.g. SOC_E for E1/E2/E3)
+ * C: RZ series generation
+ * D: RZ series SoC identifier (e.g. RZG3E)
+ *
+ * Bits 16+ are used for capability flags.
+ */
#define RSND_GEN_MASK (0xF << 0)
#define RSND_GEN1 (1 << 0)
#define RSND_GEN2 (2 << 0)
#define RSND_GEN3 (3 << 0)
#define RSND_GEN4 (4 << 0)
-#define RSND_SOC_MASK (0xF << 4)
-#define RSND_SOC_E (1 << 4) /* E1/E2/E3 */
-
+#define RSND_SOC_MASK (0xF << 4) /* nibble B */
+#define RSND_SOC_E (1 << 4) /* E1/E2/E3 */
+#define RSND_RZ_MASK (0xF << 8) /* nibble C */
+#define RSND_RZ3 (3 << 8)
+#define RSND_RZ_ID_MASK (0xF << 12) /* nibble D */
+#define RSND_RZG3E (1 << 12)
/*
* below value will be filled on rsnd_gen_probe()
*/
@@ -727,6 +744,9 @@ struct rsnd_priv {
#define rsnd_is_gen3_e3(priv) (((priv)->flags & \
(RSND_GEN_MASK | RSND_SOC_MASK)) == \
(RSND_GEN3 | RSND_SOC_E))
+#define rsnd_is_rzg3e(priv) (((priv)->flags & \
+ (RSND_RZ_MASK | RSND_RZ_ID_MASK)) == \
+ (RSND_RZ3 | RSND_RZG3E))
#define rsnd_flags_has(p, f) ((p)->flags & (f))
#define rsnd_flags_set(p, f) ((p)->flags |= (f))
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 06/16] ASoC: rsnd: Add audmacpp clock and reset support for RZ/G3E
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
` (4 preceding siblings ...)
2026-05-12 18:26 ` [PATCH v6 05/16] ASoC: rsnd: Add RZ/G3E SoC probing and register map John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 07/16] ASoC: rsnd: Refactor DMA address tables with named structs John Madieu
` (9 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
RZ/G3E requires additional audmapp clock and reset lines for
Audio DMA-PP operation.
Add global audmacpp clock/reset management in rsnd_dma_probe()
using optional APIs to remain transparent to other platforms.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6:
- Enable the audmapp clock before deasserting the audmapp reset
so the block sees a stable clock on the way out of reset.
- Drop redundant braces around single-statement if blocks (style).
v5:
- Add comment on audmapp clock/reset acquisition clarifying these
are optional and transparent to platforms that don't have them
in DT, per Kuninori's request.
- Drop spurious blank line added to struct rsnd_priv in rsnd.h.
v4:
- Move audmapp_clk and audmapp_rstc from struct rsnd_priv into
struct rsnd_dma_ctrl.
v3: No changes
v2: No changes
sound/soc/renesas/rcar/dma.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/sound/soc/renesas/rcar/dma.c b/sound/soc/renesas/rcar/dma.c
index 68c859897e68..71774dae8847 100644
--- a/sound/soc/renesas/rcar/dma.c
+++ b/sound/soc/renesas/rcar/dma.c
@@ -47,6 +47,9 @@ struct rsnd_dma_ctrl {
phys_addr_t ppres;
int dmaen_num;
int dmapp_num;
+ /* RZ/G3E: Audio DMAC peri-peri clock and reset */
+ struct clk *audmapp_clk;
+ struct reset_control *audmapp_rstc;
};
#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
@@ -864,6 +867,25 @@ int rsnd_dma_probe(struct rsnd_priv *priv)
if (rsnd_is_gen4(priv))
goto audmapp_end;
+ /*
+ * Audio DMAC peri-peri clock and reset for RZ/G3E.
+ * These use optional APIs, so they gracefully return NULL
+ * (no error) on platforms whose DT does not provide them.
+ *
+ * Enable the clock first so the block sees a stable clock on
+ * the way out of reset, then deassert the reset line.
+ */
+ dmac->audmapp_clk = devm_clk_get_optional_enabled(dev, "audmapp");
+ if (IS_ERR(dmac->audmapp_clk))
+ return dev_err_probe(dev, PTR_ERR(dmac->audmapp_clk),
+ "failed to get audmapp clock\n");
+
+ dmac->audmapp_rstc =
+ devm_reset_control_get_optional_exclusive_deasserted(dev, "audmapp");
+ if (IS_ERR(dmac->audmapp_rstc))
+ return dev_err_probe(dev, PTR_ERR(dmac->audmapp_rstc),
+ "failed to get audmapp reset\n");
+
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp");
if (!res) {
dev_err(dev, "lack of audmapp in DT\n");
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 07/16] ASoC: rsnd: Refactor DMA address tables with named structs
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
` (5 preceding siblings ...)
2026-05-12 18:26 ` [PATCH v6 06/16] ASoC: rsnd: Add audmacpp clock and reset support for RZ/G3E John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 08/16] ASoC: rsnd: Add RZ/G3E DMA address calculation support John Madieu
` (8 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
Replace the raw multi-dimensional array used for DMA address lookup in
rsnd_gen2_dma_addr() with properly named structs: rsnd_dma_addr (in/out
pair), rsnd_dma_addr_dir (capture/playback arrays), and
rsnd_dma_addr_map (src/ssi/ssiu module sets).
While at it, extract the common lookup logic (is_ssi / use_src / use_cmd
evaluation and table indexing) into a shared rsnd_dma_addr_lookup()
function.
No functional change. This is a preparatory refactor for upcoming RZ/G3E
support which will add its own DMA address map using the same struct and
lookup function.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6: No changes
v5:
- New patch, extracted from v4 patch 06/12 as a standalone
preparatory refactor per Kuninori's request.
- No RZ/G3E content; purely the struct introduction and
rsnd_gen2 conversion.
sound/soc/renesas/rcar/dma.c | 147 +++++++++++++++++++++++------------
1 file changed, 99 insertions(+), 48 deletions(-)
diff --git a/sound/soc/renesas/rcar/dma.c b/sound/soc/renesas/rcar/dma.c
index 71774dae8847..24c23cb89390 100644
--- a/sound/soc/renesas/rcar/dma.c
+++ b/sound/soc/renesas/rcar/dma.c
@@ -481,6 +481,69 @@ static struct rsnd_mod_ops rsnd_dmapp_ops = {
DEBUG_INFO
};
+struct rsnd_dma_addr {
+ dma_addr_t out_addr;
+ dma_addr_t in_addr;
+};
+
+struct rsnd_dma_addr_dir {
+ struct rsnd_dma_addr capture[3];
+ struct rsnd_dma_addr playback[3];
+};
+
+struct rsnd_dma_addr_map {
+ struct rsnd_dma_addr_dir src;
+ struct rsnd_dma_addr_dir ssi;
+ struct rsnd_dma_addr_dir ssiu;
+};
+
+static dma_addr_t
+rsnd_dma_addr_lookup(struct rsnd_dai_stream *io,
+ struct rsnd_mod *mod,
+ struct rsnd_priv *priv,
+ const struct rsnd_dma_addr_map *map,
+ int is_play, int is_from)
+{
+ struct device *dev = rsnd_priv_to_dev(priv);
+ int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod) ||
+ !!(rsnd_io_to_mod_ssiu(io) == mod);
+ int use_src = !!rsnd_io_to_mod_src(io);
+ int use_cmd = !!rsnd_io_to_mod_dvc(io) ||
+ !!rsnd_io_to_mod_mix(io) ||
+ !!rsnd_io_to_mod_ctu(io);
+ int id = rsnd_mod_id(mod);
+ const struct rsnd_dma_addr_dir *dir;
+ const struct rsnd_dma_addr *addr;
+
+ /* it shouldn't happen */
+ if (use_cmd && !use_src)
+ dev_err(dev, "DVC is selected without SRC\n");
+
+ /* use SSIU or SSI? */
+ if (is_ssi && rsnd_ssi_use_busif(io))
+ is_ssi++;
+
+ dev_dbg(dev, "dma%d addr : is_ssi=%d use_src=%d use_cmd=%d\n",
+ id, is_ssi, use_src, use_cmd);
+
+ switch (is_ssi) {
+ case 2:
+ dir = &map->ssiu;
+ break;
+ case 1:
+ dir = &map->ssi;
+ break;
+ default:
+ dir = &map->src;
+ break;
+ }
+
+ addr = is_play ? &dir->playback[use_src + use_cmd]
+ : &dir->capture[use_src + use_cmd];
+
+ return is_from ? addr->out_addr : addr->in_addr;
+}
+
/*
* Common DMAC Interface
*/
@@ -527,47 +590,45 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
struct device *dev = rsnd_priv_to_dev(priv);
phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_BASE_SSI);
phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_BASE_SCU);
- int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod) ||
- !!(rsnd_io_to_mod_ssiu(io) == mod);
- int use_src = !!rsnd_io_to_mod_src(io);
- int use_cmd = !!rsnd_io_to_mod_dvc(io) ||
- !!rsnd_io_to_mod_mix(io) ||
- !!rsnd_io_to_mod_ctu(io);
int id = rsnd_mod_id(mod);
int busif = rsnd_mod_id_sub(rsnd_io_to_mod_ssiu(io));
- struct dma_addr {
- dma_addr_t out_addr;
- dma_addr_t in_addr;
- } dma_addrs[3][2][3] = {
- /* SRC */
- /* Capture */
- {{{ 0, 0 },
- { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) },
- { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } },
- /* Playback */
- {{ 0, 0, },
- { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) },
- { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } }
+ const struct rsnd_dma_addr_map map = {
+ .src = {
+ .capture = {
+ { 0, 0 },
+ { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) },
+ { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) },
+ },
+ .playback = {
+ { 0, 0 },
+ { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) },
+ { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) },
+ },
+ },
+ .ssi = {
+ .capture = {
+ { RDMA_SSI_O_N(ssi, id), 0 },
+ { RDMA_SSIU_O_P(ssi, id, busif), 0 },
+ { RDMA_SSIU_O_P(ssi, id, busif), 0 },
+ },
+ .playback = {
+ { 0, RDMA_SSI_I_N(ssi, id) },
+ { 0, RDMA_SSIU_I_P(ssi, id, busif) },
+ { 0, RDMA_SSIU_I_P(ssi, id, busif) },
+ },
},
- /* SSI */
- /* Capture */
- {{{ RDMA_SSI_O_N(ssi, id), 0 },
- { RDMA_SSIU_O_P(ssi, id, busif), 0 },
- { RDMA_SSIU_O_P(ssi, id, busif), 0 } },
- /* Playback */
- {{ 0, RDMA_SSI_I_N(ssi, id) },
- { 0, RDMA_SSIU_I_P(ssi, id, busif) },
- { 0, RDMA_SSIU_I_P(ssi, id, busif) } }
+ .ssiu = {
+ .capture = {
+ { RDMA_SSIU_O_N(ssi, id, busif), 0 },
+ { RDMA_SSIU_O_P(ssi, id, busif), 0 },
+ { RDMA_SSIU_O_P(ssi, id, busif), 0 },
+ },
+ .playback = {
+ { 0, RDMA_SSIU_I_N(ssi, id, busif) },
+ { 0, RDMA_SSIU_I_P(ssi, id, busif) },
+ { 0, RDMA_SSIU_I_P(ssi, id, busif) },
+ },
},
- /* SSIU */
- /* Capture */
- {{{ RDMA_SSIU_O_N(ssi, id, busif), 0 },
- { RDMA_SSIU_O_P(ssi, id, busif), 0 },
- { RDMA_SSIU_O_P(ssi, id, busif), 0 } },
- /* Playback */
- {{ 0, RDMA_SSIU_I_N(ssi, id, busif) },
- { 0, RDMA_SSIU_I_P(ssi, id, busif) },
- { 0, RDMA_SSIU_I_P(ssi, id, busif) } } },
};
/*
@@ -580,17 +641,7 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
dev_err(dev, "This driver doesn't support SSI%d-%d, so far",
id, busif);
- /* it shouldn't happen */
- if (use_cmd && !use_src)
- dev_err(dev, "DVC is selected without SRC\n");
-
- /* use SSIU or SSI ? */
- if (is_ssi && rsnd_ssi_use_busif(io))
- is_ssi++;
-
- return (is_from) ?
- dma_addrs[is_ssi][is_play][use_src + use_cmd].out_addr :
- dma_addrs[is_ssi][is_play][use_src + use_cmd].in_addr;
+ return rsnd_dma_addr_lookup(io, mod, priv, &map, is_play, is_from);
}
/*
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 08/16] ASoC: rsnd: Add RZ/G3E DMA address calculation support
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
` (6 preceding siblings ...)
2026-05-12 18:26 ` [PATCH v6 07/16] ASoC: rsnd: Refactor DMA address tables with named structs John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 09/16] ASoC: rsnd: ssui: Add RZ/G3E SSIU BUSIF support John Madieu
` (7 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
RZ/G3E has different DMA register base addresses and offset
calculations compared to R-Car platforms.
Add dedicated rsnd_rzg3e_dma_addr() function with dispatch from
rsnd_dma_addr(), following the existing per-generation pattern.
The function reuses rsnd_dma_addr_lookup() and rsnd_dma_addr_map.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6: No changes
v5:
- Split from v4 patch 06/12 per Kuninori's request.
- Move G3E DMA address comment block into rsnd_rzg3e_dma_addr()
per Kuninori's request.
v4:
- Replace raw [3][2][3] DMA address array with named structs
rsnd_dma_addr_dir and rsnd_dma_addr_map. Use designated
initializers in both rsnd_gen2_dma_addr() and
rsnd_rzg3e_dma_addr().
v3: No changes
v2: No changes
sound/soc/renesas/rcar/dma.c | 81 ++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/sound/soc/renesas/rcar/dma.c b/sound/soc/renesas/rcar/dma.c
index 24c23cb89390..ede0123d40eb 100644
--- a/sound/soc/renesas/rcar/dma.c
+++ b/sound/soc/renesas/rcar/dma.c
@@ -644,6 +644,85 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
return rsnd_dma_addr_lookup(io, mod, priv, &map, is_play, is_from);
}
+/*
+ * ex) G3E case
+ * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out
+ * SSI : 0x13C31000 / 0x13C40000 / 0x13C40000
+ * SSIU: 0x13C31000 / 0x13C40000 / 0x13C40000 / 0xEC400000 / 0xEC400000
+ * SCU : 0x13C00000 / 0x13C10000 / 0x13C14000 / 0xEC300000 / 0xEC304000
+ * CMD : 0x13C00000 / / 0x13C18000 0xEC308000
+ */
+
+/* RZ/G3E DMA address macros */
+#define RDMA_SSI_I_N_G3E(addr, i) (addr ##_reg + 0x0000F000 + (0x1000 * i))
+#define RDMA_SSI_O_N_G3E(addr, i) (addr ##_reg + 0x0000F000 + (0x1000 * i))
+
+#define RDMA_SSIU_I_N_G3E(addr, i, j) (addr ##_reg + 0x0000F000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j) % 4) * 0x400) - (0x4000 * ((i) / 9) * ((j) / 4)))
+#define RDMA_SSIU_O_N_G3E(addr, i, j) RDMA_SSIU_I_N_G3E(addr, i, j)
+
+#define RDMA_SSIU_I_P_G3E(addr, i, j) (addr ##_reg + 0xD87CF000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j) % 4) * 0x400) - (0x4000 * ((i) / 9) * ((j) / 4)))
+#define RDMA_SSIU_O_P_G3E(addr, i, j) RDMA_SSIU_I_P_G3E(addr, i, j)
+
+#define RDMA_SRC_I_N_G3E(addr, i) (addr ##_reg + 0x00010000 + (0x400 * i))
+#define RDMA_SRC_O_N_G3E(addr, i) (addr ##_reg + 0x00014000 + (0x400 * i))
+
+#define RDMA_SRC_I_P_G3E(addr, i) (addr ##_reg + 0xD8700000 + (0x400 * i))
+#define RDMA_SRC_O_P_G3E(addr, i) (addr ##_reg + 0xD8704000 + (0x400 * i))
+
+#define RDMA_CMD_O_N_G3E(addr, i) (addr ##_reg + 0x00018000 + (0x400 * i))
+#define RDMA_CMD_O_P_G3E(addr, i) (addr ##_reg + 0xD8708000 + (0x400 * i))
+
+static dma_addr_t
+rsnd_rzg3e_dma_addr(struct rsnd_dai_stream *io,
+ struct rsnd_mod *mod, int is_play, int is_from)
+{
+ struct rsnd_priv *priv = rsnd_io_to_priv(io);
+ phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_BASE_SSI);
+ phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_BASE_SCU);
+ int id = rsnd_mod_id(mod);
+ int busif = rsnd_mod_id_sub(rsnd_io_to_mod_ssiu(io));
+ const struct rsnd_dma_addr_map map = {
+ .src = {
+ .capture = {
+ { 0, 0 },
+ { RDMA_SRC_O_N_G3E(src, id), RDMA_SRC_I_P_G3E(src, id) },
+ { RDMA_CMD_O_N_G3E(src, id), RDMA_SRC_I_P_G3E(src, id) },
+ },
+ .playback = {
+ { 0, 0 },
+ { RDMA_SRC_O_P_G3E(src, id), RDMA_SRC_I_N_G3E(src, id) },
+ { RDMA_CMD_O_P_G3E(src, id), RDMA_SRC_I_N_G3E(src, id) },
+ },
+ },
+ .ssi = {
+ .capture = {
+ { RDMA_SSI_O_N_G3E(ssi, id), 0 },
+ { RDMA_SSIU_O_P_G3E(ssi, id, busif), 0 },
+ { RDMA_SSIU_O_P_G3E(ssi, id, busif), 0 },
+ },
+ .playback = {
+ { 0, RDMA_SSI_I_N_G3E(ssi, id) },
+ { 0, RDMA_SSIU_I_P_G3E(ssi, id, busif) },
+ { 0, RDMA_SSIU_I_P_G3E(ssi, id, busif) },
+ },
+ },
+ .ssiu = {
+ .capture = {
+ { RDMA_SSIU_O_N_G3E(ssi, id, busif), 0 },
+ { RDMA_SSIU_O_P_G3E(ssi, id, busif), 0 },
+ { RDMA_SSIU_O_P_G3E(ssi, id, busif), 0 },
+ },
+ .playback = {
+ { 0, RDMA_SSIU_I_N_G3E(ssi, id, busif) },
+ { 0, RDMA_SSIU_I_P_G3E(ssi, id, busif) },
+ { 0, RDMA_SSIU_I_P_G3E(ssi, id, busif) },
+ },
+ },
+ };
+
+ return rsnd_dma_addr_lookup(io, mod, priv, &map, is_play, is_from);
+}
+
/*
* Gen4 DMA read/write register offset
*
@@ -690,6 +769,8 @@ static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io,
return 0;
else if (rsnd_is_gen4(priv))
return rsnd_gen4_dma_addr(io, mod, is_play, is_from);
+ else if (rsnd_is_rzg3e(priv))
+ return rsnd_rzg3e_dma_addr(io, mod, is_play, is_from);
else
return rsnd_gen2_dma_addr(io, mod, is_play, is_from);
}
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 09/16] ASoC: rsnd: ssui: Add RZ/G3E SSIU BUSIF support
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
` (7 preceding siblings ...)
2026-05-12 18:26 ` [PATCH v6 08/16] ASoC: rsnd: Add RZ/G3E DMA address calculation support John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-13 0:35 ` Kuninori Morimoto
2026-05-13 9:41 ` Geert Uytterhoeven
2026-05-12 18:26 ` [PATCH v6 10/16] ASoC: rsnd: Add SSI reset support for RZ/G3E platform John Madieu
` (6 subsequent siblings)
15 siblings, 2 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
Add support for the SSIU found on the Renesas RZ/G3E SoC, which
provides a different BUSIF layout compared to earlier generations:
- SSI0-SSI4: 4 BUSIF instances each (BUSIF0-3)
- SSI5-SSI8: 1 BUSIF instance each (BUSIF0 only)
- SSI9: 4 BUSIF instances (BUSIF0-3)
- Total: 28 BUSIFs
RZ/G3E also differs from Gen2/Gen3 implementations in that only two
pairs of BUSIF error-status registers are available instead of four,
and the SSI always operates in BUSIF mode with no PIO fallback.
Rather than scattering SoC-specific checks across functional code,
introduce an extra capability flags in the match data:
- RSND_SSIU_BUSIF_STATUS_COUNT_2: only two BUSIF error-status
register pairs are present. Used in rsnd_ssiu_busif_err_irq_ctrl()
and rsnd_ssiu_busif_err_status_clear() to limit register iteration.
Future SoCs sharing these constraints can set the flags without
requiring code changes.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6: No changes
v5: No changes
v4:
- Move busif_status_count from rsnd_priv into new
struct rsnd_ssiu_ctrl, following the rsnd_dma_ctrl pattern for
shared non-per-instance module resources.
- Properly propagate reset control errors via dev_err_probe()
instead of silencing them.
- Update changelog to accurately describe rsnd_is_rzg3e() usage
for SoC-specific register handling.
v3: No changes
v2: No changes
sound/soc/renesas/rcar/core.c | 3 +-
sound/soc/renesas/rcar/rsnd.h | 2 ++
sound/soc/renesas/rcar/ssiu.c | 63 +++++++++++++++++++++++++----------
3 files changed, 49 insertions(+), 19 deletions(-)
diff --git a/sound/soc/renesas/rcar/core.c b/sound/soc/renesas/rcar/core.c
index fa6a12571198..9022f03c45d6 100644
--- a/sound/soc/renesas/rcar/core.c
+++ b/sound/soc/renesas/rcar/core.c
@@ -107,7 +107,8 @@ static const struct of_device_id rsnd_of_match[] = {
{ .compatible = "renesas,rcar_sound-gen4", .data = (void *)RSND_GEN4 },
/* Special Handling */
{ .compatible = "renesas,rcar_sound-r8a77990", .data = (void *)(RSND_GEN3 | RSND_SOC_E) },
- { .compatible = "renesas,r9a09g047-sound", .data = (void *)(RSND_RZ3 | RSND_RZG3E) },
+ { .compatible = "renesas,r9a09g047-sound", .data = (void *)(RSND_RZ3 | RSND_RZG3E |
+ RSND_SSIU_BUSIF_STATUS_COUNT_2) },
{},
};
MODULE_DEVICE_TABLE(of, rsnd_of_match);
diff --git a/sound/soc/renesas/rcar/rsnd.h b/sound/soc/renesas/rcar/rsnd.h
index e917aa12fa80..186468a584fe 100644
--- a/sound/soc/renesas/rcar/rsnd.h
+++ b/sound/soc/renesas/rcar/rsnd.h
@@ -666,6 +666,7 @@ struct rsnd_priv {
#define RSND_RZ3 (3 << 8)
#define RSND_RZ_ID_MASK (0xF << 12) /* nibble D */
#define RSND_RZG3E (1 << 12)
+#define RSND_SSIU_BUSIF_STATUS_COUNT_2 BIT(16) /* Only 2 BUSIF error-status register pairs */
/*
* below value will be filled on rsnd_gen_probe()
*/
@@ -684,6 +685,7 @@ struct rsnd_priv {
/*
* below value will be filled on rsnd_ssi_probe()
*/
+ void *ssiu_ctrl;
void *ssi;
int ssi_nr;
diff --git a/sound/soc/renesas/rcar/ssiu.c b/sound/soc/renesas/rcar/ssiu.c
index 0cfa84fe5ea8..f483389868d2 100644
--- a/sound/soc/renesas/rcar/ssiu.c
+++ b/sound/soc/renesas/rcar/ssiu.c
@@ -29,31 +29,39 @@ struct rsnd_ssiu {
i++)
/*
- * SSI Gen2 Gen3 Gen4
- * 0 BUSIF0-3 BUSIF0-7 BUSIF0-7
- * 1 BUSIF0-3 BUSIF0-7
- * 2 BUSIF0-3 BUSIF0-7
- * 3 BUSIF0 BUSIF0-7
- * 4 BUSIF0 BUSIF0-7
- * 5 BUSIF0 BUSIF0
- * 6 BUSIF0 BUSIF0
- * 7 BUSIF0 BUSIF0
- * 8 BUSIF0 BUSIF0
- * 9 BUSIF0-3 BUSIF0-7
- * total 22 52 8
+ * SSI Gen2 Gen3 Gen4 RZ/G3E
+ * 0 BUSIF0-3 BUSIF0-7 BUSIF0-7 BUSIF0-3
+ * 1 BUSIF0-3 BUSIF0-7 BUSIF0-3
+ * 2 BUSIF0-3 BUSIF0-7 BUSIF0-3
+ * 3 BUSIF0 BUSIF0-7 BUSIF0-3
+ * 4 BUSIF0 BUSIF0-7 BUSIF0-3
+ * 5 BUSIF0 BUSIF0 BUSIF0
+ * 6 BUSIF0 BUSIF0 BUSIF0
+ * 7 BUSIF0 BUSIF0 BUSIF0
+ * 8 BUSIF0 BUSIF0 BUSIF0
+ * 9 BUSIF0-3 BUSIF0-7 BUSIF0-3
+ * total 22 52 8 28
*/
static const int gen2_id[] = { 0, 4, 8, 12, 13, 14, 15, 16, 17, 18 };
static const int gen3_id[] = { 0, 8, 16, 24, 32, 40, 41, 42, 43, 44 };
static const int gen4_id[] = { 0 };
+static const int rzg3e_id[] = { 0, 4, 8, 12, 16, 20, 21, 22, 23, 24 };
+
+struct rsnd_ssiu_ctrl {
+ unsigned int busif_status_count;
+};
+
+#define rsnd_priv_to_ssiu_ctrl(priv) \
+ ((struct rsnd_ssiu_ctrl *)(priv)->ssiu_ctrl)
/* enable busif buffer over/under run interrupt. */
#define rsnd_ssiu_busif_err_irq_enable(mod) rsnd_ssiu_busif_err_irq_ctrl(mod, 1)
#define rsnd_ssiu_busif_err_irq_disable(mod) rsnd_ssiu_busif_err_irq_ctrl(mod, 0)
static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
{
+ struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
int id = rsnd_mod_id(mod);
int shift, offset;
- int i;
switch (id) {
case 0:
@@ -72,7 +80,7 @@ static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
return;
}
- for (i = 0; i < 4; i++) {
+ for (unsigned int i = 0; i < rsnd_priv_to_ssiu_ctrl(priv)->busif_status_count; i++) {
enum rsnd_reg reg = SSI_SYS_INT_ENABLE((i * 2) + offset);
u32 val = 0xf << (shift * 4);
u32 sys_int_enable = rsnd_mod_read(mod, reg);
@@ -87,10 +95,10 @@ static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod)
{
+ struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
bool error = false;
int id = rsnd_mod_id(mod);
int shift, offset;
- int i;
switch (id) {
case 0:
@@ -109,7 +117,7 @@ bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod)
goto out;
}
- for (i = 0; i < 4; i++) {
+ for (unsigned int i = 0; i < rsnd_priv_to_ssiu_ctrl(priv)->busif_status_count; i++) {
u32 reg = SSI_SYS_STATUS(i * 2) + offset;
u32 status = rsnd_mod_read(mod, reg);
u32 val = 0xf << (shift * 4);
@@ -160,7 +168,8 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod,
/*
* SSI_MODE0
*/
- rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);
+ if (!rsnd_is_rzg3e(priv))
+ rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);
/*
* SSI_MODE1 / SSI_MODE2
@@ -510,6 +519,8 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)
{
struct device *dev = rsnd_priv_to_dev(priv);
struct device_node *node __free(device_node) = rsnd_ssiu_of_node(priv);
+ struct reset_control *rstc;
+ struct rsnd_ssiu_ctrl *ctrl;
struct rsnd_ssiu *ssiu;
struct rsnd_mod_ops *ops;
const int *list = NULL;
@@ -534,8 +545,15 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)
if (!ssiu)
return -ENOMEM;
+ ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
+ if (!ctrl)
+ return -ENOMEM;
+
+ ctrl->busif_status_count = rsnd_flags_has(priv, RSND_SSIU_BUSIF_STATUS_COUNT_2) ? 2 : 4;
+
priv->ssiu = ssiu;
priv->ssiu_nr = nr;
+ priv->ssiu_ctrl = ctrl;
if (rsnd_is_gen1(priv))
ops = &rsnd_ssiu_ops_gen1;
@@ -558,12 +576,21 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)
} else if (rsnd_is_gen4(priv)) {
list = gen4_id;
nr = ARRAY_SIZE(gen4_id);
+ } else if (rsnd_is_rzg3e(priv)) {
+ list = rzg3e_id;
+ nr = ARRAY_SIZE(rzg3e_id);
} else {
dev_err(dev, "unknown SSIU\n");
return -ENODEV;
}
}
+ /* Acquire shared reset once for all SSIU modules */
+ rstc = devm_reset_control_get_optional_shared(dev, "ssi-all");
+ if (IS_ERR(rstc))
+ return dev_err_probe(dev, PTR_ERR(rstc),
+ "failed to get ssi-all reset\n");
+
for_each_rsnd_ssiu(ssiu, priv, i) {
int ret;
@@ -586,7 +613,7 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)
}
ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu),
- ops, NULL, NULL, RSND_MOD_SSIU, i);
+ ops, NULL, rstc, RSND_MOD_SSIU, i);
if (ret)
return ret;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 10/16] ASoC: rsnd: Add SSI reset support for RZ/G3E platform
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
` (8 preceding siblings ...)
2026-05-12 18:26 ` [PATCH v6 09/16] ASoC: rsnd: ssui: Add RZ/G3E SSIU BUSIF support John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 11/16] ASoC: rsnd: Add ADG reset support for RZ/G3E John Madieu
` (5 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
Add SSI reset support for the Renesas RZ/G3E SoC, which differs from
earlier generations in several ways:
- The SSI block always operates in BUSIF mode; RZ/G3E does not
implement the SSITDR/SSIRDR registers used by R-Car Gen2/Gen3/Gen4
for direct SSI DMA. Consequently, for the RZ/G3E, all audio data
must pass through BUSIF. PIO mode remains available for R-Car
Gen2/Gen3/Gen4 platforms.
- Each SSI instance has its own reset line, exposed using per-SSI
names such as "ssi-0", "ssi-1", etc., rather than a single shared
reset.
To support these differences, rsnd_ssi_use_busif() always returns 1
on RZ/G3E, ensuring that the driver consistently selects the BUSIF
DMA path. While at it, acquire the per-SSI reset controller through
the indexed-name helper added earlier in the series, so the same code
accepts both the hyphenated RZ/G3E names and the legacy dotted names
used by R-Car.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6:
- Acquire the per-SSI reset through the new
rsnd_devm_reset_control_get_optional_indexed() helper from
patch 04/16, so the same code accepts both the hyphenated
RZ/G3E names ("ssi-0") and the legacy dotted names ("ssi.0").
- Rewrite the commit message accordingly.
v5: No changes
v4:
- Clarify in commit message that PIO mode remains available on
R-Car Gen2/Gen3/Gen4 platforms.
v3: No changes
v2: No changes
sound/soc/renesas/rcar/ssi.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/sound/soc/renesas/rcar/ssi.c b/sound/soc/renesas/rcar/ssi.c
index cf98cc9ee44c..e6734671328c 100644
--- a/sound/soc/renesas/rcar/ssi.c
+++ b/sound/soc/renesas/rcar/ssi.c
@@ -1157,6 +1157,7 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
int rsnd_ssi_probe(struct rsnd_priv *priv)
{
+ struct reset_control *rstc;
struct device_node *node;
struct device *dev = rsnd_priv_to_dev(priv);
struct rsnd_mod_ops *ops;
@@ -1202,6 +1203,17 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
goto rsnd_ssi_probe_done;
}
+ /*
+ * RZ/G3E uses per-SSI reset controllers.
+ * R-Car platforms typically don't have SSI reset controls.
+ */
+ rstc = rsnd_devm_reset_control_get_optional_indexed(dev,
+ SSI_NAME, i);
+ if (IS_ERR(rstc)) {
+ ret = PTR_ERR(rstc);
+ goto rsnd_ssi_probe_done;
+ }
+
if (of_property_read_bool(np, "shared-pin"))
rsnd_flags_set(ssi, RSND_SSI_CLK_PIN_SHARE);
@@ -1220,7 +1232,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
ops = &rsnd_ssi_dma_ops;
ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk,
- NULL, RSND_MOD_SSI, i);
+ rstc, RSND_MOD_SSI, i);
if (ret)
goto rsnd_ssi_probe_done;
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 11/16] ASoC: rsnd: Add ADG reset support for RZ/G3E
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
` (9 preceding siblings ...)
2026-05-12 18:26 ` [PATCH v6 10/16] ASoC: rsnd: Add SSI reset support for RZ/G3E platform John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 12/16] ASoC: rsnd: adg: Add per-SSI ADG and SSIF supply clock management John Madieu
` (4 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
RZ/G3E requires the ADG reset line to be deasserted for the audio
subsystem to operate. The ADG module clock is already managed via
rsnd_adg_clk_enable/disable() through adg->adg, so no additional
clock handling is needed.
Add support for the optional "adg" reset control on Renesas RZ/G3E SoC.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6: No changes
v5: No changes
v4:
- Collapse dev_err_probe() and rsnd_mod_init() calls to single
lines.
v3: No changes
v2: No changes
sound/soc/renesas/rcar/adg.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/sound/soc/renesas/rcar/adg.c b/sound/soc/renesas/rcar/adg.c
index 0105c60a144e..813ad5eabba6 100644
--- a/sound/soc/renesas/rcar/adg.c
+++ b/sound/soc/renesas/rcar/adg.c
@@ -771,6 +771,7 @@ void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct seq_file *m)
int rsnd_adg_probe(struct rsnd_priv *priv)
{
+ struct reset_control *rstc;
struct rsnd_adg *adg;
struct device *dev = rsnd_priv_to_dev(priv);
int ret;
@@ -779,8 +780,11 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
if (!adg)
return -ENOMEM;
- ret = rsnd_mod_init(priv, &adg->mod, &adg_ops,
- NULL, NULL, 0, 0);
+ rstc = devm_reset_control_get_optional_exclusive(dev, "adg");
+ if (IS_ERR(rstc))
+ return dev_err_probe(dev, PTR_ERR(rstc), "failed to get adg reset\n");
+
+ ret = rsnd_mod_init(priv, &adg->mod, &adg_ops, NULL, rstc, 0, 0);
if (ret)
return ret;
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 12/16] ASoC: rsnd: adg: Add per-SSI ADG and SSIF supply clock management
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
` (10 preceding siblings ...)
2026-05-12 18:26 ` [PATCH v6 11/16] ASoC: rsnd: Add ADG reset support for RZ/G3E John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 13/16] ASoC: rsnd: adg: Look up RZ/G3E clkin under audio-clk{a,b,c,i} John Madieu
` (3 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
RZ/G3E's ADG module requires explicit clock management for SSI audio
interfaces that differs from R-Car Gen2/Gen3/Gen4:
- Per-SSI ADG clocks (adg-ssi-N, or adg.ssi.N in legacy bindings)
for each SSI module
- A shared SSIF supply clock for the SSI subsystem
These clocks are acquired using optional APIs, making them transparent
to platforms that do not require them.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6:
- Rename the per-SSI clock lookup string in code from
"adg.ssi.%d" to "adg-ssi-%d", matching the new DT binding. The
clock is RZ/G3E-only and has no legacy dotted form, so the
indexed helper from patch 04/16 is not needed here.
- Simplify rsnd_adg_clk_control(): collapse the per-SSI ADG and
SSIF supply prepare/unprepare path into the accumulating
"ret |= clk_prepare(...)" style already used for the regular
clkin loop above, restructured as a single if (enable) / else
block.
- Update the in-driver comment to refer to the hyphenated name.
v5: No changes
v4:
- Move clk_prepare/unprepare for per-SSI ADG and SSIF supply
clocks into rsnd_adg_clk_control() instead of separate
prepare/unprepare functions, centralising clock lifecycle
management.
- Return proper errors on clk_enable() failure instead of
dev_warn().
- Eliminates hw_params prepare leak concern since prepare now
happens once at probe/resume.
v3: No changes
v2:
- Split clock handling into prepare/enable phases for atomic
context safety.
sound/soc/renesas/rcar/adg.c | 86 +++++++++++++++++++++++++++++++++++-
1 file changed, 85 insertions(+), 1 deletion(-)
diff --git a/sound/soc/renesas/rcar/adg.c b/sound/soc/renesas/rcar/adg.c
index 813ad5eabba6..a6d34252dfea 100644
--- a/sound/soc/renesas/rcar/adg.c
+++ b/sound/soc/renesas/rcar/adg.c
@@ -19,6 +19,9 @@
#define CLKOUT3 3
#define CLKOUTMAX 4
+/* Maximum SSI count for per-SSI clocks */
+#define ADG_SSI_MAX 10
+
#define BRGCKR_31 (1 << 31)
#define BRRx_MASK(x) (0x3FF & x)
@@ -34,6 +37,9 @@ struct rsnd_adg {
struct clk *adg;
struct clk *clkin[CLKINMAX];
struct clk *clkout[CLKOUTMAX];
+ /* RZ/G3E: per-SSI ADG clocks (adg-ssi-0 through adg-ssi-9) */
+ struct clk *clk_adg_ssi[ADG_SSI_MAX];
+ struct clk *clk_ssif_supply;
struct clk *null_clk;
struct clk_onecell_data onecell;
struct rsnd_mod mod;
@@ -343,8 +349,16 @@ int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate)
int rsnd_adg_ssi_clk_stop(struct rsnd_mod *ssi_mod)
{
+ struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
+ struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
+ int id = rsnd_mod_id(ssi_mod);
+
rsnd_adg_set_ssi_clk(ssi_mod, 0);
+ /* RZ/G3E: only disable here, unprepare is done in hw_free */
+ clk_disable(adg->clk_adg_ssi[id]);
+ clk_disable(adg->clk_ssif_supply);
+
return 0;
}
@@ -354,7 +368,8 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
struct device *dev = rsnd_priv_to_dev(priv);
struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
- int data;
+ int id = rsnd_mod_id(ssi_mod);
+ int ret, data;
u32 ckr = 0;
data = rsnd_adg_clk_query(priv, rate);
@@ -376,6 +391,22 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
(ckr) ? adg->brg_rate[ADG_HZ_48] :
adg->brg_rate[ADG_HZ_441]);
+ /*
+ * RZ/G3E: enable per-SSI and supply clocks
+ */
+ ret = clk_enable(adg->clk_adg_ssi[id]);
+ if (ret) {
+ dev_err(dev, "Cannot enable adg-ssi-%d ADG clock\n", id);
+ return ret;
+ }
+
+ ret = clk_enable(adg->clk_ssif_supply);
+ if (ret) {
+ dev_err(dev, "Cannot enable SSIF supply clock\n");
+ clk_disable(adg->clk_adg_ssi[id]);
+ return ret;
+ }
+
return 0;
}
@@ -417,6 +448,29 @@ int rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
}
}
+ /*
+ * rsnd_adg_clk_enable() might return error (_disable() will not).
+ * We need to rollback in such case
+ */
+ /*
+ * RZ/G3E per-SSI ADG and SSIF supply clocks.
+ *
+ * Follow the same style as for_each_rsnd_clkin() above: on enable,
+ * try to prepare every clock and accumulate the error. On disable
+ * (which is also used as the rollback path below), unprepare every
+ * clock. Absent optional clocks are NULL, for which clk_prepare()
+ * and clk_unprepare() are no-ops.
+ */
+ if (enable) {
+ for (i = 0; i < ADG_SSI_MAX; i++)
+ ret |= clk_prepare(adg->clk_adg_ssi[i]);
+ ret |= clk_prepare(adg->clk_ssif_supply);
+ } else {
+ clk_unprepare(adg->clk_ssif_supply);
+ for (i = 0; i < ADG_SSI_MAX; i++)
+ clk_unprepare(adg->clk_adg_ssi[i]);
+ }
+
/*
* rsnd_adg_clk_enable() might return error (_disable() will not).
* We need to rollback in such case
@@ -769,6 +823,31 @@ void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct seq_file *m)
#define rsnd_adg_clk_dbg_info(priv, m)
#endif
+static int rsnd_adg_get_ssi_clks(struct rsnd_priv *priv)
+{
+ struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
+ struct device *dev = rsnd_priv_to_dev(priv);
+ char name[16];
+ int i;
+
+ /* SSIF supply clock */
+ adg->clk_ssif_supply = devm_clk_get_optional(dev, "ssif_supply");
+ if (IS_ERR(adg->clk_ssif_supply))
+ return dev_err_probe(dev, PTR_ERR(adg->clk_ssif_supply),
+ "failed to get ssif_supply clock\n");
+
+ /* Per-SSI ADG clocks (RZ/G3E-only; no legacy dotted form exists) */
+ for (i = 0; i < ADG_SSI_MAX; i++) {
+ snprintf(name, sizeof(name), "adg-ssi-%d", i);
+ adg->clk_adg_ssi[i] = devm_clk_get_optional(dev, name);
+ if (IS_ERR(adg->clk_adg_ssi[i]))
+ return dev_err_probe(dev, PTR_ERR(adg->clk_adg_ssi[i]),
+ "failed to get %s clock\n", name);
+ }
+
+ return 0;
+}
+
int rsnd_adg_probe(struct rsnd_priv *priv)
{
struct reset_control *rstc;
@@ -798,6 +877,11 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
if (ret)
return ret;
+ /* RZ/G3E-specific: per-SSI ADG and SSIF supply clocks */
+ ret = rsnd_adg_get_ssi_clks(priv);
+ if (ret)
+ return ret;
+
ret = rsnd_adg_clk_enable(priv);
if (ret)
return ret;
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 13/16] ASoC: rsnd: adg: Look up RZ/G3E clkin under audio-clk{a,b,c,i}
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
` (11 preceding siblings ...)
2026-05-12 18:26 ` [PATCH v6 12/16] ASoC: rsnd: adg: Add per-SSI ADG and SSIF supply clock management John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 14/16] ASoC: rsnd: src: Add SRC reset and clock support for RZ/G3E John Madieu
` (2 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
The R-Car Sound ADG block has up to four external master-clock inputs
named CLKA, CLKB, CLKC and CLKI by the silicon. On Gen2 R-Car these
come from DT under the legacy names "clk_a", "clk_b", "clk_c", "clk_i"
defined by renesas,rsnd.yaml. Gen4 collapses them to a single "clkin".
The new standalone RZ/G3E sound binding (renesas,r9a09g047-sound.yaml)
uses the standard DT naming convention with a vendor-meaningful prefix
that matches the SoC datasheet pin labels: "audio-clka", "audio-clkb",
"audio-clkc", "audio-clki".
Add a third clkin name table for RZ/G3E and dispatch to it from
rsnd_adg_get_clkin() in the same style as the existing Gen4 branch.
The CLKA/B/C/I enum values, the clkin[] array, and the BRGA/BRGB
derivation are unchanged - only the DT lookup names differ.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6: New patch
sound/soc/renesas/rcar/adg.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/sound/soc/renesas/rcar/adg.c b/sound/soc/renesas/rcar/adg.c
index a6d34252dfea..203298b63b76 100644
--- a/sound/soc/renesas/rcar/adg.c
+++ b/sound/soc/renesas/rcar/adg.c
@@ -76,6 +76,13 @@ static const char * const clkin_name_gen2[] = {
[CLKI] = "clk_i",
};
+static const char * const clkin_name_rzg3e[] = {
+ [CLKA] = "audio-clka",
+ [CLKB] = "audio-clkb",
+ [CLKC] = "audio-clkc",
+ [CLKI] = "audio-clki",
+};
+
static const char * const clkout_name_gen2[] = {
[CLKOUT] = "audio_clkout",
[CLKOUT1] = "audio_clkout1",
@@ -536,6 +543,9 @@ static int rsnd_adg_get_clkin(struct rsnd_priv *priv)
if (rsnd_is_gen4(priv)) {
clkin_name = clkin_name_gen4;
clkin_size = ARRAY_SIZE(clkin_name_gen4);
+ } else if (rsnd_is_rzg3e(priv)) {
+ clkin_name = clkin_name_rzg3e;
+ clkin_size = ARRAY_SIZE(clkin_name_rzg3e);
}
/*
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 14/16] ASoC: rsnd: src: Add SRC reset and clock support for RZ/G3E
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
` (12 preceding siblings ...)
2026-05-12 18:26 ` [PATCH v6 13/16] ASoC: rsnd: adg: Look up RZ/G3E clkin under audio-clk{a,b,c,i} John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-13 0:44 ` Kuninori Morimoto
2026-05-12 18:26 ` [PATCH v6 15/16] ASoC: rsnd: Support unprefixed DT node names " John Madieu
2026-05-12 18:26 ` [PATCH v6 16/16] ASoC: rsnd: Add system suspend/resume support John Madieu
15 siblings, 1 reply; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
The RZ/G3E SoC requires explicit SCU (Sampling Rate Converter Unit)
reset and clock management unlike previous R-Car generations:
- scu: SCU top-level module clock (CPG_CLKON_15.CLK6_ON)
- scu_x2: SCU top-level double-rate clock (CPG_CLKON_15.CLK7_ON)
- scu_supply: SCU register-access / housekeeping clock
(CPG_CLKON_23.CLK14_ON, described by the HW manual as the system
clock for "function modules excluding SRC0-9, DVC0-1, CTU0-1 and
MIX0-1 (including the setting registers, etc.)")
Without every one of them enabled, no SCU register is reachable.
Add support for the shared SCU reset controller used by all SRC
modules on the RZ/G3E SoC and manage scu_supply with the same lifetime
as scu and scu_x2. This matches the hardware description and avoids
unnecessary clock toggling.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6:
- Use devm_clk_get_optional_enabled() for scu_supply so it has
the same lifetime as scu and scu_x2, and drop the manual
clk_prepare_enable()/clk_disable_unprepare() in
rsnd_src_init()/rsnd_src_quit(). This matches the HW
description ("system clock for function modules excluding
SRC0-9, DVC0-1, CTU0-1 and MIX0-1") and avoids unnecessary
clock toggling on each stream open/close.
- Acquire the per-SRC clock via rsnd_devm_clk_get_indexed() from
patch 04/16, so both "src-N" and the legacy "src.N" work.
- Drop the per-module name buffer and RSND_SRC_NAME_SIZE.
v5: No changes
v4:
- Move shared SCU clocks (scu, scu_x2, scu_supply) from
rsnd_priv variables into new struct rsnd_src_ctrl, following
the rsnd_dma_ctrl pattern for shared non-per-instance module
resources.
- Keep original declaration order for struct device_node *node.
v3: No changes
v2: No changes
sound/soc/renesas/rcar/rsnd.h | 1 +
sound/soc/renesas/rcar/src.c | 50 ++++++++++++++++++++++++++++++++++-
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/sound/soc/renesas/rcar/rsnd.h b/sound/soc/renesas/rcar/rsnd.h
index 186468a584fe..bdc4a99394de 100644
--- a/sound/soc/renesas/rcar/rsnd.h
+++ b/sound/soc/renesas/rcar/rsnd.h
@@ -698,6 +698,7 @@ struct rsnd_priv {
/*
* below value will be filled on rsnd_src_probe()
*/
+ void *src_ctrl;
void *src;
int src_nr;
diff --git a/sound/soc/renesas/rcar/src.c b/sound/soc/renesas/rcar/src.c
index 43abe13137bf..0237b5d2e79e 100644
--- a/sound/soc/renesas/rcar/src.c
+++ b/sound/soc/renesas/rcar/src.c
@@ -53,6 +53,14 @@ struct rsnd_src {
((pos) = (struct rsnd_src *)(priv)->src + i); \
i++)
+struct rsnd_src_ctrl {
+ struct clk *scu;
+ struct clk *scu_x2;
+ struct clk *scu_supply;
+};
+
+#define rsnd_priv_to_src_ctrl(priv) \
+ ((struct rsnd_src_ctrl *)(priv)->src_ctrl)
/*
* image of SRC (Sampling Rate Converter)
@@ -712,6 +720,8 @@ int rsnd_src_probe(struct rsnd_priv *priv)
{
struct device_node *node;
struct device *dev = rsnd_priv_to_dev(priv);
+ struct reset_control *rstc;
+ struct rsnd_src_ctrl *src_ctrl;
struct rsnd_src *src;
struct clk *clk;
int i, nr, ret;
@@ -726,6 +736,12 @@ int rsnd_src_probe(struct rsnd_priv *priv)
goto rsnd_src_probe_done;
}
+ src_ctrl = devm_kzalloc(dev, sizeof(*src_ctrl), GFP_KERNEL);
+ if (!src_ctrl) {
+ ret = -ENOMEM;
+ goto rsnd_src_probe_done;
+ }
+
src = devm_kcalloc(dev, nr, sizeof(*src), GFP_KERNEL);
if (!src) {
ret = -ENOMEM;
@@ -734,6 +750,28 @@ int rsnd_src_probe(struct rsnd_priv *priv)
priv->src_nr = nr;
priv->src = src;
+ priv->src_ctrl = src_ctrl;
+
+ src_ctrl->scu = devm_clk_get_optional_enabled(dev, "scu");
+ if (IS_ERR(src_ctrl->scu)) {
+ ret = dev_err_probe(dev, PTR_ERR(src_ctrl->scu),
+ "failed to get scu clock\n");
+ goto rsnd_src_probe_done;
+ }
+
+ src_ctrl->scu_x2 = devm_clk_get_optional_enabled(dev, "scu_x2");
+ if (IS_ERR(src_ctrl->scu_x2)) {
+ ret = dev_err_probe(dev, PTR_ERR(src_ctrl->scu_x2),
+ "failed to get scu_x2 clock\n");
+ goto rsnd_src_probe_done;
+ }
+
+ src_ctrl->scu_supply = devm_clk_get_optional_enabled(dev, "scu_supply");
+ if (IS_ERR(src_ctrl->scu_supply)) {
+ ret = dev_err_probe(dev, PTR_ERR(src_ctrl->scu_supply),
+ "failed to get scu_supply clock\n");
+ goto rsnd_src_probe_done;
+ }
i = 0;
for_each_child_of_node_scoped(node, np) {
@@ -754,6 +792,16 @@ int rsnd_src_probe(struct rsnd_priv *priv)
goto rsnd_src_probe_done;
}
+ /*
+ * RZ/G3E uses a shared SCU reset controller for all SRC modules.
+ * R-Car platforms typically don't have SRC reset controls.
+ */
+ rstc = devm_reset_control_get_optional_shared(dev, "scu");
+ if (IS_ERR(rstc)) {
+ ret = PTR_ERR(rstc);
+ goto rsnd_src_probe_done;
+ }
+
clk = rsnd_devm_clk_get_indexed(dev, SRC_NAME, i);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
@@ -761,7 +809,7 @@ int rsnd_src_probe(struct rsnd_priv *priv)
}
ret = rsnd_mod_init(priv, rsnd_mod_get(src),
- &rsnd_src_ops, clk, NULL, RSND_MOD_SRC, i);
+ &rsnd_src_ops, clk, rstc, RSND_MOD_SRC, i);
if (ret)
goto rsnd_src_probe_done;
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 15/16] ASoC: rsnd: Support unprefixed DT node names for RZ/G3E
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
` (13 preceding siblings ...)
2026-05-12 18:26 ` [PATCH v6 14/16] ASoC: rsnd: src: Add SRC reset and clock support for RZ/G3E John Madieu
@ 2026-05-12 18:26 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 16/16] ASoC: rsnd: Add system suspend/resume support John Madieu
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
The RZ/G3E device tree binding uses standard unprefixed node names
("ssi", "ssiu", "src", "dvc", "mix", "ctu") instead of the legacy
"rcar_sound," prefixed names used by R-Car bindings.
Convert rsnd_parse_of_node() from a macro into a function that tries
the legacy prefixed name first, then falls back to the unprefixed name
by stripping the "rcar_sound," prefix. This makes the driver work
transparently with both old and new bindings.
While at it, update the related comments in dma.c, ssi.c and ssiu.c
that reference the hardcoded "rcar_sound,ssiu" / "rcar_sound,ssi"
names to note that the driver now accepts both the prefixed and the
unprefixed forms.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6:
- Factor the "rcar_sound," prefix-strip into a small static
helper rsnd_node_name_strip_prefix() and call it from
rsnd_parse_of_node(), so the convention is in one place.
- Drop the of_node_name_eq() "dai" fallback that v5 added to
rsnd_dai_of_node() and rsnd_dai_probe(); not needed once
rsnd_parse_of_node() handles both forms uniformly.
v5: New patch.
sound/soc/renesas/rcar/core.c | 34 ++++++++++++++++++++++++++++++++++
sound/soc/renesas/rcar/dma.c | 8 ++++----
sound/soc/renesas/rcar/rsnd.h | 4 ++--
sound/soc/renesas/rcar/ssi.c | 8 ++++----
sound/soc/renesas/rcar/ssiu.c | 8 ++++----
5 files changed, 48 insertions(+), 14 deletions(-)
diff --git a/sound/soc/renesas/rcar/core.c b/sound/soc/renesas/rcar/core.c
index 9022f03c45d6..679c833fd001 100644
--- a/sound/soc/renesas/rcar/core.c
+++ b/sound/soc/renesas/rcar/core.c
@@ -1302,6 +1302,40 @@ rsnd_devm_reset_control_get_optional_indexed(struct device *dev,
return devm_reset_control_get_optional(dev, name);
}
+/*
+ * Strip the "rcar_sound," prefix from a legacy node name.
+ *
+ * The RZ/G3E binding uses unprefixed sub-node names (e.g. "ssi",
+ * "ssiu") while earlier R-Car bindings use the legacy "rcar_sound,*"
+ * form. This helper returns the unprefixed portion (the part after
+ * the comma) or NULL if there is no prefix.
+ *
+ * Centralising the convention here keeps every call site consistent.
+ */
+static const char *rsnd_node_name_strip_prefix(const char *name)
+{
+ const char *comma = strchr(name, ',');
+
+ return comma ? comma + 1 : NULL;
+}
+
+struct device_node *rsnd_parse_of_node(struct rsnd_priv *priv, const char *name)
+{
+ struct device_node *np = rsnd_priv_to_dev(priv)->of_node;
+ struct device_node *node;
+ const char *unprefixed;
+
+ node = of_get_child_by_name(np, name);
+ if (node)
+ return node;
+
+ unprefixed = rsnd_node_name_strip_prefix(name);
+ if (unprefixed)
+ node = of_get_child_by_name(np, unprefixed);
+
+ return node;
+}
+
static struct device_node*
rsnd_pick_endpoint_node_for_ports(struct device_node *e_ports,
struct device_node *e_port)
diff --git a/sound/soc/renesas/rcar/dma.c b/sound/soc/renesas/rcar/dma.c
index ede0123d40eb..0bca0b303191 100644
--- a/sound/soc/renesas/rcar/dma.c
+++ b/sound/soc/renesas/rcar/dma.c
@@ -794,11 +794,11 @@ static void rsnd_dma_of_path(struct rsnd_mod *this,
int nr, i, idx;
/*
- * It should use "rcar_sound,ssiu" on DT.
- * But, we need to keep compatibility for old version.
+ * It should use "rcar_sound,ssiu" (R-Car) or "ssiu" (RZ/G3E) on DT.
+ * We need to keep compatibility for old version.
*
- * If it has "rcar_sound.ssiu", it will be used.
- * If not, "rcar_sound.ssi" will be used.
+ * If it has "rcar_sound.ssiu" or "ssiu", it will be used.
+ * If not, "rcar_sound.ssi" or "ssi" will be used.
* see
* rsnd_ssiu_dma_req()
* rsnd_ssi_dma_req()
diff --git a/sound/soc/renesas/rcar/rsnd.h b/sound/soc/renesas/rcar/rsnd.h
index bdc4a99394de..1e4bc8a6c55c 100644
--- a/sound/soc/renesas/rcar/rsnd.h
+++ b/sound/soc/renesas/rcar/rsnd.h
@@ -501,8 +501,8 @@ rsnd_devm_reset_control_get_optional_indexed(struct device *dev,
/*
* DT
*/
-#define rsnd_parse_of_node(priv, node) \
- of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, node)
+struct device_node *rsnd_parse_of_node(struct rsnd_priv *priv, const char *name);
+
#define RSND_NODE_DAI "rcar_sound,dai"
#define RSND_NODE_SSI "rcar_sound,ssi"
#define RSND_NODE_SSIU "rcar_sound,ssiu"
diff --git a/sound/soc/renesas/rcar/ssi.c b/sound/soc/renesas/rcar/ssi.c
index e6734671328c..007a7c91d470 100644
--- a/sound/soc/renesas/rcar/ssi.c
+++ b/sound/soc/renesas/rcar/ssi.c
@@ -1009,11 +1009,11 @@ static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io,
char *name;
/*
- * It should use "rcar_sound,ssiu" on DT.
- * But, we need to keep compatibility for old version.
+ * It should use "rcar_sound,ssiu" (R-Car) or "ssiu" (RZ/G3E) on DT.
+ * We need to keep compatibility for old version.
*
- * If it has "rcar_sound.ssiu", it will be used.
- * If not, "rcar_sound.ssi" will be used.
+ * If it has "rcar_sound.ssiu" or "ssiu", it will be used.
+ * If not, "rcar_sound.ssi" or "ssi" will be used.
* see
* rsnd_ssiu_dma_req()
* rsnd_dma_of_path()
diff --git a/sound/soc/renesas/rcar/ssiu.c b/sound/soc/renesas/rcar/ssiu.c
index f483389868d2..8fb0ec5dc791 100644
--- a/sound/soc/renesas/rcar/ssiu.c
+++ b/sound/soc/renesas/rcar/ssiu.c
@@ -401,11 +401,11 @@ static struct dma_chan *rsnd_ssiu_dma_req(struct rsnd_dai_stream *io,
char *name;
/*
- * It should use "rcar_sound,ssiu" on DT.
- * But, we need to keep compatibility for old version.
+ * It should use "rcar_sound,ssiu" (R-Car) or "ssiu" (RZ/G3E) on DT.
+ * We need to keep compatibility for old versions.
*
- * If it has "rcar_sound.ssiu", it will be used.
- * If not, "rcar_sound.ssi" will be used.
+ * If it has "rcar_sound.ssiu" or "ssiu", it will be used.
+ * If not, "rcar_sound.ssi" or "ssi" will be used.
* see
* rsnd_ssi_dma_req()
* rsnd_dma_of_path()
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 16/16] ASoC: rsnd: Add system suspend/resume support
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
` (14 preceding siblings ...)
2026-05-12 18:26 ` [PATCH v6 15/16] ASoC: rsnd: Support unprefixed DT node names " John Madieu
@ 2026-05-12 18:26 ` John Madieu
15 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-12 18:26 UTC (permalink / raw)
To: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven, Magnus Damm,
Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu, linux-sound,
linux-renesas-soc, devicetree, linux-kernel, John Madieu
Add system suspend/resume support for the ASoC rsnd driver, required
for RZ/G3E platforms. Distribute the per-module suspend/resume work
across the relevant files (adg.c, ssi.c, ssiu.c, src.c, ctu.c, mix.c,
dvc.c, dma.c) rather than centralising it in core.c.
Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
---
Changes:
v6:
- rsnd_dma_suspend()/_resume(): respect the audmapp probe
ordering. On suspend, assert the reset before disabling the
clock; on resume, enable the clock before deasserting the
reset.
- rsnd_src_suspend()/_resume(): cache src_ctrl in a local and
add an "if (!src_ctrl) return;" early-out so platforms that
do not instantiate the SRC subsystem are safe.
v5: No changes
v4:
- Absorb rsnd_adg_mod_get() helper directly instead of a
separate preparatory patch.
- Distribute suspend/resume declarations into their respective
IP sections in rsnd.h.
v3: No changes
v2:
- Distribute suspend/resume into per-module files (ssi.c,
ssiu.c, src.c, ctu.c, mix.c, dvc.c, adg.c, dma.c) instead of
monolithic loops in core.c, following Morimoto-san's
architecture suggestion.
sound/soc/renesas/rcar/adg.c | 26 +++++++++++++++++++++
sound/soc/renesas/rcar/core.c | 43 +++++++++++++++++++++++++++++++++--
sound/soc/renesas/rcar/ctu.c | 20 ++++++++++++++++
sound/soc/renesas/rcar/dma.c | 22 ++++++++++++++++++
sound/soc/renesas/rcar/dvc.c | 20 ++++++++++++++++
sound/soc/renesas/rcar/mix.c | 20 ++++++++++++++++
sound/soc/renesas/rcar/rsnd.h | 18 +++++++++++++++
sound/soc/renesas/rcar/src.c | 34 +++++++++++++++++++++++++++
sound/soc/renesas/rcar/ssi.c | 20 ++++++++++++++++
sound/soc/renesas/rcar/ssiu.c | 20 ++++++++++++++++
10 files changed, 241 insertions(+), 2 deletions(-)
diff --git a/sound/soc/renesas/rcar/adg.c b/sound/soc/renesas/rcar/adg.c
index 203298b63b76..3d8fd66be648 100644
--- a/sound/soc/renesas/rcar/adg.c
+++ b/sound/soc/renesas/rcar/adg.c
@@ -915,3 +915,29 @@ void rsnd_adg_remove(struct rsnd_priv *priv)
/* It should be called after rsnd_adg_clk_disable() */
rsnd_adg_null_clk_clean(priv);
}
+
+static struct rsnd_mod *rsnd_adg_mod_get(struct rsnd_priv *priv)
+{
+ struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
+
+ if (!adg)
+ return NULL;
+
+ return rsnd_mod_get(adg);
+}
+
+void rsnd_adg_suspend(struct rsnd_priv *priv)
+{
+ struct rsnd_mod *mod = rsnd_adg_mod_get(priv);
+
+ if (mod)
+ rsnd_suspend_clk_reset(mod->clk, mod->rstc);
+}
+
+void rsnd_adg_resume(struct rsnd_priv *priv)
+{
+ struct rsnd_mod *mod = rsnd_adg_mod_get(priv);
+
+ if (mod)
+ rsnd_resume_clk_reset(mod->clk, mod->rstc);
+}
diff --git a/sound/soc/renesas/rcar/core.c b/sound/soc/renesas/rcar/core.c
index 679c833fd001..26cd908299e6 100644
--- a/sound/soc/renesas/rcar/core.c
+++ b/sound/soc/renesas/rcar/core.c
@@ -963,7 +963,8 @@ static int rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params,
static const struct snd_pcm_hardware rsnd_pcm_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID,
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_RESUME,
.buffer_bytes_max = 64 * 1024,
.period_bytes_min = 32,
.period_bytes_max = 8192,
@@ -2160,11 +2161,35 @@ static void rsnd_remove(struct platform_device *pdev)
remove_func[i](priv);
}
+void rsnd_suspend_clk_reset(struct clk *clk, struct reset_control *rstc)
+{
+ clk_unprepare(clk);
+ reset_control_assert(rstc);
+}
+
+void rsnd_resume_clk_reset(struct clk *clk, struct reset_control *rstc)
+{
+ reset_control_deassert(rstc);
+ clk_prepare(clk);
+}
+
static int rsnd_suspend(struct device *dev)
{
struct rsnd_priv *priv = dev_get_drvdata(dev);
+ /*
+ * Reverse order of probe:
+ * ADG -> DVC -> MIX -> CTU -> SRC -> SSIU -> SSI -> DMA
+ */
rsnd_adg_clk_disable(priv);
+ rsnd_adg_suspend(priv);
+ rsnd_dvc_suspend(priv);
+ rsnd_mix_suspend(priv);
+ rsnd_ctu_suspend(priv);
+ rsnd_src_suspend(priv);
+ rsnd_ssiu_suspend(priv);
+ rsnd_ssi_suspend(priv);
+ rsnd_dma_suspend(priv);
return 0;
}
@@ -2173,7 +2198,21 @@ static int rsnd_resume(struct device *dev)
{
struct rsnd_priv *priv = dev_get_drvdata(dev);
- return rsnd_adg_clk_enable(priv);
+ /*
+ * Same order as probe:
+ * DMA -> SSI -> SSIU -> SRC -> CTU -> MIX -> DVC -> ADG
+ */
+ rsnd_dma_resume(priv);
+ rsnd_ssi_resume(priv);
+ rsnd_ssiu_resume(priv);
+ rsnd_src_resume(priv);
+ rsnd_ctu_resume(priv);
+ rsnd_mix_resume(priv);
+ rsnd_dvc_resume(priv);
+ rsnd_adg_resume(priv);
+ rsnd_adg_clk_enable(priv);
+
+ return 0;
}
static const struct dev_pm_ops rsnd_pm_ops = {
diff --git a/sound/soc/renesas/rcar/ctu.c b/sound/soc/renesas/rcar/ctu.c
index 293b0eec1ded..7db0fb3612bc 100644
--- a/sound/soc/renesas/rcar/ctu.c
+++ b/sound/soc/renesas/rcar/ctu.c
@@ -378,3 +378,23 @@ void rsnd_ctu_remove(struct rsnd_priv *priv)
rsnd_mod_quit(rsnd_mod_get(ctu));
}
}
+
+void rsnd_ctu_suspend(struct rsnd_priv *priv)
+{
+ struct rsnd_ctu *ctu;
+ int i;
+
+ for_each_rsnd_ctu(ctu, priv, i)
+ rsnd_suspend_clk_reset(rsnd_mod_get(ctu)->clk,
+ rsnd_mod_get(ctu)->rstc);
+}
+
+void rsnd_ctu_resume(struct rsnd_priv *priv)
+{
+ struct rsnd_ctu *ctu;
+ int i;
+
+ for_each_rsnd_ctu(ctu, priv, i)
+ rsnd_resume_clk_reset(rsnd_mod_get(ctu)->clk,
+ rsnd_mod_get(ctu)->rstc);
+}
diff --git a/sound/soc/renesas/rcar/dma.c b/sound/soc/renesas/rcar/dma.c
index 0bca0b303191..0bf97a12a9a7 100644
--- a/sound/soc/renesas/rcar/dma.c
+++ b/sound/soc/renesas/rcar/dma.c
@@ -1035,3 +1035,25 @@ int rsnd_dma_probe(struct rsnd_priv *priv)
/* dummy mem mod for debug */
return rsnd_mod_init(NULL, &mem, &mem_ops, NULL, NULL, 0, 0);
}
+
+void rsnd_dma_suspend(struct rsnd_priv *priv)
+{
+ struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
+
+ if (dmac) {
+ /* Mirror probe (which enables clk before deasserting reset) */
+ rsnd_suspend_clk_reset(NULL, dmac->audmapp_rstc);
+ clk_disable_unprepare(dmac->audmapp_clk);
+ }
+}
+
+void rsnd_dma_resume(struct rsnd_priv *priv)
+{
+ struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
+
+ if (dmac) {
+ /* Clock must be stable before reset is deasserted */
+ clk_prepare_enable(dmac->audmapp_clk);
+ rsnd_resume_clk_reset(NULL, dmac->audmapp_rstc);
+ }
+}
diff --git a/sound/soc/renesas/rcar/dvc.c b/sound/soc/renesas/rcar/dvc.c
index 26f80d542da8..7601dfb0810a 100644
--- a/sound/soc/renesas/rcar/dvc.c
+++ b/sound/soc/renesas/rcar/dvc.c
@@ -381,3 +381,23 @@ void rsnd_dvc_remove(struct rsnd_priv *priv)
rsnd_mod_quit(rsnd_mod_get(dvc));
}
}
+
+void rsnd_dvc_suspend(struct rsnd_priv *priv)
+{
+ struct rsnd_dvc *dvc;
+ int i;
+
+ for_each_rsnd_dvc(dvc, priv, i)
+ rsnd_suspend_clk_reset(rsnd_mod_get(dvc)->clk,
+ rsnd_mod_get(dvc)->rstc);
+}
+
+void rsnd_dvc_resume(struct rsnd_priv *priv)
+{
+ struct rsnd_dvc *dvc;
+ int i;
+
+ for_each_rsnd_dvc(dvc, priv, i)
+ rsnd_resume_clk_reset(rsnd_mod_get(dvc)->clk,
+ rsnd_mod_get(dvc)->rstc);
+}
diff --git a/sound/soc/renesas/rcar/mix.c b/sound/soc/renesas/rcar/mix.c
index 9ffa591aa4a4..c4da4c4bedb3 100644
--- a/sound/soc/renesas/rcar/mix.c
+++ b/sound/soc/renesas/rcar/mix.c
@@ -345,3 +345,23 @@ void rsnd_mix_remove(struct rsnd_priv *priv)
rsnd_mod_quit(rsnd_mod_get(mix));
}
}
+
+void rsnd_mix_suspend(struct rsnd_priv *priv)
+{
+ struct rsnd_mix *mix;
+ int i;
+
+ for_each_rsnd_mix(mix, priv, i)
+ rsnd_suspend_clk_reset(rsnd_mod_get(mix)->clk,
+ rsnd_mod_get(mix)->rstc);
+}
+
+void rsnd_mix_resume(struct rsnd_priv *priv)
+{
+ struct rsnd_mix *mix;
+ int i;
+
+ for_each_rsnd_mix(mix, priv, i)
+ rsnd_resume_clk_reset(rsnd_mod_get(mix)->clk,
+ rsnd_mod_get(mix)->rstc);
+}
diff --git a/sound/soc/renesas/rcar/rsnd.h b/sound/soc/renesas/rcar/rsnd.h
index 1e4bc8a6c55c..7c9b2d064d50 100644
--- a/sound/soc/renesas/rcar/rsnd.h
+++ b/sound/soc/renesas/rcar/rsnd.h
@@ -267,6 +267,8 @@ u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod);
int rsnd_dma_attach(struct rsnd_dai_stream *io,
struct rsnd_mod *mod, struct rsnd_mod **dma_mod);
int rsnd_dma_probe(struct rsnd_priv *priv);
+void rsnd_dma_suspend(struct rsnd_priv *priv);
+void rsnd_dma_resume(struct rsnd_priv *priv);
struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, char *name,
struct rsnd_mod *mod, char *x);
@@ -429,6 +431,8 @@ int rsnd_mod_init(struct rsnd_priv *priv,
enum rsnd_mod_type type,
int id);
void rsnd_mod_quit(struct rsnd_mod *mod);
+void rsnd_suspend_clk_reset(struct clk *clk, struct reset_control *rstc);
+void rsnd_resume_clk_reset(struct clk *clk, struct reset_control *rstc);
struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io,
struct rsnd_mod *mod);
void rsnd_mod_interrupt(struct rsnd_mod *mod,
@@ -625,6 +629,8 @@ int rsnd_adg_ssi_clk_stop(struct rsnd_mod *ssi_mod);
int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate);
int rsnd_adg_probe(struct rsnd_priv *priv);
void rsnd_adg_remove(struct rsnd_priv *priv);
+void rsnd_adg_suspend(struct rsnd_priv *priv);
+void rsnd_adg_resume(struct rsnd_priv *priv);
int rsnd_adg_set_src_timesel_gen2(struct rsnd_mod *src_mod,
struct rsnd_dai_stream *io,
unsigned int in_rate,
@@ -822,6 +828,8 @@ extern const char * const volume_ramp_rate[];
*/
int rsnd_ssi_probe(struct rsnd_priv *priv);
void rsnd_ssi_remove(struct rsnd_priv *priv);
+void rsnd_ssi_suspend(struct rsnd_priv *priv);
+void rsnd_ssi_resume(struct rsnd_priv *priv);
struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
int rsnd_ssi_use_busif(struct rsnd_dai_stream *io);
u32 rsnd_ssi_multi_secondaries_runtime(struct rsnd_dai_stream *io);
@@ -845,6 +853,8 @@ int rsnd_ssiu_attach(struct rsnd_dai_stream *io,
struct rsnd_mod *mod);
int rsnd_ssiu_probe(struct rsnd_priv *priv);
void rsnd_ssiu_remove(struct rsnd_priv *priv);
+void rsnd_ssiu_suspend(struct rsnd_priv *priv);
+void rsnd_ssiu_resume(struct rsnd_priv *priv);
void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai,
struct device_node *playback,
struct device_node *capture);
@@ -856,6 +866,8 @@ bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod);
*/
int rsnd_src_probe(struct rsnd_priv *priv);
void rsnd_src_remove(struct rsnd_priv *priv);
+void rsnd_src_suspend(struct rsnd_priv *priv);
+void rsnd_src_resume(struct rsnd_priv *priv);
struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id);
#define rsnd_src_get_in_rate(priv, io) rsnd_src_get_rate(priv, io, 1)
@@ -875,6 +887,8 @@ unsigned int rsnd_src_get_rate(struct rsnd_priv *priv,
*/
int rsnd_ctu_probe(struct rsnd_priv *priv);
void rsnd_ctu_remove(struct rsnd_priv *priv);
+void rsnd_ctu_suspend(struct rsnd_priv *priv);
+void rsnd_ctu_resume(struct rsnd_priv *priv);
struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id);
#define rsnd_ctu_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_CTU)
#define rsnd_parse_connect_ctu(rdai, playback, capture) \
@@ -887,6 +901,8 @@ struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id);
*/
int rsnd_mix_probe(struct rsnd_priv *priv);
void rsnd_mix_remove(struct rsnd_priv *priv);
+void rsnd_mix_suspend(struct rsnd_priv *priv);
+void rsnd_mix_resume(struct rsnd_priv *priv);
struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id);
#define rsnd_mix_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_MIX)
#define rsnd_parse_connect_mix(rdai, playback, capture) \
@@ -899,6 +915,8 @@ struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id);
*/
int rsnd_dvc_probe(struct rsnd_priv *priv);
void rsnd_dvc_remove(struct rsnd_priv *priv);
+void rsnd_dvc_suspend(struct rsnd_priv *priv);
+void rsnd_dvc_resume(struct rsnd_priv *priv);
struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);
#define rsnd_dvc_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_DVC)
#define rsnd_parse_connect_dvc(rdai, playback, capture) \
diff --git a/sound/soc/renesas/rcar/src.c b/sound/soc/renesas/rcar/src.c
index 0237b5d2e79e..a84425587978 100644
--- a/sound/soc/renesas/rcar/src.c
+++ b/sound/soc/renesas/rcar/src.c
@@ -834,3 +834,37 @@ void rsnd_src_remove(struct rsnd_priv *priv)
rsnd_mod_quit(rsnd_mod_get(src));
}
}
+
+void rsnd_src_suspend(struct rsnd_priv *priv)
+{
+ struct rsnd_src_ctrl *src_ctrl = rsnd_priv_to_src_ctrl(priv);
+ struct rsnd_src *src;
+ int i;
+
+ if (!src_ctrl)
+ return;
+
+ for_each_rsnd_src(src, priv, i)
+ rsnd_suspend_clk_reset(rsnd_mod_get(src)->clk,
+ rsnd_mod_get(src)->rstc);
+
+ clk_disable_unprepare(src_ctrl->scu_x2);
+ clk_disable_unprepare(src_ctrl->scu);
+}
+
+void rsnd_src_resume(struct rsnd_priv *priv)
+{
+ struct rsnd_src_ctrl *src_ctrl = rsnd_priv_to_src_ctrl(priv);
+ struct rsnd_src *src;
+ int i;
+
+ if (!src_ctrl)
+ return;
+
+ clk_prepare_enable(src_ctrl->scu);
+ clk_prepare_enable(src_ctrl->scu_x2);
+
+ for_each_rsnd_src(src, priv, i)
+ rsnd_resume_clk_reset(rsnd_mod_get(src)->clk,
+ rsnd_mod_get(src)->rstc);
+}
diff --git a/sound/soc/renesas/rcar/ssi.c b/sound/soc/renesas/rcar/ssi.c
index 007a7c91d470..2fa76a079982 100644
--- a/sound/soc/renesas/rcar/ssi.c
+++ b/sound/soc/renesas/rcar/ssi.c
@@ -1257,3 +1257,23 @@ void rsnd_ssi_remove(struct rsnd_priv *priv)
rsnd_mod_quit(rsnd_mod_get(ssi));
}
}
+
+void rsnd_ssi_suspend(struct rsnd_priv *priv)
+{
+ struct rsnd_ssi *ssi;
+ int i;
+
+ for_each_rsnd_ssi(ssi, priv, i)
+ rsnd_suspend_clk_reset(rsnd_mod_get(ssi)->clk,
+ rsnd_mod_get(ssi)->rstc);
+}
+
+void rsnd_ssi_resume(struct rsnd_priv *priv)
+{
+ struct rsnd_ssi *ssi;
+ int i;
+
+ for_each_rsnd_ssi(ssi, priv, i)
+ rsnd_resume_clk_reset(rsnd_mod_get(ssi)->clk,
+ rsnd_mod_get(ssi)->rstc);
+}
diff --git a/sound/soc/renesas/rcar/ssiu.c b/sound/soc/renesas/rcar/ssiu.c
index 8fb0ec5dc791..60b58096531d 100644
--- a/sound/soc/renesas/rcar/ssiu.c
+++ b/sound/soc/renesas/rcar/ssiu.c
@@ -630,3 +630,23 @@ void rsnd_ssiu_remove(struct rsnd_priv *priv)
rsnd_mod_quit(rsnd_mod_get(ssiu));
}
}
+
+void rsnd_ssiu_suspend(struct rsnd_priv *priv)
+{
+ struct rsnd_ssiu *ssiu;
+ int i;
+
+ for_each_rsnd_ssiu(ssiu, priv, i)
+ rsnd_suspend_clk_reset(rsnd_mod_get(ssiu)->clk,
+ rsnd_mod_get(ssiu)->rstc);
+}
+
+void rsnd_ssiu_resume(struct rsnd_priv *priv)
+{
+ struct rsnd_ssiu *ssiu;
+ int i;
+
+ for_each_rsnd_ssiu(ssiu, priv, i)
+ rsnd_resume_clk_reset(rsnd_mod_get(ssiu)->clk,
+ rsnd_mod_get(ssiu)->rstc);
+}
--
2.25.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v6 09/16] ASoC: rsnd: ssui: Add RZ/G3E SSIU BUSIF support
2026-05-12 18:26 ` [PATCH v6 09/16] ASoC: rsnd: ssui: Add RZ/G3E SSIU BUSIF support John Madieu
@ 2026-05-13 0:35 ` Kuninori Morimoto
2026-05-13 5:04 ` John Madieu
2026-05-13 9:41 ` Geert Uytterhoeven
1 sibling, 1 reply; 22+ messages in thread
From: Kuninori Morimoto @ 2026-05-13 0:35 UTC (permalink / raw)
To: John Madieu
Cc: Mark Brown, Liam Girdwood, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven,
Magnus Damm, Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu,
linux-sound, linux-renesas-soc, devicetree, linux-kernel
Hi John
Thank you for the patch
> Add support for the SSIU found on the Renesas RZ/G3E SoC, which
> provides a different BUSIF layout compared to earlier generations:
>
> - SSI0-SSI4: 4 BUSIF instances each (BUSIF0-3)
> - SSI5-SSI8: 1 BUSIF instance each (BUSIF0 only)
> - SSI9: 4 BUSIF instances (BUSIF0-3)
> - Total: 28 BUSIFs
>
> RZ/G3E also differs from Gen2/Gen3 implementations in that only two
> pairs of BUSIF error-status registers are available instead of four,
> and the SSI always operates in BUSIF mode with no PIO fallback.
>
> Rather than scattering SoC-specific checks across functional code,
> introduce an extra capability flags in the match data:
>
> - RSND_SSIU_BUSIF_STATUS_COUNT_2: only two BUSIF error-status
> register pairs are present. Used in rsnd_ssiu_busif_err_irq_ctrl()
> and rsnd_ssiu_busif_err_status_clear() to limit register iteration.
>
> Future SoCs sharing these constraints can set the flags without
> requiring code changes.
>
> Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> ---
If my understanding was correct, this patch includes 3 features ?
- adding busif_status_count
- adding rag3e_id
- adding rstc
I guess these can be separated ?
Thank you for your help !!
Best regards
---
Kuninori Morimoto
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v6 14/16] ASoC: rsnd: src: Add SRC reset and clock support for RZ/G3E
2026-05-12 18:26 ` [PATCH v6 14/16] ASoC: rsnd: src: Add SRC reset and clock support for RZ/G3E John Madieu
@ 2026-05-13 0:44 ` Kuninori Morimoto
2026-05-13 5:17 ` John Madieu
0 siblings, 1 reply; 22+ messages in thread
From: Kuninori Morimoto @ 2026-05-13 0:44 UTC (permalink / raw)
To: John Madieu
Cc: Mark Brown, Liam Girdwood, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven,
Magnus Damm, Philipp Zabel, Claudiu Beznea, Biju Das, john.madieu,
linux-sound, linux-renesas-soc, devicetree, linux-kernel
Hi John
Thank you for the patch
> The RZ/G3E SoC requires explicit SCU (Sampling Rate Converter Unit)
> reset and clock management unlike previous R-Car generations:
>
> - scu: SCU top-level module clock (CPG_CLKON_15.CLK6_ON)
> - scu_x2: SCU top-level double-rate clock (CPG_CLKON_15.CLK7_ON)
> - scu_supply: SCU register-access / housekeeping clock
> (CPG_CLKON_23.CLK14_ON, described by the HW manual as the system
> clock for "function modules excluding SRC0-9, DVC0-1, CTU0-1 and
> MIX0-1 (including the setting registers, etc.)")
>
> Without every one of them enabled, no SCU register is reachable.
> Add support for the shared SCU reset controller used by all SRC
> modules on the RZ/G3E SoC and manage scu_supply with the same lifetime
> as scu and scu_x2. This matches the hardware description and avoids
> unnecessary clock toggling.
>
> Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> ---
I guess this patch has 2 features.
(A) add rsnd_src_ctrl
(B) add rstc
These are independent ?
And in (A), I guess no one is using scu_supply ?
If it is just for lifetime, and is necessary, could you please add such
comment ?
(A) can be merged into [16/16] ? or be as "prepare patch".
Thank you for your help !!
Best regards
---
Kuninori Morimoto
^ permalink raw reply [flat|nested] 22+ messages in thread
* RE: [PATCH v6 09/16] ASoC: rsnd: ssui: Add RZ/G3E SSIU BUSIF support
2026-05-13 0:35 ` Kuninori Morimoto
@ 2026-05-13 5:04 ` John Madieu
0 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-13 5:04 UTC (permalink / raw)
To: Kuninori Morimoto
Cc: Mark Brown, Liam Girdwood, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven,
magnus.damm, Philipp Zabel, Claudiu.Beznea, Biju Das,
john.madieu@gmail.com, linux-sound@vger.kernel.org,
linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
Hi Kuninori,
Thanks for your review.
> -----Original Message-----
> From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> Sent: Mittwoch, 13. Mai 2026 02:35
> To: John Madieu <john.madieu.xa@bp.renesas.com>
> Subject: Re: [PATCH v6 09/16] ASoC: rsnd: ssui: Add RZ/G3E SSIU BUSIF
> support
>
>
> Hi John
>
> Thank you for the patch
>
> > Add support for the SSIU found on the Renesas RZ/G3E SoC, which
> > provides a different BUSIF layout compared to earlier generations:
> >
> > - SSI0-SSI4: 4 BUSIF instances each (BUSIF0-3)
> > - SSI5-SSI8: 1 BUSIF instance each (BUSIF0 only)
> > - SSI9: 4 BUSIF instances (BUSIF0-3)
> > - Total: 28 BUSIFs
> >
> > RZ/G3E also differs from Gen2/Gen3 implementations in that only two
> > pairs of BUSIF error-status registers are available instead of four,
> > and the SSI always operates in BUSIF mode with no PIO fallback.
> >
> > Rather than scattering SoC-specific checks across functional code,
> > introduce an extra capability flags in the match data:
> >
> > - RSND_SSIU_BUSIF_STATUS_COUNT_2: only two BUSIF error-status
> > register pairs are present. Used in rsnd_ssiu_busif_err_irq_ctrl()
> > and rsnd_ssiu_busif_err_status_clear() to limit register iteration.
> >
> > Future SoCs sharing these constraints can set the flags without
> > requiring code changes.
> >
> > Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> > ---
>
> If my understanding was correct, this patch includes 3 features ?
>
> - adding busif_status_count
> - adding rag3e_id
> - adding rstc
>
> I guess these can be separated ?
You are right, three things are happening here. I will split them as:
09a/N: ASoC: rsnd: ssiu: Add shared SSI reset controller support
- just the devm_reset_control_get_optional_shared("ssi-all") in
rsnd_ssiu_probe() and passing it to rsnd_mod_init().
- No-op for non-RZ/G3E DTs.
09b/N: ASoC: rsnd: ssiu: Add RZ/G3E BUSIF support
- introduces struct rsnd_ssiu_ctrl with busif_status_count and
parametrises the loops in rsnd_ssiu_busif_err_irq_ctrl() and
rsnd_ssiu_busif_err_status_clear().
- adds the rzg3e_id[] BUSIF index table and the SSI_MODE0 guard.
- sets RSND_SSIU_BUSIF_STATUS_COUNT_2 in the r9a09g047 match data.
I am keeping busif_status_count and rzg3e_id together because they are
both keyed on RZ/G3E and form one feature ("RZ/G3E SSIU BUSIF layout").
Splitting them would leave an intermediate state where the BUSIF index
table and the error-status loop bound disagree on the SoC. Please let me
know if you would prefer them as two separate patches anyway, then I
will do a three-way split with the busif_status_count refactor placed
first as a no-behavior-change preparation.
Regards,
John
^ permalink raw reply [flat|nested] 22+ messages in thread
* RE: [PATCH v6 14/16] ASoC: rsnd: src: Add SRC reset and clock support for RZ/G3E
2026-05-13 0:44 ` Kuninori Morimoto
@ 2026-05-13 5:17 ` John Madieu
0 siblings, 0 replies; 22+ messages in thread
From: John Madieu @ 2026-05-13 5:17 UTC (permalink / raw)
To: Kuninori Morimoto
Cc: Mark Brown, Liam Girdwood, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jaroslav Kysela, Takashi Iwai, Geert Uytterhoeven,
magnus.damm, Philipp Zabel, Claudiu.Beznea, Biju Das,
john.madieu@gmail.com, linux-sound@vger.kernel.org,
linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
Hi Kuninori,
Thanks fort he review.
> -----Original Message-----
> From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> Sent: Mittwoch, 13. Mai 2026 02:45
> To: John Madieu <john.madieu.xa@bp.renesas.com>
> Subject: Re: [PATCH v6 14/16] ASoC: rsnd: src: Add SRC reset and clock
> support for RZ/G3E
>
>
> Hi John
>
> Thank you for the patch
>
> > The RZ/G3E SoC requires explicit SCU (Sampling Rate Converter Unit)
> > reset and clock management unlike previous R-Car generations:
> >
> > - scu: SCU top-level module clock (CPG_CLKON_15.CLK6_ON)
> > - scu_x2: SCU top-level double-rate clock (CPG_CLKON_15.CLK7_ON)
> > - scu_supply: SCU register-access / housekeeping clock
> > (CPG_CLKON_23.CLK14_ON, described by the HW manual as the system
> > clock for "function modules excluding SRC0-9, DVC0-1, CTU0-1 and
> > MIX0-1 (including the setting registers, etc.)")
> >
> > Without every one of them enabled, no SCU register is reachable.
> > Add support for the shared SCU reset controller used by all SRC
> > modules on the RZ/G3E SoC and manage scu_supply with the same lifetime
> > as scu and scu_x2. This matches the hardware description and avoids
> > unnecessary clock toggling.
> >
> > Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> > ---
>
> I guess this patch has 2 features.
>
> (A) add rsnd_src_ctrl
> (B) add rstc
>
> These are independent ?
Yes, fully independent. I will split:
14a/N: ASoC: rsnd: src: Acquire shared SCU clocks for RZ/G3E
- introduces struct rsnd_src_ctrl with scu/scu_x2/scu_supply.
- uses devm_clk_get_optional_enabled(), so non-RZ/G3E DTs are
unaffected.
14b/N: ASoC: rsnd: src: Add SRC reset support for RZ/G3E
- per-SRC devm_reset_control_get_optional_shared("scu") and
rsnd_mod_init() plumbing only.
>
> And in (A), I guess no one is using scu_supply ?
> If it is just for lifetime, and is necessary, could you please add such
> comment ?
Correct, scu_supply is only acquired for its devm-managed enabled
lifetime; nothing reads src_ctrl->scu_supply after probe. Per the HW
manual scu_supply is the SCU register-access / housekeeping clock, so it
must stay enabled while the device is bound, including across system
suspend, otherwise no SCU register is reachable. The suspend path
deliberately gates only scu and scu_x2 for the same reason. I will add
this comment next to the acquisition in 14a/N.
>
> (A) can be merged into [16/16] ? or be as "prepare patch".
I will make (A) a preparation patch (14a/N above). Folding it into 16/16
would mix clock acquisition into the PM patch, and the SCU clocks need
to be enabled at probe so SCU registers are reachable before any
suspend/resume cycle.
Regards,
John
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v6 09/16] ASoC: rsnd: ssui: Add RZ/G3E SSIU BUSIF support
2026-05-12 18:26 ` [PATCH v6 09/16] ASoC: rsnd: ssui: Add RZ/G3E SSIU BUSIF support John Madieu
2026-05-13 0:35 ` Kuninori Morimoto
@ 2026-05-13 9:41 ` Geert Uytterhoeven
1 sibling, 0 replies; 22+ messages in thread
From: Geert Uytterhoeven @ 2026-05-13 9:41 UTC (permalink / raw)
To: John Madieu
Cc: Kuninori Morimoto, Mark Brown, Liam Girdwood, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
Geert Uytterhoeven, Magnus Damm, Philipp Zabel, Claudiu Beznea,
Biju Das, john.madieu, linux-sound, linux-renesas-soc, devicetree,
linux-kernel
Hi John,
On Tue, 12 May 2026 at 20:28, John Madieu <john.madieu.xa@bp.renesas.com> wrote:
> Add support for the SSIU found on the Renesas RZ/G3E SoC, which
> provides a different BUSIF layout compared to earlier generations:
>
> - SSI0-SSI4: 4 BUSIF instances each (BUSIF0-3)
> - SSI5-SSI8: 1 BUSIF instance each (BUSIF0 only)
> - SSI9: 4 BUSIF instances (BUSIF0-3)
> - Total: 28 BUSIFs
>
> RZ/G3E also differs from Gen2/Gen3 implementations in that only two
> pairs of BUSIF error-status registers are available instead of four,
> and the SSI always operates in BUSIF mode with no PIO fallback.
>
> Rather than scattering SoC-specific checks across functional code,
> introduce an extra capability flags in the match data:
>
> - RSND_SSIU_BUSIF_STATUS_COUNT_2: only two BUSIF error-status
> register pairs are present. Used in rsnd_ssiu_busif_err_irq_ctrl()
> and rsnd_ssiu_busif_err_status_clear() to limit register iteration.
>
> Future SoCs sharing these constraints can set the flags without
> requiring code changes.
>
> Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
Thanks for your patch!
> --- a/sound/soc/renesas/rcar/core.c
> +++ b/sound/soc/renesas/rcar/core.c
> @@ -107,7 +107,8 @@ static const struct of_device_id rsnd_of_match[] = {
> { .compatible = "renesas,rcar_sound-gen4", .data = (void *)RSND_GEN4 },
> /* Special Handling */
> { .compatible = "renesas,rcar_sound-r8a77990", .data = (void *)(RSND_GEN3 | RSND_SOC_E) },
> - { .compatible = "renesas,r9a09g047-sound", .data = (void *)(RSND_RZ3 | RSND_RZG3E) },
> + { .compatible = "renesas,r9a09g047-sound", .data = (void *)(RSND_RZ3 | RSND_RZG3E |
> + RSND_SSIU_BUSIF_STATUS_COUNT_2) },
Nit: please split the line after the comma instead of after the pipe character.
> {},
> };
> MODULE_DEVICE_TABLE(of, rsnd_of_match);
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] 22+ messages in thread
end of thread, other threads:[~2026-05-13 9:50 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-12 18:26 [PATCH v6 00/16] ASoC: rsnd: Add RZ/G3E audio driver support John Madieu
2026-05-12 18:26 ` [PATCH v6 01/16] ASoC: dt-bindings: sound: Add DT binding for RZ/G3E sound John Madieu
2026-05-12 18:26 ` [PATCH v6 02/16] ASoC: rsnd: Fix RSND_SOC_MASK width to single nibble John Madieu
2026-05-12 18:26 ` [PATCH v6 03/16] ASoC: rsnd: Add reset controller support to rsnd_mod John Madieu
2026-05-12 18:26 ` [PATCH v6 04/16] ASoC: rsnd: Support hyphen or dot in indexed clock and reset names John Madieu
2026-05-12 18:26 ` [PATCH v6 05/16] ASoC: rsnd: Add RZ/G3E SoC probing and register map John Madieu
2026-05-12 18:26 ` [PATCH v6 06/16] ASoC: rsnd: Add audmacpp clock and reset support for RZ/G3E John Madieu
2026-05-12 18:26 ` [PATCH v6 07/16] ASoC: rsnd: Refactor DMA address tables with named structs John Madieu
2026-05-12 18:26 ` [PATCH v6 08/16] ASoC: rsnd: Add RZ/G3E DMA address calculation support John Madieu
2026-05-12 18:26 ` [PATCH v6 09/16] ASoC: rsnd: ssui: Add RZ/G3E SSIU BUSIF support John Madieu
2026-05-13 0:35 ` Kuninori Morimoto
2026-05-13 5:04 ` John Madieu
2026-05-13 9:41 ` Geert Uytterhoeven
2026-05-12 18:26 ` [PATCH v6 10/16] ASoC: rsnd: Add SSI reset support for RZ/G3E platform John Madieu
2026-05-12 18:26 ` [PATCH v6 11/16] ASoC: rsnd: Add ADG reset support for RZ/G3E John Madieu
2026-05-12 18:26 ` [PATCH v6 12/16] ASoC: rsnd: adg: Add per-SSI ADG and SSIF supply clock management John Madieu
2026-05-12 18:26 ` [PATCH v6 13/16] ASoC: rsnd: adg: Look up RZ/G3E clkin under audio-clk{a,b,c,i} John Madieu
2026-05-12 18:26 ` [PATCH v6 14/16] ASoC: rsnd: src: Add SRC reset and clock support for RZ/G3E John Madieu
2026-05-13 0:44 ` Kuninori Morimoto
2026-05-13 5:17 ` John Madieu
2026-05-12 18:26 ` [PATCH v6 15/16] ASoC: rsnd: Support unprefixed DT node names " John Madieu
2026-05-12 18:26 ` [PATCH v6 16/16] ASoC: rsnd: Add system suspend/resume support John Madieu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox