[PATCH 04/11] spi: cadence-quadspi: enable opcode extension based on command length
Greg Malysa
greg.malysa at timesys.com
Fri Apr 12 00:36:48 CEST 2024
From: Ian Roberts <ian.roberts at timesys.com>
Some flash chips use dual opcodes in other modes. For example, the
Macronix MX66 requires dual opcodes for STR octal operation. Thus,
enable opcode extension based on the length of the command instead
of the DTR mode of the controller.
Co-developed-by: Nathan Barrett-Morrison <nathan.morrison at timesys.com>
Signed-off-by: Nathan Barrett-Morrison <nathan.morrison at timesys.com>
Signed-off-by: Greg Malysa <greg.malysa at timesys.com>
Signed-off-by: Ian Roberts <ian.roberts at timesys.com>
---
drivers/spi/cadence_qspi_apb.c | 66 +++++++++++++++++++++++++---------
1 file changed, 49 insertions(+), 17 deletions(-)
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index 34cacf1880..eb9f4ed63d 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -412,19 +412,27 @@ static int cadence_qspi_enable_dtr(struct cadence_spi_priv *priv,
reg = readl(priv->regbase + CQSPI_REG_CONFIG);
- if (enable) {
- reg |= CQSPI_REG_CONFIG_DTR_PROTO;
+ switch (op->cmd.nbytes) {
+ case 1:
+ reg &= ~CQSPI_REG_CONFIG_DUAL_OPCODE;
+ break;
+ case 2:
reg |= CQSPI_REG_CONFIG_DUAL_OPCODE;
/* Set up command opcode extension. */
ret = cadence_qspi_setup_opcode_ext(priv, op, shift);
if (ret)
return ret;
- } else {
- reg &= ~CQSPI_REG_CONFIG_DTR_PROTO;
- reg &= ~CQSPI_REG_CONFIG_DUAL_OPCODE;
+ break;
+ default:
+ return log_msg_ret("QSPI: Invalid command length", -EINVAL);
}
+ if (enable)
+ reg |= CQSPI_REG_CONFIG_DTR_PROTO;
+ else
+ reg &= ~CQSPI_REG_CONFIG_DTR_PROTO;
+
writel(reg, priv->regbase + CQSPI_REG_CONFIG);
return 0;
@@ -465,10 +473,16 @@ int cadence_qspi_apb_command_read(struct cadence_spi_priv *priv,
unsigned int dummy_clk;
u8 opcode;
- if (priv->dtr)
- opcode = op->cmd.opcode >> 8;
- else
+ switch (op->cmd.nbytes) {
+ case 1:
opcode = op->cmd.opcode;
+ break;
+ case 2:
+ opcode = op->cmd.opcode >> 8;
+ break;
+ default:
+ return log_msg_ret("QSPI: Invalid command length", -EINVAL);
+ }
if (opcode == CMD_4BYTE_OCTAL_READ && !priv->dtr)
opcode = CMD_4BYTE_FAST_READ;
@@ -557,10 +571,16 @@ int cadence_qspi_apb_command_write(struct cadence_spi_priv *priv,
void *reg_base = priv->regbase;
u8 opcode;
- if (priv->dtr)
- opcode = op->cmd.opcode >> 8;
- else
+ switch (op->cmd.nbytes) {
+ case 1:
opcode = op->cmd.opcode;
+ break;
+ case 2:
+ opcode = op->cmd.opcode >> 8;
+ break;
+ default:
+ return log_msg_ret("QSPI: Invalid command length", -EINVAL);
+ }
reg |= opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
@@ -634,10 +654,16 @@ int cadence_qspi_apb_read_setup(struct cadence_spi_priv *priv,
priv->regbase + CQSPI_REG_INDIRECTTRIGGER);
/* Configure the opcode */
- if (priv->dtr)
- opcode = op->cmd.opcode >> 8;
- else
+ switch (op->cmd.nbytes) {
+ case 1:
opcode = op->cmd.opcode;
+ break;
+ case 2:
+ opcode = op->cmd.opcode >> 8;
+ break;
+ default:
+ return log_msg_ret("QSPI: Invalid command length", -EINVAL);
+ }
rd_reg = opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
rd_reg |= op->cmd.dtr ? CQSPI_REG_RD_INSTR_DDR_EN_MASK : 0;
@@ -804,10 +830,16 @@ int cadence_qspi_apb_write_setup(struct cadence_spi_priv *priv,
priv->regbase + CQSPI_REG_INDIRECTTRIGGER);
/* Configure the opcode */
- if (priv->dtr)
- opcode = op->cmd.opcode >> 8;
- else
+ switch (op->cmd.nbytes) {
+ case 1:
opcode = op->cmd.opcode;
+ break;
+ case 2:
+ opcode = op->cmd.opcode >> 8;
+ break;
+ default:
+ return log_msg_ret("QSPI: Invalid command length", -EINVAL);
+ }
reg = opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
reg |= priv->data_width << CQSPI_REG_WR_INSTR_TYPE_DATA_LSB;
--
2.43.2
More information about the U-Boot
mailing list