diff options
| author | Sneha Narnakaje <nsnehaprabha@ti.com> | 2009-09-18 15:51:48 -0400 |
|---|---|---|
| committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-09-19 14:16:57 -0400 |
| commit | f12a9473283e68ae708e9ada37cb352ea2652397 (patch) | |
| tree | d0886b69596a6031ac705352daa38a13fa0dcc06 /drivers/mtd | |
| parent | 6e0cb135b3f3713b95ea41a11155e83a8c70f5f8 (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.c | 45 |
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 | */ | ||
| 515 | static 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 | ||
| 504 | static int __init nand_davinci_probe(struct platform_device *pdev) | 532 | static 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 | ||
