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