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