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...@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

Reply via email to