Re: [PATCH RFC 2/2] dmaengine: fsl-edma: Support dynamic scatter/gather chaining

From: Benoît Monin

Date: Tue May 05 2026 - 09:52:32 EST


On Monday, 4 May 2026 at 18:04:49 CEST, Frank Li wrote:
> On Thu, Apr 30, 2026 at 11:49:33AM +0200, Benoît Monin wrote:
> > Implement dynamic linking of scatter/gather transfers to enable
> > chaining multiple DMA descriptors without stopping the channel.
> > This avoids waiting for the channel to go idle if there is another
> > transaction already issued.
> >
> > Add fsl_edma_link_sg() to dynamically link the last TCD of a previously
> > submitted descriptor to the first TCD of a new descriptor by setting
> > the scatter/gather address and the E_SG flag, and keeping the channel
> > active by clearing the DREQ bit.
>
> Thank for your trying this, which I want to do long time ago.
>
> The key problem is
>
> how to guarratee safe when link to last TCD and DMA is working it?
> if update last TCD's next pointer before DMA load it, it is good.
> but, if update last TCD's next pointer after DMA load it. DMA engine
> may stop.
>
I followed what is described in the dynamic scatter/gather chapter of the
i.MX93 reference manual. We update two registers of the last TCD when
chaining SG transfers, first TCD_DLAST_SGA then TCD_CSR. This gives us
three possibilities of concurrence between CPU writes and eDMA reads.

* First case, both registers are updated before the eDMA reads the TCD, we
get the expected chaining.
* Second case, both registers are updated too late and the eDMA have already
read the TCD, we are back to the current implementation. After processing
the last TCD, the eDMA will disable the channel and the call to
fsl_edma_xfer_desc() from fsl_edma_tx_chan_handler() will move to the next
issued descriptor and re-enable the channel.
* Final case, only TCD_DLAST_SGA gets picked up by the eDMA. The eDMA will
also disable the channel after processing the last TCD, the only difference
is that it will update TCD_DADDR by adding the value TCD_DLAST_SGA. Since
we are not reusing TCD_DADDR, this has no impact.

> how do you test it? and how much preformance improved?
I did my tests by doing SPI transfers with the LPSPI controllers, doing DMA
transactions with different number of buffers and different buffer sizes.
Without chaining, interruptions on the SPI bus occur between each DMA
transaction. With chaining, the activity on the SPI bus is continuous as
long as DMA transactions are issued before the end of the current
transaction.

Best regards,
--
Benoît Monin, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com