dmaengine: sun4i: Add support for cyclic requests with dedicated DMA
Currently the cyclic transfers can be used only with normal DMAs. They can be used by pcm_dmaengine module, which is required for implementing sound with sun4i-hdmi encoder. This is so because the controller can accept audio only from a dedicated DMA. This patch enables them, following the existing style for the scatter/gather type transfers. Signed-off-by: Stefan Mavrodiev <stefan@olimex.com> Acked-by: Maxime Ripard <mripard@kernel.org> Link: https://lore.kernel.org/r/20200110141140.28527-2-stefan@olimex.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Родитель
4b04817885
Коммит
ffc079a4ac
|
@ -669,43 +669,41 @@ sun4i_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf, size_t len,
|
||||||
dma_addr_t src, dest;
|
dma_addr_t src, dest;
|
||||||
u32 endpoints;
|
u32 endpoints;
|
||||||
int nr_periods, offset, plength, i;
|
int nr_periods, offset, plength, i;
|
||||||
|
u8 ram_type, io_mode, linear_mode;
|
||||||
|
|
||||||
if (!is_slave_direction(dir)) {
|
if (!is_slave_direction(dir)) {
|
||||||
dev_err(chan2dev(chan), "Invalid DMA direction\n");
|
dev_err(chan2dev(chan), "Invalid DMA direction\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vchan->is_dedicated) {
|
|
||||||
/*
|
|
||||||
* As we are using this just for audio data, we need to use
|
|
||||||
* normal DMA. There is nothing stopping us from supporting
|
|
||||||
* dedicated DMA here as well, so if a client comes up and
|
|
||||||
* requires it, it will be simple to implement it.
|
|
||||||
*/
|
|
||||||
dev_err(chan2dev(chan),
|
|
||||||
"Cyclic transfers are only supported on Normal DMA\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
contract = generate_dma_contract();
|
contract = generate_dma_contract();
|
||||||
if (!contract)
|
if (!contract)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
contract->is_cyclic = 1;
|
contract->is_cyclic = 1;
|
||||||
|
|
||||||
/* Figure out the endpoints and the address we need */
|
if (vchan->is_dedicated) {
|
||||||
|
io_mode = SUN4I_DDMA_ADDR_MODE_IO;
|
||||||
|
linear_mode = SUN4I_DDMA_ADDR_MODE_LINEAR;
|
||||||
|
ram_type = SUN4I_DDMA_DRQ_TYPE_SDRAM;
|
||||||
|
} else {
|
||||||
|
io_mode = SUN4I_NDMA_ADDR_MODE_IO;
|
||||||
|
linear_mode = SUN4I_NDMA_ADDR_MODE_LINEAR;
|
||||||
|
ram_type = SUN4I_NDMA_DRQ_TYPE_SDRAM;
|
||||||
|
}
|
||||||
|
|
||||||
if (dir == DMA_MEM_TO_DEV) {
|
if (dir == DMA_MEM_TO_DEV) {
|
||||||
src = buf;
|
src = buf;
|
||||||
dest = sconfig->dst_addr;
|
dest = sconfig->dst_addr;
|
||||||
endpoints = SUN4I_DMA_CFG_SRC_DRQ_TYPE(SUN4I_NDMA_DRQ_TYPE_SDRAM) |
|
endpoints = SUN4I_DMA_CFG_DST_DRQ_TYPE(vchan->endpoint) |
|
||||||
SUN4I_DMA_CFG_DST_DRQ_TYPE(vchan->endpoint) |
|
SUN4I_DMA_CFG_DST_ADDR_MODE(io_mode) |
|
||||||
SUN4I_DMA_CFG_DST_ADDR_MODE(SUN4I_NDMA_ADDR_MODE_IO);
|
SUN4I_DMA_CFG_SRC_DRQ_TYPE(ram_type);
|
||||||
} else {
|
} else {
|
||||||
src = sconfig->src_addr;
|
src = sconfig->src_addr;
|
||||||
dest = buf;
|
dest = buf;
|
||||||
endpoints = SUN4I_DMA_CFG_SRC_DRQ_TYPE(vchan->endpoint) |
|
endpoints = SUN4I_DMA_CFG_DST_DRQ_TYPE(ram_type) |
|
||||||
SUN4I_DMA_CFG_SRC_ADDR_MODE(SUN4I_NDMA_ADDR_MODE_IO) |
|
SUN4I_DMA_CFG_SRC_DRQ_TYPE(vchan->endpoint) |
|
||||||
SUN4I_DMA_CFG_DST_DRQ_TYPE(SUN4I_NDMA_DRQ_TYPE_SDRAM);
|
SUN4I_DMA_CFG_SRC_ADDR_MODE(io_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -747,8 +745,13 @@ sun4i_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf, size_t len,
|
||||||
dest = buf + offset;
|
dest = buf + offset;
|
||||||
|
|
||||||
/* Make the promise */
|
/* Make the promise */
|
||||||
promise = generate_ndma_promise(chan, src, dest,
|
if (vchan->is_dedicated)
|
||||||
plength, sconfig, dir);
|
promise = generate_ddma_promise(chan, src, dest,
|
||||||
|
plength, sconfig);
|
||||||
|
else
|
||||||
|
promise = generate_ndma_promise(chan, src, dest,
|
||||||
|
plength, sconfig, dir);
|
||||||
|
|
||||||
if (!promise) {
|
if (!promise) {
|
||||||
/* TODO: should we free everything? */
|
/* TODO: should we free everything? */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче