* [PATCHv2 0/2] mtd: nand: Extend MLC support @ 2010-05-05 3:58 ` Kevin Cernekee 0 siblings, 0 replies; 12+ messages in thread From: Kevin Cernekee @ 2010-05-05 3:58 UTC (permalink / raw) To: dwmw2; +Cc: linux-mtd, linux-kernel, Reuben.Dowle Part 1/2 is an improved version of my previous submission. Additional checks were added to ensure that certain "5-byte" Micron and Samsung parts are not falsely detected as having 6-byte IDs. I also rolled in the 256B NAND_MAX_OOBSIZE change. Part 2/2 is a resubmission/rebase of Reuben Dowle's 2009/02/03 patch: http://lists.infradead.org/pipermail/linux-mtd/2009-February/024473.html I am trying to compile a table of NAND IDs to make sure the detection algorithm correctly handles all known cases. If you could send me the following information for any NAND chips you have access to (via private email), it would be appreciated: 1) Part number 2) ID code (please read 8 bytes so I can see where it wraps around) 3) Device size, block size, page size, OOB bytes per page, bus width, and bad block marker location 4) Datasheet, if available Thanks. ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCHv2 0/2] mtd: nand: Extend MLC support @ 2010-05-05 3:58 ` Kevin Cernekee 0 siblings, 0 replies; 12+ messages in thread From: Kevin Cernekee @ 2010-05-05 3:58 UTC (permalink / raw) To: dwmw2; +Cc: linux-mtd, linux-kernel, Reuben.Dowle Part 1/2 is an improved version of my previous submission. Additional checks were added to ensure that certain "5-byte" Micron and Samsung parts are not falsely detected as having 6-byte IDs. I also rolled in the 256B NAND_MAX_OOBSIZE change. Part 2/2 is a resubmission/rebase of Reuben Dowle's 2009/02/03 patch: http://lists.infradead.org/pipermail/linux-mtd/2009-February/024473.html I am trying to compile a table of NAND IDs to make sure the detection algorithm correctly handles all known cases. If you could send me the following information for any NAND chips you have access to (via private email), it would be appreciated: 1) Part number 2) ID code (please read 8 bytes so I can see where it wraps around) 3) Device size, block size, page size, OOB bytes per page, bus width, and bad block marker location 4) Datasheet, if available Thanks. ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCHv2 1/2] mtd: nand: Extend NAND flash detection to new MLC chips 2010-05-05 3:58 ` Kevin Cernekee @ 2010-05-05 3:58 ` Kevin Cernekee -1 siblings, 0 replies; 12+ messages in thread From: Kevin Cernekee @ 2010-05-05 3:58 UTC (permalink / raw) To: dwmw2; +Cc: linux-mtd, linux-kernel, Reuben.Dowle Some of the newer MLC devices have a 6-byte ID sequence in which several field definitions differ from older chips in a manner that is not backward compatible. For instance: Samsung K9GAG08U0M (5-byte sequence): ec d5 14 b6 74 4th byte, bits 1:0 encode the page size: 0=1KiB, 1=2KiB, 2=4KiB, 3=8KiB 4th byte, bits 5:4 encode the block size: 0=64KiB, 1=128KiB, ... 4th byte, bit 6 encodes the OOB size: 0=8B/512B, 1=16B/512B Samsung K9GAG08U0D (6-byte sequence): ec d5 94 29 34 41 4th byte, bits 1:0 encode the page size: 0=2KiB, 1=4KiB, 3=8KiB, 4=rsvd 4th byte, bits 7;5:4 encode the block size: 0=128KiB, 1=256KiB, ... 4th byte, bits 6;3:2 encode the OOB size: 1=128B/page, 2=218B/page This patch uses the new 6-byte scheme if the following conditions are all true: 1) The ID code wraps around after exactly 6 bytes 2) Manufacturer is Samsung 3) 6th byte is zero The patch also extends the maximum OOB size from 128B to 256B. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> --- drivers/mtd/nand/nand_base.c | 64 ++++++++++++++++++++++++++++------------- include/linux/mtd/nand.h | 2 +- 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index b9dc65c..85891dc 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2774,8 +2774,8 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, int busw, int *maf_id, struct nand_flash_dev *type) { - int dev_id, maf_idx; - int tmp_id, tmp_manf; + int i, dev_id, maf_idx; + u8 id_data[8]; /* Select the device */ chip->select_chip(mtd, 0); @@ -2801,15 +2801,15 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); - /* Read manufacturer and device IDs */ + /* Read entire ID string */ - tmp_manf = chip->read_byte(mtd); - tmp_id = chip->read_byte(mtd); + for (i = 0; i < 8; i++) + id_data[i] = chip->read_byte(mtd); - if (tmp_manf != *maf_id || tmp_id != dev_id) { + if (id_data[0] != *maf_id || id_data[1] != 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, id_data[0], id_data[1]); return ERR_PTR(-ENODEV); } @@ -2832,21 +2832,45 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, if (!type->pagesize) { int extid; /* The 3rd id byte holds MLC / multichip data */ - chip->cellinfo = chip->read_byte(mtd); + chip->cellinfo = id_data[2]; /* The 4th id byte is the important one */ - extid = chip->read_byte(mtd); - /* Calc pagesize */ - mtd->writesize = 1024 << (extid & 0x3); - 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; + extid = id_data[3]; + /* + * 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) + * + * Check for wraparound + Samsung ID + nonzero 6th byte + * to decide what to do. + */ + if (id_data[0] == id_data[6] && id_data[1] == id_data[7] && + id_data[0] == NAND_MFR_SAMSUNG && + id_data[5] != 0x00) { + /* Calc pagesize */ + mtd->writesize = 2048 << (extid & 0x03); + extid >>= 2; + /* Calc oobsize */ + mtd->oobsize = (extid & 0x03) == 0x01 ? 128 : 218; + extid >>= 2; + /* Calc blocksize */ + mtd->erasesize = (128 * 1024) << + (((extid >> 1) & 0x04) | (extid & 0x03)); + busw = 0; + } else { + /* 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; + } } else { /* * Old devices have chip data hardcoded in the device id table diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 8bdacb8..50f3aa0 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -53,7 +53,7 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); * is supported now. If you add a chip with bigger oobsize/page * adjust this accordingly. */ -#define NAND_MAX_OOBSIZE 128 +#define NAND_MAX_OOBSIZE 256 #define NAND_MAX_PAGESIZE 4096 /* -- 1.6.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCHv2 1/2] mtd: nand: Extend NAND flash detection to new MLC chips @ 2010-05-05 3:58 ` Kevin Cernekee 0 siblings, 0 replies; 12+ messages in thread From: Kevin Cernekee @ 2010-05-05 3:58 UTC (permalink / raw) To: dwmw2; +Cc: linux-mtd, linux-kernel, Reuben.Dowle Some of the newer MLC devices have a 6-byte ID sequence in which several field definitions differ from older chips in a manner that is not backward compatible. For instance: Samsung K9GAG08U0M (5-byte sequence): ec d5 14 b6 74 4th byte, bits 1:0 encode the page size: 0=1KiB, 1=2KiB, 2=4KiB, 3=8KiB 4th byte, bits 5:4 encode the block size: 0=64KiB, 1=128KiB, ... 4th byte, bit 6 encodes the OOB size: 0=8B/512B, 1=16B/512B Samsung K9GAG08U0D (6-byte sequence): ec d5 94 29 34 41 4th byte, bits 1:0 encode the page size: 0=2KiB, 1=4KiB, 3=8KiB, 4=rsvd 4th byte, bits 7;5:4 encode the block size: 0=128KiB, 1=256KiB, ... 4th byte, bits 6;3:2 encode the OOB size: 1=128B/page, 2=218B/page This patch uses the new 6-byte scheme if the following conditions are all true: 1) The ID code wraps around after exactly 6 bytes 2) Manufacturer is Samsung 3) 6th byte is zero The patch also extends the maximum OOB size from 128B to 256B. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> --- drivers/mtd/nand/nand_base.c | 64 ++++++++++++++++++++++++++++------------- include/linux/mtd/nand.h | 2 +- 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index b9dc65c..85891dc 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2774,8 +2774,8 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, int busw, int *maf_id, struct nand_flash_dev *type) { - int dev_id, maf_idx; - int tmp_id, tmp_manf; + int i, dev_id, maf_idx; + u8 id_data[8]; /* Select the device */ chip->select_chip(mtd, 0); @@ -2801,15 +2801,15 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); - /* Read manufacturer and device IDs */ + /* Read entire ID string */ - tmp_manf = chip->read_byte(mtd); - tmp_id = chip->read_byte(mtd); + for (i = 0; i < 8; i++) + id_data[i] = chip->read_byte(mtd); - if (tmp_manf != *maf_id || tmp_id != dev_id) { + if (id_data[0] != *maf_id || id_data[1] != 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, id_data[0], id_data[1]); return ERR_PTR(-ENODEV); } @@ -2832,21 +2832,45 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, if (!type->pagesize) { int extid; /* The 3rd id byte holds MLC / multichip data */ - chip->cellinfo = chip->read_byte(mtd); + chip->cellinfo = id_data[2]; /* The 4th id byte is the important one */ - extid = chip->read_byte(mtd); - /* Calc pagesize */ - mtd->writesize = 1024 << (extid & 0x3); - 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; + extid = id_data[3]; + /* + * 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) + * + * Check for wraparound + Samsung ID + nonzero 6th byte + * to decide what to do. + */ + if (id_data[0] == id_data[6] && id_data[1] == id_data[7] && + id_data[0] == NAND_MFR_SAMSUNG && + id_data[5] != 0x00) { + /* Calc pagesize */ + mtd->writesize = 2048 << (extid & 0x03); + extid >>= 2; + /* Calc oobsize */ + mtd->oobsize = (extid & 0x03) == 0x01 ? 128 : 218; + extid >>= 2; + /* Calc blocksize */ + mtd->erasesize = (128 * 1024) << + (((extid >> 1) & 0x04) | (extid & 0x03)); + busw = 0; + } else { + /* 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; + } } else { /* * Old devices have chip data hardcoded in the device id table diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 8bdacb8..50f3aa0 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -53,7 +53,7 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); * is supported now. If you add a chip with bigger oobsize/page * adjust this accordingly. */ -#define NAND_MAX_OOBSIZE 128 +#define NAND_MAX_OOBSIZE 256 #define NAND_MAX_PAGESIZE 4096 /* -- 1.6.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCHv2 1/2] mtd: nand: Extend NAND flash detection to new MLC chips 2010-05-05 3:58 ` Kevin Cernekee @ 2010-05-05 7:34 ` Matthieu CASTET -1 siblings, 0 replies; 12+ messages in thread From: Matthieu CASTET @ 2010-05-05 7:34 UTC (permalink / raw) To: Kevin Cernekee Cc: linux-mtd@lists.infradead.org, dwmw2@infradead.org, linux-kernel@vger.kernel.org, Reuben.Dowle@navico.com Hi, Kevin Cernekee a écrit : > Some of the newer MLC devices have a 6-byte ID sequence in which > several field definitions differ from older chips in a manner that is > not backward compatible. For instance: > Doesn't these nand support ONFI "Read Parameter Page" (cmd 0xec) ? If yes it will be a more generic way to detect new nand features. Matthieu > Samsung K9GAG08U0M (5-byte sequence): ec d5 14 b6 74 > 4th byte, bits 1:0 encode the page size: 0=1KiB, 1=2KiB, 2=4KiB, 3=8KiB > 4th byte, bits 5:4 encode the block size: 0=64KiB, 1=128KiB, ... > 4th byte, bit 6 encodes the OOB size: 0=8B/512B, 1=16B/512B > > Samsung K9GAG08U0D (6-byte sequence): ec d5 94 29 34 41 > 4th byte, bits 1:0 encode the page size: 0=2KiB, 1=4KiB, 3=8KiB, 4=rsvd > 4th byte, bits 7;5:4 encode the block size: 0=128KiB, 1=256KiB, ... > 4th byte, bits 6;3:2 encode the OOB size: 1=128B/page, 2=218B/page > > This patch uses the new 6-byte scheme if the following conditions are > all true: > > 1) The ID code wraps around after exactly 6 bytes > > 2) Manufacturer is Samsung > > 3) 6th byte is zero > > The patch also extends the maximum OOB size from 128B to 256B. > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCHv2 1/2] mtd: nand: Extend NAND flash detection to new MLC chips @ 2010-05-05 7:34 ` Matthieu CASTET 0 siblings, 0 replies; 12+ messages in thread From: Matthieu CASTET @ 2010-05-05 7:34 UTC (permalink / raw) To: Kevin Cernekee Cc: dwmw2@infradead.org, linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org, Reuben.Dowle@navico.com Hi, Kevin Cernekee a écrit : > Some of the newer MLC devices have a 6-byte ID sequence in which > several field definitions differ from older chips in a manner that is > not backward compatible. For instance: > Doesn't these nand support ONFI "Read Parameter Page" (cmd 0xec) ? If yes it will be a more generic way to detect new nand features. Matthieu > Samsung K9GAG08U0M (5-byte sequence): ec d5 14 b6 74 > 4th byte, bits 1:0 encode the page size: 0=1KiB, 1=2KiB, 2=4KiB, 3=8KiB > 4th byte, bits 5:4 encode the block size: 0=64KiB, 1=128KiB, ... > 4th byte, bit 6 encodes the OOB size: 0=8B/512B, 1=16B/512B > > Samsung K9GAG08U0D (6-byte sequence): ec d5 94 29 34 41 > 4th byte, bits 1:0 encode the page size: 0=2KiB, 1=4KiB, 3=8KiB, 4=rsvd > 4th byte, bits 7;5:4 encode the block size: 0=128KiB, 1=256KiB, ... > 4th byte, bits 6;3:2 encode the OOB size: 1=128B/page, 2=218B/page > > This patch uses the new 6-byte scheme if the following conditions are > all true: > > 1) The ID code wraps around after exactly 6 bytes > > 2) Manufacturer is Samsung > > 3) 6th byte is zero > > The patch also extends the maximum OOB size from 128B to 256B. > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCHv2 1/2] mtd: nand: Extend NAND flash detection to new MLC chips 2010-05-05 7:34 ` Matthieu CASTET @ 2010-05-05 15:20 ` Kevin Cernekee -1 siblings, 0 replies; 12+ messages in thread From: Kevin Cernekee @ 2010-05-05 15:20 UTC (permalink / raw) To: Matthieu CASTET Cc: linux-mtd@lists.infradead.org, dwmw2@infradead.org, linux-kernel@vger.kernel.org, Reuben.Dowle@navico.com On Wed, May 5, 2010 at 12:34 AM, Matthieu CASTET <matthieu.castet@parrot.com> wrote: > Doesn't these nand support ONFI "Read Parameter Page" (cmd 0xec) ? > If yes it will be a more generic way to detect new nand features. Unfortunately, Samsung and Toshiba do not support ONFI: http://onfi.org/membership/ http://www.hantat.com/News-Read-281-1.html ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCHv2 1/2] mtd: nand: Extend NAND flash detection to new MLC chips @ 2010-05-05 15:20 ` Kevin Cernekee 0 siblings, 0 replies; 12+ messages in thread From: Kevin Cernekee @ 2010-05-05 15:20 UTC (permalink / raw) To: Matthieu CASTET Cc: dwmw2@infradead.org, linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org, Reuben.Dowle@navico.com On Wed, May 5, 2010 at 12:34 AM, Matthieu CASTET <matthieu.castet@parrot.com> wrote: > Doesn't these nand support ONFI "Read Parameter Page" (cmd 0xec) ? > If yes it will be a more generic way to detect new nand features. Unfortunately, Samsung and Toshiba do not support ONFI: http://onfi.org/membership/ http://www.hantat.com/News-Read-281-1.html ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCHv2 2/2] mtd: nand: Support alternate BB marker locations on MLC 2010-05-05 3:58 ` Kevin Cernekee @ 2010-05-05 3:58 ` Kevin Cernekee -1 siblings, 0 replies; 12+ messages in thread From: Kevin Cernekee @ 2010-05-05 3:58 UTC (permalink / raw) To: dwmw2; +Cc: linux-mtd, linux-kernel, Reuben.Dowle This is a slightly modified version of a patch submitted last year by Reuben Dowle <reuben.dowle@navico.com>. His original comments follow: This patch adds support for some MLC NAND flashes that place the BB marker in the LAST page of the bad block rather than the FIRST page used for SLC NAND and other types of MLC nand. Lifted from Samsung datasheet for K9LG8G08U0A (1Gbyte MLC NAND): " Identifying Initial Invalid Block(s) All device locations are erased(FFh) except locations where the initial invalid block(s) information is written prior to shipping. The initial invalid block(s) status is defined by the 1st byte in the spare area. Samsung makes sure that the last page of every initial invalid block has non-FFh data at the column address of 2,048. ... " As far as I can tell, this is the same for all Samsung MLC nand, and in fact the samsung bsp for the processor used in our project (s3c6410) actually contained a hack similar to this patch but less portable to enable use of their NAND parts. I discovered this problem when trying to use a Micron NAND which does not used this layout - I wish samsung would put their stuff in main-line to avoid this type of problem. Currently this patch causes all MLC nand with manufacturer codes from Samsung and ST(Numonyx) to use this alternative location, since these are the manufactures that I know of that use this layout. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> --- drivers/mtd/nand/nand_base.c | 15 +++++++++++++++ drivers/mtd/nand/nand_bbt.c | 3 +++ include/linux/mtd/nand.h | 2 ++ 3 files changed, 20 insertions(+), 0 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 85891dc..4a7b864 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -347,6 +347,9 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) struct nand_chip *chip = mtd->priv; u16 bad; + if (chip->options & NAND_BB_LAST_PAGE) + ofs += mtd->erasesize - mtd->writesize; + page = (int)(ofs >> chip->page_shift) & chip->pagemask; if (getchip) { @@ -396,6 +399,9 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) uint8_t buf[2] = { 0, 0 }; int block, ret; + if (chip->options & NAND_BB_LAST_PAGE) + ofs += mtd->erasesize - mtd->writesize; + /* Get block number */ block = (int)(ofs >> chip->bbt_erase_shift); if (chip->bbt) @@ -2933,6 +2939,15 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize) chip->options &= ~NAND_SAMSUNG_LP_OPTIONS; + /* + * Bad block marker is stored in the last page of each block + * on Samsung and Hynix MLC devices + */ + if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) && + (*maf_id == NAND_MFR_SAMSUNG || + *maf_id == NAND_MFR_HYNIX)) + chip->options |= NAND_BB_LAST_PAGE; + /* Check for AND chips with 4 page planes */ if (chip->options & NAND_4PAGE_ARRAY) chip->erase_cmd = multi_erase_cmd; diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 387c45c..ad97c0c 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -432,6 +432,9 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, from = (loff_t)startblock << (this->bbt_erase_shift - 1); } + if (this->options & NAND_BB_LAST_PAGE) + from += mtd->erasesize - (mtd->writesize * len); + for (i = startblock; i < numblocks;) { int ret; diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 50f3aa0..a81b185 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -181,6 +181,8 @@ typedef enum { #define NAND_NO_READRDY 0x00000100 /* Chip does not allow subpage writes */ #define NAND_NO_SUBPAGE_WRITE 0x00000200 +/* Chip stores bad block marker on the last page of the eraseblock */ +#define NAND_BB_LAST_PAGE 0x00000400 /* Device is one of 'new' xD cards that expose fake nand command set */ #define NAND_BROKEN_XD 0x00000400 -- 1.6.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCHv2 2/2] mtd: nand: Support alternate BB marker locations on MLC @ 2010-05-05 3:58 ` Kevin Cernekee 0 siblings, 0 replies; 12+ messages in thread From: Kevin Cernekee @ 2010-05-05 3:58 UTC (permalink / raw) To: dwmw2; +Cc: linux-mtd, linux-kernel, Reuben.Dowle This is a slightly modified version of a patch submitted last year by Reuben Dowle <reuben.dowle@navico.com>. His original comments follow: This patch adds support for some MLC NAND flashes that place the BB marker in the LAST page of the bad block rather than the FIRST page used for SLC NAND and other types of MLC nand. Lifted from Samsung datasheet for K9LG8G08U0A (1Gbyte MLC NAND): " Identifying Initial Invalid Block(s) All device locations are erased(FFh) except locations where the initial invalid block(s) information is written prior to shipping. The initial invalid block(s) status is defined by the 1st byte in the spare area. Samsung makes sure that the last page of every initial invalid block has non-FFh data at the column address of 2,048. ... " As far as I can tell, this is the same for all Samsung MLC nand, and in fact the samsung bsp for the processor used in our project (s3c6410) actually contained a hack similar to this patch but less portable to enable use of their NAND parts. I discovered this problem when trying to use a Micron NAND which does not used this layout - I wish samsung would put their stuff in main-line to avoid this type of problem. Currently this patch causes all MLC nand with manufacturer codes from Samsung and ST(Numonyx) to use this alternative location, since these are the manufactures that I know of that use this layout. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> --- drivers/mtd/nand/nand_base.c | 15 +++++++++++++++ drivers/mtd/nand/nand_bbt.c | 3 +++ include/linux/mtd/nand.h | 2 ++ 3 files changed, 20 insertions(+), 0 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 85891dc..4a7b864 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -347,6 +347,9 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) struct nand_chip *chip = mtd->priv; u16 bad; + if (chip->options & NAND_BB_LAST_PAGE) + ofs += mtd->erasesize - mtd->writesize; + page = (int)(ofs >> chip->page_shift) & chip->pagemask; if (getchip) { @@ -396,6 +399,9 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) uint8_t buf[2] = { 0, 0 }; int block, ret; + if (chip->options & NAND_BB_LAST_PAGE) + ofs += mtd->erasesize - mtd->writesize; + /* Get block number */ block = (int)(ofs >> chip->bbt_erase_shift); if (chip->bbt) @@ -2933,6 +2939,15 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize) chip->options &= ~NAND_SAMSUNG_LP_OPTIONS; + /* + * Bad block marker is stored in the last page of each block + * on Samsung and Hynix MLC devices + */ + if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) && + (*maf_id == NAND_MFR_SAMSUNG || + *maf_id == NAND_MFR_HYNIX)) + chip->options |= NAND_BB_LAST_PAGE; + /* Check for AND chips with 4 page planes */ if (chip->options & NAND_4PAGE_ARRAY) chip->erase_cmd = multi_erase_cmd; diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 387c45c..ad97c0c 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -432,6 +432,9 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, from = (loff_t)startblock << (this->bbt_erase_shift - 1); } + if (this->options & NAND_BB_LAST_PAGE) + from += mtd->erasesize - (mtd->writesize * len); + for (i = startblock; i < numblocks;) { int ret; diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 50f3aa0..a81b185 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -181,6 +181,8 @@ typedef enum { #define NAND_NO_READRDY 0x00000100 /* Chip does not allow subpage writes */ #define NAND_NO_SUBPAGE_WRITE 0x00000200 +/* Chip stores bad block marker on the last page of the eraseblock */ +#define NAND_BB_LAST_PAGE 0x00000400 /* Device is one of 'new' xD cards that expose fake nand command set */ #define NAND_BROKEN_XD 0x00000400 -- 1.6.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCHv2 0/2] mtd: nand: Extend MLC support 2010-05-05 3:58 ` Kevin Cernekee @ 2010-05-05 12:19 ` Artem Bityutskiy -1 siblings, 0 replies; 12+ messages in thread From: Artem Bityutskiy @ 2010-05-05 12:19 UTC (permalink / raw) To: Kevin Cernekee; +Cc: linux-mtd, dwmw2, linux-kernel, Reuben.Dowle On Tue, 2010-05-04 at 20:58 -0700, Kevin Cernekee wrote: > Part 1/2 is an improved version of my previous submission. Additional > checks were added to ensure that certain "5-byte" Micron and Samsung > parts are not falsely detected as having 6-byte IDs. I also rolled in > the 256B NAND_MAX_OOBSIZE change. > > Part 2/2 is a resubmission/rebase of Reuben Dowle's 2009/02/03 patch: > > http://lists.infradead.org/pipermail/linux-mtd/2009-February/024473.html > > I am trying to compile a table of NAND IDs to make sure the detection > algorithm correctly handles all known cases. If you could send me the > following information for any NAND chips you have access to (via > private email), it would be appreciated: > > 1) Part number > > 2) ID code (please read 8 bytes so I can see where it wraps around) > > 3) Device size, block size, page size, OOB bytes per page, bus width, > and bad block marker location > > 4) Datasheet, if available Removed older patches and taken these ones to l2-mtd-2.6 / dunno. -- Best Regards, Artem Bityutskiy (Артём Битюцкий) ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCHv2 0/2] mtd: nand: Extend MLC support @ 2010-05-05 12:19 ` Artem Bityutskiy 0 siblings, 0 replies; 12+ messages in thread From: Artem Bityutskiy @ 2010-05-05 12:19 UTC (permalink / raw) To: Kevin Cernekee; +Cc: dwmw2, linux-mtd, linux-kernel, Reuben.Dowle On Tue, 2010-05-04 at 20:58 -0700, Kevin Cernekee wrote: > Part 1/2 is an improved version of my previous submission. Additional > checks were added to ensure that certain "5-byte" Micron and Samsung > parts are not falsely detected as having 6-byte IDs. I also rolled in > the 256B NAND_MAX_OOBSIZE change. > > Part 2/2 is a resubmission/rebase of Reuben Dowle's 2009/02/03 patch: > > http://lists.infradead.org/pipermail/linux-mtd/2009-February/024473.html > > I am trying to compile a table of NAND IDs to make sure the detection > algorithm correctly handles all known cases. If you could send me the > following information for any NAND chips you have access to (via > private email), it would be appreciated: > > 1) Part number > > 2) ID code (please read 8 bytes so I can see where it wraps around) > > 3) Device size, block size, page size, OOB bytes per page, bus width, > and bad block marker location > > 4) Datasheet, if available Removed older patches and taken these ones to l2-mtd-2.6 / dunno. -- Best Regards, Artem Bityutskiy (Артём Битюцкий) ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2010-05-05 15:20 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-05-05 3:58 [PATCHv2 0/2] mtd: nand: Extend MLC support Kevin Cernekee 2010-05-05 3:58 ` Kevin Cernekee 2010-05-05 3:58 ` [PATCHv2 1/2] mtd: nand: Extend NAND flash detection to new MLC chips Kevin Cernekee 2010-05-05 3:58 ` Kevin Cernekee 2010-05-05 7:34 ` Matthieu CASTET 2010-05-05 7:34 ` Matthieu CASTET 2010-05-05 15:20 ` Kevin Cernekee 2010-05-05 15:20 ` Kevin Cernekee 2010-05-05 3:58 ` [PATCHv2 2/2] mtd: nand: Support alternate BB marker locations on MLC Kevin Cernekee 2010-05-05 3:58 ` Kevin Cernekee 2010-05-05 12:19 ` [PATCHv2 0/2] mtd: nand: Extend MLC support Artem Bityutskiy 2010-05-05 12:19 ` Artem Bityutskiy
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.