From e5f63e6e86eaeaac14d9db888c2441803e0038b2 Mon Sep 17 00:00:00 2001 From: Christophe Priouzeau Date: Mon, 3 May 2021 12:18:42 +0200 Subject: [PATCH] U-BOOT-STM32MP: update to v2020.10-stm32mp-r2 Change-Id: I4e58162aafc5f6dcd94793dae7018bc03ae136e9 --- .../u-boot/u-boot-stm32mp-common_2020.10.inc | 11 +- .../0006-ARM-v2020.10-stm32mp-r1.1.patch | 340 ++ ...0007-ARM-v2020.10-stm32mp-r2-MACHINE.patch | 946 ++++++ .../0008-ARM-v2020.10-stm32mp-r2-BOARD.patch | 117 + ...ARM-v2020.10-stm32mp-r2-MISC-DRIVERS.patch | 2957 +++++++++++++++++ ...0-ARM-v2020.10-stm32mp-r2-DEVICETREE.patch | 573 ++++ .../0011-ARM-v2020.10-stm32mp-r2-CONFIG.patch | 186 ++ 7 files changed, 5128 insertions(+), 2 deletions(-) create mode 100644 recipes-bsp/u-boot/u-boot-stm32mp/0006-ARM-v2020.10-stm32mp-r1.1.patch create mode 100644 recipes-bsp/u-boot/u-boot-stm32mp/0007-ARM-v2020.10-stm32mp-r2-MACHINE.patch create mode 100644 recipes-bsp/u-boot/u-boot-stm32mp/0008-ARM-v2020.10-stm32mp-r2-BOARD.patch create mode 100644 recipes-bsp/u-boot/u-boot-stm32mp/0009-ARM-v2020.10-stm32mp-r2-MISC-DRIVERS.patch create mode 100644 recipes-bsp/u-boot/u-boot-stm32mp/0010-ARM-v2020.10-stm32mp-r2-DEVICETREE.patch create mode 100644 recipes-bsp/u-boot/u-boot-stm32mp/0011-ARM-v2020.10-stm32mp-r2-CONFIG.patch diff --git a/recipes-bsp/u-boot/u-boot-stm32mp-common_2020.10.inc b/recipes-bsp/u-boot/u-boot-stm32mp-common_2020.10.inc index cb6567c..af44ff2 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp-common_2020.10.inc +++ b/recipes-bsp/u-boot/u-boot-stm32mp-common_2020.10.inc @@ -21,6 +21,13 @@ SRC_URI += "\ file://0004-ARM-v2020.10-stm32mp-r1-DEVICETREE.patch \ file://0005-ARM-v2020.10-stm32mp-r1-CONFIG.patch \ \ + file://0006-ARM-v2020.10-stm32mp-r1.1.patch \ + file://0007-ARM-v2020.10-stm32mp-r2-MACHINE.patch \ + file://0008-ARM-v2020.10-stm32mp-r2-BOARD.patch \ + file://0009-ARM-v2020.10-stm32mp-r2-MISC-DRIVERS.patch \ + file://0010-ARM-v2020.10-stm32mp-r2-DEVICETREE.patch \ + file://0011-ARM-v2020.10-stm32mp-r2-CONFIG.patch \ + \ file://0099-Add-external-var-to-allow-build-of-new-devicetree-fi.patch \ " @@ -29,7 +36,7 @@ SRC_URI += "${@bb.utils.contains('ST_UBOOT_DEBUG_TRACE', '1', '', 'file://0098-s U_BOOT_VERSION = "v2020.10" U_BOOT_SUBVERSION = "stm32mp" -U_BOOT_RELEASE = "r1" +U_BOOT_RELEASE = "r2" PV = "${U_BOOT_VERSION}-${U_BOOT_SUBVERSION}-${U_BOOT_RELEASE}" ARCHIVER_ST_BRANCH = "${U_BOOT_VERSION}-${U_BOOT_SUBVERSION}" @@ -45,7 +52,7 @@ S = "${WORKDIR}/git" BBCLASSEXTEND = "devupstream:target" SRC_URI_class-devupstream = "git://github.com/STMicroelectronics/u-boot.git;protocol=https;branch=${ARCHIVER_ST_BRANCH}" -SRCREV_class-devupstream = "d2c99cb7e5b7dc74236f67fcced156956155cd71" +SRCREV_class-devupstream = "6fde82adf71ebad4b16d99f76ed69abfd9cfaf42" # --------------------------------- # Configure default preference to manage dynamic selection between tarball and github diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0006-ARM-v2020.10-stm32mp-r1.1.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0006-ARM-v2020.10-stm32mp-r1.1.patch new file mode 100644 index 0000000..c94b803 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0006-ARM-v2020.10-stm32mp-r1.1.patch @@ -0,0 +1,340 @@ +From 77f5697167358c634bee38a98ad059f1b6b33dbf Mon Sep 17 00:00:00 2001 +From: Romuald JEANNE +Date: Tue, 25 May 2021 20:18:25 +0200 +Subject: [PATCH 6/7] ARM v2020.10-stm32mp-r1.1 + +Signed-off-by: Romuald JEANNE +--- + Makefile | 2 +- + .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 14 +- + .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 5 - + .../cmd_stm32prog/stm32prog_serial.c | 163 +++--------------- + 4 files changed, 33 insertions(+), 151 deletions(-) + +diff --git a/Makefile b/Makefile +index 6bd0841c4b..59493deed3 100644 +--- a/Makefile ++++ b/Makefile +@@ -3,7 +3,7 @@ + VERSION = 2020 + PATCHLEVEL = 10 + SUBLEVEL = +-EXTRAVERSION = -stm32mp-r1 ++EXTRAVERSION = -stm32mp-r1.1 + NAME = + + # *DOCUMENTATION* +diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +index 627bb52a11..7cd31462ba 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c ++++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +@@ -368,23 +368,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; + } + } +@@ -1730,7 +1731,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 */ +diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +index fadcd1fa8f..eebc4d2e71 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h ++++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +@@ -134,14 +134,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; +diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c +index 0c3c215b3d..a0bf7e1884 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c ++++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c +@@ -59,6 +59,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) + { +@@ -263,6 +266,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); +@@ -272,6 +276,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; + } +@@ -291,56 +299,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; +@@ -387,23 +345,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) +@@ -626,14 +567,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; + +@@ -667,13 +606,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++; +@@ -721,7 +655,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; +@@ -739,80 +673,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) { +- pr_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); +-- +2.17.1 + diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0007-ARM-v2020.10-stm32mp-r2-MACHINE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0007-ARM-v2020.10-stm32mp-r2-MACHINE.patch new file mode 100644 index 0000000..f417a9c --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0007-ARM-v2020.10-stm32mp-r2-MACHINE.patch @@ -0,0 +1,946 @@ +From 85fa6b016df48fdd465f8b5314b2e96a575c3228 Mon Sep 17 00:00:00 2001 +From: Lionel Vitte +Date: Mon, 18 Oct 2021 17:10:29 +0200 +Subject: [PATCH 07/11] ARM v2020.10-stm32mp-r2 MACHINE + +--- + Makefile | 2 +- + arch/arm/cpu/armv7/cache_v7.c | 3 - + arch/arm/include/asm/cache.h | 1 - + arch/arm/include/asm/system.h | 18 +- + arch/arm/lib/cache-cp15.c | 13 +- + arch/arm/mach-omap2/omap-cache.c | 17 -- + arch/arm/mach-stm32mp/Kconfig | 4 +- + arch/arm/mach-stm32mp/cmd_stm32key.c | 235 +++++++++++++++--- + .../cmd_stm32prog/cmd_stm32prog.c | 36 ++- + .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 35 ++- + .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 3 + + .../cmd_stm32prog/stm32prog_serial.c | 10 +- + .../cmd_stm32prog/stm32prog_usb.c | 9 +- + arch/arm/mach-stm32mp/cpu.c | 61 ++++- + arch/arm/mach-stm32mp/dram_init.c | 19 +- + arch/arm/mach-stm32mp/syscon.c | 14 ++ + 16 files changed, 351 insertions(+), 129 deletions(-) + +diff --git a/Makefile b/Makefile +index 59493deed3..25a42acc37 100644 +--- a/Makefile ++++ b/Makefile +@@ -3,7 +3,7 @@ + VERSION = 2020 + PATCHLEVEL = 10 + SUBLEVEL = +-EXTRAVERSION = -stm32mp-r1.1 ++EXTRAVERSION = -stm32mp-r2 + NAME = + + # *DOCUMENTATION* +diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c +index 146cf52608..19ff432352 100644 +--- a/arch/arm/cpu/armv7/cache_v7.c ++++ b/arch/arm/cpu/armv7/cache_v7.c +@@ -176,9 +176,6 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop) + { + } + +-void arm_init_domains(void) +-{ +-} + #endif /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */ + + #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) +diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h +index c20e05ec7f..b10edf805b 100644 +--- a/arch/arm/include/asm/cache.h ++++ b/arch/arm/include/asm/cache.h +@@ -35,7 +35,6 @@ void l2_cache_disable(void); + void set_section_dcache(int section, enum dcache_option option); + + void arm_init_before_mmu(void); +-void arm_init_domains(void); + void cpu_cache_initialization(void); + void dram_bank_mmu_setup(int bank); + +diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h +index 932f12af1c..cab23ca7b2 100644 +--- a/arch/arm/include/asm/system.h ++++ b/arch/arm/include/asm/system.h +@@ -397,20 +397,6 @@ static inline void set_cr(unsigned int val) + isb(); + } + +-static inline unsigned int get_dacr(void) +-{ +- unsigned int val; +- asm("mrc p15, 0, %0, c3, c0, 0 @ get DACR" : "=r" (val) : : "cc"); +- return val; +-} +- +-static inline void set_dacr(unsigned int val) +-{ +- asm volatile("mcr p15, 0, %0, c3, c0, 0 @ set DACR" +- : : "r" (val) : "cc"); +- isb(); +-} +- + #ifdef CONFIG_ARMV7_LPAE + /* Long-Descriptor Translation Table Level 1/2 Bits */ + #define TTB_SECT_XN_MASK (1ULL << 54) +@@ -476,7 +462,7 @@ enum dcache_option { + #define TTB_SECT_XN_MASK (1 << 4) + #define TTB_SECT_C_MASK (1 << 3) + #define TTB_SECT_B_MASK (1 << 2) +-#define TTB_SECT (2 << 0) ++#define TTB_SECT (2 << 0) + + /* + * Short-descriptor format memory region attributes, without TEX remap +@@ -491,7 +477,7 @@ enum dcache_option { + enum dcache_option { + INVALID_ENTRY = 0, + DCACHE_OFF = TTB_SECT_DOMAIN(0) | TTB_SECT_XN_MASK | TTB_SECT, +- DCACHE_WRITETHROUGH = DCACHE_OFF | TTB_SECT_C_MASK, ++ DCACHE_WRITETHROUGH = TTB_SECT_DOMAIN(0) | TTB_SECT | TTB_SECT_C_MASK, + DCACHE_WRITEBACK = DCACHE_WRITETHROUGH | TTB_SECT_B_MASK, + DCACHE_WRITEALLOC = DCACHE_WRITEBACK | TTB_SECT_TEX(1), + }; +diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c +index 94e9b9c861..369be44b17 100644 +--- a/arch/arm/lib/cache-cp15.c ++++ b/arch/arm/lib/cache-cp15.c +@@ -22,10 +22,6 @@ __weak void arm_init_before_mmu(void) + { + } + +-__weak void arm_init_domains(void) +-{ +-} +- + static void set_section_phys(int section, phys_addr_t phys, + enum dcache_option option) + { +@@ -209,11 +205,12 @@ static inline void mmu_setup(void) + asm volatile("mcr p15, 0, %0, c2, c0, 0" + : : "r" (gd->arch.tlb_addr) : "memory"); + #endif +- /* Set the access control to all-supervisor */ ++ /* ++ * initial value of Domain Access Control Register (DACR) ++ * Set the access control to client (1U) for each of the 16 domains ++ */ + asm volatile("mcr p15, 0, %0, c3, c0, 0" +- : : "r" (~0)); +- +- arm_init_domains(); ++ : : "r" (0x55555555)); + + /* and enable the mmu */ + reg = get_cr(); /* get control reg. */ +diff --git a/arch/arm/mach-omap2/omap-cache.c b/arch/arm/mach-omap2/omap-cache.c +index 502ea6987a..451d8e4542 100644 +--- a/arch/arm/mach-omap2/omap-cache.c ++++ b/arch/arm/mach-omap2/omap-cache.c +@@ -40,9 +40,6 @@ DECLARE_GLOBAL_DATA_PTR; + #define ARMV7_DCACHE_POLICY DCACHE_WRITEBACK & ~TTB_SECT_XN_MASK + #endif + +-#define ARMV7_DOMAIN_CLIENT 1 +-#define ARMV7_DOMAIN_MASK (0x3 << 0) +- + void enable_caches(void) + { + +@@ -66,17 +63,3 @@ void dram_bank_mmu_setup(int bank) + for (i = start; i < end; i++) + set_section_dcache(i, ARMV7_DCACHE_POLICY); + } +- +-void arm_init_domains(void) +-{ +- u32 reg; +- +- reg = get_dacr(); +- /* +- * Set DOMAIN to client access so that all permissions +- * set in pagetables are validated by the mmu. +- */ +- reg &= ~ARMV7_DOMAIN_MASK; +- reg |= ARMV7_DOMAIN_CLIENT; +- set_dacr(reg); +-} +diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig +index af0246d031..44bfac9000 100644 +--- a/arch/arm/mach-stm32mp/Kconfig ++++ b/arch/arm/mach-stm32mp/Kconfig +@@ -130,10 +130,12 @@ config STM32_ETZPC + + config CMD_STM32KEY + bool "command stm32key to fuse public key hash" +- default y ++ default n + help + fuse public key hash in corresponding fuse used to authenticate + binary. ++ This command is used to evaluate the secure boot on stm32mp SOC, ++ it is deactivated by default in real products. + + config PRE_CON_BUF_ADDR + default 0xC02FF000 +diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c +index f191085a12..d1755f4595 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32key.c ++++ b/arch/arm/mach-stm32mp/cmd_stm32key.c +@@ -10,13 +10,30 @@ + #include + #include + +-#define STM32_OTP_HASH_KEY_START 24 +-#define STM32_OTP_HASH_KEY_SIZE 8 ++/* Closed device : bit 6 of OPT0*/ ++#define STM32_OTP_CLOSE_ID 0 ++#define STM32_OTP_CLOSE_MASK BIT(6) ++ ++/* HASH of key: 8 OTPs, starting with OTP24) */ ++#define STM32_OTP_HASH_KEY_START 24 ++#define STM32_OTP_HASH_KEY_SIZE 8 ++ ++static int get_misc_dev(struct udevice **dev) ++{ ++ int ret; ++ ++ ret = uclass_get_device_by_driver(UCLASS_MISC, DM_GET_DRIVER(stm32mp_bsec), dev); ++ if (ret) ++ pr_err("Can't find stm32mp_bsec driver\n"); ++ ++ return ret; ++} + + static void read_hash_value(u32 addr) + { + int i; + ++ printf("Read KEY at 0x%x\n", addr); + for (i = 0; i < STM32_OTP_HASH_KEY_SIZE; i++) { + printf("OTP value %i: %x\n", STM32_OTP_HASH_KEY_START + i, + __be32_to_cpu(*(u32 *)addr)); +@@ -24,32 +41,101 @@ static void read_hash_value(u32 addr) + } + } + +-static void fuse_hash_value(u32 addr, bool print) ++static int read_hash_otp(bool print, bool *locked, bool *closed) + { + struct udevice *dev; +- u32 word, val; +- int i, ret; ++ int i, word, ret; ++ int nb_invalid = 0, nb_zero = 0, nb_lock = 0; ++ u32 val, lock; ++ bool status; + +- ret = uclass_get_device_by_driver(UCLASS_MISC, +- DM_GET_DRIVER(stm32mp_bsec), +- &dev); +- if (ret) { +- pr_err("Can't find stm32mp_bsec driver\n"); +- return; ++ ret = get_misc_dev(&dev); ++ if (ret) ++ return ret; ++ ++ for (i = 0, word = STM32_OTP_HASH_KEY_START; i < STM32_OTP_HASH_KEY_SIZE; i++, word++) { ++ ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4); ++ if (ret != 4) ++ val = ~0x0; ++ ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4); ++ if (ret != 4) ++ lock = -1; ++ if (print) ++ printf("OTP HASH %i: %x lock : %d\n", word, val, lock); ++ if (val == ~0x0) ++ nb_invalid++; ++ else if (val == 0x0) ++ nb_zero++; ++ if (lock == 1) ++ nb_lock++; + } + +- for (i = 0; i < STM32_OTP_HASH_KEY_SIZE; i++) { ++ word = STM32_OTP_CLOSE_ID; ++ ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4); ++ if (ret != 4) ++ val = 0x0; ++ ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4); ++ if (ret != 4) ++ lock = -1; ++ ++ status = (val & STM32_OTP_CLOSE_MASK) == STM32_OTP_CLOSE_MASK; ++ if (closed) ++ *closed = status; ++ if (print) ++ printf("OTP %d: closed status: %d lock : %d\n", word, status, lock); ++ ++ status = (nb_lock == STM32_OTP_HASH_KEY_SIZE); ++ if (locked) ++ *locked = status; ++ if (!status && print) ++ printf("HASK key is not locked!\n"); ++ ++ if (nb_invalid == STM32_OTP_HASH_KEY_SIZE) { ++ if (print) ++ printf("HASK key is invalid!\n"); ++ return -EINVAL; ++ } ++ if (nb_zero == STM32_OTP_HASH_KEY_SIZE) { + if (print) +- printf("Fuse OTP %i : %x\n", +- STM32_OTP_HASH_KEY_START + i, +- __be32_to_cpu(*(u32 *)addr)); ++ printf("HASK key is free!\n"); ++ return -ENOENT; ++ } ++ ++ return 0; ++} + +- word = STM32_OTP_HASH_KEY_START + i; ++static int fuse_hash_value(u32 addr, bool print) ++{ ++ struct udevice *dev; ++ u32 word, val; ++ int i, ret; ++ ++ ret = get_misc_dev(&dev); ++ if (ret) ++ return ret; ++ ++ for (i = 0, word = STM32_OTP_HASH_KEY_START; ++ i < STM32_OTP_HASH_KEY_SIZE; ++ i++, word++, addr += 4) { + val = __be32_to_cpu(*(u32 *)addr); +- misc_write(dev, STM32_BSEC_OTP(word), &val, 4); ++ if (print) ++ printf("Fuse OTP %i : %x\n", word, val); + +- addr += 4; ++ ret = misc_write(dev, STM32_BSEC_OTP(word), &val, 4); ++ if (ret != 4) { ++ printf("Fuse OTP %i failed\n", word); ++ return ret; ++ } ++ /* on success, lock the OTP for HASH key */ ++ val = 1; ++ ret = misc_write(dev, STM32_BSEC_LOCK(word), &val, 4); ++ if (ret != 4) { ++ printf("Lock OTP %i failed\n", word); ++ return ret; ++ } + } ++ ++ return 0; + } + + static int confirm_prog(void) +@@ -66,36 +152,113 @@ static int confirm_prog(void) + return 0; + } + +-static int do_stm32key(struct cmd_tbl *cmdtp, int flag, int argc, +- char *const argv[]) ++static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) + { + u32 addr; +- const char *op = argc >= 2 ? argv[1] : NULL; +- int confirmed = argc > 3 && !strcmp(argv[2], "-y"); + +- argc -= 2 + confirmed; +- argv += 2 + confirmed; ++ if (argc == 1) { ++ read_hash_otp(true, NULL, NULL); ++ return CMD_RET_SUCCESS; ++ } + +- if (argc < 1) ++ addr = simple_strtoul(argv[1], NULL, 16); ++ if (!addr) + return CMD_RET_USAGE; + +- addr = simple_strtoul(argv[0], NULL, 16); ++ read_hash_value(addr); ++ ++ return CMD_RET_SUCCESS; ++} ++ ++static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) ++{ ++ u32 addr; ++ bool yes = false, lock, closed; ++ ++ if (argc < 2) ++ return CMD_RET_USAGE; ++ ++ if (argc == 3) { ++ if (strcmp(argv[1], "-y")) ++ return CMD_RET_USAGE; ++ yes = true; ++ } ++ ++ addr = simple_strtoul(argv[argc - 1], NULL, 16); + if (!addr) + return CMD_RET_USAGE; + +- if (!strcmp(op, "read")) +- read_hash_value(addr); ++ if (read_hash_otp(!yes, &lock, &closed) != -ENOENT) { ++ printf("Error: can't fuse again the OTP\n"); ++ return CMD_RET_FAILURE; ++ } + +- if (!strcmp(op, "fuse")) { +- if (!confirmed && !confirm_prog()) +- return CMD_RET_FAILURE; +- fuse_hash_value(addr, !confirmed); ++ if (lock || closed) { ++ printf("Error: invalid OTP configuration (lock=%d, closed=%d)\n", lock, closed); ++ return CMD_RET_FAILURE; + } + ++ if (!yes && !confirm_prog()) ++ return CMD_RET_FAILURE; ++ ++ if (fuse_hash_value(addr, !yes)) ++ return CMD_RET_FAILURE; ++ ++ printf("Hash key updated !\n"); ++ + return CMD_RET_SUCCESS; + } + +-U_BOOT_CMD(stm32key, 4, 1, do_stm32key, +- "Fuse ST Hash key", +- "read : Read the hash store at addr in memory\n" +- "stm32key fuse [-y] : Fuse hash store at addr in otp\n"); ++static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) ++{ ++ bool yes, lock, closed; ++ struct udevice *dev; ++ u32 val; ++ int ret; ++ ++ yes = false; ++ if (argc == 2) { ++ if (strcmp(argv[1], "-y")) ++ return CMD_RET_USAGE; ++ yes = true; ++ } ++ ++ if (read_hash_otp(!yes, &lock, &closed)) ++ return CMD_RET_FAILURE; ++ ++ if (closed) { ++ printf("Error: already closed!\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ if (!lock) ++ printf("Warning: OTP not locked, revocation is possible!\n"); ++ ++ if (!yes && !confirm_prog()) ++ return CMD_RET_FAILURE; ++ ++ ret = get_misc_dev(&dev); ++ if (ret) ++ return CMD_RET_FAILURE; ++ ++ val = STM32_OTP_CLOSE_MASK; ++ ret = misc_write(dev, STM32_BSEC_OTP(STM32_OTP_CLOSE_ID), &val, 4); ++ if (ret != 4) { ++ printf("Error: can't update OTP\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ printf("Device is closed !\n"); ++ ++ return CMD_RET_SUCCESS; ++} ++ ++static char stm32key_help_text[] = ++ "read []: Read the hash stored at addr in memory or in OTP\n" ++ "stm32key fuse [-y] : Fuse hash stored at addr in OTP\n" ++ "stm32key close [-y] : Close the device, the hash stored in OTP\n"; ++ ++U_BOOT_CMD_WITH_SUBCMDS(stm32key, "Fuse ST Hash key", stm32key_help_text, ++ U_BOOT_SUBCMD_MKENT(read, 2, 0, do_stm32key_read), ++ U_BOOT_SUBCMD_MKENT(fuse, 3, 0, do_stm32key_fuse), ++ U_BOOT_SUBCMD_MKENT(close, 2, 0, do_stm32key_close)); +diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +index a20980a6ae..b2a17314ee 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); +@@ -167,12 +177,12 @@ cleanup: + } + + U_BOOT_CMD(stm32prog, 5, 0, do_stm32prog, ++ "start communication with tools STM32Cubeprogrammer", + " [] []\n" +- "start communication with tools STM32Cubeprogrammer on with Flashlayout at ", +- " = serial|usb\n" +- " = device instance\n" +- " = address of flashlayout\n" +- " = size of flashlayout\n" ++ " = serial|usb\n" ++ " = device instance\n" ++ " = address of flashlayout\n" ++ " = size of flashlayout (optional for image with STM32 header)\n" + ); + + #ifdef CONFIG_STM32MP15x_STM32IMAGE +diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +index 7cd31462ba..62b386582d 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c ++++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +@@ -1153,7 +1153,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 +@@ -1199,13 +1202,13 @@ static int dfu_init_entities(struct stm32prog_data *data) + } + + if (!ret) +- ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, 512); ++ ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, CMD_SIZE); + + if (!ret) +- ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, 512); ++ ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, OTP_SIZE); + + if (!ret && CONFIG_IS_ENABLED(DM_PMIC)) +- ret = stm32prog_alt_add_virt(dfu, "PMIC", PHASE_PMIC, 8); ++ ret = stm32prog_alt_add_virt(dfu, "PMIC", PHASE_PMIC, PMIC_SIZE); + + if (ret) + stm32prog_err("dfu init failed: %d", ret); +@@ -1476,7 +1479,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)) +@@ -1492,6 +1495,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) && +@@ -1750,7 +1757,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 */ + } + } +@@ -1759,7 +1766,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); + } + } +@@ -1779,3 +1786,17 @@ void dfu_initiated_callback(struct dfu_entity *dfu) + pr_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 eebc4d2e71..f4243ae2ec 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h ++++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +@@ -19,6 +19,7 @@ + + #define DEFAULT_ADDRESS 0xFFFFFFFF + ++#define CMD_SIZE 512 + #define OTP_SIZE 1024 + #define PMIC_SIZE 8 + +@@ -144,6 +145,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 a0bf7e1884..3d32adcf62 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 + #include + #include ++#include + #include + #include + #include +@@ -18,8 +19,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 -----------------------------*/ +@@ -435,10 +435,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); + } + +diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +index 30547f94c9..6ddf08523e 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c ++++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +@@ -178,7 +178,7 @@ int stm32prog_get_medium_size_virt(struct dfu_entity *dfu, u64 *size) + + switch (dfu->data.virt.dev_num) { + case PHASE_CMD: +- *size = 512; ++ *size = CMD_SIZE; + break; + case PHASE_OTP: + *size = OTP_SIZE; +@@ -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/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c +index b81825a0bf..2495d4aaad 100644 +--- a/arch/arm/mach-stm32mp/cpu.c ++++ b/arch/arm/mach-stm32mp/cpu.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -86,6 +87,8 @@ + */ + u8 early_tlb[PGTABLE_SIZE] __section(".data") __aligned(0x4000); + ++struct lmb lmb; ++ + #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) + #ifndef CONFIG_TFABOOT + static void security_init(void) +@@ -207,6 +210,44 @@ u32 get_bootmode(void) + TAMP_BOOT_MODE_SHIFT; + } + ++/* ++ * weak function overidde: set the DDR/SYSRAM executable before to enable the ++ * MMU and configure DACR, for early early_enable_caches (SPL or pre-reloc) ++ */ ++void dram_bank_mmu_setup(int bank) ++{ ++ struct bd_info *bd = gd->bd; ++ int i; ++ phys_addr_t start; ++ phys_size_t size; ++ bool use_lmb = false; ++ enum dcache_option option; ++ ++ if (IS_ENABLED(CONFIG_SPL_BUILD)) { ++#ifdef CONFIG_SPL ++ start = ALIGN_DOWN(STM32_SYSRAM_BASE, MMU_SECTION_SIZE); ++ size = ALIGN(STM32_SYSRAM_SIZE, MMU_SECTION_SIZE); ++#endif ++ } else if (gd->flags & GD_FLG_RELOC) { ++ /* bd->bi_dram is available only after relocation */ ++ start = bd->bi_dram[bank].start; ++ size = bd->bi_dram[bank].size; ++ use_lmb = true; ++ } else { ++ /* mark cacheable and executable the beggining of the DDR */ ++ start = STM32_DDR_BASE; ++ size = CONFIG_DDR_CACHEABLE_SIZE; ++ } ++ ++ for (i = start >> MMU_SECTION_SHIFT; ++ i < (start >> MMU_SECTION_SHIFT) + (size >> MMU_SECTION_SHIFT); ++ i++) { ++ option = DCACHE_DEFAULT_OPTION; ++ if (use_lmb && lmb_is_reserved_flags(&lmb, i << MMU_SECTION_SHIFT, LMB_NOMAP)) ++ option = INVALID_ENTRY; ++ set_section_dcache(i, option); ++ } ++} + /* + * initialize the MMU and activate cache in SPL or in U-Boot pre-reloc stage + * MMU/TLB is updated in enable_caches() for U-Boot after relocation +@@ -224,17 +265,8 @@ static void early_enable_caches(void) + gd->arch.tlb_addr = (unsigned long)&early_tlb; + #endif + ++ /* enable MMU (default configuration) */ + dcache_enable(); +- +- if (IS_ENABLED(CONFIG_SPL_BUILD)) +- mmu_set_region_dcache_behaviour( +- ALIGN_DOWN(STM32_SYSRAM_BASE, MMU_SECTION_SIZE), +- ALIGN(STM32_SYSRAM_SIZE, MMU_SECTION_SIZE), +- DCACHE_DEFAULT_OPTION); +- else +- mmu_set_region_dcache_behaviour(STM32_DDR_BASE, +- CONFIG_DDR_CACHEABLE_SIZE, +- DCACHE_DEFAULT_OPTION); + } + + /* +@@ -278,6 +310,9 @@ int arch_cpu_init(void) + + void enable_caches(void) + { ++ /* parse device tree when data cache is still activated */ ++ lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); ++ + /* I-cache is already enabled in start.S: icache_enable() not needed */ + + /* deactivate the data cache, early enabled in arch_cpu_init() */ +@@ -479,7 +514,7 @@ static void setup_boot_mode(void) + gd->flags &= ~(GD_FLG_SILENT | + GD_FLG_DISABLE_CONSOLE); + printf("uart%d = %s not found in device tree!\n", +- instance, cmd); ++ instance + 1, cmd); + break; + } + sprintf(cmd, "%d", dev->seq); +@@ -517,7 +552,9 @@ static void setup_boot_mode(void) + env_set("boot_instance", "0"); + break; + default: +- pr_debug("unexpected boot mode = %x\n", boot_mode); ++ env_set("boot_device", "invalid"); ++ env_set("boot_instance", ""); ++ log_err("unexpected boot mode = %x\n", boot_mode); + break; + } + +diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c +index 0e8ce63f4a..2c409ee217 100644 +--- a/arch/arm/mach-stm32mp/dram_init.c ++++ b/arch/arm/mach-stm32mp/dram_init.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + DECLARE_GLOBAL_DATA_PTR; + +@@ -38,17 +39,27 @@ int dram_init(void) + + ulong board_get_usable_ram_top(ulong total_size) + { ++ phys_size_t size; + phys_addr_t reg; + struct lmb lmb; + ++ if (!total_size) ++ return gd->ram_top; ++ + /* found enough not-reserved memory to relocated U-Boot */ + lmb_init(&lmb); + lmb_add(&lmb, gd->ram_base, gd->ram_size); + boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); +- reg = lmb_alloc(&lmb, CONFIG_SYS_MALLOC_LEN + total_size, SZ_4K); ++ /* add 8M for reserved memory for display, fdt, gd,... */ ++ size = ALIGN(SZ_8M + CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE), ++ reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE); ++ ++ if (!reg) ++ reg = gd->ram_top - size; + +- if (reg) +- return ALIGN(reg + CONFIG_SYS_MALLOC_LEN + total_size, SZ_4K); ++ /* before relocation, mark the U-Boot memory as cacheable by default */ ++ if (!(gd->flags & GD_FLG_RELOC)) ++ mmu_set_region_dcache_behaviour(reg, size, DCACHE_DEFAULT_OPTION); + +- return gd->ram_top; ++ return reg + size; + } +diff --git a/arch/arm/mach-stm32mp/syscon.c b/arch/arm/mach-stm32mp/syscon.c +index 3e61ce4097..a0e8e1dfdc 100644 +--- a/arch/arm/mach-stm32mp/syscon.c ++++ b/arch/arm/mach-stm32mp/syscon.c +@@ -4,6 +4,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -14,9 +15,22 @@ static const struct udevice_id stm32mp_syscon_ids[] = { + { } + }; + ++static int stm32mp_syscon_probe(struct udevice *dev) ++{ ++ struct clk_bulk clk_bulk; ++ int ret; ++ ++ ret = clk_get_bulk(dev, &clk_bulk); ++ if (!ret) ++ clk_enable_bulk(&clk_bulk); ++ ++ return 0; ++} ++ + U_BOOT_DRIVER(syscon_stm32mp) = { + .name = "stmp32mp_syscon", + .id = UCLASS_SYSCON, + .of_match = stm32mp_syscon_ids, + .bind = dm_scan_fdt_dev, ++ .probe = stm32mp_syscon_probe, + }; +-- +2.25.1 + diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0008-ARM-v2020.10-stm32mp-r2-BOARD.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0008-ARM-v2020.10-stm32mp-r2-BOARD.patch new file mode 100644 index 0000000..b491b92 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0008-ARM-v2020.10-stm32mp-r2-BOARD.patch @@ -0,0 +1,117 @@ +From ad6a40bb66269882f124e9c2b6b106cca3fb8abc Mon Sep 17 00:00:00 2001 +From: Lionel Vitte +Date: Mon, 18 Oct 2021 17:10:51 +0200 +Subject: [PATCH 08/11] ARM v2020.10-stm32mp-r2 BOARD + +--- + board/dhelectronics/dh_stm32mp1/board.c | 7 ++----- + board/raspberrypi/rpi/rpi.c | 2 +- + board/st/stm32mp1/stm32mp1.c | 13 ++++++++----- + 3 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c +index c9abe3cc6d..77f2730a3f 100644 +--- a/board/dhelectronics/dh_stm32mp1/board.c ++++ b/board/dhelectronics/dh_stm32mp1/board.c +@@ -551,9 +551,6 @@ int board_init(void) + /* address of boot parameters */ + gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100; + +- if (CONFIG_IS_ENABLED(DM_GPIO_HOG)) +- gpio_hog_probe_all(); +- + board_key_check(); + + #ifdef CONFIG_DM_REGULATOR +@@ -618,11 +615,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/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c +index 6b1fa5fc14..f25b2aa219 100644 +--- a/board/raspberrypi/rpi/rpi.c ++++ b/board/raspberrypi/rpi/rpi.c +@@ -485,7 +485,7 @@ int ft_board_setup(void *blob, struct bd_info *bd) + * should be more intelligent, and e.g. only do this if no enabled DT + * node exists for the "real" graphics driver. + */ +- lcd_dt_simplefb_add_node(blob); ++ fdt_simplefb_add_node(blob); + + #ifdef CONFIG_EFI_LOADER + /* Reserve the spin table */ +diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c +index 9a02e14ba5..42979d80f5 100644 +--- a/board/st/stm32mp1/stm32mp1.c ++++ b/board/st/stm32mp1/stm32mp1.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -155,6 +156,7 @@ static void board_key_check(void) + debug("%s: could not find a /config/st,fastboot-gpios\n", + __func__); + } else { ++ udelay(20); + if (dm_gpio_get_value(&gpio)) { + puts("Fastboot key pressed, "); + boot_mode = BOOT_FASTBOOT; +@@ -169,6 +171,7 @@ static void board_key_check(void) + debug("%s: could not find a /config/st,stm32prog-gpios\n", + __func__); + } else { ++ udelay(20); + if (dm_gpio_get_value(&gpio)) { + puts("STM32Programmer key pressed, "); + boot_mode = BOOT_STM32PROG; +@@ -649,9 +652,6 @@ int board_init(void) + /* address of boot parameters */ + gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100; + +- if (CONFIG_IS_ENABLED(DM_GPIO_HOG)) +- gpio_hog_probe_all(); +- + board_key_check(); + + if (board_is_ev1()) +@@ -739,11 +739,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); + +@@ -886,6 +886,9 @@ int ft_board_setup(void *blob, struct bd_info *bd) + if (IS_ENABLED(CONFIG_FDT_FIXUP_PARTITIONS)) + fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); + ++ if (CONFIG_IS_ENABLED(FDT_SIMPLEFB)) ++ fdt_simplefb_add_node_and_mem_rsv(blob); ++ + return 0; + } + #endif +-- +2.25.1 + diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0009-ARM-v2020.10-stm32mp-r2-MISC-DRIVERS.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0009-ARM-v2020.10-stm32mp-r2-MISC-DRIVERS.patch new file mode 100644 index 0000000..d8f5f27 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0009-ARM-v2020.10-stm32mp-r2-MISC-DRIVERS.patch @@ -0,0 +1,2957 @@ +From 0aacafd68c7d68c67f70cc5a9e37c5034d1076d9 Mon Sep 17 00:00:00 2001 +From: Lionel Vitte +Date: Mon, 18 Oct 2021 17:12:24 +0200 +Subject: [PATCH 09/11] ARM v2020.10-stm32mp-r2 MISC-DRIVERS + +--- + cmd/pxe_utils.c | 103 +++++++++++ + cmd/pxe_utils.h | 1 + + common/Kconfig | 9 + + common/Makefile | 2 +- + common/fdt_simplefb.c | 144 +++++++++++++++ + common/lcd_simplefb.c | 90 --------- + doc/README.pxe | 9 + + drivers/adc/stm32-adc.c | 136 ++++++++++++-- + drivers/clk/clk_stm32mp1.c | 14 ++ + drivers/dfu/dfu.c | 12 ++ + drivers/firmware/scmi/smt.c | 6 +- + drivers/i2c/stm32f7_i2c.c | 92 ++++++---- + drivers/led/led_gpio.c | 7 +- + drivers/net/Kconfig | 1 + + drivers/net/dwc_eth_qos.c | 152 +++------------- + drivers/net/eth-phy-uclass.c | 78 +++++++- + drivers/phy/phy-stm32-usbphyc.c | 212 ++++++++++++++++++++-- + drivers/ram/stm32mp1/stm32mp1_ddr.c | 8 +- + drivers/ram/stm32mp1/stm32mp1_ddr_regs.h | 1 + + drivers/remoteproc/rproc-optee.c | 22 ++- + drivers/remoteproc/stm32_copro.c | 213 ++++++++-------------- + drivers/spi/stm32_qspi.c | 29 +-- + drivers/spi/stm32_spi.c | 222 +++++++++++++---------- + drivers/video/video-uclass.c | 14 ++ + include/configs/rpi.h | 1 - + include/configs/stm32mp1.h | 1 + + include/dfu.h | 11 ++ + include/fdt_simplefb.h | 5 +- + include/video.h | 7 + + scripts/config_whitelist.txt | 1 - + 30 files changed, 1034 insertions(+), 569 deletions(-) + create mode 100644 common/fdt_simplefb.c + delete mode 100644 common/lcd_simplefb.c + +diff --git a/cmd/pxe_utils.c b/cmd/pxe_utils.c +index 8716e782f6..25367190a7 100644 +--- a/cmd/pxe_utils.c ++++ b/cmd/pxe_utils.c +@@ -13,6 +13,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -284,6 +286,9 @@ static void label_destroy(struct pxe_label *label) + if (label->fdtdir) + free(label->fdtdir); + ++ if (label->fdtoverlays) ++ free(label->fdtoverlays); ++ + free(label); + } + +@@ -331,6 +336,92 @@ static int label_localboot(struct pxe_label *label) + return run_command_list(localcmd, strlen(localcmd), 0); + } + ++/* ++ * Loads fdt overlays specified in 'fdtoverlays'. ++ */ ++#ifdef CONFIG_OF_LIBFDT_OVERLAY ++static void label_boot_fdtoverlay(struct cmd_tbl *cmdtp, struct pxe_label *label) ++{ ++ char *fdtoverlay = label->fdtoverlays; ++ struct fdt_header *working_fdt; ++ char *fdtoverlay_addr_env; ++ ulong fdtoverlay_addr; ++ ulong fdt_addr; ++ int err; ++ ++ /* Get the main fdt and map it */ ++ fdt_addr = simple_strtoul(env_get("fdt_addr_r"), NULL, 16); ++ working_fdt = map_sysmem(fdt_addr, 0); ++ err = fdt_check_header(working_fdt); ++ if (err) ++ return; ++ ++ /* Get the specific overlay loading address */ ++ fdtoverlay_addr_env = env_get("fdtoverlay_addr_r"); ++ if (!fdtoverlay_addr_env) { ++ printf("Invalid fdtoverlay_addr_r for loading overlays\n"); ++ return; ++ } ++ ++ fdtoverlay_addr = simple_strtoul(fdtoverlay_addr_env, NULL, 16); ++ ++ /* Cycle over the overlay files and apply them in order */ ++ do { ++ struct fdt_header *blob; ++ char *overlayfile; ++ char *end; ++ int len; ++ ++ /* Drop leading spaces */ ++ while (*fdtoverlay == ' ') ++ ++fdtoverlay; ++ ++ /* Copy a single filename if multiple provided */ ++ end = strstr(fdtoverlay, " "); ++ if (end) { ++ len = (int)(end - fdtoverlay); ++ overlayfile = malloc(len + 1); ++ strncpy(overlayfile, fdtoverlay, len); ++ overlayfile[len] = '\0'; ++ } else ++ overlayfile = fdtoverlay; ++ ++ if (!strlen(overlayfile)) ++ goto skip_overlay; ++ ++ /* Load overlay file */ ++ err = get_relfile_envaddr(cmdtp, overlayfile, ++ "fdtoverlay_addr_r"); ++ if (err < 0) { ++ printf("Failed loading overlay %s\n", overlayfile); ++ goto skip_overlay; ++ } ++ ++ /* Resize main fdt */ ++ fdt_shrink_to_minimum(working_fdt, 8192); ++ ++ blob = map_sysmem(fdtoverlay_addr, 0); ++ err = fdt_check_header(blob); ++ if (err) { ++ printf("Invalid overlay %s, skipping\n", ++ overlayfile); ++ goto skip_overlay; ++ } ++ ++ err = fdt_overlay_apply_verbose(working_fdt, blob); ++ if (err) { ++ printf("Failed to apply overlay %s, skipping\n", ++ overlayfile); ++ goto skip_overlay; ++ } ++ ++skip_overlay: ++ if (end) ++ free(overlayfile); ++ } while ((fdtoverlay = strstr(fdtoverlay, " "))); ++} ++#endif ++ + /* + * Boot according to the contents of a pxe_label. + * +@@ -525,6 +616,11 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label) + label->name); + goto cleanup; + } ++ ++#ifdef CONFIG_OF_LIBFDT_OVERLAY ++ if (label->fdtoverlays) ++ label_boot_fdtoverlay(cmdtp, label); ++#endif + } else { + bootm_argv[3] = NULL; + } +@@ -582,6 +678,7 @@ enum token_type { + T_INCLUDE, + T_FDT, + T_FDTDIR, ++ T_FDTOVERLAYS, + T_ONTIMEOUT, + T_IPAPPEND, + T_BACKGROUND, +@@ -616,6 +713,7 @@ static const struct token keywords[] = { + {"fdt", T_FDT}, + {"devicetreedir", T_FDTDIR}, + {"fdtdir", T_FDTDIR}, ++ {"fdtoverlays", T_FDTOVERLAYS}, + {"ontimeout", T_ONTIMEOUT,}, + {"ipappend", T_IPAPPEND,}, + {"background", T_BACKGROUND,}, +@@ -1048,6 +1146,11 @@ static int parse_label(char **c, struct pxe_menu *cfg) + err = parse_sliteral(c, &label->fdtdir); + break; + ++ case T_FDTOVERLAYS: ++ if (!label->fdtoverlays) ++ err = parse_sliteral(c, &label->fdtoverlays); ++ break; ++ + case T_LOCALBOOT: + label->localboot = 1; + err = parse_integer(c, &label->localboot_val); +diff --git a/cmd/pxe_utils.h b/cmd/pxe_utils.h +index 77d2588875..6af9523734 100644 +--- a/cmd/pxe_utils.h ++++ b/cmd/pxe_utils.h +@@ -43,6 +43,7 @@ struct pxe_label { + char *initrd; + char *fdt; + char *fdtdir; ++ char *fdtoverlays; + int ipappend; + int attempted; + int localboot; +diff --git a/common/Kconfig b/common/Kconfig +index 7099bbf902..f1dd16bd2d 100644 +--- a/common/Kconfig ++++ b/common/Kconfig +@@ -1146,3 +1146,12 @@ config SPL_IMAGE_SIGN_INFO + Enable image_sign_info helper functions in SPL. + + endif ++ ++config FDT_SIMPLEFB ++ bool "FDT tools for simplefb support" ++ depends on OF_LIBFDT ++ help ++ Enable the fdt tools to manage the simple fb nodes in device tree. ++ These functions can be used by board to indicate to the OS ++ the presence of the simple frame buffer with associated reserved ++ memory +\ No newline at end of file +diff --git a/common/Makefile b/common/Makefile +index 2e7a090588..39d65b941b 100644 +--- a/common/Makefile ++++ b/common/Makefile +@@ -28,6 +28,7 @@ obj-$(CONFIG_CMD_BOOTZ) += bootm.o bootm_os.o + obj-$(CONFIG_CMD_BOOTI) += bootm.o bootm_os.o + + obj-$(CONFIG_CMD_BEDBUG) += bedbug.o ++obj-$(CONFIG_FDT_SIMPLEFB) += fdt_simplefb.o + obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o + obj-$(CONFIG_MII) += miiphyutil.o + obj-$(CONFIG_CMD_MII) += miiphyutil.o +@@ -50,7 +51,6 @@ ifndef CONFIG_DM_VIDEO + obj-$(CONFIG_LCD) += lcd.o lcd_console.o + endif + obj-$(CONFIG_LCD_ROTATION) += lcd_console_rotation.o +-obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o + obj-$(CONFIG_LYNXKDI) += lynxkdi.o + obj-$(CONFIG_MENU) += menu.o + obj-$(CONFIG_UPDATE_TFTP) += update.o +diff --git a/common/fdt_simplefb.c b/common/fdt_simplefb.c +new file mode 100644 +index 0000000000..06a02bfde5 +--- /dev/null ++++ b/common/fdt_simplefb.c +@@ -0,0 +1,144 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Simplefb device tree support ++ * ++ * (C) Copyright 2015 ++ * Stephen Warren ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++static int fdt_simplefb_configure_node(void *blob, int off) ++{ ++ int xsize, ysize; ++ int bpix; /* log2 of bits per pixel */ ++ const char *name; ++ ulong fb_base; ++#ifdef CONFIG_DM_VIDEO ++ struct video_uc_platdata *plat; ++ struct video_priv *uc_priv; ++ struct udevice *dev; ++ int ret; ++ ++ ret = uclass_first_device_err(UCLASS_VIDEO, &dev); ++ if (ret) ++ return ret; ++ uc_priv = dev_get_uclass_priv(dev); ++ plat = dev_get_uclass_platdata(dev); ++ xsize = uc_priv->xsize; ++ ysize = uc_priv->ysize; ++ bpix = uc_priv->bpix; ++ fb_base = plat->base; ++#else ++ xsize = lcd_get_pixel_width(); ++ ysize = lcd_get_pixel_height(); ++ bpix = LCD_BPP; ++ fb_base = gd->fb_base; ++#endif ++ switch (bpix) { ++ case 4: /* VIDEO_BPP16 */ ++ name = "r5g6b5"; ++ break; ++ case 5: /* VIDEO_BPP32 */ ++ name = "a8r8g8b8"; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return fdt_setup_simplefb_node(blob, off, fb_base, xsize, ysize, ++ xsize * (1 << bpix) / 8, name); ++} ++ ++int fdt_simplefb_add_node(void *blob) ++{ ++ static const char compat[] = "simple-framebuffer"; ++ static const char disabled[] = "disabled"; ++ int off, ret; ++ int na, ns, len; ++ fdt32_t value; ++ const fdt32_t *c; ++ ++ /* find or create "/chosen" node. */ ++ off = fdt_find_or_add_subnode(blob, 0, "chosen"); ++ if (off < 0) ++ return off; ++ ++ /* inherit #address-cells and #size-cells from the root node */ ++ c = fdt_getprop(blob, off, "#address-cells", &len); ++ if (!c && len == -FDT_ERR_NOTFOUND) { ++ na = fdt_address_cells(blob, 0); ++ value = cpu_to_fdt32(na); ++ ret = fdt_setprop(blob, off, "#address-cells", &value, sizeof(value)); ++ if (ret < 0) ++ return ret; ++ } ++ ++ c = fdt_getprop(blob, off, "#size-cells", &len); ++ if (!c && len == -FDT_ERR_NOTFOUND) { ++ ns = fdt_size_cells(blob, 0); ++ value = cpu_to_fdt32(ns); ++ ret = fdt_setprop(blob, off, "#size-cells", &value, sizeof(value)); ++ if (ret < 0) ++ return ret; ++ } ++ ++ /* add empty "ranges" property to indicate 1:1 translation */ ++ ret = fdt_setprop_empty(blob, off, "ranges"); ++ if (ret < 0) ++ return ret; ++ ++ off = fdt_add_subnode(blob, off, "framebuffer"); ++ if (off < 0) ++ return -1; ++ ++ ret = fdt_setprop(blob, off, "status", disabled, sizeof(disabled)); ++ if (ret < 0) ++ return -1; ++ ++ ret = fdt_setprop(blob, off, "compatible", compat, sizeof(compat)); ++ if (ret < 0) ++ return -1; ++ ++ return fdt_simplefb_configure_node(blob, off); ++} ++ ++#if CONFIG_IS_ENABLED(DM_VIDEO) ++int fdt_simplefb_add_node_and_mem_rsv(void *blob) ++{ ++ struct fdt_memory mem; ++ int ret; ++ ++ /* nothing to do when no the frame buffer or video is not active */ ++ if (gd->video_bottom == gd->video_top || !video_is_active()) ++ return 0; ++ ++ ret = fdt_simplefb_add_node(blob); ++ if (ret) ++ return ret; ++ ++ /* reserved with no-map tag the video buffer */ ++ mem.start = gd->video_bottom; ++ mem.end = gd->video_top - 1; ++ ++ return fdtdec_add_reserved_memory(blob, "framebuffer", &mem, NULL, true); ++} ++#endif ++ ++int fdt_simplefb_enable_existing_node(void *blob) ++{ ++ int off; ++ ++ off = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer"); ++ if (off < 0) ++ return -1; ++ ++ return fdt_simplefb_configure_node(blob, off); ++} +diff --git a/common/lcd_simplefb.c b/common/lcd_simplefb.c +deleted file mode 100644 +index fca600691e..0000000000 +--- a/common/lcd_simplefb.c ++++ /dev/null +@@ -1,90 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ +-/* +- * Simplefb device tree support +- * +- * (C) Copyright 2015 +- * Stephen Warren +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-DECLARE_GLOBAL_DATA_PTR; +- +-static int lcd_dt_simplefb_configure_node(void *blob, int off) +-{ +- int xsize, ysize; +- int bpix; /* log2 of bits per pixel */ +- const char *name; +- ulong fb_base; +-#ifdef CONFIG_DM_VIDEO +- struct video_uc_platdata *plat; +- struct video_priv *uc_priv; +- struct udevice *dev; +- int ret; +- +- ret = uclass_first_device_err(UCLASS_VIDEO, &dev); +- if (ret) +- return ret; +- uc_priv = dev_get_uclass_priv(dev); +- plat = dev_get_uclass_platdata(dev); +- xsize = uc_priv->xsize; +- ysize = uc_priv->ysize; +- bpix = uc_priv->bpix; +- fb_base = plat->base; +-#else +- xsize = lcd_get_pixel_width(); +- ysize = lcd_get_pixel_height(); +- bpix = LCD_BPP; +- fb_base = gd->fb_base; +-#endif +- switch (bpix) { +- case 4: /* VIDEO_BPP16 */ +- name = "r5g6b5"; +- break; +- case 5: /* VIDEO_BPP32 */ +- name = "a8r8g8b8"; +- break; +- default: +- return -EINVAL; +- } +- +- return fdt_setup_simplefb_node(blob, off, fb_base, xsize, ysize, +- xsize * (1 << bpix) / 8, name); +-} +- +-int lcd_dt_simplefb_add_node(void *blob) +-{ +- static const char compat[] = "simple-framebuffer"; +- static const char disabled[] = "disabled"; +- int off, ret; +- +- off = fdt_add_subnode(blob, 0, "framebuffer"); +- if (off < 0) +- return -1; +- +- ret = fdt_setprop(blob, off, "status", disabled, sizeof(disabled)); +- if (ret < 0) +- return -1; +- +- ret = fdt_setprop(blob, off, "compatible", compat, sizeof(compat)); +- if (ret < 0) +- return -1; +- +- return lcd_dt_simplefb_configure_node(blob, off); +-} +- +-int lcd_dt_simplefb_enable_existing_node(void *blob) +-{ +- int off; +- +- off = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer"); +- if (off < 0) +- return -1; +- +- return lcd_dt_simplefb_configure_node(blob, off); +-} +diff --git a/doc/README.pxe b/doc/README.pxe +index 42f913c61f..b67151ca51 100644 +--- a/doc/README.pxe ++++ b/doc/README.pxe +@@ -89,6 +89,9 @@ pxe boot + fdt_addr - the location of a fdt blob. 'fdt_addr' will be passed to bootm + command if it is set and 'fdt_addr_r' is not passed to bootm command. + ++ fdtoverlay_addr_r - location in RAM at which 'pxe boot' will temporarily store ++ fdt overlay(s) before applying them to the fdt blob stored at 'fdt_addr_r'. ++ + pxe file format + =============== + The pxe file format is nearly a subset of the PXELINUX file format; see +@@ -148,6 +151,12 @@ kernel - if this label is chosen, use tftp to retrieve the kernel + It useful for overlay selection in pxe file + (see: doc/uImage.FIT/overlay-fdt-boot.txt) + ++fdtoverlays [...] - if this label is chosen, use tftp to retrieve the DT ++ overlay(s) at . it will be temporarily stored at the ++ address indicated in the fdtoverlay_addr_r environment variable, ++ and then applied in the load order to the fdt blob stored at the ++ address indicated in the fdt_addr_r environment variable. ++ + append - use as the kernel command line when booting this + label. + +diff --git a/drivers/adc/stm32-adc.c b/drivers/adc/stm32-adc.c +index 3f0ed48846..c007209657 100644 +--- a/drivers/adc/stm32-adc.c ++++ b/drivers/adc/stm32-adc.c +@@ -33,8 +33,11 @@ + #define STM32H7_ADRDY BIT(0) + + /* STM32H7_ADC_CR - bit fields */ ++#define STM32H7_ADCAL BIT(31) ++#define STM32H7_ADCALDIF BIT(30) + #define STM32H7_DEEPPWD BIT(29) + #define STM32H7_ADVREGEN BIT(28) ++#define STM32H7_ADCALLIN BIT(16) + #define STM32H7_BOOST BIT(8) + #define STM32H7_ADSTART BIT(2) + #define STM32H7_ADDIS BIT(1) +@@ -65,47 +68,72 @@ struct stm32_adc { + const struct stm32_adc_cfg *cfg; + }; + +-static int stm32_adc_stop(struct udevice *dev) ++static void stm32_adc_enter_pwr_down(struct udevice *dev) + { + struct stm32_adc *adc = dev_get_priv(dev); + +- setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADDIS); + clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_BOOST); + /* Setting DEEPPWD disables ADC vreg and clears ADVREGEN */ + setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_DEEPPWD); +- adc->active_channel = -1; +- +- return 0; + } + +-static int stm32_adc_start_channel(struct udevice *dev, int channel) ++static int stm32_adc_exit_pwr_down(struct udevice *dev) + { +- struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); +- struct stm32_adc_common *common = dev_get_priv(dev_get_parent(dev)); + struct stm32_adc *adc = dev_get_priv(dev); ++ struct stm32_adc_common *common = dev_get_priv(dev_get_parent(dev)); + int ret; + u32 val; + ++ /* return immediately if ADC is not in deep power down mode */ ++ if (!(readl(adc->regs + STM32H7_ADC_CR) & STM32H7_DEEPPWD)) ++ return 0; ++ + /* Exit deep power down, then enable ADC voltage regulator */ + clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_DEEPPWD); + setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADVREGEN); ++ + if (common->rate > STM32H7_BOOST_CLKRATE) + setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_BOOST); + + /* Wait for startup time */ + if (!adc->cfg->has_vregready) { + udelay(20); +- } else { +- ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val, +- val & STM32MP1_VREGREADY, +- STM32_ADC_TIMEOUT_US); +- if (ret < 0) { +- stm32_adc_stop(dev); +- dev_err(dev, "Failed to enable vreg: %d\n", ret); +- return ret; +- } ++ return 0; + } + ++ ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val, ++ val & STM32MP1_VREGREADY, ++ STM32_ADC_TIMEOUT_US); ++ if (ret < 0) { ++ stm32_adc_enter_pwr_down(dev); ++ dev_err(dev, "Failed to enable vreg: %d\n", ret); ++ } ++ ++ return ret; ++} ++ ++static int stm32_adc_stop(struct udevice *dev) ++{ ++ struct stm32_adc *adc = dev_get_priv(dev); ++ ++ setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADDIS); ++ stm32_adc_enter_pwr_down(dev); ++ adc->active_channel = -1; ++ ++ return 0; ++} ++ ++static int stm32_adc_start_channel(struct udevice *dev, int channel) ++{ ++ struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); ++ struct stm32_adc *adc = dev_get_priv(dev); ++ int ret; ++ u32 val; ++ ++ ret = stm32_adc_exit_pwr_down(dev); ++ if (ret < 0) ++ return ret; ++ + /* Only use single ended channels */ + writel(0, adc->regs + STM32H7_ADC_DIFSEL); + +@@ -162,6 +190,64 @@ static int stm32_adc_channel_data(struct udevice *dev, int channel, + return 0; + } + ++/** ++ * Fixed timeout value for ADC calibration. ++ * worst cases: ++ * - low clock frequency (0.12 MHz min) ++ * - maximum prescalers ++ * Calibration requires: ++ * - 16384 ADC clock cycle for the linear calibration ++ * - 20 ADC clock cycle for the offset calibration ++ * ++ * Set to 100ms for now ++ */ ++#define STM32H7_ADC_CALIB_TIMEOUT_US 100000 ++ ++static int stm32_adc_selfcalib(struct udevice *dev) ++{ ++ struct stm32_adc *adc = dev_get_priv(dev); ++ int ret; ++ u32 val; ++ ++ /* ++ * Select calibration mode: ++ * - Offset calibration for single ended inputs ++ * - No linearity calibration. Done in next step. ++ */ ++ clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADCALDIF | STM32H7_ADCALLIN); ++ ++ /* Start calibration, then wait for completion */ ++ setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADCAL); ++ ret = readl_poll_sleep_timeout(adc->regs + STM32H7_ADC_CR, val, ++ !(val & STM32H7_ADCAL), 100, ++ STM32H7_ADC_CALIB_TIMEOUT_US); ++ if (ret) { ++ dev_err(dev, "calibration failed\n"); ++ goto out; ++ } ++ ++ /* ++ * Select calibration mode, then start calibration: ++ * - Offset calibration for differential input ++ * - Linearity calibration (needs to be done only once for single/diff) ++ * will run simultaneously with offset calibration. ++ */ ++ setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADCALDIF | STM32H7_ADCALLIN); ++ ++ /* Start calibration, then wait for completion */ ++ setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADCAL); ++ ret = readl_poll_sleep_timeout(adc->regs + STM32H7_ADC_CR, val, ++ !(val & STM32H7_ADCAL), 100, ++ STM32H7_ADC_CALIB_TIMEOUT_US); ++ if (ret) ++ dev_err(dev, "calibration failed\n"); ++ ++out: ++ clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADCALDIF | STM32H7_ADCALLIN); ++ ++ return ret; ++} ++ + static int stm32_adc_chan_of_init(struct udevice *dev) + { + struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); +@@ -209,7 +295,7 @@ static int stm32_adc_probe(struct udevice *dev) + struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); + struct stm32_adc_common *common = dev_get_priv(dev_get_parent(dev)); + struct stm32_adc *adc = dev_get_priv(dev); +- int offset; ++ int offset, ret; + + offset = dev_read_u32_default(dev, "reg", -ENODATA); + if (offset < 0) { +@@ -224,7 +310,19 @@ static int stm32_adc_probe(struct udevice *dev) + uc_pdata->vdd_microvolts = common->vref_uv; + uc_pdata->vss_microvolts = 0; + +- return stm32_adc_chan_of_init(dev); ++ ret = stm32_adc_chan_of_init(dev); ++ if (ret < 0) ++ return ret; ++ ++ ret = stm32_adc_exit_pwr_down(dev); ++ if (ret < 0) ++ return ret; ++ ++ ret = stm32_adc_selfcalib(dev); ++ if (ret) ++ stm32_adc_enter_pwr_down(dev); ++ ++ return ret; + } + + static const struct adc_ops stm32_adc_ops = { +diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c +index efa402da52..a4cfef1e3d 100644 +--- a/drivers/clk/clk_stm32mp1.c ++++ b/drivers/clk/clk_stm32mp1.c +@@ -69,6 +69,7 @@ DECLARE_GLOBAL_DATA_PTR; + #define RCC_PLL2FRACR 0xA0 + #define RCC_PLL2CSGR 0xA4 + #define RCC_I2C46CKSELR 0xC0 ++#define RCC_SPI6CKSELR 0xC4 + #define RCC_CPERCKSELR 0xD0 + #define RCC_STGENCKSELR 0xD4 + #define RCC_DDRITFCR 0xD8 +@@ -99,6 +100,7 @@ DECLARE_GLOBAL_DATA_PTR; + #define RCC_I2C12CKSELR 0x8C0 + #define RCC_I2C35CKSELR 0x8C4 + #define RCC_SPI2S1CKSELR 0x8D8 ++#define RCC_SPI2S23CKSELR 0x8DC + #define RCC_SPI45CKSELR 0x8E0 + #define RCC_UART6CKSELR 0x8E4 + #define RCC_UART24CKSELR 0x8E8 +@@ -309,7 +311,9 @@ enum stm32mp1_parent_sel { + _DSI_SEL, + _ADC12_SEL, + _SPI1_SEL, ++ _SPI23_SEL, + _SPI45_SEL, ++ _SPI6_SEL, + _RTC_SEL, + _PARENT_SEL_NB, + _UNKNOWN_SEL = 0xff, +@@ -520,6 +524,8 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { + STM32MP1_CLK(RCC_DDRITFCR, 9, DDRPHYCAPB, _UNKNOWN_SEL), + STM32MP1_CLK(RCC_DDRITFCR, 10, DDRPHYCAPBLP, _UNKNOWN_SEL), + ++ STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 11, SPI2_K, _SPI23_SEL), ++ STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 12, SPI3_K, _SPI23_SEL), + STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 14, USART2_K, _UART24_SEL), + STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 15, USART3_K, _UART35_SEL), + STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 16, UART4_K, _UART24_SEL), +@@ -532,10 +538,12 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { + STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 24, I2C5_K, _I2C35_SEL), + + STM32MP1_CLK_SET_CLR(RCC_MP_APB2ENSETR, 8, SPI1_K, _SPI1_SEL), ++ STM32MP1_CLK_SET_CLR(RCC_MP_APB2ENSETR, 9, SPI4_K, _SPI45_SEL), + STM32MP1_CLK_SET_CLR(RCC_MP_APB2ENSETR, 10, SPI5_K, _SPI45_SEL), + STM32MP1_CLK_SET_CLR(RCC_MP_APB2ENSETR, 13, USART6_K, _UART6_SEL), + + STM32MP1_CLK_SET_CLR_F(RCC_MP_APB3ENSETR, 13, VREF, _PCLK3), ++ STM32MP1_CLK_SET_CLR_F(RCC_MP_APB3ENSETR, 11, SYSCFG, _UNKNOWN_SEL), + + STM32MP1_CLK_SET_CLR_F(RCC_MP_APB4ENSETR, 0, LTDC_PX, _PLL4_Q), + STM32MP1_CLK_SET_CLR_F(RCC_MP_APB4ENSETR, 4, DSI_PX, _PLL4_Q), +@@ -544,6 +552,7 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { + STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 15, IWDG2, _UNKNOWN_SEL), + STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 16, USBPHY_K, _USBPHY_SEL), + ++ STM32MP1_CLK_SET_CLR(RCC_MP_APB5ENSETR, 0, SPI6_K, _SPI6_SEL), + STM32MP1_CLK_SET_CLR(RCC_MP_APB5ENSETR, 2, I2C4_K, _I2C46_SEL), + STM32MP1_CLK_SET_CLR(RCC_MP_APB5ENSETR, 3, I2C6_K, _I2C46_SEL), + STM32MP1_CLK_SET_CLR(RCC_MP_APB5ENSETR, 8, RTCAPB, _PCLK5), +@@ -608,10 +617,13 @@ static const u8 usbo_parents[] = {_PLL4_R, _USB_PHY_48}; + static const u8 stgen_parents[] = {_HSI_KER, _HSE_KER}; + static const u8 dsi_parents[] = {_DSI_PHY, _PLL4_P}; + static const u8 adc_parents[] = {_PLL4_R, _CK_PER, _PLL3_Q}; ++/* same parents for SPI1=RCC_SPI2S1CKSELR and SPI2&3 = RCC_SPI2S23CKSELR */ + static const u8 spi_parents[] = {_PLL4_P, _PLL3_Q, _I2S_CKIN, _CK_PER, + _PLL3_R}; + static const u8 spi45_parents[] = {_PCLK2, _PLL4_Q, _HSI_KER, _CSI_KER, + _HSE_KER}; ++static const u8 spi6_parents[] = {_PCLK5, _PLL4_Q, _HSI_KER, _CSI_KER, ++ _HSE_KER, _PLL3_Q}; + static const u8 rtc_parents[] = {_UNKNOWN_ID, _LSE, _LSI, _HSE}; + + static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { +@@ -638,7 +650,9 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { + STM32MP1_CLK_PARENT(_DSI_SEL, RCC_DSICKSELR, 0, 0x1, dsi_parents), + STM32MP1_CLK_PARENT(_ADC12_SEL, RCC_ADCCKSELR, 0, 0x3, adc_parents), + STM32MP1_CLK_PARENT(_SPI1_SEL, RCC_SPI2S1CKSELR, 0, 0x7, spi_parents), ++ STM32MP1_CLK_PARENT(_SPI23_SEL, RCC_SPI2S23CKSELR, 0, 0x7, spi_parents), + STM32MP1_CLK_PARENT(_SPI45_SEL, RCC_SPI45CKSELR, 0, 0x7, spi45_parents), ++ STM32MP1_CLK_PARENT(_SPI6_SEL, RCC_SPI6CKSELR, 0, 0x7, spi6_parents), + STM32MP1_CLK_PARENT(_RTC_SEL, RCC_BDCR, RCC_BDCR_RTCSRC_SHIFT, + (RCC_BDCR_RTCSRC_MASK >> RCC_BDCR_RTCSRC_SHIFT), + rtc_parents), +diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c +index a298c2c439..7fdcfa1aba 100644 +--- a/drivers/dfu/dfu.c ++++ b/drivers/dfu/dfu.c +@@ -42,6 +42,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 +@@ -338,6 +346,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; + } + +@@ -362,6 +371,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; + } + } +@@ -371,6 +381,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; + } + +@@ -382,6 +393,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/firmware/scmi/smt.c b/drivers/firmware/scmi/smt.c +index ce8fe49939..7f0223cc17 100644 +--- a/drivers/firmware/scmi/smt.c ++++ b/drivers/firmware/scmi/smt.c +@@ -53,8 +53,10 @@ int scmi_dt_get_smt_buffer(struct udevice *dev, struct scmi_smt *smt) + + #ifdef CONFIG_ARM + if (dcache_status()) +- mmu_set_region_dcache_behaviour((uintptr_t)smt->buf, +- smt->size, DCACHE_OFF); ++ mmu_set_region_dcache_behaviour(ALIGN_DOWN((uintptr_t)smt->buf, MMU_SECTION_SIZE), ++ ALIGN(smt->size, MMU_SECTION_SIZE), ++ DCACHE_OFF); ++ + #endif + + return 0; +diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c +index 2f60911549..07b9356f3f 100644 +--- a/drivers/i2c/stm32f7_i2c.c ++++ b/drivers/i2c/stm32f7_i2c.c +@@ -43,6 +43,8 @@ struct stm32_i2c_regs { + + /* STM32 I2C control 1 */ + #define STM32_I2C_CR1_ANFOFF BIT(12) ++#define STM32_I2C_CR1_DNF_MASK GENMASK(11, 8) ++#define STM32_I2C_CR1_DNF(n) (((n) & 0xf) << 8) + #define STM32_I2C_CR1_ERRIE BIT(7) + #define STM32_I2C_CR1_TCIE BIT(6) + #define STM32_I2C_CR1_STOPIE BIT(5) +@@ -103,10 +105,8 @@ struct stm32_i2c_regs { + + #define STM32_I2C_MAX_LEN 0xff + +-#define STM32_I2C_DNF_DEFAULT 0 +-#define STM32_I2C_DNF_MAX 16 ++#define STM32_I2C_DNF_MAX 15 + +-#define STM32_I2C_ANALOG_FILTER_ENABLE 1 + #define STM32_I2C_ANALOG_FILTER_DELAY_MIN 50 /* ns */ + #define STM32_I2C_ANALOG_FILTER_DELAY_MAX 260 /* ns */ + +@@ -154,9 +154,8 @@ struct stm32_i2c_spec { + * @clock_src: I2C clock source frequency (Hz) + * @rise_time: Rise time (ns) + * @fall_time: Fall time (ns) +- * @dnf: Digital filter coefficient (0-16) ++ * @dnf: value of digital filter to apply + * @analog_filter: Analog filter delay (On/Off) +- * @fmp_clr_offset: Fast Mode Plus clear register offset from set register + */ + struct stm32_i2c_setup { + u32 speed_freq; +@@ -165,6 +164,13 @@ struct stm32_i2c_setup { + u32 fall_time; + u8 dnf; + bool analog_filter; ++}; ++ ++/** ++ * struct stm32_i2c_data - driver data for I2C configuration by compatible ++ * @fmp_clr_offset: Fast Mode Plus clear register offset from set register ++ */ ++struct stm32_i2c_data { + u32 fmp_clr_offset; + }; + +@@ -195,16 +201,18 @@ struct stm32_i2c_timings { + * @regmap_sreg: register address for setting Fast Mode Plus bits + * @regmap_creg: register address for clearing Fast Mode Plus bits + * @regmap_mask: mask for Fast Mode Plus bits ++ * @dnf_dt: value of digital filter requested via dt + */ + struct stm32_i2c_priv { + struct stm32_i2c_regs *regs; + struct clk clk; +- struct stm32_i2c_setup *setup; ++ struct stm32_i2c_setup setup; + u32 speed; + struct regmap *regmap; + u32 regmap_sreg; + u32 regmap_creg; + u32 regmap_mask; ++ u32 dnf_dt; + }; + + static const struct stm32_i2c_spec i2c_specs[] = { +@@ -249,18 +257,11 @@ static const struct stm32_i2c_spec i2c_specs[] = { + }, + }; + +-static const struct stm32_i2c_setup stm32f7_setup = { +- .rise_time = STM32_I2C_RISE_TIME_DEFAULT, +- .fall_time = STM32_I2C_FALL_TIME_DEFAULT, +- .dnf = STM32_I2C_DNF_DEFAULT, +- .analog_filter = STM32_I2C_ANALOG_FILTER_ENABLE, ++static const struct stm32_i2c_data stm32f7_data = { ++ .fmp_clr_offset = 0x00, + }; + +-static const struct stm32_i2c_setup stm32mp15_setup = { +- .rise_time = STM32_I2C_RISE_TIME_DEFAULT, +- .fall_time = STM32_I2C_FALL_TIME_DEFAULT, +- .dnf = STM32_I2C_DNF_DEFAULT, +- .analog_filter = STM32_I2C_ANALOG_FILTER_ENABLE, ++static const struct stm32_i2c_data stm32mp15_data = { + .fmp_clr_offset = 0x40, + }; + +@@ -504,14 +505,13 @@ static int stm32_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, + return 0; + } + +-static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, ++static int stm32_i2c_compute_solutions(u32 i2cclk, ++ struct stm32_i2c_setup *setup, + const struct stm32_i2c_spec *specs, + struct list_head *solutions) + { + struct stm32_i2c_timings *v; + u32 p_prev = STM32_PRESC_MAX; +- u32 i2cclk = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC, +- setup->clock_src); + u32 af_delay_min, af_delay_max; + u16 p, l, a; + int sdadel_min, sdadel_max, scldel_min; +@@ -579,7 +579,8 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, + return ret; + } + +-static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, ++static int stm32_i2c_choose_solution(u32 i2cclk, ++ struct stm32_i2c_setup *setup, + const struct stm32_i2c_spec *specs, + struct list_head *solutions, + struct stm32_i2c_timings *s) +@@ -588,8 +589,6 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, + u32 i2cbus = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC, + setup->speed_freq); + u32 clk_error_prev = i2cbus; +- u32 i2cclk = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC, +- setup->clock_src); + u32 clk_min, clk_max; + u32 af_delay_min; + u32 dnf_delay; +@@ -676,12 +675,13 @@ static const struct stm32_i2c_spec *get_specs(u32 rate) + } + + static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, +- struct stm32_i2c_setup *setup, + struct stm32_i2c_timings *output) + { ++ struct stm32_i2c_setup *setup = &i2c_priv->setup; + const struct stm32_i2c_spec *specs; + struct stm32_i2c_timings *v, *_v; + struct list_head solutions; ++ u32 i2cclk = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC, setup->clock_src); + int ret; + + specs = get_specs(setup->speed_freq); +@@ -700,6 +700,8 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, + return -EINVAL; + } + ++ /* Analog and Digital Filters */ ++ setup->dnf = DIV_ROUND_CLOSEST(i2c_priv->dnf_dt, i2cclk); + if (setup->dnf > STM32_I2C_DNF_MAX) { + pr_err("%s: DNF out of bound %d/%d\n", __func__, + setup->dnf, STM32_I2C_DNF_MAX); +@@ -707,11 +709,11 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, + } + + INIT_LIST_HEAD(&solutions); +- ret = stm32_i2c_compute_solutions(setup, specs, &solutions); ++ ret = stm32_i2c_compute_solutions(i2cclk, setup, specs, &solutions); + if (ret) + goto exit; + +- ret = stm32_i2c_choose_solution(setup, specs, &solutions, output); ++ ret = stm32_i2c_choose_solution(i2cclk, setup, specs, &solutions, output); + if (ret) + goto exit; + +@@ -744,7 +746,7 @@ static u32 get_lower_rate(u32 rate) + static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv, + struct stm32_i2c_timings *timing) + { +- struct stm32_i2c_setup *setup = i2c_priv->setup; ++ struct stm32_i2c_setup *setup = &i2c_priv->setup; + int ret = 0; + + setup->speed_freq = i2c_priv->speed; +@@ -756,7 +758,7 @@ static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv, + } + + do { +- ret = stm32_i2c_compute_timing(i2c_priv, setup, timing); ++ ret = stm32_i2c_compute_timing(i2c_priv, timing); + if (ret) { + debug("%s: failed to compute I2C timings.\n", + __func__); +@@ -839,10 +841,15 @@ static int stm32_i2c_hw_config(struct stm32_i2c_priv *i2c_priv) + writel(timing, ®s->timingr); + + /* Enable I2C */ +- if (i2c_priv->setup->analog_filter) ++ if (i2c_priv->setup.analog_filter) + clrbits_le32(®s->cr1, STM32_I2C_CR1_ANFOFF); + else + setbits_le32(®s->cr1, STM32_I2C_CR1_ANFOFF); ++ ++ /* Program the Digital Filter */ ++ clrsetbits_le32(®s->cr1, STM32_I2C_CR1_DNF_MASK, ++ STM32_I2C_CR1_DNF(i2c_priv->setup.dnf)); ++ + setbits_le32(®s->cr1, STM32_I2C_CR1_PE); + + return 0; +@@ -903,21 +910,27 @@ clk_free: + + static int stm32_ofdata_to_platdata(struct udevice *dev) + { ++ const struct stm32_i2c_data *data; + struct stm32_i2c_priv *i2c_priv = dev_get_priv(dev); + u32 rise_time, fall_time; + int ret; + +- i2c_priv->setup = (struct stm32_i2c_setup *)dev_get_driver_data(dev); +- if (!i2c_priv->setup) ++ data = (const struct stm32_i2c_data *)dev_get_driver_data(dev); ++ if (!data) + return -EINVAL; + +- rise_time = dev_read_u32_default(dev, "i2c-scl-rising-time-ns", 0); +- if (rise_time) +- i2c_priv->setup->rise_time = rise_time; ++ rise_time = dev_read_u32_default(dev, "i2c-scl-rising-time-ns", ++ STM32_I2C_RISE_TIME_DEFAULT); ++ ++ ++ fall_time = dev_read_u32_default(dev, "i2c-scl-falling-time-ns", ++ STM32_I2C_FALL_TIME_DEFAULT); ++ ++ i2c_priv->dnf_dt = dev_read_u32_default(dev, "i2c-digital-filter-width-ns", 0); ++ if (!dev_read_bool(dev, "i2c-digital-filter")) ++ i2c_priv->dnf_dt = 0; + +- fall_time = dev_read_u32_default(dev, "i2c-scl-falling-time-ns", 0); +- if (fall_time) +- i2c_priv->setup->fall_time = fall_time; ++ i2c_priv->setup.analog_filter = dev_read_bool(dev, "i2c-analog-filter"); + + /* Optional */ + i2c_priv->regmap = syscon_regmap_lookup_by_phandle(dev, +@@ -930,8 +943,7 @@ static int stm32_ofdata_to_platdata(struct udevice *dev) + return ret; + + i2c_priv->regmap_sreg = fmp[1]; +- i2c_priv->regmap_creg = fmp[1] + +- i2c_priv->setup->fmp_clr_offset; ++ i2c_priv->regmap_creg = fmp[1] + data->fmp_clr_offset; + i2c_priv->regmap_mask = fmp[2]; + } + +@@ -944,8 +956,8 @@ static const struct dm_i2c_ops stm32_i2c_ops = { + }; + + static const struct udevice_id stm32_i2c_of_match[] = { +- { .compatible = "st,stm32f7-i2c", .data = (ulong)&stm32f7_setup }, +- { .compatible = "st,stm32mp15-i2c", .data = (ulong)&stm32mp15_setup }, ++ { .compatible = "st,stm32f7-i2c", .data = (ulong)&stm32f7_data }, ++ { .compatible = "st,stm32mp15-i2c", .data = (ulong)&stm32mp15_data }, + {} + }; + +diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c +index ef9b61ee62..2cdb0269f4 100644 +--- a/drivers/led/led_gpio.c ++++ b/drivers/led/led_gpio.c +@@ -99,11 +99,8 @@ static int led_gpio_bind(struct udevice *parent) + const char *label; + + label = ofnode_read_string(node, "label"); +- if (!label) { +- debug("%s: node %s has no label\n", __func__, +- ofnode_get_name(node)); +- return -EINVAL; +- } ++ if (!label) ++ label = ofnode_get_name(node); + ret = device_bind_driver_to_node(parent, "gpio_led", + ofnode_get_name(node), + node, &dev); +diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig +index 039f9fb058..2f11ba2e2d 100644 +--- a/drivers/net/Kconfig ++++ b/drivers/net/Kconfig +@@ -168,6 +168,7 @@ config DWC_ETH_QOS_IMX + config DWC_ETH_QOS_STM32 + bool "Synopsys DWC Ethernet QOS device support for STM32" + depends on DWC_ETH_QOS ++ select DM_ETH_PHY + default y if ARCH_STM32MP + help + The Synopsys Designware Ethernet QOS IP block with the specific +diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c +index 810a2b95b1..0f33c08253 100644 +--- a/drivers/net/dwc_eth_qos.c ++++ b/drivers/net/dwc_eth_qos.c +@@ -300,7 +300,7 @@ struct eqos_ops { + int (*eqos_remove_resources)(struct udevice *dev); + int (*eqos_stop_resets)(struct udevice *dev); + int (*eqos_start_resets)(struct udevice *dev); +- void (*eqos_stop_clks)(struct udevice *dev); ++ int (*eqos_stop_clks)(struct udevice *dev); + int (*eqos_start_clks)(struct udevice *dev); + int (*eqos_calibrate_pads)(struct udevice *dev); + int (*eqos_disable_calibration)(struct udevice *dev); +@@ -326,7 +326,6 @@ struct eqos_priv { + struct clk clk_slave_bus; + struct mii_dev *mii; + struct phy_device *phy; +- int phyaddr; + u32 max_speed; + void *descs; + struct eqos_desc *tx_descs; +@@ -653,12 +652,7 @@ err: + #endif + } + +-static int eqos_start_clks_imx(struct udevice *dev) +-{ +- return 0; +-} +- +-static void eqos_stop_clks_tegra186(struct udevice *dev) ++static int eqos_stop_clks_tegra186(struct udevice *dev) + { + #ifdef CONFIG_CLK + struct eqos_priv *eqos = dev_get_priv(dev); +@@ -673,9 +667,10 @@ static void eqos_stop_clks_tegra186(struct udevice *dev) + #endif + + debug("%s: OK\n", __func__); ++ return 0; + } + +-static void eqos_stop_clks_stm32(struct udevice *dev) ++static int eqos_stop_clks_stm32(struct udevice *dev) + { + #ifdef CONFIG_CLK + struct eqos_priv *eqos = dev_get_priv(dev); +@@ -690,11 +685,7 @@ static void eqos_stop_clks_stm32(struct udevice *dev) + #endif + + debug("%s: OK\n", __func__); +-} +- +-static void eqos_stop_clks_imx(struct udevice *dev) +-{ +- /* empty */ ++ return 0; + } + + static int eqos_start_resets_tegra186(struct udevice *dev) +@@ -736,39 +727,6 @@ static int eqos_start_resets_tegra186(struct udevice *dev) + return 0; + } + +-static int eqos_start_resets_stm32(struct udevice *dev) +-{ +- struct eqos_priv *eqos = dev_get_priv(dev); +- int ret; +- +- debug("%s(dev=%p):\n", __func__, dev); +- if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) { +- ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1); +- if (ret < 0) { +- pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d", +- ret); +- return ret; +- } +- +- udelay(2); +- +- ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0); +- if (ret < 0) { +- pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d", +- ret); +- return ret; +- } +- } +- debug("%s: OK\n", __func__); +- +- return 0; +-} +- +-static int eqos_start_resets_imx(struct udevice *dev) +-{ +- return 0; +-} +- + static int eqos_stop_resets_tegra186(struct udevice *dev) + { + struct eqos_priv *eqos = dev_get_priv(dev); +@@ -779,28 +737,6 @@ static int eqos_stop_resets_tegra186(struct udevice *dev) + return 0; + } + +-static int eqos_stop_resets_stm32(struct udevice *dev) +-{ +- struct eqos_priv *eqos = dev_get_priv(dev); +- int ret; +- +- if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) { +- ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1); +- if (ret < 0) { +- pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d", +- ret); +- return ret; +- } +- } +- +- return 0; +-} +- +-static int eqos_stop_resets_imx(struct udevice *dev) +-{ +- return 0; +-} +- + static int eqos_calibrate_pads_tegra186(struct udevice *dev) + { + struct eqos_priv *eqos = dev_get_priv(dev); +@@ -889,26 +825,6 @@ static ulong eqos_get_tick_clk_rate_imx(struct udevice *dev) + return imx_get_eqos_csr_clk(); + } + +-static int eqos_calibrate_pads_stm32(struct udevice *dev) +-{ +- return 0; +-} +- +-static int eqos_calibrate_pads_imx(struct udevice *dev) +-{ +- return 0; +-} +- +-static int eqos_disable_calibration_stm32(struct udevice *dev) +-{ +- return 0; +-} +- +-static int eqos_disable_calibration_imx(struct udevice *dev) +-{ +- return 0; +-} +- + static int eqos_set_full_duplex(struct udevice *dev) + { + struct eqos_priv *eqos = dev_get_priv(dev); +@@ -1005,11 +921,6 @@ static int eqos_set_tx_clk_speed_tegra186(struct udevice *dev) + return 0; + } + +-static int eqos_set_tx_clk_speed_stm32(struct udevice *dev) +-{ +- return 0; +-} +- + static int eqos_set_tx_clk_speed_imx(struct udevice *dev) + { + struct eqos_priv *eqos = dev_get_priv(dev); +@@ -1815,7 +1726,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev) + struct eqos_priv *eqos = dev_get_priv(dev); + int ret; + phy_interface_t interface; +- struct ofnode_phandle_args phandle_args; + + debug("%s(dev=%p):\n", __func__, dev); + +@@ -1855,24 +1765,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev) + if (ret) + pr_warn("No phy clock provided %d", ret); + +- eqos->phyaddr = -1; +- ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, +- &phandle_args); +- if (!ret) { +- /* search "reset-gpios" in phy node */ +- ret = gpio_request_by_name_nodev(phandle_args.node, +- "reset-gpios", 0, +- &eqos->phy_reset_gpio, +- GPIOD_IS_OUT | +- GPIOD_IS_OUT_ACTIVE); +- if (ret) +- pr_warn("gpio_request_by_name(phy reset) not provided %d", +- ret); +- +- eqos->phyaddr = ofnode_read_u32_default(phandle_args.node, +- "reg", -1); +- } +- + debug("%s: OK\n", __func__); + return 0; + +@@ -1980,11 +1872,6 @@ static int eqos_remove_resources_stm32(struct udevice *dev) + return 0; + } + +-static int eqos_remove_resources_imx(struct udevice *dev) +-{ +- return 0; +-} +- + static int eqos_probe(struct udevice *dev) + { + struct eqos_priv *eqos = dev_get_priv(dev); +@@ -2073,6 +1960,11 @@ static int eqos_remove(struct udevice *dev) + return 0; + } + ++static int eqos_null_ops(struct udevice *dev) ++{ ++ return 0; ++} ++ + static const struct eth_ops eqos_ops = { + .start = eqos_start, + .stop = eqos_stop, +@@ -2117,13 +2009,13 @@ static struct eqos_ops eqos_stm32_ops = { + .eqos_flush_buffer = eqos_flush_buffer_generic, + .eqos_probe_resources = eqos_probe_resources_stm32, + .eqos_remove_resources = eqos_remove_resources_stm32, +- .eqos_stop_resets = eqos_stop_resets_stm32, +- .eqos_start_resets = eqos_start_resets_stm32, ++ .eqos_stop_resets = eqos_null_ops, ++ .eqos_start_resets = eqos_null_ops, + .eqos_stop_clks = eqos_stop_clks_stm32, + .eqos_start_clks = eqos_start_clks_stm32, +- .eqos_calibrate_pads = eqos_calibrate_pads_stm32, +- .eqos_disable_calibration = eqos_disable_calibration_stm32, +- .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_stm32, ++ .eqos_calibrate_pads = eqos_null_ops, ++ .eqos_disable_calibration = eqos_null_ops, ++ .eqos_set_tx_clk_speed = eqos_null_ops, + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32 + }; + +@@ -2143,13 +2035,13 @@ static struct eqos_ops eqos_imx_ops = { + .eqos_inval_buffer = eqos_inval_buffer_generic, + .eqos_flush_buffer = eqos_flush_buffer_generic, + .eqos_probe_resources = eqos_probe_resources_imx, +- .eqos_remove_resources = eqos_remove_resources_imx, +- .eqos_stop_resets = eqos_stop_resets_imx, +- .eqos_start_resets = eqos_start_resets_imx, +- .eqos_stop_clks = eqos_stop_clks_imx, +- .eqos_start_clks = eqos_start_clks_imx, +- .eqos_calibrate_pads = eqos_calibrate_pads_imx, +- .eqos_disable_calibration = eqos_disable_calibration_imx, ++ .eqos_remove_resources = eqos_null_ops, ++ .eqos_stop_resets = eqos_null_ops, ++ .eqos_start_resets = eqos_null_ops, ++ .eqos_stop_clks = eqos_null_ops, ++ .eqos_start_clks = eqos_null_ops, ++ .eqos_calibrate_pads = eqos_null_ops, ++ .eqos_disable_calibration = eqos_null_ops, + .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_imx, + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_imx + }; +diff --git a/drivers/net/eth-phy-uclass.c b/drivers/net/eth-phy-uclass.c +index b383f45527..ded7d77a35 100644 +--- a/drivers/net/eth-phy-uclass.c ++++ b/drivers/net/eth-phy-uclass.c +@@ -5,13 +5,20 @@ + + #include + #include ++#include + #include ++#include ++#include + #include + #include + #include ++#include + + struct eth_phy_device_priv { + struct mii_dev *mdio_bus; ++ struct gpio_desc reset_gpio; ++ u32 reset_assert_delay; ++ u32 reset_deassert_delay; + }; + + int eth_phy_binds_nodes(struct udevice *eth_dev) +@@ -20,27 +27,33 @@ int eth_phy_binds_nodes(struct udevice *eth_dev) + const char *node_name; + int ret; + +- mdio_node = dev_read_subnode(eth_dev, "mdio"); ++ /* search a subnode named "mdio.*" */ ++ dev_for_each_subnode(mdio_node, eth_dev) { ++ node_name = ofnode_get_name(mdio_node); ++ if (!strncmp(node_name, "mdio", 4)) ++ break; ++ } + if (!ofnode_valid(mdio_node)) { +- debug("%s: %s mdio subnode not found!", __func__, +- eth_dev->name); ++ dev_dbg(eth_dev, "%s: %s mdio subnode not found!\n", __func__, ++ eth_dev->name); + return -ENXIO; + } ++ dev_dbg(eth_dev, "%s: %s subnode found!\n", __func__, node_name); + + ofnode_for_each_subnode(phy_node, mdio_node) { + node_name = ofnode_get_name(phy_node); + +- debug("* Found child node: '%s'\n", node_name); ++ dev_dbg(eth_dev, "* Found child node: '%s'\n", node_name); + + ret = device_bind_driver_to_node(eth_dev, + "eth_phy_generic_drv", + node_name, phy_node, NULL); + if (ret) { +- debug(" - Eth phy binding error: %d\n", ret); ++ dev_dbg(eth_dev, " - Eth phy binding error: %d\n", ret); + continue; + } + +- debug(" - bound phy device: '%s'\n", node_name); ++ dev_dbg(eth_dev, " - bound phy device: '%s'\n", node_name); + } + + return 0; +@@ -81,14 +94,14 @@ struct mii_dev *eth_phy_get_mdio_bus(struct udevice *eth_dev) + */ + uc_priv = (struct eth_phy_device_priv *)(phy_dev->uclass_priv); + if (uc_priv->mdio_bus) +- printf("Get shared mii bus on %s\n", eth_dev->name); ++ log_notice("Get shared mii bus on %s\n", eth_dev->name); + else +- printf("Can't get shared mii bus on %s\n", eth_dev->name); ++ log_notice("Can't get shared mii bus on %s\n", eth_dev->name); + + return uc_priv->mdio_bus; + } + } else { +- printf("FEC: can't find phy-handle\n"); ++ log_notice("FEC: can't find phy-handle\n"); + } + + return NULL; +@@ -101,7 +114,7 @@ int eth_phy_get_addr(struct udevice *dev) + + if (dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, + &phandle_args)) { +- debug("Failed to find phy-handle"); ++ dev_dbg(dev, "Failed to find phy-handle"); + return -ENODEV; + } + +@@ -110,13 +123,58 @@ int eth_phy_get_addr(struct udevice *dev) + return reg; + } + ++/* parsing generic properties of devicetree/bindings/net/ethernet-phy.yaml */ ++static int eth_phy_of_to_plat(struct udevice *dev) ++{ ++ struct eth_phy_device_priv *uc_priv = dev_get_uclass_priv(dev); ++ int ret; ++ ++ /* search "reset-gpios" in phy node */ ++ ret = gpio_request_by_name(dev, "reset-gpios", 0, ++ &uc_priv->reset_gpio, ++ GPIOD_IS_OUT); ++ if (ret != -ENOENT) ++ return ret; ++ ++ uc_priv->reset_assert_delay = dev_read_u32_default(dev, "reset-assert-us", 0); ++ uc_priv->reset_deassert_delay = dev_read_u32_default(dev, "reset-deassert-us", 0); ++ ++ return 0; ++} ++ ++void eth_phy_reset(struct udevice *dev, int value) ++{ ++ struct eth_phy_device_priv *uc_priv = dev_get_uclass_priv(dev); ++ u32 delay; ++ ++ if (!dm_gpio_is_valid(&uc_priv->reset_gpio)) ++ return; ++ ++ dm_gpio_set_value(&uc_priv->reset_gpio, value); ++ ++ delay = value ? uc_priv->reset_assert_delay : uc_priv->reset_deassert_delay; ++ if (delay) ++ udelay(delay); ++} ++ ++static int eth_phy_pre_probe(struct udevice *dev) ++{ ++ /* Assert and deassert the reset signal */ ++ eth_phy_reset(dev, 1); ++ eth_phy_reset(dev, 0); ++ ++ return 0; ++} ++ + UCLASS_DRIVER(eth_phy_generic) = { + .id = UCLASS_ETH_PHY, + .name = "eth_phy_generic", + .per_device_auto_alloc_size = sizeof(struct eth_phy_device_priv), ++ .pre_probe = eth_phy_pre_probe, + }; + + U_BOOT_DRIVER(eth_phy_generic_drv) = { + .name = "eth_phy_generic_drv", + .id = UCLASS_ETH_PHY, ++ .ofdata_to_platdata = eth_phy_of_to_plat, + }; +diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c +index d4a82f73f4..6d89c85516 100644 +--- a/drivers/phy/phy-stm32-usbphyc.c ++++ b/drivers/phy/phy-stm32-usbphyc.c +@@ -15,6 +15,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -22,6 +24,7 @@ + /* USBPHYC registers */ + #define STM32_USBPHYC_PLL 0x0 + #define STM32_USBPHYC_MISC 0x8 ++#define STM32_USBPHYC_TUNE(X) (0x10C + ((X) * 0x100)) + + /* STM32_USBPHYC_PLL bit fields */ + #define PLLNDIV GENMASK(6, 0) +@@ -38,6 +41,26 @@ + /* STM32_USBPHYC_MISC bit fields */ + #define SWITHOST BIT(0) + ++/* STM32_USBPHYC_TUNE bit fields */ ++#define INCURREN BIT(0) ++#define INCURRINT BIT(1) ++#define LFSCAPEN BIT(2) ++#define HSDRVSLEW BIT(3) ++#define HSDRVDCCUR BIT(4) ++#define HSDRVDCLEV BIT(5) ++#define HSDRVCURINCR BIT(6) ++#define FSDRVRFADJ BIT(7) ++#define HSDRVRFRED BIT(8) ++#define HSDRVCHKITRM GENMASK(12, 9) ++#define HSDRVCHKZTRM GENMASK(14, 13) ++#define OTPCOMP GENMASK(19, 15) ++#define SQLCHCTL GENMASK(21, 20) ++#define HDRXGNEQEN BIT(22) ++#define HSRXOFF GENMASK(24, 23) ++#define HSFALLPREEM BIT(25) ++#define SHTCCTCTLPROT BIT(26) ++#define STAGSEL BIT(27) ++ + #define MAX_PHYS 2 + + /* max 100 us for PLL lock and 100 us for PHY init */ +@@ -47,6 +70,63 @@ + #define PLL_INFF_MIN_RATE 19200000 /* in Hz */ + #define PLL_INFF_MAX_RATE 38400000 /* in Hz */ + ++enum boosting_vals { ++ BOOST_1_MA = 1, ++ BOOST_2_MA, ++ BOOST_MAX, ++}; ++ ++enum dc_level_vals { ++ DC_MINUS_5_TO_7_MV, ++ DC_PLUS_5_TO_7_MV, ++ DC_PLUS_10_TO_14_MV, ++ DC_MAX, ++}; ++ ++enum current_trim { ++ CUR_NOMINAL, ++ CUR_PLUS_1_56_PCT, ++ CUR_PLUS_3_12_PCT, ++ CUR_PLUS_4_68_PCT, ++ CUR_PLUS_6_24_PCT, ++ CUR_PLUS_7_8_PCT, ++ CUR_PLUS_9_36_PCT, ++ CUR_PLUS_10_92_PCT, ++ CUR_PLUS_12_48_PCT, ++ CUR_PLUS_14_04_PCT, ++ CUR_PLUS_15_6_PCT, ++ CUR_PLUS_17_16_PCT, ++ CUR_PLUS_19_01_PCT, ++ CUR_PLUS_20_58_PCT, ++ CUR_PLUS_22_16_PCT, ++ CUR_PLUS_23_73_PCT, ++ CUR_MAX, ++}; ++ ++enum impedance_trim { ++ IMP_NOMINAL, ++ IMP_MINUS_2_OHMS, ++ IMP_MINUS_4_OMHS, ++ IMP_MINUS_6_OHMS, ++ IMP_MAX, ++}; ++ ++enum squelch_level { ++ SQLCH_NOMINAL, ++ SQLCH_PLUS_7_MV, ++ SQLCH_MINUS_5_MV, ++ SQLCH_PLUS_14_MV, ++ SQLCH_MAX, ++}; ++ ++enum rx_offset { ++ NO_RX_OFFSET, ++ RX_OFFSET_PLUS_5_MV, ++ RX_OFFSET_PLUS_10_MV, ++ RX_OFFSET_MINUS_5_MV, ++ RX_OFFSET_MAX, ++}; ++ + struct pll_params { + u8 ndiv; + u16 frac; +@@ -325,6 +405,98 @@ static int stm32_usbphyc_of_xlate(struct phy *phy, + return 0; + } + ++static void stm32_usbphyc_tuning(struct udevice *dev, ofnode node, u32 index) ++{ ++ struct stm32_usbphyc *usbphyc = dev_get_priv(dev); ++ struct ofnode_phandle_args tune_phandle; ++ u32 reg = STM32_USBPHYC_TUNE(index); ++ u32 otpcomp, val, tune = 0; ++ int ret; ++ ++ ret = ofnode_parse_phandle_with_args(node, "st,phy-tuning", NULL, 0, ++ 0, &tune_phandle); ++ if (ret) { ++ dev_dbg(dev, "phy%d: can't find phy tuning phandle\n", index); ++ return; ++ } ++ ++ /* Backup OTP compensation code */ ++ otpcomp = FIELD_GET(OTPCOMP, readl(usbphyc->base + reg)); ++ ++ ret = ofnode_read_u32(tune_phandle.node, "st,current-boost", &val); ++ if (!ret && val < BOOST_MAX) { ++ val = (val == BOOST_2_MA) ? 1 : 0; ++ tune |= INCURREN | FIELD_PREP(INCURRINT, val); ++ } else if (ret != -EINVAL) { ++ dev_warn(dev, "phy%d: invalid st,current-boost value\n", index); ++ } ++ ++ if (!ofnode_read_bool(tune_phandle.node, "st,no-lsfs-fb-cap")) ++ tune |= LFSCAPEN; ++ ++ if (ofnode_read_bool(tune_phandle.node, "st,hs-slew-ctrl")) ++ tune |= HSDRVSLEW; ++ ++ ret = ofnode_read_u32(tune_phandle.node, "st,hs-dc-level", &val); ++ if (!ret && val < DC_MAX) { ++ if (val == DC_MINUS_5_TO_7_MV) { ++ tune |= HSDRVDCCUR; ++ } else { ++ val = (val == DC_PLUS_10_TO_14_MV) ? 1 : 0; ++ tune |= HSDRVCURINCR | FIELD_PREP(HSDRVDCLEV, val); ++ } ++ } else if (ret != -EINVAL) { ++ dev_warn(dev, "phy%d: invalid st,hs-dc-level value\n", index); ++ } ++ ++ if (ofnode_read_bool(tune_phandle.node, "st,fs-rftime-tuning")) ++ tune |= FSDRVRFADJ; ++ ++ if (ofnode_read_bool(tune_phandle.node, "st,hs-rftime-reduction")) ++ tune |= HSDRVRFRED; ++ ++ ret = ofnode_read_u32(tune_phandle.node, "st,hs-current-trim", &val); ++ if (!ret && val < CUR_MAX) ++ tune |= FIELD_PREP(HSDRVCHKITRM, val); ++ else if (ret != -EINVAL) ++ dev_warn(dev, "phy%d: invalid st,hs-current-trim value\n", index); ++ ++ ret = ofnode_read_u32(tune_phandle.node, "st,hs-impedance-trim", &val); ++ if (!ret && val < IMP_MAX) ++ tune |= FIELD_PREP(HSDRVCHKZTRM, val); ++ else if (ret != -EINVAL) ++ dev_warn(dev, "phy%d: invalid hs-impedance-trim value\n", index); ++ ++ ret = ofnode_read_u32(tune_phandle.node, "st,squelch-level", &val); ++ if (!ret && val < SQLCH_MAX) ++ tune |= FIELD_PREP(SQLCHCTL, val); ++ else if (ret != -EINVAL) ++ dev_warn(dev, "phy%d: invalid st,squelch-level value\n", index); ++ ++ if (ofnode_read_bool(tune_phandle.node, "st,hs-rx-gain-eq")) ++ tune |= HDRXGNEQEN; ++ ++ ret = ofnode_read_u32(tune_phandle.node, "st,hs-rx-offset", &val); ++ if (!ret && val < RX_OFFSET_MAX) ++ tune |= FIELD_PREP(HSRXOFF, val); ++ else if (ret != -EINVAL) ++ dev_warn(dev, "phy%d: invalid st,hs-rx-offset value\n", index); ++ ++ if (ofnode_read_bool(tune_phandle.node, "st,no-hs-ftime-ctrl")) ++ tune |= HSFALLPREEM; ++ ++ if (!ofnode_read_bool(tune_phandle.node, "st,no-lsfs-sc")) ++ tune |= SHTCCTCTLPROT; ++ ++ if (ofnode_read_bool(tune_phandle.node, "st,hs-tx-staggering")) ++ tune |= STAGSEL; ++ ++ /* Restore OTP compensation code */ ++ tune |= FIELD_PREP(OTPCOMP, otpcomp); ++ ++ writel(tune, usbphyc->base + reg); ++} ++ + static const struct phy_ops stm32_usbphyc_phy_ops = { + .init = stm32_usbphyc_phy_init, + .exit = stm32_usbphyc_phy_exit, +@@ -337,8 +509,8 @@ static int stm32_usbphyc_probe(struct udevice *dev) + { + struct stm32_usbphyc *usbphyc = dev_get_priv(dev); + struct reset_ctl reset; +- ofnode node; +- int i, ret; ++ ofnode node, connector; ++ int ret; + + usbphyc->base = dev_read_addr(dev); + if (usbphyc->base == FDT_ADDR_T_NONE) +@@ -376,14 +548,22 @@ static int stm32_usbphyc_probe(struct udevice *dev) + return ret; + } + +- /* +- * parse all PHY subnodes in order to populate regulator associated +- * to each PHY port +- */ +- node = dev_read_first_subnode(dev); +- for (i = 0; i < MAX_PHYS; i++) { +- struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + i; ++ /* parse all PHY subnodes to populate regulator associated to each PHY port */ ++ dev_for_each_subnode(node, dev) { ++ fdt_addr_t phy_id; ++ struct stm32_usbphyc_phy *usbphyc_phy; + ++ phy_id = ofnode_read_u32_default(node, "reg", FDT_ADDR_T_NONE); ++ if (phy_id >= MAX_PHYS) { ++ dev_err(dev, "invalid reg value %lx for %s\n", ++ phy_id, ofnode_get_name(node)); ++ return -ENOENT; ++ } ++ ++ /* Configure phy tuning */ ++ stm32_usbphyc_tuning(dev, node, phy_id); ++ ++ usbphyc_phy = usbphyc->phys + phy_id; + usbphyc_phy->init = false; + usbphyc_phy->powered = false; + ret = stm32_usbphyc_get_regulator(node, "phy-supply", +@@ -393,12 +573,14 @@ static int stm32_usbphyc_probe(struct udevice *dev) + return ret; + } + +- ret = stm32_usbphyc_get_regulator(node, "vbus-supply", +- &usbphyc_phy->vbus); +- if (ret) +- usbphyc_phy->vbus = NULL; +- +- node = dev_read_next_subnode(node); ++ usbphyc_phy->vbus = NULL; ++ connector = ofnode_find_subnode(node, "connector"); ++ if (ofnode_valid(connector)) { ++ ret = stm32_usbphyc_get_regulator(connector, "vbus-supply", ++ &usbphyc_phy->vbus); ++ if (ret) ++ usbphyc_phy->vbus = NULL; ++ } + } + + /* Check if second port has to be used for host controller */ +diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c +index bf3a4c97a4..cc3269c52b 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_ddr.c ++++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c +@@ -824,8 +824,12 @@ start: + */ + + /* 10. configure PUBL PIR register to specify which training step to run */ +- /* warning : RVTRN is not supported by this PUBL */ +- stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_QSTRN); ++ /* RVTRN is executed only on LPDDR2/LPDDR3 */ ++ if (config->c_reg.mstr & DDRCTRL_MSTR_DDR3) ++ pir = DDRPHYC_PIR_QSTRN; ++ else ++ pir = DDRPHYC_PIR_QSTRN | DDRPHYC_PIR_RVTRN; ++ stm32mp1_ddrphy_init(priv->phy, pir); + + /* 11. monitor PUB PGSR.IDONE to poll cpmpletion of training sequence */ + ddrphy_idone_wait(priv->phy); +diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h +index 3c8885a965..ada3087328 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h ++++ b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h +@@ -309,6 +309,7 @@ struct stm32mp1_ddrphy { + #define DDRPHYC_PIR_DRAMRST BIT(5) + #define DDRPHYC_PIR_DRAMINIT BIT(6) + #define DDRPHYC_PIR_QSTRN BIT(7) ++#define DDRPHYC_PIR_RVTRN BIT(8) + #define DDRPHYC_PIR_ICPC BIT(16) + #define DDRPHYC_PIR_ZCALBYP BIT(30) + #define DDRPHYC_PIR_INITSTEPS_MASK GENMASK(31, 7) +diff --git a/drivers/remoteproc/rproc-optee.c b/drivers/remoteproc/rproc-optee.c +index 07d2811e22..8b0b4bdd51 100644 +--- a/drivers/remoteproc/rproc-optee.c ++++ b/drivers/remoteproc/rproc-optee.c +@@ -202,18 +202,32 @@ int rproc_optee_open(struct rproc_optee *trproc) + + tee_optee_ta_uuid_to_octets(arg.uuid, &uuid); + rc = tee_open_session(tee, &arg, 0, NULL); +- if (!rc) { +- trproc->tee = tee; +- trproc->session = arg.session; ++ if (rc < 0 || arg.ret != 0) { ++ if (!rc) ++ rc = -EIO; ++ return rc; + } + ++ trproc->tee = tee; ++ trproc->session = arg.session; ++ + return 0; + } + + int rproc_optee_close(struct rproc_optee *trproc) + { ++ int rc; ++ + if (!trproc->tee) + return -ENODEV; + +- return tee_close_session(trproc->tee, trproc->session); ++ rc = tee_close_session(trproc->tee, trproc->session); ++ if (rc) ++ return rc; ++ ++ trproc->tee = NULL; ++ trproc->session = 0; ++ ++ return 0; ++ + } +diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c +index 55d7303c55..847d98b387 100644 +--- a/drivers/remoteproc/stm32_copro.c ++++ b/drivers/remoteproc/stm32_copro.c +@@ -27,6 +27,7 @@ struct stm32_copro_privdata { + struct reset_ctl reset_ctl; + struct reset_ctl hold_boot; + ulong rsc_table_addr; ++ struct rproc_optee trproc; + }; + + /** +@@ -36,10 +37,16 @@ struct stm32_copro_privdata { + */ + static int stm32_copro_probe(struct udevice *dev) + { +- struct stm32_copro_privdata *priv; ++ struct stm32_copro_privdata *priv = dev_get_priv(dev); ++ struct rproc_optee *trproc = &priv->trproc; + int ret; + +- priv = dev_get_priv(dev); ++ trproc->fw_id = (u32)dev_get_driver_data(dev); ++ ret = rproc_optee_open(trproc); ++ if (!ret) { ++ dev_info(dev, "delegate the firmware management to OPTEE\n"); ++ return 0; ++ } + + ret = reset_get_by_name(dev, "mcu_rst", &priv->reset_ctl); + if (ret) { +@@ -58,30 +65,20 @@ static int stm32_copro_probe(struct udevice *dev) + return 0; + } + +-/** +- * stm32_copro_optee_probe() - Open a session toward rproc trusted application +- * @dev: corresponding STM32 remote processor device +- * @return 0 if all went ok, else corresponding -ve error +- */ +-static int stm32_copro_optee_probe(struct udevice *dev) +-{ +- struct rproc_optee *trproc = dev_get_priv(dev); +- +- trproc->fw_id = (u32)dev_get_driver_data(dev); +- +- return rproc_optee_open(trproc); +-} +- + /** + * stm32_copro_optee_remove() - Close the rproc trusted application session + * @dev: corresponding STM32 remote processor device + * @return 0 if all went ok, else corresponding -ve error + */ +-static int stm32_copro_optee_remove(struct udevice *dev) ++static int stm32_copro_remove(struct udevice *dev) + { +- struct rproc_optee *trproc = dev_get_priv(dev); ++ struct stm32_copro_privdata *priv = dev_get_priv(dev); ++ struct rproc_optee *trproc = &priv->trproc; ++ ++ if (trproc->tee) ++ return rproc_optee_close(trproc); + +- return rproc_optee_close(trproc); ++ return 0; + } + + /** +@@ -121,11 +118,13 @@ static void *stm32_copro_device_to_virt(struct udevice *dev, ulong da, + */ + static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size) + { +- struct stm32_copro_privdata *priv; ++ struct stm32_copro_privdata *priv = dev_get_priv(dev); ++ struct rproc_optee *trproc = &priv->trproc; + ulong rsc_table_size; + int ret; + +- priv = dev_get_priv(dev); ++ if (trproc->tee) ++ return rproc_optee_load(trproc, addr, size); + + ret = reset_assert(&priv->hold_boot); + if (ret) { +@@ -148,18 +147,6 @@ static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size) + return rproc_elf32_load_image(dev, addr, size); + } + +-/** +- * stm32_copro_optee_load() - Request OP−TEE to load the remote processor firmware +- * @dev: corresponding OP-TEE remote processor device +- * @return 0 if all went ok, else corresponding -ve error +- */ +-static int stm32_copro_optee_load(struct udevice *dev, ulong addr, ulong size) +-{ +- struct rproc_optee *trproc = dev_get_priv(dev); +- +- return rproc_optee_load(trproc, addr, size); +-} +- + /** + * stm32_copro_start() - Start the STM32 remote processor + * @dev: corresponding STM32 remote processor device +@@ -167,25 +154,39 @@ static int stm32_copro_optee_load(struct udevice *dev, ulong addr, ulong size) + */ + static int stm32_copro_start(struct udevice *dev) + { +- struct stm32_copro_privdata *priv; ++ struct stm32_copro_privdata *priv = dev_get_priv(dev); ++ struct rproc_optee *trproc = &priv->trproc; ++ phys_size_t rsc_size; + int ret; + +- priv = dev_get_priv(dev); +- +- ret = reset_deassert(&priv->hold_boot); +- if (ret) { +- dev_err(dev, "Unable to deassert hold boot (ret=%d)\n", ret); +- return ret; ++ if (trproc->tee) { ++ ret = rproc_optee_get_rsc_table(trproc, &priv->rsc_table_addr, ++ &rsc_size); ++ if (ret) ++ return ret; ++ ++ ret = rproc_optee_start(trproc); ++ if (ret) ++ return ret; ++ ++ } else { ++ ret = reset_deassert(&priv->hold_boot); ++ if (ret) { ++ dev_err(dev, "Unable to deassert hold boot (ret=%d)\n", ++ ret); ++ return ret; ++ } ++ ++ /* ++ * Once copro running, reset hold boot flag to avoid copro ++ * rebooting autonomously (error should never occur) ++ */ ++ ret = reset_assert(&priv->hold_boot); ++ if (ret) ++ dev_err(dev, "Unable to assert hold boot (ret=%d)\n", ++ ret); + } + +- /* +- * Once copro running, reset hold boot flag to avoid copro +- * rebooting autonomously (error should never occur) +- */ +- ret = reset_assert(&priv->hold_boot); +- if (ret) +- dev_err(dev, "Unable to assert hold boot (ret=%d)\n", ret); +- + /* indicates that copro is running */ + writel(TAMP_COPRO_STATE_CRUN, TAMP_COPRO_STATE); + /* Store rsc_address in bkp register */ +@@ -194,34 +195,6 @@ static int stm32_copro_start(struct udevice *dev) + return 0; + } + +-/** +- * stm32_copro_optee_start() - Request OP−TEE to start the STM32 remote processor +- * @dev: corresponding OP-TEE remote processor device +- * @return 0 if all went ok, else corresponding -ve error +- */ +-static int stm32_copro_optee_start(struct udevice *dev) +-{ +- struct rproc_optee *trproc = dev_get_priv(dev); +- phys_addr_t rsc_addr; +- phys_size_t rsc_size; +- int ret; +- +- ret = rproc_optee_get_rsc_table(trproc, &rsc_addr, &rsc_size); +- if (ret) +- return ret; +- +- ret = rproc_optee_start(trproc); +- if (ret) +- return ret; +- +- /* indicates that copro is running */ +- writel(TAMP_COPRO_STATE_CRUN, TAMP_COPRO_STATE); +- /* Store rsc_address in bkp register */ +- writel(rsc_addr, TAMP_COPRO_RSC_TBL_ADDRESS); +- +- return 0; +-} +- + /** + * stm32_copro_reset() - Reset the STM32 remote processor + * @dev: corresponding STM32 remote processor device +@@ -229,21 +202,29 @@ static int stm32_copro_optee_start(struct udevice *dev) + */ + static int stm32_copro_reset(struct udevice *dev) + { +- struct stm32_copro_privdata *priv; ++ struct stm32_copro_privdata *priv = dev_get_priv(dev); ++ struct rproc_optee *trproc = &priv->trproc; + int ret; + +- priv = dev_get_priv(dev); + +- ret = reset_assert(&priv->hold_boot); +- if (ret) { +- dev_err(dev, "Unable to assert hold boot (ret=%d)\n", ret); +- return ret; +- } +- +- ret = reset_assert(&priv->reset_ctl); +- if (ret) { +- dev_err(dev, "Unable to assert reset line (ret=%d)\n", ret); +- return ret; ++ if (trproc->tee) { ++ ret = rproc_optee_stop(trproc); ++ if (ret) ++ return ret; ++ } else { ++ ret = reset_assert(&priv->hold_boot); ++ if (ret) { ++ dev_err(dev, "Unable to assert hold boot (ret=%d)\n", ++ ret); ++ return ret; ++ } ++ ++ ret = reset_assert(&priv->reset_ctl); ++ if (ret) { ++ dev_err(dev, "Unable to assert reset line (ret=%d)\n", ++ ret); ++ return ret; ++ } + } + + writel(TAMP_COPRO_STATE_OFF, TAMP_COPRO_STATE); +@@ -261,35 +242,6 @@ static int stm32_copro_stop(struct udevice *dev) + return stm32_copro_reset(dev); + } + +-/** +- * stm32_copro_optee_reset() - Request OP−TEE to reset the STM32 remote processor +- * @dev: corresponding STM32 remote processor device +- * @return 0 if all went ok, else corresponding -ve error +- */ +-static int stm32_copro_optee_reset(struct udevice *dev) +-{ +- struct rproc_optee *trproc = dev_get_priv(dev); +- int ret; +- +- ret = rproc_optee_stop(trproc); +- if (ret) +- return ret; +- +- writel(TAMP_COPRO_STATE_OFF, TAMP_COPRO_STATE); +- +- return 0; +-} +- +-/** +- * stm32_copro_optee_stop() - Request OP−TEE to stop the STM32 remote processor +- * @dev: corresponding STM32 remote processor device +- * @return 0 if all went ok, else corresponding -ve error +- */ +-static int stm32_copro_optee_stop(struct udevice *dev) +-{ +- return stm32_copro_optee_reset(dev); +-} +- + /** + * stm32_copro_is_running() - Is the STM32 remote processor running + * @dev: corresponding STM32 remote processor device +@@ -310,7 +262,7 @@ static const struct dm_rproc_ops stm32_copro_ops = { + }; + + static const struct udevice_id stm32_copro_ids[] = { +- {.compatible = "st,stm32mp1-m4"}, ++ { .compatible = "st,stm32mp1-m4", .data = STM32MP15_M4_FW_ID }, + {} + }; + +@@ -320,30 +272,7 @@ U_BOOT_DRIVER(stm32_copro) = { + .id = UCLASS_REMOTEPROC, + .ops = &stm32_copro_ops, + .probe = stm32_copro_probe, ++ .remove = stm32_copro_remove, + .priv_auto_alloc_size = sizeof(struct stm32_copro_privdata), +-}; +- +-static const struct dm_rproc_ops stm32_copro_optee_ops = { +- .load = stm32_copro_optee_load, +- .start = stm32_copro_optee_start, +- .stop = stm32_copro_optee_stop, +- .reset = stm32_copro_optee_reset, +- .is_running = stm32_copro_is_running, +- .device_to_virt = stm32_copro_device_to_virt, +-}; +- +-static const struct udevice_id stm32_copro_optee_ids[] = { +- { .compatible = "st,stm32mp1-m4_optee", .data = STM32MP15_M4_FW_ID }, +- {} +-}; +- +-U_BOOT_DRIVER(stm32_copro_optee) = { +- .name = "stm32_m4_proc_optee", +- .of_match = stm32_copro_optee_ids, +- .id = UCLASS_REMOTEPROC, +- .ops = &stm32_copro_optee_ops, +- .probe = stm32_copro_optee_probe, +- .remove = stm32_copro_optee_remove, +- .priv_auto_alloc_size = sizeof(struct rproc_optee), + .flags = DM_FLAG_OS_PREPARE, + }; +diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c +index 72a169e196..864ee96e77 100644 +--- a/drivers/spi/stm32_qspi.c ++++ b/drivers/spi/stm32_qspi.c +@@ -146,23 +146,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) { +- pr_err("cmd timeout (stat:%#x)\n", sr); +- } else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) { +- pr_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) { ++ pr_err("cmd timeout (stat:%#x)\n", sr); ++ } else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) { ++ pr_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/drivers/spi/stm32_spi.c b/drivers/spi/stm32_spi.c +index 4a0833b6fa..b2b1f9dcb8 100644 +--- a/drivers/spi/stm32_spi.c ++++ b/drivers/spi/stm32_spi.c +@@ -94,11 +94,14 @@ + #define SPI_SIMPLEX_RX 2 + #define SPI_HALF_DUPLEX 3 + +-struct stm32_spi_priv { ++struct stm32_spi_platdata { + void __iomem *base; + struct clk clk; + struct reset_ctl rst_ctl; + struct gpio_desc cs_gpios[MAX_CS_COUNT]; ++}; ++ ++struct stm32_spi_priv { + ulong bus_clk_rate; + unsigned int fifo_size; + unsigned int cur_bpw; +@@ -112,28 +115,32 @@ struct stm32_spi_priv { + bool cs_high; + }; + +-static void stm32_spi_write_txfifo(struct stm32_spi_priv *priv) ++static void stm32_spi_write_txfifo(struct udevice *bus) + { ++ struct stm32_spi_priv *priv = dev_get_priv(bus); ++ struct stm32_spi_platdata *plat = dev_get_platdata(bus); ++ void __iomem *base = plat->base; ++ + while ((priv->tx_len > 0) && +- (readl(priv->base + STM32_SPI_SR) & SPI_SR_TXP)) { ++ (readl(base + STM32_SPI_SR) & SPI_SR_TXP)) { + u32 offs = priv->cur_xferlen - priv->tx_len; + + if (priv->tx_len >= sizeof(u32) && + IS_ALIGNED((uintptr_t)(priv->tx_buf + offs), sizeof(u32))) { + const u32 *tx_buf32 = (const u32 *)(priv->tx_buf + offs); + +- writel(*tx_buf32, priv->base + STM32_SPI_TXDR); ++ writel(*tx_buf32, base + STM32_SPI_TXDR); + priv->tx_len -= sizeof(u32); + } else if (priv->tx_len >= sizeof(u16) && + IS_ALIGNED((uintptr_t)(priv->tx_buf + offs), sizeof(u16))) { + const u16 *tx_buf16 = (const u16 *)(priv->tx_buf + offs); + +- writew(*tx_buf16, priv->base + STM32_SPI_TXDR); ++ writew(*tx_buf16, base + STM32_SPI_TXDR); + priv->tx_len -= sizeof(u16); + } else { + const u8 *tx_buf8 = (const u8 *)(priv->tx_buf + offs); + +- writeb(*tx_buf8, priv->base + STM32_SPI_TXDR); ++ writeb(*tx_buf8, base + STM32_SPI_TXDR); + priv->tx_len -= sizeof(u8); + } + } +@@ -141,9 +148,12 @@ static void stm32_spi_write_txfifo(struct stm32_spi_priv *priv) + debug("%s: %d bytes left\n", __func__, priv->tx_len); + } + +-static void stm32_spi_read_rxfifo(struct stm32_spi_priv *priv) ++static void stm32_spi_read_rxfifo(struct udevice *bus) + { +- u32 sr = readl(priv->base + STM32_SPI_SR); ++ struct stm32_spi_priv *priv = dev_get_priv(bus); ++ struct stm32_spi_platdata *plat = dev_get_platdata(bus); ++ void __iomem *base = plat->base; ++ u32 sr = readl(base + STM32_SPI_SR); + u32 rxplvl = (sr & SPI_SR_RXPLVL) >> SPI_SR_RXPLVL_SHIFT; + + while ((priv->rx_len > 0) && +@@ -155,7 +165,7 @@ static void stm32_spi_read_rxfifo(struct stm32_spi_priv *priv) + (priv->rx_len >= sizeof(u32) || (sr & SPI_SR_RXWNE))) { + u32 *rx_buf32 = (u32 *)(priv->rx_buf + offs); + +- *rx_buf32 = readl(priv->base + STM32_SPI_RXDR); ++ *rx_buf32 = readl(base + STM32_SPI_RXDR); + priv->rx_len -= sizeof(u32); + } else if (IS_ALIGNED((uintptr_t)(priv->rx_buf + offs), sizeof(u16)) && + (priv->rx_len >= sizeof(u16) || +@@ -163,38 +173,38 @@ static void stm32_spi_read_rxfifo(struct stm32_spi_priv *priv) + (rxplvl >= 2 || priv->cur_bpw > 8)))) { + u16 *rx_buf16 = (u16 *)(priv->rx_buf + offs); + +- *rx_buf16 = readw(priv->base + STM32_SPI_RXDR); ++ *rx_buf16 = readw(base + STM32_SPI_RXDR); + priv->rx_len -= sizeof(u16); + } else { + u8 *rx_buf8 = (u8 *)(priv->rx_buf + offs); + +- *rx_buf8 = readb(priv->base + STM32_SPI_RXDR); ++ *rx_buf8 = readb(base + STM32_SPI_RXDR); + priv->rx_len -= sizeof(u8); + } + +- sr = readl(priv->base + STM32_SPI_SR); ++ sr = readl(base + STM32_SPI_SR); + rxplvl = (sr & SPI_SR_RXPLVL) >> SPI_SR_RXPLVL_SHIFT; + } + + debug("%s: %d bytes left\n", __func__, priv->rx_len); + } + +-static int stm32_spi_enable(struct stm32_spi_priv *priv) ++static int stm32_spi_enable(void __iomem *base) + { + debug("%s\n", __func__); + + /* Enable the SPI hardware */ +- setbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_SPE); ++ setbits_le32(base + STM32_SPI_CR1, SPI_CR1_SPE); + + return 0; + } + +-static int stm32_spi_disable(struct stm32_spi_priv *priv) ++static int stm32_spi_disable(void __iomem *base) + { + debug("%s\n", __func__); + + /* Disable the SPI hardware */ +- clrbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_SPE); ++ clrbits_le32(base + STM32_SPI_CR1, SPI_CR1_SPE); + + return 0; + } +@@ -202,45 +212,48 @@ static int stm32_spi_disable(struct stm32_spi_priv *priv) + static int stm32_spi_claim_bus(struct udevice *slave) + { + struct udevice *bus = dev_get_parent(slave); +- struct stm32_spi_priv *priv = dev_get_priv(bus); ++ struct stm32_spi_platdata *plat = dev_get_platdata(bus); ++ void __iomem *base = plat->base; + + debug("%s\n", __func__); + + /* Enable the SPI hardware */ +- return stm32_spi_enable(priv); ++ return stm32_spi_enable(base); + } + + static int stm32_spi_release_bus(struct udevice *slave) + { + struct udevice *bus = dev_get_parent(slave); +- struct stm32_spi_priv *priv = dev_get_priv(bus); ++ struct stm32_spi_platdata *plat = dev_get_platdata(bus); ++ void __iomem *base = plat->base; + + debug("%s\n", __func__); + + /* Disable the SPI hardware */ +- return stm32_spi_disable(priv); ++ return stm32_spi_disable(base); + } + + static void stm32_spi_stopxfer(struct udevice *dev) + { +- struct stm32_spi_priv *priv = dev_get_priv(dev); ++ struct stm32_spi_platdata *plat = dev_get_platdata(dev); ++ void __iomem *base = plat->base; + u32 cr1, sr; + int ret; + + debug("%s\n", __func__); + +- cr1 = readl(priv->base + STM32_SPI_CR1); ++ cr1 = readl(base + STM32_SPI_CR1); + + if (!(cr1 & SPI_CR1_SPE)) + return; + + /* Wait on EOT or suspend the flow */ +- ret = readl_poll_timeout(priv->base + STM32_SPI_SR, sr, ++ ret = readl_poll_timeout(base + STM32_SPI_SR, sr, + !(sr & SPI_SR_EOT), 100000); + if (ret < 0) { + if (cr1 & SPI_CR1_CSTART) { +- writel(cr1 | SPI_CR1_CSUSP, priv->base + STM32_SPI_CR1); +- if (readl_poll_timeout(priv->base + STM32_SPI_SR, ++ writel(cr1 | SPI_CR1_CSUSP, base + STM32_SPI_CR1); ++ if (readl_poll_timeout(base + STM32_SPI_SR, + sr, !(sr & SPI_SR_SUSP), + 100000) < 0) + dev_err(dev, "Suspend request timeout\n"); +@@ -248,11 +261,12 @@ static void stm32_spi_stopxfer(struct udevice *dev) + } + + /* clear status flags */ +- setbits_le32(priv->base + STM32_SPI_IFCR, SPI_IFCR_ALL); ++ setbits_le32(base + STM32_SPI_IFCR, SPI_IFCR_ALL); + } + + static int stm32_spi_set_cs(struct udevice *dev, unsigned int cs, bool enable) + { ++ struct stm32_spi_platdata *plat = dev_get_platdata(dev); + struct stm32_spi_priv *priv = dev_get_priv(dev); + + debug("%s: cs=%d enable=%d\n", __func__, cs, enable); +@@ -260,18 +274,20 @@ static int stm32_spi_set_cs(struct udevice *dev, unsigned int cs, bool enable) + if (cs >= MAX_CS_COUNT) + return -ENODEV; + +- if (!dm_gpio_is_valid(&priv->cs_gpios[cs])) ++ if (!dm_gpio_is_valid(&plat->cs_gpios[cs])) + return -EINVAL; + + if (priv->cs_high) + enable = !enable; + +- return dm_gpio_set_value(&priv->cs_gpios[cs], enable ? 1 : 0); ++ return dm_gpio_set_value(&plat->cs_gpios[cs], enable ? 1 : 0); + } + + static int stm32_spi_set_mode(struct udevice *bus, uint mode) + { + struct stm32_spi_priv *priv = dev_get_priv(bus); ++ struct stm32_spi_platdata *plat = dev_get_platdata(bus); ++ void __iomem *base = plat->base; + u32 cfg2_clrb = 0, cfg2_setb = 0; + + debug("%s: mode=%d\n", __func__, mode); +@@ -292,7 +308,7 @@ static int stm32_spi_set_mode(struct udevice *bus, uint mode) + cfg2_clrb |= SPI_CFG2_LSBFRST; + + if (cfg2_clrb || cfg2_setb) +- clrsetbits_le32(priv->base + STM32_SPI_CFG2, ++ clrsetbits_le32(base + STM32_SPI_CFG2, + cfg2_clrb, cfg2_setb); + + if (mode & SPI_CS_HIGH) +@@ -305,6 +321,8 @@ static int stm32_spi_set_mode(struct udevice *bus, uint mode) + static int stm32_spi_set_fthlv(struct udevice *dev, u32 xfer_len) + { + struct stm32_spi_priv *priv = dev_get_priv(dev); ++ struct stm32_spi_platdata *plat = dev_get_platdata(dev); ++ void __iomem *base = plat->base; + u32 fthlv, half_fifo; + + /* data packet should not exceed 1/2 of fifo space */ +@@ -318,7 +336,7 @@ static int stm32_spi_set_fthlv(struct udevice *dev, u32 xfer_len) + + if (!fthlv) + fthlv = 1; +- clrsetbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_FTHLV, ++ clrsetbits_le32(base + STM32_SPI_CFG1, SPI_CFG1_FTHLV, + (fthlv - 1) << SPI_CFG1_FTHLV_SHIFT); + + return 0; +@@ -327,6 +345,8 @@ static int stm32_spi_set_fthlv(struct udevice *dev, u32 xfer_len) + static int stm32_spi_set_speed(struct udevice *bus, uint hz) + { + struct stm32_spi_priv *priv = dev_get_priv(bus); ++ struct stm32_spi_platdata *plat = dev_get_platdata(bus); ++ void __iomem *base = plat->base; + u32 mbrdiv; + long div; + +@@ -350,7 +370,7 @@ static int stm32_spi_set_speed(struct udevice *bus, uint hz) + if (!mbrdiv) + return -EINVAL; + +- clrsetbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_MBR, ++ clrsetbits_le32(base + STM32_SPI_CFG1, SPI_CFG1_MBR, + (mbrdiv - 1) << SPI_CFG1_MBR_SHIFT); + + priv->cur_hz = hz; +@@ -364,6 +384,8 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen, + struct udevice *bus = dev_get_parent(slave); + struct dm_spi_slave_platdata *slave_plat; + struct stm32_spi_priv *priv = dev_get_priv(bus); ++ struct stm32_spi_platdata *plat = dev_get_platdata(bus); ++ void __iomem *base = plat->base; + u32 sr; + u32 ifcr = 0; + u32 xferlen; +@@ -373,7 +395,7 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen, + xferlen = bitlen / 8; + + if (xferlen <= SPI_CR2_TSIZE) +- writel(xferlen, priv->base + STM32_SPI_CR2); ++ writel(xferlen, base + STM32_SPI_CR2); + else + return -EMSGSIZE; + +@@ -393,15 +415,15 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen, + priv->cur_xferlen = xferlen; + + /* Disable the SPI hardware to unlock CFG1/CFG2 registers */ +- stm32_spi_disable(priv); ++ stm32_spi_disable(base); + +- clrsetbits_le32(priv->base + STM32_SPI_CFG2, SPI_CFG2_COMM, ++ clrsetbits_le32(base + STM32_SPI_CFG2, SPI_CFG2_COMM, + mode << SPI_CFG2_COMM_SHIFT); + + stm32_spi_set_fthlv(bus, xferlen); + + /* Enable the SPI hardware */ +- stm32_spi_enable(priv); ++ stm32_spi_enable(base); + } + + debug("%s: priv->tx_len=%d priv->rx_len=%d\n", __func__, +@@ -413,12 +435,12 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen, + + /* Be sure to have data in fifo before starting data transfer */ + if (priv->tx_buf) +- stm32_spi_write_txfifo(priv); ++ stm32_spi_write_txfifo(bus); + +- setbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_CSTART); ++ setbits_le32(base + STM32_SPI_CR1, SPI_CR1_CSTART); + + while (1) { +- sr = readl(priv->base + STM32_SPI_SR); ++ sr = readl(base + STM32_SPI_SR); + + if (sr & SPI_SR_OVR) { + dev_err(bus, "Overrun: RX data lost\n"); +@@ -430,7 +452,7 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen, + dev_warn(bus, "System too slow is limiting data throughput\n"); + + if (priv->rx_buf && priv->rx_len > 0) +- stm32_spi_read_rxfifo(priv); ++ stm32_spi_read_rxfifo(bus); + + ifcr |= SPI_SR_SUSP; + } +@@ -440,23 +462,23 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen, + + if (sr & SPI_SR_TXP) + if (priv->tx_buf && priv->tx_len > 0) +- stm32_spi_write_txfifo(priv); ++ stm32_spi_write_txfifo(bus); + + if (sr & SPI_SR_RXP) + if (priv->rx_buf && priv->rx_len > 0) +- stm32_spi_read_rxfifo(priv); ++ stm32_spi_read_rxfifo(bus); + + if (sr & SPI_SR_EOT) { + if (priv->rx_buf && priv->rx_len > 0) +- stm32_spi_read_rxfifo(priv); ++ stm32_spi_read_rxfifo(bus); + break; + } + +- writel(ifcr, priv->base + STM32_SPI_IFCR); ++ writel(ifcr, base + STM32_SPI_IFCR); + } + + /* clear status flags */ +- setbits_le32(priv->base + STM32_SPI_IFCR, SPI_IFCR_ALL); ++ setbits_le32(base + STM32_SPI_IFCR, SPI_IFCR_ALL); + stm32_spi_stopxfer(bus); + + if (flags & SPI_XFER_END) +@@ -467,42 +489,72 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen, + + static int stm32_spi_get_fifo_size(struct udevice *dev) + { +- struct stm32_spi_priv *priv = dev_get_priv(dev); ++ struct stm32_spi_platdata *plat = dev_get_platdata(dev); ++ void __iomem *base = plat->base; + u32 count = 0; + +- stm32_spi_enable(priv); ++ stm32_spi_enable(base); + +- while (readl(priv->base + STM32_SPI_SR) & SPI_SR_TXP) +- writeb(++count, priv->base + STM32_SPI_TXDR); ++ while (readl(base + STM32_SPI_SR) & SPI_SR_TXP) ++ writeb(++count, base + STM32_SPI_TXDR); + +- stm32_spi_disable(priv); ++ stm32_spi_disable(base); + + debug("%s %d x 8-bit fifo size\n", __func__, count); + + return count; + } + ++static int stm32_spi_ofdata_to_platdata(struct udevice *dev) ++{ ++ struct stm32_spi_platdata *plat = dev_get_platdata(dev); ++ int ret; ++ ++ plat->base = dev_read_addr_ptr(dev); ++ if (!plat->base) { ++ dev_err(dev, "can't get registers base address\n"); ++ return -ENOENT; ++ } ++ ++ ret = clk_get_by_index(dev, 0, &plat->clk); ++ if (ret < 0) ++ return ret; ++ ++ ret = reset_get_by_index(dev, 0, &plat->rst_ctl); ++ if (ret < 0) ++ goto clk_err; ++ ++ ret = gpio_request_list_by_name(dev, "cs-gpios", plat->cs_gpios, ++ ARRAY_SIZE(plat->cs_gpios), 0); ++ if (ret < 0) { ++ dev_err(dev, "Can't get %s cs gpios: %d", dev->name, ret); ++ ret = -ENOENT; ++ goto clk_err; ++ } ++ ++ return 0; ++ ++clk_err: ++ clk_free(&plat->clk); ++ ++ return ret; ++} ++ + static int stm32_spi_probe(struct udevice *dev) + { ++ struct stm32_spi_platdata *plat = dev_get_platdata(dev); + struct stm32_spi_priv *priv = dev_get_priv(dev); ++ void __iomem *base = plat->base; + unsigned long clk_rate; + int ret; + unsigned int i; + +- priv->base = dev_remap_addr(dev); +- if (!priv->base) +- return -EINVAL; +- + /* enable clock */ +- ret = clk_get_by_index(dev, 0, &priv->clk); ++ ret = clk_enable(&plat->clk); + if (ret < 0) + return ret; + +- ret = clk_enable(&priv->clk); +- if (ret < 0) +- return ret; +- +- clk_rate = clk_get_rate(&priv->clk); ++ clk_rate = clk_get_rate(&plat->clk); + if (!clk_rate) { + ret = -EINVAL; + goto clk_err; +@@ -511,46 +563,34 @@ static int stm32_spi_probe(struct udevice *dev) + priv->bus_clk_rate = clk_rate; + + /* perform reset */ +- ret = reset_get_by_index(dev, 0, &priv->rst_ctl); +- if (ret < 0) +- goto clk_err; +- +- reset_assert(&priv->rst_ctl); ++ reset_assert(&plat->rst_ctl); + udelay(2); +- reset_deassert(&priv->rst_ctl); +- +- ret = gpio_request_list_by_name(dev, "cs-gpios", priv->cs_gpios, +- ARRAY_SIZE(priv->cs_gpios), 0); +- if (ret < 0) { +- pr_err("Can't get %s cs gpios: %d", dev->name, ret); +- goto reset_err; +- } ++ reset_deassert(&plat->rst_ctl); + + priv->fifo_size = stm32_spi_get_fifo_size(dev); +- + priv->cur_mode = SPI_FULL_DUPLEX; + priv->cur_xferlen = 0; + priv->cur_bpw = SPI_DEFAULT_WORDLEN; +- clrsetbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_DSIZE, ++ clrsetbits_le32(base + STM32_SPI_CFG1, SPI_CFG1_DSIZE, + priv->cur_bpw - 1); + +- for (i = 0; i < ARRAY_SIZE(priv->cs_gpios); i++) { +- if (!dm_gpio_is_valid(&priv->cs_gpios[i])) ++ for (i = 0; i < ARRAY_SIZE(plat->cs_gpios); i++) { ++ if (!dm_gpio_is_valid(&plat->cs_gpios[i])) + continue; + +- dm_gpio_set_dir_flags(&priv->cs_gpios[i], ++ dm_gpio_set_dir_flags(&plat->cs_gpios[i], + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + } + + /* Ensure I2SMOD bit is kept cleared */ +- clrbits_le32(priv->base + STM32_SPI_I2SCFGR, SPI_I2SCFGR_I2SMOD); ++ clrbits_le32(base + STM32_SPI_I2SCFGR, SPI_I2SCFGR_I2SMOD); + + /* + * - SS input value high + * - transmitter half duplex direction + * - automatic communication suspend when RX-Fifo is full + */ +- setbits_le32(priv->base + STM32_SPI_CR1, ++ setbits_le32(base + STM32_SPI_CR1, + SPI_CR1_SSI | SPI_CR1_HDDIR | SPI_CR1_MASRX); + + /* +@@ -559,40 +599,38 @@ static int stm32_spi_probe(struct udevice *dev) + * SS input value is determined by the SSI bit + * - keep control of all associated GPIOs + */ +- setbits_le32(priv->base + STM32_SPI_CFG2, ++ setbits_le32(base + STM32_SPI_CFG2, + SPI_CFG2_MASTER | SPI_CFG2_SSM | SPI_CFG2_AFCNTR); + + return 0; + +-reset_err: +- reset_free(&priv->rst_ctl); +- + clk_err: +- clk_disable(&priv->clk); +- clk_free(&priv->clk); ++ clk_disable(&plat->clk); ++ clk_free(&plat->clk); + + return ret; + }; + + static int stm32_spi_remove(struct udevice *dev) + { +- struct stm32_spi_priv *priv = dev_get_priv(dev); ++ struct stm32_spi_platdata *plat = dev_get_platdata(dev); ++ void __iomem *base = plat->base; + int ret; + + stm32_spi_stopxfer(dev); +- stm32_spi_disable(priv); ++ stm32_spi_disable(base); + +- ret = reset_assert(&priv->rst_ctl); ++ ret = reset_assert(&plat->rst_ctl); + if (ret < 0) + return ret; + +- reset_free(&priv->rst_ctl); ++ reset_free(&plat->rst_ctl); + +- ret = clk_disable(&priv->clk); ++ ret = clk_disable(&plat->clk); + if (ret < 0) + return ret; + +- clk_free(&priv->clk); ++ clk_free(&plat->clk); + + return ret; + }; +@@ -615,6 +653,8 @@ U_BOOT_DRIVER(stm32_spi) = { + .id = UCLASS_SPI, + .of_match = stm32_spi_ids, + .ops = &stm32_spi_ops, ++ .ofdata_to_platdata = stm32_spi_ofdata_to_platdata, ++ .platdata_auto_alloc_size = sizeof(struct stm32_spi_platdata), + .priv_auto_alloc_size = sizeof(struct stm32_spi_priv), + .probe = stm32_spi_probe, + .remove = stm32_spi_remove, +diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c +index 650891e49d..2939e5d0a0 100644 +--- a/drivers/video/video-uclass.c ++++ b/drivers/video/video-uclass.c +@@ -210,6 +210,20 @@ void video_sync_all(void) + } + } + ++bool video_is_active(void) ++{ ++ struct udevice *dev; ++ ++ for (uclass_find_first_device(UCLASS_VIDEO, &dev); ++ dev; ++ uclass_find_next_device(&dev)) { ++ if (device_active(dev)) ++ return true; ++ } ++ ++ return false; ++} ++ + int video_get_xsize(struct udevice *dev) + { + struct video_priv *priv = dev_get_uclass_priv(dev); +diff --git a/include/configs/rpi.h b/include/configs/rpi.h +index 834f1cd236..86f59ae2a1 100644 +--- a/include/configs/rpi.h ++++ b/include/configs/rpi.h +@@ -65,7 +65,6 @@ + /* GPIO */ + #define CONFIG_BCM2835_GPIO + /* LCD */ +-#define CONFIG_LCD_DT_SIMPLEFB + #define CONFIG_VIDEO_BCM2835 + + #ifdef CONFIG_CMD_USB +diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h +index 32d0723d62..72424abb8b 100644 +--- a/include/configs/stm32mp1.h ++++ b/include/configs/stm32mp1.h +@@ -150,6 +150,7 @@ + #define CONFIG_EXTRA_ENV_SETTINGS \ + "kernel_addr_r=0xc2000000\0" \ + "fdt_addr_r=0xc4000000\0" \ ++ "fdtoverlay_addr_r=0xc4100000\0" \ + "scriptaddr=0xc4100000\0" \ + "pxefile_addr_r=0xc4200000\0" \ + "splashimage=0xc4300000\0" \ +diff --git a/include/dfu.h b/include/dfu.h +index 84abdc79ac..45f6fd9b40 100644 +--- a/include/dfu.h ++++ b/include/dfu.h +@@ -378,6 +378,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); + +diff --git a/include/fdt_simplefb.h b/include/fdt_simplefb.h +index 7cc305e1fd..2ac13a5131 100644 +--- a/include/fdt_simplefb.h ++++ b/include/fdt_simplefb.h +@@ -8,6 +8,7 @@ + + #ifndef _FDT_SIMPLEFB_H_ + #define _FDT_SIMPLEFB_H_ +-int lcd_dt_simplefb_add_node(void *blob); +-int lcd_dt_simplefb_enable_existing_node(void *blob); ++int fdt_simplefb_add_node(void *blob); ++int fdt_simplefb_add_node_and_mem_rsv(void *blob); ++int fdt_simplefb_enable_existing_node(void *blob); + #endif +diff --git a/include/video.h b/include/video.h +index 1a0ffd8037..39f36c32fd 100644 +--- a/include/video.h ++++ b/include/video.h +@@ -243,6 +243,13 @@ static inline int video_sync_copy(struct udevice *dev, void *from, void *to) + } + #endif + ++/** ++ * video_is_active() - Test if one video device it active ++ * ++ * @return true if at least one video device is active, else false. ++ */ ++bool video_is_active(void); ++ + #endif /* CONFIG_DM_VIDEO */ + + #ifndef CONFIG_DM_VIDEO +diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt +index bb6aef5ce4..04740122a0 100644 +--- a/scripts/config_whitelist.txt ++++ b/scripts/config_whitelist.txt +@@ -957,7 +957,6 @@ CONFIG_LBA48 + CONFIG_LBDAF + CONFIG_LCD_ALIGNMENT + CONFIG_LCD_BMP_RLE8 +-CONFIG_LCD_DT_SIMPLEFB + CONFIG_LCD_INFO + CONFIG_LCD_INFO_BELOW_LOGO + CONFIG_LCD_IN_PSRAM +-- +2.25.1 + diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0010-ARM-v2020.10-stm32mp-r2-DEVICETREE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0010-ARM-v2020.10-stm32mp-r2-DEVICETREE.patch new file mode 100644 index 0000000..77299e2 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0010-ARM-v2020.10-stm32mp-r2-DEVICETREE.patch @@ -0,0 +1,573 @@ +From bb83031bcca4f234206cc428cb9c79d9ec652ba6 Mon Sep 17 00:00:00 2001 +From: Lionel Vitte +Date: Mon, 18 Oct 2021 17:14:59 +0200 +Subject: [PATCH 10/11] ARM v2020.10-stm32mp-r2 DEVICETREE + +--- + arch/arm/dts/stm32f746.dtsi | 4 +++ + arch/arm/dts/stm32h743.dtsi | 4 +++ + arch/arm/dts/stm32mp15-m4-srm.dtsi | 8 +++++- + arch/arm/dts/stm32mp15-no-scmi.dtsi | 8 ++---- + arch/arm/dts/stm32mp15-pinctrl.dtsi | 4 +-- + arch/arm/dts/stm32mp151.dtsi | 35 ++++++++++++++++-------- + arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi | 4 +-- + arch/arm/dts/stm32mp157a-dk1.dts | 6 ---- + arch/arm/dts/stm32mp157a-ed1-u-boot.dtsi | 4 +-- + arch/arm/dts/stm32mp157a-ev1.dts | 5 ---- + arch/arm/dts/stm32mp157c-dk2.dts | 3 -- + arch/arm/dts/stm32mp157c-ev1.dts | 5 ---- + arch/arm/dts/stm32mp157d-dk1.dts | 6 ---- + arch/arm/dts/stm32mp157d-ev1.dts | 5 ---- + arch/arm/dts/stm32mp157f-dk2.dts | 3 -- + arch/arm/dts/stm32mp157f-ev1.dts | 5 ---- + arch/arm/dts/stm32mp15xx-dkx.dtsi | 23 ++++++++++++++-- + arch/arm/dts/stm32mp15xx-edx.dtsi | 8 +++++- + arch/arm/dts/stm32mp15xx-evx.dtsi | 12 +++++++- + 19 files changed, 85 insertions(+), 67 deletions(-) + +diff --git a/arch/arm/dts/stm32f746.dtsi b/arch/arm/dts/stm32f746.dtsi +index 3f312ab3a7..c32d2a81f1 100644 +--- a/arch/arm/dts/stm32f746.dtsi ++++ b/arch/arm/dts/stm32f746.dtsi +@@ -315,6 +315,7 @@ + clocks = <&rcc 1 CLK_I2C1>; + #address-cells = <1>; + #size-cells = <0>; ++ i2c-analog-filter; + status = "disabled"; + }; + +@@ -327,6 +328,7 @@ + clocks = <&rcc 1 CLK_I2C2>; + #address-cells = <1>; + #size-cells = <0>; ++ i2c-analog-filter; + status = "disabled"; + }; + +@@ -339,6 +341,7 @@ + clocks = <&rcc 1 CLK_I2C3>; + #address-cells = <1>; + #size-cells = <0>; ++ i2c-analog-filter; + status = "disabled"; + }; + +@@ -351,6 +354,7 @@ + clocks = <&rcc 1 CLK_I2C4>; + #address-cells = <1>; + #size-cells = <0>; ++ i2c-analog-filter; + status = "disabled"; + }; + +diff --git a/arch/arm/dts/stm32h743.dtsi b/arch/arm/dts/stm32h743.dtsi +index 4b4e7a99f7..5964f7b238 100644 +--- a/arch/arm/dts/stm32h743.dtsi ++++ b/arch/arm/dts/stm32h743.dtsi +@@ -106,6 +106,7 @@ + <32>; + resets = <&rcc STM32H7_APB1L_RESET(I2C1)>; + clocks = <&rcc I2C1_CK>; ++ i2c-analog-filter; + status = "disabled"; + }; + +@@ -118,6 +119,7 @@ + <34>; + resets = <&rcc STM32H7_APB1L_RESET(I2C2)>; + clocks = <&rcc I2C2_CK>; ++ i2c-analog-filter; + status = "disabled"; + }; + +@@ -130,6 +132,7 @@ + <73>; + resets = <&rcc STM32H7_APB1L_RESET(I2C3)>; + clocks = <&rcc I2C3_CK>; ++ i2c-analog-filter; + status = "disabled"; + }; + +@@ -349,6 +352,7 @@ + <96>; + resets = <&rcc STM32H7_APB4_RESET(I2C4)>; + clocks = <&rcc I2C4_CK>; ++ i2c-analog-filter; + status = "disabled"; + }; + +diff --git a/arch/arm/dts/stm32mp15-m4-srm.dtsi b/arch/arm/dts/stm32mp15-m4-srm.dtsi +index 60454aee41..3162c35950 100644 +--- a/arch/arm/dts/stm32mp15-m4-srm.dtsi ++++ b/arch/arm/dts/stm32mp15-m4-srm.dtsi +@@ -177,7 +177,7 @@ + reg = <0x40016000 0x400>; + interrupt-parent = <&exti>; + interrupts = <69 1>; +- clocks = <&rcc CEC_K>, <&scmi0_clk CK_SCMI0_LSE>; ++ clocks = <&rcc CEC_K>, <&rcc CEC>; + clock-names = "cec", "hdmi-cec"; + status = "disabled"; + }; +@@ -415,6 +415,12 @@ + clocks = <&rcc SAI4_K>; + clock-names = "sai_ck"; + status = "disabled"; ++ }; ++ m4_fmc: memory-controller@58002000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x5800200 0x1000>; ++ clocks = <&rcc FMC_K>; ++ status = "disabled"; + }; + m4_qspi: qspi@58003000 { + compatible = "rproc-srm-dev"; +diff --git a/arch/arm/dts/stm32mp15-no-scmi.dtsi b/arch/arm/dts/stm32mp15-no-scmi.dtsi +index 94a10b86a1..c7d2d7c8f5 100644 +--- a/arch/arm/dts/stm32mp15-no-scmi.dtsi ++++ b/arch/arm/dts/stm32mp15-no-scmi.dtsi +@@ -79,10 +79,6 @@ + resets = <&rcc MCU_R>, <&rcc MCU_HOLD_BOOT_R>; + + m4_system_resources { +- m4_cec: cec@40016000 { +- clocks = <&rcc CEC_K>, <&rcc CK_LSE>; +- }; +- + m4_m_can1: can@4400e000 { + clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; + }; +@@ -101,8 +97,8 @@ + /delete-node/ sram@2ffff000; + }; + +-&cec { +- clocks = <&rcc CEC_K>, <&clk_lse>; ++&bsec { ++ clocks = <&rcc BSEC>; + }; + + &gpioz { +diff --git a/arch/arm/dts/stm32mp15-pinctrl.dtsi b/arch/arm/dts/stm32mp15-pinctrl.dtsi +index a0b76e238c..236d77e09c 100644 +--- a/arch/arm/dts/stm32mp15-pinctrl.dtsi ++++ b/arch/arm/dts/stm32mp15-pinctrl.dtsi +@@ -1937,7 +1937,7 @@ + ; /* USART2_RTS */ + bias-disable; + drive-push-pull; +- slew-rate = <3>; ++ slew-rate = <0>; + }; + pins2 { + pinmux = , /* USART2_RX */ +@@ -1955,7 +1955,7 @@ + pinmux = ; /* USART2_RTS */ + bias-disable; + drive-push-pull; +- slew-rate = <3>; ++ slew-rate = <0>; + }; + pins3 { + pinmux = ; /* USART2_RX */ +diff --git a/arch/arm/dts/stm32mp151.dtsi b/arch/arm/dts/stm32mp151.dtsi +index ca71139f3a..ab5723c472 100644 +--- a/arch/arm/dts/stm32mp151.dtsi ++++ b/arch/arm/dts/stm32mp151.dtsi +@@ -647,7 +647,7 @@ + compatible = "st,stm32-cec"; + reg = <0x40016000 0x400>; + interrupts = ; +- clocks = <&rcc CEC_K>, <&scmi0_clk CK_SCMI0_LSE>; ++ clocks = <&rcc CEC_K>, <&rcc CEC>; + clock-names = "cec", "hdmi-cec"; + status = "disabled"; + }; +@@ -1181,6 +1181,8 @@ + interrupts = <1>; + dmas = <&dmamux1 10 0x400 0x80000001>; + dma-names = "rx"; ++ nvmem-cells = <&vrefint>; ++ nvmem-cell-names = "vrefint"; + status = "disabled"; + }; + }; +@@ -1212,6 +1214,7 @@ + g-np-tx-fifo-size = <32>; + g-tx-fifo-size = <256 16 16 16 16 16 16 16>; + dr_mode = "otg"; ++ otg-rev = <0x200>; + usb33d-supply = <&usb33>; + power-domains = <&pd_core>; + wakeup-source; +@@ -1266,6 +1269,7 @@ + <&scmi0_clk CK_SCMI0_CSI>, + <&scmi0_clk CK_SCMI0_LSE>, + <&scmi0_clk CK_SCMI0_LSI>; ++ clocks-boot-on = ; + }; + + pwr_regulators: pwr@50001000 { +@@ -1574,8 +1578,8 @@ + reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; + reg-names = "qspi", "qspi_mm"; + interrupts = ; +- dmas = <&mdma1 22 0x2 0x100002 0x0 0x0 0x0>, +- <&mdma1 22 0x2 0x100008 0x0 0x0 0x0>; ++ dmas = <&mdma1 22 0x2 0x10100002 0x0 0x0 0x0>, ++ <&mdma1 22 0x2 0x10100008 0x0 0x0 0x0>; + dma-names = "tx", "rx"; + clocks = <&rcc QSPI_K>; + resets = <&rcc QSPI_R>; +@@ -1621,12 +1625,6 @@ + status = "disabled"; + }; + +- stmmac_axi_config_0: stmmac-axi-config { +- snps,wr_osr_lmt = <0x7>; +- snps,rd_osr_lmt = <0x7>; +- snps,blen = <0 0 0 0 16 8 4>; +- }; +- + ethernet0: ethernet@5800a000 { + compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; + reg = <0x5800a000 0x2000>; +@@ -1639,12 +1637,14 @@ + "mac-clk-tx", + "mac-clk-rx", + "eth-ck", +- "ethstp"; ++ "ethstp", ++ "ptp_ref"; + clocks = <&rcc ETHMAC>, + <&rcc ETHTX>, + <&rcc ETHRX>, + <&rcc ETHCK_K>, +- <&rcc ETHSTP>; ++ <&rcc ETHSTP>, ++ <&rcc ETHPTP_K>; + st,syscon = <&syscfg 0x4>; + snps,mixed-burst; + snps,pbl = <2>; +@@ -1653,12 +1653,18 @@ + snps,tso; + power-domains = <&pd_core>; + status = "disabled"; ++ ++ stmmac_axi_config_0: stmmac-axi-config { ++ snps,wr_osr_lmt = <0x7>; ++ snps,rd_osr_lmt = <0x7>; ++ snps,blen = <0 0 0 0 16 8 4>; ++ }; + }; + + usbh_ohci: usbh-ohci@5800c000 { + compatible = "generic-ohci"; + reg = <0x5800c000 0x1000>; +- clocks = <&rcc USBH>; ++ clocks = <&rcc USBH>, <&usbphyc>; + resets = <&rcc USBH_R>; + interrupts = ; + status = "disabled"; +@@ -1728,6 +1734,7 @@ + reg = <0x5a007000 0x400>; + clocks = <&rcc DDRPERFM>; + resets = <&rcc DDRPERFM_R>; ++ status = "disabled"; + }; + + usart1: serial@5c000000 { +@@ -1789,11 +1796,15 @@ + bsec: efuse@5c005000 { + compatible = "st,stm32mp15-bsec"; + reg = <0x5c005000 0x400>; ++ clocks = <&scmi0_clk CK_SCMI0_BSEC>; + #address-cells = <1>; + #size-cells = <1>; + part_number_otp: part_number_otp@4 { + reg = <0x4 0x1>; + }; ++ vrefint: calib@52 { ++ reg = <0x52 0x2>; ++ }; + ts_cal1: calib@5c { + reg = <0x5c 0x2>; + }; +diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi +index 8553570642..06267f2917 100644 +--- a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi ++++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi +@@ -18,8 +18,8 @@ + u-boot,error-led = "error"; + u-boot,mmc-env-partition = "fip"; + st,adc_usb_pd = <&adc1 18>, <&adc1 19>; +- st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; +- st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; ++ st,fastboot-gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ st,stm32prog-gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + }; + + #ifdef CONFIG_STM32MP15x_STM32IMAGE +diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts +index f415e581a6..f48207dad5 100644 +--- a/arch/arm/dts/stm32mp157a-dk1.dts ++++ b/arch/arm/dts/stm32mp157a-dk1.dts +@@ -16,12 +16,6 @@ + model = "STMicroelectronics STM32MP157A-DK1 Discovery Board"; + compatible = "st,stm32mp157a-dk1", "st,stm32mp157"; + +- aliases { +- serial0 = &uart4; +- serial1 = &usart3; +- serial2 = &uart7; +- }; +- + chosen { + stdout-path = "serial0:115200n8"; + }; +diff --git a/arch/arm/dts/stm32mp157a-ed1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-ed1-u-boot.dtsi +index f0761901a6..5b9772a0a9 100644 +--- a/arch/arm/dts/stm32mp157a-ed1-u-boot.dtsi ++++ b/arch/arm/dts/stm32mp157a-ed1-u-boot.dtsi +@@ -18,8 +18,8 @@ + u-boot,boot-led = "heartbeat"; + u-boot,error-led = "error"; + u-boot,mmc-env-partition = "fip"; +- st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; +- st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; ++ st,fastboot-gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ st,stm32prog-gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + }; + + led { +diff --git a/arch/arm/dts/stm32mp157a-ev1.dts b/arch/arm/dts/stm32mp157a-ev1.dts +index 11bd88a82f..85c73a916c 100644 +--- a/arch/arm/dts/stm32mp157a-ev1.dts ++++ b/arch/arm/dts/stm32mp157a-ev1.dts +@@ -15,11 +15,6 @@ + chosen { + stdout-path = "serial0:115200n8"; + }; +- +- aliases { +- serial0 = &uart4; +- serial1 = &usart3; +- }; + }; + + <dc { +diff --git a/arch/arm/dts/stm32mp157c-dk2.dts b/arch/arm/dts/stm32mp157c-dk2.dts +index 1c894f288c..53d75e1c25 100644 +--- a/arch/arm/dts/stm32mp157c-dk2.dts ++++ b/arch/arm/dts/stm32mp157c-dk2.dts +@@ -18,9 +18,6 @@ + compatible = "st,stm32mp157c-dk2", "st,stm32mp157"; + + aliases { +- serial0 = &uart4; +- serial1 = &usart3; +- serial2 = &uart7; + serial3 = &usart2; + }; + +diff --git a/arch/arm/dts/stm32mp157c-ev1.dts b/arch/arm/dts/stm32mp157c-ev1.dts +index e84897ef44..3dd1244121 100644 +--- a/arch/arm/dts/stm32mp157c-ev1.dts ++++ b/arch/arm/dts/stm32mp157c-ev1.dts +@@ -15,11 +15,6 @@ + chosen { + stdout-path = "serial0:115200n8"; + }; +- +- aliases { +- serial0 = &uart4; +- serial1 = &usart3; +- }; + }; + + <dc { +diff --git a/arch/arm/dts/stm32mp157d-dk1.dts b/arch/arm/dts/stm32mp157d-dk1.dts +index bcc012cfff..d54dcf16a7 100644 +--- a/arch/arm/dts/stm32mp157d-dk1.dts ++++ b/arch/arm/dts/stm32mp157d-dk1.dts +@@ -16,12 +16,6 @@ + model = "STMicroelectronics STM32MP157D-DK1 Discovery Board"; + compatible = "st,stm32mp157d-dk1", "st,stm32mp157"; + +- aliases { +- serial0 = &uart4; +- serial1 = &usart3; +- serial2 = &uart7; +- }; +- + chosen { + stdout-path = "serial0:115200n8"; + }; +diff --git a/arch/arm/dts/stm32mp157d-ev1.dts b/arch/arm/dts/stm32mp157d-ev1.dts +index 5cb08c7079..dbb2b3e059 100644 +--- a/arch/arm/dts/stm32mp157d-ev1.dts ++++ b/arch/arm/dts/stm32mp157d-ev1.dts +@@ -15,11 +15,6 @@ + chosen { + stdout-path = "serial0:115200n8"; + }; +- +- aliases { +- serial0 = &uart4; +- serial1 = &usart3; +- }; + }; + + <dc { +diff --git a/arch/arm/dts/stm32mp157f-dk2.dts b/arch/arm/dts/stm32mp157f-dk2.dts +index 15a397c4cf..1244ae1841 100644 +--- a/arch/arm/dts/stm32mp157f-dk2.dts ++++ b/arch/arm/dts/stm32mp157f-dk2.dts +@@ -18,9 +18,6 @@ + compatible = "st,stm32mp157f-dk2", "st,stm32mp157"; + + aliases { +- serial0 = &uart4; +- serial1 = &usart3; +- serial2 = &uart7; + serial3 = &usart2; + }; + +diff --git a/arch/arm/dts/stm32mp157f-ev1.dts b/arch/arm/dts/stm32mp157f-ev1.dts +index 6fe600f813..0ef17cdc63 100644 +--- a/arch/arm/dts/stm32mp157f-ev1.dts ++++ b/arch/arm/dts/stm32mp157f-ev1.dts +@@ -16,11 +16,6 @@ + chosen { + stdout-path = "serial0:115200n8"; + }; +- +- aliases { +- serial0 = &uart4; +- serial1 = &usart3; +- }; + }; + + <dc { +diff --git a/arch/arm/dts/stm32mp15xx-dkx.dtsi b/arch/arm/dts/stm32mp15xx-dkx.dtsi +index acff8755d3..884c538fcb 100644 +--- a/arch/arm/dts/stm32mp15xx-dkx.dtsi ++++ b/arch/arm/dts/stm32mp15xx-dkx.dtsi +@@ -12,6 +12,9 @@ + / { + aliases { + ethernet0 = ðernet0; ++ serial0 = &uart4; ++ serial1 = &usart3; ++ serial2 = &uart7; + }; + + memory@c0000000 { +@@ -48,6 +51,12 @@ + no-map; + }; + ++ mcu_rsc_table: mcu_rsc_table@10048000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10048000 0x8000>; ++ no-map; ++ }; ++ + mcuram: mcuram@30000000 { + compatible = "shared-dma-pool"; + reg = <0x30000000 0x40000>; +@@ -284,7 +293,7 @@ + stusb1600@28 { + compatible = "st,stusb1600"; + reg = <0x28>; +- interrupts = <11 IRQ_TYPE_EDGE_FALLING>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + interrupt-parent = <&gpioi>; + pinctrl-names = "default"; + pinctrl-0 = <&stusb1600_pins_a>; +@@ -505,7 +514,7 @@ + + &m4_rproc { + memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, +- <&vdev0vring1>, <&vdev0buffer>; ++ <&vdev0vring1>, <&vdev0buffer>, <&mcu_rsc_table>; + mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; + mbox-names = "vq0", "vq1", "shutdown"; + interrupt-parent = <&exti>; +@@ -755,6 +764,16 @@ + &usbphyc_port0 { + phy-supply = <&vdd_usb>; + st,phy-tuning = <&usb_phy_tuning>; ++ ++ /* ++ * Hack to keep hub active until all connected devices are suspended ++ * otherwise the hub will be powered off as soon as the v3v3 is disabled ++ * and it can disturb connected devices. ++ */ ++ connector { ++ compatible = "usb-a-connector"; ++ vbus-supply = <&v3v3>; ++ }; + }; + + &usbphyc_port1 { +diff --git a/arch/arm/dts/stm32mp15xx-edx.dtsi b/arch/arm/dts/stm32mp15xx-edx.dtsi +index 3662f449de..817982009c 100644 +--- a/arch/arm/dts/stm32mp15xx-edx.dtsi ++++ b/arch/arm/dts/stm32mp15xx-edx.dtsi +@@ -44,6 +44,12 @@ + no-map; + }; + ++ mcu_rsc_table: mcu_rsc_table@10048000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10048000 0x8000>; ++ no-map; ++ }; ++ + mcuram: mcuram@30000000 { + compatible = "shared-dma-pool"; + reg = <0x30000000 0x40000>; +@@ -315,7 +321,7 @@ + + &m4_rproc { + memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, +- <&vdev0vring1>, <&vdev0buffer>; ++ <&vdev0vring1>, <&vdev0buffer>, <&mcu_rsc_table>; + mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; + mbox-names = "vq0", "vq1", "shutdown"; + interrupt-parent = <&exti>; +diff --git a/arch/arm/dts/stm32mp15xx-evx.dtsi b/arch/arm/dts/stm32mp15xx-evx.dtsi +index 47a2c8e5ea..a7589d9d73 100644 +--- a/arch/arm/dts/stm32mp15xx-evx.dtsi ++++ b/arch/arm/dts/stm32mp15xx-evx.dtsi +@@ -10,6 +10,7 @@ + / { + aliases { + ethernet0 = ðernet0; ++ serial1 = &usart3; + }; + + clocks { +@@ -678,7 +679,16 @@ + + &usbphyc_port0 { + st,phy-tuning = <&usb_phy_tuning>; +- vbus-supply = <&vbus_sw>; ++ ++ /* ++ * Hack to keep hub active until all connected devices are suspended ++ * otherwise the hub will be powered off as soon as the v3v3 is disabled ++ * and it can disturb connected devices. ++ */ ++ connector { ++ compatible = "usb-a-connector"; ++ vbus-supply = <&v3v3>; ++ }; + }; + + &usbphyc_port1 { +-- +2.25.1 + diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0011-ARM-v2020.10-stm32mp-r2-CONFIG.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0011-ARM-v2020.10-stm32mp-r2-CONFIG.patch new file mode 100644 index 0000000..88a211f --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0011-ARM-v2020.10-stm32mp-r2-CONFIG.patch @@ -0,0 +1,186 @@ +From e1969811c8ae2c4874734aab703ff54ba1fe5206 Mon Sep 17 00:00:00 2001 +From: Lionel Vitte +Date: Mon, 18 Oct 2021 17:12:48 +0200 +Subject: [PATCH 11/11] ARM v2020.10-stm32mp-r2 CONFIG + +--- + configs/rpi_0_w_defconfig | 1 + + configs/rpi_2_defconfig | 1 + + configs/rpi_3_32b_defconfig | 1 + + configs/rpi_3_b_plus_defconfig | 1 + + configs/rpi_3_defconfig | 1 + + configs/rpi_4_32b_defconfig | 1 + + configs/rpi_4_defconfig | 1 + + configs/rpi_arm64_defconfig | 1 + + configs/rpi_defconfig | 1 + + configs/stm32mp15_basic_defconfig | 3 +++ + configs/stm32mp15_trusted_defconfig | 3 +++ + 11 files changed, 15 insertions(+) + +diff --git a/configs/rpi_0_w_defconfig b/configs/rpi_0_w_defconfig +index bba5e12b12..ed0707ea21 100644 +--- a/configs/rpi_0_w_defconfig ++++ b/configs/rpi_0_w_defconfig +@@ -12,6 +12,7 @@ CONFIG_USE_PREBOOT=y + CONFIG_MISC_INIT_R=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set ++CONFIG_FDT_SIMPLEFB=y + CONFIG_SYS_PROMPT="U-Boot> " + CONFIG_CMD_GPIO=y + CONFIG_CMD_MMC=y +diff --git a/configs/rpi_2_defconfig b/configs/rpi_2_defconfig +index 1c2bbb29ce..1bbb2adf36 100644 +--- a/configs/rpi_2_defconfig ++++ b/configs/rpi_2_defconfig +@@ -12,6 +12,7 @@ CONFIG_USE_PREBOOT=y + CONFIG_MISC_INIT_R=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set ++CONFIG_FDT_SIMPLEFB=y + CONFIG_SYS_PROMPT="U-Boot> " + CONFIG_CMD_GPIO=y + CONFIG_CMD_MMC=y +diff --git a/configs/rpi_3_32b_defconfig b/configs/rpi_3_32b_defconfig +index b8a3d17f43..c3f1e4a2db 100644 +--- a/configs/rpi_3_32b_defconfig ++++ b/configs/rpi_3_32b_defconfig +@@ -13,6 +13,7 @@ CONFIG_USE_PREBOOT=y + CONFIG_MISC_INIT_R=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set ++CONFIG_FDT_SIMPLEFB=y + CONFIG_SYS_PROMPT="U-Boot> " + CONFIG_CMD_GPIO=y + CONFIG_CMD_MMC=y +diff --git a/configs/rpi_3_b_plus_defconfig b/configs/rpi_3_b_plus_defconfig +index 4c361438fa..6fd55a8e45 100644 +--- a/configs/rpi_3_b_plus_defconfig ++++ b/configs/rpi_3_b_plus_defconfig +@@ -13,6 +13,7 @@ CONFIG_USE_PREBOOT=y + CONFIG_MISC_INIT_R=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set ++CONFIG_FDT_SIMPLEFB=y + CONFIG_SYS_PROMPT="U-Boot> " + CONFIG_CMD_GPIO=y + CONFIG_CMD_MMC=y +diff --git a/configs/rpi_3_defconfig b/configs/rpi_3_defconfig +index 9b281a4f15..08db309452 100644 +--- a/configs/rpi_3_defconfig ++++ b/configs/rpi_3_defconfig +@@ -13,6 +13,7 @@ CONFIG_USE_PREBOOT=y + CONFIG_MISC_INIT_R=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set ++CONFIG_FDT_SIMPLEFB=y + CONFIG_SYS_PROMPT="U-Boot> " + CONFIG_CMD_GPIO=y + CONFIG_CMD_MMC=y +diff --git a/configs/rpi_4_32b_defconfig b/configs/rpi_4_32b_defconfig +index 4a88448e9d..05bd355d5b 100644 +--- a/configs/rpi_4_32b_defconfig ++++ b/configs/rpi_4_32b_defconfig +@@ -11,6 +11,7 @@ CONFIG_PREBOOT="pci enum; usb start;" + CONFIG_MISC_INIT_R=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set ++CONFIG_FDT_SIMPLEFB=y + CONFIG_SYS_PROMPT="U-Boot> " + CONFIG_CMD_DFU=y + CONFIG_CMD_GPIO=y +diff --git a/configs/rpi_4_defconfig b/configs/rpi_4_defconfig +index 71f95ed8f7..367abb5bac 100644 +--- a/configs/rpi_4_defconfig ++++ b/configs/rpi_4_defconfig +@@ -11,6 +11,7 @@ CONFIG_PREBOOT="pci enum; usb start;" + CONFIG_MISC_INIT_R=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set ++CONFIG_FDT_SIMPLEFB=y + CONFIG_SYS_PROMPT="U-Boot> " + CONFIG_CMD_DFU=y + CONFIG_CMD_GPIO=y +diff --git a/configs/rpi_arm64_defconfig b/configs/rpi_arm64_defconfig +index 4ce8469f43..cb1513bb31 100644 +--- a/configs/rpi_arm64_defconfig ++++ b/configs/rpi_arm64_defconfig +@@ -11,6 +11,7 @@ CONFIG_PREBOOT="pci enum; usb start;" + CONFIG_MISC_INIT_R=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set ++CONFIG_FDT_SIMPLEFB=y + CONFIG_SYS_PROMPT="U-Boot> " + CONFIG_CMD_GPIO=y + CONFIG_CMD_MMC=y +diff --git a/configs/rpi_defconfig b/configs/rpi_defconfig +index b5ad53c37b..4722f161c9 100644 +--- a/configs/rpi_defconfig ++++ b/configs/rpi_defconfig +@@ -12,6 +12,7 @@ CONFIG_USE_PREBOOT=y + CONFIG_MISC_INIT_R=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set ++CONFIG_FDT_SIMPLEFB=y + CONFIG_SYS_PROMPT="U-Boot> " + CONFIG_CMD_GPIO=y + CONFIG_CMD_MMC=y +diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig +index c08d06474b..c90220a60d 100644 +--- a/configs/stm32mp15_basic_defconfig ++++ b/configs/stm32mp15_basic_defconfig +@@ -8,6 +8,7 @@ CONFIG_SPL_DM_SPI=y + CONFIG_SPL_TEXT_BASE=0x2FFC2500 + CONFIG_SPL_MMC_SUPPORT=y + CONFIG_SPL=y ++CONFIG_CMD_STM32KEY=y + CONFIG_TARGET_ST_STM32MP15x=y + CONFIG_CMD_STM32PROG=y + CONFIG_TYPEC_STUSB160X=y +@@ -29,6 +30,7 @@ CONFIG_SPL_MTD_SUPPORT=y + CONFIG_SPL_DM_SPI_FLASH=y + CONFIG_SPL_POWER_SUPPORT=y + CONFIG_SPL_SPI_FLASH_MTD=y ++CONFIG_FDT_SIMPLEFB=y + CONFIG_SYS_PROMPT="STM32MP> " + CONFIG_CMD_ADTIMG=y + # CONFIG_CMD_ELF is not set +@@ -51,6 +53,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y + CONFIG_CMD_BMP=y + CONFIG_CMD_CACHE=y + CONFIG_CMD_TIME=y ++CONFIG_CMD_RNG=y + CONFIG_CMD_TIMER=y + CONFIG_CMD_PMIC=y + CONFIG_CMD_REGULATOR=y +diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig +index 5b4cfc4ca3..2161ccbefa 100644 +--- a/configs/stm32mp15_trusted_defconfig ++++ b/configs/stm32mp15_trusted_defconfig +@@ -4,6 +4,7 @@ CONFIG_TFABOOT=y + CONFIG_SYS_MALLOC_F_LEN=0x3000 + CONFIG_ENV_OFFSET=0x480000 + CONFIG_ENV_SECT_SIZE=0x40000 ++CONFIG_CMD_STM32KEY=y + CONFIG_TARGET_ST_STM32MP15x=y + CONFIG_CMD_STM32PROG=y + CONFIG_TYPEC_STUSB160X=y +@@ -13,6 +14,7 @@ CONFIG_DISTRO_DEFAULTS=y + CONFIG_FIT=y + CONFIG_BOOTDELAY=1 + CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" ++CONFIG_FDT_SIMPLEFB=y + CONFIG_SYS_PROMPT="STM32MP> " + CONFIG_CMD_ADTIMG=y + # CONFIG_CMD_ELF is not set +@@ -35,6 +37,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y + CONFIG_CMD_BMP=y + CONFIG_CMD_CACHE=y + CONFIG_CMD_TIME=y ++CONFIG_CMD_RNG=y + CONFIG_CMD_TIMER=y + CONFIG_CMD_PMIC=y + CONFIG_CMD_REGULATOR=y +-- +2.25.1 +