diff options
-rw-r--r-- | board/omap3430lv_som/nand.c | 53 | ||||
-rw-r--r-- | common/cmd_nand.c | 14 | ||||
-rw-r--r-- | common/env_nand.c | 39 | ||||
-rw-r--r-- | drivers/nand/nand.c | 3 | ||||
-rw-r--r-- | drivers/nand/nand_base.c | 10 | ||||
-rw-r--r-- | include/configs/omap3530lv_som.h | 17 |
6 files changed, 119 insertions, 17 deletions
diff --git a/board/omap3430lv_som/nand.c b/board/omap3430lv_som/nand.c index a037cf2380c..a1489b6b97c 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 f8133009d59..5c76ec46cdd 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 376154d5910..b00d649197a 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 313e4acb63d..64948c7e9c5 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 033784f97bc..246b3500501 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 8c23f7023f2..397dbb1e9e3 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 |