[PATCH] spi: cadence-qspi: Disable Auto-HW polling
Anurag Dutta
a-dutta at ti.com
Tue Feb 17 11:32:32 CET 2026
From: Apurva Nandan <a-nandan at ti.com>
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 <a-nandan at ti.com>
Signed-off-by: Anurag Dutta <a-dutta at ti.com>
---
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
More information about the U-Boot
mailing list