7bcbeee0ae12562a234a2973508a740f2267286e
[openocd.git] / src / flash / lpc3180_nand_controller.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "lpc3180_nand_controller.h"
25
26 #include "replacements.h"
27 #include "log.h"
28
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "nand.h"
33 #include "target.h"
34
35 int lpc3180_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device);
36 int lpc3180_register_commands(struct command_context_s *cmd_ctx);
37 int lpc3180_init(struct nand_device_s *device);
38 int lpc3180_reset(struct nand_device_s *device);
39 int lpc3180_command(struct nand_device_s *device, u8 command);
40 int lpc3180_address(struct nand_device_s *device, u8 address);
41 int lpc3180_write_data(struct nand_device_s *device, u16 data);
42 int lpc3180_read_data(struct nand_device_s *device, void *data);
43 int lpc3180_write_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);
44 int lpc3180_read_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size);
45 int lpc3180_controller_ready(struct nand_device_s *device, int timeout);
46 int lpc3180_nand_ready(struct nand_device_s *device, int timeout);
47
48 int handle_lpc3180_select_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
49
50 nand_flash_controller_t lpc3180_nand_controller =
51 {
52 .name = "lpc3180",
53 .nand_device_command = lpc3180_nand_device_command,
54 .register_commands = lpc3180_register_commands,
55 .init = lpc3180_init,
56 .reset = lpc3180_reset,
57 .command = lpc3180_command,
58 .address = lpc3180_address,
59 .write_data = lpc3180_write_data,
60 .read_data = lpc3180_read_data,
61 .write_page = lpc3180_write_page,
62 .read_page = lpc3180_read_page,
63 .controller_ready = lpc3180_controller_ready,
64 .nand_ready = lpc3180_nand_ready,
65 };
66
67 /* nand device lpc3180 <target#> <oscillator_frequency>
68 */
69 int lpc3180_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device)
70 {
71 lpc3180_nand_controller_t *lpc3180_info;
72
73 if (argc < 3)
74 {
75 LOG_WARNING("incomplete 'lpc3180' nand flash configuration");
76 return ERROR_FLASH_BANK_INVALID;
77 }
78
79 lpc3180_info = malloc(sizeof(lpc3180_nand_controller_t));
80 device->controller_priv = lpc3180_info;
81
82 lpc3180_info->target = get_target_by_num(strtoul(args[1], NULL, 0));
83 if (!lpc3180_info->target)
84 {
85 LOG_ERROR("no target '%s' configured", args[1]);
86 return ERROR_NAND_DEVICE_INVALID;
87 }
88
89 lpc3180_info->osc_freq = strtoul(args[2], NULL, 0);
90 if ((lpc3180_info->osc_freq < 1000) || (lpc3180_info->osc_freq > 20000))
91 {
92 LOG_WARNING("LPC3180 oscillator frequency should be between 1000 and 20000 kHz, was %i", lpc3180_info->osc_freq);
93 }
94 lpc3180_info->selected_controller = LPC3180_NO_CONTROLLER;
95 lpc3180_info->sw_write_protection = 0;
96 lpc3180_info->sw_wp_lower_bound = 0x0;
97 lpc3180_info->sw_wp_upper_bound = 0x0;
98
99 return ERROR_OK;
100 }
101
102 int lpc3180_register_commands(struct command_context_s *cmd_ctx)
103 {
104 command_t *lpc3180_cmd = register_command(cmd_ctx, NULL, "lpc3180", NULL, COMMAND_ANY, "commands specific to the LPC3180 NAND flash controllers");
105
106 register_command(cmd_ctx, lpc3180_cmd, "select", handle_lpc3180_select_command, COMMAND_EXEC, "select <'mlc'|'slc'> controller (default is mlc)");
107
108 return ERROR_OK;
109 }
110
111 int lpc3180_pll(int fclkin, u32 pll_ctrl)
112 {
113 int bypass = (pll_ctrl & 0x8000) >> 15;
114 int direct = (pll_ctrl & 0x4000) >> 14;
115 int feedback = (pll_ctrl & 0x2000) >> 13;
116 int p = (1 << ((pll_ctrl & 0x1800) >> 11) * 2);
117 int n = ((pll_ctrl & 0x0600) >> 9) + 1;
118 int m = ((pll_ctrl & 0x01fe) >> 1) + 1;
119 int lock = (pll_ctrl & 0x1);
120
121 if (!lock)
122 LOG_WARNING("PLL is not locked");
123
124 if (!bypass && direct) /* direct mode */
125 return (m * fclkin) / n;
126
127 if (bypass && !direct) /* bypass mode */
128 return fclkin / (2 * p);
129
130 if (bypass & direct) /* direct bypass mode */
131 return fclkin;
132
133 if (feedback) /* integer mode */
134 return m * (fclkin / n);
135 else /* non-integer mode */
136 return (m / (2 * p)) * (fclkin / n);
137 }
138
139 float lpc3180_cycle_time(lpc3180_nand_controller_t *lpc3180_info)
140 {
141 target_t *target = lpc3180_info->target;
142 u32 sysclk_ctrl, pwr_ctrl, hclkdiv_ctrl, hclkpll_ctrl;
143 int sysclk;
144 int hclk;
145 int hclk_pll;
146 float cycle;
147
148 /* calculate timings */
149
150 /* determine current SYSCLK (13'MHz or main oscillator) */
151 target_read_u32(target, 0x40004050, &sysclk_ctrl);
152
153 if ((sysclk_ctrl & 1) == 0)
154 sysclk = lpc3180_info->osc_freq;
155 else
156 sysclk = 13000;
157
158 /* determine selected HCLK source */
159 target_read_u32(target, 0x40004044, &pwr_ctrl);
160
161 if ((pwr_ctrl & (1 << 2)) == 0) /* DIRECT RUN mode */
162 {
163 hclk = sysclk;
164 }
165 else
166 {
167 target_read_u32(target, 0x40004058, &hclkpll_ctrl);
168 hclk_pll = lpc3180_pll(sysclk, hclkpll_ctrl);
169
170 target_read_u32(target, 0x40004040, &hclkdiv_ctrl);
171
172 if (pwr_ctrl & (1 << 10)) /* ARM_CLK and HCLK use PERIPH_CLK */
173 {
174 hclk = hclk_pll / (((hclkdiv_ctrl & 0x7c) >> 2) + 1);
175 }
176 else /* HCLK uses HCLK_PLL */
177 {
178 hclk = hclk_pll / (1 << (hclkdiv_ctrl & 0x3));
179 }
180 }
181
182 LOG_DEBUG("LPC3180 HCLK currently clocked at %i kHz", hclk);
183
184 cycle = (1.0 / hclk) * 1000000.0;
185
186 return cycle;
187 }
188
189 int lpc3180_init(struct nand_device_s *device)
190 {
191 lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
192 target_t *target = lpc3180_info->target;
193 int bus_width = (device->bus_width) ? (device->bus_width) : 8;
194 int address_cycles = (device->address_cycles) ? (device->address_cycles) : 3;
195 int page_size = (device->page_size) ? (device->page_size) : 512;
196
197 if (target->state != TARGET_HALTED)
198 {
199 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
200 return ERROR_NAND_OPERATION_FAILED;
201 }
202
203 /* sanitize arguments */
204 if ((bus_width != 8) && (bus_width != 16))
205 {
206 LOG_ERROR("LPC3180 only supports 8 or 16 bit bus width, not %i", bus_width);
207 return ERROR_NAND_OPERATION_NOT_SUPPORTED;
208 }
209
210 /* The LPC3180 only brings out 8 bit NAND data bus, but the controller
211 * would support 16 bit, too, so we just warn about this for now
212 */
213 if (bus_width == 16)
214 {
215 LOG_WARNING("LPC3180 only supports 8 bit bus width");
216 }
217
218 /* inform calling code about selected bus width */
219 device->bus_width = bus_width;
220
221 if ((address_cycles != 3) && (address_cycles != 4))
222 {
223 LOG_ERROR("LPC3180 only supports 3 or 4 address cycles, not %i", address_cycles);
224 return ERROR_NAND_OPERATION_NOT_SUPPORTED;
225 }
226
227 if ((page_size != 512) && (page_size != 2048))
228 {
229 LOG_ERROR("LPC3180 only supports 512 or 2048 byte pages, not %i", page_size);
230 return ERROR_NAND_OPERATION_NOT_SUPPORTED;
231 }
232
233 /* select MLC controller if none is currently selected */
234 if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER)
235 {
236 LOG_DEBUG("no LPC3180 NAND flash controller selected, using default 'mlc'");
237 lpc3180_info->selected_controller = LPC3180_MLC_CONTROLLER;
238 }
239
240 if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
241 {
242 u32 mlc_icr_value = 0x0;
243 float cycle;
244 int twp, twh, trp, treh, trhz, trbwb, tcea;
245
246 /* FLASHCLK_CTRL = 0x22 (enable clock for MLC flash controller) */
247 target_write_u32(target, 0x400040c8, 0x22);
248
249 /* MLC_CEH = 0x0 (Force nCE assert) */
250 target_write_u32(target, 0x200b804c, 0x0);
251
252 /* MLC_LOCK = 0xa25e (unlock protected registers) */
253 target_write_u32(target, 0x200b8044, 0xa25e);
254
255 /* MLC_ICR = configuration */
256 if (lpc3180_info->sw_write_protection)
257 mlc_icr_value |= 0x8;
258 if (page_size == 2048)
259 mlc_icr_value |= 0x4;
260 if (address_cycles == 4)
261 mlc_icr_value |= 0x2;
262 if (bus_width == 16)
263 mlc_icr_value |= 0x1;
264 target_write_u32(target, 0x200b8030, mlc_icr_value);
265
266 /* calculate NAND controller timings */
267 cycle = lpc3180_cycle_time(lpc3180_info);
268
269 twp = ((40 / cycle) + 1);
270 twh = ((20 / cycle) + 1);
271 trp = ((30 / cycle) + 1);
272 treh = ((15 / cycle) + 1);
273 trhz = ((30 / cycle) + 1);
274 trbwb = ((100 / cycle) + 1);
275 tcea = ((45 / cycle) + 1);
276
277 /* MLC_LOCK = 0xa25e (unlock protected registers) */
278 target_write_u32(target, 0x200b8044, 0xa25e);
279
280 /* MLC_TIME_REG */
281 target_write_u32(target, 0x200b8034, (twp & 0xf) | ((twh & 0xf) << 4) |
282 ((trp & 0xf) << 8) | ((treh & 0xf) << 12) | ((trhz & 0x7) << 16) |
283 ((trbwb & 0x1f) << 19) | ((tcea & 0x3) << 24));
284
285 lpc3180_reset(device);
286 }
287 else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
288 {
289 float cycle;
290 int r_setup, r_hold, r_width, r_rdy;
291 int w_setup, w_hold, w_width, w_rdy;
292
293 /* FLASHCLK_CTRL = 0x05 (enable clock for SLC flash controller) */
294 target_write_u32(target, 0x400040c8, 0x05);
295
296 /* SLC_CFG = 0x (Force nCE assert, ECC enabled, WIDTH = bus_width) */
297 target_write_u32(target, 0x20020014, 0x28 | (bus_width == 16) ? 1 : 0);
298
299 /* calculate NAND controller timings */
300 cycle = lpc3180_cycle_time(lpc3180_info);
301
302 r_setup = w_setup = 0;
303 r_hold = w_hold = 10 / cycle;
304 r_width = 30 / cycle;
305 w_width = 40 / cycle;
306 r_rdy = w_rdy = 100 / cycle;
307
308 /* SLC_TAC: SLC timing arcs register */
309 target_write_u32(target, 0x2002002c, (r_setup & 0xf) | ((r_hold & 0xf) << 4) |
310 ((r_width & 0xf) << 8) | ((r_rdy & 0xf) << 12) | ((w_setup & 0xf) << 16) |
311 ((w_hold & 0xf) << 20) | ((w_width & 0xf) << 24) | ((w_rdy & 0xf) << 28));
312
313 lpc3180_reset(device);
314 }
315
316 return ERROR_OK;
317 }
318
319 int lpc3180_reset(struct nand_device_s *device)
320 {
321 lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
322 target_t *target = lpc3180_info->target;
323
324 if (target->state != TARGET_HALTED)
325 {
326 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
327 return ERROR_NAND_OPERATION_FAILED;
328 }
329
330 if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER)
331 {
332 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
333 return ERROR_NAND_OPERATION_FAILED;
334 }
335 else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
336 {
337 /* MLC_CMD = 0xff (reset controller and NAND device) */
338 target_write_u32(target, 0x200b8000, 0xff);
339
340 if (!lpc3180_controller_ready(device, 100))
341 {
342 LOG_ERROR("LPC3180 NAND controller timed out after reset");
343 return ERROR_NAND_OPERATION_TIMEOUT;
344 }
345 }
346 else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
347 {
348 /* SLC_CTRL = 0x6 (ECC_CLEAR, SW_RESET) */
349 target_write_u32(target, 0x20020010, 0x6);
350
351 if (!lpc3180_controller_ready(device, 100))
352 {
353 LOG_ERROR("LPC3180 NAND controller timed out after reset");
354 return ERROR_NAND_OPERATION_TIMEOUT;
355 }
356 }
357
358 return ERROR_OK;
359 }
360
361 int lpc3180_command(struct nand_device_s *device, u8 command)
362 {
363 lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
364 target_t *target = lpc3180_info->target;
365
366 if (target->state != TARGET_HALTED)
367 {
368 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
369 return ERROR_NAND_OPERATION_FAILED;
370 }
371
372 if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER)
373 {
374 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
375 return ERROR_NAND_OPERATION_FAILED;
376 }
377 else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
378 {
379 /* MLC_CMD = command */
380 target_write_u32(target, 0x200b8000, command);
381 }
382 else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
383 {
384 /* SLC_CMD = command */
385 target_write_u32(target, 0x20020008, command);
386 }
387
388 return ERROR_OK;
389 }
390
391 int lpc3180_address(struct nand_device_s *device, u8 address)
392 {
393 lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
394 target_t *target = lpc3180_info->target;
395
396 if (target->state != TARGET_HALTED)
397 {
398 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
399 return ERROR_NAND_OPERATION_FAILED;
400 }
401
402 if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER)
403 {
404 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
405 return ERROR_NAND_OPERATION_FAILED;
406 }
407 else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
408 {
409 /* MLC_ADDR = address */
410 target_write_u32(target, 0x200b8004, address);
411 }
412 else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
413 {
414 /* SLC_ADDR = address */
415 target_write_u32(target, 0x20020004, address);
416 }
417
418 return ERROR_OK;
419 }
420
421 int lpc3180_write_data(struct nand_device_s *device, u16 data)
422 {
423 lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
424 target_t *target = lpc3180_info->target;
425
426 if (target->state != TARGET_HALTED)
427 {
428 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
429 return ERROR_NAND_OPERATION_FAILED;
430 }
431
432 if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER)
433 {
434 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
435 return ERROR_NAND_OPERATION_FAILED;
436 }
437 else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
438 {
439 /* MLC_DATA = data */
440 target_write_u32(target, 0x200b0000, data);
441 }
442 else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
443 {
444 /* SLC_DATA = data */
445 target_write_u32(target, 0x20020000, data);
446 }
447
448 return ERROR_OK;
449 }
450
451 int lpc3180_read_data(struct nand_device_s *device, void *data)
452 {
453 lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
454 target_t *target = lpc3180_info->target;
455
456 if (target->state != TARGET_HALTED)
457 {
458 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
459 return ERROR_NAND_OPERATION_FAILED;
460 }
461
462 if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER)
463 {
464 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
465 return ERROR_NAND_OPERATION_FAILED;
466 }
467 else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
468 {
469 /* data = MLC_DATA, use sized access */
470 if (device->bus_width == 8)
471 {
472 u8 *data8 = data;
473 target_read_u8(target, 0x200b0000, data8);
474 }
475 else if (device->bus_width == 16)
476 {
477 u16 *data16 = data;
478 target_read_u16(target, 0x200b0000, data16);
479 }
480 else
481 {
482 LOG_ERROR("BUG: bus_width neither 8 nor 16 bit");
483 return ERROR_NAND_OPERATION_FAILED;
484 }
485 }
486 else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
487 {
488 u32 data32;
489
490 /* data = SLC_DATA, must use 32-bit access */
491 target_read_u32(target, 0x20020000, &data32);
492
493 if (device->bus_width == 8)
494 {
495 u8 *data8 = data;
496 *data8 = data32 & 0xff;
497 }
498 else if (device->bus_width == 16)
499 {
500 u16 *data16 = data;
501 *data16 = data32 & 0xffff;
502 }
503 else
504 {
505 LOG_ERROR("BUG: bus_width neither 8 nor 16 bit");
506 return ERROR_NAND_OPERATION_FAILED;
507 }
508 }
509
510 return ERROR_OK;
511 }
512
513 int lpc3180_write_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size)
514 {
515 lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
516 target_t *target = lpc3180_info->target;
517 int retval;
518 u8 status;
519
520 if (target->state != TARGET_HALTED)
521 {
522 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
523 return ERROR_NAND_OPERATION_FAILED;
524 }
525
526 if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER)
527 {
528 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
529 return ERROR_NAND_OPERATION_FAILED;
530 }
531 else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
532 {
533 u8 *page_buffer;
534 u8 *oob_buffer;
535 int quarter, num_quarters;
536
537 if (!data && oob)
538 {
539 LOG_ERROR("LPC3180 MLC controller can't write OOB data only");
540 return ERROR_NAND_OPERATION_NOT_SUPPORTED;
541 }
542
543 if (oob && (oob_size > 6))
544 {
545 LOG_ERROR("LPC3180 MLC controller can't write more than 6 bytes of OOB data");
546 return ERROR_NAND_OPERATION_NOT_SUPPORTED;
547 }
548
549 if (data_size > device->page_size)
550 {
551 LOG_ERROR("data size exceeds page size");
552 return ERROR_NAND_OPERATION_NOT_SUPPORTED;
553 }
554
555 /* MLC_CMD = sequential input */
556 target_write_u32(target, 0x200b8000, NAND_CMD_SEQIN);
557
558 page_buffer = malloc(512);
559 oob_buffer = malloc(6);
560
561 if (device->page_size == 512)
562 {
563 /* MLC_ADDR = 0x0 (one column cycle) */
564 target_write_u32(target, 0x200b8004, 0x0);
565
566 /* MLC_ADDR = row */
567 target_write_u32(target, 0x200b8004, page & 0xff);
568 target_write_u32(target, 0x200b8004, (page >> 8) & 0xff);
569
570 if (device->address_cycles == 4)
571 target_write_u32(target, 0x200b8004, (page >> 16) & 0xff);
572 }
573 else
574 {
575 /* MLC_ADDR = 0x0 (two column cycles) */
576 target_write_u32(target, 0x200b8004, 0x0);
577 target_write_u32(target, 0x200b8004, 0x0);
578
579 /* MLC_ADDR = row */
580 target_write_u32(target, 0x200b8004, page & 0xff);
581 target_write_u32(target, 0x200b8004, (page >> 8) & 0xff);
582 }
583
584 /* when using the MLC controller, we have to treat a large page device
585 * as being made out of four quarters, each the size of a small page device
586 */
587 num_quarters = (device->page_size == 2048) ? 4 : 1;
588
589 for (quarter = 0; quarter < num_quarters; quarter++)
590 {
591 int thisrun_data_size = (data_size > 512) ? 512 : data_size;
592 int thisrun_oob_size = (oob_size > 6) ? 6 : oob_size;
593
594 memset(page_buffer, 0xff, 512);
595 if (data)
596 {
597 memcpy(page_buffer, data, thisrun_data_size);
598 data_size -= thisrun_data_size;
599 data += thisrun_data_size;
600 }
601
602 memset(oob_buffer, 0xff, (device->page_size == 512) ? 6 : 24);
603 if (oob)
604 {
605 memcpy(page_buffer, oob, thisrun_oob_size);
606 oob_size -= thisrun_oob_size;
607 oob += thisrun_oob_size;
608 }
609
610 /* write MLC_ECC_ENC_REG to start encode cycle */
611 target_write_u32(target, 0x200b8008, 0x0);
612
613 target->type->write_memory(target, 0x200a8000, 4, 128, page_buffer + (quarter * 512));
614 target->type->write_memory(target, 0x200a8000, 1, 6, oob_buffer + (quarter * 6));
615
616 /* write MLC_ECC_AUTO_ENC_REG to start auto encode */
617 target_write_u32(target, 0x200b8010, 0x0);
618
619 if (!lpc3180_controller_ready(device, 1000))
620 {
621 LOG_ERROR("timeout while waiting for completion of auto encode cycle");
622 return ERROR_NAND_OPERATION_FAILED;
623 }
624 }
625
626 /* MLC_CMD = auto program command */
627 target_write_u32(target, 0x200b8000, NAND_CMD_PAGEPROG);
628
629 if ((retval = nand_read_status(device, &status)) != ERROR_OK)
630 {
631 LOG_ERROR("couldn't read status");
632 return ERROR_NAND_OPERATION_FAILED;
633 }
634
635 if (status & NAND_STATUS_FAIL)
636 {
637 LOG_ERROR("write operation didn't pass, status: 0x%2.2x", status);
638 return ERROR_NAND_OPERATION_FAILED;
639 }
640
641 free(page_buffer);
642 free(oob_buffer);
643 }
644 else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
645 {
646 return nand_write_page_raw(device, page, data, data_size, oob, oob_size);
647 }
648
649 return ERROR_OK;
650 }
651
652 int lpc3180_read_page(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size)
653 {
654 lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
655 target_t *target = lpc3180_info->target;
656
657 if (target->state != TARGET_HALTED)
658 {
659 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
660 return ERROR_NAND_OPERATION_FAILED;
661 }
662
663 if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER)
664 {
665 LOG_ERROR("BUG: no LPC3180 NAND flash controller selected");
666 return ERROR_NAND_OPERATION_FAILED;
667 }
668 else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
669 {
670 u8 *page_buffer;
671 u8 *oob_buffer;
672 u32 page_bytes_done = 0;
673 u32 oob_bytes_done = 0;
674 u32 mlc_isr;
675
676 #if 0
677 if (oob && (oob_size > 6))
678 {
679 LOG_ERROR("LPC3180 MLC controller can't read more than 6 bytes of OOB data");
680 return ERROR_NAND_OPERATION_NOT_SUPPORTED;
681 }
682 #endif
683
684 if (data_size > device->page_size)
685 {
686 LOG_ERROR("data size exceeds page size");
687 return ERROR_NAND_OPERATION_NOT_SUPPORTED;
688 }
689
690 if (device->page_size == 2048)
691 {
692 page_buffer = malloc(2048);
693 oob_buffer = malloc(64);
694 }
695 else
696 {
697 page_buffer = malloc(512);
698 oob_buffer = malloc(16);
699 }
700
701 if (!data && oob)
702 {
703 /* MLC_CMD = Read OOB
704 * we can use the READOOB command on both small and large page devices,
705 * as the controller translates the 0x50 command to a 0x0 with appropriate
706 * positioning of the serial buffer read pointer
707 */
708 target_write_u32(target, 0x200b8000, NAND_CMD_READOOB);
709 }
710 else
711 {
712 /* MLC_CMD = Read0 */
713 target_write_u32(target, 0x200b8000, NAND_CMD_READ0);
714 }
715
716 if (device->page_size == 512)
717 {
718 /* small page device */
719 /* MLC_ADDR = 0x0 (one column cycle) */
720 target_write_u32(target, 0x200b8004, 0x0);
721
722 /* MLC_ADDR = row */
723 target_write_u32(target, 0x200b8004, page & 0xff);
724 target_write_u32(target, 0x200b8004, (page >> 8) & 0xff);
725
726 if (device->address_cycles == 4)
727 target_write_u32(target, 0x200b8004, (page >> 16) & 0xff);
728 }
729 else
730 {
731 /* large page device */
732 /* MLC_ADDR = 0x0 (two column cycles) */
733 target_write_u32(target, 0x200b8004, 0x0);
734 target_write_u32(target, 0x200b8004, 0x0);
735
736 /* MLC_ADDR = row */
737 target_write_u32(target, 0x200b8004, page & 0xff);
738 target_write_u32(target, 0x200b8004, (page >> 8) & 0xff);
739
740 /* MLC_CMD = Read Start */
741 target_write_u32(target, 0x200b8000, NAND_CMD_READSTART);
742 }
743
744 while (page_bytes_done < device->page_size)
745 {
746 /* MLC_ECC_AUTO_DEC_REG = dummy */
747 target_write_u32(target, 0x200b8014, 0xaa55aa55);
748
749 if (!lpc3180_controller_ready(device, 1000))
750 {
751 LOG_ERROR("timeout while waiting for completion of auto decode cycle");
752 return ERROR_NAND_OPERATION_FAILED;
753 }
754
755 target_read_u32(target, 0x200b8048, &mlc_isr);
756
757 if (mlc_isr & 0x8)
758 {
759 if (mlc_isr & 0x40)
760 {
761 LOG_ERROR("uncorrectable error detected: 0x%2.2x", mlc_isr);
762 return ERROR_NAND_OPERATION_FAILED;
763 }
764
765 LOG_WARNING("%i symbol error detected and corrected", ((mlc_isr & 0x30) >> 4) + 1);
766 }
767
768 if (data)
769 {
770 target->type->read_memory(target, 0x200a8000, 4, 128, page_buffer + page_bytes_done);
771 }
772
773 if (oob)
774 {
775 target->type->read_memory(target, 0x200a8000, 4, 4, oob_buffer + oob_bytes_done);
776 }
777
778 page_bytes_done += 512;
779 oob_bytes_done += 16;
780 }
781
782 if (data)
783 memcpy(data, page_buffer, data_size);
784
785 if (oob)
786 memcpy(oob, oob_buffer, oob_size);
787
788 free(page_buffer);
789 free(oob_buffer);
790 }
791 else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
792 {
793 return nand_read_page_raw(device, page, data, data_size, oob, oob_size);
794 }
795
796 return ERROR_OK;
797 }
798
799 int lpc3180_controller_ready(struct nand_device_s *device, int timeout)
800 {
801 lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
802 target_t *target = lpc3180_info->target;
803 u8 status = 0x0;
804
805 if (target->state != TARGET_HALTED)
806 {
807 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
808 return ERROR_NAND_OPERATION_FAILED;
809 }
810
811 do
812 {
813 if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
814 {
815 /* Read MLC_ISR, wait for controller to become ready */
816 target_read_u8(target, 0x200b8048, &status);
817
818 if (status & 2)
819 return 1;
820 }
821 else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
822 {
823 /* we pretend that the SLC controller is always ready */
824 return 1;
825 }
826
827 alive_sleep(1);
828 } while (timeout-- > 0);
829
830 return 0;
831 }
832
833 int lpc3180_nand_ready(struct nand_device_s *device, int timeout)
834 {
835 lpc3180_nand_controller_t *lpc3180_info = device->controller_priv;
836 target_t *target = lpc3180_info->target;
837
838 if (target->state != TARGET_HALTED)
839 {
840 LOG_ERROR("target must be halted to use LPC3180 NAND flash controller");
841 return ERROR_NAND_OPERATION_FAILED;
842 }
843
844 do
845 {
846 if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
847 {
848 u8 status = 0x0;
849
850 /* Read MLC_ISR, wait for NAND flash device to become ready */
851 target_read_u8(target, 0x200b8048, &status);
852
853 if (status & 1)
854 return 1;
855 }
856 else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
857 {
858 u32 status = 0x0;
859
860 /* Read SLC_STAT and check READY bit */
861 target_read_u32(target, 0x20020018, &status);
862
863 if (status & 1)
864 return 1;
865 }
866
867 alive_sleep(1);
868 } while (timeout-- > 0);
869
870 return 0;
871 }
872
873 int handle_lpc3180_select_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
874 {
875 nand_device_t *device = NULL;
876 lpc3180_nand_controller_t *lpc3180_info = NULL;
877 char *selected[] =
878 {
879 "no", "mlc", "slc"
880 };
881
882 if ((argc < 1) || (argc > 2))
883 {
884 return ERROR_COMMAND_SYNTAX_ERROR;
885 }
886
887 device = get_nand_device_by_num(strtoul(args[0], NULL, 0));
888 if (!device)
889 {
890 command_print(cmd_ctx, "nand device '#%s' is out of bounds", args[0]);
891 return ERROR_OK;
892 }
893
894 lpc3180_info = device->controller_priv;
895
896 if (argc == 2)
897 {
898 if (strcmp(args[1], "mlc") == 0)
899 {
900 lpc3180_info->selected_controller = LPC3180_MLC_CONTROLLER;
901 }
902 else if (strcmp(args[1], "slc") == 0)
903 {
904 lpc3180_info->selected_controller = LPC3180_SLC_CONTROLLER;
905 }
906 else
907 {
908 return ERROR_COMMAND_SYNTAX_ERROR;
909 }
910 }
911
912 command_print(cmd_ctx, "%s controller selected", selected[lpc3180_info->selected_controller]);
913
914 return ERROR_OK;
915 }

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)