mirror of
https://github.com/openwrt/openwrt.git
synced 2026-05-05 22:25:44 +04:00
5ff0e70930
This patch series greatly improve airoha snfi driver and fix a number of serious bugs. Fixed bugs: * Fix reading/writing of flashes with more than one plane per lun * Fill the buffer with 0xff before writing * Fix reading of flashes supporting continuous reading mode * Fix error paths Improvements: * Add support of dual/quad wires spi modes in exec_op(). This also fix flash reading/writing if dirmap can't be created. * Support of dualio/quadio flash reading commands Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu> Link: https://github.com/openwrt/openwrt/pull/20295 Signed-off-by: Robert Marko <robimarko@gmail.com>
136 lines
3.9 KiB
Diff
136 lines
3.9 KiB
Diff
From 995b1a65206ee28d5403db0518cb230f2ce429ef Mon Sep 17 00:00:00 2001
|
|
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
|
Date: Mon, 11 Aug 2025 19:57:43 +0300
|
|
Subject: [PATCH v6 07/13] spi: airoha: unify dirmap read/write code
|
|
|
|
Makes dirmap writing looks similar to dirmap reading. Just a minor
|
|
refactoring, no behavior change is expected.
|
|
|
|
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
|
---
|
|
drivers/spi/spi-airoha-snfi.c | 50 ++++++++++++++++++++++-------------
|
|
1 file changed, 32 insertions(+), 18 deletions(-)
|
|
|
|
--- a/drivers/spi/spi-airoha-snfi.c
|
|
+++ b/drivers/spi/spi-airoha-snfi.c
|
|
@@ -672,6 +672,8 @@ static ssize_t airoha_snand_dirmap_read(
|
|
u32 val, rd_mode;
|
|
int err;
|
|
|
|
+ as_ctrl = spi_controller_get_devdata(spi->controller);
|
|
+
|
|
switch (op->cmd.opcode) {
|
|
case SPI_NAND_OP_READ_FROM_CACHE_DUAL:
|
|
rd_mode = 1;
|
|
@@ -684,7 +686,6 @@ static ssize_t airoha_snand_dirmap_read(
|
|
break;
|
|
}
|
|
|
|
- as_ctrl = spi_controller_get_devdata(spi->controller);
|
|
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA);
|
|
if (err < 0)
|
|
return err;
|
|
@@ -748,7 +749,7 @@ static ssize_t airoha_snand_dirmap_read(
|
|
if (err)
|
|
goto error_dma_unmap;
|
|
|
|
- /* trigger dma start read */
|
|
+ /* trigger dma reading */
|
|
err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
|
|
SPI_NFI_RD_TRIG);
|
|
if (err)
|
|
@@ -806,37 +807,47 @@ error_dma_mode_off:
|
|
static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc,
|
|
u64 offs, size_t len, const void *buf)
|
|
{
|
|
- struct spi_mem_op *op = &desc->info.op_tmpl;
|
|
struct spi_device *spi = desc->mem->spi;
|
|
u8 *txrx_buf = spi_get_ctldata(spi);
|
|
struct airoha_snand_ctrl *as_ctrl;
|
|
dma_addr_t dma_addr;
|
|
- u32 wr_mode, val;
|
|
+ u32 wr_mode, val, opcode;
|
|
int err;
|
|
|
|
as_ctrl = spi_controller_get_devdata(spi->controller);
|
|
|
|
+ opcode = desc->info.op_tmpl.cmd.opcode;
|
|
+ switch (opcode) {
|
|
+ case SPI_NAND_OP_PROGRAM_LOAD_SINGLE:
|
|
+ case SPI_NAND_OP_PROGRAM_LOAD_RAMDOM_SINGLE:
|
|
+ wr_mode = 0;
|
|
+ break;
|
|
+ case SPI_NAND_OP_PROGRAM_LOAD_QUAD:
|
|
+ case SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD:
|
|
+ wr_mode = 2;
|
|
+ break;
|
|
+ default:
|
|
+ /* unknown opcode */
|
|
+ return -EOPNOTSUPP;
|
|
+ }
|
|
+
|
|
memcpy(txrx_buf + offs, buf, len);
|
|
- dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
|
|
- DMA_TO_DEVICE);
|
|
- err = dma_mapping_error(as_ctrl->dev, dma_addr);
|
|
- if (err)
|
|
- return err;
|
|
|
|
err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA);
|
|
if (err < 0)
|
|
- goto error_dma_unmap;
|
|
+ return err;
|
|
|
|
err = airoha_snand_nfi_config(as_ctrl);
|
|
if (err)
|
|
- goto error_dma_unmap;
|
|
+ goto error_dma_mode_off;
|
|
|
|
- if (op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_QUAD ||
|
|
- op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD)
|
|
- wr_mode = BIT(1);
|
|
- else
|
|
- wr_mode = 0;
|
|
+ dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE,
|
|
+ DMA_TO_DEVICE);
|
|
+ err = dma_mapping_error(as_ctrl->dev, dma_addr);
|
|
+ if (err)
|
|
+ goto error_dma_mode_off;
|
|
|
|
+ /* set dma addr */
|
|
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR,
|
|
dma_addr);
|
|
if (err)
|
|
@@ -850,12 +861,13 @@ static ssize_t airoha_snand_dirmap_write
|
|
if (err)
|
|
goto error_dma_unmap;
|
|
|
|
+ /* set write command */
|
|
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL1,
|
|
- FIELD_PREP(SPI_NFI_PG_LOAD_CMD,
|
|
- op->cmd.opcode));
|
|
+ FIELD_PREP(SPI_NFI_PG_LOAD_CMD, opcode));
|
|
if (err)
|
|
goto error_dma_unmap;
|
|
|
|
+ /* set write mode */
|
|
err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL,
|
|
FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, wr_mode));
|
|
if (err)
|
|
@@ -887,6 +899,7 @@ static ssize_t airoha_snand_dirmap_write
|
|
if (err)
|
|
goto error_dma_unmap;
|
|
|
|
+ /* trigger dma writing */
|
|
err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON,
|
|
SPI_NFI_WR_TRIG);
|
|
if (err)
|
|
@@ -931,6 +944,7 @@ static ssize_t airoha_snand_dirmap_write
|
|
error_dma_unmap:
|
|
dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE,
|
|
DMA_TO_DEVICE);
|
|
+error_dma_mode_off:
|
|
airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL);
|
|
return err;
|
|
}
|