mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-09 14:43:16 +00:00
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:
commit
ed5a25ac75
@ -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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user