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