On the 83xx controller, snooping is necessary for the DMA controller to ensure cache coherence with the CPU when transferring to/from RAM.
The last descriptor in a chain will always have the End-of-Chain interrupt bit set, so we can set the snoop bit while adding the End-of-Chain interrupt bit. Signed-off-by: Ira W. Snyder <i...@ovro.caltech.edu> --- While working on adding the DMA_SLAVE feature, I noticed that the last descriptor in a chain does not have the snoop bits enabled. This is easily verified by doing the following: 1) set FSL_DMA_BCR_MAX_CNT = (1 << 18) 2) #define DEBUG 1 3) #define FSL_DMA_LD_DEBUG 1 4) setup a 1MB memcpy operation The memcpy must be set up on an idle channel, and must be submitted without any other transactions. dma_async_memcpy_issue_pending() must be called without queueing any more transactions. You will see that the snoop bit (bit 4) is not set in the last descriptor. drivers/dma/fsldma.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 4264c98..dba0b58 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -179,9 +179,14 @@ static void dma_halt(struct fsl_dma_chan *fsl_chan) static void set_ld_eol(struct fsl_dma_chan *fsl_chan, struct fsl_desc_sw *desc) { + u64 snoop_bits; + + snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_83XX) + ? FSL_DMA_SNEN : 0; + desc->hw.next_ln_addr = CPU_TO_DMA(fsl_chan, - DMA_TO_CPU(fsl_chan, desc->hw.next_ln_addr, 64) | FSL_DMA_EOL, - 64); + DMA_TO_CPU(fsl_chan, desc->hw.next_ln_addr, 64) | FSL_DMA_EOL + | snoop_bits, 64); } static void append_ld_queue(struct fsl_dma_chan *fsl_chan, -- 1.5.4.3 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev