|
@@ -11,7 +11,7 @@
|
|
|
* Added 16-bit nand support
|
|
|
* (C) 2004 Texas Instruments
|
|
|
*
|
|
|
- * Copyright 2010 Freescale Semiconductor
|
|
|
+ * Copyright 2010, 2012 Freescale Semiconductor
|
|
|
* The portions of this file whose copyright is held by Freescale and which
|
|
|
* are not considered a derived work of GPL v2-only code may be distributed
|
|
|
* and/or modified under the terms of the GNU General Public License as
|
|
@@ -390,6 +390,41 @@ static void nand_print_and_set_info(int idx)
|
|
|
setenv("nand_erasesize", buf);
|
|
|
}
|
|
|
|
|
|
+static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count,
|
|
|
+ int read)
|
|
|
+{
|
|
|
+ int ret = 0;
|
|
|
+ size_t rwsize;
|
|
|
+
|
|
|
+ while (count--) {
|
|
|
+ /* 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);
|
|
|
+
|
|
|
+ if (ret) {
|
|
|
+ printf("%s: error at offset %llx, ret %d\n",
|
|
|
+ __func__, (long long)off, ret);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ addr += nand->writesize + nand->oobsize;
|
|
|
+ off += nand->writesize;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
|
|
{
|
|
|
int i, ret = 0;
|
|
@@ -568,7 +603,9 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
|
|
|
|
|
if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
|
|
|
size_t rwsize;
|
|
|
+ ulong pagecount = 1;
|
|
|
int read;
|
|
|
+ int raw;
|
|
|
|
|
|
if (argc < 4)
|
|
|
goto usage;
|
|
@@ -577,13 +614,36 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
|
|
|
|
|
read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
|
|
|
printf("\nNAND %s: ", read ? "read" : "write");
|
|
|
- if (arg_off_size(argc - 3, argv + 3, &dev, &off, &size) != 0)
|
|
|
- return 1;
|
|
|
|
|
|
nand = &nand_info[dev];
|
|
|
- rwsize = size;
|
|
|
|
|
|
s = strchr(cmd, '.');
|
|
|
+
|
|
|
+ if (!strcmp(s, ".raw")) {
|
|
|
+ raw = 1;
|
|
|
+
|
|
|
+ if (arg_off(argv[3], &dev, &off, &size))
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ if (argc > 4 && !str2long(argv[4], &pagecount)) {
|
|
|
+ printf("'%s' is not a number\n", argv[4]);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pagecount * nand->writesize > size) {
|
|
|
+ puts("Size exceeds partition or device limit\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ rwsize = pagecount * (nand->writesize + nand->oobsize);
|
|
|
+ } else {
|
|
|
+ if (arg_off_size(argc - 3, argv + 3, &dev,
|
|
|
+ &off, &size) != 0)
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ rwsize = size;
|
|
|
+ }
|
|
|
+
|
|
|
if (!s || !strcmp(s, ".jffs2") ||
|
|
|
!strcmp(s, ".e") || !strcmp(s, ".i")) {
|
|
|
if (read)
|
|
@@ -609,7 +669,8 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
|
|
return 1;
|
|
|
}
|
|
|
ret = nand_write_skip_bad(nand, off, &rwsize,
|
|
|
- (u_char *)addr, WITH_YAFFS_OOB);
|
|
|
+ (u_char *)addr,
|
|
|
+ WITH_INLINE_OOB);
|
|
|
#endif
|
|
|
} else if (!strcmp(s, ".oob")) {
|
|
|
/* out-of-band data */
|
|
@@ -623,22 +684,8 @@ 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 if (raw) {
|
|
|
+ ret = raw_access(nand, addr, off, pagecount, read);
|
|
|
} else {
|
|
|
printf("Unknown nand command suffix '%s'.\n", s);
|
|
|
return 1;
|
|
@@ -732,9 +779,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"
|
|
|
+ "nand read.raw - addr off|partition [count]\n"
|
|
|
+ "nand write.raw - addr off|partition [count]\n"
|
|
|
+ " Use read.raw/write.raw to avoid ECC and access the flash 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"
|