Commit f6424c22 authored by Marek Behún's avatar Marek Behún Committed by Miquel Raynal

mtd: rawnand: fsl_elbc: Make SW ECC work

Move the code that choses ECC into _attach_chip, which is executed only
after the chip->ecc.* properties were loaded from device-tree. This way
we know which ECC method was chosen by the device-tree and can set
methods appropriately.

The chip->ecc.*page methods should be set to fsl_elbc_*page only in HW
ECC mode.
Signed-off-by: default avatarMarek Behún <marek.behun@nic.cz>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
parent 070fb974
...@@ -730,13 +730,30 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) ...@@ -730,13 +730,30 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
chip->controller = &elbc_fcm_ctrl->controller; chip->controller = &elbc_fcm_ctrl->controller;
nand_set_controller_data(chip, priv); nand_set_controller_data(chip, priv);
chip->ecc.read_page = fsl_elbc_read_page; return 0;
chip->ecc.write_page = fsl_elbc_write_page; }
chip->ecc.write_subpage = fsl_elbc_write_subpage;
static int fsl_elbc_attach_chip(struct nand_chip *chip)
{
struct mtd_info *mtd = nand_to_mtd(chip);
struct fsl_elbc_mtd *priv = nand_get_controller_data(chip);
struct fsl_lbc_ctrl *ctrl = priv->ctrl;
struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
unsigned int al;
switch (chip->ecc.mode) {
/*
* if ECC was not chosen in DT, decide whether to use HW or SW ECC from
* CS Base Register
*/
case NAND_ECC_NONE:
/* If CS Base Register selects full hardware ECC then use it */ /* If CS Base Register selects full hardware ECC then use it */
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.read_page = fsl_elbc_read_page;
chip->ecc.write_page = fsl_elbc_write_page;
chip->ecc.write_subpage = fsl_elbc_write_subpage;
chip->ecc.mode = NAND_ECC_HW; chip->ecc.mode = NAND_ECC_HW;
mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops); mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops);
chip->ecc.size = 512; chip->ecc.size = 512;
...@@ -747,17 +764,16 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) ...@@ -747,17 +764,16 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
chip->ecc.mode = NAND_ECC_SOFT; chip->ecc.mode = NAND_ECC_SOFT;
chip->ecc.algo = NAND_ECC_HAMMING; chip->ecc.algo = NAND_ECC_HAMMING;
} }
break;
return 0; /* if SW ECC was chosen in DT, we do not need to set anything here */
} case NAND_ECC_SOFT:
break;
static int fsl_elbc_attach_chip(struct nand_chip *chip) /* should we also implement NAND_ECC_HW to do as the code above? */
{ default:
struct mtd_info *mtd = nand_to_mtd(chip); return -EINVAL;
struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); }
struct fsl_lbc_ctrl *ctrl = priv->ctrl;
struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
unsigned int al;
/* calculate FMR Address Length field */ /* calculate FMR Address Length field */
al = 0; al = 0;
......
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