aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/edma.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2014-04-28 15:23:55 -0400
committerVinod Koul <vinod.koul@intel.com>2014-04-30 01:03:42 -0400
commitb5088ad9630c0aa477a4ed57747b8b3fa8e4b86b (patch)
tree8c6562f8da89ccf5df4ec000fb771813b5daf3f8 /drivers/dma/edma.c
parentde135939716dcdc8a6ea62e9228feb2eec0fca11 (diff)
dmaengine: edma: Create private pset struct
Preparatory patch to support finer grained accounting. Move the edma_params array out of edma_desc so we can add further per pset data to it. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> [joelf@ti.com: Fixed up hunk #3 in original patch to apply] 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.c67
1 files changed, 36 insertions, 31 deletions
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index cfc267e819eb..c6f60e9af8af 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -57,6 +57,10 @@
57#define EDMA_MAX_SLOTS MAX_NR_SG 57#define EDMA_MAX_SLOTS MAX_NR_SG
58#define EDMA_DESCRIPTORS 16 58#define EDMA_DESCRIPTORS 16
59 59
60struct edma_pset {
61 struct edmacc_param param;
62};
63
60struct edma_desc { 64struct edma_desc {
61 struct virt_dma_desc vdesc; 65 struct virt_dma_desc vdesc;
62 struct list_head node; 66 struct list_head node;
@@ -65,7 +69,7 @@ struct edma_desc {
65 int pset_nr; 69 int pset_nr;
66 int processed; 70 int processed;
67 u32 residue; 71 u32 residue;
68 struct edmacc_param pset[0]; 72 struct edma_pset pset[0];
69}; 73};
70 74
71struct edma_cc; 75struct edma_cc;
@@ -141,7 +145,7 @@ static void edma_execute(struct edma_chan *echan)
141 /* Write descriptor PaRAM set(s) */ 145 /* Write descriptor PaRAM set(s) */
142 for (i = 0; i < nslots; i++) { 146 for (i = 0; i < nslots; i++) {
143 j = i + edesc->processed; 147 j = i + edesc->processed;
144 edma_write_slot(echan->slot[i], &edesc->pset[j]); 148 edma_write_slot(echan->slot[i], &edesc->pset[j].param);
145 dev_vdbg(echan->vchan.chan.device->dev, 149 dev_vdbg(echan->vchan.chan.device->dev,
146 "\n pset[%d]:\n" 150 "\n pset[%d]:\n"
147 " chnum\t%d\n" 151 " chnum\t%d\n"
@@ -155,14 +159,14 @@ static void edma_execute(struct edma_chan *echan)
155 " cidx\t%08x\n" 159 " cidx\t%08x\n"
156 " lkrld\t%08x\n", 160 " lkrld\t%08x\n",
157 j, echan->ch_num, echan->slot[i], 161 j, echan->ch_num, echan->slot[i],
158 edesc->pset[j].opt, 162 edesc->pset[j].param.opt,
159 edesc->pset[j].src, 163 edesc->pset[j].param.src,
160 edesc->pset[j].dst, 164 edesc->pset[j].param.dst,
161 edesc->pset[j].a_b_cnt, 165 edesc->pset[j].param.a_b_cnt,
162 edesc->pset[j].ccnt, 166 edesc->pset[j].param.ccnt,
163 edesc->pset[j].src_dst_bidx, 167 edesc->pset[j].param.src_dst_bidx,
164 edesc->pset[j].src_dst_cidx, 168 edesc->pset[j].param.src_dst_cidx,
165 edesc->pset[j].link_bcntrld); 169 edesc->pset[j].param.link_bcntrld);
166 /* Link to the previous slot if not the last set */ 170 /* Link to the previous slot if not the last set */
167 if (i != (nslots - 1)) 171 if (i != (nslots - 1))
168 edma_link(echan->slot[i], echan->slot[i+1]); 172 edma_link(echan->slot[i], echan->slot[i+1]);
@@ -305,13 +309,14 @@ static int edma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
305 * @dma_length: Total length of the DMA transfer 309 * @dma_length: Total length of the DMA transfer
306 * @direction: Direction of the transfer 310 * @direction: Direction of the transfer
307 */ 311 */
308static int edma_config_pset(struct dma_chan *chan, struct edmacc_param *pset, 312static int edma_config_pset(struct dma_chan *chan, struct edma_pset *epset,
309 dma_addr_t src_addr, dma_addr_t dst_addr, u32 burst, 313 dma_addr_t src_addr, dma_addr_t dst_addr, u32 burst,
310 enum dma_slave_buswidth dev_width, unsigned int dma_length, 314 enum dma_slave_buswidth dev_width, unsigned int dma_length,
311 enum dma_transfer_direction direction) 315 enum dma_transfer_direction direction)
312{ 316{
313 struct edma_chan *echan = to_edma_chan(chan); 317 struct edma_chan *echan = to_edma_chan(chan);
314 struct device *dev = chan->device->dev; 318 struct device *dev = chan->device->dev;
319 struct edmacc_param *param = &epset->param;
315 int acnt, bcnt, ccnt, cidx; 320 int acnt, bcnt, ccnt, cidx;
316 int src_bidx, dst_bidx, src_cidx, dst_cidx; 321 int src_bidx, dst_bidx, src_cidx, dst_cidx;
317 int absync; 322 int absync;
@@ -391,26 +396,26 @@ static int edma_config_pset(struct dma_chan *chan, struct edmacc_param *pset,
391 return -EINVAL; 396 return -EINVAL;
392 } 397 }
393 398
394 pset->opt = EDMA_TCC(EDMA_CHAN_SLOT(echan->ch_num)); 399 param->opt = EDMA_TCC(EDMA_CHAN_SLOT(echan->ch_num));
395 /* Configure A or AB synchronized transfers */ 400 /* Configure A or AB synchronized transfers */
396 if (absync) 401 if (absync)
397 pset->opt |= SYNCDIM; 402 param->opt |= SYNCDIM;
398 403
399 pset->src = src_addr; 404 param->src = src_addr;
400 pset->dst = dst_addr; 405 param->dst = dst_addr;
401 406
402 pset->src_dst_bidx = (dst_bidx << 16) | src_bidx; 407 param->src_dst_bidx = (dst_bidx << 16) | src_bidx;
403 pset->src_dst_cidx = (dst_cidx << 16) | src_cidx; 408 param->src_dst_cidx = (dst_cidx << 16) | src_cidx;
404 409
405 pset->a_b_cnt = bcnt << 16 | acnt; 410 param->a_b_cnt = bcnt << 16 | acnt;
406 pset->ccnt = ccnt; 411 param->ccnt = ccnt;
407 /* 412 /*
408 * Only time when (bcntrld) auto reload is required is for 413 * Only time when (bcntrld) auto reload is required is for
409 * A-sync case, and in this case, a requirement of reload value 414 * A-sync case, and in this case, a requirement of reload value
410 * of SZ_64K-1 only is assured. 'link' is initially set to NULL 415 * of SZ_64K-1 only is assured. 'link' is initially set to NULL
411 * and then later will be populated by edma_execute. 416 * and then later will be populated by edma_execute.
412 */ 417 */
413 pset->link_bcntrld = 0xffffffff; 418 param->link_bcntrld = 0xffffffff;
414 return absync; 419 return absync;
415} 420}
416 421
@@ -498,11 +503,11 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
498 /* If this is the last in a current SG set of transactions, 503 /* If this is the last in a current SG set of transactions,
499 enable interrupts so that next set is processed */ 504 enable interrupts so that next set is processed */
500 if (!((i+1) % MAX_NR_SG)) 505 if (!((i+1) % MAX_NR_SG))
501 edesc->pset[i].opt |= TCINTEN; 506 edesc->pset[i].param.opt |= TCINTEN;
502 507
503 /* If this is the last set, enable completion interrupt flag */ 508 /* If this is the last set, enable completion interrupt flag */
504 if (i == sg_len - 1) 509 if (i == sg_len - 1)
505 edesc->pset[i].opt |= TCINTEN; 510 edesc->pset[i].param.opt |= TCINTEN;
506 } 511 }
507 512
508 return vchan_tx_prep(&echan->vchan, &edesc->vdesc, tx_flags); 513 return vchan_tx_prep(&echan->vchan, &edesc->vdesc, tx_flags);
@@ -661,14 +666,14 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
661 " cidx\t%08x\n" 666 " cidx\t%08x\n"
662 " lkrld\t%08x\n", 667 " lkrld\t%08x\n",
663 i, echan->ch_num, echan->slot[i], 668 i, echan->ch_num, echan->slot[i],
664 edesc->pset[i].opt, 669 edesc->pset[i].param.opt,
665 edesc->pset[i].src, 670 edesc->pset[i].param.src,
666 edesc->pset[i].dst, 671 edesc->pset[i].param.dst,
667 edesc->pset[i].a_b_cnt, 672 edesc->pset[i].param.a_b_cnt,
668 edesc->pset[i].ccnt, 673 edesc->pset[i].param.ccnt,
669 edesc->pset[i].src_dst_bidx, 674 edesc->pset[i].param.src_dst_bidx,
670 edesc->pset[i].src_dst_cidx, 675 edesc->pset[i].param.src_dst_cidx,
671 edesc->pset[i].link_bcntrld); 676 edesc->pset[i].param.link_bcntrld);
672 677
673 edesc->absync = ret; 678 edesc->absync = ret;
674 679
@@ -676,7 +681,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
676 * Enable interrupts for every period because callback 681 * Enable interrupts for every period because callback
677 * has to be called for every period. 682 * has to be called for every period.
678 */ 683 */
679 edesc->pset[i].opt |= TCINTEN; 684 edesc->pset[i].param.opt |= TCINTEN;
680 } 685 }
681 686
682 return vchan_tx_prep(&echan->vchan, &edesc->vdesc, tx_flags); 687 return vchan_tx_prep(&echan->vchan, &edesc->vdesc, tx_flags);