[PATCH v2] spi: imx: keep dma request disabled before dma transfer setup

carlos.song at nxp.com carlos.song at nxp.com
Mon Oct 27 04:04:06 PDT 2025


From: Robin Gong <yibin.gong at nxp.com>

Due to a hardware limitation on SDMA event enable (ENBLn), the DMA request
must remain disabled until the DMA transfer setup is complete.

Refer SDMA 2.6.28 Channel Enable RAM (SDMAARMx_CHNENBLn) section:

"
It is thus essential for the Arm platform to program them before any DMA
request is triggered to the SDMA, otherwise an unpredictable combination
of channels may be started.
"

SDMA hardware configuration is postponed to transfer phase, so enabling
the DMA request too early may cause unpredictable channel activation.
Then keep dma request disabled before dma transfer setup.

Signed-off-by: Carlos Song <carlos.song at nxp.com>
Signed-off-by: Robin Gong <yibin.gong at nxp.com>
---
Change for V2:
- Change commit log with spec doc
---
 drivers/spi/spi-imx.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 9a1113ea4ba2..00132f300e38 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -528,9 +528,15 @@ static void mx51_ecspi_trigger(struct spi_imx_data *spi_imx)
 {
 	u32 reg;
 
-	reg = readl(spi_imx->base + MX51_ECSPI_CTRL);
-	reg |= MX51_ECSPI_CTRL_XCH;
-	writel(reg, spi_imx->base + MX51_ECSPI_CTRL);
+	if (spi_imx->usedma) {
+		reg = readl(spi_imx->base + MX51_ECSPI_DMA);
+		reg |= MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN;
+		writel(reg, spi_imx->base + MX51_ECSPI_DMA);
+	} else {
+		reg = readl(spi_imx->base + MX51_ECSPI_CTRL);
+		reg |= MX51_ECSPI_CTRL_XCH;
+		writel(reg, spi_imx->base + MX51_ECSPI_CTRL);
+	}
 }
 
 static void mx51_ecspi_disable(struct spi_imx_data *spi_imx)
@@ -771,7 +777,6 @@ static void mx51_setup_wml(struct spi_imx_data *spi_imx)
 	writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml - 1) |
 		MX51_ECSPI_DMA_TX_WML(tx_wml) |
 		MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) |
-		MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN |
 		MX51_ECSPI_DMA_RXTDEN, spi_imx->base + MX51_ECSPI_DMA);
 }
 
@@ -1535,6 +1540,8 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
 	reinit_completion(&spi_imx->dma_tx_completion);
 	dma_async_issue_pending(controller->dma_tx);
 
+	spi_imx->devtype_data->trigger(spi_imx);
+
 	transfer_timeout = spi_imx_calculate_timeout(spi_imx, transfer->len);
 
 	/* Wait SDMA to finish the data transfer.*/
-- 
2.34.1




More information about the linux-arm-kernel mailing list