
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@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@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;