30 #define SPIXFC_FIFO_DEPTH 16
32 #define SPIXFC_HEADER_NULL 0xF000
34 #define SPIXF_BASE 0x40026000
35 #define SPIXF_CFG (SPIXF_BASE | 0x00)
36 #define SPIXF_FETCH_CTRL (SPIXF_BASE | 0x04)
37 #define SPIXF_MODE_CTRL (SPIXF_BASE | 0x08)
38 #define SPIXF_MODE_DATA (SPIXF_BASE | 0x0C)
39 #define SPIXF_SCLK_FB_CTRL (SPIXF_BASE | 0x10)
40 #define SPIXF_IO_CTRL (SPIXF_BASE | 0x1C)
41 #define SPIXF_MEMSECCN (SPIXF_BASE | 0x20)
42 #define SPIXF_BUS_IDLE (SPIXF_BASE | 0x24)
44 #define SPIXF_MEMSECCN_ENC_ENABLE 0x1
45 #define SPIXF_MEMSECCN_AUTH_DISABLE 0x2
47 #define SPI_ICC_BASE 0x4002F000
48 #define SPI_ICC_CTRL (SPI_ICC_BASE | 0x100)
49 #define SPI_ICC_INV (SPI_ICC_BASE | 0x700)
51 #define SPI_ICC_CTRL_EN_POS 0
52 #define SPI_ICC_CTRL_EN (0x1UL << SPI_ICC_CTRL_EN_POS)
53 #define SPI_ICC_CTRL_RDY_POS 16
54 #define SPI_ICC_CTRL_RDY (0x1UL << SPI_ICC_CTRL_RDY_POS)
56 #define GCR_BASE 0x40000000
57 #define GCR_SCON (GCR_BASE | 0x00)
58 #define GCR_RST1 (GCR_BASE | 0x44)
59 #define GCR_RST1_XSPIM (0x1 << 4)
60 #define GCR_RST1_SPIXIP (0x1 << 5)
63 #define SPI_CLOCK_PERIOD 2
66 #define MAX32XXX_QSPI_MASS_ERASE_TIMEOUT_MS 100000
67 #define MAX32XXX_QSPI_ERASE_TIMEOUT_MS 10000
68 #define MAX32XXX_QSPI_WE_TIMEOUT_MS 100
69 #define MAX32XXX_QSPI_FIFO_TIMEOUT_MS 100
73 #define SPI_DUAL_MODE 0
77 #include "contrib/loaders/flash/max32xxx_qspi/max32xxx_qspi.inc"
91 if (CMD_ARGC < 7 || CMD_ARGC > 7) {
92 LOG_ERROR(
"incorrect flash bank max32xxx_qspi configuration: "
93 "<flash_addr_base> <flash_addr_size> 0 0 <target> <opitons>");
106 info->probed =
false;
181 (0x1 << 10) | (0x1 << 12) | max32xxx_qspi_info->
dev.
dread_cmd);
240 temp32 |= (0x1 << 6);
249 const uint8_t *data,
unsigned int len)
252 unsigned int data_i = 0;
254 while (len - data_i) {
255 unsigned int write_len;
261 write_len = len - data_i;
265 unsigned int tx_fifo_avail;
279 }
while (tx_fifo_avail < write_len);
304 unsigned int data_i = 0;
306 while (len - data_i) {
307 unsigned int read_len;
311 unsigned int rx_fifo_avail;
324 }
while (!rx_fifo_avail);
327 if (len - data_i > rx_fifo_avail)
328 read_len = rx_fifo_avail;
330 read_len = len - data_i;
344 unsigned int len,
bool deass)
347 unsigned int data_i = 0;
350 while (len - data_i) {
351 unsigned int chunk_len;
353 if (len - data_i > 32)
356 chunk_len = len - data_i;
364 if (deass && (len - data_i - chunk_len == 0))
384 unsigned int len,
bool deass)
387 unsigned int data_i = 0;
390 while (len - data_i) {
391 unsigned int chunk_len;
393 if (len - data_i > 32)
396 chunk_len = len - data_i;
404 if (deass && (len - data_i - chunk_len == 0))
425 unsigned int len,
bool deass)
428 unsigned int data_i = 0;
440 while (len - data_i) {
441 unsigned int chunk_len;
443 if (len - data_i > 32)
446 chunk_len = len - data_i;
454 if (deass && (len - data_i - chunk_len == 0))
464 uint8_t *data8 = (uint8_t *)data;
466 (uint8_t *)&data8[data_i * 4], chunk_len * 4);
490 LOG_ERROR(
"Failed to read the status bytes");
498 LOG_ERROR(
"Timed out waiting for flash");
517 LOG_ERROR(
"Failed to write the read status bytes");
524 LOG_ERROR(
"Failed to read the status bytes");
532 LOG_ERROR(
"Timed out waiting for write enable");
548 LOG_ERROR(
"Failed to write the write-enable bytes");
561 LOG_DEBUG(
"%s: first = %d last = %d\n", __func__, first, last);
572 while (first <= last) {
576 LOG_ERROR(
"Failed to set the write-enable bit!");
584 uint32_t
addr = (first++) * ((max32xxx_qspi_info)->dev.sectorsize);
587 cmd_data[4] = (
addr & 0x000000FF) >> 0;
588 cmd_data[3] = (
addr & 0x0000FF00) >> 8;
589 cmd_data[2] = (
addr & 0x00FF0000) >> 16;
590 cmd_data[1] = (
addr & 0xFF000000) >> 24;
593 cmd_data[3] = (
addr & 0x0000FF) >> 0;
594 cmd_data[2] = (
addr & 0x00FF00) >> 8;
595 cmd_data[1] = (
addr & 0xFF0000) >> 16;
605 LOG_ERROR(
"Flash bank didn't respond to status request after erase");
614 retval = post_retval;
626 LOG_DEBUG(
"max32xxx_write_block bank=%p buffer=%p offset=%08" PRIx32
627 " len=%08" PRIx32
"",
640 const uint32_t minimal_buffer_size = algo_overhead + 256;
647 LOG_WARNING(
"Insufficient working area for block write algorithm");
696 " source->size=0x%08" PRIx32,
699 const uint32_t source_data_size =
source->size - algo_overhead;
706 source->address, source_data_size,
707 write_algorithm->
address, algo_end,
730 LOG_DEBUG(
"%s: offset=0x%08" PRIx32
" count=0x%08" PRIx32, __func__,
offset,
751 uint32_t max_sector_plain =
753 uint32_t max_sector_auth = (
offset +
count * 10 / 8) /
755 if (max_sector_auth > max_sector_plain) {
756 LOG_WARNING(
"Erasing extra flash for authentication data");
773 LOG_ERROR(
"Must use algorithm in working area for "
777 LOG_DEBUG(
"working area algorithm not available");
795 unsigned int buffer_i = 0;
797 while (
count - buffer_i) {
805 if (write_len >
count - buffer_i)
806 write_len =
count - buffer_i;
809 cmd_data[4] = (
offset & 0x000000FF) >> 0;
810 cmd_data[3] = (
offset & 0x0000FF00) >> 8;
811 cmd_data[2] = (
offset & 0x00FF0000) >> 16;
812 cmd_data[1] = (
offset & 0xFF000000) >> 24;
817 cmd_data[3] = (
offset & 0x0000FF) >> 0;
818 cmd_data[2] = (
offset & 0x00FF00) >> 8;
819 cmd_data[1] = (
offset & 0xFF0000) >> 16;
829 &
buffer[buffer_i], write_len,
true);
834 buffer_i += write_len;
842 retval = post_retval;
849 uint32_t words, uint32_t *
buffer)
858 cmd_data[3] = (
addr & 0x0000FF) >> 0;
859 cmd_data[2] = (
addr & 0x00FF00) >> 8;
860 cmd_data[1] = (
addr & 0xFF0000) >> 16;
878 bool pre_op_done =
false;
882 if (max32xxx_qspi_info->
probed) {
884 bank->num_sectors = 0;
887 memset(&max32xxx_qspi_info->
dev, 0,
sizeof(max32xxx_qspi_info->
dev));
888 max32xxx_qspi_info->
probed =
false;
901 LOG_DEBUG(
"SPIXFC_CFG = 0x%08X", temp32);
906 LOG_DEBUG(
"SPIXFC_SS_POL = 0x%08X", temp32);
911 LOG_DEBUG(
"SPIXFC_GEN_CTRL = 0x%08X", temp32);
916 LOG_DEBUG(
"SPIXFC_FIFO_CTRL = 0x%08X", temp32);
923 LOG_INFO(
"max32xxx flash \'%s\' size = %" PRIu32
" kbytes",
926 max32xxx_qspi_info->
dev = temp_flash_device;
935 (uint8_t *)&max32xxx_qspi_info->
dev.
device_id, 3,
true);
941 bank->write_start_alignment =
943 bank->write_end_alignment =
bank->write_start_alignment;
957 for (
unsigned int sector = 0; sector <
bank->num_sectors; sector++) {
964 bank->sectors = sectors;
966 max32xxx_qspi_info->
probed =
true;
981 LOG_DEBUG(
"SPIXF_FETCH_CTRL = 0x%08X", temp32);
985 LOG_DEBUG(
"SPIXF_MODE_CTRL = 0x%08X", temp32);
989 LOG_DEBUG(
"SPIXF_MODE_DATA = 0x%08X", temp32);
993 LOG_DEBUG(
"SPIXF_SCLK_FB_CTRL = 0x%08X", temp32);
997 LOG_DEBUG(
"SPIXF_IO_CTRL = 0x%08X", temp32);
1001 LOG_DEBUG(
"SPIXF_MEMSECCN = 0x%08X", temp32);
1005 LOG_DEBUG(
"SPIXF_BUS_IDLE = 0x%08X", temp32);
1011 retval = post_retval;
1021 if (max32xxx_qspi_info->
probed)
1058 if (!(max32xxx_qspi_info->
probed)) {
1064 LOG_ERROR(
"Mass erase not available for this device");
1078 uint8_t cmd_data[1];
1092 retval = post_retval;
1103 if (!(max32xxx_qspi_info->
probed)) {
1111 max32xxx_qspi_info->
dev.
name);
1142 .
name =
"mem_mapping_setup",
1143 .handler = max32xxx_qspi_handle_mem_mapping_setup_command,
1146 .help =
"Setup memory-mapped QSPI access.",
1149 .name =
"mass_erase",
1150 .handler = max32xxx_qspi_handle_mass_erase_command,
1153 .help =
"Mass erase entire flash device.",
1160 .
name =
"max32xxx_qspi",
1162 .help =
"max32xxx_qspi flash command group",
1170 .
name =
"max32xxx_qspi",
1172 .flash_bank_command = max32xxx_qspi_flash_bank_command,
1181 .protect_check =
NULL,
void init_reg_param(struct reg_param *param, const char *reg_name, uint32_t size, enum param_direction direction)
void destroy_reg_param(struct reg_param *param)
void init_mem_param(struct mem_param *param, uint32_t address, uint32_t size, enum param_direction direction)
#define ARMV7M_COMMON_MAGIC
Support functions to access arbitrary bits in a byte array.
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.
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#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...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
uint64_t buffer
Pointer to data buffer to send over SPI.
uint32_t buffer_size
Size of dw_spi_program::buffer.
#define ERROR_FLASH_OPER_UNSUPPORTED
#define ERROR_FLASH_BANK_NOT_PROBED
#define ERROR_FLASH_OPERATION_FAILED
#define ERROR_FLASH_DST_OUT_OF_BANK
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.
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define ERROR_TIMEOUT_REACHED
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
static int max32xxx_qspi_read_rxfifo(struct target *target, uint8_t *data, unsigned int len)
static int max32xxx_qspi_read_words(struct target *target, uint32_t *data, unsigned int len, bool deass)
static int max32xxx_qspi_probe(struct flash_bank *bank)
#define SPIXF_MEMSECCN_AUTH_DISABLE
static int max32xxx_qspi_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
const struct flash_driver max32xxx_qspi_flash
#define SPIXFC_FIFO_DEPTH
static int max32xxx_qspi_post_op(struct flash_bank *bank)
static const uint8_t write_code[]
#define MAX32XXX_QSPI_FIFO_TIMEOUT_MS
static int read_sfdp_block(struct flash_bank *bank, uint32_t addr, uint32_t words, uint32_t *buffer)
#define SPIXF_SCLK_FB_CTRL
#define MAX32XXX_QSPI_MASS_ERASE_TIMEOUT_MS
#define MAX32XXX_QSPI_ERASE_TIMEOUT_MS
static const struct command_registration max32xxx_qspi_command_handlers[]
static int max32xxx_qspi_write_txfifo(struct target *target, const uint8_t *data, unsigned int len)
#define MAX32XXX_QSPI_WE_TIMEOUT_MS
#define SPIXF_MEMSECCN_ENC_ENABLE
static int max32xxx_qspi_auto_probe(struct flash_bank *bank)
static int max32xxx_qspi_poll_wip(struct target *target, unsigned int timeout)
static int max32xxx_qspi_pre_op(struct flash_bank *bank)
static int max32xxx_qspi_write_bytes(struct target *target, const uint8_t *data, unsigned int len, bool deass)
static int max32xxx_qspi_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t len)
static int max32xxx_qspi_read_bytes(struct target *target, uint8_t *data, unsigned int len, bool deass)
static const struct command_registration max32xxx_qspi_exec_command_handlers[]
static int get_max32xxx_qspi_info(struct flash_bank *bank, struct command_invocation *cmd)
static int max32xxx_qspi_poll_we(struct target *target)
static int max32xxx_qspi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
FLASH_BANK_COMMAND_HANDLER(max32xxx_qspi_flash_bank_command)
COMMAND_HANDLER(max32xxx_qspi_handle_mem_mapping_setup_command)
#define SPIXFC_HEADER_NULL
static int max32xxx_qspi_set_we(struct target *target)
#define SPI_WRITE_BOUNDARY
#define SPIXFC_HEADER_BYTE
#define SPIXFC_HEADER_PAGE
#define SPIX_ALGO_OPTIONS_OFFSET
#define SPIXFC_HEADER_SS_DEASS
#define SPIXFC_FIFO_CTRL_TX_FIFO_CNT
#define SPIXFC_HEADER_SIZE_POS
#define SPIXFC_CONFIG_PAGE_SIZE_4_BYTES
#define SPIXFC_FIFO_CTRL_RX_FIFO_CNT_POS
#define SPIX_ALGO_TAIL_SIZE
#define SPIXFC_FIFO_CTRL_RX_FIFO_CNT
#define SPIXFC_CONFIG_PAGE_SIZE
#define SPIXFC_FIFO_CTRL_TX_FIFO_CNT_POS
#define SPIX_ALGO_SPI_WRITE_CMD_OFFSET
target_addr_t addr
Start address to search for the control block.
int spi_sfdp(struct flash_bank *bank, struct flash_device *dev, read_sfdp_block_t read_sfdp_block)
#define SPIFLASH_READ_SFDP
#define SPIFLASH_READ_STATUS
#define SPIFLASH_WRITE_ENABLE
unsigned int common_magic
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Provides details of a flash bank, available either on-chip or through a major interface.
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Describes the geometry and status of a single flash sector within a flash bank.
int is_erased
Indication of erasure status: 0 = not erased, 1 = erased, other = unknown.
uint32_t offset
Bus offset from start of the flash chip (in bytes).
int is_protected
Indication of protection status: 0 = unprotected/unlocked, 1 = protected/locked, other = unknown.
uint32_t size
Number of bytes in this flash sector.
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
int target_write_u16(struct target *target, target_addr_t address, uint16_t value)
int target_read_u8(struct target *target, target_addr_t address, uint8_t *value)
uint32_t target_get_working_area_avail(struct target *target)
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
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...
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
static void write_data(FILE *f, const void *data, size_t len)
#define ERROR_TARGET_NOT_HALTED
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
static struct ublast_lowlevel_priv info