[PATCH] mtd: nand: parse the Hynix nand which uses <26nm technology

Huang Shijie b32955 at freescale.com
Mon Dec 2 04:01:46 EST 2013


The Hynix uses different ID parsing rules for <26nm technology.
We should check the id_data[5] for Hynix nand now.

This patch adds the parsing code for the Hynix nand which use <26nm technology,
and it also parses out the datasheet's minimum required ECC.

Tested with H27UBG8T2CTR(8192 + 640).

Signed-off-by: Huang Shijie <b32955 at freescale.com>
---
 drivers/mtd/nand/nand_base.c |   65 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 64 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index bd39f7b..4dab696 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3162,7 +3162,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 			(((extid >> 1) & 0x04) | (extid & 0x03));
 		*busw = 0;
 	} else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
-			!nand_is_slc(chip)) {
+			!nand_is_slc(chip) && (id_data[5] & 0x7) < 3) {
 		unsigned int tmp;
 
 		/* Calc pagesize */
@@ -3202,6 +3202,69 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 		else
 			mtd->erasesize = (64 * 1024) << tmp;
 		*busw = 0;
+	} else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
+			!nand_is_slc(chip) && (id_data[5] & 0x7) > 3) {
+		unsigned int tmp;
+
+		/* Calc pagesize */
+		mtd->writesize = 4096 << (extid & 0x03);
+		extid >>= 2;
+		/* Calc oobsize */
+		switch (((extid >> 2) & 0x04) | (extid & 0x03)) {
+		case 0:
+			mtd->oobsize = 640;
+			break;
+		case 1:
+			mtd->oobsize = 448;
+			break;
+		case 2:
+			mtd->oobsize = 224;
+			break;
+		case 3:
+			mtd->oobsize = 128;
+			break;
+		case 4:
+			mtd->oobsize = 64;
+			break;
+		case 5:
+			mtd->oobsize = 32;
+			break;
+		case 6:
+			mtd->oobsize = 16;
+			break;
+		default:
+			mtd->oobsize = 640;
+			break;
+		}
+		extid >>= 2;
+		/* Calc blocksize */
+		tmp = ((extid >> 1) & 0x04) | (extid & 0x03);
+		if (tmp < 0x03)
+			mtd->erasesize = (128 * 1024) << tmp;
+		else if (tmp == 0x03)
+			mtd->erasesize = 768 * 1024;
+		else
+			mtd->erasesize = (64 * 1024) << tmp;
+
+		/* ecc info */
+		tmp = (id_data[4] >> 4) & 0x7;
+
+		if (tmp < 4) {
+			chip->ecc_strength_ds = 1 << tmp;
+			chip->ecc_step_ds = 512;
+		} else {
+			chip->ecc_step_ds = 1024;
+			if (tmp == 4)
+				chip->ecc_strength_ds = 24;
+			else if (tmp == 5)
+				chip->ecc_strength_ds = 32;
+			else if (tmp == 6)
+				chip->ecc_strength_ds = 40;
+			else /* (tmp == 7) */
+				chip->ecc_strength_ds = 100;
+		}
+
+		*busw = 0;
 	} else {
 		/* Calc pagesize */
 		mtd->writesize = 1024 << (extid & 0x03);
-- 
1.7.2.rc3





More information about the linux-mtd mailing list