aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/edma.c
diff options
context:
space:
mode:
authorJoel Fernandes <joelf@ti.com>2013-08-29 19:05:40 -0400
committerVinod Koul <vinod.koul@intel.com>2013-09-04 09:08:46 -0400
commit6fbe24da828ff344372c38441156caefc4a51b3e (patch)
treef457417afa566d215ddb564bf926d4779b6f2ea9 /drivers/dma/edma.c
parentbd127639f43ed00f721b403c7c252caa19d0f613 (diff)
dma: edma: Setup parameters to DMA MAX_NR_SG at a time
Changes are made here for configuring existing parameters to support DMA'ing them out in batches as needed. Also allocate as many as slots as needed by the SG list, but not more than MAX_NR_SG. Then these slots will be reused accordingly. For ex, if MAX_NR_SG=10, and number of SG entries is 40, still only 10 slots will be allocated to DMA the entire SG list of size 40. Also enable TC interrupts for slots that are a last in a current iteration, or that fall on a MAX_NR_SG boundary. Signed-off-by: Joel Fernandes <joelf@ti.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/edma.c')
-rw-r--r--drivers/dma/edma.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 4f6d87bcaa0d..f9075129d27c 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -222,9 +222,9 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
222 enum dma_slave_buswidth dev_width; 222 enum dma_slave_buswidth dev_width;
223 u32 burst; 223 u32 burst;
224 struct scatterlist *sg; 224 struct scatterlist *sg;
225 int i;
226 int acnt, bcnt, ccnt, src, dst, cidx; 225 int acnt, bcnt, ccnt, src, dst, cidx;
227 int src_bidx, dst_bidx, src_cidx, dst_cidx; 226 int src_bidx, dst_bidx, src_cidx, dst_cidx;
227 int i, nslots;
228 228
229 if (unlikely(!echan || !sgl || !sg_len)) 229 if (unlikely(!echan || !sgl || !sg_len))
230 return NULL; 230 return NULL;
@@ -262,8 +262,10 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
262 262
263 edesc->pset_nr = sg_len; 263 edesc->pset_nr = sg_len;
264 264
265 for_each_sg(sgl, sg, sg_len, i) { 265 /* Allocate a PaRAM slot, if needed */
266 /* Allocate a PaRAM slot, if needed */ 266 nslots = min_t(unsigned, MAX_NR_SG, sg_len);
267
268 for (i = 0; i < nslots; i++) {
267 if (echan->slot[i] < 0) { 269 if (echan->slot[i] < 0) {
268 echan->slot[i] = 270 echan->slot[i] =
269 edma_alloc_slot(EDMA_CTLR(echan->ch_num), 271 edma_alloc_slot(EDMA_CTLR(echan->ch_num),
@@ -273,6 +275,10 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
273 return NULL; 275 return NULL;
274 } 276 }
275 } 277 }
278 }
279
280 /* Configure PaRAM sets for each SG */
281 for_each_sg(sgl, sg, sg_len, i) {
276 282
277 acnt = dev_width; 283 acnt = dev_width;
278 284
@@ -330,6 +336,12 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
330 /* Configure A or AB synchronized transfers */ 336 /* Configure A or AB synchronized transfers */
331 if (edesc->absync) 337 if (edesc->absync)
332 edesc->pset[i].opt |= SYNCDIM; 338 edesc->pset[i].opt |= SYNCDIM;
339
340 /* If this is the last in a current SG set of transactions,
341 enable interrupts so that next set is processed */
342 if (!((i+1) % MAX_NR_SG))
343 edesc->pset[i].opt |= TCINTEN;
344
333 /* If this is the last set, enable completion interrupt flag */ 345 /* If this is the last set, enable completion interrupt flag */
334 if (i == sg_len - 1) 346 if (i == sg_len - 1)
335 edesc->pset[i].opt |= TCINTEN; 347 edesc->pset[i].opt |= TCINTEN;