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