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