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

Pali Rohár pali at kernel.org
Mon Aug 8 11:26:42 PDT 2022


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 at kernel.org>
> ---
>  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
> 



More information about the linux-mtd mailing list