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. Changes from v1: none (just retested with current next) 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