Hey,

I had a look at using hardware ECC for the s3c244x. I'm in a state that I 
patched uboot to write a ECC for dfu flashed stuff that the kernel likes to 
read it and is happy.

What is left:
        - Flag day? Provide a upgrade path?
        - hardware_ecc=1 into the cmdline and then enable it in the kernel
        - Check if the ECC is useful at all (have to look at the result of the 
hardware register)
        - Is the ECC config useful? We have main memory ECC0 and ECC1 but only 
write 
in so small chunks that we fill up ECC0? How does this relate to the 2K page
        - I have to learn more about OOB, ECC and NAND. And figure out why we 
do the 
ECC over 256 bytes for LP...
        - Find out why it is not twice as fast?
        - Wonder why we only have 8-bit flash and if it is matters?
        - Handle hardware_ecc=1 in the kernel and have a default for software.. 
(specially after the revert)...

attached:
        - two uboot patches
        - two kernel patches
        - my primary log... for performance...

have fun
        z.
From 9449252787861fa476a8586067436eaa54d81d69 Mon Sep 17 00:00:00 2001
From: Holger Freyther <[EMAIL PROTECTED](none)>
Date: Sat, 26 Jul 2008 22:49:23 +0200
Subject: [PATCH] [s3c2440] Enable hardware ECC for large page NAND devices
     Enable hardware ECC for the s3c2442 CPU and large page (2K) NAND pages as
     used by the freerunner (gta02). NAND_ECC_HW3_256 was picked to be
     compatible with the Linux kernel. The values of ECC have not been verified.

    This way we can flash the kernel and rootfs from uboot and be able to use
    that from the kernel.
---
 cpu/arm920t/s3c24x0/nand.c      |   54 ++++++++++++++++++++++++++++++++++----
 include/configs/neo1973_gta02.h |    4 +-
 2 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/cpu/arm920t/s3c24x0/nand.c b/cpu/arm920t/s3c24x0/nand.c
index 2d76798..73a9f6b 100644
--- a/cpu/arm920t/s3c24x0/nand.c
+++ b/cpu/arm920t/s3c24x0/nand.c
@@ -1,6 +1,7 @@
 /*
  * (C) Copyright 2006 OpenMoko, Inc.
  * Author: Harald Welte <[EMAIL PROTECTED]>
+ *         Holger Freyther <[EMAIL PROTECTED]>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -200,18 +201,50 @@ static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
 	return 0;
 }
 
-static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
-				     u_char *read_ecc, u_char *calc_ecc)
+#endif
+
+#ifdef CONFIG_S3C2440_NAND_HWECC
+static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+	DEBUGN("%s(%p, %d)\n", __func__, mtd, mode);
+
+	/* 
+	 * In software mode, ECC module generates ECC parity code for all
+	 * read / write data. So you have to reset ECC value by writing the
+	 * InitECC(NFCONT[4]) bit as ‘1’ and have to clear theMainECCLock(
+	 * NFCONT[5]) bit to ‘0’(Unlock) before read or write data.
+	 */
+	NFCONT |= S3C2440_NFCONF_INITECC;
+	NFCONT &= ~S3C2440_NFCONF_MAINECCLOCK;
+}
+
+static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+                                      u_char *ecc_code)
+{
+	unsigned long ecc = NFMECC0;
+
+	ecc_code[0] = ecc;
+	ecc_code[1] = ecc >> 8;
+	ecc_code[2] = ecc >> 16;
+
+	DEBUGN("%s(%p,): 0x%02x 0x%02x 0x%02x\n",
+		__func__, mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
+
+	return 0;
+}
+#endif
+
+static int s3c24xx_nand_correct_data_noop(struct mtd_info *mtd, u_char *dat,
+				          u_char *read_ecc, u_char *calc_ecc)
 {
 	if (read_ecc[0] == calc_ecc[0] &&
 	    read_ecc[1] == calc_ecc[1] &&
 	    read_ecc[2] == calc_ecc[2])
 		return 0;
 
-	printf("s3c2410_nand_correct_data: not implemented\n");
+	printf("%s: not implemented\n", __func__);
 	return -1;
 }
-#endif
 
 int board_nand_init(void) __attribute__((weak, alias("__board_nand_init")));
 
@@ -252,11 +285,20 @@ int __board_nand_init(struct nand_chip *nand)
 
 	nand->dev_ready = s3c2410_dev_ready;
 
-#ifdef CONFIG_S3C2410_NAND_HWECC
+#if defined(CONFIG_S3C2410_NAND_HWECC)
 	nand->enable_hwecc = s3c2410_nand_enable_hwecc;
 	nand->calculate_ecc = s3c2410_nand_calculate_ecc;
-	nand->correct_data = s3c2410_nand_correct_data;
+	nand->correct_data = s3c24xx_nand_correct_data_noop;
 	nand->eccmode = NAND_ECC_HW3_512;
+#elif defined(CONFIG_S3C2440_NAND_HWECC)
+	/*
+	 * Assume we have a large page flash and set the eccmode so that it 
+	 * will be compatible with the linux kernel.
+         */
+	nand->enable_hwecc = s3c2440_nand_enable_hwecc;
+	nand->calculate_ecc = s3c2440_nand_calculate_ecc;
+	nand->correct_data = s3c24xx_nand_correct_data_noop;
+	nand->eccmode = NAND_ECC_HW3_256;
 #else
 	nand->eccmode = NAND_ECC_SOFT;
 #endif
diff --git a/include/configs/neo1973_gta02.h b/include/configs/neo1973_gta02.h
index d69d348..9133545 100644
--- a/include/configs/neo1973_gta02.h
+++ b/include/configs/neo1973_gta02.h
@@ -194,7 +194,7 @@ extern char __cfg_prompt[20];
 #define CONFIG_EXTRA_ENV_SETTINGS 					\
 	"usbtty=cdc_acm\0"						\
 	"stderr=usbtty\0stdout=usbtty\0stdin=usbtty\0"			\
-	"bootargs_base=rootfstype=jffs2 root=/dev/mtdblock6 console=ttySAC2,115200 console=tty0 loglevel=8\0" \
+	"bootargs_base=rootfstype=jffs2 root=/dev/mtdblock6 console=ttySAC2,115200 console=tty0 loglevel=8 hardware_ecc=1\0" \
 	""
 #define CONFIG_CMD_LOADENV
 #define CONFIG_CMD_DEFAULTENV
@@ -281,7 +281,7 @@ extern char __cfg_prompt[20];
 #endif
 
 #define CONFIG_S3C2410_NAND_BBT                1
-//#define CONFIG_S3C2410_NAND_HWECC              1
+#define CONFIG_S3C2440_NAND_HWECC              1
 
 #define CONFIG_DRIVER_PCF50633		1
 #define	CONFIG_RTC_PCF50633		1
-- 
1.5.4.3

From 94f13becd26989e9ee17673bc3211fd180d911af Mon Sep 17 00:00:00 2001
From: Holger Freyther <[EMAIL PROTECTED](none)>
Date: Sat, 26 Jul 2008 08:51:02 +0200
Subject: [PATCH] [gta02] Remove the code as it is marked liked this
     We can read the PCB version from kernel/user space so I assume
     we do not need this anymore.

---
 board/neo1973/gta02/gta02.c |    7 -------
 1 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/board/neo1973/gta02/gta02.c b/board/neo1973/gta02/gta02.c
index e77359b..6162f37 100644
--- a/board/neo1973/gta02/gta02.c
+++ b/board/neo1973/gta02/gta02.c
@@ -309,13 +309,6 @@ static void set_revision(void)
 		}
 	}
 	sprintf(__cfg_prompt, "GTA02v%d # ", gta02_revision);
-
-#if 1 /* remove these after checking that Andy doesn't need them anymore */
-	printf("PCB rev: 0x%03X\n", rev);
-	/* expose in the env so we can add to kernel commandline */
-	sprintf(buf, "0x%03X", rev);
-	setenv("pcb_rev", buf);
-#endif
 }
 
 static void poll_charger(void)
-- 
1.5.4.3

Hardware ECC: 256 bytes
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  1.9  0.4   1524   564 ?        Ss   16:16   0:05 init [5]      
root         2  0.0  0.0      0     0 ?        S<   16:16   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S<   16:16   0:00 [ksoftirqd/0]
root         4  0.0  0.0      0     0 ?        S<   16:16   0:00 [watchdog/0]
root         5  0.1  0.0      0     0 ?        S<   16:16   0:00 [events/0]
root         6  0.0  0.0      0     0 ?        S<   16:16   0:00 [khelper]
root        79  0.0  0.0      0     0 ?        S<   16:16   0:00 [kblockd/0]
root        85  0.0  0.0      0     0 ?        S<   16:16   0:00 [ksuspend_usbd]
root        91  0.0  0.0      0     0 ?        S<   16:16   0:00 [khubd]
root        94  0.0  0.0      0     0 ?        S<   16:16   0:00 [kseriod]
root       101  0.0  0.0      0     0 ?        S<   16:16   0:00 [kmmcd]
root       136  0.0  0.0      0     0 ?        S    16:16   0:00 [pdflush]
root       137  0.0  0.0      0     0 ?        S    16:16   0:00 [pdflush]
root       138  0.0  0.0      0     0 ?        S<   16:16   0:00 [kswapd0]
root       139  0.0  0.0      0     0 ?        S<   16:16   0:00 [aio/0]
root       157  0.0  0.0      0     0 ?        S<   16:16   0:00 [kapmd]
root       189  0.0  0.0      0     0 ?        S<   16:16   0:00 [glamo-spi-gpi]
root       199  0.0  0.0      0     0 ?        S<   16:16   0:00 [mtdblockd]
root       228  0.0  0.0      0     0 ?        S<   16:16   0:00 [spi_s3c24xx_g]
root       281  0.0  0.0      0     0 ?        S<   16:16   0:00 [SDIO Helper]
root       285  0.0  0.0      0     0 ?        S<   16:16   0:00 [SDIO Helper]
root       310  0.0  0.0      0     0 ?        S<   16:16   0:00 [krfcommd]
root      1020  8.1  0.0      0     0 ?        SN   16:17   0:21 [jffs2_gcd_mtd]
root      1750  0.1  0.5   2808   684 ?        Ss   16:18   0:00 /sbin/syslogd -
root      1752  0.2  0.4   2744   608 ?        Ss   16:18   0:00 /sbin/klogd -n
root      1819  0.1  0.6   2924   840 ttySAC2  Ss   16:19   0:00 -sh
root      1820  0.0  0.4   1764   540 tty1     Ss+  16:19   0:00 /sbin/getty 384
root      1974  0.0  0.7   2248   884 ttySAC2  R+   16:21   0:00 ps xua
[EMAIL PROTECTED]:~# cat /proc/partitions 
major minor  #blocks  name

  31     0       2048 mtdblock0
  31     1        256 mtdblock1
  31     2        256 mtdblock2
  31     3       8192 mtdblock3
  31     4        640 mtdblock4
  31     5        256 mtdblock5
  31     6     252544 mtdblock6
[EMAIL PROTECTED]:~#  time dd if=/dev/mtdblock6 bs=1024 count=10240 of=/dev/null
10240+0 records in
10240+0 records out
real    0m 2.82s
user    0m 0.03s
sys     0m 0.72s
[EMAIL PROTECTED]:~# cat /proc/partitions 
major minor  #blocks  name

  31     0       2048 mtdblock0
  31     1        256 mtdblock1
  31     2        256 mtdblock2
  31     3       8192 mtdblock3
  31     4        640 mtdblock4
  31     5        256 mtdblock5
  31     6     252544 mtdblock6
[EMAIL PROTECTED]:~#  time dd if=/dev/mtdblock6 bs=1024 count=10240 of=/dev/null
10240+0 records in
10240+0 records out
real    0m 3.10s
user    0m 0.02s
sys     0m 0.76s
[EMAIL PROTECTED]:~#  time dd if=/dev/mtdblock6 bs=1024 count=10240 of=/dev/null
10240+0 records in
10240+0 records out
real    0m 2.90s
user    0m 0.03s
sys     0m 0.70s
[EMAIL PROTECTED]:~#  time dd if=/dev/mtdblock6 bs=1024 count=10240 of=/dev/null
10240+0 records in
10240+0 records out
real    0m 2.88s
user    0m 0.00s
sys     0m 0.72s
[EMAIL PROTECTED]:~#  time dd if=/dev/mtdblock6 bs=1024 count=10240 of=/dev/null
10240+0 records in
10240+0 records out
real    0m 2.65s
user    0m 0.03s
sys     0m 0.68s
[EMAIL PROTECTED]:~#  time dd if=/dev/mtdblock6 bs=1024 count=10240 of=/dev/null
10240+0 records in
10240+0 records out
real    0m 3.14s
user    0m 0.04s
sys     0m 0.76s

Software ECC:
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  1.5  0.4   1524   564 ?        Ss   15:26   0:06 init [5]      
root         2  0.0  0.0      0     0 ?        S<   15:26   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S<   15:26   0:00 [ksoftirqd/0]
root         4  0.0  0.0      0     0 ?        S<   15:26   0:00 [watchdog/0]
root         5  0.1  0.0      0     0 ?        S<   15:26   0:00 [events/0]
root         6  0.0  0.0      0     0 ?        S<   15:26   0:00 [khelper]
root        79  0.0  0.0      0     0 ?        S<   15:26   0:00 [kblockd/0]
root        85  0.0  0.0      0     0 ?        S<   15:26   0:00 [ksuspend_usbd]
root        91  0.0  0.0      0     0 ?        S<   15:26   0:00 [khubd]
root        94  0.0  0.0      0     0 ?        S<   15:26   0:00 [kseriod]
root       101  0.0  0.0      0     0 ?        S<   15:26   0:00 [kmmcd]
root       136  0.0  0.0      0     0 ?        S    15:26   0:00 [pdflush]
root       137  0.0  0.0      0     0 ?        S    15:26   0:00 [pdflush]
root       138  0.0  0.0      0     0 ?        S<   15:26   0:00 [kswapd0]
root       139  0.0  0.0      0     0 ?        S<   15:26   0:00 [aio/0]
root       157  0.0  0.0      0     0 ?        S<   15:26   0:00 [kapmd]
root       189  0.0  0.0      0     0 ?        S<   15:26   0:00 [glamo-spi-gpi]
root       199  0.0  0.0      0     0 ?        S<   15:26   0:00 [mtdblockd]
root       228  0.0  0.0      0     0 ?        S<   15:26   0:00 [spi_s3c24xx_g]
root       283  0.0  0.0      0     0 ?        S<   15:26   0:00 [SDIO Helper]
root       287  0.0  0.0      0     0 ?        S<   15:26   0:00 [SDIO Helper]
root       312  0.0  0.0      0     0 ?        S<   15:26   0:00 [krfcommd]
root      1021  7.4  0.0      0     0 ?        SN   15:27   0:26 [jffs2_gcd_mtd]
root      1755  0.1  0.5   2808   684 ?        Ss   15:29   0:00 /sbin/syslogd -
root      1757  0.2  0.4   2744   608 ?        Ss   15:29   0:00 /sbin/klogd -n
root      1824  0.1  0.6   2924   836 ttySAC2  Ss   15:29   0:00 -sh
root      1825  0.0  0.4   1764   540 tty1     Ss+  15:29   0:00 /sbin/getty 384
root      1981  0.0  0.7   2248   884 ttySAC2  R+   15:33   0:00 ps xua



[EMAIL PROTECTED]:~# time dd if=/dev/mtdblockX bs=1024 count=10240 of=/dev/null
dd: can't open '/dev/mtdblockX': No such file or directory
Command exited with non-zero status 1
real    0m 0.03s
user    0m 0.00s
sys     0m 0.02s
[EMAIL PROTECTED]:~# 
[EMAIL PROTECTED]:~# time dd if=/dev/mtdblockX bs=1024 count=10240 of=/dev/null
[EMAIL PROTECTED]:~# ls /dev/mtd
/dev/mtd0       /dev/mtd2ro     /dev/mtd5       /dev/mtdblock1  /dev/mtdblock6
/dev/mtd0ro     /dev/mtd3       /dev/mtd5ro     /dev/mtdblock2
/dev/mtd1       /dev/mtd3ro     /dev/mtd6       /dev/mtdblock3
/dev/mtd1ro     /dev/mtd4       /dev/mtd6ro     /dev/mtdblock4
/dev/mtd2       /dev/mtd4ro     /dev/mtdblock0  /dev/mtdblock5
[EMAIL PROTECTED]:~# ls /dev/mtd
/dev/mtd0       /dev/mtd2ro     /dev/mtd5       /dev/mtdblock1  /dev/mtdblock6
/dev/mtd0ro     /dev/mtd3       /dev/mtd5ro     /dev/mtdblock2
/dev/mtd1       /dev/mtd3ro     /dev/mtd6       /dev/mtdblock3
/dev/mtd1ro     /dev/mtd4       /dev/mtd6ro     /dev/mtdblock4
/dev/mtd2       /dev/mtd4ro     /dev/mtdblock0  /dev/mtdblock5
[EMAIL PROTECTED]:~# ls /dev/mtdblock1 
[EMAIL PROTECTED]:~# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 00200000 00010000 "physmap-flash.0"
mtd1: 00040000 00020000 "u-boot"
mtd2: 00040000 00020000 "u-boot_env"
mtd3: 00800000 00020000 "kernel"
mtd4: 000a0000 00020000 "splash"
mtd5: 00040000 00020000 "factory"
mtd6: 0f6a0000 00020000 "rootfs"
[EMAIL PROTECTED]:~# time dd if=/dev/mtdblock2 bs=1024 count=10240 of=/dev/null
256+0 records in
256+0 records out
real    0m 0.11s
user    0m 0.00s
sys     0m 0.04s
[EMAIL PROTECTED]:~# time dd if=/dev/mtdblock6 bs=1024 count=10240 of=/dev/null
10240+0 records in
10240+0 records out
real    0m 3.60s
user    0m 0.02s
sys     0m 0.90s
[EMAIL PROTECTED]:~# time dd if=/dev/mtdblock6 bs=1024 count=10240 of=/dev/null
10240+0 records in
10240+0 records out
real    0m 3.86s
user    0m 0.04s
sys     0m 0.90s
[EMAIL PROTECTED]:~# time dd if=/dev/mtdblock6 bs=1024 count=10240 of=/dev/null
10240+0 records in
10240+0 records out
real    0m 3.94s
user    0m 0.03s
sys     0m 0.93s
[EMAIL PROTECTED]:~# time dd if=/dev/mtdblock6 bs=1024 count=10240 of=/dev/null
10240+0 records in
10240+0 records out
real    0m 3.90s
user    0m 0.02s
sys     0m 0.90s
[EMAIL PROTECTED]:~# time dd if=/dev/mtdblock6 bs=1024 count=10240 of=/dev/null
10240+0 records in
10240+0 records out
real    0m 3.97s
user    0m 0.03s
sys     0m 0.89s
[EMAIL PROTECTED]:~# time dd if=/dev/mtdblock6 bs=1024 count=10240 of=/dev/null
10240+0 records in
10240+0 records out
real    0m 3.96s
user    0m 0.06s
sys     0m 0.88s

From 42862206c5c586c0e92a1c3bb087bbcc7c9c4194 Mon Sep 17 00:00:00 2001
From: Holger Freyther <[EMAIL PROTECTED]>
Date: Thu, 24 Jul 2008 18:37:49 +0200
Subject: [PATCH] Revert "s3c2440-nand-disable-hwecc.patch"

This reverts commit 1d89da736ed33d3f7c398fb9f8dfddecb7c7c7a9.
---
 drivers/mtd/nand/s3c2410.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index f7dd4e0..495381c 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -656,7 +656,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
 	nmtd->mtd.owner    = THIS_MODULE;
 	nmtd->set	   = set;
 
-	if (info->cpu_type == TYPE_S3C2410 && hardware_ecc) {
+	if (hardware_ecc) {
 		chip->ecc.calculate = s3c2410_nand_calculate_ecc;
 		chip->ecc.correct   = s3c2410_nand_correct_data;
 		chip->ecc.mode	    = NAND_ECC_HW;
-- 
1.5.2.3

From 67d278f16f4291816790dcd7716d9e8a73cb4e9d Mon Sep 17 00:00:00 2001
From: Holger Freyther <[EMAIL PROTECTED]>
Date: Sat, 26 Jul 2008 22:57:27 +0200
Subject: [PATCH] [gta02] Disable the NAND debugging as it would print every hardware ECC

---
 defconfig-2.6.24 |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/defconfig-2.6.24 b/defconfig-2.6.24
index 6d9faff..f185d5d 100644
--- a/defconfig-2.6.24
+++ b/defconfig-2.6.24
@@ -726,7 +726,7 @@ CONFIG_MTD_NAND_VERIFY_WRITE=y
 # CONFIG_MTD_NAND_MUSEUM_IDS is not set
 CONFIG_MTD_NAND_IDS=y
 CONFIG_MTD_NAND_S3C2410=y
-CONFIG_MTD_NAND_S3C2410_DEBUG=y
+# CONFIG_MTD_NAND_S3C2410_DEBUG is not set
 CONFIG_MTD_NAND_S3C2410_HWECC=y
 # CONFIG_MTD_NAND_S3C2410_CLKSTOP is not set
 # CONFIG_MTD_NAND_DISKONCHIP is not set
-- 
1.5.2.3

Reply via email to