From: Baruch Siach <baruch@tkos.co.il>
To: Sascha Hauer <s.hauer@pengutronix.de>
Cc: barebox@lists.infradead.org
Subject: [PATCH] mxc_nand: fix correct_data function
Date: Mon, 15 Nov 2010 14:08:14 +0200 [thread overview]
Message-ID: <8b25e654c4237599ff3d2252e34c5e890480c7f7.1289822485.git.baruch@tkos.co.il> (raw)
In-Reply-To: <20101111103259.GY6017@pengutronix.de>
From: Sascha Hauer <s.hauer@pengutronix.de>
Commit da1ad19 upstream.
The v2 controller has a totally different mechanism to check
whether the data we read had ecc errors or not. Implement this.
The mechanism in the v2 controller happens to be identical to
the v3 controller.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
Hi Sascha,
This should apply cleanly on v2010.09.0, v2010.10.0, and v2010.11.0. I tested
this on v2010.09.0 with i.MX25 (not the actual correction algorithm, just
verified that it doesn't break anything). Please consider using this for a
stable release.
drivers/mtd/nand/nand_imx.c | 73 ++++++++++++++++++++++++++++++++++---------
1 files changed, 58 insertions(+), 15 deletions(-)
diff --git a/drivers/mtd/nand/nand_imx.c b/drivers/mtd/nand/nand_imx.c
index 5454e32..8bfa2ba 100644
--- a/drivers/mtd/nand/nand_imx.c
+++ b/drivers/mtd/nand/nand_imx.c
@@ -43,10 +43,15 @@
#define NFC_FLASH_ADDR 0xE06
#define NFC_FLASH_CMD 0xE08
#define NFC_CONFIG 0xE0A
-#define NFC_ECC_STATUS_RESULT 0xE0C
-#define NFC_RSLTMAIN_AREA 0xE0E
-#define NFC_RSLTSPARE_AREA 0xE10
-#define NFC_SPAS 0xe10
+
+#define NFC_V1_ECC_STATUS_RESULT 0xE0C
+#define NFC_V1_RSLTMAIN_AREA 0xE0E
+#define NFC_V1_RSLTSPARE_AREA 0xE10
+
+#define NFC_V2_ECC_STATUS_RESULT1 0xE0C
+#define NFC_V2_ECC_STATUS_RESULT2 0xE0E
+#define NFC_V2_SPAS 0xE10
+
#define NFC_WRPROT 0xE12
#define NFC_V1_UNLOCKSTART_BLKADDR 0xe14
#define NFC_V1_UNLOCKEND_BLKADDR 0xe16
@@ -153,6 +158,7 @@ struct imx_nand_host {
uint8_t *data_buf;
unsigned int buf_start;
int spare_len;
+ int eccsize;
};
@@ -416,7 +422,7 @@ static void imx_nand_enable_hwecc(struct mtd_info *mtd, int mode)
*/
}
-static int imx_nand_correct_data(struct mtd_info *mtd, u_char * dat,
+static int imx_nand_correct_data_v1(struct mtd_info *mtd, u_char * dat,
u_char * read_ecc, u_char * calc_ecc)
{
struct nand_chip *nand_chip = mtd->priv;
@@ -427,7 +433,7 @@ static int imx_nand_correct_data(struct mtd_info *mtd, u_char * dat,
* additional correction. 2-Bit errors cannot be corrected by
* HW ECC, so we need to return failure
*/
- u16 ecc_status = readw(host->regs + NFC_ECC_STATUS_RESULT);
+ u16 ecc_status = readw(host->regs + NFC_V1_ECC_STATUS_RESULT);
if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
MTD_DEBUG(MTD_DEBUG_LEVEL0,
@@ -438,6 +444,38 @@ static int imx_nand_correct_data(struct mtd_info *mtd, u_char * dat,
return 0;
}
+static int imx_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
+ u_char *read_ecc, u_char *calc_ecc)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct imx_nand_host *host = nand_chip->priv;
+ u32 ecc_stat, err;
+ int no_subpages = mtd->writesize >> 9;
+ int ret = 0;
+ u8 ecc_bit_mask, err_limit;
+
+ ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf;
+ err_limit = (host->eccsize == 4) ? 0x4 : 0x8;
+
+ ecc_stat = readl(host->regs + NFC_V2_ECC_STATUS_RESULT1);
+
+ do {
+ err = ecc_stat & ecc_bit_mask;
+ if (err > err_limit) {
+ printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
+ return -1;
+ } else {
+ ret += err;
+ }
+ ecc_stat >>= 4;
+ } while (--no_subpages);
+
+ mtd->ecc_stats.corrected += ret;
+ pr_debug("%d Symbol Correctable RS-ECC Error\n", ret);
+
+ return ret;
+}
+
static int imx_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat,
u_char * ecc_code)
{
@@ -864,12 +902,14 @@ static int __init imxnd_probe(struct device_d *dev)
host->regs = host->base + 0x1000;
host->spare0 = host->base + 0x1000;
host->spare_len = 64;
+ host->eccsize = 1;
oob_smallpage = &nandv2_hw_eccoob_smallpage;
oob_largepage = &nandv2_hw_eccoob_largepage;
} else if (nfc_is_v1()) {
host->regs = host->base;
host->spare0 = host->base + 0x800;
host->spare_len = 16;
+ host->eccsize = 4;
oob_smallpage = &nandv1_hw_eccoob_smallpage;
oob_largepage = &nandv1_hw_eccoob_largepage;
}
@@ -911,7 +951,10 @@ static int __init imxnd_probe(struct device_d *dev)
if (pdata->hw_ecc) {
this->ecc.calculate = imx_nand_calculate_ecc;
this->ecc.hwctl = imx_nand_enable_hwecc;
- this->ecc.correct = imx_nand_correct_data;
+ if (nfc_is_v1())
+ this->ecc.correct = imx_nand_correct_data_v1;
+ else
+ this->ecc.correct = imx_nand_correct_data_v2_v3;
this->ecc.mode = NAND_ECC_HW;
this->ecc.size = 512;
tmp = readw(host->regs + NFC_CONFIG1);
@@ -974,17 +1017,17 @@ static int __init imxnd_probe(struct device_d *dev)
this->ecc.layout = oob_largepage;
host->pagesize_2k = 1;
if (nfc_is_v21()) {
- tmp = readw(host->regs + NFC_SPAS);
+ tmp = readw(host->regs + NFC_V2_SPAS);
tmp &= 0xff00;
tmp |= NFC_SPAS_64;
- writew(tmp, host->regs + NFC_SPAS);
+ writew(tmp, host->regs + NFC_V2_SPAS);
}
} else {
if (nfc_is_v21()) {
- tmp = readw(host->regs + NFC_SPAS);
+ tmp = readw(host->regs + NFC_V2_SPAS);
tmp &= 0xff00;
tmp |= NFC_SPAS_16;
- writew(tmp, host->regs + NFC_SPAS);
+ writew(tmp, host->regs + NFC_V2_SPAS);
}
}
@@ -1109,15 +1152,15 @@ void __nand_boot_init imx_nand_load_image(void *dest, int size)
if (nfc_is_v21()) {
if (host.pagesize_2k) {
- tmp = readw(host.regs + NFC_SPAS);
+ tmp = readw(host.regs + NFC_V2_SPAS);
tmp &= 0xff00;
tmp |= NFC_SPAS_64;
- writew(tmp, host.regs + NFC_SPAS);
+ writew(tmp, host.regs + NFC_V2_SPAS);
} else {
- tmp = readw(host.regs + NFC_SPAS);
+ tmp = readw(host.regs + NFC_V2_SPAS);
tmp &= 0xff00;
tmp |= NFC_SPAS_16;
- writew(tmp, host.regs + NFC_SPAS);
+ writew(tmp, host.regs + NFC_V2_SPAS);
}
}
--
1.7.2.3
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2010-11-15 12:09 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-10 14:53 add i.MX51 Nand support Sascha Hauer
2010-11-10 14:53 ` [PATCH 01/13] NAND: reset chips before usage like the kernel does Sascha Hauer
2010-11-10 14:53 ` [PATCH 02/13] imx_nand: remove 0xe00 offset from registers Sascha Hauer
2010-11-10 14:53 ` [PATCH 03/13] imx_nand: rework get_dev_status Sascha Hauer
2010-11-10 14:53 ` [PATCH 04/13] imx nand: remove unnecessary register write Sascha Hauer
2010-11-10 14:53 ` [PATCH 05/13] imx_nand: make some internally used functions overwriteable Sascha Hauer
2010-11-10 14:53 ` [PATCH 06/13] imx nand: do not read-modify-write SPAS register Sascha Hauer
2010-11-10 14:53 ` [PATCH 07/13] imx nand: add V1_V2 namespace to registers Sascha Hauer
2010-11-10 14:53 ` [PATCH 08/13] mxc_nand: fix correct_data function Sascha Hauer
2010-11-11 5:25 ` Baruch Siach
2010-11-11 10:32 ` Sascha Hauer
2010-11-15 12:08 ` Baruch Siach [this message]
2010-11-10 14:53 ` [PATCH 09/13] imx nand: move initialization to preset function Sascha Hauer
2010-11-10 14:53 ` [PATCH 10/13] imx nand: introduce overwritable check_int function Sascha Hauer
2010-11-10 14:53 ` [PATCH 11/13] imx nand: Add v3 (i.MX51) support Sascha Hauer
2010-11-10 14:53 ` [PATCH 12/13] fb: set id for framebuffer device correctly Sascha Hauer
2010-11-10 14:55 ` Sascha Hauer
2010-11-10 14:53 ` [PATCH 13/13] ARM i.MX51: Add nand device Sascha Hauer
2010-11-11 5:26 ` add i.MX51 Nand support Jean-Christophe PLAGNIOL-VILLARD
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8b25e654c4237599ff3d2252e34c5e890480c7f7.1289822485.git.baruch@tkos.co.il \
--to=baruch@tkos.co.il \
--cc=barebox@lists.infradead.org \
--cc=s.hauer@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox