summaryrefslogtreecommitdiff
path: root/sound/soc/sh/rcar/dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sh/rcar/dma.c')
-rw-r--r--sound/soc/sh/rcar/dma.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 463ab237d7bd..1c494e521463 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -653,22 +653,54 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
dma_addrs[is_ssi][is_play][use_src + use_cmd].in_addr;
}
+/*
+ * Gen4 DMA read/write register offset
+ *
+ * ex) R-Car V4H case
+ * mod / SYS-DMAC in / SYS-DMAC out
+ * SSI_SDMC: 0xec400000 / 0xec400000 / 0xec400000
+ */
+#define RDMA_SSI_SDMC(addr, i) (addr + (0x8000 * i))
+static dma_addr_t
+rsnd_gen4_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 addr = rsnd_gen_get_phy_addr(priv, RSND_GEN4_SDMC);
+ int id = rsnd_mod_id(mod);
+ int busif = rsnd_mod_id_sub(mod);
+
+ /*
+ * SSI0 only is supported
+ */
+ if (id != 0) {
+ struct device *dev = rsnd_priv_to_dev(priv);
+
+ dev_err(dev, "This driver doesn't support non SSI0");
+ return -EINVAL;
+ }
+
+ return RDMA_SSI_SDMC(addr, busif);
+}
+
static dma_addr_t rsnd_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);
+ if (!mod)
+ return 0;
+
/*
* gen1 uses default DMA addr
*/
if (rsnd_is_gen1(priv))
return 0;
-
- if (!mod)
- return 0;
-
- return rsnd_gen2_dma_addr(io, mod, is_play, is_from);
+ else if (rsnd_is_gen4(priv))
+ return rsnd_gen4_dma_addr(io, mod, is_play, is_from);
+ else
+ return rsnd_gen2_dma_addr(io, mod, is_play, is_from);
}
#define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */
@@ -885,19 +917,28 @@ int rsnd_dma_probe(struct rsnd_priv *priv)
/*
* for Gen2 or later
*/
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp");
dmac = devm_kzalloc(dev, sizeof(*dmac), GFP_KERNEL);
- if (!dmac || !res) {
+ if (!dmac) {
dev_err(dev, "dma allocate failed\n");
return 0; /* it will be PIO mode */
}
+ /* for Gen4 doesn't have DMA-pp */
+ if (rsnd_is_gen4(priv))
+ goto audmapp_end;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp");
+ if (!res) {
+ dev_err(dev, "lack of audmapp in DT\n");
+ return 0; /* it will be PIO mode */
+ }
+
dmac->dmapp_num = 0;
dmac->ppres = res->start;
dmac->ppbase = devm_ioremap_resource(dev, res);
if (IS_ERR(dmac->ppbase))
return PTR_ERR(dmac->ppbase);
-
+audmapp_end:
priv->dma = dmac;
/* dummy mem mod for debug */