@@ -307,6 +307,109 @@ static inline u32 atc_calc_bytes_left(u32 current_len, u32 ctrla)
307
307
return current_len - (btsize << src_width );
308
308
}
309
309
310
+ /**
311
+ * atc_get_llis_residue - Get residue for a hardware linked list transfer
312
+ *
313
+ * Calculate the residue by removing the length of the child descriptors already
314
+ * transferred from the total length. To get the current child descriptor we can
315
+ * use the value of the channel's DSCR register and compare it against the value
316
+ * of the hardware linked list structure of each child descriptor.
317
+ *
318
+ * The CTRLA register provides us with the amount of data already read from the
319
+ * source for the current child descriptor. So we can compute a more accurate
320
+ * residue by also removing the number of bytes corresponding to this amount of
321
+ * data.
322
+ *
323
+ * However, the DSCR and CTRLA registers cannot be read both atomically. Hence a
324
+ * race condition may occur: the first read register may refer to one child
325
+ * descriptor whereas the second read may refer to a later child descriptor in
326
+ * the list because of the DMA transfer progression inbetween the two reads.
327
+ *
328
+ * One solution could have been to pause the DMA transfer, read the DSCR and
329
+ * CTRLA then resume the DMA transfer. Nonetheless, this approach presents some
330
+ * drawbacks:
331
+ * - If the DMA transfer is paused, RX overruns or TX underruns are more likey
332
+ * to occur depending on the system latency. Taking the USART driver as an
333
+ * example, it uses a cyclic DMA transfer to read data from the Receive
334
+ * Holding Register (RHR) to avoid RX overruns since the RHR is not protected
335
+ * by any FIFO on most Atmel SoCs. So pausing the DMA transfer to compute the
336
+ * residue would break the USART driver design.
337
+ * - The atc_pause() function masks interrupts but we'd rather avoid to do so
338
+ * for system latency purpose.
339
+ *
340
+ * Then we'd rather use another solution: the DSCR is read a first time, the
341
+ * CTRLA is read in turn, next the DSCR is read a second time. If the two
342
+ * consecutive read values of the DSCR are the same then we assume both refers
343
+ * to the very same child descriptor as well as the CTRLA value read inbetween
344
+ * does. For cyclic tranfers, the assumption is that a full loop is "not so
345
+ * fast". If the two DSCR values are different, we read again the CTRLA then the
346
+ * DSCR till two consecutive read values from DSCR are equal or till the
347
+ * maximum trials is reach. This algorithm is very unlikely not to find a stable
348
+ * value for DSCR.
349
+ * @atchan: pointer to an atmel hdmac channel.
350
+ * @desc: pointer to the descriptor for which the residue is calculated.
351
+ * @residue: residue to be set to dma_tx_state.
352
+ * Returns 0 on success, -errno otherwise.
353
+ */
354
+ static int atc_get_llis_residue (struct at_dma_chan * atchan ,
355
+ struct at_desc * desc , u32 * residue )
356
+ {
357
+ struct at_desc * child ;
358
+ u32 len , ctrla , dscr ;
359
+ unsigned int i ;
360
+
361
+ len = desc -> total_len ;
362
+ dscr = channel_readl (atchan , DSCR );
363
+ rmb (); /* ensure DSCR is read before CTRLA */
364
+ ctrla = channel_readl (atchan , CTRLA );
365
+ for (i = 0 ; i < ATC_MAX_DSCR_TRIALS ; ++ i ) {
366
+ u32 new_dscr ;
367
+
368
+ rmb (); /* ensure DSCR is read after CTRLA */
369
+ new_dscr = channel_readl (atchan , DSCR );
370
+
371
+ /*
372
+ * If the DSCR register value has not changed inside the DMA
373
+ * controller since the previous read, we assume that both the
374
+ * dscr and ctrla values refers to the very same descriptor.
375
+ */
376
+ if (likely (new_dscr == dscr ))
377
+ break ;
378
+
379
+ /*
380
+ * DSCR has changed inside the DMA controller, so the previouly
381
+ * read value of CTRLA may refer to an already processed
382
+ * descriptor hence could be outdated. We need to update ctrla
383
+ * to match the current descriptor.
384
+ */
385
+ dscr = new_dscr ;
386
+ rmb (); /* ensure DSCR is read before CTRLA */
387
+ ctrla = channel_readl (atchan , CTRLA );
388
+ }
389
+ if (unlikely (i == ATC_MAX_DSCR_TRIALS ))
390
+ return - ETIMEDOUT ;
391
+
392
+ /* For the first descriptor we can be more accurate. */
393
+ if (desc -> lli .dscr == dscr ) {
394
+ * residue = atc_calc_bytes_left (len , ctrla );
395
+ return 0 ;
396
+ }
397
+
398
+ len -= desc -> len ;
399
+ list_for_each_entry (child , & desc -> tx_list , desc_node ) {
400
+ if (child -> lli .dscr == dscr )
401
+ break ;
402
+ len -= child -> len ;
403
+ }
404
+
405
+ /*
406
+ * For the current descriptor in the chain we can calculate the
407
+ * remaining bytes using the channel's register.
408
+ */
409
+ * residue = atc_calc_bytes_left (len , ctrla );
410
+ return 0 ;
411
+ }
412
+
310
413
/**
311
414
* atc_get_residue - get the number of bytes residue for a cookie.
312
415
* The residue is passed by address and updated on success.
@@ -321,8 +424,7 @@ static int atc_get_residue(struct dma_chan *chan, dma_cookie_t cookie,
321
424
struct at_dma_chan * atchan = to_at_dma_chan (chan );
322
425
struct at_desc * desc_first = atc_first_active (atchan );
323
426
struct at_desc * desc ;
324
- u32 len , ctrla , dscr ;
325
- unsigned int i ;
427
+ u32 len , ctrla ;
326
428
327
429
/*
328
430
* If the cookie doesn't match to the currently running transfer then
@@ -335,117 +437,14 @@ static int atc_get_residue(struct dma_chan *chan, dma_cookie_t cookie,
335
437
else if (desc != desc_first )
336
438
return desc -> total_len ;
337
439
338
- /* cookie matches to the currently running transfer */
339
- len = desc_first -> total_len ;
340
-
341
- if (desc_first -> lli .dscr ) {
440
+ if (desc_first -> lli .dscr )
342
441
/* hardware linked list transfer */
442
+ return atc_get_llis_residue (atchan , desc_first , residue );
343
443
344
- /*
345
- * Calculate the residue by removing the length of the child
346
- * descriptors already transferred from the total length.
347
- * To get the current child descriptor we can use the value of
348
- * the channel's DSCR register and compare it against the value
349
- * of the hardware linked list structure of each child
350
- * descriptor.
351
- *
352
- * The CTRLA register provides us with the amount of data
353
- * already read from the source for the current child
354
- * descriptor. So we can compute a more accurate residue by also
355
- * removing the number of bytes corresponding to this amount of
356
- * data.
357
- *
358
- * However, the DSCR and CTRLA registers cannot be read both
359
- * atomically. Hence a race condition may occur: the first read
360
- * register may refer to one child descriptor whereas the second
361
- * read may refer to a later child descriptor in the list
362
- * because of the DMA transfer progression inbetween the two
363
- * reads.
364
- *
365
- * One solution could have been to pause the DMA transfer, read
366
- * the DSCR and CTRLA then resume the DMA transfer. Nonetheless,
367
- * this approach presents some drawbacks:
368
- * - If the DMA transfer is paused, RX overruns or TX underruns
369
- * are more likey to occur depending on the system latency.
370
- * Taking the USART driver as an example, it uses a cyclic DMA
371
- * transfer to read data from the Receive Holding Register
372
- * (RHR) to avoid RX overruns since the RHR is not protected
373
- * by any FIFO on most Atmel SoCs. So pausing the DMA transfer
374
- * to compute the residue would break the USART driver design.
375
- * - The atc_pause() function masks interrupts but we'd rather
376
- * avoid to do so for system latency purpose.
377
- *
378
- * Then we'd rather use another solution: the DSCR is read a
379
- * first time, the CTRLA is read in turn, next the DSCR is read
380
- * a second time. If the two consecutive read values of the DSCR
381
- * are the same then we assume both refers to the very same
382
- * child descriptor as well as the CTRLA value read inbetween
383
- * does. For cyclic tranfers, the assumption is that a full loop
384
- * is "not so fast".
385
- * If the two DSCR values are different, we read again the CTRLA
386
- * then the DSCR till two consecutive read values from DSCR are
387
- * equal or till the maxium trials is reach.
388
- * This algorithm is very unlikely not to find a stable value for
389
- * DSCR.
390
- */
391
-
392
- dscr = channel_readl (atchan , DSCR );
393
- rmb (); /* ensure DSCR is read before CTRLA */
394
- ctrla = channel_readl (atchan , CTRLA );
395
- for (i = 0 ; i < ATC_MAX_DSCR_TRIALS ; ++ i ) {
396
- u32 new_dscr ;
397
-
398
- rmb (); /* ensure DSCR is read after CTRLA */
399
- new_dscr = channel_readl (atchan , DSCR );
400
-
401
- /*
402
- * If the DSCR register value has not changed inside the
403
- * DMA controller since the previous read, we assume
404
- * that both the dscr and ctrla values refers to the
405
- * very same descriptor.
406
- */
407
- if (likely (new_dscr == dscr ))
408
- break ;
409
-
410
- /*
411
- * DSCR has changed inside the DMA controller, so the
412
- * previouly read value of CTRLA may refer to an already
413
- * processed descriptor hence could be outdated.
414
- * We need to update ctrla to match the current
415
- * descriptor.
416
- */
417
- dscr = new_dscr ;
418
- rmb (); /* ensure DSCR is read before CTRLA */
419
- ctrla = channel_readl (atchan , CTRLA );
420
- }
421
- if (unlikely (i == ATC_MAX_DSCR_TRIALS ))
422
- return - ETIMEDOUT ;
423
-
424
- /* for the first descriptor we can be more accurate */
425
- if (desc_first -> lli .dscr == dscr ) {
426
- * residue = atc_calc_bytes_left (len , ctrla );
427
- return 0 ;
428
- }
429
-
430
- len -= desc_first -> len ;
431
- list_for_each_entry (desc , & desc_first -> tx_list , desc_node ) {
432
- if (desc -> lli .dscr == dscr )
433
- break ;
434
-
435
- len -= desc -> len ;
436
- }
437
-
438
- /*
439
- * For the current descriptor in the chain we can calculate
440
- * the remaining bytes using the channel's register.
441
- */
442
- * residue = atc_calc_bytes_left (len , ctrla );
443
- } else {
444
- /* single transfer */
445
- ctrla = channel_readl (atchan , CTRLA );
446
- * residue = atc_calc_bytes_left (len , ctrla );
447
- }
448
-
444
+ /* single transfer */
445
+ len = desc_first -> total_len ;
446
+ ctrla = channel_readl (atchan , CTRLA );
447
+ * residue = atc_calc_bytes_left (len , ctrla );
449
448
return 0 ;
450
449
}
451
450
0 commit comments