flash/nor/tcl.c: fix formatting in "rejected" error message
[openocd.git] / src / flash / nor / lpcspifi.c
blob7355c30a9ceacc627e9a6d80e1d7d253311cc26a
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 ***************************************************************************/
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
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>
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 */
39 /* Status register fields */
40 #define SSP_BSY (0x00000010)
42 /* Timeout in ms */
43 #define SSP_CMD_TIMEOUT (100)
44 #define SSP_PROBE_TIMEOUT (100)
45 #define SSP_MAX_TIMEOUT (3000)
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
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;
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 */
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 }
76 /* flash_bank lpcspifi <base> <size> <chip_width> <bus_width> <target>
78 FLASH_BANK_COMMAND_HANDLER(lpcspifi_flash_bank_command)
80 struct lpcspifi_flash_bank *lpcspifi_info;
82 if (CMD_ARGC < 6)
83 return ERROR_COMMAND_SYNTAX_ERROR;
85 lpcspifi_info = malloc(sizeof(struct lpcspifi_flash_bank));
86 if (lpcspifi_info == NULL) {
87 LOG_ERROR("not enough memory");
88 return ERROR_FAIL;
91 bank->driver_priv = lpcspifi_info;
92 lpcspifi_info->probed = 0;
94 return ERROR_OK;
97 static inline int ioconfig_write_reg(struct target *target, uint32_t ioconfig_base, uint32_t offset, uint32_t value)
99 return target_write_u32(target, ioconfig_base + offset, value);
102 static inline int ssp_write_reg(struct target *target, uint32_t ssp_base, uint32_t offset, uint32_t value)
104 return target_write_u32(target, ssp_base + offset, value);
107 static inline int io_write_reg(struct target *target, uint32_t io_base, uint32_t offset, uint32_t value)
109 return target_write_u32(target, io_base + offset, value);
112 static inline int ssp_read_reg(struct target *target, uint32_t ssp_base, uint32_t offset, uint32_t *value)
114 return target_read_u32(target, ssp_base + offset, value);
117 static int ssp_setcs(struct target *target, uint32_t io_base, unsigned int value)
119 return io_write_reg(target, io_base, 0x12ac, value ? 0xffffffff : 0x00000000);
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)
126 long long endtime;
127 uint32_t value;
128 int retval;
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;
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);
146 LOG_ERROR("Timeout while polling BSY");
147 return ERROR_FLASH_OPERATION_FAILED;
150 /* Un-initialize the ssp module and initialize the SPIFI module */
151 static int lpcspifi_set_hw_mode(struct flash_bank *bank)
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;
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;
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
188 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
189 armv7m_info.core_mode = ARM_MODE_THREAD;
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
203 return retval;
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
215 if (retval != ERROR_OK) {
216 target_free_working_area(target, spifi_init_algorithm);
217 return retval;
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);
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);
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);
241 if (retval != ERROR_OK)
242 LOG_ERROR("Error executing SPIFI init algorithm");
244 target_free_working_area(target, spifi_init_algorithm);
246 destroy_reg_param(&reg_params[0]);
247 destroy_reg_param(&reg_params[1]);
249 return retval;
252 /* Initialize the ssp module */
253 static int lpcspifi_set_sw_mode(struct flash_bank *bank)
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;
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);
266 /* If we couldn't initialize hardware mode, don't even bother continuing */
267 if (retval != ERROR_OK)
268 return retval;
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);
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);
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);
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);
303 return retval;
306 /* Read the status register of the external SPI flash chip. */
307 static int read_status_reg(struct flash_bank *bank, uint32_t *status)
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;
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);
331 if (retval == ERROR_OK)
332 retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);
333 if (retval == ERROR_OK)
334 *status = value;
336 return retval;
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)
343 uint32_t status;
344 int retval;
345 long long endtime;
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;
354 if ((status & SPIFLASH_BSY_BIT) == 0)
355 return ERROR_OK;
356 alive_sleep(1);
357 } while (timeval_ms() < endtime);
359 LOG_ERROR("timeout waiting for flash to finish write/erase operation");
360 return ERROR_FAIL;
363 /* Send "write enable" command to SPI flash chip. */
364 static int lpcspifi_write_enable(struct flash_bank *bank)
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;
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);
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;
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;
395 return retval;
398 static int lpcspifi_bulk_erase(struct flash_bank *bank)
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;
407 retval = lpcspifi_set_sw_mode(bank);
409 if (retval == ERROR_OK)
410 retval = lpcspifi_write_enable(bank);
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);
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);
428 return retval;
431 static int lpcspifi_erase(struct flash_bank *bank, int first, int last)
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;
441 LOG_DEBUG("erase from sector %d to sector %d", first, last);
443 if (target->state != TARGET_HALTED) {
444 LOG_ERROR("Target not halted");
445 return ERROR_TARGET_NOT_HALTED;
448 if ((first < 0) || (last < first) || (last >= bank->num_sectors)) {
449 LOG_ERROR("Flash sector invalid");
450 return ERROR_FLASH_SECTOR_INVALID;
453 if (!(lpcspifi_info->probed)) {
454 LOG_ERROR("Flash bank not probed");
455 return ERROR_FLASH_BANK_NOT_PROBED;
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;
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);
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.");
480 retval = lpcspifi_set_hw_mode(bank);
481 if (retval != ERROR_OK)
482 return retval;
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
531 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
532 armv7m_info.core_mode = ARM_MODE_THREAD;
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;
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;
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 */
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);
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);
569 if (retval != ERROR_OK)
570 LOG_ERROR("Error executing flash erase algorithm");
572 target_free_working_area(target, erase_algorithm);
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]);
579 retval = lpcspifi_set_hw_mode(bank);
581 return retval;
584 static int lpcspifi_protect(struct flash_bank *bank, int set,
585 int first, int last)
587 int sector;
589 for (sector = first; sector <= last; sector++)
590 bank->sectors[sector].is_protected = set;
591 return ERROR_OK;
594 static int lpcspifi_write(struct flash_bank *bank, const uint8_t *buffer,
595 uint32_t offset, uint32_t count)
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;
607 LOG_DEBUG("offset=0x%08" PRIx32 " count=0x%08" PRIx32,
608 offset, count);
610 if (target->state != TARGET_HALTED) {
611 LOG_ERROR("Target not halted");
612 return ERROR_TARGET_NOT_HALTED;
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;
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;
633 page_size = lpcspifi_info->dev->pagesize;
635 retval = lpcspifi_set_hw_mode(bank);
636 if (retval != ERROR_OK)
637 return retval;
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
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;
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;
710 /* FIFO allocation */
711 fifo_size = target_get_working_area_avail(target);
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);
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
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)
730 else if (fifo_size > 0x2000) /* Beyond this point, we start to get diminishing returns */
731 fifo_size = 0x2000;
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;
738 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
739 armv7m_info.core_mode = ARM_MODE_THREAD;
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 */
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);
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
761 if (retval != ERROR_OK)
762 LOG_ERROR("Error executing flash write algorithm");
764 target_free_working_area(target, fifo);
765 target_free_working_area(target, write_algorithm);
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]);
773 /* Switch to HW mode before return to prompt */
774 retval = lpcspifi_set_hw_mode(bank);
775 return retval;
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)
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;
790 if (target->state != TARGET_HALTED) {
791 LOG_ERROR("Target not halted");
792 return ERROR_TARGET_NOT_HALTED;
795 LOG_DEBUG("Getting ID");
796 retval = lpcspifi_set_sw_mode(bank);
797 if (retval != ERROR_OK)
798 return retval;
800 /* poll WIP */
801 if (retval == ERROR_OK)
802 retval = wait_till_ready(bank, SSP_PROBE_TIMEOUT);
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);
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;
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;
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;
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];
849 return retval;
852 static int lpcspifi_probe(struct flash_bank *bank)
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;
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;
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;
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;
886 LOG_DEBUG("Valid SPIFI on device %s at address 0x%" PRIx32,
887 target_device->name, bank->base);
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;
894 retval = lpcspifi_set_hw_mode(bank);
895 if (retval != ERROR_OK)
896 return retval;
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;
905 if (!lpcspifi_info->dev) {
906 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id);
907 return ERROR_FAIL;
910 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
911 lpcspifi_info->dev->name, lpcspifi_info->dev->device_id);
913 /* Set correct size value */
914 bank->size = lpcspifi_info->dev->size_in_bytes;
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;
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;
932 bank->sectors = sectors;
934 lpcspifi_info->probed = 1;
935 return ERROR_OK;
938 static int lpcspifi_auto_probe(struct flash_bank *bank)
940 struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
941 if (lpcspifi_info->probed)
942 return ERROR_OK;
943 return lpcspifi_probe(bank);
946 static int lpcspifi_protect_check(struct flash_bank *bank)
948 /* Nothing to do. Protection is only handled in SW. */
949 return ERROR_OK;
952 static int get_lpcspifi_info(struct flash_bank *bank, char *buf, int buf_size)
954 struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;
956 if (!(lpcspifi_info->probed)) {
957 snprintf(buf, buf_size,
958 "\nSPIFI flash bank not probed yet\n");
959 return ERROR_OK;
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);
966 return ERROR_OK;
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,