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