summaryrefslogtreecommitdiffstats
path: root/drivers/dma/fsl-edma-common.c
diff options
context:
space:
mode:
authorFrank Li <Frank.Li@nxp.com>2023-09-21 10:46:52 -0400
committerVinod Koul <vkoul@kernel.org>2023-09-28 16:50:34 +0530
commit3c67c5236fbf7a58c1a26d57da4465ea5fb25537 (patch)
tree5b612c94179f0d3a247a777bd7fd9d0017f1bb36 /drivers/dma/fsl-edma-common.c
parent0bb80ecc33a8fb5a682236443c1e740d5c917d1d (diff)
downloadlinux-3c67c5236fbf7a58c1a26d57da4465ea5fb25537.tar.gz
linux-3c67c5236fbf7a58c1a26d57da4465ea5fb25537.tar.bz2
linux-3c67c5236fbf7a58c1a26d57da4465ea5fb25537.zip
dmaengine: fsl-dma: fix DMA error when enabling sg if 'DONE' bit is set
In eDMAv3, clearing 'DONE' bit (bit 30) of CHn_CSR is required when enabling scatter-gather (SG). eDMAv4 does not require this change. Cc: stable@vger.kernel.org Fixes: 72f5801a4e2b ("dmaengine: fsl-edma: integrate v3 support") Signed-off-by: Frank Li <Frank.Li@nxp.com> Link: https://lore.kernel.org/r/20230921144652.3259813-1-Frank.Li@nxp.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/dma/fsl-edma-common.c')
-rw-r--r--drivers/dma/fsl-edma-common.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
index a0f5741abcc4..50203b82f9f5 100644
--- a/drivers/dma/fsl-edma-common.c
+++ b/drivers/dma/fsl-edma-common.c
@@ -448,12 +448,25 @@ static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
edma_write_tcdreg(fsl_chan, tcd->dlast_sga, dlast_sga);
+ csr = le16_to_cpu(tcd->csr);
+
if (fsl_chan->is_sw) {
- csr = le16_to_cpu(tcd->csr);
csr |= EDMA_TCD_CSR_START;
tcd->csr = cpu_to_le16(csr);
}
+ /*
+ * Must clear CHn_CSR[DONE] bit before enable TCDn_CSR[ESG] at EDMAv3
+ * eDMAv4 have not such requirement.
+ * Change MLINK need clear CHn_CSR[DONE] for both eDMAv3 and eDMAv4.
+ */
+ if (((fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_CLEAR_DONE_E_SG) &&
+ (csr & EDMA_TCD_CSR_E_SG)) ||
+ ((fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_CLEAR_DONE_E_LINK) &&
+ (csr & EDMA_TCD_CSR_E_LINK)))
+ edma_writel_chreg(fsl_chan, edma_readl_chreg(fsl_chan, ch_csr), ch_csr);
+
+
edma_write_tcdreg(fsl_chan, tcd->csr, csr);
}