flash/nor: use command_print() in command "flash banks"
[openocd.git] / src / flash / nand / mx3.c
1
2 /***************************************************************************
3 * Copyright (C) 2009 by Alexei Babich *
4 * Rezonans plc., Chelyabinsk, Russia *
5 * impatt@mail.ru *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 ***************************************************************************/
20
21 /*
22 * Freescale iMX3* OpenOCD NAND Flash controller support.
23 *
24 * Many thanks to Ben Dooks for writing s3c24xx driver.
25 */
26
27 /*
28 driver tested with STMicro NAND512W3A @imx31
29 tested "nand probe #", "nand erase # 0 #", "nand dump # file 0 #", "nand write # file 0"
30 get_next_halfword_from_sram_buffer() not tested
31 */
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include "imp.h"
37 #include "mx3.h"
38 #include <target/target.h>
39
40 static const char target_not_halted_err_msg[] =
41 "target must be halted to use mx3 NAND flash controller";
42 static const char data_block_size_err_msg[] =
43 "minimal granularity is one half-word, %" PRId32 " is incorrect";
44 static const char sram_buffer_bounds_err_msg[] =
45 "trying to access out of SRAM buffer bound (addr=0x%" PRIx32 ")";
46 static const char get_status_register_err_msg[] = "can't get NAND status";
47 static uint32_t in_sram_address;
48 static unsigned char sign_of_sequental_byte_read;
49
50 static int test_iomux_settings(struct target *target, uint32_t value,
51 uint32_t mask, const char *text);
52 static int initialize_nf_controller(struct nand_device *nand);
53 static int get_next_byte_from_sram_buffer(struct target *target, uint8_t *value);
54 static int get_next_halfword_from_sram_buffer(struct target *target,
55 uint16_t *value);
56 static int poll_for_complete_op(struct target *target, const char *text);
57 static int validate_target_state(struct nand_device *nand);
58 static int do_data_output(struct nand_device *nand);
59
60 static int imx31_command(struct nand_device *nand, uint8_t command);
61 static int imx31_address(struct nand_device *nand, uint8_t address);
62
63 NAND_DEVICE_COMMAND_HANDLER(imx31_nand_device_command)
64 {
65 struct mx3_nf_controller *mx3_nf_info;
66 mx3_nf_info = malloc(sizeof(struct mx3_nf_controller));
67 if (mx3_nf_info == NULL) {
68 LOG_ERROR("no memory for nand controller");
69 return ERROR_FAIL;
70 }
71
72 nand->controller_priv = mx3_nf_info;
73
74 if (CMD_ARGC < 3)
75 return ERROR_COMMAND_SYNTAX_ERROR;
76 /*
77 * check hwecc requirements
78 */
79 {
80 int hwecc_needed;
81 hwecc_needed = strcmp(CMD_ARGV[2], "hwecc");
82 if (hwecc_needed == 0)
83 mx3_nf_info->flags.hw_ecc_enabled = 1;
84 else
85 mx3_nf_info->flags.hw_ecc_enabled = 0;
86 }
87
88 mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE;
89 mx3_nf_info->fin = MX3_NF_FIN_NONE;
90 mx3_nf_info->flags.target_little_endian =
91 (nand->target->endianness == TARGET_LITTLE_ENDIAN);
92
93 return ERROR_OK;
94 }
95
96 static int imx31_init(struct nand_device *nand)
97 {
98 struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
99 struct target *target = nand->target;
100
101 {
102 /*
103 * validate target state
104 */
105 int validate_target_result;
106 validate_target_result = validate_target_state(nand);
107 if (validate_target_result != ERROR_OK)
108 return validate_target_result;
109 }
110
111 {
112 uint16_t buffsize_register_content;
113 target_read_u16(target, MX3_NF_BUFSIZ, &buffsize_register_content);
114 mx3_nf_info->flags.one_kb_sram = !(buffsize_register_content & 0x000f);
115 }
116
117 {
118 uint32_t pcsr_register_content;
119 target_read_u32(target, MX3_PCSR, &pcsr_register_content);
120 if (!nand->bus_width) {
121 nand->bus_width = (pcsr_register_content & 0x80000000) ? 16 : 8;
122 } else {
123 pcsr_register_content |= ((nand->bus_width == 16) ? 0x80000000 : 0x00000000);
124 target_write_u32(target, MX3_PCSR, pcsr_register_content);
125 }
126
127 if (!nand->page_size) {
128 nand->page_size = (pcsr_register_content & 0x40000000) ? 2048 : 512;
129 } else {
130 pcsr_register_content |= ((nand->page_size == 2048) ? 0x40000000 : 0x00000000);
131 target_write_u32(target, MX3_PCSR, pcsr_register_content);
132 }
133 if (mx3_nf_info->flags.one_kb_sram && (nand->page_size == 2048)) {
134 LOG_ERROR("NAND controller have only 1 kb SRAM, "
135 "so pagesize 2048 is incompatible with it");
136 }
137 }
138
139 {
140 uint32_t cgr_register_content;
141 target_read_u32(target, MX3_CCM_CGR2, &cgr_register_content);
142 if (!(cgr_register_content & 0x00000300)) {
143 LOG_ERROR("clock gating to EMI disabled");
144 return ERROR_FAIL;
145 }
146 }
147
148 {
149 uint32_t gpr_register_content;
150 target_read_u32(target, MX3_GPR, &gpr_register_content);
151 if (gpr_register_content & 0x00000060) {
152 LOG_ERROR("pins mode overrided by GPR");
153 return ERROR_FAIL;
154 }
155 }
156
157 {
158 /*
159 * testing IOMUX settings; must be in "functional-mode output and
160 * functional-mode input" mode
161 */
162 int test_iomux;
163 test_iomux = ERROR_OK;
164 test_iomux |= test_iomux_settings(target, 0x43fac0c0, 0x7f7f7f00, "d0,d1,d2");
165 test_iomux |= test_iomux_settings(target, 0x43fac0c4, 0x7f7f7f7f, "d3,d4,d5,d6");
166 test_iomux |= test_iomux_settings(target, 0x43fac0c8, 0x0000007f, "d7");
167 if (nand->bus_width == 16) {
168 test_iomux |= test_iomux_settings(target, 0x43fac0c8, 0x7f7f7f00, "d8,d9,d10");
169 test_iomux |= test_iomux_settings(target, 0x43fac0cc, 0x7f7f7f7f, "d11,d12,d13,d14");
170 test_iomux |= test_iomux_settings(target, 0x43fac0d0, 0x0000007f, "d15");
171 }
172 test_iomux |= test_iomux_settings(target, 0x43fac0d0, 0x7f7f7f00, "nfwp,nfce,nfrb");
173 test_iomux |= test_iomux_settings(target, 0x43fac0d4, 0x7f7f7f7f,
174 "nfwe,nfre,nfale,nfcle");
175 if (test_iomux != ERROR_OK)
176 return ERROR_FAIL;
177 }
178
179 initialize_nf_controller(nand);
180
181 {
182 int retval;
183 uint16_t nand_status_content;
184 retval = ERROR_OK;
185 retval |= imx31_command(nand, NAND_CMD_STATUS);
186 retval |= imx31_address(nand, 0x00);
187 retval |= do_data_output(nand);
188 if (retval != ERROR_OK) {
189 LOG_ERROR(get_status_register_err_msg);
190 return ERROR_FAIL;
191 }
192 target_read_u16(target, MX3_NF_MAIN_BUFFER0, &nand_status_content);
193 if (!(nand_status_content & 0x0080)) {
194 /*
195 * is host-big-endian correctly ??
196 */
197 LOG_INFO("NAND read-only");
198 mx3_nf_info->flags.nand_readonly = 1;
199 } else
200 mx3_nf_info->flags.nand_readonly = 0;
201 }
202 return ERROR_OK;
203 }
204
205 static int imx31_read_data(struct nand_device *nand, void *data)
206 {
207 struct target *target = nand->target;
208 {
209 /*
210 * validate target state
211 */
212 int validate_target_result;
213 validate_target_result = validate_target_state(nand);
214 if (validate_target_result != ERROR_OK)
215 return validate_target_result;
216 }
217
218 {
219 /*
220 * get data from nand chip
221 */
222 int try_data_output_from_nand_chip;
223 try_data_output_from_nand_chip = do_data_output(nand);
224 if (try_data_output_from_nand_chip != ERROR_OK)
225 return try_data_output_from_nand_chip;
226 }
227
228 if (nand->bus_width == 16)
229 get_next_halfword_from_sram_buffer(target, data);
230 else
231 get_next_byte_from_sram_buffer(target, data);
232
233 return ERROR_OK;
234 }
235
236 static int imx31_write_data(struct nand_device *nand, uint16_t data)
237 {
238 LOG_ERROR("write_data() not implemented");
239 return ERROR_NAND_OPERATION_FAILED;
240 }
241
242 static int imx31_reset(struct nand_device *nand)
243 {
244 /*
245 * validate target state
246 */
247 int validate_target_result;
248 validate_target_result = validate_target_state(nand);
249 if (validate_target_result != ERROR_OK)
250 return validate_target_result;
251 initialize_nf_controller(nand);
252 return ERROR_OK;
253 }
254
255 static int imx31_command(struct nand_device *nand, uint8_t command)
256 {
257 struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
258 struct target *target = nand->target;
259 {
260 /*
261 * validate target state
262 */
263 int validate_target_result;
264 validate_target_result = validate_target_state(nand);
265 if (validate_target_result != ERROR_OK)
266 return validate_target_result;
267 }
268
269 switch (command) {
270 case NAND_CMD_READOOB:
271 command = NAND_CMD_READ0;
272 in_sram_address = MX3_NF_SPARE_BUFFER0; /* set read point for
273 * data_read() and
274 * read_block_data() to
275 * spare area in SRAM
276 * buffer */
277 break;
278 case NAND_CMD_READ1:
279 command = NAND_CMD_READ0;
280 /*
281 * offset == one half of page size
282 */
283 in_sram_address = MX3_NF_MAIN_BUFFER0 + (nand->page_size >> 1);
284 break;
285 default:
286 in_sram_address = MX3_NF_MAIN_BUFFER0;
287 }
288
289 target_write_u16(target, MX3_NF_FCMD, command);
290 /*
291 * start command input operation (set MX3_NF_BIT_OP_DONE==0)
292 */
293 target_write_u16(target, MX3_NF_CFG2, MX3_NF_BIT_OP_FCI);
294 {
295 int poll_result;
296 poll_result = poll_for_complete_op(target, "command");
297 if (poll_result != ERROR_OK)
298 return poll_result;
299 }
300 /*
301 * reset cursor to begin of the buffer
302 */
303 sign_of_sequental_byte_read = 0;
304 switch (command) {
305 case NAND_CMD_READID:
306 mx3_nf_info->optype = MX3_NF_DATAOUT_NANDID;
307 mx3_nf_info->fin = MX3_NF_FIN_DATAOUT;
308 break;
309 case NAND_CMD_STATUS:
310 mx3_nf_info->optype = MX3_NF_DATAOUT_NANDSTATUS;
311 mx3_nf_info->fin = MX3_NF_FIN_DATAOUT;
312 break;
313 case NAND_CMD_READ0:
314 mx3_nf_info->fin = MX3_NF_FIN_DATAOUT;
315 mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE;
316 break;
317 default:
318 mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE;
319 }
320 return ERROR_OK;
321 }
322
323 static int imx31_address(struct nand_device *nand, uint8_t address)
324 {
325 struct target *target = nand->target;
326 {
327 /*
328 * validate target state
329 */
330 int validate_target_result;
331 validate_target_result = validate_target_state(nand);
332 if (validate_target_result != ERROR_OK)
333 return validate_target_result;
334 }
335
336 target_write_u16(target, MX3_NF_FADDR, address);
337 /*
338 * start address input operation (set MX3_NF_BIT_OP_DONE==0)
339 */
340 target_write_u16(target, MX3_NF_CFG2, MX3_NF_BIT_OP_FAI);
341 {
342 int poll_result;
343 poll_result = poll_for_complete_op(target, "address");
344 if (poll_result != ERROR_OK)
345 return poll_result;
346 }
347 return ERROR_OK;
348 }
349
350 static int imx31_nand_ready(struct nand_device *nand, int tout)
351 {
352 uint16_t poll_complete_status;
353 struct target *target = nand->target;
354
355 {
356 /*
357 * validate target state
358 */
359 int validate_target_result;
360 validate_target_result = validate_target_state(nand);
361 if (validate_target_result != ERROR_OK)
362 return validate_target_result;
363 }
364
365 do {
366 target_read_u16(target, MX3_NF_CFG2, &poll_complete_status);
367 if (poll_complete_status & MX3_NF_BIT_OP_DONE)
368 return tout;
369 alive_sleep(1);
370 } while (tout-- > 0);
371 return tout;
372 }
373
374 static int imx31_write_page(struct nand_device *nand, uint32_t page,
375 uint8_t *data, uint32_t data_size, uint8_t *oob,
376 uint32_t oob_size)
377 {
378 struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
379 struct target *target = nand->target;
380
381 if (data_size % 2) {
382 LOG_ERROR(data_block_size_err_msg, data_size);
383 return ERROR_NAND_OPERATION_FAILED;
384 }
385 if (oob_size % 2) {
386 LOG_ERROR(data_block_size_err_msg, oob_size);
387 return ERROR_NAND_OPERATION_FAILED;
388 }
389 if (!data) {
390 LOG_ERROR("nothing to program");
391 return ERROR_NAND_OPERATION_FAILED;
392 }
393 {
394 /*
395 * validate target state
396 */
397 int retval;
398 retval = validate_target_state(nand);
399 if (retval != ERROR_OK)
400 return retval;
401 }
402 {
403 int retval = ERROR_OK;
404 retval |= imx31_command(nand, NAND_CMD_SEQIN);
405 retval |= imx31_address(nand, 0x00);
406 retval |= imx31_address(nand, page & 0xff);
407 retval |= imx31_address(nand, (page >> 8) & 0xff);
408 if (nand->address_cycles >= 4) {
409 retval |= imx31_address(nand, (page >> 16) & 0xff);
410 if (nand->address_cycles >= 5)
411 retval |= imx31_address(nand, (page >> 24) & 0xff);
412 }
413 target_write_buffer(target, MX3_NF_MAIN_BUFFER0, data_size, data);
414 if (oob) {
415 if (mx3_nf_info->flags.hw_ecc_enabled) {
416 /*
417 * part of spare block will be overrided by hardware
418 * ECC generator
419 */
420 LOG_DEBUG("part of spare block will be overrided by hardware ECC generator");
421 }
422 target_write_buffer(target, MX3_NF_SPARE_BUFFER0, oob_size, oob);
423 }
424 /*
425 * start data input operation (set MX3_NF_BIT_OP_DONE==0)
426 */
427 target_write_u16(target, MX3_NF_CFG2, MX3_NF_BIT_OP_FDI);
428 {
429 int poll_result;
430 poll_result = poll_for_complete_op(target, "data input");
431 if (poll_result != ERROR_OK)
432 return poll_result;
433 }
434 retval |= imx31_command(nand, NAND_CMD_PAGEPROG);
435 if (retval != ERROR_OK)
436 return retval;
437
438 /*
439 * check status register
440 */
441 {
442 uint16_t nand_status_content;
443 retval = ERROR_OK;
444 retval |= imx31_command(nand, NAND_CMD_STATUS);
445 retval |= imx31_address(nand, 0x00);
446 retval |= do_data_output(nand);
447 if (retval != ERROR_OK) {
448 LOG_ERROR(get_status_register_err_msg);
449 return retval;
450 }
451 target_read_u16(target, MX3_NF_MAIN_BUFFER0, &nand_status_content);
452 if (nand_status_content & 0x0001) {
453 /*
454 * is host-big-endian correctly ??
455 */
456 return ERROR_NAND_OPERATION_FAILED;
457 }
458 }
459 }
460 return ERROR_OK;
461 }
462
463 static int imx31_read_page(struct nand_device *nand, uint32_t page,
464 uint8_t *data, uint32_t data_size, uint8_t *oob,
465 uint32_t oob_size)
466 {
467 struct target *target = nand->target;
468
469 if (data_size % 2) {
470 LOG_ERROR(data_block_size_err_msg, data_size);
471 return ERROR_NAND_OPERATION_FAILED;
472 }
473 if (oob_size % 2) {
474 LOG_ERROR(data_block_size_err_msg, oob_size);
475 return ERROR_NAND_OPERATION_FAILED;
476 }
477
478 {
479 /*
480 * validate target state
481 */
482 int retval;
483 retval = validate_target_state(nand);
484 if (retval != ERROR_OK)
485 return retval;
486 }
487 {
488 int retval = ERROR_OK;
489 retval |= imx31_command(nand, NAND_CMD_READ0);
490 retval |= imx31_address(nand, 0x00);
491 retval |= imx31_address(nand, page & 0xff);
492 retval |= imx31_address(nand, (page >> 8) & 0xff);
493 if (nand->address_cycles >= 4) {
494 retval |= imx31_address(nand, (page >> 16) & 0xff);
495 if (nand->address_cycles >= 5) {
496 retval |= imx31_address(nand, (page >> 24) & 0xff);
497 retval |= imx31_command(nand, NAND_CMD_READSTART);
498 }
499 }
500 retval |= do_data_output(nand);
501 if (retval != ERROR_OK)
502 return retval;
503
504 if (data) {
505 target_read_buffer(target, MX3_NF_MAIN_BUFFER0, data_size,
506 data);
507 }
508 if (oob) {
509 target_read_buffer(target, MX3_NF_SPARE_BUFFER0, oob_size,
510 oob);
511 }
512 }
513 return ERROR_OK;
514 }
515
516 static int test_iomux_settings(struct target *target, uint32_t address,
517 uint32_t mask, const char *text)
518 {
519 uint32_t register_content;
520 target_read_u32(target, address, &register_content);
521 if ((register_content & mask) != (0x12121212 & mask)) {
522 LOG_ERROR("IOMUX for {%s} is bad", text);
523 return ERROR_FAIL;
524 }
525 return ERROR_OK;
526 }
527
528 static int initialize_nf_controller(struct nand_device *nand)
529 {
530 struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
531 struct target *target = nand->target;
532 /*
533 * resets NAND flash controller in zero time ? I dont know.
534 */
535 target_write_u16(target, MX3_NF_CFG1, MX3_NF_BIT_RESET_EN);
536 {
537 uint16_t work_mode;
538 work_mode = MX3_NF_BIT_INT_DIS; /* disable interrupt */
539 if (target->endianness == TARGET_BIG_ENDIAN)
540 work_mode |= MX3_NF_BIT_BE_EN;
541 if (mx3_nf_info->flags.hw_ecc_enabled)
542 work_mode |= MX3_NF_BIT_ECC_EN;
543 target_write_u16(target, MX3_NF_CFG1, work_mode);
544 }
545 /*
546 * unlock SRAM buffer for write; 2 mean "Unlock", other values means "Lock"
547 */
548 target_write_u16(target, MX3_NF_BUFCFG, 2);
549 {
550 uint16_t temp;
551 target_read_u16(target, MX3_NF_FWP, &temp);
552 if ((temp & 0x0007) == 1) {
553 LOG_ERROR("NAND flash is tight-locked, reset needed");
554 return ERROR_FAIL;
555 }
556
557 }
558 /*
559 * unlock NAND flash for write
560 */
561 target_write_u16(target, MX3_NF_FWP, 4);
562 target_write_u16(target, MX3_NF_LOCKSTART, 0x0000);
563 target_write_u16(target, MX3_NF_LOCKEND, 0xFFFF);
564 /*
565 * 0x0000 means that first SRAM buffer @0xB800_0000 will be used
566 */
567 target_write_u16(target, MX3_NF_BUFADDR, 0x0000);
568 /*
569 * address of SRAM buffer
570 */
571 in_sram_address = MX3_NF_MAIN_BUFFER0;
572 sign_of_sequental_byte_read = 0;
573 return ERROR_OK;
574 }
575
576 static int get_next_byte_from_sram_buffer(struct target *target, uint8_t *value)
577 {
578 static uint8_t even_byte;
579 /*
580 * host-big_endian ??
581 */
582 if (sign_of_sequental_byte_read == 0)
583 even_byte = 0;
584 if (in_sram_address > MX3_NF_LAST_BUFFER_ADDR) {
585 LOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address);
586 *value = 0;
587 sign_of_sequental_byte_read = 0;
588 even_byte = 0;
589 return ERROR_NAND_OPERATION_FAILED;
590 } else {
591 uint16_t temp;
592 target_read_u16(target, in_sram_address, &temp);
593 if (even_byte) {
594 *value = temp >> 8;
595 even_byte = 0;
596 in_sram_address += 2;
597 } else {
598 *value = temp & 0xff;
599 even_byte = 1;
600 }
601 }
602 sign_of_sequental_byte_read = 1;
603 return ERROR_OK;
604 }
605
606 static int get_next_halfword_from_sram_buffer(struct target *target,
607 uint16_t *value)
608 {
609 if (in_sram_address > MX3_NF_LAST_BUFFER_ADDR) {
610 LOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address);
611 *value = 0;
612 return ERROR_NAND_OPERATION_FAILED;
613 } else {
614 target_read_u16(target, in_sram_address, value);
615 in_sram_address += 2;
616 }
617 return ERROR_OK;
618 }
619
620 static int poll_for_complete_op(struct target *target, const char *text)
621 {
622 uint16_t poll_complete_status;
623 for (int poll_cycle_count = 0; poll_cycle_count < 100; poll_cycle_count++) {
624 usleep(25);
625 target_read_u16(target, MX3_NF_CFG2, &poll_complete_status);
626 if (poll_complete_status & MX3_NF_BIT_OP_DONE)
627 break;
628 }
629 if (!(poll_complete_status & MX3_NF_BIT_OP_DONE)) {
630 LOG_ERROR("%s sending timeout", text);
631 return ERROR_NAND_OPERATION_FAILED;
632 }
633 return ERROR_OK;
634 }
635
636 static int validate_target_state(struct nand_device *nand)
637 {
638 struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
639 struct target *target = nand->target;
640
641 if (target->state != TARGET_HALTED) {
642 LOG_ERROR(target_not_halted_err_msg);
643 return ERROR_NAND_OPERATION_FAILED;
644 }
645
646 if (mx3_nf_info->flags.target_little_endian !=
647 (target->endianness == TARGET_LITTLE_ENDIAN)) {
648 /*
649 * endianness changed after NAND controller probed
650 */
651 return ERROR_NAND_OPERATION_FAILED;
652 }
653 return ERROR_OK;
654 }
655
656 static int do_data_output(struct nand_device *nand)
657 {
658 struct mx3_nf_controller *mx3_nf_info = nand->controller_priv;
659 struct target *target = nand->target;
660 switch (mx3_nf_info->fin) {
661 case MX3_NF_FIN_DATAOUT:
662 /*
663 * start data output operation (set MX3_NF_BIT_OP_DONE==0)
664 */
665 target_write_u16 (target, MX3_NF_CFG2,
666 MX3_NF_BIT_DATAOUT_TYPE(mx3_nf_info->optype));
667 {
668 int poll_result;
669 poll_result = poll_for_complete_op(target, "data output");
670 if (poll_result != ERROR_OK)
671 return poll_result;
672 }
673 mx3_nf_info->fin = MX3_NF_FIN_NONE;
674 /*
675 * ECC stuff
676 */
677 if ((mx3_nf_info->optype == MX3_NF_DATAOUT_PAGE)
678 && mx3_nf_info->flags.hw_ecc_enabled) {
679 uint16_t ecc_status;
680 target_read_u16 (target, MX3_NF_ECCSTATUS, &ecc_status);
681 switch (ecc_status & 0x000c) {
682 case 1 << 2:
683 LOG_DEBUG("main area readed with 1 (correctable) error");
684 break;
685 case 2 << 2:
686 LOG_DEBUG("main area readed with more than 1 (incorrectable) error");
687 return ERROR_NAND_OPERATION_FAILED;
688 break;
689 }
690 switch (ecc_status & 0x0003) {
691 case 1:
692 LOG_DEBUG("spare area readed with 1 (correctable) error");
693 break;
694 case 2:
695 LOG_DEBUG("main area readed with more than 1 (incorrectable) error");
696 return ERROR_NAND_OPERATION_FAILED;
697 break;
698 }
699 }
700 break;
701 case MX3_NF_FIN_NONE:
702 break;
703 }
704 return ERROR_OK;
705 }
706
707 struct nand_flash_controller imx31_nand_flash_controller = {
708 .name = "imx31",
709 .usage = "nand device imx31 target noecc|hwecc",
710 .nand_device_command = &imx31_nand_device_command,
711 .init = &imx31_init,
712 .reset = &imx31_reset,
713 .command = &imx31_command,
714 .address = &imx31_address,
715 .write_data = &imx31_write_data,
716 .read_data = &imx31_read_data,
717 .write_page = &imx31_write_page,
718 .read_page = &imx31_read_page,
719 .nand_ready = &imx31_nand_ready,
720 };

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)