Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad32d0c7 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown
Browse files

ASoC: rsnd: add rsnd_gen_dma_addr() for DMAC addr



The DMAC src/dst addr needs to be set from driver when DT case.
(It was set from SoC/DMAEngine code when non-DT case)
This patch adds rsnd_gen_dma_addr() to set DMAC src/dst addr.

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent 199e7688
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -358,10 +358,7 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
		return -EIO;
	}

	cfg.slave_id	= id;
	cfg.dst_addr	= 0; /* use default addr when playback */
	cfg.src_addr	= 0; /* use default addr when capture */
	cfg.direction	= is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
	rsnd_gen_dma_addr(priv, dma, &cfg, is_play, id);

	ret = dmaengine_slave_config(dma->chan, &cfg);
	if (ret < 0)
+95 −0
Original line number Diff line number Diff line
@@ -155,6 +155,101 @@ static int rsnd_gen_regmap_init(struct rsnd_priv *priv,
	return 0;
}

/*
 *	DMA read/write register offset
 *
 *	RSND_xxx_I_N	for Audio DMAC input
 *	RSND_xxx_O_N	for Audio DMAC output
 *	RSND_xxx_I_P	for Audio DMAC peri peri input
 *	RSND_xxx_O_P	for Audio DMAC peri peri output
 *
 *	ex) R-Car H2 case
 *	      mod        / DMAC in    / DMAC out   / DMAC PP in / DMAC pp out
 *	SSI : 0xec541000 / 0xec241008 / 0xec24100c / 0xec400000 / 0xec400000
 *	SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
 *	CMD : 0xec500000 / 0xec008000                             0xec308000
 */
#define RDMA_SSI_I_N(addr, i)	(addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
#define RDMA_SSI_O_N(addr, i)	(addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)

#define RDMA_SSI_I_P(addr, i)	(addr ##_reg - 0x00141000 + (0x1000 * i))
#define RDMA_SSI_O_P(addr, i)	(addr ##_reg - 0x00141000 + (0x1000 * i))

#define RDMA_SRC_I_N(addr, i)	(addr ##_reg - 0x00500000 + (0x400 * i))
#define RDMA_SRC_O_N(addr, i)	(addr ##_reg - 0x004fc000 + (0x400 * i))

#define RDMA_SRC_I_P(addr, i)	(addr ##_reg - 0x00200000 + (0x400 * i))
#define RDMA_SRC_O_P(addr, i)	(addr ##_reg - 0x001fc000 + (0x400 * i))

#define RDMA_CMD_O_N(addr, i)	(addr ##_reg - 0x004f8000 + (0x400 * i))
#define RDMA_CMD_O_P(addr, i)	(addr ##_reg - 0x001f8000 + (0x400 * i))

void rsnd_gen_dma_addr(struct rsnd_priv *priv,
		       struct rsnd_dma *dma,
		       struct dma_slave_config *cfg,
		       int is_play, int slave_id)
{
	struct platform_device *pdev = rsnd_priv_to_pdev(priv);
	struct device *dev = rsnd_priv_to_dev(priv);
	struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
	dma_addr_t ssi_reg = platform_get_resource(pdev,
				IORESOURCE_MEM, RSND_GEN2_SSI)->start;
	dma_addr_t src_reg = platform_get_resource(pdev,
				IORESOURCE_MEM, RSND_GEN2_SCU)->start;
	int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
	int use_src = !!rsnd_io_to_mod_src(io);
	int use_dvc = !!rsnd_io_to_mod_dvc(io);
	int id = rsnd_mod_id(mod);
	struct dma_addr {
		dma_addr_t src_addr;
		dma_addr_t dst_addr;
	} dma_addrs[2][2][3] = {
		{ /* SRC */
			/* Capture */
			{{ 0,				0 },
			 { RDMA_SRC_O_N(src, id),	0 },
			 { RDMA_CMD_O_N(src, id),	0 }},
			/* Playback */
			{{ 0,				0, },
			 { 0,				RDMA_SRC_I_N(src, id) },
			 { 0,				RDMA_SRC_I_N(src, id) }}
		}, { /* SSI */
			/* Capture */
			{{ RDMA_SSI_O_N(ssi, id),	0 },
			 { RDMA_SSI_O_P(ssi, id),	RDMA_SRC_I_P(src, id) },
			 { RDMA_SSI_O_P(ssi, id),	RDMA_SRC_I_P(src, id) }},
			/* Playback */
			{{ 0,				RDMA_SSI_I_N(ssi, id) },
			 { RDMA_SRC_O_P(src, id),	RDMA_SSI_I_P(ssi, id) },
			 { RDMA_CMD_O_P(src, id),	RDMA_SSI_I_P(ssi, id) }}
		}
	};

	cfg->slave_id	= slave_id;
	cfg->src_addr	= 0;
	cfg->dst_addr	= 0;
	cfg->direction	= is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;

	/*
	 * gen1 uses default DMA addr
	 */
	if (rsnd_is_gen1(priv))
		return;

	/* it shouldn't happen */
	if (use_dvc & !use_src) {
		dev_err(dev, "DVC is selected without SRC\n");
		return;
	}

	cfg->src_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].src_addr;
	cfg->dst_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].dst_addr;

	dev_dbg(dev, "dma%d addr - src : %x / dst : %x\n",
		id, cfg->src_addr, cfg->dst_addr);
}

/*
 *		Gen2
 */
+5 −0
Original line number Diff line number Diff line
@@ -281,6 +281,11 @@ int rsnd_gen_probe(struct platform_device *pdev,
void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
			       struct rsnd_mod *mod,
			       enum rsnd_reg reg);
void rsnd_gen_dma_addr(struct rsnd_priv *priv,
		       struct rsnd_dma *dma,
		       struct dma_slave_config *cfg,
		       int is_play,  int slave_id);

#define rsnd_is_gen1(s)		(((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1)
#define rsnd_is_gen2(s)		(((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2)