|
@@ -222,9 +222,9 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
|
|
|
enum dma_slave_buswidth dev_width;
|
|
|
u32 burst;
|
|
|
struct scatterlist *sg;
|
|
|
- int i;
|
|
|
int acnt, bcnt, ccnt, src, dst, cidx;
|
|
|
int src_bidx, dst_bidx, src_cidx, dst_cidx;
|
|
|
+ int i, nslots;
|
|
|
|
|
|
if (unlikely(!echan || !sgl || !sg_len))
|
|
|
return NULL;
|
|
@@ -262,8 +262,10 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
|
|
|
|
|
|
edesc->pset_nr = sg_len;
|
|
|
|
|
|
- for_each_sg(sgl, sg, sg_len, i) {
|
|
|
- /* Allocate a PaRAM slot, if needed */
|
|
|
+ /* Allocate a PaRAM slot, if needed */
|
|
|
+ nslots = min_t(unsigned, MAX_NR_SG, sg_len);
|
|
|
+
|
|
|
+ for (i = 0; i < nslots; i++) {
|
|
|
if (echan->slot[i] < 0) {
|
|
|
echan->slot[i] =
|
|
|
edma_alloc_slot(EDMA_CTLR(echan->ch_num),
|
|
@@ -273,6 +275,10 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
|
|
|
return NULL;
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Configure PaRAM sets for each SG */
|
|
|
+ for_each_sg(sgl, sg, sg_len, i) {
|
|
|
|
|
|
acnt = dev_width;
|
|
|
|
|
@@ -330,6 +336,12 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
|
|
|
/* Configure A or AB synchronized transfers */
|
|
|
if (edesc->absync)
|
|
|
edesc->pset[i].opt |= SYNCDIM;
|
|
|
+
|
|
|
+ /* If this is the last in a current SG set of transactions,
|
|
|
+ enable interrupts so that next set is processed */
|
|
|
+ if (!((i+1) % MAX_NR_SG))
|
|
|
+ edesc->pset[i].opt |= TCINTEN;
|
|
|
+
|
|
|
/* If this is the last set, enable completion interrupt flag */
|
|
|
if (i == sg_len - 1)
|
|
|
edesc->pset[i].opt |= TCINTEN;
|