Loading drivers/mtd/nand/fsl_elbc_nand.c +47 −36 Original line number Diff line number Diff line Loading @@ -79,32 +79,53 @@ struct fsl_elbc_fcm_ctrl { /* These map to the positions used by the FCM hardware ECC generator */ /* Small Page FLASH with FMR[ECCM] = 0 */ static struct nand_ecclayout fsl_elbc_oob_sp_eccm0 = { .eccbytes = 3, .eccpos = {6, 7, 8}, .oobfree = { {0, 5}, {9, 7} }, }; static int fsl_elbc_ooblayout_ecc(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); /* Small Page FLASH with FMR[ECCM] = 1 */ static struct nand_ecclayout fsl_elbc_oob_sp_eccm1 = { .eccbytes = 3, .eccpos = {8, 9, 10}, .oobfree = { {0, 5}, {6, 2}, {11, 5} }, }; if (section >= chip->ecc.steps) return -ERANGE; /* Large Page FLASH with FMR[ECCM] = 0 */ static struct nand_ecclayout fsl_elbc_oob_lp_eccm0 = { .eccbytes = 12, .eccpos = {6, 7, 8, 22, 23, 24, 38, 39, 40, 54, 55, 56}, .oobfree = { {1, 5}, {9, 13}, {25, 13}, {41, 13}, {57, 7} }, }; oobregion->offset = (16 * section) + 6; if (priv->fmr & FMR_ECCM) oobregion->offset += 2; oobregion->length = chip->ecc.bytes; return 0; } static int fsl_elbc_ooblayout_free(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); if (section > chip->ecc.steps) return -ERANGE; /* Large Page FLASH with FMR[ECCM] = 1 */ static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = { .eccbytes = 12, .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}, .oobfree = { {1, 7}, {11, 13}, {27, 13}, {43, 13}, {59, 5} }, if (!section) { oobregion->offset = 0; if (mtd->writesize > 512) oobregion->offset++; oobregion->length = (priv->fmr & FMR_ECCM) ? 7 : 5; } else { oobregion->offset = (16 * section) - ((priv->fmr & FMR_ECCM) ? 5 : 7); if (section < chip->ecc.steps) oobregion->length = 13; else oobregion->length = mtd->oobsize - oobregion->offset; } return 0; } static const struct mtd_ooblayout_ops fsl_elbc_ooblayout_ops = { .ecc = fsl_elbc_ooblayout_ecc, .free = fsl_elbc_ooblayout_free, }; /* Loading Loading @@ -657,8 +678,8 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) chip->ecc.bytes); dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.total = %d\n", chip->ecc.total); dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.layout = %p\n", chip->ecc.layout); dev_dbg(priv->dev, "fsl_elbc_init: mtd->ooblayout = %p\n", mtd->ooblayout); dev_dbg(priv->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags); dev_dbg(priv->dev, "fsl_elbc_init: mtd->size = %lld\n", mtd->size); dev_dbg(priv->dev, "fsl_elbc_init: mtd->erasesize = %d\n", Loading @@ -675,14 +696,6 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) } else if (mtd->writesize == 2048) { priv->page_size = 1; setbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS); /* adjust ecc setup if needed */ if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) == BR_DECC_CHK_GEN) { chip->ecc.size = 512; chip->ecc.layout = (priv->fmr & FMR_ECCM) ? &fsl_elbc_oob_lp_eccm1 : &fsl_elbc_oob_lp_eccm0; } } else { dev_err(priv->dev, "fsl_elbc_init: page size %d is not supported\n", Loading Loading @@ -780,9 +793,7 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) == BR_DECC_CHK_GEN) { chip->ecc.mode = NAND_ECC_HW; /* put in small page settings and adjust later if needed */ chip->ecc.layout = (priv->fmr & FMR_ECCM) ? &fsl_elbc_oob_sp_eccm1 : &fsl_elbc_oob_sp_eccm0; mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops); chip->ecc.size = 512; chip->ecc.bytes = 3; chip->ecc.strength = 1; Loading Loading
drivers/mtd/nand/fsl_elbc_nand.c +47 −36 Original line number Diff line number Diff line Loading @@ -79,32 +79,53 @@ struct fsl_elbc_fcm_ctrl { /* These map to the positions used by the FCM hardware ECC generator */ /* Small Page FLASH with FMR[ECCM] = 0 */ static struct nand_ecclayout fsl_elbc_oob_sp_eccm0 = { .eccbytes = 3, .eccpos = {6, 7, 8}, .oobfree = { {0, 5}, {9, 7} }, }; static int fsl_elbc_ooblayout_ecc(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); /* Small Page FLASH with FMR[ECCM] = 1 */ static struct nand_ecclayout fsl_elbc_oob_sp_eccm1 = { .eccbytes = 3, .eccpos = {8, 9, 10}, .oobfree = { {0, 5}, {6, 2}, {11, 5} }, }; if (section >= chip->ecc.steps) return -ERANGE; /* Large Page FLASH with FMR[ECCM] = 0 */ static struct nand_ecclayout fsl_elbc_oob_lp_eccm0 = { .eccbytes = 12, .eccpos = {6, 7, 8, 22, 23, 24, 38, 39, 40, 54, 55, 56}, .oobfree = { {1, 5}, {9, 13}, {25, 13}, {41, 13}, {57, 7} }, }; oobregion->offset = (16 * section) + 6; if (priv->fmr & FMR_ECCM) oobregion->offset += 2; oobregion->length = chip->ecc.bytes; return 0; } static int fsl_elbc_ooblayout_free(struct mtd_info *mtd, int section, struct mtd_oob_region *oobregion) { struct nand_chip *chip = mtd_to_nand(mtd); struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); if (section > chip->ecc.steps) return -ERANGE; /* Large Page FLASH with FMR[ECCM] = 1 */ static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = { .eccbytes = 12, .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}, .oobfree = { {1, 7}, {11, 13}, {27, 13}, {43, 13}, {59, 5} }, if (!section) { oobregion->offset = 0; if (mtd->writesize > 512) oobregion->offset++; oobregion->length = (priv->fmr & FMR_ECCM) ? 7 : 5; } else { oobregion->offset = (16 * section) - ((priv->fmr & FMR_ECCM) ? 5 : 7); if (section < chip->ecc.steps) oobregion->length = 13; else oobregion->length = mtd->oobsize - oobregion->offset; } return 0; } static const struct mtd_ooblayout_ops fsl_elbc_ooblayout_ops = { .ecc = fsl_elbc_ooblayout_ecc, .free = fsl_elbc_ooblayout_free, }; /* Loading Loading @@ -657,8 +678,8 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) chip->ecc.bytes); dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.total = %d\n", chip->ecc.total); dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.layout = %p\n", chip->ecc.layout); dev_dbg(priv->dev, "fsl_elbc_init: mtd->ooblayout = %p\n", mtd->ooblayout); dev_dbg(priv->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags); dev_dbg(priv->dev, "fsl_elbc_init: mtd->size = %lld\n", mtd->size); dev_dbg(priv->dev, "fsl_elbc_init: mtd->erasesize = %d\n", Loading @@ -675,14 +696,6 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) } else if (mtd->writesize == 2048) { priv->page_size = 1; setbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS); /* adjust ecc setup if needed */ if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) == BR_DECC_CHK_GEN) { chip->ecc.size = 512; chip->ecc.layout = (priv->fmr & FMR_ECCM) ? &fsl_elbc_oob_lp_eccm1 : &fsl_elbc_oob_lp_eccm0; } } else { dev_err(priv->dev, "fsl_elbc_init: page size %d is not supported\n", Loading Loading @@ -780,9 +793,7 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) == BR_DECC_CHK_GEN) { chip->ecc.mode = NAND_ECC_HW; /* put in small page settings and adjust later if needed */ chip->ecc.layout = (priv->fmr & FMR_ECCM) ? &fsl_elbc_oob_sp_eccm1 : &fsl_elbc_oob_sp_eccm0; mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops); chip->ecc.size = 512; chip->ecc.bytes = 3; chip->ecc.strength = 1; Loading