summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Sweeny <scott.sweeny@timesys.com>2009-04-29 16:12:02 -0400
committerScott Sweeny <scott.sweeny@timesys.com>2009-04-29 16:12:02 -0400
commit13c7c993f472eec5b9961750056c57f4f1494c0f (patch)
tree08d4b92a1bc3ee0d806e3c0e8f647b7a77bc906f
parent1ef67de43fb51c00f5e355f8ed03352e67b89fc9 (diff)
Improved NAND support and environment options for OMAP3430LV SOM
This patch originally from LogicPD OMAP35x Release 1.5.0 Original Patch Name: u-boot-1.1.4-omap3430-lv-som-06.patch
-rw-r--r--board/omap3430lv_som/nand.c53
-rw-r--r--common/cmd_nand.c14
-rw-r--r--common/env_nand.c39
-rw-r--r--drivers/nand/nand.c3
-rw-r--r--drivers/nand/nand_base.c10
-rw-r--r--include/configs/omap3530lv_som.h17
6 files changed, 119 insertions, 17 deletions
diff --git a/board/omap3430lv_som/nand.c b/board/omap3430lv_som/nand.c
index a037cf2380..a1489b6b97 100644
--- a/board/omap3430lv_som/nand.c
+++ b/board/omap3430lv_som/nand.c
@@ -48,16 +48,29 @@ extern int debug_nand_actions;
int nand_unlock(struct mtd_info *mtd, unsigned long off, unsigned long size)
{
register struct nand_chip *this = mtd->priv;
- int start_page, end_page;
+ unsigned int start_block, end_block;
u8 val;
int ret = 0;
int block;
+ int pages_per_block;
debug_nand_actions = 0;
- start_page = (int) (off >> this->page_shift);
- end_page = (int) ((off + size) >> this->page_shift);
- printk("\nUnlocking %x - %x. locking rest..\n", off, off + size);
+ start_block = (int) (off >> this->page_shift);
+ end_block = (int) ((off + size - 1) >> this->page_shift);
+
+ // printk("start_block 0x%x end_block 0x%x\n", start_block, end_block);
+
+ // printk("phys_erase_shift %d page_shift %d\n", this->phys_erase_shift, this->page_shift);
+
+ // Calculate pages in each block
+ pages_per_block = 1 << (this->phys_erase_shift - this->page_shift);
+
+ // printk("Pages per block %d\n", pages_per_block);
+
+ // Shift up into position
+ start_block *= pages_per_block;
+ end_block *= pages_per_block;
// First reset the chip, read status
this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
@@ -65,17 +78,18 @@ int nand_unlock(struct mtd_info *mtd, unsigned long off, unsigned long size)
this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
ndelay (100);
val = this->read_byte(mtd);
- printk("%s: Status after reset %02x\n", __FUNCTION__, val);
+ // printk("%s: Status after reset %02x\n", __FUNCTION__, val);
- this->cmdfunc(mtd, 0x23, -1, start_page);
- this->cmdfunc(mtd, 0x24, -1, end_page);
+ this->cmdfunc(mtd, 0x23, -1, start_block);
+ this->cmdfunc(mtd, 0x24, -1, end_block);
ndelay (100);
+
// Now scan the same block range looking for lock status
- for (block = start_page; block <= end_page; block+=(1<<6)) {
+ for (block = start_block; block <= end_block; block+= pages_per_block) {
this->cmdfunc(mtd, 0x7a, -1, block);
val = this->read_byte(mtd);
if (!(val & 0x4)) {
- printk("%s: Block %d didn't unlock(%02x)\n", __FUNCTION__, block, val);
+ printk("NAND block %d didn't unlock(status %02x)\n", block/pages_per_block, val);
ret = -1;
goto exit;
}
@@ -386,6 +400,16 @@ static struct nand_oobinfo sw_nand_oob_64 = {
.oobfree = { {2, 38} }
};
+// Return 0 if soft nand ecc, !0 if hardware nand ecc
+int omap_nand_get_ecc(struct mtd_info *mtd)
+{
+ struct nand_chip *nand = mtd->priv;
+
+ if (nand->eccmode == NAND_ECC_SOFT)
+ return 0;
+ return !0;
+}
+
void omap_nand_switch_ecc(struct mtd_info *mtd, int hardware)
{
struct nand_chip *nand = mtd->priv;
@@ -498,6 +522,17 @@ void board_nand_init(struct mtd_info *mtd)
}
+void board_post_nand_init(struct mtd_info *mtd)
+{
+ register struct nand_chip *this = mtd->priv;
+
+ if (!mtd->name)
+ return; // No NAND chip?
+
+ // Set u-boot environment offset as *last* block in NAND
+ boot_flash_off = this->chipsize - (1<<this->phys_erase_shift);
+
+}
#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index f8133009d5..5c76ec46cd 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -130,6 +130,7 @@ arg_off_size(int argc, char *argv[], ulong *off, ulong *size, ulong totsize)
}
#if defined(CONFIG_OMAP) && (defined(CONFIG_3430LABRADOR) || defined(CONFIG_3430LV_SOM))
extern void omap_nand_switch_ecc(nand_info_t *nand, int hardware);
+extern int omap_nand_get_ecc(nand_info_t *nand);
extern int nand_unlock(nand_info_t *nand, ulong off, ulong size);
#else
#define omap_nand_switch_ecc(x, y) do {} while(0)
@@ -239,7 +240,18 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
}
if (strncmp(cmd, "ecc", 3) == 0) {
- if (argc < 3)
+ if (argc < 3) {
+#if defined(CONFIG_3430LV_SOM)
+ int ecc;
+ ecc = omap_nand_get_ecc(nand);
+ if (ecc)
+ printf("Hardware ECC\n");
+ else
+ printf("Software ECC\n");
+#else
+ goto usage;
+#endif
+ } else if (argc > 4)
goto usage;
if (strncmp(argv[2], "hw", 2) == 0)
omap_nand_switch_ecc(nand, 1);
diff --git a/common/env_nand.c b/common/env_nand.c
index 376154d591..b00d649197 100644
--- a/common/env_nand.c
+++ b/common/env_nand.c
@@ -149,9 +149,13 @@ int saveenv(void)
puts ("Writing to Nand... ");
ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total,
(u_char*) env_ptr);
+ if (ret || total != CFG_ENV_SIZE)
+ printf("%s:%d ret %d, total %d size %d\n", __FUNCTION__, __LINE__, ret, total, CFG_ENV_SIZE);
}
- if (ret || total != CFG_ENV_SIZE)
+ if (ret || total != CFG_ENV_SIZE) {
+ printf("%s:%d\n", __FUNCTION__);
return 1;
+ }
puts ("done\n");
gd->env_valid = (gd->env_valid == 2 ? 1 : 2);
@@ -167,6 +171,31 @@ int saveenv(void)
ulong total;
int ret = 0;
+#if defined(CONFIG_OMAP)
+ extern void omap_nand_switch_ecc(nand_info_t *nand, int hardware);
+ extern int omap_nand_get_ecc(nand_info_t *nand);
+
+ int mode;
+
+ // Switch to soft ECC for environment
+ mode = omap_nand_get_ecc(&nand_info[0]);
+ omap_nand_switch_ecc(&nand_info[0], 0);
+
+#if defined(CONFIG_3430LV_SOM)
+ // Unlock the entire NAND chip
+ {
+ struct nand_chip *this;
+ this = (struct nand_chip *)nand_info[0].priv;
+ puts("Unlocking NAND...");
+ ret = nand_unlock(&nand_info[0], 0, this->chipsize);
+
+ if (ret) {
+ printk("NAND unlock of entire chip failed\n");
+ }
+ }
+#endif
+#endif
+
puts ("Erasing Nand...");
if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE))
return 1;
@@ -175,6 +204,13 @@ int saveenv(void)
total = CFG_ENV_SIZE;
ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
if (ret || total != CFG_ENV_SIZE)
+ printf("%s:%d ret %d, total %d size %d\n", __FUNCTION__, __LINE__, ret, total, CFG_ENV_SIZE);
+
+#if defined(CONFIG_OMAP)
+ omap_nand_switch_ecc(&nand_info[0], mode);
+#endif
+
+ if (ret || total != CFG_ENV_SIZE)
return 1;
puts ("done\n");
@@ -255,6 +291,7 @@ void env_relocate_spec (void)
ulong total;
int ret;
+ // printf("%s: off 0x%x size 0x%x read %p\n", __FUNCTION__, CFG_ENV_OFFSET, CFG_ENV_SIZE, nand_info[0].read);
total = CFG_ENV_SIZE;
ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
if (ret || total != CFG_ENV_SIZE)
diff --git a/drivers/nand/nand.c b/drivers/nand/nand.c
index 313e4acb63..64948c7e9c 100644
--- a/drivers/nand/nand.c
+++ b/drivers/nand/nand.c
@@ -40,6 +40,7 @@ static ulong base_address[CFG_MAX_NAND_DEVICE] = CFG_NAND_BASE_LIST;
static const char default_nand_name[] = "nand";
extern void board_nand_init(struct mtd_info *mtd);
+extern void board_post_nand_init(struct mtd_info *mtd);
static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
ulong base_addr)
@@ -54,7 +55,7 @@ static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
mtd->name = (char *)default_nand_name;
} else
mtd->name = NULL;
-
+ board_post_nand_init(mtd);
}
void nand_init(void)
diff --git a/drivers/nand/nand_base.c b/drivers/nand/nand_base.c
index 033784f97b..246b350050 100644
--- a/drivers/nand/nand_base.c
+++ b/drivers/nand/nand_base.c
@@ -1662,8 +1662,10 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
this->select_chip(mtd, chipnr);
/* Check, if it is write protected */
- if (nand_check_wp(mtd))
+ if (nand_check_wp(mtd)) {
+ printf("%s:%d\n", __FUNCTION__, __LINE__);
goto out;
+ }
/* if oobsel is NULL, use chip defaults */
if (oobsel == NULL)
@@ -1704,6 +1706,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
if (ret) {
DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
+ printf("%s:%d\n", __FUNCTION__);
goto out;
}
/* Next oob page */
@@ -1728,6 +1731,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
oobbuf, oobsel, chipnr, (eccbuf != NULL));
if (ret) {
DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
+ printf("%s:%d\n", __FUNCTION__);
goto out;
}
*retlen = written;
@@ -1758,8 +1762,10 @@ cmp:
oobbuf, oobsel, chipnr, (eccbuf != NULL));
if (!ret)
*retlen = written;
- else
+ else {
DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
+ printf("%s:%d\n", __FUNCTION__);
+ }
out:
/* Deselect and wake up anyone waiting on the device */
diff --git a/include/configs/omap3530lv_som.h b/include/configs/omap3530lv_som.h
index 8c23f7023f..397dbb1e9e 100644
--- a/include/configs/omap3530lv_som.h
+++ b/include/configs/omap3530lv_som.h
@@ -172,8 +172,10 @@
"rootfsaddr=0x81200000\0" \
"consoledev=ttyS0\0" \
"rootpath=/opt/nfs-exports/ltib-omap\0" \
- "nfsboot=setenv bootargs display=${display} console=${consoledev},${baudrate} root=/dev/nfs rw nfsroot=${serverip}:${rootpath} ip=dhcp;tftpboot ${loadaddr} uImage;bootm ${loadaddr}\0" \
- "ramboot=setenv bootargs display=${display} console=${consoledev},${baudrate} root=/dev/ram rw ramdisk_size=23000;tftpboot ${loadaddr} uImage;tftpboot ${rootfsaddr} rootfs.ext2.gz.uboot;bootm ${loadaddr} ${rootfsaddr}\0"
+ "ramdisksize=45000\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;tftpboot ${loadaddr} uImage;bootm ${loadaddr}\0" \
+ "ramboot=setenv bootargs display=${display} console=${consoledev},${baudrate} root=/dev/ram rw ramdisk_size=${ramdisksize};tftpboot ${loadaddr} uImage;tftpboot ${rootfsaddr} rootfs.ext2.gz.uboot;bootm ${loadaddr} ${rootfsaddr}\0"
#endif
#else
#define CONFIG_BOOTARGS "console=ttyS0,115200n8 root=/dev/nfs rw nfsroot=192.168.3.5:/opt/nfs-exports/ltib-omap ip=dhcp"
@@ -287,12 +289,21 @@
# define CFG_ENV_IS_IN_FLASH 1
#endif
-#define SMNAND_ENV_OFFSET 0xc0000 /* environment starts here */
+#define SMNAND_ENV_OFFSET (8<<20) /* environment starts here
+ (64MB point) */
#define CFG_ENV_SECT_SIZE boot_flash_sec
#define CFG_ENV_OFFSET boot_flash_off
#define CFG_ENV_ADDR boot_flash_env_addr
+#define CONFIG_CMDLINE_EDITING
+
+#ifdef CONFIG_CMDLINE_EDITING
+#undef CONFIG_AUTO_COMPLETE
+#else
+#define CONFIG_AUTO_COMPLETE
+#endif
+
/*-----------------------------------------------------------------------
* CFI FLASH driver setup