[PATCH] spi: cadence_qspi: Fix OSPI DDR mode alignment issue

If the least significant bit of the address is set to one when using the DDR protocol for data transfer then the results are indeterminate for few flash devices. To fix this the least significant bit of the address is set to zero.
Signed-off-by: Padmarao Begari padmarao.begari@amd.com --- drivers/spi/cadence_ospi_versal.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index 222f828f54..8827a24ee6 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -24,6 +24,13 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, u8 opcode, addr_bytes, *rxbuf, dummy_cycles;
n_rx = op->data.nbytes; + + if (op->addr.dtr && (op->addr.val % 2)) { + n_rx += 1; + writel(op->addr.val & ~0x1, + priv->regbase + CQSPI_REG_INDIRECTRDSTARTADDR); + } + rxbuf = op->data.buf.in; rx_rem = n_rx % 4; bytes_to_dma = n_rx - rx_rem; @@ -104,6 +111,11 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, memcpy(rxbuf, &data, rx_rem); }
+ if (op->addr.dtr && (op->addr.val % 2)) { + rxbuf -= bytes_to_dma; + memcpy(rxbuf, rxbuf + 1, n_rx - 1); + } + return 0; }

On 1/6/25 10:51, Padmarao Begari wrote:
If the least significant bit of the address is set to one when using the DDR protocol for data transfer then the results are indeterminate for few flash devices. To fix this the least significant bit of the address is set to zero.
Signed-off-by: Padmarao Begari padmarao.begari@amd.com
drivers/spi/cadence_ospi_versal.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index 222f828f54..8827a24ee6 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -24,6 +24,13 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, u8 opcode, addr_bytes, *rxbuf, dummy_cycles;
n_rx = op->data.nbytes;
- if (op->addr.dtr && (op->addr.val % 2)) {
n_rx += 1;
writel(op->addr.val & ~0x1,
priv->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
- }
- rxbuf = op->data.buf.in; rx_rem = n_rx % 4; bytes_to_dma = n_rx - rx_rem;
@@ -104,6 +111,11 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, memcpy(rxbuf, &data, rx_rem); }
- if (op->addr.dtr && (op->addr.val % 2)) {
rxbuf -= bytes_to_dma;
memcpy(rxbuf, rxbuf + 1, n_rx - 1);
- }
- return 0; }
Applied. M
participants (2)
-
Michal Simek
-
Padmarao Begari