67 .spi_mst = 0x70000024UL,
68 .si_if_owner_offset = 6,
77 .spi_mst = 0x70000024UL,
78 .si_if_owner_offset = 4,
81 #define DW_SPI_IF_OWNER_WIDTH 2
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
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))
129 #define DW_SPI_ARG_REG "r4"
134 #define DW_SPI_TIMEOUT_DEFAULT (600 * 1000)
140 #define DW_SPI_TIMEOUT_TRANSACTION 1000
165 LOG_ERROR(
"DW SPI SPI:MST register read error");
174 LOG_ERROR(
"DW SPI controller mode configuration error");
204 LOG_ERROR(
"DW SPI controller mode query error");
252 LOG_ERROR(
"DW SPI master controller enable flag configuration error");
279 LOG_ERROR(
"DW SPI master controller configuration query error");
286 LOG_ERROR(
"DW SPI slave select configuration error");
305 const uint16_t div =
MIN((regmap->
freq / driver->
speed), 0xfffe) & 0xfffe;
310 LOG_ERROR(
"DW SPI speed configuration error");
314 unsigned int speed = regmap->
freq / div;
315 LOG_DEBUG(
"DW SPI setting NOR controller speed to %u kHz", speed / 1000);
335 LOG_ERROR(
"DW SPI disable interrupts error");
357 uint8_t *
const buffer,
size_t size,
bool read)
363 static const uint8_t target_code[] = {
364 #include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-transaction.inc"
366 const size_t target_code_size =
sizeof(target_code);
367 const size_t total_working_area_size =
374 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
375 total_working_area_size);
383 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
384 total_working_area_size);
385 goto err_helper_args;
391 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
392 total_working_area_size);
393 goto err_target_buffer;
400 LOG_ERROR(
"DW SPI writing to working area error");
401 goto err_write_buffer;
406 LOG_ERROR(
"DW SPI writing to working area error");
407 goto err_write_buffer;
439 LOG_ERROR(
"DW SPI flash algorithm error");
446 LOG_ERROR(
"DW SPI target buffer read error");
489 static const uint8_t target_code[] = {
490 #include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-check_fill.inc"
492 const size_t target_code_size =
sizeof(target_code);
493 const size_t total_working_area_size =
500 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
501 total_working_area_size);
509 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
510 total_working_area_size);
511 goto err_helper_args;
517 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
518 total_working_area_size);
519 goto err_target_buffer;
526 LOG_ERROR(
"DW SPI writing to working area error");
527 goto err_write_buffer;
567 LOG_ERROR(
"DW SPI flash algorithm error");
574 LOG_ERROR(
"DW SPI target buffer read error");
610 uint32_t
page_size, uint8_t stat_cmd, uint8_t we_cmd,
617 static const uint8_t target_code[] = {
618 #include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-program.inc"
620 const size_t target_code_size =
sizeof(target_code);
621 const size_t total_working_area_size =
628 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
629 total_working_area_size);
637 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
638 total_working_area_size);
639 goto err_helper_args;
645 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
646 total_working_area_size);
647 goto err_target_buffer;
654 LOG_ERROR(
"DW SPI writing to working area error");
655 goto err_write_buffer;
661 LOG_ERROR(
"DW SPI writing to working area error");
662 goto err_write_buffer;
702 LOG_ERROR(
"DW SPI flash algorithm error");
735 uint8_t stat_cmd, uint8_t we_cmd,
743 static const uint8_t target_code[] = {
744 #include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-erase.inc"
746 const size_t target_code_size =
sizeof(target_code);
747 const size_t total_working_area_size =
754 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
755 total_working_area_size);
763 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
764 total_working_area_size);
765 goto err_helper_args;
772 LOG_ERROR(
"DW SPI writing to working area error");
773 goto err_write_buffer;
811 LOG_ERROR(
"DW SPI flash algorithm error");
843 static const uint8_t target_code[] = {
844 #include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-read.inc"
846 const size_t target_code_size =
sizeof(target_code);
847 const size_t total_working_area_size =
854 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
855 total_working_area_size);
863 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
864 total_working_area_size);
865 goto err_helper_args;
871 LOG_ERROR(
"DW SPI could not allocate working area. Need %zx",
872 total_working_area_size);
873 goto err_target_buffer;
880 LOG_ERROR(
"DW SPI writing to working area error");
881 goto err_write_buffer;
914 LOG_ERROR(
"DW SPI flash algorithm error");
921 LOG_ERROR(
"DW SPI target buffer read error");
964 LOG_DEBUG(
"DW SPI read flash ID %" PRIx32, driver->
id);
987 LOG_ERROR(
"DW SPI flash status read error");
1041 LOG_ERROR(
"DW SPI flash write enable error");
1082 LOG_ERROR(
"DW SPI erase flash timeout");
1103 if (first == 0 && last >= (
bank->num_sectors - 1)) {
1118 LOG_ERROR(
"DW SPI flash erase sectors error");
1143 for (
unsigned int sector_idx = 0; sector_idx <
sector_count; sector_idx++)
1144 bank->sectors[sector_idx].is_erased = 2;
1151 for (
unsigned int sector_idx = 0; sector_idx <
sector_count;
1153 bank->sectors[sector_idx].is_erased = erased[sector_idx];
1155 LOG_ERROR(
"DW SPI flash erase check error");
1193 chunks[1].count -= chunks[0].count;
1194 chunks[1].address += chunks[0].count;
1195 chunks[1].buffer += chunks[0].count;
1198 for (
unsigned int chunk_idx = 0; chunk_idx <
ARRAY_SIZE(chunks);
1200 if (chunks[chunk_idx].
count > 0) {
1202 chunks[chunk_idx].
buffer,
1233 unsigned int idx = 0;
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",
1258 unsigned int speed = 1000000;
1266 for (
unsigned int idx = 6; idx <
CMD_ARGC; idx++) {
1267 if (strcmp(
CMD_ARGV[idx],
"-jaguar2") == 0) {
1270 }
else if (strcmp(
CMD_ARGV[idx],
"-ocelot") == 0) {
1273 }
else if (strcmp(
CMD_ARGV[idx],
"-freq") == 0) {
1275 }
else if (strcmp(
CMD_ARGV[idx],
"-simc") == 0) {
1277 }
else if (strcmp(
CMD_ARGV[idx],
"-spi_mst") == 0) {
1279 }
else if (strcmp(
CMD_ARGV[idx],
"-if_owner_offset") == 0) {
1282 }
else if (strcmp(
CMD_ARGV[idx],
"-speed") == 0) {
1284 }
else if (strcmp(
CMD_ARGV[idx],
"-timeout") == 0) {
1287 }
else if (strcmp(
CMD_ARGV[idx],
"-chip_select") == 0) {
1288 unsigned int cs_bit;
1290 chip_select_bitmask =
BIT(cs_bit);
1297 LOG_ERROR(
"DW SPI cannot use boot controller with unconfigured simc");
1302 if (!
bank->driver_priv) {
1348 LOG_ERROR(
"DW SPI switch to master controller mode error");
1353 LOG_ERROR(
"DW SPI disable master controller error");
1358 LOG_ERROR(
"DW SPI speed configuration error");
1363 LOG_ERROR(
"DW SPI disable SPI interrupts error");
1368 LOG_ERROR(
"DW SPI controller configuration error");
1373 LOG_ERROR(
"DW SPI enable master controller error");
1391 LOG_ERROR(
"DW SPI disable master controller error");
1396 LOG_ERROR(
"DW SPI controller restore error");
1419 LOG_ERROR(
"DW SPI currently only supports "
1420 "little endian mips_m4k target");
1432 bank->write_start_alignment = 0;
1433 bank->write_end_alignment = 0;
1437 bank->size = flash_size;
1438 LOG_INFO(
"DW SPI probed flash size 0x%" PRIx32, flash_size);
1440 if (flash_size >
bank->size)
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);
1455 free(
bank->sectors);
1460 if (!
bank->sectors) {
1598 .flash_bank_command = dw_spi_flash_bank_command,
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
void destroy_mem_param(struct mem_param *param)
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)
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,...)
void command_print(struct command_invocation *cmd, const char *format,...)
#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...
Driver for SPI NOR flash chips connected via DesignWare SPI Core.
uint8_t erase_sector_cmd
Erase sector command.
uint8_t read_cmd
Read data command.
uint8_t pattern
Fill pattern.
uint32_t sector_count
Number of sectors to check.
uint32_t sector_size
Sector size.
uint64_t buffer
Pointer to data buffer to send over SPI.
uint32_t page_size
Page size.
uint8_t program_cmd
Program command.
uint32_t size
Size of dw_spi_transaction::buffer.
uint32_t buffer_size
Size of dw_spi_program::buffer.
uint32_t address
Starting address. Sector aligned.
uint8_t busy_mask
Busy mask.
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.
static int dw_spi_erase_sectors(const struct flash_bank *const bank, unsigned int first, unsigned int last)
Flash device erase sectors.
#define DW_SPI_REG_DR
Data register.
static int dw_spi_ctrl_transaction(const struct flash_bank *const bank, uint8_t *const buffer, size_t size, bool read)
Do data transaction.
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.
static int dw_spi_auto_probe(struct flash_bank *bank)
Autoprobe driver.
#define DW_SPI_REG_CTRLR0
General configuration register.
#define DW_SPI_REG_SER
Slave select register.
static int dw_spi_master_ctrl_enable(const struct flash_bank *const bank, bool value)
Enable master controller.
static int dw_spi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Flash bank write data.
dw_spi_si_mode
Owner of the SI interface.
@ DW_SPI_SI_MODE_MASTER
SPI controller mode for reading/writing SPI Flash.
@ DW_SPI_SI_MODE_BOOT
Boot controller maps contents of SPI Flash to memory in read-only mode.
static const struct dw_spi_regmap ocelot_regmap
Register map for Ocelot switch devices.
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.
static int dw_spi_master_ctrl_restore(struct flash_bank *bank)
Restore SI controller selection.
static int dw_spi_erase_check(struct flash_bank *bank)
Flash bank erase check.
static int dw_spi_probe(struct flash_bank *bank)
Flash bank probe.
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.
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.
static int dw_spi_wait_finish(const struct flash_bank *const bank, unsigned int timeout)
Wait for Flash command to finish.
#define DW_SPI_REG_SIMCEN
Master controller enable register.
static int dw_spi_ctrl_configure_speed(const struct flash_bank *const bank)
Configure SI transfer speed.
#define DW_SPI_REG_BAUDR
Baud rate configuration register.
static int dw_spi_erase_chip(const struct flash_bank *const bank)
Erase Flash chip.
#define DW_SPI_REG_CTRLR0_SCPOL(x)
Probe polarity.
#define DW_SPI_REG_BAUDR_SCKDV(x)
Clock divisor.
static int dw_spi_write_enable(const struct flash_bank *const bank)
Flash device write enable.
static int dw_spi_info(struct flash_bank *bank, struct command_invocation *cmd)
Flash bank info.
static int dw_spi_spiflash_search(const struct flash_bank *const bank)
Search for Flash chip info.
#define DW_SPI_REG_CTRLR0_FRF(x)
SI protocol.
static int dw_spi_ctrl_disable_interrupts(const struct flash_bank *const bank)
Disable SI master controller interrupts.
const struct flash_driver dw_spi_flash
DW-SPI NOR flash functions.
#define DW_SPI_ARG_REG
Register used to pass argument struct to helper functions.
#define DW_SPI_REG_SER_SER(x)
Slave select bitmask.
static int dw_spi_master_ctrl_configure(struct flash_bank *bank)
Prepare master controller for transaction.
static int dw_spi_assert_halted(const struct flash_bank *const bank)
Assert target is halted.
#define DW_SPI_REG_CTRLR0_TMOD(x)
SI mode.
#define DW_SPI_REG_CTRLR0_DFS(x)
Data frame size.
static int dw_spi_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Flash bank erase sectors.
static int dw_spi_ctrl_configure_si(const struct flash_bank *const bank)
Configure SI transfer mode.
#define DW_SPI_TIMEOUT_TRANSACTION
Timeout value in ms for short flash transactions, e.g.
static int dw_spi_read_status(const struct flash_bank *const bank, uint8_t *const status)
Read Flash device status.
static int dw_spi_ctrl_mode_restore(const struct flash_bank *const bank)
Restore SI controller mode.
static int dw_spi_ctrl_mode(const struct flash_bank *const bank, enum dw_spi_si_mode mode)
Select SI interface owner.
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.
#define DW_SPI_IF_OWNER_WIDTH
IF owner register field width.
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.
#define DW_SPI_TIMEOUT_DEFAULT
Default timeout value in ms for flash transaction jobs.
#define DW_SPI_REG_SIMCEN_SIMCEN(x)
Controller enable.
#define DW_SPI_REG_SR
Status register.
static const struct dw_spi_regmap jaguar2_regmap
Register map for Jaguar2 switch devices.
static int dw_spi_read_id(const struct flash_bank *const bank)
Read Flash device ID.
FLASH_BANK_COMMAND_HANDLER(dw_spi_flash_bank_command)
Handle flash bank command.
static int dw_spi_blank_check(struct flash_bank *bank, size_t sector_count, uint8_t pattern)
Flash bank blank check.
#define DW_SPI_REG_CTRLR0_SCPH(x)
Probe position.
#define DW_SPI_REG_IMR
Interrupt configuration register.
#define ERROR_FLASH_BANK_INVALID
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)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define ERROR_TIMEOUT_REACHED
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
#define MIPS32_COMMON_MAGIC
struct target_type mips_m4k_target
struct rtt_control ctrl
Control block.
const struct flash_device flash_devices[]
#define SPIFLASH_READ_STATUS
#define SPIFLASH_WRITE_ENABLE
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Arguments for check_fill helper function.
uint8_t read_cmd
Read data command.
uint64_t status_reg
Pointer to SR register.
uint8_t pattern
Fill pattern.
uint32_t address
Starting address. Sector aligned.
uint64_t fill_status_array
Pointer to array describing sectors fill status.
uint8_t four_byte_mode
Four byte addressing mode flag.
uint32_t sector_count
Number of sectors to check.
uint32_t sector_size
Sector size.
uint64_t data_reg
Pointer to DR register.
uint8_t chip_select_bitmask
Chip select bitmask.
const struct flash_device * spi_flash
SPI flash device info.
unsigned int timeout
Flash timeout in milliseconds.
bool probed
Bank is probed.
bool four_byte_mode
Flash chip is in 32bit address mode.
unsigned int speed
Flash speed.
enum dw_spi_si_mode saved_ctrl_mode
Previously selected controller mode.
struct dw_spi_regmap regmap
SI controller regmap.
Arguments for erase helper function.
uint64_t data_reg
Pointer to DR register.
uint32_t sector_size
Sector size.
uint8_t read_status_cmd
Read status command.
uint8_t erase_sector_cmd
Erase sector command.
uint8_t four_byte_mode
Four byte addressing mode flag.
uint32_t sector_count
Number of sectors to erase.
uint8_t write_enable_cmd
Write enable command.
uint64_t status_reg
Pointer to SR register.
uint8_t write_enable_mask
Write enable mask.
uint8_t busy_mask
Busy mask.
uint32_t address
First sector address. Sector aligned.
Arguments for program helper function.
uint8_t four_byte_mode
Four byte addressing mode flag.
uint64_t status_reg
Pointer to SR register.
uint8_t busy_mask
Busy mask.
uint64_t buffer
Data buffer pointer.
uint32_t buffer_size
Size of dw_spi_program::buffer.
uint8_t write_enable_mask
Write enable mask.
uint64_t data_reg
Pointer to DR register.
uint32_t address
First page address.
uint8_t program_cmd
Program command.
uint8_t read_status_cmd
Read status command.
uint8_t write_enable_cmd
Write enable command.
uint32_t page_size
Page size.
Arguments for read helper function.
uint32_t buffer_size
Size of dw_spi_read::buffer.
uint64_t data_reg
Pointer to DR register.
uint32_t address
First sector address.
uint64_t buffer
Data buffer pointer.
uint8_t four_byte_mode
Four byte addressing mode flag.
uint64_t status_reg
Pointer to SR register.
uint8_t read_cmd
Read data command.
target_addr_t spi_mst
Absolute offset of ICPU_CFG:SPI_MST register. 0 if not available.
target_addr_t simc
Absolute offset of SIMC register block.
uint32_t freq
Clock frequency.
uint8_t si_if_owner_offset
Offset of si_mode bits in ICPU_CFG:SPI_MST.
Arguments for transaction helper function.
uint8_t read_flag
When 1, store RX FIFO data to dw_spi_transaction::buffer.
uint64_t buffer
Pointer to data buffer to send over SPI.
uint32_t size
Size of dw_spi_transaction::buffer.
uint64_t status_reg
Pointer to SR register.
uint64_t data_reg
Pointer to DR register.
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...
unsigned int common_magic
const char * name
Name of this type of target.
void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value)
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
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.
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_read_u32(struct target *target, target_addr_t address, uint32_t *value)
#define ERROR_TARGET_NOT_HALTED
#define ERROR_TARGET_INVALID
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
static uint32_t le_to_h_u32(const uint8_t *buf)