Commit c9494866df835bcee68e17339aec1090faa704da

Authored by Ben Gardiner
Committed by Scott Wood
1 parent 169d54d8b3

cmd_nand: add nand write.trimffs command

Add another nand write. variant, trimffs. This command will request of
nand_write_skip_bad() that all trailing all-0xff pages will be
dropped from eraseblocks when they are written to flash as-per the
reccommended behaviour of the UBI FAQ [1].

The function that implements this timming is the drop_ffs() function
by Artem Bityutskiy, ported from the mtd-utils tree.

[1] http://www.linux-mtd.infradead.org/doc/ubi.html#L_flasher_algo

Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
CC: Artem Bityutskiy <dedekind1@gmail.com>
CC: Detlev Zundel <dzu@denx.de>
Acked-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>

Showing 2 changed files with 26 additions and 0 deletions Inline Diff

1 /* 1 /*
2 * Driver for NAND support, Rick Bronson 2 * Driver for NAND support, Rick Bronson
3 * borrowed heavily from: 3 * borrowed heavily from:
4 * (c) 1999 Machine Vision Holdings, Inc. 4 * (c) 1999 Machine Vision Holdings, Inc.
5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> 5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
6 * 6 *
7 * Ported 'dynenv' to 'nand env.oob' command 7 * Ported 'dynenv' to 'nand env.oob' command
8 * (C) 2010 Nanometrics, Inc. 8 * (C) 2010 Nanometrics, Inc.
9 * 'dynenv' -- Dynamic environment offset in NAND OOB 9 * 'dynenv' -- Dynamic environment offset in NAND OOB
10 * (C) Copyright 2006-2007 OpenMoko, Inc. 10 * (C) Copyright 2006-2007 OpenMoko, Inc.
11 * Added 16-bit nand support 11 * Added 16-bit nand support
12 * (C) 2004 Texas Instruments 12 * (C) 2004 Texas Instruments
13 * 13 *
14 * Copyright 2010 Freescale Semiconductor 14 * Copyright 2010 Freescale Semiconductor
15 * The portions of this file whose copyright is held by Freescale and which 15 * The portions of this file whose copyright is held by Freescale and which
16 * are not considered a derived work of GPL v2-only code may be distributed 16 * are not considered a derived work of GPL v2-only code may be distributed
17 * and/or modified under the terms of the GNU General Public License as 17 * and/or modified under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of the 18 * published by the Free Software Foundation; either version 2 of the
19 * License, or (at your option) any later version. 19 * License, or (at your option) any later version.
20 */ 20 */
21 21
22 #include <common.h> 22 #include <common.h>
23 #include <linux/mtd/mtd.h> 23 #include <linux/mtd/mtd.h>
24 #include <command.h> 24 #include <command.h>
25 #include <watchdog.h> 25 #include <watchdog.h>
26 #include <malloc.h> 26 #include <malloc.h>
27 #include <asm/byteorder.h> 27 #include <asm/byteorder.h>
28 #include <jffs2/jffs2.h> 28 #include <jffs2/jffs2.h>
29 #include <nand.h> 29 #include <nand.h>
30 30
31 #if defined(CONFIG_CMD_MTDPARTS) 31 #if defined(CONFIG_CMD_MTDPARTS)
32 32
33 /* partition handling routines */ 33 /* partition handling routines */
34 int mtdparts_init(void); 34 int mtdparts_init(void);
35 int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num); 35 int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num);
36 int find_dev_and_part(const char *id, struct mtd_device **dev, 36 int find_dev_and_part(const char *id, struct mtd_device **dev,
37 u8 *part_num, struct part_info **part); 37 u8 *part_num, struct part_info **part);
38 #endif 38 #endif
39 39
40 static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat) 40 static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat)
41 { 41 {
42 int i; 42 int i;
43 u_char *datbuf, *oobbuf, *p; 43 u_char *datbuf, *oobbuf, *p;
44 static loff_t last; 44 static loff_t last;
45 45
46 if (repeat) 46 if (repeat)
47 off = last + nand->writesize; 47 off = last + nand->writesize;
48 48
49 last = off; 49 last = off;
50 50
51 datbuf = malloc(nand->writesize + nand->oobsize); 51 datbuf = malloc(nand->writesize + nand->oobsize);
52 oobbuf = malloc(nand->oobsize); 52 oobbuf = malloc(nand->oobsize);
53 if (!datbuf || !oobbuf) { 53 if (!datbuf || !oobbuf) {
54 puts("No memory for page buffer\n"); 54 puts("No memory for page buffer\n");
55 return 1; 55 return 1;
56 } 56 }
57 off &= ~(nand->writesize - 1); 57 off &= ~(nand->writesize - 1);
58 loff_t addr = (loff_t) off; 58 loff_t addr = (loff_t) off;
59 struct mtd_oob_ops ops; 59 struct mtd_oob_ops ops;
60 memset(&ops, 0, sizeof(ops)); 60 memset(&ops, 0, sizeof(ops));
61 ops.datbuf = datbuf; 61 ops.datbuf = datbuf;
62 ops.oobbuf = oobbuf; /* must exist, but oob data will be appended to ops.datbuf */ 62 ops.oobbuf = oobbuf; /* must exist, but oob data will be appended to ops.datbuf */
63 ops.len = nand->writesize; 63 ops.len = nand->writesize;
64 ops.ooblen = nand->oobsize; 64 ops.ooblen = nand->oobsize;
65 ops.mode = MTD_OOB_RAW; 65 ops.mode = MTD_OOB_RAW;
66 i = nand->read_oob(nand, addr, &ops); 66 i = nand->read_oob(nand, addr, &ops);
67 if (i < 0) { 67 if (i < 0) {
68 printf("Error (%d) reading page %08lx\n", i, off); 68 printf("Error (%d) reading page %08lx\n", i, off);
69 free(datbuf); 69 free(datbuf);
70 free(oobbuf); 70 free(oobbuf);
71 return 1; 71 return 1;
72 } 72 }
73 printf("Page %08lx dump:\n", off); 73 printf("Page %08lx dump:\n", off);
74 i = nand->writesize >> 4; 74 i = nand->writesize >> 4;
75 p = datbuf; 75 p = datbuf;
76 76
77 while (i--) { 77 while (i--) {
78 if (!only_oob) 78 if (!only_oob)
79 printf("\t%02x %02x %02x %02x %02x %02x %02x %02x" 79 printf("\t%02x %02x %02x %02x %02x %02x %02x %02x"
80 " %02x %02x %02x %02x %02x %02x %02x %02x\n", 80 " %02x %02x %02x %02x %02x %02x %02x %02x\n",
81 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], 81 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
82 p[8], p[9], p[10], p[11], p[12], p[13], p[14], 82 p[8], p[9], p[10], p[11], p[12], p[13], p[14],
83 p[15]); 83 p[15]);
84 p += 16; 84 p += 16;
85 } 85 }
86 puts("OOB:\n"); 86 puts("OOB:\n");
87 i = nand->oobsize >> 3; 87 i = nand->oobsize >> 3;
88 while (i--) { 88 while (i--) {
89 printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n", 89 printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
90 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); 90 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
91 p += 8; 91 p += 8;
92 } 92 }
93 free(datbuf); 93 free(datbuf);
94 free(oobbuf); 94 free(oobbuf);
95 95
96 return 0; 96 return 0;
97 } 97 }
98 98
99 /* ------------------------------------------------------------------------- */ 99 /* ------------------------------------------------------------------------- */
100 100
101 static int set_dev(int dev) 101 static int set_dev(int dev)
102 { 102 {
103 if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE || 103 if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE ||
104 !nand_info[dev].name) { 104 !nand_info[dev].name) {
105 puts("No such device\n"); 105 puts("No such device\n");
106 return -1; 106 return -1;
107 } 107 }
108 108
109 if (nand_curr_device == dev) 109 if (nand_curr_device == dev)
110 return 0; 110 return 0;
111 111
112 printf("Device %d: %s", dev, nand_info[dev].name); 112 printf("Device %d: %s", dev, nand_info[dev].name);
113 puts("... is now current device\n"); 113 puts("... is now current device\n");
114 nand_curr_device = dev; 114 nand_curr_device = dev;
115 115
116 #ifdef CONFIG_SYS_NAND_SELECT_DEVICE 116 #ifdef CONFIG_SYS_NAND_SELECT_DEVICE
117 board_nand_select_device(nand_info[dev].priv, dev); 117 board_nand_select_device(nand_info[dev].priv, dev);
118 #endif 118 #endif
119 119
120 return 0; 120 return 0;
121 } 121 }
122 122
123 static inline int str2off(const char *p, loff_t *num) 123 static inline int str2off(const char *p, loff_t *num)
124 { 124 {
125 char *endptr; 125 char *endptr;
126 126
127 *num = simple_strtoull(p, &endptr, 16); 127 *num = simple_strtoull(p, &endptr, 16);
128 return *p != '\0' && *endptr == '\0'; 128 return *p != '\0' && *endptr == '\0';
129 } 129 }
130 130
131 static inline int str2long(const char *p, ulong *num) 131 static inline int str2long(const char *p, ulong *num)
132 { 132 {
133 char *endptr; 133 char *endptr;
134 134
135 *num = simple_strtoul(p, &endptr, 16); 135 *num = simple_strtoul(p, &endptr, 16);
136 return *p != '\0' && *endptr == '\0'; 136 return *p != '\0' && *endptr == '\0';
137 } 137 }
138 138
139 static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size) 139 static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size)
140 { 140 {
141 #ifdef CONFIG_CMD_MTDPARTS 141 #ifdef CONFIG_CMD_MTDPARTS
142 struct mtd_device *dev; 142 struct mtd_device *dev;
143 struct part_info *part; 143 struct part_info *part;
144 u8 pnum; 144 u8 pnum;
145 int ret; 145 int ret;
146 146
147 ret = mtdparts_init(); 147 ret = mtdparts_init();
148 if (ret) 148 if (ret)
149 return ret; 149 return ret;
150 150
151 ret = find_dev_and_part(partname, &dev, &pnum, &part); 151 ret = find_dev_and_part(partname, &dev, &pnum, &part);
152 if (ret) 152 if (ret)
153 return ret; 153 return ret;
154 154
155 if (dev->id->type != MTD_DEV_TYPE_NAND) { 155 if (dev->id->type != MTD_DEV_TYPE_NAND) {
156 puts("not a NAND device\n"); 156 puts("not a NAND device\n");
157 return -1; 157 return -1;
158 } 158 }
159 159
160 *off = part->offset; 160 *off = part->offset;
161 *size = part->size; 161 *size = part->size;
162 *idx = dev->id->num; 162 *idx = dev->id->num;
163 163
164 ret = set_dev(*idx); 164 ret = set_dev(*idx);
165 if (ret) 165 if (ret)
166 return ret; 166 return ret;
167 167
168 return 0; 168 return 0;
169 #else 169 #else
170 puts("offset is not a number\n"); 170 puts("offset is not a number\n");
171 return -1; 171 return -1;
172 #endif 172 #endif
173 } 173 }
174 174
175 static int arg_off(const char *arg, int *idx, loff_t *off, loff_t *maxsize) 175 static int arg_off(const char *arg, int *idx, loff_t *off, loff_t *maxsize)
176 { 176 {
177 if (!str2off(arg, off)) 177 if (!str2off(arg, off))
178 return get_part(arg, idx, off, maxsize); 178 return get_part(arg, idx, off, maxsize);
179 179
180 if (*off >= nand_info[*idx].size) { 180 if (*off >= nand_info[*idx].size) {
181 puts("Offset exceeds device limit\n"); 181 puts("Offset exceeds device limit\n");
182 return -1; 182 return -1;
183 } 183 }
184 184
185 *maxsize = nand_info[*idx].size - *off; 185 *maxsize = nand_info[*idx].size - *off;
186 return 0; 186 return 0;
187 } 187 }
188 188
189 static int arg_off_size(int argc, char *const argv[], int *idx, 189 static int arg_off_size(int argc, char *const argv[], int *idx,
190 loff_t *off, loff_t *size) 190 loff_t *off, loff_t *size)
191 { 191 {
192 int ret; 192 int ret;
193 loff_t maxsize; 193 loff_t maxsize;
194 194
195 if (argc == 0) { 195 if (argc == 0) {
196 *off = 0; 196 *off = 0;
197 *size = nand_info[*idx].size; 197 *size = nand_info[*idx].size;
198 goto print; 198 goto print;
199 } 199 }
200 200
201 ret = arg_off(argv[0], idx, off, &maxsize); 201 ret = arg_off(argv[0], idx, off, &maxsize);
202 if (ret) 202 if (ret)
203 return ret; 203 return ret;
204 204
205 if (argc == 1) { 205 if (argc == 1) {
206 *size = maxsize; 206 *size = maxsize;
207 goto print; 207 goto print;
208 } 208 }
209 209
210 if (!str2off(argv[1], size)) { 210 if (!str2off(argv[1], size)) {
211 printf("'%s' is not a number\n", argv[1]); 211 printf("'%s' is not a number\n", argv[1]);
212 return -1; 212 return -1;
213 } 213 }
214 214
215 if (*size > maxsize) { 215 if (*size > maxsize) {
216 puts("Size exceeds partition or device limit\n"); 216 puts("Size exceeds partition or device limit\n");
217 return -1; 217 return -1;
218 } 218 }
219 219
220 print: 220 print:
221 printf("device %d ", *idx); 221 printf("device %d ", *idx);
222 if (*size == nand_info[*idx].size) 222 if (*size == nand_info[*idx].size)
223 puts("whole chip\n"); 223 puts("whole chip\n");
224 else 224 else
225 printf("offset 0x%llx, size 0x%llx\n", 225 printf("offset 0x%llx, size 0x%llx\n",
226 (unsigned long long)*off, (unsigned long long)*size); 226 (unsigned long long)*off, (unsigned long long)*size);
227 return 0; 227 return 0;
228 } 228 }
229 229
230 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK 230 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
231 static void print_status(ulong start, ulong end, ulong erasesize, int status) 231 static void print_status(ulong start, ulong end, ulong erasesize, int status)
232 { 232 {
233 printf("%08lx - %08lx: %08lx blocks %s%s%s\n", 233 printf("%08lx - %08lx: %08lx blocks %s%s%s\n",
234 start, 234 start,
235 end - 1, 235 end - 1,
236 (end - start) / erasesize, 236 (end - start) / erasesize,
237 ((status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), 237 ((status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""),
238 ((status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""), 238 ((status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""),
239 ((status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); 239 ((status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : ""));
240 } 240 }
241 241
242 static void do_nand_status(nand_info_t *nand) 242 static void do_nand_status(nand_info_t *nand)
243 { 243 {
244 ulong block_start = 0; 244 ulong block_start = 0;
245 ulong off; 245 ulong off;
246 int last_status = -1; 246 int last_status = -1;
247 247
248 struct nand_chip *nand_chip = nand->priv; 248 struct nand_chip *nand_chip = nand->priv;
249 /* check the WP bit */ 249 /* check the WP bit */
250 nand_chip->cmdfunc(nand, NAND_CMD_STATUS, -1, -1); 250 nand_chip->cmdfunc(nand, NAND_CMD_STATUS, -1, -1);
251 printf("device is %swrite protected\n", 251 printf("device is %swrite protected\n",
252 (nand_chip->read_byte(nand) & 0x80 ? 252 (nand_chip->read_byte(nand) & 0x80 ?
253 "NOT " : "")); 253 "NOT " : ""));
254 254
255 for (off = 0; off < nand->size; off += nand->erasesize) { 255 for (off = 0; off < nand->size; off += nand->erasesize) {
256 int s = nand_get_lock_status(nand, off); 256 int s = nand_get_lock_status(nand, off);
257 257
258 /* print message only if status has changed */ 258 /* print message only if status has changed */
259 if (s != last_status && off != 0) { 259 if (s != last_status && off != 0) {
260 print_status(block_start, off, nand->erasesize, 260 print_status(block_start, off, nand->erasesize,
261 last_status); 261 last_status);
262 block_start = off; 262 block_start = off;
263 } 263 }
264 last_status = s; 264 last_status = s;
265 } 265 }
266 /* Print the last block info */ 266 /* Print the last block info */
267 print_status(block_start, off, nand->erasesize, last_status); 267 print_status(block_start, off, nand->erasesize, last_status);
268 } 268 }
269 #endif 269 #endif
270 270
271 #ifdef CONFIG_ENV_OFFSET_OOB 271 #ifdef CONFIG_ENV_OFFSET_OOB
272 unsigned long nand_env_oob_offset; 272 unsigned long nand_env_oob_offset;
273 273
274 int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[]) 274 int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[])
275 { 275 {
276 int ret; 276 int ret;
277 uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)]; 277 uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)];
278 nand_info_t *nand = &nand_info[0]; 278 nand_info_t *nand = &nand_info[0];
279 char *cmd = argv[1]; 279 char *cmd = argv[1];
280 280
281 if (CONFIG_SYS_MAX_NAND_DEVICE == 0 || !nand->name) { 281 if (CONFIG_SYS_MAX_NAND_DEVICE == 0 || !nand->name) {
282 puts("no devices available\n"); 282 puts("no devices available\n");
283 return 1; 283 return 1;
284 } 284 }
285 285
286 set_dev(0); 286 set_dev(0);
287 287
288 if (!strcmp(cmd, "get")) { 288 if (!strcmp(cmd, "get")) {
289 ret = get_nand_env_oob(nand, &nand_env_oob_offset); 289 ret = get_nand_env_oob(nand, &nand_env_oob_offset);
290 if (ret) 290 if (ret)
291 return 1; 291 return 1;
292 292
293 printf("0x%08lx\n", nand_env_oob_offset); 293 printf("0x%08lx\n", nand_env_oob_offset);
294 } else if (!strcmp(cmd, "set")) { 294 } else if (!strcmp(cmd, "set")) {
295 loff_t addr; 295 loff_t addr;
296 loff_t maxsize; 296 loff_t maxsize;
297 struct mtd_oob_ops ops; 297 struct mtd_oob_ops ops;
298 int idx = 0; 298 int idx = 0;
299 299
300 if (argc < 3) 300 if (argc < 3)
301 goto usage; 301 goto usage;
302 302
303 if (arg_off(argv[2], &idx, &addr, &maxsize)) { 303 if (arg_off(argv[2], &idx, &addr, &maxsize)) {
304 puts("Offset or partition name expected\n"); 304 puts("Offset or partition name expected\n");
305 return 1; 305 return 1;
306 } 306 }
307 307
308 if (idx != 0) { 308 if (idx != 0) {
309 puts("Partition not on first NAND device\n"); 309 puts("Partition not on first NAND device\n");
310 return 1; 310 return 1;
311 } 311 }
312 312
313 if (nand->oobavail < ENV_OFFSET_SIZE) { 313 if (nand->oobavail < ENV_OFFSET_SIZE) {
314 printf("Insufficient available OOB bytes:\n" 314 printf("Insufficient available OOB bytes:\n"
315 "%d OOB bytes available but %d required for " 315 "%d OOB bytes available but %d required for "
316 "env.oob support\n", 316 "env.oob support\n",
317 nand->oobavail, ENV_OFFSET_SIZE); 317 nand->oobavail, ENV_OFFSET_SIZE);
318 return 1; 318 return 1;
319 } 319 }
320 320
321 if ((addr & (nand->erasesize - 1)) != 0) { 321 if ((addr & (nand->erasesize - 1)) != 0) {
322 printf("Environment offset must be block-aligned\n"); 322 printf("Environment offset must be block-aligned\n");
323 return 1; 323 return 1;
324 } 324 }
325 325
326 ops.datbuf = NULL; 326 ops.datbuf = NULL;
327 ops.mode = MTD_OOB_AUTO; 327 ops.mode = MTD_OOB_AUTO;
328 ops.ooboffs = 0; 328 ops.ooboffs = 0;
329 ops.ooblen = ENV_OFFSET_SIZE; 329 ops.ooblen = ENV_OFFSET_SIZE;
330 ops.oobbuf = (void *) oob_buf; 330 ops.oobbuf = (void *) oob_buf;
331 331
332 oob_buf[0] = ENV_OOB_MARKER; 332 oob_buf[0] = ENV_OOB_MARKER;
333 oob_buf[1] = addr / nand->erasesize; 333 oob_buf[1] = addr / nand->erasesize;
334 334
335 ret = nand->write_oob(nand, ENV_OFFSET_SIZE, &ops); 335 ret = nand->write_oob(nand, ENV_OFFSET_SIZE, &ops);
336 if (ret) { 336 if (ret) {
337 printf("Error writing OOB block 0\n"); 337 printf("Error writing OOB block 0\n");
338 return ret; 338 return ret;
339 } 339 }
340 340
341 ret = get_nand_env_oob(nand, &nand_env_oob_offset); 341 ret = get_nand_env_oob(nand, &nand_env_oob_offset);
342 if (ret) { 342 if (ret) {
343 printf("Error reading env offset in OOB\n"); 343 printf("Error reading env offset in OOB\n");
344 return ret; 344 return ret;
345 } 345 }
346 346
347 if (addr != nand_env_oob_offset) { 347 if (addr != nand_env_oob_offset) {
348 printf("Verification of env offset in OOB failed: " 348 printf("Verification of env offset in OOB failed: "
349 "0x%08llx expected but got 0x%08lx\n", 349 "0x%08llx expected but got 0x%08lx\n",
350 (unsigned long long)addr, nand_env_oob_offset); 350 (unsigned long long)addr, nand_env_oob_offset);
351 return 1; 351 return 1;
352 } 352 }
353 } else { 353 } else {
354 goto usage; 354 goto usage;
355 } 355 }
356 356
357 return ret; 357 return ret;
358 358
359 usage: 359 usage:
360 return cmd_usage(cmdtp); 360 return cmd_usage(cmdtp);
361 } 361 }
362 362
363 #endif 363 #endif
364 364
365 static void nand_print_info(int idx) 365 static void nand_print_info(int idx)
366 { 366 {
367 nand_info_t *nand = &nand_info[idx]; 367 nand_info_t *nand = &nand_info[idx];
368 struct nand_chip *chip = nand->priv; 368 struct nand_chip *chip = nand->priv;
369 printf("Device %d: ", idx); 369 printf("Device %d: ", idx);
370 if (chip->numchips > 1) 370 if (chip->numchips > 1)
371 printf("%dx ", chip->numchips); 371 printf("%dx ", chip->numchips);
372 printf("%s, sector size %u KiB\n", 372 printf("%s, sector size %u KiB\n",
373 nand->name, nand->erasesize >> 10); 373 nand->name, nand->erasesize >> 10);
374 } 374 }
375 375
376 int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) 376 int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
377 { 377 {
378 int i, ret = 0; 378 int i, ret = 0;
379 ulong addr; 379 ulong addr;
380 loff_t off, size; 380 loff_t off, size;
381 char *cmd, *s; 381 char *cmd, *s;
382 nand_info_t *nand; 382 nand_info_t *nand;
383 #ifdef CONFIG_SYS_NAND_QUIET 383 #ifdef CONFIG_SYS_NAND_QUIET
384 int quiet = CONFIG_SYS_NAND_QUIET; 384 int quiet = CONFIG_SYS_NAND_QUIET;
385 #else 385 #else
386 int quiet = 0; 386 int quiet = 0;
387 #endif 387 #endif
388 const char *quiet_str = getenv("quiet"); 388 const char *quiet_str = getenv("quiet");
389 int dev = nand_curr_device; 389 int dev = nand_curr_device;
390 int repeat = flag & CMD_FLAG_REPEAT; 390 int repeat = flag & CMD_FLAG_REPEAT;
391 391
392 /* at least two arguments please */ 392 /* at least two arguments please */
393 if (argc < 2) 393 if (argc < 2)
394 goto usage; 394 goto usage;
395 395
396 if (quiet_str) 396 if (quiet_str)
397 quiet = simple_strtoul(quiet_str, NULL, 0) != 0; 397 quiet = simple_strtoul(quiet_str, NULL, 0) != 0;
398 398
399 cmd = argv[1]; 399 cmd = argv[1];
400 400
401 /* Only "dump" is repeatable. */ 401 /* Only "dump" is repeatable. */
402 if (repeat && strcmp(cmd, "dump")) 402 if (repeat && strcmp(cmd, "dump"))
403 return 0; 403 return 0;
404 404
405 if (strcmp(cmd, "info") == 0) { 405 if (strcmp(cmd, "info") == 0) {
406 406
407 putc('\n'); 407 putc('\n');
408 for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) { 408 for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) {
409 if (nand_info[i].name) 409 if (nand_info[i].name)
410 nand_print_info(i); 410 nand_print_info(i);
411 } 411 }
412 return 0; 412 return 0;
413 } 413 }
414 414
415 if (strcmp(cmd, "device") == 0) { 415 if (strcmp(cmd, "device") == 0) {
416 if (argc < 3) { 416 if (argc < 3) {
417 putc('\n'); 417 putc('\n');
418 if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE) 418 if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE)
419 puts("no devices available\n"); 419 puts("no devices available\n");
420 else 420 else
421 nand_print_info(dev); 421 nand_print_info(dev);
422 return 0; 422 return 0;
423 } 423 }
424 424
425 dev = (int)simple_strtoul(argv[2], NULL, 10); 425 dev = (int)simple_strtoul(argv[2], NULL, 10);
426 set_dev(dev); 426 set_dev(dev);
427 427
428 return 0; 428 return 0;
429 } 429 }
430 430
431 #ifdef CONFIG_ENV_OFFSET_OOB 431 #ifdef CONFIG_ENV_OFFSET_OOB
432 /* this command operates only on the first nand device */ 432 /* this command operates only on the first nand device */
433 if (strcmp(cmd, "env.oob") == 0) 433 if (strcmp(cmd, "env.oob") == 0)
434 return do_nand_env_oob(cmdtp, argc - 1, argv + 1); 434 return do_nand_env_oob(cmdtp, argc - 1, argv + 1);
435 #endif 435 #endif
436 436
437 /* The following commands operate on the current device, unless 437 /* The following commands operate on the current device, unless
438 * overridden by a partition specifier. Note that if somehow the 438 * overridden by a partition specifier. Note that if somehow the
439 * current device is invalid, it will have to be changed to a valid 439 * current device is invalid, it will have to be changed to a valid
440 * one before these commands can run, even if a partition specifier 440 * one before these commands can run, even if a partition specifier
441 * for another device is to be used. 441 * for another device is to be used.
442 */ 442 */
443 if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE || 443 if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE ||
444 !nand_info[dev].name) { 444 !nand_info[dev].name) {
445 puts("\nno devices available\n"); 445 puts("\nno devices available\n");
446 return 1; 446 return 1;
447 } 447 }
448 nand = &nand_info[dev]; 448 nand = &nand_info[dev];
449 449
450 if (strcmp(cmd, "bad") == 0) { 450 if (strcmp(cmd, "bad") == 0) {
451 printf("\nDevice %d bad blocks:\n", dev); 451 printf("\nDevice %d bad blocks:\n", dev);
452 for (off = 0; off < nand->size; off += nand->erasesize) 452 for (off = 0; off < nand->size; off += nand->erasesize)
453 if (nand_block_isbad(nand, off)) 453 if (nand_block_isbad(nand, off))
454 printf(" %08llx\n", (unsigned long long)off); 454 printf(" %08llx\n", (unsigned long long)off);
455 return 0; 455 return 0;
456 } 456 }
457 457
458 /* 458 /*
459 * Syntax is: 459 * Syntax is:
460 * 0 1 2 3 4 460 * 0 1 2 3 4
461 * nand erase [clean] [off size] 461 * nand erase [clean] [off size]
462 */ 462 */
463 if (strncmp(cmd, "erase", 5) == 0 || strncmp(cmd, "scrub", 5) == 0) { 463 if (strncmp(cmd, "erase", 5) == 0 || strncmp(cmd, "scrub", 5) == 0) {
464 nand_erase_options_t opts; 464 nand_erase_options_t opts;
465 /* "clean" at index 2 means request to write cleanmarker */ 465 /* "clean" at index 2 means request to write cleanmarker */
466 int clean = argc > 2 && !strcmp("clean", argv[2]); 466 int clean = argc > 2 && !strcmp("clean", argv[2]);
467 int o = clean ? 3 : 2; 467 int o = clean ? 3 : 2;
468 int scrub = !strncmp(cmd, "scrub", 5); 468 int scrub = !strncmp(cmd, "scrub", 5);
469 int part = 0; 469 int part = 0;
470 int chip = 0; 470 int chip = 0;
471 int spread = 0; 471 int spread = 0;
472 int args = 2; 472 int args = 2;
473 473
474 if (cmd[5] != 0) { 474 if (cmd[5] != 0) {
475 if (!strcmp(&cmd[5], ".spread")) { 475 if (!strcmp(&cmd[5], ".spread")) {
476 spread = 1; 476 spread = 1;
477 } else if (!strcmp(&cmd[5], ".part")) { 477 } else if (!strcmp(&cmd[5], ".part")) {
478 part = 1; 478 part = 1;
479 args = 1; 479 args = 1;
480 } else if (!strcmp(&cmd[5], ".chip")) { 480 } else if (!strcmp(&cmd[5], ".chip")) {
481 chip = 1; 481 chip = 1;
482 args = 0; 482 args = 0;
483 } else { 483 } else {
484 goto usage; 484 goto usage;
485 } 485 }
486 } 486 }
487 487
488 /* 488 /*
489 * Don't allow missing arguments to cause full chip/partition 489 * Don't allow missing arguments to cause full chip/partition
490 * erases -- easy to do accidentally, e.g. with a misspelled 490 * erases -- easy to do accidentally, e.g. with a misspelled
491 * variable name. 491 * variable name.
492 */ 492 */
493 if (argc != o + args) 493 if (argc != o + args)
494 goto usage; 494 goto usage;
495 495
496 printf("\nNAND %s: ", cmd); 496 printf("\nNAND %s: ", cmd);
497 /* skip first two or three arguments, look for offset and size */ 497 /* skip first two or three arguments, look for offset and size */
498 if (arg_off_size(argc - o, argv + o, &dev, &off, &size) != 0) 498 if (arg_off_size(argc - o, argv + o, &dev, &off, &size) != 0)
499 return 1; 499 return 1;
500 500
501 nand = &nand_info[dev]; 501 nand = &nand_info[dev];
502 502
503 memset(&opts, 0, sizeof(opts)); 503 memset(&opts, 0, sizeof(opts));
504 opts.offset = off; 504 opts.offset = off;
505 opts.length = size; 505 opts.length = size;
506 opts.jffs2 = clean; 506 opts.jffs2 = clean;
507 opts.quiet = quiet; 507 opts.quiet = quiet;
508 opts.spread = spread; 508 opts.spread = spread;
509 509
510 if (scrub) { 510 if (scrub) {
511 puts("Warning: " 511 puts("Warning: "
512 "scrub option will erase all factory set " 512 "scrub option will erase all factory set "
513 "bad blocks!\n" 513 "bad blocks!\n"
514 " " 514 " "
515 "There is no reliable way to recover them.\n" 515 "There is no reliable way to recover them.\n"
516 " " 516 " "
517 "Use this command only for testing purposes " 517 "Use this command only for testing purposes "
518 "if you\n" 518 "if you\n"
519 " " 519 " "
520 "are sure of what you are doing!\n" 520 "are sure of what you are doing!\n"
521 "\nReally scrub this NAND flash? <y/N>\n"); 521 "\nReally scrub this NAND flash? <y/N>\n");
522 522
523 if (getc() == 'y') { 523 if (getc() == 'y') {
524 puts("y"); 524 puts("y");
525 if (getc() == '\r') 525 if (getc() == '\r')
526 opts.scrub = 1; 526 opts.scrub = 1;
527 else { 527 else {
528 puts("scrub aborted\n"); 528 puts("scrub aborted\n");
529 return -1; 529 return -1;
530 } 530 }
531 } else { 531 } else {
532 puts("scrub aborted\n"); 532 puts("scrub aborted\n");
533 return -1; 533 return -1;
534 } 534 }
535 } 535 }
536 ret = nand_erase_opts(nand, &opts); 536 ret = nand_erase_opts(nand, &opts);
537 printf("%s\n", ret ? "ERROR" : "OK"); 537 printf("%s\n", ret ? "ERROR" : "OK");
538 538
539 return ret == 0 ? 0 : 1; 539 return ret == 0 ? 0 : 1;
540 } 540 }
541 541
542 if (strncmp(cmd, "dump", 4) == 0) { 542 if (strncmp(cmd, "dump", 4) == 0) {
543 if (argc < 3) 543 if (argc < 3)
544 goto usage; 544 goto usage;
545 545
546 off = (int)simple_strtoul(argv[2], NULL, 16); 546 off = (int)simple_strtoul(argv[2], NULL, 16);
547 ret = nand_dump(nand, off, !strcmp(&cmd[4], ".oob"), repeat); 547 ret = nand_dump(nand, off, !strcmp(&cmd[4], ".oob"), repeat);
548 548
549 return ret == 0 ? 1 : 0; 549 return ret == 0 ? 1 : 0;
550 } 550 }
551 551
552 if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { 552 if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
553 size_t rwsize; 553 size_t rwsize;
554 int read; 554 int read;
555 555
556 if (argc < 4) 556 if (argc < 4)
557 goto usage; 557 goto usage;
558 558
559 addr = (ulong)simple_strtoul(argv[2], NULL, 16); 559 addr = (ulong)simple_strtoul(argv[2], NULL, 16);
560 560
561 read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ 561 read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
562 printf("\nNAND %s: ", read ? "read" : "write"); 562 printf("\nNAND %s: ", read ? "read" : "write");
563 if (arg_off_size(argc - 3, argv + 3, &dev, &off, &size) != 0) 563 if (arg_off_size(argc - 3, argv + 3, &dev, &off, &size) != 0)
564 return 1; 564 return 1;
565 565
566 nand = &nand_info[dev]; 566 nand = &nand_info[dev];
567 rwsize = size; 567 rwsize = size;
568 568
569 s = strchr(cmd, '.'); 569 s = strchr(cmd, '.');
570 if (!s || !strcmp(s, ".jffs2") || 570 if (!s || !strcmp(s, ".jffs2") ||
571 !strcmp(s, ".e") || !strcmp(s, ".i")) { 571 !strcmp(s, ".e") || !strcmp(s, ".i")) {
572 if (read) 572 if (read)
573 ret = nand_read_skip_bad(nand, off, &rwsize, 573 ret = nand_read_skip_bad(nand, off, &rwsize,
574 (u_char *)addr); 574 (u_char *)addr);
575 else 575 else
576 ret = nand_write_skip_bad(nand, off, &rwsize, 576 ret = nand_write_skip_bad(nand, off, &rwsize,
577 (u_char *)addr, 0); 577 (u_char *)addr, 0);
578 #ifdef CONFIG_CMD_NAND_TRIMFFS
579 } else if (!strcmp(s, ".trimffs")) {
580 if (read) {
581 printf("Unknown nand command suffix '%s'\n", s);
582 return 1;
583 }
584 ret = nand_write_skip_bad(nand, off, &rwsize,
585 (u_char *)addr,
586 WITH_DROP_FFS);
587 #endif
578 #ifdef CONFIG_CMD_NAND_YAFFS 588 #ifdef CONFIG_CMD_NAND_YAFFS
579 } else if (!strcmp(s, ".yaffs")) { 589 } else if (!strcmp(s, ".yaffs")) {
580 if (read) { 590 if (read) {
581 printf("Unknown nand command suffix '%s'.\n", s); 591 printf("Unknown nand command suffix '%s'.\n", s);
582 return 1; 592 return 1;
583 } 593 }
584 ret = nand_write_skip_bad(nand, off, &rwsize, 594 ret = nand_write_skip_bad(nand, off, &rwsize,
585 (u_char *)addr, WITH_YAFFS_OOB); 595 (u_char *)addr, WITH_YAFFS_OOB);
586 #endif 596 #endif
587 } else if (!strcmp(s, ".oob")) { 597 } else if (!strcmp(s, ".oob")) {
588 /* out-of-band data */ 598 /* out-of-band data */
589 mtd_oob_ops_t ops = { 599 mtd_oob_ops_t ops = {
590 .oobbuf = (u8 *)addr, 600 .oobbuf = (u8 *)addr,
591 .ooblen = rwsize, 601 .ooblen = rwsize,
592 .mode = MTD_OOB_RAW 602 .mode = MTD_OOB_RAW
593 }; 603 };
594 604
595 if (read) 605 if (read)
596 ret = nand->read_oob(nand, off, &ops); 606 ret = nand->read_oob(nand, off, &ops);
597 else 607 else
598 ret = nand->write_oob(nand, off, &ops); 608 ret = nand->write_oob(nand, off, &ops);
599 } else { 609 } else {
600 printf("Unknown nand command suffix '%s'.\n", s); 610 printf("Unknown nand command suffix '%s'.\n", s);
601 return 1; 611 return 1;
602 } 612 }
603 613
604 printf(" %zu bytes %s: %s\n", rwsize, 614 printf(" %zu bytes %s: %s\n", rwsize,
605 read ? "read" : "written", ret ? "ERROR" : "OK"); 615 read ? "read" : "written", ret ? "ERROR" : "OK");
606 616
607 return ret == 0 ? 0 : 1; 617 return ret == 0 ? 0 : 1;
608 } 618 }
609 619
610 if (strcmp(cmd, "markbad") == 0) { 620 if (strcmp(cmd, "markbad") == 0) {
611 argc -= 2; 621 argc -= 2;
612 argv += 2; 622 argv += 2;
613 623
614 if (argc <= 0) 624 if (argc <= 0)
615 goto usage; 625 goto usage;
616 626
617 while (argc > 0) { 627 while (argc > 0) {
618 addr = simple_strtoul(*argv, NULL, 16); 628 addr = simple_strtoul(*argv, NULL, 16);
619 629
620 if (nand->block_markbad(nand, addr)) { 630 if (nand->block_markbad(nand, addr)) {
621 printf("block 0x%08lx NOT marked " 631 printf("block 0x%08lx NOT marked "
622 "as bad! ERROR %d\n", 632 "as bad! ERROR %d\n",
623 addr, ret); 633 addr, ret);
624 ret = 1; 634 ret = 1;
625 } else { 635 } else {
626 printf("block 0x%08lx successfully " 636 printf("block 0x%08lx successfully "
627 "marked as bad\n", 637 "marked as bad\n",
628 addr); 638 addr);
629 } 639 }
630 --argc; 640 --argc;
631 ++argv; 641 ++argv;
632 } 642 }
633 return ret; 643 return ret;
634 } 644 }
635 645
636 if (strcmp(cmd, "biterr") == 0) { 646 if (strcmp(cmd, "biterr") == 0) {
637 /* todo */ 647 /* todo */
638 return 1; 648 return 1;
639 } 649 }
640 650
641 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK 651 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
642 if (strcmp(cmd, "lock") == 0) { 652 if (strcmp(cmd, "lock") == 0) {
643 int tight = 0; 653 int tight = 0;
644 int status = 0; 654 int status = 0;
645 if (argc == 3) { 655 if (argc == 3) {
646 if (!strcmp("tight", argv[2])) 656 if (!strcmp("tight", argv[2]))
647 tight = 1; 657 tight = 1;
648 if (!strcmp("status", argv[2])) 658 if (!strcmp("status", argv[2]))
649 status = 1; 659 status = 1;
650 } 660 }
651 if (status) { 661 if (status) {
652 do_nand_status(nand); 662 do_nand_status(nand);
653 } else { 663 } else {
654 if (!nand_lock(nand, tight)) { 664 if (!nand_lock(nand, tight)) {
655 puts("NAND flash successfully locked\n"); 665 puts("NAND flash successfully locked\n");
656 } else { 666 } else {
657 puts("Error locking NAND flash\n"); 667 puts("Error locking NAND flash\n");
658 return 1; 668 return 1;
659 } 669 }
660 } 670 }
661 return 0; 671 return 0;
662 } 672 }
663 673
664 if (strcmp(cmd, "unlock") == 0) { 674 if (strcmp(cmd, "unlock") == 0) {
665 if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size) < 0) 675 if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size) < 0)
666 return 1; 676 return 1;
667 677
668 if (!nand_unlock(&nand_info[dev], off, size)) { 678 if (!nand_unlock(&nand_info[dev], off, size)) {
669 puts("NAND flash successfully unlocked\n"); 679 puts("NAND flash successfully unlocked\n");
670 } else { 680 } else {
671 puts("Error unlocking NAND flash, " 681 puts("Error unlocking NAND flash, "
672 "write and erase will probably fail\n"); 682 "write and erase will probably fail\n");
673 return 1; 683 return 1;
674 } 684 }
675 return 0; 685 return 0;
676 } 686 }
677 #endif 687 #endif
678 688
679 usage: 689 usage:
680 return cmd_usage(cmdtp); 690 return cmd_usage(cmdtp);
681 } 691 }
682 692
683 U_BOOT_CMD( 693 U_BOOT_CMD(
684 nand, CONFIG_SYS_MAXARGS, 1, do_nand, 694 nand, CONFIG_SYS_MAXARGS, 1, do_nand,
685 "NAND sub-system", 695 "NAND sub-system",
686 "info - show available NAND devices\n" 696 "info - show available NAND devices\n"
687 "nand device [dev] - show or set current device\n" 697 "nand device [dev] - show or set current device\n"
688 "nand read - addr off|partition size\n" 698 "nand read - addr off|partition size\n"
689 "nand write - addr off|partition size\n" 699 "nand write - addr off|partition size\n"
690 " read/write 'size' bytes starting at offset 'off'\n" 700 " read/write 'size' bytes starting at offset 'off'\n"
691 " to/from memory address 'addr', skipping bad blocks.\n" 701 " to/from memory address 'addr', skipping bad blocks.\n"
702 #ifdef CONFIG_CMD_NAND_TRIMFFS
703 "nand write.trimffs - addr off|partition size\n"
704 " write 'size' bytes starting at offset 'off' from memory address\n"
705 " 'addr', skipping bad blocks and dropping any pages at the end\n"
706 " of eraseblocks that contain only 0xFF\n"
707 #endif
692 #ifdef CONFIG_CMD_NAND_YAFFS 708 #ifdef CONFIG_CMD_NAND_YAFFS
693 "nand write.yaffs - addr off|partition size\n" 709 "nand write.yaffs - addr off|partition size\n"
694 " write 'size' bytes starting at offset 'off' with yaffs format\n" 710 " write 'size' bytes starting at offset 'off' with yaffs format\n"
695 " from memory address 'addr', skipping bad blocks.\n" 711 " from memory address 'addr', skipping bad blocks.\n"
696 #endif 712 #endif
697 "nand erase[.spread] [clean] off size - erase 'size' bytes " 713 "nand erase[.spread] [clean] off size - erase 'size' bytes "
698 "from offset 'off'\n" 714 "from offset 'off'\n"
699 " With '.spread', erase enough for given file size, otherwise,\n" 715 " With '.spread', erase enough for given file size, otherwise,\n"
700 " 'size' includes skipped bad blocks.\n" 716 " 'size' includes skipped bad blocks.\n"
701 "nand erase.part [clean] partition - erase entire mtd partition'\n" 717 "nand erase.part [clean] partition - erase entire mtd partition'\n"
702 "nand erase.chip [clean] - erase entire chip'\n" 718 "nand erase.chip [clean] - erase entire chip'\n"
703 "nand bad - show bad blocks\n" 719 "nand bad - show bad blocks\n"
704 "nand dump[.oob] off - dump page\n" 720 "nand dump[.oob] off - dump page\n"
705 "nand scrub off size | scrub.part partition | scrub.chip\n" 721 "nand scrub off size | scrub.part partition | scrub.chip\n"
706 " really clean NAND erasing bad blocks (UNSAFE)\n" 722 " really clean NAND erasing bad blocks (UNSAFE)\n"
707 "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n" 723 "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
708 "nand biterr off - make a bit error at offset (UNSAFE)" 724 "nand biterr off - make a bit error at offset (UNSAFE)"
709 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK 725 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
710 "\n" 726 "\n"
711 "nand lock [tight] [status]\n" 727 "nand lock [tight] [status]\n"
712 " bring nand to lock state or display locked pages\n" 728 " bring nand to lock state or display locked pages\n"
713 "nand unlock [offset] [size] - unlock section" 729 "nand unlock [offset] [size] - unlock section"
714 #endif 730 #endif
715 #ifdef CONFIG_ENV_OFFSET_OOB 731 #ifdef CONFIG_ENV_OFFSET_OOB
716 "\n" 732 "\n"
717 "nand env.oob - environment offset in OOB of block 0 of" 733 "nand env.oob - environment offset in OOB of block 0 of"
718 " first device.\n" 734 " first device.\n"
719 "nand env.oob set off|partition - set enviromnent offset\n" 735 "nand env.oob set off|partition - set enviromnent offset\n"
720 "nand env.oob get - get environment offset" 736 "nand env.oob get - get environment offset"
721 #endif 737 #endif
722 ); 738 );
723 739
724 static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, 740 static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
725 ulong offset, ulong addr, char *cmd) 741 ulong offset, ulong addr, char *cmd)
726 { 742 {
727 int r; 743 int r;
728 char *ep, *s; 744 char *ep, *s;
729 size_t cnt; 745 size_t cnt;
730 image_header_t *hdr; 746 image_header_t *hdr;
731 #if defined(CONFIG_FIT) 747 #if defined(CONFIG_FIT)
732 const void *fit_hdr = NULL; 748 const void *fit_hdr = NULL;
733 #endif 749 #endif
734 750
735 s = strchr(cmd, '.'); 751 s = strchr(cmd, '.');
736 if (s != NULL && 752 if (s != NULL &&
737 (strcmp(s, ".jffs2") && strcmp(s, ".e") && strcmp(s, ".i"))) { 753 (strcmp(s, ".jffs2") && strcmp(s, ".e") && strcmp(s, ".i"))) {
738 printf("Unknown nand load suffix '%s'\n", s); 754 printf("Unknown nand load suffix '%s'\n", s);
739 show_boot_progress(-53); 755 show_boot_progress(-53);
740 return 1; 756 return 1;
741 } 757 }
742 758
743 printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset); 759 printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset);
744 760
745 cnt = nand->writesize; 761 cnt = nand->writesize;
746 r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr); 762 r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr);
747 if (r) { 763 if (r) {
748 puts("** Read error\n"); 764 puts("** Read error\n");
749 show_boot_progress (-56); 765 show_boot_progress (-56);
750 return 1; 766 return 1;
751 } 767 }
752 show_boot_progress (56); 768 show_boot_progress (56);
753 769
754 switch (genimg_get_format ((void *)addr)) { 770 switch (genimg_get_format ((void *)addr)) {
755 case IMAGE_FORMAT_LEGACY: 771 case IMAGE_FORMAT_LEGACY:
756 hdr = (image_header_t *)addr; 772 hdr = (image_header_t *)addr;
757 773
758 show_boot_progress (57); 774 show_boot_progress (57);
759 image_print_contents (hdr); 775 image_print_contents (hdr);
760 776
761 cnt = image_get_image_size (hdr); 777 cnt = image_get_image_size (hdr);
762 break; 778 break;
763 #if defined(CONFIG_FIT) 779 #if defined(CONFIG_FIT)
764 case IMAGE_FORMAT_FIT: 780 case IMAGE_FORMAT_FIT:
765 fit_hdr = (const void *)addr; 781 fit_hdr = (const void *)addr;
766 puts ("Fit image detected...\n"); 782 puts ("Fit image detected...\n");
767 783
768 cnt = fit_get_size (fit_hdr); 784 cnt = fit_get_size (fit_hdr);
769 break; 785 break;
770 #endif 786 #endif
771 default: 787 default:
772 show_boot_progress (-57); 788 show_boot_progress (-57);
773 puts ("** Unknown image type\n"); 789 puts ("** Unknown image type\n");
774 return 1; 790 return 1;
775 } 791 }
776 show_boot_progress (57); 792 show_boot_progress (57);
777 793
778 r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr); 794 r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr);
779 if (r) { 795 if (r) {
780 puts("** Read error\n"); 796 puts("** Read error\n");
781 show_boot_progress (-58); 797 show_boot_progress (-58);
782 return 1; 798 return 1;
783 } 799 }
784 show_boot_progress (58); 800 show_boot_progress (58);
785 801
786 #if defined(CONFIG_FIT) 802 #if defined(CONFIG_FIT)
787 /* This cannot be done earlier, we need complete FIT image in RAM first */ 803 /* This cannot be done earlier, we need complete FIT image in RAM first */
788 if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) { 804 if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) {
789 if (!fit_check_format (fit_hdr)) { 805 if (!fit_check_format (fit_hdr)) {
790 show_boot_progress (-150); 806 show_boot_progress (-150);
791 puts ("** Bad FIT image format\n"); 807 puts ("** Bad FIT image format\n");
792 return 1; 808 return 1;
793 } 809 }
794 show_boot_progress (151); 810 show_boot_progress (151);
795 fit_print_contents (fit_hdr); 811 fit_print_contents (fit_hdr);
796 } 812 }
797 #endif 813 #endif
798 814
799 /* Loading ok, update default load address */ 815 /* Loading ok, update default load address */
800 816
801 load_addr = addr; 817 load_addr = addr;
802 818
803 /* Check if we should attempt an auto-start */ 819 /* Check if we should attempt an auto-start */
804 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) { 820 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) {
805 char *local_args[2]; 821 char *local_args[2];
806 822
807 local_args[0] = cmd; 823 local_args[0] = cmd;
808 local_args[1] = NULL; 824 local_args[1] = NULL;
809 825
810 printf("Automatic boot of image at addr 0x%08lx ...\n", addr); 826 printf("Automatic boot of image at addr 0x%08lx ...\n", addr);
811 827
812 do_bootm(cmdtp, 0, 1, local_args); 828 do_bootm(cmdtp, 0, 1, local_args);
813 return 1; 829 return 1;
814 } 830 }
815 return 0; 831 return 0;
816 } 832 }
817 833
818 int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) 834 int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
819 { 835 {
820 char *boot_device = NULL; 836 char *boot_device = NULL;
821 int idx; 837 int idx;
822 ulong addr, offset = 0; 838 ulong addr, offset = 0;
823 #if defined(CONFIG_CMD_MTDPARTS) 839 #if defined(CONFIG_CMD_MTDPARTS)
824 struct mtd_device *dev; 840 struct mtd_device *dev;
825 struct part_info *part; 841 struct part_info *part;
826 u8 pnum; 842 u8 pnum;
827 843
828 if (argc >= 2) { 844 if (argc >= 2) {
829 char *p = (argc == 2) ? argv[1] : argv[2]; 845 char *p = (argc == 2) ? argv[1] : argv[2];
830 if (!(str2long(p, &addr)) && (mtdparts_init() == 0) && 846 if (!(str2long(p, &addr)) && (mtdparts_init() == 0) &&
831 (find_dev_and_part(p, &dev, &pnum, &part) == 0)) { 847 (find_dev_and_part(p, &dev, &pnum, &part) == 0)) {
832 if (dev->id->type != MTD_DEV_TYPE_NAND) { 848 if (dev->id->type != MTD_DEV_TYPE_NAND) {
833 puts("Not a NAND device\n"); 849 puts("Not a NAND device\n");
834 return 1; 850 return 1;
835 } 851 }
836 if (argc > 3) 852 if (argc > 3)
837 goto usage; 853 goto usage;
838 if (argc == 3) 854 if (argc == 3)
839 addr = simple_strtoul(argv[1], NULL, 16); 855 addr = simple_strtoul(argv[1], NULL, 16);
840 else 856 else
841 addr = CONFIG_SYS_LOAD_ADDR; 857 addr = CONFIG_SYS_LOAD_ADDR;
842 return nand_load_image(cmdtp, &nand_info[dev->id->num], 858 return nand_load_image(cmdtp, &nand_info[dev->id->num],
843 part->offset, addr, argv[0]); 859 part->offset, addr, argv[0]);
844 } 860 }
845 } 861 }
846 #endif 862 #endif
847 863
848 show_boot_progress(52); 864 show_boot_progress(52);
849 switch (argc) { 865 switch (argc) {
850 case 1: 866 case 1:
851 addr = CONFIG_SYS_LOAD_ADDR; 867 addr = CONFIG_SYS_LOAD_ADDR;
852 boot_device = getenv("bootdevice"); 868 boot_device = getenv("bootdevice");
853 break; 869 break;
854 case 2: 870 case 2:
855 addr = simple_strtoul(argv[1], NULL, 16); 871 addr = simple_strtoul(argv[1], NULL, 16);
856 boot_device = getenv("bootdevice"); 872 boot_device = getenv("bootdevice");
857 break; 873 break;
858 case 3: 874 case 3:
859 addr = simple_strtoul(argv[1], NULL, 16); 875 addr = simple_strtoul(argv[1], NULL, 16);
860 boot_device = argv[2]; 876 boot_device = argv[2];
861 break; 877 break;
862 case 4: 878 case 4:
863 addr = simple_strtoul(argv[1], NULL, 16); 879 addr = simple_strtoul(argv[1], NULL, 16);
864 boot_device = argv[2]; 880 boot_device = argv[2];
865 offset = simple_strtoul(argv[3], NULL, 16); 881 offset = simple_strtoul(argv[3], NULL, 16);
866 break; 882 break;
867 default: 883 default:
868 #if defined(CONFIG_CMD_MTDPARTS) 884 #if defined(CONFIG_CMD_MTDPARTS)
869 usage: 885 usage:
870 #endif 886 #endif
871 show_boot_progress(-53); 887 show_boot_progress(-53);
872 return cmd_usage(cmdtp); 888 return cmd_usage(cmdtp);
873 } 889 }
874 890
875 show_boot_progress(53); 891 show_boot_progress(53);
876 if (!boot_device) { 892 if (!boot_device) {
877 puts("\n** No boot device **\n"); 893 puts("\n** No boot device **\n");
878 show_boot_progress(-54); 894 show_boot_progress(-54);
879 return 1; 895 return 1;
880 } 896 }
881 show_boot_progress(54); 897 show_boot_progress(54);
882 898
883 idx = simple_strtoul(boot_device, NULL, 16); 899 idx = simple_strtoul(boot_device, NULL, 16);
884 900
885 if (idx < 0 || idx >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[idx].name) { 901 if (idx < 0 || idx >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[idx].name) {
886 printf("\n** Device %d not available\n", idx); 902 printf("\n** Device %d not available\n", idx);
887 show_boot_progress(-55); 903 show_boot_progress(-55);
888 return 1; 904 return 1;
889 } 905 }
890 show_boot_progress(55); 906 show_boot_progress(55);
891 907
892 return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]); 908 return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]);
893 } 909 }
894 910
895 U_BOOT_CMD(nboot, 4, 1, do_nandboot, 911 U_BOOT_CMD(nboot, 4, 1, do_nandboot,
896 "boot from NAND device", 912 "boot from NAND device",
897 "[partition] | [[[loadAddr] dev] offset]" 913 "[partition] | [[[loadAddr] dev] offset]"
898 ); 914 );
899 915
1 NAND FLASH commands and notes 1 NAND FLASH commands and notes
2 2
3 See NOTE below!!! 3 See NOTE below!!!
4 4
5 # (C) Copyright 2003 5 # (C) Copyright 2003
6 # Dave Ellis, SIXNET, dge@sixnetio.com 6 # Dave Ellis, SIXNET, dge@sixnetio.com
7 # 7 #
8 # See file CREDITS for list of people who contributed to this 8 # See file CREDITS for list of people who contributed to this
9 # project. 9 # project.
10 # 10 #
11 # This program is free software; you can redistribute it and/or 11 # This program is free software; you can redistribute it and/or
12 # modify it under the terms of the GNU General Public License as 12 # modify it under the terms of the GNU General Public License as
13 # published by the Free Software Foundation; either version 2 of 13 # published by the Free Software Foundation; either version 2 of
14 # the License, or (at your option) any later version. 14 # the License, or (at your option) any later version.
15 # 15 #
16 # This program is distributed in the hope that it will be useful, 16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details. 19 # GNU General Public License for more details.
20 # 20 #
21 # You should have received a copy of the GNU General Public License 21 # You should have received a copy of the GNU General Public License
22 # along with this program; if not, write to the Free Software 22 # along with this program; if not, write to the Free Software
23 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23 # Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 # MA 02111-1307 USA 24 # MA 02111-1307 USA
25 25
26 Commands: 26 Commands:
27 27
28 nand bad 28 nand bad
29 Print a list of all of the bad blocks in the current device. 29 Print a list of all of the bad blocks in the current device.
30 30
31 nand device 31 nand device
32 Print information about the current NAND device. 32 Print information about the current NAND device.
33 33
34 nand device num 34 nand device num
35 Make device `num' the current device and print information about it. 35 Make device `num' the current device and print information about it.
36 36
37 nand erase off|partition size 37 nand erase off|partition size
38 nand erase clean [off|partition size] 38 nand erase clean [off|partition size]
39 Erase `size' bytes starting at offset `off'. Alternatively partition 39 Erase `size' bytes starting at offset `off'. Alternatively partition
40 name can be specified, in this case size will be eventually limited 40 name can be specified, in this case size will be eventually limited
41 to not exceed partition size (this behaviour applies also to read 41 to not exceed partition size (this behaviour applies also to read
42 and write commands). Only complete erase blocks can be erased. 42 and write commands). Only complete erase blocks can be erased.
43 43
44 If `erase' is specified without an offset or size, the entire flash 44 If `erase' is specified without an offset or size, the entire flash
45 is erased. If `erase' is specified with partition but without an 45 is erased. If `erase' is specified with partition but without an
46 size, the entire partition is erased. 46 size, the entire partition is erased.
47 47
48 If `clean' is specified, a JFFS2-style clean marker is written to 48 If `clean' is specified, a JFFS2-style clean marker is written to
49 each block after it is erased. 49 each block after it is erased.
50 50
51 This command will not erase blocks that are marked bad. There is 51 This command will not erase blocks that are marked bad. There is
52 a debug option in cmd_nand.c to allow bad blocks to be erased. 52 a debug option in cmd_nand.c to allow bad blocks to be erased.
53 Please read the warning there before using it, as blocks marked 53 Please read the warning there before using it, as blocks marked
54 bad by the manufacturer must _NEVER_ be erased. 54 bad by the manufacturer must _NEVER_ be erased.
55 55
56 nand info 56 nand info
57 Print information about all of the NAND devices found. 57 Print information about all of the NAND devices found.
58 58
59 nand read addr ofs|partition size 59 nand read addr ofs|partition size
60 Read `size' bytes from `ofs' in NAND flash to `addr'. Blocks that 60 Read `size' bytes from `ofs' in NAND flash to `addr'. Blocks that
61 are marked bad are skipped. If a page cannot be read because an 61 are marked bad are skipped. If a page cannot be read because an
62 uncorrectable data error is found, the command stops with an error. 62 uncorrectable data error is found, the command stops with an error.
63 63
64 nand read.oob addr ofs|partition size 64 nand read.oob addr ofs|partition size
65 Read `size' bytes from the out-of-band data area corresponding to 65 Read `size' bytes from the out-of-band data area corresponding to
66 `ofs' in NAND flash to `addr'. This is limited to the 16 bytes of 66 `ofs' in NAND flash to `addr'. This is limited to the 16 bytes of
67 data for one 512-byte page or 2 256-byte pages. There is no check 67 data for one 512-byte page or 2 256-byte pages. There is no check
68 for bad blocks or ECC errors. 68 for bad blocks or ECC errors.
69 69
70 nand write addr ofs|partition size 70 nand write addr ofs|partition size
71 Write `size' bytes from `addr' to `ofs' in NAND flash. Blocks that 71 Write `size' bytes from `addr' to `ofs' in NAND flash. Blocks that
72 are marked bad are skipped. If a page cannot be read because an 72 are marked bad are skipped. If a page cannot be read because an
73 uncorrectable data error is found, the command stops with an error. 73 uncorrectable data error is found, the command stops with an error.
74 74
75 As JFFS2 skips blocks similarly, this allows writing a JFFS2 image, 75 As JFFS2 skips blocks similarly, this allows writing a JFFS2 image,
76 as long as the image is short enough to fit even after skipping the 76 as long as the image is short enough to fit even after skipping the
77 bad blocks. Compact images, such as those produced by mkfs.jffs2 77 bad blocks. Compact images, such as those produced by mkfs.jffs2
78 should work well, but loading an image copied from another flash is 78 should work well, but loading an image copied from another flash is
79 going to be trouble if there are any bad blocks. 79 going to be trouble if there are any bad blocks.
80 80
81 nand write.trimffs addr ofs|partition size
82 Enabled by the CONFIG_CMD_NAND_TRIMFFS macro. This command will write to
83 the NAND flash in a manner identical to the 'nand write' command
84 described above -- with the additional check that all pages at the end
85 of eraseblocks which contain only 0xff data will not be written to the
86 NAND flash. This behaviour is required when flashing UBI images
87 containing UBIFS volumes as per the UBI FAQ[1].
88
89 [1] http://www.linux-mtd.infradead.org/doc/ubi.html#L_flasher_algo
90
81 nand write.oob addr ofs|partition size 91 nand write.oob addr ofs|partition size
82 Write `size' bytes from `addr' to the out-of-band data area 92 Write `size' bytes from `addr' to the out-of-band data area
83 corresponding to `ofs' in NAND flash. This is limited to the 16 bytes 93 corresponding to `ofs' in NAND flash. This is limited to the 16 bytes
84 of data for one 512-byte page or 2 256-byte pages. There is no check 94 of data for one 512-byte page or 2 256-byte pages. There is no check
85 for bad blocks. 95 for bad blocks.
86 96
87 Configuration Options: 97 Configuration Options:
88 98
89 CONFIG_CMD_NAND 99 CONFIG_CMD_NAND
90 Enables NAND support and commmands. 100 Enables NAND support and commmands.
91 101
92 CONFIG_MTD_NAND_ECC_JFFS2 102 CONFIG_MTD_NAND_ECC_JFFS2
93 Define this if you want the Error Correction Code information in 103 Define this if you want the Error Correction Code information in
94 the out-of-band data to be formatted to match the JFFS2 file system. 104 the out-of-band data to be formatted to match the JFFS2 file system.
95 CONFIG_MTD_NAND_ECC_YAFFS would be another useful choice for 105 CONFIG_MTD_NAND_ECC_YAFFS would be another useful choice for
96 someone to implement. 106 someone to implement.
97 107
98 CONFIG_SYS_MAX_NAND_DEVICE 108 CONFIG_SYS_MAX_NAND_DEVICE
99 The maximum number of NAND devices you want to support. 109 The maximum number of NAND devices you want to support.
100 110
101 CONFIG_SYS_NAND_MAX_CHIPS 111 CONFIG_SYS_NAND_MAX_CHIPS
102 The maximum number of NAND chips per device to be supported. 112 The maximum number of NAND chips per device to be supported.
103 113
104 NOTE: 114 NOTE:
105 ===== 115 =====
106 116
107 The current NAND implementation is based on what is in recent 117 The current NAND implementation is based on what is in recent
108 Linux kernels. The old legacy implementation has been removed. 118 Linux kernels. The old legacy implementation has been removed.
109 119
110 If you have board code which used CONFIG_NAND_LEGACY, you'll need 120 If you have board code which used CONFIG_NAND_LEGACY, you'll need
111 to convert to the current NAND interface for it to continue to work. 121 to convert to the current NAND interface for it to continue to work.
112 122
113 The Disk On Chip driver is currently broken and has been for some time. 123 The Disk On Chip driver is currently broken and has been for some time.
114 There is a driver in drivers/mtd/nand, taken from Linux, that works with 124 There is a driver in drivers/mtd/nand, taken from Linux, that works with
115 the current NAND system but has not yet been adapted to the u-boot 125 the current NAND system but has not yet been adapted to the u-boot
116 environment. 126 environment.
117 127
118 Additional improvements to the NAND subsystem by Guido Classen, 10-10-2006 128 Additional improvements to the NAND subsystem by Guido Classen, 10-10-2006
119 129
120 JFFS2 related commands: 130 JFFS2 related commands:
121 131
122 implement "nand erase clean" and old "nand erase" 132 implement "nand erase clean" and old "nand erase"
123 using both the new code which is able to skip bad blocks 133 using both the new code which is able to skip bad blocks
124 "nand erase clean" additionally writes JFFS2-cleanmarkers in the oob. 134 "nand erase clean" additionally writes JFFS2-cleanmarkers in the oob.
125 135
126 Miscellaneous and testing commands: 136 Miscellaneous and testing commands:
127 "markbad [offset]" 137 "markbad [offset]"
128 create an artificial bad block (for testing bad block handling) 138 create an artificial bad block (for testing bad block handling)
129 139
130 "scrub [offset length]" 140 "scrub [offset length]"
131 like "erase" but don't skip bad block. Instead erase them. 141 like "erase" but don't skip bad block. Instead erase them.
132 DANGEROUS!!! Factory set bad blocks will be lost. Use only 142 DANGEROUS!!! Factory set bad blocks will be lost. Use only
133 to remove artificial bad blocks created with the "markbad" command. 143 to remove artificial bad blocks created with the "markbad" command.
134 144
135 145
136 NAND locking command (for chips with active LOCKPRE pin) 146 NAND locking command (for chips with active LOCKPRE pin)
137 147
138 "nand lock" 148 "nand lock"
139 set NAND chip to lock state (all pages locked) 149 set NAND chip to lock state (all pages locked)
140 150
141 "nand lock tight" 151 "nand lock tight"
142 set NAND chip to lock tight state (software can't change locking anymore) 152 set NAND chip to lock tight state (software can't change locking anymore)
143 153
144 "nand lock status" 154 "nand lock status"
145 displays current locking status of all pages 155 displays current locking status of all pages
146 156
147 "nand unlock [offset] [size]" 157 "nand unlock [offset] [size]"
148 unlock consecutive area (can be called multiple times for different areas) 158 unlock consecutive area (can be called multiple times for different areas)
149 159
150 160
151 I have tested the code with board containing 128MiB NAND large page chips 161 I have tested the code with board containing 128MiB NAND large page chips
152 and 32MiB small page chips. 162 and 32MiB small page chips.
153 163