flash/nor/lpcspifi: Use 'bool' data type
[fw/openocd] / src / flash / nor / lpcspifi.c
1 /***************************************************************************
2  *   Copyright (C) 2012 by George Harris                                   *
3  *   george@luminairecoffee.com                                            *
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, see <http://www.gnu.org/licenses/>. *
17  ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "imp.h"
24 #include "spi.h"
25 #include <jtag/jtag.h>
26 #include <helper/time_support.h>
27 #include <target/algorithm.h>
28 #include <target/armv7m.h>
29
30 /* Offsets from ssp_base into config & data registers */
31 #define SSP_CR0         (0x00)  /* Control register 0 */
32 #define SSP_CR1         (0x04)  /* Control register 1 */
33 #define SSP_DATA        (0x08)  /* Data register (TX and RX) */
34 #define SSP_SR          (0x0C)  /* Status register */
35 #define SSP_CPSR        (0x10)  /* Clock prescale register */
36
37 /* Status register fields */
38 #define SSP_BSY         (0x00000010)
39
40 /* Timeout in ms */
41 #define SSP_CMD_TIMEOUT   (100)
42 #define SSP_PROBE_TIMEOUT (100)
43 #define SSP_MAX_TIMEOUT  (3000)
44
45 /* Size of the stack to alloc in the working area for the execution of
46  * the ROM spifi_init() function */
47 #define SPIFI_INIT_STACK_SIZE  512
48
49 struct lpcspifi_flash_bank {
50         bool probed;
51         uint32_t ssp_base;
52         uint32_t io_base;
53         uint32_t ioconfig_base;
54         uint32_t bank_num;
55         uint32_t max_spi_clock_mhz;
56         const struct flash_device *dev;
57 };
58
59 /* flash_bank lpcspifi <base> <size> <chip_width> <bus_width> <target>
60  */
61 FLASH_BANK_COMMAND_HANDLER(lpcspifi_flash_bank_command)
62 {
63         struct lpcspifi_flash_bank *lpcspifi_info;
64
65         if (CMD_ARGC < 6)
66                 return ERROR_COMMAND_SYNTAX_ERROR;
67
68         lpcspifi_info = malloc(sizeof(struct lpcspifi_flash_bank));
69         if (lpcspifi_info == NULL) {
70                 LOG_ERROR("not enough memory");
71                 return ERROR_FAIL;
72         }
73
74         bank->driver_priv = lpcspifi_info;
75         lpcspifi_info->probed = false;
76
77         return ERROR_OK;
78 }
79
80 static inline int ioconfig_write_reg(struct target *target, uint32_t ioconfig_base, uint32_t offset, uint32_t value)
81 {
82         return target_write_u32(target, ioconfig_base + offset, value);
83 }
84
85 static inline int ssp_write_reg(struct target *target, uint32_t ssp_base, uint32_t offset, uint32_t value)
86 {
87         return target_write_u32(target, ssp_base + offset, value);
88 }
89
90 static inline int io_write_reg(struct target *target, uint32_t io_base, uint32_t offset, uint32_t value)
91 {
92         return target_write_u32(target, io_base + offset, value);
93 }
94
95 static inline int ssp_read_reg(struct target *target, uint32_t ssp_base, uint32_t offset, uint32_t *value)
96 {
97         return target_read_u32(target, ssp_base + offset, value);
98 }
99
100 static int ssp_setcs(struct target *target, uint32_t io_base, unsigned int value)
101 {
102         return io_write_reg(target, io_base, 0x12ac, value ? 0xffffffff : 0x00000000);
103 }
104
105 /* Poll the SSP busy flag. When this comes back as 0, the transfer is complete
106  * and the controller is idle. */
107 static int poll_ssp_busy(struct target *target, uint32_t ssp_base, int timeout)
108 {
109         int64_t endtime;
110         uint32_t value;
111         int retval;
112
113         retval = ssp_read_reg(target, ssp_base, SSP_SR, &value);
114         if ((retval == ERROR_OK) && (value & SSP_BSY) == 0)
115                 return ERROR_OK;
116         else if (retval != ERROR_OK)
117                 return retval;
118
119         endtime = timeval_ms() + timeout;
120         do {
121                 alive_sleep(1);
122                 retval = ssp_read_reg(target, ssp_base, SSP_SR, &value);
123                 if ((retval == ERROR_OK) && (value & SSP_BSY) == 0)
124                         return ERROR_OK;
125                 else if (retval != ERROR_OK)
126                         return retval;
127         } while (timeval_ms() < endtime);
128
129         LOG_ERROR("Timeout while polling BSY");
130         return ERROR_FLASH_OPERATION_FAILED;
131 }
132
133 /* Un-initialize the ssp module and initialize the SPIFI module */
134 static int lpcspifi_set_hw_mode(struct flash_bank *bank)
135 {
136         struct target *target = bank->target;
137         struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
138         uint32_t ssp_base = lpcspifi_info->ssp_base;
139         struct armv7m_algorithm armv7m_info;
140         struct working_area *spifi_init_algorithm;
141         struct reg_param reg_params[2];
142         int retval = ERROR_OK;
143
144         LOG_DEBUG("Uninitializing LPC43xx SSP");
145         /* Turn off the SSP module */
146         retval = ssp_write_reg(target, ssp_base, SSP_CR1, 0x00000000);
147         if (retval != ERROR_OK)
148                 return retval;
149
150         /* see contrib/loaders/flash/lpcspifi_init.S for src */
151         static const uint8_t spifi_init_code[] = {
152                 0x4f, 0xea, 0x00, 0x08, 0xa1, 0xb0, 0x00, 0xaf,
153                 0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03,
154                 0x4f, 0xf0, 0xf3, 0x02, 0xc3, 0xf8, 0x8c, 0x21,
155                 0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03,
156                 0x4f, 0xf4, 0xc0, 0x42, 0xc4, 0xf2, 0x08, 0x02,
157                 0x4f, 0xf4, 0xc0, 0x41, 0xc4, 0xf2, 0x08, 0x01,
158                 0x4f, 0xf4, 0xc0, 0x40, 0xc4, 0xf2, 0x08, 0x00,
159                 0x4f, 0xf0, 0xd3, 0x04, 0xc0, 0xf8, 0x9c, 0x41,
160                 0x20, 0x46, 0xc1, 0xf8, 0x98, 0x01, 0x01, 0x46,
161                 0xc2, 0xf8, 0x94, 0x11, 0xc3, 0xf8, 0x90, 0x11,
162                 0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03,
163                 0x4f, 0xf0, 0x13, 0x02, 0xc3, 0xf8, 0xa0, 0x21,
164                 0x40, 0xf2, 0x18, 0x13, 0xc1, 0xf2, 0x40, 0x03,
165                 0x1b, 0x68, 0x1c, 0x68, 0x40, 0xf2, 0xb4, 0x30,
166                 0xc1, 0xf2, 0x00, 0x00, 0x4f, 0xf0, 0x03, 0x01,
167                 0x4f, 0xf0, 0xc0, 0x02, 0x4f, 0xea, 0x08, 0x03,
168                 0xa0, 0x47, 0x00, 0xf0, 0x00, 0xb8, 0x00, 0xbe
169         };
170
171         armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
172         armv7m_info.core_mode = ARM_MODE_THREAD;
173
174
175         LOG_DEBUG("Allocating working area for SPIFI init algorithm");
176         /* Get memory for spifi initialization algorithm */
177         retval = target_alloc_working_area(target, sizeof(spifi_init_code)
178                 + SPIFI_INIT_STACK_SIZE, &spifi_init_algorithm);
179         if (retval != ERROR_OK) {
180                 LOG_ERROR("Insufficient working area to initialize SPIFI "
181                         "module. You must allocate at least %zdB of working "
182                         "area in order to use this driver.",
183                         sizeof(spifi_init_code) + SPIFI_INIT_STACK_SIZE
184                 );
185
186                 return retval;
187         }
188
189         LOG_DEBUG("Writing algorithm to working area at " TARGET_ADDR_FMT,
190                 spifi_init_algorithm->address);
191         /* Write algorithm to working area */
192         retval = target_write_buffer(target,
193                 spifi_init_algorithm->address,
194                 sizeof(spifi_init_code),
195                 spifi_init_code
196         );
197
198         if (retval != ERROR_OK) {
199                 target_free_working_area(target, spifi_init_algorithm);
200                 return retval;
201         }
202
203         init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);            /* spifi clk speed */
204         /* the spifi_init() rom API makes use of the stack */
205         init_reg_param(&reg_params[1], "sp", 32, PARAM_OUT);
206
207         /* For now, the algorithm will set up the SPIFI module
208          * @ the IRC clock speed. In the future, it could be made
209          * a bit smarter to use other clock sources if the user has
210          * already configured them in order to speed up memory-
211          * mapped reads. */
212         buf_set_u32(reg_params[0].value, 0, 32, 12);
213         /* valid stack pointer */
214         buf_set_u32(reg_params[1].value, 0, 32, (spifi_init_algorithm->address +
215                 sizeof(spifi_init_code) + SPIFI_INIT_STACK_SIZE) & ~7UL);
216
217         /* Run the algorithm */
218         LOG_DEBUG("Running SPIFI init algorithm");
219         retval = target_run_algorithm(target, 0 , NULL, 2, reg_params,
220                 spifi_init_algorithm->address,
221                 spifi_init_algorithm->address + sizeof(spifi_init_code) - 2,
222                 1000, &armv7m_info);
223
224         if (retval != ERROR_OK)
225                 LOG_ERROR("Error executing SPIFI init algorithm");
226
227         target_free_working_area(target, spifi_init_algorithm);
228
229         destroy_reg_param(&reg_params[0]);
230         destroy_reg_param(&reg_params[1]);
231
232         return retval;
233 }
234
235 /* Initialize the ssp module */
236 static int lpcspifi_set_sw_mode(struct flash_bank *bank)
237 {
238         struct target *target = bank->target;
239         struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
240         uint32_t ssp_base = lpcspifi_info->ssp_base;
241         uint32_t io_base = lpcspifi_info->io_base;
242         uint32_t ioconfig_base = lpcspifi_info->ioconfig_base;
243         int retval = ERROR_OK;
244
245         /* Re-initialize SPIFI. There are a couple of errata on this, so this makes
246         sure that nothing's in an unhappy state. */
247         retval = lpcspifi_set_hw_mode(bank);
248
249         /* If we couldn't initialize hardware mode, don't even bother continuing */
250         if (retval != ERROR_OK)
251                 return retval;
252
253         /* Initialize the pins */
254         retval = ioconfig_write_reg(target, ioconfig_base, 0x194, 0x00000040);
255         if (retval == ERROR_OK)
256                 retval = ioconfig_write_reg(target, ioconfig_base, 0x1a0, 0x00000044);
257         if (retval == ERROR_OK)
258                 retval = ioconfig_write_reg(target, ioconfig_base, 0x190, 0x00000040);
259         if (retval == ERROR_OK)
260                 retval = ioconfig_write_reg(target, ioconfig_base, 0x19c, 0x000000ed);
261         if (retval == ERROR_OK)
262                 retval = ioconfig_write_reg(target, ioconfig_base, 0x198, 0x000000ed);
263         if (retval == ERROR_OK)
264                 retval = ioconfig_write_reg(target, ioconfig_base, 0x18c, 0x000000ea);
265
266         /* Set CS high & as an output */
267         if (retval == ERROR_OK)
268                 retval = io_write_reg(target, io_base, 0x12ac, 0xffffffff);
269         if (retval == ERROR_OK)
270                 retval = io_write_reg(target, io_base, 0x2014, 0x00000800);
271
272         /* Initialize the module */
273         if (retval == ERROR_OK)
274                 retval = ssp_write_reg(target, ssp_base, SSP_CR0, 0x00000007);
275         if (retval == ERROR_OK)
276                 retval = ssp_write_reg(target, ssp_base, SSP_CR1, 0x00000000);
277         if (retval == ERROR_OK)
278                 retval = ssp_write_reg(target, ssp_base, SSP_CPSR, 0x00000008);
279         if (retval == ERROR_OK)
280                 retval = ssp_write_reg(target, ssp_base, SSP_CR1, 0x00000002);
281
282         /* If something didn't work out, attempt to return SPIFI to HW mode */
283         if (retval != ERROR_OK)
284                 lpcspifi_set_hw_mode(bank);
285
286         return retval;
287 }
288
289 /* Read the status register of the external SPI flash chip. */
290 static int read_status_reg(struct flash_bank *bank, uint32_t *status)
291 {
292         struct target *target = bank->target;
293         struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
294         uint32_t ssp_base = lpcspifi_info->ssp_base;
295         uint32_t io_base = lpcspifi_info->io_base;
296         uint32_t value;
297         int retval = ERROR_OK;
298
299         retval = ssp_setcs(target, io_base, 0);
300         if (retval == ERROR_OK)
301                 retval = ssp_write_reg(target, ssp_base, SSP_DATA, SPIFLASH_READ_STATUS);
302         if (retval == ERROR_OK)
303                 retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);
304         if (retval == ERROR_OK)
305                 retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
306         /* Dummy write to clock in the register */
307         if (retval == ERROR_OK)
308                 retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
309         if (retval == ERROR_OK)
310                 retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);
311         if (retval == ERROR_OK)
312                 retval = ssp_setcs(target, io_base, 1);
313
314         if (retval == ERROR_OK)
315                 retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
316         if (retval == ERROR_OK)
317                 *status = value;
318
319         return retval;
320 }
321
322 /* check for BSY bit in flash status register */
323 /* timeout in ms */
324 static int wait_till_ready(struct flash_bank *bank, int timeout)
325 {
326         uint32_t status;
327         int retval;
328         int64_t endtime;
329
330         endtime = timeval_ms() + timeout;
331         do {
332                 /* read flash status register */
333                 retval = read_status_reg(bank, &status);
334                 if (retval != ERROR_OK)
335                         return retval;
336
337                 if ((status & SPIFLASH_BSY_BIT) == 0)
338                         return ERROR_OK;
339                 alive_sleep(1);
340         } while (timeval_ms() < endtime);
341
342         LOG_ERROR("timeout waiting for flash to finish write/erase operation");
343         return ERROR_FAIL;
344 }
345
346 /* Send "write enable" command to SPI flash chip. */
347 static int lpcspifi_write_enable(struct flash_bank *bank)
348 {
349         struct target *target = bank->target;
350         struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
351         uint32_t ssp_base = lpcspifi_info->ssp_base;
352         uint32_t io_base = lpcspifi_info->io_base;
353         uint32_t status, value;
354         int retval = ERROR_OK;
355
356         retval = ssp_setcs(target, io_base, 0);
357         if (retval == ERROR_OK)
358                 retval = ssp_write_reg(target, ssp_base, SSP_DATA, SPIFLASH_WRITE_ENABLE);
359         if (retval == ERROR_OK)
360                 retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);
361         if (retval == ERROR_OK)
362                 retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
363         if (retval == ERROR_OK)
364                 retval = ssp_setcs(target, io_base, 1);
365
366         /* read flash status register */
367         if (retval == ERROR_OK)
368                 retval = read_status_reg(bank, &status);
369         if (retval != ERROR_OK)
370                 return retval;
371
372         /* Check write enabled */
373         if ((status & SPIFLASH_WE_BIT) == 0) {
374                 LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32, status);
375                 return ERROR_FAIL;
376         }
377
378         return retval;
379 }
380
381 static int lpcspifi_bulk_erase(struct flash_bank *bank)
382 {
383         struct target *target = bank->target;
384         struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
385         uint32_t ssp_base = lpcspifi_info->ssp_base;
386         uint32_t io_base = lpcspifi_info->io_base;
387         uint32_t value;
388         int retval = ERROR_OK;
389
390         if (lpcspifi_info->dev->chip_erase_cmd == 0x00)
391                 return ERROR_FLASH_OPER_UNSUPPORTED;
392
393         retval = lpcspifi_set_sw_mode(bank);
394
395         if (retval == ERROR_OK)
396                 retval = lpcspifi_write_enable(bank);
397
398         /* send SPI command "bulk erase" */
399         if (retval == ERROR_OK)
400                 ssp_setcs(target, io_base, 0);
401         if (retval == ERROR_OK)
402                 retval = ssp_write_reg(target, ssp_base, SSP_DATA, lpcspifi_info->dev->chip_erase_cmd);
403         if (retval == ERROR_OK)
404                 retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);
405         if (retval == ERROR_OK)
406                 retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
407         if (retval == ERROR_OK)
408                 retval = ssp_setcs(target, io_base, 1);
409
410         /* poll flash BSY for self-timed bulk erase */
411         if (retval == ERROR_OK)
412                 retval = wait_till_ready(bank, bank->num_sectors*SSP_MAX_TIMEOUT);
413
414         return retval;
415 }
416
417 static int lpcspifi_erase(struct flash_bank *bank, unsigned int first,
418                 unsigned int last)
419 {
420         struct target *target = bank->target;
421         struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
422         struct reg_param reg_params[4];
423         struct armv7m_algorithm armv7m_info;
424         struct working_area *erase_algorithm;
425         int retval = ERROR_OK;
426
427         LOG_DEBUG("erase from sector %u to sector %u", first, last);
428
429         if (target->state != TARGET_HALTED) {
430                 LOG_ERROR("Target not halted");
431                 return ERROR_TARGET_NOT_HALTED;
432         }
433
434         if ((last < first) || (last >= bank->num_sectors)) {
435                 LOG_ERROR("Flash sector invalid");
436                 return ERROR_FLASH_SECTOR_INVALID;
437         }
438
439         if (!(lpcspifi_info->probed)) {
440                 LOG_ERROR("Flash bank not probed");
441                 return ERROR_FLASH_BANK_NOT_PROBED;
442         }
443
444         for (unsigned int sector = first; sector <= last; sector++) {
445                 if (bank->sectors[sector].is_protected) {
446                         LOG_ERROR("Flash sector %u protected", sector);
447                         return ERROR_FAIL;
448                 }
449         }
450
451         /* If we're erasing the entire chip and the flash supports
452          * it, use a bulk erase instead of going sector-by-sector. */
453         if (first == 0 && last == (bank->num_sectors - 1)
454                 && lpcspifi_info->dev->chip_erase_cmd != lpcspifi_info->dev->erase_cmd) {
455                 LOG_DEBUG("Chip supports the bulk erase command."
456                 " Will use bulk erase instead of sector-by-sector erase.");
457                 retval = lpcspifi_bulk_erase(bank);
458
459                 if (retval == ERROR_OK) {
460                         retval = lpcspifi_set_hw_mode(bank);
461                         return retval;
462                 } else
463                         LOG_WARNING("Bulk flash erase failed. Falling back to sector-by-sector erase.");
464         }
465
466         if (lpcspifi_info->dev->erase_cmd == 0x00)
467                 return ERROR_FLASH_OPER_UNSUPPORTED;
468
469         retval = lpcspifi_set_hw_mode(bank);
470         if (retval != ERROR_OK)
471                 return retval;
472
473         /* see contrib/loaders/flash/lpcspifi_erase.S for src */
474         static const uint8_t lpcspifi_flash_erase_code[] = {
475                 0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x08, 0x0a,
476                 0x4f, 0xf0, 0xea, 0x08, 0xca, 0xf8, 0x8c, 0x81,
477                 0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x90, 0x81,
478                 0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x94, 0x81,
479                 0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x98, 0x81,
480                 0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x9c, 0x81,
481                 0x4f, 0xf0, 0x44, 0x08, 0xca, 0xf8, 0xa0, 0x81,
482                 0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
483                 0x4f, 0xf4, 0x00, 0x68, 0xca, 0xf8, 0x14, 0x80,
484                 0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
485                 0x4f, 0xf0, 0xff, 0x08, 0xca, 0xf8, 0xab, 0x80,
486                 0x4f, 0xf0, 0x00, 0x0a, 0xc4, 0xf2, 0x05, 0x0a,
487                 0x4f, 0xf0, 0x00, 0x08, 0xc0, 0xf2, 0x00, 0x18,
488                 0xca, 0xf8, 0x94, 0x80, 0x4f, 0xf4, 0x00, 0x5a,
489                 0xc4, 0xf2, 0x05, 0x0a, 0x4f, 0xf0, 0x01, 0x08,
490                 0xca, 0xf8, 0x00, 0x87, 0x4f, 0xf4, 0x40, 0x5a,
491                 0xc4, 0xf2, 0x08, 0x0a, 0x4f, 0xf0, 0x07, 0x08,
492                 0xca, 0xf8, 0x00, 0x80, 0x4f, 0xf0, 0x02, 0x08,
493                 0xca, 0xf8, 0x10, 0x80, 0xca, 0xf8, 0x04, 0x80,
494                 0x00, 0xf0, 0x52, 0xf8, 0x4f, 0xf0, 0x06, 0x09,
495                 0x00, 0xf0, 0x3b, 0xf8, 0x00, 0xf0, 0x48, 0xf8,
496                 0x00, 0xf0, 0x4a, 0xf8, 0x4f, 0xf0, 0x05, 0x09,
497                 0x00, 0xf0, 0x33, 0xf8, 0x4f, 0xf0, 0x00, 0x09,
498                 0x00, 0xf0, 0x2f, 0xf8, 0x00, 0xf0, 0x3c, 0xf8,
499                 0x19, 0xf0, 0x02, 0x0f, 0x00, 0xf0, 0x45, 0x80,
500                 0x00, 0xf0, 0x3a, 0xf8, 0x4f, 0xea, 0x02, 0x09,
501                 0x00, 0xf0, 0x23, 0xf8, 0x4f, 0xea, 0x10, 0x49,
502                 0x00, 0xf0, 0x1f, 0xf8, 0x4f, 0xea, 0x10, 0x29,
503                 0x00, 0xf0, 0x1b, 0xf8, 0x4f, 0xea, 0x00, 0x09,
504                 0x00, 0xf0, 0x17, 0xf8, 0x00, 0xf0, 0x24, 0xf8,
505                 0x00, 0xf0, 0x26, 0xf8, 0x4f, 0xf0, 0x05, 0x09,
506                 0x00, 0xf0, 0x0f, 0xf8, 0x4f, 0xf0, 0x00, 0x09,
507                 0x00, 0xf0, 0x0b, 0xf8, 0x00, 0xf0, 0x18, 0xf8,
508                 0x19, 0xf0, 0x01, 0x0f, 0x7f, 0xf4, 0xf0, 0xaf,
509                 0x01, 0x39, 0xf9, 0xb1, 0x18, 0x44, 0xff, 0xf7,
510                 0xbf, 0xbf, 0x4f, 0xf4, 0x40, 0x5a, 0xc4, 0xf2,
511                 0x08, 0x0a, 0xca, 0xf8, 0x08, 0x90, 0xda, 0xf8,
512                 0x0c, 0x90, 0x19, 0xf0, 0x10, 0x0f, 0x7f, 0xf4,
513                 0xfa, 0xaf, 0xda, 0xf8, 0x08, 0x90, 0x70, 0x47,
514                 0x4f, 0xf0, 0xff, 0x08, 0x00, 0xf0, 0x02, 0xb8,
515                 0x4f, 0xf0, 0x00, 0x08, 0x4f, 0xf4, 0x80, 0x4a,
516                 0xc4, 0xf2, 0x0f, 0x0a, 0xca, 0xf8, 0xab, 0x80,
517                 0x70, 0x47, 0x00, 0x20, 0x00, 0xbe, 0xff, 0xff
518         };
519
520         armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
521         armv7m_info.core_mode = ARM_MODE_THREAD;
522
523
524         /* Get memory for spifi initialization algorithm */
525         retval = target_alloc_working_area(target, sizeof(lpcspifi_flash_erase_code),
526                 &erase_algorithm);
527         if (retval != ERROR_OK) {
528                 LOG_ERROR("Insufficient working area. You must configure a working"
529                         " area of at least %zdB in order to erase SPIFI flash.",
530                         sizeof(lpcspifi_flash_erase_code));
531                 return retval;
532         }
533
534         /* Write algorithm to working area */
535         retval = target_write_buffer(target, erase_algorithm->address,
536                 sizeof(lpcspifi_flash_erase_code), lpcspifi_flash_erase_code);
537         if (retval != ERROR_OK) {
538                 target_free_working_area(target, erase_algorithm);
539                 return retval;
540         }
541
542         init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* Start address */
543         init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);    /* Sector count */
544         init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);    /* Erase command */
545         init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);    /* Sector size */
546
547         buf_set_u32(reg_params[0].value, 0, 32, bank->sectors[first].offset);
548         buf_set_u32(reg_params[1].value, 0, 32, last - first + 1);
549         buf_set_u32(reg_params[2].value, 0, 32, lpcspifi_info->dev->erase_cmd);
550         buf_set_u32(reg_params[3].value, 0, 32, bank->sectors[first].size);
551
552         /* Run the algorithm */
553         retval = target_run_algorithm(target, 0 , NULL, 4, reg_params,
554                 erase_algorithm->address,
555                 erase_algorithm->address + sizeof(lpcspifi_flash_erase_code) - 4,
556                 3000*(last - first + 1), &armv7m_info);
557
558         if (retval != ERROR_OK)
559                 LOG_ERROR("Error executing flash erase algorithm");
560
561         target_free_working_area(target, erase_algorithm);
562
563         destroy_reg_param(&reg_params[0]);
564         destroy_reg_param(&reg_params[1]);
565         destroy_reg_param(&reg_params[2]);
566         destroy_reg_param(&reg_params[3]);
567
568         retval = lpcspifi_set_hw_mode(bank);
569
570         return retval;
571 }
572
573 static int lpcspifi_protect(struct flash_bank *bank, int set,
574         unsigned int first, unsigned int last)
575 {
576         for (unsigned int sector = first; sector <= last; sector++)
577                 bank->sectors[sector].is_protected = set;
578         return ERROR_OK;
579 }
580
581 static int lpcspifi_write(struct flash_bank *bank, const uint8_t *buffer,
582         uint32_t offset, uint32_t count)
583 {
584         struct target *target = bank->target;
585         struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
586         uint32_t page_size, fifo_size;
587         struct working_area *fifo;
588         struct reg_param reg_params[5];
589         struct armv7m_algorithm armv7m_info;
590         struct working_area *write_algorithm;
591         int retval = ERROR_OK;
592
593         LOG_DEBUG("offset=0x%08" PRIx32 " count=0x%08" PRIx32,
594                 offset, count);
595
596         if (target->state != TARGET_HALTED) {
597                 LOG_ERROR("Target not halted");
598                 return ERROR_TARGET_NOT_HALTED;
599         }
600
601         if (offset + count > lpcspifi_info->dev->size_in_bytes) {
602                 LOG_WARNING("Writes past end of flash. Extra data discarded.");
603                 count = lpcspifi_info->dev->size_in_bytes - offset;
604         }
605
606         /* Check sector protection */
607         for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
608                 /* Start offset in or before this sector? */
609                 /* End offset in or behind this sector? */
610                 if ((offset <
611                                 (bank->sectors[sector].offset + bank->sectors[sector].size))
612                         && ((offset + count - 1) >= bank->sectors[sector].offset)
613                         && bank->sectors[sector].is_protected) {
614                         LOG_ERROR("Flash sector %u protected", sector);
615                         return ERROR_FAIL;
616                 }
617         }
618
619         /* if no valid page_size, use reasonable default */
620         page_size = lpcspifi_info->dev->pagesize ?
621                 lpcspifi_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;
622
623         retval = lpcspifi_set_hw_mode(bank);
624         if (retval != ERROR_OK)
625                 return retval;
626
627         /* see contrib/loaders/flash/lpcspifi_write.S for src */
628         static const uint8_t lpcspifi_flash_write_code[] = {
629                 0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x08, 0x0a,
630                 0x4f, 0xf0, 0xea, 0x08, 0xca, 0xf8, 0x8c, 0x81,
631                 0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x90, 0x81,
632                 0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x94, 0x81,
633                 0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x98, 0x81,
634                 0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x9c, 0x81,
635                 0x4f, 0xf0, 0x44, 0x08, 0xca, 0xf8, 0xa0, 0x81,
636                 0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
637                 0x4f, 0xf4, 0x00, 0x68, 0xca, 0xf8, 0x14, 0x80,
638                 0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
639                 0x4f, 0xf0, 0xff, 0x08, 0xca, 0xf8, 0xab, 0x80,
640                 0x4f, 0xf0, 0x00, 0x0a, 0xc4, 0xf2, 0x05, 0x0a,
641                 0x4f, 0xf0, 0x00, 0x08, 0xc0, 0xf2, 0x00, 0x18,
642                 0xca, 0xf8, 0x94, 0x80, 0x4f, 0xf4, 0x00, 0x5a,
643                 0xc4, 0xf2, 0x05, 0x0a, 0x4f, 0xf0, 0x01, 0x08,
644                 0xca, 0xf8, 0x00, 0x87, 0x4f, 0xf4, 0x40, 0x5a,
645                 0xc4, 0xf2, 0x08, 0x0a, 0x4f, 0xf0, 0x07, 0x08,
646                 0xca, 0xf8, 0x00, 0x80, 0x4f, 0xf0, 0x02, 0x08,
647                 0xca, 0xf8, 0x10, 0x80, 0xca, 0xf8, 0x04, 0x80,
648                 0x4f, 0xf0, 0x00, 0x0b, 0xa3, 0x44, 0x93, 0x45,
649                 0x7f, 0xf6, 0xfc, 0xaf, 0x00, 0xf0, 0x6a, 0xf8,
650                 0x4f, 0xf0, 0x06, 0x09, 0x00, 0xf0, 0x53, 0xf8,
651                 0x00, 0xf0, 0x60, 0xf8, 0x00, 0xf0, 0x62, 0xf8,
652                 0x4f, 0xf0, 0x05, 0x09, 0x00, 0xf0, 0x4b, 0xf8,
653                 0x4f, 0xf0, 0x00, 0x09, 0x00, 0xf0, 0x47, 0xf8,
654                 0x00, 0xf0, 0x54, 0xf8, 0x19, 0xf0, 0x02, 0x0f,
655                 0x00, 0xf0, 0x5d, 0x80, 0x00, 0xf0, 0x52, 0xf8,
656                 0x4f, 0xf0, 0x02, 0x09, 0x00, 0xf0, 0x3b, 0xf8,
657                 0x4f, 0xea, 0x12, 0x49, 0x00, 0xf0, 0x37, 0xf8,
658                 0x4f, 0xea, 0x12, 0x29, 0x00, 0xf0, 0x33, 0xf8,
659                 0x4f, 0xea, 0x02, 0x09, 0x00, 0xf0, 0x2f, 0xf8,
660                 0xd0, 0xf8, 0x00, 0x80, 0xb8, 0xf1, 0x00, 0x0f,
661                 0x00, 0xf0, 0x47, 0x80, 0x47, 0x68, 0x47, 0x45,
662                 0x3f, 0xf4, 0xf6, 0xaf, 0x17, 0xf8, 0x01, 0x9b,
663                 0x00, 0xf0, 0x21, 0xf8, 0x8f, 0x42, 0x28, 0xbf,
664                 0x00, 0xf1, 0x08, 0x07, 0x47, 0x60, 0x01, 0x3b,
665                 0xbb, 0xb3, 0x02, 0xf1, 0x01, 0x02, 0x93, 0x45,
666                 0x7f, 0xf4, 0xe6, 0xaf, 0x00, 0xf0, 0x22, 0xf8,
667                 0xa3, 0x44, 0x00, 0xf0, 0x23, 0xf8, 0x4f, 0xf0,
668                 0x05, 0x09, 0x00, 0xf0, 0x0c, 0xf8, 0x4f, 0xf0,
669                 0x00, 0x09, 0x00, 0xf0, 0x08, 0xf8, 0x00, 0xf0,
670                 0x15, 0xf8, 0x19, 0xf0, 0x01, 0x0f, 0x7f, 0xf4,
671                 0xf0, 0xaf, 0xff, 0xf7, 0xa7, 0xbf, 0x4f, 0xf4,
672                 0x40, 0x5a, 0xc4, 0xf2, 0x08, 0x0a, 0xca, 0xf8,
673                 0x08, 0x90, 0xda, 0xf8, 0x0c, 0x90, 0x19, 0xf0,
674                 0x10, 0x0f, 0x7f, 0xf4, 0xfa, 0xaf, 0xda, 0xf8,
675                 0x08, 0x90, 0x70, 0x47, 0x4f, 0xf0, 0xff, 0x08,
676                 0x00, 0xf0, 0x02, 0xb8, 0x4f, 0xf0, 0x00, 0x08,
677                 0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,
678                 0xca, 0xf8, 0xab, 0x80, 0x70, 0x47, 0x00, 0x20,
679                 0x50, 0x60, 0xff, 0xf7, 0xef, 0xff, 0x30, 0x46,
680                 0x00, 0xbe, 0xff, 0xff
681         };
682
683         if (target_alloc_working_area(target, sizeof(lpcspifi_flash_write_code),
684                         &write_algorithm) != ERROR_OK) {
685                 LOG_ERROR("Insufficient working area. You must configure"
686                         " a working area > %zdB in order to write to SPIFI flash.",
687                         sizeof(lpcspifi_flash_write_code));
688                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
689         }
690
691         retval = target_write_buffer(target, write_algorithm->address,
692                         sizeof(lpcspifi_flash_write_code),
693                         lpcspifi_flash_write_code);
694         if (retval != ERROR_OK) {
695                 target_free_working_area(target, write_algorithm);
696                 return retval;
697         }
698
699         /* FIFO allocation */
700         fifo_size = target_get_working_area_avail(target);
701
702         if (fifo_size == 0) {
703                 /* if we already allocated the writing code but failed to get fifo
704                  * space, free the algorithm */
705                 target_free_working_area(target, write_algorithm);
706
707                 LOG_ERROR("Insufficient working area. Please allocate at least"
708                         " %zdB of working area to enable flash writes.",
709                         sizeof(lpcspifi_flash_write_code) + 1
710                 );
711
712                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
713         } else if (fifo_size < page_size)
714                 LOG_WARNING("Working area size is limited; flash writes may be"
715                         " slow. Increase working area size to at least %zdB"
716                         " to reduce write times.",
717                         (size_t)(sizeof(lpcspifi_flash_write_code) + page_size)
718                 );
719         else if (fifo_size > 0x2000) /* Beyond this point, we start to get diminishing returns */
720                 fifo_size = 0x2000;
721
722         if (target_alloc_working_area(target, fifo_size, &fifo) != ERROR_OK) {
723                 target_free_working_area(target, write_algorithm);
724                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
725         }
726
727         armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
728         armv7m_info.core_mode = ARM_MODE_THREAD;
729
730         init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);         /* buffer start, status (out) */
731         init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);            /* buffer end */
732         init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);            /* target address */
733         init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);            /* count (halfword-16bit) */
734         init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT);            /* page size */
735
736         buf_set_u32(reg_params[0].value, 0, 32, fifo->address);
737         buf_set_u32(reg_params[1].value, 0, 32, fifo->address + fifo->size);
738         buf_set_u32(reg_params[2].value, 0, 32, offset);
739         buf_set_u32(reg_params[3].value, 0, 32, count);
740         buf_set_u32(reg_params[4].value, 0, 32, page_size);
741
742         retval = target_run_flash_async_algorithm(target, buffer, count, 1,
743                         0, NULL,
744                         5, reg_params,
745                         fifo->address, fifo->size,
746                         write_algorithm->address, 0,
747                         &armv7m_info
748         );
749
750         if (retval != ERROR_OK)
751                 LOG_ERROR("Error executing flash write algorithm");
752
753         target_free_working_area(target, fifo);
754         target_free_working_area(target, write_algorithm);
755
756         destroy_reg_param(&reg_params[0]);
757         destroy_reg_param(&reg_params[1]);
758         destroy_reg_param(&reg_params[2]);
759         destroy_reg_param(&reg_params[3]);
760         destroy_reg_param(&reg_params[4]);
761
762         /* Switch to HW mode before return to prompt */
763         retval = lpcspifi_set_hw_mode(bank);
764         return retval;
765 }
766
767 /* Return ID of flash device */
768 /* On exit, SW mode is kept */
769 static int lpcspifi_read_flash_id(struct flash_bank *bank, uint32_t *id)
770 {
771         struct target *target = bank->target;
772         struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
773         uint32_t ssp_base = lpcspifi_info->ssp_base;
774         uint32_t io_base = lpcspifi_info->io_base;
775         uint32_t value;
776         uint8_t id_buf[3] = {0, 0, 0};
777         int retval;
778
779         if (target->state != TARGET_HALTED) {
780                 LOG_ERROR("Target not halted");
781                 return ERROR_TARGET_NOT_HALTED;
782         }
783
784         LOG_DEBUG("Getting ID");
785         retval = lpcspifi_set_sw_mode(bank);
786         if (retval != ERROR_OK)
787                 return retval;
788
789         /* poll WIP */
790         if (retval == ERROR_OK)
791                 retval = wait_till_ready(bank, SSP_PROBE_TIMEOUT);
792
793         /* Send SPI command "read ID" */
794         if (retval == ERROR_OK)
795                 retval = ssp_setcs(target, io_base, 0);
796         if (retval == ERROR_OK)
797                 retval = ssp_write_reg(target, ssp_base, SSP_DATA, SPIFLASH_READ_ID);
798         if (retval == ERROR_OK)
799                 retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);
800         if (retval == ERROR_OK)
801                 retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
802
803         /* Dummy write to clock in data */
804         if (retval == ERROR_OK)
805                 retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
806         if (retval == ERROR_OK)
807                 retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);
808         if (retval == ERROR_OK)
809                 retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
810         if (retval == ERROR_OK)
811                 id_buf[0] = value;
812
813         /* Dummy write to clock in data */
814         if (retval == ERROR_OK)
815                 retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
816         if (retval == ERROR_OK)
817                 retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);
818         if (retval == ERROR_OK)
819                 retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
820         if (retval == ERROR_OK)
821                 id_buf[1] = value;
822
823         /* Dummy write to clock in data */
824         if (retval == ERROR_OK)
825                 retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);
826         if (retval == ERROR_OK)
827                 retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);
828         if (retval == ERROR_OK)
829                 retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
830         if (retval == ERROR_OK)
831                 id_buf[2] = value;
832
833         if (retval == ERROR_OK)
834                 retval = ssp_setcs(target, io_base, 1);
835         if (retval == ERROR_OK)
836                 *id = id_buf[2] << 16 | id_buf[1] << 8 | id_buf[0];
837
838         return retval;
839 }
840
841 static int lpcspifi_probe(struct flash_bank *bank)
842 {
843         struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
844         struct flash_sector *sectors;
845         uint32_t id = 0; /* silence uninitialized warning */
846         int retval;
847         uint32_t sectorsize;
848
849         /* If we've already probed, we should be fine to skip this time. */
850         if (lpcspifi_info->probed)
851                 return ERROR_OK;
852         lpcspifi_info->probed = false;
853
854         lpcspifi_info->ssp_base = 0x40083000;
855         lpcspifi_info->io_base = 0x400F4000;
856         lpcspifi_info->ioconfig_base = 0x40086000;
857         lpcspifi_info->bank_num = bank->bank_number;
858
859         /* read and decode flash ID; returns in SW mode */
860         retval = lpcspifi_read_flash_id(bank, &id);
861         if (retval != ERROR_OK)
862                 return retval;
863
864         retval = lpcspifi_set_hw_mode(bank);
865         if (retval != ERROR_OK)
866                 return retval;
867
868         lpcspifi_info->dev = NULL;
869         for (const struct flash_device *p = flash_devices; p->name ; p++)
870                 if (p->device_id == id) {
871                         lpcspifi_info->dev = p;
872                         break;
873                 }
874
875         if (!lpcspifi_info->dev) {
876                 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id);
877                 return ERROR_FAIL;
878         }
879
880         LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
881                 lpcspifi_info->dev->name, lpcspifi_info->dev->device_id);
882
883         /* Set correct size value */
884         bank->size = lpcspifi_info->dev->size_in_bytes;
885         if (bank->size <= (1UL << 16))
886                 LOG_WARNING("device needs 2-byte addresses - not implemented");
887         if (bank->size > (1UL << 24))
888                 LOG_WARNING("device needs paging or 4-byte addresses - not implemented");
889
890         /* if no sectors, treat whole bank as single sector */
891         sectorsize = lpcspifi_info->dev->sectorsize ?
892                 lpcspifi_info->dev->sectorsize : lpcspifi_info->dev->size_in_bytes;
893
894         /* create and fill sectors array */
895         bank->num_sectors = lpcspifi_info->dev->size_in_bytes / sectorsize;
896         sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
897         if (sectors == NULL) {
898                 LOG_ERROR("not enough memory");
899                 return ERROR_FAIL;
900         }
901
902         for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
903                 sectors[sector].offset = sector * sectorsize;
904                 sectors[sector].size = sectorsize;
905                 sectors[sector].is_erased = -1;
906                 sectors[sector].is_protected = 0;
907         }
908
909         bank->sectors = sectors;
910
911         lpcspifi_info->probed = true;
912         return ERROR_OK;
913 }
914
915 static int lpcspifi_auto_probe(struct flash_bank *bank)
916 {
917         struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
918         if (lpcspifi_info->probed)
919                 return ERROR_OK;
920         return lpcspifi_probe(bank);
921 }
922
923 static int lpcspifi_protect_check(struct flash_bank *bank)
924 {
925         /* Nothing to do. Protection is only handled in SW. */
926         return ERROR_OK;
927 }
928
929 static int get_lpcspifi_info(struct flash_bank *bank, char *buf, int buf_size)
930 {
931         struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
932
933         if (!(lpcspifi_info->probed)) {
934                 snprintf(buf, buf_size,
935                         "\nSPIFI flash bank not probed yet\n");
936                 return ERROR_OK;
937         }
938
939         snprintf(buf, buf_size, "\nSPIFI flash information:\n"
940                 "  Device \'%s\' (ID 0x%08" PRIx32 ")\n",
941                 lpcspifi_info->dev->name, lpcspifi_info->dev->device_id);
942
943         return ERROR_OK;
944 }
945
946 const struct flash_driver lpcspifi_flash = {
947         .name = "lpcspifi",
948         .flash_bank_command = lpcspifi_flash_bank_command,
949         .erase = lpcspifi_erase,
950         .protect = lpcspifi_protect,
951         .write = lpcspifi_write,
952         .read = default_flash_read,
953         .probe = lpcspifi_probe,
954         .auto_probe = lpcspifi_auto_probe,
955         .erase_check = default_flash_blank_check,
956         .protect_check = lpcspifi_protect_check,
957         .info = get_lpcspifi_info,
958         .free_driver_priv = default_flash_free_driver_priv,
959 };