Commit 3aee8a3a authored by Fabio Estevam's avatar Fabio Estevam Committed by Miquel Raynal
Browse files

mtd: rawnand: ifc: Move the ECC engine initialization to the right place



No ECC initialization should happen during the host controller probe.

In fact, we need the probe function to call nand_scan() in order to:
- identify the device, its capabilities and constraints (nand_scan_ident())
- configure the ECC engine accordingly (->attach_chip())
- scan its content and prepare the core (nand_scan_tail())

Moving these lines to fsl_ifc_attach_chip() fixes a regression caused by
a previous commit supposed to clarify these steps.

Based on a fix done for the mxc_nand driver by Miquel Raynal.

Fixes: d7157ff4 ("mtd: rawnand: Use the ECC framework user input parsing bits")
Reported-by: default avatarHan Xu <xhnjupt@gmail.com>
Signed-off-by: default avatarFabio Estevam <festevam@gmail.com>
Tested-by: default avatarHan Xu <xhnjupt@gmail.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20201016132626.30112-1-festevam@gmail.com
parent 1b8d1070
Loading
Loading
Loading
Loading
+24 −19
Original line number Diff line number Diff line
@@ -707,6 +707,30 @@ static int fsl_ifc_attach_chip(struct nand_chip *chip)
{
	struct mtd_info *mtd = nand_to_mtd(chip);
	struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
	struct fsl_ifc_ctrl *ctrl = priv->ctrl;
	struct fsl_ifc_global __iomem *ifc_global = ctrl->gregs;
	u32 csor;

	csor = ifc_in32(&ifc_global->csor_cs[priv->bank].csor);

	/* Must also set CSOR_NAND_ECC_ENC_EN if DEC_EN set */
	if (csor & CSOR_NAND_ECC_DEC_EN) {
		chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
		mtd_set_ooblayout(mtd, &fsl_ifc_ooblayout_ops);

		/* Hardware generates ECC per 512 Bytes */
		chip->ecc.size = 512;
		if ((csor & CSOR_NAND_ECC_MODE_MASK) == CSOR_NAND_ECC_MODE_4) {
			chip->ecc.bytes = 8;
			chip->ecc.strength = 4;
		} else {
			chip->ecc.bytes = 16;
			chip->ecc.strength = 8;
		}
	} else {
		chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
	}

	dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__,
		nanddev_ntargets(&chip->base));
@@ -910,25 +934,6 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
		return -ENODEV;
	}

	/* Must also set CSOR_NAND_ECC_ENC_EN if DEC_EN set */
	if (csor & CSOR_NAND_ECC_DEC_EN) {
		chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
		mtd_set_ooblayout(mtd, &fsl_ifc_ooblayout_ops);

		/* Hardware generates ECC per 512 Bytes */
		chip->ecc.size = 512;
		if ((csor & CSOR_NAND_ECC_MODE_MASK) == CSOR_NAND_ECC_MODE_4) {
			chip->ecc.bytes = 8;
			chip->ecc.strength = 4;
		} else {
			chip->ecc.bytes = 16;
			chip->ecc.strength = 8;
		}
	} else {
		chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
	}

	ret = fsl_ifc_sram_init(priv);
	if (ret)
		return ret;