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