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