[CAD QSPI v1] spi: cadence-qspi: Add disable STIG mode quikrs.

Boon Khai Ng boon.khai.ng at altera.com
Wed Mar 12 10:09:44 CET 2025


Adding quirk to disable STIG mode since cadence controller has
issue for read/write using the STIG mode. STIG mode is enabled
by default since 2023.04 for small read/write(<8bytes).

Updated STIG mode reading from dev_get_driver_data by assigning
to platdata struct before read quirks variable.

The STIG mode is disabled for normal read case and enabled
for QSPI Jedec ID read/write since it requires STIG read/write.

Signed-off-by: Boon Khai Ng <boon.khai.ng at altera.com>
---
 drivers/spi/cadence_qspi.c | 29 +++++++++++++++++++++++++----
 drivers/spi/cadence_qspi.h |  7 +++++++
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index 623904ecda..c2990ac833 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -27,6 +27,9 @@
 #define CQSPI_READ			2
 #define CQSPI_WRITE			3
 
+/* Quirks */
+#define CQSPI_DISABLE_STIG_MODE		BIT(0)
+
 __weak int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
 				     const struct spi_mem_op *op)
 {
@@ -217,6 +220,7 @@ static int cadence_spi_probe(struct udevice *bus)
 	priv->tsd2d_ns		= plat->tsd2d_ns;
 	priv->tchsh_ns		= plat->tchsh_ns;
 	priv->tslch_ns		= plat->tslch_ns;
+	priv->quirks		= plat->quirks;
 
 	if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE))
 		xilinx_pm_request(PM_REQUEST_NODE, PM_DEV_OSPI,
@@ -307,12 +311,16 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi,
 		 * which is unsupported on some flash devices during register
 		 * reads, prefer STIG mode for such small reads.
 		 */
-		if (op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX)
+		if (!op->addr.nbytes ||
+		    (op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX &&
+		     !(priv->quirks & CQSPI_DISABLE_STIG_MODE)))
 			mode = CQSPI_STIG_READ;
 		else
 			mode = CQSPI_READ;
 	} else {
-		if (op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX)
+		if (!op->addr.nbytes || !op->data.buf.out ||
+		    (op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX &&
+		     !(priv->quirks & CQSPI_DISABLE_STIG_MODE)))
 			mode = CQSPI_STIG_WRITE;
 		else
 			mode = CQSPI_WRITE;
@@ -427,6 +435,10 @@ static int cadence_spi_of_to_plat(struct udevice *bus)
 	plat->read_delay = ofnode_read_s32_default(subnode, "cdns,read-delay",
 						   -1);
 
+	const struct cqspi_driver_platdata *drvdata =
+		(struct cqspi_driver_platdata *)dev_get_driver_data(bus);
+	plat->quirks = drvdata->quirks;
+
 	debug("%s: regbase=%p ahbbase=%p max-frequency=%d page-size=%d\n",
 	      __func__, plat->regbase, plat->ahbbase, plat->max_hz,
 	      plat->page_size);
@@ -449,9 +461,18 @@ static const struct dm_spi_ops cadence_spi_ops = {
 	 */
 };
 
+static const struct cqspi_driver_platdata cdns_qspi = {
+	.quirks = CQSPI_DISABLE_STIG_MODE,
+};
+
 static const struct udevice_id cadence_spi_ids[] = {
-	{ .compatible = "cdns,qspi-nor" },
-	{ .compatible = "ti,am654-ospi" },
+	{
+		.compatible = "cdns,qspi-nor",
+		.data = (ulong)&cdns_qspi,
+	},
+	{
+		.compatible = "ti,am654-ospi"
+	},
 	{ }
 };
 
diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h
index 1f9125cd23..e6ea9e6c1f 100644
--- a/drivers/spi/cadence_qspi.h
+++ b/drivers/spi/cadence_qspi.h
@@ -220,6 +220,7 @@ struct cadence_spi_plat {
 	u32		tsd2d_ns;
 	u32		tchsh_ns;
 	u32		tslch_ns;
+	u32		quirks;
 
 	bool            is_dma;
 };
@@ -251,6 +252,7 @@ struct cadence_spi_priv {
 	u32		tsd2d_ns;
 	u32		tchsh_ns;
 	u32		tslch_ns;
+	u32		quirks;
 	u8              edge_mode;
 	u8              dll_mode;
 	bool		extra_dummy;
@@ -266,6 +268,11 @@ struct cadence_spi_priv {
 	bool		dtr;
 };
 
+struct cqspi_driver_platdata {
+	u32 hwcaps_mask;
+	u32 quirks;
+};
+
 /* Functions call declaration */
 void cadence_qspi_apb_controller_init(struct cadence_spi_priv *priv);
 void cadence_qspi_apb_controller_enable(void *reg_base_addr);
-- 
2.25.1



More information about the U-Boot mailing list