spi: cadence-quadspi: Fix random issues with Xilinx

Merge series from Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>:

Update Xilinx Versal external DMA read logic to fix random issues
- Instead of having the fixed timeout, update the read timeout based on
the length of the transfer to avoid timeout for larger data size.
- While switching between external DMA read and indirect read, disable the
SPI before configuration and enable it after configuration as recommended
by Octal-SPI Flash Controller specification.

Sai Krishna Potthuri (2):
  spi: cadence-quadspi: Update the read timeout based on the length
  spi: cadence-quadspi: Disable the SPI before reconfiguring

 drivers/spi/spi-cadence-quadspi.c | 40 ++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 16 deletions(-)

--
2.25.1
This commit is contained in:
Mark Brown 2023-04-17 20:27:00 +01:00
commit ed5a25ac75
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -791,6 +791,21 @@ failrd:
return ret;
}
static void cqspi_controller_enable(struct cqspi_st *cqspi, bool enable)
{
void __iomem *reg_base = cqspi->iobase;
unsigned int reg;
reg = readl(reg_base + CQSPI_REG_CONFIG);
if (enable)
reg |= CQSPI_REG_CONFIG_ENABLE_MASK;
else
reg &= ~CQSPI_REG_CONFIG_ENABLE_MASK;
writel(reg, reg_base + CQSPI_REG_CONFIG);
}
static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
u_char *rxbuf, loff_t from_addr,
size_t n_rx)
@ -815,10 +830,14 @@ static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
if (ret)
return ret;
cqspi_controller_enable(cqspi, 0);
reg = readl(cqspi->iobase + CQSPI_REG_CONFIG);
reg |= CQSPI_REG_CONFIG_DMA_MASK;
writel(reg, cqspi->iobase + CQSPI_REG_CONFIG);
cqspi_controller_enable(cqspi, 1);
dma_addr = dma_map_single(dev, rxbuf, bytes_to_dma, DMA_FROM_DEVICE);
if (dma_mapping_error(dev, dma_addr)) {
dev_err(dev, "dma mapping failed\n");
@ -863,7 +882,7 @@ static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
reinit_completion(&cqspi->transfer_complete);
if (!wait_for_completion_timeout(&cqspi->transfer_complete,
msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) {
msecs_to_jiffies(max_t(size_t, bytes_to_dma, 500)))) {
ret = -ETIMEDOUT;
goto failrd;
}
@ -876,10 +895,14 @@ static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
cqspi->iobase + CQSPI_REG_INDIRECTRD);
dma_unmap_single(dev, dma_addr, bytes_to_dma, DMA_FROM_DEVICE);
cqspi_controller_enable(cqspi, 0);
reg = readl(cqspi->iobase + CQSPI_REG_CONFIG);
reg &= ~CQSPI_REG_CONFIG_DMA_MASK;
writel(reg, cqspi->iobase + CQSPI_REG_CONFIG);
cqspi_controller_enable(cqspi, 1);
ret = zynqmp_pm_ospi_mux_select(cqspi->pd_dev_id,
PM_OSPI_MUX_SEL_LINEAR);
if (ret)
@ -1182,21 +1205,6 @@ static void cqspi_readdata_capture(struct cqspi_st *cqspi,
writel(reg, reg_base + CQSPI_REG_READCAPTURE);
}
static void cqspi_controller_enable(struct cqspi_st *cqspi, bool enable)
{
void __iomem *reg_base = cqspi->iobase;
unsigned int reg;
reg = readl(reg_base + CQSPI_REG_CONFIG);
if (enable)
reg |= CQSPI_REG_CONFIG_ENABLE_MASK;
else
reg &= ~CQSPI_REG_CONFIG_ENABLE_MASK;
writel(reg, reg_base + CQSPI_REG_CONFIG);
}
static void cqspi_configure(struct cqspi_flash_pdata *f_pdata,
unsigned long sclk)
{