Cadence Octal SPI Flash Controller has PHY module, which is used for handling SPI transactions when there is a requirement for high performance. Also, this controller supports DQS(data strobe) used for data capturing in PHY mode rather than internally generated ref_clk. Xilinx Versal Octal SPI use PHY module and DQS signal when operating in DTR protocol. Signed-off-by: Sai Krishna Potthuri <sai.krishna.potthuri@xxxxxxx> --- drivers/spi/spi-cadence-quadspi.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 676313e1bdad..b55b763003f0 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -40,6 +40,8 @@ #define CQSPI_SUPPORT_EXTERNAL_DMA BIT(2) #define CQSPI_NO_SUPPORT_WR_COMPLETION BIT(3) #define CQSPI_SLOW_SRAM BIT(4) +#define CQSPI_HAS_PHY BIT(5) +#define CQSPI_HAS_DQS BIT(6) /* Capabilities */ #define CQSPI_SUPPORTS_OCTAL BIT(0) @@ -89,6 +91,8 @@ struct cqspi_st { u32 pd_dev_id; bool wr_completion; bool slow_sram; + bool use_phy; + bool use_dqs; }; struct cqspi_driver_platdata { @@ -112,6 +116,7 @@ struct cqspi_driver_platdata { /* Register map */ #define CQSPI_REG_CONFIG 0x00 #define CQSPI_REG_CONFIG_ENABLE_MASK BIT(0) +#define CQSPI_REG_CONFIG_PHY_MODE BIT(3) #define CQSPI_REG_CONFIG_ENB_DIR_ACC_CTRL BIT(7) #define CQSPI_REG_CONFIG_DECODE_MASK BIT(9) #define CQSPI_REG_CONFIG_CHIPSELECT_LSB 10 @@ -151,6 +156,7 @@ struct cqspi_driver_platdata { #define CQSPI_REG_DELAY_TSHSL_MASK 0xFF #define CQSPI_REG_READCAPTURE 0x10 +#define CQSPI_REG_READCAPTURE_DQS BIT(8) #define CQSPI_REG_READCAPTURE_BYPASS_LSB 0 #define CQSPI_REG_READCAPTURE_DELAY_LSB 1 #define CQSPI_REG_READCAPTURE_DELAY_MASK 0xF @@ -468,6 +474,8 @@ static int cqspi_enable_dtr(struct cqspi_flash_pdata *f_pdata, if (op->cmd.dtr) { reg |= CQSPI_REG_CONFIG_DTR_PROTO; reg |= CQSPI_REG_CONFIG_DUAL_OPCODE; + if (cqspi->use_phy) + reg |= CQSPI_REG_CONFIG_PHY_MODE; /* Set up command opcode extension. */ ret = cqspi_setup_opcode_ext(f_pdata, op, shift); @@ -476,10 +484,20 @@ static int cqspi_enable_dtr(struct cqspi_flash_pdata *f_pdata, } else { reg &= ~CQSPI_REG_CONFIG_DTR_PROTO; reg &= ~CQSPI_REG_CONFIG_DUAL_OPCODE; + reg &= ~CQSPI_REG_CONFIG_PHY_MODE; } writel(reg, reg_base + CQSPI_REG_CONFIG); + reg = readl(reg_base + CQSPI_REG_READCAPTURE); + + if (op->cmd.dtr) + reg |= CQSPI_REG_READCAPTURE_DQS; + else + reg &= ~CQSPI_REG_READCAPTURE_DQS; + + writel(reg, reg_base + CQSPI_REG_READCAPTURE); + return cqspi_wait_idle(cqspi); } @@ -1700,6 +1718,10 @@ static int cqspi_probe(struct platform_device *pdev) cqspi->wr_completion = false; if (ddata->quirks & CQSPI_SLOW_SRAM) cqspi->slow_sram = true; + if (ddata->quirks & CQSPI_HAS_PHY) + cqspi->use_phy = true; + if (ddata->quirks & CQSPI_HAS_DQS) + cqspi->use_dqs = true; if (of_device_is_compatible(pdev->dev.of_node, "xlnx,versal-ospi-1.0")) @@ -1820,7 +1842,8 @@ static const struct cqspi_driver_platdata socfpga_qspi = { static const struct cqspi_driver_platdata versal_ospi = { .hwcaps_mask = CQSPI_SUPPORTS_OCTAL, - .quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_SUPPORT_EXTERNAL_DMA, + .quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_SUPPORT_EXTERNAL_DMA + | CQSPI_HAS_PHY | CQSPI_HAS_DQS, .indirect_read_dma = cqspi_versal_indirect_read_dma, .get_dma_status = cqspi_get_versal_dma_status, }; -- 2.25.1