[PATCH V4 0/2] spi: cqspi: Fix register reads in STIG Mode

Intent of these patches is to fix register reads in STIG mode and also use STIG mode while reading flash registers. Currently if you try to read a register while in STIG mode there is no support for ADDR and thus naturally a register never gets read from the flash.
This series supercedes the previously sent: https://lore.kernel.org/u-boot/20221125055932.398322-1-d-gole@ti.com/
Logs demonstrating the usage and working of QSPI-NOR Flash (Cypress s25hs512t) can be found on the link below: https://gist.github.com/DhruvaG2000/11e7b4ee6a381be9d86b69b2bc2616e4
change log: ----------
v4: * Improve the commit message for PATCH 2/2 * Address Pratyush's review to use <= CQSPI_STIG_DATA_LEN_MAX instead.
v3: Improvements over the last 2 versions, I have added a bit mask to make sure nbytes dont overflow bit fields. Also minor improvements in wording of comments and commit log.
v2: add the setup ADDR bits patch because STIG read of registers wasn't present earlier.
v1: use STIG mode if reads are small.
Dhruva Gole (2): spi: cadence_qspi: setup ADDR Bits in cmd reads spi: cadence_qspi: use STIG mode for small reads
drivers/spi/cadence_qspi.c | 8 +++++++- drivers/spi/cadence_qspi_apb.c | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-)

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 Reviewed-by: Pratyush Yadav pratyush@kernel.org --- drivers/spi/cadence_qspi_apb.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index d1f89138ef15..21fe2e655c5f 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -479,6 +479,19 @@ 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); + /* + * address bytes are zero indexed + */ + reg |= (((op->addr.nbytes - 1) & + CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) << + 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 return the value of the same register over and over in DAC mode.
For example in the TI K3-AM62x Processors refer [0] Technical Reference Manual there is a layer of digital logic in front of the QSPI/OSPI Drive when used in DAC mode. This is part of the Flash Subsystem (FSS) which provides access to external Flash devices.
The FSS0_0_SYSCONFIG Register (Offset = 4h) has a BIT Field for OSPI_32B_DISABLE_MODE which has a Reset value = 0. This means, OSPI 32bit mode enabled by default.
Thus, by default controller operates in 32 bit mode causing it to always align all data 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 that was requested and inorder to read the next reg, we have to stop and re-initiate a new transaction.
This causes wrong register values to be read than what is desired when registers are read in DAC mode. Hence if the data.nbytes is very less then prefer STIG mode for such small reads.
[0] https://www.ti.com/lit/ug/spruiv7a/spruiv7a.pdf
Tested-by: Vaishnav Achath vaishnav.a@ti.com Signed-off-by: Dhruva Gole d-gole@ti.com --- drivers/spi/cadence_qspi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index ab0a681c8376..dc4602449eda 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -307,7 +307,13 @@ 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) + /* + * Performing reads in DAC mode forces to read minimum 4 bytes + * which is unsupported on some flash devices during register + * reads, prefer STIG mode for such small reads. + */ + if (!op->addr.nbytes || + op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX) mode = CQSPI_STIG_READ; else mode = CQSPI_READ;

On Tue, Jan 3, 2023 at 12:01 PM Dhruva Gole d-gole@ti.com wrote:
Intent of these patches is to fix register reads in STIG mode and also use STIG mode while reading flash registers. Currently if you try to read a register while in STIG mode there is no support for ADDR and thus naturally a register never gets read from the flash.
This series supercedes the previously sent: https://lore.kernel.org/u-boot/20221125055932.398322-1-d-gole@ti.com/
Logs demonstrating the usage and working of QSPI-NOR Flash (Cypress s25hs512t) can be found on the link below: https://gist.github.com/DhruvaG2000/11e7b4ee6a381be9d86b69b2bc2616e4
change log:
Applied to u-boot-spi/master
participants (2)
-
Dhruva Gole
-
Jagan Teki