This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x NAND flash ECC discreptancy between u-boot and kernel.

Other Parts Discussed in Thread: AM3352

Hi,

We have an issue with NAND flash corruption we are working to resolve. The processor we are using is an AM3352, in a custom board. We are on PSP 04.06.00.08. Our NAND flash requires at least 4 bits of ECC per 516 bytes + 8 bytes for parity data.

PSP 04.06.00.08 follows this procedure for board bootup:

  • ROM boot loader reads MLO using BCH8 (8 bit ECC).
  • MLO is initialized using BCH8 (8 bit ECC).
  • MLO reads u-boot in BCH8 (8 bit ECC).
  • U-boot switches over to Hamming (1 bit ECC).
  • U-boot reads kernel in Hamming (1 bit ECC).
  • Kernel initializes in Hamming (1 bit ECC).
  • Kernel accesses root file system in hamming (1 bit ECC).

To address the flash corruption issue (4 ECC bits required per 516 bytes), we are attempting to change the kernel over to BCH8 (from Hamming to get adequate ECC bit count).

So, our updated boot sequence would be this:

  • ROM boot loader reads MLO using BCH8 (8 bit ECC).
  • MLO is initialized using BCH8 (8 bit ECC).
  • MLO reads u-boot in BCH8 (8 bit ECC). *** change here, u-boot does not switch over to Hamming. ***
  • U-boot reads kernel in BCH8 (8 bit ECC). *** Changed from 1 bit Hamming ***
  • Kernel initializes in BCH8 (8 bit ECC). *** Changed from 1 bit Hamming ***
  • Kernel accesses root file system in BCH8 (8 bit ECC). *** Changed from 1 bit Hamming ***

After flipping the kernel to BCH8, Linux displays many ECC errors for file system images flashed from u-boot. It appears that the root cause of the problem is ECC layout. Both U-BOOT and Kernel use HW ECC BCH8 mode to read/write partitions. However, it seems there is mismatch between U-Boot and Kernel in the source code in used ECC layout.

U-boot uses 56 bytes for every 2K block:

#define GPMC_NAND_HW_BCH8_ECC_LAYOUT {\

         .eccbytes = 56,\

         .eccpos = { 2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\

                    16, 17, 18, 19, 20, 21, 22, 23, 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},\

         .oobfree = {\

                 {.offset = 58,\

                  .length = 6 } }

 

While Linux Kernel uses mixed size constants (14*4 = 56 and 13*4 = 52):

omap2.c:

#define OMAP_BCH8_ECC_SECT_BYTES        14

elm.c/elm.h

#define BCH8_ECC_BYTES                  (512)

#define BCH8_ECC_OOB_BYTES              (13)

#define BCH_MAX_ECC_BYTES_PER_SECTOR    (28)

Is there a recommened way to fix this?