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

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)