[PATCH] spi: cadence-qspi: use STIG mode for small reads
Dhruva Gole
d-gole at ti.com
Fri Nov 11 12:07:20 CET 2022
Fix the issue where some flash chips like cypress S25HS256T for example
return the value of the same register once a SPI transaction starts. So
for example if read reg of 0x2 is requested and we start reading
registers in DAC mode we start reading 4 byte aligned ie. 0x0, 0x1, 0x2
and then 0x3. In such a case the flash chip keeps returning the value of
0x0 even though we actually want the value of 0x2.
STIG mode solves the above issue by not issuing a read continuosly for 4
byte aligned data.
Signed-off-by: Dhruva Gole <d-gole at ti.com>
---
Tested using a TI AM 625 SK-EVM with a QSPI Flash on board.
sf read, upate and also booted up using xSPI mode till uboot prompt.
drivers/spi/cadence_qspi.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index ab0a681c8376..6f2924fe4515 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -307,7 +307,22 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi,
priv->is_decoded_cs);
if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
- if (!op->addr.nbytes)
+ /*
+ * In some cases there is a layer of digital logic in front of the QSPI
+ * /OSPI Driver when used in DAC mode. This digital logic layer ensures
+ * that even if we are trying to read 1 or 2 bytes of data, it will
+ * always align it to 4 bytes from a 4byte aligned address. In some
+ * flash chips like cypress for example, if we try to read some regs
+ * in DAC mode then it keeps sending the value of the first register
+ * who was requested and inorder to read the next register we have to
+ * stop and re-initiate a new transaction.
+ * This causes wrong registers values to be read than what is desired
+ * when registers are read in DAC mode. Hence if the data.nbytes
+ * is very less then do not use DAC mode. Registers are generally only
+ * 1-2 bytes and thus switching to STIG mode will be a work around.
+ */
+ if (!op->addr.nbytes ||
+ op->data.nbytes < CQSPI_STIG_DATA_LEN_MAX)
mode = CQSPI_STIG_READ;
else
mode = CQSPI_READ;
--
2.25.1
More information about the U-Boot
mailing list