]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
spi: airoha: support of dualio/quadio flash reading commands
authorMikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Sun, 12 Oct 2025 12:16:59 +0000 (15:16 +0300)
committerMark Brown <broonie@kernel.org>
Fri, 17 Oct 2025 12:30:48 +0000 (13:30 +0100)
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 <mikhail.kshevetskiy@iopsys.eu>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patch.msgid.link/20251012121707.2296160-9-mikhail.kshevetskiy@iopsys.eu
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-airoha-snfi.c

index e90fab69d81e51bf6e55e696d22cc4296e73f6a0..744eeb2b24efcc324e75c90b793eb9041251b552 100644 (file)
 #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
 
 #define REG_SPI_NFI_PG_CTL1                    0x0524
 #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
@@ -664,26 +668,38 @@ 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_device *spi = desc->mem->spi;
        struct airoha_snand_ctrl *as_ctrl;
        u8 *txrx_buf = spi_get_ctldata(spi);
        dma_addr_t dma_addr;
-       u32 val, rd_mode;
+       u32 val, rd_mode, opcode;
        int err;
 
        as_ctrl = spi_controller_get_devdata(spi->controller);
 
-       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(as_ctrl, SPI_MODE_DMA);
@@ -717,7 +733,7 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc,
 
        /* set read command */
        err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL2,
-                          op->cmd.opcode);
+                          FIELD_PREP(SPI_NFI_DATA_READ_CMD, opcode));
        if (err)
                goto error_dma_unmap;