Message ID | 1245183812-11500-1-git-send-email-s-paulraj@ti.com |
---|---|
State | New, archived |
Headers | show |
s-paulraj@ti.com wrote: > From: Sandeep Paulraj <s-paulraj@ti.com> > > The patch applies to linux-mtd GIT tree > > This patch adds 4-bit ECC support for large page NAND chips using the new ECC > mode NAND_ECC_HW_OOB_FIRST. The platform data from board-dm355-evm has been > adjusted to use this mode. > > The patches have been verified on DM355 device with 2K and 4K page size > Micron devices using mtd-tests. > Error correction upto 4-bits has also been verified using > nandwrite/nanddump utilities. > > Reviewed-by: David Brownell <dbrownell@users.sourceforge.net> > Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com> > Signed-off-by: Sneha Narnakaje <nsnehaprabha@ti.com> > --- > drivers/mtd/nand/davinci_nand.c | 65 ++++++++++++++++++++++++++++++++++---- > 1 files changed, 58 insertions(+), 7 deletions(-) > > diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c > index ba6940d..2ff0712 100644 > --- a/drivers/mtd/nand/davinci_nand.c > +++ b/drivers/mtd/nand/davinci_nand.c > @@ -500,6 +500,49 @@ static struct nand_ecclayout hwecc4_small __initconst = { > }, > }; > > +/* An ECC layout for using 4-bit ECC with large-page (2048bytes) flash, > + * storing ten ECC bytes plus the manufacturer's bad block marker byte, > + * and not overlapping the default BBT markers. > + */ > +static struct nand_ecclayout hwecc4_2048 __initconst = { > + .eccbytes = 40, > + .eccpos = { /* 2 bytes at offset 0 hold the badblock markers */ > + /* 4 bytes at offset 8 hold BBT header */ > + /* 1 byte at offset 12 holds BBT version */ > + /* 8 bytes at offset 16 hold JFFS2 clean markers */ > + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, > + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, > + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, > + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, }, > + .oobfree = { > + {.offset = 16, .length = 8, }, why not offset = 2, length = 22 Won't the badblock marker show if this is used as a BBT? Can JFFS2 not use the same bytes when not a BBT? > + {.offset = 64, }, You can kill the above line. > + }, > +}; > + > +/* An ECC layout for using 4-bit ECC with large-page (4096bytes) flash, > + * storing ten ECC bytes plus the manufacturer's bad block marker byte, > + * and not overlapping the default BBT markers. > + */ > +static struct nand_ecclayout hwecc4_4096 __initconst = { > + .eccbytes = 80, > + .eccpos = { /* 2 bytes at offset 0 hold the badblock markers */ > + /* 4 bytes at offset 8 hold BBT header */ > + /* 1 byte at offset 12 holds BBT version */ > + /* 8 bytes at offset 16 hold JFFS2 clean markers */ > + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, > + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, > + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, > + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, > + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, > + 74, 75, 76, 77, 78, 69, 80, 81, 82, 83, > + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, > + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, }, Can these not be at the end??? i.e. 48-127 > + .oobfree = { > + {.offset = 16, .length = 8, }, > + {.offset = 104, }, > + }, > +}; > > static int __init nand_davinci_probe(struct platform_device *pdev) > { > @@ -689,15 +732,23 @@ static int __init nand_davinci_probe(struct platform_device *pdev) > info->mtd.oobsize - 16; > goto syndrome_done; > } > + if (chunks == 4) { > + info->ecclayout = hwecc4_2048; > + info->ecclayout.oobfree[1].length = info->mtd.oobsize - > + info->ecclayout.oobfree[1].offset; This can be removed, it is already 0. > + info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST; > + goto syndrome_done; > + } > + if (chunks == 8) { > + info->ecclayout = hwecc4_4096; > + info->ecclayout.oobfree[1].length = info->mtd.oobsize - > + info->ecclayout.oobfree[1].offset; > + info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST; > + goto syndrome_done; > + } > > - /* For large page chips we'll be wanting to use a > - * not-yet-implemented mode that reads OOB data > - * before reading the body of the page, to avoid > - * the "infix OOB" model of NAND_ECC_HW_SYNDROME > - * (and preserve manufacturer badblock markings). > - */ > dev_warn(&pdev->dev, "no 4-bit ECC support yet " > - "for large page NAND\n"); > + "for >4K page NAND\n"); > ret = -EIO; > goto err_scan; >
> -----Original Message----- > From: Troy Kisky [mailto:troy.kisky@boundarydevices.com] > Sent: Thursday, June 18, 2009 5:16 PM > To: Paulraj, Sandeep > Cc: davinci-linux-open-source@linux.davincidsp.com; linux- > mtd@lists.infradead.org; dwmw2@infradead.org; tglx@linutronix.de; > akpm@linux-foundation.org > Subject: Re: [PATCH v2 3/3] Add 4-bit ECC support for large page NAND > chips on Davinci > > s-paulraj@ti.com wrote: > > From: Sandeep Paulraj <s-paulraj@ti.com> > > > > The patch applies to linux-mtd GIT tree > > > > This patch adds 4-bit ECC support for large page NAND chips using the > new ECC > > mode NAND_ECC_HW_OOB_FIRST. The platform data from board-dm355-evm has > been > > adjusted to use this mode. > > > > The patches have been verified on DM355 device with 2K and 4K page size > > Micron devices using mtd-tests. > > Error correction upto 4-bits has also been verified using > > nandwrite/nanddump utilities. > > > > Reviewed-by: David Brownell <dbrownell@users.sourceforge.net> > > Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com> > > Signed-off-by: Sneha Narnakaje <nsnehaprabha@ti.com> > > --- > > drivers/mtd/nand/davinci_nand.c | 65 > ++++++++++++++++++++++++++++++++++---- > > 1 files changed, 58 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/mtd/nand/davinci_nand.c > b/drivers/mtd/nand/davinci_nand.c > > index ba6940d..2ff0712 100644 > > --- a/drivers/mtd/nand/davinci_nand.c > > +++ b/drivers/mtd/nand/davinci_nand.c > > @@ -500,6 +500,49 @@ static struct nand_ecclayout hwecc4_small > __initconst = { > > }, > > }; > > > > +/* An ECC layout for using 4-bit ECC with large-page (2048bytes) flash, > > + * storing ten ECC bytes plus the manufacturer's bad block marker byte, > > + * and not overlapping the default BBT markers. > > + */ > > +static struct nand_ecclayout hwecc4_2048 __initconst = { > > + .eccbytes = 40, > > + .eccpos = { /* 2 bytes at offset 0 hold the badblock markers */ > > + /* 4 bytes at offset 8 hold BBT header */ > > + /* 1 byte at offset 12 holds BBT version */ > > + /* 8 bytes at offset 16 hold JFFS2 clean markers */ > > + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, > > + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, > > + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, > > + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, }, > > + .oobfree = { > > + {.offset = 16, .length = 8, }, > > why not offset = 2, length = 22 > Won't the badblock marker show if this is used as a BBT? > Can JFFS2 not use the same bytes when not a BBT? [Sandeep] We do not want any overlap between the ECC bytes and any of the above so just reserving as explained above and using the last 40 bytes. > > > + {.offset = 64, }, > > You can kill the above line. > > > + }, > > +}; > > + > > +/* An ECC layout for using 4-bit ECC with large-page (4096bytes) flash, > > + * storing ten ECC bytes plus the manufacturer's bad block marker byte, > > + * and not overlapping the default BBT markers. > > + */ > > +static struct nand_ecclayout hwecc4_4096 __initconst = { > > + .eccbytes = 80, > > + .eccpos = { /* 2 bytes at offset 0 hold the badblock markers */ > > + /* 4 bytes at offset 8 hold BBT header */ > > + /* 1 byte at offset 12 holds BBT version */ > > + /* 8 bytes at offset 16 hold JFFS2 clean markers */ > > + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, > > + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, > > + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, > > + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, > > + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, > > + 74, 75, 76, 77, 78, 69, 80, 81, 82, 83, > > + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, > > + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, }, > > Can these not be at the end??? i.e. 48-127 [Sandeep] I am just using the first available free bytes. To answer your question, yes it can be at the end but I do not see any reason why it has to be at the end Any reason why you insist that it should be at the end. > > > + .oobfree = { > > + {.offset = 16, .length = 8, }, > > + {.offset = 104, }, > > + }, > > +}; > > > > static int __init nand_davinci_probe(struct platform_device *pdev) > > { > > @@ -689,15 +732,23 @@ static int __init nand_davinci_probe(struct > platform_device *pdev) > > info->mtd.oobsize - 16; > > goto syndrome_done; > > } > > + if (chunks == 4) { > > + info->ecclayout = hwecc4_2048; > > + info->ecclayout.oobfree[1].length = info->mtd.oobsize - > > + info->ecclayout.oobfree[1].offset; > > This can be removed, it is already 0. > > > + info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST; > > + goto syndrome_done; > > + } > > + if (chunks == 8) { > > + info->ecclayout = hwecc4_4096; > > + info->ecclayout.oobfree[1].length = info->mtd.oobsize - > > + info->ecclayout.oobfree[1].offset; > > + info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST; > > + goto syndrome_done; > > + } > > > > - /* For large page chips we'll be wanting to use a > > - * not-yet-implemented mode that reads OOB data > > - * before reading the body of the page, to avoid > > - * the "infix OOB" model of NAND_ECC_HW_SYNDROME > > - * (and preserve manufacturer badblock markings). > > - */ > > dev_warn(&pdev->dev, "no 4-bit ECC support yet " > > - "for large page NAND\n"); > > + "for >4K page NAND\n"); > > ret = -EIO; > > goto err_scan; > > >
Paulraj, Sandeep wrote: > >> -----Original Message----- >> From: Troy Kisky [mailto:troy.kisky@boundarydevices.com] >> Sent: Thursday, June 18, 2009 5:16 PM >> To: Paulraj, Sandeep >> Cc: davinci-linux-open-source@linux.davincidsp.com; linux- >> mtd@lists.infradead.org; dwmw2@infradead.org; tglx@linutronix.de; >> akpm@linux-foundation.org >> Subject: Re: [PATCH v2 3/3] Add 4-bit ECC support for large page NAND >> chips on Davinci >> >> s-paulraj@ti.com wrote: >>> From: Sandeep Paulraj <s-paulraj@ti.com> >>> >>> The patch applies to linux-mtd GIT tree >>> >>> This patch adds 4-bit ECC support for large page NAND chips using the >> new ECC >>> mode NAND_ECC_HW_OOB_FIRST. The platform data from board-dm355-evm has >> been >>> adjusted to use this mode. >>> >>> The patches have been verified on DM355 device with 2K and 4K page size >>> Micron devices using mtd-tests. >>> Error correction upto 4-bits has also been verified using >>> nandwrite/nanddump utilities. >>> >>> Reviewed-by: David Brownell <dbrownell@users.sourceforge.net> >>> Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com> >>> Signed-off-by: Sneha Narnakaje <nsnehaprabha@ti.com> >>> --- >>> drivers/mtd/nand/davinci_nand.c | 65 >> ++++++++++++++++++++++++++++++++++---- >>> 1 files changed, 58 insertions(+), 7 deletions(-) >>> >>> diff --git a/drivers/mtd/nand/davinci_nand.c >> b/drivers/mtd/nand/davinci_nand.c >>> index ba6940d..2ff0712 100644 >>> --- a/drivers/mtd/nand/davinci_nand.c >>> +++ b/drivers/mtd/nand/davinci_nand.c >>> @@ -500,6 +500,49 @@ static struct nand_ecclayout hwecc4_small >> __initconst = { >>> }, >>> }; >>> >>> +/* An ECC layout for using 4-bit ECC with large-page (2048bytes) flash, >>> + * storing ten ECC bytes plus the manufacturer's bad block marker byte, >>> + * and not overlapping the default BBT markers. >>> + */ >>> +static struct nand_ecclayout hwecc4_2048 __initconst = { >>> + .eccbytes = 40, >>> + .eccpos = { /* 2 bytes at offset 0 hold the badblock markers */ >>> + /* 4 bytes at offset 8 hold BBT header */ >>> + /* 1 byte at offset 12 holds BBT version */ >>> + /* 8 bytes at offset 16 hold JFFS2 clean markers */ >>> + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, >>> + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, >>> + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, >>> + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, }, >>> + .oobfree = { >>> + {.offset = 16, .length = 8, }, >> why not offset = 2, length = 22 >> Won't the badblock marker show if this is used as a BBT? >> Can JFFS2 not use the same bytes when not a BBT? > [Sandeep] We do not want any overlap between the ECC bytes and any of the above so just reserving as explained above and using the last 40 bytes. You mean that you want no overlap between JFFS2 and BBT header. Can you explain this need or point me to a document that will explain it? Thanks... >>> + {.offset = 64, }, >> You can kill the above line. >> >>> + }, >>> +}; >>> + >>> +/* An ECC layout for using 4-bit ECC with large-page (4096bytes) flash, >>> + * storing ten ECC bytes plus the manufacturer's bad block marker byte, >>> + * and not overlapping the default BBT markers. >>> + */ >>> +static struct nand_ecclayout hwecc4_4096 __initconst = { >>> + .eccbytes = 80, >>> + .eccpos = { /* 2 bytes at offset 0 hold the badblock markers */ >>> + /* 4 bytes at offset 8 hold BBT header */ >>> + /* 1 byte at offset 12 holds BBT version */ >>> + /* 8 bytes at offset 16 hold JFFS2 clean markers */ >>> + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, >>> + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, >>> + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, >>> + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, >>> + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, >>> + 74, 75, 76, 77, 78, 69, 80, 81, 82, 83, >>> + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, >>> + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, }, >> Can these not be at the end??? i.e. 48-127 > [Sandeep] I am just using the first available free bytes. > To answer your question, yes it can be at the end but I do not see any reason why it has to be at the end > Any reason why you insist that it should be at the end. Well, for one, it is nice to have oobfree contiguous. But mainly, I hope to eventually use a default layout which will have the oob data at the end when 0 holds the badblock marker. > >>> + .oobfree = { >>> + {.offset = 16, .length = 8, }, >>> + {.offset = 104, }, Then, the above line can disappear if the ecc is at the end. >>> + }, >>> +}; >>> >>> static int __init nand_davinci_probe(struct platform_device *pdev) >>> { >>> @@ -689,15 +732,23 @@ static int __init nand_davinci_probe(struct >> platform_device *pdev) >>> info->mtd.oobsize - 16; >>> goto syndrome_done; >>> } >>> + if (chunks == 4) { >>> + info->ecclayout = hwecc4_2048; >>> + info->ecclayout.oobfree[1].length = info->mtd.oobsize - >>> + info->ecclayout.oobfree[1].offset; >> This can be removed, it is already 0. >> >>> + info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST; >>> + goto syndrome_done; >>> + } >>> + if (chunks == 8) { >>> + info->ecclayout = hwecc4_4096; >>> + info->ecclayout.oobfree[1].length = info->mtd.oobsize - >>> + info->ecclayout.oobfree[1].offset; Along with this line. >>> + info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST; >>> + goto syndrome_done; >>> + } >>> >>> - /* For large page chips we'll be wanting to use a >>> - * not-yet-implemented mode that reads OOB data >>> - * before reading the body of the page, to avoid >>> - * the "infix OOB" model of NAND_ECC_HW_SYNDROME >>> - * (and preserve manufacturer badblock markings). >>> - */ >>> dev_warn(&pdev->dev, "no 4-bit ECC support yet " >>> - "for large page NAND\n"); >>> + "for >4K page NAND\n"); >>> ret = -EIO; >>> goto err_scan; >>> > > > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ >
On Thursday 18 June 2009, Troy Kisky wrote: > > To answer your question, yes it can be at the end but I do not > > see any reason why it has to be at the end > > Any reason why you insist that it should be at the end. > > Well, for one, it is nice to have oobfree contiguous. But mainly, I hope > to eventually use a default layout which will have the oob data at the > end when 0 holds the badblock marker. Also, I thought the agreement from previous discussions was to put it at the end, keeping a contiguous oobfree area ... which is why the OpenOCD [1] DaVinci NAND driver puts it at the end in the standard HWECC4 mode (not HWECC4_INFIX): - with 2K pages ... ECC in bytes 24..63 inclusive. - with 4K pages ... ECC in bytes 48..127 inclusive. Now, the 0.2.0 release for that hasn't frozen yet, but the idea was to have it match what Linux does. So if the plans for Linux change, make sure I know so I can submit a patch ... though I'd rather see the previous agreement kept. - Dave [1] http://openocd.berlios.de/doc/html/index.html
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index ba6940d..2ff0712 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -500,6 +500,49 @@ static struct nand_ecclayout hwecc4_small __initconst = { }, }; +/* An ECC layout for using 4-bit ECC with large-page (2048bytes) flash, + * storing ten ECC bytes plus the manufacturer's bad block marker byte, + * and not overlapping the default BBT markers. + */ +static struct nand_ecclayout hwecc4_2048 __initconst = { + .eccbytes = 40, + .eccpos = { /* 2 bytes at offset 0 hold the badblock markers */ + /* 4 bytes at offset 8 hold BBT header */ + /* 1 byte at offset 12 holds BBT version */ + /* 8 bytes at offset 16 hold JFFS2 clean markers */ + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, }, + .oobfree = { + {.offset = 16, .length = 8, }, + {.offset = 64, }, + }, +}; + +/* An ECC layout for using 4-bit ECC with large-page (4096bytes) flash, + * storing ten ECC bytes plus the manufacturer's bad block marker byte, + * and not overlapping the default BBT markers. + */ +static struct nand_ecclayout hwecc4_4096 __initconst = { + .eccbytes = 80, + .eccpos = { /* 2 bytes at offset 0 hold the badblock markers */ + /* 4 bytes at offset 8 hold BBT header */ + /* 1 byte at offset 12 holds BBT version */ + /* 8 bytes at offset 16 hold JFFS2 clean markers */ + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 69, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, }, + .oobfree = { + {.offset = 16, .length = 8, }, + {.offset = 104, }, + }, +}; static int __init nand_davinci_probe(struct platform_device *pdev) { @@ -689,15 +732,23 @@ static int __init nand_davinci_probe(struct platform_device *pdev) info->mtd.oobsize - 16; goto syndrome_done; } + if (chunks == 4) { + info->ecclayout = hwecc4_2048; + info->ecclayout.oobfree[1].length = info->mtd.oobsize - + info->ecclayout.oobfree[1].offset; + info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST; + goto syndrome_done; + } + if (chunks == 8) { + info->ecclayout = hwecc4_4096; + info->ecclayout.oobfree[1].length = info->mtd.oobsize - + info->ecclayout.oobfree[1].offset; + info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST; + goto syndrome_done; + } - /* For large page chips we'll be wanting to use a - * not-yet-implemented mode that reads OOB data - * before reading the body of the page, to avoid - * the "infix OOB" model of NAND_ECC_HW_SYNDROME - * (and preserve manufacturer badblock markings). - */ dev_warn(&pdev->dev, "no 4-bit ECC support yet " - "for large page NAND\n"); + "for >4K page NAND\n"); ret = -EIO; goto err_scan;