mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-19 05:31:32 +00:00
- stm32mp157c-odyssey-som DT fixes
- stm32_qspi: Fix short data write operation - dfu: set max_buf_size to erasesize also for NOR devices - Fixes ethernet clock property name for STM32MP1 board - STM32CubeProgrammer: various fixes - clk: cosmetic update for clk-uclass -----BEGIN PGP SIGNATURE----- iQJQBAABCgA6FiEEXyrViUccKBz9c35Jysd4L3sz/6YFAmDMi68cHHBhdHJpY2Uu Y2hvdGFyZEBmb3NzLnN0LmNvbQAKCRDKx3gvezP/pgixD/43iCVCzv+pQE1+yz3N UNl3oSPu/FstrgzNIcIu6rYJi0MVO1g/hwIshSzfYgWflAgixR9T8nORbmi7MdJS JPwbrnhhZ6gKcVnnOeLa0J47PP1Abm4gUze1wSmDjqKQXwap6maYsmOn7O8P+v8p 63G5ZMvj4CUG8+kPMnldSiyHNGZbcLmUbFeQ47sawQsrTDJWnN7a9UvjS+equYpM cZDG8EuvSPMdavyUYtuZ/Ram/BwzVTbrwWgHdeK3LPTspcS7EhVipXAIM8khYVZp /bACtteLzA6opgXI5KAmzeh50ah8oizAWNt0fHjpTqZ/Ibn5lCEqRFIv6agwKX+w 4c31+E3KaXhg6MUBp3TJKOGVRxr5HuyiAiRVcTXa7X1tGHB25aVtLQ4IM3jPIJ51 GZdroBqISnq0oN9V5TNVlpsznUepLs/6mvwydasPy31L+7AnG4bkiZ0oHcdCfmEW nvMsQiRp6ufolNlfnvm8YOP1JevVp8V8EjOB3I07dAVsHiqWJFqfHiKs/EsG9sl4 q6zEd6qkZCaG0cdkwMx67k+pgmtjGRSe6pSVSNNILcjSaEEVY2aC7cDGTJbkN88J JaC9JkSfyrgLteMtcse54TDe+/v5IWQ2tYlb8w+IM+mRXup9mqkHm5B4Nc5PowD0 azHmZAre4NeXUt40TgqB3am6Hg== =5v48 -----END PGP SIGNATURE----- Merge tag 'u-boot-stm32-20210618' of https://source.denx.de/u-boot/custodians/u-boot-stm into next - stm32mp157c-odyssey-som DT fixes - stm32_qspi: Fix short data write operation - dfu: set max_buf_size to erasesize also for NOR devices - Fixes ethernet clock property name for STM32MP1 board - STM32CubeProgrammer: various fixes - clk: cosmetic update for clk-uclass
This commit is contained in:
commit
0699dbdbd8
14 changed files with 160 additions and 201 deletions
|
@ -123,3 +123,24 @@
|
||||||
u-boot,dm-pre-reloc;
|
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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -264,14 +264,17 @@
|
||||||
|
|
||||||
&sdmmc2 {
|
&sdmmc2 {
|
||||||
pinctrl-names = "default", "opendrain", "sleep";
|
pinctrl-names = "default", "opendrain", "sleep";
|
||||||
pinctrl-0 = <&sdmmc2_b4_pins_a>;
|
pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_d>;
|
||||||
pinctrl-1 = <&sdmmc2_b4_od_pins_a>;
|
pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_d>;
|
||||||
pinctrl-2 = <&sdmmc2_b4_sleep_pins_a>;
|
pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_d>;
|
||||||
broken-cd;
|
non-removable;
|
||||||
disable-wp;
|
no-sd;
|
||||||
|
no-sdio;
|
||||||
st,neg-edge;
|
st,neg-edge;
|
||||||
bus-width = <4>;
|
bus-width = <8>;
|
||||||
vmmc-supply = <&v3v3>;
|
vmmc-supply = <&v3v3>;
|
||||||
|
vqmmc-supply = <&vdd>;
|
||||||
|
mmc-ddr-3_3v;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
bool reset = false;
|
bool reset = false;
|
||||||
struct image_header_s header;
|
struct image_header_s header;
|
||||||
struct stm32prog_data *data;
|
struct stm32prog_data *data;
|
||||||
u32 uimage, dtb;
|
|
||||||
|
|
||||||
if (argc < 3 || argc > 5)
|
if (argc < 3 || argc > 5)
|
||||||
return CMD_RET_USAGE;
|
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) {
|
if (header.type == HEADER_STM32IMAGE) {
|
||||||
size = header.image_length + BL_HEADER_SIZE;
|
size = header.image_length + BL_HEADER_SIZE;
|
||||||
|
|
||||||
|
#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
|
||||||
/* uImage detected in STM32IMAGE, execute the script */
|
/* uImage detected in STM32IMAGE, execute the script */
|
||||||
if (IMAGE_FORMAT_LEGACY ==
|
if (IMAGE_FORMAT_LEGACY ==
|
||||||
genimg_get_format((void *)(addr + BL_HEADER_SIZE)))
|
genimg_get_format((void *)(addr + BL_HEADER_SIZE)))
|
||||||
return image_source_script(addr + BL_HEADER_SIZE, "script@1");
|
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);
|
ret = stm32prog_init(data, addr, size);
|
||||||
if (ret)
|
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 */
|
/* prepare DFU for device read/write */
|
||||||
ret = stm32prog_dfu_init(data);
|
ret = stm32prog_dfu_init(data);
|
||||||
|
@ -119,21 +120,23 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
uimage = data->uimage;
|
|
||||||
dtb = data->dtb;
|
|
||||||
|
|
||||||
stm32prog_clean(data);
|
stm32prog_clean(data);
|
||||||
free(stm32prog_data);
|
free(stm32prog_data);
|
||||||
stm32prog_data = NULL;
|
stm32prog_data = NULL;
|
||||||
|
|
||||||
puts("Download done\n");
|
puts("Download done\n");
|
||||||
|
|
||||||
if (uimage) {
|
if (data->uimage) {
|
||||||
char boot_addr_start[20];
|
char boot_addr_start[20];
|
||||||
char dtb_addr[20];
|
char dtb_addr[20];
|
||||||
|
char initrd_addr[40];
|
||||||
char *bootm_argv[5] = {
|
char *bootm_argv[5] = {
|
||||||
"bootm", boot_addr_start, "-", dtb_addr, NULL
|
"bootm", boot_addr_start, "-", dtb_addr, NULL
|
||||||
};
|
};
|
||||||
|
u32 uimage = data->uimage;
|
||||||
|
u32 dtb = data->dtb;
|
||||||
|
u32 initrd = data->initrd;
|
||||||
|
|
||||||
if (!dtb)
|
if (!dtb)
|
||||||
bootm_argv[3] = env_get("fdtcontroladdr");
|
bootm_argv[3] = env_get("fdtcontroladdr");
|
||||||
else
|
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,
|
snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
|
||||||
"0x%x", uimage);
|
"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 */
|
/* Try bootm for legacy and FIT format image */
|
||||||
if (genimg_get_format((void *)uimage) != IMAGE_FORMAT_INVALID)
|
if (genimg_get_format((void *)uimage) != IMAGE_FORMAT_INVALID)
|
||||||
do_bootm(cmdtp, 0, 4, bootm_argv);
|
do_bootm(cmdtp, 0, 4, bootm_argv);
|
||||||
|
|
|
@ -369,23 +369,24 @@ static int parse_flash_layout(struct stm32prog_data *data,
|
||||||
bool end_of_line, eof;
|
bool end_of_line, eof;
|
||||||
char *p, *start, *last, *col;
|
char *p, *start, *last, *col;
|
||||||
struct stm32prog_part_t *part;
|
struct stm32prog_part_t *part;
|
||||||
|
struct image_header_s header;
|
||||||
int part_list_size;
|
int part_list_size;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
data->part_nb = 0;
|
data->part_nb = 0;
|
||||||
|
|
||||||
/* check if STM32image is detected */
|
/* check if STM32image is detected */
|
||||||
stm32prog_header_check((struct raw_header_s *)addr, &data->header);
|
stm32prog_header_check((struct raw_header_s *)addr, &header);
|
||||||
if (data->header.type == HEADER_STM32IMAGE) {
|
if (header.type == HEADER_STM32IMAGE) {
|
||||||
u32 checksum;
|
u32 checksum;
|
||||||
|
|
||||||
addr = addr + BL_HEADER_SIZE;
|
addr = addr + BL_HEADER_SIZE;
|
||||||
size = data->header.image_length;
|
size = header.image_length;
|
||||||
|
|
||||||
checksum = stm32prog_header_checksum(addr, &data->header);
|
checksum = stm32prog_header_checksum(addr, &header);
|
||||||
if (checksum != data->header.image_checksum) {
|
if (checksum != header.image_checksum) {
|
||||||
stm32prog_err("Layout: invalid checksum : 0x%x expected 0x%x",
|
stm32prog_err("Layout: invalid checksum : 0x%x expected 0x%x",
|
||||||
checksum, data->header.image_checksum);
|
checksum, header.image_checksum);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1149,7 +1150,10 @@ static int dfu_init_entities(struct stm32prog_data *data)
|
||||||
struct dfu_entity *dfu;
|
struct dfu_entity *dfu;
|
||||||
int alt_nb;
|
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)
|
if (data->part_nb == 0)
|
||||||
alt_nb++; /* +1 for FlashLayout */
|
alt_nb++; /* +1 for FlashLayout */
|
||||||
else
|
else
|
||||||
|
@ -1472,7 +1476,7 @@ error:
|
||||||
return ret;
|
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 (data->phase == PHASE_FLASHLAYOUT) {
|
||||||
if (parse_flash_layout(data, STM32_DDR_BASE, 0))
|
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;
|
data->uimage = data->cur_part->addr;
|
||||||
if (data->cur_part->part_type == PART_FILESYSTEM)
|
if (data->cur_part->part_type == PART_FILESYSTEM)
|
||||||
data->dtb = data->cur_part->addr;
|
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) &&
|
if (CONFIG_IS_ENABLED(MMC) &&
|
||||||
|
@ -1727,7 +1735,6 @@ void stm32prog_clean(struct stm32prog_data *data)
|
||||||
free(data->part_array);
|
free(data->part_array);
|
||||||
free(data->otp_part);
|
free(data->otp_part);
|
||||||
free(data->buffer);
|
free(data->buffer);
|
||||||
free(data->header_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DFU callback: used after serial and direct DFU USB access */
|
/* 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->dev_type == DFU_DEV_RAM) {
|
||||||
if (dfu->alt == 0 &&
|
if (dfu->alt == 0 &&
|
||||||
stm32prog_data->phase == PHASE_FLASHLAYOUT) {
|
stm32prog_data->phase == PHASE_FLASHLAYOUT) {
|
||||||
stm32prog_end_phase(stm32prog_data);
|
stm32prog_end_phase(stm32prog_data, dfu->offset);
|
||||||
/* waiting DFU DETACH for reenumeration */
|
/* waiting DFU DETACH for reenumeration */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1756,7 +1763,7 @@ void dfu_flush_callback(struct dfu_entity *dfu)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (dfu->alt == stm32prog_data->cur_part->alt_id) {
|
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);
|
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);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -132,14 +132,9 @@ struct stm32prog_data {
|
||||||
u32 *otp_part;
|
u32 *otp_part;
|
||||||
u8 pmic_part[PMIC_SIZE];
|
u8 pmic_part[PMIC_SIZE];
|
||||||
|
|
||||||
/* STM32 header information */
|
|
||||||
struct raw_header_s *header_data;
|
|
||||||
struct image_header_s header;
|
|
||||||
|
|
||||||
/* SERIAL information */
|
/* SERIAL information */
|
||||||
u32 cursor;
|
u32 cursor;
|
||||||
u32 packet_number;
|
u32 packet_number;
|
||||||
u32 checksum;
|
|
||||||
u8 *buffer; /* size = USART_RAM_BUFFER_SIZE*/
|
u8 *buffer; /* size = USART_RAM_BUFFER_SIZE*/
|
||||||
int dfu_seq;
|
int dfu_seq;
|
||||||
u8 read_phase;
|
u8 read_phase;
|
||||||
|
@ -147,6 +142,8 @@ struct stm32prog_data {
|
||||||
/* bootm information */
|
/* bootm information */
|
||||||
u32 uimage;
|
u32 uimage;
|
||||||
u32 dtb;
|
u32 dtb;
|
||||||
|
u32 initrd;
|
||||||
|
u32 initrd_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct stm32prog_data *stm32prog_data;
|
extern struct stm32prog_data *stm32prog_data;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
#include <watchdog.h>
|
#include <watchdog.h>
|
||||||
|
#include <asm/arch/sys_proto.h>
|
||||||
#include <dm/lists.h>
|
#include <dm/lists.h>
|
||||||
#include <dm/device-internal.h>
|
#include <dm/device-internal.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
@ -19,8 +20,7 @@
|
||||||
/* - configuration part -----------------------------*/
|
/* - configuration part -----------------------------*/
|
||||||
#define USART_BL_VERSION 0x40 /* USART bootloader version V4.0*/
|
#define USART_BL_VERSION 0x40 /* USART bootloader version V4.0*/
|
||||||
#define UBOOT_BL_VERSION 0x03 /* bootloader version V0.3*/
|
#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*/
|
#define USART_RAM_BUFFER_SIZE 256 /* Size of USART_RAM_Buf buffer*/
|
||||||
|
|
||||||
/* - Commands -----------------------------*/
|
/* - Commands -----------------------------*/
|
||||||
|
@ -60,6 +60,9 @@ const u8 cmd_id[] = {
|
||||||
|
|
||||||
#define NB_CMD sizeof(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 *********************************************/
|
/* DFU support for serial *********************************************/
|
||||||
static struct dfu_entity *stm32prog_get_entity(struct stm32prog_data *data)
|
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);
|
struct dm_serial_ops *ops = serial_get_ops(down_serial_dev);
|
||||||
int err;
|
int err;
|
||||||
|
ulong start = get_timer(0);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
err = ops->getc(down_serial_dev);
|
err = ops->getc(down_serial_dev);
|
||||||
|
@ -273,6 +277,10 @@ static bool stm32prog_serial_get_buffer(u8 *buffer, u32 *count)
|
||||||
} else if (err == -EAGAIN) {
|
} else if (err == -EAGAIN) {
|
||||||
ctrlc();
|
ctrlc();
|
||||||
WATCHDOG_RESET();
|
WATCHDOG_RESET();
|
||||||
|
if (get_timer(start) > TIMEOUT_SERIAL_BUFFER) {
|
||||||
|
err = -ETIMEDOUT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -292,56 +300,6 @@ static void stm32prog_serial_putc(u8 w_byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function ************************************************/
|
/* 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)
|
static u8 stm32prog_start(struct stm32prog_data *data, u32 address)
|
||||||
{
|
{
|
||||||
u8 ret = 0;
|
u8 ret = 0;
|
||||||
|
@ -388,23 +346,6 @@ static u8 stm32prog_start(struct stm32prog_data *data, u32 address)
|
||||||
data->dfu_seq = 0;
|
data->dfu_seq = 0;
|
||||||
|
|
||||||
printf("\n received length = 0x%x\n", data->cursor);
|
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 */
|
/* update DFU with received flashlayout */
|
||||||
if (data->phase == PHASE_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)
|
static void get_id_command(struct stm32prog_data *data)
|
||||||
{
|
{
|
||||||
|
u32 cpu = get_cpu_dev();
|
||||||
|
|
||||||
/* Send Device IDCode */
|
/* Send Device IDCode */
|
||||||
stm32prog_serial_putc(0x1);
|
stm32prog_serial_putc(0x1);
|
||||||
stm32prog_serial_putc(DEVICE_ID_BYTE1);
|
stm32prog_serial_putc((cpu >> 8) & 0xFF);
|
||||||
stm32prog_serial_putc(DEVICE_ID_BYTE2);
|
stm32prog_serial_putc(cpu & 0xFF);
|
||||||
stm32prog_serial_result(ACK_BYTE);
|
stm32prog_serial_result(ACK_BYTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,14 +570,12 @@ static void download_command(struct stm32prog_data *data)
|
||||||
u32 counter = 0x0, codesize = 0x0;
|
u32 counter = 0x0, codesize = 0x0;
|
||||||
u8 *ramaddress = 0;
|
u8 *ramaddress = 0;
|
||||||
u8 rcv_data = 0x0;
|
u8 rcv_data = 0x0;
|
||||||
struct image_header_s *image_header = &data->header;
|
|
||||||
u32 cursor = data->cursor;
|
u32 cursor = data->cursor;
|
||||||
long size = 0;
|
long size = 0;
|
||||||
u8 operation;
|
u8 operation;
|
||||||
u32 packet_number;
|
u32 packet_number;
|
||||||
u32 result = ACK_BYTE;
|
u32 result = ACK_BYTE;
|
||||||
u8 ret;
|
u8 ret;
|
||||||
unsigned int i;
|
|
||||||
bool error;
|
bool error;
|
||||||
int rcv;
|
int rcv;
|
||||||
|
|
||||||
|
@ -668,13 +609,8 @@ static void download_command(struct stm32prog_data *data)
|
||||||
if (packet_number == 0) {
|
if (packet_number == 0) {
|
||||||
/* erase: re-initialize the image_header struct */
|
/* erase: re-initialize the image_header struct */
|
||||||
data->packet_number = 0;
|
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;
|
cursor = 0;
|
||||||
data->cursor = 0;
|
data->cursor = 0;
|
||||||
data->checksum = 0;
|
|
||||||
/*idx = cursor;*/
|
/*idx = cursor;*/
|
||||||
} else {
|
} else {
|
||||||
data->packet_number++;
|
data->packet_number++;
|
||||||
|
@ -722,7 +658,7 @@ static void download_command(struct stm32prog_data *data)
|
||||||
printf("transmission error on packet %d, byte %d\n",
|
printf("transmission error on packet %d, byte %d\n",
|
||||||
packet_number, codesize - counter);
|
packet_number, codesize - counter);
|
||||||
/* waiting end of packet before flush & NACK */
|
/* waiting end of packet before flush & NACK */
|
||||||
mdelay(30);
|
mdelay(TIMEOUT_SERIAL_BUFFER);
|
||||||
data->packet_number--;
|
data->packet_number--;
|
||||||
result = NACK_BYTE;
|
result = NACK_BYTE;
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -740,80 +676,33 @@ static void download_command(struct stm32prog_data *data)
|
||||||
/* wait to be sure that all data are received
|
/* wait to be sure that all data are received
|
||||||
* in the FIFO before flush
|
* in the FIFO before flush
|
||||||
*/
|
*/
|
||||||
mdelay(30);
|
mdelay(TIMEOUT_SERIAL_BUFFER);
|
||||||
data->packet_number--;
|
data->packet_number--;
|
||||||
result = NACK_BYTE;
|
result = NACK_BYTE;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update current position in buffer */
|
switch (operation) {
|
||||||
data->cursor += codesize;
|
case PHASE_OTP:
|
||||||
|
size = codesize;
|
||||||
|
ret = stm32prog_otp_write(data, cursor, data->buffer, &size);
|
||||||
|
break;
|
||||||
|
|
||||||
if (operation == PHASE_OTP) {
|
case PHASE_PMIC:
|
||||||
size = data->cursor - cursor;
|
size = codesize;
|
||||||
/* no header for OTP */
|
ret = stm32prog_pmic_write(data, cursor, data->buffer, &size);
|
||||||
if (stm32prog_otp_write(data, cursor,
|
break;
|
||||||
data->buffer, &size))
|
|
||||||
result = ABORT_BYTE;
|
default:
|
||||||
goto end;
|
ret = stm32prog_write(data, data->buffer, codesize);
|
||||||
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
if (ret)
|
||||||
result = ABORT_BYTE;
|
result = ABORT_BYTE;
|
||||||
|
else
|
||||||
|
/* Update current position in buffer */
|
||||||
|
data->cursor += codesize;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
stm32prog_serial_result(result);
|
stm32prog_serial_result(result);
|
||||||
|
|
|
@ -207,13 +207,10 @@ bool stm32prog_usb_loop(struct stm32prog_data *data, int dev)
|
||||||
|
|
||||||
if (stm32prog_data->phase == PHASE_FLASHLAYOUT) {
|
if (stm32prog_data->phase == PHASE_FLASHLAYOUT) {
|
||||||
ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu");
|
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;
|
return ret;
|
||||||
/* prepare the second enumeration with the FlashLayout */
|
/* prepare the second enumeration with the FlashLayout */
|
||||||
if (stm32prog_data->phase == PHASE_FLASHLAYOUT)
|
stm32prog_dfu_init(data);
|
||||||
stm32prog_dfu_init(data);
|
|
||||||
/* found next selected partition */
|
|
||||||
stm32prog_next_phase(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu");
|
ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu");
|
||||||
|
|
|
@ -660,11 +660,11 @@ int board_interface_eth_init(struct udevice *dev,
|
||||||
bool eth_ref_clk_sel_reg = false;
|
bool eth_ref_clk_sel_reg = false;
|
||||||
|
|
||||||
/* Gigabit Ethernet 125MHz clock selection. */
|
/* 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 */
|
/* Ethernet 50Mhz RMII clock selection */
|
||||||
eth_ref_clk_sel_reg =
|
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);
|
syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
|
||||||
|
|
||||||
|
|
|
@ -733,11 +733,11 @@ int board_interface_eth_init(struct udevice *dev,
|
||||||
bool eth_ref_clk_sel_reg = false;
|
bool eth_ref_clk_sel_reg = false;
|
||||||
|
|
||||||
/* Gigabit Ethernet 125MHz clock selection. */
|
/* 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 */
|
/* Ethernet 50Mhz RMII clock selection */
|
||||||
eth_ref_clk_sel_reg =
|
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);
|
syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
|
||||||
|
|
||||||
|
|
|
@ -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 clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk)
|
||||||
{
|
{
|
||||||
int i, ret, err, count;
|
int i, ret, err, count;
|
||||||
|
|
||||||
bulk->count = 0;
|
bulk->count = 0;
|
||||||
|
|
||||||
count = dev_count_phandle_with_args(dev, "clocks", "#clock-cells", 0);
|
count = dev_count_phandle_with_args(dev, "clocks", "#clock-cells", 0);
|
||||||
|
|
|
@ -44,6 +44,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
|
* The purpose of the dfu_usb_get_reset() function is to
|
||||||
* provide information if after USB_DETACH request
|
* provide information if after USB_DETACH request
|
||||||
|
@ -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",
|
printf("%s: Wrong sequence number! [%d] [%d]\n",
|
||||||
__func__, dfu->i_blk_seq_num, blk_seq_num);
|
__func__, dfu->i_blk_seq_num, blk_seq_num);
|
||||||
dfu_transaction_cleanup(dfu);
|
dfu_transaction_cleanup(dfu);
|
||||||
|
dfu_error_callback(dfu, "Wrong sequence number");
|
||||||
return -1;
|
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);
|
ret = dfu_write_buffer_drain(dfu);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dfu_transaction_cleanup(dfu);
|
dfu_transaction_cleanup(dfu);
|
||||||
|
dfu_error_callback(dfu, "DFU write error");
|
||||||
return ret;
|
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,
|
pr_err("Buffer overflow! (0x%p + 0x%x > 0x%p)\n", dfu->i_buf,
|
||||||
size, dfu->i_buf_end);
|
size, dfu->i_buf_end);
|
||||||
dfu_transaction_cleanup(dfu);
|
dfu_transaction_cleanup(dfu);
|
||||||
|
dfu_error_callback(dfu, "Buffer overflow");
|
||||||
return -1;
|
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);
|
ret = dfu_write_buffer_drain(dfu);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dfu_transaction_cleanup(dfu);
|
dfu_transaction_cleanup(dfu);
|
||||||
|
dfu_error_callback(dfu, "DFU write error");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,7 +254,6 @@ int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char *s)
|
||||||
{
|
{
|
||||||
char *st;
|
char *st;
|
||||||
struct mtd_info *mtd;
|
struct mtd_info *mtd;
|
||||||
bool has_pages;
|
|
||||||
int ret, part;
|
int ret, part;
|
||||||
|
|
||||||
mtd = get_mtd_device_nm(devstr);
|
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->dev_type = DFU_DEV_MTD;
|
||||||
dfu->data.mtd.info = mtd;
|
dfu->data.mtd.info = mtd;
|
||||||
|
dfu->max_buf_size = mtd->erasesize;
|
||||||
has_pages = mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH;
|
|
||||||
dfu->max_buf_size = has_pages ? mtd->erasesize : 0;
|
|
||||||
|
|
||||||
st = strsep(&s, " ");
|
st = strsep(&s, " ");
|
||||||
if (!strcmp(st, "raw")) {
|
if (!strcmp(st, "raw")) {
|
||||||
|
|
|
@ -148,23 +148,24 @@ static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv *priv,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
u32 sr;
|
u32 sr;
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
if (!op->data.nbytes)
|
if (op->data.nbytes) {
|
||||||
return _stm32_qspi_wait_for_not_busy(priv);
|
ret = readl_poll_timeout(&priv->regs->sr, sr,
|
||||||
|
sr & STM32_QSPI_SR_TCF,
|
||||||
ret = readl_poll_timeout(&priv->regs->sr, sr,
|
STM32_QSPI_CMD_TIMEOUT_US);
|
||||||
sr & STM32_QSPI_SR_TCF,
|
if (ret) {
|
||||||
STM32_QSPI_CMD_TIMEOUT_US);
|
log_err("cmd timeout (stat:%#x)\n", sr);
|
||||||
if (ret) {
|
} else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) {
|
||||||
log_err("cmd timeout (stat:%#x)\n", sr);
|
log_err("transfer error (stat:%#x)\n", sr);
|
||||||
} else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) {
|
ret = -EIO;
|
||||||
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 */
|
if (!ret)
|
||||||
writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, &priv->regs->fcr);
|
ret = _stm32_qspi_wait_for_not_busy(priv);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -377,6 +377,17 @@ void dfu_initiated_callback(struct dfu_entity *dfu);
|
||||||
*/
|
*/
|
||||||
void dfu_flush_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);
|
int dfu_transaction_initiate(struct dfu_entity *dfu, bool read);
|
||||||
void dfu_transaction_cleanup(struct dfu_entity *dfu);
|
void dfu_transaction_cleanup(struct dfu_entity *dfu);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue