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

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)