Commit c2e197b0 authored by Boris Brezillon's avatar Boris Brezillon

mtd: nand: fsl_elbc: switch to mtd_ooblayout_ops

Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
parent 6b75065e
...@@ -79,32 +79,53 @@ struct fsl_elbc_fcm_ctrl { ...@@ -79,32 +79,53 @@ struct fsl_elbc_fcm_ctrl {
/* These map to the positions used by the FCM hardware ECC generator */ /* These map to the positions used by the FCM hardware ECC generator */
/* Small Page FLASH with FMR[ECCM] = 0 */ static int fsl_elbc_ooblayout_ecc(struct mtd_info *mtd, int section,
static struct nand_ecclayout fsl_elbc_oob_sp_eccm0 = { struct mtd_oob_region *oobregion)
.eccbytes = 3, {
.eccpos = {6, 7, 8}, struct nand_chip *chip = mtd_to_nand(mtd);
.oobfree = { {0, 5}, {9, 7} }, struct fsl_elbc_mtd *priv = nand_get_controller_data(chip);
};
/* Small Page FLASH with FMR[ECCM] = 1 */ if (section >= chip->ecc.steps)
static struct nand_ecclayout fsl_elbc_oob_sp_eccm1 = { return -ERANGE;
.eccbytes = 3,
.eccpos = {8, 9, 10},
.oobfree = { {0, 5}, {6, 2}, {11, 5} },
};
/* Large Page FLASH with FMR[ECCM] = 0 */ oobregion->offset = (16 * section) + 6;
static struct nand_ecclayout fsl_elbc_oob_lp_eccm0 = { if (priv->fmr & FMR_ECCM)
.eccbytes = 12, oobregion->offset += 2;
.eccpos = {6, 7, 8, 22, 23, 24, 38, 39, 40, 54, 55, 56},
.oobfree = { {1, 5}, {9, 13}, {25, 13}, {41, 13}, {57, 7} },
};
/* Large Page FLASH with FMR[ECCM] = 1 */ oobregion->length = chip->ecc.bytes;
static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = {
.eccbytes = 12, return 0;
.eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}, }
.oobfree = { {1, 7}, {11, 13}, {27, 13}, {43, 13}, {59, 5} },
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;
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,
}; };
/* /*
...@@ -657,8 +678,8 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) ...@@ -657,8 +678,8 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
chip->ecc.bytes); chip->ecc.bytes);
dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.total = %d\n", dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.total = %d\n",
chip->ecc.total); chip->ecc.total);
dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.layout = %p\n", dev_dbg(priv->dev, "fsl_elbc_init: mtd->ooblayout = %p\n",
chip->ecc.layout); mtd->ooblayout);
dev_dbg(priv->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags); 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->size = %lld\n", mtd->size);
dev_dbg(priv->dev, "fsl_elbc_init: mtd->erasesize = %d\n", dev_dbg(priv->dev, "fsl_elbc_init: mtd->erasesize = %d\n",
...@@ -675,14 +696,6 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) ...@@ -675,14 +696,6 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
} else if (mtd->writesize == 2048) { } else if (mtd->writesize == 2048) {
priv->page_size = 1; priv->page_size = 1;
setbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS); 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 { } else {
dev_err(priv->dev, dev_err(priv->dev,
"fsl_elbc_init: page size %d is not supported\n", "fsl_elbc_init: page size %d is not supported\n",
...@@ -780,9 +793,7 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) ...@@ -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) == if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) ==
BR_DECC_CHK_GEN) { BR_DECC_CHK_GEN) {
chip->ecc.mode = NAND_ECC_HW; chip->ecc.mode = NAND_ECC_HW;
/* put in small page settings and adjust later if needed */ mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops);
chip->ecc.layout = (priv->fmr & FMR_ECCM) ?
&fsl_elbc_oob_sp_eccm1 : &fsl_elbc_oob_sp_eccm0;
chip->ecc.size = 512; chip->ecc.size = 512;
chip->ecc.bytes = 3; chip->ecc.bytes = 3;
chip->ecc.strength = 1; chip->ecc.strength = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment