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 Tool or nandlib does not support BCH 16-bit ECC

Other Parts Discussed in Thread: AM3354, SYSCONFIG, AM3352

I have a custom board with AM335x connected to a NAND flash that has page size of 4Kbyte and 224 bytes spare area.

Reading in the AM335x documentation regarding booting from NAND, the boot will use 16bit BCH ECC.

However, there is no support in either NAND Flash Tool or nandlib to turn on BCH 16bit. I am currently trying to add this, but are having trouble to set up everything correctly.

For example, the NAND Page Mapping documentation talks about eccsize1 and eccsize0 being nibbles, but the register GPMC_ECC_SIZE_CONFIG states bytes.

Also, the spare mapping expected by the NAND boot loader is hard to match with the described page mappings found under GPMC documentation (2 bytes + ECC sector 0 + ECC sector 1...ECC sector 8)

Have anyone succeeded in boot with NAND that has a large spare area using BCH 16-bit? Any example code from TI?

Or am I completely wrong in my assumptions?

Any help is appreciated!

  • Just an update, I have been able to modify NAND Flash Tool to generate correct BCH 16-bit ECC sufficient for the boot loader to accept the boot image. Which is good. But I can still not verify, meaning the read NAND functions do work as they should.

  • Karlsson,

    I believe why this is not attempted and not yet part of the nand driver in linux is probably because none of the Evaluation modules of TI SoCs comes with 4K page NAND. Infact most of the EVMs available these days use SLC NAND with 2K page size.

  • hi Karlsson,

    I hope you got sometime to test your NAND flash utility with BCH-16 ECC..

    Is it possible for you to share your work with us, we would like to use it and enhance it further .

    with regards, pekon

  • Ulf,

    can you share your changes to the tools so others may benefit from your insight?

    Kind regards
    Tiemen

  • Ulf,

    Can you please share your modifications so others can take advantage of the same. If you have been able to modify to the OOB so the ROM bootcode actually boots, then that is a huge step in the right direction.

    Sharing the details of your solution would  benefit many.

    Kind regards

    Tiemen

  • We are also trying to get a 4k page/224 byte oob flash to boot on the am335x processor.  So, my understanding is this requires BCH16, but there is currently no way to write an image (short of adding support to nandflashwriter as Ulf did)?  Are there any other workarounds?

    We can boot Linux from SD card, can we write a bootable image from there or does the Linux kernel have the same issues? 

    It seems like u-boot has some support for BCH16 but it is disabled.  Are there any plans or patches to support BCH16 from u-boot?  If I just ignore the error (in source) I get when running "hwecc 3" it seems to set all the ECC bytes to 0.  Is this a limitation in the processor hardware?

    Ulf, I would also like to see your modifications to make this work if you're able to post them.

    Regards,

    ADam

  • Adam,

    The requirement of BCH-16 on 4K/224b NAND comes from the fact that ROM selects the ECC-Type based on max OOB size of flash-device it detects on board.

    However, ECC-Type is user-configurable on UBoot and Kernel.So you can have different ECC-Types (HAM-1/BCH-8) used for ROM, U-BOOT and Kernel.


    Adam Boggs1 said:

    We can boot Linux from SD card, can we write a bootable image from there or does the Linux kernel have the same issues? 

    To be able to boot 'kernel' from NAND, using existing code.

    (Step-1): Build the SD-card UBoot image with NAND ECC options of either BCH-8 or HAM-1


    (step-2): At UBoot prompt change the ECC-type to one based for which UBoot was build in 'step-1' 

    Usage: UBOOT# nandecc [sw | hw <hw_type>] 
    • sw - Set software ECC for NAND 
    • hw <hw_type> - Set hardware ECC for NAND
    • 0 for Hamming code
    • 2 for bch8

    (step-3): Flash the kernel and File-system on NAND, using above specified ECC-type.

    (Note): If you are flashing the file-system to NAND, then make sure that File-system is flashed using the ECC-type for which the kernel is build (which the kernel can understand).

    ECC-types selection can be updated in following files:

    (a $KERNEL/drivers/mtd/nand/omap2.c:   omap_nand_probe():     pdata->ecc_opt   = OMAP_ECC_BCH8_CODE_HW;

    (b) $KERNEL/arch/arm/mach-omap2/board-flash.cboard_nand_init():    if (cpu_is_ti81xx()) { board_nand_data.ecc_opt = OMAP_ECC_BCH8_CODE_HW; }

    with regards, pekon

  • Hi Pekon,

    Thanks for your reply!  It sounds like the only thing that HAS to be written with BCH16 is MLO, then.  I'm assuming MLO should be able to load u-boot with BCH8 and the rest is easy as you point out.

    But the question still remains... are there any tools (standalone, linux, u-boot patches, etc) which will allow us to flash MLO with BCH16?  Since we can boot the kernel off SD, can we flash MLO to NAND using the kernel and mtd-tools with BCH16?

    Is there a way to force RBL to assume BCH8 regardless of OOB size? (I2CNAND maybe?)

    Just trying to think of a workaround.  I'm a bit surprised the ROM bootloader supports BCH16 but u-boot doesn't.

    Thanks again,

    -Adam

  • Hi Adam,

    Adam Boggs1 said:

    It sounds like the only thing that HAS to be written with BCH16 is MLO, then.  I'm assuming MLO should be able to load u-boot with BCH8 and the rest is easy as you point out.

    If you are using SD card for loading U-boot,

    then you have to load both first-stage(MLO) and second-stage(u-boot.bin.sd) from SD card itself.

    You _CANNOT_ load first-stage(MLO) from SD, and second-stage(u-boot.bin.nand) from NAND.

    Likewise, you can load both first-stage(uboot.min.nand) and second-stage(u-boot.bin.nand) from NAND, provided they are flashed with BCH16, using some third-party tool.

    So in summary,

    (a) Both stages of u-boot should be loaded from same source | device.

    (b) If both stages of u-boot are loaded from 4K/224B NAND, then both u-boot stages need to be flashed using BCH-16 utility.

    Adam Boggs1 said:

    But the question still remains... are there any tools (standalone, linux, u-boot patches, etc) which will allow us to flash MLO with BCH16?  Since we can boot the kernel off SD, can we flash MLO to NAND using the kernel and mtd-tools with BCH16?

    Currently there is no support for BCH-16 in either kernel or u-boot. Neither i could find that in 'mtd-linux' release.

    However, as you need to just flash both the stages of U-boot using BCH-16, so you can modify flashing-tool utility to support BCH-16.

    And then select some other ECC-type option for loading kernel and file-system.

    Adam Boggs1 said:

    Is there a way to force RBL to assume BCH8 regardless of OOB size? (I2CNAND maybe?)

    Just trying to think of a workaround.  I'm a bit surprised the ROM bootloader supports BCH16 but u-boot doesn't.

    Currently there is no way to modify the choice of ECC-type used in ROM.

    ROM code is generic code developed for larger set of devices, whereas  features in U-boot and kernel may be supported based on individual platforms.

    One other thing you can look at is SPI-based NAND, which may not have this constrain, as device would interact via SPI interface.

    Both SPI based NAND, and Raw-NAND are recognized as MTD devices, so using SPI based NAND should not affect ur linux setup.

    with regards, pekon

  • I'm in the process of adding BCH16 support to U-Boot (mainline) for our project. Atm I'm not yet able to boot from NAND, but I can use it in U-Boot itself. Is there anyway I can verify the generated ECC ? Are there tools/patches/etc available for this?

    I will submit a patch to mainline, when I'm sure everything works properly.

  • Pekon,

    You could also use NANDI2C, right? Since this is supported by the sysboot pins, you could set BCH8 and since the ROM code won't look fo the size of the OOB to determine the BCH, but will actually read it from the NANDI2C, the bootstrap should work correctly with BCH8.

    Kind regards

    Tiemen

  • I've just put up a patch for 16-bit BCH support in StarterWare if that helps anyone:

    http://e2e.ti.com/support/dsp/sitara_arm174_microprocessors/f/791/t/241321.aspx

    I can now boot an AM3354 from a 4KiB/page NAND flash with ECC turned on.

    Enjoy!

    Jonathan

  • I submitted my patch for BCH16 and NAND 4k page size to U-Boot. It's probably not compatible with the TI tree.

    http://patchwork.ozlabs.org/patch/216188/

  • Hi Jordy van Wolferen1, I have applied your patch with my Mircon 29F16G08CBA Chip 2GiB, Page size:4096, OOB size: 224 and 1 MiB erase size, u-boot able to recognize as the chip(ONFI detection). but still cannot boot MLO from nand, and reading from Uboot of my freshly written data, will report "ECC: uncorrectable". any ideas?

  • Hi Yiling,

    (1) Hope you have selected the BCH16 ECC scheme before flashing the U-Boot & MLO using 'nandecc' command. (BCH8_ECC is selected by default).

    (2) Also, you may check yourself if the ECC is flashed correctly by using following command which will show how your flashed OOB area looks.

    UBOOT#> nand dump.oob <offset>

    with regards, pekon

  • Hi Pekon,

    1. nandecc is missing from  version 2013.01 and the patch provided is compliant with 2013.01 u-boot version.

    2. nand dump.oob still gives 58 byte which is still BCH8, seems the patch not working with my situation.

    Thanks.

     

  • How do one select "BCH16 ECC scheme" ?

  • We are also trying to boot an AM335X part from a x8 4Gib (512MB) (M29F4G08ABAEA) that has 4k pages. I can read/write from linux, but (as stated above) the ROM bootloader uses the BCH16 ECC scheme. Obviously someone at TI has implemented code to read/write flash in a manner consistent with the ROM bootloader, and if they could share that code (or at least part of it) that would be much appreciated.

    I have tried back-porting Jordy Van Wooferen1's patch to the PSP 04.06.00.08 u-boot (that is our baseline), but have not been able to get it to work (it compiles, but no luck in the actually working dept, same errors as Cao Yiling is seeing.

  • On U-Boot

    There is no BCH16 support so you have to port the 'Jordy Van Wooferen1's patch' to mainline to get it working.

    On Linux,

    I could just get BCH16 ECC scheme working for an older linux kernel-2.6.37. Though BCH16 ECC support is planned on AM335x, but cannot commit now, as the forward porting of mentioned patches require sufficient testing.

    Reference from http://arago-project.org/git/projects/linux-omap3.git

     

    with regards, pekon

  • Cao Yiling said:

    How do one select "BCH16 ECC scheme" ?

    I havn't seen the latest U-Boot, so don't know if 'nandecc' is deprecated. But still u-boot can be build with BCH16 ECC selected as default, and then mentioned patch should work.

    with regards, pekon

  • I can confirm the u-boot patch + some other mods are working prefectly for my nand chip,(can boot from NAND by boot ROM), due to my nand chip requires 1MiB erase size, I had to modify the partition offset address in uboot and kernel. (otherwise u-boot or kernel will not erase the partition)

    Currently I still have problem with `flash_erase` utility within linux with my oob 224 devices, as it reports "... ibmtd: error!: MEMERASE64 ioctl failed for eraseblock..." I am still investigating and hopefully can make a guide for others when all done. 

  • Cao

    Did you have to make changes to the patchset to get BCH16 working? I am still struggling with this. I am not having much luck getting the BCH16 ECC to work.

    cheers

    /Tim

  • Hi, the patch works only after I put some more changes with "include/configs/am335x_evm.h" and diff is below :

    after this boot up is like a charm, BUT I still have problem with kernel correctly read/write with a specific nand Micron 29F16G08CBACA?

    Are you able to share your nand chip model, in order to allow me investigate?

    368 368 #define CONFIG_SPL_NAND_DRIVERS  
    369 369 #define CONFIG_SPL_NAND_ECC  
    370 370 #define CONFIG_SYS_NAND_5_ADDR_CYCLE  
    371   -#define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \  
    372   - CONFIG_SYS_NAND_PAGE_SIZE)  
    373   -#define CONFIG_SYS_NAND_PAGE_SIZE 2048  
    374   -#define CONFIG_SYS_NAND_OOBSIZE 64  
    375   -#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024)  
    376   -#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS  
    377   -#define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, \  
    378   - 10, 11, 12, 13, 14, 15, 16, 17, \  
    379   - 18, 19, 20, 21, 22, 23, 24, 25, \  
    380   - 26, 27, 28, 29, 30, 31, 32, 33, \  
    381   - 34, 35, 36, 37, 38, 39, 40, 41, \  
    382   - 42, 43, 44, 45, 46, 47, 48, 49, \  
    383   - 50, 51, 52, 53, 54, 55, 56, 57, }  
    384 371  
    385   -#define CONFIG_SYS_NAND_ECCSIZE 512  
    386   -#define CONFIG_SYS_NAND_ECCBYTES 14  
    387 372  
    388   -#define CONFIG_SYS_NAND_ECCSTEPS 4  
      373 +/*#define CONFIG_SYS_NAND_PAGE_SIZE 2048  
      374 +#define CONFIG_SYS_NAND_OOBSIZE 64  
      375 +#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024)  
      376 +#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS  
      377 +#define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, \  
      378 + 10, 11, 12, 13, 14, 15, 16, 17, \  
      379 + 18, 19, 20, 21, 22, 23, 24, 25, \  
      380 + 26, 27, 28, 29, 30, 31, 32, 33, \  
      381 + 34, 35, 36, 37, 38, 39, 40, 41, \  
      382 + 42, 43, 44, 45, 46, 47, 48, 49, \  
      383 + 50, 51, 52, 53, 54, 55, 56, 57, }  
      384 +*/  
      385 +  
      386 +#define CONFIG_SYS_NAND_PAGE_SIZE 4096  
      387 +#define CONFIG_SYS_NAND_OOBSIZE 224  
      388 +#define CONFIG_SYS_NAND_BLOCK_SIZE (1024*1024)  
      389 +#define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / CONFIG_SYS_NAND_PAGE_SIZE)  
      390 +#define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\  
      391 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\  
      392 + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\  
      393 + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\  
      394 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\  
      395 + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,\  
      396 + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,\  
      397 + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,\  
      398 + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,\  
      399 + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,\  
      400 + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,\  
      401 + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,\  
      402 + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,\  
      403 + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,\  
      404 + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,\  
      405 + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,\  
      406 + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,\  
      407 + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,\  
      408 + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209}  
      409 +  
      410 +  
      411 +#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS  
      412 +#define CONFIG_SYS_NAND_ECCSIZE 512  
      413 +  
      414 +#define CONFIG_SYS_NAND_ECCBYTES 26  
      415 +  
      416 +  
      417 +#define CONFIG_SYS_NAND_ECCSTEPS 8  
      418 +  
      419 +  
    389 420 #define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \  
    390 421 CONFIG_SYS_NAND_ECCSTEPS)  
    391 422  


  • You need more changes to BCH 16 work correctly:

    In file u-boot-2011.09-psp04.06.00.08/arch/arm/include/asm/arch-ti81xx/cpu.h is neccesary to complete the structure gpmc as follow:

    struct gpmc {
    u8 res1[0x10];
    u32 sysconfig; /* 0x10 */
    u8 res2[0x4];
    u32 irqstatus; /* 0x18 */
    u32 irqenable; /* 0x1C */
    u8 res3[0x20];
    u32 timeout_control; /* 0x40 */
    u8 res4[0xC];
    u32 config; /* 0x50 */
    u32 status; /* 0x54 */
    u8 res5[0x8]; /* 0x58 */
    struct gpmc_cs cs[8]; /* 0x60, 0x90, .. */
    u8 res6[0x14]; /* 0x1E0 */
    u32 ecc_config; /* 0x1F4 */
    u32 ecc_control; /* 0x1F8 */
    u32 ecc_size_config; /* 0x1FC */
    u32 ecc1_result; /* 0x200 */
    u32 ecc2_result; /* 0x204 */
    u32 ecc3_result; /* 0x208 */
    u32 ecc4_result; /* 0x20C */
    u32 ecc5_result; /* 0x210 */
    u32 ecc6_result; /* 0x214 */
    u32 ecc7_result; /* 0x218 */
    u32 ecc8_result; /* 0x21C */
    u32 ecc9_result; /* 0x220 */
    u8 res7[12]; /* 0x224 */
    u32 testmomde_ctrl; /* 0x230 */
    u8 res8[12]; /* 0x234 */
    struct bch_res_0_3 bch_result_0_3[7]; /* 0x240 */ 
    u8 res9[32];/* 0x2B0 */ 
    u32 gpmc_bch_swdata;/* 0x2D0 */ 
    u8 res10[44]; /* 0x2D4 */ 
    struct bch_res_4_6 bch_result_4_6[7]; /* 0x300 */ 
    };

    Then change the function __ti81xx_nand_switch_ecc in the u-boot-2011.09-psp04.06.00.08/drivers/mtd/nand/ti81xx_nand.c:

    void __ti81xx_nand_switch_ecc(struct nand_chip *nand,
    nand_ecc_modes_t hardware, int32_t mode)
    {
    struct nand_bch_priv *bch;

    bch = nand->priv;
    nand->options |= NAND_OWN_BUFFERS;

    /* Reset ecc interface */
    nand->ecc.read_page = NULL;
    nand->ecc.write_page = NULL;
    nand->ecc.read_oob = NULL;
    nand->ecc.write_oob = NULL;
    nand->ecc.hwctl = NULL;
    nand->ecc.correct = NULL;
    nand->ecc.calculate = NULL;

    nand->ecc.write_page = NULL;
    nand->ecc.read_page = NULL;
    nand->ecc.mode = hardware;
    /* Setup the ecc configurations again */
    if (hardware == NAND_ECC_HW) {
    if (mode) {
    bch->mode = NAND_ECC_HW_BCH;
    /* -1 for converting mode to bch type */
    bch->type = mode - 1;
    printf("HW ECC BCH");
    switch (bch->type) {
    case ECC_BCH4:
    nand->ecc.layout = &hw_bch4_nand_oob;
    bch->nibbles = ECC_BCH4_NIBBLES;
    nand->ecc.bytes = 8;
    printf("4 not supported\n");
    goto no_support;
    break;
    case ECC_BCH16:
    nand->ecc.bytes = 26;
    nand->ecc.layout = &hw_bch16_nand_oob;
    bch->nibbles = ECC_BCH16_NIBBLES;
    printf("16 Selected\n");
    // printf("16 not supported\n");
    // goto no_support;
    break;
    case ECC_BCH8:
    default:
    nand->ecc.bytes = 14;
    nand->ecc.layout = &hw_bch8_nand_oob;
    bch->nibbles = ECC_BCH8_NIBBLES;
    printf("8 Selected\n");
    break;
    }
    bch->mode = NAND_ECC_HW;
    nand->ecc.mode = NAND_ECC_HW_SYNDROME;
    // nand->ecc.steps = 4;
    nand->ecc.steps = 8;//4kB Page has nor 4 but 8 steps (4096 / 512)
    nand->ecc.size = 512;
    nand->ecc.total = (nand->ecc.steps * nand->ecc.bytes);
    nand->ecc.write_page = ti81xx_write_page_bch;
    nand->ecc.read_page = ti81xx_read_page_bch;
    nand->ecc.hwctl = ti81xx_enable_ecc_bch;
    nand->ecc.correct = ti81xx_correct_data_bch;
    nand->ecc.calculate = ti81xx_calculate_ecc_bch;
    ti81xx_hwecc_init_bch(nand, NAND_ECC_READ);
    } else {
    bch->mode = NAND_ECC_HW;
    nand->ecc.layout = &hw_nand_oob;
    nand->ecc.size = 512;
    nand->ecc.bytes = 3;
    nand->ecc.hwctl = ti81xx_enable_ecc;
    nand->ecc.correct = ti81xx_correct_data;
    nand->ecc.calculate = ti81xx_calculate_ecc;
    ti81xx_hwecc_init(nand);
    printf("HW ECC Hamming Code selected\n");
    }
    } else if(hardware == NAND_ECC_SOFT) {
    /* Use mtd default settings */
    nand->ecc.layout = NULL;
    printf("SW ECC selected\n");
    } else {
    printf("ECC Disabled\n");
    }

    no_support:
    return;
    }

    and the function:

    static int ti81xx_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
    uint8_t *ecc_code)
    {
    struct nand_chip *chip = mtd->priv;
    struct nand_bch_priv *bch = chip->priv;
    uint8_t big_endian = 1;
    int8_t ret = 0;

    if (bch->type == ECC_BCH16) //Add support for BCH 16
    ti81xx_read_bch16_result(mtd, big_endian, ecc_code);
    else//Cs
    if (bch->type == ECC_BCH8)
    ti81xx_read_bch8_result(mtd, big_endian, ecc_code);
    else /* BCH4 and BCH16 currently not supported */
    ret = -1;

    #ifdef NAND_DEBUG
    {
    int8_t i = 0;
    printf("----\nECC\n---\n");
    for (i = 0; i < 13; i++)
    printf(" 0x%2x", ecc_code[i]);
    printf("\n");
    }
    #endif

    /*
    * Stop reading anymore ECC vals and clear old results
    * enable will be called if more reads are required
    */
    ti81xx_ecc_disable(mtd);

    return ret;
    }

    to add the support for BCH 16. You need allso to add the function ti81xx_read_bch16_result:

    static void ti81xx_read_bch16_result(struct mtd_info *mtd, uint8_t big_endian,
    uint8_t *ecc_code)
    {
    uint32_t *ptr;
    int8_t i = 0, j;

    if(big_endian)
    {
    ecc_code[i++] = (GET_BCH_RESULT(6, 0) >> 8) & 0xFF;
    ecc_code[i++] = (GET_BCH_RESULT(6, 0)) & 0xFF;
    for(j = 1; j < 7; j++)
    {
    ecc_code[i++] = (GET_BCH_RESULT(6 - j, 0) >> 24) & 0xFF;
    ecc_code[i++] = (GET_BCH_RESULT(6 - j, 0) >> 16) & 0xFF;
    ecc_code[i++] = (GET_BCH_RESULT(6 - j, 0) >> 8) & 0xFF;
    ecc_code[i++] = (GET_BCH_RESULT(6 - j, 0)) & 0xFF;
    }
    }else
    {
    for(j = 0; j < 6; j++)
    {
    ecc_code[i++] = (GET_BCH_RESULT(j, 0)) & 0xFF;
    ecc_code[i++] = (GET_BCH_RESULT(j, 0) >> 8) & 0xFF;
    ecc_code[i++] = (GET_BCH_RESULT(j, 0) >> 16) & 0xFF;
    ecc_code[i++] = (GET_BCH_RESULT(j, 0) >> 24) & 0xFF;
    }
    ecc_code[i++] = (GET_BCH_RESULT(6, 0)) & 0xFF;
    ecc_code[i++] = (GET_BCH_RESULT(6, 0) >> 8) & 0xFF;
    }

    }

    where the macro GET_BCH_RESULT is defined as follow:

    #define GET_BCH_RESULT(reg, cs) (reg < 4 ? readl(&gpmc_cfg->bch_result_0_3[cs].bch_result_x[reg]) : readl(&gpmc_cfg->bch_result_4_6[cs].bch_result_x[reg - 4]))

    After those changes you should be able to set BCH16 with the u-boot command:

    nandecc hw 3

    and if you store the MLO with this settings, you should be able to boot the system from the NAND FLASH.

    Regards,

    Karel


  • Sorry, I have forgot two things. I have allso changed the definition of ECC_BCH16_NIBBLES to 102 and in the file u-boot-2011.09-psp04.06.00.08/include/linux/mtd/mtd-abi.h it is neccesary to increse the array size of eccpos:

    struct nand_ecclayout {
    uint32_t eccbytes;
    uint32_t eccpos[256];
    uint32_t oobavail;
    struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
    };


  • Thanks Karel..

    It would be really helpful, if you can make a formal patch for your changes and post it to Tom Rini (Uboot).

    We would try to get this ported to mainline, and push it upstream so that everyone is benefited from your work.

    (You can also attach the patch in this forum-post as reference, instead of posting it inline)

     

    with regards, pekon

  • Hi Pekon,

    sorry for late reply. I have interrupted my work on AM335x because of some project with higher priority. Now I am back and have prepared the patches. 0245.NAND_Patches.zip

    Those patches are for BeagleBone with MT29F8G08 NAND Flash. Perhaps it helps somebody.

    Regards,

    Karel

  • Thanks Karel. This would be very helpful.

    I'll try to get these ported to mainline u-boot, and post them with your authorship.

    Also, If you are working on mainline linux kernel, there were some clean-up patches posted of omap2-nand driver, you may like to try them.

    -- Though these do not change any much of feature for AM335x, but these improve usability of the driver w.r.t. ECC schemes

    + many more coming on linux-mtd@lists.infradead.org

    with regards, pekon

  • MT29F8G08 SLC or MLC (Micron provides 2 versions).  SLC + 4k BCH16 is perfectly fine with uboot and kernel.  MLC has kernel I/O issue, but uboot works well.

    Left me with no choice. Hardware team has redesigned layout to use eMMC, as SLC 2GiB are too expensive for 100-200k annual production qty.

  • Cao,

    The issues with MLC NAND can still be fixed in kernel if BCH-16 is implemented properly.

  • Cao,

    Which kernel are you using that works with the SLC + 4K/BCH16 scheme?

    We are still based from 3.1 and BCH16 is not supported. We are trying to port patches from the omap3 repo.

    p.s. Our NAND device is a Micron 29F4G08ABAEA

    cheers

    /Tim

  • All,

    Just published BCH16 ECC support on mainline kernel. Though its still needs to be accepted, but would be good if you can test & provide feedbacks,

    As mentioned in cover-letter this series is applicable on top of other two Patch series, which are awaiting acceptance in mainline. So you need to pull following patche *series* in given order

    [1] [Patch] mtd:nand:omap2: clean-up of supported ECC schemes 

    http://lists.infradead.org/pipermail/linux-mtd/2013-July/047530.html

    [2] [Patch] optimize and clean-up of OMAP NAND and ELM driver

    http://lists.infradead.org/pipermail/linux-mtd/2013-July/047538.html

    [3] [Patch] add support for BCH16_ECC

      http://lists.infradead.org/pipermail/linux-mtd/2013-July/047562.html

    Request all to provide feedbacks, Acks or Tested-by via 'linux-mtd@lists.infradead.org" only. So that its visible to all.

    with regards, pekon

  • Hi All,

    I meant to post a follow up to this a while ago and was not able to get to it, but I hope this is useful info to someone still.

    I'm very happy to see BCH16 support implemented and think it will be very useful!  However, after talking with Micron about their MLC NAND technology, their engineers advised us that 16 bits of error correction would not be sufficient to meet their error correction requirements and that a minimum of 18 bits (I think?) would be required.  We asked whether 16 bits would simply cause a shorter MTBF, and they seemed to suggest it could be worse than that.

    Unfortunately since it has been a couple of months since our discussion with them, I don't remember all the details. I would suggest though, if you're considering a 4 K / 224 byte MLC part that you contact the manufacturer to find out if 16-bit ECC will be sufficient for the part.  Based on this discussion we switched to eMMC storage since the ECC computation is all handled on the module.

    If you do talk to them, please post any specific details which either confirms or contradicts this as I'm sure that will be valuable to everyone.

    Thanks,

    -Adam

  • Hi Adam,

    I hope you are using following patch series for BCH16 from mainline kernel.

    (1) http://lists.infradead.org/pipermail/linux-mtd/2013-July/047530.html

    (2) http://lists.infradead.org/pipermail/linux-mtd/2013-July/047538.html

    (3)  http://lists.infradead.org/pipermail/linux-mtd/2013-July/047562.html

    (Above series need to be applied in given order on mainline kernel)

    We are also working to get BCH16 done on mainline u-boot, I'll post when ready. However some basic clean-up patches are available.

    Now coming to your query.. I think, 16bit ECC scheme is more than enough for even very large sized NAND devices available today because the ECC scheme works on chunks of 512Bytes of data at a time, *irrespective* of the total size of the NAND flash. Example:

    -          for 2K page NAND, our GPMC hardware would *divide each page into 4 parts of 512-bytes each, and then protect each 512-bytes with individual ECC signatures.*

    -          Likewise for 4K page NAND, our GPMC hardware would *divide each page into 8 parts of 512-bytes each, and calculate ECC for all 8 parts independently.*

     

    So, this mean that;

    (a)    A 16bit ECC scheme can detect and correct upto 16 bit-flips in *every* 512-Bytes of data, irrespective of total size of the NAND, which I think can handle aging of large sized Flash device for at-least 2-3 years.

    (b)   Over and above that flash based file-systems do wear-leveling, so that all sectors of flash are equally worn-out. This increases flash endurance much further.

    Hence, even for all kinds of large page NANDs BCH16 (as calculated on every 512B data) is more than enough. Hope that answers your query..

    But I need some help from all people using BCH16 or NAND on AM335x..

    (1) Above patches are not getting accepted in mainline due to lack of independent reviews and tests by independent people like you. Hence in-case the patches work for you, I request to send a tested-by or Acked-by to above patches on mainline. So that patch acceptance is expedited.

    (2) Same applies for u-boot. Request you to please pull-in following patches, and test and ack / review them.

    thanks much..

    with regards, pekon

  • Hi Pekon,

    These patches doesn't seem to be for the current TI SDK. Which exact kernel version are these patches made for?

    We're trying to boot from a Micron MT29F2G08ABAFAH4:F (8bit ECC and 224 bytes OOB).

    This should actually work out-of-the box according to am3352 datasheet, but since the RBL "detects" the OOB it switches to 16bit ECC (BCH16) which is a no go at this stage.

    David

  • Any news here? Would be great if this could be part of the next release of the AM335x SDK.

    By the way, it's possible to trick RBL by adding a eeprom and telling it that it's a 8-bit ECC and thus getting around the issue of RBL incorrectly choosing 16-bit ECC (due to 224 OBB size). Of course, adding an eeprom is unwanted.

    best David

  • Hi David,

    Dav01 said:

    These patches doesn't seem to be for the current TI SDK. Which exact kernel version are these patches made for?

    The patches were meant for mainline kernel linux-3.11-rcx. But due to some NAK they could not make it to mainline. However, if you have any feedbacks please let me know.

    Dav01 said:

    By the way, it's possible to trick RBL by adding a eeprom and telling it that it's a 8-bit ECC and thus getting around the issue of RBL incorrectly choosing 16-bit ECC (due to 224 OBB size). Of course, adding an eeprom is unwanted.

    Also, Issue is that AM335x based ROM code automatically switches to BCH16 ECC when it detects 4K/224B NAND, and expects boot-loaders to be flashed in that ECC format. However, currently there is no TI provided flashing utility which supports BCH16.

    I'm also planning to add BCH16 support on u-boot, but to use that also you have to move to mainline u-boot.

    with regards, pekon

  • Hi Pekon,

    Just checking in if any news here? Would be great if we could get this in the next AM335x PSP/SDK. Do you know when we'll see this?

    David

  • Hi David,

    I'm not the correct person to provide you details about AM33xx SDK releases, but next version of SDK should be coming from latest linux kernel version available.And therefore I'm trying to get these patches up-streamed.

    However, you can always port these patches to your project if you are somewhere near latest kernel version. But if you are working on earlier SDK releases (with linux-3.2 kernel) then porting all these updates might be tough, so its better to wait for next SDK release.

     

    with regards, pekon

  • Hello Pekon

    then ,when the next SDK will be released?

    Best regards

    wangl

  • Sorry as stated above.. "I'm not the correct person to provide you details about AM33xx SDK releases"

    Please contact someone from Sales/Marketing or AE at you side for the AMSDK release details..

    with regards, pekon

  • Hi all,

    has anybody managed to run the nand flash with BCH16 in 3.2.0-linux-ti-sdk-psp04.06.00.11 from AM335x-evm-06.00.00.00?, could someone make a patch for this linux sdk version?.
    If nobody has done it yet , where can I get the best patches or source files to try using BCH16?. There are many sources:
    * http://arago-project.org/git/projects/linux-omap3.git

    * (0) http://lists.infradead.org/pipermail/linux-mtd/2013-May/047026.html
      (1) http://lists.infradead.org/pipermail/linux-mtd/2013-May/047029.html
      (2) http://lists.infradead.org/pipermail/linux-mtd/2013-May/047027.html
      (3) http://lists.infradead.org/pipermail/linux-mtd/2013-May/047028.html
      (4) http://lists.infradead.org/pipermail/linux-mtd/2013-May/047032.html 

    * (1) http://lists.infradead.org/pipermail/linux-mtd/2013-July/047530.html
      (2) http://lists.infradead.org/pipermail/linux-mtd/2013-July/047538.html
      (3) http://lists.infradead.org/pipermail/linux-mtd/2013-July/047562.html

    I have a custom board running MLO and U-Boot from nand flash using BCH16 using patch from this post: http://e2e.ti.com/support/arm/sitara_arm/f/791/p/307463/1074280.aspx#1074280

    Now my Kernel boots from nand flash but can't mount root filesystem in nand flash because it does not support BCH16.

    Thank you in advance

  • Hi,

    There are three *patch series* which you need to pick to get BCH16 working:

    (1) http://lists.infradead.org/pipermail/linux-mtd/2013-October/049410.html

    There are 10 patches in this series (status: accepted in mainline)

    (2) http://lists.infradead.org/pipermail/linux-mtd/2013-December/050572.html

    There are 4 patches in this series (status: needs re-submission so keep watching)

    (3) http://lists.infradead.org/pipermail/linux-mtd/2013-July/047562.html

    This patch series has 4 patches which have not been re-based from long, so you need to re-base it above (1) and (2) .


    with regards, pekon

  • Hello Pekon Gupta

    I have tried to apply the patches to /home/sitara/ti-sdk-am335x-evm-06.00.00.00/board-support/linux-3.2.0-psp04.06.00.11/ but it is not possible, I suppose the patches are for newer linux releases with many changes.

    Could you please create a patch for ti-sdk-am335x-evm-06.00.00.00?, could you please attach full files instead of patches?, could you please help ti-sdk-am335x-evm-06.00.00.00 users to get BCH16 working?, I'm sorry I'm still a Linux newbie and I need more help.

    Thank you

  • Hi.

    I'm facing the same problem using a Micron NAND flash (MT29F8G08ABABAWP) with an AM3352 on a custom board.

    After multiples actions, I succeeded in flashing  u-boot, kernel and ubifs system images into the NAND.

    The kernel starts booting when launching a "run nandboot" from the u-boot prompt. Unfortunatly, the boot sequence fails when the kernel try to mount the system file from the nand partition mtd7, with the following error message :

    "UBI error: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 0:0, read 64 bytes".

    What I did :

    • I modified u-boot source code to configure BCH16 instead of initial BCH8.
    • I updated, in many places, page size from 2048 to 4096, and block size from 64 to 128 pages, and also mtd partitions with new block size.
    • I updated also the flash_cat_util utility to make it uses 4096 as page size (instead of 2048)
    • My system file has been made on a development machine, using mkfs.ubifs and ubinize tools with the following parameters :
    1
    2
    mkfs.ubifs -r /export/rootfs/ -o ubifs.img -F -m 4096 -e 516096 -c 2016,
    ubinize -o ubi.img -m 4096 -p 512KiB -s 4096 -O 4096 -v ubinize.cfg

    I saw, in your post http://e2e.ti.com/support/arm/sitara_arm/f/791/t/214942.aspx?pi301021=3, that many patches should be applied to the kernel to enable it to work with BCH16. Unfortunatly it's not totally clear for me what I'm supposed to change (I'm not familar with forums like http://lists.infradead.org/pipermail/linux-mtd/2013-October and I didn't found the patch mentioned in it).

    So I didn't make any change in the kernel yet

    In http://arago-project.org/git/projects/linux-omap3.git, there is also several patches available, but I would appreciate some help to tell me which are related to my problem and which are not.

    Does it exist something else, elsewhere, that may concatenate all changes together to simplify the modification process ? Are these patches still relevant for a situation like mine ?

    To summarize, I need help to add support for my nand in the kernel (linux-3.2.0-psp04.06.00.10) I use. At least, some help about links above.

    All comments are welcome.

    Thank you in advance.

  • Could you share your code with me? I urgently need Nand flash tool with BCH16 support.