Trying to boot my Rock Pi 4B from its XTX SPI NOR Flash failed when my
custom compiled TF-A had a load address of 0.

The same TF-A booted correctly from MMC.

Add a local variable to spi_mem_exec_op() to determine operation
direction, instead of testing rx_buf or tx_buf for null value, so that
a buffer at RAM address 0 is accepted.

This commit also cuts short a debug dump of the image loaded to show
only the first 0x1000 and the last 0x100 bytes, and not swamping the
serial log. When adding the #define DEBUG to the .c file one can
change these limits at the same time if they don't fit.

Changed since v2: 

    - no changes

Changed since v1: 

    - no changes

Signed-off-by: Xavier Drudis Ferran <xdru...@tinet.cat>

Cc: Jagan Teki <ja...@amarulasolutions.com>

---
 drivers/spi/spi-mem.c | 34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 9c1ede1b61..4dc90addb3 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -21,6 +21,8 @@
 #include <spi.h>
 #include <spi-mem.h>
 #include <dm/device_compat.h>
+#define DEBUG_DUMP_START_LENGTH        0x1000
+#define DEBUG_DUMP_END_LENGTH  0x100
 #endif
 
 #ifndef __UBOOT__
@@ -373,12 +375,21 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct 
spi_mem_op *op)
        if (msg.actual_length != totalxferlen)
                return -EIO;
 #else
+       enum spi_mem_data_dir dir = SPI_MEM_NO_DATA;
 
        if (op->data.nbytes) {
-               if (op->data.dir == SPI_MEM_DATA_IN)
+               dir = op->data.dir;
+               if (dir == SPI_MEM_DATA_IN) {
                        rx_buf = op->data.buf.in;
-               else
+               } else {
                        tx_buf = op->data.buf.out;
+                       /**
+                        * keep old behaviour, to assume SPI_MEM_DATA_OUT
+                        * if ever data.nbytes!=0 but data.dir==SPI_MEM_NO_DATA
+                        * (hopefully never)
+                        */
+                       dir = SPI_MEM_DATA_OUT;
+               }
        }
 
        op_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
@@ -410,7 +421,7 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct 
spi_mem_op *op)
        /* 1st transfer: opcode + address + dummy cycles */
        flag = SPI_XFER_BEGIN;
        /* Make sure to set END bit if no tx or rx data messages follow */
-       if (!tx_buf && !rx_buf)
+       if (dir == SPI_MEM_NO_DATA)
                flag |= SPI_XFER_END;
 
        ret = spi_xfer(slave, op_len * 8, op_buf, NULL, flag);
@@ -418,7 +429,7 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct 
spi_mem_op *op)
                return ret;
 
        /* 2nd transfer: rx or tx data path */
-       if (tx_buf || rx_buf) {
+       if (dir != SPI_MEM_NO_DATA) {
                ret = spi_xfer(slave, op->data.nbytes * 8, tx_buf,
                               rx_buf, SPI_XFER_END);
                if (ret)
@@ -430,10 +441,17 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct 
spi_mem_op *op)
        for (i = 0; i < pos; i++)
                debug("%02x ", op_buf[i]);
        debug("| [%dB %s] ",
-             tx_buf || rx_buf ? op->data.nbytes : 0,
-             tx_buf || rx_buf ? (tx_buf ? "out" : "in") : "-");
-       for (i = 0; i < op->data.nbytes; i++)
-               debug("%02x ", tx_buf ? tx_buf[i] : rx_buf[i]);
+             op->data.nbytes,
+             dir == SPI_MEM_DATA_IN ? "in" : (dir == SPI_MEM_DATA_OUT ? "out" 
: "-"));
+       for (i = 0; i < op->data.nbytes && i < DEBUG_DUMP_START_LENGTH ; i++)
+               debug("%02x ", dir == SPI_MEM_DATA_OUT ? tx_buf[i] : rx_buf[i]);
+       if (op->data.nbytes > DEBUG_DUMP_END_LENGTH && op->data.nbytes > 
DEBUG_DUMP_START_LENGTH &&
+           i < op->data.nbytes - DEBUG_DUMP_END_LENGTH) {
+               debug(" ... ");
+               i = op->data.nbytes - DEBUG_DUMP_END_LENGTH;
+       }
+       for (; i < op->data.nbytes  ; i++)
+               debug("%02x ", dir == SPI_MEM_DATA_OUT ? tx_buf[i] : rx_buf[i]);
        debug("[ret %d]\n", ret);
 
        if (ret < 0)
-- 
2.20.1

Reply via email to