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.

Linux/PROCESSOR-SDK-AM335X: NAND not detected in Latest ti sdk

Part Number: PROCESSOR-SDK-AM335X

Tool/software: Linux

Hi,

I'm working on latest ti sdk ti-processor-sdk-linux-am335x-evm-03.02.00.05-Linux-x86-Install and wants to configure NAND Flash IC S34ML08G1 for my customized board.

I have configured gpmc lines in u-boot/board/ti/am335x/mux.c, but nand is not getting detected as shown in the logs below. Could anyone please let me know the configuration I'm missing.

U-Boot 2016.05-00305-g3b08611-dirty (Mar 29 2017 - 12:07:45 +0530)

CPU  : AM335X-GP rev 2.1

Inside show_board_info
Model: TI AM335x BeagleBone Black
       Watchdog enabled
DRAM:  256 MiB
NAND:  0 MiB
MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
reading uboot.env

Thanks and Regards

Deshvir Malik

  • Hi Deshvir,

    Could you specify which u-boot config file you are using? Are you try to build u-boot with "am335x_evm_nandboot_defconfig" config file?

    Also check weather the CONFIG_NAND preprocessor switch is defined.

    BR
    Tsvetolin Shulev

  • 0143..config.txtHi Tsvetolin,

    I'll tell you the way I'm compiling.

    1. For u-boot, I'm using the following command:

    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- am335x_evm_config all

    I have attached the generated .config file

    2. But for kernel compilation, I'm using specific config file as mentioned below

    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- tisdk_am335x-evm_defconfig

    CONFIG_NAND preprocessor switch is not defined.

    Thanks and Regards

    Deshvir Malik

  • Hi Tsvetolin,

    I have done the pin muxing of NAND in u-boot and it seems that nand is getting detected but new error is coming this time as indicated by red color font. 

    Could you suggest something on this error?

    U-Boot 2016.05-00305-g3b08611-dirty (Mar 30 2017 - 13:02:13 +0530)

    CPU  : AM335X-GP rev 2.1

    Inside show_board_info
    Model: TI AM335x BeagleBone Black
           Watchdog enabled
    DRAM:  256 MiB
    NAND:  nand: error: insufficient OOB: require=106
    0 MiB
    MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
    reading uboot.env

    Thanks and Regards

    Deshvir Malik

  • Deshvir,

    The error message "nand: error: insufficient OOB: require=106" is caused by unsuccessful checking of ecc-scheme requirements before updating ecc info. This check is executed in case of using hardware error code correction in ../u-boot/drivers/mtd/nand/omap_gpmc.c file but there is 3 different place where the message can be printed. For further debugging you can add additional prints. I suggest you to try to use software ECC as attempt for workaround.

    BR
    Tsvetolin Shulev
  • Hi Tsvetolin,

    I have modified the code at "u-boot/drivers/mtd/nand/omap_gpmc.c" and gave the errors name as error1, error2, error3 and erro4.

    It's coming at swich case of OMAP_ECC_BCH16_CODE_HW but expected is OMAP_ECC_BCH8_CODE_HW.

    I have modified  OMAP_ECC_BCH8_CODE_HW with #define CONFIG_NAND_OMAP_ECCSCHEME      OMAP_ECC_BCH8_CODE_HW_DETECTION_SW  in

    include/configs/am335x_evm.h , but still facing same error

    NAND:  nand: error4: insufficient OOB: require=106
    0 MiB

    Below is the omap_gpmc.c code for reference:

    static int omap_select_ecc_scheme(struct nand_chip *nand,

    enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {

    struct omap_nand_info *info = nand->priv;

    struct nand_ecclayout *ecclayout = &omap_ecclayout;

    int eccsteps = pagesize / SECTOR_BYTES;

    int i;

    switch (ecc_scheme) {

    // switch (OMAP_ECC_BCH8_CODE_HW) {

    case OMAP_ECC_HAM1_CODE_SW:

    debug("nand: selected OMAP_ECC_HAM1_CODE_SW\n");

    /* For this ecc-scheme, ecc.bytes, ecc.layout, ... are

    * initialized in nand_scan_tail(), so just set ecc.mode */

    info->control = NULL;

    nand->ecc.mode = NAND_ECC_SOFT;

    nand->ecc.layout = NULL;

    nand->ecc.size = 0;

    break;

    case OMAP_ECC_HAM1_CODE_HW:

    debug("nand: selected OMAP_ECC_HAM1_CODE_HW\n");

    /* check ecc-scheme requirements before updating ecc info */

    if ((3 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {

    printf("nand: error1: insufficient OOB: require=%d\n", (

    (3 * eccsteps) + BADBLOCK_MARKER_LENGTH));

    return -EINVAL;

    }

    info->control = NULL;

    /* populate ecc specific fields */

    memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));

    nand->ecc.mode = NAND_ECC_HW;

    nand->ecc.strength = 1;

    nand->ecc.size = SECTOR_BYTES;

    nand->ecc.bytes = 3;

    nand->ecc.hwctl = omap_enable_hwecc;

    nand->ecc.correct = omap_correct_data;

    nand->ecc.calculate = omap_calculate_ecc;

    /* define ecc-layout */

    ecclayout->eccbytes = nand->ecc.bytes * eccsteps;

    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;

    break;

    case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:

    #ifdef CONFIG_BCH

    debug("nand: selected OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");

    /* check ecc-scheme requirements before updating ecc info */

    if ((13 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {

    printf("nand: error2: insufficient OOB: require=%d\n", (

    (13 * eccsteps) + BADBLOCK_MARKER_LENGTH));

    return -EINVAL;

    }

    /* check if BCH S/W library can be used for error detection */

    info->control = init_bch(13, 8, 0x201b);

    if (!info->control) {

    printf("nand: error: could not init_bch()\n");

    return -ENODEV;

    }

    /* populate ecc specific fields */

    memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));

    nand->ecc.mode = NAND_ECC_HW;

    nand->ecc.strength = 8;

    nand->ecc.size = SECTOR_BYTES;

    nand->ecc.bytes = 13;

    nand->ecc.hwctl = omap_enable_hwecc;

    nand->ecc.correct = omap_correct_data_bch_sw;

    nand->ecc.calculate = omap_calculate_ecc;

    /* define ecc-layout */

    ecclayout->eccbytes = nand->ecc.bytes * eccsteps;

    ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH;

    for (i = 1; i < ecclayout->eccbytes; i++) {

    if (i % nand->ecc.bytes)

    ecclayout->eccpos[i] =

    ecclayout->eccpos[i - 1] + 1;

    else

    ecclayout->eccpos[i] =

    ecclayout->eccpos[i - 1] + 2;

    }

    ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;

    ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -

    BADBLOCK_MARKER_LENGTH;

    break;

    #else

    printf("nand: error: CONFIG_BCH required for ECC\n");

    return -EINVAL;

    #endif

    case OMAP_ECC_BCH8_CODE_HW:

    #ifdef CONFIG_NAND_OMAP_ELM

    debug("nand: selected OMAP_ECC_BCH8_CODE_HW\n");

    /* check ecc-scheme requirements before updating ecc info */

    if ((14 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {

    printf("nand: error3: insufficient OOB: require=%d\n", (

    (14 * eccsteps) + BADBLOCK_MARKER_LENGTH));

    return -EINVAL;

    }

    /* intialize ELM for ECC error detection */

    elm_init();

    info->control = NULL;

    /* populate ecc specific fields */

    memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));

    nand->ecc.mode = NAND_ECC_HW;

    nand->ecc.strength = 8;

    nand->ecc.size = SECTOR_BYTES;

    nand->ecc.bytes = 14;

    nand->ecc.hwctl = omap_enable_hwecc;

    nand->ecc.correct = omap_correct_data_bch;

    nand->ecc.calculate = omap_calculate_ecc;

    nand->ecc.read_page = omap_read_page_bch;

    /* define ecc-layout */

    ecclayout->eccbytes = nand->ecc.bytes * eccsteps;

    for (i = 0; i < ecclayout->eccbytes; i++)

    ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;

    ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;

    ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -

    BADBLOCK_MARKER_LENGTH;

    break;

    #else

    printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");

    return -EINVAL;

    #endif

    case OMAP_ECC_BCH16_CODE_HW:

    #ifdef CONFIG_NAND_OMAP_ELM

    debug("nand: using OMAP_ECC_BCH16_CODE_HW\n");

    /* check ecc-scheme requirements before updating ecc info */

    if ((26 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {

    printf("nand: error4: insufficient OOB: require=%d\n", (

    (26 * eccsteps) + BADBLOCK_MARKER_LENGTH));

    return -EINVAL;

    }

    /* intialize ELM for ECC error detection */

    elm_init();

    /* populate ecc specific fields */

    nand->ecc.mode = NAND_ECC_HW;

    nand->ecc.size = SECTOR_BYTES;

    nand->ecc.bytes = 26;

    nand->ecc.strength = 16;

    nand->ecc.hwctl = omap_enable_hwecc;

    nand->ecc.correct = omap_correct_data_bch;

    nand->ecc.calculate = omap_calculate_ecc;

    nand->ecc.read_page = omap_read_page_bch;

    /* define ecc-layout */

    ecclayout->eccbytes = nand->ecc.bytes * eccsteps;

    for (i = 0; i < ecclayout->eccbytes; i++)

    ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;

    ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;

    ecclayout->oobfree[0].length = oobsize - nand->ecc.bytes -

    BADBLOCK_MARKER_LENGTH;

    break;

    #else

    printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");

    return -EINVAL;

    #endif

    default:

    debug("nand: error: ecc scheme not enabled or supported\n");

    return -EINVAL;

    }

    /* nand_scan_tail() sets ham1 sw ecc; hw ecc layout is set by driver */

    if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW)

    nand->ecc.layout = ecclayout;

    info->ecc_scheme = ecc_scheme;

    return 0;

    }

    Thanks and Regards

    DEshvir Malik