OpenOCD
dw-spi.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include "dw-spi-helper.h"
34 #include "imp.h"
35 #include "spi.h"
36 
37 #include <helper/bits.h>
38 #include <helper/time_support.h>
39 #include <target/algorithm.h>
40 #include <target/breakpoints.h>
41 #include <target/mips32.h>
42 #include <target/target_type.h>
43 
52 struct dw_spi_regmap {
53  uint32_t freq;
59 };
60 
64 static const struct dw_spi_regmap jaguar2_regmap = {
65  .freq = 250000000UL,
66  .simc = 0x70101000UL,
67  .spi_mst = 0x70000024UL,
68  .si_if_owner_offset = 6,
69 };
70 
74 static const struct dw_spi_regmap ocelot_regmap = {
75  .freq = 250000000UL,
76  .simc = 0x70101000UL,
77  .spi_mst = 0x70000024UL,
78  .si_if_owner_offset = 4,
79 };
80 
81 #define DW_SPI_IF_OWNER_WIDTH 2
82 
91 };
92 
93 #define DW_SPI_REG_CTRLR0 0x00
94 #define DW_SPI_REG_SIMCEN 0x08
95 #define DW_SPI_REG_SER 0x10
96 #define DW_SPI_REG_BAUDR 0x14
97 #define DW_SPI_REG_SR 0x28
98 #define DW_SPI_REG_IMR 0x2c
99 #define DW_SPI_REG_DR 0x60
100 
101 #define DW_SPI_REG_CTRLR0_DFS(x) ((x) & GENMASK(3, 0))
102 #define DW_SPI_REG_CTRLR0_FRF(x) (((x) << 4) & GENMASK(5, 4))
103 #define DW_SPI_REG_CTRLR0_SCPH(x) ((!!(x)) << 6)
104 #define DW_SPI_REG_CTRLR0_SCPOL(x) ((!!(x)) << 7)
105 #define DW_SPI_REG_CTRLR0_TMOD(x) (((x) << 8) & GENMASK(9, 8))
106 #define DW_SPI_REG_SIMCEN_SIMCEN(x) (!!(x))
107 #define DW_SPI_REG_SER_SER(x) ((x) & GENMASK(15, 0))
108 #define DW_SPI_REG_BAUDR_SCKDV(x) ((x) & GENMASK(15, 0))
109 
114  bool probed;
115  uint32_t id;
116  unsigned int speed;
117  unsigned int timeout;
122  struct dw_spi_regmap regmap;
123  const struct flash_device *spi_flash;
124 };
125 
129 #define DW_SPI_ARG_REG "r4"
130 
134 #define DW_SPI_TIMEOUT_DEFAULT (600 * 1000)
135 
140 #define DW_SPI_TIMEOUT_TRANSACTION 1000
141 
152 static int
154 {
155  struct target *const target = bank->target;
156  const struct dw_spi_driver *const driver = bank->driver_priv;
157  const struct dw_spi_regmap *const regmap = &driver->regmap;
158 
159  if (!regmap->spi_mst)
160  return ERROR_OK;
161 
162  uint32_t ctrl;
163  int ret = target_read_u32(target, regmap->spi_mst, &ctrl);
164  if (ret) {
165  LOG_ERROR("DW SPI SPI:MST register read error");
166  return ret;
167  }
169  driver->regmap.si_if_owner_offset);
170  ctrl |= mode << driver->regmap.si_if_owner_offset;
171 
172  ret = target_write_u32(target, regmap->spi_mst, ctrl);
173  if (ret)
174  LOG_ERROR("DW SPI controller mode configuration error");
175 
176  return ret;
177 }
178 
190 static int
192  enum dw_spi_si_mode mode)
193 {
194  struct target *const target = bank->target;
195  struct dw_spi_driver *const driver = bank->driver_priv;
196  const struct dw_spi_regmap *const regmap = &driver->regmap;
197 
198  if (!regmap->spi_mst)
199  return ERROR_OK;
200 
201  uint32_t ctrl;
202  int ret = target_read_u32(target, regmap->spi_mst, &ctrl);
203  if (ret) {
204  LOG_ERROR("DW SPI controller mode query error");
205  return ret;
206  }
207  driver->saved_ctrl_mode =
208  (enum dw_spi_si_mode)((ctrl >> driver->regmap.si_if_owner_offset) &
210 
211  return dw_spi_ctrl_mode(bank, mode);
212 }
213 
225 static int
227 {
228  const struct dw_spi_driver *const driver = bank->driver_priv;
229 
230  return dw_spi_ctrl_mode(bank, driver->saved_ctrl_mode);
231 }
232 
242 static int
243 dw_spi_master_ctrl_enable(const struct flash_bank *const bank, bool value)
244 {
245  struct target *const target = bank->target;
246  const struct dw_spi_driver *const driver = bank->driver_priv;
247  const struct dw_spi_regmap *const regmap = &driver->regmap;
248 
249  int ret = target_write_u32(target, regmap->simc + DW_SPI_REG_SIMCEN,
250  DW_SPI_REG_SIMCEN_SIMCEN(value));
251  if (ret)
252  LOG_ERROR("DW SPI master controller enable flag configuration error");
253 
254  return ret;
255 }
256 
263 static int
265 {
266  struct target *const target = bank->target;
267  const struct dw_spi_driver *const driver = bank->driver_priv;
268  const struct dw_spi_regmap *const regmap = &driver->regmap;
269 
270  // 8 bit frame; Motorola protocol; middle lo probe; TX RX mode
271  const uint32_t mode = DW_SPI_REG_CTRLR0_DFS(0x7) |
276 
277  int ret = target_write_u32(target, regmap->simc + DW_SPI_REG_CTRLR0, mode);
278  if (ret) {
279  LOG_ERROR("DW SPI master controller configuration query error");
280  return ret;
281  }
282 
283  ret = target_write_u32(target, regmap->simc + DW_SPI_REG_SER,
285  if (ret)
286  LOG_ERROR("DW SPI slave select configuration error");
287 
288  return ret;
289 }
290 
297 static int
299 {
300  struct target *const target = bank->target;
301  const struct dw_spi_driver *const driver = bank->driver_priv;
302  const struct dw_spi_regmap *const regmap = &driver->regmap;
303 
304  // divisor LSB must be zero
305  const uint16_t div = MIN((regmap->freq / driver->speed), 0xfffe) & 0xfffe;
306 
307  int ret = target_write_u32(target, regmap->simc + DW_SPI_REG_BAUDR,
309  if (ret) {
310  LOG_ERROR("DW SPI speed configuration error");
311  return ret;
312  }
313 
314  unsigned int speed = regmap->freq / div;
315  LOG_DEBUG("DW SPI setting NOR controller speed to %u kHz", speed / 1000);
316 
317  return ret;
318 }
319 
326 static int
328 {
329  struct target *const target = bank->target;
330  const struct dw_spi_driver *const driver = bank->driver_priv;
331  const struct dw_spi_regmap *const regmap = &driver->regmap;
332 
333  int ret = target_write_u32(target, regmap->simc + DW_SPI_REG_IMR, 0);
334  if (ret)
335  LOG_ERROR("DW SPI disable interrupts error");
336 
337  return ret;
338 }
339 
355 static int
357  uint8_t *const buffer, size_t size, bool read)
358 {
359  struct target *const target = bank->target;
360  const struct dw_spi_driver *const driver = bank->driver_priv;
361  const struct dw_spi_regmap *const regmap = &driver->regmap;
362 
363  static const uint8_t target_code[] = {
364 #include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-transaction.inc"
365  };
366  const size_t target_code_size = sizeof(target_code);
367  const size_t total_working_area_size =
368  target_code_size + sizeof(struct dw_spi_transaction) + size;
369 
370  // allocate working area, memory args and data buffer
371  struct working_area *helper;
372  int ret = target_alloc_working_area(target, target_code_size, &helper);
373  if (ret) {
374  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
375  total_working_area_size);
376  goto err_helper;
377  }
378 
379  struct working_area *helper_args;
381  &helper_args);
382  if (ret) {
383  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
384  total_working_area_size);
385  goto err_helper_args;
386  }
387 
388  struct working_area *target_buffer;
389  ret = target_alloc_working_area(target, size, &target_buffer);
390  if (ret) {
391  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
392  total_working_area_size);
393  goto err_target_buffer;
394  }
395 
396  // write algorithm code and buffer to working areas
397  ret = target_write_buffer(target, helper->address, target_code_size,
398  target_code);
399  if (ret) {
400  LOG_ERROR("DW SPI writing to working area error");
401  goto err_write_buffer;
402  }
403 
404  ret = target_write_buffer(target, target_buffer->address, size, buffer);
405  if (ret) {
406  LOG_ERROR("DW SPI writing to working area error");
407  goto err_write_buffer;
408  }
409 
410  // prepare helper execution
411  struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC,
412  .isa_mode = MIPS32_ISA_MIPS32 };
413 
414  struct reg_param reg_param;
416  struct mem_param mem_param;
417  init_mem_param(&mem_param, helper_args->address, helper_args->size,
418  PARAM_OUT);
419 
420  // Set the arguments for the helper
421  buf_set_u32(reg_param.value, 0, 32, helper_args->address);
422 
423  struct dw_spi_transaction *helper_args_val =
425  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer,
426  target_buffer->address);
427  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->size, size);
428  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg,
429  regmap->simc + DW_SPI_REG_SR);
430  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg,
431  regmap->simc + DW_SPI_REG_DR);
432  helper_args_val->read_flag = read;
433 
436  &mips32_algo);
437 
438  if (ret) {
439  LOG_ERROR("DW SPI flash algorithm error");
440  goto cleanup;
441  }
442 
443  if (read) {
444  ret = target_read_buffer(target, target_buffer->address, size, buffer);
445  if (ret)
446  LOG_ERROR("DW SPI target buffer read error");
447  }
448 
449 cleanup:
452 
453 err_write_buffer:
454  target_free_working_area(target, target_buffer);
455 err_target_buffer:
456  target_free_working_area(target, helper_args);
457 err_helper_args:
459 err_helper:
460 
461  return ret;
462 }
463 
479 static int
481  uint32_t address, size_t sector_size,
482  size_t sector_count, uint8_t pattern,
483  uint8_t read_cmd, uint8_t *buffer)
484 {
485  struct target *const target = bank->target;
486  const struct dw_spi_driver *const driver = bank->driver_priv;
487  const struct dw_spi_regmap *const regmap = &driver->regmap;
488 
489  static const uint8_t target_code[] = {
490 #include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-check_fill.inc"
491  };
492  const size_t target_code_size = sizeof(target_code);
493  const size_t total_working_area_size =
494  target_code_size + sizeof(struct dw_spi_check_fill) + sector_count;
495 
496  // allocate working area, memory args and data buffer
497  struct working_area *helper;
498  int ret = target_alloc_working_area(target, target_code_size, &helper);
499  if (ret) {
500  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
501  total_working_area_size);
502  goto err_helper;
503  }
504 
505  struct working_area *helper_args;
506  ret = target_alloc_working_area(target, sizeof(struct dw_spi_check_fill),
507  &helper_args);
508  if (ret) {
509  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
510  total_working_area_size);
511  goto err_helper_args;
512  }
513 
514  struct working_area *target_buffer;
515  ret = target_alloc_working_area(target, sector_count, &target_buffer);
516  if (ret) {
517  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
518  total_working_area_size);
519  goto err_target_buffer;
520  }
521 
522  // write algorithm code and buffer to working areas
523  ret = target_write_buffer(target, helper->address, target_code_size,
524  target_code);
525  if (ret) {
526  LOG_ERROR("DW SPI writing to working area error");
527  goto err_write_buffer;
528  }
529 
530  // prepare helper execution
531  struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC,
532  .isa_mode = MIPS32_ISA_MIPS32 };
533 
534  struct reg_param reg_param;
536  struct mem_param mem_param;
537  init_mem_param(&mem_param, helper_args->address, helper_args->size,
538  PARAM_OUT);
539 
540  // Set the arguments for the helper
541  buf_set_u32(reg_param.value, 0, 32, helper_args->address);
542 
543  struct dw_spi_check_fill *helper_args_val =
545  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->address,
546  address);
547  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->sector_size,
548  sector_size);
549  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->sector_count,
550  sector_count);
551  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg,
552  regmap->simc + DW_SPI_REG_SR);
553  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg,
554  regmap->simc + DW_SPI_REG_DR);
556  (uint8_t *)&helper_args_val->fill_status_array,
557  target_buffer->address);
558  helper_args_val->pattern = pattern;
559  helper_args_val->read_cmd = read_cmd;
560  helper_args_val->four_byte_mode = driver->four_byte_mode;
561 
563  helper->address, 0, driver->timeout,
564  &mips32_algo);
565 
566  if (ret) {
567  LOG_ERROR("DW SPI flash algorithm error");
568  goto cleanup;
569  }
570 
571  ret = target_read_buffer(target, target_buffer->address, sector_count,
572  buffer);
573  if (ret)
574  LOG_ERROR("DW SPI target buffer read error");
575 
576 cleanup:
579 
580 err_write_buffer:
581  target_free_working_area(target, target_buffer);
582 err_target_buffer:
583  target_free_working_area(target, helper_args);
584 err_helper_args:
586 err_helper:
587 
588  return ret;
589 }
590 
607 static int
608 dw_spi_ctrl_program(const struct flash_bank *const bank, uint32_t address,
609  const uint8_t *const buffer, size_t buffer_size,
610  uint32_t page_size, uint8_t stat_cmd, uint8_t we_cmd,
611  uint8_t program_cmd, uint8_t we_mask, uint8_t busy_mask)
612 {
613  struct target *const target = bank->target;
614  const struct dw_spi_driver *const driver = bank->driver_priv;
615  const struct dw_spi_regmap *const regmap = &driver->regmap;
616 
617  static const uint8_t target_code[] = {
618 #include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-program.inc"
619  };
620  const size_t target_code_size = sizeof(target_code);
621  const size_t total_working_area_size =
622  target_code_size + sizeof(struct dw_spi_program) + buffer_size;
623 
624  // allocate working area, memory args and data buffer
625  struct working_area *helper;
626  int ret = target_alloc_working_area(target, target_code_size, &helper);
627  if (ret) {
628  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
629  total_working_area_size);
630  goto err_helper;
631  }
632 
633  struct working_area *helper_args;
634  ret = target_alloc_working_area(target, sizeof(struct dw_spi_program),
635  &helper_args);
636  if (ret) {
637  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
638  total_working_area_size);
639  goto err_helper_args;
640  }
641 
642  struct working_area *target_buffer;
643  ret = target_alloc_working_area(target, buffer_size, &target_buffer);
644  if (ret) {
645  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
646  total_working_area_size);
647  goto err_target_buffer;
648  }
649 
650  // write algorithm code and buffer to working areas
651  ret = target_write_buffer(target, helper->address, target_code_size,
652  target_code);
653  if (ret) {
654  LOG_ERROR("DW SPI writing to working area error");
655  goto err_write_buffer;
656  }
657 
658  ret = target_write_buffer(target, target_buffer->address, buffer_size,
659  buffer);
660  if (ret) {
661  LOG_ERROR("DW SPI writing to working area error");
662  goto err_write_buffer;
663  }
664 
665  // prepare helper execution
666  struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC,
667  .isa_mode = MIPS32_ISA_MIPS32 };
668 
669  struct reg_param reg_param;
671  struct mem_param mem_param;
672  init_mem_param(&mem_param, helper_args->address, helper_args->size,
673  PARAM_OUT);
674 
675  // Set the arguments for the helper
676  buf_set_u32(reg_param.value, 0, 32, helper_args->address);
677  struct dw_spi_program *helper_args_val =
678  (struct dw_spi_program *)mem_param.value;
679  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->address,
680  address);
681  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->page_size,
682  page_size);
683  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer,
684  target_buffer->address);
685  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer_size,
686  buffer_size);
687  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg,
688  regmap->simc + DW_SPI_REG_SR);
689  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg,
690  regmap->simc + DW_SPI_REG_DR);
691  helper_args_val->read_status_cmd = stat_cmd;
692  helper_args_val->write_enable_cmd = we_cmd;
693  helper_args_val->program_cmd = program_cmd;
694  helper_args_val->write_enable_mask = we_mask;
695  helper_args_val->busy_mask = busy_mask;
696  helper_args_val->four_byte_mode = driver->four_byte_mode;
697 
699  helper->address, 0, driver->timeout,
700  &mips32_algo);
701  if (ret)
702  LOG_ERROR("DW SPI flash algorithm error");
703 
706 
707 err_write_buffer:
708  target_free_working_area(target, target_buffer);
709 err_target_buffer:
710  target_free_working_area(target, helper_args);
711 err_helper_args:
713 err_helper:
714 
715  return ret;
716 }
717 
732 static int
733 dw_spi_ctrl_erase_sectors(const struct flash_bank *const bank, uint32_t address,
734  uint32_t sector_size, size_t sector_count,
735  uint8_t stat_cmd, uint8_t we_cmd,
736  uint8_t erase_sector_cmd, uint8_t we_mask,
737  uint8_t busy_mask)
738 {
739  struct target *const target = bank->target;
740  const struct dw_spi_driver *const driver = bank->driver_priv;
741  const struct dw_spi_regmap *const regmap = &driver->regmap;
742 
743  static const uint8_t target_code[] = {
744 #include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-erase.inc"
745  };
746  const size_t target_code_size = sizeof(target_code);
747  const size_t total_working_area_size =
748  target_code_size + sizeof(struct dw_spi_erase);
749 
750  // allocate working area and memory args
751  struct working_area *helper;
752  int ret = target_alloc_working_area(target, target_code_size, &helper);
753  if (ret) {
754  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
755  total_working_area_size);
756  goto err_helper;
757  }
758 
759  struct working_area *helper_args;
760  ret = target_alloc_working_area(target, sizeof(struct dw_spi_erase),
761  &helper_args);
762  if (ret) {
763  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
764  total_working_area_size);
765  goto err_helper_args;
766  }
767 
768  // write algorithm code to working area
769  ret = target_write_buffer(target, helper->address, target_code_size,
770  target_code);
771  if (ret) {
772  LOG_ERROR("DW SPI writing to working area error");
773  goto err_write_buffer;
774  }
775 
776  // prepare helper execution
777  struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC,
778  .isa_mode = MIPS32_ISA_MIPS32 };
779 
780  struct reg_param reg_param;
782  struct mem_param mem_param;
783  init_mem_param(&mem_param, helper_args->address, helper_args->size,
784  PARAM_OUT);
785 
786  // Set the arguments for the helper
787  buf_set_u32(reg_param.value, 0, 32, helper_args->address);
788  struct dw_spi_erase *helper_args_val =
789  (struct dw_spi_erase *)mem_param.value;
790  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->address,
791  address);
792  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->sector_size,
793  sector_size);
794  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->sector_count,
795  sector_count);
796  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg,
797  regmap->simc + DW_SPI_REG_SR);
798  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg,
799  regmap->simc + DW_SPI_REG_DR);
800  helper_args_val->read_status_cmd = stat_cmd;
801  helper_args_val->write_enable_cmd = we_cmd;
802  helper_args_val->erase_sector_cmd = erase_sector_cmd;
803  helper_args_val->write_enable_mask = we_mask;
804  helper_args_val->busy_mask = busy_mask;
805  helper_args_val->four_byte_mode = driver->four_byte_mode;
806 
808  helper->address, 0, driver->timeout,
809  &mips32_algo);
810  if (ret)
811  LOG_ERROR("DW SPI flash algorithm error");
812 
815 
816 err_write_buffer:
817  target_free_working_area(target, helper_args);
818 err_helper_args:
820 err_helper:
821 
822  return ret;
823 }
824 
835 static int
836 dw_spi_ctrl_read(const struct flash_bank *const bank, uint32_t address,
837  uint8_t *buffer, size_t buffer_size, uint8_t read_cmd)
838 {
839  struct target *const target = bank->target;
840  const struct dw_spi_driver *const driver = bank->driver_priv;
841  const struct dw_spi_regmap *const regmap = &driver->regmap;
842 
843  static const uint8_t target_code[] = {
844 #include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-read.inc"
845  };
846  const size_t target_code_size = sizeof(target_code);
847  const size_t total_working_area_size =
848  target_code_size + sizeof(struct dw_spi_read) + buffer_size;
849 
850  // allocate working area and memory args
851  struct working_area *helper;
852  int ret = target_alloc_working_area(target, target_code_size, &helper);
853  if (ret) {
854  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
855  total_working_area_size);
856  goto err_helper;
857  }
858 
859  struct working_area *helper_args;
860  ret = target_alloc_working_area(target, sizeof(struct dw_spi_read),
861  &helper_args);
862  if (ret) {
863  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
864  total_working_area_size);
865  goto err_helper_args;
866  }
867 
868  struct working_area *target_buffer;
869  ret = target_alloc_working_area(target, buffer_size, &target_buffer);
870  if (ret) {
871  LOG_ERROR("DW SPI could not allocate working area. Need %zx",
872  total_working_area_size);
873  goto err_target_buffer;
874  }
875 
876  // write algorithm code to working area
877  ret = target_write_buffer(target, helper->address, target_code_size,
878  target_code);
879  if (ret) {
880  LOG_ERROR("DW SPI writing to working area error");
881  goto err_write_buffer;
882  }
883 
884  // prepare helper execution
885  struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC,
886  .isa_mode = MIPS32_ISA_MIPS32 };
887 
888  struct reg_param reg_param;
890  struct mem_param mem_param;
891  init_mem_param(&mem_param, helper_args->address, helper_args->size,
892  PARAM_OUT);
893 
894  // Set the arguments for the helper
895  buf_set_u32(reg_param.value, 0, 32, helper_args->address);
896  struct dw_spi_read *helper_args_val = (struct dw_spi_read *)mem_param.value;
897  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->address,
898  address);
899  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer,
900  target_buffer->address);
901  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer_size,
902  buffer_size);
903  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg,
904  regmap->simc + DW_SPI_REG_SR);
905  target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg,
906  regmap->simc + DW_SPI_REG_DR);
907  helper_args_val->read_cmd = read_cmd;
908  helper_args_val->four_byte_mode = driver->four_byte_mode;
909 
911  helper->address, 0, driver->timeout,
912  &mips32_algo);
913  if (ret) {
914  LOG_ERROR("DW SPI flash algorithm error");
915  goto cleanup;
916  }
917 
918  ret =
920  if (ret)
921  LOG_ERROR("DW SPI target buffer read error");
922 
923 cleanup:
926 
927 err_write_buffer:
928  target_free_working_area(target, target_buffer);
929 err_target_buffer:
930  target_free_working_area(target, helper_args);
931 err_helper_args:
933 err_helper:
934 
935  return ret;
936 }
937 
944 static int
945 dw_spi_read_id(const struct flash_bank *const bank)
946 {
947  struct dw_spi_driver *const driver = bank->driver_priv;
948 
949  const size_t buffer_size = 1 + 3 + 1;
950  uint8_t buffer[buffer_size];
951 
952  memset(buffer, 0, buffer_size);
954 
955  int ret = dw_spi_ctrl_transaction(bank, buffer, buffer_size, true);
956  if (ret) {
957  LOG_ERROR("DW SPI flash ID read error");
958  return ret;
959  }
960 
961  buffer[buffer_size - 1] = 0;
962  // use le_to_h_u32 to decode flash ID as per JEDEC SFDP
963  driver->id = le_to_h_u32(buffer + 1);
964  LOG_DEBUG("DW SPI read flash ID %" PRIx32, driver->id);
965 
966  return ERROR_OK;
967 }
968 
976 static int
977 dw_spi_read_status(const struct flash_bank *const bank, uint8_t *const status)
978 {
979  const int buffer_size = 2;
980  uint8_t buffer[buffer_size];
981 
982  memset(buffer, 0, buffer_size);
984 
985  int ret = dw_spi_ctrl_transaction(bank, buffer, buffer_size, true);
986  if (ret) {
987  LOG_ERROR("DW SPI flash status read error");
988  return ret;
989  }
990 
991  *status = buffer[1];
992 
993  return ERROR_OK;
994 }
995 
1003 static int
1004 dw_spi_wait_finish(const struct flash_bank *const bank, unsigned int timeout)
1005 {
1006  const int64_t end_time = timeval_ms() + timeout;
1007  while (timeval_ms() <= end_time) {
1008  uint8_t status;
1009  int ret = dw_spi_read_status(bank, &status);
1010  if (ret) {
1011  LOG_ERROR("DW SPI status query error");
1012  return ret;
1013  }
1014  if (!(status & SPIFLASH_BSY_BIT))
1015  return ERROR_OK;
1016 
1017  alive_sleep(1);
1018  }
1019 
1020  LOG_ERROR("DW SPI process timeout");
1021  return ERROR_TIMEOUT_REACHED;
1022 }
1023 
1030 static int
1032 {
1033  const int buffer_size = 1;
1034  uint8_t buffer[buffer_size];
1035 
1036  memset(buffer, 0, buffer_size);
1038 
1039  int ret = dw_spi_ctrl_transaction(bank, buffer, buffer_size, false);
1040  if (ret) {
1041  LOG_ERROR("DW SPI flash write enable error");
1042  return ret;
1043  }
1044 
1045  uint8_t status;
1046  ret = dw_spi_read_status(bank, &status);
1047  if (ret)
1048  return ret;
1049 
1051 }
1052 
1059 static int
1060 dw_spi_erase_chip(const struct flash_bank *const bank)
1061 {
1062  const struct dw_spi_driver *const driver = bank->driver_priv;
1063 
1064  const int buffer_size = 1;
1065  uint8_t buffer[buffer_size];
1066 
1067  int ret = dw_spi_write_enable(bank);
1068  if (ret)
1069  return ret;
1070 
1071  memset(buffer, 0, buffer_size);
1072  buffer[0] = driver->spi_flash->chip_erase_cmd;
1073 
1075  if (ret) {
1076  LOG_ERROR("DW SPI erase flash error");
1077  return ret;
1078  }
1079 
1080  ret = dw_spi_wait_finish(bank, driver->timeout);
1081  if (ret) {
1082  LOG_ERROR("DW SPI erase flash timeout");
1083  return ret;
1084  }
1085 
1086  return ERROR_OK;
1087 }
1088 
1097 static int
1098 dw_spi_erase_sectors(const struct flash_bank *const bank, unsigned int first,
1099  unsigned int last)
1100 {
1101  const struct dw_spi_driver *const driver = bank->driver_priv;
1102 
1103  if (first == 0 && last >= (bank->num_sectors - 1)) {
1104  // full erase
1105  int ret = dw_spi_erase_chip(bank);
1106  if (ret)
1107  return ret;
1108  } else {
1109  // partial erase
1110  int ret = dw_spi_ctrl_erase_sectors(bank, bank->sectors[first].offset,
1111  driver->spi_flash->sectorsize,
1112  last - first + 1,
1115  driver->spi_flash->erase_cmd,
1117  if (ret) {
1118  LOG_ERROR("DW SPI flash erase sectors error");
1119  return ret;
1120  }
1121  }
1122 
1123  return ERROR_OK;
1124 }
1125 
1129 static int
1131  uint8_t pattern)
1132 {
1133  const struct dw_spi_driver *const driver = bank->driver_priv;
1134 
1135  uint8_t *erased = malloc(sector_count);
1136  if (!erased) {
1137  LOG_ERROR("could not allocate memory");
1138  return ERROR_FAIL;
1139  }
1140 
1141  // set initial erased value to unknown
1142  memset(erased, 2, sector_count);
1143  for (unsigned int sector_idx = 0; sector_idx < sector_count; sector_idx++)
1144  bank->sectors[sector_idx].is_erased = 2;
1145 
1146  int ret = dw_spi_ctrl_check_sectors_fill(bank, 0, bank->sectors[0].size,
1148  driver->spi_flash->read_cmd,
1149  erased);
1150  if (!ret) {
1151  for (unsigned int sector_idx = 0; sector_idx < sector_count;
1152  sector_idx++)
1153  bank->sectors[sector_idx].is_erased = erased[sector_idx];
1154  } else {
1155  LOG_ERROR("DW SPI flash erase check error");
1156  }
1157 
1158  free(erased);
1159 
1160  return ret;
1161 }
1162 
1172 static int
1173 dw_spi_write_buffer(const struct flash_bank *const bank, const uint8_t *buffer,
1174  uint32_t offset, uint32_t count)
1175 {
1176  const struct dw_spi_driver *const driver = bank->driver_priv;
1177  const size_t page_size = driver->spi_flash->pagesize;
1178 
1179  // Write unaligned first sector separately as helper function does
1180  // not handle this case well.
1181  struct {
1182  uint32_t address;
1183  const uint8_t *buffer;
1184  size_t count;
1185  } chunks[2] = {
1186  { .address = offset, .buffer = buffer, .count = 0 },
1187  { .address = offset, .buffer = buffer, .count = count },
1188  };
1189 
1190  if (offset % page_size) {
1191  // start is not aligned
1192  chunks[0].count = MIN(page_size - (offset % page_size), count);
1193  chunks[1].count -= chunks[0].count;
1194  chunks[1].address += chunks[0].count;
1195  chunks[1].buffer += chunks[0].count;
1196  }
1197 
1198  for (unsigned int chunk_idx = 0; chunk_idx < ARRAY_SIZE(chunks);
1199  chunk_idx++) {
1200  if (chunks[chunk_idx].count > 0) {
1201  int ret = dw_spi_ctrl_program(bank, chunks[chunk_idx].address,
1202  chunks[chunk_idx].buffer,
1203  chunks[chunk_idx].count, page_size,
1206  driver->spi_flash->pprog_cmd,
1208  if (ret) {
1209  LOG_ERROR("DW SPI flash write error");
1210  return ret;
1211  }
1212  }
1213  }
1214 
1215  return ERROR_OK;
1216 }
1217 
1224 static int
1226 {
1227  struct dw_spi_driver *const driver = bank->driver_priv;
1228 
1229  int ret = dw_spi_read_id(bank);
1230  if (ret)
1231  return ret;
1232 
1233  unsigned int idx = 0;
1234  while (flash_devices[idx].name) {
1235  if (flash_devices[idx].device_id == driver->id) {
1236  driver->spi_flash = &flash_devices[idx];
1237  return ERROR_OK;
1238  }
1239  idx++;
1240  }
1241 
1242  LOG_ERROR("DW SPI could not find Flash with ID %" PRIx32
1243  " in SPI Flash table: either Flash device is not supported "
1244  "or communication speed is too high",
1245  driver->id);
1246  return ERROR_FAIL;
1247 }
1248 
1256 FLASH_BANK_COMMAND_HANDLER(dw_spi_flash_bank_command)
1257 {
1258  unsigned int speed = 1000000;
1259  unsigned int timeout = DW_SPI_TIMEOUT_DEFAULT;
1260  uint8_t chip_select_bitmask = BIT(0);
1261  struct dw_spi_regmap regmap = { 0 };
1262 
1263  if (CMD_ARGC < 6)
1265 
1266  for (unsigned int idx = 6; idx < CMD_ARGC; idx++) {
1267  if (strcmp(CMD_ARGV[idx], "-jaguar2") == 0) {
1268  // Fast config for Jaguar2 chips.
1269  memcpy(&regmap, &jaguar2_regmap, sizeof(jaguar2_regmap));
1270  } else if (strcmp(CMD_ARGV[idx], "-ocelot") == 0) {
1271  // Fast config for Ocelot chips.
1272  memcpy(&regmap, &ocelot_regmap, sizeof(ocelot_regmap));
1273  } else if (strcmp(CMD_ARGV[idx], "-freq") == 0) {
1274  COMMAND_PARSE_NUMBER(u32, CMD_ARGV[++idx], regmap.freq);
1275  } else if (strcmp(CMD_ARGV[idx], "-simc") == 0) {
1276  COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[++idx], regmap.simc);
1277  } else if (strcmp(CMD_ARGV[idx], "-spi_mst") == 0) {
1278  COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[++idx], regmap.spi_mst);
1279  } else if (strcmp(CMD_ARGV[idx], "-if_owner_offset") == 0) {
1280  COMMAND_PARSE_NUMBER(u8, CMD_ARGV[++idx],
1281  regmap.si_if_owner_offset);
1282  } else if (strcmp(CMD_ARGV[idx], "-speed") == 0) {
1283  COMMAND_PARSE_NUMBER(uint, CMD_ARGV[++idx], speed);
1284  } else if (strcmp(CMD_ARGV[idx], "-timeout") == 0) {
1285  COMMAND_PARSE_NUMBER(uint, CMD_ARGV[++idx], timeout);
1286  timeout *= 1000; // convert to ms
1287  } else if (strcmp(CMD_ARGV[idx], "-chip_select") == 0) {
1288  unsigned int cs_bit;
1289  COMMAND_PARSE_NUMBER(uint, CMD_ARGV[++idx], cs_bit);
1290  chip_select_bitmask = BIT(cs_bit);
1291  } else {
1292  LOG_WARNING("DW SPI unknown argument %s", CMD_ARGV[idx]);
1293  }
1294  }
1295 
1296  if (!regmap.simc) {
1297  LOG_ERROR("DW SPI cannot use boot controller with unconfigured simc");
1299  }
1300 
1301  bank->driver_priv = malloc(sizeof(struct dw_spi_driver));
1302  if (!bank->driver_priv) {
1303  LOG_ERROR("could not allocate memory");
1304  return ERROR_FAIL;
1305  }
1306 
1307  struct dw_spi_driver *driver = bank->driver_priv;
1308  memset(driver, 0, sizeof(struct dw_spi_driver));
1309  driver->speed = speed;
1310  driver->timeout = timeout;
1312  driver->four_byte_mode = true; // 24bit commands not provided by spi.h
1313  memcpy(&driver->regmap, &regmap, sizeof(regmap));
1314 
1315  return ERROR_OK;
1316 }
1317 
1324 static int
1326 {
1327  if (bank->target->state != TARGET_HALTED) {
1328  LOG_ERROR("target not halted");
1329  return ERROR_TARGET_NOT_HALTED;
1330  }
1331  return ERROR_OK;
1332 }
1333 
1340 static int
1342 {
1343  int ret = dw_spi_assert_halted(bank);
1344  if (ret)
1345  return ret;
1347  if (ret) {
1348  LOG_ERROR("DW SPI switch to master controller mode error");
1349  return ret;
1350  }
1351  ret = dw_spi_master_ctrl_enable(bank, false);
1352  if (ret) {
1353  LOG_ERROR("DW SPI disable master controller error");
1354  return ret;
1355  }
1357  if (ret) {
1358  LOG_ERROR("DW SPI speed configuration error");
1359  return ret;
1360  }
1362  if (ret) {
1363  LOG_ERROR("DW SPI disable SPI interrupts error");
1364  return ret;
1365  }
1367  if (ret) {
1368  LOG_ERROR("DW SPI controller configuration error");
1369  return ret;
1370  }
1371  ret = dw_spi_master_ctrl_enable(bank, true);
1372  if (ret) {
1373  LOG_ERROR("DW SPI enable master controller error");
1374  return ret;
1375  }
1376 
1377  return ERROR_OK;
1378 }
1379 
1386 static int
1388 {
1389  int ret = dw_spi_master_ctrl_enable(bank, false);
1390  if (ret) {
1391  LOG_ERROR("DW SPI disable master controller error");
1392  return ret;
1393  }
1395  if (ret) {
1396  LOG_ERROR("DW SPI controller restore error");
1397  return ret;
1398  }
1399 
1400  return ret;
1401 }
1402 
1409 static int
1411 {
1412  struct dw_spi_driver *const driver = bank->driver_priv;
1413 
1414  if (!driver)
1415  return ERROR_FAIL;
1416 
1417  if (strcmp(bank->target->type->name, mips_m4k_target.name) != 0 ||
1418  bank->target->endianness != TARGET_LITTLE_ENDIAN) {
1419  LOG_ERROR("DW SPI currently only supports "
1420  "little endian mips_m4k target");
1421  return ERROR_TARGET_INVALID;
1422  }
1423 
1425  if (ret)
1426  return ret;
1427 
1429  if (ret)
1430  goto err;
1431 
1432  bank->write_start_alignment = 0;
1433  bank->write_end_alignment = 0;
1434 
1435  uint32_t flash_size = driver->spi_flash->size_in_bytes;
1436  if (!bank->size) {
1437  bank->size = flash_size;
1438  LOG_INFO("DW SPI probed flash size 0x%" PRIx32, flash_size);
1439  } else {
1440  if (flash_size > bank->size)
1441  LOG_WARNING("DW SPI probed flash size 0x%" PRIx32
1442  " is greater then declared 0x%" PRIx32,
1443  flash_size, bank->size);
1444  if (flash_size < bank->size) {
1445  LOG_ERROR("DW SPI probed flash size 0x%" PRIx32
1446  " is smaller then declared 0x%" PRIx32,
1447  flash_size, bank->size);
1449  goto err;
1450  }
1451  }
1452  bank->num_sectors = bank->size / driver->spi_flash->sectorsize;
1453 
1454  // free previously allocated in case of reprobing
1455  free(bank->sectors);
1456 
1457  bank->sectors =
1458  alloc_block_array(0, driver->spi_flash->sectorsize, bank->num_sectors);
1459 
1460  if (!bank->sectors) {
1461  LOG_ERROR("could not allocate memory");
1462  ret = ERROR_FAIL;
1463  goto err;
1464  }
1465 
1466  driver->probed = true;
1467 
1468 err:
1470  return ret;
1471 }
1472 
1481 static int
1482 dw_spi_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
1483 {
1485  if (ret)
1486  return ret;
1487 
1488  ret = dw_spi_erase_sectors(bank, first, last);
1490  return ret;
1491 }
1492 
1502 static int
1503 dw_spi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset,
1504  uint32_t count)
1505 {
1507  if (ret)
1508  return ret;
1509 
1512  return ret;
1513 }
1514 
1524 static int
1525 dw_spi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset,
1526  uint32_t count)
1527 {
1528  struct dw_spi_driver *const driver = bank->driver_priv;
1529 
1531  if (ret)
1532  return ret;
1533 
1535  driver->spi_flash->read_cmd);
1537  return ret;
1538 }
1539 
1546 static int
1548 {
1550  if (ret)
1551  return ret;
1552 
1553  ret = dw_spi_blank_check(bank, bank->num_sectors, bank->erased_value);
1554 
1556  return ret;
1557 }
1558 
1566 static int
1568 {
1569  const struct dw_spi_driver *const driver = bank->driver_priv;
1570  command_print(cmd, "model %s", driver->spi_flash->name);
1571  command_print(cmd, "ID 0x%" PRIx32, driver->id);
1572  command_print_sameline(cmd, "size 0x%" PRIx32, bank->size);
1573  return ERROR_OK;
1574 }
1575 
1582 static int
1584 {
1585  struct dw_spi_driver *driver = bank->driver_priv;
1586  if (!driver)
1587  return ERROR_FAIL;
1588  if (!driver->probed)
1589  return dw_spi_probe(bank);
1590  return ERROR_OK;
1591 }
1592 
1596 const struct flash_driver dw_spi_flash = {
1597  .name = "dw-spi",
1598  .flash_bank_command = dw_spi_flash_bank_command,
1599  .erase = dw_spi_erase,
1600  .write = dw_spi_write,
1601  .read = dw_spi_read,
1602  .probe = dw_spi_probe,
1603  .auto_probe = dw_spi_auto_probe,
1604  .erase_check = dw_spi_erase_check,
1605  .info = dw_spi_info,
1606  .verify = default_flash_verify,
1607  .free_driver_priv = default_flash_free_driver_priv,
1608 };
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
Definition: algorithm.c:29
void destroy_mem_param(struct mem_param *param)
Definition: algorithm.c:23
void destroy_reg_param(struct reg_param *param)
Definition: algorithm.c:37
void init_mem_param(struct mem_param *param, uint32_t address, uint32_t size, enum param_direction direction)
Definition: algorithm.c:15
@ PARAM_OUT
Definition: algorithm.h:16
enum arm_mode mode
Definition: armv4_5.c:281
const char * name
Definition: armv4_5.c:76
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:34
#define GENMASK(h, l)
Definition: bits.h:24
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:420
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:443
#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
Driver for SPI NOR flash chips connected via DesignWare SPI Core.
uint8_t erase_sector_cmd
Erase sector command.
Definition: dw-spi-helper.h:7
uint8_t read_cmd
Read data command.
Definition: dw-spi-helper.h:9
uint8_t pattern
Fill pattern.
Definition: dw-spi-helper.h:8
uint32_t sector_count
Number of sectors to check.
Definition: dw-spi-helper.h:2
uint32_t sector_size
Sector size.
Definition: dw-spi-helper.h:1
uint64_t buffer
Pointer to data buffer to send over SPI.
Definition: dw-spi-helper.h:0
uint32_t page_size
Page size.
Definition: dw-spi-helper.h:3
uint8_t program_cmd
Program command.
Definition: dw-spi-helper.h:10
uint32_t size
Size of dw_spi_transaction::buffer.
Definition: dw-spi-helper.h:4
uint32_t buffer_size
Size of dw_spi_program::buffer.
Definition: dw-spi-helper.h:5
uint32_t address
Starting address. Sector aligned.
Definition: dw-spi-helper.h:0
uint8_t busy_mask
Busy mask.
Definition: dw-spi-helper.h:9
static int dw_spi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Flash bank read data using master controller.
Definition: dw-spi.c:1525
static int dw_spi_erase_sectors(const struct flash_bank *const bank, unsigned int first, unsigned int last)
Flash device erase sectors.
Definition: dw-spi.c:1098
#define DW_SPI_REG_DR
Data register.
Definition: dw-spi.c:99
static int dw_spi_ctrl_transaction(const struct flash_bank *const bank, uint8_t *const buffer, size_t size, bool read)
Do data transaction.
Definition: dw-spi.c:356
static int dw_spi_ctrl_mode_configure(const struct flash_bank *const bank, enum dw_spi_si_mode mode)
Select master controller as SI interface owner.
Definition: dw-spi.c:191
static int dw_spi_auto_probe(struct flash_bank *bank)
Autoprobe driver.
Definition: dw-spi.c:1583
#define DW_SPI_REG_CTRLR0
General configuration register.
Definition: dw-spi.c:93
#define DW_SPI_REG_SER
Slave select register.
Definition: dw-spi.c:95
static int dw_spi_master_ctrl_enable(const struct flash_bank *const bank, bool value)
Enable master controller.
Definition: dw-spi.c:243
static int dw_spi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Flash bank write data.
Definition: dw-spi.c:1503
dw_spi_si_mode
Owner of the SI interface.
Definition: dw-spi.c:86
@ DW_SPI_SI_MODE_MASTER
SPI controller mode for reading/writing SPI Flash.
Definition: dw-spi.c:89
@ DW_SPI_SI_MODE_BOOT
Boot controller maps contents of SPI Flash to memory in read-only mode.
Definition: dw-spi.c:87
static const struct dw_spi_regmap ocelot_regmap
Register map for Ocelot switch devices.
Definition: dw-spi.c:74
static int dw_spi_ctrl_erase_sectors(const struct flash_bank *const bank, uint32_t address, uint32_t sector_size, size_t sector_count, uint8_t stat_cmd, uint8_t we_cmd, uint8_t erase_sector_cmd, uint8_t we_mask, uint8_t busy_mask)
Erase sectors.
Definition: dw-spi.c:733
static int dw_spi_master_ctrl_restore(struct flash_bank *bank)
Restore SI controller selection.
Definition: dw-spi.c:1387
static int dw_spi_erase_check(struct flash_bank *bank)
Flash bank erase check.
Definition: dw-spi.c:1547
static int dw_spi_probe(struct flash_bank *bank)
Flash bank probe.
Definition: dw-spi.c:1410
static int dw_spi_ctrl_read(const struct flash_bank *const bank, uint32_t address, uint8_t *buffer, size_t buffer_size, uint8_t read_cmd)
Read flash data.
Definition: dw-spi.c:836
static int dw_spi_write_buffer(const struct flash_bank *const bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Write buffer to Flash.
Definition: dw-spi.c:1173
static int dw_spi_wait_finish(const struct flash_bank *const bank, unsigned int timeout)
Wait for Flash command to finish.
Definition: dw-spi.c:1004
#define DW_SPI_REG_SIMCEN
Master controller enable register.
Definition: dw-spi.c:94
static int dw_spi_ctrl_configure_speed(const struct flash_bank *const bank)
Configure SI transfer speed.
Definition: dw-spi.c:298
#define DW_SPI_REG_BAUDR
Baud rate configuration register.
Definition: dw-spi.c:96
static int dw_spi_erase_chip(const struct flash_bank *const bank)
Erase Flash chip.
Definition: dw-spi.c:1060
#define DW_SPI_REG_CTRLR0_SCPOL(x)
Probe polarity.
Definition: dw-spi.c:104
#define DW_SPI_REG_BAUDR_SCKDV(x)
Clock divisor.
Definition: dw-spi.c:108
static int dw_spi_write_enable(const struct flash_bank *const bank)
Flash device write enable.
Definition: dw-spi.c:1031
static int dw_spi_info(struct flash_bank *bank, struct command_invocation *cmd)
Flash bank info.
Definition: dw-spi.c:1567
static int dw_spi_spiflash_search(const struct flash_bank *const bank)
Search for Flash chip info.
Definition: dw-spi.c:1225
#define DW_SPI_REG_CTRLR0_FRF(x)
SI protocol.
Definition: dw-spi.c:102
static int dw_spi_ctrl_disable_interrupts(const struct flash_bank *const bank)
Disable SI master controller interrupts.
Definition: dw-spi.c:327
const struct flash_driver dw_spi_flash
DW-SPI NOR flash functions.
Definition: dw-spi.c:1596
#define DW_SPI_ARG_REG
Register used to pass argument struct to helper functions.
Definition: dw-spi.c:129
#define DW_SPI_REG_SER_SER(x)
Slave select bitmask.
Definition: dw-spi.c:107
static int dw_spi_master_ctrl_configure(struct flash_bank *bank)
Prepare master controller for transaction.
Definition: dw-spi.c:1341
static int dw_spi_assert_halted(const struct flash_bank *const bank)
Assert target is halted.
Definition: dw-spi.c:1325
#define DW_SPI_REG_CTRLR0_TMOD(x)
SI mode.
Definition: dw-spi.c:105
#define DW_SPI_REG_CTRLR0_DFS(x)
Data frame size.
Definition: dw-spi.c:101
static int dw_spi_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Flash bank erase sectors.
Definition: dw-spi.c:1482
static int dw_spi_ctrl_configure_si(const struct flash_bank *const bank)
Configure SI transfer mode.
Definition: dw-spi.c:264
#define DW_SPI_TIMEOUT_TRANSACTION
Timeout value in ms for short flash transactions, e.g.
Definition: dw-spi.c:140
static int dw_spi_read_status(const struct flash_bank *const bank, uint8_t *const status)
Read Flash device status.
Definition: dw-spi.c:977
static int dw_spi_ctrl_mode_restore(const struct flash_bank *const bank)
Restore SI controller mode.
Definition: dw-spi.c:226
static int dw_spi_ctrl_mode(const struct flash_bank *const bank, enum dw_spi_si_mode mode)
Select SI interface owner.
Definition: dw-spi.c:153
static int dw_spi_ctrl_program(const struct flash_bank *const bank, uint32_t address, const uint8_t *const buffer, size_t buffer_size, uint32_t page_size, uint8_t stat_cmd, uint8_t we_cmd, uint8_t program_cmd, uint8_t we_mask, uint8_t busy_mask)
Write flash region.
Definition: dw-spi.c:608
#define DW_SPI_IF_OWNER_WIDTH
IF owner register field width.
Definition: dw-spi.c:81
static int dw_spi_ctrl_check_sectors_fill(const struct flash_bank *const bank, uint32_t address, size_t sector_size, size_t sector_count, uint8_t pattern, uint8_t read_cmd, uint8_t *buffer)
Check that selected region is filled with pattern.
Definition: dw-spi.c:480
#define DW_SPI_TIMEOUT_DEFAULT
Default timeout value in ms for flash transaction jobs.
Definition: dw-spi.c:134
#define DW_SPI_REG_SIMCEN_SIMCEN(x)
Controller enable.
Definition: dw-spi.c:106
#define DW_SPI_REG_SR
Status register.
Definition: dw-spi.c:97
static const struct dw_spi_regmap jaguar2_regmap
Register map for Jaguar2 switch devices.
Definition: dw-spi.c:64
static int dw_spi_read_id(const struct flash_bank *const bank)
Read Flash device ID.
Definition: dw-spi.c:945
FLASH_BANK_COMMAND_HANDLER(dw_spi_flash_bank_command)
Handle flash bank command.
Definition: dw-spi.c:1256
static int dw_spi_blank_check(struct flash_bank *bank, size_t sector_count, uint8_t pattern)
Flash bank blank check.
Definition: dw-spi.c:1130
#define DW_SPI_REG_CTRLR0_SCPH(x)
Probe position.
Definition: dw-spi.c:103
#define DW_SPI_REG_IMR
Interrupt configuration register.
Definition: dw-spi.c:98
uint8_t bank
Definition: esirisc.c:135
#define ERROR_FLASH_BANK_INVALID
Definition: flash/common.h:28
int default_flash_verify(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default verify implementation for flash memory.
struct flash_sector * alloc_block_array(uint32_t offset, uint32_t size, unsigned int num_blocks)
Allocate and fill an array of sectors or protection blocks.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
void alive_sleep(uint64_t ms)
Definition: log.c:467
#define LOG_WARNING(expr ...)
Definition: log.h:129
#define ERROR_FAIL
Definition: log.h:173
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define ERROR_TIMEOUT_REACHED
Definition: log.h:176
#define LOG_INFO(expr ...)
Definition: log.h:126
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:167
#define MIPS32_COMMON_MAGIC
Definition: mips32.h:21
@ MIPS32_ISA_MIPS32
Definition: mips32.h:250
struct target_type mips_m4k_target
Definition: mips_m4k.c:1449
#define MIN(a, b)
Definition: replacements.h:22
struct rtt_control ctrl
Control block.
Definition: rtt/rtt.c:25
const struct flash_device flash_devices[]
Definition: spi.c:24
#define SPIFLASH_READ_STATUS
Definition: spi.h:74
#define SPIFLASH_READ_ID
Definition: spi.h:72
#define SPIFLASH_WRITE_ENABLE
Definition: spi.h:75
#define SPIFLASH_WE_BIT
Definition: spi.h:69
#define SPIFLASH_BSY_BIT
Definition: spi.h:67
#define BIT(nr)
Definition: stm32l4x.h:18
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
Arguments for check_fill helper function.
Definition: dw-spi-helper.h:38
uint8_t read_cmd
Read data command.
Definition: dw-spi-helper.h:48
uint64_t status_reg
Pointer to SR register.
Definition: dw-spi-helper.h:42
uint8_t pattern
Fill pattern.
Definition: dw-spi-helper.h:47
uint32_t address
Starting address. Sector aligned.
Definition: dw-spi-helper.h:39
uint64_t fill_status_array
Pointer to array describing sectors fill status.
Definition: dw-spi-helper.h:44
uint8_t four_byte_mode
Four byte addressing mode flag.
Definition: dw-spi-helper.h:49
uint32_t sector_count
Number of sectors to check.
Definition: dw-spi-helper.h:41
uint32_t sector_size
Sector size.
Definition: dw-spi-helper.h:40
uint64_t data_reg
Pointer to DR register.
Definition: dw-spi-helper.h:43
Driver private state.
Definition: dw-spi.c:113
uint8_t chip_select_bitmask
Chip select bitmask.
Definition: dw-spi.c:118
const struct flash_device * spi_flash
SPI flash device info.
Definition: dw-spi.c:123
unsigned int timeout
Flash timeout in milliseconds.
Definition: dw-spi.c:117
bool probed
Bank is probed.
Definition: dw-spi.c:114
bool four_byte_mode
Flash chip is in 32bit address mode.
Definition: dw-spi.c:119
unsigned int speed
Flash speed.
Definition: dw-spi.c:116
enum dw_spi_si_mode saved_ctrl_mode
Previously selected controller mode.
Definition: dw-spi.c:120
struct dw_spi_regmap regmap
SI controller regmap.
Definition: dw-spi.c:122
uint32_t id
Chip ID.
Definition: dw-spi.c:115
Arguments for erase helper function.
Definition: dw-spi-helper.h:55
uint64_t data_reg
Pointer to DR register.
Definition: dw-spi-helper.h:60
uint32_t sector_size
Sector size.
Definition: dw-spi-helper.h:57
uint8_t read_status_cmd
Read status command.
Definition: dw-spi-helper.h:61
uint8_t erase_sector_cmd
Erase sector command.
Definition: dw-spi-helper.h:63
uint8_t four_byte_mode
Four byte addressing mode flag.
Definition: dw-spi-helper.h:66
uint32_t sector_count
Number of sectors to erase.
Definition: dw-spi-helper.h:58
uint8_t write_enable_cmd
Write enable command.
Definition: dw-spi-helper.h:62
uint64_t status_reg
Pointer to SR register.
Definition: dw-spi-helper.h:59
uint8_t write_enable_mask
Write enable mask.
Definition: dw-spi-helper.h:64
uint8_t busy_mask
Busy mask.
Definition: dw-spi-helper.h:65
uint32_t address
First sector address. Sector aligned.
Definition: dw-spi-helper.h:56
Arguments for program helper function.
Definition: dw-spi-helper.h:72
uint8_t four_byte_mode
Four byte addressing mode flag.
Definition: dw-spi-helper.h:86
uint64_t status_reg
Pointer to SR register.
Definition: dw-spi-helper.h:79
uint8_t busy_mask
Busy mask.
Definition: dw-spi-helper.h:85
uint64_t buffer
Data buffer pointer.
Definition: dw-spi-helper.h:77
uint32_t buffer_size
Size of dw_spi_program::buffer.
Definition: dw-spi-helper.h:78
uint8_t write_enable_mask
Write enable mask.
Definition: dw-spi-helper.h:84
uint64_t data_reg
Pointer to DR register.
Definition: dw-spi-helper.h:80
uint32_t address
First page address.
Definition: dw-spi-helper.h:73
uint8_t program_cmd
Program command.
Definition: dw-spi-helper.h:83
uint8_t read_status_cmd
Read status command.
Definition: dw-spi-helper.h:81
uint8_t write_enable_cmd
Write enable command.
Definition: dw-spi-helper.h:82
uint32_t page_size
Page size.
Definition: dw-spi-helper.h:76
Arguments for read helper function.
Definition: dw-spi-helper.h:92
uint32_t buffer_size
Size of dw_spi_read::buffer.
Definition: dw-spi-helper.h:95
uint64_t data_reg
Pointer to DR register.
Definition: dw-spi-helper.h:97
uint32_t address
First sector address.
Definition: dw-spi-helper.h:93
uint64_t buffer
Data buffer pointer.
Definition: dw-spi-helper.h:94
uint8_t four_byte_mode
Four byte addressing mode flag.
Definition: dw-spi-helper.h:99
uint64_t status_reg
Pointer to SR register.
Definition: dw-spi-helper.h:96
uint8_t read_cmd
Read data command.
Definition: dw-spi-helper.h:98
IP block placement map.
Definition: dw-spi.c:52
target_addr_t spi_mst
Absolute offset of ICPU_CFG:SPI_MST register. 0 if not available.
Definition: dw-spi.c:55
target_addr_t simc
Absolute offset of SIMC register block.
Definition: dw-spi.c:54
uint32_t freq
Clock frequency.
Definition: dw-spi.c:53
uint8_t si_if_owner_offset
Offset of si_mode bits in ICPU_CFG:SPI_MST.
Definition: dw-spi.c:57
Arguments for transaction helper function.
Definition: dw-spi-helper.h:23
uint8_t read_flag
When 1, store RX FIFO data to dw_spi_transaction::buffer.
Definition: dw-spi-helper.h:31
uint64_t buffer
Pointer to data buffer to send over SPI.
Definition: dw-spi-helper.h:24
uint32_t size
Size of dw_spi_transaction::buffer.
Definition: dw-spi-helper.h:28
uint64_t status_reg
Pointer to SR register.
Definition: dw-spi-helper.h:29
uint64_t data_reg
Pointer to DR register.
Definition: dw-spi-helper.h:30
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:75
uint8_t read_cmd
Definition: spi.h:22
uint32_t sectorsize
Definition: spi.h:29
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 pprog_cmd
Definition: spi.h:24
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
uint8_t * value
Definition: algorithm.h:23
unsigned int common_magic
Definition: mips32.h:456
uint8_t * value
Definition: algorithm.h:30
const char * name
Name of this type of target.
Definition: target_type.h:31
Definition: target.h:116
Definition: psoc6.c:83
uint32_t size
Definition: target.h:87
target_addr_t address
Definition: target.h:86
void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value)
Definition: target.c:352
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2342
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
Definition: target.c:2407
int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t entry_point, target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
Downloads a target-specific native code algorithm to the target, and executes it.
Definition: target.c:773
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_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
#define ERROR_TARGET_INVALID
Definition: target.h:787
@ TARGET_HALTED
Definition: target.h:56
@ TARGET_LITTLE_ENDIAN
Definition: target.h:82
int64_t timeval_ms(void)
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
uint64_t target_addr_t
Definition: types.h:335
static uint32_t le_to_h_u32(const uint8_t *buf)
Definition: types.h:112
uint8_t status[4]
Definition: vdebug.c:17
uint8_t cmd
Definition: vdebug.c:1
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22