Skip to content

Commit 3c67c52

Browse files
nxpfranklivinodkoul
authored andcommitted
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: 72f5801 ("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>
1 parent 0bb80ec commit 3c67c52

3 files changed

Lines changed: 28 additions & 3 deletions

File tree

drivers/dma/fsl-edma-common.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,12 +448,25 @@ static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
448448

449449
edma_write_tcdreg(fsl_chan, tcd->dlast_sga, dlast_sga);
450450

451+
csr = le16_to_cpu(tcd->csr);
452+
451453
if (fsl_chan->is_sw) {
452-
csr = le16_to_cpu(tcd->csr);
453454
csr |= EDMA_TCD_CSR_START;
454455
tcd->csr = cpu_to_le16(csr);
455456
}
456457

458+
/*
459+
* Must clear CHn_CSR[DONE] bit before enable TCDn_CSR[ESG] at EDMAv3
460+
* eDMAv4 have not such requirement.
461+
* Change MLINK need clear CHn_CSR[DONE] for both eDMAv3 and eDMAv4.
462+
*/
463+
if (((fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_CLEAR_DONE_E_SG) &&
464+
(csr & EDMA_TCD_CSR_E_SG)) ||
465+
((fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_CLEAR_DONE_E_LINK) &&
466+
(csr & EDMA_TCD_CSR_E_LINK)))
467+
edma_writel_chreg(fsl_chan, edma_readl_chreg(fsl_chan, ch_csr), ch_csr);
468+
469+
457470
edma_write_tcdreg(fsl_chan, tcd->csr, csr);
458471
}
459472

drivers/dma/fsl-edma-common.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,23 @@ struct fsl_edma_desc {
183183
#define FSL_EDMA_DRV_BUS_8BYTE BIT(10)
184184
#define FSL_EDMA_DRV_DEV_TO_DEV BIT(11)
185185
#define FSL_EDMA_DRV_ALIGN_64BYTE BIT(12)
186+
/* Need clean CHn_CSR DONE before enable TCD's ESG */
187+
#define FSL_EDMA_DRV_CLEAR_DONE_E_SG BIT(13)
188+
/* Need clean CHn_CSR DONE before enable TCD's MAJORELINK */
189+
#define FSL_EDMA_DRV_CLEAR_DONE_E_LINK BIT(14)
186190

187191
#define FSL_EDMA_DRV_EDMA3 (FSL_EDMA_DRV_SPLIT_REG | \
188192
FSL_EDMA_DRV_BUS_8BYTE | \
189193
FSL_EDMA_DRV_DEV_TO_DEV | \
190-
FSL_EDMA_DRV_ALIGN_64BYTE)
194+
FSL_EDMA_DRV_ALIGN_64BYTE | \
195+
FSL_EDMA_DRV_CLEAR_DONE_E_SG | \
196+
FSL_EDMA_DRV_CLEAR_DONE_E_LINK)
197+
198+
#define FSL_EDMA_DRV_EDMA4 (FSL_EDMA_DRV_SPLIT_REG | \
199+
FSL_EDMA_DRV_BUS_8BYTE | \
200+
FSL_EDMA_DRV_DEV_TO_DEV | \
201+
FSL_EDMA_DRV_ALIGN_64BYTE | \
202+
FSL_EDMA_DRV_CLEAR_DONE_E_LINK)
191203

192204
struct fsl_edma_drvdata {
193205
u32 dmamuxs; /* only used before v3 */

drivers/dma/fsl-edma-main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ static struct fsl_edma_drvdata imx93_data3 = {
355355
};
356356

357357
static struct fsl_edma_drvdata imx93_data4 = {
358-
.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA3,
358+
.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA4,
359359
.chreg_space_sz = 0x8000,
360360
.chreg_off = 0x10000,
361361
.setup_irq = fsl_edma3_irq_init,

0 commit comments

Comments
 (0)