spi: cadence_qspi: use STIG mode for small reads
authorDhruva Gole <d-gole@ti.com>
Tue, 3 Jan 2023 06:31:12 +0000 (12:01 +0530)
committerJagan Teki <jagan@amarulasolutions.com>
Thu, 26 Jan 2023 15:31:56 +0000 (21:01 +0530)
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>
[jagan: add tab space for comments]
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
drivers/spi/cadence_qspi.c

index 973f455e233139f22b24fc238fc85a808d9f9709..328dfb0a38800ed0e34c6c1d74326463c05ac08d 100644 (file)
@@ -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;