summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schaeffer <daniel.schaeffer@timesys.com>2009-10-08 13:37:39 -0400
committerDaniel Schaeffer <daniel.schaeffer@timesys.com>2009-10-08 13:37:39 -0400
commit0d01165105959ee63c492cfe0bb3acf903c611a8 (patch)
tree96122c5137d3e23cbe462b9fc65bb4de7859e829
parentd2788bb87bc499f7a04970766f0972683ce6f002 (diff)
This patch originally from LogicPD OMAP35x Release 1.6.1 Original Patch Name: u-boot-2009.03-lv-som-09-yaffs2.patch
-rw-r--r--Makefile2
-rw-r--r--board/omap3/lv_som/lv_som.c3
-rw-r--r--common/cmd_nand.c15
-rw-r--r--cpu/arm_cortexa8/omap3/board.c20
-rw-r--r--drivers/mtd/nand/nand_base.c1
-rw-r--r--drivers/mtd/nand/nand_util.c276
-rw-r--r--drivers/mtd/nand/omap_gpmc.c22
-rw-r--r--include/asm-arm/arch-omap3/omap_gpmc.h15
-rw-r--r--include/configs/omap3_lv_som.h46
-rw-r--r--lib_arm/board.c6
10 files changed, 395 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index 64666420d0..4582f0639d 100644
--- a/Makefile
+++ b/Makefile
@@ -276,7 +276,7 @@ LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a
LIBBOARD := $(addprefix $(obj),$(LIBBOARD))
# Add GCC lib
-PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
+PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc -lgcc_eh
# The "tools" are needed early, so put this first
# Don't include stuff already done in $(LIBS)
diff --git a/board/omap3/lv_som/lv_som.c b/board/omap3/lv_som/lv_som.c
index 2d6967a8e7..ebcedcc01b 100644
--- a/board/omap3/lv_som/lv_som.c
+++ b/board/omap3/lv_som/lv_som.c
@@ -225,6 +225,9 @@ int misc_init_r(void)
fix_flash_sync();
+ /* Switch to Hardware ECC mode */
+ omap_nand_switch_ecc(1);
+
dieid_num_r();
return 0;
}
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 04b3200e57..f657172b9f 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -381,6 +381,19 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
else
ret = nand_write_skip_bad(nand, off, &size,
(u_char *)addr);
+ } else if (s != NULL && !strcmp(s, ".yaffs")) {
+ nand_write_options_t opts;
+ memset(&opts, 0, sizeof(opts));
+ opts.buffer = (u_char *) addr;
+ opts.length = size;
+ opts.offset = off;
+ opts.pad = 0;
+ opts.blockalign = 1;
+ opts.quiet = quiet;
+ opts.writeoob = 1;
+ opts.autoplace = 1;
+ opts.forceyaffs = 1;
+ nand_write_opts(nand, &opts);
} else if (s != NULL && !strcmp(s, ".oob")) {
/* out-of-band data */
mtd_oob_ops_t ops = {
@@ -475,6 +488,8 @@ U_BOOT_CMD(nand, 5, 1, do_nand,
"nand write - addr off|partition size\n"
" read/write 'size' bytes starting at offset 'off'\n"
" to/from memory address 'addr', skipping bad blocks.\n"
+ "nand write[.yaffs] - addr off size - write `size' byte yaffs2 image\n"
+ " at offset `off' from memory address `addr'\n"
"nand erase [clean] [off size] - erase 'size' bytes from\n"
" offset 'off' (entire device if not specified)\n"
"nand bad - show bad blocks\n"
diff --git a/cpu/arm_cortexa8/omap3/board.c b/cpu/arm_cortexa8/omap3/board.c
index 7bb3e284b5..a591082992 100644
--- a/cpu/arm_cortexa8/omap3/board.c
+++ b/cpu/arm_cortexa8/omap3/board.c
@@ -36,6 +36,7 @@
#include <asm/io.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/mem.h>
+#include <nand.h>
extern omap3_sysinfo sysinfo;
@@ -319,6 +320,25 @@ void abort(void)
*****************************************************************************/
static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
+ struct mtd_info *mtd;
+ struct nand_chip *nand;
+
+ /* the following commands operate on the current device */
+ if (nand_curr_device < 0 || nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
+ !nand_info[nand_curr_device].name) {
+ puts("\nno devices available\n");
+ return 1;
+ }
+ mtd = &nand_info[nand_curr_device];
+ nand = mtd->priv;
+
+ if (argc == 1) {
+ if (nand->ecc.mode == NAND_ECC_SOFT)
+ printf("Software ECC\n");
+ else
+ printf("Hardware ECC\n");
+ return 0;
+ }
if (argc != 2)
goto usage;
if (strncmp(argv[1], "hw", 2) == 0)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index d33fee242f..4af3f50f3d 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1993,6 +1993,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n",
(unsigned int)to, (int)ops->ooblen);
+
if (ops->mode == MTD_OOB_AUTO)
len = chip->ecc.layout->oobavail;
else
diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
index 6ba52b30c0..34b9755858 100644
--- a/drivers/mtd/nand/nand_util.c
+++ b/drivers/mtd/nand/nand_util.c
@@ -204,7 +204,6 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
}
/* XXX U-BOOT XXX */
-#if 0
#define MAX_PAGE_SIZE 2048
#define MAX_OOB_SIZE 64
@@ -217,26 +216,48 @@ static unsigned char oob_buf[MAX_OOB_SIZE];
/* OOB layouts to pass into the kernel as default */
static struct nand_ecclayout none_ecclayout = {
- .useecc = MTD_NANDECC_OFF,
+ .eccbytes = 0,
};
static struct nand_ecclayout jffs2_ecclayout = {
- .useecc = MTD_NANDECC_PLACE,
.eccbytes = 6,
- .eccpos = { 0, 1, 2, 3, 6, 7 }
+ .eccpos = {0, 1, 2, 3, 6, 7},
+ .oobfree = { {8, 8} },
+ .oobavail = 8,
};
static struct nand_ecclayout yaffs_ecclayout = {
- .useecc = MTD_NANDECC_PLACE,
.eccbytes = 6,
- .eccpos = { 8, 9, 10, 13, 14, 15}
+ .eccpos = { 8, 9, 10, 13, 14, 15},
+ .oobfree = { {0, 4}, {6, 2}, {11, 2} },
+ .oobavail = 8,
};
-static struct nand_ecclayout autoplace_ecclayout = {
- .useecc = MTD_NANDECC_AUTOPLACE
+#ifdef CONFIG_OMAP3_LV_SOM
+/* ecclayout for OMAP3_LV_SOM, using omap HW ecc */
+static struct nand_ecclayout yaffs2_ecclayout = {
+ .eccbytes = 12,
+ .eccpos = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13},
+ .oobfree = { { 1, 1}, { 14, 50} },
+ .oobavail = 51,
+};
+#else
+/* ecclayout on chips that page_size = 2K, byte 0,1 is bad block marker */
+static struct nand_ecclayout yaffs2_ecclayout = {
+ .eccbytes = 24,
+ .eccpos = {
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63},
+ .oobfree = { {2, 38} },
+ .oobavail = 38,
};
#endif
+static struct nand_ecclayout autoplace_ecclayout = {
+ .oobavail = 38,
+};
+
/* XXX U-BOOT XXX */
#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
@@ -534,6 +555,245 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
}
/**
+ * nand_write_opts: - write image to NAND flash with support for various options
+ *
+ * @param meminfo NAND device to erase
+ * @param opts write options (@see nand_write_options)
+ * @return 0 in case of success
+ *
+ * This code is ported from nandwrite.c from Linux mtd utils by
+ * Steven J. Hill and Thomas Gleixner.
+ */
+int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts)
+{
+ int imglen = 0;
+ int pagelen;
+ int baderaseblock;
+ int blockstart = -1;
+ loff_t offs;
+ int readlen;
+ int ecclayout_changed = 0;
+ int percent_complete = -1;
+ struct nand_ecclayout *old_ecclayout;
+ struct nand_chip *chip = meminfo->priv;
+ ulong mtdoffset = opts->offset;
+ ulong erasesize_blockalign;
+ u_char *buffer = opts->buffer;
+ size_t written;
+ int result;
+
+ if (opts->pad && opts->writeoob) {
+ printf("Can't pad when oob data is present.\n");
+ return -1;
+ }
+
+ /* set erasesize to specified number of blocks - to match
+ * jffs2 (virtual) block size */
+ if (opts->blockalign == 0)
+ erasesize_blockalign = meminfo->erasesize;
+ else
+ erasesize_blockalign = meminfo->erasesize * opts->blockalign;
+
+ /* make sure device page sizes are valid */
+ if (!(meminfo->oobsize == 16 && meminfo->writesize == 512)
+ && !(meminfo->oobsize == 8 && meminfo->writesize == 256)
+ && !(meminfo->oobsize == 64 && meminfo->writesize == 2048)) {
+ printf("Unknown flash (not normal NAND)\n");
+ return -1;
+ }
+
+ /* read the current ecclayout */
+ old_ecclayout = meminfo->ecclayout;
+
+ /* write without ecc? */
+ if (opts->noecc) {
+ meminfo->ecclayout = &none_ecclayout;
+ ecclayout_changed = 1;
+ }
+
+ /* autoplace ECC? */
+ if (opts->autoplace && (chip->ecc.mode != MTD_NANDECC_AUTOPLACE)) {
+
+ meminfo->ecclayout = &autoplace_ecclayout,
+ ecclayout_changed = 1;
+ }
+
+ /* force OOB layout for jffs2 or yaffs? */
+ if (opts->forcejffs2 || opts->forceyaffs) {
+ struct nand_ecclayout *oobsel =
+ opts->forcejffs2 ? &jffs2_ecclayout : &yaffs2_ecclayout;
+
+ if (meminfo->oobsize == 8) {
+ if (opts->forceyaffs) {
+ printf("YAFSS cannot operate on "
+ "256 Byte page size\n");
+ goto restoreoob;
+ }
+ }
+
+ meminfo->ecclayout = oobsel;
+ ecclayout_changed = 1;
+ }
+
+ /* get image length */
+ imglen = opts->length;
+ pagelen = meminfo->writesize
+ + ((opts->writeoob != 0) ? meminfo->oobsize : 0);
+
+ /* check, if file is pagealigned */
+ if ((!opts->pad) && ((imglen % pagelen) != 0)) {
+ printf("Input block length is not page aligned\n");
+ goto restoreoob;
+ }
+
+ /* check, if length fits into device */
+ if (((imglen / pagelen) * meminfo->writesize)
+ > (meminfo->size - opts->offset)) {
+ printf("Image %d bytes, NAND page %d bytes, "
+ "OOB area %u bytes, device size %u bytes\n",
+ imglen, pagelen, meminfo->writesize, meminfo->size);
+ printf("Input block does not fit into device\n");
+ goto restoreoob;
+ }
+
+ if (!opts->quiet)
+ printf("\n");
+
+ /* get data from input and write to the device */
+ while (imglen && (mtdoffset < meminfo->size)) {
+
+ WATCHDOG_RESET();
+
+ /*
+ * new eraseblock, check for bad block(s). Stay in the
+ * loop to be sure if the offset changes because of
+ * a bad block, that the next block that will be
+ * written to is also checked. Thus avoiding errors if
+ * the block(s) after the skipped block(s) is also bad
+ * (number of blocks depending on the blockalign
+ */
+ while (blockstart != (mtdoffset & (~erasesize_blockalign+1))) {
+ blockstart = mtdoffset & (~erasesize_blockalign+1);
+ offs = blockstart;
+ baderaseblock = 0;
+
+ /* check all the blocks in an erase block for
+ * bad blocks */
+ do {
+ int ret = meminfo->block_isbad(meminfo, offs);
+
+ if (ret < 0) {
+ printf("Bad block check failed\n");
+ goto restoreoob;
+ }
+ if (ret == 1) {
+ baderaseblock = 1;
+ if (!opts->quiet)
+ printf("\rBad block at 0x%lx "
+ "in erase block from "
+ "0x%x will be skipped\n",
+ (long) offs,
+ blockstart);
+ }
+
+ if (baderaseblock) {
+ mtdoffset = blockstart
+ + erasesize_blockalign;
+ }
+ offs += erasesize_blockalign
+ / opts->blockalign;
+ } while (offs < blockstart + erasesize_blockalign);
+ }
+
+ readlen = meminfo->writesize;
+ if (opts->pad && (imglen < readlen)) {
+ readlen = imglen;
+ memset(data_buf + readlen, 0xff,
+ meminfo->writesize - readlen);
+ }
+
+ /* read page data from input memory buffer */
+ memcpy(data_buf, buffer, readlen);
+ buffer += readlen;
+
+ if (opts->writeoob) {
+ /* read OOB data from input memory block, exit
+ * on failure */
+ memcpy(oob_buf, buffer, meminfo->oobsize);
+ buffer += meminfo->oobsize;
+
+ struct mtd_oob_ops ops = {
+ .mode = MTD_OOB_AUTO,
+ .len = meminfo->writesize,
+ .retlen = 0,
+ .ooblen = meminfo->ecclayout->oobavail,
+ .oobretlen = 0,
+ .ooboffs = 0,
+ .datbuf = NULL,
+ .oobbuf = oob_buf,
+ };
+
+ result = meminfo->write_oob(meminfo, mtdoffset, &ops);
+
+ if (result != 0) {
+ printf("\nMTD writeoob failure: %d\n",
+ result);
+ goto restoreoob;
+ }
+ imglen -= meminfo->oobsize;
+ }
+
+ /* write out the page data */
+ result = meminfo->write(meminfo,
+ mtdoffset,
+ meminfo->writesize,
+ &written,
+ (unsigned char *) &data_buf);
+
+ if (result != 0) {
+ printf("writing NAND page at offset 0x%lx failed\n",
+ mtdoffset);
+ goto restoreoob;
+ }
+ imglen -= readlen;
+
+ if (!opts->quiet) {
+ int percent = (int)
+ ((unsigned long long)
+ (opts->length-imglen) * 100
+ / opts->length);
+ /* output progress message only at whole percent
+ * steps to reduce the number of messages printed
+ * on (slow) serial consoles
+ */
+ if (percent != percent_complete) {
+ printf("\rWriting data at 0x%lx "
+ "-- %3d%% complete.",
+ mtdoffset, percent);
+ percent_complete = percent;
+ }
+ }
+
+ mtdoffset += meminfo->writesize;
+ }
+
+ if (!opts->quiet)
+ printf("\n");
+
+restoreoob:
+ if (ecclayout_changed)
+ meminfo->ecclayout = old_ecclayout;
+
+ if (imglen > 0) {
+ printf("Data did not fit into device(imglen %d), due to bad blocks\n", imglen);
+ return -1;
+ }
+
+ /* return happy */
+ return 0;
+}
+
+/**
* nand_read_skip_bad:
*
* Read image from NAND flash.
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index 5f8ed3984d..b60fa958f9 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -150,7 +150,9 @@ static int omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
*/
if ((orig_ecc == 0x0FFF0FFF) && (new_ecc == 0x00000000))
return 0;
+#if 0
printf("Error: Bad compare! failed\n");
+#endif
/* detected 2 bit error */
return -1;
}
@@ -269,12 +271,12 @@ void omap_nand_switch_ecc(int32_t hardware)
nand->ecc.correct = omap_correct_data;
nand->ecc.calculate = omap_calculate_ecc;
omap_hwecc_init(nand);
- printf("HW ECC selected\n");
+ printf("NAND: HW ECC selected\n");
} else {
nand->ecc.mode = NAND_ECC_SOFT;
/* Use mtd default settings */
nand->ecc.layout = NULL;
- printf("SW ECC selected\n");
+ printf("NAND: SW ECC selected\n");
}
/* Update NAND handling after ECC mode switch */
@@ -298,6 +300,17 @@ void omap_nand_switch_ecc(int32_t hardware)
* nand_scan about special functionality. See the defines for further
* explanation
*/
+
+#ifdef CONFIG_OMAP3_LV_SOM
+static uint8_t omap3_lv_som_scan_ff_pattern[] = { 0xff, 0xff };
+static struct nand_bbt_descr omap3_lv_som_largepage_memorybased = {
+ .options = 0,
+ .offs = 0,
+ .len = 1, /* to match LoLo, only first byte is looked at */
+ .pattern = omap3_lv_som_scan_ff_pattern
+};
+#endif
+
int board_nand_init(struct nand_chip *nand)
{
int32_t gpmc_config = 0;
@@ -349,5 +362,10 @@ int board_nand_init(struct nand_chip *nand)
/* Default ECC mode */
nand->ecc.mode = NAND_ECC_SOFT;
+#ifdef CONFIG_OMAP3_LV_SOM
+ /* Use our specific bad-block definition (first byte only) */
+ nand->badblock_pattern = &omap3_lv_som_largepage_memorybased;
+#endif
+
return 0;
}
diff --git a/include/asm-arm/arch-omap3/omap_gpmc.h b/include/asm-arm/arch-omap3/omap_gpmc.h
index bd22bce837..601f4b45ad 100644
--- a/include/asm-arm/arch-omap3/omap_gpmc.h
+++ b/include/asm-arm/arch-omap3/omap_gpmc.h
@@ -48,14 +48,29 @@
/* Large Page x16 NAND device Layout */
#ifdef GPMC_NAND_ECC_LP_x16_LAYOUT
+#ifdef CONFIG_OMAP3_LV_SOM
+/* OMAP3_LV_SOM only uses first byte for bad block marker, not first
+ half-word */
#define GPMC_NAND_HW_ECC_LAYOUT {\
.eccbytes = 12,\
.eccpos = {2, 3, 4, 5, 6, 7, 8, 9,\
10, 11, 12, 13},\
.oobfree = {\
+ {.offset = 1,\
+ .length = 1 }, \
{.offset = 14,\
.length = 50 } } \
}
+#else
+#define GPMC_NAND_HW_ECC_LAYOUT {\
+ .eccbytes = 12,\
+ .eccpos = {2, 3, 4, 5, 6, 7, 8, 9,\
+ 10, 11, 12, 13},\
+ .oobfree = {\
+ {.offset = 14,\
+ .length = 50 } } \
+}
+#endif
#endif
/* Small Page x8 NAND device Layout */
diff --git a/include/configs/omap3_lv_som.h b/include/configs/omap3_lv_som.h
index 4733ab51cd..3a038d4757 100644
--- a/include/configs/omap3_lv_som.h
+++ b/include/configs/omap3_lv_som.h
@@ -114,6 +114,7 @@
#define CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */
#define CONFIG_CMD_PING /* ping */
#define CONFIG_CMD_DHCP /* dhcp */
+#define CONFIG_CMD_ASKENV /* askenv */
/*----------------------------------------------------------------------------
* SMSC9115 Ethernet from SMSC9118 family
@@ -174,6 +175,25 @@
/* Environment information */
#define CONFIG_BOOTDELAY 10
+#if 1
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "display=15\0" \
+ "loadaddr=0x81000000\0" \
+ "rootfsaddr=0x81300000\0" \
+ "consoledev=ttyS0\0" \
+ "rootpath=/opt/nfs-exports/ltib-omap\0" \
+ "ramdisksize=89000\0" \
+ "nfsoptions=,wsize=1500,rsize=1500\0" \
+ "nfsboot=setenv bootargs display=${display} console=${consoledev},${baudrate} root=/dev/nfs rw nfsroot=${serverip}:${rootpath}${nfsoptions} ip=dhcp ${otherbootargs};tftpboot ${loadaddr} uImage;bootm ${loadaddr}\0" \
+ "ramboot=setenv bootargs display=${display} console=${consoledev},${baudrate} root=/dev/ram rw ramdisk_size=${ramdisksize} ${otherbootargs};tftpboot ${loadaddr} uImage;tftpboot ${rootfsaddr} rootfs.ext2.gz.uboot;bootm ${loadaddr} ${rootfsaddr}\0" \
+ "xipboot=setenv bootargs display=${display} console=${consoledev},${baudrate} root=/dev/ram rw ramdisk_size=${ramdisksize} ${otherbootargs};bootm ${loadaddr} ${rootfsaddr}\0" \
+ "mtdboot=setenv bootargs display=${display} console=${consoledev},${baudrate} root=/dev/mtdblock3 rw ${otherbootargs};tftpboot ${loadaddr} uImage;bootm ${loadaddr}\0"
+
+#define CONFIG_BOOTCOMMAND "run xipboot"
+
+#else
+
+// Beagle ENV_SETTINGS
#define CONFIG_EXTRA_ENV_SETTINGS \
"loadaddr=0x82000000\0" \
"console=ttyS2,115200n8\0" \
@@ -199,6 +219,7 @@
"nand read ${loadaddr} 280000 400000; " \
"bootm ${loadaddr}\0" \
+// Beagle BOOTCOMMAND
#define CONFIG_BOOTCOMMAND \
"if mmcinit; then " \
"if run loadbootscript; then " \
@@ -210,8 +231,28 @@
"fi; " \
"fi; " \
"else run nandboot; fi"
+#endif
+#define CONFIG_PREBOOT \
+ "echo ======================NOTICE============================;" \
+ "echo This is the first time that you boot up this board. You are;" \
+ "echo required to set a valid display for your LCD panel.;" \
+ "echo Enter the display number of the LCD panel(none for no LCD panel);" \
+ "echo Pick one of:;" \
+ "echo 2 == LQ121S1DG31 TFT SVGA (12.1) Sharp;" \
+ "echo 3 == LQ036Q1DA01 TFT QVGA (3.6) Sharp w/ASIC;" \
+ "echo 5 == LQ064D343 TFT VGA (6.4) Sharp;" \
+ "echo 7 == LQ10D368 TFT VGA (10.4) Sharp;" \
+ "echo 15 == LQ043T1DG01 TFT WQVGA (4.3) Sharp;" \
+ "echo MAKE SURE YOUR DISPLAY IS CORRECTLY ENTERED!;" \
+ "askenv display 'Please enter your LCD display number:' 2;" \
+ "printenv display;" \
+ "setenv preboot;" \
+ "saveenv;"
+
+#define CONFIG_CMDLINE_EDITING 1
#define CONFIG_AUTO_COMPLETE 1
+
/*
* Miscellaneous configurable options
*/
@@ -298,6 +339,11 @@
#define CONFIG_ENV_OFFSET boot_flash_off
#define CONFIG_ENV_ADDR boot_flash_env_addr
+#if 0
+#define CONFIG_MTD_DEBUG 1
+#define CONFIG_MTD_DEBUG_VERBOSE 2 // Loud MTD debug messages
+#endif
+
/*-----------------------------------------------------------------------
* CFI FLASH driver setup
*/
diff --git a/lib_arm/board.c b/lib_arm/board.c
index 3dfaec01b4..c7b77e521b 100644
--- a/lib_arm/board.c
+++ b/lib_arm/board.c
@@ -353,6 +353,12 @@ void start_armboot (void)
#if defined(CONFIG_CMD_NAND)
puts ("NAND: ");
nand_init(); /* go init the NAND */
+
+#ifdef CONFIG_OMAP3_LV_SOM
+ /* Switch to Hardware ECC mode */
+ omap_nand_switch_ecc(1);
+#endif
+
#endif
#if defined(CONFIG_CMD_ONENAND)