Clear all controller interrupt status bits and enable the DMA DONE interrupt in the DMA DST interrupt enable register before starting the DMA read. Also poll the BUSY bit in the DMA status register until it becomes zero, which implies that the DMA is done with the transfer and may accept a new command. Return -ETIMEDOUT if the BUSY bit does not clear.
Signed-off-by: Venkatesh Yadav Abbarapu <[email protected]> Signed-off-by: Padmarao Begari <[email protected]> --- drivers/spi/cadence_ospi_versal.c | 20 ++++++++++++++++++++ drivers/spi/cadence_qspi.h | 1 + 2 files changed, 21 insertions(+) diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index f97bf744122..0133c92b60c 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -50,6 +50,12 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, writel(CQSPI_DFLT_INDIR_TRIG_ADDR_RANGE, priv->regbase + CQSPI_REG_INDIR_TRIG_ADDR_RANGE); + /* Clear all interrupts. */ + writel(CQSPI_IRQ_STATUS_MASK, + priv->regbase + CQSPI_REG_IRQSTATUS); + /* Enable DMA done interrupt */ + writel(CQSPI_DMA_DST_I_STS_DONE, + priv->regbase + CQSPI_DMA_DST_I_ENBL_REG); writel(CQSPI_DFLT_DMA_PERIPH_CFG, priv->regbase + CQSPI_REG_DMA_PERIPH_CFG); writel(lower_32_bits((unsigned long)rxbuf), priv->regbase + @@ -73,6 +79,8 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, if (ret) return ret; + /* Disable DMA interrupt */ + writel(0x0, priv->regbase + CQSPI_DMA_DST_I_DISBL_REG); /* Clear indirect completion status */ writel(CQSPI_REG_INDIRECTRD_DONE, priv->regbase + CQSPI_REG_INDIRECTRD); @@ -152,6 +160,18 @@ int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_priv *priv) writel(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG), priv->regbase + CQSPI_DMA_DST_I_STS_REG); + + /* Wait until the DMA is ready to accept a new command */ + timeout = CQSPI_DMA_TIMEOUT; + while ((readl(priv->regbase + CQSPI_DMA_DST_STS_REG) & + CQSPI_DMA_DST_STS_BUSY) && --timeout) + udelay(1); + + if (!timeout) { + printf("DMA busy timeout\n"); + return -ETIMEDOUT; + } + return 0; } diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index 86f2fd639c5..7efe0454936 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -192,6 +192,7 @@ #define CQSPI_DFLT_DMA_PERIPH_CFG 0x602 #define CQSPI_DFLT_DST_CTRL_REG_VAL 0xF43FFA00 +#define CQSPI_DMA_DST_STS_BUSY BIT(0) #define CQSPI_DMA_DST_I_STS_DONE BIT(1) #define CQSPI_DMA_TIMEOUT 10000000 -- 2.34.1
