OpenOCD
mrvlqspi.c
Go to the documentation of this file.
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 
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 
82 }
83 
84 static inline int mrvlqspi_set_addr(struct flash_bank *bank, uint32_t addr)
85 {
86  struct target *target = bank->target;
87 
89 }
90 
91 static inline int mrvlqspi_set_instr(struct flash_bank *bank, uint32_t instr)
92 {
93  struct target *target = bank->target;
94 
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 
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 
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 
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 
316 {
317  uint8_t val;
318  int retval;
319 
320  /* Flush read/write fifos */
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 */
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 */
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 
364 }
365 
367 {
368  int retval;
369  uint32_t instr;
370 
371  /* Flush read/write fifos */
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 
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 */
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 */
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 
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]);
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 */
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 
480  if (retval != ERROR_OK)
481  return retval;
482 
483  retval = mrvlqspi_stop_transfer(bank);
484  if (retval != ERROR_OK)
485  return retval;
486 
488 }
489 
491 {
492  int retval;
493  struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;
494 
495  if (mrvlqspi_info->dev->chip_erase_cmd == 0x00)
497 
498  /* Set flash 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 
509  if (retval != ERROR_OK)
510  return retval;
511 
512  retval = mrvlqspi_stop_transfer(bank);
513  if (retval != ERROR_OK)
514  return retval;
515 
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");
531  }
532 
533  if ((last < first) || (last >= bank->num_sectors)) {
534  LOG_ERROR("Flash sector invalid");
536  }
537 
538  if (!(mrvlqspi_info->probed)) {
539  LOG_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)
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");
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));
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 */
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 
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);
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 
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 
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");
764  }
765 
766  if (!(mrvlqspi_info->probed)) {
767  LOG_ERROR("Flash bank not probed");
769  }
770 
771  /* Flush read/write fifos */
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 */
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 
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 
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");
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 
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 
901 {
902  /* Not implemented yet */
903  return ERROR_OK;
904 }
905 
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)
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 };
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
Definition: algorithm.c:29
void destroy_reg_param(struct reg_param *param)
Definition: algorithm.c:37
@ PARAM_OUT
Definition: algorithm.h:16
@ PARAM_IN_OUT
Definition: algorithm.h:17
@ ARM_MODE_THREAD
Definition: arm.h:93
enum arm_mode mode
Definition: armv4_5.c:277
#define ARMV7M_COMMON_MAGIC
Definition: armv7m.h:220
Support functions to access arbitrary bits in a byte array.
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:31
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:420
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:156
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:151
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
Definition: command.h:442
uint8_t bank
Definition: esirisc.c:135
#define ERROR_FLASH_OPER_UNSUPPORTED
Definition: flash/common.h:36
#define ERROR_FLASH_SECTOR_INVALID
Definition: flash/common.h:29
#define ERROR_FLASH_BANK_NOT_PROBED
Definition: flash/common.h:35
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
void alive_sleep(uint64_t ms)
Definition: log.c:456
#define LOG_WARNING(expr ...)
Definition: log.h:129
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_INFO(expr ...)
Definition: log.h:126
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
#define RFIFO_EMPTY
Definition: mrvlqspi.c:39
#define WRITE_ENABLE
Definition: mrvlqspi.c:30
#define INS_WRITE_DISABLE
Definition: mrvlqspi.c:50
#define WFIFO_EMPTY
Definition: mrvlqspi.c:40
#define QSPI_TIMEOUT
Definition: mrvlqspi.c:32
static int mrvlqspi_fifo_flush(struct flash_bank *bank, int timeout)
Definition: mrvlqspi.c:251
static int mrvlqspi_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: mrvlqspi.c:753
static int mrvlqspi_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: mrvlqspi.c:578
static int mrvlqspi_flash_erase_check(struct flash_bank *bank)
Definition: mrvlqspi.c:900
#define QSPI_SS_DISABLE
Definition: mrvlqspi.c:27
static uint32_t mrvlqspi_get_reg(struct flash_bank *bank, uint32_t reg)
Definition: mrvlqspi.c:71
static int mrvlqspi_set_hdr_cnt(struct flash_bank *bank, uint32_t hdr_cnt)
Definition: mrvlqspi.c:98
#define XFER_START
Definition: mrvlqspi.c:45
FLASH_BANK_COMMAND_HANDLER(mrvlqspi_flash_bank_command)
Definition: mrvlqspi.c:922
#define HDRCNT
Definition: mrvlqspi.c:61
static int mrvlqspi_set_din_cnt(struct flash_bank *bank, uint32_t count)
Definition: mrvlqspi.c:77
#define DINCNT
Definition: mrvlqspi.c:62
#define FIFO_FLUSH
Definition: mrvlqspi.c:42
static int mrvlqspi_start_transfer(struct flash_bank *bank, bool rw_mode)
Definition: mrvlqspi.c:162
static int mrvlqspi_flash_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: mrvlqspi.c:519
static int mrvlqspi_flash_busy_status(struct flash_bank *bank, int timeout)
Definition: mrvlqspi.c:315
static int mrvlqspi_set_instr(struct flash_bank *bank, uint32_t instr)
Definition: mrvlqspi.c:91
static int mrvlqspi_get_info(struct flash_bank *bank, struct command_invocation *cmd)
Definition: mrvlqspi.c:906
#define INS_READ_STATUS
Definition: mrvlqspi.c:51
static int mrvlqspi_set_addr(struct flash_bank *bank, uint32_t addr)
Definition: mrvlqspi.c:84
#define CHIP_ERASE_TIMEOUT
Definition: mrvlqspi.c:35
const struct flash_driver mrvlqspi_flash
Definition: mrvlqspi.c:943
#define QSPI_SS_ENABLE
Definition: mrvlqspi.c:28
static int mrvlqspi_block_erase(struct flash_bank *bank, uint32_t offset)
Definition: mrvlqspi.c:454
#define SS_EN
Definition: mrvlqspi.c:37
#define BLOCK_ERASE_TIMEOUT
Definition: mrvlqspi.c:34
#define CNTL
Definition: mrvlqspi.c:54
#define FIFO_FLUSH_TIMEOUT
Definition: mrvlqspi.c:33
static int mrvlqspi_set_write_status(struct flash_bank *bank, bool mode)
Definition: mrvlqspi.c:366
static int mrvlqspi_read_byte(struct flash_bank *bank, uint8_t *data)
Definition: mrvlqspi.c:287
static int mrvlqspi_probe(struct flash_bank *bank)
Definition: mrvlqspi.c:818
#define XFER_RDY
Definition: mrvlqspi.c:38
#define DIN
Definition: mrvlqspi.c:57
static int mrvlqspi_stop_transfer(struct flash_bank *bank)
Definition: mrvlqspi.c:192
#define CONF_MASK
Definition: mrvlqspi.c:46
#define ADDR
Definition: mrvlqspi.c:59
#define XFER_STOP
Definition: mrvlqspi.c:44
static int mrvlqspi_auto_probe(struct flash_bank *bank)
Definition: mrvlqspi.c:892
#define INSTR
Definition: mrvlqspi.c:58
static int mrvlqspi_read_id(struct flash_bank *bank, uint32_t *id)
Definition: mrvlqspi.c:402
static int mrvlqspi_set_ss_state(struct flash_bank *bank, bool state, int timeout)
Definition: mrvlqspi.c:123
static int mrvlqspi_bulk_erase(struct flash_bank *bank)
Definition: mrvlqspi.c:490
#define QSPI_W_EN
Definition: mrvlqspi.c:26
#define RW_EN
Definition: mrvlqspi.c:43
#define INS_WRITE_ENABLE
Definition: mrvlqspi.c:49
#define QSPI_R_EN
Definition: mrvlqspi.c:25
#define CONF_OFFSET
Definition: mrvlqspi.c:47
#define CONF
Definition: mrvlqspi.c:55
static int mrvlqspi_set_conf(struct flash_bank *bank, uint32_t conf_val)
Definition: mrvlqspi.c:105
target_addr_t addr
Start address to search for the control block.
Definition: rtt/rtt.c:28
const struct flash_device flash_devices[]
Definition: spi.c:24
#define SPIFLASH_READ_ID
Definition: spi.h:72
#define SPIFLASH_READ
Definition: spi.h:78
#define SPIFLASH_DEF_PAGESIZE
Definition: spi.h:82
unsigned int common_magic
Definition: armv7m.h:295
enum arm_mode core_mode
Definition: armv7m.h:297
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:75
uint32_t sectorsize
Definition: spi.h:29
uint32_t device_id
Definition: spi.h:27
uint8_t chip_erase_cmd
Definition: spi.h:26
const char * name
Definition: spi.h:21
uint32_t pagesize
Definition: spi.h:28
uint32_t size_in_bytes
Definition: spi.h:30
uint8_t erase_cmd
Definition: spi.h:25
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
Definition: nor/driver.h:39
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Definition: nor/driver.h:44
Describes the geometry and status of a single flash sector within a flash bank.
Definition: nor/core.h:28
int is_erased
Indication of erasure status: 0 = not erased, 1 = erased, other = unknown.
Definition: nor/core.h:42
uint32_t offset
Bus offset from start of the flash chip (in bytes).
Definition: nor/core.h:30
int is_protected
Indication of protection status: 0 = unprotected/unlocked, 1 = protected/locked, other = unknown.
Definition: nor/core.h:55
uint32_t size
Number of bytes in this flash sector.
Definition: nor/core.h:32
uint32_t reg_base
Definition: mrvlqspi.c:66
uint32_t bank_num
Definition: mrvlqspi.c:67
const struct flash_device * dev
Definition: mrvlqspi.c:68
Definition: register.h:111
Definition: target.h:116
enum target_state state
Definition: target.h:157
Definition: psoc6.c:84
uint32_t size
Definition: target.h:87
target_addr_t address
Definition: target.h:86
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2342
uint32_t target_get_working_area_avail(struct target *target)
Definition: target.c:2164
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
Definition: target.c:2060
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2641
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
Definition: target.c:2118
int target_run_flash_async_algorithm(struct target *target, const uint8_t *buffer, uint32_t count, int block_size, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t buffer_start, uint32_t buffer_size, uint32_t entry_point, uint32_t exit_point, void *arch_info)
Streams data to a circular buffer on target intended for consumption by code running asynchronously o...
Definition: target.c:930
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2550
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:790
@ TARGET_HALTED
Definition: target.h:56
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:794
#define NULL
Definition: usb.h:16
uint8_t cmd
Definition: vdebug.c:1
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t state[4]
Definition: vdebug.c:21
uint8_t count[4]
Definition: vdebug.c:22