From: Cheng Ming Lin <linchengming884@gmail.com>
To: miquel.raynal@bootlin.com, vigneshr@ti.com,
linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org
Cc: richard@nod.at, alvinzhou@mxic.com.tw, leoyu@mxic.com.tw,
Cheng Ming Lin <chengminglin@mxic.com.tw>
Subject: [PATCH 2/2] mtd: spi-nand: macronix: Add randomizer support
Date: Fri, 8 Aug 2025 17:55:03 +0800 [thread overview]
Message-ID: <20250808095503.906244-3-linchengming884@gmail.com> (raw)
In-Reply-To: <20250808095503.906244-1-linchengming884@gmail.com>
From: Cheng Ming Lin <chengminglin@mxic.com.tw>
Enable randomizer function by specific flowchart to set the default value
of RANDEN to 1.
Randomizer introduces two new DT properties for child nodes to configure
the randomizer functionality and coverage options.
- mxic,enable-randomizer-otp: Specify whether to activate the randomizer
feature.
- mxic,randopt: 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@mxic.com.tw>
---
drivers/mtd/nand/spi/macronix.c | 94 +++++++++++++++++++++++++++++----
1 file changed, 84 insertions(+), 10 deletions(-)
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
index edf63b9996cf..5354b1894bb4 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,66 @@ 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 mtd_info *mtd = spinand_to_mtd(spinand);
+ struct nand_device *nand = mtd_to_nanddev(mtd);
+ struct device_node *dn = nanddev_get_of_node(nand);
+ int rand_dt, randopt, ret;
+ u8 cfg, status, check;
+
+ rand_dt = of_property_read_bool(dn, "mxic,enable-randomizer-otp");
+ if (!rand_dt)
+ return 0;
+
+ 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, &check);
+ if (ret)
+ return ret;
+ if (check != 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 +277,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 +290,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 +302,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 +315,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 +327,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 +374,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 +387,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 +426,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 +439,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 +486,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
next prev parent reply other threads:[~2025-08-08 9:57 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-08 9:55 [PATCH 0/2] Add support for randomizer Cheng Ming Lin
2025-08-08 9:55 ` [PATCH 1/2] mtd: spi-nand: " Cheng Ming Lin
2025-08-08 10:15 ` Miquel Raynal
2025-08-08 11:35 ` Cheng Ming Lin
2025-08-08 9:55 ` Cheng Ming Lin [this message]
2025-08-08 10:19 ` [PATCH 2/2] mtd: spi-nand: macronix: Add randomizer support Miquel Raynal
2025-08-08 11:49 ` Cheng Ming Lin
2025-08-11 3:01 ` Cheng Ming Lin
2025-08-18 8:47 ` Miquel Raynal
2025-09-05 1:14 ` Cheng Ming Lin
2025-09-05 14:08 ` Miquel Raynal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250808095503.906244-3-linchengming884@gmail.com \
--to=linchengming884@gmail.com \
--cc=alvinzhou@mxic.com.tw \
--cc=chengminglin@mxic.com.tw \
--cc=leoyu@mxic.com.tw \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=miquel.raynal@bootlin.com \
--cc=richard@nod.at \
--cc=vigneshr@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox