Patchwork [U-Boot,v2] NAND: davinci: choose correct 1-bit h/w ECC reg

login
register
mail settings
Submitter Laurence Withers
Date Sept. 26, 2011, 4:02 p.m.
Message ID <E1R9Dgr-00053H-7g@rhodium.platinum.guralp.com>
Download mbox | patch
Permalink /patch/116933/
State Accepted
Headers show

Comments

Laurence Withers - Sept. 26, 2011, 4:02 p.m.
In nand_davinci_readecc(), select the correct NANDF<n>ECC register based
on CONFIG_SYS_NAND_CS rather than hardcoding the choice of NANDF1ECC.
This allows 1-bit hardware ECC to work with chip select other than CS2.

Note this now matches the usage in nand_davinci_enable_hwecc(), which
already had the correct handling, and allows refactoring to a single
function encapsulating the register read.

Without this fix, writing NAND pages to a chip not wired to CS2 would
result in in the ECC calculation always returning FFFFFF for each
512-byte segment, and reading back a correctly written page (one with
ECC intact) would always fail. With this fix, the ECC is written and
verified correctly.

Signed-off-by: Laurence Withers <lwithers@guralp.com>
---
Changes for v2:
  Add Signed-off-by to commit message.
---
 drivers/mtd/nand/davinci_nand.c |   26 +++++++++++++-------------
 1 files changed, 13 insertions(+), 13 deletions(-)
Laurence Withers - Oct. 10, 2011, 1:45 p.m.
On Mon, Sep 26, 2011 at 04:02:30PM +0000, Laurence Withers wrote:
> In nand_davinci_readecc(), select the correct NANDF<n>ECC register based
> on CONFIG_SYS_NAND_CS rather than hardcoding the choice of NANDF1ECC.
> This allows 1-bit hardware ECC to work with chip select other than CS2.
> 
> Note this now matches the usage in nand_davinci_enable_hwecc(), which
> already had the correct handling, and allows refactoring to a single
> function encapsulating the register read.
> 
> Without this fix, writing NAND pages to a chip not wired to CS2 would
> result in in the ECC calculation always returning FFFFFF for each
> 512-byte segment, and reading back a correctly written page (one with
> ECC intact) would always fail. With this fix, the ECC is written and
> verified correctly.
> 
> Signed-off-by: Laurence Withers <lwithers@guralp.com>

Does anybody have any comments on this bugfix? If not, can it be accepted?

Many thanks, and bye for now,
Scott Wood - Oct. 10, 2011, 8:29 p.m.
On 09/26/2011 11:02 AM, Laurence Withers wrote:
> In nand_davinci_readecc(), select the correct NANDF<n>ECC register based
> on CONFIG_SYS_NAND_CS rather than hardcoding the choice of NANDF1ECC.
> This allows 1-bit hardware ECC to work with chip select other than CS2.
> 
> Note this now matches the usage in nand_davinci_enable_hwecc(), which
> already had the correct handling, and allows refactoring to a single
> function encapsulating the register read.
> 
> Without this fix, writing NAND pages to a chip not wired to CS2 would
> result in in the ECC calculation always returning FFFFFF for each
> 512-byte segment, and reading back a correctly written page (one with
> ECC intact) would always fail. With this fix, the ECC is written and
> verified correctly.
> 
> Signed-off-by: Laurence Withers <lwithers@guralp.com>
> ---
> Changes for v2:
>   Add Signed-off-by to commit message.
> ---
>  drivers/mtd/nand/davinci_nand.c |   26 +++++++++++++-------------
>  1 files changed, 13 insertions(+), 13 deletions(-)

Applied to u-boot-nand-flash

-Scott

Patch

diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index d41579c..e8506dd 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -176,12 +176,22 @@  static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd,
 
 #ifdef CONFIG_SYS_NAND_HW_ECC
 
+static u_int32_t nand_davinci_readecc(struct mtd_info *mtd)
+{
+	u_int32_t	ecc = 0;
+
+	ecc = __raw_readl(&(davinci_emif_regs->nandfecc[
+				CONFIG_SYS_NAND_CS - 2]));
+
+	return ecc;
+}
+
 static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode)
 {
 	u_int32_t	val;
 
-	(void)__raw_readl(&(davinci_emif_regs->nandfecc[
-				CONFIG_SYS_NAND_CS - 2]));
+	/* reading the ECC result register resets the ECC calculation */
+	nand_davinci_readecc(mtd);
 
 	val = __raw_readl(&davinci_emif_regs->nandfcr);
 	val |= DAVINCI_NANDFCR_NAND_ENABLE(CONFIG_SYS_NAND_CS);
@@ -189,22 +199,12 @@  static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode)
 	__raw_writel(val, &davinci_emif_regs->nandfcr);
 }
 
-static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region)
-{
-	u_int32_t	ecc = 0;
-
-	ecc = __raw_readl(&(davinci_emif_regs->nandfecc[region - 1]));
-
-	return ecc;
-}
-
 static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
 		u_char *ecc_code)
 {
 	u_int32_t		tmp;
-	const int region = 1;
 
-	tmp = nand_davinci_readecc(mtd, region);
+	tmp = nand_davinci_readecc(mtd);
 
 	/* Squeeze 4 bytes ECC into 3 bytes by removing RESERVED bits
 	 * and shifting. RESERVED bits are 31 to 28 and 15 to 12. */