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

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)