Patchwork [v3,4/5] mtd: nand: support Micron READ RETRY

login
register
mail settings
Submitter Brian Norris
Date Jan. 4, 2014, 12:37 a.m.
Message ID <1388795828-24808-4-git-send-email-computersforpeace@gmail.com>
Download mbox | patch
Permalink /patch/306759/
State New
Headers show

Comments

Brian Norris - Jan. 4, 2014, 12:37 a.m.
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->set_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: Brian Norris <computersforpeace@gmail.com>
---
v2 -> v3: - split out from the previous patch
	  - support Micron via replaceable vendor-specific/flash-specific
	    callback
	  - add vendor-revision check (I've only seen Micron with vendor
	    revision >= 1)

Note that I intentionally *haven't* accomodated a DMA-able buffer for the ONFI
set-features command, so GPMI NAND may have problems with this.

 drivers/mtd/nand/nand_base.c | 27 +++++++++++++++++++++++++++
 include/linux/mtd/nand.h     |  3 +++
 2 files changed, 30 insertions(+)
Huang Shijie - Jan. 4, 2014, 12:49 p.m.
On Fri, Jan 03, 2014 at 04:37:07PM -0800, Brian Norris wrote:
> 
> Note that I intentionally *haven't* accomodated a DMA-able buffer for the ONFI
> set-features command, so GPMI NAND may have problems with this.

I have fixed it in another patch set:
http://lists.infradead.org/pipermail/linux-mtd/2013-December/051085.html

http://lists.infradead.org/pipermail/linux-mtd/2013-December/051086.html

thanks
Huang Shijie
Huang Shijie - Jan. 7, 2014, 6:54 a.m.
On Fri, Jan 03, 2014 at 04:37:07PM -0800, Brian Norris wrote:
> +static int nand_set_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->set_read_retry = nand_set_read_retry_micron;
Besides the name, i am okay with this patch.

thanks
Huang Shijie

Patch

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index d47c5bbca2b3..df20c43f186a 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2979,6 +2979,30 @@  ext_out:
 	return ret;
 }
 
+static int nand_set_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->set_read_retry = nand_set_read_retry_micron;
+}
+
 /*
  * 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");
 	}
 
+	if (p->jedec_id == NAND_MFR_MICRON)
+		nand_onfi_detect_micron(chip, p);
+
 	return 1;
 }
 
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index ef70505dade1..e3621aba1417 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -219,6 +219,9 @@  struct nand_chip;
 /* ONFI feature address */
 #define ONFI_FEATURE_ADDR_TIMING_MODE	0x1
 
+/* Vendor-specific feature address (Micron) */
+#define ONFI_FEATURE_ADDR_READ_RETRY	0x89
+
 /* ONFI subfeature parameters length */
 #define ONFI_SUBFEATURE_PARAM_LEN	4