aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/at_hdmac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/at_hdmac.c')
-rw-r--r--drivers/dma/at_hdmac.c184
1 files changed, 112 insertions, 72 deletions
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 4f5b262f9a40..57b2141ddddc 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -253,93 +253,126 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first)
253} 253}
254 254
255/* 255/*
256 * atc_get_current_descriptors - 256 * atc_get_desc_by_cookie - get the descriptor of a cookie
257 * locate the descriptor which equal to physical address in DSCR 257 * @atchan: the DMA channel
258 * @atchan: the channel we want to start 258 * @cookie: the cookie to get the descriptor for
259 * @dscr_addr: physical descriptor address in DSCR
260 */ 259 */
261static struct at_desc *atc_get_current_descriptors(struct at_dma_chan *atchan, 260static struct at_desc *atc_get_desc_by_cookie(struct at_dma_chan *atchan,
262 u32 dscr_addr) 261 dma_cookie_t cookie)
263{ 262{
264 struct at_desc *desc, *_desc, *child, *desc_cur = NULL; 263 struct at_desc *desc, *_desc;
265 264
266 list_for_each_entry_safe(desc, _desc, &atchan->active_list, desc_node) { 265 list_for_each_entry_safe(desc, _desc, &atchan->queue, desc_node) {
267 if (desc->lli.dscr == dscr_addr) { 266 if (desc->txd.cookie == cookie)
268 desc_cur = desc; 267 return desc;
269 break; 268 }
270 }
271 269
272 list_for_each_entry(child, &desc->tx_list, desc_node) { 270 list_for_each_entry_safe(desc, _desc, &atchan->active_list, desc_node) {
273 if (child->lli.dscr == dscr_addr) { 271 if (desc->txd.cookie == cookie)
274 desc_cur = child; 272 return desc;
275 break;
276 }
277 }
278 } 273 }
279 274
280 return desc_cur; 275 return NULL;
281} 276}
282 277
283/* 278/**
284 * atc_get_bytes_left - 279 * atc_calc_bytes_left - calculates the number of bytes left according to the
285 * Get the number of bytes residue in dma buffer, 280 * value read from CTRLA.
286 * @chan: the channel we want to start 281 *
282 * @current_len: the number of bytes left before reading CTRLA
283 * @ctrla: the value of CTRLA
284 * @desc: the descriptor containing the transfer width
285 */
286static inline int atc_calc_bytes_left(int current_len, u32 ctrla,
287 struct at_desc *desc)
288{
289 return current_len - ((ctrla & ATC_BTSIZE_MAX) << desc->tx_width);
290}
291
292/**
293 * atc_calc_bytes_left_from_reg - calculates the number of bytes left according
294 * to the current value of CTRLA.
295 *
296 * @current_len: the number of bytes left before reading CTRLA
297 * @atchan: the channel to read CTRLA for
298 * @desc: the descriptor containing the transfer width
287 */ 299 */
288static int atc_get_bytes_left(struct dma_chan *chan) 300static inline int atc_calc_bytes_left_from_reg(int current_len,
301 struct at_dma_chan *atchan, struct at_desc *desc)
302{
303 u32 ctrla = channel_readl(atchan, CTRLA);
304
305 return atc_calc_bytes_left(current_len, ctrla, desc);
306}
307
308/**
309 * atc_get_bytes_left - get the number of bytes residue for a cookie
310 * @chan: DMA channel
311 * @cookie: transaction identifier to check status of
312 */
313static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie)
289{ 314{
290 struct at_dma_chan *atchan = to_at_dma_chan(chan); 315 struct at_dma_chan *atchan = to_at_dma_chan(chan);
291 struct at_dma *atdma = to_at_dma(chan->device);
292 int chan_id = atchan->chan_common.chan_id;
293 struct at_desc *desc_first = atc_first_active(atchan); 316 struct at_desc *desc_first = atc_first_active(atchan);
294 struct at_desc *desc_cur; 317 struct at_desc *desc;
295 int ret = 0, count = 0; 318 int ret;
319 u32 ctrla, dscr;
296 320
297 /* 321 /*
298 * Initialize necessary values in the first time. 322 * If the cookie doesn't match to the currently running transfer then
299 * remain_desc record remain desc length. 323 * we can return the total length of the associated DMA transfer,
324 * because it is still queued.
300 */ 325 */
301 if (atchan->remain_desc == 0) 326 desc = atc_get_desc_by_cookie(atchan, cookie);
302 /* First descriptor embedds the transaction length */ 327 if (desc == NULL)
303 atchan->remain_desc = desc_first->len; 328 return -EINVAL;
329 else if (desc != desc_first)
330 return desc->total_len;
304 331
305 /* 332 /* cookie matches to the currently running transfer */
306 * This happens when current descriptor transfer complete. 333 ret = desc_first->total_len;
307 * The residual buffer size should reduce current descriptor length. 334
308 */ 335 if (desc_first->lli.dscr) {
309 if (unlikely(test_bit(ATC_IS_BTC, &atchan->status))) { 336 /* hardware linked list transfer */
310 clear_bit(ATC_IS_BTC, &atchan->status); 337
311 desc_cur = atc_get_current_descriptors(atchan, 338 /*
312 channel_readl(atchan, DSCR)); 339 * Calculate the residue by removing the length of the child
313 if (!desc_cur) { 340 * descriptors already transferred from the total length.
314 ret = -EINVAL; 341 * To get the current child descriptor we can use the value of
315 goto out; 342 * the channel's DSCR register and compare it against the value
316 } 343 * of the hardware linked list structure of each child
344 * descriptor.
345 */
317 346
318 count = (desc_cur->lli.ctrla & ATC_BTSIZE_MAX) 347 ctrla = channel_readl(atchan, CTRLA);
319 << desc_first->tx_width; 348 rmb(); /* ensure CTRLA is read before DSCR */
320 if (atchan->remain_desc < count) { 349 dscr = channel_readl(atchan, DSCR);
321 ret = -EINVAL; 350
322 goto out; 351 /* for the first descriptor we can be more accurate */
352 if (desc_first->lli.dscr == dscr)
353 return atc_calc_bytes_left(ret, ctrla, desc_first);
354
355 ret -= desc_first->len;
356 list_for_each_entry(desc, &desc_first->tx_list, desc_node) {
357 if (desc->lli.dscr == dscr)
358 break;
359
360 ret -= desc->len;
323 } 361 }
324 362
325 atchan->remain_desc -= count;
326 ret = atchan->remain_desc;
327 } else {
328 /* 363 /*
329 * Get residual bytes when current 364 * For the last descriptor in the chain we can calculate
330 * descriptor transfer in progress. 365 * the remaining bytes using the channel's register.
366 * Note that the transfer width of the first and last
367 * descriptor may differ.
331 */ 368 */
332 count = (channel_readl(atchan, CTRLA) & ATC_BTSIZE_MAX) 369 if (!desc->lli.dscr)
333 << (desc_first->tx_width); 370 ret = atc_calc_bytes_left_from_reg(ret, atchan, desc);
334 ret = atchan->remain_desc - count; 371 } else {
372 /* single transfer */
373 ret = atc_calc_bytes_left_from_reg(ret, atchan, desc_first);
335 } 374 }
336 /*
337 * Check fifo empty.
338 */
339 if (!(dma_readl(atdma, CHSR) & AT_DMA_EMPT(chan_id)))
340 atc_issue_pending(chan);
341 375
342out:
343 return ret; 376 return ret;
344} 377}
345 378
@@ -554,8 +587,6 @@ static irqreturn_t at_dma_interrupt(int irq, void *dev_id)
554 /* Give information to tasklet */ 587 /* Give information to tasklet */
555 set_bit(ATC_IS_ERROR, &atchan->status); 588 set_bit(ATC_IS_ERROR, &atchan->status);
556 } 589 }
557 if (pending & AT_DMA_BTC(i))
558 set_bit(ATC_IS_BTC, &atchan->status);
559 tasklet_schedule(&atchan->tasklet); 590 tasklet_schedule(&atchan->tasklet);
560 ret = IRQ_HANDLED; 591 ret = IRQ_HANDLED;
561 } 592 }
@@ -662,14 +693,18 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
662 desc->lli.ctrlb = ctrlb; 693 desc->lli.ctrlb = ctrlb;
663 694
664 desc->txd.cookie = 0; 695 desc->txd.cookie = 0;
696 desc->len = xfer_count << src_width;
665 697
666 atc_desc_chain(&first, &prev, desc); 698 atc_desc_chain(&first, &prev, desc);
667 } 699 }
668 700
669 /* First descriptor of the chain embedds additional information */ 701 /* First descriptor of the chain embedds additional information */
670 first->txd.cookie = -EBUSY; 702 first->txd.cookie = -EBUSY;
671 first->len = len; 703 first->total_len = len;
704
705 /* set transfer width for the calculation of the residue */
672 first->tx_width = src_width; 706 first->tx_width = src_width;
707 prev->tx_width = src_width;
673 708
674 /* set end-of-link to the last link descriptor of list*/ 709 /* set end-of-link to the last link descriptor of list*/
675 set_desc_eol(desc); 710 set_desc_eol(desc);
@@ -761,6 +796,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
761 | ATC_SRC_WIDTH(mem_width) 796 | ATC_SRC_WIDTH(mem_width)
762 | len >> mem_width; 797 | len >> mem_width;
763 desc->lli.ctrlb = ctrlb; 798 desc->lli.ctrlb = ctrlb;
799 desc->len = len;
764 800
765 atc_desc_chain(&first, &prev, desc); 801 atc_desc_chain(&first, &prev, desc);
766 total_len += len; 802 total_len += len;
@@ -801,6 +837,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
801 | ATC_DST_WIDTH(mem_width) 837 | ATC_DST_WIDTH(mem_width)
802 | len >> reg_width; 838 | len >> reg_width;
803 desc->lli.ctrlb = ctrlb; 839 desc->lli.ctrlb = ctrlb;
840 desc->len = len;
804 841
805 atc_desc_chain(&first, &prev, desc); 842 atc_desc_chain(&first, &prev, desc);
806 total_len += len; 843 total_len += len;
@@ -815,8 +852,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
815 852
816 /* First descriptor of the chain embedds additional information */ 853 /* First descriptor of the chain embedds additional information */
817 first->txd.cookie = -EBUSY; 854 first->txd.cookie = -EBUSY;
818 first->len = total_len; 855 first->total_len = total_len;
856
857 /* set transfer width for the calculation of the residue */
819 first->tx_width = reg_width; 858 first->tx_width = reg_width;
859 prev->tx_width = reg_width;
820 860
821 /* first link descriptor of list is responsible of flags */ 861 /* first link descriptor of list is responsible of flags */
822 first->txd.flags = flags; /* client is in control of this ack */ 862 first->txd.flags = flags; /* client is in control of this ack */
@@ -1019,6 +1059,7 @@ atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc,
1019 | ATC_FC_MEM2PER 1059 | ATC_FC_MEM2PER
1020 | ATC_SIF(atchan->mem_if) 1060 | ATC_SIF(atchan->mem_if)
1021 | ATC_DIF(atchan->per_if); 1061 | ATC_DIF(atchan->per_if);
1062 desc->len = period_len;
1022 break; 1063 break;
1023 1064
1024 case DMA_DEV_TO_MEM: 1065 case DMA_DEV_TO_MEM:
@@ -1030,6 +1071,7 @@ atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc,
1030 | ATC_FC_PER2MEM 1071 | ATC_FC_PER2MEM
1031 | ATC_SIF(atchan->per_if) 1072 | ATC_SIF(atchan->per_if)
1032 | ATC_DIF(atchan->mem_if); 1073 | ATC_DIF(atchan->mem_if);
1074 desc->len = period_len;
1033 break; 1075 break;
1034 1076
1035 default: 1077 default:
@@ -1111,7 +1153,7 @@ atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
1111 1153
1112 /* First descriptor of the chain embedds additional information */ 1154 /* First descriptor of the chain embedds additional information */
1113 first->txd.cookie = -EBUSY; 1155 first->txd.cookie = -EBUSY;
1114 first->len = buf_len; 1156 first->total_len = buf_len;
1115 first->tx_width = reg_width; 1157 first->tx_width = reg_width;
1116 1158
1117 return &first->txd; 1159 return &first->txd;
@@ -1265,7 +1307,7 @@ atc_tx_status(struct dma_chan *chan,
1265 spin_lock_irqsave(&atchan->lock, flags); 1307 spin_lock_irqsave(&atchan->lock, flags);
1266 1308
1267 /* Get number of bytes left in the active transactions */ 1309 /* Get number of bytes left in the active transactions */
1268 bytes = atc_get_bytes_left(chan); 1310 bytes = atc_get_bytes_left(chan, cookie);
1269 1311
1270 spin_unlock_irqrestore(&atchan->lock, flags); 1312 spin_unlock_irqrestore(&atchan->lock, flags);
1271 1313
@@ -1361,7 +1403,6 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
1361 1403
1362 spin_lock_irqsave(&atchan->lock, flags); 1404 spin_lock_irqsave(&atchan->lock, flags);
1363 atchan->descs_allocated = i; 1405 atchan->descs_allocated = i;
1364 atchan->remain_desc = 0;
1365 list_splice(&tmp_list, &atchan->free_list); 1406 list_splice(&tmp_list, &atchan->free_list);
1366 dma_cookie_init(chan); 1407 dma_cookie_init(chan);
1367 spin_unlock_irqrestore(&atchan->lock, flags); 1408 spin_unlock_irqrestore(&atchan->lock, flags);
@@ -1404,7 +1445,6 @@ static void atc_free_chan_resources(struct dma_chan *chan)
1404 list_splice_init(&atchan->free_list, &list); 1445 list_splice_init(&atchan->free_list, &list);
1405 atchan->descs_allocated = 0; 1446 atchan->descs_allocated = 0;
1406 atchan->status = 0; 1447 atchan->status = 0;
1407 atchan->remain_desc = 0;
1408 1448
1409 dev_vdbg(chan2dev(chan), "free_chan_resources: done\n"); 1449 dev_vdbg(chan2dev(chan), "free_chan_resources: done\n");
1410} 1450}