summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2011-10-04 22:20:25 +0200
committerWolfgang Denk <wd@denx.de>2011-10-04 22:20:25 +0200
commit4f7549d2dc00023c5f33d1adc7fee0a77575fcb2 (patch)
treef87d6f02fe74f832d18ab8c11feb0978da53014a /common
parent1fed668b3fb9c35932f58af00ff5539239fa4e1d (diff)
parent169de9059f24f50c4c7ac794ded060b2c133a29c (diff)
downloadu-boot-imx-4f7549d2dc00023c5f33d1adc7fee0a77575fcb2.zip
u-boot-imx-4f7549d2dc00023c5f33d1adc7fee0a77575fcb2.tar.gz
u-boot-imx-4f7549d2dc00023c5f33d1adc7fee0a77575fcb2.tar.bz2
Merge branch 'master' of git://git.denx.de/u-boot-nand-flash
* 'master' of git://git.denx.de/u-boot-nand-flash: PPC: Fix socrates NAND problem PPC: Fix fsl_upm.c by renaming nand handling functions NAND: Make page, erase, oob size available via cmd_nand mtd: eLBC NAND: remove elbc_fcm_ctrl->oob_poi NAND: Add -y option to nand scrub command NAND: Add nand read.raw and write.raw commands NAND: Really ignore bad blocks when scrubbing spl, nand: add 4bit HW ecc oob first nand_read_page function mxc_nand: fix a problem writing more than 32MB mxc_nand: fixed some typos (cosmetic) nand: increase chip_delay in mv kirkwood nand driver
Diffstat (limited to 'common')
-rw-r--r--common/cmd_nand.c75
1 files changed, 57 insertions, 18 deletions
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 6edca76..3e2edb8 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -362,15 +362,31 @@ usage:
#endif
-static void nand_print_info(int idx)
+static void nand_print_and_set_info(int idx)
{
nand_info_t *nand = &nand_info[idx];
struct nand_chip *chip = nand->priv;
+ const int bufsz = 32;
+ char buf[bufsz];
+
printf("Device %d: ", idx);
if (chip->numchips > 1)
printf("%dx ", chip->numchips);
printf("%s, sector size %u KiB\n",
nand->name, nand->erasesize >> 10);
+ printf(" Page size %8d b\n", nand->writesize);
+ printf(" OOB size %8d b\n", nand->oobsize);
+ printf(" Erase size %8d b\n", nand->erasesize);
+
+ /* Set geometry info */
+ sprintf(buf, "%x", nand->writesize);
+ setenv("nand_writesize", buf);
+
+ sprintf(buf, "%x", nand->oobsize);
+ setenv("nand_oobsize", buf);
+
+ sprintf(buf, "%x", nand->erasesize);
+ setenv("nand_erasesize", buf);
}
int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
@@ -407,7 +423,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
putc('\n');
for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) {
if (nand_info[i].name)
- nand_print_info(i);
+ nand_print_and_set_info(i);
}
return 0;
}
@@ -418,7 +434,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE)
puts("no devices available\n");
else
- nand_print_info(dev);
+ nand_print_and_set_info(dev);
return 0;
}
@@ -464,10 +480,21 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
nand_erase_options_t opts;
/* "clean" at index 2 means request to write cleanmarker */
int clean = argc > 2 && !strcmp("clean", argv[2]);
- int o = clean ? 3 : 2;
+ int scrub_yes = argc > 2 && !strcmp("-y", argv[2]);
+ int o = (clean || scrub_yes) ? 3 : 2;
int scrub = !strncmp(cmd, "scrub", 5);
int spread = 0;
int args = 2;
+ const char *scrub_warn =
+ "Warning: "
+ "scrub option will erase all factory set bad blocks!\n"
+ " "
+ "There is no reliable way to recover them.\n"
+ " "
+ "Use this command only for testing purposes if you\n"
+ " "
+ "are sure of what you are doing!\n"
+ "\nReally scrub this NAND flash? <y/N>\n";
if (cmd[5] != 0) {
if (!strcmp(&cmd[5], ".spread")) {
@@ -504,19 +531,12 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
opts.spread = spread;
if (scrub) {
- puts("Warning: "
- "scrub option will erase all factory set "
- "bad blocks!\n"
- " "
- "There is no reliable way to recover them.\n"
- " "
- "Use this command only for testing purposes "
- "if you\n"
- " "
- "are sure of what you are doing!\n"
- "\nReally scrub this NAND flash? <y/N>\n");
-
- if (getc() == 'y') {
+ if (!scrub_yes)
+ puts(scrub_warn);
+
+ if (scrub_yes)
+ opts.scrub = 1;
+ else if (getc() == 'y') {
puts("y");
if (getc() == '\r')
opts.scrub = 1;
@@ -602,6 +622,22 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
ret = nand->read_oob(nand, off, &ops);
else
ret = nand->write_oob(nand, off, &ops);
+ } else if (!strcmp(s, ".raw")) {
+ /* Raw access */
+ mtd_oob_ops_t ops = {
+ .datbuf = (u8 *)addr,
+ .oobbuf = ((u8 *)addr) + nand->writesize,
+ .len = nand->writesize,
+ .ooblen = nand->oobsize,
+ .mode = MTD_OOB_RAW
+ };
+
+ rwsize = nand->writesize + nand->oobsize;
+
+ if (read)
+ ret = nand->read_oob(nand, off, &ops);
+ else
+ ret = nand->write_oob(nand, off, &ops);
} else {
printf("Unknown nand command suffix '%s'.\n", s);
return 1;
@@ -695,6 +731,9 @@ U_BOOT_CMD(
"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 read.raw - addr off|partition\n"
+ "nand write.raw - addr off|partition\n"
+ " Use read.raw/write.raw to avoid ECC and access the page as-is.\n"
#ifdef CONFIG_CMD_NAND_TRIMFFS
"nand write.trimffs - addr off|partition size\n"
" write 'size' bytes starting at offset 'off' from memory address\n"
@@ -714,7 +753,7 @@ U_BOOT_CMD(
"nand erase.chip [clean] - erase entire chip'\n"
"nand bad - show bad blocks\n"
"nand dump[.oob] off - dump page\n"
- "nand scrub off size | scrub.part partition | scrub.chip\n"
+ "nand scrub [-y] off size | scrub.part partition | scrub.chip\n"
" really clean NAND erasing bad blocks (UNSAFE)\n"
"nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
"nand biterr off - make a bit error at offset (UNSAFE)"