On Mon, 2013-09-30 at 19:43 +0530, Pekon Gupta wrote:
> +Platform specific options
> +=========================
> +
> +   CONFIG_NAND_OMAP_ECCSCHEME
> +     On OMAP platforms, this specifies NAND ECC scheme.
> +     1 - HAM1_SW     1-bit Hamming code using software library
> +                     (for legacy devices only)
> +     2 - HAM1_HW     1-bit Hamming code using GPMC hardware engine
> +                     (for legacy devices only)
> +     3 - BCH4_SW     4-bit BCH code (unsupported)
> +     4 - BCH4_HW     4-bit BCH code (unsupported)
> +     5 - BCH8_SW     8-bit BCH code with
> +                     - ecc calculation using GPMC hardware engine,
> +                     - error detection using software library.
> +                     - requires CONFIG_BCH to enable software BCH library
> +                     (For legacy device which do not have ELM h/w engine)
> +     6 - BCH8_HW     8-bit BCH code with
> +                     - ecc calculation using GPMC hardware engine,
> +                     - error detection using ELM hardware engine.

You should document the symbols, not the numbers that happen to be
assigned to them.

> +/**
> + * omap_select_ecc_scheme - configures driver for particular ecc-scheme
> + * @nand: NAND chip device structure
> + * @ecc_scheme: ecc scheme to configure
> + * @pagesize: number of main-area bytes per page of NAND device
> + * @oobsize: number of OOB/spare bytes per page of NAND device
> + */
> +static int omap_select_ecc_scheme(struct nand_chip *nand, int ecc_scheme,
> +             unsigned int pagesize, unsigned int oobsize) {

s/int ecc_scheme/enum omap_ecc ecc_scheme/

> +     struct nand_bch_priv    *bch            = nand->priv;
> +     struct nand_ecclayout   *ecclayout      = nand->ecc.layout;
> +     int i;
> +
> +     switch (ecc_scheme) {
> +     case OMAP_ECC_HAM1_CODE_SW:
> +             debug("nand: selected OMAP_ECC_HAM1_CODE_SW\n");
> +             nand->ecc.mode          = NAND_ECC_SOFT;
> +             nand->ecc.layout        = NULL;
> +             nand->ecc.size          = 0;
> +             nand->ecc.strength      = 1;
> +             bch->ecc_scheme         = OMAP_ECC_HAM1_CODE_SW;
> +             break;
> +     case OMAP_ECC_HAM1_CODE_HW:
> +             debug("nand: selected OMAP_ECC_HAM1_CODE_HW\n");
> +             nand->ecc.mode          = NAND_ECC_HW;
> +             nand->ecc.strength      = 1;
> +             nand->ecc.size          = 512;
> +             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 *
> +                                             (pagesize / SECTOR_BYTES);
> +             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;
> +             bch->ecc_scheme         = OMAP_ECC_HAM1_CODE_HW;
> +             break;
> +#ifdef CONFIG_BCH
> +     case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
> +             debug("nand: selected OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
> +             nand->ecc.mode          = NAND_ECC_HW;
> +             nand->ecc.strength      = 8;
> +             nand->ecc.size          = 512;
> +             nand->ecc.bytes         = 13;
> +             nand->ecc.hwctl         = omap_enable_ecc_bch;
> +             nand->ecc.correct       = omap_correct_data_bch_sw;
> +             nand->ecc.calculate     = omap_calculate_ecc_bch_sw;
> +             /* BCH SW library is used for error detection */
> +             bch_priv.control        = init_bch(13, 8, 0x201b);
> +             if (!bch_priv.control) {
> +                     printf("nand: error: could not init_bch()\n");
> +                     return -ENODEV;
> +             }
> +             bch_priv.type           = ECC_BCH8;
> +             /* define ecc-layout */
> +             ecclayout->eccbytes     = nand->ecc.bytes *
> +                                             (pagesize / SECTOR_BYTES);
> +             for (i = 0; i < ecclayout->eccbytes; i++)
> +                     ecclayout->eccpos[i] = i + (oobsize -
> +                                             ecclayout->eccbytes);
> +             ecclayout->oobfree[0].offset = BADBLOCK_MARKER_LENGTH;
> +             ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
> +                                             BADBLOCK_MARKER_LENGTH;
> +             omap_hwecc_init_bch(nand, NAND_ECC_READ);
> +             bch->ecc_scheme         = OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
> +             break;
> +#endif
> +     case OMAP_ECC_BCH8_CODE_HW:
> +             debug("nand: selected OMAP_ECC_BCH8_CODE_HW\n");
> +             nand->ecc.mode          = NAND_ECC_HW;
> +             nand->ecc.strength      = 8;
> +             nand->ecc.size          = 512;
> +             nand->ecc.bytes         = 14;
> +             nand->ecc.hwctl         = omap_enable_ecc_bch;
> +             nand->ecc.correct       = omap_correct_data_bch;
> +             nand->ecc.calculate     = omap_calculate_ecc_bch;
> +             nand->ecc.read_page     = omap_read_page_bch;
> +             /* ELM is used for ECC error detection */
> +             elm_init();
> +             bch_priv.type           = ECC_BCH8;
> +             /* define ecc-layout */
> +             ecclayout->eccbytes     = nand->ecc.bytes *
> +                                             (pagesize / SECTOR_BYTES);
> +             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;
> +             bch->ecc_scheme         = OMAP_ECC_BCH8_CODE_HW;
> +             break;
> +     default:
> +             debug("nand: error: ecc scheme not enabled or supported\n");
> +             return -EINVAL;
> +     }
> +
> +     /* check if NAND spare/OOB has enough bytes to accomodate ecclayout */
> +     if ((ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH) > oobsize) {
> +             printf("nand: error: insufficient OOB bytes. require=%d\n", (
> +                             ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH));
> +             return -EINVAL;
> +     }

Check this before you make any changes to the current ECC setup.

> +             err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
> +                                     mtd->writesize, mtd->oobsize);
> +     }
> +     if (err) {
> +             printf("nand: error: could not switch ecc, reverting\n");
> +             omap_select_ecc_scheme(nand, bch->ecc_scheme,
> +                                    mtd->writesize, mtd->oobsize);
> +             return -EINVAL;
>       }

You won't need to "revert" here if omap_select_ecc_scheme doesn't damage
anything in error cases.

-Scott



_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to