]> git.sur5r.net Git - u-boot/commitdiff
mtd: nand: omap: fix ecc-layout for HAM1 ecc-scheme
authorpekon gupta <pekon@ti.com>
Thu, 5 Dec 2013 12:24:21 +0000 (17:54 +0530)
committerScott Wood <scottwood@freescale.com>
Tue, 17 Dec 2013 23:28:41 +0000 (17:28 -0600)
As per OMAP3530 TRM referenced below [1]

For large-page NAND, ROM code expects following ecc-layout for HAM1 ecc-scheme
 - OOB[1] (offset of 1 *byte* from start of OOB) for x8 NAND device
 - OOB[2] (offset of 1 *word* from start of OOB) for x16 NAND device

Thus ecc-layout expected by ROM code for HAM1 ecc-scheme is:
 *for x8 NAND Device*
 +--------+---------+---------+---------+---------+---------+---------+
 | xxxx   | ECC[A0] | ECC[A1] | ECC[A2] | ECC[B0] | ECC[B1] | ECC[B2] | ...
 +--------+---------+---------+---------+---------+---------+---------+

 *for x16 NAND Device*
 +--------+--------+---------+---------+---------+---------+---------+---------+
 | xxxxx  | xxxxx  | ECC[A0] | ECC[A1] | ECC[A2] | ECC[B0] | ECC[B1] | ECC[B2] |
 +--------+--------+---------+---------+---------+---------+---------+---------+

This patch fixes ecc-layout *only* for HAM1, as required by ROM-code
For other ecc-schemes like (BCH8) ecc-layout is same for x8 or x16 devices.

[1] OMAP3530: http://www.ti.com/product/omap3530
    TRM: http://www.ti.com/litv/pdf/spruf98x
Chapter-25: Initialization Sub-topic: Memory Booting
Section: 25.4.7.4 NAND
Figure 25-19. ECC Locations in NAND Spare Areas

Reported-by: Stefan Roese <sr@denx.de>
Signed-off-by: Pekon Gupta <pekon@ti.com>
Tested-by: Stefan Roese <sr@denx.de>
drivers/mtd/nand/omap_gpmc.c

index 5e7e6b337544f3f7543baf7e8c1bcee9242a00e4..23a961c9d4efcd49d8062d7d7f5c6f0c5ec20fff 100644 (file)
@@ -798,8 +798,12 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
                nand->ecc.calculate     = omap_calculate_ecc;
                /* define ecc-layout */
                ecclayout->eccbytes     = nand->ecc.bytes * eccsteps;
-               for (i = 0; i < ecclayout->eccbytes; i++)
-                       ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
+               for (i = 0; i < ecclayout->eccbytes; i++) {
+                       if (nand->options & NAND_BUSWIDTH_16)
+                               ecclayout->eccpos[i] = i + 2;
+                       else
+                               ecclayout->eccpos[i] = i + 1;
+               }
                ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
                ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
                                                BADBLOCK_MARKER_LENGTH;