From 531e1fe34be024cf2d68843c959ef5f90c8bce64 Mon Sep 17 00:00:00 2001 From: Mikhail Kshevetskiy Date: Sun, 9 Nov 2025 10:06:51 +0300 Subject: [PATCH] spi: airoha: support of dualio/quadio flash reading commands Airoha snfi spi controller supports acceleration of DUAL/QUAD operations, but does not supports DUAL_IO/QUAD_IO operations. Luckily DUAL/QUAD operations do the same as DUAL_IO/QUAD_IO ones, so we can issue corresponding DUAL/QUAD operation instead of DUAL_IO/QUAD_IO one. Signed-off-by: Mikhail Kshevetskiy --- drivers/spi/airoha_snfi_spi.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/spi/airoha_snfi_spi.c b/drivers/spi/airoha_snfi_spi.c index bec4ec0bf00..65381060407 100644 --- a/drivers/spi/airoha_snfi_spi.c +++ b/drivers/spi/airoha_snfi_spi.c @@ -141,6 +141,7 @@ #define SPI_NFI_CUS_SEC_SIZE_EN BIT(16) #define REG_SPI_NFI_RD_CTL2 0x0510 +#define SPI_NFI_DATA_READ_CMD GENMASK(7, 0) #define REG_SPI_NFI_RD_CTL3 0x0514 @@ -175,7 +176,9 @@ #define SPI_NAND_OP_READ_FROM_CACHE_SINGLE 0x03 #define SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST 0x0b #define SPI_NAND_OP_READ_FROM_CACHE_DUAL 0x3b +#define SPI_NAND_OP_READ_FROM_CACHE_DUALIO 0xbb #define SPI_NAND_OP_READ_FROM_CACHE_QUAD 0x6b +#define SPI_NAND_OP_READ_FROM_CACHE_QUADIO 0xeb #define SPI_NAND_OP_WRITE_ENABLE 0x06 #define SPI_NAND_OP_WRITE_DISABLE 0x04 #define SPI_NAND_OP_PROGRAM_LOAD_SINGLE 0x02 @@ -643,25 +646,37 @@ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc) static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, void *buf) { - struct spi_mem_op *op = &desc->info.op_tmpl; struct spi_slave *slave = desc->slave; struct udevice *bus = slave->dev->parent; struct airoha_snand_priv *priv = dev_get_priv(bus); u8 *txrx_buf = priv->txrx_buf; dma_addr_t dma_addr; - u32 val, rd_mode; + u32 val, rd_mode, opcode; int err; - switch (op->cmd.opcode) { + /* + * DUALIO and QUADIO opcodes are not supported by the spi controller, + * replace them with supported opcodes. + */ + opcode = desc->info.op_tmpl.cmd.opcode; + switch (opcode) { + case SPI_NAND_OP_READ_FROM_CACHE_SINGLE: + case SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST: + rd_mode = 0; + break; case SPI_NAND_OP_READ_FROM_CACHE_DUAL: + case SPI_NAND_OP_READ_FROM_CACHE_DUALIO: + opcode = SPI_NAND_OP_READ_FROM_CACHE_DUAL; rd_mode = 1; break; case SPI_NAND_OP_READ_FROM_CACHE_QUAD: + case SPI_NAND_OP_READ_FROM_CACHE_QUADIO: + opcode = SPI_NAND_OP_READ_FROM_CACHE_QUAD; rd_mode = 2; break; default: - rd_mode = 0; - break; + /* unknown opcode */ + return -EOPNOTSUPP; } err = airoha_snand_set_mode(priv, SPI_MODE_DMA); @@ -692,7 +707,7 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, /* set read command */ err = regmap_write(priv->regmap_nfi, REG_SPI_NFI_RD_CTL2, - op->cmd.opcode); + FIELD_PREP(SPI_NFI_DATA_READ_CMD, opcode)); if (err) goto error_dma_unmap; -- 2.47.3