[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250910030301.1368372-4-linchengming884@gmail.com>
Date: Wed, 10 Sep 2025 11:03:01 +0800
From: Cheng Ming Lin <linchengming884@...il.com>
To: miquel.raynal@...tlin.com,
richard@....at,
vigneshr@...com,
robh@...nel.org,
krzk+dt@...nel.org,
conor+dt@...nel.org
Cc: tudor.ambarus@...aro.org,
mmkurbanov@...utedevices.com,
Takahiro.Kuwano@...ineon.com,
pratyush@...nel.org,
linux-mtd@...ts.infradead.org,
devicetree@...r.kernel.org,
linux-kernel@...r.kernel.org,
alvinzhou@...c.com.tw,
Cheng Ming Lin <chengminglin@...c.com.tw>
Subject: [PATCH v2 3/3] mtd: spi-nand: macronix: Add randomizer support
From: Cheng Ming Lin <chengminglin@...c.com.tw>
Enable randomizer function by specific flowchart to set the default value
of RANDEN to 1.
Randomizer introduces a new DT property "mxic,randopt" to define the
randomizer area per page.
The penalty of randomizer are subpage accesses prohibited and more time
period is needed in program operation and entering deep power-down mode.
i.e., tPROG 320us to 360us (randomizer enabled).
Signed-off-by: Cheng Ming Lin <chengminglin@...c.com.tw>
---
drivers/mtd/nand/spi/macronix.c | 89 +++++++++++++++++++++++++++++----
1 file changed, 79 insertions(+), 10 deletions(-)
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
index edf63b999..7450ee1d3 100644
--- a/drivers/mtd/nand/spi/macronix.c
+++ b/drivers/mtd/nand/spi/macronix.c
@@ -14,6 +14,10 @@
#define MACRONIX_ECCSR_BF_LAST_PAGE(eccsr) FIELD_GET(GENMASK(3, 0), eccsr)
#define MACRONIX_ECCSR_BF_ACCUMULATED_PAGES(eccsr) FIELD_GET(GENMASK(7, 4), eccsr)
#define MACRONIX_CFG_CONT_READ BIT(2)
+#define MACRONIX_CFG_ENPGM BIT(0)
+#define MACRONIX_CFG_RANDEN BIT(1)
+#define MACRONIX_CFG_RANDOPT BIT(2)
+#define MACRONIX_FEATURE_ADDR_RANDOMIZER 0x10
#define MACRONIX_FEATURE_ADDR_READ_RETRY 0x70
#define MACRONIX_NUM_READ_RETRY_MODES 5
@@ -155,6 +159,61 @@ static int macronix_set_read_retry(struct spinand_device *spinand,
return spi_mem_exec_op(spinand->spimem, &op);
}
+static int macronix_set_randomizer(struct spinand_device *spinand)
+{
+ struct spi_mem_op exec_op = SPINAND_PROG_EXEC_1S_1S_0_OP(0);
+ struct nand_device *nand = spinand_to_nand(spinand);
+ struct device_node *dn = nanddev_get_of_node(nand);
+ int randopt, ret;
+ u8 cfg, status;
+
+ ret = spinand_read_reg_op(spinand, MACRONIX_FEATURE_ADDR_RANDOMIZER, &cfg);
+ if (ret)
+ return ret;
+ if (cfg)
+ return 0;
+
+ cfg = MACRONIX_CFG_ENPGM | MACRONIX_CFG_RANDEN;
+ randopt = of_property_read_bool(dn, "mxic,randopt");
+ if (randopt)
+ cfg |= MACRONIX_CFG_RANDOPT;
+
+ ret = spinand_write_reg_op(spinand, MACRONIX_FEATURE_ADDR_RANDOMIZER, cfg);
+ if (ret)
+ return ret;
+
+ ret = spinand_write_enable_op(spinand);
+ if (ret)
+ return ret;
+
+ ret = spi_mem_exec_op(spinand->spimem, &exec_op);
+ if (ret)
+ return ret;
+
+ ret = spinand_wait(spinand,
+ SPINAND_WRITE_INITIAL_DELAY_US,
+ SPINAND_WRITE_POLL_DELAY_US,
+ &status);
+ if (ret)
+ return ret;
+
+ if (status & STATUS_PROG_FAILED)
+ return -EIO;
+
+ ret = spinand_read_reg_op(spinand, MACRONIX_FEATURE_ADDR_RANDOMIZER, &status);
+ if (ret)
+ return ret;
+ if (status != cfg)
+ return -EIO;
+
+ cfg &= ~MACRONIX_CFG_ENPGM;
+ ret = spinand_write_reg_op(spinand, MACRONIX_FEATURE_ADDR_RANDOMIZER, cfg);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static const struct spinand_info macronix_spinand_table[] = {
SPINAND_INFO("MX35LF1GE4AB",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12),
@@ -213,7 +272,8 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
- macronix_set_read_retry)),
+ macronix_set_read_retry),
+ SPINAND_RANDOMIZER(macronix_set_randomizer)),
SPINAND_INFO("MX35LF2G24AD",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24, 0x03),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
@@ -225,7 +285,8 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_HAS_PROG_PLANE_SELECT_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
- macronix_set_read_retry)),
+ macronix_set_read_retry),
+ SPINAND_RANDOMIZER(macronix_set_randomizer)),
SPINAND_INFO("MX35LF2G24AD-Z4I8",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x64, 0x03),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
@@ -236,7 +297,8 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
- macronix_set_read_retry)),
+ macronix_set_read_retry),
+ SPINAND_RANDOMIZER(macronix_set_randomizer)),
SPINAND_INFO("MX35LF4G24AD",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35, 0x03),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1),
@@ -248,7 +310,8 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_HAS_PROG_PLANE_SELECT_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
- macronix_set_read_retry)),
+ macronix_set_read_retry),
+ SPINAND_RANDOMIZER(macronix_set_randomizer)),
SPINAND_INFO("MX35LF4G24AD-Z4I8",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x75, 0x03),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
@@ -259,7 +322,8 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
- macronix_set_read_retry)),
+ macronix_set_read_retry),
+ SPINAND_RANDOMIZER(macronix_set_randomizer)),
SPINAND_INFO("MX31LF1GE4BC",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
@@ -305,7 +369,8 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
macronix_ecc_get_status),
SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
- macronix_set_read_retry)),
+ macronix_set_read_retry),
+ SPINAND_RANDOMIZER(macronix_set_randomizer)),
SPINAND_INFO("MX35UF4G24AD-Z4I8",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xf5, 0x03),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
@@ -317,7 +382,8 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
macronix_ecc_get_status),
SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
- macronix_set_read_retry)),
+ macronix_set_read_retry),
+ SPINAND_RANDOMIZER(macronix_set_randomizer)),
SPINAND_INFO("MX35UF4GE4AD",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb7, 0x03),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
@@ -355,7 +421,8 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
macronix_ecc_get_status),
SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
- macronix_set_read_retry)),
+ macronix_set_read_retry),
+ SPINAND_RANDOMIZER(macronix_set_randomizer)),
SPINAND_INFO("MX35UF2G24AD-Z4I8",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xe4, 0x03),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
@@ -367,7 +434,8 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
macronix_ecc_get_status),
SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
- macronix_set_read_retry)),
+ macronix_set_read_retry),
+ SPINAND_RANDOMIZER(macronix_set_randomizer)),
SPINAND_INFO("MX35UF2GE4AD",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa6, 0x03),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
@@ -413,7 +481,8 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
macronix_ecc_get_status),
SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
- macronix_set_read_retry)),
+ macronix_set_read_retry),
+ SPINAND_RANDOMIZER(macronix_set_randomizer)),
SPINAND_INFO("MX35UF1GE4AD",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x96, 0x03),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
--
2.25.1
Powered by blists - more mailing lists