提交 e0c7ea83 编写于 作者: S Shengjiu Wang 提交者: Vinod Koul

dmaengine: imx-sdma: Add FIFO stride support for multi FIFO script

The peripheral may have several FIFOs, but some case just select
some FIFOs from them for data transfer, which means FIFO0 and FIFO2
may be selected. So add FIFO address stride support, 0 means all FIFOs
are continuous, 1 means 1 word stride between FIFOs. All stride between
FIFOs should be same.

Another option words_per_fifo means how many audio channel data copied
to one FIFO one time, 1 means one channel per FIFO, 2 means 2 channels
per FIFO.

If 'n_fifos_src =  4' and 'words_per_fifo = 2', it means the first two
words(channels) fetch from FIFO0 and then jump to FIFO1 for next two words,
and so on after the last FIFO3 fetched, roll back to FIFO0.
Signed-off-by: NJoy Zou <joy.zou@nxp.com>
Signed-off-by: NShengjiu Wang <shengjiu.wang@nxp.com>
Link: https://lore.kernel.org/r/1657162829-9273-1-git-send-email-shengjiu.wang@nxp.comSigned-off-by: NVinod Koul <vkoul@kernel.org>
上级 d0b55afa
...@@ -183,6 +183,8 @@ ...@@ -183,6 +183,8 @@
BIT(DMA_DEV_TO_DEV)) BIT(DMA_DEV_TO_DEV))
#define SDMA_WATERMARK_LEVEL_N_FIFOS GENMASK(15, 12) #define SDMA_WATERMARK_LEVEL_N_FIFOS GENMASK(15, 12)
#define SDMA_WATERMARK_LEVEL_OFF_FIFOS GENMASK(19, 16)
#define SDMA_WATERMARK_LEVEL_WORDS_PER_FIFO GENMASK(31, 28)
#define SDMA_WATERMARK_LEVEL_SW_DONE BIT(23) #define SDMA_WATERMARK_LEVEL_SW_DONE BIT(23)
#define SDMA_DONE0_CONFIG_DONE_SEL BIT(7) #define SDMA_DONE0_CONFIG_DONE_SEL BIT(7)
...@@ -429,6 +431,9 @@ struct sdma_desc { ...@@ -429,6 +431,9 @@ struct sdma_desc {
* @n_fifos_src: number of source device fifos * @n_fifos_src: number of source device fifos
* @n_fifos_dst: number of destination device fifos * @n_fifos_dst: number of destination device fifos
* @sw_done: software done flag * @sw_done: software done flag
* @stride_fifos_src: stride for source device FIFOs
* @stride_fifos_dst: stride for destination device FIFOs
* @words_per_fifo: copy number of words one time for one FIFO
*/ */
struct sdma_channel { struct sdma_channel {
struct virt_dma_chan vc; struct virt_dma_chan vc;
...@@ -456,6 +461,9 @@ struct sdma_channel { ...@@ -456,6 +461,9 @@ struct sdma_channel {
bool is_ram_script; bool is_ram_script;
unsigned int n_fifos_src; unsigned int n_fifos_src;
unsigned int n_fifos_dst; unsigned int n_fifos_dst;
unsigned int stride_fifos_src;
unsigned int stride_fifos_dst;
unsigned int words_per_fifo;
bool sw_done; bool sw_done;
}; };
...@@ -1245,17 +1253,29 @@ static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac) ...@@ -1245,17 +1253,29 @@ static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
static void sdma_set_watermarklevel_for_sais(struct sdma_channel *sdmac) static void sdma_set_watermarklevel_for_sais(struct sdma_channel *sdmac)
{ {
unsigned int n_fifos; unsigned int n_fifos;
unsigned int stride_fifos;
unsigned int words_per_fifo;
if (sdmac->sw_done) if (sdmac->sw_done)
sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_SW_DONE; sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_SW_DONE;
if (sdmac->direction == DMA_DEV_TO_MEM) if (sdmac->direction == DMA_DEV_TO_MEM) {
n_fifos = sdmac->n_fifos_src; n_fifos = sdmac->n_fifos_src;
else stride_fifos = sdmac->stride_fifos_src;
} else {
n_fifos = sdmac->n_fifos_dst; n_fifos = sdmac->n_fifos_dst;
stride_fifos = sdmac->stride_fifos_dst;
}
words_per_fifo = sdmac->words_per_fifo;
sdmac->watermark_level |= sdmac->watermark_level |=
FIELD_PREP(SDMA_WATERMARK_LEVEL_N_FIFOS, n_fifos); FIELD_PREP(SDMA_WATERMARK_LEVEL_N_FIFOS, n_fifos);
sdmac->watermark_level |=
FIELD_PREP(SDMA_WATERMARK_LEVEL_OFF_FIFOS, stride_fifos);
if (words_per_fifo)
sdmac->watermark_level |=
FIELD_PREP(SDMA_WATERMARK_LEVEL_WORDS_PER_FIFO, (words_per_fifo - 1));
} }
static int sdma_config_channel(struct dma_chan *chan) static int sdma_config_channel(struct dma_chan *chan)
...@@ -1769,6 +1789,9 @@ static int sdma_config(struct dma_chan *chan, ...@@ -1769,6 +1789,9 @@ static int sdma_config(struct dma_chan *chan,
} }
sdmac->n_fifos_src = sdmacfg->n_fifos_src; sdmac->n_fifos_src = sdmacfg->n_fifos_src;
sdmac->n_fifos_dst = sdmacfg->n_fifos_dst; sdmac->n_fifos_dst = sdmacfg->n_fifos_dst;
sdmac->stride_fifos_src = sdmacfg->stride_fifos_src;
sdmac->stride_fifos_dst = sdmacfg->stride_fifos_dst;
sdmac->words_per_fifo = sdmacfg->words_per_fifo;
sdmac->sw_done = sdmacfg->sw_done; sdmac->sw_done = sdmacfg->sw_done;
} }
......
...@@ -70,6 +70,16 @@ static inline int imx_dma_is_general_purpose(struct dma_chan *chan) ...@@ -70,6 +70,16 @@ static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
* struct sdma_peripheral_config - SDMA config for audio * struct sdma_peripheral_config - SDMA config for audio
* @n_fifos_src: Number of FIFOs for recording * @n_fifos_src: Number of FIFOs for recording
* @n_fifos_dst: Number of FIFOs for playback * @n_fifos_dst: Number of FIFOs for playback
* @stride_fifos_src: FIFO address stride for recording, 0 means all FIFOs are
* continuous, 1 means 1 word stride between FIFOs. All stride
* between FIFOs should be same.
* @stride_fifos_dst: FIFO address stride for playback
* @words_per_fifo: numbers of words per FIFO fetch/fill, 1 means
* one channel per FIFO, 2 means 2 channels per FIFO..
* If 'n_fifos_src = 4' and 'words_per_fifo = 2', it
* means the first two words(channels) fetch from FIFO0
* and then jump to FIFO1 for next two words, and so on
* after the last FIFO3 fetched, roll back to FIFO0.
* @sw_done: Use software done. Needed for PDM (micfil) * @sw_done: Use software done. Needed for PDM (micfil)
* *
* Some i.MX Audio devices (SAI, micfil) have multiple successive FIFO * Some i.MX Audio devices (SAI, micfil) have multiple successive FIFO
...@@ -82,6 +92,9 @@ static inline int imx_dma_is_general_purpose(struct dma_chan *chan) ...@@ -82,6 +92,9 @@ static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
struct sdma_peripheral_config { struct sdma_peripheral_config {
int n_fifos_src; int n_fifos_src;
int n_fifos_dst; int n_fifos_dst;
int stride_fifos_src;
int stride_fifos_dst;
int words_per_fifo;
bool sw_done; bool sw_done;
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册