diff options
author | Shengjiu Wang <shengjiu.wang@nxp.com> | 2018-01-23 13:28:05 +0800 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | bb4258bafba2c01f27816a7a1dc26baf386636ce (patch) | |
tree | 8ec5d4e71c45c95dbc45031252d72f428da4e0e8 /drivers/dma | |
parent | eb968dee63e383b8a78f60c22c393dc92978158e (diff) |
MLK-16224-5: dma: imx-sdma: support mulit fifo script
The type IMX_DMATYPE_MULTI_SAI is used for SAI multi-fifo mode,
in this mode, the fifo num parameter is configured through
dma_slave_config
The watermark definition is:
bit0~7: wartermark level
bit8~11: fifo number
bit16~19: fifo offset
bit27~24: sw done selector
bit23: sw done enabled
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Reviewed-by: Robin Gong<yibin.gong@nxp.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/imx-sdma.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 4ddf03369cb8..d31d744336e7 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -193,6 +193,10 @@ BIT(DMA_MEM_TO_DEV) | \ BIT(DMA_DEV_TO_DEV)) +#define SDMA_WATERMARK_LEVEL_FIFOS_OFF 8 +#define SDMA_WATERMARK_LEVEL_SW_DONE BIT(23) +#define SDMA_WATERMARK_LEVEL_SW_DONE_SEL_OFF 24 + /* * Mode/Count of data node descriptors - IPCv2 */ @@ -358,6 +362,7 @@ struct sdma_channel { u32 bd_size_sum; bool src_dualfifo; bool dst_dualfifo; + unsigned int fifo_num; struct dma_pool *bd_pool; }; @@ -970,6 +975,9 @@ static void sdma_get_pc(struct sdma_channel *sdmac, case IMX_DMATYPE_HDMI: emi_2_per = sdma->script_addrs->hdmi_dma_addr; break; + case IMX_DMATYPE_MULTI_SAI: + per_2_emi = sdma->script_addrs->sai_2_mcu_addr; + emi_2_per = sdma->script_addrs->mcu_2_sai_addr; default: break; } @@ -1132,6 +1140,20 @@ static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac) sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_DD; } +static void sdma_set_watermarklevel_for_sais(struct sdma_channel *sdmac) +{ + sdmac->watermark_level &= ~(0xFFF << SDMA_WATERMARK_LEVEL_FIFOS_OFF | + SDMA_WATERMARK_LEVEL_SW_DONE); + + /* For fifo_num + * bit 0-7 is the fifo number; + * bit 8-11 is the fifo offset, + * so here only need to shift left fifo_num 8 bit for watermake_level + */ + sdmac->watermark_level |= sdmac->fifo_num<< + SDMA_WATERMARK_LEVEL_FIFOS_OFF; +} + static int sdma_config_channel(struct dma_chan *chan) { struct sdma_channel *sdmac = to_sdma_chan(chan); @@ -1181,6 +1203,9 @@ static int sdma_config_channel(struct dma_chan *chan) sdmac->direction == DMA_MEM_TO_DEV && sdmac->sdma->drvdata == &sdma_imx6ul) __set_bit(31, &sdmac->watermark_level); + else if (sdmac->peripheral_type == + IMX_DMATYPE_MULTI_SAI) + sdma_set_watermarklevel_for_sais(sdmac); __set_bit(sdmac->event_id0, sdmac->event_mask); } @@ -1776,12 +1801,14 @@ static int sdma_config(struct dma_chan *chan, struct dma_slave_config *dmaengine_cfg) { struct sdma_channel *sdmac = to_sdma_chan(chan); - + /* clear watermark_level before setting */ + sdmac->watermark_level = 0; if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) { sdmac->per_address = dmaengine_cfg->src_addr; sdmac->watermark_level = dmaengine_cfg->src_maxburst * dmaengine_cfg->src_addr_width; sdmac->word_size = dmaengine_cfg->src_addr_width; + sdmac->fifo_num = dmaengine_cfg->src_fifo_num; } else if (dmaengine_cfg->direction == DMA_DEV_TO_DEV) { sdmac->per_address2 = dmaengine_cfg->src_addr; sdmac->per_address = dmaengine_cfg->dst_addr; @@ -1801,6 +1828,7 @@ static int sdma_config(struct dma_chan *chan, sdmac->watermark_level = dmaengine_cfg->dst_maxburst * dmaengine_cfg->dst_addr_width; sdmac->word_size = dmaengine_cfg->dst_addr_width; + sdmac->fifo_num = dmaengine_cfg->dst_fifo_num; } sdmac->direction = dmaengine_cfg->direction; return sdma_config_channel(chan); |