* [U-Boot] [PATH] at91: add hwecc method for nand
@ 2010-03-18 6:55 Nikolay Petukhov
2010-03-18 22:46 ` Scott Wood
0 siblings, 1 reply; 13+ messages in thread
From: Nikolay Petukhov @ 2010-03-18 6:55 UTC (permalink / raw)
To: u-boot
Hi, all.
This is a patch to use the hardware ECC controller of
the AT91SAM9260 for the AT91 nand. Taken from the kernel 2.6.33.
To use this it is necessary to add two definitions in config:
CONFIG_ATMEL_NAND_HWECC
CONFIG_SYS_NAND_ECC_BASE (AT91_ECC for the AT91SAM9260 and AT91_ECC0
for the AT91SAM9263 boards)
It has been tested only on AT91SAM9260-EK.
u-boot version : 2009.11
kernel version : 2.6.27(32)
Results of read bandwidth:
u-boot with SWECC: 1MB/s
u-boot with HWECC: 3MB/s
linux with HWECC: 6MB/s
Signed-off-by: Nikolay Petukhov <Nikolay.Petukhov@gmail.com>
diff -uprN u-boot-2009.11/drivers/mtd/nand/atmel_nand.c
u-boot-2009.11-at91-nand-hwecc/drivers/mtd/nand/atmel_nand.c
--- u-boot-2009.11/drivers/mtd/nand/atmel_nand.c 2009-12-16
03:20:54.000000000 +0500
+++ u-boot-2009.11-at91-nand-hwecc/drivers/mtd/nand/atmel_nand.c 2010-03-18
11:15:01.000000000 +0500
@@ -31,6 +31,210 @@
#include <nand.h>
+#ifdef CONFIG_ATMEL_NAND_HWECC
+
+/* Register access macros */
+#define ecc_readl(add, reg) \
+ readl(AT91_BASE_SYS + add + ATMEL_ECC_##reg)
+#define ecc_writel(add, reg, value) \
+ writel((value), AT91_BASE_SYS + add + ATMEL_ECC_##reg)
+
+#include "atmel_nand_ecc.h" /* Hardware ECC registers */
+
+/* oob layout for large page size
+ * bad block info is on bytes 0 and 1
+ * the bytes have to be consecutives to avoid
+ * several NAND_CMD_RNDOUT during read
+ */
+static struct nand_ecclayout atmel_oobinfo_large = {
+ .eccbytes = 4,
+ .eccpos = {60, 61, 62, 63},
+ .oobfree = {
+ {2, 58}
+ },
+};
+
+/* oob layout for small page size
+ * bad block info is on bytes 4 and 5
+ * the bytes have to be consecutives to avoid
+ * several NAND_CMD_RNDOUT during read
+ */
+static struct nand_ecclayout atmel_oobinfo_small = {
+ .eccbytes = 4,
+ .eccpos = {0, 1, 2, 3},
+ .oobfree = {
+ {6, 10}
+ },
+};
+
+/*
+ * Calculate HW ECC
+ *
+ * function called after a write
+ *
+ * mtd: MTD block structure
+ * dat: raw data (unused)
+ * ecc_code: buffer for ECC
+ */
+static int atmel_nand_calculate(struct mtd_info *mtd,
+ const u_char *dat, unsigned char *ecc_code)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ unsigned int ecc_value;
+
+ /* get the first 2 ECC bytes */
+ ecc_value = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, PR);
+
+ ecc_code[0] = ecc_value & 0xFF;
+ ecc_code[1] = (ecc_value >> 8) & 0xFF;
+
+ /* get the last 2 ECC bytes */
+ ecc_value = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, NPR) & ATMEL_ECC_NPARITY;
+
+ ecc_code[2] = ecc_value & 0xFF;
+ ecc_code[3] = (ecc_value >> 8) & 0xFF;
+
+ return 0;
+}
+
+/*
+ * HW ECC read page function
+ *
+ * mtd: mtd info structure
+ * chip: nand chip info structure
+ * buf: buffer to store read data
+ */
+static int atmel_nand_read_page(struct mtd_info *mtd,
+ struct nand_chip *chip, uint8_t *buf, int page)
+{
+ int eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ uint32_t *eccpos = chip->ecc.layout->eccpos;
+ uint8_t *p = buf;
+ uint8_t *oob = chip->oob_poi;
+ uint8_t *ecc_pos;
+ int stat;
+
+ /* read the page */
+ chip->read_buf(mtd, p, eccsize);
+
+ /* move to ECC position if needed */
+ if (eccpos[0] != 0) {
+ /* This only works on large pages
+ * because the ECC controller waits for
+ * NAND_CMD_RNDOUTSTART after the
+ * NAND_CMD_RNDOUT.
+ * anyway, for small pages, the eccpos[0] == 0
+ */
+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
+ mtd->writesize + eccpos[0], -1);
+ }
+
+ /* the ECC controller needs to read the ECC just after the data */
+ ecc_pos = oob + eccpos[0];
+ chip->read_buf(mtd, ecc_pos, eccbytes);
+
+ /* check if there's an error */
+ stat = chip->ecc.correct(mtd, p, oob, NULL);
+
+ if (stat < 0)
+ mtd->ecc_stats.failed++;
+ else
+ mtd->ecc_stats.corrected += stat;
+
+ /* get back to oob start (end of page) */
+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
+
+ /* read the oob */
+ chip->read_buf(mtd, oob, mtd->oobsize);
+
+ return 0;
+}
+
+/*
+ * HW ECC Correction
+ *
+ * function called after a read
+ *
+ * mtd: MTD block structure
+ * dat: raw data read from the chip
+ * read_ecc: ECC from the chip (unused)
+ * isnull: unused
+ *
+ * Detect and correct a 1 bit error for a page
+ */
+static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat,
+ u_char *read_ecc, u_char *isnull)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ //struct atmel_nand_host *host = nand_chip->priv;
+ unsigned int ecc_status, ecc_parity, ecc_mode;
+ unsigned int ecc_word, ecc_bit;
+
+ /* get the status from the Status Register */
+ ecc_status = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, SR);
+
+ /* if there's no error */
+ if (likely(!(ecc_status & ATMEL_ECC_RECERR)))
+ return 0;
+
+ /* get error bit offset (4 bits) */
+ ecc_bit = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, PR) & ATMEL_ECC_BITADDR;
+ /* get word address (12 bits) */
+ ecc_word = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, PR) & ATMEL_ECC_WORDADDR;
+ ecc_word >>= 4;
+
+ /* if there are multiple errors */
+ if (ecc_status & ATMEL_ECC_MULERR) {
+ /* check if it is a freshly erased block
+ * (filled with 0xff) */
+ if ((ecc_bit == ATMEL_ECC_BITADDR)
+ && (ecc_word == (ATMEL_ECC_WORDADDR >> 4))) {
+ /* the block has just been erased, return OK */
+ return 0;
+ }
+ /* it doesn't seems to be a freshly
+ * erased block.
+ * We can't correct so many errors */
+ printk(KERN_WARNING "atmel_nand : multiple errors detected."
+ " Unable to correct.\n");
+ return -EIO;
+ }
+
+ /* if there's a single bit error : we can correct it */
+ if (ecc_status & ATMEL_ECC_ECCERR) {
+ /* there's nothing much to do here.
+ * the bit error is on the ECC itself.
+ */
+ printk(KERN_WARNING "atmel_nand : one bit error on ECC code."
+ " Nothing to correct\n");
+ return 0;
+ }
+
+ printk(KERN_WARNING "atmel_nand : one bit error on data."
+ " (word offset in the page :"
+ " 0x%x bit offset : 0x%x)\n",
+ ecc_word, ecc_bit);
+ /* correct the error */
+ if (nand_chip->options & NAND_BUSWIDTH_16) {
+ /* 16 bits words */
+ ((unsigned short *) dat)[ecc_word] ^= (1 << ecc_bit);
+ } else {
+ /* 8 bits words */
+ dat[ecc_word] ^= (1 << ecc_bit);
+ }
+ printk(KERN_WARNING "atmel_nand : error corrected\n");
+ return 1;
+}
+
+/*
+ * Enable HW ECC : unused on most chips
+ */
+static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
+{
+}
+#endif
+
static void at91_nand_hwcontrol(struct mtd_info *mtd,
int cmd, unsigned int ctrl)
{
@@ -64,6 +268,11 @@ static int at91_nand_ready(struct mtd_in
int board_nand_init(struct nand_chip *nand)
{
+#ifdef CONFIG_ATMEL_NAND_HWECC
+ static int chip_nr = 0;
+ struct mtd_info *mtd;
+#endif
+
nand->ecc.mode = NAND_ECC_SOFT;
#ifdef CONFIG_SYS_NAND_DBW_16
nand->options = NAND_BUSWIDTH_16;
@@ -74,5 +283,62 @@ int board_nand_init(struct nand_chip *na
#endif
nand->chip_delay = 20;
+#ifdef CONFIG_ATMEL_NAND_HWECC
+ nand->ecc.mode = NAND_ECC_HW;
+ nand->ecc.calculate = atmel_nand_calculate;
+ nand->ecc.correct = atmel_nand_correct;
+ nand->ecc.hwctl = atmel_nand_hwctl;
+ nand->ecc.read_page = atmel_nand_read_page;
+ nand->ecc.bytes = 4;
+#endif
+
+#ifdef CONFIG_ATMEL_NAND_HWECC
+ mtd = &nand_info[chip_nr++];
+ mtd->priv = nand;
+
+ /* Detect NAND chips */
+ if (nand_scan_ident(mtd, 1)) {
+ printk(KERN_WARNING "NAND Flash not found !\n");
+ return -ENXIO;
+ }
+
+ if (nand->ecc.mode == NAND_ECC_HW) {
+ /* ECC is calculated for the whole page (1 step) */
+ nand->ecc.size = mtd->writesize;
+
+ /* set ECC page size and oob layout */
+ switch (mtd->writesize) {
+ case 512:
+ nand->ecc.layout = &atmel_oobinfo_small;
+ ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_528);
+ break;
+ case 1024:
+ nand->ecc.layout = &atmel_oobinfo_large;
+ ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_1056);
+ break;
+ case 2048:
+ nand->ecc.layout = &atmel_oobinfo_large;
+ ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_2112);
+ break;
+ case 4096:
+ nand->ecc.layout = &atmel_oobinfo_large;
+ ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_4224);
+ break;
+ default:
+ /* page size not handled by HW ECC */
+ /* switching back to soft ECC */
+ nand->ecc.mode = NAND_ECC_SOFT;
+ nand->ecc.calculate = NULL;
+ nand->ecc.correct = NULL;
+ nand->ecc.hwctl = NULL;
+ nand->ecc.read_page = NULL;
+ nand->ecc.postpad = 0;
+ nand->ecc.prepad = 0;
+ nand->ecc.bytes = 0;
+ break;
+ }
+ }
+#endif
+
return 0;
}
diff -uprN u-boot-2009.11/drivers/mtd/nand/atmel_nand_ecc.h
u-boot-2009.11-at91-nand-hwecc/drivers/mtd/nand/atmel_nand_ecc.h
--- u-boot-2009.11/drivers/mtd/nand/atmel_nand_ecc.h 1970-01-01
05:00:00.000000000 +0500
+++ u-boot-2009.11-at91-nand-hwecc/drivers/mtd/nand/atmel_nand_ecc.h 2010-03-18
11:15:01.000000000 +0500
@@ -0,0 +1,36 @@
+/*
+ * Error Corrected Code Controller (ECC) - System peripherals regsters.
+ * Based on AT91SAM9260 datasheet revision B.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef ATMEL_NAND_ECC_H
+#define ATMEL_NAND_ECC_H
+
+#define ATMEL_ECC_CR 0x00 /* Control register */
+#define ATMEL_ECC_RST (1 << 0) /* Reset parity */
+
+#define ATMEL_ECC_MR 0x04 /* Mode register */
+#define ATMEL_ECC_PAGESIZE (3 << 0) /* Page Size */
+#define ATMEL_ECC_PAGESIZE_528 (0)
+#define ATMEL_ECC_PAGESIZE_1056 (1)
+#define ATMEL_ECC_PAGESIZE_2112 (2)
+#define ATMEL_ECC_PAGESIZE_4224 (3)
+
+#define ATMEL_ECC_SR 0x08 /* Status register */
+#define ATMEL_ECC_RECERR (1 << 0) /* Recoverable Error */
+#define ATMEL_ECC_ECCERR (1 << 1) /* ECC Single Bit Error */
+#define ATMEL_ECC_MULERR (1 << 2) /* Multiple Errors */
+
+#define ATMEL_ECC_PR 0x0c /* Parity register */
+#define ATMEL_ECC_BITADDR (0xf << 0) /* Bit Error Address */
+#define ATMEL_ECC_WORDADDR (0xfff << 4) /* Word Error Address */
+
+#define ATMEL_ECC_NPR 0x10 /* NParity register */
+#define ATMEL_ECC_NPARITY (0xffff << 0) /* NParity */
+
+#endif
--
Nikolay
^ permalink raw reply [flat|nested] 13+ messages in thread
* [U-Boot] [PATH] at91: add hwecc method for nand
2010-03-18 6:55 [U-Boot] [PATH] at91: add hwecc method for nand Nikolay Petukhov
@ 2010-03-18 22:46 ` Scott Wood
2010-03-19 5:49 ` Nikolay Petukhov
0 siblings, 1 reply; 13+ messages in thread
From: Scott Wood @ 2010-03-18 22:46 UTC (permalink / raw)
To: u-boot
On Thu, Mar 18, 2010 at 11:55:29AM +0500, Nikolay Petukhov wrote:
> + /* move to ECC position if needed */
> + if (eccpos[0] != 0) {
> + /* This only works on large pages
> + * because the ECC controller waits for
> + * NAND_CMD_RNDOUTSTART after the
> + * NAND_CMD_RNDOUT.
> + * anyway, for small pages, the eccpos[0] == 0
> + */
> + chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
> + mtd->writesize + eccpos[0], -1);
> + }
[snip]
> + /* get back to oob start (end of page) */
> + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
Is the second RNDOUT OK on small page NAND?
> + //struct atmel_nand_host *host = nand_chip->priv;
Just remove the line.
-Scott
^ permalink raw reply [flat|nested] 13+ messages in thread
* [U-Boot] [PATH] at91: add hwecc method for nand
2010-03-18 22:46 ` Scott Wood
@ 2010-03-19 5:49 ` Nikolay Petukhov
2010-03-19 22:17 ` Scott Wood
0 siblings, 1 reply; 13+ messages in thread
From: Nikolay Petukhov @ 2010-03-19 5:49 UTC (permalink / raw)
To: u-boot
2010/3/19 Scott Wood <scottwood@freescale.com>:
> On Thu, Mar 18, 2010 at 11:55:29AM +0500, Nikolay Petukhov wrote:
>> + ? ? /* move to ECC position if needed */
>> + ? ? if (eccpos[0] != 0) {
>> + ? ? ? ? ? ? /* This only works on large pages
>> + ? ? ? ? ? ? ?* because the ECC controller waits for
>> + ? ? ? ? ? ? ?* NAND_CMD_RNDOUTSTART after the
>> + ? ? ? ? ? ? ?* NAND_CMD_RNDOUT.
>> + ? ? ? ? ? ? ?* anyway, for small pages, the eccpos[0] == 0
>> + ? ? ? ? ? ? ?*/
>> + ? ? ? ? ? ? chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? mtd->writesize + eccpos[0], -1);
>> + ? ? }
> [snip]
>> + ? ? /* get back to oob start (end of page) */
>> + ? ? chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
>
> Is the second RNDOUT OK on small page NAND?
>
I have NAND chip with 2K page size.
NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB
3,3V 8-bit)
Here, the positive results of operation of the at91_nand with small
pages http://patchwork.ozlabs.org/patch/4049/
>> + ? ? //struct atmel_nand_host *host = nand_chip->priv;
>
> Just remove the line.
Done
>
> -Scott
>
This is a patch to use the hardware ECC controller of
the AT91SAM9260 for the AT91 nand. Taken from the kernel 2.6.33.
Signed-off-by: Nikolay Petukhov <Nikolay.Petukhov@gmail.com>
diff -uprN u-boot-2009.11/drivers/mtd/nand/atmel_nand.c
u-boot-2009.11-at91-nand-hwecc/drivers/mtd/nand/atmel_nand.c
--- u-boot-2009.11/drivers/mtd/nand/atmel_nand.c 2009-12-16
03:20:54.000000000 +0500
+++ u-boot-2009.11-at91-nand-hwecc/drivers/mtd/nand/atmel_nand.c 2010-03-19
10:34:28.000000000 +0500
@@ -31,6 +31,209 @@
#include <nand.h>
+#ifdef CONFIG_ATMEL_NAND_HWECC
+
+/* Register access macros */
+#define ecc_readl(add, reg) \
+ readl(AT91_BASE_SYS + add + ATMEL_ECC_##reg)
+#define ecc_writel(add, reg, value) \
+ writel((value), AT91_BASE_SYS + add + ATMEL_ECC_##reg)
+
+#include "atmel_nand_ecc.h" /* Hardware ECC registers */
+
+/* oob layout for large page size
+ * bad block info is on bytes 0 and 1
+ * the bytes have to be consecutives to avoid
+ * several NAND_CMD_RNDOUT during read
+ */
+static struct nand_ecclayout atmel_oobinfo_large = {
+ .eccbytes = 4,
+ .eccpos = {60, 61, 62, 63},
+ .oobfree = {
+ {2, 58}
+ },
+};
+
+/* oob layout for small page size
+ * bad block info is on bytes 4 and 5
+ * the bytes have to be consecutives to avoid
+ * several NAND_CMD_RNDOUT during read
+ */
+static struct nand_ecclayout atmel_oobinfo_small = {
+ .eccbytes = 4,
+ .eccpos = {0, 1, 2, 3},
+ .oobfree = {
+ {6, 10}
+ },
+};
+
+/*
+ * Calculate HW ECC
+ *
+ * function called after a write
+ *
+ * mtd: MTD block structure
+ * dat: raw data (unused)
+ * ecc_code: buffer for ECC
+ */
+static int atmel_nand_calculate(struct mtd_info *mtd,
+ const u_char *dat, unsigned char *ecc_code)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ unsigned int ecc_value;
+
+ /* get the first 2 ECC bytes */
+ ecc_value = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, PR);
+
+ ecc_code[0] = ecc_value & 0xFF;
+ ecc_code[1] = (ecc_value >> 8) & 0xFF;
+
+ /* get the last 2 ECC bytes */
+ ecc_value = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, NPR) & ATMEL_ECC_NPARITY;
+
+ ecc_code[2] = ecc_value & 0xFF;
+ ecc_code[3] = (ecc_value >> 8) & 0xFF;
+
+ return 0;
+}
+
+/*
+ * HW ECC read page function
+ *
+ * mtd: mtd info structure
+ * chip: nand chip info structure
+ * buf: buffer to store read data
+ */
+static int atmel_nand_read_page(struct mtd_info *mtd,
+ struct nand_chip *chip, uint8_t *buf, int page)
+{
+ int eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ uint32_t *eccpos = chip->ecc.layout->eccpos;
+ uint8_t *p = buf;
+ uint8_t *oob = chip->oob_poi;
+ uint8_t *ecc_pos;
+ int stat;
+
+ /* read the page */
+ chip->read_buf(mtd, p, eccsize);
+
+ /* move to ECC position if needed */
+ if (eccpos[0] != 0) {
+ /* This only works on large pages
+ * because the ECC controller waits for
+ * NAND_CMD_RNDOUTSTART after the
+ * NAND_CMD_RNDOUT.
+ * anyway, for small pages, the eccpos[0] == 0
+ */
+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
+ mtd->writesize + eccpos[0], -1);
+ }
+
+ /* the ECC controller needs to read the ECC just after the data */
+ ecc_pos = oob + eccpos[0];
+ chip->read_buf(mtd, ecc_pos, eccbytes);
+
+ /* check if there's an error */
+ stat = chip->ecc.correct(mtd, p, oob, NULL);
+
+ if (stat < 0)
+ mtd->ecc_stats.failed++;
+ else
+ mtd->ecc_stats.corrected += stat;
+
+ /* get back to oob start (end of page) */
+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
+
+ /* read the oob */
+ chip->read_buf(mtd, oob, mtd->oobsize);
+
+ return 0;
+}
+
+/*
+ * HW ECC Correction
+ *
+ * function called after a read
+ *
+ * mtd: MTD block structure
+ * dat: raw data read from the chip
+ * read_ecc: ECC from the chip (unused)
+ * isnull: unused
+ *
+ * Detect and correct a 1 bit error for a page
+ */
+static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat,
+ u_char *read_ecc, u_char *isnull)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ unsigned int ecc_status, ecc_parity, ecc_mode;
+ unsigned int ecc_word, ecc_bit;
+
+ /* get the status from the Status Register */
+ ecc_status = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, SR);
+
+ /* if there's no error */
+ if (likely(!(ecc_status & ATMEL_ECC_RECERR)))
+ return 0;
+
+ /* get error bit offset (4 bits) */
+ ecc_bit = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, PR) & ATMEL_ECC_BITADDR;
+ /* get word address (12 bits) */
+ ecc_word = ecc_readl(CONFIG_SYS_NAND_ECC_BASE, PR) & ATMEL_ECC_WORDADDR;
+ ecc_word >>= 4;
+
+ /* if there are multiple errors */
+ if (ecc_status & ATMEL_ECC_MULERR) {
+ /* check if it is a freshly erased block
+ * (filled with 0xff) */
+ if ((ecc_bit == ATMEL_ECC_BITADDR)
+ && (ecc_word == (ATMEL_ECC_WORDADDR >> 4))) {
+ /* the block has just been erased, return OK */
+ return 0;
+ }
+ /* it doesn't seems to be a freshly
+ * erased block.
+ * We can't correct so many errors */
+ printk(KERN_WARNING "atmel_nand : multiple errors detected."
+ " Unable to correct.\n");
+ return -EIO;
+ }
+
+ /* if there's a single bit error : we can correct it */
+ if (ecc_status & ATMEL_ECC_ECCERR) {
+ /* there's nothing much to do here.
+ * the bit error is on the ECC itself.
+ */
+ printk(KERN_WARNING "atmel_nand : one bit error on ECC code."
+ " Nothing to correct\n");
+ return 0;
+ }
+
+ printk(KERN_WARNING "atmel_nand : one bit error on data."
+ " (word offset in the page :"
+ " 0x%x bit offset : 0x%x)\n",
+ ecc_word, ecc_bit);
+ /* correct the error */
+ if (nand_chip->options & NAND_BUSWIDTH_16) {
+ /* 16 bits words */
+ ((unsigned short *) dat)[ecc_word] ^= (1 << ecc_bit);
+ } else {
+ /* 8 bits words */
+ dat[ecc_word] ^= (1 << ecc_bit);
+ }
+ printk(KERN_WARNING "atmel_nand : error corrected\n");
+ return 1;
+}
+
+/*
+ * Enable HW ECC : unused on most chips
+ */
+static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
+{
+}
+#endif
+
static void at91_nand_hwcontrol(struct mtd_info *mtd,
int cmd, unsigned int ctrl)
{
@@ -64,6 +267,11 @@ static int at91_nand_ready(struct mtd_in
int board_nand_init(struct nand_chip *nand)
{
+#ifdef CONFIG_ATMEL_NAND_HWECC
+ static int chip_nr = 0;
+ struct mtd_info *mtd;
+#endif
+
nand->ecc.mode = NAND_ECC_SOFT;
#ifdef CONFIG_SYS_NAND_DBW_16
nand->options = NAND_BUSWIDTH_16;
@@ -74,5 +282,62 @@ int board_nand_init(struct nand_chip *na
#endif
nand->chip_delay = 20;
+#ifdef CONFIG_ATMEL_NAND_HWECC
+ nand->ecc.mode = NAND_ECC_HW;
+ nand->ecc.calculate = atmel_nand_calculate;
+ nand->ecc.correct = atmel_nand_correct;
+ nand->ecc.hwctl = atmel_nand_hwctl;
+ nand->ecc.read_page = atmel_nand_read_page;
+ nand->ecc.bytes = 4;
+#endif
+
+#ifdef CONFIG_ATMEL_NAND_HWECC
+ mtd = &nand_info[chip_nr++];
+ mtd->priv = nand;
+
+ /* Detect NAND chips */
+ if (nand_scan_ident(mtd, 1)) {
+ printk(KERN_WARNING "NAND Flash not found !\n");
+ return -ENXIO;
+ }
+
+ if (nand->ecc.mode == NAND_ECC_HW) {
+ /* ECC is calculated for the whole page (1 step) */
+ nand->ecc.size = mtd->writesize;
+
+ /* set ECC page size and oob layout */
+ switch (mtd->writesize) {
+ case 512:
+ nand->ecc.layout = &atmel_oobinfo_small;
+ ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_528);
+ break;
+ case 1024:
+ nand->ecc.layout = &atmel_oobinfo_large;
+ ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_1056);
+ break;
+ case 2048:
+ nand->ecc.layout = &atmel_oobinfo_large;
+ ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_2112);
+ break;
+ case 4096:
+ nand->ecc.layout = &atmel_oobinfo_large;
+ ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_4224);
+ break;
+ default:
+ /* page size not handled by HW ECC */
+ /* switching back to soft ECC */
+ nand->ecc.mode = NAND_ECC_SOFT;
+ nand->ecc.calculate = NULL;
+ nand->ecc.correct = NULL;
+ nand->ecc.hwctl = NULL;
+ nand->ecc.read_page = NULL;
+ nand->ecc.postpad = 0;
+ nand->ecc.prepad = 0;
+ nand->ecc.bytes = 0;
+ break;
+ }
+ }
+#endif
+
return 0;
}
diff -uprN u-boot-2009.11/drivers/mtd/nand/atmel_nand_ecc.h
u-boot-2009.11-at91-nand-hwecc/drivers/mtd/nand/atmel_nand_ecc.h
--- u-boot-2009.11/drivers/mtd/nand/atmel_nand_ecc.h 1970-01-01
05:00:00.000000000 +0500
+++ u-boot-2009.11-at91-nand-hwecc/drivers/mtd/nand/atmel_nand_ecc.h 2010-03-19
10:33:54.000000000 +0500
@@ -0,0 +1,36 @@
+/*
+ * Error Corrected Code Controller (ECC) - System peripherals regsters.
+ * Based on AT91SAM9260 datasheet revision B.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef ATMEL_NAND_ECC_H
+#define ATMEL_NAND_ECC_H
+
+#define ATMEL_ECC_CR 0x00 /* Control register */
+#define ATMEL_ECC_RST (1 << 0) /* Reset parity */
+
+#define ATMEL_ECC_MR 0x04 /* Mode register */
+#define ATMEL_ECC_PAGESIZE (3 << 0) /* Page Size */
+#define ATMEL_ECC_PAGESIZE_528 (0)
+#define ATMEL_ECC_PAGESIZE_1056 (1)
+#define ATMEL_ECC_PAGESIZE_2112 (2)
+#define ATMEL_ECC_PAGESIZE_4224 (3)
+
+#define ATMEL_ECC_SR 0x08 /* Status register */
+#define ATMEL_ECC_RECERR (1 << 0) /* Recoverable Error */
+#define ATMEL_ECC_ECCERR (1 << 1) /* ECC Single Bit Error */
+#define ATMEL_ECC_MULERR (1 << 2) /* Multiple Errors */
+
+#define ATMEL_ECC_PR 0x0c /* Parity register */
+#define ATMEL_ECC_BITADDR (0xf << 0) /* Bit Error Address */
+#define ATMEL_ECC_WORDADDR (0xfff << 4) /* Word Error Address */
+
+#define ATMEL_ECC_NPR 0x10 /* NParity register */
+#define ATMEL_ECC_NPARITY (0xffff << 0) /* NParity */
+
+#endif
--
Nikolay
^ permalink raw reply [flat|nested] 13+ messages in thread
* [U-Boot] [PATH] at91: add hwecc method for nand
2010-03-19 5:49 ` Nikolay Petukhov
@ 2010-03-19 22:17 ` Scott Wood
2010-03-28 12:42 ` [U-Boot] [PATCH 0/2] atmel_nand with HW-ECC Alexander Holler
0 siblings, 1 reply; 13+ messages in thread
From: Scott Wood @ 2010-03-19 22:17 UTC (permalink / raw)
To: u-boot
On Fri, Mar 19, 2010 at 10:49:27AM +0500, Nikolay Petukhov wrote:
> 2010/3/19 Scott Wood <scottwood@freescale.com>:
> > Is the second RNDOUT OK on small page NAND?
> >
>
> I have NAND chip with 2K page size.
> NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB
> 3,3V 8-bit)
>
> Here, the positive results of operation of the at91_nand with small
> pages http://patchwork.ozlabs.org/patch/4049/
>
> >> + ? ? //struct atmel_nand_host *host = nand_chip->priv;
> >
> > Just remove the line.
>
> Done
>
> >
> > -Scott
> >
>
> This is a patch to use the hardware ECC controller of
> the AT91SAM9260 for the AT91 nand. Taken from the kernel 2.6.33.
>
> Signed-off-by: Nikolay Petukhov <Nikolay.Petukhov@gmail.com>
Applied to u-boot-nand-flash next, but it took some manual editing of the
e-mail to apply. Please don't let quoted printable be used when sending a
patch (git seems to kind of support it, but I had to unwrap a couple lines
manually, and if "git am" fails, the standard patch utility cannot be used),
and make sure any comments which aren't to become part of the changelog go
below a --- line.
It's usually simpler to just send the new patch in a separate e-mail rather
than combined with a discussion reply.
-Scott
^ permalink raw reply [flat|nested] 13+ messages in thread
* [U-Boot] [PATCH 0/2] atmel_nand with HW-ECC
2010-03-19 22:17 ` Scott Wood
@ 2010-03-28 12:42 ` Alexander Holler
2010-03-28 12:42 ` [U-Boot] [PATCH 1/2] Add AT91_ECC_BASE to at91sam9260.h to use " Alexander Holler
0 siblings, 1 reply; 13+ messages in thread
From: Alexander Holler @ 2010-03-28 12:42 UTC (permalink / raw)
To: u-boot
Hello,
I've cherry-picked the patch for atmel_nand to enable HW-ECC on the master
and had to apply some changes. Afterwards it seems to work on an AT91SAM9263.
Thanks for that functionality.
Regards,
Alexander Holler
^ permalink raw reply [flat|nested] 13+ messages in thread
* [U-Boot] [PATCH 1/2] Add AT91_ECC_BASE to at91sam9260.h to use atmel_nand with HW-ECC
2010-03-28 12:42 ` [U-Boot] [PATCH 0/2] atmel_nand with HW-ECC Alexander Holler
@ 2010-03-28 12:42 ` Alexander Holler
2010-03-28 12:42 ` [U-Boot] [PATCH 2/2] Fix compile errors for atmel_nand with hw-ecc and new SoC access Alexander Holler
0 siblings, 1 reply; 13+ messages in thread
From: Alexander Holler @ 2010-03-28 12:42 UTC (permalink / raw)
To: u-boot
---
include/asm-arm/arch-at91/at91sam9260.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/include/asm-arm/arch-at91/at91sam9260.h b/include/asm-arm/arch-at91/at91sam9260.h
index a60a081..3bc7167 100644
--- a/include/asm-arm/arch-at91/at91sam9260.h
+++ b/include/asm-arm/arch-at91/at91sam9260.h
@@ -50,6 +50,7 @@
#define AT91SAM9260_ID_IRQ2 31 /* Advanced Interrupt Controller (IRQ2) */
#define AT91_EMAC_BASE 0xfffc4000
+#define AT91_ECC_BASE 0xffffe800
#define AT91_SDRAMC_BASE 0xffffea00
#define AT91_SMC_BASE 0xffffec00
#define AT91_MATRIX_BASE 0xffffee00
--
1.6.2.5
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [U-Boot] [PATCH 2/2] Fix compile errors for atmel_nand with hw-ecc and new SoC access
2010-03-28 12:42 ` [U-Boot] [PATCH 1/2] Add AT91_ECC_BASE to at91sam9260.h to use " Alexander Holler
@ 2010-03-28 12:42 ` Alexander Holler
2010-04-02 16:38 ` Scott Wood
2010-04-04 16:26 ` Tom
0 siblings, 2 replies; 13+ messages in thread
From: Alexander Holler @ 2010-03-28 12:42 UTC (permalink / raw)
To: u-boot
atmel_nand.c with HW-ECC doesn't compile with the new SoC access.
Using CONFIG_AT91_LEGACY to circumvent the compile errors only leaves
the driver in a state where it doesn't find the NAND.
To use HW-ECC with atmel_nand one has to use
CONFIG_SYS_NAND_ECC_BASE AT91_ECC0_BASE (instead of AT91_ECC0)
for an AT91SAM9263 or AT91_ECC_BASE for an AT91SAM9260.
I've removed three unused variables too.
---
drivers/mtd/nand/atmel_nand.c | 7 +++----
1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index d5eb54a..5f10a02 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -35,9 +35,9 @@
/* Register access macros */
#define ecc_readl(add, reg) \
- readl(AT91_BASE_SYS + add + ATMEL_ECC_##reg)
+ readl(add + ATMEL_ECC_##reg)
#define ecc_writel(add, reg, value) \
- writel((value), AT91_BASE_SYS + add + ATMEL_ECC_##reg)
+ writel((value), add + ATMEL_ECC_##reg)
#include "atmel_nand_ecc.h" /* Hardware ECC registers */
@@ -79,7 +79,6 @@ static struct nand_ecclayout atmel_oobinfo_small = {
static int atmel_nand_calculate(struct mtd_info *mtd,
const u_char *dat, unsigned char *ecc_code)
{
- struct nand_chip *nand_chip = mtd->priv;
unsigned int ecc_value;
/* get the first 2 ECC bytes */
@@ -167,7 +166,7 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat,
u_char *read_ecc, u_char *isnull)
{
struct nand_chip *nand_chip = mtd->priv;
- unsigned int ecc_status, ecc_parity, ecc_mode;
+ unsigned int ecc_status;
unsigned int ecc_word, ecc_bit;
/* get the status from the Status Register */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [U-Boot] [PATCH 2/2] Fix compile errors for atmel_nand with hw-ecc and new SoC access
2010-03-28 12:42 ` [U-Boot] [PATCH 2/2] Fix compile errors for atmel_nand with hw-ecc and new SoC access Alexander Holler
@ 2010-04-02 16:38 ` Scott Wood
2010-04-03 11:08 ` Alexander Holler
2010-04-04 16:26 ` Tom
1 sibling, 1 reply; 13+ messages in thread
From: Scott Wood @ 2010-04-02 16:38 UTC (permalink / raw)
To: u-boot
On Sun, Mar 28, 2010 at 02:42:25PM +0200, Alexander Holler wrote:
> atmel_nand.c with HW-ECC doesn't compile with the new SoC access.
> Using CONFIG_AT91_LEGACY to circumvent the compile errors only leaves
> the driver in a state where it doesn't find the NAND.
>
> To use HW-ECC with atmel_nand one has to use
> CONFIG_SYS_NAND_ECC_BASE AT91_ECC0_BASE (instead of AT91_ECC0)
> for an AT91SAM9263 or AT91_ECC_BASE for an AT91SAM9260.
>
> I've removed three unused variables too.
> ---
> drivers/mtd/nand/atmel_nand.c | 7 +++----
> 1 files changed, 3 insertions(+), 4 deletions(-)
Missing Signed-off-by line.
-Scott
^ permalink raw reply [flat|nested] 13+ messages in thread
* [U-Boot] [PATCH 2/2] Fix compile errors for atmel_nand with hw-ecc and new SoC access
2010-04-02 16:38 ` Scott Wood
@ 2010-04-03 11:08 ` Alexander Holler
2010-04-03 11:08 ` [U-Boot] [PATCH 1/2] Add AT91_ECC_BASE to at91sam9260.h to use atmel_nand with HW-ECC Alexander Holler
0 siblings, 1 reply; 13+ messages in thread
From: Alexander Holler @ 2010-04-03 11:08 UTC (permalink / raw)
To: u-boot
If someone else wonders why an author should sign his own patches, a good explanation
can be found here: http://kerneltrap.org/files/Jeremy/DCO.txt ;)
Regards,
Alexander
^ permalink raw reply [flat|nested] 13+ messages in thread
* [U-Boot] [PATCH 1/2] Add AT91_ECC_BASE to at91sam9260.h to use atmel_nand with HW-ECC
2010-04-03 11:08 ` Alexander Holler
@ 2010-04-03 11:08 ` Alexander Holler
2010-04-03 11:08 ` [U-Boot] [PATCH 2/2] Fix compile errors for atmel_nand with hw-ecc and new SoC access Alexander Holler
0 siblings, 1 reply; 13+ messages in thread
From: Alexander Holler @ 2010-04-03 11:08 UTC (permalink / raw)
To: u-boot
Signed-off-by: Alexander Holler <holler@ahsoftware.de>
---
include/asm-arm/arch-at91/at91sam9260.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/include/asm-arm/arch-at91/at91sam9260.h b/include/asm-arm/arch-at91/at91sam9260.h
index a60a081..3bc7167 100644
--- a/include/asm-arm/arch-at91/at91sam9260.h
+++ b/include/asm-arm/arch-at91/at91sam9260.h
@@ -50,6 +50,7 @@
#define AT91SAM9260_ID_IRQ2 31 /* Advanced Interrupt Controller (IRQ2) */
#define AT91_EMAC_BASE 0xfffc4000
+#define AT91_ECC_BASE 0xffffe800
#define AT91_SDRAMC_BASE 0xffffea00
#define AT91_SMC_BASE 0xffffec00
#define AT91_MATRIX_BASE 0xffffee00
--
1.6.2.5
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [U-Boot] [PATCH 2/2] Fix compile errors for atmel_nand with hw-ecc and new SoC access
2010-04-03 11:08 ` [U-Boot] [PATCH 1/2] Add AT91_ECC_BASE to at91sam9260.h to use atmel_nand with HW-ECC Alexander Holler
@ 2010-04-03 11:08 ` Alexander Holler
0 siblings, 0 replies; 13+ messages in thread
From: Alexander Holler @ 2010-04-03 11:08 UTC (permalink / raw)
To: u-boot
atmel_nand.c with HW-ECC doesn't compile with the new SoC access.
Using CONFIG_AT91_LEGACY to circumvent the compile errors only leaves
the driver in a state where it doesn't find the NAND.
To use HW-ECC with atmel_nand one has to use
CONFIG_SYS_NAND_ECC_BASE AT91_ECC0_BASE (instead of AT91_ECC0)
for an AT91SAM9263 or AT91_ECC_BASE for an AT91SAM9260.
I've removed three unused variables too.
Signed-off-by: Alexander Holler <holler@ahsoftware.de>
---
drivers/mtd/nand/atmel_nand.c | 7 +++----
1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index d5eb54a..5f10a02 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -35,9 +35,9 @@
/* Register access macros */
#define ecc_readl(add, reg) \
- readl(AT91_BASE_SYS + add + ATMEL_ECC_##reg)
+ readl(add + ATMEL_ECC_##reg)
#define ecc_writel(add, reg, value) \
- writel((value), AT91_BASE_SYS + add + ATMEL_ECC_##reg)
+ writel((value), add + ATMEL_ECC_##reg)
#include "atmel_nand_ecc.h" /* Hardware ECC registers */
@@ -79,7 +79,6 @@ static struct nand_ecclayout atmel_oobinfo_small = {
static int atmel_nand_calculate(struct mtd_info *mtd,
const u_char *dat, unsigned char *ecc_code)
{
- struct nand_chip *nand_chip = mtd->priv;
unsigned int ecc_value;
/* get the first 2 ECC bytes */
@@ -167,7 +166,7 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat,
u_char *read_ecc, u_char *isnull)
{
struct nand_chip *nand_chip = mtd->priv;
- unsigned int ecc_status, ecc_parity, ecc_mode;
+ unsigned int ecc_status;
unsigned int ecc_word, ecc_bit;
/* get the status from the Status Register */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [U-Boot] [PATCH 2/2] Fix compile errors for atmel_nand with hw-ecc and new SoC access
2010-03-28 12:42 ` [U-Boot] [PATCH 2/2] Fix compile errors for atmel_nand with hw-ecc and new SoC access Alexander Holler
2010-04-02 16:38 ` Scott Wood
@ 2010-04-04 16:26 ` Tom
2010-04-04 17:26 ` Alexander Holler
1 sibling, 1 reply; 13+ messages in thread
From: Tom @ 2010-04-04 16:26 UTC (permalink / raw)
To: u-boot
Alexander Holler wrote:
> atmel_nand.c with HW-ECC doesn't compile with the new SoC access.
> Using CONFIG_AT91_LEGACY to circumvent the compile errors only leaves
> the driver in a state where it doesn't find the NAND.
>
> To use HW-ECC with atmel_nand one has to use
> CONFIG_SYS_NAND_ECC_BASE AT91_ECC0_BASE (instead of AT91_ECC0)
> for an AT91SAM9263 or AT91_ECC_BASE for an AT91SAM9260.
>
Nak
The new Soc access is the preferred method.
The fix should use the Soc access, not the legacy method.
Tom
> I've removed three unused variables too.
> ---
> drivers/mtd/nand/atmel_nand.c | 7 +++----
> 1 files changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
> index d5eb54a..5f10a02 100644
> --- a/drivers/mtd/nand/atmel_nand.c
> +++ b/drivers/mtd/nand/atmel_nand.c
> @@ -35,9 +35,9 @@
>
> /* Register access macros */
> #define ecc_readl(add, reg) \
> - readl(AT91_BASE_SYS + add + ATMEL_ECC_##reg)
> + readl(add + ATMEL_ECC_##reg)
> #define ecc_writel(add, reg, value) \
> - writel((value), AT91_BASE_SYS + add + ATMEL_ECC_##reg)
> + writel((value), add + ATMEL_ECC_##reg)
>
> #include "atmel_nand_ecc.h" /* Hardware ECC registers */
>
> @@ -79,7 +79,6 @@ static struct nand_ecclayout atmel_oobinfo_small = {
> static int atmel_nand_calculate(struct mtd_info *mtd,
> const u_char *dat, unsigned char *ecc_code)
> {
> - struct nand_chip *nand_chip = mtd->priv;
> unsigned int ecc_value;
>
> /* get the first 2 ECC bytes */
> @@ -167,7 +166,7 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat,
> u_char *read_ecc, u_char *isnull)
> {
> struct nand_chip *nand_chip = mtd->priv;
> - unsigned int ecc_status, ecc_parity, ecc_mode;
> + unsigned int ecc_status;
> unsigned int ecc_word, ecc_bit;
>
> /* get the status from the Status Register */
^ permalink raw reply [flat|nested] 13+ messages in thread
* [U-Boot] [PATCH 2/2] Fix compile errors for atmel_nand with hw-ecc and new SoC access
2010-04-04 16:26 ` Tom
@ 2010-04-04 17:26 ` Alexander Holler
0 siblings, 0 replies; 13+ messages in thread
From: Alexander Holler @ 2010-04-04 17:26 UTC (permalink / raw)
To: u-boot
Hi,
please just forget my patches.
I don't feel the need to waste your and my time in posting examples of
my obivous incompetence and I'm long out of school and don't want to
take lessons about exploring how other people want their names of variables.
Happy easter,
Alexander
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2010-04-04 17:26 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-18 6:55 [U-Boot] [PATH] at91: add hwecc method for nand Nikolay Petukhov
2010-03-18 22:46 ` Scott Wood
2010-03-19 5:49 ` Nikolay Petukhov
2010-03-19 22:17 ` Scott Wood
2010-03-28 12:42 ` [U-Boot] [PATCH 0/2] atmel_nand with HW-ECC Alexander Holler
2010-03-28 12:42 ` [U-Boot] [PATCH 1/2] Add AT91_ECC_BASE to at91sam9260.h to use " Alexander Holler
2010-03-28 12:42 ` [U-Boot] [PATCH 2/2] Fix compile errors for atmel_nand with hw-ecc and new SoC access Alexander Holler
2010-04-02 16:38 ` Scott Wood
2010-04-03 11:08 ` Alexander Holler
2010-04-03 11:08 ` [U-Boot] [PATCH 1/2] Add AT91_ECC_BASE to at91sam9260.h to use atmel_nand with HW-ECC Alexander Holler
2010-04-03 11:08 ` [U-Boot] [PATCH 2/2] Fix compile errors for atmel_nand with hw-ecc and new SoC access Alexander Holler
2010-04-04 16:26 ` Tom
2010-04-04 17:26 ` Alexander Holler
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox