diff options
-rw-r--r-- | arch/arm/dts/stm32mp157c-odyssey-som-u-boot.dtsi | 21 | ||||
-rw-r--r-- | arch/arm/dts/stm32mp157c-odyssey-som.dtsi | 15 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c | 26 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 43 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h | 7 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c | 173 | ||||
-rw-r--r-- | arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c | 7 | ||||
-rw-r--r-- | board/dhelectronics/dh_stm32mp1/board.c | 4 | ||||
-rw-r--r-- | board/st/stm32mp1/stm32mp1.c | 4 | ||||
-rw-r--r-- | drivers/clk/clk-uclass.c | 2 | ||||
-rw-r--r-- | drivers/dfu/dfu.c | 12 | ||||
-rw-r--r-- | drivers/dfu/dfu_mtd.c | 5 | ||||
-rw-r--r-- | drivers/spi/stm32_qspi.c | 29 | ||||
-rw-r--r-- | include/dfu.h | 11 |
14 files changed, 159 insertions, 200 deletions
diff --git a/arch/arm/dts/stm32mp157c-odyssey-som-u-boot.dtsi b/arch/arm/dts/stm32mp157c-odyssey-som-u-boot.dtsi index 6be7288..4ff8483 100644 --- a/arch/arm/dts/stm32mp157c-odyssey-som-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157c-odyssey-som-u-boot.dtsi @@ -123,3 +123,24 @@ u-boot,dm-pre-reloc; }; }; + +&sdmmc2 { + u-boot,dm-spl; +}; + +&sdmmc2_b4_pins_a { + u-boot,dm-spl; + pins1 { + u-boot,dm-spl; + }; + pins2 { + u-boot,dm-spl; + }; +}; + +&sdmmc2_d47_pins_d { + u-boot,dm-spl; + pins { + u-boot,dm-spl; + }; +}; diff --git a/arch/arm/dts/stm32mp157c-odyssey-som.dtsi b/arch/arm/dts/stm32mp157c-odyssey-som.dtsi index e367a31..1510a5b 100644 --- a/arch/arm/dts/stm32mp157c-odyssey-som.dtsi +++ b/arch/arm/dts/stm32mp157c-odyssey-som.dtsi @@ -264,14 +264,17 @@ &sdmmc2 { pinctrl-names = "default", "opendrain", "sleep"; - pinctrl-0 = <&sdmmc2_b4_pins_a>; - pinctrl-1 = <&sdmmc2_b4_od_pins_a>; - pinctrl-2 = <&sdmmc2_b4_sleep_pins_a>; - broken-cd; - disable-wp; + pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_d>; + pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_d>; + pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_d>; + non-removable; + no-sd; + no-sdio; st,neg-edge; - bus-width = <4>; + bus-width = <8>; vmmc-supply = <&v3v3>; + vqmmc-supply = <&vdd>; + mmc-ddr-3_3v; status = "okay"; }; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index e36501a..feff73c 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -45,7 +45,6 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, bool reset = false; struct image_header_s header; struct stm32prog_data *data; - u32 uimage, dtb; if (argc < 3 || argc > 5) return CMD_RET_USAGE; @@ -78,10 +77,12 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, if (header.type == HEADER_STM32IMAGE) { size = header.image_length + BL_HEADER_SIZE; +#if defined(CONFIG_LEGACY_IMAGE_FORMAT) /* uImage detected in STM32IMAGE, execute the script */ if (IMAGE_FORMAT_LEGACY == genimg_get_format((void *)(addr + BL_HEADER_SIZE))) return image_source_script(addr + BL_HEADER_SIZE, "script@1"); +#endif } } @@ -98,7 +99,7 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, ret = stm32prog_init(data, addr, size); if (ret) - printf("Invalid or missing layout file."); + log_debug("Invalid or missing layout file at 0x%lx.\n", addr); /* prepare DFU for device read/write */ ret = stm32prog_dfu_init(data); @@ -119,21 +120,23 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, goto cleanup; } - uimage = data->uimage; - dtb = data->dtb; - stm32prog_clean(data); free(stm32prog_data); stm32prog_data = NULL; puts("Download done\n"); - if (uimage) { + if (data->uimage) { char boot_addr_start[20]; char dtb_addr[20]; + char initrd_addr[40]; char *bootm_argv[5] = { "bootm", boot_addr_start, "-", dtb_addr, NULL }; + u32 uimage = data->uimage; + u32 dtb = data->dtb; + u32 initrd = data->initrd; + if (!dtb) bootm_argv[3] = env_get("fdtcontroladdr"); else @@ -142,8 +145,15 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, snprintf(boot_addr_start, sizeof(boot_addr_start) - 1, "0x%x", uimage); - printf("Booting kernel at %s - %s...\n\n\n", - boot_addr_start, bootm_argv[3]); + + if (initrd) { + snprintf(initrd_addr, sizeof(initrd_addr) - 1, "0x%x:0x%x", + initrd, data->initrd_size); + bootm_argv[2] = initrd_addr; + } + + printf("Booting kernel at %s %s %s...\n\n\n", + boot_addr_start, bootm_argv[2], bootm_argv[3]); /* Try bootm for legacy and FIT format image */ if (genimg_get_format((void *)uimage) != IMAGE_FORMAT_INVALID) do_bootm(cmdtp, 0, 4, bootm_argv); diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 4c4d8a7..f7c93a1 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -369,23 +369,24 @@ static int parse_flash_layout(struct stm32prog_data *data, bool end_of_line, eof; char *p, *start, *last, *col; struct stm32prog_part_t *part; + struct image_header_s header; int part_list_size; int i; data->part_nb = 0; /* check if STM32image is detected */ - stm32prog_header_check((struct raw_header_s *)addr, &data->header); - if (data->header.type == HEADER_STM32IMAGE) { + stm32prog_header_check((struct raw_header_s *)addr, &header); + if (header.type == HEADER_STM32IMAGE) { u32 checksum; addr = addr + BL_HEADER_SIZE; - size = data->header.image_length; + size = header.image_length; - checksum = stm32prog_header_checksum(addr, &data->header); - if (checksum != data->header.image_checksum) { + checksum = stm32prog_header_checksum(addr, &header); + if (checksum != header.image_checksum) { stm32prog_err("Layout: invalid checksum : 0x%x expected 0x%x", - checksum, data->header.image_checksum); + checksum, header.image_checksum); return -EIO; } } @@ -1149,7 +1150,10 @@ static int dfu_init_entities(struct stm32prog_data *data) struct dfu_entity *dfu; int alt_nb; - alt_nb = 3; /* number of virtual = CMD, OTP, PMIC*/ + alt_nb = 2; /* number of virtual = CMD, OTP*/ + if (CONFIG_IS_ENABLED(DM_PMIC)) + alt_nb++; /* PMIC NVMEM*/ + if (data->part_nb == 0) alt_nb++; /* +1 for FlashLayout */ else @@ -1472,7 +1476,7 @@ error: return ret; } -static void stm32prog_end_phase(struct stm32prog_data *data) +static void stm32prog_end_phase(struct stm32prog_data *data, u64 offset) { if (data->phase == PHASE_FLASHLAYOUT) { if (parse_flash_layout(data, STM32_DDR_BASE, 0)) @@ -1488,6 +1492,10 @@ static void stm32prog_end_phase(struct stm32prog_data *data) data->uimage = data->cur_part->addr; if (data->cur_part->part_type == PART_FILESYSTEM) data->dtb = data->cur_part->addr; + if (data->cur_part->part_type == PART_BINARY) { + data->initrd = data->cur_part->addr; + data->initrd_size = offset; + } } if (CONFIG_IS_ENABLED(MMC) && @@ -1727,7 +1735,6 @@ void stm32prog_clean(struct stm32prog_data *data) free(data->part_array); free(data->otp_part); free(data->buffer); - free(data->header_data); } /* DFU callback: used after serial and direct DFU USB access */ @@ -1747,7 +1754,7 @@ void dfu_flush_callback(struct dfu_entity *dfu) if (dfu->dev_type == DFU_DEV_RAM) { if (dfu->alt == 0 && stm32prog_data->phase == PHASE_FLASHLAYOUT) { - stm32prog_end_phase(stm32prog_data); + stm32prog_end_phase(stm32prog_data, dfu->offset); /* waiting DFU DETACH for reenumeration */ } } @@ -1756,7 +1763,7 @@ void dfu_flush_callback(struct dfu_entity *dfu) return; if (dfu->alt == stm32prog_data->cur_part->alt_id) { - stm32prog_end_phase(stm32prog_data); + stm32prog_end_phase(stm32prog_data, dfu->offset); stm32prog_next_phase(stm32prog_data); } } @@ -1776,3 +1783,17 @@ void dfu_initiated_callback(struct dfu_entity *dfu) log_debug("dfu offset = 0x%llx\n", dfu->offset); } } + +void dfu_error_callback(struct dfu_entity *dfu, const char *msg) +{ + struct stm32prog_data *data = stm32prog_data; + + if (!stm32prog_data) + return; + + if (!stm32prog_data->cur_part) + return; + + if (dfu->alt == stm32prog_data->cur_part->alt_id) + stm32prog_err(msg); +} diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index 581b10d..efb51a3 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -132,14 +132,9 @@ struct stm32prog_data { u32 *otp_part; u8 pmic_part[PMIC_SIZE]; - /* STM32 header information */ - struct raw_header_s *header_data; - struct image_header_s header; - /* SERIAL information */ u32 cursor; u32 packet_number; - u32 checksum; u8 *buffer; /* size = USART_RAM_BUFFER_SIZE*/ int dfu_seq; u8 read_phase; @@ -147,6 +142,8 @@ struct stm32prog_data { /* bootm information */ u32 uimage; u32 dtb; + u32 initrd; + u32 initrd_size; }; extern struct stm32prog_data *stm32prog_data; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c index 2b92e3b..7de6266 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c @@ -10,6 +10,7 @@ #include <malloc.h> #include <serial.h> #include <watchdog.h> +#include <asm/arch/sys_proto.h> #include <dm/lists.h> #include <dm/device-internal.h> #include <linux/delay.h> @@ -19,8 +20,7 @@ /* - configuration part -----------------------------*/ #define USART_BL_VERSION 0x40 /* USART bootloader version V4.0*/ #define UBOOT_BL_VERSION 0x03 /* bootloader version V0.3*/ -#define DEVICE_ID_BYTE1 0x05 /* MSB byte of device ID*/ -#define DEVICE_ID_BYTE2 0x00 /* LSB byte of device ID*/ + #define USART_RAM_BUFFER_SIZE 256 /* Size of USART_RAM_Buf buffer*/ /* - Commands -----------------------------*/ @@ -60,6 +60,9 @@ const u8 cmd_id[] = { #define NB_CMD sizeof(cmd_id) +/* with 115200 bauds, 20 ms allow to receive the 256 bytes buffer */ +#define TIMEOUT_SERIAL_BUFFER 30 + /* DFU support for serial *********************************************/ static struct dfu_entity *stm32prog_get_entity(struct stm32prog_data *data) { @@ -264,6 +267,7 @@ static bool stm32prog_serial_get_buffer(u8 *buffer, u32 *count) { struct dm_serial_ops *ops = serial_get_ops(down_serial_dev); int err; + ulong start = get_timer(0); do { err = ops->getc(down_serial_dev); @@ -273,6 +277,10 @@ static bool stm32prog_serial_get_buffer(u8 *buffer, u32 *count) } else if (err == -EAGAIN) { ctrlc(); WATCHDOG_RESET(); + if (get_timer(start) > TIMEOUT_SERIAL_BUFFER) { + err = -ETIMEDOUT; + break; + } } else { break; } @@ -292,56 +300,6 @@ static void stm32prog_serial_putc(u8 w_byte) } /* Helper function ************************************************/ - -static u8 stm32prog_header(struct stm32prog_data *data) -{ - u8 ret; - u8 boot = 0; - struct dfu_entity *dfu_entity; - u64 size = 0; - - dfu_entity = stm32prog_get_entity(data); - if (!dfu_entity) - return -ENODEV; - - printf("\nSTM32 download write %s\n", dfu_entity->name); - - /* force cleanup to avoid issue with previous read */ - dfu_transaction_cleanup(dfu_entity); - - stm32prog_header_check(data->header_data, &data->header); - - /* no stm32 image header : max size is partition size */ - if (data->header.type != HEADER_STM32IMAGE) { - dfu_entity->get_medium_size(dfu_entity, &size); - data->header.image_length = size; - } - - /**** Flash the header if necessary for boot partition */ - if (data->phase < PHASE_FIRST_USER) - boot = 1; - - /* write header if boot partition */ - if (boot) { - if (ret) { - stm32prog_err("invalid header (error %d)", ret); - } else { - ret = stm32prog_write(data, - (u8 *)data->header_data, - BL_HEADER_SIZE); - } - } else { - if (ret) - printf(" partition without checksum\n"); - ret = 0; - } - - free(data->header_data); - data->header_data = NULL; - - return ret; -} - static u8 stm32prog_start(struct stm32prog_data *data, u32 address) { u8 ret = 0; @@ -388,23 +346,6 @@ static u8 stm32prog_start(struct stm32prog_data *data, u32 address) data->dfu_seq = 0; printf("\n received length = 0x%x\n", data->cursor); - if (data->header.type == HEADER_STM32IMAGE) { - if (data->cursor != - (data->header.image_length + BL_HEADER_SIZE)) { - stm32prog_err("transmission interrupted (length=0x%x expected=0x%x)", - data->cursor, - data->header.image_length + - BL_HEADER_SIZE); - return -EIO; - } - if (data->header.image_checksum != data->checksum) { - stm32prog_err("invalid checksum received (0x%x expected 0x%x)", - data->checksum, - data->header.image_checksum); - return -EIO; - } - printf("\n checksum OK (0x%x)\n", data->checksum); - } /* update DFU with received flashlayout */ if (data->phase == PHASE_FLASHLAYOUT) @@ -495,10 +436,12 @@ static void get_version_command(struct stm32prog_data *data) */ static void get_id_command(struct stm32prog_data *data) { + u32 cpu = get_cpu_dev(); + /* Send Device IDCode */ stm32prog_serial_putc(0x1); - stm32prog_serial_putc(DEVICE_ID_BYTE1); - stm32prog_serial_putc(DEVICE_ID_BYTE2); + stm32prog_serial_putc((cpu >> 8) & 0xFF); + stm32prog_serial_putc(cpu & 0xFF); stm32prog_serial_result(ACK_BYTE); } @@ -627,14 +570,12 @@ static void download_command(struct stm32prog_data *data) u32 counter = 0x0, codesize = 0x0; u8 *ramaddress = 0; u8 rcv_data = 0x0; - struct image_header_s *image_header = &data->header; u32 cursor = data->cursor; long size = 0; u8 operation; u32 packet_number; u32 result = ACK_BYTE; u8 ret; - unsigned int i; bool error; int rcv; @@ -668,13 +609,8 @@ static void download_command(struct stm32prog_data *data) if (packet_number == 0) { /* erase: re-initialize the image_header struct */ data->packet_number = 0; - if (data->header_data) - memset(data->header_data, 0, BL_HEADER_SIZE); - else - data->header_data = calloc(1, BL_HEADER_SIZE); cursor = 0; data->cursor = 0; - data->checksum = 0; /*idx = cursor;*/ } else { data->packet_number++; @@ -722,7 +658,7 @@ static void download_command(struct stm32prog_data *data) printf("transmission error on packet %d, byte %d\n", packet_number, codesize - counter); /* waiting end of packet before flush & NACK */ - mdelay(30); + mdelay(TIMEOUT_SERIAL_BUFFER); data->packet_number--; result = NACK_BYTE; goto end; @@ -740,80 +676,33 @@ static void download_command(struct stm32prog_data *data) /* wait to be sure that all data are received * in the FIFO before flush */ - mdelay(30); + mdelay(TIMEOUT_SERIAL_BUFFER); data->packet_number--; result = NACK_BYTE; goto end; } - /* Update current position in buffer */ - data->cursor += codesize; - - if (operation == PHASE_OTP) { - size = data->cursor - cursor; - /* no header for OTP */ - if (stm32prog_otp_write(data, cursor, - data->buffer, &size)) - result = ABORT_BYTE; - goto end; - } + switch (operation) { + case PHASE_OTP: + size = codesize; + ret = stm32prog_otp_write(data, cursor, data->buffer, &size); + break; - if (operation == PHASE_PMIC) { - size = data->cursor - cursor; - /* no header for PMIC */ - if (stm32prog_pmic_write(data, cursor, - data->buffer, &size)) - result = ABORT_BYTE; - goto end; - } + case PHASE_PMIC: + size = codesize; + ret = stm32prog_pmic_write(data, cursor, data->buffer, &size); + break; - if (cursor < BL_HEADER_SIZE) { - /* size = portion of header in this chunck */ - if (data->cursor >= BL_HEADER_SIZE) - size = BL_HEADER_SIZE - cursor; - else - size = data->cursor - cursor; - memcpy((void *)((u32)(data->header_data) + cursor), - data->buffer, size); - cursor += size; - - if (cursor == BL_HEADER_SIZE) { - /* Check and Write the header */ - if (stm32prog_header(data)) { - result = ABORT_BYTE; - goto end; - } - } else { - goto end; - } + default: + ret = stm32prog_write(data, data->buffer, codesize); + break; } - if (data->header.type == HEADER_STM32IMAGE) { - if (data->cursor <= BL_HEADER_SIZE) - goto end; - /* compute checksum on payload */ - for (i = (unsigned long)size; i < codesize; i++) - data->checksum += data->buffer[i]; - - if (data->cursor > - image_header->image_length + BL_HEADER_SIZE) { - log_err("expected size exceeded\n"); - result = ABORT_BYTE; - goto end; - } - - /* write data (payload) */ - ret = stm32prog_write(data, - &data->buffer[size], - codesize - size); - } else { - /* write all */ - ret = stm32prog_write(data, - data->buffer, - codesize); - } if (ret) result = ABORT_BYTE; + else + /* Update current position in buffer */ + data->cursor += codesize; end: stm32prog_serial_result(result); diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c index bc44d9f..d4a3f7e 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c @@ -207,13 +207,10 @@ bool stm32prog_usb_loop(struct stm32prog_data *data, int dev) if (stm32prog_data->phase == PHASE_FLASHLAYOUT) { ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu"); - if (ret || stm32prog_data->phase == PHASE_DO_RESET) + if (ret || stm32prog_data->phase != PHASE_FLASHLAYOUT) return ret; /* prepare the second enumeration with the FlashLayout */ - if (stm32prog_data->phase == PHASE_FLASHLAYOUT) - stm32prog_dfu_init(data); - /* found next selected partition */ - stm32prog_next_phase(data); + stm32prog_dfu_init(data); } ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu"); diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c index ac1af71..d7c1857 100644 --- a/board/dhelectronics/dh_stm32mp1/board.c +++ b/board/dhelectronics/dh_stm32mp1/board.c @@ -660,11 +660,11 @@ int board_interface_eth_init(struct udevice *dev, bool eth_ref_clk_sel_reg = false; /* Gigabit Ethernet 125MHz clock selection. */ - eth_clk_sel_reg = dev_read_bool(dev, "st,eth_clk_sel"); + eth_clk_sel_reg = dev_read_bool(dev, "st,eth-clk-sel"); /* Ethernet 50Mhz RMII clock selection */ eth_ref_clk_sel_reg = - dev_read_bool(dev, "st,eth_ref_clk_sel"); + dev_read_bool(dev, "st,eth-ref-clk-sel"); syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 261ec15..18b8870 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -733,11 +733,11 @@ int board_interface_eth_init(struct udevice *dev, bool eth_ref_clk_sel_reg = false; /* Gigabit Ethernet 125MHz clock selection. */ - eth_clk_sel_reg = dev_read_bool(dev, "st,eth_clk_sel"); + eth_clk_sel_reg = dev_read_bool(dev, "st,eth-clk-sel"); /* Ethernet 50Mhz RMII clock selection */ eth_ref_clk_sel_reg = - dev_read_bool(dev, "st,eth_ref_clk_sel"); + dev_read_bool(dev, "st,eth-ref-clk-sel"); syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index cac0f6a..1425421 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -160,7 +160,7 @@ int clk_get_by_index_nodev(ofnode node, int index, struct clk *clk) int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk) { int i, ret, err, count; - + bulk->count = 0; count = dev_count_phandle_with_args(dev, "clocks", "#clock-cells", 0); diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index 213a20e..ff1859d 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -45,6 +45,14 @@ __weak void dfu_initiated_callback(struct dfu_entity *dfu) } /* + * The purpose of the dfu_error_callback() function is to + * provide callback for dfu user + */ +__weak void dfu_error_callback(struct dfu_entity *dfu, const char *msg) +{ +} + +/* * The purpose of the dfu_usb_get_reset() function is to * provide information if after USB_DETACH request * being sent the dfu-util performed reset of USB @@ -342,6 +350,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) printf("%s: Wrong sequence number! [%d] [%d]\n", __func__, dfu->i_blk_seq_num, blk_seq_num); dfu_transaction_cleanup(dfu); + dfu_error_callback(dfu, "Wrong sequence number"); return -1; } @@ -366,6 +375,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) ret = dfu_write_buffer_drain(dfu); if (ret) { dfu_transaction_cleanup(dfu); + dfu_error_callback(dfu, "DFU write error"); return ret; } } @@ -375,6 +385,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) pr_err("Buffer overflow! (0x%p + 0x%x > 0x%p)\n", dfu->i_buf, size, dfu->i_buf_end); dfu_transaction_cleanup(dfu); + dfu_error_callback(dfu, "Buffer overflow"); return -1; } @@ -386,6 +397,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) ret = dfu_write_buffer_drain(dfu); if (ret) { dfu_transaction_cleanup(dfu); + dfu_error_callback(dfu, "DFU write error"); return ret; } } diff --git a/drivers/dfu/dfu_mtd.c b/drivers/dfu/dfu_mtd.c index ec40b8f..894b570 100644 --- a/drivers/dfu/dfu_mtd.c +++ b/drivers/dfu/dfu_mtd.c @@ -254,7 +254,6 @@ int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char *s) { char *st; struct mtd_info *mtd; - bool has_pages; int ret, part; mtd = get_mtd_device_nm(devstr); @@ -264,9 +263,7 @@ int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char *s) dfu->dev_type = DFU_DEV_MTD; dfu->data.mtd.info = mtd; - - has_pages = mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH; - dfu->max_buf_size = has_pages ? mtd->erasesize : 0; + dfu->max_buf_size = mtd->erasesize; st = strsep(&s, " "); if (!strcmp(st, "raw")) { diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c index 4acc904..8f4aabc 100644 --- a/drivers/spi/stm32_qspi.c +++ b/drivers/spi/stm32_qspi.c @@ -148,23 +148,24 @@ static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv *priv, const struct spi_mem_op *op) { u32 sr; - int ret; - - if (!op->data.nbytes) - return _stm32_qspi_wait_for_not_busy(priv); + int ret = 0; - ret = readl_poll_timeout(&priv->regs->sr, sr, - sr & STM32_QSPI_SR_TCF, - STM32_QSPI_CMD_TIMEOUT_US); - if (ret) { - log_err("cmd timeout (stat:%#x)\n", sr); - } else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) { - log_err("transfer error (stat:%#x)\n", sr); - ret = -EIO; + if (op->data.nbytes) { + ret = readl_poll_timeout(&priv->regs->sr, sr, + sr & STM32_QSPI_SR_TCF, + STM32_QSPI_CMD_TIMEOUT_US); + if (ret) { + log_err("cmd timeout (stat:%#x)\n", sr); + } else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) { + log_err("transfer error (stat:%#x)\n", sr); + ret = -EIO; + } + /* clear flags */ + writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, &priv->regs->fcr); } - /* clear flags */ - writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, &priv->regs->fcr); + if (!ret) + ret = _stm32_qspi_wait_for_not_busy(priv); return ret; } diff --git a/include/dfu.h b/include/dfu.h index afada39..f686898 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -377,6 +377,17 @@ void dfu_initiated_callback(struct dfu_entity *dfu); */ void dfu_flush_callback(struct dfu_entity *dfu); +/** + * dfu_error_callback() - weak callback called at the DFU write error + * + * It is a callback function called by DFU stack after DFU write error. + * This function allows to manage some board specific behavior on DFU targets + * + * @dfu: pointer to the dfu_entity which cause the error + * @msg: the message of the error + */ +void dfu_error_callback(struct dfu_entity *dfu, const char *msg); + int dfu_transaction_initiate(struct dfu_entity *dfu, bool read); void dfu_transaction_cleanup(struct dfu_entity *dfu); |