]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
spi: cadence_qspi: Fix OSPI DDR mode alignment issue
authorPadmarao Begari <padmarao.begari@amd.com>
Mon, 6 Jan 2025 09:51:20 +0000 (15:21 +0530)
committerMichal Simek <michal.simek@amd.com>
Wed, 5 Feb 2025 15:22:55 +0000 (16:22 +0100)
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>
Link: https://lore.kernel.org/r/20250106095120.800753-1-padmarao.begari@amd.com
Signed-off-by: Michal Simek <michal.simek@amd.com>
drivers/spi/cadence_ospi_versal.c

index dcf28c755968f10e3f838cc28e159e5ab1bed90a..816916de16d26294b992cd5ee83148dc4b3fb3e6 100644 (file)
@@ -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;
 }