diff options
author | Robin Gong <yibin.gong@nxp.com> | 2017-07-04 16:04:36 +0800 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | 70219f0374dfb577af1d4a8a611a7e21f0bca34c (patch) | |
tree | 15412f00ed28218b03fa6642c8318d0265fe81a3 | |
parent | 71832a52a20e6b88cfcd44f6ccb9a07b75d30cc7 (diff) |
MLK-15330-3 dma: fsl-edma-v3: add dual fifo support
There is Audio dual fifo cause that fill fifo one by one and
loop back after every minor loop:
-- fill the first 32bit width fifo
-- fill the next 32bit width fifo
-- +MLOFF signed offset after the above two FIFOs filled
-- loop back to the first step to handle the next minor loop.
Signed-off-by: Robin Gong <yibin.gong@nxp.com>
-rw-r--r-- | Documentation/devicetree/bindings/dma/fsl-edma-v3.txt | 2 | ||||
-rw-r--r-- | drivers/dma/fsl-edma-v3.c | 29 |
2 files changed, 29 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt b/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt index 9c84de7e402c..222ccf8605b0 100644 --- a/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt +++ b/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt @@ -22,6 +22,8 @@ Required properties: 0: transmit, 1: receive. BIT(1): local or remote access: 0: local, 1: remote. + BIT(2): dualfifo case or not(only in Audio cyclic now): + 0: not dual fifo case, 1: dualfifo case. See the SoC's reference manual for all the supported request sources. - dma-channels : Number of channels supported by the controller diff --git a/drivers/dma/fsl-edma-v3.c b/drivers/dma/fsl-edma-v3.c index 20126a867dec..ef8280e0f2e1 100644 --- a/drivers/dma/fsl-edma-v3.c +++ b/drivers/dma/fsl-edma-v3.c @@ -78,6 +78,9 @@ #define EDMA_TCD_SOFF_SOFF(x) (x) #define EDMA_TCD_NBYTES_NBYTES(x) (x) +#define EDMA_TCD_NBYTES_MLOFF(x) (x << 10) +#define EDMA_TCD_NBYTES_DMLOE (1 << 30) +#define EDMA_TCD_NBYTES_SMLOE (1 << 31) #define EDMA_TCD_SLAST_SLAST(x) (x) #define EDMA_TCD_DADDR_DADDR(x) (x) #define EDMA_TCD_CITER_CITER(x) ((x) & 0x7FFF) @@ -102,6 +105,7 @@ #define ARGS_RX BIT(0) #define ARGS_REMOTE BIT(1) +#define ARGS_DFIFO BIT(2) struct fsl_edma3_hw_tcd { __le32 saddr; @@ -143,6 +147,7 @@ struct fsl_edma3_chan { int priority; int is_rxchan; int is_remote; + int is_dfifo; struct dma_pool *tcd_pool; u32 chn_real_count; char txirq_name[32]; @@ -454,6 +459,19 @@ void fsl_edma3_fill_tcd(struct fsl_edma3_chan *fsl_chan, tcd->soff = cpu_to_le16(EDMA_TCD_SOFF_SOFF(soff)); + if (fsl_chan->is_dfifo) { + /* set mloff as -8 */ + nbytes |= EDMA_TCD_NBYTES_MLOFF(-8); + /* enable DMLOE/SMLOE */ + if (fsl_chan->fsc.dir == DMA_MEM_TO_DEV) { + nbytes |= EDMA_TCD_NBYTES_DMLOE; + nbytes &= ~EDMA_TCD_NBYTES_SMLOE; + } else { + nbytes |= EDMA_TCD_NBYTES_SMLOE; + nbytes &= ~EDMA_TCD_NBYTES_DMLOE; + } + } + tcd->nbytes = cpu_to_le32(EDMA_TCD_NBYTES_NBYTES(nbytes)); tcd->slast = cpu_to_le32(EDMA_TCD_SLAST_SLAST(slast)); @@ -540,11 +558,17 @@ static struct dma_async_tx_descriptor *fsl_edma3_prep_dma_cyclic( src_addr = dma_buf_next; dst_addr = fsl_chan->fsc.dev_addr; soff = fsl_chan->fsc.addr_width; - doff = 0; + if (fsl_chan->is_dfifo) + doff = 4; + else + doff = 0; } else if (fsl_chan->fsc.dir == DMA_DEV_TO_MEM) { src_addr = fsl_chan->fsc.dev_addr; dst_addr = dma_buf_next; - soff = 0; + if (fsl_chan->is_dfifo) + soff = 4; + else + soff = 0; doff = fsl_chan->fsc.addr_width; } else { /* DMA_DEV_TO_DEV */ @@ -715,6 +739,7 @@ static struct dma_chan *fsl_edma3_xlate(struct of_phandle_args *dma_spec, fsl_chan->priority = dma_spec->args[1]; fsl_chan->is_rxchan = dma_spec->args[2] & ARGS_RX; fsl_chan->is_remote = dma_spec->args[2] & ARGS_REMOTE; + fsl_chan->is_dfifo = dma_spec->args[2] & ARGS_DFIFO; mutex_unlock(&fsl_edma3->fsl_edma3_mutex); return chan; } |