* [PATCH v3 0/2] Add support for read retry
@ 2025-01-22 6:56 Cheng Ming Lin
2025-01-22 6:56 ` [PATCH v3 1/2] mtd: spi-nand: Add read retry support Cheng Ming Lin
2025-01-22 6:56 ` [PATCH v3 2/2] mtd: spi-nand: macronix: Add support for read retry Cheng Ming Lin
0 siblings, 2 replies; 10+ messages in thread
From: Cheng Ming Lin @ 2025-01-22 6:56 UTC (permalink / raw)
To: miquel.raynal, vigneshr, linux-mtd, linux-kernel
Cc: richard, alvinzhou, leoyu, Cheng Ming Lin
From: Cheng Ming Lin <chengminglin@mxic.com.tw>
When the host ECC fails to correct the data error of NAND device,
there's a special read for data recovery method which can be setup
by the host for the next read. There are several retry levels that
can be attempted until the lost data is recovered or definitely
assumed lost.
For more detailed information, please refer to the link below:
Link: https://www.macronix.com/Lists/Datasheet/Attachments/9034/MX35LF1G24AD,%203V,%201Gb,%20v1.4.pdf
v3:
* If set_read_retry fails, it should return an error
v2:
* Remove fixups
* Remove the function of init_read_retry
Cheng Ming Lin (2):
mtd: spi-nand: Add read retry support
mtd: spi-nand: macronix: Add support for read retry
drivers/mtd/nand/spi/core.c | 35 ++++++++++++++-
drivers/mtd/nand/spi/macronix.c | 79 ++++++++++++++++++++++++++-------
include/linux/mtd/spinand.h | 14 ++++++
3 files changed, 111 insertions(+), 17 deletions(-)
--
2.25.1
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 1/2] mtd: spi-nand: Add read retry support
2025-01-22 6:56 [PATCH v3 0/2] Add support for read retry Cheng Ming Lin
@ 2025-01-22 6:56 ` Cheng Ming Lin
2025-02-06 17:13 ` Miquel Raynal
2025-01-22 6:56 ` [PATCH v3 2/2] mtd: spi-nand: macronix: Add support for read retry Cheng Ming Lin
1 sibling, 1 reply; 10+ messages in thread
From: Cheng Ming Lin @ 2025-01-22 6:56 UTC (permalink / raw)
To: miquel.raynal, vigneshr, linux-mtd, linux-kernel
Cc: richard, alvinzhou, leoyu, Cheng Ming Lin
From: Cheng Ming Lin <chengminglin@mxic.com.tw>
When the host ECC fails to correct the data error of NAND device,
there's a special read for data recovery method which can be setup
by the host for the next read. There are several retry levels that
can be attempted until the lost data is recovered or definitely
assumed lost.
Signed-off-by: Cheng Ming Lin <chengminglin@mxic.com.tw>
---
drivers/mtd/nand/spi/core.c | 35 +++++++++++++++++++++++++++++++++--
include/linux/mtd/spinand.h | 14 ++++++++++++++
2 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 4d76f9f71a0e..3f72d94c09f3 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -671,11 +671,15 @@ static int spinand_mtd_regular_page_read(struct mtd_info *mtd, loff_t from,
{
struct spinand_device *spinand = mtd_to_spinand(mtd);
struct nand_device *nand = mtd_to_nanddev(mtd);
+ struct mtd_ecc_stats old_stats;
struct nand_io_iter iter;
bool disable_ecc = false;
bool ecc_failed = false;
+ unsigned int retry_mode = 0;
int ret;
+ old_stats = mtd->ecc_stats;
+
if (ops->mode == MTD_OPS_RAW || !mtd->ooblayout)
disable_ecc = true;
@@ -687,18 +691,43 @@ static int spinand_mtd_regular_page_read(struct mtd_info *mtd, loff_t from,
if (ret)
break;
+read_retry:
ret = spinand_read_page(spinand, &iter.req);
if (ret < 0 && ret != -EBADMSG)
break;
- if (ret == -EBADMSG)
+ if (ret == -EBADMSG && spinand->set_read_retry) {
+ if (spinand->read_retries && (++retry_mode < spinand->read_retries)) {
+ ret = spinand->set_read_retry(spinand, retry_mode);
+ if (ret < 0) {
+ ecc_failed = true;
+ return ret;
+ }
+
+ /* Reset ecc_stats; retry */
+ mtd->ecc_stats = old_stats;
+ goto read_retry;
+ } else {
+ /* No more retry modes; real failure */
+ ecc_failed = true;
+ }
+ } else if (ret == -EBADMSG) {
ecc_failed = true;
- else
+ } else {
*max_bitflips = max_t(unsigned int, *max_bitflips, ret);
+ }
ret = 0;
ops->retlen += iter.req.datalen;
ops->oobretlen += iter.req.ooblen;
+
+ /* Reset to retry mode 0 */
+ if (retry_mode) {
+ retry_mode = 0;
+ ret = spinand->set_read_retry(spinand, retry_mode);
+ if (ret < 0)
+ return ret;
+ }
}
if (ecc_failed && !ret)
@@ -1268,6 +1297,8 @@ int spinand_match_and_init(struct spinand_device *spinand,
spinand->id.len = 1 + table[i].devid.len;
spinand->select_target = table[i].select_target;
spinand->set_cont_read = table[i].set_cont_read;
+ spinand->read_retries = table[i].read_retries;
+ spinand->set_read_retry = table[i].set_read_retry;
op = spinand_select_op_variant(spinand,
info->op_variants.read_cache);
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 702e5fb13dae..bbfef90135f5 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -339,6 +339,8 @@ struct spinand_ondie_ecc_conf {
* @select_target: function used to select a target/die. Required only for
* multi-die chips
* @set_cont_read: enable/disable continuous cached reads
+ * @read_retries: the number of read retry modes supported
+ * @set_read_retry: enable/disable read retry for data recovery
*
* Each SPI NAND manufacturer driver should have a spinand_info table
* describing all the chips supported by the driver.
@@ -359,6 +361,9 @@ struct spinand_info {
unsigned int target);
int (*set_cont_read)(struct spinand_device *spinand,
bool enable);
+ unsigned int read_retries;
+ int (*set_read_retry)(struct spinand_device *spinand,
+ unsigned int read_retry);
};
#define SPINAND_ID(__method, ...) \
@@ -387,6 +392,10 @@ struct spinand_info {
#define SPINAND_CONT_READ(__set_cont_read) \
.set_cont_read = __set_cont_read,
+#define SPINAND_READ_RETRY(__read_retries, __set_read_retry) \
+ .read_retries = __read_retries, \
+ .set_read_retry = __set_read_retry,
+
#define SPINAND_INFO(__model, __id, __memorg, __eccreq, __op_variants, \
__flags, ...) \
{ \
@@ -436,6 +445,8 @@ struct spinand_dirmap {
* A per-transfer check must of course be done to ensure it is
* actually relevant to enable this feature.
* @set_cont_read: Enable/disable the continuous read feature
+ * @read_retries: the number of read retry modes supported
+ * @set_read_retry: Enable/disable the read retry feature
* @priv: manufacturer private data
*/
struct spinand_device {
@@ -469,6 +480,9 @@ struct spinand_device {
bool cont_read_possible;
int (*set_cont_read)(struct spinand_device *spinand,
bool enable);
+ unsigned int read_retries;
+ int (*set_read_retry)(struct spinand_device *spinand,
+ unsigned int retry_mode);
};
/**
--
2.25.1
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 2/2] mtd: spi-nand: macronix: Add support for read retry
2025-01-22 6:56 [PATCH v3 0/2] Add support for read retry Cheng Ming Lin
2025-01-22 6:56 ` [PATCH v3 1/2] mtd: spi-nand: Add read retry support Cheng Ming Lin
@ 2025-01-22 6:56 ` Cheng Ming Lin
2025-02-06 17:07 ` Miquel Raynal
1 sibling, 1 reply; 10+ messages in thread
From: Cheng Ming Lin @ 2025-01-22 6:56 UTC (permalink / raw)
To: miquel.raynal, vigneshr, linux-mtd, linux-kernel
Cc: richard, alvinzhou, leoyu, Cheng Ming Lin
From: Cheng Ming Lin <chengminglin@mxic.com.tw>
Add read retry support.
The Special Read for Data Recovery operation is enabled by
Set Feature function.
There are 6 modes for the user to recover the lost data.
Signed-off-by: Cheng Ming Lin <chengminglin@mxic.com.tw>
---
drivers/mtd/nand/spi/macronix.c | 79 ++++++++++++++++++++++++++-------
1 file changed, 64 insertions(+), 15 deletions(-)
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
index d277c3220fdc..d7087bac8da7 100644
--- a/drivers/mtd/nand/spi/macronix.c
+++ b/drivers/mtd/nand/spi/macronix.c
@@ -14,6 +14,8 @@
#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_FEATURE_ADDR_READ_RETRY 0x70
+#define MACRONIX_NUM_READ_RETRY_MODES 6
#define STATUS_ECC_HAS_BITFLIPS_THRESHOLD (3 << 4)
@@ -136,6 +138,23 @@ static int macronix_set_cont_read(struct spinand_device *spinand, bool enable)
return 0;
}
+/**
+ * macronix_set_read_retry - Set the retry mode
+ * @spinand: SPI NAND device
+ * @retry_mode: Specify which retry mode to set
+ *
+ * Return: 0 on success, a negative error code otherwise.
+ */
+static int macronix_set_read_retry(struct spinand_device *spinand,
+ unsigned int retry_mode)
+{
+ struct spi_mem_op op = SPINAND_SET_FEATURE_OP(MACRONIX_FEATURE_ADDR_READ_RETRY,
+ spinand->scratchbuf);
+
+ *spinand->scratchbuf = retry_mode;
+ return spi_mem_exec_op(spinand->spimem, &op);
+}
+
static const struct spinand_info macronix_spinand_table[] = {
SPINAND_INFO("MX35LF1GE4AB",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12),
@@ -168,7 +187,9 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
macronix_ecc_get_status),
- SPINAND_CONT_READ(macronix_set_cont_read)),
+ SPINAND_CONT_READ(macronix_set_cont_read)
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35LF4GE4AD",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37, 0x03),
NAND_MEMORG(1, 4096, 128, 64, 2048, 40, 1, 1, 1),
@@ -179,7 +200,9 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
macronix_ecc_get_status),
- SPINAND_CONT_READ(macronix_set_cont_read)),
+ SPINAND_CONT_READ(macronix_set_cont_read)
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35LF1G24AD",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14, 0x03),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
@@ -188,7 +211,9 @@ static const struct spinand_info macronix_spinand_table[] = {
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35LF2G24AD",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24, 0x03),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
@@ -198,7 +223,9 @@ static const struct spinand_info macronix_spinand_table[] = {
&update_cache_variants),
SPINAND_HAS_QE_BIT |
SPINAND_HAS_PROG_PLANE_SELECT_BIT,
- SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35LF2G24AD-Z4I8",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x64, 0x03),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
@@ -207,7 +234,9 @@ static const struct spinand_info macronix_spinand_table[] = {
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35LF4G24AD",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35, 0x03),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1),
@@ -217,7 +246,9 @@ static const struct spinand_info macronix_spinand_table[] = {
&update_cache_variants),
SPINAND_HAS_QE_BIT |
SPINAND_HAS_PROG_PLANE_SELECT_BIT,
- SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35LF4G24AD-Z4I8",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x75, 0x03),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
@@ -226,7 +257,9 @@ static const struct spinand_info macronix_spinand_table[] = {
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL),
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX31LF1GE4BC",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
@@ -270,7 +303,9 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_HAS_QE_BIT |
SPINAND_HAS_PROG_PLANE_SELECT_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
- macronix_ecc_get_status)),
+ macronix_ecc_get_status),
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35UF4G24AD-Z4I8",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xf5, 0x03),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
@@ -280,7 +315,9 @@ static const struct spinand_info macronix_spinand_table[] = {
&update_cache_variants),
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
- macronix_ecc_get_status)),
+ macronix_ecc_get_status),
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35UF4GE4AD",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb7, 0x03),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
@@ -291,7 +328,9 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
macronix_ecc_get_status),
- SPINAND_CONT_READ(macronix_set_cont_read)),
+ SPINAND_CONT_READ(macronix_set_cont_read)
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35UF2G14AC",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa0),
NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
@@ -314,7 +353,9 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_HAS_QE_BIT |
SPINAND_HAS_PROG_PLANE_SELECT_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
- macronix_ecc_get_status)),
+ macronix_ecc_get_status),
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35UF2G24AD-Z4I8",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xe4, 0x03),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
@@ -324,7 +365,9 @@ static const struct spinand_info macronix_spinand_table[] = {
&update_cache_variants),
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
- macronix_ecc_get_status)),
+ macronix_ecc_get_status),
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35UF2GE4AD",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa6, 0x03),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
@@ -335,7 +378,9 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
macronix_ecc_get_status),
- SPINAND_CONT_READ(macronix_set_cont_read)),
+ SPINAND_CONT_READ(macronix_set_cont_read)
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35UF2GE4AC",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa2, 0x01),
NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
@@ -366,7 +411,9 @@ static const struct spinand_info macronix_spinand_table[] = {
&update_cache_variants),
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
- macronix_ecc_get_status)),
+ macronix_ecc_get_status),
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35UF1GE4AD",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x96, 0x03),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
@@ -377,7 +424,9 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
macronix_ecc_get_status),
- SPINAND_CONT_READ(macronix_set_cont_read)),
+ SPINAND_CONT_READ(macronix_set_cont_read)
+ SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
+ macronix_set_read_retry)),
SPINAND_INFO("MX35UF1GE4AC",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92, 0x01),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
--
2.25.1
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v3 2/2] mtd: spi-nand: macronix: Add support for read retry
2025-01-22 6:56 ` [PATCH v3 2/2] mtd: spi-nand: macronix: Add support for read retry Cheng Ming Lin
@ 2025-02-06 17:07 ` Miquel Raynal
2025-02-10 2:46 ` Cheng Ming Lin
0 siblings, 1 reply; 10+ messages in thread
From: Miquel Raynal @ 2025-02-06 17:07 UTC (permalink / raw)
To: Cheng Ming Lin
Cc: vigneshr, linux-mtd, linux-kernel, richard, alvinzhou, leoyu,
Cheng Ming Lin
Hello,
On 22/01/2025 at 14:56:05 +08, Cheng Ming Lin <linchengming884@gmail.com> wrote:
> @@ -377,7 +424,9 @@ static const struct spinand_info macronix_spinand_table[] = {
> SPINAND_HAS_QE_BIT,
> SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
> macronix_ecc_get_status),
> - SPINAND_CONT_READ(macronix_set_cont_read)),
> + SPINAND_CONT_READ(macronix_set_cont_read)
I think there is a missing coma here and everywhere else where there is
continuous read support?
> + SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
> + macronix_set_read_retry)),
> SPINAND_INFO("MX35UF1GE4AC",
> SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92, 0x01),
> NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/2] mtd: spi-nand: Add read retry support
2025-01-22 6:56 ` [PATCH v3 1/2] mtd: spi-nand: Add read retry support Cheng Ming Lin
@ 2025-02-06 17:13 ` Miquel Raynal
2025-02-10 2:46 ` Cheng Ming Lin
0 siblings, 1 reply; 10+ messages in thread
From: Miquel Raynal @ 2025-02-06 17:13 UTC (permalink / raw)
To: Cheng Ming Lin
Cc: vigneshr, linux-mtd, linux-kernel, richard, alvinzhou, leoyu,
Cheng Ming Lin
Hello Cheng,
> @@ -687,18 +691,43 @@ static int spinand_mtd_regular_page_read(struct mtd_info *mtd, loff_t from,
> if (ret)
> break;
>
> +read_retry:
> ret = spinand_read_page(spinand, &iter.req);
> if (ret < 0 && ret != -EBADMSG)
> break;
>
> - if (ret == -EBADMSG)
> + if (ret == -EBADMSG && spinand->set_read_retry) {
> + if (spinand->read_retries && (++retry_mode < spinand->read_retries)) {
I believe the condition should be:
if (spinand->read_retries && (++retry_mode <= spinand->read_retries)) {
So if you have 5 retry modes, you can provide 5 in the manufacturer driver,
and not 6.
> + ret = spinand->set_read_retry(spinand, retry_mode);
> + if (ret < 0) {
> + ecc_failed = true;
> + return ret;
Shall we try to set the read_retry level to 0 upon:
if (ret < 0 && retry_mode > 1)
?
> + }
> +
> + /* Reset ecc_stats; retry */
> + mtd->ecc_stats = old_stats;
> + goto read_retry;
> + } else {
> + /* No more retry modes; real failure */
> + ecc_failed = true;
> + }
> + } else if (ret == -EBADMSG) {
Rest lgtm.
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/2] mtd: spi-nand: Add read retry support
2025-02-06 17:13 ` Miquel Raynal
@ 2025-02-10 2:46 ` Cheng Ming Lin
2025-02-10 10:07 ` Miquel Raynal
0 siblings, 1 reply; 10+ messages in thread
From: Cheng Ming Lin @ 2025-02-10 2:46 UTC (permalink / raw)
To: Miquel Raynal
Cc: vigneshr, linux-mtd, linux-kernel, richard, alvinzhou, leoyu,
Cheng Ming Lin
Hi Miquel,
Miquel Raynal <miquel.raynal@bootlin.com> 於 2025年2月7日 週五 上午1:13寫道:
>
> Hello Cheng,
>
> > @@ -687,18 +691,43 @@ static int spinand_mtd_regular_page_read(struct mtd_info *mtd, loff_t from,
> > if (ret)
> > break;
> >
> > +read_retry:
> > ret = spinand_read_page(spinand, &iter.req);
> > if (ret < 0 && ret != -EBADMSG)
> > break;
> >
> > - if (ret == -EBADMSG)
> > + if (ret == -EBADMSG && spinand->set_read_retry) {
> > + if (spinand->read_retries && (++retry_mode < spinand->read_retries)) {
>
> I believe the condition should be:
>
> if (spinand->read_retries && (++retry_mode <= spinand->read_retries)) {
>
> So if you have 5 retry modes, you can provide 5 in the manufacturer driver,
> and not 6.
This was originally based on the configuration in rawnand.
However, I agree that your proposed condition is a better approach.
Thank you for the suggestion.
>
> > + ret = spinand->set_read_retry(spinand, retry_mode);
> > + if (ret < 0) {
> > + ecc_failed = true;
> > + return ret;
>
> Shall we try to set the read_retry level to 0 upon:
>
> if (ret < 0 && retry_mode > 1)
>
> ?
If we set the read_retry level to 0 upon, and set_read_retry fails
when retry_mode equals to 1, it won't return an error. This could
potentially mask an underlying issue.
>
> > + }
> > +
> > + /* Reset ecc_stats; retry */
> > + mtd->ecc_stats = old_stats;
> > + goto read_retry;
> > + } else {
> > + /* No more retry modes; real failure */
> > + ecc_failed = true;
> > + }
> > + } else if (ret == -EBADMSG) {
>
> Rest lgtm.
>
> Thanks,
> Miquèl
Thanks,
Cheng Ming Lin
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 2/2] mtd: spi-nand: macronix: Add support for read retry
2025-02-06 17:07 ` Miquel Raynal
@ 2025-02-10 2:46 ` Cheng Ming Lin
0 siblings, 0 replies; 10+ messages in thread
From: Cheng Ming Lin @ 2025-02-10 2:46 UTC (permalink / raw)
To: Miquel Raynal
Cc: vigneshr, linux-mtd, linux-kernel, richard, alvinzhou, leoyu,
Cheng Ming Lin
Hi Miquel,
Miquel Raynal <miquel.raynal@bootlin.com> 於 2025年2月7日 週五 上午1:07寫道:
>
> Hello,
>
> On 22/01/2025 at 14:56:05 +08, Cheng Ming Lin <linchengming884@gmail.com> wrote:
>
> > @@ -377,7 +424,9 @@ static const struct spinand_info macronix_spinand_table[] = {
> > SPINAND_HAS_QE_BIT,
> > SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
> > macronix_ecc_get_status),
> > - SPINAND_CONT_READ(macronix_set_cont_read)),
> > + SPINAND_CONT_READ(macronix_set_cont_read)
>
> I think there is a missing coma here and everywhere else where there is
> continuous read support?
Thank you for pointing this out. I will correct the missing comma in this
instance and also review other areas with continuous read support to
ensure consistency.
>
> > + SPINAND_READ_RETRY(MACRONIX_NUM_READ_RETRY_MODES,
> > + macronix_set_read_retry)),
> > SPINAND_INFO("MX35UF1GE4AC",
> > SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92, 0x01),
> > NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
>
> Thanks,
> Miquèl
Thanks,
Cheng Ming Lin
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/2] mtd: spi-nand: Add read retry support
2025-02-10 2:46 ` Cheng Ming Lin
@ 2025-02-10 10:07 ` Miquel Raynal
2025-02-11 8:13 ` Cheng Ming Lin
0 siblings, 1 reply; 10+ messages in thread
From: Miquel Raynal @ 2025-02-10 10:07 UTC (permalink / raw)
To: Cheng Ming Lin
Cc: vigneshr, linux-mtd, linux-kernel, richard, alvinzhou, leoyu,
Cheng Ming Lin
Hello,
>> > + ret = spinand->set_read_retry(spinand, retry_mode);
>> > + if (ret < 0) {
>> > + ecc_failed = true;
>> > + return ret;
>>
>> Shall we try to set the read_retry level to 0 upon:
>>
>> if (ret < 0 && retry_mode > 1)
>>
>> ?
>
> If we set the read_retry level to 0 upon, and set_read_retry fails
> when retry_mode equals to 1, it won't return an error. This could
> potentially mask an underlying issue.
Don't save the return value in this case? But otherwise you would leave
the chip in a retry state, no?
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/2] mtd: spi-nand: Add read retry support
2025-02-10 10:07 ` Miquel Raynal
@ 2025-02-11 8:13 ` Cheng Ming Lin
2025-02-11 10:40 ` Miquel Raynal
0 siblings, 1 reply; 10+ messages in thread
From: Cheng Ming Lin @ 2025-02-11 8:13 UTC (permalink / raw)
To: Miquel Raynal
Cc: vigneshr, linux-mtd, linux-kernel, richard, alvinzhou, leoyu,
Cheng Ming Lin
Hi Miquel,
Miquel Raynal <miquel.raynal@bootlin.com> 於 2025年2月10日 週一 下午6:07寫道:
>
> Hello,
>
> >> > + ret = spinand->set_read_retry(spinand, retry_mode);
> >> > + if (ret < 0) {
> >> > + ecc_failed = true;
> >> > + return ret;
> >>
> >> Shall we try to set the read_retry level to 0 upon:
> >>
> >> if (ret < 0 && retry_mode > 1)
> >>
> >> ?
> >
> > If we set the read_retry level to 0 upon, and set_read_retry fails
> > when retry_mode equals to 1, it won't return an error. This could
> > potentially mask an underlying issue.
>
> Don't save the return value in this case? But otherwise you would leave
> the chip in a retry state, no?
However, if we set the read_retry level to 0 upon, the chip would still
remain in the retry state if set_read_retry fails.
I come up with a solution: setting the read_retry level to 0 right before
the read_retry label. This ensures that subsequent reads always start
from level 0, and it eliminates the need to reset the read_retry level at
the end.
>
> Thanks,
> Miquèl
Thanks,
Cheng Ming Lin
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/2] mtd: spi-nand: Add read retry support
2025-02-11 8:13 ` Cheng Ming Lin
@ 2025-02-11 10:40 ` Miquel Raynal
0 siblings, 0 replies; 10+ messages in thread
From: Miquel Raynal @ 2025-02-11 10:40 UTC (permalink / raw)
To: Cheng Ming Lin
Cc: vigneshr, linux-mtd, linux-kernel, richard, alvinzhou, leoyu,
Cheng Ming Lin
On 11/02/2025 at 16:13:32 +08, Cheng Ming Lin <linchengming884@gmail.com> wrote:
> Hi Miquel,
>
> Miquel Raynal <miquel.raynal@bootlin.com> 於 2025年2月10日 週一 下午6:07寫道:
>>
>> Hello,
>>
>> >> > + ret = spinand->set_read_retry(spinand, retry_mode);
>> >> > + if (ret < 0) {
>> >> > + ecc_failed = true;
>> >> > + return ret;
>> >>
>> >> Shall we try to set the read_retry level to 0 upon:
>> >>
>> >> if (ret < 0 && retry_mode > 1)
>> >>
>> >> ?
>> >
>> > If we set the read_retry level to 0 upon, and set_read_retry fails
>> > when retry_mode equals to 1, it won't return an error. This could
>> > potentially mask an underlying issue.
>>
>> Don't save the return value in this case? But otherwise you would leave
>> the chip in a retry state, no?
>
> However, if we set the read_retry level to 0 upon, the chip would still
> remain in the retry state if set_read_retry fails.
Well, if even this fails, you have bigger troubles than read_retry being
enabled.
>
> I come up with a solution: setting the read_retry level to 0 right before
> the read_retry label. This ensures that subsequent reads always start
> from level 0, and it eliminates the need to reset the read_retry level at
> the end.
I don't see the difference with the previous solution. If it fails, it's
exactly the same.
Please do not add a function call to *every* read regardless of the fact
that we enabled read_retry (which I think is what you are suggesting).
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-02-11 10:55 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-22 6:56 [PATCH v3 0/2] Add support for read retry Cheng Ming Lin
2025-01-22 6:56 ` [PATCH v3 1/2] mtd: spi-nand: Add read retry support Cheng Ming Lin
2025-02-06 17:13 ` Miquel Raynal
2025-02-10 2:46 ` Cheng Ming Lin
2025-02-10 10:07 ` Miquel Raynal
2025-02-11 8:13 ` Cheng Ming Lin
2025-02-11 10:40 ` Miquel Raynal
2025-01-22 6:56 ` [PATCH v3 2/2] mtd: spi-nand: macronix: Add support for read retry Cheng Ming Lin
2025-02-06 17:07 ` Miquel Raynal
2025-02-10 2:46 ` Cheng Ming Lin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox