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