diff options
Diffstat (limited to 'drivers/spi/cadence_qspi.c')
-rw-r--r-- | drivers/spi/cadence_qspi.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index 7209bb43a7..907f5dadc4 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -18,7 +18,9 @@ #include <linux/err.h> #include <linux/errno.h> #include <linux/sizes.h> +#include <zynqmp_firmware.h> #include "cadence_qspi.h" +#include <dt-bindings/power/xlnx-versal-power.h> #define NSEC_PER_SEC 1000000000L @@ -27,6 +29,17 @@ #define CQSPI_READ 2 #define CQSPI_WRITE 3 +__weak int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat, + const struct spi_mem_op *op) +{ + return 0; +} + +__weak int cadence_qspi_versal_flash_reset(struct udevice *dev) +{ + return 0; +} + static int cadence_spi_write_speed(struct udevice *bus, uint hz) { struct cadence_spi_plat *plat = dev_get_plat(bus); @@ -138,7 +151,7 @@ static int cadence_spi_set_speed(struct udevice *bus, uint hz) struct cadence_spi_priv *priv = dev_get_priv(bus); int err; - if (hz > plat->max_hz) + if (!hz || hz > plat->max_hz) hz = plat->max_hz; /* Disable QSPI */ @@ -185,6 +198,11 @@ static int cadence_spi_probe(struct udevice *bus) priv->regbase = plat->regbase; priv->ahbbase = plat->ahbbase; + if (CONFIG_IS_ENABLED(ZYNQMP_FIRMWARE)) + xilinx_pm_request(PM_REQUEST_NODE, PM_DEV_OSPI, + ZYNQMP_PM_CAPABILITY_ACCESS, ZYNQMP_PM_MAX_QOS, + ZYNQMP_PM_REQUEST_ACK_NO, NULL); + if (plat->ref_clk_hz == 0) { ret = clk_get_by_index(bus, 0, &clk); if (ret) { @@ -214,6 +232,16 @@ static int cadence_spi_probe(struct udevice *bus) plat->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC, plat->ref_clk_hz); + if (CONFIG_IS_ENABLED(ARCH_VERSAL)) { + /* Versal platform uses spi calibration to set read delay */ + if (plat->read_delay >= 0) + plat->read_delay = -1; + /* Reset ospi flash device */ + ret = cadence_qspi_versal_flash_reset(bus); + if (ret) + return ret; + } + return 0; } @@ -288,8 +316,12 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi, break; case CQSPI_READ: err = cadence_qspi_apb_read_setup(plat, op); - if (!err) - err = cadence_qspi_apb_read_execute(plat, op); + if (!err) { + if (plat->is_dma) + err = cadence_qspi_apb_dma_read(plat, op); + else + err = cadence_qspi_apb_read_execute(plat, op); + } break; case CQSPI_WRITE: err = cadence_qspi_apb_write_setup(plat, op); @@ -342,6 +374,8 @@ static int cadence_spi_of_to_plat(struct udevice *bus) if (plat->ahbsize >= SZ_8M) plat->use_dac_mode = true; + plat->is_dma = dev_read_bool(bus, "cdns,is-dma"); + /* All other paramters are embedded in the child node */ subnode = dev_read_first_subnode(bus); if (!ofnode_valid(subnode)) { |