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 ***************************************************************************/
26 #include <target/target.h>
29 static int lpc3180_reset(struct nand_device
*nand
);
30 static int lpc3180_controller_ready(struct nand_device
*nand
, int timeout
);
32 /* nand device lpc3180 <target#> <oscillator_frequency>
34 NAND_DEVICE_COMMAND_HANDLER(lpc3180_nand_device_command
)
38 LOG_WARNING("incomplete 'lpc3180' nand flash configuration");
39 return ERROR_FLASH_BANK_INVALID
;
42 struct target
*target
= get_target(CMD_ARGV
[1]);
45 LOG_ERROR("target '%s' not defined", CMD_ARGV
[1]);
46 return ERROR_NAND_DEVICE_INVALID
;
50 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], osc_freq
);
52 struct lpc3180_nand_controller
*lpc3180_info
;
53 lpc3180_info
= malloc(sizeof(struct lpc3180_nand_controller
));
54 nand
->controller_priv
= lpc3180_info
;
56 lpc3180_info
->target
= target
;
57 lpc3180_info
->osc_freq
= osc_freq
;
59 if ((lpc3180_info
->osc_freq
< 1000) || (lpc3180_info
->osc_freq
> 20000))
61 LOG_WARNING("LPC3180 oscillator frequency should be between 1000 and 20000 kHz, was %i", lpc3180_info
->osc_freq
);
63 lpc3180_info
->selected_controller
= LPC3180_NO_CONTROLLER
;
64 lpc3180_info
->sw_write_protection
= 0;
65 lpc3180_info
->sw_wp_lower_bound
= 0x0;
66 lpc3180_info
->sw_wp_upper_bound
= 0x0;
71 static int lpc3180_pll(int fclkin
, uint32_t pll_ctrl
)
73 int bypass
= (pll_ctrl
& 0x8000) >> 15;
74 int direct
= (pll_ctrl
& 0x4000) >> 14;
75 int feedback
= (pll_ctrl
& 0x2000) >> 13;
76 int p
= (1 << ((pll_ctrl
& 0x1800) >> 11) * 2);
77 int n
= ((pll_ctrl
& 0x0600) >> 9) + 1;
78 int m
= ((pll_ctrl
& 0x01fe) >> 1) + 1;
79 int lock
= (pll_ctrl
& 0x1);
82 LOG_WARNING("PLL is not locked");
84 if (!bypass
&& direct
) /* direct mode */
85 return (m
* fclkin
) / n
;
87 if (bypass
&& !direct
) /* bypass mode */
88 return fclkin
/ (2 * p
);
90 if (bypass
& direct
) /* direct bypass mode */
93 if (feedback
) /* integer mode */
94 return m
* (fclkin
/ n
);
95 else /* non-integer mode */
96 return (m
/ (2 * p
)) * (fclkin
/ n
);
99 static float lpc3180_cycle_time(struct lpc3180_nand_controller
*lpc3180_info
)
101 struct target
*target
= lpc3180_info
->target
;
102 uint32_t sysclk_ctrl
, pwr_ctrl
, hclkdiv_ctrl
, hclkpll_ctrl
;
108 /* calculate timings */
110 /* determine current SYSCLK (13'MHz or main oscillator) */
111 target_read_u32(target
, 0x40004050, &sysclk_ctrl
);
113 if ((sysclk_ctrl
& 1) == 0)
114 sysclk
= lpc3180_info
->osc_freq
;
118 /* determine selected HCLK source */
119 target_read_u32(target
, 0x40004044, &pwr_ctrl
);
121 if ((pwr_ctrl
& (1 << 2)) == 0) /* DIRECT RUN mode */
127 target_read_u32(target
, 0x40004058, &hclkpll_ctrl
);
128 hclk_pll
= lpc3180_pll(sysclk
, hclkpll_ctrl
);
130 target_read_u32(target
, 0x40004040, &hclkdiv_ctrl
);
132 if (pwr_ctrl
& (1 << 10)) /* ARM_CLK and HCLK use PERIPH_CLK */
134 hclk
= hclk_pll
/ (((hclkdiv_ctrl
& 0x7c) >> 2) + 1);
136 else /* HCLK uses HCLK_PLL */
138 hclk
= hclk_pll
/ (1 << (hclkdiv_ctrl
& 0x3));
142 LOG_DEBUG("LPC3180 HCLK currently clocked at %i kHz", hclk
);
144 cycle
= (1.0 / hclk
) * 1000000.0;
149 static int lpc3180_init(struct nand_device
*nand
)
151 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
152 struct target
*target
= lpc3180_info
->target
;
153 int bus_width
= nand
->bus_width
? : 8;
154 int address_cycles
= nand
->address_cycles
? : 3;
155 int page_size
= nand
->page_size
? : 512;
157 if (target
->state
!= TARGET_HALTED
)
159 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
160 return ERROR_NAND_OPERATION_FAILED
;
163 /* sanitize arguments */
164 if ((bus_width
!= 8) && (bus_width
!= 16))
166 LOG_ERROR("LPC3180 only supports 8 or 16 bit bus width, not %i", bus_width
);
167 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
170 /* The LPC3180 only brings out 8 bit NAND data bus, but the controller
171 * would support 16 bit, too, so we just warn about this for now
175 LOG_WARNING("LPC3180 only supports 8 bit bus width");
178 /* inform calling code about selected bus width */
179 nand
->bus_width
= bus_width
;
181 if ((address_cycles
!= 3) && (address_cycles
!= 4))
183 LOG_ERROR("LPC3180 only supports 3 or 4 address cycles, not %i", address_cycles
);
184 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
187 if ((page_size
!= 512) && (page_size
!= 2048))
189 LOG_ERROR("LPC3180 only supports 512 or 2048 byte pages, not %i", page_size
);
190 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
193 /* select MLC controller if none is currently selected */
194 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
196 LOG_DEBUG("no LPC3180 NAND flash controller selected, using default 'mlc'");
197 lpc3180_info
->selected_controller
= LPC3180_MLC_CONTROLLER
;
200 if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
202 uint32_t mlc_icr_value
= 0x0;
204 int twp
, twh
, trp
, treh
, trhz
, trbwb
, tcea
;
206 /* FLASHCLK_CTRL = 0x22 (enable clock for MLC flash controller) */
207 target_write_u32(target
, 0x400040c8, 0x22);
209 /* MLC_CEH = 0x0 (Force nCE assert) */
210 target_write_u32(target
, 0x200b804c, 0x0);
212 /* MLC_LOCK = 0xa25e (unlock protected registers) */
213 target_write_u32(target
, 0x200b8044, 0xa25e);
215 /* MLC_ICR = configuration */
216 if (lpc3180_info
->sw_write_protection
)
217 mlc_icr_value
|= 0x8;
218 if (page_size
== 2048)
219 mlc_icr_value
|= 0x4;
220 if (address_cycles
== 4)
221 mlc_icr_value
|= 0x2;
223 mlc_icr_value
|= 0x1;
224 target_write_u32(target
, 0x200b8030, mlc_icr_value
);
226 /* calculate NAND controller timings */
227 cycle
= lpc3180_cycle_time(lpc3180_info
);
229 twp
= ((40 / cycle
) + 1);
230 twh
= ((20 / cycle
) + 1);
231 trp
= ((30 / cycle
) + 1);
232 treh
= ((15 / cycle
) + 1);
233 trhz
= ((30 / cycle
) + 1);
234 trbwb
= ((100 / cycle
) + 1);
235 tcea
= ((45 / cycle
) + 1);
237 /* MLC_LOCK = 0xa25e (unlock protected registers) */
238 target_write_u32(target
, 0x200b8044, 0xa25e);
241 target_write_u32(target
, 0x200b8034, (twp
& 0xf) | ((twh
& 0xf) << 4) |
242 ((trp
& 0xf) << 8) | ((treh
& 0xf) << 12) | ((trhz
& 0x7) << 16) |
243 ((trbwb
& 0x1f) << 19) | ((tcea
& 0x3) << 24));
247 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
250 int r_setup
, r_hold
, r_width
, r_rdy
;
251 int w_setup
, w_hold
, w_width
, w_rdy
;
253 /* FLASHCLK_CTRL = 0x05 (enable clock for SLC flash controller) */
254 target_write_u32(target
, 0x400040c8, 0x05);
256 /* SLC_CFG = 0x (Force nCE assert, ECC enabled, WIDTH = bus_width) */
257 target_write_u32(target
, 0x20020014, 0x28 | (bus_width
== 16) ? 1 : 0);
259 /* calculate NAND controller timings */
260 cycle
= lpc3180_cycle_time(lpc3180_info
);
262 r_setup
= w_setup
= 0;
263 r_hold
= w_hold
= 10 / cycle
;
264 r_width
= 30 / cycle
;
265 w_width
= 40 / cycle
;
266 r_rdy
= w_rdy
= 100 / cycle
;
268 /* SLC_TAC: SLC timing arcs register */
269 target_write_u32(target
, 0x2002002c, (r_setup
& 0xf) | ((r_hold
& 0xf) << 4) |
270 ((r_width
& 0xf) << 8) | ((r_rdy
& 0xf) << 12) | ((w_setup
& 0xf) << 16) |
271 ((w_hold
& 0xf) << 20) | ((w_width
& 0xf) << 24) | ((w_rdy
& 0xf) << 28));
279 static int lpc3180_reset(struct nand_device
*nand
)
281 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
282 struct target
*target
= lpc3180_info
->target
;
284 if (target
->state
!= TARGET_HALTED
)
286 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
287 return ERROR_NAND_OPERATION_FAILED
;
290 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
292 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
293 return ERROR_NAND_OPERATION_FAILED
;
295 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
297 /* MLC_CMD = 0xff (reset controller and NAND device) */
298 target_write_u32(target
, 0x200b8000, 0xff);
300 if (!lpc3180_controller_ready(nand
, 100))
302 LOG_ERROR("LPC3180 NAND controller timed out after reset");
303 return ERROR_NAND_OPERATION_TIMEOUT
;
306 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
308 /* SLC_CTRL = 0x6 (ECC_CLEAR, SW_RESET) */
309 target_write_u32(target
, 0x20020010, 0x6);
311 if (!lpc3180_controller_ready(nand
, 100))
313 LOG_ERROR("LPC3180 NAND controller timed out after reset");
314 return ERROR_NAND_OPERATION_TIMEOUT
;
321 static int lpc3180_command(struct nand_device
*nand
, uint8_t command
)
323 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
324 struct target
*target
= lpc3180_info
->target
;
326 if (target
->state
!= TARGET_HALTED
)
328 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
329 return ERROR_NAND_OPERATION_FAILED
;
332 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
334 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
335 return ERROR_NAND_OPERATION_FAILED
;
337 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
339 /* MLC_CMD = command */
340 target_write_u32(target
, 0x200b8000, command
);
342 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
344 /* SLC_CMD = command */
345 target_write_u32(target
, 0x20020008, command
);
351 static int lpc3180_address(struct nand_device
*nand
, uint8_t address
)
353 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
354 struct target
*target
= lpc3180_info
->target
;
356 if (target
->state
!= TARGET_HALTED
)
358 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
359 return ERROR_NAND_OPERATION_FAILED
;
362 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
364 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
365 return ERROR_NAND_OPERATION_FAILED
;
367 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
369 /* MLC_ADDR = address */
370 target_write_u32(target
, 0x200b8004, address
);
372 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
374 /* SLC_ADDR = address */
375 target_write_u32(target
, 0x20020004, address
);
381 static int lpc3180_write_data(struct nand_device
*nand
, uint16_t data
)
383 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
384 struct target
*target
= lpc3180_info
->target
;
386 if (target
->state
!= TARGET_HALTED
)
388 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
389 return ERROR_NAND_OPERATION_FAILED
;
392 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
394 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
395 return ERROR_NAND_OPERATION_FAILED
;
397 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
399 /* MLC_DATA = data */
400 target_write_u32(target
, 0x200b0000, data
);
402 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
404 /* SLC_DATA = data */
405 target_write_u32(target
, 0x20020000, data
);
411 static int lpc3180_read_data(struct nand_device
*nand
, void *data
)
413 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
414 struct target
*target
= lpc3180_info
->target
;
416 if (target
->state
!= TARGET_HALTED
)
418 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
419 return ERROR_NAND_OPERATION_FAILED
;
422 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
424 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
425 return ERROR_NAND_OPERATION_FAILED
;
427 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
429 /* data = MLC_DATA, use sized access */
430 if (nand
->bus_width
== 8)
432 uint8_t *data8
= data
;
433 target_read_u8(target
, 0x200b0000, data8
);
435 else if (nand
->bus_width
== 16)
437 uint16_t *data16
= data
;
438 target_read_u16(target
, 0x200b0000, data16
);
442 LOG_ERROR("BUG: bus_width neither 8 nor 16 bit");
443 return ERROR_NAND_OPERATION_FAILED
;
446 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
450 /* data = SLC_DATA, must use 32-bit access */
451 target_read_u32(target
, 0x20020000, &data32
);
453 if (nand
->bus_width
== 8)
455 uint8_t *data8
= data
;
456 *data8
= data32
& 0xff;
458 else if (nand
->bus_width
== 16)
460 uint16_t *data16
= data
;
461 *data16
= data32
& 0xffff;
465 LOG_ERROR("BUG: bus_width neither 8 nor 16 bit");
466 return ERROR_NAND_OPERATION_FAILED
;
473 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
)
475 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
476 struct target
*target
= lpc3180_info
->target
;
480 if (target
->state
!= TARGET_HALTED
)
482 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
483 return ERROR_NAND_OPERATION_FAILED
;
486 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
488 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
489 return ERROR_NAND_OPERATION_FAILED
;
491 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
493 uint8_t *page_buffer
;
495 int quarter
, num_quarters
;
499 LOG_ERROR("LPC3180 MLC controller can't write OOB data only");
500 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
503 if (oob
&& (oob_size
> 6))
505 LOG_ERROR("LPC3180 MLC controller can't write more than 6 bytes of OOB data");
506 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
509 if (data_size
> (uint32_t)nand
->page_size
)
511 LOG_ERROR("data size exceeds page size");
512 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
515 /* MLC_CMD = sequential input */
516 target_write_u32(target
, 0x200b8000, NAND_CMD_SEQIN
);
518 page_buffer
= malloc(512);
519 oob_buffer
= malloc(6);
521 if (nand
->page_size
== 512)
523 /* MLC_ADDR = 0x0 (one column cycle) */
524 target_write_u32(target
, 0x200b8004, 0x0);
527 target_write_u32(target
, 0x200b8004, page
& 0xff);
528 target_write_u32(target
, 0x200b8004, (page
>> 8) & 0xff);
530 if (nand
->address_cycles
== 4)
531 target_write_u32(target
, 0x200b8004, (page
>> 16) & 0xff);
535 /* MLC_ADDR = 0x0 (two column cycles) */
536 target_write_u32(target
, 0x200b8004, 0x0);
537 target_write_u32(target
, 0x200b8004, 0x0);
540 target_write_u32(target
, 0x200b8004, page
& 0xff);
541 target_write_u32(target
, 0x200b8004, (page
>> 8) & 0xff);
544 /* when using the MLC controller, we have to treat a large page device
545 * as being made out of four quarters, each the size of a small page device
547 num_quarters
= (nand
->page_size
== 2048) ? 4 : 1;
549 for (quarter
= 0; quarter
< num_quarters
; quarter
++)
551 int thisrun_data_size
= (data_size
> 512) ? 512 : data_size
;
552 int thisrun_oob_size
= (oob_size
> 6) ? 6 : oob_size
;
554 memset(page_buffer
, 0xff, 512);
557 memcpy(page_buffer
, data
, thisrun_data_size
);
558 data_size
-= thisrun_data_size
;
559 data
+= thisrun_data_size
;
562 memset(oob_buffer
, 0xff, (nand
->page_size
== 512) ? 6 : 24);
565 memcpy(page_buffer
, oob
, thisrun_oob_size
);
566 oob_size
-= thisrun_oob_size
;
567 oob
+= thisrun_oob_size
;
570 /* write MLC_ECC_ENC_REG to start encode cycle */
571 target_write_u32(target
, 0x200b8008, 0x0);
573 target_write_memory(target
, 0x200a8000, 4, 128, page_buffer
+ (quarter
* 512));
574 target_write_memory(target
, 0x200a8000, 1, 6, oob_buffer
+ (quarter
* 6));
576 /* write MLC_ECC_AUTO_ENC_REG to start auto encode */
577 target_write_u32(target
, 0x200b8010, 0x0);
579 if (!lpc3180_controller_ready(nand
, 1000))
581 LOG_ERROR("timeout while waiting for completion of auto encode cycle");
582 return ERROR_NAND_OPERATION_FAILED
;
586 /* MLC_CMD = auto program command */
587 target_write_u32(target
, 0x200b8000, NAND_CMD_PAGEPROG
);
589 if ((retval
= nand_read_status(nand
, &status
)) != ERROR_OK
)
591 LOG_ERROR("couldn't read status");
592 return ERROR_NAND_OPERATION_FAILED
;
595 if (status
& NAND_STATUS_FAIL
)
597 LOG_ERROR("write operation didn't pass, status: 0x%2.2x", status
);
598 return ERROR_NAND_OPERATION_FAILED
;
604 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
606 return nand_write_page_raw(nand
, page
, data
, data_size
, oob
, oob_size
);
612 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
)
614 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
615 struct target
*target
= lpc3180_info
->target
;
617 if (target
->state
!= TARGET_HALTED
)
619 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
620 return ERROR_NAND_OPERATION_FAILED
;
623 if (lpc3180_info
->selected_controller
== LPC3180_NO_CONTROLLER
)
625 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
626 return ERROR_NAND_OPERATION_FAILED
;
628 else if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
630 uint8_t *page_buffer
;
632 uint32_t page_bytes_done
= 0;
633 uint32_t oob_bytes_done
= 0;
637 if (oob
&& (oob_size
> 6))
639 LOG_ERROR("LPC3180 MLC controller can't read more than 6 bytes of OOB data");
640 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
644 if (data_size
> (uint32_t)nand
->page_size
)
646 LOG_ERROR("data size exceeds page size");
647 return ERROR_NAND_OPERATION_NOT_SUPPORTED
;
650 if (nand
->page_size
== 2048)
652 page_buffer
= malloc(2048);
653 oob_buffer
= malloc(64);
657 page_buffer
= malloc(512);
658 oob_buffer
= malloc(16);
663 /* MLC_CMD = Read OOB
664 * we can use the READOOB command on both small and large page devices,
665 * as the controller translates the 0x50 command to a 0x0 with appropriate
666 * positioning of the serial buffer read pointer
668 target_write_u32(target
, 0x200b8000, NAND_CMD_READOOB
);
672 /* MLC_CMD = Read0 */
673 target_write_u32(target
, 0x200b8000, NAND_CMD_READ0
);
676 if (nand
->page_size
== 512)
678 /* small page device */
679 /* MLC_ADDR = 0x0 (one column cycle) */
680 target_write_u32(target
, 0x200b8004, 0x0);
683 target_write_u32(target
, 0x200b8004, page
& 0xff);
684 target_write_u32(target
, 0x200b8004, (page
>> 8) & 0xff);
686 if (nand
->address_cycles
== 4)
687 target_write_u32(target
, 0x200b8004, (page
>> 16) & 0xff);
691 /* large page device */
692 /* MLC_ADDR = 0x0 (two column cycles) */
693 target_write_u32(target
, 0x200b8004, 0x0);
694 target_write_u32(target
, 0x200b8004, 0x0);
697 target_write_u32(target
, 0x200b8004, page
& 0xff);
698 target_write_u32(target
, 0x200b8004, (page
>> 8) & 0xff);
700 /* MLC_CMD = Read Start */
701 target_write_u32(target
, 0x200b8000, NAND_CMD_READSTART
);
704 while (page_bytes_done
< (uint32_t)nand
->page_size
)
706 /* MLC_ECC_AUTO_DEC_REG = dummy */
707 target_write_u32(target
, 0x200b8014, 0xaa55aa55);
709 if (!lpc3180_controller_ready(nand
, 1000))
711 LOG_ERROR("timeout while waiting for completion of auto decode cycle");
712 return ERROR_NAND_OPERATION_FAILED
;
715 target_read_u32(target
, 0x200b8048, &mlc_isr
);
721 LOG_ERROR("uncorrectable error detected: 0x%2.2x", (unsigned)mlc_isr
);
722 return ERROR_NAND_OPERATION_FAILED
;
725 LOG_WARNING("%i symbol error detected and corrected", ((int)(((mlc_isr
& 0x30) >> 4) + 1)));
730 target_read_memory(target
, 0x200a8000, 4, 128, page_buffer
+ page_bytes_done
);
735 target_read_memory(target
, 0x200a8000, 4, 4, oob_buffer
+ oob_bytes_done
);
738 page_bytes_done
+= 512;
739 oob_bytes_done
+= 16;
743 memcpy(data
, page_buffer
, data_size
);
746 memcpy(oob
, oob_buffer
, oob_size
);
751 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
753 return nand_read_page_raw(nand
, page
, data
, data_size
, oob
, oob_size
);
759 static int lpc3180_controller_ready(struct nand_device
*nand
, int timeout
)
761 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
762 struct target
*target
= lpc3180_info
->target
;
763 uint8_t status
= 0x0;
765 if (target
->state
!= TARGET_HALTED
)
767 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
768 return ERROR_NAND_OPERATION_FAILED
;
773 if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
775 /* Read MLC_ISR, wait for controller to become ready */
776 target_read_u8(target
, 0x200b8048, &status
);
781 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
783 /* we pretend that the SLC controller is always ready */
788 } while (timeout
-- > 0);
793 static int lpc3180_nand_ready(struct nand_device
*nand
, int timeout
)
795 struct lpc3180_nand_controller
*lpc3180_info
= nand
->controller_priv
;
796 struct target
*target
= lpc3180_info
->target
;
798 if (target
->state
!= TARGET_HALTED
)
800 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
801 return ERROR_NAND_OPERATION_FAILED
;
806 if (lpc3180_info
->selected_controller
== LPC3180_MLC_CONTROLLER
)
808 uint8_t status
= 0x0;
810 /* Read MLC_ISR, wait for NAND flash device to become ready */
811 target_read_u8(target
, 0x200b8048, &status
);
816 else if (lpc3180_info
->selected_controller
== LPC3180_SLC_CONTROLLER
)
818 uint32_t status
= 0x0;
820 /* Read SLC_STAT and check READY bit */
821 target_read_u32(target
, 0x20020018, &status
);
828 } while (timeout
-- > 0);
833 COMMAND_HANDLER(handle_lpc3180_select_command
)
835 struct lpc3180_nand_controller
*lpc3180_info
= NULL
;
841 if ((CMD_ARGC
< 1) || (CMD_ARGC
> 2))
843 return ERROR_COMMAND_SYNTAX_ERROR
;
847 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[1], num
);
848 struct nand_device
*nand
= get_nand_device_by_num(num
);
851 command_print(CMD_CTX
, "nand device '#%s' is out of bounds", CMD_ARGV
[0]);
855 lpc3180_info
= nand
->controller_priv
;
859 if (strcmp(CMD_ARGV
[1], "mlc") == 0)
861 lpc3180_info
->selected_controller
= LPC3180_MLC_CONTROLLER
;
863 else if (strcmp(CMD_ARGV
[1], "slc") == 0)
865 lpc3180_info
->selected_controller
= LPC3180_SLC_CONTROLLER
;
869 return ERROR_COMMAND_SYNTAX_ERROR
;
873 command_print(CMD_CTX
, "%s controller selected", selected
[lpc3180_info
->selected_controller
]);
878 static const struct command_registration lpc3180_exec_command_handlers
[] = {
881 .handler
= &handle_lpc3180_select_command
,
882 .mode
= COMMAND_EXEC
,
883 .help
= "select <'mlc'|'slc'> controller (default is mlc)",
884 .usage
= "<device_id> (mlc|slc)",
886 COMMAND_REGISTRATION_DONE
888 static const struct command_registration lpc3180_command_handler
[] = {
892 .help
= "LPC3180 NAND flash controller commands",
893 .chain
= lpc3180_exec_command_handlers
,
895 COMMAND_REGISTRATION_DONE
898 struct nand_flash_controller lpc3180_nand_controller
= {
900 .commands
= lpc3180_command_handler
,
901 .nand_device_command
= lpc3180_nand_device_command
,
902 .init
= lpc3180_init
,
903 .reset
= lpc3180_reset
,
904 .command
= lpc3180_command
,
905 .address
= lpc3180_address
,
906 .write_data
= lpc3180_write_data
,
907 .read_data
= lpc3180_read_data
,
908 .write_page
= lpc3180_write_page
,
909 .read_page
= lpc3180_read_page
,
910 .controller_ready
= lpc3180_controller_ready
,
911 .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)