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.

U-Boot 2012.10 missing nandecc??

So I want to boot my custom board entirely from NAND flash and I am having problems with U-Boot showing that all blocks are bad.  I thought I needed to change my ECC algorithm (I have MT29F4G08ABADAWP which has HW ECC), but I find U-Boot is missing the nandecc command.

I checked the sources and it is located in arch/arm/cpu/armv7/omap3/board.c, but this isn't even compiled for the am335x_evm target.

So, what should I do?  Should I copy the implementation over to arch/arm/cpu/armv7/am33xx/board.c?  Why isn't this code part of the generic OMAP GPMC code?

Also, can someone tell my what HW ECC algorithm to use with the above NAND chip?

BTW, this u-boot came from ti-sdk-am335x-evm-05.06.00.00 and prints this string on boot: U-Boot 2012.10-svn8

Thanks

  • Hi,

    nandecc command is no more supported as U-boot by default falls to BCH 8 ecc and is the requirement for am335x.

    Hence eliminated the need for ecc switching and code duplication from arch/arm/cpu/armv7/omap3/board.c.

    David Paden said:
    Also, can someone tell my what HW ECC algorithm to use with the above NAND chip?

    spec says ECC Req. as 4-bit/528-byte.

    Hence you can use default ecc scheme BCH8 which is capable of 8-bit ecc correction/528-byte

    I was not sure why all blocks showing bad for you. May be you can scrub the nand from U-boot using nand scrub and try to re-use it.

    Thanks Avinash

  • I needed to do more reading.  The issue is that my NAND has on-die ECC (which I was mistaking for HW ECC) and the chip ships from the factory using their ECC layout (which is very different from the AM33xx bch8 layout), so the bad sector marks are in the wrong location.

    Micron has some nice information about implementing the on-die ECC which should have speed improvements even over the AM335x HW ECC engine.  It's not hard to implement (they have step-by-step instructions for the OMAP3 platform), and in fact I think I'm just about done modifying the u-boot/SPL code.  I can even auto-detect if the chip has hardware ECC or not, though I just use a config macro since the omap_nand_switch_ecc function is no longer used.

    But, if you think using BCH8 is OK for most every use case, it would make more sense just to use it, I think.

  • OK, so I got a lot of that going, but decided it wouldn't work anyway because the boot ROM in the CPU will use BCH8 HW ECC and I want to boot directly from NAND.  So...

    I tried to do nand scrub.chip as indicated, but it causes a CPU abort and resets!  Just to be sure, I reverted all my on-die ECC code changes and tried again with the same issue.  I dug a little further and discovered the line below causes the abort inside nand_erase_opts():

    if(chip->bbt) {

        kfree(chip->bbt);

    }

    It still wasn't working after commenting that line out, so I I kept digging and, after turning on MTD debug, I get this line at bootup:

    nand_isbad_bbt(): bbt info for offs 0x00260000: (block 0) 0x01

    and on nand scrub.chip I get the following (this is just one of the lines...it happens for every block):

    nand_erase_nand: start = 0x00001fda0000, len = 131072
    check_offs_len: Unaligned address
    check_offs_len: Length not block aligned

    nand0: MTD Erase failure: -22

    So my guess is I don't have the correct NAND settings in my board configuration?  Could someone help me out with this, because I don't half understand where these numbers are coming from (probably because I don't know what chip they originally came from...)

    Current NAND configuration settings:

    #define CONFIG_SYS_NAND_5_ADDR_CYCLE
    #define CONFIG_SYS_NAND_PAGE_COUNT    (CONFIG_SYS_NAND_BLOCK_SIZE / \
                         CONFIG_SYS_NAND_PAGE_SIZE)
    #define CONFIG_SYS_NAND_PAGE_SIZE    2048
    #define CONFIG_SYS_NAND_OOBSIZE        64
    #define CONFIG_SYS_NAND_BLOCK_SIZE    (128*1024)
    #define CONFIG_SYS_NAND_BAD_BLOCK_POS    NAND_LARGE_BADBLOCK_POS
    #define CONFIG_SYS_NAND_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, }


    #define CONFIG_SYS_NAND_ECCSIZE        512
    #define CONFIG_SYS_NAND_ECCBYTES    14
    #define CONFIG_SYS_NAND_ECCSTEPS    4
    #define    CONFIG_SYS_NAND_ECCTOTAL    (CONFIG_SYS_NAND_ECCBYTES * \
                            CONFIG_SYS_NAND_ECCSTEPS)

    But the AM335x code is using this in omap_gpmc.c:

    #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 } } \
    }

    Thanks

  • Another note, it looks like CONFIG_SYS_NAND_ECCSIZE and CONFIG_SYS_ECCBYTES are still used in omap_gpmc.c

  • In case anyone's following, the nand_erase_opts function has a parameter, meminfo, which is supposed to be the same as the mtd pointer.  This pointer appears to be invalid, as the meminfo->priv field does NOT match the mtd->priv from the nand init.  It looks like that pointer is not set...

  • Solved.  Bug in omap_mmc_init.  If called with omap_mmc_init(2, 0, 0) to initialize the third mmc bus (used on my board for WLAN), something is changing the global nand_info data.

    I don't really need this bus (probably ever), but it would be cool if I could transfer images over WLAN at some point (probably too big a pain to try it, though).

    Also, I noticed someone else had trouble if enabling this MMC in the linux kernel...maybe that function ought to be fixed?

  • can ypu please tell me why we use CONFIG_SYS_NAND_5_ADDR_CYCLE and  CONFIG_SYS_NAND_ECCPOS

    in our configurations

    thnx

    Ravi Kant

  • CONFIG_SYS_NAND_5_ADDR_CYCLE is needed on larger NAND chips with so-called "Large-block devices," generally 2Gb or larger.  Google search for "nand 5 address cycle" has a nice note from Micron as the first result.

    CONFIG_SYS_NAND_ECCPOS defines the locations of the ECC data stored in the NAND Flash.  If you were changing ECC algorithms, you might have to adjust the ECC positions (for example, if using the NAND on-die ECC).

  • Which Linux are you using?  

    I'm using linux-3.2.0-psp04.06.00.11 (from TI SDK 6), and WLAN (mmc2) and NAND, but I haven't seen any problem.

    What is the bug/fix in omap_mmc_init()?


    BTW, you need to do mmc2_wl12xx_init() before mmc0_init() as mmc0_init() sets up the other mmc.


    EDIT:  Ah, just realised, you're talking about u-boot (not Linux).  I don't use mmc2 in u-boot.

  • The problem is specific to u-boot from EZSDK 05.06.00.00.  This problem is specific to initializing MMC2 (not MMC0 or MMC1) while in u-boot.

    In this case, u-boot NAND does not work properly because passing the index for MMC2 in the omap_mmc_init() is not handled and causes memory corruption.  I have not checked for this behavior in EZSDK 6.00.00.00 since I simply stopped trying to init the third MMC bus in u-boot due to the bug.

  • SYSBOOT[9] has the purpose of the Rom BOOT loader to use "internal NAND ECC".

    But I think it is easier to stick with BCH-8 handled in the am335x instead of in the NAND, as this seems to be what TI supports in the SDK.

  • Yes, what you suggested is what I originally tried.  Unfortunately, I couldn't find clear documentation to suggest what the POS array should be for the NAND I used, and u-boot and the kernel must also be modified to work with it.  It's not trivial and not worth the trouble since the CPU has it's own embedded ECC HW.