NAND write data page refactoring.
[openocd.git] / src / flash / nand / core.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de> *
3 * Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de> *
4 * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
5 * *
6 * Partially based on drivers/mtd/nand_ids.c from Linux. *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "imp.h"
28
29 /* configured NAND devices and NAND Flash command handler */
30 struct nand_device *nand_devices = NULL;
31
32 void nand_device_add(struct nand_device *c)
33 {
34 if (nand_devices) {
35 struct nand_device *p = nand_devices;
36 while (p && p->next) p = p->next;
37 p->next = c;
38 } else
39 nand_devices = c;
40 }
41
42
43 /* Chip ID list
44 *
45 * Name, ID code, pagesize, chipsize in MegaByte, eraseblock size,
46 * options
47 *
48 * Pagesize; 0, 256, 512
49 * 0 get this information from the extended chip ID
50 * 256 256 Byte page size
51 * 512 512 Byte page size
52 */
53 static struct nand_info nand_flash_ids[] =
54 {
55 /* start "museum" IDs */
56 {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0},
57 {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0},
58 {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, 0},
59 {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, 0},
60 {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0},
61 {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, 0},
62 {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0},
63 {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0},
64 {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0},
65 {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0},
66
67 {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0},
68 {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0},
69 {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
70 {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
71 /* end "museum" IDs */
72
73 {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0},
74 {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0},
75 {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
76 {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
77
78 {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0},
79 {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0},
80 {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
81 {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
82
83 {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0},
84 {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0},
85 {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
86 {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
87
88 {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0},
89 {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0},
90 {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0},
91 {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
92 {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
93 {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
94 {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
95
96 {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
97
98 {"NAND 64MiB 1,8V 8-bit", 0xA2, 0, 64, 0, LP_OPTIONS},
99 {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, LP_OPTIONS},
100 {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, LP_OPTIONS16},
101 {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, LP_OPTIONS16},
102
103 {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, LP_OPTIONS},
104 {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, LP_OPTIONS},
105 {"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, LP_OPTIONS16},
106 {"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, LP_OPTIONS16},
107
108 {"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, LP_OPTIONS},
109 {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, LP_OPTIONS},
110 {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, LP_OPTIONS16},
111 {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, LP_OPTIONS16},
112
113 {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, LP_OPTIONS},
114 {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, LP_OPTIONS},
115 {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, LP_OPTIONS16},
116 {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, LP_OPTIONS16},
117
118 {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, LP_OPTIONS},
119 {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, LP_OPTIONS},
120 {"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, LP_OPTIONS16},
121 {"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, LP_OPTIONS16},
122
123 {"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, LP_OPTIONS},
124 {"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, LP_OPTIONS},
125 {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, LP_OPTIONS16},
126 {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, LP_OPTIONS16},
127
128 {NULL, 0, 0, 0, 0, 0 }
129 };
130
131 /* Manufacturer ID list
132 */
133 static struct nand_manufacturer nand_manuf_ids[] =
134 {
135 {0x0, "unknown"},
136 {NAND_MFR_TOSHIBA, "Toshiba"},
137 {NAND_MFR_SAMSUNG, "Samsung"},
138 {NAND_MFR_FUJITSU, "Fujitsu"},
139 {NAND_MFR_NATIONAL, "National"},
140 {NAND_MFR_RENESAS, "Renesas"},
141 {NAND_MFR_STMICRO, "ST Micro"},
142 {NAND_MFR_HYNIX, "Hynix"},
143 {NAND_MFR_MICRON, "Micron"},
144 {0x0, NULL},
145 };
146
147 /*
148 * Define default oob placement schemes for large and small page devices
149 */
150
151 #if 0
152 static struct nand_ecclayout nand_oob_8 = {
153 .eccbytes = 3,
154 .eccpos = {0, 1, 2},
155 .oobfree = {
156 {.offset = 3,
157 .length = 2},
158 {.offset = 6,
159 .length = 2}}
160 };
161 #endif
162
163 struct nand_device *get_nand_device_by_name(const char *name)
164 {
165 unsigned requested = get_flash_name_index(name);
166 unsigned found = 0;
167
168 struct nand_device *nand;
169 for (nand = nand_devices; NULL != nand; nand = nand->next)
170 {
171 if (strcmp(nand->name, name) == 0)
172 return nand;
173 if (!flash_driver_name_matches(nand->controller->name, name))
174 continue;
175 if (++found < requested)
176 continue;
177 return nand;
178 }
179 return NULL;
180 }
181
182 struct nand_device *get_nand_device_by_num(int num)
183 {
184 struct nand_device *p;
185 int i = 0;
186
187 for (p = nand_devices; p; p = p->next)
188 {
189 if (i++ == num)
190 {
191 return p;
192 }
193 }
194
195 return NULL;
196 }
197
198 COMMAND_HELPER(nand_command_get_device, unsigned name_index,
199 struct nand_device **nand)
200 {
201 const char *str = CMD_ARGV[name_index];
202 *nand = get_nand_device_by_name(str);
203 if (*nand)
204 return ERROR_OK;
205
206 unsigned num;
207 COMMAND_PARSE_NUMBER(uint, str, num);
208 *nand = get_nand_device_by_num(num);
209 if (!*nand) {
210 command_print(CMD_CTX, "NAND flash device '%s' not found", str);
211 return ERROR_INVALID_ARGUMENTS;
212 }
213 return ERROR_OK;
214 }
215
216 int nand_build_bbt(struct nand_device *nand, int first, int last)
217 {
218 uint32_t page = 0x0;
219 int i;
220 uint8_t oob[6];
221
222 if ((first < 0) || (first >= nand->num_blocks))
223 first = 0;
224
225 if ((last >= nand->num_blocks) || (last == -1))
226 last = nand->num_blocks - 1;
227
228 for (i = first; i < last; i++)
229 {
230 nand_read_page(nand, page, NULL, 0, oob, 6);
231
232 if (((nand->device->options & NAND_BUSWIDTH_16) && ((oob[0] & oob[1]) != 0xff))
233 || (((nand->page_size == 512) && (oob[5] != 0xff)) ||
234 ((nand->page_size == 2048) && (oob[0] != 0xff))))
235 {
236 LOG_WARNING("bad block: %i", i);
237 nand->blocks[i].is_bad = 1;
238 }
239 else
240 {
241 nand->blocks[i].is_bad = 0;
242 }
243
244 page += (nand->erase_size / nand->page_size);
245 }
246
247 return ERROR_OK;
248 }
249
250 int nand_read_status(struct nand_device *nand, uint8_t *status)
251 {
252 if (!nand->device)
253 return ERROR_NAND_DEVICE_NOT_PROBED;
254
255 /* Send read status command */
256 nand->controller->command(nand, NAND_CMD_STATUS);
257
258 alive_sleep(1);
259
260 /* read status */
261 if (nand->device->options & NAND_BUSWIDTH_16)
262 {
263 uint16_t data;
264 nand->controller->read_data(nand, &data);
265 *status = data & 0xff;
266 }
267 else
268 {
269 nand->controller->read_data(nand, status);
270 }
271
272 return ERROR_OK;
273 }
274
275 static int nand_poll_ready(struct nand_device *nand, int timeout)
276 {
277 uint8_t status;
278
279 nand->controller->command(nand, NAND_CMD_STATUS);
280 do {
281 if (nand->device->options & NAND_BUSWIDTH_16) {
282 uint16_t data;
283 nand->controller->read_data(nand, &data);
284 status = data & 0xff;
285 } else {
286 nand->controller->read_data(nand, &status);
287 }
288 if (status & NAND_STATUS_READY)
289 break;
290 alive_sleep(1);
291 } while (timeout--);
292
293 return (status & NAND_STATUS_READY) != 0;
294 }
295
296 int nand_probe(struct nand_device *nand)
297 {
298 uint8_t manufacturer_id, device_id;
299 uint8_t id_buff[6];
300 int retval;
301 int i;
302
303 /* clear device data */
304 nand->device = NULL;
305 nand->manufacturer = NULL;
306
307 /* clear device parameters */
308 nand->bus_width = 0;
309 nand->address_cycles = 0;
310 nand->page_size = 0;
311 nand->erase_size = 0;
312
313 /* initialize controller (device parameters are zero, use controller default) */
314 if ((retval = nand->controller->init(nand) != ERROR_OK))
315 {
316 switch (retval)
317 {
318 case ERROR_NAND_OPERATION_FAILED:
319 LOG_DEBUG("controller initialization failed");
320 return ERROR_NAND_OPERATION_FAILED;
321 case ERROR_NAND_OPERATION_NOT_SUPPORTED:
322 LOG_ERROR("BUG: controller reported that it doesn't support default parameters");
323 return ERROR_NAND_OPERATION_FAILED;
324 default:
325 LOG_ERROR("BUG: unknown controller initialization failure");
326 return ERROR_NAND_OPERATION_FAILED;
327 }
328 }
329
330 nand->controller->command(nand, NAND_CMD_RESET);
331 nand->controller->reset(nand);
332
333 nand->controller->command(nand, NAND_CMD_READID);
334 nand->controller->address(nand, 0x0);
335
336 if (nand->bus_width == 8)
337 {
338 nand->controller->read_data(nand, &manufacturer_id);
339 nand->controller->read_data(nand, &device_id);
340 }
341 else
342 {
343 uint16_t data_buf;
344 nand->controller->read_data(nand, &data_buf);
345 manufacturer_id = data_buf & 0xff;
346 nand->controller->read_data(nand, &data_buf);
347 device_id = data_buf & 0xff;
348 }
349
350 for (i = 0; nand_flash_ids[i].name; i++)
351 {
352 if (nand_flash_ids[i].id == device_id)
353 {
354 nand->device = &nand_flash_ids[i];
355 break;
356 }
357 }
358
359 for (i = 0; nand_manuf_ids[i].name; i++)
360 {
361 if (nand_manuf_ids[i].id == manufacturer_id)
362 {
363 nand->manufacturer = &nand_manuf_ids[i];
364 break;
365 }
366 }
367
368 if (!nand->manufacturer)
369 {
370 nand->manufacturer = &nand_manuf_ids[0];
371 nand->manufacturer->id = manufacturer_id;
372 }
373
374 if (!nand->device)
375 {
376 LOG_ERROR("unknown NAND flash device found, manufacturer id: 0x%2.2x device id: 0x%2.2x",
377 manufacturer_id, device_id);
378 return ERROR_NAND_OPERATION_FAILED;
379 }
380
381 LOG_DEBUG("found %s (%s)", nand->device->name, nand->manufacturer->name);
382
383 /* initialize device parameters */
384
385 /* bus width */
386 if (nand->device->options & NAND_BUSWIDTH_16)
387 nand->bus_width = 16;
388 else
389 nand->bus_width = 8;
390
391 /* Do we need extended device probe information? */
392 if (nand->device->page_size == 0 ||
393 nand->device->erase_size == 0)
394 {
395 if (nand->bus_width == 8)
396 {
397 nand->controller->read_data(nand, id_buff + 3);
398 nand->controller->read_data(nand, id_buff + 4);
399 nand->controller->read_data(nand, id_buff + 5);
400 }
401 else
402 {
403 uint16_t data_buf;
404
405 nand->controller->read_data(nand, &data_buf);
406 id_buff[3] = data_buf;
407
408 nand->controller->read_data(nand, &data_buf);
409 id_buff[4] = data_buf;
410
411 nand->controller->read_data(nand, &data_buf);
412 id_buff[5] = data_buf >> 8;
413 }
414 }
415
416 /* page size */
417 if (nand->device->page_size == 0)
418 {
419 nand->page_size = 1 << (10 + (id_buff[4] & 3));
420 }
421 else if (nand->device->page_size == 256)
422 {
423 LOG_ERROR("NAND flashes with 256 byte pagesize are not supported");
424 return ERROR_NAND_OPERATION_FAILED;
425 }
426 else
427 {
428 nand->page_size = nand->device->page_size;
429 }
430
431 /* number of address cycles */
432 if (nand->page_size <= 512)
433 {
434 /* small page devices */
435 if (nand->device->chip_size <= 32)
436 nand->address_cycles = 3;
437 else if (nand->device->chip_size <= 8*1024)
438 nand->address_cycles = 4;
439 else
440 {
441 LOG_ERROR("BUG: small page NAND device with more than 8 GiB encountered");
442 nand->address_cycles = 5;
443 }
444 }
445 else
446 {
447 /* large page devices */
448 if (nand->device->chip_size <= 128)
449 nand->address_cycles = 4;
450 else if (nand->device->chip_size <= 32*1024)
451 nand->address_cycles = 5;
452 else
453 {
454 LOG_ERROR("BUG: large page NAND device with more than 32 GiB encountered");
455 nand->address_cycles = 6;
456 }
457 }
458
459 /* erase size */
460 if (nand->device->erase_size == 0)
461 {
462 switch ((id_buff[4] >> 4) & 3) {
463 case 0:
464 nand->erase_size = 64 << 10;
465 break;
466 case 1:
467 nand->erase_size = 128 << 10;
468 break;
469 case 2:
470 nand->erase_size = 256 << 10;
471 break;
472 case 3:
473 nand->erase_size =512 << 10;
474 break;
475 }
476 }
477 else
478 {
479 nand->erase_size = nand->device->erase_size;
480 }
481
482 /* initialize controller, but leave parameters at the controllers default */
483 if ((retval = nand->controller->init(nand) != ERROR_OK))
484 {
485 switch (retval)
486 {
487 case ERROR_NAND_OPERATION_FAILED:
488 LOG_DEBUG("controller initialization failed");
489 return ERROR_NAND_OPERATION_FAILED;
490 case ERROR_NAND_OPERATION_NOT_SUPPORTED:
491 LOG_ERROR("controller doesn't support requested parameters (buswidth: %i, address cycles: %i, page size: %i)",
492 nand->bus_width, nand->address_cycles, nand->page_size);
493 return ERROR_NAND_OPERATION_FAILED;
494 default:
495 LOG_ERROR("BUG: unknown controller initialization failure");
496 return ERROR_NAND_OPERATION_FAILED;
497 }
498 }
499
500 nand->num_blocks = (nand->device->chip_size * 1024) / (nand->erase_size / 1024);
501 nand->blocks = malloc(sizeof(struct nand_block) * nand->num_blocks);
502
503 for (i = 0; i < nand->num_blocks; i++)
504 {
505 nand->blocks[i].size = nand->erase_size;
506 nand->blocks[i].offset = i * nand->erase_size;
507 nand->blocks[i].is_erased = -1;
508 nand->blocks[i].is_bad = -1;
509 }
510
511 return ERROR_OK;
512 }
513
514 int nand_erase(struct nand_device *nand, int first_block, int last_block)
515 {
516 int i;
517 uint32_t page;
518 uint8_t status;
519 int retval;
520
521 if (!nand->device)
522 return ERROR_NAND_DEVICE_NOT_PROBED;
523
524 if ((first_block < 0) || (last_block > nand->num_blocks))
525 return ERROR_INVALID_ARGUMENTS;
526
527 /* make sure we know if a block is bad before erasing it */
528 for (i = first_block; i <= last_block; i++)
529 {
530 if (nand->blocks[i].is_bad == -1)
531 {
532 nand_build_bbt(nand, i, last_block);
533 break;
534 }
535 }
536
537 for (i = first_block; i <= last_block; i++)
538 {
539 /* Send erase setup command */
540 nand->controller->command(nand, NAND_CMD_ERASE1);
541
542 page = i * (nand->erase_size / nand->page_size);
543
544 /* Send page address */
545 if (nand->page_size <= 512)
546 {
547 /* row */
548 nand->controller->address(nand, page & 0xff);
549 nand->controller->address(nand, (page >> 8) & 0xff);
550
551 /* 3rd cycle only on devices with more than 32 MiB */
552 if (nand->address_cycles >= 4)
553 nand->controller->address(nand, (page >> 16) & 0xff);
554
555 /* 4th cycle only on devices with more than 8 GiB */
556 if (nand->address_cycles >= 5)
557 nand->controller->address(nand, (page >> 24) & 0xff);
558 }
559 else
560 {
561 /* row */
562 nand->controller->address(nand, page & 0xff);
563 nand->controller->address(nand, (page >> 8) & 0xff);
564
565 /* 3rd cycle only on devices with more than 128 MiB */
566 if (nand->address_cycles >= 5)
567 nand->controller->address(nand, (page >> 16) & 0xff);
568 }
569
570 /* Send erase confirm command */
571 nand->controller->command(nand, NAND_CMD_ERASE2);
572
573 retval = nand->controller->nand_ready ?
574 nand->controller->nand_ready(nand, 1000) :
575 nand_poll_ready(nand, 1000);
576 if (!retval) {
577 LOG_ERROR("timeout waiting for NAND flash block erase to complete");
578 return ERROR_NAND_OPERATION_TIMEOUT;
579 }
580
581 if ((retval = nand_read_status(nand, &status)) != ERROR_OK)
582 {
583 LOG_ERROR("couldn't read status");
584 return ERROR_NAND_OPERATION_FAILED;
585 }
586
587 if (status & 0x1)
588 {
589 LOG_ERROR("didn't erase %sblock %d; status: 0x%2.2x",
590 (nand->blocks[i].is_bad == 1)
591 ? "bad " : "",
592 i, status);
593 /* continue; other blocks might still be erasable */
594 }
595
596 nand->blocks[i].is_erased = 1;
597 }
598
599 return ERROR_OK;
600 }
601
602 #if 0
603 static int nand_read_plain(struct nand_device *nand, uint32_t address, uint8_t *data, uint32_t data_size)
604 {
605 uint8_t *page;
606
607 if (!nand->device)
608 return ERROR_NAND_DEVICE_NOT_PROBED;
609
610 if (address % nand->page_size)
611 {
612 LOG_ERROR("reads need to be page aligned");
613 return ERROR_NAND_OPERATION_FAILED;
614 }
615
616 page = malloc(nand->page_size);
617
618 while (data_size > 0)
619 {
620 uint32_t thisrun_size = (data_size > nand->page_size) ? nand->page_size : data_size;
621 uint32_t page_address;
622
623
624 page_address = address / nand->page_size;
625
626 nand_read_page(nand, page_address, page, nand->page_size, NULL, 0);
627
628 memcpy(data, page, thisrun_size);
629
630 address += thisrun_size;
631 data += thisrun_size;
632 data_size -= thisrun_size;
633 }
634
635 free(page);
636
637 return ERROR_OK;
638 }
639
640 static int nand_write_plain(struct nand_device *nand, uint32_t address, uint8_t *data, uint32_t data_size)
641 {
642 uint8_t *page;
643
644 if (!nand->device)
645 return ERROR_NAND_DEVICE_NOT_PROBED;
646
647 if (address % nand->page_size)
648 {
649 LOG_ERROR("writes need to be page aligned");
650 return ERROR_NAND_OPERATION_FAILED;
651 }
652
653 page = malloc(nand->page_size);
654
655 while (data_size > 0)
656 {
657 uint32_t thisrun_size = (data_size > nand->page_size) ? nand->page_size : data_size;
658 uint32_t page_address;
659
660 memset(page, 0xff, nand->page_size);
661 memcpy(page, data, thisrun_size);
662
663 page_address = address / nand->page_size;
664
665 nand_write_page(nand, page_address, page, nand->page_size, NULL, 0);
666
667 address += thisrun_size;
668 data += thisrun_size;
669 data_size -= thisrun_size;
670 }
671
672 free(page);
673
674 return ERROR_OK;
675 }
676 #endif
677
678 int nand_write_page(struct nand_device *nand, uint32_t page,
679 uint8_t *data, uint32_t data_size,
680 uint8_t *oob, uint32_t oob_size)
681 {
682 uint32_t block;
683
684 if (!nand->device)
685 return ERROR_NAND_DEVICE_NOT_PROBED;
686
687 block = page / (nand->erase_size / nand->page_size);
688 if (nand->blocks[block].is_erased == 1)
689 nand->blocks[block].is_erased = 0;
690
691 if (nand->use_raw || nand->controller->write_page == NULL)
692 return nand_write_page_raw(nand, page, data, data_size, oob, oob_size);
693 else
694 return nand->controller->write_page(nand, page, data, data_size, oob, oob_size);
695 }
696
697 int nand_read_page(struct nand_device *nand, uint32_t page,
698 uint8_t *data, uint32_t data_size,
699 uint8_t *oob, uint32_t oob_size)
700 {
701 if (!nand->device)
702 return ERROR_NAND_DEVICE_NOT_PROBED;
703
704 if (nand->use_raw || nand->controller->read_page == NULL)
705 return nand_read_page_raw(nand, page, data, data_size, oob, oob_size);
706 else
707 return nand->controller->read_page(nand, page, data, data_size, oob, oob_size);
708 }
709
710 int nand_page_command(struct nand_device *nand, uint32_t page,
711 uint8_t cmd, bool oob_only)
712 {
713 if (!nand->device)
714 return ERROR_NAND_DEVICE_NOT_PROBED;
715
716 if (oob_only && NAND_CMD_READ0 == cmd && nand->page_size <= 512)
717 cmd = NAND_CMD_READOOB;
718
719 nand->controller->command(nand, cmd);
720
721 if (nand->page_size <= 512) {
722 /* small page device */
723
724 /* column (always 0, we start at the beginning of a page/OOB area) */
725 nand->controller->address(nand, 0x0);
726
727 /* row */
728 nand->controller->address(nand, page & 0xff);
729 nand->controller->address(nand, (page >> 8) & 0xff);
730
731 /* 4th cycle only on devices with more than 32 MiB */
732 if (nand->address_cycles >= 4)
733 nand->controller->address(nand, (page >> 16) & 0xff);
734
735 /* 5th cycle only on devices with more than 8 GiB */
736 if (nand->address_cycles >= 5)
737 nand->controller->address(nand, (page >> 24) & 0xff);
738 } else {
739 /* large page device */
740
741 /* column (0 when we start at the beginning of a page,
742 * or 2048 for the beginning of OOB area)
743 */
744 nand->controller->address(nand, 0x0);
745 if (oob_only)
746 nand->controller->address(nand, 0x8);
747 else
748 nand->controller->address(nand, 0x0);
749
750 /* row */
751 nand->controller->address(nand, page & 0xff);
752 nand->controller->address(nand, (page >> 8) & 0xff);
753
754 /* 5th cycle only on devices with more than 128 MiB */
755 if (nand->address_cycles >= 5)
756 nand->controller->address(nand, (page >> 16) & 0xff);
757
758 /* large page devices need a start command if reading */
759 if (NAND_CMD_READ0 == cmd)
760 nand->controller->command(nand, NAND_CMD_READSTART);
761 }
762
763 if (nand->controller->nand_ready) {
764 if (!nand->controller->nand_ready(nand, 100))
765 return ERROR_NAND_OPERATION_TIMEOUT;
766 } else {
767 alive_sleep(1);
768 }
769
770 return ERROR_OK;
771 }
772
773 int nand_read_data_page(struct nand_device *nand, uint8_t *data, uint32_t size)
774 {
775 int retval = ERROR_NAND_NO_BUFFER;
776
777 if (nand->controller->read_block_data != NULL)
778 retval = (nand->controller->read_block_data)(nand, data, size);
779
780 if (ERROR_NAND_NO_BUFFER == retval) {
781 uint32_t i;
782 int incr = (nand->device->options & NAND_BUSWIDTH_16) ? 2 : 1;
783
784 retval = ERROR_OK;
785 for (i = 0; retval == ERROR_OK && i < size; i += incr) {
786 retval = nand->controller->read_data(nand, data);
787 data += incr;
788 }
789 }
790
791 return retval;
792 }
793
794 int nand_read_page_raw(struct nand_device *nand, uint32_t page,
795 uint8_t *data, uint32_t data_size,
796 uint8_t *oob, uint32_t oob_size)
797 {
798 int retval;
799
800 retval = nand_page_command(nand, page, NAND_CMD_READ0, !data);
801 if (ERROR_OK != retval)
802 return retval;
803
804 if (data)
805 nand_read_data_page(nand, data, data_size);
806
807 if (oob)
808 nand_read_data_page(nand, oob, oob_size);
809
810 return ERROR_OK;
811 }
812
813 int nand_write_data_page(struct nand_device *nand, uint8_t *data, uint32_t size)
814 {
815 int retval = ERROR_NAND_NO_BUFFER;
816
817 if (nand->controller->write_block_data != NULL)
818 retval = (nand->controller->write_block_data)(nand, data, size);
819
820 if (ERROR_NAND_NO_BUFFER == retval) {
821 bool is16bit = nand->device->options & NAND_BUSWIDTH_16;
822 uint32_t incr = is16bit ? 2 : 1;
823 uint16_t write_data;
824 uint32_t i;
825
826 for (i = 0; i < size; i += incr) {
827 if (is16bit)
828 write_data = le_to_h_u16(data);
829 else
830 write_data = *data;
831
832 retval = nand->controller->write_data(nand, write_data);
833 if (ERROR_OK != retval)
834 break;
835
836 data += incr;
837 }
838 }
839
840 return retval;
841 }
842
843 int nand_write_finish(struct nand_device *nand)
844 {
845 int retval;
846 uint8_t status;
847
848 nand->controller->command(nand, NAND_CMD_PAGEPROG);
849
850 retval = nand->controller->nand_ready ?
851 nand->controller->nand_ready(nand, 100) :
852 nand_poll_ready(nand, 100);
853 if (!retval)
854 return ERROR_NAND_OPERATION_TIMEOUT;
855
856 retval = nand_read_status(nand, &status);
857 if (ERROR_OK != retval) {
858 LOG_ERROR("couldn't read status");
859 return ERROR_NAND_OPERATION_FAILED;
860 }
861
862 if (status & NAND_STATUS_FAIL) {
863 LOG_ERROR("write operation didn't pass, status: 0x%2.2x",
864 status);
865 return ERROR_NAND_OPERATION_FAILED;
866 }
867
868 return ERROR_OK;
869 }
870
871 int nand_write_page_raw(struct nand_device *nand, uint32_t page,
872 uint8_t *data, uint32_t data_size,
873 uint8_t *oob, uint32_t oob_size)
874 {
875 int retval;
876
877 retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data);
878 if (ERROR_OK != retval)
879 return retval;
880
881 if (data) {
882 retval = nand_write_data_page(nand, data, data_size);
883 if (ERROR_OK != retval) {
884 LOG_ERROR("Unable to write data to NAND device");
885 return retval;
886 }
887 }
888
889 if (oob) {
890 retval = nand_write_data_page(nand, oob, oob_size);
891 if (ERROR_OK != retval) {
892 LOG_ERROR("Unable to write OOB data to NAND device");
893 return retval;
894 }
895 }
896
897 return nand_write_finish(nand);
898 }
899

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)