diff mbox series

mtd: rawnand: fsl_elbc: Propagate HW ECC settings to HW

Message ID 20230128134111.32559-1-pali@kernel.org
State Accepted
Headers show
Series mtd: rawnand: fsl_elbc: Propagate HW ECC settings to HW | expand

Commit Message

Pali Rohár Jan. 28, 2023, 1:41 p.m. UTC
It is possible that current chip->ecc.engine_type value does not match to
configured HW value (if HW ECC checking and generating is enabled or not).

This can happen with old U-Boot bootloader version which either does not
initialize NAND (and let it in some default unusable state) or initialize
NAND with different parameters than what is specified in kernel DTS file.

So if kernel chose to use some chip->ecc.engine_type settings (e.g. from
DTS file) then do not depend on bootloader HW configuration and configures
HW ECC settings according to chip->ecc.engine_type value.

BR_DECC must be set to BR_DECC_CHK_GEN when HW is doing ECC (both
generating and checking), or to BR_DECC_OFF when HW is not doing ECC.

This change fixes usage of SW ECC support in case bootloader explicitly
enabled HW ECC support and kernel DTS file has specified to use SW ECC.
(Of course this works only in case when NAND is not a boot device and both
bootloader and kernel are loaded from different location, e.g. FLASH NOR.)

Fixes: f6424c22aa36 ("mtd: rawnand: fsl_elbc: Make SW ECC work")
Signed-off-by: Pali Rohár <pali@kernel.org>
---
 drivers/mtd/nand/raw/fsl_elbc_nand.c | 8 ++++++++
 1 file changed, 8 insertions(+)

Comments

Miquel Raynal Jan. 30, 2023, 4:18 p.m. UTC | #1
On Sat, 2023-01-28 at 13:41:11 UTC, =?utf-8?q?Pali_Roh=C3=A1r?= wrote:
> It is possible that current chip->ecc.engine_type value does not match to
> configured HW value (if HW ECC checking and generating is enabled or not).
> 
> This can happen with old U-Boot bootloader version which either does not
> initialize NAND (and let it in some default unusable state) or initialize
> NAND with different parameters than what is specified in kernel DTS file.
> 
> So if kernel chose to use some chip->ecc.engine_type settings (e.g. from
> DTS file) then do not depend on bootloader HW configuration and configures
> HW ECC settings according to chip->ecc.engine_type value.
> 
> BR_DECC must be set to BR_DECC_CHK_GEN when HW is doing ECC (both
> generating and checking), or to BR_DECC_OFF when HW is not doing ECC.
> 
> This change fixes usage of SW ECC support in case bootloader explicitly
> enabled HW ECC support and kernel DTS file has specified to use SW ECC.
> (Of course this works only in case when NAND is not a boot device and both
> bootloader and kernel are loaded from different location, e.g. FLASH NOR.)
> 
> Fixes: f6424c22aa36 ("mtd: rawnand: fsl_elbc: Make SW ECC work")
> Signed-off-by: Pali Rohár <pali@kernel.org>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel
diff mbox series

Patch

diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
index a18d121396aa..e25119e58b69 100644
--- a/drivers/mtd/nand/raw/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
@@ -725,6 +725,7 @@  static int fsl_elbc_attach_chip(struct nand_chip *chip)
 	struct fsl_lbc_ctrl *ctrl = priv->ctrl;
 	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
 	unsigned int al;
+	u32 br;
 
 	/*
 	 * if ECC was not chosen in DT, decide whether to use HW or SW ECC from
@@ -764,6 +765,13 @@  static int fsl_elbc_attach_chip(struct nand_chip *chip)
 		return -EINVAL;
 	}
 
+	/* enable/disable HW ECC checking and generating based on if HW ECC was chosen */
+	br = in_be32(&lbc->bank[priv->bank].br) & ~BR_DECC;
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST)
+		out_be32(&lbc->bank[priv->bank].br, br | BR_DECC_CHK_GEN);
+	else
+		out_be32(&lbc->bank[priv->bank].br, br | BR_DECC_OFF);
+
 	/* calculate FMR Address Length field */
 	al = 0;
 	if (chip->pagemask & 0xffff0000)