Commit a9d94a2a authored by Cheng Ming Lin's avatar Cheng Ming Lin Committed by Miquel Raynal
Browse files

mtd: spinand: macronix: Add support for read retry



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: default avatarCheng Ming Lin <chengminglin@mxic.com.tw>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
parent f2cb43c9
Loading
Loading
Loading
Loading
+64 −15
Original line number Diff line number Diff line
@@ -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),