NAND hardware ECC controller on at91sam9263 / at91sam9260
Subsystems (5)
PATCH 1/1 NAND hardware ECC controller on at91sam9263 / at91sam9260
This is a patch to use the hardware ECC controller of the AT91SAM9260 and AT91SAM9263 for the AT91 nand. On AT91 NAND, there's now a choice between ECC soft, ECC hard or no ECC (for debug).
It has been tested on AT91SAM9263 with 8 bits large and small page NAND.
kernel version : 2.6.25-rc2
--- arch/arm/mach-at91/at91sam9260_devices.c | 9 +- arch/arm/mach-at91/at91sam9263_devices.c | 9 +- drivers/mtd/nand/Kconfig | 41 ++++ drivers/mtd/nand/at91_nand.c | 361 +++++++++++++++++++++++++++++- include/asm-arm/arch-at91/at91_ecc.h | 12 +- include/asm-arm/arch-at91/at91sam9260.h | 21 ++ include/asm-arm/arch-at91/at91sam9263.h | 27 +++ 7 files changed, 466 insertions(+), 14 deletions(-)
arch/arm/mach-at91/at91sam9260_devices.c +7 -2
@@ -288,11 +288,16 @@ static struct at91_nand_data nand_data;#define NAND_BASE AT91_CHIPSELECT_3static struct resource nand_resources[] = { - { + [0 ] = { .start =NAND_BASE , .end =NAND_BASE +SZ_256M -1 , .flags =IORESOURCE_MEM , - } + }, + [1 ] = { + .start =AT91SAM9260_ECC , + .end =AT91SAM9260_ECC +SZ_512 -1 , + .flags =IORESOURCE_MEM , + }, };static struct platform_device at91sam9260_nand_device = {
arch/arm/mach-at91/at91sam9263_devices.c +7 -2
@@ -358,11 +358,16 @@ static struct at91_nand_data nand_data;#define NAND_BASE AT91_CHIPSELECT_3static struct resource nand_resources[] = { - { + [0 ] = { .start =NAND_BASE , .end =NAND_BASE +SZ_256M -1 , .flags =IORESOURCE_MEM , - } + }, + [1 ] = { + .start =AT91SAM9263_ECC0 , + .end =AT91SAM9263_ECC0 +SZ_512 -1 , + .flags =IORESOURCE_MEM , + }, };static struct platform_device at91sam9263_nand_device = {
drivers/mtd/nand/Kconfig +41 -0
47 lines not on this page · raw message
drivers/mtd/nand/at91_nand.c +356 -5
433 lines not on this page · raw message
include/asm-arm/arch-at91/at91_ecc.h +7 -5
@@ -13,26 +13,28 @@#ifndef AT91_ECC_H #define AT91_ECC_H -#define AT91_ECC_CR (AT91_ECC + 0x00)/* Control register */ +/* ECC registers offsets */ +#define AT91_ECC_CR 0x00/* Control register */ #define AT91_ECC_RST (1 << 0)/* Reset parity */ -#define AT91_ECC_MR (AT91_ECC + 0x04)/* Mode register */ +#define AT91_ECC_MR 0x04/* Mode register */ #define AT91_ECC_PAGESIZE (3 << 0)/* Page Size */ #define AT91_ECC_PAGESIZE_528 (0)#define AT91_ECC_PAGESIZE_1056 (1)#define AT91_ECC_PAGESIZE_2112 (2)#define AT91_ECC_PAGESIZE_4224 (3) -#define AT91_ECC_SR (AT91_ECC + 0x08)/* Status register */ +#define AT91_ECC_SR 0x08/* Status register */ #define AT91_ECC_RECERR (1 << 0)/* Recoverable Error */ #define AT91_ECC_ECCERR (1 << 1)/* ECC Single Bit Error */ #define AT91_ECC_MULERR (1 << 2)/* Multiple Errors */ -#define AT91_ECC_PR (AT91_ECC + 0x0c)/* Parity register */ +#define AT91_ECC_PR 0x0c/* Parity register */ #define AT91_ECC_BITADDR (0xf << 0)/* Bit Error Address */ #define AT91_ECC_WORDADDR (0xfff << 4)/* Word Error Address */ +#define AT91_ECC_PARITY (0xffff << 0)/* Parity */ -#define AT91_ECC_NPR (AT91_ECC + 0x10)/* NParity register */ +#define AT91_ECC_NPR 0x10/* NParity register */ #define AT91_ECC_NPARITY (0xffff << 0)/* NParity */ #endif
include/asm-arm/arch-at91/at91sam9260.h +21 -0
@@ -79,6 +79,27 @@#define AT91_BASE_SYS 0xffffe800/* +* System Peripherals physical base addresses. +*/ +#define AT91SAM9260_ECC 0xffffe800 +#define AT91SAM9260_SDRAMC 0xffffea00 +#define AT91SAM9260_SMC 0xffffec00 +#define AT91SAM9260_MATRIX 0xffffee00 +#define AT91SAM9260_CCFG 0xffffef10 +#define AT91SAM9260_AIC 0xfffff000 +#define AT91SAM9260_DBGU 0xfffff200 +#define AT91SAM9260_PIOA 0xfffff400 +#define AT91SAM9260_PIOB 0xfffff600 +#define AT91SAM9260_PIOC 0xfffff800 +#define AT91SAM9260_PMC 0xfffffc00 +#define AT91SAM9260_RSTC 0xfffffd00 +#define AT91SAM9260_SHDWC 0xfffffd10 +#define AT91SAM9260_RTT 0xfffffd20 +#define AT91SAM9260_PIT 0xfffffd30 +#define AT91SAM9260_WDT 0xfffffd40 +#define AT91SAM9260_GPBR 0xfffffd50 + +/* * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_ECC (0xffffe800 - AT91_BASE_SYS)
include/asm-arm/arch-at91/at91sam9263.h +27 -0
@@ -75,6 +75,33 @@#define AT91_BASE_SYS 0xffffe000/* +* System Peripherals physical base addresses. +*/ +#define AT91SAM9263_ECC0 0xffffe000 +#define AT91SAM9263_SDRAMC0 0xffffe200 +#define AT91SAM9263_SMC0 0xffffe400 +#define AT91SAM9263_ECC1 0xffffe600 +#define AT91SAM9263_SDRAMC1 0xffffe800 +#define AT91SAM9263_SMC1 0xffffea00 +#define AT91SAM9263_MATRIX 0xffffec00 +#define AT91SAM9263_CCFG 0xffffed10 +#define AT91SAM9263_DBGU 0xffffee00 +#define AT91SAM9263_AIC 0xfffff000 +#define AT91SAM9263_PIOA 0xfffff200 +#define AT91SAM9263_PIOB 0xfffff400 +#define AT91SAM9263_PIOC 0xfffff600 +#define AT91SAM9263_PIOD 0xfffff800 +#define AT91SAM9263_PIOE 0xfffffa00 +#define AT91SAM9263_PMC 0xfffffc00 +#define AT91SAM9263_RSTC 0xfffffd00 +#define AT91SAM9263_SHDWC 0xfffffd10 +#define AT91SAM9263_RTT0 0xfffffd20 +#define AT91SAM9263_PIT 0xfffffd30 +#define AT91SAM9263_WDT 0xfffffd40 +#define AT91SAM9263_RTT1 0xfffffd50 +#define AT91SAM9263_GPBR 0xfffffd60 + +/* * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_ECC0 (0xffffe000 - AT91_BASE_SYS)
Quoted 5 lines · Richard Genoud
This is a patch to use the hardware ECC controller of the AT91SAM9260 and AT91SAM9263 for the AT91 nand. On AT91 NAND, there's now a choice between ECC soft, ECC hard or no ECC (for debug).
Quoted 7 lines
It has been tested on AT91SAM9263 with 8 bits large and small page NAND.
kernel version : 2.6.25-rc2
Signed-off-by Richard Genoud <[email protected]>
patching file arch/arm/mach-at91/at91sam9260_devices.c
Hunk #1 FAILED at 288.
1 out of 1 hunk FAILED -- saving rejects to file arch/arm/mach-at91/at91sam9260_devices.c.rej patching file arch/arm/mach-at91/at91sam9263_devices.c
Hunk #1 FAILED at 358.
1 out of 1 hunk FAILED -- saving rejects to file arch/arm/mach-at91/at91sam9263_devices.c.rej patching file drivers/mtd/nand/Kconfig
Hunk #1 succeeded at 278 with fuzz 2.
patching file drivers/mtd/nand/at91_nand.c
Hunk #3 succeeded at 139 with fuzz 2.
Hunk #11 FAILED at 584.
1 out of 11 hunks FAILED -- saving rejects to file drivers/mtd/nand/at91_nand.c.rej patching file include/asm-arm/arch-at91/at91_ecc.h
Hunk #1 FAILED at 13.
1 out of 1 hunk FAILED -- saving rejects to file include/asm-arm/arch-at91/at91_ecc.h.rej patching file include/asm-arm/arch-at91/at91sam9260.h
patching file include/asm-arm/arch-at91/at91sam9263.h
Signature · 1 line
dwmw2
Quoted 3 lines · Richard Genoud
I don't know what kernel you use, but I'm getting no error with this patch on kernel 2.6.25-rc2 (and on 2.6.25 it's also ok) that I've downloaded from kernel.org:
Hm, that's true. There seem to have been changes since 2.6.25 which cause the conflicts. Please could you make it apply to the current git tree?
Thanks.
Signature · 1 line
dwmw2
Quoted 5 lines
Hm, that's true. There seem to have been changes since 2.6.25 which
cause the conflicts. Please could you make it apply to the current git tree?Thanks.
I'm firewalled for the moment (I can't use git), I'll try to do this at home.
Richard.
Quoted 7 lines · Richard Genoud
Quoted 5 lines
Hm, that's true. There seem to have been changes since 2.6.25 which
cause the conflicts. Please could you make it apply to the current git tree?Thanks.
I'm firewalled for the moment (I can't use git), I'll try to do this at home.
Try http://git.infradead.org/mtd-2.6.git?a=snapshot;h=HEAD;sf=tgz or
http://git.infradead.org/mtd-2.6.git?a=commitdiff_plain;h=HEAD;hp=linus
Signature · 1 line
dwmw2
Quoted 11 lines
patching file
arch/arm/mach-at91/at91sam9260_devices.c
Hunk #1 FAILED at 288.
1 out of 1 hunk FAILED -- saving rejects to filearch/arm/mach-at91/at91sam9260_devices.c.rejpatching filearch/arm/mach-at91/at91sam9263_devices.c
Hunk #1 FAILED at 358.
1 out of 1 hunk FAILED -- saving rejects to filearch/arm/mach-at91/at91sam9263_devices.c.rejpatching filedrivers/mtd/nand/Kconfig
Hunk #1 succeeded at 278 with fuzz 2.
patching filedrivers/mtd/nand/at91_nand.c
Hunk #3 succeeded at 139 with fuzz 2.
Hunk #11 FAILED at 584.
Quoted 8 lines
1 out of 11 hunks FAILED -- saving rejects to file
drivers/mtd/nand/at91_nand.c.rejpatching fileinclude/asm-arm/arch-at91/at91_ecc.h
Hunk #1 FAILED at 13.
1 out of 1 hunk FAILED -- saving rejects to fileinclude/asm-arm/arch-at91/at91_ecc.h.rejpatching fileinclude/asm-arm/arch-at91/at91sam9260.h
patching fileinclude/asm-arm/arch-at91/at91sam9263.h
--
dwmw2
I don't know what kernel you use, but I'm getting no error with this patch on kernel 2.6.25-rc2 (and on 2.6.25 it's also ok) that I've downloaded from kernel.org:
~/dev/kernels/linux-2.6.25-rc2$ patch -p1 < ../mail.google.com patching file arch/arm/mach-at91/at91sam9260_devices.c patching file arch/arm/mach-at91/at91sam9263_devices.c patching file drivers/mtd/nand/Kconfig
patching file drivers/mtd/nand/at91_nand.c
patching file include/asm-arm/arch-at91/at91_ecc.h patching file include/asm-arm/arch-at91/at91sam9260.h patching file include/asm-arm/arch-at91/at91sam9263.h
This is a patch to use the hardware ECC controller of the AT91SAM9260 and AT91SAM9263 for the AT91 nand. On AT91 NAND, there's now a choice between ECC soft, ECC hard or no ECC (for debug).
It has been tested on AT91SAM9263 with 8 bits large and small page NAND.
kernel version : 2.6.25 linux-mtd master tree
--- drivers/mtd/nand/Kconfig | 41 ++++ drivers/mtd/nand/at91_nand.c | 361 +++++++++++++++++++++++++++++- 2 files changed, 397 insertions(+), 5 deletions(-)
arch/arm/mach-at91/at91sam9260_devices.c +0 -0
drivers/mtd/nand/Kconfig +41 -0
47 lines not on this page · raw message
drivers/mtd/nand/at91_nand.c +356 -5
434 lines not on this page · raw message
drivers/mtd/nand/at91_nand.c static void at91_nand_disable(struct at91_nand_host *host) · line 205
Quoted 13 lines · Richard Genoud
drivers/mtd/nand/at91_nand.c +13
-0+static int at91_nand_calculate (struct mtd_info *mtd, + const u_char *dat, unsigned char *ecc_code) +{ + struct nand_chip *nand_chip = mtd->priv; + struct at91_nand_host *host = nand_chip->priv; + uint32_t *eccpos = nand_chip->ecc.layout->eccpos; + unsigned int ecc_value; + + /* get the first 2 ECC bytes */ + ecc_value = ecc_readl(host->ecc, PR) & AT91_ECC_PARITY; + + ecc_code[eccpos[0]] = ecc_value & 0xFF; + ecc_code[eccpos[1]] = (ecc_value >> 8) & 0xFF;
My copy of the sam9263 docs doesn't list an "ECC_PARITY" field in the PR register ... just two masked fields, 0xfff0 and 0x000f labeled WORDADDR and BITADDR respectively. (Which evidently are combined into a single opague 0xffff mask on block writes, and are interpretable only on block reads.)
And the system header doesn't have an ECC_PARITY mask ... so I get build errors with current GIT.
drivers/mtd/nand/at91_nand.c static void at91_nand_disable(struct at91_nand_host *host) · line 211
Quoted 6 lines
drivers/mtd/nand/at91_nand.c +6
-0+ + /* get the last 2 ECC bytes */ + ecc_value = ecc_readl(host->ecc, NPR) & AT91_ECC_NPARITY; + + ecc_code[eccpos[2]] = ecc_value & 0xFF; + ecc_code[eccpos[3]] = (ecc_value >> 8) & 0xFF;
That one builds OK.
I suggest you just remove the masks from the readl() lines. They're not necessary.
- Dave
Quoted 3 lines
drivers/mtd/nand/at91_nand.c +3
-0+ + return 0; +}
2008/4/24, David Brownell <[email protected]>:
Quoted 11 lines
My copy of the sam9263 docs doesn't list an "
ECC_PARITY" field
in the PR register ... just two masked fields,0xfff0and0x000flabeled WORDADDR and BITADDR respectively. (Which evidently are combined into a single opague0xffffmask on block writes, and are interpretable only on block reads.)And the system header doesn't have an
ECC_PARITYmask ... so I get build errors with current GIT.- Dave
you're right, this is my bad. Thanks for pointing this out.
David W., could you apply the patch bellow to make things right again ?
The AT91_ECC_PARITY mask does not exist (and masking with it was useless). kernel version : mtd-2.6 current git
---
mtd/nand/at91_nand.c renamed from mtd/nand/at91_nand.c.orig +1 -1
@@ -199,7 +199,7 @@ static int at91_nand_calculate(struct mtunsigned int ecc_value;/* get the first 2 ECC bytes */ - ecc_value =ecc_readl (host->ecc,PR ) &AT91_ECC_PARITY ; + ecc_value =ecc_readl (host->ecc,PR ); ecc_code[eccpos[0 ]] = ecc_value &0xFF ; ecc_code[eccpos[1 ]] = (ecc_value >>8 ) &0xFF ;