@@ -238,93 +238,126 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first)
238
238
}
239
239
240
240
/*
241
- * atc_get_current_descriptors -
242
- * locate the descriptor which equal to physical address in DSCR
243
- * @atchan: the channel we want to start
244
- * @dscr_addr: physical descriptor address in DSCR
241
+ * atc_get_desc_by_cookie - get the descriptor of a cookie
242
+ * @atchan: the DMA channel
243
+ * @cookie: the cookie to get the descriptor for
245
244
*/
246
- static struct at_desc * atc_get_current_descriptors (struct at_dma_chan * atchan ,
247
- u32 dscr_addr )
245
+ static struct at_desc * atc_get_desc_by_cookie (struct at_dma_chan * atchan ,
246
+ dma_cookie_t cookie )
248
247
{
249
- struct at_desc * desc , * _desc , * child , * desc_cur = NULL ;
248
+ struct at_desc * desc , * _desc ;
250
249
251
- list_for_each_entry_safe (desc , _desc , & atchan -> active_list , desc_node ) {
252
- if (desc -> lli .dscr == dscr_addr ) {
253
- desc_cur = desc ;
254
- break ;
255
- }
250
+ list_for_each_entry_safe (desc , _desc , & atchan -> queue , desc_node ) {
251
+ if (desc -> txd .cookie == cookie )
252
+ return desc ;
253
+ }
256
254
257
- list_for_each_entry (child , & desc -> tx_list , desc_node ) {
258
- if (child -> lli .dscr == dscr_addr ) {
259
- desc_cur = child ;
260
- break ;
261
- }
262
- }
255
+ list_for_each_entry_safe (desc , _desc , & atchan -> active_list , desc_node ) {
256
+ if (desc -> txd .cookie == cookie )
257
+ return desc ;
263
258
}
264
259
265
- return desc_cur ;
260
+ return NULL ;
266
261
}
267
262
268
- /*
269
- * atc_get_bytes_left -
270
- * Get the number of bytes residue in dma buffer,
271
- * @chan: the channel we want to start
263
+ /**
264
+ * atc_calc_bytes_left - calculates the number of bytes left according to the
265
+ * value read from CTRLA.
266
+ *
267
+ * @current_len: the number of bytes left before reading CTRLA
268
+ * @ctrla: the value of CTRLA
269
+ * @desc: the descriptor containing the transfer width
270
+ */
271
+ static inline int atc_calc_bytes_left (int current_len , u32 ctrla ,
272
+ struct at_desc * desc )
273
+ {
274
+ return current_len - ((ctrla & ATC_BTSIZE_MAX ) << desc -> tx_width );
275
+ }
276
+
277
+ /**
278
+ * atc_calc_bytes_left_from_reg - calculates the number of bytes left according
279
+ * to the current value of CTRLA.
280
+ *
281
+ * @current_len: the number of bytes left before reading CTRLA
282
+ * @atchan: the channel to read CTRLA for
283
+ * @desc: the descriptor containing the transfer width
284
+ */
285
+ static inline int atc_calc_bytes_left_from_reg (int current_len ,
286
+ struct at_dma_chan * atchan , struct at_desc * desc )
287
+ {
288
+ u32 ctrla = channel_readl (atchan , CTRLA );
289
+
290
+ return atc_calc_bytes_left (current_len , ctrla , desc );
291
+ }
292
+
293
+ /**
294
+ * atc_get_bytes_left - get the number of bytes residue for a cookie
295
+ * @chan: DMA channel
296
+ * @cookie: transaction identifier to check status of
272
297
*/
273
- static int atc_get_bytes_left (struct dma_chan * chan )
298
+ static int atc_get_bytes_left (struct dma_chan * chan , dma_cookie_t cookie )
274
299
{
275
300
struct at_dma_chan * atchan = to_at_dma_chan (chan );
276
- struct at_dma * atdma = to_at_dma (chan -> device );
277
- int chan_id = atchan -> chan_common .chan_id ;
278
301
struct at_desc * desc_first = atc_first_active (atchan );
279
- struct at_desc * desc_cur ;
280
- int ret = 0 , count = 0 ;
302
+ struct at_desc * desc ;
303
+ int ret ;
304
+ u32 ctrla , dscr ;
281
305
282
306
/*
283
- * Initialize necessary values in the first time.
284
- * remain_desc record remain desc length.
307
+ * If the cookie doesn't match to the currently running transfer then
308
+ * we can return the total length of the associated DMA transfer,
309
+ * because it is still queued.
285
310
*/
286
- if (atchan -> remain_desc == 0 )
287
- /* First descriptor embedds the transaction length */
288
- atchan -> remain_desc = desc_first -> len ;
311
+ desc = atc_get_desc_by_cookie (atchan , cookie );
312
+ if (desc == NULL )
313
+ return - EINVAL ;
314
+ else if (desc != desc_first )
315
+ return desc -> total_len ;
289
316
290
- /*
291
- * This happens when current descriptor transfer complete.
292
- * The residual buffer size should reduce current descriptor length.
293
- */
294
- if (unlikely (test_bit (ATC_IS_BTC , & atchan -> status ))) {
295
- clear_bit (ATC_IS_BTC , & atchan -> status );
296
- desc_cur = atc_get_current_descriptors (atchan ,
297
- channel_readl (atchan , DSCR ));
298
- if (!desc_cur ) {
299
- ret = - EINVAL ;
300
- goto out ;
301
- }
317
+ /* cookie matches to the currently running transfer */
318
+ ret = desc_first -> total_len ;
302
319
303
- count = (desc_cur -> lli .ctrla & ATC_BTSIZE_MAX )
304
- << desc_first -> tx_width ;
305
- if (atchan -> remain_desc < count ) {
306
- ret = - EINVAL ;
307
- goto out ;
320
+ if (desc_first -> lli .dscr ) {
321
+ /* hardware linked list transfer */
322
+
323
+ /*
324
+ * Calculate the residue by removing the length of the child
325
+ * descriptors already transferred from the total length.
326
+ * To get the current child descriptor we can use the value of
327
+ * the channel's DSCR register and compare it against the value
328
+ * of the hardware linked list structure of each child
329
+ * descriptor.
330
+ */
331
+
332
+ ctrla = channel_readl (atchan , CTRLA );
333
+ rmb (); /* ensure CTRLA is read before DSCR */
334
+ dscr = channel_readl (atchan , DSCR );
335
+
336
+ /* for the first descriptor we can be more accurate */
337
+ if (desc_first -> lli .dscr == dscr )
338
+ return atc_calc_bytes_left (ret , ctrla , desc_first );
339
+
340
+ ret -= desc_first -> len ;
341
+ list_for_each_entry (desc , & desc_first -> tx_list , desc_node ) {
342
+ if (desc -> lli .dscr == dscr )
343
+ break ;
344
+
345
+ ret -= desc -> len ;
308
346
}
309
347
310
- atchan -> remain_desc -= count ;
311
- ret = atchan -> remain_desc ;
312
- } else {
313
348
/*
314
- * Get residual bytes when current
315
- * descriptor transfer in progress.
349
+ * For the last descriptor in the chain we can calculate
350
+ * the remaining bytes using the channel's register.
351
+ * Note that the transfer width of the first and last
352
+ * descriptor may differ.
316
353
*/
317
- count = (channel_readl (atchan , CTRLA ) & ATC_BTSIZE_MAX )
318
- << (desc_first -> tx_width );
319
- ret = atchan -> remain_desc - count ;
354
+ if (!desc -> lli .dscr )
355
+ ret = atc_calc_bytes_left_from_reg (ret , atchan , desc );
356
+ } else {
357
+ /* single transfer */
358
+ ret = atc_calc_bytes_left_from_reg (ret , atchan , desc_first );
320
359
}
321
- /*
322
- * Check fifo empty.
323
- */
324
- if (!(dma_readl (atdma , CHSR ) & AT_DMA_EMPT (chan_id )))
325
- atc_issue_pending (chan );
326
360
327
- out :
328
361
return ret ;
329
362
}
330
363
@@ -539,8 +572,6 @@ static irqreturn_t at_dma_interrupt(int irq, void *dev_id)
539
572
/* Give information to tasklet */
540
573
set_bit (ATC_IS_ERROR , & atchan -> status );
541
574
}
542
- if (pending & AT_DMA_BTC (i ))
543
- set_bit (ATC_IS_BTC , & atchan -> status );
544
575
tasklet_schedule (& atchan -> tasklet );
545
576
ret = IRQ_HANDLED ;
546
577
}
@@ -653,14 +684,18 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
653
684
desc -> lli .ctrlb = ctrlb ;
654
685
655
686
desc -> txd .cookie = 0 ;
687
+ desc -> len = xfer_count << src_width ;
656
688
657
689
atc_desc_chain (& first , & prev , desc );
658
690
}
659
691
660
692
/* First descriptor of the chain embedds additional information */
661
693
first -> txd .cookie = - EBUSY ;
662
- first -> len = len ;
694
+ first -> total_len = len ;
695
+
696
+ /* set transfer width for the calculation of the residue */
663
697
first -> tx_width = src_width ;
698
+ prev -> tx_width = src_width ;
664
699
665
700
/* set end-of-link to the last link descriptor of list*/
666
701
set_desc_eol (desc );
@@ -752,6 +787,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
752
787
| ATC_SRC_WIDTH (mem_width )
753
788
| len >> mem_width ;
754
789
desc -> lli .ctrlb = ctrlb ;
790
+ desc -> len = len ;
755
791
756
792
atc_desc_chain (& first , & prev , desc );
757
793
total_len += len ;
@@ -792,6 +828,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
792
828
| ATC_DST_WIDTH (mem_width )
793
829
| len >> reg_width ;
794
830
desc -> lli .ctrlb = ctrlb ;
831
+ desc -> len = len ;
795
832
796
833
atc_desc_chain (& first , & prev , desc );
797
834
total_len += len ;
@@ -806,8 +843,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
806
843
807
844
/* First descriptor of the chain embedds additional information */
808
845
first -> txd .cookie = - EBUSY ;
809
- first -> len = total_len ;
846
+ first -> total_len = total_len ;
847
+
848
+ /* set transfer width for the calculation of the residue */
810
849
first -> tx_width = reg_width ;
850
+ prev -> tx_width = reg_width ;
811
851
812
852
/* first link descriptor of list is responsible of flags */
813
853
first -> txd .flags = flags ; /* client is in control of this ack */
@@ -872,6 +912,7 @@ atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc,
872
912
| ATC_FC_MEM2PER
873
913
| ATC_SIF (atchan -> mem_if )
874
914
| ATC_DIF (atchan -> per_if );
915
+ desc -> len = period_len ;
875
916
break ;
876
917
877
918
case DMA_DEV_TO_MEM :
@@ -883,6 +924,7 @@ atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc,
883
924
| ATC_FC_PER2MEM
884
925
| ATC_SIF (atchan -> per_if )
885
926
| ATC_DIF (atchan -> mem_if );
927
+ desc -> len = period_len ;
886
928
break ;
887
929
888
930
default :
@@ -964,7 +1006,7 @@ atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
964
1006
965
1007
/* First descriptor of the chain embedds additional information */
966
1008
first -> txd .cookie = - EBUSY ;
967
- first -> len = buf_len ;
1009
+ first -> total_len = buf_len ;
968
1010
first -> tx_width = reg_width ;
969
1011
970
1012
return & first -> txd ;
@@ -1118,7 +1160,7 @@ atc_tx_status(struct dma_chan *chan,
1118
1160
spin_lock_irqsave (& atchan -> lock , flags );
1119
1161
1120
1162
/* Get number of bytes left in the active transactions */
1121
- bytes = atc_get_bytes_left (chan );
1163
+ bytes = atc_get_bytes_left (chan , cookie );
1122
1164
1123
1165
spin_unlock_irqrestore (& atchan -> lock , flags );
1124
1166
@@ -1214,7 +1256,6 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
1214
1256
1215
1257
spin_lock_irqsave (& atchan -> lock , flags );
1216
1258
atchan -> descs_allocated = i ;
1217
- atchan -> remain_desc = 0 ;
1218
1259
list_splice (& tmp_list , & atchan -> free_list );
1219
1260
dma_cookie_init (chan );
1220
1261
spin_unlock_irqrestore (& atchan -> lock , flags );
@@ -1257,7 +1298,6 @@ static void atc_free_chan_resources(struct dma_chan *chan)
1257
1298
list_splice_init (& atchan -> free_list , & list );
1258
1299
atchan -> descs_allocated = 0 ;
1259
1300
atchan -> status = 0 ;
1260
- atchan -> remain_desc = 0 ;
1261
1301
1262
1302
dev_vdbg (chan2dev (chan ), "free_chan_resources: done\n" );
1263
1303
}
0 commit comments