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

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;

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@ti.com ---
v2: No changes from previous patch. However this DEPENDS on PATCH 1/2 of the same series. Hence disregard the previously sent patch: [PATCH] spi: cadence-qspi: use STIG mode for small reads https://lore.kernel.org/u-boot/20221111110720.283013-1-d-gole@ti.com/T/#u
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;

Hi,
On 15/11/22 17:19, Dhruva Gole wrote:
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@ti.com
v2: No changes from previous patch. However this DEPENDS on PATCH 1/2 of the same series. Hence disregard the previously sent patch: [PATCH] spi: cadence-qspi: use STIG mode for small reads https://lore.kernel.org/u-boot/20221111110720.283013-1-d-gole@ti.com/T/#u
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);
[...]
Kindly disregard this series, a newer series with slight improvements posted upstream:
https://lore.kernel.org/u-boot/20221125055932.398322-1-d-gole@ti.com/
participants (1)
-
Dhruva Gole