flash/nor: mrvlqspi: fix printf formatting issues
[openocd.git] / src / flash / nor / mrvlqspi.c
1 /***************************************************************************
2 * Copyright (C) 2014 by Mahavir Jain <mjain@marvell.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
18 * *
19 ***************************************************************************/
20
21 /*
22 * This is QSPI flash controller driver for Marvell's Wireless
23 * Microcontroller platform.
24 *
25 * For more information please refer,
26 * https://origin-www.marvell.com/microcontrollers/wi-fi-microcontroller-platform/
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "imp.h"
34 #include "spi.h"
35 #include <helper/binarybuffer.h>
36 #include <target/algorithm.h>
37 #include <target/armv7m.h>
38
39 #define QSPI_R_EN (0x0)
40 #define QSPI_W_EN (0x1)
41 #define QSPI_SS_DISABLE (0x0)
42 #define QSPI_SS_ENABLE (0x1)
43 #define WRITE_DISBALE (0x0)
44 #define WRITE_ENABLE (0x1)
45
46 #define QSPI_TIMEOUT (1000)
47 #define FIFO_FLUSH_TIMEOUT (1000)
48 #define BLOCK_ERASE_TIMEOUT (1000)
49 #define CHIP_ERASE_TIMEOUT (10000)
50
51 #define SS_EN (1 << 0)
52 #define XFER_RDY (1 << 1)
53 #define RFIFO_EMPTY (1 << 4)
54 #define WFIFO_EMPTY (1 << 6)
55 #define WFIFO_FULL (1 << 7)
56 #define FIFO_FLUSH (1 << 9)
57 #define RW_EN (1 << 13)
58 #define XFER_STOP (1 << 14)
59 #define XFER_START (1 << 15)
60 #define CONF_MASK (0x7)
61 #define CONF_OFFSET (10)
62
63 #define INS_WRITE_ENABLE 0x06
64 #define INS_WRITE_DISABLE 0x04
65 #define INS_READ_STATUS 0x05
66 #define INS_PAGE_PROGRAM 0x02
67
68 #define CNTL 0x0 /* QSPI_BASE + 0x0 */
69 #define CONF 0x4
70 #define DOUT 0x8
71 #define DIN 0xc
72 #define INSTR 0x10
73 #define ADDR 0x14
74 #define RDMODE 0x18
75 #define HDRCNT 0x1c
76 #define DINCNT 0x20
77
78 struct mrvlqspi_flash_bank {
79 int probed;
80 uint32_t reg_base;
81 uint32_t bank_num;
82 const struct flash_device *dev;
83 };
84
85 static inline uint32_t mrvlqspi_get_reg(struct flash_bank *bank, uint32_t reg)
86 {
87 struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;
88 return reg + mrvlqspi_info->reg_base;
89 }
90
91 static inline int mrvlqspi_set_din_cnt(struct flash_bank *bank, uint32_t count)
92 {
93 struct target *target = bank->target;
94
95 return target_write_u32(target, mrvlqspi_get_reg(bank, DINCNT), count);
96 }
97
98 static inline int mrvlqspi_set_addr(struct flash_bank *bank, uint32_t addr)
99 {
100 struct target *target = bank->target;
101
102 return target_write_u32(target, mrvlqspi_get_reg(bank, ADDR), addr);
103 }
104
105 static inline int mrvlqspi_set_instr(struct flash_bank *bank, uint32_t instr)
106 {
107 struct target *target = bank->target;
108
109 return target_write_u32(target, mrvlqspi_get_reg(bank, INSTR), instr);
110 }
111
112 static inline int mrvlqspi_set_hdr_cnt(struct flash_bank *bank, uint32_t hdr_cnt)
113 {
114 struct target *target = bank->target;
115
116 return target_write_u32(target, mrvlqspi_get_reg(bank, HDRCNT), hdr_cnt);
117 }
118
119 static int mrvlqspi_set_conf(struct flash_bank *bank, uint32_t conf_val)
120 {
121 int retval;
122 uint32_t regval;
123 struct target *target = bank->target;
124
125 retval = target_read_u32(target,
126 mrvlqspi_get_reg(bank, CONF), &regval);
127 if (retval != ERROR_OK)
128 return retval;
129
130 regval &= ~(CONF_MASK << CONF_OFFSET);
131 regval |= (conf_val << CONF_OFFSET);
132
133 return target_write_u32(target,
134 mrvlqspi_get_reg(bank, CONF), regval);
135 }
136
137 static int mrvlqspi_set_ss_state(struct flash_bank *bank, bool state, int timeout)
138 {
139 int retval;
140 uint32_t regval;
141 struct target *target = bank->target;
142
143 retval = target_read_u32(target,
144 mrvlqspi_get_reg(bank, CNTL), &regval);
145 if (retval != ERROR_OK)
146 return retval;
147
148 if (state)
149 regval |= SS_EN;
150 else
151 regval &= ~(SS_EN);
152
153 retval = target_write_u32(target,
154 mrvlqspi_get_reg(bank, CNTL), regval);
155 if (retval != ERROR_OK)
156 return retval;
157
158 /* wait for xfer_ready to set */
159 for (;;) {
160 retval = target_read_u32(target,
161 mrvlqspi_get_reg(bank, CNTL), &regval);
162 if (retval != ERROR_OK)
163 return retval;
164 LOG_DEBUG("status: 0x%08" PRIx32, regval);
165 if ((regval & XFER_RDY) == XFER_RDY)
166 break;
167 if (timeout-- <= 0) {
168 LOG_ERROR("timed out waiting for flash");
169 return ERROR_FAIL;
170 }
171 alive_sleep(1);
172 }
173 return ERROR_OK;
174 }
175
176 static int mrvlqspi_start_transfer(struct flash_bank *bank, bool rw_mode)
177 {
178 int retval;
179 uint32_t regval;
180 struct target *target = bank->target;
181
182 retval = mrvlqspi_set_ss_state(bank, QSPI_SS_ENABLE, QSPI_TIMEOUT);
183 if (retval != ERROR_OK)
184 return retval;
185
186 retval = target_read_u32(target,
187 mrvlqspi_get_reg(bank, CONF), &regval);
188 if (retval != ERROR_OK)
189 return retval;
190
191 if (rw_mode)
192 regval |= RW_EN;
193 else
194 regval &= ~(RW_EN);
195
196 regval |= XFER_START;
197
198 retval = target_write_u32(target,
199 mrvlqspi_get_reg(bank, CONF), regval);
200 if (retval != ERROR_OK)
201 return retval;
202
203 return ERROR_OK;
204 }
205
206 static int mrvlqspi_stop_transfer(struct flash_bank *bank)
207 {
208 int retval;
209 uint32_t regval;
210 struct target *target = bank->target;
211 int timeout = QSPI_TIMEOUT;
212
213 /* wait for xfer_ready and wfifo_empty to set */
214 for (;;) {
215 retval = target_read_u32(target,
216 mrvlqspi_get_reg(bank, CNTL), &regval);
217 if (retval != ERROR_OK)
218 return retval;
219 LOG_DEBUG("status: 0x%08" PRIx32, regval);
220 if ((regval & (XFER_RDY | WFIFO_EMPTY)) ==
221 (XFER_RDY | WFIFO_EMPTY))
222 break;
223 if (timeout-- <= 0) {
224 LOG_ERROR("timed out waiting for flash");
225 return ERROR_FAIL;
226 }
227 alive_sleep(1);
228 }
229
230 retval = target_read_u32(target,
231 mrvlqspi_get_reg(bank, CONF), &regval);
232 if (retval != ERROR_OK)
233 return retval;
234
235 regval |= XFER_STOP;
236
237 retval = target_write_u32(target,
238 mrvlqspi_get_reg(bank, CONF), regval);
239 if (retval != ERROR_OK)
240 return retval;
241
242 /* wait for xfer_start to reset */
243 for (;;) {
244 retval = target_read_u32(target,
245 mrvlqspi_get_reg(bank, CONF), &regval);
246 if (retval != ERROR_OK)
247 return retval;
248 LOG_DEBUG("status: 0x%08" PRIx32, regval);
249 if ((regval & XFER_START) == 0)
250 break;
251 if (timeout-- <= 0) {
252 LOG_ERROR("timed out waiting for flash");
253 return ERROR_FAIL;
254 }
255 alive_sleep(1);
256 }
257
258 retval = mrvlqspi_set_ss_state(bank, QSPI_SS_DISABLE, QSPI_TIMEOUT);
259 if (retval != ERROR_OK)
260 return retval;
261
262 return ERROR_OK;
263 }
264
265 static int mrvlqspi_fifo_flush(struct flash_bank *bank, int timeout)
266 {
267 int retval;
268 uint32_t val;
269 struct target *target = bank->target;
270
271 retval = target_read_u32(target,
272 mrvlqspi_get_reg(bank, CONF), &val);
273 if (retval != ERROR_OK)
274 return retval;
275
276 val |= FIFO_FLUSH;
277
278 retval = target_write_u32(target,
279 mrvlqspi_get_reg(bank, CONF), val);
280 if (retval != ERROR_OK)
281 return retval;
282
283 /* wait for fifo_flush to clear */
284 for (;;) {
285 retval = target_read_u32(target,
286 mrvlqspi_get_reg(bank, CONF), &val);
287 if (retval != ERROR_OK)
288 return retval;
289 LOG_DEBUG("status: 0x%08" PRIX32, val);
290 if ((val & FIFO_FLUSH) == 0)
291 break;
292 if (timeout-- <= 0) {
293 LOG_ERROR("timed out waiting for flash");
294 return ERROR_FAIL;
295 }
296 alive_sleep(1);
297 }
298 return ERROR_OK;
299 }
300
301 static int mrvlqspi_read_byte(struct flash_bank *bank, uint8_t *data)
302 {
303 int retval;
304 uint32_t val;
305 struct target *target = bank->target;
306
307 /* wait for rfifo_empty to reset */
308 for (;;) {
309 retval = target_read_u32(target,
310 mrvlqspi_get_reg(bank, CNTL), &val);
311 if (retval != ERROR_OK)
312 return retval;
313 LOG_DEBUG("status: 0x%08" PRIx32, val);
314 if ((val & RFIFO_EMPTY) == 0)
315 break;
316 usleep(10);
317 }
318
319 retval = target_read_u32(target,
320 mrvlqspi_get_reg(bank, DIN), &val);
321 if (retval != ERROR_OK)
322 return retval;
323
324 *data = val & 0xFF;
325
326 return ERROR_OK;
327 }
328
329 static int mrvlqspi_flash_busy_status(struct flash_bank *bank, int timeout)
330 {
331 uint8_t val;
332 int retval;
333
334 /* Flush read/write fifo's */
335 retval = mrvlqspi_fifo_flush(bank, FIFO_FLUSH_TIMEOUT);
336 if (retval != ERROR_OK)
337 return retval;
338
339 /* Set instruction/addr count value */
340 retval = mrvlqspi_set_hdr_cnt(bank, 0x1);
341 if (retval != ERROR_OK)
342 return retval;
343
344 /* Read flash status register in continuous manner */
345 retval = mrvlqspi_set_din_cnt(bank, 0x0);
346 if (retval != ERROR_OK)
347 return retval;
348
349 /* Set instruction */
350 retval = mrvlqspi_set_instr(bank, INS_READ_STATUS);
351 if (retval != ERROR_OK)
352 return retval;
353
354 /* Set data and addr pin length */
355 retval = mrvlqspi_set_conf(bank, 0x0);
356 if (retval != ERROR_OK)
357 return retval;
358
359 /* Enable read mode transfer */
360 retval = mrvlqspi_start_transfer(bank, QSPI_R_EN);
361 if (retval != ERROR_OK)
362 return retval;
363
364 for (;;) {
365 retval = mrvlqspi_read_byte(bank, &val);
366 if (retval != ERROR_OK)
367 return retval;
368 if (!(val & 0x1))
369 break;
370 if (timeout-- <= 0) {
371 LOG_ERROR("timed out waiting for flash");
372 return ERROR_FAIL;
373 }
374 alive_sleep(1);
375 }
376
377 return mrvlqspi_stop_transfer(bank);
378 }
379
380 static int mrvlqspi_set_write_status(struct flash_bank *bank, bool mode)
381 {
382 int retval;
383 uint32_t instr;
384
385 /* Flush read/write fifo's */
386 retval = mrvlqspi_fifo_flush(bank, FIFO_FLUSH_TIMEOUT);
387 if (retval != ERROR_OK)
388 return retval;
389
390 /* Set instruction/addr count value */
391 retval = mrvlqspi_set_hdr_cnt(bank, 0x1);
392 if (retval != ERROR_OK)
393 return retval;
394
395 if (mode)
396 instr = INS_WRITE_ENABLE;
397 else
398 instr = INS_WRITE_DISABLE;
399
400 /* Set instruction */
401 retval = mrvlqspi_set_instr(bank, instr);
402 if (retval != ERROR_OK)
403 return retval;
404
405 retval = mrvlqspi_start_transfer(bank, QSPI_W_EN);
406 if (retval != ERROR_OK)
407 return retval;
408
409 retval = mrvlqspi_stop_transfer(bank);
410 if (retval != ERROR_OK)
411 return retval;
412
413 return retval;
414 }
415
416 static int mrvlqspi_read_id(struct flash_bank *bank, uint32_t *id)
417 {
418 uint8_t id_buf[3] = {0, 0, 0};
419 int retval, i;
420
421 LOG_DEBUG("Getting ID");
422
423 /* Flush read/write fifo's */
424 retval = mrvlqspi_fifo_flush(bank, FIFO_FLUSH_TIMEOUT);
425 if (retval != ERROR_OK)
426 return retval;
427
428 /* Set instruction/addr count value */
429 retval = mrvlqspi_set_hdr_cnt(bank, 0x1);
430 if (retval != ERROR_OK)
431 return retval;
432
433 /* Set count for number of bytes to read */
434 retval = mrvlqspi_set_din_cnt(bank, 0x3);
435 if (retval != ERROR_OK)
436 return retval;
437
438 /* Set instruction */
439 retval = mrvlqspi_set_instr(bank, SPIFLASH_READ_ID);
440 if (retval != ERROR_OK)
441 return retval;
442
443 /* Set data and addr pin length */
444 retval = mrvlqspi_set_conf(bank, 0x0);
445 if (retval != ERROR_OK)
446 return retval;
447
448 retval = mrvlqspi_start_transfer(bank, QSPI_R_EN);
449 if (retval != ERROR_OK)
450 return retval;
451
452 for (i = 0; i < 3; i++) {
453 retval = mrvlqspi_read_byte(bank, &id_buf[i]);
454 if (retval != ERROR_OK)
455 return retval;
456 }
457
458 LOG_DEBUG("ID is 0x%02" PRIx8 " 0x%02" PRIx8 " 0x%02" PRIx8,
459 id_buf[0], id_buf[1], id_buf[2]);
460 retval = mrvlqspi_set_ss_state(bank, QSPI_SS_DISABLE, QSPI_TIMEOUT);
461 if (retval != ERROR_OK)
462 return retval;
463
464 *id = id_buf[2] << 16 | id_buf[1] << 8 | id_buf[0];
465 return ERROR_OK;
466 }
467
468 static int mrvlqspi_block_erase(struct flash_bank *bank, uint32_t offset)
469 {
470 int retval;
471 struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;
472
473 /* Set flash write enable */
474 retval = mrvlqspi_set_write_status(bank, WRITE_ENABLE);
475 if (retval != ERROR_OK)
476 return retval;
477
478 /* Set instruction/addr count value */
479 retval = mrvlqspi_set_hdr_cnt(bank, (0x1 | (0x3 << 4)));
480 if (retval != ERROR_OK)
481 return retval;
482
483 /* Set read offset address */
484 retval = mrvlqspi_set_addr(bank, offset);
485 if (retval != ERROR_OK)
486 return retval;
487
488 /* Set instruction */
489 retval = mrvlqspi_set_instr(bank, mrvlqspi_info->dev->erase_cmd);
490 if (retval != ERROR_OK)
491 return retval;
492
493 retval = mrvlqspi_start_transfer(bank, QSPI_W_EN);
494 if (retval != ERROR_OK)
495 return retval;
496
497 retval = mrvlqspi_stop_transfer(bank);
498 if (retval != ERROR_OK)
499 return retval;
500
501 return mrvlqspi_flash_busy_status(bank, BLOCK_ERASE_TIMEOUT);
502 }
503
504 static int mrvlqspi_bulk_erase(struct flash_bank *bank)
505 {
506 int retval;
507 struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;
508
509 /* Set flash write enable */
510 retval = mrvlqspi_set_write_status(bank, WRITE_ENABLE);
511 if (retval != ERROR_OK)
512 return retval;
513
514 /* Set instruction */
515 retval = mrvlqspi_set_instr(bank, mrvlqspi_info->dev->chip_erase_cmd);
516 if (retval != ERROR_OK)
517 return retval;
518
519 retval = mrvlqspi_start_transfer(bank, QSPI_W_EN);
520 if (retval != ERROR_OK)
521 return retval;
522
523 retval = mrvlqspi_stop_transfer(bank);
524 if (retval != ERROR_OK)
525 return retval;
526
527 return mrvlqspi_flash_busy_status(bank, CHIP_ERASE_TIMEOUT);
528 }
529
530 static int mrvlqspi_flash_erase(struct flash_bank *bank, int first, int last)
531 {
532 struct target *target = bank->target;
533 struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;
534 int retval = ERROR_OK;
535 int sector;
536
537 LOG_DEBUG("erase from sector %d to sector %d", first, last);
538
539 if (target->state != TARGET_HALTED) {
540 LOG_ERROR("Target not halted");
541 return ERROR_TARGET_NOT_HALTED;
542 }
543
544 if ((first < 0) || (last < first) || (last >= bank->num_sectors)) {
545 LOG_ERROR("Flash sector invalid");
546 return ERROR_FLASH_SECTOR_INVALID;
547 }
548
549 if (!(mrvlqspi_info->probed)) {
550 LOG_ERROR("Flash bank not probed");
551 return ERROR_FLASH_BANK_NOT_PROBED;
552 }
553
554 for (sector = first; sector <= last; sector++) {
555 if (bank->sectors[sector].is_protected) {
556 LOG_ERROR("Flash sector %d protected", sector);
557 return ERROR_FAIL;
558 }
559 }
560
561 /* If we're erasing the entire chip and the flash supports
562 * it, use a bulk erase instead of going sector-by-sector. */
563 if (first == 0 && last == (bank->num_sectors - 1)
564 && mrvlqspi_info->dev->chip_erase_cmd !=
565 mrvlqspi_info->dev->erase_cmd) {
566 LOG_DEBUG("Chip supports the bulk erase command."\
567 " Will use bulk erase instead of sector-by-sector erase.");
568 retval = mrvlqspi_bulk_erase(bank);
569 if (retval == ERROR_OK) {
570 return retval;
571 } else
572 LOG_WARNING("Bulk flash erase failed."
573 " Falling back to sector-by-sector erase.");
574 }
575
576 for (sector = first; sector <= last; sector++) {
577 retval = mrvlqspi_block_erase(bank,
578 sector * mrvlqspi_info->dev->sectorsize);
579 if (retval != ERROR_OK)
580 return retval;
581 }
582
583 return retval;
584 }
585
586 static int mrvlqspi_flash_write(struct flash_bank *bank, const uint8_t *buffer,
587 uint32_t offset, uint32_t count)
588 {
589 struct target *target = bank->target;
590 struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;
591 int retval = ERROR_OK;
592 uint32_t page_size, fifo_size;
593 struct working_area *fifo;
594 struct reg_param reg_params[6];
595 struct armv7m_algorithm armv7m_info;
596 struct working_area *write_algorithm;
597 int sector;
598
599 LOG_DEBUG("offset=0x%08" PRIx32 " count=0x%08" PRIx32,
600 offset, count);
601
602 if (target->state != TARGET_HALTED) {
603 LOG_ERROR("Target not halted");
604 return ERROR_TARGET_NOT_HALTED;
605 }
606
607 if (offset + count > mrvlqspi_info->dev->size_in_bytes) {
608 LOG_WARNING("Writes past end of flash. Extra data discarded.");
609 count = mrvlqspi_info->dev->size_in_bytes - offset;
610 }
611
612 /* Check sector protection */
613 for (sector = 0; sector < bank->num_sectors; sector++) {
614 /* Start offset in or before this sector? */
615 /* End offset in or behind this sector? */
616 if ((offset <
617 (bank->sectors[sector].offset + bank->sectors[sector].size))
618 && ((offset + count - 1) >= bank->sectors[sector].offset)
619 && bank->sectors[sector].is_protected) {
620 LOG_ERROR("Flash sector %d protected", sector);
621 return ERROR_FAIL;
622 }
623 }
624
625 page_size = mrvlqspi_info->dev->pagesize;
626
627 /* See contrib/loaders/flash/mrvlqspi.S for src */
628 static const uint8_t mrvlqspi_flash_write_code[] = {
629 0x4f, 0xf0, 0x00, 0x0a, 0xa2, 0x44, 0x92, 0x45,
630 0x7f, 0xf6, 0xfc, 0xaf, 0x00, 0xf0, 0x6b, 0xf8,
631 0x5f, 0xf0, 0x01, 0x08, 0xc5, 0xf8, 0x1c, 0x80,
632 0x5f, 0xf0, 0x06, 0x08, 0xc5, 0xf8, 0x10, 0x80,
633 0x5f, 0xf0, 0x01, 0x09, 0x00, 0xf0, 0x6b, 0xf8,
634 0x00, 0xf0, 0x7d, 0xf8, 0x5f, 0xf0, 0x31, 0x08,
635 0xc5, 0xf8, 0x1c, 0x80, 0x90, 0x46, 0xc5, 0xf8,
636 0x14, 0x80, 0x5f, 0xf0, 0x02, 0x08, 0xc5, 0xf8,
637 0x10, 0x80, 0x5f, 0xf0, 0x01, 0x09, 0x00, 0xf0,
638 0x5a, 0xf8, 0xd0, 0xf8, 0x00, 0x80, 0xb8, 0xf1,
639 0x00, 0x0f, 0x00, 0xf0, 0x8b, 0x80, 0x47, 0x68,
640 0x47, 0x45, 0x3f, 0xf4, 0xf6, 0xaf, 0x17, 0xf8,
641 0x01, 0x9b, 0x00, 0xf0, 0x30, 0xf8, 0x8f, 0x42,
642 0x28, 0xbf, 0x00, 0xf1, 0x08, 0x07, 0x47, 0x60,
643 0x01, 0x3b, 0x00, 0x2b, 0x00, 0xf0, 0x05, 0x80,
644 0x02, 0xf1, 0x01, 0x02, 0x92, 0x45, 0x7f, 0xf4,
645 0xe4, 0xaf, 0x00, 0xf0, 0x50, 0xf8, 0xa2, 0x44,
646 0x00, 0xf0, 0x2d, 0xf8, 0x5f, 0xf0, 0x01, 0x08,
647 0xc5, 0xf8, 0x1c, 0x80, 0x5f, 0xf0, 0x00, 0x08,
648 0xc5, 0xf8, 0x20, 0x80, 0x5f, 0xf0, 0x05, 0x08,
649 0xc5, 0xf8, 0x10, 0x80, 0x5f, 0xf0, 0x00, 0x09,
650 0x00, 0xf0, 0x29, 0xf8, 0x00, 0xf0, 0x13, 0xf8,
651 0x09, 0xf0, 0x01, 0x09, 0xb9, 0xf1, 0x00, 0x0f,
652 0xf8, 0xd1, 0x00, 0xf0, 0x34, 0xf8, 0x00, 0x2b,
653 0xa4, 0xd1, 0x00, 0xf0, 0x53, 0xb8, 0xd5, 0xf8,
654 0x00, 0x80, 0x5f, 0xea, 0x08, 0x68, 0xfa, 0xd4,
655 0xc5, 0xf8, 0x08, 0x90, 0x70, 0x47, 0xd5, 0xf8,
656 0x00, 0x80, 0x5f, 0xea, 0xc8, 0x68, 0xfa, 0xd4,
657 0xd5, 0xf8, 0x0c, 0x90, 0x70, 0x47, 0xd5, 0xf8,
658 0x04, 0x80, 0x48, 0xf4, 0x00, 0x78, 0xc5, 0xf8,
659 0x04, 0x80, 0xd5, 0xf8, 0x04, 0x80, 0x5f, 0xea,
660 0x88, 0x58, 0xfa, 0xd4, 0x70, 0x47, 0xd5, 0xf8,
661 0x00, 0x80, 0x48, 0xf0, 0x01, 0x08, 0xc5, 0xf8,
662 0x00, 0x80, 0xd5, 0xf8, 0x00, 0x80, 0x5f, 0xea,
663 0x88, 0x78, 0xfa, 0xd5, 0xd5, 0xf8, 0x04, 0x80,
664 0x69, 0xf3, 0x4d, 0x38, 0x48, 0xf4, 0x00, 0x48,
665 0xc5, 0xf8, 0x04, 0x80, 0x70, 0x47, 0xd5, 0xf8,
666 0x00, 0x80, 0x5f, 0xea, 0x88, 0x78, 0xfa, 0xd5,
667 0xd5, 0xf8, 0x00, 0x80, 0x5f, 0xea, 0x48, 0x68,
668 0xfa, 0xd5, 0xd5, 0xf8, 0x04, 0x80, 0x48, 0xf4,
669 0x80, 0x48, 0xc5, 0xf8, 0x04, 0x80, 0xd5, 0xf8,
670 0x04, 0x80, 0x5f, 0xea, 0x08, 0x48, 0xfa, 0xd4,
671 0xd5, 0xf8, 0x00, 0x80, 0x28, 0xf0, 0x01, 0x08,
672 0xc5, 0xf8, 0x00, 0x80, 0xd5, 0xf8, 0x00, 0x80,
673 0x5f, 0xea, 0x88, 0x78, 0xfa, 0xd5, 0x70, 0x47,
674 0x00, 0x20, 0x50, 0x60, 0x30, 0x46, 0x00, 0xbe
675 };
676
677 if (target_alloc_working_area(target, sizeof(mrvlqspi_flash_write_code),
678 &write_algorithm) != ERROR_OK) {
679 LOG_ERROR("Insufficient working area. You must configure"\
680 " a working area > %zdB in order to write to SPIFI flash.",
681 sizeof(mrvlqspi_flash_write_code));
682 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
683 };
684
685 retval = target_write_buffer(target, write_algorithm->address,
686 sizeof(mrvlqspi_flash_write_code),
687 mrvlqspi_flash_write_code);
688 if (retval != ERROR_OK) {
689 target_free_working_area(target, write_algorithm);
690 return retval;
691 }
692
693 /* FIFO allocation */
694 fifo_size = target_get_working_area_avail(target);
695
696 if (fifo_size == 0) {
697 /* if we already allocated the writing code but failed to get fifo
698 * space, free the algorithm */
699 target_free_working_area(target, write_algorithm);
700
701 LOG_ERROR("Insufficient working area. Please allocate at least"\
702 " %zdB of working area to enable flash writes.",
703 sizeof(mrvlqspi_flash_write_code) + 1
704 );
705
706 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
707 } else if (fifo_size < page_size)
708 LOG_WARNING("Working area size is limited; flash writes may be"\
709 " slow. Increase working area size to at least %zdB"\
710 " to reduce write times.",
711 (size_t)(sizeof(mrvlqspi_flash_write_code) + page_size)
712 );
713
714 if (target_alloc_working_area(target, fifo_size, &fifo) != ERROR_OK) {
715 target_free_working_area(target, write_algorithm);
716 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
717 };
718
719 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
720 armv7m_info.core_mode = ARM_MODE_THREAD;
721
722 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* buffer start, status (out) */
723 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* buffer end */
724 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* target address */
725 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* count (halfword-16bit) */
726 init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT); /* page size */
727 init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT); /* qspi base address */
728
729 buf_set_u32(reg_params[0].value, 0, 32, fifo->address);
730 buf_set_u32(reg_params[1].value, 0, 32, fifo->address + fifo->size);
731 buf_set_u32(reg_params[2].value, 0, 32, offset);
732 buf_set_u32(reg_params[3].value, 0, 32, count);
733 buf_set_u32(reg_params[4].value, 0, 32, page_size);
734 buf_set_u32(reg_params[5].value, 0, 32, (uint32_t) mrvlqspi_info->reg_base);
735
736 retval = target_run_flash_async_algorithm(target, buffer, count, 1,
737 0, NULL,
738 6, reg_params,
739 fifo->address, fifo->size,
740 write_algorithm->address, 0,
741 &armv7m_info
742 );
743
744 if (retval != ERROR_OK)
745 LOG_ERROR("Error executing flash write algorithm");
746
747 target_free_working_area(target, fifo);
748 target_free_working_area(target, write_algorithm);
749
750 destroy_reg_param(&reg_params[0]);
751 destroy_reg_param(&reg_params[1]);
752 destroy_reg_param(&reg_params[2]);
753 destroy_reg_param(&reg_params[3]);
754 destroy_reg_param(&reg_params[4]);
755 destroy_reg_param(&reg_params[5]);
756
757 return retval;
758 }
759
760 int mrvlqspi_flash_read(struct flash_bank *bank, uint8_t *buffer,
761 uint32_t offset, uint32_t count)
762 {
763 struct target *target = bank->target;
764 struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;
765 int retval;
766 uint32_t i;
767
768 if (target->state != TARGET_HALTED) {
769 LOG_ERROR("Target not halted");
770 return ERROR_TARGET_NOT_HALTED;
771 }
772
773 if (!(mrvlqspi_info->probed)) {
774 LOG_ERROR("Flash bank not probed");
775 return ERROR_FLASH_BANK_NOT_PROBED;
776 }
777
778 /* Flush read/write fifo's */
779 retval = mrvlqspi_fifo_flush(bank, FIFO_FLUSH_TIMEOUT);
780 if (retval != ERROR_OK)
781 return retval;
782
783 /* Set instruction/addr count value */
784 retval = mrvlqspi_set_hdr_cnt(bank, (0x1 | (0x3 << 4)));
785 if (retval != ERROR_OK)
786 return retval;
787
788 /* Set count for number of bytes to read */
789 retval = mrvlqspi_set_din_cnt(bank, count);
790 if (retval != ERROR_OK)
791 return retval;
792
793 /* Set read address */
794 retval = mrvlqspi_set_addr(bank, offset);
795 if (retval != ERROR_OK)
796 return retval;
797
798 /* Set instruction */
799 retval = mrvlqspi_set_instr(bank, SPIFLASH_READ);
800 if (retval != ERROR_OK)
801 return retval;
802
803 /* Set data and addr pin length */
804 retval = mrvlqspi_set_conf(bank, 0x0);
805 if (retval != ERROR_OK)
806 return retval;
807
808 retval = mrvlqspi_start_transfer(bank, QSPI_R_EN);
809 if (retval != ERROR_OK)
810 return retval;
811
812 for (i = 0; i < count; i++) {
813 retval = mrvlqspi_read_byte(bank, &buffer[i]);
814 if (retval != ERROR_OK)
815 return retval;
816 }
817
818 retval = mrvlqspi_set_ss_state(bank, QSPI_SS_DISABLE, QSPI_TIMEOUT);
819 if (retval != ERROR_OK)
820 return retval;
821
822 return ERROR_OK;
823 }
824
825 static int mrvlqspi_probe(struct flash_bank *bank)
826 {
827 struct target *target = bank->target;
828 struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;
829 uint32_t id = 0;
830 int retval;
831 struct flash_sector *sectors;
832
833 /* If we've already probed, we should be fine to skip this time. */
834 if (mrvlqspi_info->probed)
835 return ERROR_OK;
836
837 if (target->state != TARGET_HALTED) {
838 LOG_ERROR("Target not halted");
839 return ERROR_TARGET_NOT_HALTED;
840 }
841
842 mrvlqspi_info->probed = 0;
843 mrvlqspi_info->bank_num = bank->bank_number;
844
845 /* Read flash JEDEC ID */
846 retval = mrvlqspi_read_id(bank, &id);
847 if (retval != ERROR_OK)
848 return retval;
849
850 mrvlqspi_info->dev = NULL;
851 for (const struct flash_device *p = flash_devices; p->name ; p++)
852 if (p->device_id == id) {
853 mrvlqspi_info->dev = p;
854 break;
855 }
856
857 if (!mrvlqspi_info->dev) {
858 LOG_ERROR("Unknown flash device ID 0x%08" PRIx32, id);
859 return ERROR_FAIL;
860 }
861
862 LOG_INFO("Found flash device \'%s\' ID 0x%08" PRIx32,
863 mrvlqspi_info->dev->name, mrvlqspi_info->dev->device_id);
864
865 /* Set correct size value */
866 bank->size = mrvlqspi_info->dev->size_in_bytes;
867
868 /* create and fill sectors array */
869 bank->num_sectors = mrvlqspi_info->dev->size_in_bytes /
870 mrvlqspi_info->dev->sectorsize;
871 sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
872 if (sectors == NULL) {
873 LOG_ERROR("not enough memory");
874 return ERROR_FAIL;
875 }
876
877 for (int sector = 0; sector < bank->num_sectors; sector++) {
878 sectors[sector].offset =
879 sector * mrvlqspi_info->dev->sectorsize;
880 sectors[sector].size = mrvlqspi_info->dev->sectorsize;
881 sectors[sector].is_erased = -1;
882 sectors[sector].is_protected = 0;
883 }
884
885 bank->sectors = sectors;
886 mrvlqspi_info->probed = 1;
887
888 return ERROR_OK;
889 }
890
891 static int mrvlqspi_auto_probe(struct flash_bank *bank)
892 {
893 struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;
894 if (mrvlqspi_info->probed)
895 return ERROR_OK;
896 return mrvlqspi_probe(bank);
897 }
898
899 static int mrvlqspi_flash_erase_check(struct flash_bank *bank)
900 {
901 /* Not implemented yet */
902 return ERROR_OK;
903 }
904
905 static int mrvlqspi_protect_check(struct flash_bank *bank)
906 {
907 /* Not implemented yet */
908 return ERROR_OK;
909 }
910
911 int mrvlqspi_get_info(struct flash_bank *bank, char *buf, int buf_size)
912 {
913 struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;
914
915 if (!(mrvlqspi_info->probed)) {
916 snprintf(buf, buf_size,
917 "\nQSPI flash bank not probed yet\n");
918 return ERROR_OK;
919 }
920
921 snprintf(buf, buf_size, "\nQSPI flash information:\n"
922 " Device \'%s\' ID 0x%08" PRIx32 "\n",
923 mrvlqspi_info->dev->name, mrvlqspi_info->dev->device_id);
924
925 return ERROR_OK;
926 }
927
928 FLASH_BANK_COMMAND_HANDLER(mrvlqspi_flash_bank_command)
929 {
930 struct mrvlqspi_flash_bank *mrvlqspi_info;
931
932 if (CMD_ARGC < 7)
933 return ERROR_COMMAND_SYNTAX_ERROR;
934
935 mrvlqspi_info = malloc(sizeof(struct mrvlqspi_flash_bank));
936 if (mrvlqspi_info == NULL) {
937 LOG_ERROR("not enough memory");
938 return ERROR_FAIL;
939 }
940
941 /* Get QSPI controller register map base address */
942 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], mrvlqspi_info->reg_base);
943 bank->driver_priv = mrvlqspi_info;
944 mrvlqspi_info->probed = 0;
945
946 return ERROR_OK;
947 }
948
949 struct flash_driver mrvlqspi_flash = {
950 .name = "mrvlqspi",
951 .flash_bank_command = mrvlqspi_flash_bank_command,
952 .erase = mrvlqspi_flash_erase,
953 .protect = NULL,
954 .write = mrvlqspi_flash_write,
955 .read = mrvlqspi_flash_read,
956 .probe = mrvlqspi_probe,
957 .auto_probe = mrvlqspi_auto_probe,
958 .erase_check = mrvlqspi_flash_erase_check,
959 .protect_check = mrvlqspi_protect_check,
960 .info = mrvlqspi_get_info,
961 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)