Skip to content

Commit ed5a25a

Browse files
committed
spi: cadence-quadspi: Fix random issues with Xilinx
Merge series from Sai Krishna Potthuri <[email protected]>: 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
2 parents 2c86060 + c0b53f4 commit ed5a25a

File tree

1 file changed

+24
-16
lines changed

1 file changed

+24
-16
lines changed

drivers/spi/spi-cadence-quadspi.c

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,21 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
791791
return ret;
792792
}
793793

794+
static void cqspi_controller_enable(struct cqspi_st *cqspi, bool enable)
795+
{
796+
void __iomem *reg_base = cqspi->iobase;
797+
unsigned int reg;
798+
799+
reg = readl(reg_base + CQSPI_REG_CONFIG);
800+
801+
if (enable)
802+
reg |= CQSPI_REG_CONFIG_ENABLE_MASK;
803+
else
804+
reg &= ~CQSPI_REG_CONFIG_ENABLE_MASK;
805+
806+
writel(reg, reg_base + CQSPI_REG_CONFIG);
807+
}
808+
794809
static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
795810
u_char *rxbuf, loff_t from_addr,
796811
size_t n_rx)
@@ -815,10 +830,14 @@ static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
815830
if (ret)
816831
return ret;
817832

833+
cqspi_controller_enable(cqspi, 0);
834+
818835
reg = readl(cqspi->iobase + CQSPI_REG_CONFIG);
819836
reg |= CQSPI_REG_CONFIG_DMA_MASK;
820837
writel(reg, cqspi->iobase + CQSPI_REG_CONFIG);
821838

839+
cqspi_controller_enable(cqspi, 1);
840+
822841
dma_addr = dma_map_single(dev, rxbuf, bytes_to_dma, DMA_FROM_DEVICE);
823842
if (dma_mapping_error(dev, dma_addr)) {
824843
dev_err(dev, "dma mapping failed\n");
@@ -863,7 +882,7 @@ static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
863882
reinit_completion(&cqspi->transfer_complete);
864883

865884
if (!wait_for_completion_timeout(&cqspi->transfer_complete,
866-
msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) {
885+
msecs_to_jiffies(max_t(size_t, bytes_to_dma, 500)))) {
867886
ret = -ETIMEDOUT;
868887
goto failrd;
869888
}
@@ -876,10 +895,14 @@ static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
876895
cqspi->iobase + CQSPI_REG_INDIRECTRD);
877896
dma_unmap_single(dev, dma_addr, bytes_to_dma, DMA_FROM_DEVICE);
878897

898+
cqspi_controller_enable(cqspi, 0);
899+
879900
reg = readl(cqspi->iobase + CQSPI_REG_CONFIG);
880901
reg &= ~CQSPI_REG_CONFIG_DMA_MASK;
881902
writel(reg, cqspi->iobase + CQSPI_REG_CONFIG);
882903

904+
cqspi_controller_enable(cqspi, 1);
905+
883906
ret = zynqmp_pm_ospi_mux_select(cqspi->pd_dev_id,
884907
PM_OSPI_MUX_SEL_LINEAR);
885908
if (ret)
@@ -1182,21 +1205,6 @@ static void cqspi_readdata_capture(struct cqspi_st *cqspi,
11821205
writel(reg, reg_base + CQSPI_REG_READCAPTURE);
11831206
}
11841207

1185-
static void cqspi_controller_enable(struct cqspi_st *cqspi, bool enable)
1186-
{
1187-
void __iomem *reg_base = cqspi->iobase;
1188-
unsigned int reg;
1189-
1190-
reg = readl(reg_base + CQSPI_REG_CONFIG);
1191-
1192-
if (enable)
1193-
reg |= CQSPI_REG_CONFIG_ENABLE_MASK;
1194-
else
1195-
reg &= ~CQSPI_REG_CONFIG_ENABLE_MASK;
1196-
1197-
writel(reg, reg_base + CQSPI_REG_CONFIG);
1198-
}
1199-
12001208
static void cqspi_configure(struct cqspi_flash_pdata *f_pdata,
12011209
unsigned long sclk)
12021210
{

0 commit comments

Comments
 (0)