Re: [PATCH] mtd: rawnand: fsl_elbc: Fix none ECC mode

From: Pali Rohár
Date: Mon Aug 08 2022 - 14:26:51 EST


PING?

On Thursday 07 July 2022 20:43:28 Pali Rohár wrote:
> Commit f6424c22aa36 ("mtd: rawnand: fsl_elbc: Make SW ECC work") added
> support for specifying ECC mode via DTS and skipping autodetection.
>
> But it broke explicit specification of HW ECC mode in DTS as correct
> settings for HW ECC mode are applied only when NONE mode or nothing was
> specified in DTS file.
>
> Also it started aliasing NONE mode to be same as when ECC mode was not
> specified and disallowed usage of ON_DIE mode.
>
> Fix all these issues. Use autodetection of ECC mode only in case when mode
> was really not specified in DTS file by checking that ecc value is invalid.
> Set HW ECC settings either when HW ECC was specified in DTS or it was
> autodetected. And do not fail when ON_DIE mode is set.
>
> Fixes: f6424c22aa36 ("mtd: rawnand: fsl_elbc: Make SW ECC work")
> Signed-off-by: Pali Rohár <pali@xxxxxxxxxx>
> ---
> drivers/mtd/nand/raw/fsl_elbc_nand.c | 28 ++++++++++++++++------------
> 1 file changed, 16 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
> index aab93b9e6052..a18d121396aa 100644
> --- a/drivers/mtd/nand/raw/fsl_elbc_nand.c
> +++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
> @@ -726,36 +726,40 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip)
> struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
> unsigned int al;
>
> - switch (chip->ecc.engine_type) {
> /*
> * if ECC was not chosen in DT, decide whether to use HW or SW ECC from
> * CS Base Register
> */
> - case NAND_ECC_ENGINE_TYPE_NONE:
> + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_INVALID) {
> /* If CS Base Register selects full hardware ECC then use it */
> if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) ==
> 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.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
> - mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops);
> - chip->ecc.size = 512;
> - chip->ecc.bytes = 3;
> - chip->ecc.strength = 1;
> } else {
> /* otherwise fall back to default software ECC */
> chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
> chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
> }
> + }
> +
> + switch (chip->ecc.engine_type) {
> + /* if HW ECC was chosen, setup ecc and oob layout */
> + case NAND_ECC_ENGINE_TYPE_ON_HOST:
> + chip->ecc.read_page = fsl_elbc_read_page;
> + chip->ecc.write_page = fsl_elbc_write_page;
> + chip->ecc.write_subpage = fsl_elbc_write_subpage;
> + mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops);
> + chip->ecc.size = 512;
> + chip->ecc.bytes = 3;
> + chip->ecc.strength = 1;
> break;
>
> - /* if SW ECC was chosen in DT, we do not need to set anything here */
> + /* if none or SW ECC was chosen, we do not need to set anything here */
> + case NAND_ECC_ENGINE_TYPE_NONE:
> case NAND_ECC_ENGINE_TYPE_SOFT:
> + case NAND_ECC_ENGINE_TYPE_ON_DIE:
> break;
>
> - /* should we also implement *_ECC_ENGINE_CONTROLLER to do as above? */
> default:
> return -EINVAL;
> }
> --
> 2.20.1
>