aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2026-01-09 18:18:19 +0100
committerMiquel Raynal <miquel.raynal@bootlin.com>2026-01-29 20:21:41 +0100
commitbe0b86c648bf811237cc17e274e9f9488fccb772 (patch)
treef6f2686a1251f1d1633662fe3e29e33990f615df
parentef1ed296fb9d9246256e1b5b2cf2e86e85606ac3 (diff)
mtd: spinand: Gather all the bus interface steps in one single function
Writing the quad enable bit in one helper and doing the chip configuration in another does not make much sense from a bus interface setup point of view. Instead, let's create a broader helper which is going to be in charge of all the bus configuration steps at once. This will specifically allow to transition to octal DDR mode, and even fallback to quad (if suppoorted) or single mode otherwise. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-rw-r--r--drivers/mtd/nand/spi/core.c62
1 files changed, 37 insertions, 25 deletions
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index cdf45d054082..e52d76afb5b5 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -261,18 +261,9 @@ static int spinand_init_cfg_cache(struct spinand_device *spinand)
return 0;
}
-static int spinand_init_quad_enable(struct spinand_device *spinand)
+static int spinand_init_quad_enable(struct spinand_device *spinand,
+ bool enable)
{
- bool enable = false;
-
- if (!(spinand->flags & SPINAND_HAS_QE_BIT))
- return 0;
-
- if (spinand->op_templates->read_cache->data.buswidth == 4 ||
- spinand->op_templates->write_cache->data.buswidth == 4 ||
- spinand->op_templates->update_cache->data.buswidth == 4)
- enable = true;
-
return spinand_upd_cfg(spinand, CFG_QUAD_ENABLE,
enable ? CFG_QUAD_ENABLE : 0);
}
@@ -1392,12 +1383,6 @@ static int spinand_manufacturer_init(struct spinand_device *spinand)
return ret;
}
- if (spinand->configure_chip) {
- ret = spinand->configure_chip(spinand);
- if (ret)
- return ret;
- }
-
return 0;
}
@@ -1600,6 +1585,31 @@ static int spinand_detect(struct spinand_device *spinand)
return 0;
}
+static int spinand_configure_chip(struct spinand_device *spinand)
+{
+ bool quad_enable = false;
+ int ret;
+
+ if (spinand->flags & SPINAND_HAS_QE_BIT) {
+ if (spinand->ssdr_op_templates.read_cache->data.buswidth == 4 ||
+ spinand->ssdr_op_templates.write_cache->data.buswidth == 4 ||
+ spinand->ssdr_op_templates.update_cache->data.buswidth == 4)
+ quad_enable = true;
+ }
+
+ ret = spinand_init_quad_enable(spinand, quad_enable);
+ if (ret)
+ return ret;
+
+ if (spinand->configure_chip) {
+ ret = spinand->configure_chip(spinand);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+
static int spinand_init_flash(struct spinand_device *spinand)
{
struct device *dev = &spinand->spimem->spi->dev;
@@ -1610,10 +1620,6 @@ static int spinand_init_flash(struct spinand_device *spinand)
if (ret)
return ret;
- ret = spinand_init_quad_enable(spinand);
- if (ret)
- return ret;
-
ret = spinand_upd_cfg(spinand, CFG_OTP_ENABLE, 0);
if (ret)
return ret;
@@ -1626,19 +1632,25 @@ static int spinand_init_flash(struct spinand_device *spinand)
return ret;
}
+ ret = spinand_configure_chip(spinand);
+ if (ret)
+ goto manuf_cleanup;
+
/* After power up, all blocks are locked, so unlock them here. */
for (i = 0; i < nand->memorg.ntargets; i++) {
ret = spinand_select_target(spinand, i);
if (ret)
- break;
+ goto manuf_cleanup;
ret = spinand_lock_block(spinand, BL_ALL_UNLOCKED);
if (ret)
- break;
+ goto manuf_cleanup;
}
- if (ret)
- spinand_manufacturer_cleanup(spinand);
+ return 0;
+
+manuf_cleanup:
+ spinand_manufacturer_cleanup(spinand);
return ret;
}