diff options
Diffstat (limited to 'drivers/spi/cadence_qspi.c')
-rw-r--r-- | drivers/spi/cadence_qspi.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index 623904ecdad..9edbfaa821b 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -27,12 +27,20 @@ #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) { return 0; } +__weak int cadence_device_reset(struct udevice *dev) +{ + return 0; +} + __weak int cadence_qspi_flash_reset(struct udevice *dev) { return 0; @@ -217,6 +225,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, @@ -251,6 +260,9 @@ static int cadence_spi_probe(struct udevice *bus) priv->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC, priv->ref_clk_hz); + if (device_is_compatible(bus, "amd,versal2-ospi")) + return cadence_device_reset(bus); + /* Reset ospi flash device */ return cadence_qspi_flash_reset(bus); @@ -307,12 +319,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 +443,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 +469,21 @@ 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" + }, + { + .compatible = "amd,versal2-ospi" + }, { } }; |