[PATCH v6 08/16] ASoC: rsnd: Add RZ/G3E DMA address calculation support
From: John Madieu
Date: Tue May 12 2026 - 14:33:00 EST
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@xxxxxxxxxxxxxx>
---
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