]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mtd: spinand: macronix: Add support for read retry
authorCheng Ming Lin <chengminglin@mxic.com.tw>
Mon, 24 Feb 2025 07:03:49 +0000 (15:03 +0800)
committerMiquel Raynal <miquel.raynal@bootlin.com>
Tue, 4 Mar 2025 11:02:16 +0000 (12:02 +0100)
Add read retry support.

The Special Read for Data Recovery operation is enabled by
Set Feature function.

There are 5 modes for the user to recover the lost data.

Signed-off-by: Cheng Ming Lin <chengminglin@mxic.com.tw>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
drivers/mtd/nand/spi/macronix.c

index 3dc4d63d6832d0213387f335fd233f1c4306bfff..c9abac46ed0539b69ef5990dff83e9a7453861f6 100644 (file)
@@ -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 5
 
 #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),