Skip to content

Commit a482f4e

Browse files
jognessVinod Koul
authored andcommitted
dmaengine: edma: special case slot limit workaround
Currently drivers are limited to 19 slots for cyclic transfers. However, if the DMA burst size is the same as the period size, the period size can be changed to the full buffer size and intermediate interrupts activated. Since intermediate interrupts will trigger for each burst and the burst size is the same as the period size, the driver will get interrupts each period as expected. This has the benefit of allowing the functionality of many more slots, but only uses 2 slots. This workaround is only active if more than 19 slots are needed and the burst size matches the period size. Acked-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Signed-off-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Sekhar Nori <nsekhar@ti.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
1 parent 23f49fd commit a482f4e

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

drivers/dma/edma.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
12381238
struct edma_desc *edesc;
12391239
dma_addr_t src_addr, dst_addr;
12401240
enum dma_slave_buswidth dev_width;
1241+
bool use_intermediate = false;
12411242
u32 burst;
12421243
int i, ret, nslots;
12431244

@@ -1279,8 +1280,21 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
12791280
* but the synchronization is difficult to achieve with Cyclic and
12801281
* cannot be guaranteed, so we error out early.
12811282
*/
1282-
if (nslots > MAX_NR_SG)
1283-
return NULL;
1283+
if (nslots > MAX_NR_SG) {
1284+
/*
1285+
* If the burst and period sizes are the same, we can put
1286+
* the full buffer into a single period and activate
1287+
* intermediate interrupts. This will produce interrupts
1288+
* after each burst, which is also after each desired period.
1289+
*/
1290+
if (burst == period_len) {
1291+
period_len = buf_len;
1292+
nslots = 2;
1293+
use_intermediate = true;
1294+
} else {
1295+
return NULL;
1296+
}
1297+
}
12841298

12851299
edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]),
12861300
GFP_ATOMIC);
@@ -1358,8 +1372,13 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
13581372
/*
13591373
* Enable period interrupt only if it is requested
13601374
*/
1361-
if (tx_flags & DMA_PREP_INTERRUPT)
1375+
if (tx_flags & DMA_PREP_INTERRUPT) {
13621376
edesc->pset[i].param.opt |= TCINTEN;
1377+
1378+
/* Also enable intermediate interrupts if necessary */
1379+
if (use_intermediate)
1380+
edesc->pset[i].param.opt |= ITCINTEN;
1381+
}
13631382
}
13641383

13651384
/* Place the cyclic channel to highest priority queue */

0 commit comments

Comments
 (0)