1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "lpc3180_nand_controller.h"
27 static int lpc3180_reset(struct nand_device
*nand
);
28 static int lpc3180_controller_ready(struct nand_device
*nand
, int timeout
);
30 /* nand device lpc3180 <target#> <oscillator_frequency>
32 NAND_DEVICE_COMMAND_HANDLER(lpc3180_nand_device_command
)
36 LOG_WARNING("incomplete 'lpc3180' nand flash configuration");
37 return ERROR_FLASH_BANK_INVALID
;
40 struct target
*target
= get_target(CMD_ARGV
[1]);
43 LOG_ERROR("target '%s' not defined", CMD_ARGV
[1]);
44 return ERROR_NAND_DEVICE_INVALID
;
48 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], osc_freq
);
50 struct lpc3180_nand_controller
*lpc3180_info
;
51 lpc3180_info
= malloc(sizeof(struct lpc3180_nand_controller
));
52 nand
->controller_priv
= lpc3180_info
;
54 lpc3180_info
->target
= target
;
55 lpc3180_info
->osc_freq
= osc_freq
;
57 if ((lpc3180_info
->osc_freq
< 1000) || (lpc3180_info
->osc_freq
> 20000))
59 LOG_WARNING("LPC3180 oscillator frequency should be between 1000 and 20000 kHz, was %i", lpc3180_info
->osc_freq
);
61 lpc3180_info
->selected_controller
= LPC3180_NO_CONTROLLER
;
62 lpc3180_info
->sw_write_protection
= 0;
63 lpc3180_info
->sw_wp_lower_bound
= 0x0;
64 lpc3180_info
->sw_wp_upper_bound
= 0x0;
69 static int lpc3180_pll(int fclkin
, uint32_t pll_ctrl
)
71 int bypass
= (pll_ctrl
& 0x8000) >> 15;
72 int direct
= (pll_ctrl
& 0x4000) >> 14;
73 int feedback
= (pll_ctrl
& 0x2000) >> 13;
74 int p
= (1 << ((pll_ctrl
& 0x1800) >> 11) * 2);
75 int n
= ((pll_ctrl
& 0x0600) >> 9) + 1;
76 int m
= ((pll_ctrl
& 0x01fe) >> 1) + 1;
77 int lock
= (pll_ctrl
& 0x1);
80 LOG_WARNING("PLL is not locked");
82 if (!bypass
&& direct
) /* direct mode */
83 return (m
* fclkin
) / n
;
85 if (bypass
&& !direct
) /* bypass mode */
86 return fclkin
/ (2 * p
);
88 if (bypass
& direct
) /* direct bypass mode */
91 if (feedback
) /* integer mode */
92 return m
* (fclkin
/ n
);
93 else /* non-integer mode */
94 return (m
/ (2 * p
)) * (fclkin
/ n
);
97 static float lpc3180_cycle_time(struct lpc3180_nand_controller
*lpc3180_info
)
99 struct target
*target
= lpc3180_info
->target
;
100 uint32_t sysclk_ctrl
, pwr_ctrl
, hclkdiv_ctrl
, hclkpll_ctrl
;
106 /* calculate timings */
108 /* determine current SYSCLK (13'MHz or main oscillator) */
109 target_read_u32(target
, 0x40004050, &sysclk_ctrl
);
111 if ((sysclk_ctrl
& 1) == 0)
112 sysclk
= lpc3180_info
->osc_freq
;
116 /* determine selected HCLK source */
117 target_read_u32(target
, 0x40004044, &pwr_ctrl
);
119 if ((pwr_ctrl
& (1 << 2)) == 0) /* DIRECT RUN mode */
125 target_read_u32(target
, 0x40004058, &hclkpll_ctrl
);
126 hclk_pll
= lpc3180_pll(sysclk
, hclkpll_ctrl
);
128 target_read_u32(target
, 0x40004040, &hclkdiv_ctrl
);
130 if (pwr_ctrl
& (1 << 10)) /* ARM_CLK and HCLK use PERIPH_CLK */
132 hclk
= hclk_pll
/ (((hclkdiv_ctrl
& 0x7c) >> 2) + 1);
134 else /* HCLK uses HCLK_PLL */
136 hclk
= hclk_pll
/ (1 << (hclkdiv_ctrl
& 0x3));
140 LOG_DEBUG("LPC3180 HCLK currently clocked at %i kHz", hclk
);
142 cycle
= (1.0 / hclk
) * 1000000.0;
147 static int lpc3180_init(struct nand_device
*nand
)
149 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
150 struct target
*target
= lpc3180_info
->target
;
151 int bus_width
= nand
->bus_width
? : 8;
152 int address_cycles
= nand
->address_cycles
? : 3;
153 int page_size
= nand
->page_size
? : 512;
155 if (target
->state
!= TARGET_HALTED
)
157 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
158 return ERROR_NAND_OPERATION_FAILED
;
161 /* sanitize arguments */
162 if ((bus_width
!= 8) && (bus_width
!= 16))
164 LOG_ERROR("LPC3180 only supports 8 or 16 bit bus width, not %i", bus_width
);
165 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
168 /* The LPC3180 only brings out 8 bit NAND data bus, but the controller
169 * would support 16 bit, too, so we just warn about this for now
173 LOG_WARNING("LPC3180 only supports 8 bit bus width");
176 /* inform calling code about selected bus width */
177 nand
->bus_width
= bus_width
;
179 if ((address_cycles
!= 3) && (address_cycles
!= 4))
181 LOG_ERROR("LPC3180 only supports 3 or 4 address cycles, not %i", address_cycles
);
182 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
185 if ((page_size
!= 512) && (page_size
!= 2048))
187 LOG_ERROR("LPC3180 only supports 512 or 2048 byte pages, not %i", page_size
);
188 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
191 /* select MLC controller if none is currently selected */
192 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
194 LOG_DEBUG("no LPC3180 NAND flash controller selected, using default 'mlc'");
195 lpc3180_info
->selected_controller
= LPC3180_MLC_CONTROLLER
;
198 if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
200 uint32_t mlc_icr_value
= 0x0;
202 int twp
, twh
, trp
, treh
, trhz
, trbwb
, tcea
;
204 /* FLASHCLK_CTRL = 0x22 (enable clock for MLC flash controller) */
205 target_write_u32(target
, 0x400040c8, 0x22);
207 /* MLC_CEH = 0x0 (Force nCE assert) */
208 target_write_u32(target
, 0x200b804c, 0x0);
210 /* MLC_LOCK = 0xa25e (unlock protected registers) */
211 target_write_u32(target
, 0x200b8044, 0xa25e);
213 /* MLC_ICR = configuration */
214 if (lpc3180_info
->sw_write_protection
)
215 mlc_icr_value
|= 0x8;
216 if (page_size
== 2048)
217 mlc_icr_value
|= 0x4;
218 if (address_cycles
== 4)
219 mlc_icr_value
|= 0x2;
221 mlc_icr_value
|= 0x1;
222 target_write_u32(target
, 0x200b8030, mlc_icr_value
);
224 /* calculate NAND controller timings */
225 cycle
= lpc3180_cycle_time(lpc3180_info
);
227 twp
= ((40 / cycle
) + 1);
228 twh
= ((20 / cycle
) + 1);
229 trp
= ((30 / cycle
) + 1);
230 treh
= ((15 / cycle
) + 1);
231 trhz
= ((30 / cycle
) + 1);
232 trbwb
= ((100 / cycle
) + 1);
233 tcea
= ((45 / cycle
) + 1);
235 /* MLC_LOCK = 0xa25e (unlock protected registers) */
236 target_write_u32(target
, 0x200b8044, 0xa25e);
239 target_write_u32(target
, 0x200b8034, (twp
& 0xf) | ((twh
& 0xf) << 4) |
240 ((trp
& 0xf) << 8) | ((treh
& 0xf) << 12) | ((trhz
& 0x7) << 16) |
241 ((trbwb
& 0x1f) << 19) | ((tcea
& 0x3) << 24));
245 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
248 int r_setup
, r_hold
, r_width
, r_rdy
;
249 int w_setup
, w_hold
, w_width
, w_rdy
;
251 /* FLASHCLK_CTRL = 0x05 (enable clock for SLC flash controller) */
252 target_write_u32(target
, 0x400040c8, 0x05);
254 /* SLC_CFG = 0x (Force nCE assert, ECC enabled, WIDTH = bus_width) */
255 target_write_u32(target
, 0x20020014, 0x28 | (bus_width
== 16) ? 1 : 0);
257 /* calculate NAND controller timings */
258 cycle
= lpc3180_cycle_time(lpc3180_info
);
260 r_setup
= w_setup
= 0;
261 r_hold
= w_hold
= 10 / cycle
;
262 r_width
= 30 / cycle
;
263 w_width
= 40 / cycle
;
264 r_rdy
= w_rdy
= 100 / cycle
;
266 /* SLC_TAC: SLC timing arcs register */
267 target_write_u32(target
, 0x2002002c, (r_setup
& 0xf) | ((r_hold
& 0xf) << 4) |
268 ((r_width
& 0xf) << 8) | ((r_rdy
& 0xf) << 12) | ((w_setup
& 0xf) << 16) |
269 ((w_hold
& 0xf) << 20) | ((w_width
& 0xf) << 24) | ((w_rdy
& 0xf) << 28));
277 static int lpc3180_reset(struct nand_device
*nand
)
279 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
280 struct target
*target
= lpc3180_info
->target
;
282 if (target
->state
!= TARGET_HALTED
)
284 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
285 return ERROR_NAND_OPERATION_FAILED
;
288 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
290 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
291 return ERROR_NAND_OPERATION_FAILED
;
293 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
295 /* MLC_CMD = 0xff (reset controller and NAND device) */
296 target_write_u32(target
, 0x200b8000, 0xff);
298 if (!lpc3180_controller_ready(nand
, 100))
300 LOG_ERROR("LPC3180 NAND controller timed out after reset");
301 return ERROR_NAND_OPERATION_TIMEOUT
;
304 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
306 /* SLC_CTRL = 0x6 (ECC_CLEAR, SW_RESET) */
307 target_write_u32(target
, 0x20020010, 0x6);
309 if (!lpc3180_controller_ready(nand
, 100))
311 LOG_ERROR("LPC3180 NAND controller timed out after reset");
312 return ERROR_NAND_OPERATION_TIMEOUT
;
319 static int lpc3180_command(struct nand_device
*nand
, uint8_t command
)
321 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
322 struct target
*target
= lpc3180_info
->target
;
324 if (target
->state
!= TARGET_HALTED
)
326 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
327 return ERROR_NAND_OPERATION_FAILED
;
330 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
332 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
333 return ERROR_NAND_OPERATION_FAILED
;
335 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
337 /* MLC_CMD = command */
338 target_write_u32(target
, 0x200b8000, command
);
340 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
342 /* SLC_CMD = command */
343 target_write_u32(target
, 0x20020008, command
);
349 static int lpc3180_address(struct nand_device
*nand
, uint8_t address
)
351 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
352 struct target
*target
= lpc3180_info
->target
;
354 if (target
->state
!= TARGET_HALTED
)
356 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
357 return ERROR_NAND_OPERATION_FAILED
;
360 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
362 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
363 return ERROR_NAND_OPERATION_FAILED
;
365 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
367 /* MLC_ADDR = address */
368 target_write_u32(target
, 0x200b8004, address
);
370 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
372 /* SLC_ADDR = address */
373 target_write_u32(target
, 0x20020004, address
);
379 static int lpc3180_write_data(struct nand_device
*nand
, uint16_t data
)
381 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
382 struct target
*target
= lpc3180_info
->target
;
384 if (target
->state
!= TARGET_HALTED
)
386 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
387 return ERROR_NAND_OPERATION_FAILED
;
390 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
392 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
393 return ERROR_NAND_OPERATION_FAILED
;
395 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
397 /* MLC_DATA = data */
398 target_write_u32(target
, 0x200b0000, data
);
400 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
402 /* SLC_DATA = data */
403 target_write_u32(target
, 0x20020000, data
);
409 static int lpc3180_read_data(struct nand_device
*nand
, void *data
)
411 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
412 struct target
*target
= lpc3180_info
->target
;
414 if (target
->state
!= TARGET_HALTED
)
416 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
417 return ERROR_NAND_OPERATION_FAILED
;
420 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
422 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
423 return ERROR_NAND_OPERATION_FAILED
;
425 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
427 /* data = MLC_DATA, use sized access */
428 if (nand
->bus_width
== 8)
430 uint8_t *data8
= data
;
431 target_read_u8(target
, 0x200b0000, data8
);
433 else if (nand
->bus_width
== 16)
435 uint16_t *data16
= data
;
436 target_read_u16(target
, 0x200b0000, data16
);
440 LOG_ERROR("BUG: bus_width neither 8 nor 16 bit");
441 return ERROR_NAND_OPERATION_FAILED
;
444 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
448 /* data = SLC_DATA, must use 32-bit access */
449 target_read_u32(target
, 0x20020000, &data32
);
451 if (nand
->bus_width
== 8)
453 uint8_t *data8
= data
;
454 *data8
= data32
& 0xff;
456 else if (nand
->bus_width
== 16)
458 uint16_t *data16
= data
;
459 *data16
= data32
& 0xffff;
463 LOG_ERROR("BUG: bus_width neither 8 nor 16 bit");
464 return ERROR_NAND_OPERATION_FAILED
;
471 static int lpc3180_write_page(struct nand_device
*nand
, uint32_t page
, uint8_t *data
, uint32_t data_size
, uint8_t *oob
, uint32_t oob_size
)
473 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
474 struct target
*target
= lpc3180_info
->target
;
478 if (target
->state
!= TARGET_HALTED
)
480 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
481 return ERROR_NAND_OPERATION_FAILED
;
484 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
486 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
487 return ERROR_NAND_OPERATION_FAILED
;
489 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
491 uint8_t *page_buffer
;
493 int quarter
, num_quarters
;
497 LOG_ERROR("LPC3180 MLC controller can't write OOB data only");
498 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
501 if (oob
&& (oob_size
> 6))
503 LOG_ERROR("LPC3180 MLC controller can't write more than 6 bytes of OOB data");
504 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
507 if (data_size
> (uint32_t)nand
->page_size
)
509 LOG_ERROR("data size exceeds page size");
510 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
513 /* MLC_CMD = sequential input */
514 target_write_u32(target
, 0x200b8000, NAND_CMD_SEQIN
);
516 page_buffer
= malloc(512);
517 oob_buffer
= malloc(6);
519 if (nand
->page_size
== 512)
521 /* MLC_ADDR = 0x0 (one column cycle) */
522 target_write_u32(target
, 0x200b8004, 0x0);
525 target_write_u32(target
, 0x200b8004, page
& 0xff);
526 target_write_u32(target
, 0x200b8004, (page
>> 8) & 0xff);
528 if (nand
->address_cycles
== 4)
529 target_write_u32(target
, 0x200b8004, (page
>> 16) & 0xff);
533 /* MLC_ADDR = 0x0 (two column cycles) */
534 target_write_u32(target
, 0x200b8004, 0x0);
535 target_write_u32(target
, 0x200b8004, 0x0);
538 target_write_u32(target
, 0x200b8004, page
& 0xff);
539 target_write_u32(target
, 0x200b8004, (page
>> 8) & 0xff);
542 /* when using the MLC controller, we have to treat a large page device
543 * as being made out of four quarters, each the size of a small page device
545 num_quarters
= (nand
->page_size
== 2048) ? 4 : 1;
547 for (quarter
= 0; quarter
< num_quarters
; quarter
++)
549 int thisrun_data_size
= (data_size
> 512) ? 512 : data_size
;
550 int thisrun_oob_size
= (oob_size
> 6) ? 6 : oob_size
;
552 memset(page_buffer
, 0xff, 512);
555 memcpy(page_buffer
, data
, thisrun_data_size
);
556 data_size
-= thisrun_data_size
;
557 data
+= thisrun_data_size
;
560 memset(oob_buffer
, 0xff, (nand
->page_size
== 512) ? 6 : 24);
563 memcpy(page_buffer
, oob
, thisrun_oob_size
);
564 oob_size
-= thisrun_oob_size
;
565 oob
+= thisrun_oob_size
;
568 /* write MLC_ECC_ENC_REG to start encode cycle */
569 target_write_u32(target
, 0x200b8008, 0x0);
571 target_write_memory(target
, 0x200a8000, 4, 128, page_buffer
+ (quarter
* 512));
572 target_write_memory(target
, 0x200a8000, 1, 6, oob_buffer
+ (quarter
* 6));
574 /* write MLC_ECC_AUTO_ENC_REG to start auto encode */
575 target_write_u32(target
, 0x200b8010, 0x0);
577 if (!lpc3180_controller_ready(nand
, 1000))
579 LOG_ERROR("timeout while waiting for completion of auto encode cycle");
580 return ERROR_NAND_OPERATION_FAILED
;
584 /* MLC_CMD = auto program command */
585 target_write_u32(target
, 0x200b8000, NAND_CMD_PAGEPROG
);
587 if ((retval
= nand_read_status(nand
, &status
)) != ERROR_OK
)
589 LOG_ERROR("couldn't read status");
590 return ERROR_NAND_OPERATION_FAILED
;
593 if (status
& NAND_STATUS_FAIL
)
595 LOG_ERROR("write operation didn't pass, status: 0x%2.2x", status
);
596 return ERROR_NAND_OPERATION_FAILED
;
602 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
604 return nand_write_page_raw(nand
, page
, data
, data_size
, oob
, oob_size
);
610 static int lpc3180_read_page(struct nand_device
*nand
, uint32_t page
, uint8_t *data
, uint32_t data_size
, uint8_t *oob
, uint32_t oob_size
)
612 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
613 struct target
*target
= lpc3180_info
->target
;
615 if (target
->state
!= TARGET_HALTED
)
617 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
618 return ERROR_NAND_OPERATION_FAILED
;
621 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
623 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
624 return ERROR_NAND_OPERATION_FAILED
;
626 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
628 uint8_t *page_buffer
;
630 uint32_t page_bytes_done
= 0;
631 uint32_t oob_bytes_done
= 0;
635 if (oob
&& (oob_size
> 6))
637 LOG_ERROR("LPC3180 MLC controller can't read more than 6 bytes of OOB data");
638 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
642 if (data_size
> (uint32_t)nand
->page_size
)
644 LOG_ERROR("data size exceeds page size");
645 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
648 if (nand
->page_size
== 2048)
650 page_buffer
= malloc(2048);
651 oob_buffer
= malloc(64);
655 page_buffer
= malloc(512);
656 oob_buffer
= malloc(16);
661 /* MLC_CMD = Read OOB
662 * we can use the READOOB command on both small and large page devices,
663 * as the controller translates the 0x50 command to a 0x0 with appropriate
664 * positioning of the serial buffer read pointer
666 target_write_u32(target
, 0x200b8000, NAND_CMD_READOOB
);
670 /* MLC_CMD = Read0 */
671 target_write_u32(target
, 0x200b8000, NAND_CMD_READ0
);
674 if (nand
->page_size
== 512)
676 /* small page device */
677 /* MLC_ADDR = 0x0 (one column cycle) */
678 target_write_u32(target
, 0x200b8004, 0x0);
681 target_write_u32(target
, 0x200b8004, page
& 0xff);
682 target_write_u32(target
, 0x200b8004, (page
>> 8) & 0xff);
684 if (nand
->address_cycles
== 4)
685 target_write_u32(target
, 0x200b8004, (page
>> 16) & 0xff);
689 /* large page device */
690 /* MLC_ADDR = 0x0 (two column cycles) */
691 target_write_u32(target
, 0x200b8004, 0x0);
692 target_write_u32(target
, 0x200b8004, 0x0);
695 target_write_u32(target
, 0x200b8004, page
& 0xff);
696 target_write_u32(target
, 0x200b8004, (page
>> 8) & 0xff);
698 /* MLC_CMD = Read Start */
699 target_write_u32(target
, 0x200b8000, NAND_CMD_READSTART
);
702 while (page_bytes_done
< (uint32_t)nand
->page_size
)
704 /* MLC_ECC_AUTO_DEC_REG = dummy */
705 target_write_u32(target
, 0x200b8014, 0xaa55aa55);
707 if (!lpc3180_controller_ready(nand
, 1000))
709 LOG_ERROR("timeout while waiting for completion of auto decode cycle");
710 return ERROR_NAND_OPERATION_FAILED
;
713 target_read_u32(target
, 0x200b8048, &mlc_isr
);
719 LOG_ERROR("uncorrectable error detected: 0x%2.2x", (unsigned)mlc_isr
);
720 return ERROR_NAND_OPERATION_FAILED
;
723 LOG_WARNING("%i symbol error detected and corrected", ((int)(((mlc_isr
& 0x30) >> 4) + 1)));
728 target_read_memory(target
, 0x200a8000, 4, 128, page_buffer
+ page_bytes_done
);
733 target_read_memory(target
, 0x200a8000, 4, 4, oob_buffer
+ oob_bytes_done
);
736 page_bytes_done
+= 512;
737 oob_bytes_done
+= 16;
741 memcpy(data
, page_buffer
, data_size
);
744 memcpy(oob
, oob_buffer
, oob_size
);
749 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
751 return nand_read_page_raw(nand
, page
, data
, data_size
, oob
, oob_size
);
757 static int lpc3180_controller_ready(struct nand_device
*nand
, int timeout
)
759 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
760 struct target
*target
= lpc3180_info
->target
;
761 uint8_t status
= 0x0;
763 if (target
->state
!= TARGET_HALTED
)
765 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
766 return ERROR_NAND_OPERATION_FAILED
;
771 if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
773 /* Read MLC_ISR, wait for controller to become ready */
774 target_read_u8(target
, 0x200b8048, &status
);
779 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
781 /* we pretend that the SLC controller is always ready */
786 } while (timeout
-- > 0);
791 static int lpc3180_nand_ready(struct nand_device
*nand
, int timeout
)
793 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
794 struct target
*target
= lpc3180_info
->target
;
796 if (target
->state
!= TARGET_HALTED
)
798 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
799 return ERROR_NAND_OPERATION_FAILED
;
804 if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
806 uint8_t status
= 0x0;
808 /* Read MLC_ISR, wait for NAND flash device to become ready */
809 target_read_u8(target
, 0x200b8048, &status
);
814 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
816 uint32_t status
= 0x0;
818 /* Read SLC_STAT and check READY bit */
819 target_read_u32(target
, 0x20020018, &status
);
826 } while (timeout
-- > 0);
831 COMMAND_HANDLER(handle_lpc3180_select_command
)
833 struct lpc3180_nand_controller
*lpc3180_info
= NULL
;
839 if ((CMD_ARGC
< 1) || (CMD_ARGC
> 2))
841 return ERROR_COMMAND_SYNTAX_ERROR
;
845 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[1], num
);
846 struct nand_device
*nand
= get_nand_device_by_num(num
);
849 command_print(CMD_CTX
, "nand device '#%s' is out of bounds", CMD_ARGV
[0]);
853 lpc3180_info
= nand
->controller_priv
;
857 if (strcmp(CMD_ARGV
[1], "mlc") == 0)
859 lpc3180_info
->selected_controller
= LPC3180_MLC_CONTROLLER
;
861 else if (strcmp(CMD_ARGV
[1], "slc") == 0)
863 lpc3180_info
->selected_controller
= LPC3180_SLC_CONTROLLER
;
867 return ERROR_COMMAND_SYNTAX_ERROR
;
871 command_print(CMD_CTX
, "%s controller selected", selected
[lpc3180_info
->selected_controller
]);
876 static int lpc3180_register_commands(struct command_context
*cmd_ctx
)
878 struct command
*lpc3180_cmd
= COMMAND_REGISTER(cmd_ctx
, NULL
, "lpc3180", NULL
, COMMAND_ANY
, "commands specific to the LPC3180 NAND flash controllers");
880 COMMAND_REGISTER(cmd_ctx
, lpc3180_cmd
, "select", handle_lpc3180_select_command
, COMMAND_EXEC
, "select <'mlc'|'slc'> controller (default is mlc)");
885 struct nand_flash_controller lpc3180_nand_controller
= {
887 .nand_device_command
= lpc3180_nand_device_command
,
888 .register_commands
= lpc3180_register_commands
,
889 .init
= lpc3180_init
,
890 .reset
= lpc3180_reset
,
891 .command
= lpc3180_command
,
892 .address
= lpc3180_address
,
893 .write_data
= lpc3180_write_data
,
894 .read_data
= lpc3180_read_data
,
895 .write_page
= lpc3180_write_page
,
896 .read_page
= lpc3180_read_page
,
897 .controller_ready
= lpc3180_controller_ready
,
898 .nand_ready
= lpc3180_nand_ready
,
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)