
From: T Karthik Reddy t.karthik.reddy@xilinx.com
Set cmd, address & data buswidth to octal. Handle dummy clock cycles incase of reads & writes. Convert odd bytes to even bytes lengths in ddr mode, as we cannot rx/tx odd data in ddr mode.
Disable the DMA once the transfer is done to avoid disabling it at other places.
Signed-off-by: T Karthik Reddy t.karthik.reddy@xilinx.com Signed-off-by: Tejas Bhumkar tejas.arvind.bhumkar@amd.com --- drivers/spi/cadence_ospi_versal.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index 243de6efaf..9db1911110 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -21,12 +21,13 @@
#define CMD_4BYTE_READ 0x13 #define CMD_4BYTE_FAST_READ 0x0C +#define CMD_4BYTE_OCTAL_READ 0x7c
int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data; - u8 opcode, addr_bytes, *rxbuf, dummy_cycles; + u8 opcode, addr_bytes, *rxbuf, dummy_cycles, unaligned_byte;
n_rx = op->data.nbytes; rxbuf = op->data.buf.in; @@ -70,13 +71,14 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, writel(CQSPI_REG_INDIRECTRD_DONE, priv->regbase + CQSPI_REG_INDIRECTRD); rxbuf += bytes_to_dma; - }
- if (rx_rem) { + /* Disable DMA on completion */ reg = readl(priv->regbase + CQSPI_REG_CONFIG); reg &= ~CQSPI_REG_CONFIG_ENBL_DMA; writel(reg, priv->regbase + CQSPI_REG_CONFIG); + }
+ if (rx_rem) { reg = readl(priv->regbase + CQSPI_REG_INDIRECTRDSTARTADDR); reg += bytes_to_dma; writel(reg, priv->regbase + CQSPI_REG_CMDADDRESS); @@ -84,10 +86,10 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, addr_bytes = readl(priv->regbase + CQSPI_REG_SIZE) & CQSPI_REG_SIZE_ADDRESS_MASK;
- opcode = CMD_4BYTE_FAST_READ; - dummy_cycles = 8; - writel((dummy_cycles << CQSPI_REG_RD_INSTR_DUMMY_LSB) | opcode, - priv->regbase + CQSPI_REG_RD_INSTR); + opcode = (u8)readl(priv->regbase + CQSPI_REG_RD_INSTR); + if (opcode == CMD_4BYTE_OCTAL_READ && + priv->edge_mode != CQSPI_EDGE_MODE_DDR) + opcode = CMD_4BYTE_FAST_READ;
reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB; reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB); @@ -99,7 +101,12 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, CQSPI_REG_RD_INSTR_DUMMY_MASK; reg |= (dummy_cycles & CQSPI_REG_CMDCTRL_DUMMY_MASK) << CQSPI_REG_CMDCTRL_DUMMY_LSB; - reg |= (((rx_rem - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK) << + if (priv->edge_mode == CQSPI_EDGE_MODE_DDR && (rx_rem % 2) != 0) + unaligned_byte = 1; + else + unaligned_byte = 0; + reg |= (((rx_rem - 1 + unaligned_byte) & + CQSPI_REG_CMDCTRL_RD_BYTES_MASK) << CQSPI_REG_CMDCTRL_RD_BYTES_LSB); ret = cadence_qspi_apb_exec_flash_cmd(priv->regbase, reg); if (ret)