@@ -238,93 +238,126 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first)
238238}
239239
240240/*
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
245244 */
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 )
248247{
249- struct at_desc * desc , * _desc , * child , * desc_cur = NULL ;
248+ struct at_desc * desc , * _desc ;
250249
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+ }
256254
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 ;
263258 }
264259
265- return desc_cur ;
260+ return NULL ;
266261}
267262
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
272297 */
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 )
274299{
275300 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 ;
278301 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 ;
281305
282306 /*
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.
285310 */
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 ;
289316
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 ;
302319
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 ;
308346 }
309347
310- atchan -> remain_desc -= count ;
311- ret = atchan -> remain_desc ;
312- } else {
313348 /*
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.
316353 */
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 );
320359 }
321- /*
322- * Check fifo empty.
323- */
324- if (!(dma_readl (atdma , CHSR ) & AT_DMA_EMPT (chan_id )))
325- atc_issue_pending (chan );
326360
327- out :
328361 return ret ;
329362}
330363
@@ -539,8 +572,6 @@ static irqreturn_t at_dma_interrupt(int irq, void *dev_id)
539572 /* Give information to tasklet */
540573 set_bit (ATC_IS_ERROR , & atchan -> status );
541574 }
542- if (pending & AT_DMA_BTC (i ))
543- set_bit (ATC_IS_BTC , & atchan -> status );
544575 tasklet_schedule (& atchan -> tasklet );
545576 ret = IRQ_HANDLED ;
546577 }
@@ -653,14 +684,18 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
653684 desc -> lli .ctrlb = ctrlb ;
654685
655686 desc -> txd .cookie = 0 ;
687+ desc -> len = xfer_count << src_width ;
656688
657689 atc_desc_chain (& first , & prev , desc );
658690 }
659691
660692 /* First descriptor of the chain embedds additional information */
661693 first -> txd .cookie = - EBUSY ;
662- first -> len = len ;
694+ first -> total_len = len ;
695+
696+ /* set transfer width for the calculation of the residue */
663697 first -> tx_width = src_width ;
698+ prev -> tx_width = src_width ;
664699
665700 /* set end-of-link to the last link descriptor of list*/
666701 set_desc_eol (desc );
@@ -752,6 +787,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
752787 | ATC_SRC_WIDTH (mem_width )
753788 | len >> mem_width ;
754789 desc -> lli .ctrlb = ctrlb ;
790+ desc -> len = len ;
755791
756792 atc_desc_chain (& first , & prev , desc );
757793 total_len += len ;
@@ -792,6 +828,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
792828 | ATC_DST_WIDTH (mem_width )
793829 | len >> reg_width ;
794830 desc -> lli .ctrlb = ctrlb ;
831+ desc -> len = len ;
795832
796833 atc_desc_chain (& first , & prev , desc );
797834 total_len += len ;
@@ -806,8 +843,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
806843
807844 /* First descriptor of the chain embedds additional information */
808845 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 */
810849 first -> tx_width = reg_width ;
850+ prev -> tx_width = reg_width ;
811851
812852 /* first link descriptor of list is responsible of flags */
813853 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,
872912 | ATC_FC_MEM2PER
873913 | ATC_SIF (atchan -> mem_if )
874914 | ATC_DIF (atchan -> per_if );
915+ desc -> len = period_len ;
875916 break ;
876917
877918 case DMA_DEV_TO_MEM :
@@ -883,6 +924,7 @@ atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc,
883924 | ATC_FC_PER2MEM
884925 | ATC_SIF (atchan -> per_if )
885926 | ATC_DIF (atchan -> mem_if );
927+ desc -> len = period_len ;
886928 break ;
887929
888930 default :
@@ -964,7 +1006,7 @@ atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
9641006
9651007 /* First descriptor of the chain embedds additional information */
9661008 first -> txd .cookie = - EBUSY ;
967- first -> len = buf_len ;
1009+ first -> total_len = buf_len ;
9681010 first -> tx_width = reg_width ;
9691011
9701012 return & first -> txd ;
@@ -1118,7 +1160,7 @@ atc_tx_status(struct dma_chan *chan,
11181160 spin_lock_irqsave (& atchan -> lock , flags );
11191161
11201162 /* Get number of bytes left in the active transactions */
1121- bytes = atc_get_bytes_left (chan );
1163+ bytes = atc_get_bytes_left (chan , cookie );
11221164
11231165 spin_unlock_irqrestore (& atchan -> lock , flags );
11241166
@@ -1214,7 +1256,6 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
12141256
12151257 spin_lock_irqsave (& atchan -> lock , flags );
12161258 atchan -> descs_allocated = i ;
1217- atchan -> remain_desc = 0 ;
12181259 list_splice (& tmp_list , & atchan -> free_list );
12191260 dma_cookie_init (chan );
12201261 spin_unlock_irqrestore (& atchan -> lock , flags );
@@ -1257,7 +1298,6 @@ static void atc_free_chan_resources(struct dma_chan *chan)
12571298 list_splice_init (& atchan -> free_list , & list );
12581299 atchan -> descs_allocated = 0 ;
12591300 atchan -> status = 0 ;
1260- atchan -> remain_desc = 0 ;
12611301
12621302 dev_vdbg (chan2dev (chan ), "free_chan_resources: done\n" );
12631303}
0 commit comments