aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorSneha Narnakaje <nsnehaprabha@ti.com>2009-09-18 15:51:48 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-09-19 14:16:57 -0400
commitf12a9473283e68ae708e9ada37cb352ea2652397 (patch)
treed0886b69596a6031ac705352daa38a13fa0dcc06 /drivers/mtd
parent6e0cb135b3f3713b95ea41a11155e83a8c70f5f8 (diff)
mtd: nand: DaVinci: Add 4-bit ECC support for large page NAND chips
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 2KiB-page Micron devices using mtd-tests and JFFS2. Error correction up to 4 bits has also been verified using nandwrite/nanddump utilities. Reviewed-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Sneha Narnakaje <nsnehaprabha@ti.com> Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Troy Kisky <troy.kisky@boundarydevices.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/davinci_nand.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 0fad6487e6f4..f13f5b9afaf7 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -348,6 +348,12 @@ compare:
348 if (!(syndrome[0] | syndrome[1] | syndrome[2] | syndrome[3])) 348 if (!(syndrome[0] | syndrome[1] | syndrome[2] | syndrome[3]))
349 return 0; 349 return 0;
350 350
351 /*
352 * Clear any previous address calculation by doing a dummy read of an
353 * error address register.
354 */
355 davinci_nand_readl(info, NAND_ERR_ADD1_OFFSET);
356
351 /* Start address calculation, and wait for it to complete. 357 /* Start address calculation, and wait for it to complete.
352 * We _could_ start reading more data while this is working, 358 * We _could_ start reading more data while this is working,
353 * to speed up the overall page read. 359 * to speed up the overall page read.
@@ -359,8 +365,10 @@ compare:
359 365
360 switch ((fsr >> 8) & 0x0f) { 366 switch ((fsr >> 8) & 0x0f) {
361 case 0: /* no error, should not happen */ 367 case 0: /* no error, should not happen */
368 davinci_nand_readl(info, NAND_ERR_ERRVAL1_OFFSET);
362 return 0; 369 return 0;
363 case 1: /* five or more errors detected */ 370 case 1: /* five or more errors detected */
371 davinci_nand_readl(info, NAND_ERR_ERRVAL1_OFFSET);
364 return -EIO; 372 return -EIO;
365 case 2: /* error addresses computed */ 373 case 2: /* error addresses computed */
366 case 3: 374 case 3:
@@ -500,6 +508,26 @@ static struct nand_ecclayout hwecc4_small __initconst = {
500 }, 508 },
501}; 509};
502 510
511/* An ECC layout for using 4-bit ECC with large-page (2048bytes) flash,
512 * storing ten ECC bytes plus the manufacturer's bad block marker byte,
513 * and not overlapping the default BBT markers.
514 */
515static struct nand_ecclayout hwecc4_2048 __initconst = {
516 .eccbytes = 40,
517 .eccpos = {
518 /* at the end of spare sector */
519 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
520 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
521 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
522 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
523 },
524 .oobfree = {
525 /* 2 bytes at offset 0 hold manufacturer badblock markers */
526 {.offset = 2, .length = 22, },
527 /* 5 bytes at offset 8 hold BBT markers */
528 /* 8 bytes at offset 16 hold JFFS2 clean markers */
529 },
530};
503 531
504static int __init nand_davinci_probe(struct platform_device *pdev) 532static int __init nand_davinci_probe(struct platform_device *pdev)
505{ 533{
@@ -690,15 +718,20 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
690 info->mtd.oobsize - 16; 718 info->mtd.oobsize - 16;
691 goto syndrome_done; 719 goto syndrome_done;
692 } 720 }
721 if (chunks == 4) {
722 info->ecclayout = hwecc4_2048;
723 info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST;
724 goto syndrome_done;
725 }
693 726
694 /* For large page chips we'll be wanting to use a 727 /* 4KiB page chips are not yet supported. The eccpos from
695 * not-yet-implemented mode that reads OOB data 728 * nand_ecclayout cannot hold 80 bytes and change to eccpos[]
696 * before reading the body of the page, to avoid 729 * breaks userspace ioctl interface with mtd-utils. Once we
697 * the "infix OOB" model of NAND_ECC_HW_SYNDROME 730 * resolve this issue, NAND_ECC_HW_OOB_FIRST mode can be used
698 * (and preserve manufacturer badblock markings). 731 * for the 4KiB page chips.
699 */ 732 */
700 dev_warn(&pdev->dev, "no 4-bit ECC support yet " 733 dev_warn(&pdev->dev, "no 4-bit ECC support yet "
701 "for large page NAND\n"); 734 "for 4KiB-page NAND\n");
702 ret = -EIO; 735 ret = -EIO;
703 goto err_scan; 736 goto err_scan;
704 737