From 3aee8a3a88fa533b74fb75640ca23001358e5476 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 16 Oct 2020 10:26:26 -0300 Subject: [PATCH] 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: d7157ff49a5b ("mtd: rawnand: Use the ECC framework user input parsing bits") Reported-by: Han Xu Signed-off-by: Fabio Estevam Tested-by: Han Xu Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20201016132626.30112-1-festevam@gmail.com --- drivers/mtd/nand/raw/fsl_ifc_nand.c | 43 ++++++++++++++++------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c index 0e7a9b64301e..e345f9d9f8e8 100644 --- a/drivers/mtd/nand/raw/fsl_ifc_nand.c +++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c @@ -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;