@@ -480,8 +480,8 @@ void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan,
480480 bool disable_req , bool enable_sg )
481481{
482482 struct dma_slave_config * cfg = & fsl_chan -> cfg ;
483+ u32 burst = 0 ;
483484 u16 csr = 0 ;
484- u32 burst ;
485485
486486 /*
487487 * eDMA hardware SGs require the TCDs to be stored in little
@@ -496,16 +496,30 @@ void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan,
496496
497497 fsl_edma_set_tcd_to_le (fsl_chan , tcd , soff , soff );
498498
499- if (fsl_chan -> is_multi_fifo ) {
500- /* set mloff to support multiple fifo */
501- burst = cfg -> direction == DMA_DEV_TO_MEM ?
502- cfg -> src_maxburst : cfg -> dst_maxburst ;
503- nbytes |= EDMA_V3_TCD_NBYTES_MLOFF (- (burst * 4 ));
504- /* enable DMLOE/SMLOE */
505- if (cfg -> direction == DMA_MEM_TO_DEV ) {
499+ /* If we expect to have either multi_fifo or a port window size,
500+ * we will use minor loop offset, meaning bits 29-10 will be used for
501+ * address offset, while bits 9-0 will be used to tell DMA how much
502+ * data to read from addr.
503+ * If we don't have either of those, will use a major loop reading from addr
504+ * nbytes (29bits).
505+ */
506+ if (cfg -> direction == DMA_MEM_TO_DEV ) {
507+ if (fsl_chan -> is_multi_fifo )
508+ burst = cfg -> dst_maxburst * 4 ;
509+ if (cfg -> dst_port_window_size )
510+ burst = cfg -> dst_port_window_size * cfg -> dst_addr_width ;
511+ if (burst ) {
512+ nbytes |= EDMA_V3_TCD_NBYTES_MLOFF (- burst );
506513 nbytes |= EDMA_V3_TCD_NBYTES_DMLOE ;
507514 nbytes &= ~EDMA_V3_TCD_NBYTES_SMLOE ;
508- } else {
515+ }
516+ } else {
517+ if (fsl_chan -> is_multi_fifo )
518+ burst = cfg -> src_maxburst * 4 ;
519+ if (cfg -> src_port_window_size )
520+ burst = cfg -> src_port_window_size * cfg -> src_addr_width ;
521+ if (burst ) {
522+ nbytes |= EDMA_V3_TCD_NBYTES_MLOFF (- burst );
509523 nbytes |= EDMA_V3_TCD_NBYTES_SMLOE ;
510524 nbytes &= ~EDMA_V3_TCD_NBYTES_DMLOE ;
511525 }
@@ -623,11 +637,15 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
623637 dst_addr = fsl_chan -> dma_dev_addr ;
624638 soff = fsl_chan -> cfg .dst_addr_width ;
625639 doff = fsl_chan -> is_multi_fifo ? 4 : 0 ;
640+ if (fsl_chan -> cfg .dst_port_window_size )
641+ doff = fsl_chan -> cfg .dst_addr_width ;
626642 } else if (direction == DMA_DEV_TO_MEM ) {
627643 src_addr = fsl_chan -> dma_dev_addr ;
628644 dst_addr = dma_buf_next ;
629645 soff = fsl_chan -> is_multi_fifo ? 4 : 0 ;
630646 doff = fsl_chan -> cfg .src_addr_width ;
647+ if (fsl_chan -> cfg .src_port_window_size )
648+ soff = fsl_chan -> cfg .src_addr_width ;
631649 } else {
632650 /* DMA_DEV_TO_DEV */
633651 src_addr = fsl_chan -> cfg .src_addr ;
0 commit comments