From: Apurva Nandan <[email protected]> cadence-quadspi has a builtin Auto-HW polling funtionality using which it keep tracks of completion of write operations. When Auto-HW polling is enabled, it automatically initiates status register read operation, until the flash clears its busy bit.
However, the controller doesn't allow an address phase during auto-polling. Unlike SPI NOR flashes, SPI NAND flashes do require the address of status register when polling the busy bit using the read register operation. As Auto-HW polling is enabled by default, cadence-quadspi returns a timeout for every write operation after an indefinite amount of polling on SPI NAND flashes. Add a quirk to write to the CQSPI_REG_WR_COMPLETION_CTRL register on the controller in order to disable Auto-HW polling as the spi-nor core, spinand core, etc. take care of polling the busy bit on their own. Signed-off-by: Apurva Nandan <[email protected]> Signed-off-by: Anurag Dutta <[email protected]> --- Hi This patch is taken from kernel commit [1]. [1] 98d948eb8331 ("spi: cadence-quadspi: fix write completion support") drivers/spi/cadence_qspi.c | 7 +++++++ drivers/spi/cadence_qspi.h | 1 + drivers/spi/cadence_qspi_apb.c | 21 ++++++++++++--------- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index d1404e13810..b164d6b8647 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -29,6 +29,7 @@ /* Quirks */ #define CQSPI_DISABLE_STIG_MODE BIT(0) #define CQSPI_DMA_MODE BIT(1) +#define CQSPI_NO_SUPPORT_WR_COMPLETION BIT(2) __weak int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op) @@ -231,6 +232,12 @@ static int cadence_spi_probe(struct udevice *bus) debug("Cadence QSPI: DMA mode enabled\n"); } + /* write completion is supported by default */ + priv->wr_completion = true; + + if (priv->quirks & CQSPI_NO_SUPPORT_WR_COMPLETION) + priv->wr_completion = false; + if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE)) xilinx_pm_request(PM_REQUEST_NODE, PM_DEV_OSPI, ZYNQMP_PM_CAPABILITY_ACCESS, ZYNQMP_PM_MAX_QOS, diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index 1e9081c2d17..2398e7a8dad 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -260,6 +260,7 @@ struct cadence_spi_priv { bool is_decoded_cs; bool use_dac_mode; bool is_dma; + bool wr_completion; /* Transaction protocol parameters. */ u8 inst_width; diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index 0d4bc685f5d..e43bd1f0f75 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -823,15 +823,18 @@ int cadence_qspi_apb_write_setup(struct cadence_spi_priv *priv, writel(op->addr.val, priv->regbase + CQSPI_REG_INDIRECTWRSTARTADDR); - if (priv->dtr) { - /* - * Some flashes like the cypress Semper flash expect a 4-byte - * dummy address with the Read SR command in DTR mode, but this - * controller does not support sending address with the Read SR - * command. So, disable write completion polling on the - * controller's side. spi-nor will take care of polling the - * status register. - */ + /* + * SPI NAND flashes require the address of the status register to be + * passed in the Read SR command. Also, some SPI NOR flashes like the + * cypress Semper flash expect a 4-byte dummy address in the Read SR + * command in DTR mode. + * + * But this controller does not support address phase in the Read SR + * command when doing auto-HW polling. So, disable write completion + * polling on the controller's side. spinand and spi-nor will take + * care of polling the status register. + */ + if (priv->wr_completion) { reg = readl(priv->regbase + CQSPI_REG_WR_COMPLETION_CTRL); reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL; writel(reg, priv->regbase + CQSPI_REG_WR_COMPLETION_CTRL); -- 2.34.1

