Skip to contentSkip to conversation

mtd/nand: Support Micron chips, 4KB page

PATCH Superseded Brian Norris 4 participants 13 messages Jul 26, 2010 – Aug 30, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mtd/nand: Support Micron chips, 4KB page

The following parts exhibit some interesting patterns in their ID strings. Their ID strings are not fully compatible with the current nand_base.c detection algorithm. In order to detect them properly, I have taken the liberty to develop a heuristic algorithm. None of these chips have a *good* detection pattern listed in their datasheets, although MT29F16G08MAA has a table on p.24 of its data sheet (not included here).

Part ID String Block Page OOB
MT29F16G08ABABA 2C 48 00 26 89 00 00 512K 4K 224
MT29F16G08CBABA 2C 48 04 46 85 00 00 1024K 4K 224
MT29F16G08MAA 2C D5 94 3E 74 00 00 512K 4K 218

I have attached a table logging most of the relevant data for the many chips I have researched. The three chips are highlighted red, although there are variants of the chips listed as well. I believe this patch should correctly identify all the 5-byte ID Micron chips.

And before the question is asked: I realize that these chips support ONFI, so that should be the primary means by which to identify them, but I would still like to be able to detect these properly without ONFI if necessary, especially considering some of the older NAND controllers we still use do not support reading ONFI data.

Feedback on my logic is appreciated.

---
 drivers/mtd/nand/nand_base.c |   34 +++++++++++++++++++++++++---------
 drivers/mtd/nand/nand_ids.c  |    1 +
 2 files changed, 26 insertions(+), 9 deletions(-)
drivers/mtd/nand/nand_base.c +25 -9
index 4a7b864..1ca230d 100644
@@ -2846,6 +2846,9 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 		 * Field definitions are in the following datasheets:
 		 * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
 		 * New style   (6 byte ID): Samsung K9GAG08U0D (p.40)
+		 * Micron      (5 byte ID): Micron MT29F16G08MAA (p.24)
+		 *      Note: Micron rule is based on heuristics for
+		 *            newer chips
 		 *
 		 * Check for wraparound + Samsung ID + nonzero 6th byte
 		 * to decide what to do.
@@ -2867,15 +2870,28 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 			/* Calc pagesize */
 			mtd->writesize = 1024 << (extid & 0x03);
 			extid >>= 2;
-			/* Calc oobsize */
-			mtd->oobsize = (8 << (extid & 0x01)) *
-				(mtd->writesize >> 9);
-			extid >>= 2;
-			/* Calc blocksize. Blocksize is multiples of 64KiB */
-			mtd->erasesize = (64 * 1024) << (extid & 0x03);
-			extid >>= 2;
-			/* Get buswidth information */
-			busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+			/* Check for 5 byte ID + Micron + read more 0x00 */
+			if (id_data[0] == NAND_MFR_MICRON && id_data[4] != 0x00
+					&& mtd->writesize >= 4096
+					&& id_data[5] == 0x00
+					&& id_data[6] == 0x00) {
+				mtd->oobsize = ((extid & 0x03) == 0x03) ? 218
+					: 224;
+				extid >>= 3;
+				mtd->erasesize = (256 * 1024) << (extid & 0x03);
+				/* All Micron have busw x8? */
+				busw = 0;
+			} else {
+				/* Calc oobsize */
+				mtd->oobsize = (8 << (extid & 0x01)) *
+					(mtd->writesize >> 9);
+				extid >>= 2;
+				/* Calc blocksize (multiples of 64KiB) */
+				mtd->erasesize = (64 * 1024) << (extid & 0x03);
+				extid >>= 2;
+				/* Get buswidth information */
+				busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+			}
 		}
 	} else {
 		/*
drivers/mtd/nand/nand_ids.c +1 -0
index 89907ed..25f6be2 100644
@@ -107,6 +107,7 @@ struct nand_flash_dev nand_flash_ids[] = {
 	/* 16 Gigabit */
 	{"NAND 2GiB 1,8V 8-bit",	0xA5, 0, 2048, 0, LP_OPTIONS},
 	{"NAND 2GiB 3,3V 8-bit",	0xD5, 0, 2048, 0, LP_OPTIONS},
+	{"NAND 2GiB 3,3V 8-bit",	0x48, 0, 2048, 0, LP_OPTIONS},
 	{"NAND 2GiB 1,8V 16-bit",	0xB5, 0, 2048, 0, LP_OPTIONS16},
 	{"NAND 2GiB 3,3V 16-bit",	0xC5, 0, 2048, 0, LP_OPTIONS16},
 
Signature · 1 line
1.7.0.4

"Manufacturer","Part #","Man. ID","ID Code","Full ID","MB","Page","OOB","Block","Bus","ONFI","Bad Block Location","ECC Req.","Bits per cell","ID Length","Notes" "Toshiba","TC58128AFT","0x98","0x73","0x9873",16,512,16,"16 KB","x8","N/A","All OOB bytes","?","1?",2,
"Samsung","K9F1G08U0B","0xEC","0xF1","0xECF1009540",128,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte",1,5, "Toshiba","TC58DVM72A1TG00","0x98","0x73","0x9873",16,512,16,"16 KB","x8","N/A","All OOB bytes","?","1?",2,
"Samsung","K9F5608D0C","0xEC","0x75","0xEC75",32,512,16,"16 KB","x8","N/A","1st or 2nd page (6th byte in OOB = non FFh)","? (1-bit correct, 2-bit detect)",1,2, "Samsung","K9F5608Q0C","0xEC","0x35","0xEC35",32,512,16,"16 KB","x8","N/A","1st or 2nd page (6th byte in OOB = non FFh)","? (1-bit correct, 2-bit detect)",1,2, "Samsung","K9F5608U0C","0xEC","0x75","0xEC75",32,512,16,"16 KB","x8","N/A","1st or 2nd page (6th byte in OOB = non FFh)","? (1-bit correct, 2-bit detect)",1,2, "Samsung","K9F5616D0C","0xEC","0x55","0xEC55",32,512,16,"16 KB","x16","N/A","1st or 2nd page (1st word in OOB = non FFh)","? (1-bit correct, 2-bit detect)",1,2, "Samsung","K9F5616Q0C","0xEC","0x45","0xEC45",32,512,16,"16 KB","x16","N/A","1st or 2nd page (1st word in OOB = non FFh)","? (1-bit correct, 2-bit detect)",1,2, "Samsung","K9F5616U0C","0xEC","0x55","0xEC55",32,512,16,"16 KB","x16","N/A","1st or 2nd page (1st word in OOB = non FFh)","? (1-bit correct, 2-bit detect)",1,2,"EDC" "Samsung","K9F4G08U0A","0xEC","0xDC","0xECDC109554",64,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte",1,5, "Samsung","K9K8G08U1A","0xEC","0xDC","0xECDC109554",128,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte",1,5,"Made of two K9F4G08U0As" "Samsung","K9F4G08U0M","0xEC","0xDC","0xECDC109554",512,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte",1,5, "Samsung","K9K8G08U1M","0xEC","0xDC","0xECDC109554",1024,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte",1,5,
"ST","NAND128W3A","0x20","0x73","0x2073",16,512,16,"16 KB","x8","N/A","1st page (6th byte in OOB = non FFh)","22-bit/2048-bits",1,2,
"ST","NAND256R3A","0x20","0x35","0x2035",32,512,16,"16 KB","x8","N/A","1st page (6th byte in OOB = non FFh)","22-bit/2048-bits",1,2,
"ST","NAND256W3A","0x20","0x75","0x2075",32,512,16,"16 KB","x8","N/A","1st page (6th byte in OOB = non FFh)","22-bit/2048-bits",1,2,
"ST","NAND256R4A","0x0020","0x0045","0x2045",32,512,16,"16 KB","x16","N/A","1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,2,
"ST","NAND256W4A","0x0020","0x0055","0x2055",32,512,16,"16 KB","x16","N/A","1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,2,
"ST","NAND512R3A","0x20","0x36","0x2036",64,512,16,"16 KB","x8","N/A","1st page (6th byte in OOB = non FFh)","22-bit/2048-bits",1,2,
"ST","NAND512W3A","0x20","0x76","0x2076",64,512,16,"16 KB","x8","N/A","1st page (6th byte in OOB = non FFh)","22-bit/2048-bits",1,2,
"ST","NAND512R4A","0x0020","0x0046","0x2046",64,512,16,"16 KB","x16","N/A","1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,2,
"ST","NAND512W4A","0x0020","0x0056","0x2056",64,512,16,"16 KB","x16","N/A","1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,2,
"ST","NAND01GR3A","0x20","0x39","0x2039",128,512,16,"16 KB","x8","N/A","1st page (6th byte in OOB = non FFh)","22-bit/2048-bits",1,2,
"ST","NAND01GW3A","0x20","0x79","0x2079",128,512,16,"16 KB","x8","N/A","1st page (6th byte in OOB = non FFh)","22-bit/2048-bits",1,2,
"ST","NAND01GR4A","0x0020","0x0049","0x2049",128,512,16,"16 KB","x16","N/A","1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,2,
"ST","NAND01GW4A","0x0020","0x0059","0x2059",128,512,16,"16 KB","x16","N/A","1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,2,
"ST","NAND512R3A2C","0x20","0x36","0x2036",64,512,16,"16 KB","x8","N/A","1st page (6th byte in OOB = non FFh)","22-bit/2048-bits",1,2,"Similar part, different manufacturer (Numonyx NAND512-A2D); further cycles ignored" "ST","NAND512W3A2C","0x20","0x76","0x2076",64,512,16,"16 KB","x8","N/A","1st page (6th byte in OOB = non FFh)","22-bit/2048-bits",1,2,"Similar part, different manufacturer (Numonyx NAND512-A2D); further cycles ignored" "ST","NAND512R4A2C","0x0020","0x0046","0x2046",64,512,16,"16 KB","x16","N/A","1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,2,"Similar part, different manufacturer (Numonyx NAND512-A2D); further cycles ignored" "ST","NAND512W4A2C","0x0020","0x0056","0x2056",64,512,16,"16 KB","x16","N/A","1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,2,"Similar part, different manufacturer (Numonyx NAND512-A2D); further cycles ignored" "Numonyx","NAND512R3A2D","0x20","0x36","0x2036",64,512,16,"16 KB","x8","N/A","1st page (6th byte in OOB = non FFh)","1-bit/512-byte (2-bit detect)",1,2,"further cycles ignored" "Numonyx","NAND512W3A2D","0x20","0x76","0x2076",64,512,16,"16 KB","x8","N/A","1st page (6th byte in OOB = non FFh)","1-bit/512-byte (2-bit detect)",1,2,"further cycles ignored" "Numonyx","NAND512R4A2D","0x0020","0x0046","0x2046",64,512,16,"16 KB","x16","N/A","1st page (1st word in OOB = non FFh)","1-bit/512-byte (2-bit detect)",1,2,"further cycles ignored" "Numonyx","NAND512W4A2D","0x0020","0x0056","0x2056",64,512,16,"16 KB","x16","N/A","1st page (1st word in OOB = non FFh)","1-bit/512-byte (2-bit detect)",1,2,"further cycles ignored" "Numonyx","NAND01GR3A2C","0x20","0x78","0x2078",128,512,16,"16 KB","x8","N/A","1st page (6th byte in OOB = non FFh)","1-bit/512-byte (2-bit detect)",1,2,"further cycles ignored" "Numonyx","NAND01GW3A2C","0x20","0x79","0x2079",128,512,16,"16 KB","x8","N/A","1st page (6th byte in OOB = non FFh)","1-bit/512-byte (2-bit detect)",1,2,"further cycles ignored" "Numonyx","NAND01GR4A2C","0x0020","0x0072","0x2072",128,512,16,"16 KB","x16","N/A","1st page (1st word in OOB = non FFh)","1-bit/512-byte (2-bit detect)",1,2,"further cycles ignored" "Numonyx","NAND01GW4A2C","0x0020","0x0074","0x2074",128,512,16,"16 KB","x16","N/A","1st page (1st word in OOB = non FFh)","1-bit/512-byte (2-bit detect)",1,2,"further cycles ignored" "Hynix","HY27UF081G2M","0xAD","0xF1","0xADF1XX15",128,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","?",1,4,"remains in Read ID mode" "Hynix","HY27UF161G2M","0xAD","0xC1","0xADC1XX55",128,2048,64,"128 KB","x16","N/A","1st or 2nd page (1st byte in OOB = non FFh)","?",1,4,"remains in Read ID mode" "Hynix","HY27SF081G2M","0xAD","0xA1","0xADA1XX15",128,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","?",1,4,"remains in Read ID mode" "Hynix","HY27SF161G2M","0xAD","0xAD","0xADADXX55",128,2048,64,"128 KB","x16","N/A","1st or 2nd page (1st byte in OOB = non FFh)","?",1,4,"remains in Read ID mode" "Micron","MT29F2G08AAC","0x2C","0xDA","0x2CDAXX15",256,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte (or 528-byte)","1?",4,"remains in Read ID mode" "Micron","MT29F2G08ABC","0x2C","0xAA","0x2CAAXX15",256,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte (or 528-byte)","1?",4,"remains in Read ID mode" "Micron","MT29F2G16AAC","0x2C","0xCA","0x2CCAXX55",256,2048,64,"128 KB","x16","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte (or 528-byte)","1?",4,"remains in Read ID mode" "Micron","MT29F2G16ABC","0x2C","0xBA","0x2CBAXX55",256,2048,64,"128 KB","x16","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte (or 528-byte)","1?",4,"remains in Read ID mode" "Micron","MT29F4G08BAC","0x2C","0xDC","0x2CDCXX15",512,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte (or 528-byte)","1?",4,"remains in Read ID mode" "Micron","MT29F8G08FAC","0x2C","0xDC","0x2CDCXX15",1024,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte (or 528-byte)","1?",4,"remains in Read ID mode; made of two 4Gb sections" "Micron","MT29F2G08AAB","0x2C","0xDA","0x2CDAXX15",256,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","?","1?",4,"remains in Read ID mode" "Micron","MT29F2G16AAB","0x2C","0xCA","0x2CCAXX55",256,2048,64,"128 KB","x16","N/A","1st or 2nd page (1st byte in OOB = non FFh)","?","1?",4,"remains in Read ID mode" "Micron","MT29F4G08BAB","0x2C","0xDC","0x2CDCXX15",512,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","?","1?",4,"remains in Read ID mode" "Micron","MT29F4G16BAB","0x2C","0xCC","0x2CCCXX55",512,2048,64,"128 KB","x16","N/A","1st or 2nd page (1st byte in OOB = non FFh)","?","1?",4,"remains in Read ID mode" "Micron","MT29F8G08FAB","0x2C","0xDC","0x2CDCXX15",1024,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","?","1?",4,"remains in Read ID mode" "Samsung","K9F1208R0B","0xEC","0x36","0xEC36A5C0",64,512,16,"16 KB","x8","N/A","1st or 2nd page (6th byte in OOB = non FFh)","? (1-bit correct, 2-bit detect)",1,4,"remains in Read ID mode" "Samsung","K9F1208B0B","0xEC","0x76","0xEC76A5C0",64,512,16,"16 KB","x8","N/A","1st or 2nd page (6th byte in OOB = non FFh)","? (1-bit correct, 2-bit detect)",1,4,"remains in Read ID mode" "Samsung","K9F1208U0B","0xEC","0x76","0xEC76A5C0",64,512,16,"16 KB","x8","N/A","1st or 2nd page (6th byte in OOB = non FFh)","? (1-bit correct, 2-bit detect)",1,4,"remains in Read ID mode" "Samsung","K9F2G08U0M","0xEC","0xDA","0xECDA8015",256,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","? (1-bit correct, 2-bit detect)",1,4, "Samsung","K9K4G08U1M","0xEC","0xDA","0xECDA8015",512,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","? (1-bit correct, 2-bit detect)",1,4, "Samsung","K9F2G08B0B","0xEC","0xDA","0xECDA109544",256,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5,"only differ by voltage" "Samsung","K9F2G08U0B","0xEC","0xDA","0xECDA109544",256,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5,"only differ by voltage" "Samsung","K9F2G08R0A","0xEC","0xAA","0xECAA001544",256,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5, "Samsung","K9F2G08U0A","0xEC","0xDA","0xECDA109544",256,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5, "Samsung","K9F2G08B0B","0xEC","0xDA","0xECDA109544",256,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5, "Samsung","K9F2G08U0B","0xEC","0xDA","0xECDA109544",256,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5, "Samsung","K9GAG08B0D","0xEC","0xD5","0xECD594293441",2048,4096,218,"512 KB","x8","N/A","Last page (1st byte in OOB = non FFh)","8-bit/512-byte (correction)",2,6, "Samsung","K9GAG08U0D","0xEC","0xD5","0xECD594293441",2048,4096,218,"512 KB","x8","N/A","Last page (1st byte in OOB = non FFh)","8-bit/512-byte (correction)",2,6, "Samsung","K9LBG08U1D","0xEC","0xD5","0xECD594293441",4096,4096,218,"512 KB","x8","N/A","Last page (1st byte in OOB = non FFh)","8-bit/512-byte (correction)",2,6,"Contains 2 K9GAG08U0D" "Samsung","K9HCG08U5D","0xEC","0xD5","0xECD594293441",8192,4096,218,"512 KB","x8","N/A","Last page (1st byte in OOB = non FFh)","8-bit/512-byte (correction)",2,6,"Contains 4 K9GAG08U0D" "Spansion","S30ML512P","0x01","0x76","0x0176010101",64,512,16,"512 KB","x8","N/A","1st or 2nd page (6th byte in OOB = non FFh)","1-bit/512-byte (correction)","ORNAND","6?","Each model has x8/x16 bus versions, 2%/0% bad blocks; 2% => ID byte 3 = 0x00" "Spansion","S30ML512P","0x01","0x56","0x0156010101",64,512,16,"512 KB","x16","N/A","1st or 2nd page (1st word in OOB = non FFh)","1-bit/512-byte (correction)","ORNAND","6?","Each model has x8/x16 bus versions, 2%/0% bad blocks; 2% => ID byte 3 = 0x00" "Spansion","S30ML256P","0x01","0x75","0x0175010101",32,512,16,"512 KB","x8","N/A","1st or 2nd page (6th byte in OOB = non FFh)","1-bit/512-byte (correction)","ORNAND","6?","Each model has x8/x16 bus versions, 2%/0% bad blocks; 2% => ID byte 3 = 0x00" "Spansion","S30ML256P","0x01","0x55","0x0155010101",32,512,16,"512 KB","x16","N/A","1st or 2nd page (1st word in OOB = non FFh)","1-bit/512-byte (correction)","ORNAND","6?","Each model has x8/x16 bus versions, 2%/0% bad blocks; 2% => ID byte 3 = 0x00" "Spansion","S30ML128P","0x01","0x73","0x0173010101",16,512,16,"512 KB","x8","N/A","1st or 2nd page (6th byte in OOB = non FFh)","1-bit/512-byte (correction)","ORNAND","6?","Each model has x8/x16 bus versions, 2%/0% bad blocks; 2% => ID byte 3 = 0x00" "Spansion","S30ML128P","0x01","0x53","0x0153030101",16,512,16,"512 KB","x16","N/A","1st or 2nd page (1st word in OOB = non FFh)","1-bit/512-byte (correction)","ORNAND","6?","Each model has x8/x16 bus versions, 2%/0% bad blocks; 2% => ID byte 3 = 0x04" "Samsung","K9K8G08U0A","0xEC","0xD3","0xECD3519558",1024,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte",1,5,"remains in Read ID mode" "Samsung","K9WAG08U1A","0xEC","0xD3","0xECD3519558",2048,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte",1,5,"remains in Read ID mode" "Samsung","K9NBG08U5A","0xEC","0xD3","0xECD3519558",4096,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte",1,5,"remains in Read ID mode" "Samsung","K9F8G08B0M","0xEC","0xD3","0xECD310A664",1024,4096,128,"256 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte",1,"5?", "Samsung","K9F8G08U0M","0xEC","0xD3","0xECD310A664",1024,4096,128,"256 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte",1,"5?", "Samsung","K9F8G08U1M","0xEC","0xD3","0xECD310A664",2048,4096,128,"256 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/512-byte",1,"5?","contains 2 K9F8G08U0M" "Numonyx","NAND04GR3B2D","0x20","0xAC","0x20AC101554",512,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5,"embedded 1/528 bit ECC; remains in Read ID mode" "Numonyx","NAND08GR3B4C","0x20","0xAC","0x20AC101554",1024,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5,"embedded 1/528 bit ECC; remains in Read ID mode; contains two NAND04GR3B2D" "Numonyx","NAND04GW3B2D","0x20","0xDC","0x20DC109554",512,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5,"embedded 1/528 bit ECC; remains in Read ID mode" "Numonyx","NAND08GW3B4C","0x20","0xDC","0x20DC109554",1024,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5,"embedded 1/528 bit ECC; remains in Read ID mode; contains two NAND04GW3B2D" "Numonyx","NAND04GR4B2D","0x0020","0xBC","0x20BC105554",512,2048,64,"128 KB","x16",1.0,"1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,5,"embedded 1/528 bit ECC; remains in Read ID mode" "Numonyx","NAND04GW4B2D","0x0020","0xCC","0x20CC10D554",512,2048,64,"128 KB","x16",1.0,"1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,5,"embedded 1/528 bit ECC; remains in Read ID mode" "Numonyx","NAND08GR3B2C","0x20","0xA3","0x20A3511558",1024,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5,"embedded 1/528 bit ECC; remains in Read ID mode" "Numonyx","NAND08GW3B2C","0x20","0xD3","0x20D3519558",1024,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5,"embedded 1/528 bit ECC; remains in Read ID mode" "Numonyx","NAND08GR4B2C","0x0020","0xB3","0x20B3515558",1024,2048,64,"128 KB","x16",1.0,"1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,5,"embedded 1/528 bit ECC; remains in Read ID mode" "Numonyx","NAND08GW4B2C","0x0020","0xC3","0x20C351D558",1024,2048,64,"128 KB","x16",1.0,"1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,5,"embedded 1/528 bit ECC; remains in Read ID mode" "Micron","MT29F4G08AAA","0x2C","0xDC","0x2CDC909554",512,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5, "Micron","MT29F8G08BAA","0x2C","0xD3","0x2CD3D19558",1024,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5, "Micron","MT29F8G08DAA","0x2C","0xDC","0x2CDC909554",1024,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5,"contains 2 MT29F4G08AAA" "Micron","MT29F16G08FAA","0x2C","0xD3","0x2CD3D19558",2048,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5,"contains 2 MT29F8G08BAA" "Micron","MT29F16G08MAA","0x2C","0xD5","0x2CD5943E74",2048,4096,218,"512 KB","x8",1.0,"1st page (1st byte in OOB = non FFh)","8-bit/539-byte",2,5, "Micron","MT29F32G08QAA","0x2C","0xD5","0x2CD5943E74",4096,4096,218,"512 KB","x8",1.0,"1st page (1st byte in OOB = non FFh)","8-bit/539-byte",2,5, "Micron","MT29F64G08TAA","0x2C","0xD7","0x2CD7D53E78",8192,4096,218,"512 KB","x8",1.0,"1st page (1st byte in OOB = non FFh)","8-bit/539-byte",2,5, "Micron","MT29F16G08CBABA","0x2C","0x48","0x2C48044685",2048,4096,224,"1024 KB","x8",2.1,"1st page (1st byte in OOB = non FFh)","12-bit/540-byte",2,5,"returns 0x00 after first 5 read ID bytes" "Micron","MT29F16G08CBABB","0x2C","0x48","0x2C48044685",2048,4096,224,"1024 KB","x8",2.1,"1st page (1st byte in OOB = non FFh)","12-bit/540-byte",2,5,"returns 0x00 after first 5 read ID bytes" "Micron","MT29F8G08MAA","0x2C","0xD3","0x2CD394A564",1024,2048,64,"256 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","4-bit/528-byte",2,5,"remains in Read ID mode" "Micron","MT29F16G08QAA","0x2C","0xD3","0x2CD394A564",2048,2048,64,"256 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","4-bit/528-byte",2,5,"remains in Read ID mode" "Micron","MT29F32G08TAA","0x2C","0xD5","0x2CD5D5A568",4096,2048,64,"256 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","4-bit/528-byte",2,5,"remains in Read ID mode" "ST","NAND04GR3B2D","0x20","0xAC","0x20AC101554",512,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5, "ST","NAND08GR3B4C","0x20","0xAC","0x20AC101554",1024,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5, "ST","NAND04GW3B2D","0x20","0xDC","0x20DC109554",512,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5, "ST","NAND08GW3B4C","0x20","0xDC","0x20DC109554",1024,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5, "ST","NAND04GR4B2D","0x0020","0xBC","0x20BC105554",512,2048,64,"128 KB","x16",1.0,"1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,5, "ST","NAND04GW4B2D","0x0020","0xCC","0x20CC10D554",512,2048,64,"128 KB","x16",1.0,"1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,5, "ST","NAND08GR3B2C","0x20","0xA3","0x20A3511558",1024,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5, "ST","NAND08GW3B2C","0x20","0xD3","0x20D3519558",1024,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5, "ST","NAND08GR4B2C","0x0020","0xB3","0x20B3515558",1024,2048,64,"128 KB","x16",1.0,"1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,5, "ST","NAND08GW4B2C","0x0020","0xC3","0x20C351D558",1024,2048,64,"128 KB","x16",1.0,"1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,5, "Numonyx","NAND02GR3B2D","0x20","0xAA","0x20AA101544",256,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5,"remains in Read ID mode" "Numonyx","NAND02GW3B2D","0x20","0xDA","0x20DA109544",256,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,5,"remains in Read ID mode" "Numonyx","NAND02GR4B2D","0x0020","0xBA","0x20BA105544",256,2048,64,"128 KB","x16",1.0,"1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,5,"remains in Read ID mode" "Numonyx","NAND02GW4B2D","0x0020","0xCA","0x20CA10D544",256,2048,64,"128 KB","x16",1.0,"1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,5,"remains in Read ID mode" "Numonyx","NAND01GR3B2B","0x20","0xA1","0x20A18015",128,2048,64,"128 KB","x8","N/A","1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,4, "Numonyx","NAND01GW3B2B","0x20","0xF1","0x20F1801D",128,2048,64,"128 KB","x8","N/A","1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,4, "Numonyx","NAND01GR4B2B","0x0020","0xB1","0x20B18055",128,2048,64,"128 KB","x16","N/A","1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,4, "Numonyx","NAND01GW4B2B","0x0020","0xC1","0x20C1805D",128,2048,64,"128 KB","x16","N/A","1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,4, "Numonyx","NAND02GR3B2C","0x20","0xAA","0x20AA8015",256,2048,64,"128 KB","x8","N/A","1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,4, "Numonyx","NAND02GW3B2C","0x20","0xDA","0x20DA801D",256,2048,64,"128 KB","x8","N/A","1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,4, "Numonyx","NAND02GR4B2C","0x0020","0xBA","0x20BA8055",256,2048,64,"128 KB","x16","N/A","1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,4, "Numonyx","NAND02GW42C","0x0020","0xCA","0x20CA805D",256,2048,64,"128 KB","x16","N/A","1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,4, "Numonyx","NAND01GR3B2B","0x20","0xA1","0x20A10015",128,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,4, "Numonyx","NAND01GW3B2B","0x20","0xF1","0x20F1001D",128,2048,64,"128 KB","x8",1.0,"1st page (1st or 6th byte in OOB = non FFh)","22-bit/2048-bits",1,4, "Numonyx","NAND01GR4B2B","0x20","0xB1","0x20B10055",128,2048,64,"128 KB","x16",1.0,"1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,4, "Numonyx","NAND01GW4B2B","0x20","0xC1","0x20C1005D",128,2048,64,"128 KB","x16",1.0,"1st page (1st word in OOB = non FFh)","22-bit/2048-bits",1,4, "Hynix","HY27UF082G2A","0xAD","0xDA","0xADDA801D00",256,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5, "Hynix","HY27UF162G2A","0xAD","0xCA","0xADCA805D00",256,2048,64,"128 KB","x16","N/A","1st or 2nd page (1st word in OOB = non FFh)","1-bit/528-byte",1,5, "Hynix","HY27UF082G2A","0xAD","0xDA","0xADDA801D00",256,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5, "Hynix","HY27UF162G2A","0xAD","0xCA","0xADCA805D00",256,2048,64,"128 KB","x16","N/A","1st or 2nd page (1st word in OOB = non FFh)","1-bit/528-byte",1,5, "Samsung","K9G8G08B0A","0xEC","0xD3","0xECD314A564",1024,2048,64,"256 KB","x8","N/A","Last page (1st byte in OOB = non FFh)","4-bit/512-byte",2,5, "Samsung","K9G8G08U0A","0xEC","0xD3","0xECD314A564",1024,2048,64,"256 KB","x8","N/A","Last page (1st byte in OOB = non FFh)","4-bit/512-byte",2,5, "Samsung","K9LAG08U1A","0xEC","0xD3","0xECD314A564",2048,2048,64,"256 KB","x8","N/A","Last page (1st byte in OOB = non FFh)","4-bit/512-byte",2,5, "Samsung","K9LBG08U0D","0xEC","0xD7","0xECD7D5293841",4096,4096,218,"512 KB","x8","N/A","Last page (1st byte in OOB = non FFh)","8-bit/512-byte (correction)",2,6, "Samsung","K9HCG08U1D","0xEC","0xD7","0xECD7D5293841",8192,4096,218,"512 KB","x8","N/A","Last page (1st byte in OOB = non FFh)","8-bit/512-byte (correction)",2,6, "Samsung","K9XDG08U5D","0xEC","0xD7","0xECD7D5293841",16384,4096,218,"512 KB","x8","N/A","Last page (1st byte in OOB = non FFh)","8-bit/512-byte (correction)",2,6, "Numonyx","NAND08GW3F2B","0x20","0xD3","0x20D390152441",1024,2048,64,"128 KB","x8","N/A","1st page (1st or 6th byte in OOB = non FFh)","1-bit/512-byte",1,6, "Samsung","K9K8G08U0B","0xEC","0xDC","0xECDC519558",1024,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5, "Samsung","K9WAG08U1B","0xEC","0xDC","0xECDC519558",2048,2048,64,"128 KB","x8","N/A","1st or 2nd page (1st byte in OOB = non FFh)","1-bit/528-byte",1,5, "Micron","MT29F16G08ABABA","0x2C","0x48","0x2C48002689",2048,4096,224,"512 KB","x8",2.1,"1st page (1st byte in OOB = non FFh)","4-bit/540-byte",1,5,"Read ID produces 00h after byte 5" "Micron","MT29F16G08ABCBB","0x2C","0x48","0x2C48002689",2048,4096,224,"512 KB","x8",2.1,"1st page (1st byte in OOB = non FFh)","4-bit/540-byte",1,5,"Read ID produces 00h after byte 5" "Micron","MT29F32G08AFABA","0x2C","0x48","0x2C48002689",4096,4096,224,"512 KB","x8",2.1,"1st page (1st byte in OOB = non FFh)","4-bit/540-byte",1,5,"Read ID produces 00h after byte 5" "Micron","MT29F32G08AECBB","0x2C","0x48","0x2C48002689",4096,4096,224,"512 KB","x8",2.1,"1st page (1st byte in OOB = non FFh)","4-bit/540-byte",1,5,"Read ID produces 00h after byte 5" "Micron","MT29F64G08AJABA","0x2C","0x68","0x2C6801A689",8192,4096,224,"512 KB","x8",2.1,"1st page (1st byte in OOB = non FFh)","4-bit/540-byte",1,5,"Read ID produces 00h after byte 5" "Micron","MT29F64G08AKABA","0x2C","0x68","0x2C6801A689",8192,4096,224,"512 KB","x8",2.1,"1st page (1st byte in OOB = non FFh)","4-bit/540-byte",1,5,"Read ID produces 00h after byte 5" "Micron","MT29F64G08AKCBB","0x2C","0x68","0x2C6801A689",8192,4096,224,"512 KB","x8",2.1,"1st page (1st byte in OOB = non FFh)","4-bit/540-byte",1,5,"Read ID produces 00h after byte 5" "Micron","MT29F64G08AMABA","0x2C","0x48","0x2C48002689",8192,4096,224,"512 KB","x8",2.1,"1st page (1st byte in OOB = non FFh)","4-bit/540-byte",1,5,"Read ID produces 00h after byte 5" "Micron","MT29F64G08AMCBB","0x2C","0x48","0x2C48002689",8192,4096,224,"512 KB","x8",2.1,"1st page (1st byte in OOB = non FFh)","4-bit/540-byte",1,5,"Read ID produces 00h after byte 5" "Micron","MT29F128G08AUABA","0x2C","0x68","0x2C6801A689",16384,4096,224,"512 KB","x8",2.1,"1st page (1st byte in OOB = non FFh)","4-bit/540-byte",1,5,"Read ID produces 00h after byte 5" "Micron","MT29F128G08AUCBB","0x2C","0x68","0x2C6801A689",16384,4096,224,"512 KB","x8",2.1,"1st page (1st byte in OOB = non FFh)","4-bit/540-byte",1,5,"Read ID produces 00h after byte 5"

#1 lore raw

PATCH v2 1/1 mtd/nand: Support Micron chips, pagesize >= 4KB

I found some newer Micron parts that introduce an 8K page size, and so need a modification on the algorithm. Here's the updated list and a revision to my patch.

Part ID String Block Page OOB
MT29F16G08ABABA 2C 48 00 26 89 00 00 512K 4K 224
MT29F16G08CBABA 2C 48 04 46 85 00 00 1024K 4K 224
MT29F16G08MAA 2C D5 94 3E 74 00 00 512K 4K 218
MT29F32G08CBACA 2C 68 04 4A A9 00 00 1024K 4K 224
MT29F64G08CBAAA 2C 88 04 4B A9 00 00 2048K 8K 448
MT29F256G08CJAAA 2C A8 05 CB A9 00 00 2048K 8K 448

---
 drivers/mtd/nand/nand_base.c |   37 ++++++++++++++++++++++++++++---------
 drivers/mtd/nand/nand_ids.c  |   10 ++++++++++
 2 files changed, 38 insertions(+), 9 deletions(-)
drivers/mtd/nand/nand_base.c +28 -9
index 4a7b864..a9216af 100644
@@ -2846,6 +2846,9 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 		 * Field definitions are in the following datasheets:
 		 * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
 		 * New style   (6 byte ID): Samsung K9GAG08U0D (p.40)
+		 * Micron      (5 byte ID): Micron MT29F16G08MAA (p.24)
+		 *      Note: Micron rule is based on heuristics for
+		 *            newer chips
 		 *
 		 * Check for wraparound + Samsung ID + nonzero 6th byte
 		 * to decide what to do.
@@ -2867,15 +2870,31 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 			/* Calc pagesize */
 			mtd->writesize = 1024 << (extid & 0x03);
 			extid >>= 2;
-			/* Calc oobsize */
-			mtd->oobsize = (8 << (extid & 0x01)) *
-				(mtd->writesize >> 9);
-			extid >>= 2;
-			/* Calc blocksize. Blocksize is multiples of 64KiB */
-			mtd->erasesize = (64 * 1024) << (extid & 0x03);
-			extid >>= 2;
-			/* Get buswidth information */
-			busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+			/* Check for 5 byte ID + Micron + read more 0x00 */
+			if (id_data[0] == NAND_MFR_MICRON && id_data[4] != 0x00
+					&& mtd->writesize >= 4096
+					&& id_data[5] == 0x00
+					&& id_data[6] == 0x00) {
+				/* OOB is 218B/224B per 4KiB pagesize */
+				mtd->oobsize = ((extid & 0x03) == 0x03 ? 218 :
+						224) << (mtd->writesize >> 13);
+				extid >>= 3;
+				/* Blocksize is multiple of 64KiB */
+				mtd->erasesize = mtd->writesize <<
+					(extid & 0x03) << 6;
+				/* All Micron have busw x8? */
+				busw = 0;
+			} else {
+				/* Calc oobsize */
+				mtd->oobsize = (8 << (extid & 0x01)) *
+					(mtd->writesize >> 9);
+				extid >>= 2;
+				/* Calc blocksize (multiples of 64KiB) */
+				mtd->erasesize = (64 * 1024) << (extid & 0x03);
+				extid >>= 2;
+				/* Get buswidth information */
+				busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+			}
 		}
 	} else {
 		/*
drivers/mtd/nand/nand_ids.c +10 -0
index 89907ed..4f6e59a 100644
@@ -107,9 +107,19 @@ struct nand_flash_dev nand_flash_ids[] = {
 	/* 16 Gigabit */
 	{"NAND 2GiB 1,8V 8-bit",	0xA5, 0, 2048, 0, LP_OPTIONS},
 	{"NAND 2GiB 3,3V 8-bit",	0xD5, 0, 2048, 0, LP_OPTIONS},
+	{"NAND 2GiB 3,3V 8-bit",	0x48, 0, 2048, 0, LP_OPTIONS},
 	{"NAND 2GiB 1,8V 16-bit",	0xB5, 0, 2048, 0, LP_OPTIONS16},
 	{"NAND 2GiB 3,3V 16-bit",	0xC5, 0, 2048, 0, LP_OPTIONS16},
 
+	/* 32 Gigabit */
+	{"NAND 4GiB 3,3V 8-bit",	0x68, 0, 4096, 0, LP_OPTIONS},
+
+	/* 64 Gigabit */
+	{"NAND 8GiB 3,3V 8-bit",	0x88, 0, 8192, 0, LP_OPTIONS},
+
+	/* 256 Gigabit */
+	{"NAND 32GiB 3,3V 8-bit",	0xA8, 0, 32768, 0, LP_OPTIONS},
+
 	/*
 	 * Renesas AND 1 Gigabit. Those chips do not support extended id and
 	 * have a strange page/block layout !  The chosen minimum erasesize is
Signature · 1 line
1.7.0.4
#2 lore raw

Re: [PATCH v2] mtd/nand: Support Micron chips, pagesize >= 4KB

Hi,

Quoted 4 lines · Brian Norris

I found some newer Micron parts that introduce an 8K page size, and so need a modification on the algorithm. Here's the updated list and a revision to my patch.

Doesn't these micron nands support onfi ?
The micron nands we have support it.

I have started to add onfi support to mtd, but ATM it is ugly/incomplete.

I attach what I have (it is against 2.6.27, but could easily ported to new kernel).

Matthieu

PS : onfi support is also interesting for nand driver. They could get which speed support the nand (ie mtd could export some info for them). BTW some drivers like denali one, added onfi support in their driver instead of the generic layer...

Quoted 83 lines

Part ID String Block Page OOB
MT29F16G08ABABA 2C 48 00 26 89 00 00 512K 4K 224
MT29F16G08CBABA 2C 48 04 46 85 00 00 1024K 4K 224
MT29F16G08MAA 2C D5 94 3E 74 00 00 512K 4K 218
MT29F32G08CBACA 2C 68 04 4A A9 00 00 1024K 4K 224
MT29F64G08CBAAA 2C 88 04 4B A9 00 00 2048K 8K 448
MT29F256G08CJAAA 2C A8 05 CB A9 00 00 2048K 8K 448

---
 drivers/mtd/nand/nand_base.c |   37 ++++++++++++++++++++++++++++---------
 drivers/mtd/nand/nand_ids.c  |   10 ++++++++++
 2 files changed, 38 insertions(+), 9 deletions(-)
drivers/mtd/nand/nand_base.c +28 -9
index 4a7b864..a9216af 100644
@@ -2846,6 +2846,9 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 		 * Field definitions are in the following datasheets:
 		 * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
 		 * New style   (6 byte ID): Samsung K9GAG08U0D (p.40)
+		 * Micron      (5 byte ID): Micron MT29F16G08MAA (p.24)
+		 *      Note: Micron rule is based on heuristics for
+		 *            newer chips
 		 *
 		 * Check for wraparound + Samsung ID + nonzero 6th byte
 		 * to decide what to do.
@@ -2867,15 +2870,31 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 			/* Calc pagesize */
 			mtd->writesize = 1024 << (extid & 0x03);
 			extid >>= 2;
-			/* Calc oobsize */
-			mtd->oobsize = (8 << (extid & 0x01)) *
-				(mtd->writesize >> 9);
-			extid >>= 2;
-			/* Calc blocksize. Blocksize is multiples of 64KiB */
-			mtd->erasesize = (64 * 1024) << (extid & 0x03);
-			extid >>= 2;
-			/* Get buswidth information */
-			busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+			/* Check for 5 byte ID + Micron + read more 0x00 */
+			if (id_data[0] == NAND_MFR_MICRON && id_data[4] != 0x00
+					&& mtd->writesize >= 4096
+					&& id_data[5] == 0x00
+					&& id_data[6] == 0x00) {
+				/* OOB is 218B/224B per 4KiB pagesize */
+				mtd->oobsize = ((extid & 0x03) == 0x03 ? 218 :
+						224) << (mtd->writesize >> 13);
+				extid >>= 3;
+				/* Blocksize is multiple of 64KiB */
+				mtd->erasesize = mtd->writesize <<
+					(extid & 0x03) << 6;
+				/* All Micron have busw x8? */
+				busw = 0;
+			} else {
+				/* Calc oobsize */
+				mtd->oobsize = (8 << (extid & 0x01)) *
+					(mtd->writesize >> 9);
+				extid >>= 2;
+				/* Calc blocksize (multiples of 64KiB) */
+				mtd->erasesize = (64 * 1024) << (extid & 0x03);
+				extid >>= 2;
+				/* Get buswidth information */
+				busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+			}
 		}
 	} else {
 		/*
drivers/mtd/nand/nand_ids.c +3 -0
index 89907ed..4f6e59a 100644
@@ -107,9 +107,19 @@ struct nand_flash_dev nand_flash_ids[] = {
 	/* 16 Gigabit */
 	{"NAND 2GiB 1,8V 8-bit",	0xA5, 0, 2048, 0, LP_OPTIONS},
 	{"NAND 2GiB 3,3V 8-bit",	0xD5, 0, 2048, 0, LP_OPTIONS},
+	{"NAND 2GiB 3,3V 8-bit",	0x48, 0, 2048, 0, LP_OPTIONS},
 	{"NAND 2GiB 1,8V 16-bit",	0xB5, 0, 2048, 0, LP_OPTIONS16},
 	{"NAND 2GiB 3,3V 16-bit",	0xC5, 0, 2048, 0, LP_OPTIONS16},
 
+	/* 32 Gigabit */
+	{"NAND 4GiB 3,3V 8-bit",	0x68, 0, 4096, 0, LP_OPTIONS},

drivers/mtd/nand/nand_ids.c struct nand_flash_dev nand_flash_ids[] = { · line 125

Quoted 10 lines
drivers/mtd/nand/nand_ids.c +7 -0
+
+	/* 64 Gigabit */
+	{"NAND 8GiB 3,3V 8-bit",	0x88, 0, 8192, 0, LP_OPTIONS},
+
+	/* 256 Gigabit */
+	{"NAND 32GiB 3,3V 8-bit",	0xA8, 0, 32768, 0, LP_OPTIONS},
+
 	/*
 	 * Renesas AND 1 Gigabit. Those chips do not support extended id and
 	 * have a strange page/block layout !  The chosen minimum erasesize is
drivers/mtd/nand/nand_base.c +85 -27
index c6bea32..1cde3e9 100644
@@ -2318,15 +2318,25 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
 
 }
 
+static u16 onfi_crc(u16 crc, unsigned char const *p, size_t len)
+{
+    int i;
+    while (len--) {
+        crc ^= *p++ << 8;
+        for (i = 0; i < 8; i++)
+            crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0);
+    }
+    return crc;
+}
 /*
  * Get the flash and manufacturer id and lookup if the type is supported
  */
 static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 						  struct nand_chip *chip,
-						  int busw, int *maf_id)
+						  int busw, int *maf_id, int *dev_id)
 {
 	struct nand_flash_dev *type = NULL;
-	int i, dev_id, maf_idx;
+	int i, maf_idx;
 	int tmp_id, tmp_manf;
 
 	/* Select the device */
@@ -2343,7 +2353,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 
 	/* Read manufacturer and device IDs */
 	*maf_id = chip->read_byte(mtd);
-	dev_id = chip->read_byte(mtd);
+	*dev_id = chip->read_byte(mtd);
 
 	/* Try again to make sure, as some systems the bus-hold or other
 	 * interface concerns can cause random data which looks like a
@@ -2358,20 +2368,67 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 	tmp_manf = chip->read_byte(mtd);
 	tmp_id = chip->read_byte(mtd);
 
-	if (tmp_manf != *maf_id || tmp_id != dev_id) {
+	if (tmp_manf != *maf_id || tmp_id != *dev_id) {
 		printk(KERN_INFO "%s: second ID read did not match "
 		       "%02x,%02x against %02x,%02x\n", __func__,
-		       *maf_id, dev_id, tmp_manf, tmp_id);
+		       *maf_id, *dev_id, tmp_manf, tmp_id);
 		return ERR_PTR(-ENODEV);
 	}
 
 	/* Lookup the flash id */
 	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-		if (dev_id == nand_flash_ids[i].id) {
+		if (*dev_id == nand_flash_ids[i].id) {
 			type =  &nand_flash_ids[i];
 			break;
 		}
 	}
+#if 1
+	if (!type || !type->pagesize) {
+		/* try ONFI for unknow chip or LP */
+		chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
+		if (chip->read_byte(mtd) == 'O' &&
+			chip->read_byte(mtd) == 'N' &&
+			chip->read_byte(mtd) == 'F' &&
+			chip->read_byte(mtd) == 'I') {
+
+			int param[256/4];
+			char *paramb = param;
+			int i;
+
+			printk(KERN_INFO "ONFI flash detected\n");
+			chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
+			for (i = 0; i < 3; i++) {
+				/* XXX this that ok to use read_buf at this stage ? */
+				chip->read_buf(mtd, paramb, 256);
+				if (onfi_crc(0x4F4E, paramb, 254) == le16_to_cpup(paramb+254))
+				{
+					 printk(KERN_INFO "ONFI param page %d valid\n", i);
+				}
+			}
+			if (i < 3) {
+				/* TODO */
+				if (!mtd->name)
+					mtd->name = "onfi flash";
+				mtd->writesize = le32_to_cpup(paramb+80);
+				mtd->erasesize = le32_to_cpup(paramb+92)*mtd->writesize;
+				mtd->oobsize = le16_to_cpup(paramb+84);
+				chip->chipsize = le32_to_cpup(paramb+96) * mtd->erasesize;
+				busw = 0;
+				if (le16_to_cpup(paramb+6) & 1)
+					busw = NAND_BUSWIDTH_16;
+
+				chip->options &= ~NAND_CHIPOPTIONS_MSK;
+				chip->options |= (NAND_NO_READRDY | NAND_NO_AUTOINCR) & NAND_CHIPOPTIONS_MSK;
+				goto ident_done;
+
+			}
+		}
+	}
+#endif
+	chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
+	/* Read manufacturer and device IDs */
+	tmp_manf = chip->read_byte(mtd);
+	tmp_id = chip->read_byte(mtd);
 
 	if (!type)
 		return ERR_PTR(-ENODEV);
@@ -2409,6 +2466,21 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 		mtd->oobsize = mtd->writesize / 32;
 		busw = type->options & NAND_BUSWIDTH_16;
 	}
+	/* Get chip options, preserve non chip based options */
+	chip->options &= ~NAND_CHIPOPTIONS_MSK;
+	chip->options |= type->options & NAND_CHIPOPTIONS_MSK;
+
+	/* Check if chip is a not a samsung device. Do not clear the
+	 * options for chips which are not having an extended id.
+	 */
+	if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
+		chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
+ident_done:
+
+	/*
+	 * Set chip as a default. Board drivers can override it, if necessary
+	 */
+	chip->options |= NAND_NO_AUTOINCR;
 
 	/* Try to identify manufacturer */
 	for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) {
@@ -2423,7 +2495,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 	if (busw != (chip->options & NAND_BUSWIDTH_16)) {
 		printk(KERN_INFO "NAND device: Manufacturer ID:"
 		       " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
-		       dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
+		       *dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
 		printk(KERN_WARNING "NAND bus width %d instead %d bit\n",
 		       (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
 		       busw ? 16 : 8);
@@ -2443,21 +2515,6 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 	chip->badblockpos = mtd->writesize > 512 ?
 		NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
 
-	/* Get chip options, preserve non chip based options */
-	chip->options &= ~NAND_CHIPOPTIONS_MSK;
-	chip->options |= type->options & NAND_CHIPOPTIONS_MSK;
-
-	/*
-	 * Set chip as a default. Board drivers can override it, if necessary
-	 */
-	chip->options |= NAND_NO_AUTOINCR;
-
-	/* Check if chip is a not a samsung device. Do not clear the
-	 * options for chips which are not having an extended id.
-	 */
-	if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
-		chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
-
 	/* Check for AND chips with 4 page planes */
 	if (chip->options & NAND_4PAGE_ARRAY)
 		chip->erase_cmd = multi_erase_cmd;
@@ -2468,9 +2525,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 	if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
 		chip->cmdfunc = nand_command_lp;
 
+	/* TODO onfi flash name */
 	printk(KERN_INFO "NAND device: Manufacturer ID:"
-	       " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id,
-	       nand_manuf_ids[maf_idx].name, type->name);
+	       " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id,
+	       nand_manuf_ids[maf_idx].name, type?type->name:mtd->name);
 
 	return type;
 }
@@ -2487,7 +2545,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
  */
 int nand_scan_ident(struct mtd_info *mtd, int maxchips)
 {
-	int i, busw, nand_maf_id;
+	int i, busw, nand_maf_id, nand_dev_id;
 	struct nand_chip *chip = mtd->priv;
 	struct nand_flash_dev *type;
 
@@ -2497,7 +2555,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips)
 	nand_set_defaults(chip, busw);
 
 	/* Read the flash type */
-	type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id);
+	type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id, &nand_dev_id);
 
 	if (IS_ERR(type)) {
 		printk(KERN_WARNING "No NAND device found!!!\n");
@@ -2514,7 +2572,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips)
 		chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
 		/* Read manufacturer and device IDs */
 		if (nand_maf_id != chip->read_byte(mtd) ||
-		    type->id != chip->read_byte(mtd))
+		    nand_dev_id != chip->read_byte(mtd))
 			break;
 	}
 	if (i > 1)
include/linux/mtd/nand.h +1 -0
index 81774e5..edf3d27 100644
@@ -78,6 +78,7 @@ extern void nand_wait_ready(struct mtd_info *mtd);
 #define NAND_CMD_RNDIN		0x85
 #define NAND_CMD_READID		0x90
 #define NAND_CMD_ERASE2		0xd0
+#define NAND_CMD_PARAM		0xec
 #define NAND_CMD_RESET		0xff
 
 /* Extended commands for large page devices */
#3 lore raw

Re: [PATCH v2] mtd/nand: Support Micron chips, pagesize >= 4KB

Quoted 9 lines · Matthieu CASTET

Hi,

Quoted 4 lines · Brian Norris

I found some newer Micron parts that introduce an 8K page size, and so need a modification on the algorithm. Here's the updated list and a revision to my patch.

Doesn't these micron nands support onfi ?
The micron nands we have support it.

Yes, they do support ONFI...but you missed my statements in the previous e-mail :)

Quoted 5 lines · Brian Norris

And before the question is asked: I realize that these chips support ONFI, so that should be the primary means by which to identify them, but I would still like to be able to detect these properly without ONFI if necessary, especially considering some of the older NAND controllers we still use do not support reading ONFI data.

But thanks for the interest. I guess the real question I have is: is it possible to do a contrived detection by ID for these, even though the intent is for detection by ONFI? If so, is my [PATCH v2] an acceptable solution?

#4 lore raw

Re: [PATCH v2] mtd/nand: Support Micron chips, pagesize >= 4KB

Quoted 8 lines · Brian Norris
Quoted 7 lines · Matthieu CASTET

Hi,

Quoted 4 lines · Brian Norris

I found some newer Micron parts that introduce an 8K page size, and so need a modification on the algorithm. Here's the updated list and a revision to my patch.

Quoted 5 lines
Quoted 2 lines

Doesn't these micron nands support onfi ?
The micron nands we have support it.

Yes, they do support ONFI...but you missed my statements in the previous e-mail :)

But your v2 should be independent patch and contain all the explanations from the previous version too. It basically should be ready to be git-am'ed as is... If you see what I mean.

Artem.

#5 lore raw

Re: [PATCH v2] mtd/nand: Support Micron chips, pagesize >= 4KB

In reply to Brian Norris
Quoted 12 lines · Brian Norris

I found some newer Micron parts that introduce an 8K page size, and so need a modification on the algorithm. Here's the updated list and a revision to my patch.

Part ID String Block Page OOB
MT29F16G08ABABA 2C 48 00 26 89 00 00 512K 4K 224
MT29F16G08CBABA 2C 48 04 46 85 00 00 1024K 4K 224
MT29F16G08MAA 2C D5 94 3E 74 00 00 512K 4K 218
MT29F32G08CBACA 2C 68 04 4A A9 00 00 1024K 4K 224
MT29F64G08CBAAA 2C 88 04 4B A9 00 00 2048K 8K 448
MT29F256G08CJAAA 2C A8 05 CB A9 00 00 2048K 8K 448

Quoted 1 line

I'm not picking this patch to my l2-mtd-2.6.git, since AFAICS the chips support ONFI should be detected properly.

The "older chips" which do not support reading ONFI data can then be detected using special quirks. But using heuristics even for the chips which do support reading ONFI data sounds bad.

Is this ok? :-)

Artem.

#6 lore raw

Re: [PATCH v2] mtd/nand: Support Micron chips, pagesize >= 4KB

Quoted 6 lines · Artem Bityutskiy

I'm not picking this patch to my l2-mtd-2.6.git, since AFAICS the chips support ONFI should be detected properly.

The "older chips" which do not support reading ONFI data can then be detected using special quirks. But using heuristics even for the chips which do support reading ONFI data sounds bad.

The NAND controllers on certain legacy SoCs are not able to read the ONFI parameter page, even if the flash device itself supports ONFI. Consequently, heuristics or a lookup table would need to be used to determine the device parameters.

Worst case, I guess the Micron ID decoding logic could just be moved into the low-level driver.

#7 lore raw

Re: [PATCH v2] mtd/nand: Support Micron chips, pagesize >= 4KB

hi,

Quoted 10 lines · Kevin Cernekee
Quoted 6 lines · Artem Bityutskiy

I'm not picking this patch to my l2-mtd-2.6.git, since AFAICS the chips support ONFI should be detected properly.

The "older chips" which do not support reading ONFI data can then be detected using special quirks. But using heuristics even for the chips which do support reading ONFI data sounds bad.

The NAND controllers on certain legacy SoCs are not able to read the ONFI parameter page, even if the flash device itself supports ONFI.

Why ?
Are there controllers that doesn't allow to send custom command ?

Matthieu

#8 lore raw

Re: [PATCH v2] mtd/nand: Support Micron chips, pagesize >= 4KB

Quoted 5 lines · Matthieu CASTET
Quoted 2 lines

The NAND controllers on certain legacy SoCs are not able to read the ONFI parameter page, even if the flash device itself supports ONFI.

Why ?
Are there controllers that doesn't allow to send custom command ?

Yes. The controllers I have here operate at a relatively high level (read page, write page, erase block). Part of the reason for this is because the controller is designed for XIP and DMA - operations where it is not practical to have the CPU involved in building command sequences or wiggling ALE/CLE.

Newer versions of the hardware do have the ability to issue custom commands and perform ONFI queries, but the versions in the field right now do not.

#9 lore raw

Re: [PATCH v2] mtd/nand: Support Micron chips, pagesize >= 4KB

Quoted 14 lines · Kevin Cernekee
Quoted 5 lines · Matthieu CASTET
Quoted 2 lines

The NAND controllers on certain legacy SoCs are not able to read the ONFI parameter page, even if the flash device itself supports ONFI.

Why ?
Are there controllers that doesn't allow to send custom command ?

Yes. The controllers I have here operate at a relatively high level (read page, write page, erase block). Part of the reason for this is because the controller is designed for XIP and DMA - operations where it is not practical to have the CPU involved in building command sequences or wiggling ALE/CLE.

Quoted 3 lines

Newer versions of the hardware do have the ability to issue custom commands and perform ONFI queries, but the versions in the field right now do not.

Sorry for my ignorance. Correct me if I'm wrong. I think this should work as follows:

1. First we add the ONFI detection to MTD, and make it work.
2. If we have an ONFI device which nevertheless does not allow us reading ONFI data, then we run a 'onfi_broken_devices_quirk()' or something like this. And this quirk tries to use whatever heuristics.

So, I was thinking that adding strange heuristics and quirks to generic code is bad. We should _first_ add proper ONFI code, and _then_ add exception for strange devices like you have.

Do I miss something?

Signature · 2 lines
Best Regards,
Artem Bityutskiy (Артём Битюцкий)
#10 lore raw

Re: [PATCH v2] mtd/nand: Support Micron chips, pagesize >= 4KB

Quoted 1 line · Artem Bityutskiy

1. First we add the ONFI detection to MTD, and make it work.

OK

Quoted 3 lines

2. If we have an ONFI device which nevertheless does not allow us reading ONFI data, then we run a 'onfi_broken_devices_quirk()' or something like this. And this quirk tries to use whatever heuristics.

OK

It's more of a "broken controller quirk" than a "broken flash device quirk," though.

It would be helpful to know if there are any other controller designs that are unable to read the ONFI parameter page. i.e. is this a problem to be solved in the common code, or a driver-specific situation?

Quoted 3 lines

So, I was thinking that adding strange heuristics and quirks to generic code is bad. We should _first_ add proper ONFI code, and _then_ add exception for strange devices like you have.

Unfortunately, I think the heuristic/quirk logic is unavoidable for Samsung and other non-ONFI vendors.

So the question becomes: if nand_base.c already has to have heuristic/quirk code anyway, and some controller(s) can't speak ONFI so they need even MORE heuristic/quirk code than the others - do we add the latter code into nand_base.c or just put it in the driver?

#11 lore raw

Re: [PATCH v2] mtd/nand: Support Micron chips, pagesize >= 4KB

Quoted 11 lines · Kevin Cernekee
Quoted 3 lines

So, I was thinking that adding strange heuristics and quirks to generic code is bad. We should _first_ add proper ONFI code, and _then_ add exception for strange devices like you have.

Unfortunately, I think the heuristic/quirk logic is unavoidable for Samsung and other non-ONFI vendors.

So the question becomes: if nand_base.c already has to have heuristic/quirk code anyway, and some controller(s) can't speak ONFI so they need even MORE heuristic/quirk code than the others - do we add the latter code into nand_base.c or just put it in the driver?

OK, I can apply it to the dunno branch and let dwmw2 decide. But this patch does not apply anymore to to my tree. Brian, would you refresh and resend? Also, Florian said he is going to send ONFI support soon, may be it'll make sens to wait a bit and re-send the patch on top of ONFI support?

Signature · 2 lines
Best Regards,
Artem Bityutskiy (Битюцкий Артём)
#12 lore raw
In reply to Brian Norris
Quoted 23 lines · Brian Norris

The following parts exhibit some interesting patterns in their ID strings. Their ID strings are not fully compatible with the current nand_base.c detection algorithm. In order to detect them properly, I have taken the liberty to develop a heuristic algorithm. None of these chips have a *good* detection pattern listed in their datasheets, although MT29F16G08MAA has a table on p.24 of its data sheet (not included here).

Part ID String Block Page OOB
MT29F16G08ABABA 2C 48 00 26 89 00 00 512K 4K 224
MT29F16G08CBABA 2C 48 04 46 85 00 00 1024K 4K 224
MT29F16G08MAA 2C D5 94 3E 74 00 00 512K 4K 218

I have attached a table logging most of the relevant data for the many chips I have researched. The three chips are highlighted red, although there are variants of the chips listed as well. I believe this patch should correctly identify all the 5-byte ID Micron chips.

And before the question is asked: I realize that these chips support ONFI, so that should be the primary means by which to identify them, but I would still like to be able to detect these properly without ONFI if necessary, especially considering some of the older NAND controllers we still use do not support reading ONFI data.

Quoted 3 lines

Feedback on my logic is appreciated.

Really not sure about this patch. Sounds like ONFI should be used, except for those few chips which do not support reading ONFI data. The heuristics you add smell fishy...

Signature · 2 lines
Best Regards,
Artem Bityutskiy (Артём Битюцкий)