linux-mtd.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] mtd-nand: davinci: correct 4-bit error correction
@ 2010-07-15  5:10 Sudhakar Rajashekhara
  2010-07-15 11:01 ` Jon Povey
  0 siblings, 1 reply; 7+ messages in thread
From: Sudhakar Rajashekhara @ 2010-07-15  5:10 UTC (permalink / raw)
  To: linux-mtd
  Cc: dwmw2, akpm, Sudhakar Rajashekhara, nsnehaprabha,
	davinci-linux-open-source

On TI's DA830/OMAP-L137, DA850/OMAP-L138 and DM365, after setting the
4BITECC_ADD_CALC_START bit in the NAND Flash control register to 1 and
before waiting for the NAND Flash status register to be equal to 1, 2 or
3, we have to wait till the ECC HW goes to correction state.  Without this
wait, ECC correction calculations will not be proper.

This has been tested on DA830/OMAP-L137, DA850/OMAP-L138, DM355 and DM365
EVMs.

Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj@ti.com>
Acked-by: Sneha Narnakaje <nsnehaprabha@ti.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
Since v1:
a. Timeout has been changed from 100 msec to 100 usec.
b. Comment above the do, while loop was not matching the code.
   This has been corrected.
c. Initialization of 'timeo' variable has been moved down.
d. It was observed that, while calculating the time in the loop,
   if there is a context switch between setting the 4BITECC_ADD_CALC_START
   bit and reading of ECC_STATE field, then the loop will not come out
   until the timeout happens. To prevent the context switch, spin_lock_irqsave
   and spin_unlock_irqrestore are used.

 drivers/mtd/nand/davinci_nand.c |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 9c9d893..1e2657c 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -311,7 +311,11 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd,
 	unsigned short ecc10[8];
 	unsigned short *ecc16;
 	u32 syndrome[4];
+	u32 ecc_state;
 	unsigned num_errors, corrected;
+	unsigned long timeo;
+	DEFINE_SPINLOCK(ecc_spin_lock);
+	unsigned long flags;
 
 	/* All bytes 0xff?  It's an erased page; ignore its ECC. */
 	for (i = 0; i < 10; i++) {
@@ -355,12 +359,30 @@ compare:
 	 */
 	davinci_nand_readl(info, NAND_ERR_ADD1_OFFSET);
 
+	spin_lock_irqsave(&ecc_spin_lock, flags);
 	/* Start address calculation, and wait for it to complete.
 	 * We _could_ start reading more data while this is working,
 	 * to speed up the overall page read.
 	 */
 	davinci_nand_writel(info, NANDFCR_OFFSET,
 			davinci_nand_readl(info, NANDFCR_OFFSET) | BIT(13));
+
+	/*
+	 * ECC_STATE field reads 0x3 (Error correction complete) immediately
+	 * after setting the 4BITECC_ADD_CALC_START bit. So if you immediately
+	 * begin trying to poll for the state, you may fall right out of your
+	 * loop without any of the correction calculations having taken place.
+	 * The recommendation from the hardware team is to wait till ECC_STATE
+	 * reads >= 4, which means ECC HW has entered correction state.
+	 */
+	timeo = jiffies + usecs_to_jiffies(100);
+	do {
+		ecc_state = (davinci_nand_readl(info,
+				NANDFSR_OFFSET) >> 8) & 0x0f;
+		cpu_relax();
+	} while ((ecc_state < 4) && time_before(jiffies, timeo));
+	spin_unlock_irqrestore(&ecc_spin_lock, flags);
+
 	for (;;) {
 		u32	fsr = davinci_nand_readl(info, NANDFSR_OFFSET);
 
-- 
1.5.6

^ permalink raw reply related	[flat|nested] 7+ messages in thread
* [PATCH v2] mtd-nand: davinci: Correct 4-bit error correction
@ 2009-12-10  9:36 Sudhakar Rajashekhara
  0 siblings, 0 replies; 7+ messages in thread
From: Sudhakar Rajashekhara @ 2009-12-10  9:36 UTC (permalink / raw)
  To: linux-mtd
  Cc: akpm, Sudhakar Rajashekhara, nsnehaprabha,
	davinci-linux-open-source

On TI's DA830/OMAP-L137, DA850/OMAP-L138 and DM365, after
setting the 4BITECC_ADD_CALC_START bit in the NAND Flash
control register to 1 and before waiting for the NAND Flash
status register to be equal to 1, 2 or 3, we have to wait
till the ECC HW goes to correction state. Without this wait,
ECC correction calculations will not be proper.

This has been tested on DA830/OMAP-L137, DA850/OMAP-L138,
DM355 and DM365 EVMs.

Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj@ti.com>
Acked-by: Sneha Narnakaje <nsnehaprabha@ti.com>
---
 From the previous version, timeout has been added to come out
 of the infinite loop.

 drivers/mtd/nand/davinci_nand.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index f13f5b9..89f0a0f 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -310,7 +310,9 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd,
 	unsigned short ecc10[8];
 	unsigned short *ecc16;
 	u32 syndrome[4];
+	u32 ecc_state;
 	unsigned num_errors, corrected;
+	unsigned long timeo = jiffies + msecs_to_jiffies(100);
 
 	/* All bytes 0xff?  It's an erased page; ignore its ECC. */
 	for (i = 0; i < 10; i++) {
@@ -360,6 +362,21 @@ compare:
 	 */
 	davinci_nand_writel(info, NANDFCR_OFFSET,
 			davinci_nand_readl(info, NANDFCR_OFFSET) | BIT(13));
+
+	/*
+	 * ECC_STATE field reads 0x3 (Error correction complete) immediately
+	 * after setting the 4BITECC_ADD_CALC_START bit. So if you immediately
+	 * begin trying to poll for the state, you may fall right out of your
+	 * loop without any of the correction calculations having taken place.
+	 * The recommendation from the hardware team is to wait till ECC_STATE
+	 * reads less than 4, which means ECC HW has entered correction state.
+	 */
+	do {
+		ecc_state = (davinci_nand_readl(info,
+				NANDFSR_OFFSET) >> 8) & 0x0f;
+		cpu_relax();
+	} while ((ecc_state < 4) && time_before(jiffies, timeo));
+
 	for (;;) {
 		u32	fsr = davinci_nand_readl(info, NANDFSR_OFFSET);
 
-- 
1.5.6

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-07-23  9:55 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-15  5:10 [PATCH v2] mtd-nand: davinci: correct 4-bit error correction Sudhakar Rajashekhara
2010-07-15 11:01 ` Jon Povey
2010-07-15 11:41   ` Sudhakar Rajashekhara
2010-07-15 12:03     ` Sudhakar Rajashekhara
2010-07-21 22:00       ` Andrew Morton
2010-07-23  9:49         ` Sudhakar Rajashekhara
  -- strict thread matches above, loose matches on Subject: below --
2009-12-10  9:36 [PATCH v2] mtd-nand: davinci: Correct " Sudhakar Rajashekhara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).