]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: rsnd: Add RZ/G3E DMA address calculation support
authorJohn Madieu <john.madieu.xa@bp.renesas.com>
Mon, 25 May 2026 11:02:20 +0000 (11:02 +0000)
committerMark Brown <broonie@kernel.org>
Mon, 1 Jun 2026 14:30:18 +0000 (15:30 +0100)
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>
Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://patch.msgid.link/20260525110230.4014435-9-john.madieu.xa@bp.renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/renesas/rcar/dma.c

index 0ce77eee338da7b39bcee5b5a13287158753fbbd..92974610ac153df8d274bc6e2aeb3de528a51e29 100644 (file)
@@ -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);
 }