[PATCH v2 1/2] spi: cadence_qspi: setup ADDR Bits in cmd reads

Dhruva Gole d-gole at ti.com
Tue Nov 15 12:49:25 CET 2022


Setup the Addr bit field while issuing register reads in STIG mode. This
is needed for example flashes like cypress define in their transaction
table that to read any register there is 1 cmd byte and a few more address
bytes trailing the cmd byte. Absence of addr bytes will obviously fail
to read correct data from flash register that maybe requested by flash
driver because the controller doesn't even specify which address of the
flash register the read is being requested from.

Signed-off-by: Dhruva Gole <d-gole at ti.com>
---

I was trying to use STIG mode to read flash register on my cypress QSPI
Flash. However the value that I kept reading back was 0xff and it looked
highly sus. This caused the spi-nor core to _THINK_ that okay the
register has all the necessary bits that I care about to put the flash
in QUAD mode already set, so... I Wont do ANYTHING further to make the
flash go into QUAD mode.
However this obviously was not the case and the flash was never really
going into Quad SPI mode read. Thus when I issued any ``sf read`` then I
ended up with just 0xffs and 0x00s and basically non sense data.
After actually dumping the STIG register and going into cqspi_apb driver
I came to know that in STIG mode we do not support any SPI transactions
that may involve additional address bytes after cmd.

After this patch, and the one following, I tested sf reads on my AM625 SK
EVM and now I get valid reads in Quad SPI mode. I added a few of my own
logs:

~~~
=> sf read $loadaddr 0x0 0x10000

device 0 offset 0x0, size 0x10000

jedec_spi_nor flash at 0: from 0x00000000, len 65536


[..]

mylogs: cadence_qspi_set_protocol L#137 data.buswidth = 4

[..]

myl: cadence_qspi_apb_read_execute#761 len = 65536

SF: 65536 bytes @ 0x0 Read: OK

=> md.w $loadaddr

82000000: 8230 9404 8230 fd03 03a0 0102 0202 5214 0...0..........R
[...]
82000060: 2731 2530 0306 0455 0c0a 541e 7865 7361 1'0%..U....Texas
[...]
82000070: 4920 736e 7274 6d75 6e65 7374 4920 636e  Instruments Inc
~~~
This confirms that the read back has the same data I had flashed and it
was also read back in Quad mode.

 drivers/spi/cadence_qspi_apb.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index cfae5dcbda0e..58592daa46aa 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -479,6 +479,28 @@ int cadence_qspi_apb_command_read(struct cadence_spi_priv *priv,
 	/* 0 means 1 byte. */
 	reg |= (((rxlen - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK)
 		<< CQSPI_REG_CMDCTRL_RD_BYTES_LSB);
+
+	/* setup ADDR BIT field */
+	if (op->addr.nbytes) {
+		writel(op->addr.val, priv->regbase + CQSPI_REG_CMDADDRESS);
+		/*
+		 * According to the controller register description,
+		 * Number of Address Bytes: Set to the number of address bytes
+		 * required [the address itself is programmed in the FLASH
+		 * COMMAND ADDRESS REGISTERS]. This should be setup before
+		 * triggering the command via bit 0 of this register.
+		 * 00 : 1 address byte
+		 * 01 : 2 address bytes
+		 * 10 : 3 address bytes
+		 * 11 : 4 address bytes
+		 * Hence, subtract 1 from actual addr.nbytes to follow above
+		 * spec
+		 */
+		reg |= (op->addr.nbytes - 1) <<
+			CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
+		reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
+	}
+
 	status = cadence_qspi_apb_exec_flash_cmd(reg_base, reg);
 	if (status != 0)
 		return status;
-- 
2.25.1



More information about the U-Boot mailing list