mtd: rawnand: fsl_elbc: Use ECC configuration from device tree
authorPali Rohár <pali@kernel.org>
Mon, 4 Apr 2022 16:17:20 +0000 (18:17 +0200)
committerPriyanka Jain <priyanka.jain@nxp.com>
Tue, 26 Apr 2022 11:48:39 +0000 (17:18 +0530)
Initialize ECC configuration after nand_scan_ident() call and only in case
nand_scan_ident() have not done it. nand_scan_ident() fills ECC
configuration from device tree.

Fixes usage of NAND_ECC_SOFT_BCH when it is specified in device tree.

Signed-off-by: Pali Rohár <pali@kernel.org>
Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
drivers/mtd/nand/raw/fsl_elbc_nand.c

index f8d2bdf..e734139 100644 (file)
@@ -737,36 +737,39 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr, ofnode flash_node)
        nand->controller = &elbc_ctrl->controller;
        nand_set_controller_data(nand, priv);
 
-       nand->ecc.read_page = fsl_elbc_read_page;
-       nand->ecc.write_page = fsl_elbc_write_page;
-       nand->ecc.write_subpage = fsl_elbc_write_subpage;
-
        priv->fmr = (15 << FMR_CWTO_SHIFT) | (2 << FMR_AL_SHIFT);
 
-       /* If CS Base Register selects full hardware ECC then use it */
-       if ((br & BR_DECC) == BR_DECC_CHK_GEN) {
-               nand->ecc.mode = NAND_ECC_HW;
-
-               nand->ecc.layout = (priv->fmr & FMR_ECCM) ?
-                                  &fsl_elbc_oob_sp_eccm1 :
-                                  &fsl_elbc_oob_sp_eccm0;
+       ret = nand_scan_ident(mtd, 1, NULL);
+       if (ret)
+               return ret;
 
-               nand->ecc.size = 512;
-               nand->ecc.bytes = 3;
-               nand->ecc.steps = 1;
-               nand->ecc.strength = 1;
-       } else {
-               /* otherwise fall back to software ECC */
+       /* If nand_scan_ident() has not selected ecc.mode, do it now */
+       if (nand->ecc.mode == NAND_ECC_NONE) {
+               /* If CS Base Register selects full hardware ECC then use it */
+               if ((br & BR_DECC) == BR_DECC_CHK_GEN) {
+                       nand->ecc.mode = NAND_ECC_HW;
+                       nand->ecc.layout = (priv->fmr & FMR_ECCM) ?
+                                          &fsl_elbc_oob_sp_eccm1 :
+                                          &fsl_elbc_oob_sp_eccm0;
+                       nand->ecc.size = 512;
+                       nand->ecc.bytes = 3;
+                       nand->ecc.steps = 1;
+                       nand->ecc.strength = 1;
+               } else {
+                       /* otherwise fall back to software ECC */
 #if defined(CONFIG_NAND_ECC_BCH)
-               nand->ecc.mode = NAND_ECC_SOFT_BCH;
+                       nand->ecc.mode = NAND_ECC_SOFT_BCH;
 #else
-               nand->ecc.mode = NAND_ECC_SOFT;
+                       nand->ecc.mode = NAND_ECC_SOFT;
 #endif
+               }
        }
 
-       ret = nand_scan_ident(mtd, 1, NULL);
-       if (ret)
-               return ret;
+       if (nand->ecc.mode == NAND_ECC_HW) {
+               nand->ecc.read_page = fsl_elbc_read_page;
+               nand->ecc.write_page = fsl_elbc_write_page;
+               nand->ecc.write_subpage = fsl_elbc_write_subpage;
+       }
 
        /* Large-page-specific setup */
        if (mtd->writesize == 2048) {
@@ -785,7 +788,7 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr, ofnode flash_node)
                priv->fmr |= FMR_ECCM;
 
                /* adjust ecc setup if needed */
-               if ((br & BR_DECC) == BR_DECC_CHK_GEN) {
+               if (nand->ecc.mode == NAND_ECC_HW) {
                        nand->ecc.steps = 4;
                        nand->ecc.layout = (priv->fmr & FMR_ECCM) ?
                                           &fsl_elbc_oob_lp_eccm1 :