
Enable the quad output fast read and quad input fast program support. Quad mode is supported by Cadence QSPI controller.
Signed-off-by: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@opensource.altera.com Cc: Stefan Roese sr@denx.de Cc: Vikas Manocha vikas.manocha@st.com Cc: Jagannadh Teki jteki@openedev.com Cc: Pavel Machek pavel@denx.de Cc: Marek Vasut marex@denx.de --- drivers/spi/cadence_qspi.c | 11 +++++++++++ drivers/spi/cadence_qspi_apb.c | 16 ++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index 34a0f46..c6b69c4 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -318,6 +318,16 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus) return 0; }
+static int cadence_spi_child_pre_probe(struct udevice *dev) +{ + struct spi_slave *slave = dev_get_parentdata(dev); + + /* Cadence QSPI controller can support quad read and program */ + slave->op_mode_rx = SPI_OPM_RX_QOF; + slave->op_mode_tx = SPI_OPM_TX_QPP; + return 0; +} + static const struct dm_spi_ops cadence_spi_ops = { .xfer = cadence_spi_xfer, .set_speed = cadence_spi_set_speed, @@ -341,5 +351,6 @@ U_BOOT_DRIVER(cadence_spi) = { .ofdata_to_platdata = cadence_spi_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct cadence_spi_platdata), .priv_auto_alloc_size = sizeof(struct cadence_spi_priv), + .child_pre_probe = cadence_spi_child_pre_probe, .probe = cadence_spi_probe, }; diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index d053407..deffb6b 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -29,6 +29,9 @@ #include <asm/io.h> #include <asm/errno.h> #include "cadence_qspi.h" +#include <spi.h> +#include <spi_flash.h> +#include "../mtd/spi/sf_internal.h"
#define CQSPI_REG_POLL_US (1) /* 1us */ #define CQSPI_REG_RETRY (10000) @@ -82,6 +85,7 @@
#define CQSPI_REG_WR_INSTR 0x08 #define CQSPI_REG_WR_INSTR_OPCODE_LSB 0 +#define CQSPI_REG_WR_INSTR_TYPE_DATA_LSB 16
#define CQSPI_REG_DELAY 0x0C #define CQSPI_REG_DELAY_TSLCH_LSB 0 @@ -700,10 +704,10 @@ int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat, /* Configure the opcode */ rd_reg = cmdbuf[0] << CQSPI_REG_RD_INSTR_OPCODE_LSB;
-#if (CONFIG_SPI_FLASH_QUAD == 1) - /* Instruction and address at DQ0, data at DQ0-3. */ - rd_reg |= CQSPI_INST_TYPE_QUAD << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB; -#endif + if (cmdbuf[0] == CMD_READ_QUAD_OUTPUT_FAST) + /* Instruction and address at DQ0, data at DQ0-3. */ + rd_reg |= CQSPI_INST_TYPE_QUAD << + CQSPI_REG_RD_INSTR_TYPE_DATA_LSB;
/* Get address */ addr_value = cadence_qspi_apb_cmd2addr(&cmdbuf[1], addr_bytes); @@ -796,6 +800,10 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
/* Configure the opcode */ reg = cmdbuf[0] << CQSPI_REG_WR_INSTR_OPCODE_LSB; + if (cmdbuf[0] == CMD_QUAD_PAGE_PROGRAM) + /* Instruction and address at DQ0, data at DQ0-3. */ + reg |= CQSPI_INST_TYPE_QUAD << + CQSPI_REG_WR_INSTR_TYPE_DATA_LSB; writel(reg, plat->regbase + CQSPI_REG_WR_INSTR);
/* Setup write address. */