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

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)