Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8429bb39 authored by Brian Norris's avatar Brian Norris
Browse files

mtd: nand: support Micron READ RETRY



Micron provides READ RETRY support via the ONFI vendor-specific
parameter block (to indicate how many read-retry modes are available)
and the ONFI {GET,SET}_FEATURES commands with a vendor-specific feature
address (to support reading/switching the current read-retry mode).

The recommended sequence is as follows:

  1. Perform PAGE_READ operation
  2. If no ECC error, we are done
  3. Run SET_FEATURES with feature address 89h, mode 1
  4. Retry PAGE_READ operation
  5. If ECC error and there are remaining supported modes, increment the
     mode and return to step 3. Otherwise, this is a true ECC error.
  6. Run SET_FEATURES with feature address 89h, mode 0, to return to the
     default state.

This patch implements the chip->setup_read_retry() callback for
Micron and fills in the chip->read_retries.

Tested on Micron MT29F32G08CBADA, which supports 8 read-retry modes.

The Micron vendor-specific table was checked against the datasheets for
the following Micron NAND:

Needs retry   Cell-type    Part number          Vendor revision    Byte 180
-----------   ---------    ----------------     ---------------    ------------
No            SLC          MT29F16G08ABABA      1                  Reserved (0)
No            MLC          MT29F32G08CBABA      1                  Reserved (0)
No            SLC          MT29F1G08AACWP       1                  0
Yes           MLC          MT29F32G08CBADA      1                  08h
Yes           MLC          MT29F64G08CBABA      2                  08h

Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
Acked-by: default avatarHuang Shijie <b32955@freescale.com>
parent ba84fb59
Loading
Loading
Loading
Loading
+27 −0
Original line number Original line Diff line number Diff line
@@ -2979,6 +2979,30 @@ static int nand_flash_detect_ext_param_page(struct mtd_info *mtd,
	return ret;
	return ret;
}
}


static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode)
{
	struct nand_chip *chip = mtd->priv;
	uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode};

	return chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_READ_RETRY,
			feature);
}

/*
 * Configure chip properties from Micron vendor-specific ONFI table
 */
static void nand_onfi_detect_micron(struct nand_chip *chip,
		struct nand_onfi_params *p)
{
	struct nand_onfi_vendor_micron *micron = (void *)p->vendor;

	if (le16_to_cpu(p->vendor_revision) < 1)
		return;

	chip->read_retries = micron->read_retry_options;
	chip->setup_read_retry = nand_setup_read_retry_micron;
}

/*
/*
 * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise.
 * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise.
 */
 */
@@ -3085,6 +3109,9 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
		pr_warn("Could not retrieve ONFI ECC requirements\n");
		pr_warn("Could not retrieve ONFI ECC requirements\n");
	}
	}


	if (p->jedec_id == NAND_MFR_MICRON)
		nand_onfi_detect_micron(chip, p);

	return 1;
	return 1;
}
}


+3 −0
Original line number Original line Diff line number Diff line
@@ -219,6 +219,9 @@ struct nand_chip;
/* ONFI feature address */
/* ONFI feature address */
#define ONFI_FEATURE_ADDR_TIMING_MODE	0x1
#define ONFI_FEATURE_ADDR_TIMING_MODE	0x1


/* Vendor-specific feature address (Micron) */
#define ONFI_FEATURE_ADDR_READ_RETRY	0x89

/* ONFI subfeature parameters length */
/* ONFI subfeature parameters length */
#define ONFI_SUBFEATURE_PARAM_LEN	4
#define ONFI_SUBFEATURE_PARAM_LEN	4