Skip to content

Commit e0c7ea8

Browse files
TE-N-ShengjiuWangvinodkoul
authored andcommitted
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: Joy Zou <[email protected]> Signed-off-by: Shengjiu Wang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent d0b55af commit e0c7ea8

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

drivers/dma/imx-sdma.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@
183183
BIT(DMA_DEV_TO_DEV))
184184

185185
#define SDMA_WATERMARK_LEVEL_N_FIFOS GENMASK(15, 12)
186+
#define SDMA_WATERMARK_LEVEL_OFF_FIFOS GENMASK(19, 16)
187+
#define SDMA_WATERMARK_LEVEL_WORDS_PER_FIFO GENMASK(31, 28)
186188
#define SDMA_WATERMARK_LEVEL_SW_DONE BIT(23)
187189

188190
#define SDMA_DONE0_CONFIG_DONE_SEL BIT(7)
@@ -429,6 +431,9 @@ struct sdma_desc {
429431
* @n_fifos_src: number of source device fifos
430432
* @n_fifos_dst: number of destination device fifos
431433
* @sw_done: software done flag
434+
* @stride_fifos_src: stride for source device FIFOs
435+
* @stride_fifos_dst: stride for destination device FIFOs
436+
* @words_per_fifo: copy number of words one time for one FIFO
432437
*/
433438
struct sdma_channel {
434439
struct virt_dma_chan vc;
@@ -456,6 +461,9 @@ struct sdma_channel {
456461
bool is_ram_script;
457462
unsigned int n_fifos_src;
458463
unsigned int n_fifos_dst;
464+
unsigned int stride_fifos_src;
465+
unsigned int stride_fifos_dst;
466+
unsigned int words_per_fifo;
459467
bool sw_done;
460468
};
461469

@@ -1245,17 +1253,29 @@ static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
12451253
static void sdma_set_watermarklevel_for_sais(struct sdma_channel *sdmac)
12461254
{
12471255
unsigned int n_fifos;
1256+
unsigned int stride_fifos;
1257+
unsigned int words_per_fifo;
12481258

12491259
if (sdmac->sw_done)
12501260
sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_SW_DONE;
12511261

1252-
if (sdmac->direction == DMA_DEV_TO_MEM)
1262+
if (sdmac->direction == DMA_DEV_TO_MEM) {
12531263
n_fifos = sdmac->n_fifos_src;
1254-
else
1264+
stride_fifos = sdmac->stride_fifos_src;
1265+
} else {
12551266
n_fifos = sdmac->n_fifos_dst;
1267+
stride_fifos = sdmac->stride_fifos_dst;
1268+
}
1269+
1270+
words_per_fifo = sdmac->words_per_fifo;
12561271

12571272
sdmac->watermark_level |=
12581273
FIELD_PREP(SDMA_WATERMARK_LEVEL_N_FIFOS, n_fifos);
1274+
sdmac->watermark_level |=
1275+
FIELD_PREP(SDMA_WATERMARK_LEVEL_OFF_FIFOS, stride_fifos);
1276+
if (words_per_fifo)
1277+
sdmac->watermark_level |=
1278+
FIELD_PREP(SDMA_WATERMARK_LEVEL_WORDS_PER_FIFO, (words_per_fifo - 1));
12591279
}
12601280

12611281
static int sdma_config_channel(struct dma_chan *chan)
@@ -1769,6 +1789,9 @@ static int sdma_config(struct dma_chan *chan,
17691789
}
17701790
sdmac->n_fifos_src = sdmacfg->n_fifos_src;
17711791
sdmac->n_fifos_dst = sdmacfg->n_fifos_dst;
1792+
sdmac->stride_fifos_src = sdmacfg->stride_fifos_src;
1793+
sdmac->stride_fifos_dst = sdmacfg->stride_fifos_dst;
1794+
sdmac->words_per_fifo = sdmacfg->words_per_fifo;
17721795
sdmac->sw_done = sdmacfg->sw_done;
17731796
}
17741797

include/linux/dma/imx-dma.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
7070
* struct sdma_peripheral_config - SDMA config for audio
7171
* @n_fifos_src: Number of FIFOs for recording
7272
* @n_fifos_dst: Number of FIFOs for playback
73+
* @stride_fifos_src: FIFO address stride for recording, 0 means all FIFOs are
74+
* continuous, 1 means 1 word stride between FIFOs. All stride
75+
* between FIFOs should be same.
76+
* @stride_fifos_dst: FIFO address stride for playback
77+
* @words_per_fifo: numbers of words per FIFO fetch/fill, 1 means
78+
* one channel per FIFO, 2 means 2 channels per FIFO..
79+
* If 'n_fifos_src = 4' and 'words_per_fifo = 2', it
80+
* means the first two words(channels) fetch from FIFO0
81+
* and then jump to FIFO1 for next two words, and so on
82+
* after the last FIFO3 fetched, roll back to FIFO0.
7383
* @sw_done: Use software done. Needed for PDM (micfil)
7484
*
7585
* 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)
8292
struct sdma_peripheral_config {
8393
int n_fifos_src;
8494
int n_fifos_dst;
95+
int stride_fifos_src;
96+
int stride_fifos_dst;
97+
int words_per_fifo;
8598
bool sw_done;
8699
};
87100

0 commit comments

Comments
 (0)