summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPadmarao Begari <[email protected]>2025-01-06 15:21:20 +0530
committerMichal Simek <[email protected]>2025-02-05 16:22:55 +0100
commit1621851495d341efb9c62c07a3d82feaa12cd03e (patch)
tree9a2e56ae72f92441d4b72843dcc111ca3473d8c5 /drivers
parenta1319b5487522b1cdf981ae8bb02118fc53a801f (diff)
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Michal Simek <[email protected]>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/cadence_ospi_versal.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c
index dcf28c75596..816916de16d 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;
}