diff --git a/recipes-bsp/u-boot/u-boot-stm32mp-archiver.inc b/recipes-bsp/u-boot/u-boot-stm32mp-archiver.inc index da4b920..0e4a3c7 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp-archiver.inc +++ b/recipes-bsp/u-boot/u-boot-stm32mp-archiver.inc @@ -69,9 +69,6 @@ CPPFLAGS = UBOOT_LOCALVERSION = ${UBOOT_LOCALVERSION} -# Configure default fip feature -ENABLE_FIP ?= ${@bb.utils.contains('MACHINE_FEATURES','fip','1','',d)} - # Display U-Boot config details define uboot-configs echo " \$(1)" ; \\ @@ -85,11 +82,6 @@ endef # Configure U-Boot configure rules (configure-DEFCONFIG-CONFIG) define configure-rules configure-\$(1)-\$(2): version -ifeq (\$(ENABLE_FIP),0) - @if ! grep -q 'CONFIG_STM32MP15x_STM32IMAGE=y' \$(SRC_PATH)/configs/\$(1); then \\ - echo "CONFIG_STM32MP15x_STM32IMAGE=y" >> \$(SRC_PATH)/configs/\$(1) ; \\ - fi -endif @mkdir -p \$(BLD_PATH)/\$(1) @echo \$(UBOOT_LOCALVERSION) > \$(BLD_PATH)/\$(1)/.scmversion \$(MAKE) -C \$(SRC_PATH) O=\$(BLD_PATH)/\$(1) \$(1) @@ -139,9 +131,7 @@ deploy-targets := \$(foreach config, \$(if \$(UBOOT_CONFIG),\$(UBOOT_CONFIG),\$( # Set dependencies list for building all DEPS = \$(deploy-targets) -ifeq (\$(ENABLE_FIP), 1) DEPS += fip -endif help: @echo @@ -161,10 +151,7 @@ help: @echo " DEPLOYDIR = \$(DEPLOYDIR)" @echo @echo "FIP configuration:" - @echo " ENABLE_FIP = \$(ENABLE_FIP) ('1' to generate fip binary)" -ifeq (\$(ENABLE_FIP),1) @echo " Do not forget to set FIP deploydir folders (such as FIP_DEPLOYDIR_ROOT) to provide path to needed binaries" -endif @echo @echo "Available targets:" @echo " all : build U-Boot binaries for defined config(s)" diff --git a/recipes-bsp/u-boot/u-boot-stm32mp-common_2020.10.inc b/recipes-bsp/u-boot/u-boot-stm32mp-common_2021.10.inc similarity index 67% rename from recipes-bsp/u-boot/u-boot-stm32mp-common_2020.10.inc rename to recipes-bsp/u-boot/u-boot-stm32mp-common_2021.10.inc index 16873d2..7db3cdc 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp-common_2020.10.inc +++ b/recipes-bsp/u-boot/u-boot-stm32mp-common_2021.10.inc @@ -8,25 +8,19 @@ LIC_FILES_CHKSUM = "file://Licenses/README;md5=5a7450c57ffe5ae63fd732446b988025" DEPENDS += "dtc-native bc-native" DEPENDS += "flex-native bison-native" +DEPENDS += "python3-setuptools-native" COMPATIBLE_MACHINE = "(stm32mpcommon)" SRC_URI = "git://github.com/u-boot/u-boot.git;protocol=https;branch=master" -SRCREV = "050acee119b3757fee3bd128f55d720fdd9bb890" +SRCREV = "d80bb749fab53da72c4a0e09b8c2d2aaa3103c91" SRC_URI += "\ - file://0001-ARM-v2020.10-stm32mp-r1-MACHINE.patch \ - file://0002-ARM-v2020.10-stm32mp-r1-BOARD.patch \ - file://0003-ARM-v2020.10-stm32mp-r1-MISC-DRIVERS.patch \ - 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://0001-ARM-v2021.10-stm32mp-r1-MACHINE.patch \ + file://0002-ARM-v2021.10-stm32mp-r1-BOARD.patch \ + file://0003-ARM-v2021.10-stm32mp-r1-MISC-DRIVERS.patch \ + file://0004-ARM-v2021.10-stm32mp-r1-DEVICETREE.patch \ + file://0005-ARM-v2021.10-stm32mp-r1-CONFIG.patch \ \ file://0099-Add-external-var-to-allow-build-of-new-devicetree-fi.patch \ " @@ -34,9 +28,10 @@ SRC_URI += "\ # debug and trace SRC_URI += "${@bb.utils.contains('ST_UBOOT_DEBUG_TRACE', '1', '', 'file://0098-silent_mode.patch', d)}" -U_BOOT_VERSION = "v2020.10" -U_BOOT_SUBVERSION = "stm32mp" -U_BOOT_RELEASE = "r2" +U_BOOT_VERSION = "v2021.10" +U_BOOT_SUBVERSION = "stm32mp1" +U_BOOT_RELEASE = "r1" + PV = "${U_BOOT_VERSION}-${U_BOOT_SUBVERSION}-${U_BOOT_RELEASE}" ARCHIVER_ST_BRANCH = "${U_BOOT_VERSION}-${U_BOOT_SUBVERSION}" diff --git a/recipes-bsp/u-boot/u-boot-stm32mp.inc b/recipes-bsp/u-boot/u-boot-stm32mp.inc index dd819b2..7f1ae96 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp.inc +++ b/recipes-bsp/u-boot/u-boot-stm32mp.inc @@ -80,6 +80,11 @@ do_configure:prepend() { echo "CONFIG_STM32MP15x_STM32IMAGE=y" >> "${S}/configs/${config}" fi fi + if [ "${UBOOT_SIGN_ENABLE}" = "1" ]; then + if ! grep -q 'CONFIG_FIT_SIGNATURE=y' "${S}/configs/${config}"; then + echo "CONFIG_FIT_SIGNATURE=y" >> "${S}/configs/${config}" + fi + fi fi done unset j @@ -258,6 +263,30 @@ do_deploy:append() { if [ -n "${SPL_ELF}" ] && [ -f "${B}/${config}/${SPL_ELF}" ]; then install -m 644 ${B}/${config}/${SPL_ELF} ${DEPLOYDIR}${SUBFOLDER}/debug/${SPL_ELF_NAME}${soc_suffix}-${type_suffix} fi + + if [ "${UBOOT_SIGN_ENABLE}" = "1" -a -n "${UBOOT_DTB_BINARY}" ] ; then + # rm previous installed binaries + if [ -e "${DEPLOYDIR}/${UBOOT_DTB_BINARY}" ]; then + rm ${DEPLOYDIR}/${UBOOT_DTB_BINARY} + fi + if [ -e "${DEPLOYDIR}/${UBOOT_DTB_SYMLINK}" ]; then + rm ${DEPLOYDIR}/${UBOOT_DTB_SYMLINK} + fi + if [ -e "${DEPLOYDIR}/${DEPLOYDIR}/${UBOOT_NODTB_SYMLINK}" ]; then + rm ${DEPLOYDIR}/${UBOOT_NODTB_SYMLINK} ${DEPLOYDIR}/${UBOOT_NODTB_BINARY} + fi + if [ -e "${UBOOT_DTB_BINARY}" ]; then + install u-boot-${MACHINE}-${devicetree}-${PV}-${PR}.dtb ${DEPLOYDIR}/ + install u-boot-${MACHINE}-${devicetree}.dtb ${DEPLOYDIR}/ + fi + + if [ -f "${UBOOT_NODTB_BINARY}" ]; then + install u-boot-nodtb-${soc_suffix}-${PV}-${PR}.bin ${DEPLOYDIR}/ + fi + + + fi + done fi done @@ -270,6 +299,20 @@ do_deploy:append() { bbfatal "Wrong u-boot-stm32mp configuration: please make sure to use UBOOT_CONFIG through BOOTSCHEME_LABELS config" fi fi + + if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] ; then + # work only there is only one devicetree + # get name of u-boot devicetree without signature + ubootdevicetree=`ls -1 ${DEPLOYDIR}/*.dtb | head -n 1` + namewithoutsignature=`echo $ubootdevicetree | sed "s/\.dtb/-without-signature.dtb/g"` + namewithsignature=`echo $ubootdevicetree | sed "s/\.dtb/-with-signature.dtb/g"` + mv $ubootdevicetree $namewithoutsignature + #get name of kernel uboot devicetree + nameonkernel=`ls -1 ${DEPLOY_DIR_IMAGE}/kernel/u-boot-${MACHINE}*.dtb | head -n 1` + cp $nameonkernel $namewithsignature + cp $nameonkernel $ubootdevicetree + fi + } # --------------------------------------------------------------------- diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0001-ARM-v2020.10-stm32mp-r1-MACHINE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0001-ARM-v2020.10-stm32mp-r1-MACHINE.patch deleted file mode 100644 index eb43b7e..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0001-ARM-v2020.10-stm32mp-r1-MACHINE.patch +++ /dev/null @@ -1,1362 +0,0 @@ -From 69911b18f94bb32fd3592745d5fdead473e76103 Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Tue, 16 Mar 2021 08:16:59 +0100 -Subject: [PATCH 1/5] ARM v2020.10-stm32mp-r1 MACHINE - -Signed-off-by: Romuald JEANNE ---- - .gitignore | 3 + - CONTRIBUTING.md | 30 ++++++ - Makefile | 2 +- - arch/arc/include/asm/config.h | 2 - - arch/arm/include/asm/config.h | 1 - - arch/arm/include/asm/system.h | 3 + - arch/arm/lib/cache-cp15.c | 35 +++++-- - arch/arm/mach-stm32mp/Kconfig | 38 +++---- - arch/arm/mach-stm32mp/Makefile | 2 +- - arch/arm/mach-stm32mp/bsec.c | 10 ++ - arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig | 34 +++++++ - arch/arm/mach-stm32mp/cmd_stm32prog/Makefile | 8 +- - .../cmd_stm32prog/cmd_stm32prog.c | 25 ++--- - .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 66 +++++++++---- - .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 36 ++++++- - .../cmd_stm32prog/stm32prog_serial.c | 53 ++++------ - arch/arm/mach-stm32mp/config.mk | 2 +- - arch/arm/mach-stm32mp/cpu.c | 30 +++--- - arch/arm/mach-stm32mp/fdt.c | 11 ++- - arch/arm/mach-stm32mp/include/mach/stm32.h | 2 + - .../mach-stm32mp/include/mach/stm32mp1_smc.h | 50 +++++++--- - .../arm/mach-stm32mp/include/mach/stm32prog.h | 1 + - arch/arm/mach-stm32mp/pwr_regulator.c | 5 + - arch/arm/mach-stm32mp/spl.c | 5 +- - arch/m68k/include/asm/config.h | 1 - - arch/microblaze/include/asm/config.h | 2 - - arch/mips/include/asm/config.h | 1 - - arch/nds32/include/asm/config.h | 1 - - arch/powerpc/include/asm/config.h | 1 - - arch/riscv/include/asm/config.h | 1 - - arch/riscv/lib/fdt_fixup.c | 2 +- - arch/sandbox/dts/test.dts | 37 +++++++ - arch/sandbox/include/asm/scmi_test.h | 99 +++++++++++++++++++ - arch/sh/include/asm/config.h | 2 - - arch/x86/include/asm/config.h | 1 - - arch/xtensa/include/asm/config.h | 2 - - 36 files changed, 460 insertions(+), 144 deletions(-) - create mode 100644 CONTRIBUTING.md - create mode 100644 arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig - create mode 100644 arch/sandbox/include/asm/scmi_test.h - -diff --git a/.gitignore b/.gitignore -index e66aa864da..a489ae7874 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -95,3 +95,6 @@ GTAGS - - # Python cache - __pycache__ -+ -+/oe-* -+bitbake-cookerdaemon.log -diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md -new file mode 100644 -index 0000000000..3d1bacd78a ---- /dev/null -+++ b/CONTRIBUTING.md -@@ -0,0 +1,30 @@ -+# Contributing guide -+ -+This document serves as a checklist before contributing to this repository. It includes links to read up on if topics are unclear to you. -+ -+This guide mainly focuses on the proper use of Git. -+ -+## 1. Issues -+ -+STM32MPU projects do not activate "Github issues" feature for the time being. If you need to report an issue or question about this project deliverables, you can report them using [ ST Support Center ](https://my.st.com/ols#/ols/newrequest) or [ ST Community MPU Forum ](https://community.st.com/s/topic/0TO0X0000003u2AWAQ/stm32-mpus). -+ -+## 2. Pull Requests -+ -+STMicrolectronics is happy to receive contributions from the community, based on an initial Contributor License Agreement (CLA) procedure. -+ -+* If you are an individual writing original source code and you are sure **you own the intellectual property**, then you need to sign an Individual CLA (https://cla.st.com). -+* If you work for a company that wants also to allow you to contribute with your work, your company needs to provide a Corporate CLA (https://cla.st.com) mentioning your GitHub account name. -+* If you are not sure that a CLA (Individual or Corporate) has been signed for your GitHub account you can check here (https://cla.st.com). -+ -+Please note that: -+* The Corporate CLA will always take precedence over the Individual CLA. -+* One CLA submission is sufficient, for any project proposed by STMicroelectronics. -+ -+__How to proceed__ -+ -+* We recommend to fork the project in your GitHub account to further develop your contribution. Please use the latest commit version. -+* Please, submit one Pull Request for one new feature or proposal. This will ease the analysis and final merge if accepted. -+ -+__Note__ -+ -+Merge will not be done directly in GitHub but it will need first to follow internal integration process before public deliver in a standard release. The Pull request will stay open until it is merged and delivered. -diff --git a/Makefile b/Makefile -index d4736bb501..6bd0841c4b 100644 ---- a/Makefile -+++ b/Makefile -@@ -3,7 +3,7 @@ - VERSION = 2020 - PATCHLEVEL = 10 - SUBLEVEL = --EXTRAVERSION = -+EXTRAVERSION = -stm32mp-r1 - NAME = - - # *DOCUMENTATION* -diff --git a/arch/arc/include/asm/config.h b/arch/arc/include/asm/config.h -index d88c361488..46e94be141 100644 ---- a/arch/arc/include/asm/config.h -+++ b/arch/arc/include/asm/config.h -@@ -8,6 +8,4 @@ - - #define CONFIG_SYS_BOOT_RAMDISK_HIGH - --#define CONFIG_LMB -- - #endif /*__ASM_ARC_CONFIG_H_ */ -diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h -index bf692ce279..14860d89b6 100644 ---- a/arch/arm/include/asm/config.h -+++ b/arch/arm/include/asm/config.h -@@ -6,7 +6,6 @@ - #ifndef _ASM_CONFIG_H_ - #define _ASM_CONFIG_H_ - --#define CONFIG_LMB - #define CONFIG_SYS_BOOT_RAMDISK_HIGH - - #if defined(CONFIG_ARCH_LS1021A) || \ -diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h -index ce552944b7..932f12af1c 100644 ---- a/arch/arm/include/asm/system.h -+++ b/arch/arm/include/asm/system.h -@@ -458,6 +458,7 @@ static inline void set_dacr(unsigned int val) - - /* options available for data cache on each page */ - enum dcache_option { -+ INVALID_ENTRY = 0, - DCACHE_OFF = TTB_SECT | TTB_SECT_MAIR(0) | TTB_SECT_XN_MASK, - DCACHE_WRITETHROUGH = TTB_SECT | TTB_SECT_MAIR(1), - DCACHE_WRITEBACK = TTB_SECT | TTB_SECT_MAIR(2), -@@ -488,6 +489,7 @@ enum dcache_option { - * 1 1 1 Outer/Inner Write-Back, Read-Allocate Write-Allocate - */ - 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_WRITEBACK = DCACHE_WRITETHROUGH | TTB_SECT_B_MASK, -@@ -497,6 +499,7 @@ enum dcache_option { - #define TTB_SECT_AP (3 << 10) - /* options available for data cache on each page */ - enum dcache_option { -+ INVALID_ENTRY = 0, - DCACHE_OFF = 0x12, - DCACHE_WRITETHROUGH = 0x1a, - DCACHE_WRITEBACK = 0x1e, -diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c -index abd81d21c7..94e9b9c861 100644 ---- a/arch/arm/lib/cache-cp15.c -+++ b/arch/arm/lib/cache-cp15.c -@@ -6,6 +6,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -96,27 +97,33 @@ void mmu_set_region_dcache_behaviour_phys(phys_addr_t start, phys_addr_t phys, - mmu_page_table_flush(startpt, stoppt); - } - --void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size, -- enum dcache_option option) --{ -- mmu_set_region_dcache_behaviour_phys(start, start, size, option); --} -- - __weak void dram_bank_mmu_setup(int bank) - { - struct bd_info *bd = gd->bd; -+ struct lmb lmb; - int i; - - /* bd->bi_dram is available only after relocation */ - if ((gd->flags & GD_FLG_RELOC) == 0) - return; - -+ /* -+ * don't allow cache on reserved memory tagged 'no-map' in DT -+ * => avoid speculative access to "secure" data -+ */ -+ lmb_init_and_reserve(&lmb, bd, (void *)gd->fdt_blob); -+ - debug("%s: bank: %d\n", __func__, bank); - for (i = bd->bi_dram[bank].start >> MMU_SECTION_SHIFT; - i < (bd->bi_dram[bank].start >> MMU_SECTION_SHIFT) + - (bd->bi_dram[bank].size >> MMU_SECTION_SHIFT); -- i++) -- set_section_dcache(i, DCACHE_DEFAULT_OPTION); -+ i++) { -+ if (lmb_is_reserved_flags(&lmb, i << MMU_SECTION_SHIFT, -+ LMB_NOMAP)) -+ set_section_dcache(i, INVALID_ENTRY); -+ else -+ set_section_dcache(i, DCACHE_DEFAULT_OPTION); -+ } - } - - /* to activate the MMU we need to set up virtual memory: use 1M areas */ -@@ -313,6 +320,12 @@ int dcache_status(void) - { - return 0; /* always off */ - } -+ -+void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size, -+ enum dcache_option option) -+{ -+} -+ - #else - void dcache_enable(void) - { -@@ -328,4 +341,10 @@ int dcache_status(void) - { - return (get_cr() & CR_C) != 0; - } -+ -+void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size, -+ enum dcache_option option) -+{ -+ mmu_set_region_dcache_behaviour_phys(start, start, size, option); -+} - #endif -diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig -index 478fd2f17d..af0246d031 100644 ---- a/arch/arm/mach-stm32mp/Kconfig -+++ b/arch/arm/mach-stm32mp/Kconfig -@@ -56,6 +56,13 @@ config STM32MP15x - dual core A7 for STM32MP157/3, monocore for STM32MP151 - target all the STMicroelectronics board with SOC STM32MP1 family - -+config STM32MP15x_STM32IMAGE -+ bool "Support STM32 image for generated U-Boot image" -+ depends on STM32MP15x && TFABOOT -+ help -+ Support of STM32 image generation for SOC STM32MP15x -+ for TF-A boot when FIP container is not used -+ - choice - prompt "STM32MP15x board select" - optional -@@ -93,6 +100,19 @@ config SYS_TEXT_BASE - config NR_DRAM_BANKS - default 1 - -+config DDR_CACHEABLE_SIZE -+ hex "Size of the DDR marked cacheable in pre-reloc stage" -+ default 0x10000000 if TFABOOT -+ default 0x40000000 -+ help -+ Define the size of the DDR marked as cacheable in U-Boot -+ pre-reloc stage. -+ This option can be useful to avoid speculatif access -+ to secured area of DDR used by TF-A or OP-TEE before U-Boot -+ initialization. -+ The areas marked "no-map" in device tree should be located -+ before this limit: STM32_DDR_BASE + DDR_CACHEABLE_SIZE. -+ - config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2 - hex "Partition on MMC2 to use to load U-Boot from" - depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION -@@ -108,23 +128,6 @@ config STM32_ETZPC - help - Say y to enable STM32 Extended TrustZone Protection - --config CMD_STM32PROG -- bool "command stm32prog for STM32CudeProgrammer" -- select DFU -- select DFU_RAM -- select DFU_VIRT -- select PARTITION_TYPE_GUID -- imply CMD_GPT if MMC -- imply CMD_MTD if MTD -- imply DFU_MMC if MMC -- imply DFU_MTD if MTD -- help -- activate a specific command stm32prog for STM32MP soc family -- witch update the device with the tools STM32CubeProgrammer, -- using UART with STM32 protocol or USB with DFU protocol -- NB: access to not volatile memory (NOR/NAND/SD/eMMC) is based -- on U-Boot DFU framework -- - config CMD_STM32KEY - bool "command stm32key to fuse public key hash" - default y -@@ -164,6 +167,7 @@ config DEBUG_UART_CLOCK - default 64000000 - endif - -+source "arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig" - source "board/st/stm32mp1/Kconfig" - source "board/dhelectronics/dh_stm32mp1/Kconfig" - -diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile -index c8aa24d489..aa39867080 100644 ---- a/arch/arm/mach-stm32mp/Makefile -+++ b/arch/arm/mach-stm32mp/Makefile -@@ -11,7 +11,7 @@ obj-y += bsec.o - ifdef CONFIG_SPL_BUILD - obj-y += spl.o - else --obj-$(CONFIG_CMD_STM32PROG) += cmd_stm32prog/ -+obj-y += cmd_stm32prog/ - obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o - obj-$(CONFIG_ARMV7_PSCI) += psci.o - obj-$(CONFIG_TFABOOT) += boot_params.o -diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c -index a9b9bd0902..3583368a91 100644 ---- a/arch/arm/mach-stm32mp/bsec.c -+++ b/arch/arm/mach-stm32mp/bsec.c -@@ -4,6 +4,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -486,6 +487,15 @@ static int stm32mp_bsec_probe(struct udevice *dev) - { - int otp; - struct stm32mp_bsec_platdata *plat; -+ struct clk_bulk clk_bulk; -+ int ret; -+ -+ ret = clk_get_bulk(dev, &clk_bulk); -+ if (!ret) { -+ ret = clk_enable_bulk(&clk_bulk); -+ if (ret) -+ return ret; -+ } - - /* - * update unlocked shadow for OTP cleared by the rom code -diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig -new file mode 100644 -index 0000000000..f4c0d18d4d ---- /dev/null -+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig -@@ -0,0 +1,34 @@ -+ -+config CMD_STM32PROG -+ bool "command stm32prog for STM32CudeProgrammer" -+ select DFU -+ select DFU_RAM -+ select DFU_VIRT -+ select PARTITION_TYPE_GUID -+ imply CMD_GPT if MMC -+ imply CMD_MTD if MTD -+ imply DFU_MMC if MMC -+ imply DFU_MTD if MTD -+ help -+ activate a specific command stm32prog for STM32MP soc family -+ witch update the device with the tools STM32CubeProgrammer -+ NB: access to not volatile memory (NOR/NAND/SD/eMMC) is based -+ on U-Boot DFU framework -+ -+config CMD_STM32PROG_USB -+ bool "support stm32prog over USB" -+ depends on CMD_STM32PROG -+ default y -+ help -+ activate the command "stm32prog usb" for STM32MP soc family -+ witch update the device with the tools STM32CubeProgrammer, -+ using USB with DFU protocol -+ -+config CMD_STM32PROG_SERIAL -+ bool "support stm32prog over UART" -+ depends on CMD_STM32PROG -+ default y -+ help -+ activate the command "stm32prog serial" for STM32MP soc family -+ with the tools STM32CubeProgrammer using U-Boot serial device -+ and UART protocol. -\ No newline at end of file -diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/Makefile b/arch/arm/mach-stm32mp/cmd_stm32prog/Makefile -index 548a378921..b57e1bf870 100644 ---- a/arch/arm/mach-stm32mp/cmd_stm32prog/Makefile -+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/Makefile -@@ -3,7 +3,7 @@ - # Copyright (C) 2020, STMicroelectronics - All Rights Reserved - # - --obj-y += cmd_stm32prog.o --obj-y += stm32prog.o --obj-y += stm32prog_serial.o --obj-y += stm32prog_usb.o -+obj-$(CONFIG_CMD_STM32PROG) += cmd_stm32prog.o -+obj-$(CONFIG_CMD_STM32PROG) += stm32prog.o -+obj-$(CONFIG_CMD_STM32PROG_SERIAL) += stm32prog_serial.o -+obj-$(CONFIG_CMD_STM32PROG_USB) += stm32prog_usb.o -diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c -index 49dd25b28f..a20980a6ae 100644 ---- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c -+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c -@@ -50,9 +50,9 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, - if (argc < 3 || argc > 5) - return CMD_RET_USAGE; - -- if (!strcmp(argv[1], "usb")) -+ if (IS_ENABLED(CONFIG_CMD_STM32PROG_USB) && !strcmp(argv[1], "usb")) - link = LINK_USB; -- else if (!strcmp(argv[1], "serial")) -+ else if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL) && !strcmp(argv[1], "serial")) - link = LINK_SERIAL; - - if (link == LINK_UNDEFINED) { -@@ -73,15 +73,16 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, - size = simple_strtoul(argv[4], NULL, 16); - - /* check STM32IMAGE presence */ -- if (size == 0 && -- !stm32prog_header_check((struct raw_header_s *)addr, &header)) { -- size = header.image_length + BL_HEADER_SIZE; -- -- /* 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"); -+ if (size == 0) { -+ stm32prog_header_check((struct raw_header_s *)addr, &header); -+ if (header.type == HEADER_STM32IMAGE) { -+ size = header.image_length + BL_HEADER_SIZE; -+ -+ /* 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"); -+ } - } - - if (IS_ENABLED(CONFIG_DM_VIDEO)) -@@ -174,6 +175,7 @@ U_BOOT_CMD(stm32prog, 5, 0, do_stm32prog, - " = size of flashlayout\n" - ); - -+#ifdef CONFIG_STM32MP15x_STM32IMAGE - bool stm32prog_get_tee_partitions(void) - { - if (stm32prog_data) -@@ -181,6 +183,7 @@ bool stm32prog_get_tee_partitions(void) - - return false; - } -+#endif - - bool stm32prog_get_fsbl_nor(void) - { -diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c -index ec3355d816..627bb52a11 100644 ---- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c -+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c -@@ -59,8 +59,6 @@ static const efi_guid_t uuid_mmc[3] = { - ROOTFS_MMC2_UUID - }; - --DECLARE_GLOBAL_DATA_PTR; -- - /* order of column in flash layout file */ - enum stm32prog_col_t { - COL_OPTION, -@@ -72,6 +70,16 @@ enum stm32prog_col_t { - COL_NB_STM32 - }; - -+#define FIP_TOC_HEADER_NAME 0xAA640001 -+ -+struct fip_toc_header { -+ u32 name; -+ u32 serial_number; -+ u64 flags; -+}; -+ -+DECLARE_GLOBAL_DATA_PTR; -+ - /* partition handling routines : CONFIG_CMD_MTDPARTS */ - int mtdparts_init(void); - int find_dev_and_part(const char *id, struct mtd_device **dev, -@@ -87,46 +95,57 @@ char *stm32prog_get_error(struct stm32prog_data *data) - return data->error; - } - --u8 stm32prog_header_check(struct raw_header_s *raw_header, -- struct image_header_s *header) -+static bool stm32prog_is_fip_header(struct fip_toc_header *header) -+{ -+ return (header->name == FIP_TOC_HEADER_NAME) && header->serial_number; -+} -+ -+void stm32prog_header_check(struct raw_header_s *raw_header, -+ struct image_header_s *header) - { - unsigned int i; - -- header->present = 0; -+ if (!raw_header || !header) { -+ pr_debug("%s:no header data\n", __func__); -+ return; -+ } -+ -+ header->type = HEADER_NONE; - header->image_checksum = 0x0; - header->image_length = 0x0; - -- if (!raw_header || !header) { -- pr_debug("%s:no header data\n", __func__); -- return -1; -+ if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) { -+ header->type = HEADER_FIP; -+ return; - } -+ - if (raw_header->magic_number != - (('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) { - pr_debug("%s:invalid magic number : 0x%x\n", - __func__, raw_header->magic_number); -- return -2; -+ return; - } - /* only header v1.0 supported */ - if (raw_header->header_version != 0x00010000) { - pr_debug("%s:invalid header version : 0x%x\n", - __func__, raw_header->header_version); -- return -3; -+ return; - } - if (raw_header->reserved1 != 0x0 || raw_header->reserved2) { - pr_debug("%s:invalid reserved field\n", __func__); -- return -4; -+ return; - } - for (i = 0; i < (sizeof(raw_header->padding) / 4); i++) { - if (raw_header->padding[i] != 0) { - pr_debug("%s:invalid padding field\n", __func__); -- return -5; -+ return; - } - } -- header->present = 1; -+ header->type = HEADER_STM32IMAGE; - header->image_checksum = le32_to_cpu(raw_header->image_checksum); - header->image_length = le32_to_cpu(raw_header->image_length); - -- return 0; -+ return; - } - - static u32 stm32prog_header_checksum(u32 addr, struct image_header_s *header) -@@ -355,8 +374,8 @@ static int parse_flash_layout(struct stm32prog_data *data, - data->part_nb = 0; - - /* check if STM32image is detected */ -- if (!stm32prog_header_check((struct raw_header_s *)addr, -- &data->header)) { -+ stm32prog_header_check((struct raw_header_s *)addr, &data->header); -+ if (data->header.type == HEADER_STM32IMAGE) { - u32 checksum; - - addr = addr + BL_HEADER_SIZE; -@@ -768,9 +787,8 @@ static int init_device(struct stm32prog_data *data, - part_found = true; - } - -+ /* no partition for this device */ - if (!part_found) { -- stm32prog_err("%s (0x%x): Invalid partition", -- part->name, part->id); - pr_debug("\n"); - continue; - } -@@ -804,7 +822,9 @@ static int treat_partition_list(struct stm32prog_data *data) - INIT_LIST_HEAD(&data->dev[j].part_list); - } - -+#ifdef CONFIG_STM32MP15x_STM32IMAGE - data->tee_detected = false; -+#endif - data->fsbl_nor_detected = false; - for (i = 0; i < data->part_nb; i++) { - part = &data->part_array[i]; -@@ -858,10 +878,12 @@ static int treat_partition_list(struct stm32prog_data *data) - /* fallthrough */ - case STM32PROG_NAND: - case STM32PROG_SPI_NAND: -+#ifdef CONFIG_STM32MP15x_STM32IMAGE - if (!data->tee_detected && - !strncmp(part->name, "tee", 3)) - data->tee_detected = true; - break; -+#endif - default: - break; - } -@@ -1410,7 +1432,7 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part) - - if (part->target != STM32PROG_NAND && - part->target != STM32PROG_SPI_NAND) -- return -1; -+ return -EINVAL; - - dfu = dfu_get_entity(part->alt_id); - -@@ -1420,8 +1442,10 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part) - ret = dfu->read_medium(dfu, 0, (void *)&raw_header, &size); - if (ret) - return ret; -- if (stm32prog_header_check(&raw_header, &header)) -- return -1; -+ -+ stm32prog_header_check(&raw_header, &header); -+ if (header.type != HEADER_STM32IMAGE) -+ return -ENOENT; - - /* read header + payload */ - size = header.image_length + BL_HEADER_SIZE; -diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h -index bae4e91c01..fadcd1fa8f 100644 ---- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h -+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h -@@ -37,8 +37,14 @@ enum stm32prog_link_t { - LINK_UNDEFINED, - }; - -+enum stm32prog_header_t { -+ HEADER_NONE, -+ HEADER_STM32IMAGE, -+ HEADER_FIP, -+}; -+ - struct image_header_s { -- bool present; -+ enum stm32prog_header_t type; - u32 image_checksum; - u32 image_length; - }; -@@ -115,7 +121,9 @@ struct stm32prog_data { - struct stm32prog_dev_t dev[STM32PROG_MAX_DEV]; /* array of device */ - int part_nb; /* nb of partition */ - struct stm32prog_part_t *part_array; /* array of partition */ -+#ifdef CONFIG_STM32MP15x_STM32IMAGE - bool tee_detected; -+#endif - bool fsbl_nor_detected; - - /* command internal information */ -@@ -160,8 +168,8 @@ int stm32prog_pmic_read(struct stm32prog_data *data, u32 offset, - int stm32prog_pmic_start(struct stm32prog_data *data); - - /* generic part*/ --u8 stm32prog_header_check(struct raw_header_s *raw_header, -- struct image_header_s *header); -+void stm32prog_header_check(struct raw_header_s *raw_header, -+ struct image_header_s *header); - int stm32prog_dfu_init(struct stm32prog_data *data); - void stm32prog_next_phase(struct stm32prog_data *data); - void stm32prog_do_reset(struct stm32prog_data *data); -@@ -177,9 +185,29 @@ char *stm32prog_get_error(struct stm32prog_data *data); - - /* Main function */ - int stm32prog_init(struct stm32prog_data *data, ulong addr, ulong size); -+void stm32prog_clean(struct stm32prog_data *data); -+ -+#ifdef CONFIG_CMD_STM32PROG_SERIAL - int stm32prog_serial_init(struct stm32prog_data *data, int link_dev); - bool stm32prog_serial_loop(struct stm32prog_data *data); -+#else -+static inline int stm32prog_serial_init(struct stm32prog_data *data, int link_dev) -+{ -+ return -ENOSYS; -+} -+static inline bool stm32prog_serial_loop(struct stm32prog_data *data) -+{ -+ return false; -+} -+#endif -+ -+#ifdef CONFIG_CMD_STM32PROG_USB - bool stm32prog_usb_loop(struct stm32prog_data *data, int dev); --void stm32prog_clean(struct stm32prog_data *data); -+#else -+static inline bool stm32prog_usb_loop(struct stm32prog_data *data, int dev) -+{ -+ return false; -+} -+#endif - - #endif -diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c -index 8aad4be467..0c3c215b3d 100644 ---- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c -+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c -@@ -186,36 +186,19 @@ static int stm32prog_read(struct stm32prog_data *data, u8 phase, u32 offset, - int stm32prog_serial_init(struct stm32prog_data *data, int link_dev) - { - struct udevice *dev = NULL; -- int node; -- char alias[10]; -- const char *path; - struct dm_serial_ops *ops; - /* no parity, 8 bits, 1 stop */ - u32 serial_config = SERIAL_DEFAULT_CONFIG; - - down_serial_dev = NULL; - -- sprintf(alias, "serial%d", link_dev); -- path = fdt_get_alias(gd->fdt_blob, alias); -- if (!path) { -- pr_err("%s alias not found", alias); -- return -ENODEV; -- } -- node = fdt_path_offset(gd->fdt_blob, path); -- if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, -- &dev)) { -- down_serial_dev = dev; -- } else if (node > 0 && -- !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node), -- &dev, false)) { -- if (!device_probe(dev)) -- down_serial_dev = dev; -- } -- if (!down_serial_dev) { -- pr_err("%s = %s device not found", alias, path); -+ if (uclass_get_device_by_seq(UCLASS_SERIAL, link_dev, &dev)) { -+ pr_err("serial %d device not found\n", link_dev); - return -ENODEV; - } - -+ down_serial_dev = dev; -+ - /* force silent console on uart only when used */ - if (gd->cur_serial_dev == down_serial_dev) - gd->flags |= GD_FLG_DISABLE_CONSOLE | GD_FLG_SILENT; -@@ -225,11 +208,11 @@ int stm32prog_serial_init(struct stm32prog_data *data, int link_dev) - ops = serial_get_ops(down_serial_dev); - - if (!ops) { -- pr_err("%s = %s missing ops", alias, path); -+ pr_err("serial %d = %s missing ops\n", link_dev, dev->name); - return -ENODEV; - } - if (!ops->setconfig) { -- pr_err("%s = %s missing setconfig", alias, path); -+ pr_err("serial %d = %s missing setconfig\n", link_dev, dev->name); - return -ENODEV; - } - -@@ -325,11 +308,10 @@ static u8 stm32prog_header(struct stm32prog_data *data) - /* force cleanup to avoid issue with previous read */ - dfu_transaction_cleanup(dfu_entity); - -- ret = stm32prog_header_check(data->header_data, -- &data->header); -+ stm32prog_header_check(data->header_data, &data->header); - -- /* no header : max size is partition size */ -- if (ret) { -+ /* 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; - } -@@ -397,16 +379,15 @@ static u8 stm32prog_start(struct stm32prog_data *data, u32 address) - if (!dfu_entity) - return -ENODEV; - -- if (data->dfu_seq) { -- ret = dfu_flush(dfu_entity, NULL, 0, data->dfu_seq); -- data->dfu_seq = 0; -- if (ret) { -- stm32prog_err("DFU flush failed [%d]", ret); -- return ret; -- } -+ ret = dfu_flush(dfu_entity, NULL, 0, data->dfu_seq); -+ if (ret) { -+ stm32prog_err("DFU flush failed [%d]", ret); -+ return ret; - } -+ data->dfu_seq = 0; -+ - printf("\n received length = 0x%x\n", data->cursor); -- if (data->header.present) { -+ 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)", -@@ -806,7 +787,7 @@ static void download_command(struct stm32prog_data *data) - } - } - -- if (image_header->present) { -+ if (data->header.type == HEADER_STM32IMAGE) { - if (data->cursor <= BL_HEADER_SIZE) - goto end; - /* compute checksum on payload */ -diff --git a/arch/arm/mach-stm32mp/config.mk b/arch/arm/mach-stm32mp/config.mk -index c30bf482f7..f7f5b77c41 100644 ---- a/arch/arm/mach-stm32mp/config.mk -+++ b/arch/arm/mach-stm32mp/config.mk -@@ -4,7 +4,7 @@ - # - - ifndef CONFIG_SPL --INPUTS-y += u-boot.stm32 -+INPUTS-$(CONFIG_STM32MP15x_STM32IMAGE) += u-boot.stm32 - else - ifdef CONFIG_SPL_BUILD - INPUTS-y += u-boot-spl.stm32 -diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c -index f19e5c3f33..b81825a0bf 100644 ---- a/arch/arm/mach-stm32mp/cpu.c -+++ b/arch/arm/mach-stm32mp/cpu.c -@@ -219,18 +219,21 @@ static void early_enable_caches(void) - if (CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) - return; - -+#if !(CONFIG_IS_ENABLED(SYS_ICACHE_OFF) && CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) - gd->arch.tlb_size = PGTABLE_SIZE; - gd->arch.tlb_addr = (unsigned long)&early_tlb; -+#endif - - dcache_enable(); - - if (IS_ENABLED(CONFIG_SPL_BUILD)) - mmu_set_region_dcache_behaviour( -- ALIGN(STM32_SYSRAM_BASE, MMU_SECTION_SIZE), -- round_up(STM32_SYSRAM_SIZE, MMU_SECTION_SIZE), -+ 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, STM32_DDR_SIZE, -+ mmu_set_region_dcache_behaviour(STM32_DDR_BASE, -+ CONFIG_DDR_CACHEABLE_SIZE, - DCACHE_DEFAULT_OPTION); - } - -@@ -260,7 +263,8 @@ int arch_cpu_init(void) - - boot_mode = get_bootmode(); - -- if ((boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART) -+ if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL) && -+ (boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART) - gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; - #if defined(CONFIG_DEBUG_UART) && \ - !defined(CONFIG_TFABOOT) && \ -@@ -460,7 +464,6 @@ static void setup_boot_mode(void) - unsigned int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1; - u32 forced_mode = (boot_ctx & TAMP_BOOT_FORCED_MASK); - struct udevice *dev; -- int alias; - - pr_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d forced=%x\n", - __func__, boot_ctx, boot_mode, instance, forced_mode); -@@ -470,17 +473,22 @@ static void setup_boot_mode(void) - break; - /* serial : search associated alias in devicetree */ - sprintf(cmd, "serial@%x", serial_addr[instance]); -- if (uclass_get_device_by_name(UCLASS_SERIAL, cmd, &dev)) -- break; -- if (fdtdec_get_alias_seq(gd->fdt_blob, "serial", -- dev_of_offset(dev), &alias)) -+ if (uclass_get_device_by_name(UCLASS_SERIAL, cmd, &dev)) { -+ /* restore console on error */ -+ if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL)) -+ gd->flags &= ~(GD_FLG_SILENT | -+ GD_FLG_DISABLE_CONSOLE); -+ printf("uart%d = %s not found in device tree!\n", -+ instance, cmd); - break; -- sprintf(cmd, "%d", alias); -+ } -+ sprintf(cmd, "%d", dev->seq); - env_set("boot_device", "serial"); - env_set("boot_instance", cmd); - - /* restore console on uart when not used */ -- if (gd->cur_serial_dev != dev) { -+ if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL) && -+ (gd->cur_serial_dev != dev)) { - gd->flags &= ~(GD_FLG_SILENT | - GD_FLG_DISABLE_CONSOLE); - printf("serial boot with console enabled!\n"); -diff --git a/arch/arm/mach-stm32mp/fdt.c b/arch/arm/mach-stm32mp/fdt.c -index 0de1d82291..cfaac8a416 100644 ---- a/arch/arm/mach-stm32mp/fdt.c -+++ b/arch/arm/mach-stm32mp/fdt.c -@@ -328,7 +328,16 @@ int ft_system_setup(void *blob, struct bd_info *bd) - "st,package", pkg, false); - } - -- if (!CONFIG_IS_ENABLED(OPTEE) || -+ /* -+ * TEMP: remove OP-TEE nodes in kernel device tree -+ * copied from U-Boot device tree by optee_copy_fdt_nodes -+ * when OP-TEE is not detected (probe failed) -+ * these OP-TEE nodes are present in -u-boot.dtsi -+ * under CONFIG_STM32MP15x_STM32IMAGE only for compatibility -+ * when FIP is not used by TF-A -+ */ -+ if (CONFIG_IS_ENABLED(STM32MP15x_STM32IMAGE) && -+ CONFIG_IS_ENABLED(OPTEE) && - !tee_find_device(NULL, NULL, NULL, NULL)) - stm32_fdt_disable_optee(blob); - -diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h -index 5fdb893b0e..af7ccdcc48 100644 ---- a/arch/arm/mach-stm32mp/include/mach/stm32.h -+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h -@@ -91,8 +91,10 @@ enum boot_device { - - /* TAMP registers */ - #define TAMP_BACKUP_REGISTER(x) (STM32_TAMP_BASE + 0x100 + 4 * x) -+/* secure access */ - #define TAMP_BACKUP_MAGIC_NUMBER TAMP_BACKUP_REGISTER(4) - #define TAMP_BACKUP_BRANCH_ADDRESS TAMP_BACKUP_REGISTER(5) -+/* non secure access */ - #define TAMP_COPRO_RSC_TBL_ADDRESS TAMP_BACKUP_REGISTER(17) - #define TAMP_COPRO_STATE TAMP_BACKUP_REGISTER(18) - #define TAMP_BOOT_CONTEXT TAMP_BACKUP_REGISTER(20) -diff --git a/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h -index 4ad14f963b..d72747ca31 100644 ---- a/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h -+++ b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h -@@ -8,19 +8,53 @@ - - #include - -+/* SMC service generic return codes */ -+#define STM32_SMC_OK 0x00000000U -+#define STM32_SMC_NOT_SUPPORTED 0xFFFFFFFFU -+#define STM32_SMC_FAILED 0xFFFFFFFEU -+#define STM32_SMC_INVALID_PARAMS 0xFFFFFFFDU -+ - /* -- * SMC function IDs for STM32 Service queries -+ * SMC function IDs for STM32 Service queries. - * STM32 SMC services use the space between 0x82000000 and 0x8200FFFF - * like this is defined in SMC calling Convention by ARM -- * for SiP (silicon Partner) -- * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html -+ * for SiP (silicon Partner). -+ * https://developer.arm.com/docs/den0028/latest - */ --#define STM32_SMC_VERSION 0x82000000 - - /* Secure Service access from Non-secure */ -+ -+/* -+ * SMC function STM32_SMC_PWR. -+ * -+ * Argument a0: (input) SMCC ID. -+ * (output) Status return code. -+ * Argument a1: (input) Service ID (STM32_SMC_REG_xxx). -+ * Argument a2: (input) Register offset or physical address. -+ * (output) Register read value, if applicable. -+ * Argument a3: (input) Register target value if applicable. -+ */ -+#define STM32_SMC_PWR 0x82001001 -+ -+/* -+ * SMC functions STM32_SMC_BSEC. -+ * -+ * Argument a0: (input) SMCC ID. -+ * (output) Status return code. -+ * Argument a1: (input) Service ID (STM32_SMC_READ_xxx/_PROG_xxx/_WRITE_xxx). -+ * (output) OTP read value, if applicable. -+ * Argument a2: (input) OTP index. -+ * Argument a3: (input) OTP value if applicable. -+ */ - #define STM32_SMC_BSEC 0x82001003 - --/* Service for BSEC */ -+/* Service ID for STM32_SMC_PWR */ -+#define STM32_SMC_REG_READ 0x0 -+#define STM32_SMC_REG_WRITE 0x1 -+#define STM32_SMC_REG_SET 0x2 -+#define STM32_SMC_REG_CLEAR 0x3 -+ -+/* Service ID for STM32_SMC_BSEC */ - #define STM32_SMC_READ_SHADOW 0x01 - #define STM32_SMC_PROG_OTP 0x02 - #define STM32_SMC_WRITE_SHADOW 0x03 -@@ -29,12 +63,6 @@ - #define STM32_SMC_WRITE_ALL 0x06 - #define STM32_SMC_WRLOCK_OTP 0x07 - --/* SMC error codes */ --#define STM32_SMC_OK 0x0 --#define STM32_SMC_NOT_SUPPORTED -1 --#define STM32_SMC_FAILED -2 --#define STM32_SMC_INVALID_PARAMS -3 -- - #define stm32_smc_exec(svc, op, data1, data2) \ - stm32_smc(svc, op, data1, data2, NULL) - -diff --git a/arch/arm/mach-stm32mp/include/mach/stm32prog.h b/arch/arm/mach-stm32mp/include/mach/stm32prog.h -index c080b9cc42..241eec48d5 100644 ---- a/arch/arm/mach-stm32mp/include/mach/stm32prog.h -+++ b/arch/arm/mach-stm32mp/include/mach/stm32prog.h -@@ -11,6 +11,7 @@ int stm32prog_read_medium_virt(struct dfu_entity *dfu, u64 offset, - void *buf, long *len); - int stm32prog_get_medium_size_virt(struct dfu_entity *dfu, u64 *size); - -+/* only needed for CONFIG_STM32MP15x_STM32IMAGE, prototype defined to avoid compilation issue */ - bool stm32prog_get_tee_partitions(void); - - bool stm32prog_get_fsbl_nor(void); -diff --git a/arch/arm/mach-stm32mp/pwr_regulator.c b/arch/arm/mach-stm32mp/pwr_regulator.c -index 900dee4c38..1fbd180990 100644 ---- a/arch/arm/mach-stm32mp/pwr_regulator.c -+++ b/arch/arm/mach-stm32mp/pwr_regulator.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -41,6 +42,10 @@ static int stm32mp_pwr_write(struct udevice *dev, uint reg, - if (len != 4) - return -EINVAL; - -+ if (IS_ENABLED(CONFIG_TFABOOT)) -+ return stm32_smc_exec(STM32_SMC_PWR, STM32_SMC_REG_WRITE, -+ STM32MP_PWR_CR3, val); -+ - writel(val, priv->base + STM32MP_PWR_CR3); - - return 0; -diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c -index e84bdad7bf..66a634654e 100644 ---- a/arch/arm/mach-stm32mp/spl.c -+++ b/arch/arm/mach-stm32mp/spl.c -@@ -55,6 +55,7 @@ u32 spl_mmc_boot_mode(const u32 boot_device) - return MMCSD_MODE_RAW; - } - -+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION - int spl_mmc_boot_partition(const u32 boot_device) - { - switch (boot_device) { -@@ -66,6 +67,7 @@ int spl_mmc_boot_partition(const u32 boot_device) - return -EINVAL; - } - } -+#endif - - #ifdef CONFIG_SPL_DISPLAY_PRINT - void spl_display_print(void) -@@ -138,7 +140,8 @@ void board_init_f(ulong dummy) - * to avoid speculative access and issue in get_ram_size() - */ - if (!CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) -- mmu_set_region_dcache_behaviour(STM32_DDR_BASE, STM32_DDR_SIZE, -+ mmu_set_region_dcache_behaviour(STM32_DDR_BASE, -+ CONFIG_DDR_CACHEABLE_SIZE, - DCACHE_DEFAULT_OPTION); - } - -diff --git a/arch/m68k/include/asm/config.h b/arch/m68k/include/asm/config.h -index c7363c0b51..b692cc9202 100644 ---- a/arch/m68k/include/asm/config.h -+++ b/arch/m68k/include/asm/config.h -@@ -8,7 +8,6 @@ - - #define CONFIG_NEEDS_MANUAL_RELOC - --#define CONFIG_LMB - #define CONFIG_SYS_BOOT_RAMDISK_HIGH - - #endif -diff --git a/arch/microblaze/include/asm/config.h b/arch/microblaze/include/asm/config.h -index 1124272915..e65e3649fe 100644 ---- a/arch/microblaze/include/asm/config.h -+++ b/arch/microblaze/include/asm/config.h -@@ -6,8 +6,6 @@ - #ifndef _ASM_CONFIG_H_ - #define _ASM_CONFIG_H_ - --#define CONFIG_LMB -- - #ifndef CONFIG_SPL_BUILD - #define CONFIG_NEEDS_MANUAL_RELOC - #endif -diff --git a/arch/mips/include/asm/config.h b/arch/mips/include/asm/config.h -index 7ea443673a..221eb93d58 100644 ---- a/arch/mips/include/asm/config.h -+++ b/arch/mips/include/asm/config.h -@@ -6,7 +6,6 @@ - #ifndef _ASM_CONFIG_H_ - #define _ASM_CONFIG_H_ - --#define CONFIG_LMB - #define CONFIG_SYS_BOOT_RAMDISK_HIGH - - #endif -diff --git a/arch/nds32/include/asm/config.h b/arch/nds32/include/asm/config.h -index 8964a58f27..6c1cbce7ef 100644 ---- a/arch/nds32/include/asm/config.h -+++ b/arch/nds32/include/asm/config.h -@@ -7,6 +7,5 @@ - - #ifndef _ASM_CONFIG_H_ - #define _ASM_CONFIG_H_ --#define CONFIG_LMB - - #endif -diff --git a/arch/powerpc/include/asm/config.h b/arch/powerpc/include/asm/config.h -index c9c9964630..99b410dc9b 100644 ---- a/arch/powerpc/include/asm/config.h -+++ b/arch/powerpc/include/asm/config.h -@@ -18,7 +18,6 @@ - #define HWCONFIG_BUFFER_SIZE 256 - #endif - --#define CONFIG_LMB - #define CONFIG_SYS_BOOT_RAMDISK_HIGH - - #ifndef CONFIG_MAX_MEM_MAPPED -diff --git a/arch/riscv/include/asm/config.h b/arch/riscv/include/asm/config.h -index 156cb94dc0..d911007537 100644 ---- a/arch/riscv/include/asm/config.h -+++ b/arch/riscv/include/asm/config.h -@@ -7,7 +7,6 @@ - #ifndef _ASM_CONFIG_H_ - #define _ASM_CONFIG_H_ - --#define CONFIG_LMB - #define CONFIG_SYS_BOOT_RAMDISK_HIGH - - #endif -diff --git a/arch/riscv/lib/fdt_fixup.c b/arch/riscv/lib/fdt_fixup.c -index 5b2420243f..d02062fd5b 100644 ---- a/arch/riscv/lib/fdt_fixup.c -+++ b/arch/riscv/lib/fdt_fixup.c -@@ -75,7 +75,7 @@ int riscv_fdt_copy_resv_mem_node(const void *src, void *dst) - pmp_mem.start = addr; - pmp_mem.end = addr + size - 1; - err = fdtdec_add_reserved_memory(dst, basename, &pmp_mem, -- &phandle); -+ &phandle, false); - if (err < 0 && err != -FDT_ERR_EXISTS) { - log_err("failed to add reserved memory: %d\n", err); - return err; -diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts -index 9f45c48e4e..7023f33a67 100644 ---- a/arch/sandbox/dts/test.dts -+++ b/arch/sandbox/dts/test.dts -@@ -356,6 +356,37 @@ - sandbox_firmware: sandbox-firmware { - compatible = "sandbox,firmware"; - }; -+ -+ sandbox-scmi-agent@0 { -+ compatible = "sandbox,scmi-agent"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ clk_scmi0: protocol@14 { -+ reg = <0x14>; -+ #clock-cells = <1>; -+ }; -+ -+ reset_scmi0: protocol@16 { -+ reg = <0x16>; -+ #reset-cells = <1>; -+ }; -+ }; -+ -+ sandbox-scmi-agent@1 { -+ compatible = "sandbox,scmi-agent"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ clk_scmi1: protocol@14 { -+ reg = <0x14>; -+ #clock-cells = <1>; -+ }; -+ -+ protocol@10 { -+ reg = <0x10>; -+ }; -+ }; - }; - - pinctrl-gpio { -@@ -1036,6 +1067,12 @@ - compatible = "sandbox,virtio2"; - }; - -+ sandbox_scmi { -+ compatible = "sandbox,scmi-devices"; -+ clocks = <&clk_scmi0 7>, <&clk_scmi0 3>, <&clk_scmi1 1>; -+ resets = <&reset_scmi0 3>; -+ }; -+ - pinctrl { - compatible = "sandbox,pinctrl"; - -diff --git a/arch/sandbox/include/asm/scmi_test.h b/arch/sandbox/include/asm/scmi_test.h -new file mode 100644 -index 0000000000..3e8b0068fd ---- /dev/null -+++ b/arch/sandbox/include/asm/scmi_test.h -@@ -0,0 +1,99 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2020, Linaro Limited -+ */ -+ -+#ifndef __SANDBOX_SCMI_TEST_H -+#define __SANDBOX_SCMI_TEST_H -+ -+struct udevice; -+struct sandbox_scmi_agent; -+struct sandbox_scmi_service; -+ -+/** -+ * struct sandbox_scmi_clk - Simulated clock exposed by SCMI -+ * @id: Identifier of the clock used in the SCMI protocol -+ * @enabled: Clock state: true if enabled, false if disabled -+ * @rate: Clock rate in Hertz -+ */ -+struct sandbox_scmi_clk { -+ uint id; -+ bool enabled; -+ ulong rate; -+}; -+ -+/** -+ * struct sandbox_scmi_reset - Simulated reset controller exposed by SCMI -+ * @asserted: Reset control state: true if asserted, false if desasserted -+ */ -+struct sandbox_scmi_reset { -+ uint id; -+ bool asserted; -+}; -+ -+/** -+ * struct sandbox_scmi_agent - Simulated SCMI service seen by SCMI agent -+ * @idx: Identifier for the SCMI agent, its index -+ * @clk: Simulated clocks -+ * @clk_count: Simulated clocks array size -+ * @clk: Simulated reset domains -+ * @clk_count: Simulated reset domains array size -+ */ -+struct sandbox_scmi_agent { -+ uint idx; -+ struct sandbox_scmi_clk *clk; -+ size_t clk_count; -+ struct sandbox_scmi_reset *reset; -+ size_t reset_count; -+}; -+ -+/** -+ * struct sandbox_scmi_service - Reference to simutaed SCMI agents/services -+ * @agent: Pointer to SCMI sandbox agent pointers array -+ * @agent_count: Number of emulated agents exposed in array @agent. -+ */ -+struct sandbox_scmi_service { -+ struct sandbox_scmi_agent **agent; -+ size_t agent_count; -+}; -+ -+/** -+ * struct sandbox_scmi_devices - Reference to devices probed through SCMI -+ * @clk: Array the clock devices -+ * @clk_count: Number of clock devices probed -+ * @reset: Array the reset controller devices -+ * @reset_count: Number of reset controller devices probed -+ */ -+struct sandbox_scmi_devices { -+ struct clk *clk; -+ size_t clk_count; -+ struct reset_ctl *reset; -+ size_t reset_count; -+}; -+ -+#ifdef CONFIG_SCMI_FIRMWARE -+/** -+ * sandbox_scmi_service_context - Get the simulated SCMI services context -+ * @return: Reference to backend simulated resources state -+ */ -+struct sandbox_scmi_service *sandbox_scmi_service_ctx(void); -+ -+/** -+ * sandbox_scmi_devices_get_ref - Get references to devices accessed through SCMI -+ * @dev: Reference to the test device used get test resources -+ * @return: Reference to the devices probed by the SCMI test -+ */ -+struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(struct udevice *dev); -+#else -+static inline struct sandbox_scmi_service *sandbox_scmi_service_ctx(void) -+{ -+ return NULL; -+} -+ -+static inline -+struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(struct udevice *dev) -+{ -+ return NULL; -+} -+#endif /* CONFIG_SCMI_FIRMWARE */ -+#endif /* __SANDBOX_SCMI_TEST_H */ -diff --git a/arch/sh/include/asm/config.h b/arch/sh/include/asm/config.h -index e1cd322152..406156dff5 100644 ---- a/arch/sh/include/asm/config.h -+++ b/arch/sh/include/asm/config.h -@@ -8,8 +8,6 @@ - - #include - --#define CONFIG_LMB -- - /* Timer */ - #define CONFIG_SYS_TIMER_COUNTS_DOWN - #define CONFIG_SYS_TIMER_COUNTER (TMU_BASE + 0xc) /* TCNT0 */ -diff --git a/arch/x86/include/asm/config.h b/arch/x86/include/asm/config.h -index 7ea443673a..221eb93d58 100644 ---- a/arch/x86/include/asm/config.h -+++ b/arch/x86/include/asm/config.h -@@ -6,7 +6,6 @@ - #ifndef _ASM_CONFIG_H_ - #define _ASM_CONFIG_H_ - --#define CONFIG_LMB - #define CONFIG_SYS_BOOT_RAMDISK_HIGH - - #endif -diff --git a/arch/xtensa/include/asm/config.h b/arch/xtensa/include/asm/config.h -index 5a95fc93f7..a1096ab196 100644 ---- a/arch/xtensa/include/asm/config.h -+++ b/arch/xtensa/include/asm/config.h -@@ -9,8 +9,6 @@ - - #include - --#define CONFIG_LMB -- - /* - * Make boot parameters available in the MMUv2 virtual memory layout by - * restricting used physical memory to the first 128MB. --- -2.17.1 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0001-ARM-v2021.10-stm32mp-r1-MACHINE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0001-ARM-v2021.10-stm32mp-r1-MACHINE.patch new file mode 100644 index 0000000..4a2deb5 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0001-ARM-v2021.10-stm32mp-r1-MACHINE.patch @@ -0,0 +1,4092 @@ +From ebcd6dbbef2fc9a1aa90b046cac7a810478499df Mon Sep 17 00:00:00 2001 +From: Christophe Priouzeau +Date: Mon, 30 May 2022 09:59:24 +0200 +Subject: [PATCH 1/5] ARM-v2021.10-stm32mp-r1-MACHINE + +--- + arch/arm/Kconfig | 3 - + arch/arm/mach-stm32mp/Kconfig | 162 ++----- + arch/arm/mach-stm32mp/Kconfig.13x | 57 +++ + arch/arm/mach-stm32mp/Kconfig.15x | 134 ++++++ + arch/arm/mach-stm32mp/Makefile | 5 +- + arch/arm/mach-stm32mp/bsec.c | 293 +++++++++++- + arch/arm/mach-stm32mp/cmd_stm32key.c | 329 +++++++++---- + arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig | 10 +- + .../cmd_stm32prog/cmd_stm32prog.c | 13 +- + .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 431 ++++++++++++++---- + .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 47 +- + .../cmd_stm32prog/stm32prog_usb.c | 9 +- + arch/arm/mach-stm32mp/config.mk | 29 -- + arch/arm/mach-stm32mp/cpu.c | 398 +++------------- + arch/arm/mach-stm32mp/fdt.c | 274 ++++++++--- + arch/arm/mach-stm32mp/include/mach/bsec.h | 8 + + arch/arm/mach-stm32mp/include/mach/gpio.h | 87 ---- + arch/arm/mach-stm32mp/include/mach/stm32.h | 28 ++ + .../mach-stm32mp/include/mach/stm32mp1_smc.h | 50 +- + .../arm/mach-stm32mp/include/mach/sys_proto.h | 44 +- + arch/arm/mach-stm32mp/pwr_regulator.c | 5 + + arch/arm/mach-stm32mp/spl.c | 1 + + arch/arm/mach-stm32mp/stm32mp13x.c | 123 +++++ + arch/arm/mach-stm32mp/stm32mp15x.c | 330 ++++++++++++++ + 24 files changed, 1978 insertions(+), 892 deletions(-) + create mode 100644 arch/arm/mach-stm32mp/Kconfig.13x + create mode 100644 arch/arm/mach-stm32mp/Kconfig.15x + delete mode 100644 arch/arm/mach-stm32mp/config.mk + delete mode 100644 arch/arm/mach-stm32mp/include/mach/gpio.h + create mode 100644 arch/arm/mach-stm32mp/stm32mp13x.c + create mode 100644 arch/arm/mach-stm32mp/stm32mp15x.c + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index b5bd3284cd..9dd7ea8074 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -1749,7 +1749,6 @@ config ARCH_STM32 + select CPU_V7M + select DM + select DM_SERIAL +- select GPIO_EXTRA_HEADER + imply CMD_DM + + config ARCH_STI +@@ -1775,14 +1774,12 @@ config ARCH_STM32MP + select DM_GPIO + select DM_RESET + select DM_SERIAL +- select GPIO_EXTRA_HEADER + select MISC + select OF_CONTROL + select OF_LIBFDT + select OF_SYSTEM_SETUP + select PINCTRL + select REGMAP +- select SUPPORT_SPL + select SYSCON + select SYSRESET + select SYS_THUMB_BUILD +diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig +index 5d7eca649a..09227cabed 100644 +--- a/arch/arm/mach-stm32mp/Kconfig ++++ b/arch/arm/mach-stm32mp/Kconfig +@@ -33,127 +33,54 @@ config SYS_MALLOC_LEN + config ENV_SIZE + default 0x2000 + ++choice ++ prompt "Select STMicroelectronics STM32MPxxx Soc" ++ default STM32MP15x ++ ++config STM32MP13x ++ bool "Support STMicroelectronics STM32MP13x Soc" ++ select ARM_SMCCC ++ select CPU_V7A ++ select CPU_V7_HAS_NONSEC ++ select CPU_V7_HAS_VIRT ++ select OF_BOARD_SETUP ++ select PINCTRL_STM32 ++ select STM32_RCC ++ select STM32_RESET ++ select STM32_SERIAL ++ select SYS_ARCH_TIMER ++ imply CMD_NVEDIT_INFO ++ help ++ support of STMicroelectronics SOC STM32MP13x family ++ STMicroelectronics MPU with core ARMv7 ++ + config STM32MP15x + bool "Support STMicroelectronics STM32MP15x Soc" +- select ARCH_SUPPORT_PSCI if !TFABOOT +- select ARM_SMCCC if TFABOOT ++ select ARCH_SUPPORT_PSCI ++ select BINMAN + select CPU_V7A +- select CPU_V7_HAS_NONSEC if !TFABOOT ++ select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_VIRT + select OF_BOARD_SETUP + select PINCTRL_STM32 + select STM32_RCC + select STM32_RESET + select STM32_SERIAL ++ select SUPPORT_SPL + select SYS_ARCH_TIMER + imply CMD_NVEDIT_INFO +- imply SYSRESET_PSCI if TFABOOT +- imply SYSRESET_SYSCON if !TFABOOT + help + support of STMicroelectronics SOC STM32MP15x family + STM32MP157, STM32MP153 or STM32MP151 + STMicroelectronics MPU with core ARMv7 + dual core A7 for STM32MP157/3, monocore for STM32MP151 +- target all the STMicroelectronics board with SOC STM32MP1 family +- +-config STM32MP15x_STM32IMAGE +- bool "Support STM32 image for generated U-Boot image" +- depends on STM32MP15x && TFABOOT +- help +- Support of STM32 image generation for SOC STM32MP15x +- for TF-A boot when FIP container is not used +- +-choice +- prompt "STM32MP15x board select" +- optional +- +-config TARGET_ST_STM32MP15x +- bool "STMicroelectronics STM32MP15x boards" +- select STM32MP15x +- imply BOOTCOUNT_LIMIT +- imply BOOTSTAGE +- imply CMD_BOOTCOUNT +- imply CMD_BOOTSTAGE +- imply CMD_CLS if CMD_BMP +- imply DISABLE_CONSOLE +- imply PRE_CONSOLE_BUFFER +- imply SILENT_CONSOLE +- help +- target the STMicroelectronics board with SOC STM32MP15x +- managed by board/st/stm32mp1: +- Evalulation board (EV1) or Discovery board (DK1 and DK2). +- The difference between board are managed with devicetree +- +-config TARGET_MICROGEA_STM32MP1 +- bool "Engicam MicroGEA STM32MP1 SOM" +- select STM32MP15x +- imply BOOTCOUNT_LIMIT +- imply BOOTSTAGE +- imply CMD_BOOTCOUNT +- imply CMD_BOOTSTAGE +- imply CMD_CLS if CMD_BMP +- imply DISABLE_CONSOLE +- imply PRE_CONSOLE_BUFFER +- imply SILENT_CONSOLE +- help +- MicroGEA STM32MP1 is a STM32MP157A based Micro SOM. +- +- MicroGEA STM32MP1 MicroDev 2.0: +- * MicroDev 2.0 is a general purpose miniature carrier board with CAN, +- LTE and LVDS panel interfaces. +- * MicroGEA STM32MP1 needs to mount on top of this MicroDev 2.0 board +- for creating complete MicroGEA STM32MP1 MicroDev 2.0 Carrier board. +- +- MicroGEA STM32MP1 MicroDev 2.0 7" OF: +- * 7" OF is a capacitive touch 7" Open Frame panel solutions with LVDS +- panel and toucscreen. +- * MicroGEA STM32MP1 needs to mount on top of MicroDev 2.0 board with +- pluged 7" OF for creating complete MicroGEA STM32MP1 MicroDev 2.0 7" +- Open Frame Solution board. +- +-config TARGET_ICORE_STM32MP1 +- bool "Engicam i.Core STM32MP1 SOM" +- select STM32MP15x +- imply BOOTCOUNT_LIMIT +- imply BOOTSTAGE +- imply CMD_BOOTCOUNT +- imply CMD_BOOTSTAGE +- imply CMD_CLS if CMD_BMP +- imply DISABLE_CONSOLE +- imply PRE_CONSOLE_BUFFER +- imply SILENT_CONSOLE +- help +- i.Core STM32MP1 is an EDIMM SOM based on STM32MP157A. +- +- i.Core STM32MP1 EDIMM2.2: +- * EDIMM2.2 is a Form Factor Capacitive Evaluation Board. +- * i.Core STM32MP1 needs to mount on top of EDIMM2.2 for +- creating complete i.Core STM32MP1 EDIMM2.2 Starter Kit. +- +- i.Core STM32MP1 C.TOUCH 2.0 +- * C.TOUCH 2.0 is a general purpose Carrier board. +- * i.Core STM32MP1 needs to mount on top of this Carrier board +- for creating complete i.Core STM32MP1 C.TOUCH 2.0 board. +- +-config TARGET_DH_STM32MP1_PDK2 +- bool "DH STM32MP1 PDK2" +- select STM32MP15x +- imply BOOTCOUNT_LIMIT +- imply CMD_BOOTCOUNT +- help +- Target the DH PDK2 development kit with STM32MP15x SoM. +- + endchoice + +-config SYS_TEXT_BASE +- default 0xC0100000 +- + config NR_DRAM_BANKS + default 1 + + config DDR_CACHEABLE_SIZE + hex "Size of the DDR marked cacheable in pre-reloc stage" +- default 0x10000000 if TFABOOT + default 0x40000000 + help + Define the size of the DDR marked as cacheable in U-Boot +@@ -174,7 +101,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2 + + config STM32_ETZPC + bool "STM32 Extended TrustZone Protection" +- depends on STM32MP15x ++ depends on STM32MP15x || STM32MP13x + default y + help + Say y to enable STM32 Extended TrustZone Protection +@@ -197,41 +124,8 @@ config CMD_STM32KEY + 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 +- +-config PRE_CON_BUF_SZ +- default 4096 +- +-config BOOTSTAGE_STASH_ADDR +- default 0xC3000000 +- +-if BOOTCOUNT_LIMIT +-config SYS_BOOTCOUNT_SINGLEWORD +- default y +- +-# TAMP_BOOTCOUNT = TAMP_BACKUP_REGISTER(21) +-config SYS_BOOTCOUNT_ADDR +- default 0x5C00A154 +-endif +- +-if DEBUG_UART +- +-config DEBUG_UART_BOARD_INIT +- default y +- +-# debug on UART4 by default +-config DEBUG_UART_BASE +- default 0x40010000 +- +-# clock source is HSI on reset +-config DEBUG_UART_CLOCK +- default 64000000 +-endif ++source "arch/arm/mach-stm32mp/Kconfig.13x" ++source "arch/arm/mach-stm32mp/Kconfig.15x" + + source "arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig" +-source "board/dhelectronics/dh_stm32mp1/Kconfig" +-source "board/engicam/stm32mp1/Kconfig" +-source "board/st/stm32mp1/Kconfig" +- + endif +diff --git a/arch/arm/mach-stm32mp/Kconfig.13x b/arch/arm/mach-stm32mp/Kconfig.13x +new file mode 100644 +index 0000000000..5fc000986e +--- /dev/null ++++ b/arch/arm/mach-stm32mp/Kconfig.13x +@@ -0,0 +1,57 @@ ++if STM32MP13x ++ ++choice ++ prompt "STM32MP13x board select" ++ optional ++ ++config TARGET_ST_STM32MP13x ++ bool "STMicroelectronics STM32MP13x boards" ++ imply BOOTSTAGE ++ imply CMD_BOOTSTAGE ++ imply CMD_CLS if CMD_BMP ++ imply DISABLE_CONSOLE ++ imply PRE_CONSOLE_BUFFER ++ imply SILENT_CONSOLE ++ help ++ target the STMicroelectronics board with SOC STM32MP13x ++ managed by board/st/stm32mp1. ++ The difference between board are managed with devicetree ++ ++endchoice ++ ++config SYS_TEXT_BASE ++ default 0xC0000000 ++ ++config PRE_CON_BUF_ADDR ++ default 0xC0800000 ++ ++config PRE_CON_BUF_SZ ++ default 4096 ++ ++config BOOTSTAGE_STASH_ADDR ++ default 0xC3000000 ++ ++if BOOTCOUNT_GENERIC ++config SYS_BOOTCOUNT_SINGLEWORD ++ default y ++ ++# TAMP_BOOTCOUNT = TAMP_BACKUP_REGISTER(31) ++config SYS_BOOTCOUNT_ADDR ++ default 0x5C00A17C ++endif ++ ++if DEBUG_UART ++ ++# debug on UART4 by default ++config DEBUG_UART_BASE ++ default 0x40010000 ++ ++# clock source is HSI on reset ++config DEBUG_UART_CLOCK ++ default 48000000 if STM32_FPGA ++ default 64000000 ++endif ++ ++source "board/st/stm32mp1/Kconfig" ++ ++endif +diff --git a/arch/arm/mach-stm32mp/Kconfig.15x b/arch/arm/mach-stm32mp/Kconfig.15x +new file mode 100644 +index 0000000000..1887ce15ff +--- /dev/null ++++ b/arch/arm/mach-stm32mp/Kconfig.15x +@@ -0,0 +1,134 @@ ++if STM32MP15x ++ ++config STM32MP15x_STM32IMAGE ++ bool "Support STM32 image for generated U-Boot image" ++ depends on TFABOOT ++ help ++ Support of STM32 image generation for SOC STM32MP15x ++ for TF-A boot when FIP container is not used ++ ++choice ++ prompt "STM32MP15x board select" ++ optional ++ ++config TARGET_ST_STM32MP15x ++ bool "STMicroelectronics STM32MP15x boards" ++ imply BOOTSTAGE ++ imply CMD_BOOTSTAGE ++ imply CMD_CLS if CMD_BMP ++ imply DISABLE_CONSOLE ++ imply PRE_CONSOLE_BUFFER ++ imply SILENT_CONSOLE ++ help ++ target the STMicroelectronics board with SOC STM32MP15x ++ managed by board/st/stm32mp1: ++ Evalulation board (EV1) or Discovery board (DK1 and DK2). ++ The difference between board are managed with devicetree ++ ++config TARGET_DH_STM32MP1_PDK2 ++ bool "DH STM32MP1 PDK2" ++ help ++ Target the DH PDK2 development kit with STM32MP15x SoM. ++ ++config TARGET_MICROGEA_STM32MP1 ++ bool "Engicam MicroGEA STM32MP1 SOM" ++ imply BOOTSTAGE ++ imply CMD_BOOTSTAGE ++ imply CMD_CLS if CMD_BMP ++ imply DISABLE_CONSOLE ++ imply PRE_CONSOLE_BUFFER ++ imply SILENT_CONSOLE ++ help ++ MicroGEA STM32MP1 is a STM32MP157A based Micro SOM. ++ ++ MicroGEA STM32MP1 MicroDev 2.0: ++ * MicroDev 2.0 is a general purpose miniature carrier board with CAN, ++ LTE and LVDS panel interfaces. ++ * MicroGEA STM32MP1 needs to mount on top of this MicroDev 2.0 board ++ for creating complete MicroGEA STM32MP1 MicroDev 2.0 Carrier board. ++ ++ MicroGEA STM32MP1 MicroDev 2.0 7" OF: ++ * 7" OF is a capacitive touch 7" Open Frame panel solutions with LVDS ++ panel and toucscreen. ++ * MicroGEA STM32MP1 needs to mount on top of MicroDev 2.0 board with ++ pluged 7" OF for creating complete MicroGEA STM32MP1 MicroDev 2.0 7" ++ Open Frame Solution board. ++ ++config TARGET_ICORE_STM32MP1 ++ bool "Engicam i.Core STM32MP1 SOM" ++ imply BOOTSTAGE ++ imply CMD_BOOTSTAGE ++ imply CMD_CLS if CMD_BMP ++ imply DISABLE_CONSOLE ++ imply PRE_CONSOLE_BUFFER ++ imply SILENT_CONSOLE ++ help ++ i.Core STM32MP1 is an EDIMM SOM based on STM32MP157A. ++ ++ i.Core STM32MP1 EDIMM2.2: ++ * EDIMM2.2 is a Form Factor Capacitive Evaluation Board. ++ * i.Core STM32MP1 needs to mount on top of EDIMM2.2 for ++ creating complete i.Core STM32MP1 EDIMM2.2 Starter Kit. ++ ++ i.Core STM32MP1 C.TOUCH 2.0 ++ * C.TOUCH 2.0 is a general purpose Carrier board. ++ * i.Core STM32MP1 needs to mount on top of this Carrier board ++ for creating complete i.Core STM32MP1 C.TOUCH 2.0 board. ++ ++endchoice ++ ++config STM32MP15_PWR ++ bool "Enable driver for STM32MP15x PWR" ++ depends on DM_REGULATOR && DM_PMIC ++ default y ++ help ++ This config enables implementation of driver-model pmic and ++ regulator uclass features for access to STM32MP15x PWR. ++ ++config SPL_STM32MP15_PWR ++ bool "Enable driver for STM32MP15x PWR in SPL" ++ depends on SPL && SPL_DM_REGULATOR && SPL_DM_PMIC ++ default y ++ help ++ This config enables implementation of driver-model pmic and ++ regulator uclass features for access to STM32MP15x PWR in SPL. ++config SYS_TEXT_BASE ++ default 0xC0100000 ++ ++config PRE_CON_BUF_ADDR ++ default 0xC02FF000 ++ ++config PRE_CON_BUF_SZ ++ default 4096 ++ ++config BOOTSTAGE_STASH_ADDR ++ default 0xC3000000 ++ ++if BOOTCOUNT_GENERIC ++config SYS_BOOTCOUNT_SINGLEWORD ++ default y ++ ++# TAMP_BOOTCOUNT = TAMP_BACKUP_REGISTER(21) ++config SYS_BOOTCOUNT_ADDR ++ default 0x5C00A154 ++endif ++ ++if DEBUG_UART ++ ++config DEBUG_UART_BOARD_INIT ++ default y ++ ++# debug on UART4 by default ++config DEBUG_UART_BASE ++ default 0x40010000 ++ ++# clock source is HSI on reset ++config DEBUG_UART_CLOCK ++ default 64000000 ++endif ++ ++source "board/st/stm32mp1/Kconfig" ++source "board/dhelectronics/dh_stm32mp1/Kconfig" ++source "board/engicam/stm32mp1/Kconfig" ++ ++endif +diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile +index 391b47cf13..1db9057e04 100644 +--- a/arch/arm/mach-stm32mp/Makefile ++++ b/arch/arm/mach-stm32mp/Makefile +@@ -8,6 +8,9 @@ obj-y += dram_init.o + obj-y += syscon.o + obj-y += bsec.o + ++obj-$(CONFIG_STM32MP13x) += stm32mp13x.o ++obj-$(CONFIG_STM32MP15x) += stm32mp15x.o ++ + ifdef CONFIG_SPL_BUILD + obj-y += spl.o + obj-y += tzc400.o +@@ -19,5 +22,5 @@ obj-$(CONFIG_ARMV7_PSCI) += psci.o + obj-$(CONFIG_TFABOOT) += boot_params.o + endif + +-obj-$(CONFIG_$(SPL_)DM_REGULATOR) += pwr_regulator.o ++obj-$(CONFIG_$(SPL_)STM32MP15_PWR) += pwr_regulator.o + obj-$(CONFIG_OF_SYSTEM_SETUP) += fdt.o +diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c +index fe39bd80cf..1a06331530 100644 +--- a/arch/arm/mach-stm32mp/bsec.c ++++ b/arch/arm/mach-stm32mp/bsec.c +@@ -10,14 +10,17 @@ + #include + #include + #include ++#include + #include + #include + #include ++#include + #include + #include + #include + + #define BSEC_OTP_MAX_VALUE 95 ++#define BSEC_OTP_UPPER_START 32 + #define BSEC_TIMEOUT_US 10000 + + /* BSEC REGISTER OFFSET (base relative) */ +@@ -41,6 +44,7 @@ + /* BSEC_CONTROL Register */ + #define BSEC_READ 0x000 + #define BSEC_WRITE 0x100 ++#define BSEC_LOCK 0x200 + + /* LOCK Register */ + #define OTP_LOCK_MASK 0x1F +@@ -61,6 +65,48 @@ + */ + #define BSEC_LOCK_PROGRAM 0x04 + ++#define PTA_BSEC_UUID { 0x94cf71ad, 0x80e6, 0x40b5, \ ++ { 0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03 } } ++ ++/* ++ * Read OTP memory ++ * ++ * [in] value a: OTP start offset in byte ++ * b: access type ++ * 0 to read from shadow ++ * 1 to read from fuse ++ * 2 to read lock status ++ * [out] memref buffer: Output buffer to store read values ++ * size: Size of OTP to be read ++ * ++ * Return codes: ++ * TEE_SUCCESS - Invoke command success ++ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param ++ */ ++#define PTA_BSEC_READ_MEM 0x0 /* Read OTP */ ++ ++/* ++ * Write OTP memory ++ * ++ * [in] value a: OTP start offset in byte ++ * b: access type ++ * 0 to write to shadow ++ * 1 to write to fuse ++ * 2 to update the lock status ++ * [in] memref buffer: Input buffer to read values ++ * size: Size of OTP to be written ++ * ++ * Return codes: ++ * TEE_SUCCESS - Invoke command success ++ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param ++ */ ++#define PTA_BSEC_WRITE_MEM 0x1 /* Write OTP */ ++ ++/* value of PTA_BSEC access type = value[in] b */ ++#define SHADOW_ACCESS 0 ++#define FUSE_ACCESS 1 ++#define LOCK_ACCESS 2 ++ + /** + * bsec_lock() - manage lock for each type SR/SP/SW + * @address: address of bsec IP register +@@ -160,6 +206,7 @@ static int bsec_power_safmem(u32 base, bool power) + + /** + * bsec_shadow_register() - copy safmen otp to bsec data ++ * @dev: bsec IP device + * @base: base address of bsec IP + * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) + * Return: 0 if no error +@@ -203,6 +250,7 @@ static int bsec_shadow_register(struct udevice *dev, u32 base, u32 otp) + + /** + * bsec_read_shadow() - read an otp data value from shadow ++ * @dev: bsec IP device + * @base: base address of bsec IP + * @val: read value + * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) +@@ -217,6 +265,7 @@ static int bsec_read_shadow(struct udevice *dev, u32 base, u32 *val, u32 otp) + + /** + * bsec_write_shadow() - write value in BSEC data register in shadow ++ * @dev: bsec IP device + * @base: base address of bsec IP + * @val: value to write + * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) +@@ -235,6 +284,7 @@ static int bsec_write_shadow(struct udevice *dev, u32 base, u32 val, u32 otp) + + /** + * bsec_program_otp() - program a bit in SAFMEM ++ * @dev: bsec IP device + * @base: base address of bsec IP + * @val: value to program + * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) +@@ -284,18 +334,82 @@ static int bsec_program_otp(struct udevice *dev, long base, u32 val, u32 otp) + return ret; + } + ++/** ++ * bsec_permanent_lock_otp() - permanent lock of OTP in SAFMEM ++ * @dev: bsec IP device ++ * @base: base address of bsec IP ++ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) ++ * Return: 0 if no error ++ */ ++static int bsec_permanent_lock_otp(struct udevice *dev, long base, uint32_t otp) ++{ ++ int ret; ++ bool power_up = false; ++ u32 val, addr; ++ ++ /* check if safemem is power up */ ++ if (!(readl(base + BSEC_OTP_STATUS_OFF) & BSEC_MODE_PWR_MASK)) { ++ ret = bsec_power_safmem(base, true); ++ if (ret) ++ return ret; ++ ++ power_up = true; ++ } ++ ++ /* ++ * low OTPs = 2 bits word for low OTPs, 1 bits per word for upper OTP ++ * and only 16 bits used in WRDATA ++ */ ++ if (otp < BSEC_OTP_UPPER_START) { ++ addr = otp / 8; ++ val = 0x03 << ((otp * 2) & 0xF); ++ } else { ++ addr = BSEC_OTP_UPPER_START / 8 + ++ ((otp - BSEC_OTP_UPPER_START) / 16); ++ val = 0x01 << (otp & 0xF); ++ } ++ ++ /* set value in write register*/ ++ writel(val, base + BSEC_OTP_WRDATA_OFF); ++ ++ /* set BSEC_OTP_CTRL_OFF with the otp addr and lock request*/ ++ writel(addr | BSEC_WRITE | BSEC_LOCK, base + BSEC_OTP_CTRL_OFF); ++ ++ /* check otp status*/ ++ ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF, ++ val, (val & BSEC_MODE_BUSY_MASK) == 0, ++ BSEC_TIMEOUT_US); ++ if (ret) ++ return ret; ++ ++ if (val & BSEC_MODE_PROGFAIL_MASK) ++ ret = -EACCES; ++ else ++ ret = bsec_check_error(base, otp); ++ ++ if (power_up) ++ bsec_power_safmem(base, false); ++ ++ return ret; ++} ++ + /* BSEC MISC driver *******************************************************/ + struct stm32mp_bsec_plat { + u32 base; + }; + ++struct stm32mp_bsec_privdata { ++ struct udevice *tee; ++ u32 tee_session; ++}; ++ + static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp) + { + struct stm32mp_bsec_plat *plat; + u32 tmp_data = 0; + int ret; + +- if (IS_ENABLED(CONFIG_TFABOOT)) ++ if (IS_ENABLED(CONFIG_ARM_SMCCC) && !IS_ENABLED(CONFIG_SPL_BUILD)) + return stm32_smc(STM32_SMC_BSEC, + STM32_SMC_READ_OTP, + otp, 0, val); +@@ -326,7 +440,7 @@ static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp) + { + struct stm32mp_bsec_plat *plat; + +- if (IS_ENABLED(CONFIG_TFABOOT)) ++ if (IS_ENABLED(CONFIG_ARM_SMCCC) && !IS_ENABLED(CONFIG_SPL_BUILD)) + return stm32_smc(STM32_SMC_BSEC, + STM32_SMC_READ_SHADOW, + otp, 0, val); +@@ -339,9 +453,14 @@ static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp) + static int stm32mp_bsec_read_lock(struct udevice *dev, u32 *val, u32 otp) + { + struct stm32mp_bsec_plat *plat = dev_get_plat(dev); ++ u32 wrlock; + + /* return OTP permanent write lock status */ +- *val = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp); ++ wrlock = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp); ++ ++ *val = 0; ++ if (wrlock) ++ *val = BSEC_LOCK_PERM; + + return 0; + } +@@ -350,7 +469,7 @@ static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp) + { + struct stm32mp_bsec_plat *plat; + +- if (IS_ENABLED(CONFIG_TFABOOT)) ++ if (IS_ENABLED(CONFIG_ARM_SMCCC) && !IS_ENABLED(CONFIG_SPL_BUILD)) + return stm32_smc_exec(STM32_SMC_BSEC, + STM32_SMC_PROG_OTP, + otp, val); +@@ -365,7 +484,7 @@ static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp) + { + struct stm32mp_bsec_plat *plat; + +- if (IS_ENABLED(CONFIG_TFABOOT)) ++ if (IS_ENABLED(CONFIG_ARM_SMCCC) && !IS_ENABLED(CONFIG_SPL_BUILD)) + return stm32_smc_exec(STM32_SMC_BSEC, + STM32_SMC_WRITE_SHADOW, + otp, val); +@@ -377,27 +496,103 @@ static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp) + + static int stm32mp_bsec_write_lock(struct udevice *dev, u32 val, u32 otp) + { +- if (!IS_ENABLED(CONFIG_TFABOOT)) +- return -ENOTSUPP; ++ struct stm32mp_bsec_plat *plat; + +- if (val == 1) ++ /* only permanent write lock is supported in U-Boot */ ++ if (!(val & BSEC_LOCK_PERM)) { ++ dev_dbg(dev, "lock option without BSEC_LOCK_PERM: %x\n", val); ++ return 0; /* nothing to do */ ++ } ++ ++ if (IS_ENABLED(CONFIG_ARM_SMCCC) && !IS_ENABLED(CONFIG_SPL_BUILD)) + return stm32_smc_exec(STM32_SMC_BSEC, + STM32_SMC_WRLOCK_OTP, + otp, 0); +- if (val == 0) +- return 0; /* nothing to do */ + +- return -EINVAL; ++ plat = dev_get_plat(dev); ++ ++ return bsec_permanent_lock_otp(dev, plat->base, otp); ++} ++ ++static int bsec_optee_pta_open(struct udevice *dev) ++{ ++ struct stm32mp_bsec_privdata *priv = dev_get_priv(dev); ++ const struct tee_optee_ta_uuid uuid = PTA_BSEC_UUID; ++ struct tee_open_session_arg arg; ++ struct udevice *tee = NULL; ++ int rc; ++ ++ tee = tee_find_device(NULL, NULL, NULL, NULL); ++ if (!tee) ++ return -ENODEV; ++ ++ memset(&arg, 0, sizeof(arg)); ++ tee_optee_ta_uuid_to_octets(arg.uuid, &uuid); ++ arg.clnt_login = TEE_LOGIN_REE_KERNEL; ++ rc = tee_open_session(tee, &arg, 0, NULL); ++ if (rc < 0) ++ return -ENODEV; ++ ++ priv->tee = tee; ++ priv->tee_session = arg.session; ++ ++ return 0; ++} ++ ++static int bsec_optee_pta(struct udevice *dev, int cmd, int type, int offset, ++ void *buff, ulong size) ++{ ++ struct stm32mp_bsec_privdata *priv = dev_get_priv(dev); ++ struct tee_invoke_arg arg; ++ struct tee_param param[2]; ++ struct tee_shm *fw_shm; ++ int rc; ++ ++ rc = tee_shm_register(priv->tee, buff, size, 0, &fw_shm); ++ if (rc) ++ return rc; ++ ++ memset(&arg, 0, sizeof(arg)); ++ arg.func = cmd; ++ arg.session = priv->tee_session; ++ ++ memset(param, 0, sizeof(param)); ++ ++ param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT; ++ param[0].u.value.a = offset; ++ param[0].u.value.b = type; ++ ++ if (cmd == PTA_BSEC_WRITE_MEM) ++ param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT; ++ else ++ param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT; ++ ++ param[1].u.memref.shm = fw_shm; ++ param[1].u.memref.size = size; ++ ++ rc = tee_invoke_func(priv->tee, &arg, 2, param); ++ if (rc < 0 || arg.ret != 0) { ++ dev_err(priv->tee, ++ "PTA_BSEC invoke failed TEE err: %x, err:%x\n", ++ arg.ret, rc); ++ if (!rc) ++ rc = -EIO; ++ } ++ ++ tee_shm_free(fw_shm); ++ ++ return rc; + } + + static int stm32mp_bsec_read(struct udevice *dev, int offset, + void *buf, int size) + { ++ struct stm32mp_bsec_privdata *priv = dev_get_priv(dev); + int ret; + int i; + bool shadow = true, lock = false; + int nb_otp = size / sizeof(u32); +- int otp; ++ int otp, cmd; + unsigned int offs = offset; + + if (offs >= STM32_BSEC_LOCK_OFFSET) { +@@ -411,6 +606,19 @@ static int stm32mp_bsec_read(struct udevice *dev, int offset, + if ((offs % 4) || (size % 4)) + return -EINVAL; + ++ if (IS_ENABLED(CONFIG_OPTEE) && priv->tee) { ++ cmd = FUSE_ACCESS; ++ if (shadow) ++ cmd = SHADOW_ACCESS; ++ if (lock) ++ cmd = LOCK_ACCESS; ++ ret = bsec_optee_pta(dev, PTA_BSEC_READ_MEM, cmd, offs, buf, size); ++ if (ret) ++ return ret; ++ ++ return size; ++ } ++ + otp = offs / sizeof(u32); + + for (i = otp; i < (otp + nb_otp) && i <= BSEC_OTP_MAX_VALUE; i++) { +@@ -435,11 +643,12 @@ static int stm32mp_bsec_read(struct udevice *dev, int offset, + static int stm32mp_bsec_write(struct udevice *dev, int offset, + const void *buf, int size) + { ++ struct stm32mp_bsec_privdata *priv = dev_get_priv(dev); + int ret = 0; + int i; + bool shadow = true, lock = false; + int nb_otp = size / sizeof(u32); +- int otp; ++ int otp, cmd; + unsigned int offs = offset; + + if (offs >= STM32_BSEC_LOCK_OFFSET) { +@@ -453,6 +662,19 @@ static int stm32mp_bsec_write(struct udevice *dev, int offset, + if ((offs % 4) || (size % 4)) + return -EINVAL; + ++ if (IS_ENABLED(CONFIG_OPTEE) && priv->tee) { ++ cmd = FUSE_ACCESS; ++ if (shadow) ++ cmd = SHADOW_ACCESS; ++ if (lock) ++ cmd = LOCK_ACCESS; ++ ret = bsec_optee_pta(dev, PTA_BSEC_WRITE_MEM, cmd, offs, (void *)buf, size); ++ if (ret) ++ return ret; ++ ++ return size; ++ } ++ + otp = offs / sizeof(u32); + + for (i = otp; i < otp + nb_otp && i <= BSEC_OTP_MAX_VALUE; i++) { +@@ -501,12 +723,14 @@ static int stm32mp_bsec_probe(struct udevice *dev) + return ret; + } + ++ if (IS_ENABLED(CONFIG_OPTEE)) ++ bsec_optee_pta_open(dev); ++ + /* + * update unlocked shadow for OTP cleared by the rom code +- * only executed in U-Boot proper when TF-A is not used ++ * only executed in SPL, it is done in TF-A for TFABOOT + */ +- +- if (!IS_ENABLED(CONFIG_TFABOOT) && !IS_ENABLED(CONFIG_SPL_BUILD)) { ++ if (IS_ENABLED(CONFIG_SPL_BUILD)) { + plat = dev_get_plat(dev); + + for (otp = 57; otp <= BSEC_OTP_MAX_VALUE; otp++) +@@ -517,7 +741,23 @@ static int stm32mp_bsec_probe(struct udevice *dev) + return 0; + } + ++static int stm32mp_bsec_remove(struct udevice *dev) ++{ ++ struct stm32mp_bsec_privdata *priv = dev_get_priv(dev); ++ int ret; ++ ++ if (IS_ENABLED(CONFIG_OPTEE) && priv && priv->tee) { ++ ret = tee_close_session(priv->tee, priv->tee_session); ++ if (ret) ++ return ret; ++ priv->tee = NULL; ++ } ++ ++ return 0; ++} ++ + static const struct udevice_id stm32mp_bsec_ids[] = { ++ { .compatible = "st,stm32mp13-bsec" }, + { .compatible = "st,stm32mp15-bsec" }, + {} + }; +@@ -527,9 +767,11 @@ U_BOOT_DRIVER(stm32mp_bsec) = { + .id = UCLASS_MISC, + .of_match = stm32mp_bsec_ids, + .of_to_plat = stm32mp_bsec_of_to_plat, +- .plat_auto = sizeof(struct stm32mp_bsec_plat), ++ .plat_auto = sizeof(struct stm32mp_bsec_plat), ++ .priv_auto = sizeof(struct stm32mp_bsec_privdata), + .ops = &stm32mp_bsec_ops, + .probe = stm32mp_bsec_probe, ++ .remove = stm32mp_bsec_remove, + }; + + bool bsec_dbgswenable(void) +@@ -551,3 +793,20 @@ bool bsec_dbgswenable(void) + + return false; + } ++ ++u32 get_otp(int index, int shift, int mask) ++{ ++ int ret; ++ struct udevice *dev; ++ u32 otp = 0; ++ ++ ret = uclass_get_device_by_driver(UCLASS_MISC, ++ DM_DRIVER_GET(stm32mp_bsec), ++ &dev); ++ ++ if (!ret) ++ ret = misc_read(dev, STM32_BSEC_SHADOW(index), ++ &otp, sizeof(otp)); ++ ++ return (otp >> shift) & mask; ++} +diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c +index 68f28922d1..d58c422c11 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32key.c ++++ b/arch/arm/mach-stm32mp/cmd_stm32key.c +@@ -8,16 +8,82 @@ + #include + #include + #include ++#include + #include + #include + +-/* Closed device : bit 6 of OPT0*/ ++/* ++ * Closed device: OTP0 ++ * STM32MP15x: bit 6 of OPT0 ++ * STM32MP13x: 0b111111 = 0x3F for OTP_SECURED closed device ++ */ + #define STM32_OTP_CLOSE_ID 0 +-#define STM32_OTP_CLOSE_MASK BIT(6) ++#define STM32_OTP_STM32MP13x_CLOSE_MASK 0x3F ++#define STM32_OTP_STM32MP15x_CLOSE_MASK BIT(6) ++ ++/* PKH is the first element of the key list */ ++#define STM32KEY_PKH 0 ++ ++struct stm32key { ++ char *name; ++ char *desc; ++ u8 start; ++ u8 size; ++}; ++ ++const struct stm32key stm32mp13_list[] = { ++ [STM32KEY_PKH] = { ++ .name = "PKHTH", ++ .desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm)", ++ .start = 24, ++ .size = 8, ++ }, ++ { ++ .name = "EDMK", ++ .desc = "Encryption/Decryption Master Key", ++ .start = 92, ++ .size = 4, ++ } ++}; ++ ++const struct stm32key stm32mp15_list[] = { ++ [STM32KEY_PKH] = { ++ .name = "PKH", ++ .desc = "Hash of the ECC Public Key (ECDSA is the authentication algorithm)", ++ .start = 24, ++ .size = 8, ++ } ++}; ++ ++/* index of current selected key in stm32key list, 0 = PKH by default */ ++static u8 stm32key_index; ++ ++static u8 get_key_nb(void) ++{ ++ if (IS_ENABLED(CONFIG_STM32MP13x)) ++ return ARRAY_SIZE(stm32mp13_list); + +-/* HASH of key: 8 OTPs, starting with OTP24) */ +-#define STM32_OTP_HASH_KEY_START 24 +-#define STM32_OTP_HASH_KEY_SIZE 8 ++ if (IS_ENABLED(CONFIG_STM32MP15x)) ++ return ARRAY_SIZE(stm32mp15_list); ++} ++ ++static const struct stm32key *get_key(u8 index) ++{ ++ if (IS_ENABLED(CONFIG_STM32MP13x)) ++ return &stm32mp13_list[index]; ++ ++ if (IS_ENABLED(CONFIG_STM32MP15x)) ++ return &stm32mp15_list[index]; ++} ++ ++static u32 get_otp_close_mask(void) ++{ ++ if (IS_ENABLED(CONFIG_STM32MP13x)) ++ return STM32_OTP_STM32MP13x_CLOSE_MASK; ++ ++ if (IS_ENABLED(CONFIG_STM32MP15x)) ++ return STM32_OTP_STM32MP15x_CLOSE_MASK; ++} + + static int get_misc_dev(struct udevice **dev) + { +@@ -30,108 +96,115 @@ static int get_misc_dev(struct udevice **dev) + return ret; + } + +-static void read_hash_value(u32 addr) ++static void read_key_value(const struct stm32key *key, 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)); ++ for (i = 0; i < key->size; i++) { ++ printf("%s OTP %i: [%08x] %08x\n", key->name, key->start + i, ++ addr, __be32_to_cpu(*(u32 *)addr)); + addr += 4; + } + } + +-static int read_hash_otp(bool print, bool *locked, bool *closed) ++static int read_key_otp(struct udevice *dev, const struct stm32key *key, bool print, bool *locked) + { +- struct udevice *dev; + int i, word, ret; +- int nb_invalid = 0, nb_zero = 0, nb_lock = 0; ++ int nb_invalid = 0, nb_zero = 0, nb_lock = 0, nb_lock_err = 0; + u32 val, lock; + bool status; + +- 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++) { ++ for (i = 0, word = key->start; i < 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; ++ lock = BSEC_LOCK_ERROR; + if (print) +- printf("OTP HASH %i: %x lock : %d\n", word, val, lock); ++ printf("%s OTP %i: %08x lock : %08x\n", key->name, word, val, lock); + if (val == ~0x0) + nb_invalid++; + else if (val == 0x0) + nb_zero++; +- if (lock == 1) ++ if (lock & BSEC_LOCK_PERM) + nb_lock++; ++ if (lock & BSEC_LOCK_ERROR) ++ nb_lock_err++; + } + +- 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); ++ status = nb_lock_err || (nb_lock == key->size); + if (locked) + *locked = status; +- if (!status && print) +- printf("Hash of key is not locked!\n"); ++ if (nb_lock_err && print) ++ printf("%s lock is invalid!\n", key->name); ++ else if (!status && print) ++ printf("%s is not locked!\n", key->name); + +- if (nb_invalid == STM32_OTP_HASH_KEY_SIZE) { ++ if (nb_invalid == key->size) { + if (print) +- printf("Hash of key is invalid!\n"); ++ printf("%s is invalid!\n", key->name); + return -EINVAL; + } +- if (nb_zero == STM32_OTP_HASH_KEY_SIZE) { ++ if (nb_zero == key->size) { + if (print) +- printf("Hash of key is free!\n"); ++ printf("%s is free!\n", key->name); + return -ENOENT; + } + + return 0; + } + +-static int fuse_hash_value(u32 addr, bool print) ++static int read_close_status(struct udevice *dev, bool print, bool *closed) ++{ ++ int word, ret, result; ++ u32 val, lock, mask; ++ bool status; ++ ++ result = 0; ++ word = STM32_OTP_CLOSE_ID; ++ ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4); ++ if (ret < 0) ++ result = ret; ++ if (ret != 4) ++ val = 0x0; ++ ++ ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4); ++ if (ret < 0) ++ result = ret; ++ if (ret != 4) ++ lock = BSEC_LOCK_ERROR; ++ ++ mask = get_otp_close_mask(); ++ status = (val & mask) == mask; ++ if (closed) ++ *closed = status; ++ if (print) ++ printf("OTP %d: closed status: %d lock : %08x\n", word, status, lock); ++ ++ return result; ++} ++ ++static int fuse_key_value(struct udevice *dev, const struct stm32key *key, 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) { ++ for (i = 0, word = key->start; i < key->size; i++, word++, addr += 4) { + val = __be32_to_cpu(*(u32 *)addr); + if (print) +- printf("Fuse OTP %i : %x\n", word, val); ++ printf("Fuse %s OTP %i : %08x\n", key->name, word, val); + + ret = misc_write(dev, STM32_BSEC_OTP(word), &val, 4); + if (ret != 4) { +- log_err("Fuse OTP %i failed\n", word); ++ log_err("Fuse %s OTP %i failed\n", key->name, word); + return ret; + } +- /* on success, lock the OTP for HASH key */ +- val = 1; ++ /* on success, lock the OTP for the key */ ++ val = BSEC_LOCK_PERM; + ret = misc_write(dev, STM32_BSEC_LOCK(word), &val, 4); + if (ret != 4) { +- log_err("Lock OTP %i failed\n", word); ++ log_err("Lock %s OTP %i failed\n", key->name, word); + return ret; + } + } +@@ -153,28 +226,103 @@ static int confirm_prog(void) + return 0; + } + ++static void display_key_info(const struct stm32key *key) ++{ ++ printf("%s : %s\n", key->name, key->desc); ++ printf("\tOTP%d..%d\n", key->start, key->start + key->size); ++} ++ ++static int do_stm32key_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) ++{ ++ int i; ++ ++ for (i = 0; i < get_key_nb(); i++) ++ display_key_info(get_key(i)); ++ ++ return CMD_RET_SUCCESS; ++} ++ ++static int do_stm32key_select(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) ++{ ++ const struct stm32key *key; ++ int i; ++ ++ if (argc == 1) { ++ printf("Selected key:\n"); ++ key = get_key(stm32key_index); ++ display_key_info(key); ++ return CMD_RET_SUCCESS; ++ } ++ ++ for (i = 0; i < get_key_nb(); i++) { ++ key = get_key(i); ++ if (!strcmp(key->name, argv[1])) { ++ printf("%s selected\n", key->name); ++ stm32key_index = i; ++ return CMD_RET_SUCCESS; ++ } ++ } ++ ++ printf("Unknown key %s\n", argv[1]); ++ ++ return CMD_RET_FAILURE; ++} ++ + static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) + { ++ const struct stm32key *key; ++ struct udevice *dev; + u32 addr; ++ int ret, i; ++ int result; ++ ++ ret = get_misc_dev(&dev); + + if (argc == 1) { +- read_hash_otp(true, NULL, NULL); ++ if (ret) ++ return CMD_RET_FAILURE; ++ key = get_key(stm32key_index); ++ ret = read_key_otp(dev, key, true, NULL); ++ if (ret != -ENOENT) ++ return CMD_RET_FAILURE; + return CMD_RET_SUCCESS; + } + ++ if (!strcmp("-a", argv[1])) { ++ if (ret) ++ return CMD_RET_FAILURE; ++ result = CMD_RET_SUCCESS; ++ for (i = 0; i < get_key_nb(); i++) { ++ key = get_key(i); ++ ret = read_key_otp(dev, key, true, NULL); ++ if (ret != -ENOENT) ++ result = CMD_RET_FAILURE; ++ } ++ ret = read_close_status(dev, true, NULL); ++ if (ret) ++ result = CMD_RET_FAILURE; ++ ++ return result; ++ } ++ + addr = hextoul(argv[1], NULL); + if (!addr) + return CMD_RET_USAGE; + +- read_hash_value(addr); ++ key = get_key(stm32key_index); ++ printf("Read %s at 0x%08x\n", key->name, addr); ++ read_key_value(key, addr); + + return CMD_RET_SUCCESS; + } + + static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) + { ++ const struct stm32key *key = get_key(stm32key_index); ++ struct udevice *dev; + u32 addr; +- bool yes = false, lock, closed; ++ int ret; ++ bool yes = false, lock; + + if (argc < 2) + return CMD_RET_USAGE; +@@ -189,29 +337,38 @@ static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *con + if (!addr) + return CMD_RET_USAGE; + +- if (read_hash_otp(!yes, &lock, &closed) != -ENOENT) { ++ ret = get_misc_dev(&dev); ++ if (ret) ++ return CMD_RET_FAILURE; ++ ++ if (read_key_otp(dev, key, !yes, &lock) != -ENOENT) { + printf("Error: can't fuse again the OTP\n"); + return CMD_RET_FAILURE; + } +- +- if (lock || closed) { +- printf("Error: invalid OTP configuration (lock=%d, closed=%d)\n", lock, closed); ++ if (lock) { ++ printf("Error: %s is locked\n", key->name); + return CMD_RET_FAILURE; + } + ++ if (!yes) { ++ printf("Writing %s with\n", key->name); ++ read_key_value(key, addr); ++ } ++ + if (!yes && !confirm_prog()) + return CMD_RET_FAILURE; + +- if (fuse_hash_value(addr, !yes)) ++ if (fuse_key_value(dev, key, addr, !yes)) + return CMD_RET_FAILURE; + +- printf("Hash key updated !\n"); ++ printf("%s updated !\n", key->name); + + return CMD_RET_SUCCESS; + } + + static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) + { ++ const struct stm32key *key; + bool yes, lock, closed; + struct udevice *dev; + u32 val; +@@ -224,32 +381,36 @@ static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *co + yes = true; + } + +- ret = read_hash_otp(!yes, &lock, &closed); +- if (ret) { +- if (ret == -ENOENT) +- printf("Error: OTP not programmed!\n"); ++ ret = get_misc_dev(&dev); ++ if (ret) ++ return CMD_RET_FAILURE; ++ ++ if (read_close_status(dev, !yes, &closed)) + return CMD_RET_FAILURE; +- } + + if (closed) { + printf("Error: already closed!\n"); + return CMD_RET_FAILURE; + } + ++ /* check PKH status before to close */ ++ key = get_key(STM32KEY_PKH); ++ ret = read_key_otp(dev, key, !yes, &lock); ++ if (ret) { ++ if (ret == -ENOENT) ++ printf("Error: %s not programmed!\n", key->name); ++ return CMD_RET_FAILURE; ++ } + if (!lock) +- printf("Warning: OTP not locked!\n"); ++ printf("Warning: %s not locked!\n", key->name); + + if (!yes && !confirm_prog()) + return CMD_RET_FAILURE; + +- ret = get_misc_dev(&dev); +- if (ret) +- return CMD_RET_FAILURE; +- +- val = STM32_OTP_CLOSE_MASK; ++ val = get_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"); ++ printf("Error: can't update OTP %d\n", STM32_OTP_CLOSE_ID); + return CMD_RET_FAILURE; + } + +@@ -259,11 +420,15 @@ static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *co + } + + 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, ++ "list : list the supported key with description\n" ++ "stm32key select [] : Select the key identified by or display the key used for read/fuse command\n" ++ "stm32key read [ | -a ] : Read the curent key at or current / all (-a) key in OTP\n" ++ "stm32key fuse [-y] : Fuse the current key at addr in OTP\n" ++ "stm32key close [-y] : Close the device, force use of PKH stored in OTP\n"; ++ ++U_BOOT_CMD_WITH_SUBCMDS(stm32key, "Manage key on STM32", stm32key_help_text, ++ U_BOOT_SUBCMD_MKENT(list, 1, 0, do_stm32key_list), ++ U_BOOT_SUBCMD_MKENT(select, 2, 0, do_stm32key_select), + 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/Kconfig b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig +index f4c0d18d4d..8f91db4b46 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig ++++ b/arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig +@@ -1,4 +1,3 @@ +- + config CMD_STM32PROG + bool "command stm32prog for STM32CudeProgrammer" + select DFU +@@ -31,4 +30,11 @@ config CMD_STM32PROG_SERIAL + help + activate the command "stm32prog serial" for STM32MP soc family + with the tools STM32CubeProgrammer using U-Boot serial device +- and UART protocol. +\ No newline at end of file ++ and UART protocol. ++ ++config CMD_STM32PROG_OTP ++ bool "support stm32prog for OTP update" ++ depends on CMD_STM32PROG ++ default y if ARM_SMCCC || OPTEE ++ help ++ Support the OTP update with the command "stm32prog" for STM32MP +diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +index 41452b5a29..f59414e716 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c ++++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +@@ -73,16 +73,9 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, + + /* check STM32IMAGE presence */ + if (size == 0) { +- stm32prog_header_check((struct raw_header_s *)addr, &header); ++ stm32prog_header_check(addr, &header); + 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 ++ size = header.image_length + header.length; + } + } + +@@ -160,6 +153,8 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, + else if (CONFIG_IS_ENABLED(CMD_BOOTZ)) + do_bootz(cmdtp, 0, 4, bootm_argv); + } ++ if (data->script) ++ image_source_script(data->script, "script@stm32prog"); + + if (reset) { + puts("Reset...\n"); +diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +index 3b6ca4e773..ce568b44dc 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c ++++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +@@ -6,12 +6,15 @@ + #include + #include + #include ++#include + #include + #include + #include + #include ++#include + #include + #include ++#include + #include + #include + #include +@@ -46,7 +49,7 @@ + EFI_GUID(0xFD58F1C7, 0xBE0D, 0x4338, \ + 0x88, 0xE9, 0xAD, 0x8F, 0x05, 0x0A, 0xEB, 0x18) + +-/* RAW parttion (binary / bootloader) used Linux - reserved UUID */ ++/* RAW partition (binary / bootloader) used Linux - reserved UUID */ + #define LINUX_RESERVED_UUID "8DA63339-0007-60C0-C436-083AC8230908" + + /* +@@ -60,6 +63,28 @@ static const efi_guid_t uuid_mmc[3] = { + ROOTFS_MMC2_UUID + }; + ++/* FIP type partition UUID used by TF-A*/ ++#define FIP_TYPE_UUID "19D5DF83-11B0-457B-BE2C-7559C13142A5" ++ ++/* unique partition guid (uuid) for FIP partitions A/B */ ++#define FIP_A_UUID \ ++ EFI_GUID(0x4FD84C93, 0x54EF, 0x463F, \ ++ 0xA7, 0xEF, 0xAE, 0x25, 0xFF, 0x88, 0x70, 0x87) ++ ++#define FIP_B_UUID \ ++ EFI_GUID(0x09C54952, 0xD5BF, 0x45AF, \ ++ 0xAC, 0xEE, 0x33, 0x53, 0x03, 0x76, 0x6F, 0xB3) ++ ++static const char * const fip_part_name[] = { ++ "fip-a", ++ "fip-b" ++}; ++ ++static const efi_guid_t fip_part_uuid[] = { ++ FIP_A_UUID, ++ FIP_B_UUID ++}; ++ + /* order of column in flash layout file */ + enum stm32prog_col_t { + COL_OPTION, +@@ -81,6 +106,109 @@ struct fip_toc_header { + + DECLARE_GLOBAL_DATA_PTR; + ++/* OPTEE TA NVMEM helpers fucntions */ ++#define TA_NVMEM_UUID { 0x1a8342cc, 0x81a5, 0x4512, \ ++ { 0x99, 0xfe, 0x9e, 0x2b, 0x3e, 0x37, 0xd6, 0x26 } } ++ ++/* ++ * Read NVMEM memory for STM32CubeProgrammer ++ * ++ * [in] value a: Type ++ * 0 to read OTP ++ * [out] memref buffer: Output buffer to store read values ++ * size: Size of buffer to be read ++ * ++ * Return codes: ++ * TEE_SUCCESS - Invoke command success ++ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param ++ */ ++#define TA_NVMEM_READ 0x0 ++ ++/* ++ * Write NVMEM memory for STM32CubeProgrammer ++ * ++ * [in] value a: Type ++ * 0 to read OTP ++ * [in] memref buffer: Input buffer to read values ++ * size: Size of buffer to be written ++ * ++ * Return codes: ++ * TEE_SUCCESS - Invoke command success ++ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param ++ */ ++#define TA_NVMEM_WRITE 0x1 ++ ++/* value of TA_NVMEM type = value[in] a */ ++#define NVMEM_OTP 0 ++ ++static int optee_ta_open(struct stm32prog_data *data) ++{ ++ const struct tee_optee_ta_uuid uuid = TA_NVMEM_UUID; ++ struct tee_open_session_arg arg; ++ struct udevice *tee = NULL; ++ int rc; ++ ++ if (data->tee) ++ return 0; ++ ++ tee = tee_find_device(NULL, NULL, NULL, NULL); ++ if (!tee) ++ return -ENODEV; ++ ++ memset(&arg, 0, sizeof(arg)); ++ tee_optee_ta_uuid_to_octets(arg.uuid, &uuid); ++ rc = tee_open_session(tee, &arg, 0, NULL); ++ if (rc < 0) ++ return -ENODEV; ++ ++ data->tee = tee; ++ data->tee_session = arg.session; ++ ++ return 0; ++} ++ ++static int optee_ta_invoke(struct stm32prog_data *data, int cmd, int type, ++ void *buff, ulong size) ++{ ++ struct tee_invoke_arg arg; ++ struct tee_param param[2]; ++ struct tee_shm *buff_shm; ++ int rc; ++ ++ rc = tee_shm_register(data->tee, buff, size, 0, &buff_shm); ++ if (rc) ++ return rc; ++ ++ memset(&arg, 0, sizeof(arg)); ++ arg.func = cmd; ++ arg.session = data->tee_session; ++ ++ memset(param, 0, sizeof(param)); ++ param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT; ++ param[0].u.value.a = type; ++ ++ if (cmd == TA_NVMEM_WRITE) ++ param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT; ++ else ++ param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT; ++ ++ param[1].u.memref.shm = buff_shm; ++ param[1].u.memref.size = size; ++ ++ rc = tee_invoke_func(data->tee, &arg, 2, param); ++ if (rc < 0 || arg.ret != 0) { ++ dev_err(data->tee, ++ "TA_NVMEM invoke failed TEE err: %x, err:%x\n", ++ arg.ret, rc); ++ if (!rc) ++ rc = -EIO; ++ } ++ ++ tee_shm_free(buff_shm); ++ ++ return rc; ++} ++ + /* partition handling routines : CONFIG_CMD_MTDPARTS */ + int mtdparts_init(void); + int find_dev_and_part(const char *id, struct mtd_device **dev, +@@ -101,52 +229,98 @@ static bool stm32prog_is_fip_header(struct fip_toc_header *header) + return (header->name == FIP_TOC_HEADER_NAME) && header->serial_number; + } + +-void stm32prog_header_check(struct raw_header_s *raw_header, +- struct image_header_s *header) ++static bool stm32prog_is_stm32_header_v1(struct stm32_header_v1 *header) + { + unsigned int i; + +- if (!raw_header || !header) { +- log_debug("%s:no header data\n", __func__); +- return; ++ if (header->magic_number != ++ (('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) { ++ log_debug("%s:invalid magic number : 0x%x\n", ++ __func__, header->magic_number); ++ return false; ++ } ++ if (header->header_version != 0x00010000) { ++ log_debug("%s:invalid header version : 0x%x\n", ++ __func__, header->header_version); ++ return false; + } + +- header->type = HEADER_NONE; +- header->image_checksum = 0x0; +- header->image_length = 0x0; +- +- if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) { +- header->type = HEADER_FIP; +- return; ++ if (header->reserved1 || header->reserved2) { ++ log_debug("%s:invalid reserved field\n", __func__); ++ return false; ++ } ++ for (i = 0; i < sizeof(header->padding); i++) { ++ if (header->padding[i] != 0) { ++ log_debug("%s:invalid padding field\n", __func__); ++ return false; ++ } + } + +- if (raw_header->magic_number != ++ return true; ++} ++ ++static bool stm32prog_is_stm32_header_v2(struct stm32_header_v2 *header) ++{ ++ unsigned int i; ++ ++ if (header->magic_number != + (('S' << 0) | ('T' << 8) | ('M' << 16) | (0x32 << 24))) { + log_debug("%s:invalid magic number : 0x%x\n", +- __func__, raw_header->magic_number); +- return; ++ __func__, header->magic_number); ++ return false; + } +- /* only header v1.0 supported */ +- if (raw_header->header_version != 0x00010000) { ++ if (header->header_version != 0x00020000) { + log_debug("%s:invalid header version : 0x%x\n", +- __func__, raw_header->header_version); ++ __func__, header->header_version); ++ return false; ++ } ++ if (header->reserved1 || header->reserved2) ++ return false; ++ ++ for (i = 0; i < sizeof(header->padding); i++) { ++ if (header->padding[i] != 0) { ++ log_debug("%s:invalid padding field\n", __func__); ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header) ++{ ++ struct stm32_header_v1 *v1_header = (struct stm32_header_v1 *)raw_header; ++ struct stm32_header_v2 *v2_header = (struct stm32_header_v2 *)raw_header; ++ ++ if (!raw_header || !header) { ++ log_debug("%s:no header data\n", __func__); + return; + } +- if (raw_header->reserved1 != 0x0 || raw_header->reserved2) { +- log_debug("%s:invalid reserved field\n", __func__); ++ ++ if (stm32prog_is_fip_header((struct fip_toc_header *)raw_header)) { ++ header->type = HEADER_FIP; ++ header->length = 0; + return; + } +- for (i = 0; i < (sizeof(raw_header->padding) / 4); i++) { +- if (raw_header->padding[i] != 0) { +- log_debug("%s:invalid padding field\n", __func__); +- return; +- } ++ if (stm32prog_is_stm32_header_v1(v1_header)) { ++ header->type = HEADER_STM32IMAGE; ++ header->image_checksum = le32_to_cpu(v1_header->image_checksum); ++ header->image_length = le32_to_cpu(v1_header->image_length); ++ header->length = sizeof(struct stm32_header_v1); ++ return; ++ } ++ if (stm32prog_is_stm32_header_v2(v2_header)) { ++ header->type = HEADER_STM32IMAGE_V2; ++ header->image_checksum = le32_to_cpu(v2_header->image_checksum); ++ header->image_length = le32_to_cpu(v2_header->image_length); ++ header->length = sizeof(struct stm32_header_v1) + ++ v2_header->extension_headers_length; ++ return; + } +- header->type = HEADER_STM32IMAGE; +- header->image_checksum = le32_to_cpu(raw_header->image_checksum); +- header->image_length = le32_to_cpu(raw_header->image_length); + +- return; ++ header->type = HEADER_NONE; ++ header->image_checksum = 0x0; ++ header->image_length = 0x0; + } + + static u32 stm32prog_header_checksum(u32 addr, struct image_header_s *header) +@@ -255,6 +429,8 @@ static int parse_type(struct stm32prog_data *data, + part->bin_nb = + dectoul(&p[7], NULL); + } ++ } else if (!strcmp(p, "FIP")) { ++ part->part_type = PART_FIP; + } else if (!strcmp(p, "System")) { + part->part_type = PART_SYSTEM; + } else if (!strcmp(p, "FileSystem")) { +@@ -376,11 +552,11 @@ static int parse_flash_layout(struct stm32prog_data *data, + data->part_nb = 0; + + /* check if STM32image is detected */ +- stm32prog_header_check((struct raw_header_s *)addr, &header); ++ stm32prog_header_check(addr, &header); + if (header.type == HEADER_STM32IMAGE) { + u32 checksum; + +- addr = addr + BL_HEADER_SIZE; ++ addr = addr + header.length; + size = header.image_length; + + checksum = stm32prog_header_checksum(addr, &header); +@@ -835,8 +1011,8 @@ static int treat_partition_list(struct stm32prog_data *data) + /* skip partition with IP="none" */ + if (part->target == STM32PROG_NONE) { + if (IS_SELECT(part)) { +- stm32prog_err("Layout: selected none phase = 0x%x", +- part->id); ++ stm32prog_err("Layout: selected none phase = 0x%x for part %s", ++ part->id, part->name); + return -EINVAL; + } + continue; +@@ -844,14 +1020,14 @@ static int treat_partition_list(struct stm32prog_data *data) + + if (part->id == PHASE_FLASHLAYOUT || + part->id > PHASE_LAST_USER) { +- stm32prog_err("Layout: invalid phase = 0x%x", +- part->id); ++ stm32prog_err("Layout: invalid phase = 0x%x for part %s", ++ part->id, part->name); + return -EINVAL; + } + for (j = i + 1; j < data->part_nb; j++) { + if (part->id == data->part_array[j].id) { +- stm32prog_err("Layout: duplicated phase 0x%x at line %d and %d", +- part->id, i, j); ++ stm32prog_err("Layout: duplicated phase 0x%x for part %s and %s", ++ part->id, part->name, data->part_array[j].name); + return -EINVAL; + } + } +@@ -906,9 +1082,10 @@ static int create_gpt_partitions(struct stm32prog_data *data) + char uuid[UUID_STR_LEN + 1]; + unsigned char *uuid_bin; + unsigned int mmc_id; +- int i; ++ int i, j; + bool rootfs_found; + struct stm32prog_part_t *part; ++ const char *type_str; + + buf = malloc(buflen); + if (!buf) +@@ -950,33 +1127,46 @@ static int create_gpt_partitions(struct stm32prog_data *data) + part->addr, + part->size); + +- if (part->part_type == PART_BINARY) +- offset += snprintf(buf + offset, +- buflen - offset, +- ",type=" +- LINUX_RESERVED_UUID); +- else +- offset += snprintf(buf + offset, +- buflen - offset, +- ",type=linux"); ++ switch (part->part_type) { ++ case PART_BINARY: ++ type_str = LINUX_RESERVED_UUID; ++ break; ++ case PART_FIP: ++ type_str = FIP_TYPE_UUID; ++ break; ++ default: ++ type_str = "linux"; ++ break; ++ } ++ offset += snprintf(buf + offset, ++ buflen - offset, ++ ",type=%s", type_str); + + if (part->part_type == PART_SYSTEM) + offset += snprintf(buf + offset, + buflen - offset, + ",bootable"); + ++ /* partition UUID */ ++ uuid_bin = NULL; + if (!rootfs_found && !strcmp(part->name, "rootfs")) { + mmc_id = part->dev_id; + rootfs_found = true; +- if (mmc_id < ARRAY_SIZE(uuid_mmc)) { +- uuid_bin = +- (unsigned char *)uuid_mmc[mmc_id].b; +- uuid_bin_to_str(uuid_bin, uuid, +- UUID_STR_FORMAT_GUID); +- offset += snprintf(buf + offset, +- buflen - offset, +- ",uuid=%s", uuid); +- } ++ if (mmc_id < ARRAY_SIZE(uuid_mmc)) ++ uuid_bin = (unsigned char *)uuid_mmc[mmc_id].b; ++ } ++ if (part->part_type == PART_FIP) { ++ for (j = 0; j < ARRAY_SIZE(fip_part_name); j++) ++ if (!strcmp(part->name, fip_part_name[j])) { ++ uuid_bin = (unsigned char *)fip_part_uuid[j].b; ++ break; ++ } ++ } ++ if (uuid_bin) { ++ uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID); ++ offset += snprintf(buf + offset, ++ buflen - offset, ++ ",uuid=%s", uuid); + } + + offset += snprintf(buf + offset, buflen - offset, ";"); +@@ -1154,7 +1344,9 @@ static int dfu_init_entities(struct stm32prog_data *data) + struct dfu_entity *dfu; + int alt_nb; + +- alt_nb = 2; /* number of virtual = CMD, OTP*/ ++ alt_nb = 1; /* number of virtual = CMD*/ ++ if (IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) ++ alt_nb++; /* OTP*/ + if (CONFIG_IS_ENABLED(DM_PMIC)) + alt_nb++; /* PMIC NVMEM*/ + +@@ -1205,8 +1397,12 @@ static int dfu_init_entities(struct stm32prog_data *data) + if (!ret) + ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, CMD_SIZE); + +- if (!ret) +- ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, OTP_SIZE); ++ if (!ret && IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { ++ ret = optee_ta_open(data); ++ log_debug("optee_ta result %d\n", ret); ++ ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, ++ data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC); ++ } + + if (!ret && CONFIG_IS_ENABLED(DM_PMIC)) + ret = stm32prog_alt_add_virt(dfu, "PMIC", PHASE_PMIC, PMIC_SIZE); +@@ -1224,19 +1420,26 @@ static int dfu_init_entities(struct stm32prog_data *data) + int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, + long *size) + { ++ u32 otp_size = data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC; + log_debug("%s: %x %lx\n", __func__, offset, *size); + ++ if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { ++ stm32prog_err("OTP update not supported"); ++ ++ return -ENOTSUPP; ++ } ++ + if (!data->otp_part) { +- data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE); ++ data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, otp_size); + if (!data->otp_part) + return -ENOMEM; + } + + if (!offset) +- memset(data->otp_part, 0, OTP_SIZE); ++ memset(data->otp_part, 0, otp_size); + +- if (offset + *size > OTP_SIZE) +- *size = OTP_SIZE - offset; ++ if (offset + *size > otp_size) ++ *size = otp_size - offset; + + memcpy((void *)((u32)data->otp_part + offset), buffer, *size); + +@@ -1246,12 +1449,13 @@ int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, + int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, + long *size) + { ++ u32 otp_size = data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC; + int result = 0; + +- if (!IS_ENABLED(CONFIG_ARM_SMCCC)) { ++ if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { + stm32prog_err("OTP update not supported"); + +- return -1; ++ return -ENOTSUPP; + } + + log_debug("%s: %x %lx\n", __func__, offset, *size); +@@ -1259,7 +1463,7 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, + if (!offset) { + if (!data->otp_part) + data->otp_part = +- memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE); ++ memalign(CONFIG_SYS_CACHELINE_SIZE, otp_size); + + if (!data->otp_part) { + result = -ENOMEM; +@@ -1267,11 +1471,16 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, + } + + /* init struct with 0 */ +- memset(data->otp_part, 0, OTP_SIZE); ++ memset(data->otp_part, 0, otp_size); + + /* call the service */ +- result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL, +- (u32)data->otp_part, 0); ++ result = -ENOTSUPP; ++ if (data->tee && CONFIG_IS_ENABLED(OPTEE)) ++ result = optee_ta_invoke(data, TA_NVMEM_READ, NVMEM_OTP, ++ data->otp_part, OTP_SIZE_TA); ++ else if (IS_ENABLED(CONFIG_ARM_SMCCC)) ++ result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL, ++ (u32)data->otp_part, 0); + if (result) + goto end_otp_read; + } +@@ -1281,8 +1490,8 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, + goto end_otp_read; + } + +- if (offset + *size > OTP_SIZE) +- *size = OTP_SIZE - offset; ++ if (offset + *size > otp_size) ++ *size = otp_size - offset; + memcpy(buffer, (void *)((u32)data->otp_part + offset), *size); + + end_otp_read: +@@ -1296,10 +1505,10 @@ int stm32prog_otp_start(struct stm32prog_data *data) + int result = 0; + struct arm_smccc_res res; + +- if (!IS_ENABLED(CONFIG_ARM_SMCCC)) { ++ if (!IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { + stm32prog_err("OTP update not supported"); + +- return -1; ++ return -ENOTSUPP; + } + + if (!data->otp_part) { +@@ -1307,28 +1516,34 @@ int stm32prog_otp_start(struct stm32prog_data *data) + return -1; + } + +- arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, +- (u32)data->otp_part, 0, 0, 0, 0, 0, &res); +- +- if (!res.a0) { +- switch (res.a1) { +- case 0: +- result = 0; +- break; +- case 1: +- stm32prog_err("Provisioning"); +- result = 0; +- break; +- default: +- log_err("%s: OTP incorrect value (err = %ld)\n", +- __func__, res.a1); ++ result = -ENOTSUPP; ++ if (data->tee && CONFIG_IS_ENABLED(OPTEE)) { ++ result = optee_ta_invoke(data, TA_NVMEM_WRITE, NVMEM_OTP, ++ data->otp_part, OTP_SIZE_TA); ++ } else if (IS_ENABLED(CONFIG_ARM_SMCCC)) { ++ arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, ++ (u32)data->otp_part, 0, 0, 0, 0, 0, &res); ++ ++ if (!res.a0) { ++ switch (res.a1) { ++ case 0: ++ result = 0; ++ break; ++ case 1: ++ stm32prog_err("Provisioning"); ++ result = 0; ++ break; ++ default: ++ log_err("%s: OTP incorrect value (err = %ld)\n", ++ __func__, res.a1); ++ result = -EINVAL; ++ break; ++ } ++ } else { ++ log_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n", ++ __func__, STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, res.a0); + result = -EINVAL; +- break; + } +- } else { +- log_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n", +- __func__, STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, res.a0); +- result = -EINVAL; + } + + free(data->otp_part); +@@ -1431,7 +1646,7 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part) + int ret, i; + void *fsbl; + struct image_header_s header; +- struct raw_header_s raw_header; ++ struct stm32_header_v2 raw_header; /* V2 size > v1 size */ + struct dfu_entity *dfu; + long size, offset; + +@@ -1443,17 +1658,18 @@ static int stm32prog_copy_fsbl(struct stm32prog_part_t *part) + + /* read header */ + dfu_transaction_cleanup(dfu); +- size = BL_HEADER_SIZE; ++ size = sizeof(raw_header); + ret = dfu->read_medium(dfu, 0, (void *)&raw_header, &size); + if (ret) + return ret; + +- stm32prog_header_check(&raw_header, &header); +- if (header.type != HEADER_STM32IMAGE) ++ stm32prog_header_check((ulong)&raw_header, &header); ++ if (header.type != HEADER_STM32IMAGE && ++ header.type != HEADER_STM32IMAGE_V2) + return -ENOENT; + + /* read header + payload */ +- size = header.image_length + BL_HEADER_SIZE; ++ size = header.image_length + header.length; + size = round_up(size, part->dev->mtd->erasesize); + fsbl = calloc(1, size); + if (!fsbl) +@@ -1483,7 +1699,16 @@ error: + 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)) ++#if defined(CONFIG_LEGACY_IMAGE_FORMAT) ++ if (genimg_get_format((void *)STM32_DDR_BASE) == IMAGE_FORMAT_LEGACY) { ++ data->script = STM32_DDR_BASE; ++ data->phase = PHASE_END; ++ log_notice("U-Boot script received\n"); ++ return; ++ } ++#endif ++ log_notice("\nFlashLayout received, size = %lld\n", offset); ++ if (parse_flash_layout(data, STM32_DDR_BASE, offset)) + stm32prog_err("Layout: invalid FlashLayout"); + return; + } +@@ -1739,6 +1964,12 @@ void stm32prog_clean(struct stm32prog_data *data) + free(data->part_array); + free(data->otp_part); + free(data->buffer); ++ ++ if (CONFIG_IS_ENABLED(OPTEE) && data->tee) { ++ tee_close_session(data->tee, data->tee_session); ++ data->tee = NULL; ++ data->tee_session = 0x0; ++ } + } + + /* 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 240c5c44bc..ac300768ca 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h ++++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +@@ -20,7 +20,8 @@ + #define DEFAULT_ADDRESS 0xFFFFFFFF + + #define CMD_SIZE 512 +-#define OTP_SIZE 1024 ++#define OTP_SIZE_SMC 1024 ++#define OTP_SIZE_TA 776 + #define PMIC_SIZE 8 + + enum stm32prog_target { +@@ -41,6 +42,7 @@ enum stm32prog_link_t { + enum stm32prog_header_t { + HEADER_NONE, + HEADER_STM32IMAGE, ++ HEADER_STM32IMAGE_V2, + HEADER_FIP, + }; + +@@ -48,11 +50,12 @@ struct image_header_s { + enum stm32prog_header_t type; + u32 image_checksum; + u32 image_length; ++ u32 length; + }; + +-struct raw_header_s { ++struct stm32_header_v1 { + u32 magic_number; +- u32 image_signature[64 / 4]; ++ u8 image_signature[64]; + u32 image_checksum; + u32 header_version; + u32 image_length; +@@ -63,19 +66,38 @@ struct raw_header_s { + u32 version_number; + u32 option_flags; + u32 ecdsa_algorithm; +- u32 ecdsa_public_key[64 / 4]; +- u32 padding[83 / 4]; +- u32 binary_type; ++ u8 ecdsa_public_key[64]; ++ u8 padding[83]; ++ u8 binary_type; + }; + +-#define BL_HEADER_SIZE sizeof(struct raw_header_s) ++struct stm32_header_v2 { ++ u32 magic_number; ++ u8 image_signature[64]; ++ u32 image_checksum; ++ u32 header_version; ++ u32 image_length; ++ u32 image_entry_point; ++ u32 reserved1; ++ u32 load_address; ++ u32 reserved2; ++ u32 version_number; ++ u32 extension_flags; ++ u32 extension_headers_length; ++ u32 binary_type; ++ u8 padding[16]; ++ u32 extension_header_type; ++ u32 extension_header_length; ++ u8 extension_padding[376]; ++}; + + /* partition type in flashlayout file */ + enum stm32prog_part_type { + PART_BINARY, ++ PART_FIP, + PART_SYSTEM, + PART_FILESYSTEM, +- RAW_IMAGE ++ RAW_IMAGE, + }; + + /* device information */ +@@ -147,6 +169,12 @@ struct stm32prog_data { + u32 dtb; + u32 initrd; + u32 initrd_size; ++ ++ u32 script; ++ ++ /* OPTEE PTA NVMEM */ ++ struct udevice *tee; ++ u32 tee_session; + }; + + extern struct stm32prog_data *stm32prog_data; +@@ -166,8 +194,7 @@ int stm32prog_pmic_read(struct stm32prog_data *data, u32 offset, + int stm32prog_pmic_start(struct stm32prog_data *data); + + /* generic part*/ +-void stm32prog_header_check(struct raw_header_s *raw_header, +- struct image_header_s *header); ++void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header); + int stm32prog_dfu_init(struct stm32prog_data *data); + void stm32prog_next_phase(struct stm32prog_data *data); + void stm32prog_do_reset(struct stm32prog_data *data); +diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +index e8acc302f9..a8b57c4d8f 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c ++++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +@@ -181,7 +181,7 @@ int stm32prog_get_medium_size_virt(struct dfu_entity *dfu, u64 *size) + *size = CMD_SIZE; + break; + case PHASE_OTP: +- *size = OTP_SIZE; ++ *size = stm32prog_data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC; + break; + case PHASE_PMIC: + *size = PMIC_SIZE; +@@ -206,9 +206,12 @@ bool stm32prog_usb_loop(struct stm32prog_data *data, int dev) + g_dnl_set_product(product); + + if (stm32prog_data->phase == PHASE_FLASHLAYOUT) { ++ /* forget any previous Control C */ ++ clear_ctrlc(); + ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu"); +- if (ret || stm32prog_data->phase != PHASE_FLASHLAYOUT) +- return ret; ++ /* DFU reset received, no error or CtrlC */ ++ if (ret || stm32prog_data->phase != PHASE_FLASHLAYOUT || had_ctrlc()) ++ return ret; /* true = reset on DFU error */ + /* prepare the second enumeration with the FlashLayout */ + stm32prog_dfu_init(data); + } +diff --git a/arch/arm/mach-stm32mp/config.mk b/arch/arm/mach-stm32mp/config.mk +deleted file mode 100644 +index f7f5b77c41..0000000000 +--- a/arch/arm/mach-stm32mp/config.mk ++++ /dev/null +@@ -1,29 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +-# +-# Copyright (C) 2018, STMicroelectronics - All Rights Reserved +-# +- +-ifndef CONFIG_SPL +-INPUTS-$(CONFIG_STM32MP15x_STM32IMAGE) += u-boot.stm32 +-else +-ifdef CONFIG_SPL_BUILD +-INPUTS-y += u-boot-spl.stm32 +-endif +-endif +- +-MKIMAGEFLAGS_u-boot.stm32 = -T stm32image -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) +- +-u-boot.stm32: MKIMAGEOUTPUT = u-boot.stm32.log +- +-u-boot.stm32: u-boot.bin FORCE +- $(call if_changed,mkimage) +- +-MKIMAGEFLAGS_u-boot-spl.stm32 = -T stm32image -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) +- +-spl/u-boot-spl.stm32: MKIMAGEOUTPUT = spl/u-boot-spl.stm32.log +- +-spl/u-boot-spl.stm32: spl/u-boot-spl.bin FORCE +- $(call if_changed,mkimage) +- +-u-boot-spl.stm32 : spl/u-boot-spl.stm32 +- $(call if_changed,copy) +diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c +index eb79f3ffd2..2f17833579 100644 +--- a/arch/arm/mach-stm32mp/cpu.c ++++ b/arch/arm/mach-stm32mp/cpu.c +@@ -16,7 +16,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -24,66 +23,10 @@ + #include + #include + +-/* RCC register */ +-#define RCC_TZCR (STM32_RCC_BASE + 0x00) +-#define RCC_DBGCFGR (STM32_RCC_BASE + 0x080C) +-#define RCC_BDCR (STM32_RCC_BASE + 0x0140) +-#define RCC_MP_APB5ENSETR (STM32_RCC_BASE + 0x0208) +-#define RCC_MP_AHB5ENSETR (STM32_RCC_BASE + 0x0210) +-#define RCC_BDCR_VSWRST BIT(31) +-#define RCC_BDCR_RTCSRC GENMASK(17, 16) +-#define RCC_DBGCFGR_DBGCKEN BIT(8) +- +-/* Security register */ +-#define ETZPC_TZMA1_SIZE (STM32_ETZPC_BASE + 0x04) +-#define ETZPC_DECPROT0 (STM32_ETZPC_BASE + 0x10) +- +-#define TZC_GATE_KEEPER (STM32_TZC_BASE + 0x008) +-#define TZC_REGION_ATTRIBUTE0 (STM32_TZC_BASE + 0x110) +-#define TZC_REGION_ID_ACCESS0 (STM32_TZC_BASE + 0x114) +- +-#define TAMP_CR1 (STM32_TAMP_BASE + 0x00) +- +-#define PWR_CR1 (STM32_PWR_BASE + 0x00) +-#define PWR_MCUCR (STM32_PWR_BASE + 0x14) +-#define PWR_CR1_DBP BIT(8) +-#define PWR_MCUCR_SBF BIT(6) +- +-/* DBGMCU register */ +-#define DBGMCU_IDC (STM32_DBGMCU_BASE + 0x00) +-#define DBGMCU_APB4FZ1 (STM32_DBGMCU_BASE + 0x2C) +-#define DBGMCU_APB4FZ1_IWDG2 BIT(2) +-#define DBGMCU_IDC_DEV_ID_MASK GENMASK(11, 0) +-#define DBGMCU_IDC_DEV_ID_SHIFT 0 +-#define DBGMCU_IDC_REV_ID_MASK GENMASK(31, 16) +-#define DBGMCU_IDC_REV_ID_SHIFT 16 +- +-/* GPIOZ registers */ +-#define GPIOZ_SECCFGR 0x54004030 +- +-/* boot interface from Bootrom +- * - boot instance = bit 31:16 +- * - boot device = bit 15:0 +- */ +-#define BOOTROM_PARAM_ADDR 0x2FFC0078 +-#define BOOTROM_MODE_MASK GENMASK(15, 0) +-#define BOOTROM_MODE_SHIFT 0 +-#define BOOTROM_INSTANCE_MASK GENMASK(31, 16) +-#define BOOTROM_INSTANCE_SHIFT 16 +- + /* Device Part Number (RPN) = OTP_DATA1 lower 8 bits */ + #define RPN_SHIFT 0 +-#define RPN_MASK GENMASK(7, 0) +- +-/* Package = bit 27:29 of OTP16 +- * - 100: LBGA448 (FFI) => AA = LFBGA 18x18mm 448 balls p. 0.8mm +- * - 011: LBGA354 (LCI) => AB = LFBGA 16x16mm 359 balls p. 0.8mm +- * - 010: TFBGA361 (FFC) => AC = TFBGA 12x12mm 361 balls p. 0.5mm +- * - 001: TFBGA257 (LCC) => AD = TFBGA 10x10mm 257 balls p. 0.5mm +- * - others: Reserved +- */ +-#define PKG_SHIFT 27 +-#define PKG_MASK GENMASK(2, 0) ++#define RPN_MASK_STM32MP13x GENMASK(14, 0) ++#define RPN_MASK_STM32MP15x GENMASK(7, 0) + + /* + * early TLB into the .data section so that it not get cleared +@@ -93,120 +36,6 @@ 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) +-{ +- /* Disable the backup domain write protection */ +- /* the protection is enable at each reset by hardware */ +- /* And must be disable by software */ +- setbits_le32(PWR_CR1, PWR_CR1_DBP); +- +- while (!(readl(PWR_CR1) & PWR_CR1_DBP)) +- ; +- +- /* If RTC clock isn't enable so this is a cold boot then we need +- * to reset the backup domain +- */ +- if (!(readl(RCC_BDCR) & RCC_BDCR_RTCSRC)) { +- setbits_le32(RCC_BDCR, RCC_BDCR_VSWRST); +- while (!(readl(RCC_BDCR) & RCC_BDCR_VSWRST)) +- ; +- clrbits_le32(RCC_BDCR, RCC_BDCR_VSWRST); +- } +- +- /* allow non secure access in Write/Read for all peripheral */ +- writel(GENMASK(25, 0), ETZPC_DECPROT0); +- +- /* Open SYSRAM for no secure access */ +- writel(0x0, ETZPC_TZMA1_SIZE); +- +- /* enable TZC1 TZC2 clock */ +- writel(BIT(11) | BIT(12), RCC_MP_APB5ENSETR); +- +- /* Region 0 set to no access by default */ +- /* bit 0 / 16 => nsaid0 read/write Enable +- * bit 1 / 17 => nsaid1 read/write Enable +- * ... +- * bit 15 / 31 => nsaid15 read/write Enable +- */ +- writel(0xFFFFFFFF, TZC_REGION_ID_ACCESS0); +- /* bit 30 / 31 => Secure Global Enable : write/read */ +- /* bit 0 / 1 => Region Enable for filter 0/1 */ +- writel(BIT(0) | BIT(1) | BIT(30) | BIT(31), TZC_REGION_ATTRIBUTE0); +- +- /* Enable Filter 0 and 1 */ +- setbits_le32(TZC_GATE_KEEPER, BIT(0) | BIT(1)); +- +- /* RCC trust zone deactivated */ +- writel(0x0, RCC_TZCR); +- +- /* TAMP: deactivate the internal tamper +- * Bit 23 ITAMP8E: monotonic counter overflow +- * Bit 20 ITAMP5E: RTC calendar overflow +- * Bit 19 ITAMP4E: HSE monitoring +- * Bit 18 ITAMP3E: LSE monitoring +- * Bit 16 ITAMP1E: RTC power domain supply monitoring +- */ +- writel(0x0, TAMP_CR1); +- +- /* GPIOZ: deactivate the security */ +- writel(BIT(0), RCC_MP_AHB5ENSETR); +- writel(0x0, GPIOZ_SECCFGR); +-} +-#endif /* CONFIG_TFABOOT */ +- +-/* +- * Debug init +- */ +-static void dbgmcu_init(void) +-{ +- /* +- * Freeze IWDG2 if Cortex-A7 is in debug mode +- * done in TF-A for TRUSTED boot and +- * DBGMCU access is controlled by BSEC_DENABLE.DBGSWENABLE +- */ +- if (!IS_ENABLED(CONFIG_TFABOOT) && bsec_dbgswenable()) { +- setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN); +- setbits_le32(DBGMCU_APB4FZ1, DBGMCU_APB4FZ1_IWDG2); +- } +-} +- +-void spl_board_init(void) +-{ +- dbgmcu_init(); +-} +-#endif /* !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) */ +- +-#if !defined(CONFIG_TFABOOT) && \ +- (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) +-/* get bootmode from ROM code boot context: saved in TAMP register */ +-static void update_bootmode(void) +-{ +- u32 boot_mode; +- u32 bootrom_itf = readl(BOOTROM_PARAM_ADDR); +- u32 bootrom_device, bootrom_instance; +- +- /* enable TAMP clock = RTCAPBEN */ +- writel(BIT(8), RCC_MP_APB5ENSETR); +- +- /* read bootrom context */ +- bootrom_device = +- (bootrom_itf & BOOTROM_MODE_MASK) >> BOOTROM_MODE_SHIFT; +- bootrom_instance = +- (bootrom_itf & BOOTROM_INSTANCE_MASK) >> BOOTROM_INSTANCE_SHIFT; +- boot_mode = +- ((bootrom_device << BOOT_TYPE_SHIFT) & BOOT_TYPE_MASK) | +- ((bootrom_instance << BOOT_INSTANCE_SHIFT) & +- BOOT_INSTANCE_MASK); +- +- /* save the boot mode in TAMP backup register */ +- clrsetbits_le32(TAMP_BOOT_CONTEXT, +- TAMP_BOOT_MODE_MASK, +- boot_mode << TAMP_BOOT_MODE_SHIFT); +-} +-#endif +- + u32 get_bootmode(void) + { + /* read bootmode from TAMP backup register */ +@@ -228,8 +57,11 @@ void dram_bank_mmu_setup(int bank) + enum dcache_option option; + + if (IS_ENABLED(CONFIG_SPL_BUILD)) { ++/* STM32_SYSRAM_BASE exist only when SPL is supported */ ++#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; +@@ -276,36 +108,32 @@ static void early_enable_caches(void) + */ + int arch_cpu_init(void) + { +- u32 boot_mode; +- + early_enable_caches(); + + /* early armv7 timer init: needed for polling */ + timer_init(); + +-#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) +-#ifndef CONFIG_TFABOOT +- security_init(); +- update_bootmode(); +-#endif +- /* Reset Coprocessor state unless it wakes up from Standby power mode */ +- if (!(readl(PWR_MCUCR) & PWR_MCUCR_SBF)) { +- writel(TAMP_COPRO_STATE_OFF, TAMP_COPRO_STATE); +- writel(0, TAMP_COPRO_RSC_TBL_ADDRESS); +- } +-#endif ++ return 0; ++} ++ ++/* weak function for SOC specific initialization */ ++__weak void stm32mp_cpu_init(void) ++{ ++} ++ ++int mach_cpu_init(void) ++{ ++ u32 boot_mode; ++ ++ stm32mp_cpu_init(); + + boot_mode = get_bootmode(); + + if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL) && + (boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART) + gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; +-#if defined(CONFIG_DEBUG_UART) && \ +- !defined(CONFIG_TFABOOT) && \ +- (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) +- else ++ else if (IS_ENABLED(CONFIG_DEBUG_UART) && IS_ENABLED(CONFIG_SPL_BUILD)) + debug_uart_init(); +-#endif + + return 0; + } +@@ -326,140 +154,26 @@ void enable_caches(void) + dcache_enable(); + } + +-static u32 read_idc(void) +-{ +- /* DBGMCU access is controlled by BSEC_DENABLE.DBGSWENABLE */ +- if (bsec_dbgswenable()) { +- setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN); +- +- return readl(DBGMCU_IDC); +- } +- +- if (CONFIG_IS_ENABLED(STM32MP15x)) +- return CPU_DEV_STM32MP15; /* STM32MP15x and unknown revision */ +- else +- return 0x0; +-} +- +-u32 get_cpu_dev(void) +-{ +- return (read_idc() & DBGMCU_IDC_DEV_ID_MASK) >> DBGMCU_IDC_DEV_ID_SHIFT; +-} +- +-u32 get_cpu_rev(void) +-{ +- return (read_idc() & DBGMCU_IDC_REV_ID_MASK) >> DBGMCU_IDC_REV_ID_SHIFT; +-} +- +-static u32 get_otp(int index, int shift, int mask) +-{ +- int ret; +- struct udevice *dev; +- u32 otp = 0; +- +- ret = uclass_get_device_by_driver(UCLASS_MISC, +- DM_DRIVER_GET(stm32mp_bsec), +- &dev); +- +- if (!ret) +- ret = misc_read(dev, STM32_BSEC_SHADOW(index), +- &otp, sizeof(otp)); +- +- return (otp >> shift) & mask; +-} +- + /* Get Device Part Number (RPN) from OTP */ + static u32 get_cpu_rpn(void) + { +- return get_otp(BSEC_OTP_RPN, RPN_SHIFT, RPN_MASK); +-} +- +-u32 get_cpu_type(void) +-{ +- return (get_cpu_dev() << 16) | get_cpu_rpn(); +-} +- +-/* Get Package options from OTP */ +-u32 get_cpu_package(void) +-{ +- return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK); +-} +- +-static const char * const soc_type[] = { +- "????", +- "151C", "151A", "151F", "151D", +- "153C", "153A", "153F", "153D", +- "157C", "157A", "157F", "157D" +-}; +- +-static const char * const soc_pkg[] = { "??", "AD", "AC", "AB", "AA" }; +-static const char * const soc_rev[] = { "?", "A", "B", "Z" }; ++ int mask; + +-static void get_cpu_string_offsets(unsigned int *type, unsigned int *pkg, +- unsigned int *rev) +-{ +- u32 cpu_type = get_cpu_type(); +- u32 ct = cpu_type & ~(BIT(7) | BIT(0)); +- u32 cm = ((cpu_type & BIT(7)) >> 6) | (cpu_type & BIT(0)); +- u32 cp = get_cpu_package(); +- +- /* Bits 0 and 7 are the ACDF, 00:C 01:A 10:F 11:D */ +- switch (ct) { +- case CPU_STM32MP151Cxx: +- *type = cm + 1; +- break; +- case CPU_STM32MP153Cxx: +- *type = cm + 5; +- break; +- case CPU_STM32MP157Cxx: +- *type = cm + 9; +- break; +- default: +- *type = 0; +- break; +- } ++ if (IS_ENABLED(CONFIG_STM32MP13x)) ++ mask = RPN_MASK_STM32MP13x; + +- /* Package */ +- switch (cp) { +- case PKG_AA_LBGA448: +- case PKG_AB_LBGA354: +- case PKG_AC_TFBGA361: +- case PKG_AD_TFBGA257: +- *pkg = cp; +- break; +- default: +- *pkg = 0; +- break; +- } ++ if (IS_ENABLED(CONFIG_STM32MP15x)) ++ mask = RPN_MASK_STM32MP15x; + +- /* Revision */ +- switch (get_cpu_rev()) { +- case CPU_REVA: +- *rev = 1; +- break; +- case CPU_REVB: +- *rev = 2; +- break; +- case CPU_REVZ: +- *rev = 3; +- break; +- default: +- *rev = 0; +- break; +- } ++ return get_otp(BSEC_OTP_RPN, RPN_SHIFT, mask); + } + +-void get_soc_name(char name[SOC_NAME_SIZE]) ++u32 get_cpu_type(void) + { +- unsigned int type, pkg, rev; +- +- get_cpu_string_offsets(&type, &pkg, &rev); +- +- snprintf(name, SOC_NAME_SIZE, "STM32MP%s%s Rev.%s", +- soc_type[type], soc_pkg[pkg], soc_rev[rev]); ++ return (get_cpu_dev() << 16) | get_cpu_rpn(); + } + +-#if defined(CONFIG_DISPLAY_CPUINFO) ++/* used when CONFIG_DISPLAY_CPUINFO is activated */ + int print_cpuinfo(void) + { + char name[SOC_NAME_SIZE]; +@@ -469,7 +183,6 @@ int print_cpuinfo(void) + + return 0; + } +-#endif /* CONFIG_DISPLAY_CPUINFO */ + + static void setup_boot_mode(void) + { +@@ -599,40 +312,52 @@ static void setup_boot_mode(void) + */ + __weak int setup_mac_address(void) + { +-#if defined(CONFIG_NET) + int ret; + int i; +- u32 otp[2]; ++ u32 otp[3]; + uchar enetaddr[6]; + struct udevice *dev; ++ int nb_eth, nb_otp, index; + +- /* MAC already in environment */ +- if (eth_env_get_enetaddr("ethaddr", enetaddr)) ++ if (!IS_ENABLED(CONFIG_NET)) + return 0; + ++ nb_eth = get_eth_nb(); ++ ++ /* 6 bytes for each MAC addr and 4 bytes for each OTP */ ++ nb_otp = DIV_ROUND_UP(6 * nb_eth, 4); ++ + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_DRIVER_GET(stm32mp_bsec), + &dev); + if (ret) + return ret; + +- ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_MAC), +- otp, sizeof(otp)); ++ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_MAC), otp, 4 * nb_otp); + if (ret < 0) + return ret; + +- for (i = 0; i < 6; i++) +- enetaddr[i] = ((uint8_t *)&otp)[i]; ++ for (index = 0; index < nb_eth; index++) { ++ /* MAC already in environment */ ++ if (eth_env_get_enetaddr_by_index("eth", index, enetaddr)) ++ continue; + +- if (!is_valid_ethaddr(enetaddr)) { +- log_err("invalid MAC address in OTP %pM\n", enetaddr); +- return -EINVAL; ++ for (i = 0; i < 6; i++) ++ enetaddr[i] = ((uint8_t *)&otp)[i + 6 * index]; ++ ++ if (!is_valid_ethaddr(enetaddr)) { ++ log_err("invalid MAC address %d in OTP %pM\n", ++ index, enetaddr); ++ return -EINVAL; ++ } ++ log_debug("OTP MAC address %d = %pM\n", index, enetaddr); ++ ret = eth_env_set_enetaddr_by_index("eth", index, enetaddr); ++ if (ret) { ++ log_err("Failed to set mac address %pM from OTP: %d\n", ++ enetaddr, ret); ++ return ret; ++ } + } +- log_debug("OTP MAC address = %pM\n", enetaddr); +- ret = eth_env_set_enetaddr("ethaddr", enetaddr); +- if (ret) +- log_err("Failed to set mac address %pM from OTP: %d\n", enetaddr, ret); +-#endif + + return 0; + } +@@ -664,15 +389,8 @@ static int setup_serial_number(void) + return 0; + } + +-static void setup_soc_type_pkg_rev(void) ++__weak void stm32mp_misc_init(void) + { +- unsigned int type, pkg, rev; +- +- get_cpu_string_offsets(&type, &pkg, &rev); +- +- env_set("soc_type", soc_type[type]); +- env_set("soc_pkg", soc_pkg[pkg]); +- env_set("soc_rev", soc_rev[rev]); + } + + int arch_misc_init(void) +@@ -680,7 +398,7 @@ int arch_misc_init(void) + setup_boot_mode(); + setup_mac_address(); + setup_serial_number(); +- setup_soc_type_pkg_rev(); ++ stm32mp_misc_init(); + + return 0; + } +diff --git a/arch/arm/mach-stm32mp/fdt.c b/arch/arm/mach-stm32mp/fdt.c +index a19e954cf7..3201aba03e 100644 +--- a/arch/arm/mach-stm32mp/fdt.c ++++ b/arch/arm/mach-stm32mp/fdt.c +@@ -28,13 +28,120 @@ + + #define ETZPC_RESERVED 0xffffffff + +-#define STM32_FDCAN_BASE 0x4400e000 +-#define STM32_CRYP2_BASE 0x4c005000 +-#define STM32_CRYP1_BASE 0x54001000 +-#define STM32_GPU_BASE 0x59000000 +-#define STM32_DSI_BASE 0x5a000000 ++#define STM32MP13_FDCAN_BASE 0x4400F000 ++#define STM32MP13_ADC1_BASE 0x48003000 ++#define STM32MP13_TSC_BASE 0x5000B000 ++#define STM32MP13_CRYP_BASE 0x54002000 ++#define STM32MP13_ETH2_BASE 0x5800E000 ++#define STM32MP13_DCMIPP_BASE 0x5A000000 ++#define STM32MP13_LTDC_BASE 0x5A010000 ++ ++#define STM32MP15_FDCAN_BASE 0x4400e000 ++#define STM32MP15_CRYP2_BASE 0x4c005000 ++#define STM32MP15_CRYP1_BASE 0x54001000 ++#define STM32MP15_GPU_BASE 0x59000000 ++#define STM32MP15_DSI_BASE 0x5a000000 ++ ++static const u32 stm32mp13_ip_addr[] = { ++ 0x50025000, /* 0 VREFBUF APB3 */ ++ 0x50021000, /* 1 LPTIM2 APB3 */ ++ 0x50022000, /* 2 LPTIM3 APB3 */ ++ STM32MP13_LTDC_BASE, /* 3 LTDC APB4 */ ++ STM32MP13_DCMIPP_BASE, /* 4 DCMIPP APB4 */ ++ 0x5A006000, /* 5 USBPHYCTRL APB4 */ ++ 0x5A003000, /* 6 DDRCTRLPHY APB4 */ ++ ETZPC_RESERVED, /* 7 Reserved*/ ++ ETZPC_RESERVED, /* 8 Reserved*/ ++ ETZPC_RESERVED, /* 9 Reserved*/ ++ 0x5C006000, /* 10 TZC APB5 */ ++ 0x58001000, /* 11 MCE APB5 */ ++ 0x5C000000, /* 12 IWDG1 APB5 */ ++ 0x5C008000, /* 13 STGENC APB5 */ ++ ETZPC_RESERVED, /* 14 Reserved*/ ++ ETZPC_RESERVED, /* 15 Reserved*/ ++ 0x4C000000, /* 16 USART1 APB6 */ ++ 0x4C001000, /* 17 USART2 APB6 */ ++ 0x4C002000, /* 18 SPI4 APB6 */ ++ 0x4C003000, /* 19 SPI5 APB6 */ ++ 0x4C004000, /* 20 I2C3 APB6 */ ++ 0x4C005000, /* 21 I2C4 APB6 */ ++ 0x4C006000, /* 22 I2C5 APB6 */ ++ 0x4C007000, /* 23 TIM12 APB6 */ ++ 0x4C008000, /* 24 TIM13 APB6 */ ++ 0x4C009000, /* 25 TIM14 APB6 */ ++ 0x4C00A000, /* 26 TIM15 APB6 */ ++ 0x4C00B000, /* 27 TIM16 APB6 */ ++ 0x4C00C000, /* 28 TIM17 APB6 */ ++ ETZPC_RESERVED, /* 29 Reserved*/ ++ ETZPC_RESERVED, /* 30 Reserved*/ ++ ETZPC_RESERVED, /* 31 Reserved*/ ++ STM32MP13_ADC1_BASE, /* 32 ADC1 AHB2 */ ++ 0x48004000, /* 33 ADC2 AHB2 */ ++ 0x49000000, /* 34 OTG AHB2 */ ++ ETZPC_RESERVED, /* 35 Reserved*/ ++ ETZPC_RESERVED, /* 36 Reserved*/ ++ STM32MP13_TSC_BASE, /* 37 TSC AHB4 */ ++ ETZPC_RESERVED, /* 38 Reserved*/ ++ ETZPC_RESERVED, /* 39 Reserved*/ ++ 0x54004000, /* 40 RNG AHB5 */ ++ 0x54003000, /* 41 HASH AHB5 */ ++ STM32MP13_CRYP_BASE, /* 42 CRYPT AHB5 */ ++ 0x54005000, /* 43 SAES AHB5 */ ++ 0x54006000, /* 44 PKA AHB5 */ ++ 0x54000000, /* 45 BKPSRAM AHB5 */ ++ ETZPC_RESERVED, /* 46 Reserved*/ ++ ETZPC_RESERVED, /* 47 Reserved*/ ++ 0x5800A000, /* 48 ETH1 AHB6 */ ++ STM32MP13_ETH2_BASE, /* 49 ETH2 AHB6 */ ++ 0x58005000, /* 50 SDMMC1 AHB6 */ ++ 0x58007000, /* 51 SDMMC2 AHB6 */ ++ ETZPC_RESERVED, /* 52 Reserved*/ ++ ETZPC_RESERVED, /* 53 Reserved*/ ++ 0x58002000, /* 54 FMC AHB6 */ ++ 0x58003000, /* 55 QSPI AHB6 */ ++ ETZPC_RESERVED, /* 56 Reserved*/ ++ ETZPC_RESERVED, /* 57 Reserved*/ ++ ETZPC_RESERVED, /* 58 Reserved*/ ++ ETZPC_RESERVED, /* 59 Reserved*/ ++ 0x30000000, /* 60 SRAM1 MLAHB */ ++ 0x30004000, /* 61 SRAM2 MLAHB */ ++ 0x30006000, /* 62 SRAM3 MLAHB */ ++ ETZPC_RESERVED, /* 63 Reserved*/ ++ ETZPC_RESERVED, /* 64 Reserved*/ ++ ETZPC_RESERVED, /* 65 Reserved*/ ++ ETZPC_RESERVED, /* 66 Reserved*/ ++ ETZPC_RESERVED, /* 67 Reserved*/ ++ ETZPC_RESERVED, /* 68 Reserved*/ ++ ETZPC_RESERVED, /* 69 Reserved*/ ++ ETZPC_RESERVED, /* 70 Reserved*/ ++ ETZPC_RESERVED, /* 71 Reserved*/ ++ ETZPC_RESERVED, /* 72 Reserved*/ ++ ETZPC_RESERVED, /* 73 Reserved*/ ++ ETZPC_RESERVED, /* 74 Reserved*/ ++ ETZPC_RESERVED, /* 75 Reserved*/ ++ ETZPC_RESERVED, /* 76 Reserved*/ ++ ETZPC_RESERVED, /* 77 Reserved*/ ++ ETZPC_RESERVED, /* 78 Reserved*/ ++ ETZPC_RESERVED, /* 79 Reserved*/ ++ ETZPC_RESERVED, /* 80 Reserved*/ ++ ETZPC_RESERVED, /* 81 Reserved*/ ++ ETZPC_RESERVED, /* 82 Reserved*/ ++ ETZPC_RESERVED, /* 83 Reserved*/ ++ ETZPC_RESERVED, /* 84 Reserved*/ ++ ETZPC_RESERVED, /* 85 Reserved*/ ++ ETZPC_RESERVED, /* 86 Reserved*/ ++ ETZPC_RESERVED, /* 87 Reserved*/ ++ ETZPC_RESERVED, /* 88 Reserved*/ ++ ETZPC_RESERVED, /* 89 Reserved*/ ++ ETZPC_RESERVED, /* 90 Reserved*/ ++ ETZPC_RESERVED, /* 91 Reserved*/ ++ ETZPC_RESERVED, /* 92 Reserved*/ ++ ETZPC_RESERVED, /* 93 Reserved*/ ++ ETZPC_RESERVED, /* 94 Reserved*/ ++ ETZPC_RESERVED, /* 95 Reserved*/ ++}; + +-static const u32 stm32mp1_ip_addr[] = { ++static const u32 stm32mp15_ip_addr[] = { + 0x5c008000, /* 00 stgenc */ + 0x54000000, /* 01 bkpsram */ + 0x5c003000, /* 02 iwdg1 */ +@@ -44,7 +151,7 @@ static const u32 stm32mp1_ip_addr[] = { + ETZPC_RESERVED, /* 06 reserved */ + 0x54003000, /* 07 rng1 */ + 0x54002000, /* 08 hash1 */ +- STM32_CRYP1_BASE, /* 09 cryp1 */ ++ STM32MP15_CRYP1_BASE, /* 09 cryp1 */ + 0x5a003000, /* 0A ddrctrl */ + 0x5a004000, /* 0B ddrphyc */ + 0x5c009000, /* 0C i2c6 */ +@@ -97,7 +204,7 @@ static const u32 stm32mp1_ip_addr[] = { + 0x4400b000, /* 3B sai2 */ + 0x4400c000, /* 3C sai3 */ + 0x4400d000, /* 3D dfsdm */ +- STM32_FDCAN_BASE, /* 3E tt_fdcan */ ++ STM32MP15_FDCAN_BASE, /* 3E tt_fdcan */ + ETZPC_RESERVED, /* 3F reserved */ + 0x50021000, /* 40 lptim2 */ + 0x50022000, /* 41 lptim3 */ +@@ -110,7 +217,7 @@ static const u32 stm32mp1_ip_addr[] = { + 0x48003000, /* 48 adc */ + 0x4c002000, /* 49 hash2 */ + 0x4c003000, /* 4A rng2 */ +- STM32_CRYP2_BASE, /* 4B cryp2 */ ++ STM32MP15_CRYP2_BASE, /* 4B cryp2 */ + ETZPC_RESERVED, /* 4C reserved */ + ETZPC_RESERVED, /* 4D reserved */ + ETZPC_RESERVED, /* 4E reserved */ +@@ -163,8 +270,14 @@ static int stm32_fdt_fixup_etzpc(void *fdt, int soc_node) + int offset, shift; + u32 addr, status, decprot[ETZPC_DECPROT_NB]; + +- array = stm32mp1_ip_addr; +- array_size = ARRAY_SIZE(stm32mp1_ip_addr); ++ if (IS_ENABLED(CONFIG_STM32MP13x)) { ++ array = stm32mp13_ip_addr; ++ array_size = ARRAY_SIZE(stm32mp13_ip_addr); ++ } ++ if (IS_ENABLED(CONFIG_STM32MP15x)) { ++ array = stm32mp15_ip_addr; ++ array_size = ARRAY_SIZE(stm32mp15_ip_addr); ++ } + + for (i = 0; i < ETZPC_DECPROT_NB; i++) + decprot[i] = readl(ETZPC_DECPROT(i)); +@@ -248,30 +361,46 @@ static void stm32_fdt_disable_optee(void *blob) + } + } + +-/* +- * This function is called right before the kernel is booted. "blob" is the +- * device tree that will be passed to the kernel. +- */ +-int ft_system_setup(void *blob, struct bd_info *bd) ++static void stm32mp13_fdt_fixup(void *blob, int soc, u32 cpu, char *name) + { +- int ret = 0; +- int soc; +- u32 pkg, cpu; +- char name[SOC_NAME_SIZE]; +- +- soc = fdt_path_offset(blob, "/soc"); +- if (soc < 0) +- return soc; ++ switch (cpu) { ++ case CPU_STM32MP131Fxx: ++ case CPU_STM32MP131Dxx: ++ case CPU_STM32MP131Cxx: ++ case CPU_STM32MP131Axx: ++ stm32_fdt_disable(blob, soc, STM32MP13_FDCAN_BASE, "can", name); ++ stm32_fdt_disable(blob, soc, STM32MP13_ADC1_BASE, "adc", name); ++ fallthrough; ++ case CPU_STM32MP133Fxx: ++ case CPU_STM32MP133Dxx: ++ case CPU_STM32MP133Cxx: ++ case CPU_STM32MP133Axx: ++ stm32_fdt_disable(blob, soc, STM32MP13_LTDC_BASE, "ltdc", name); ++ stm32_fdt_disable(blob, soc, STM32MP13_DCMIPP_BASE, "dcmipp", ++ name); ++ stm32_fdt_disable(blob, soc, STM32MP13_TSC_BASE, "tsc", name); ++ break; ++ default: ++ break; ++ } + +- if (CONFIG_IS_ENABLED(STM32_ETZPC)) { +- ret = stm32_fdt_fixup_etzpc(blob, soc); +- if (ret) +- return ret; ++ switch (cpu) { ++ case CPU_STM32MP135Dxx: ++ case CPU_STM32MP135Axx: ++ case CPU_STM32MP133Dxx: ++ case CPU_STM32MP133Axx: ++ case CPU_STM32MP131Dxx: ++ case CPU_STM32MP131Axx: ++ stm32_fdt_disable(blob, soc, STM32MP13_CRYP_BASE, "cryp", name); ++ break; ++ default: ++ break; + } ++} + +- /* MPUs Part Numbers and name*/ +- cpu = get_cpu_type(); +- get_soc_name(name); ++static void stm32mp15_fdt_fixup(void *blob, int soc, u32 cpu, char *name) ++{ ++ u32 pkg; + + switch (cpu) { + case CPU_STM32MP151Fxx: +@@ -281,19 +410,18 @@ int ft_system_setup(void *blob, struct bd_info *bd) + stm32_fdt_fixup_cpu(blob, name); + /* after cpu delete we can't trust the soc offsets anymore */ + soc = fdt_path_offset(blob, "/soc"); +- stm32_fdt_disable(blob, soc, STM32_FDCAN_BASE, "can", name); +- /* fall through */ ++ stm32_fdt_disable(blob, soc, STM32MP15_FDCAN_BASE, "can", name); ++ fallthrough; + case CPU_STM32MP153Fxx: + case CPU_STM32MP153Dxx: + case CPU_STM32MP153Cxx: + case CPU_STM32MP153Axx: +- stm32_fdt_disable(blob, soc, STM32_GPU_BASE, "gpu", name); +- stm32_fdt_disable(blob, soc, STM32_DSI_BASE, "dsi", name); ++ stm32_fdt_disable(blob, soc, STM32MP15_GPU_BASE, "gpu", name); ++ stm32_fdt_disable(blob, soc, STM32MP15_DSI_BASE, "dsi", name); + break; + default: + break; + } +- + switch (cpu) { + case CPU_STM32MP157Dxx: + case CPU_STM32MP157Axx: +@@ -301,24 +429,25 @@ int ft_system_setup(void *blob, struct bd_info *bd) + case CPU_STM32MP153Axx: + case CPU_STM32MP151Dxx: + case CPU_STM32MP151Axx: +- stm32_fdt_disable(blob, soc, STM32_CRYP1_BASE, "cryp", name); +- stm32_fdt_disable(blob, soc, STM32_CRYP2_BASE, "cryp", name); ++ stm32_fdt_disable(blob, soc, STM32MP15_CRYP1_BASE, "cryp", ++ name); ++ stm32_fdt_disable(blob, soc, STM32MP15_CRYP2_BASE, "cryp", ++ name); + break; + default: + break; + } +- + switch (get_cpu_package()) { +- case PKG_AA_LBGA448: ++ case STM32MP15_PKG_AA_LBGA448: + pkg = STM32MP_PKG_AA; + break; +- case PKG_AB_LBGA354: ++ case STM32MP15_PKG_AB_LBGA354: + pkg = STM32MP_PKG_AB; + break; +- case PKG_AC_TFBGA361: ++ case STM32MP15_PKG_AC_TFBGA361: + pkg = STM32MP_PKG_AC; + break; +- case PKG_AD_TFBGA257: ++ case STM32MP15_PKG_AD_TFBGA257: + pkg = STM32MP_PKG_AD; + break; + default: +@@ -331,19 +460,54 @@ int ft_system_setup(void *blob, struct bd_info *bd) + do_fixup_by_compat_u32(blob, "st,stm32mp157-z-pinctrl", + "st,package", pkg, false); + } ++} ++ ++/* ++ * This function is called right before the kernel is booted. "blob" is the ++ * device tree that will be passed to the kernel. ++ */ ++int ft_system_setup(void *blob, struct bd_info *bd) ++{ ++ int ret = 0; ++ int soc; ++ u32 cpu; ++ char name[SOC_NAME_SIZE]; ++ ++ soc = fdt_path_offset(blob, "/soc"); ++ /* when absent, nothing to do */ ++ if (soc == -FDT_ERR_NOTFOUND) ++ return 0; ++ if (soc < 0) ++ return soc; ++ ++ if (CONFIG_IS_ENABLED(STM32_ETZPC)) { ++ ret = stm32_fdt_fixup_etzpc(blob, soc); ++ if (ret) ++ return ret; ++ } + +- /* +- * TEMP: remove OP-TEE nodes in kernel device tree +- * copied from U-Boot device tree by optee_copy_fdt_nodes +- * when OP-TEE is not detected (probe failed) +- * these OP-TEE nodes are present in -u-boot.dtsi +- * under CONFIG_STM32MP15x_STM32IMAGE only for compatibility +- * when FIP is not used by TF-A +- */ +- if (CONFIG_IS_ENABLED(STM32MP15x_STM32IMAGE) && +- CONFIG_IS_ENABLED(OPTEE) && +- !tee_find_device(NULL, NULL, NULL, NULL)) +- stm32_fdt_disable_optee(blob); ++ /* MPUs Part Numbers and name*/ ++ cpu = get_cpu_type(); ++ get_soc_name(name); ++ ++ if (IS_ENABLED(CONFIG_STM32MP13x)) ++ stm32mp13_fdt_fixup(blob, soc, cpu, name); ++ if (IS_ENABLED(CONFIG_STM32MP15x)) { ++ stm32mp15_fdt_fixup(blob, soc, cpu, name); ++ ++ /* ++ * TEMP: remove OP-TEE nodes in kernel device tree ++ * copied from U-Boot device tree by optee_copy_fdt_nodes ++ * when OP-TEE is not detected (probe failed) ++ * these OP-TEE nodes are present in -u-boot.dtsi ++ * under CONFIG_STM32MP15x_STM32IMAGE only for compatibility ++ * when FIP is not used by TF-A ++ */ ++ if (CONFIG_IS_ENABLED(STM32MP15x_STM32IMAGE) && ++ CONFIG_IS_ENABLED(OPTEE) && ++ !tee_find_device(NULL, NULL, NULL, NULL)) ++ stm32_fdt_disable_optee(blob); ++ } + + return ret; + } +diff --git a/arch/arm/mach-stm32mp/include/mach/bsec.h b/arch/arm/mach-stm32mp/include/mach/bsec.h +index 252eac3946..f2e3a102a1 100644 +--- a/arch/arm/mach-stm32mp/include/mach/bsec.h ++++ b/arch/arm/mach-stm32mp/include/mach/bsec.h +@@ -5,3 +5,11 @@ + + /* check self hosted debug status = BSEC_DENABLE.DBGSWENABLE */ + bool bsec_dbgswenable(void); ++ ++/* Bitfield definition for LOCK status */ ++/* warning: bit 31 is reserved in PTA NVEM for OTP_UPDATE_REQ */ ++#define BSEC_LOCK_PERM BIT(30) ++#define BSEC_LOCK_SHADOW_R BIT(29) ++#define BSEC_LOCK_SHADOW_W BIT(28) ++#define BSEC_LOCK_SHADOW_P BIT(27) ++#define BSEC_LOCK_ERROR BIT(26) +diff --git a/arch/arm/mach-stm32mp/include/mach/gpio.h b/arch/arm/mach-stm32mp/include/mach/gpio.h +deleted file mode 100644 +index 7a0f293519..0000000000 +--- a/arch/arm/mach-stm32mp/include/mach/gpio.h ++++ /dev/null +@@ -1,87 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0+ */ +-/* +- * (C) Copyright 2016 +- * Vikas Manocha, +- */ +- +-#ifndef _STM32_GPIO_H_ +-#define _STM32_GPIO_H_ +-#include +- +-enum stm32_gpio_mode { +- STM32_GPIO_MODE_IN = 0, +- STM32_GPIO_MODE_OUT, +- STM32_GPIO_MODE_AF, +- STM32_GPIO_MODE_AN +-}; +- +-enum stm32_gpio_otype { +- STM32_GPIO_OTYPE_PP = 0, +- STM32_GPIO_OTYPE_OD +-}; +- +-enum stm32_gpio_speed { +- STM32_GPIO_SPEED_2M = 0, +- STM32_GPIO_SPEED_25M, +- STM32_GPIO_SPEED_50M, +- STM32_GPIO_SPEED_100M +-}; +- +-enum stm32_gpio_pupd { +- STM32_GPIO_PUPD_NO = 0, +- STM32_GPIO_PUPD_UP, +- STM32_GPIO_PUPD_DOWN +-}; +- +-enum stm32_gpio_af { +- STM32_GPIO_AF0 = 0, +- STM32_GPIO_AF1, +- STM32_GPIO_AF2, +- STM32_GPIO_AF3, +- STM32_GPIO_AF4, +- STM32_GPIO_AF5, +- STM32_GPIO_AF6, +- STM32_GPIO_AF7, +- STM32_GPIO_AF8, +- STM32_GPIO_AF9, +- STM32_GPIO_AF10, +- STM32_GPIO_AF11, +- STM32_GPIO_AF12, +- STM32_GPIO_AF13, +- STM32_GPIO_AF14, +- STM32_GPIO_AF15 +-}; +- +-struct stm32_gpio_dsc { +- u8 port; +- u8 pin; +-}; +- +-struct stm32_gpio_ctl { +- enum stm32_gpio_mode mode; +- enum stm32_gpio_otype otype; +- enum stm32_gpio_speed speed; +- enum stm32_gpio_pupd pupd; +- enum stm32_gpio_af af; +-}; +- +-struct stm32_gpio_regs { +- u32 moder; /* GPIO port mode */ +- u32 otyper; /* GPIO port output type */ +- u32 ospeedr; /* GPIO port output speed */ +- u32 pupdr; /* GPIO port pull-up/pull-down */ +- u32 idr; /* GPIO port input data */ +- u32 odr; /* GPIO port output data */ +- u32 bsrr; /* GPIO port bit set/reset */ +- u32 lckr; /* GPIO port configuration lock */ +- u32 afr[2]; /* GPIO alternate function */ +-}; +- +-struct stm32_gpio_priv { +- struct stm32_gpio_regs *regs; +- unsigned int gpio_range; +-}; +- +-int stm32_offset_to_index(struct udevice *dev, unsigned int offset); +- +-#endif /* _STM32_GPIO_H_ */ +diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h +index c11a9903f2..62acd76c01 100644 +--- a/arch/arm/mach-stm32mp/include/mach/stm32.h ++++ b/arch/arm/mach-stm32mp/include/mach/stm32.h +@@ -16,15 +16,23 @@ + */ + #define STM32_RCC_BASE 0x50000000 + #define STM32_PWR_BASE 0x50001000 ++#ifdef CONFIG_STM32MP15x + #define STM32_DBGMCU_BASE 0x50081000 ++#endif + #define STM32_FMC2_BASE 0x58002000 + #define STM32_TZC_BASE 0x5C006000 + #define STM32_ETZPC_BASE 0x5C007000 + #define STM32_STGEN_BASE 0x5C008000 + #define STM32_TAMP_BASE 0x5C00A000 + ++#ifdef CONFIG_STM32MP15x + #define STM32_USART1_BASE 0x5C000000 + #define STM32_USART2_BASE 0x4000E000 ++#endif ++#ifdef CONFIG_STM32MP13x ++#define STM32_USART1_BASE 0x4c000000 ++#define STM32_USART2_BASE 0x4c001000 ++#endif + #define STM32_USART3_BASE 0x4000F000 + #define STM32_UART4_BASE 0x40010000 + #define STM32_UART5_BASE 0x40011000 +@@ -36,8 +44,10 @@ + #define STM32_SDMMC2_BASE 0x58007000 + #define STM32_SDMMC3_BASE 0x48004000 + ++#ifdef CONFIG_STM32MP15x + #define STM32_SYSRAM_BASE 0x2FFC0000 + #define STM32_SYSRAM_SIZE SZ_256K ++#endif + + #define STM32_DDR_BASE 0xC0000000 + #define STM32_DDR_SIZE SZ_1G +@@ -95,8 +105,12 @@ enum boot_device { + + /* TAMP registers */ + #define TAMP_BACKUP_REGISTER(x) (STM32_TAMP_BASE + 0x100 + 4 * x) ++ ++#ifdef CONFIG_STM32MP15x ++/* secure access */ + #define TAMP_BACKUP_MAGIC_NUMBER TAMP_BACKUP_REGISTER(4) + #define TAMP_BACKUP_BRANCH_ADDRESS TAMP_BACKUP_REGISTER(5) ++/* non secure access */ + #define TAMP_COPRO_RSC_TBL_ADDRESS TAMP_BACKUP_REGISTER(17) + #define TAMP_COPRO_STATE TAMP_BACKUP_REGISTER(18) + #define TAMP_BOOT_CONTEXT TAMP_BACKUP_REGISTER(20) +@@ -108,6 +122,12 @@ enum boot_device { + #define TAMP_COPRO_STATE_CSTOP 3 + #define TAMP_COPRO_STATE_STANDBY 4 + #define TAMP_COPRO_STATE_CRASH 5 ++#endif ++ ++#ifdef CONFIG_STM32MP13x ++#define TAMP_BOOTCOUNT TAMP_BACKUP_REGISTER(31) ++#define TAMP_BOOT_CONTEXT TAMP_BACKUP_REGISTER(30) ++#endif + + #define TAMP_BOOT_MODE_MASK GENMASK(15, 8) + #define TAMP_BOOT_MODE_SHIFT 8 +@@ -135,11 +155,19 @@ enum forced_boot_mode { + #define STM32_BSEC_LOCK(id) (STM32_BSEC_LOCK_OFFSET + (id) * 4) + + /* BSEC OTP index */ ++#ifdef CONFIG_STM32MP15x + #define BSEC_OTP_RPN 1 + #define BSEC_OTP_SERIAL 13 + #define BSEC_OTP_PKG 16 + #define BSEC_OTP_MAC 57 + #define BSEC_OTP_BOARD 59 ++#endif ++#ifdef CONFIG_STM32MP13x ++#define BSEC_OTP_RPN 1 ++#define BSEC_OTP_SERIAL 13 ++#define BSEC_OTP_MAC 57 ++#define BSEC_OTP_BOARD 60 ++#endif + + #endif /* __ASSEMBLY__ */ + #endif /* _MACH_STM32_H_ */ +diff --git a/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h +index 4ad14f963b..d72747ca31 100644 +--- a/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h ++++ b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h +@@ -8,19 +8,53 @@ + + #include + ++/* SMC service generic return codes */ ++#define STM32_SMC_OK 0x00000000U ++#define STM32_SMC_NOT_SUPPORTED 0xFFFFFFFFU ++#define STM32_SMC_FAILED 0xFFFFFFFEU ++#define STM32_SMC_INVALID_PARAMS 0xFFFFFFFDU ++ + /* +- * SMC function IDs for STM32 Service queries ++ * SMC function IDs for STM32 Service queries. + * STM32 SMC services use the space between 0x82000000 and 0x8200FFFF + * like this is defined in SMC calling Convention by ARM +- * for SiP (silicon Partner) +- * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html ++ * for SiP (silicon Partner). ++ * https://developer.arm.com/docs/den0028/latest + */ +-#define STM32_SMC_VERSION 0x82000000 + + /* Secure Service access from Non-secure */ ++ ++/* ++ * SMC function STM32_SMC_PWR. ++ * ++ * Argument a0: (input) SMCC ID. ++ * (output) Status return code. ++ * Argument a1: (input) Service ID (STM32_SMC_REG_xxx). ++ * Argument a2: (input) Register offset or physical address. ++ * (output) Register read value, if applicable. ++ * Argument a3: (input) Register target value if applicable. ++ */ ++#define STM32_SMC_PWR 0x82001001 ++ ++/* ++ * SMC functions STM32_SMC_BSEC. ++ * ++ * Argument a0: (input) SMCC ID. ++ * (output) Status return code. ++ * Argument a1: (input) Service ID (STM32_SMC_READ_xxx/_PROG_xxx/_WRITE_xxx). ++ * (output) OTP read value, if applicable. ++ * Argument a2: (input) OTP index. ++ * Argument a3: (input) OTP value if applicable. ++ */ + #define STM32_SMC_BSEC 0x82001003 + +-/* Service for BSEC */ ++/* Service ID for STM32_SMC_PWR */ ++#define STM32_SMC_REG_READ 0x0 ++#define STM32_SMC_REG_WRITE 0x1 ++#define STM32_SMC_REG_SET 0x2 ++#define STM32_SMC_REG_CLEAR 0x3 ++ ++/* Service ID for STM32_SMC_BSEC */ + #define STM32_SMC_READ_SHADOW 0x01 + #define STM32_SMC_PROG_OTP 0x02 + #define STM32_SMC_WRITE_SHADOW 0x03 +@@ -29,12 +63,6 @@ + #define STM32_SMC_WRITE_ALL 0x06 + #define STM32_SMC_WRLOCK_OTP 0x07 + +-/* SMC error codes */ +-#define STM32_SMC_OK 0x0 +-#define STM32_SMC_NOT_SUPPORTED -1 +-#define STM32_SMC_FAILED -2 +-#define STM32_SMC_INVALID_PARAMS -3 +- + #define stm32_smc_exec(svc, op, data1, data2) \ + stm32_smc(svc, op, data1, data2, NULL) + +diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h +index 4149d3a133..02debea546 100644 +--- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h ++++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h +@@ -3,7 +3,7 @@ + * Copyright (C) 2015-2017, STMicroelectronics - All Rights Reserved + */ + +-/* ID = Device Version (bit31:16) + Device Part Number (RPN) (bit7:0) */ ++/* ID = Device Version (bit31:16) + Device Part Number (RPN) (bit15:0) */ + #define CPU_STM32MP157Cxx 0x05000000 + #define CPU_STM32MP157Axx 0x05000001 + #define CPU_STM32MP153Cxx 0x05000024 +@@ -17,28 +17,46 @@ + #define CPU_STM32MP151Fxx 0x050000AE + #define CPU_STM32MP151Dxx 0x050000AF + ++#define CPU_STM32MP135Cxx 0x05010000 ++#define CPU_STM32MP135Axx 0x05010001 ++#define CPU_STM32MP133Cxx 0x050100C0 ++#define CPU_STM32MP133Axx 0x050100C1 ++#define CPU_STM32MP131Cxx 0x050106C8 ++#define CPU_STM32MP131Axx 0x050106C9 ++#define CPU_STM32MP135Fxx 0x05010800 ++#define CPU_STM32MP135Dxx 0x05010801 ++#define CPU_STM32MP133Fxx 0x050108C0 ++#define CPU_STM32MP133Dxx 0x050108C1 ++#define CPU_STM32MP131Fxx 0x05010EC8 ++#define CPU_STM32MP131Dxx 0x05010EC9 ++ + /* return CPU_STMP32MP...Xxx constants */ + u32 get_cpu_type(void); + + #define CPU_DEV_STM32MP15 0x500 ++#define CPU_DEV_STM32MP13 0x501 + + /* return CPU_DEV constants */ + u32 get_cpu_dev(void); + +-#define CPU_REVA 0x1000 +-#define CPU_REVB 0x2000 +-#define CPU_REVZ 0x2001 ++#define CPU_REV1 0x1000 ++#define CPU_REV1_1 0x1001 ++#define CPU_REV1_2 0x1002 ++#define CPU_REV2 0x2000 ++#define CPU_REV2_1 0x2001 + +-/* return CPU_REV constants */ ++/* return Silicon revision = REV_ID[15:0] of Device Version */ + u32 get_cpu_rev(void); + + /* Get Package options from OTP */ + u32 get_cpu_package(void); + +-#define PKG_AA_LBGA448 4 +-#define PKG_AB_LBGA354 3 +-#define PKG_AC_TFBGA361 2 +-#define PKG_AD_TFBGA257 1 ++/* package used for STM32MP15x */ ++#define STM32MP15_PKG_AA_LBGA448 4 ++#define STM32MP15_PKG_AB_LBGA354 3 ++#define STM32MP15_PKG_AC_TFBGA361 2 ++#define STM32MP15_PKG_AD_TFBGA257 1 ++#define STM32MP15_PKG_UNKNOWN 0 + + /* Get SOC name */ + #define SOC_NAME_SIZE 20 +@@ -47,7 +65,15 @@ void get_soc_name(char name[SOC_NAME_SIZE]); + /* return boot mode */ + u32 get_bootmode(void); + ++int get_eth_nb(void); + int setup_mac_address(void); + + /* board power management : configure vddcore according OPP */ + void board_vddcore_init(u32 voltage_mv); ++ ++/* weak function */ ++void stm32mp_cpu_init(void); ++void stm32mp_misc_init(void); ++ ++/* helper function: read data from OTP */ ++u32 get_otp(int index, int shift, int mask); +diff --git a/arch/arm/mach-stm32mp/pwr_regulator.c b/arch/arm/mach-stm32mp/pwr_regulator.c +index 846637ab16..c666f9f409 100644 +--- a/arch/arm/mach-stm32mp/pwr_regulator.c ++++ b/arch/arm/mach-stm32mp/pwr_regulator.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -44,6 +45,10 @@ static int stm32mp_pwr_write(struct udevice *dev, uint reg, + if (len != 4) + return -EINVAL; + ++ if (IS_ENABLED(CONFIG_ARM_SMCCC) && !IS_ENABLED(CONFIG_SPL_BUILD)) ++ return stm32_smc_exec(STM32_SMC_PWR, STM32_SMC_REG_WRITE, ++ STM32MP_PWR_CR3, val); ++ + writel(val, priv->base + STM32MP_PWR_CR3); + + return 0; +diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c +index 405eff68a3..47d2724a70 100644 +--- a/arch/arm/mach-stm32mp/spl.c ++++ b/arch/arm/mach-stm32mp/spl.c +@@ -190,6 +190,7 @@ void board_init_f(ulong dummy) + int ret; + + arch_cpu_init(); ++ mach_cpu_init(); + + ret = spl_early_init(); + if (ret) { +diff --git a/arch/arm/mach-stm32mp/stm32mp13x.c b/arch/arm/mach-stm32mp/stm32mp13x.c +new file mode 100644 +index 0000000000..4ec55e361d +--- /dev/null ++++ b/arch/arm/mach-stm32mp/stm32mp13x.c +@@ -0,0 +1,123 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#define LOG_CATEGORY LOGC_ARCH ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* SYSCFG register */ ++#define SYSCFG_IDC_OFFSET 0x380 ++#define SYSCFG_IDC_DEV_ID_MASK GENMASK(11, 0) ++#define SYSCFG_IDC_DEV_ID_SHIFT 0 ++#define SYSCFG_IDC_REV_ID_MASK GENMASK(31, 16) ++#define SYSCFG_IDC_REV_ID_SHIFT 16 ++ ++static u32 read_idc(void) ++{ ++ void *syscfg = syscon_get_first_range(STM32MP_SYSCON_SYSCFG); ++ ++ return readl(syscfg + SYSCFG_IDC_OFFSET); ++} ++ ++u32 get_cpu_dev(void) ++{ ++ return (read_idc() & SYSCFG_IDC_DEV_ID_MASK) >> SYSCFG_IDC_DEV_ID_SHIFT; ++} ++ ++u32 get_cpu_rev(void) ++{ ++ return (read_idc() & SYSCFG_IDC_REV_ID_MASK) >> SYSCFG_IDC_REV_ID_SHIFT; ++} ++ ++int get_eth_nb(void) ++{ ++ int nb_eth = 2; ++ ++ switch (get_cpu_type()) { ++ case CPU_STM32MP131Dxx: ++ fallthrough; ++ case CPU_STM32MP131Cxx: ++ fallthrough; ++ case CPU_STM32MP131Axx: ++ nb_eth = 1; ++ break; ++ default: ++ nb_eth = 2; ++ break; ++ } ++ ++ return nb_eth; ++} ++ ++void get_soc_name(char name[SOC_NAME_SIZE]) ++{ ++ char *cpu_s, *cpu_r; ++ ++ /* MPUs Part Numbers */ ++ switch (get_cpu_type()) { ++ case CPU_STM32MP135Fxx: ++ cpu_s = "135F"; ++ break; ++ case CPU_STM32MP135Dxx: ++ cpu_s = "135D"; ++ break; ++ case CPU_STM32MP135Cxx: ++ cpu_s = "135C"; ++ break; ++ case CPU_STM32MP135Axx: ++ cpu_s = "135A"; ++ break; ++ case CPU_STM32MP133Fxx: ++ cpu_s = "133F"; ++ break; ++ case CPU_STM32MP133Dxx: ++ cpu_s = "133D"; ++ break; ++ case CPU_STM32MP133Cxx: ++ cpu_s = "133C"; ++ break; ++ case CPU_STM32MP133Axx: ++ cpu_s = "133A"; ++ break; ++ case CPU_STM32MP131Fxx: ++ cpu_s = "131F"; ++ break; ++ case CPU_STM32MP131Dxx: ++ cpu_s = "131D"; ++ break; ++ case CPU_STM32MP131Cxx: ++ cpu_s = "131C"; ++ break; ++ case CPU_STM32MP131Axx: ++ cpu_s = "131A"; ++ break; ++ default: ++ cpu_s = "????"; ++ break; ++ } ++ ++ /* REVISION */ ++ switch (get_cpu_rev()) { ++ case CPU_REV1: ++ cpu_r = "A"; ++ break; ++ case CPU_REV1_1: ++ cpu_r = "Z"; ++ break; ++ case CPU_REV1_2: ++ cpu_r = "Y"; ++ break; ++ default: ++ cpu_r = "?"; ++ break; ++ } ++ ++ snprintf(name, SOC_NAME_SIZE, "STM32MP%s Rev.%s", cpu_s, cpu_r); ++} +diff --git a/arch/arm/mach-stm32mp/stm32mp15x.c b/arch/arm/mach-stm32mp/stm32mp15x.c +new file mode 100644 +index 0000000000..0f55cc4753 +--- /dev/null ++++ b/arch/arm/mach-stm32mp/stm32mp15x.c +@@ -0,0 +1,330 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright (C) 2021, STMicroelectronics - All Rights Reserved ++ */ ++ ++#define LOG_CATEGORY LOGC_ARCH ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* RCC register */ ++#define RCC_TZCR (STM32_RCC_BASE + 0x00) ++#define RCC_BDCR (STM32_RCC_BASE + 0x0140) ++#define RCC_MP_APB5ENSETR (STM32_RCC_BASE + 0x0208) ++#define RCC_MP_AHB5ENSETR (STM32_RCC_BASE + 0x0210) ++#define RCC_DBGCFGR (STM32_RCC_BASE + 0x080C) ++ ++#define RCC_BDCR_VSWRST BIT(31) ++#define RCC_BDCR_RTCSRC GENMASK(17, 16) ++ ++#define RCC_DBGCFGR_DBGCKEN BIT(8) ++ ++/* DBGMCU register */ ++#define DBGMCU_IDC (STM32_DBGMCU_BASE + 0x00) ++#define DBGMCU_APB4FZ1 (STM32_DBGMCU_BASE + 0x2C) ++#define DBGMCU_APB4FZ1_IWDG2 BIT(2) ++ ++/* Security register */ ++#define ETZPC_TZMA1_SIZE (STM32_ETZPC_BASE + 0x04) ++#define ETZPC_DECPROT0 (STM32_ETZPC_BASE + 0x10) ++ ++#define TZC_GATE_KEEPER (STM32_TZC_BASE + 0x008) ++#define TZC_REGION_ATTRIBUTE0 (STM32_TZC_BASE + 0x110) ++#define TZC_REGION_ID_ACCESS0 (STM32_TZC_BASE + 0x114) ++ ++#define TAMP_CR1 (STM32_TAMP_BASE + 0x00) ++ ++#define PWR_CR1 (STM32_PWR_BASE + 0x00) ++#define PWR_MCUCR (STM32_PWR_BASE + 0x14) ++#define PWR_CR1_DBP BIT(8) ++#define PWR_MCUCR_SBF BIT(6) ++ ++/* GPIOZ registers */ ++#define GPIOZ_SECCFGR 0x54004030 ++ ++/* DBGMCU register */ ++#define DBGMCU_IDC (STM32_DBGMCU_BASE + 0x00) ++#define DBGMCU_IDC_DEV_ID_MASK GENMASK(11, 0) ++#define DBGMCU_IDC_DEV_ID_SHIFT 0 ++#define DBGMCU_IDC_REV_ID_MASK GENMASK(31, 16) ++#define DBGMCU_IDC_REV_ID_SHIFT 16 ++ ++/* boot interface from Bootrom ++ * - boot instance = bit 31:16 ++ * - boot device = bit 15:0 ++ */ ++#define BOOTROM_PARAM_ADDR 0x2FFC0078 ++#define BOOTROM_MODE_MASK GENMASK(15, 0) ++#define BOOTROM_MODE_SHIFT 0 ++#define BOOTROM_INSTANCE_MASK GENMASK(31, 16) ++#define BOOTROM_INSTANCE_SHIFT 16 ++ ++/* Device Part Number (RPN) = OTP_DATA1 lower 8 bits */ ++#define RPN_SHIFT 0 ++#define RPN_MASK GENMASK(7, 0) ++ ++/* Package = bit 27:29 of OTP16 => STM32MP15_PKG defines ++ * - 100: LBGA448 (FFI) => AA = LFBGA 18x18mm 448 balls p. 0.8mm ++ * - 011: LBGA354 (LCI) => AB = LFBGA 16x16mm 359 balls p. 0.8mm ++ * - 010: TFBGA361 (FFC) => AC = TFBGA 12x12mm 361 balls p. 0.5mm ++ * - 001: TFBGA257 (LCC) => AD = TFBGA 10x10mm 257 balls p. 0.5mm ++ * - others: Reserved ++ */ ++#define PKG_SHIFT 27 ++#define PKG_MASK GENMASK(2, 0) ++ ++static void security_init(void) ++{ ++ /* Disable the backup domain write protection */ ++ /* the protection is enable at each reset by hardware */ ++ /* And must be disable by software */ ++ setbits_le32(PWR_CR1, PWR_CR1_DBP); ++ ++ while (!(readl(PWR_CR1) & PWR_CR1_DBP)) ++ ; ++ ++ /* If RTC clock isn't enable so this is a cold boot then we need ++ * to reset the backup domain ++ */ ++ if (!(readl(RCC_BDCR) & RCC_BDCR_RTCSRC)) { ++ setbits_le32(RCC_BDCR, RCC_BDCR_VSWRST); ++ while (!(readl(RCC_BDCR) & RCC_BDCR_VSWRST)) ++ ; ++ clrbits_le32(RCC_BDCR, RCC_BDCR_VSWRST); ++ } ++ ++ /* allow non secure access in Write/Read for all peripheral */ ++ writel(GENMASK(25, 0), ETZPC_DECPROT0); ++ ++ /* Open SYSRAM for no secure access */ ++ writel(0x0, ETZPC_TZMA1_SIZE); ++ ++ /* enable TZC1 TZC2 clock */ ++ writel(BIT(11) | BIT(12), RCC_MP_APB5ENSETR); ++ ++ /* Region 0 set to no access by default */ ++ /* bit 0 / 16 => nsaid0 read/write Enable ++ * bit 1 / 17 => nsaid1 read/write Enable ++ * ... ++ * bit 15 / 31 => nsaid15 read/write Enable ++ */ ++ writel(0xFFFFFFFF, TZC_REGION_ID_ACCESS0); ++ /* bit 30 / 31 => Secure Global Enable : write/read */ ++ /* bit 0 / 1 => Region Enable for filter 0/1 */ ++ writel(BIT(0) | BIT(1) | BIT(30) | BIT(31), TZC_REGION_ATTRIBUTE0); ++ ++ /* Enable Filter 0 and 1 */ ++ setbits_le32(TZC_GATE_KEEPER, BIT(0) | BIT(1)); ++ ++ /* RCC trust zone deactivated */ ++ writel(0x0, RCC_TZCR); ++ ++ /* TAMP: deactivate the internal tamper ++ * Bit 23 ITAMP8E: monotonic counter overflow ++ * Bit 20 ITAMP5E: RTC calendar overflow ++ * Bit 19 ITAMP4E: HSE monitoring ++ * Bit 18 ITAMP3E: LSE monitoring ++ * Bit 16 ITAMP1E: RTC power domain supply monitoring ++ */ ++ writel(0x0, TAMP_CR1); ++ ++ /* GPIOZ: deactivate the security */ ++ writel(BIT(0), RCC_MP_AHB5ENSETR); ++ writel(0x0, GPIOZ_SECCFGR); ++} ++ ++/* ++ * Debug init ++ */ ++void dbgmcu_init(void) ++{ ++ /* ++ * Freeze IWDG2 if Cortex-A7 is in debug mode ++ * done in TF-A for TRUSTED boot and ++ * DBGMCU access is controlled by BSEC_DENABLE.DBGSWENABLE ++ */ ++ if (bsec_dbgswenable()) { ++ setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN); ++ setbits_le32(DBGMCU_APB4FZ1, DBGMCU_APB4FZ1_IWDG2); ++ } ++} ++ ++void spl_board_init(void) ++{ ++ struct udevice *dev; ++ int ret; ++ ++ dbgmcu_init(); ++ ++ /* force probe of BSEC driver to shadow the upper OTP */ ++ ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(stm32mp_bsec), &dev); ++ if (ret) ++ log_warning("BSEC probe failed: %d\n", ret); ++} ++ ++/* get bootmode from ROM code boot context: saved in TAMP register */ ++static void update_bootmode(void) ++{ ++ u32 boot_mode; ++ u32 bootrom_itf = readl(BOOTROM_PARAM_ADDR); ++ u32 bootrom_device, bootrom_instance; ++ ++ /* enable TAMP clock = RTCAPBEN */ ++ writel(BIT(8), RCC_MP_APB5ENSETR); ++ ++ /* read bootrom context */ ++ bootrom_device = ++ (bootrom_itf & BOOTROM_MODE_MASK) >> BOOTROM_MODE_SHIFT; ++ bootrom_instance = ++ (bootrom_itf & BOOTROM_INSTANCE_MASK) >> BOOTROM_INSTANCE_SHIFT; ++ boot_mode = ++ ((bootrom_device << BOOT_TYPE_SHIFT) & BOOT_TYPE_MASK) | ++ ((bootrom_instance << BOOT_INSTANCE_SHIFT) & ++ BOOT_INSTANCE_MASK); ++ ++ /* save the boot mode in TAMP backup register */ ++ clrsetbits_le32(TAMP_BOOT_CONTEXT, ++ TAMP_BOOT_MODE_MASK, ++ boot_mode << TAMP_BOOT_MODE_SHIFT); ++} ++ ++/* weak function: STM32MP15x mach init for boot without TFA */ ++void stm32mp_cpu_init(void) ++{ ++ if (IS_ENABLED(CONFIG_SPL_BUILD)) { ++ security_init(); ++ update_bootmode(); ++ } ++ ++ /* reset copro state in SPL, when used, or in U-Boot */ ++ if (!IS_ENABLED(CONFIG_SPL) || IS_ENABLED(CONFIG_SPL_BUILD)) { ++ /* Reset Coprocessor state unless it wakes up from Standby power mode */ ++ if (!(readl(PWR_MCUCR) & PWR_MCUCR_SBF)) { ++ writel(TAMP_COPRO_STATE_OFF, TAMP_COPRO_STATE); ++ writel(0, TAMP_COPRO_RSC_TBL_ADDRESS); ++ } ++ } ++} ++ ++static u32 read_idc(void) ++{ ++ /* DBGMCU access is controlled by BSEC_DENABLE.DBGSWENABLE */ ++ if (bsec_dbgswenable()) { ++ setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN); ++ ++ return readl(DBGMCU_IDC); ++ } ++ ++ return CPU_DEV_STM32MP15; /* STM32MP15x and unknown revision */ ++} ++ ++u32 get_cpu_dev(void) ++{ ++ return (read_idc() & DBGMCU_IDC_DEV_ID_MASK) >> DBGMCU_IDC_DEV_ID_SHIFT; ++} ++ ++u32 get_cpu_rev(void) ++{ ++ return (read_idc() & DBGMCU_IDC_REV_ID_MASK) >> DBGMCU_IDC_REV_ID_SHIFT; ++} ++ ++int get_eth_nb(void) ++{ ++ return 1; ++} ++ ++/* Get Package options from OTP */ ++u32 get_cpu_package(void) ++{ ++ return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK); ++} ++ ++static const char * const soc_type[] = { ++ "????", ++ "151C", "151A", "151F", "151D", ++ "153C", "153A", "153F", "153D", ++ "157C", "157A", "157F", "157D" ++}; ++ ++static const char * const soc_pkg[] = { "??", "AD", "AC", "AB", "AA" }; ++static const char * const soc_rev[] = { "?", "A", "B", "Z" }; ++ ++static void get_cpu_string_offsets(unsigned int *type, unsigned int *pkg, ++ unsigned int *rev) ++{ ++ u32 cpu_type = get_cpu_type(); ++ u32 ct = cpu_type & ~(BIT(7) | BIT(0)); ++ u32 cm = ((cpu_type & BIT(7)) >> 6) | (cpu_type & BIT(0)); ++ ++ /* Bits 0 and 7 are the ACDF, 00:C 01:A 10:F 11:D */ ++ switch (ct) { ++ case CPU_STM32MP151Cxx: ++ *type = cm + 1; ++ break; ++ case CPU_STM32MP153Cxx: ++ *type = cm + 5; ++ break; ++ case CPU_STM32MP157Cxx: ++ *type = cm + 9; ++ break; ++ default: ++ *type = 0; ++ break; ++ } ++ ++ /* Package */ ++ *pkg = get_cpu_package(); ++ if (*pkg > STM32MP15_PKG_AA_LBGA448) ++ *pkg = STM32MP15_PKG_UNKNOWN; ++ ++ /* Revision */ ++ switch (get_cpu_rev()) { ++ case CPU_REV1: ++ *rev = 1; ++ break; ++ case CPU_REV2: ++ *rev = 2; ++ break; ++ case CPU_REV2_1: ++ *rev = 3; ++ break; ++ default: ++ *rev = 0; ++ break; ++ } ++} ++ ++void get_soc_name(char name[SOC_NAME_SIZE]) ++{ ++ unsigned int type, pkg, rev; ++ ++ get_cpu_string_offsets(&type, &pkg, &rev); ++ ++ snprintf(name, SOC_NAME_SIZE, "STM32MP%s%s Rev.%s", ++ soc_type[type], soc_pkg[pkg], soc_rev[rev]); ++} ++ ++static void setup_soc_type_pkg_rev(void) ++{ ++ unsigned int type, pkg, rev; ++ ++ get_cpu_string_offsets(&type, &pkg, &rev); ++ ++ env_set("soc_type", soc_type[type]); ++ env_set("soc_pkg", soc_pkg[pkg]); ++ env_set("soc_rev", soc_rev[rev]); ++} ++ ++/* weak function called in arch_misc_init */ ++void stm32mp_misc_init(void) ++{ ++ setup_soc_type_pkg_rev(); ++} +-- +2.25.1 + diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0002-ARM-v2020.10-stm32mp-r1-BOARD.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0002-ARM-v2020.10-stm32mp-r1-BOARD.patch deleted file mode 100644 index 596e94f..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0002-ARM-v2020.10-stm32mp-r1-BOARD.patch +++ /dev/null @@ -1,811 +0,0 @@ -From f792f9d20e0a99373263c540b271adc8143de743 Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Tue, 16 Mar 2021 08:16:11 +0100 -Subject: [PATCH 2/5] ARM v2020.10-stm32mp-r1 BOARD - -Signed-off-by: Romuald JEANNE ---- - board/st/common/Kconfig | 21 +++- - board/st/common/stm32mp_dfu.c | 9 +- - board/st/common/stm32mp_mtdparts.c | 47 +++++--- - board/st/stm32mp1/fit_copro_kernel_dtb.its | 18 ++- - board/st/stm32mp1/fit_kernel_dtb.its | 6 +- - board/st/stm32mp1/stm32mp1.c | 134 +++++++++++++-------- - doc/board/st/stm32mp1.rst | 124 +++++++++++-------- - 7 files changed, 227 insertions(+), 132 deletions(-) - -diff --git a/board/st/common/Kconfig b/board/st/common/Kconfig -index ddcf33a122..2f57118bb2 100644 ---- a/board/st/common/Kconfig -+++ b/board/st/common/Kconfig -@@ -8,18 +8,22 @@ config CMD_STBOARD - - config MTDPARTS_NAND0_BOOT - string "mtd boot partitions for nand0" -- default "2m(fsbl),2m(ssbl1),2m(ssbl2)" -+ default "2m(fsbl),2m(ssbl1),2m(ssbl2)" if STM32MP15x_STM32IMAGE || \ -+ !TFABOOT -+ default "2m(fsbl),4m(fip1),4m(fip2)" - depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP - help - This define the partitions of nand0 used to build mtparts dynamically - for boot from nand0. - Each partition need to be aligned with the device erase block size, - 512KB is the max size for the NAND supported by stm32mp1 platform. -+ The fsbl partition support multiple copy of the same binary, one by -+ erase block. - - config MTDPARTS_NAND0_TEE - string "mtd tee partitions for nand0" - default "512k(teeh),512k(teed),512k(teex)" -- depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP -+ depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP && STM32MP15x_STM32IMAGE - help - This define the tee partitions added in mtparts dynamically - when tee is supported with boot from nand0. -@@ -28,7 +32,9 @@ config MTDPARTS_NAND0_TEE - - config MTDPARTS_NOR0_BOOT - string "mtd boot partitions for nor0" -- default "256k(fsbl1),256k(fsbl2),2m(ssbl),512k(u-boot-env)" -+ default "256k(fsbl1),256k(fsbl2),2m(ssbl),512k(u-boot-env)" if STM32MP15x_STM32IMAGE || \ -+ !TFABOOT -+ default "256k(fsbl1),256k(fsbl2),4m(fip),512k(u-boot-env)" - depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP - help - This define the partitions of nand0 used to build mtparts dynamically -@@ -40,24 +46,27 @@ config MTDPARTS_NOR0_BOOT - config MTDPARTS_NOR0_TEE - string "mtd tee partitions for nor0" - default "256k(teeh),512k(teed),256k(teex)" -- depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP -+ depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP && STM32MP15x_STM32IMAGE - help - This define the tee partitions added in mtparts dynamically - when tee is supported with boot from nor0. - - config MTDPARTS_SPINAND0_BOOT - string "mtd boot partitions for spi-nand0" -- default "2m(fsbl),2m(ssbl1),2m(ssbl2)" -+ default "2m(fsbl),2m(ssbl1),2m(ssbl2)" if STM32MP15x_STM32IMAGE || !TFABOOT -+ default "2m(fsbl),4m(fip1),4m(fip2)" - depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP - help - This define the partitions of nand0 used to build mtparts dynamically - for boot from spi-nand0, - 512KB is the max size for the NAND supported by stm32mp1 platform. -+ The fsbl partition support multiple copy of the same binary, one by -+ erase block. - - config MTDPARTS_SPINAND0_TEE - string "mtd tee partitions for spi-nand0" - default "512k(teeh),512k(teed),512k(teex)" -- depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP -+ depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP && STM32MP15x_STM32IMAGE - help - This define the tee partitions added in mtparts dynamically - when tee is supported with boot from spi-nand0, -diff --git a/board/st/common/stm32mp_dfu.c b/board/st/common/stm32mp_dfu.c -index aab7d741ac..09913f6ec7 100644 ---- a/board/st/common/stm32mp_dfu.c -+++ b/board/st/common/stm32mp_dfu.c -@@ -142,7 +142,8 @@ void set_dfu_alt_info(char *interface, char *devstr) - board_get_alt_info_mtd(mtd, buf); - } - -- if (IS_ENABLED(CONFIG_DFU_VIRT)) { -+ if (IS_ENABLED(CONFIG_DFU_VIRT) && -+ IS_ENABLED(CMD_STM32PROG_USB)) { - strncat(buf, "&virt 0=OTP", DFU_ALT_BUF_LEN); - - if (IS_ENABLED(CONFIG_PMIC_STPMIC1)) -@@ -216,7 +217,7 @@ int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset, - return dfu_pmic_read(offset, buf, len); - } - -- if (CONFIG_IS_ENABLED(CMD_STM32PROG) && -+ if (IS_ENABLED(CONFIG_CMD_STM32PROG_USB) && - dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM) - return stm32prog_read_medium_virt(dfu, offset, buf, len); - -@@ -227,7 +228,7 @@ int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset, - int dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset, - void *buf, long *len) - { -- if (CONFIG_IS_ENABLED(CMD_STM32PROG) && -+ if (IS_ENABLED(CONFIG_CMD_STM32PROG_USB) && - dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM) - return stm32prog_write_medium_virt(dfu, offset, buf, len); - -@@ -236,7 +237,7 @@ int dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset, - - int __weak dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size) - { -- if (CONFIG_IS_ENABLED(CMD_STM32PROG) && -+ if (IS_ENABLED(CONFIG_CMD_STM32PROG_USB) && - dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM) - return stm32prog_get_medium_size_virt(dfu, size); - -diff --git a/board/st/common/stm32mp_mtdparts.c b/board/st/common/stm32mp_mtdparts.c -index 9f5897f8c8..baddadc3a5 100644 ---- a/board/st/common/stm32mp_mtdparts.c -+++ b/board/st/common/stm32mp_mtdparts.c -@@ -10,7 +10,9 @@ - #include - #include - #include -+#ifdef CONFIG_STM32MP15x_STM32IMAGE - #include -+#endif - #include - #include - -@@ -29,7 +31,9 @@ static void board_set_mtdparts(const char *dev, - char *mtdids, - char *mtdparts, - const char *boot, -+#ifdef CONFIG_STM32MP15x_STM32IMAGE - const char *tee, -+#endif - const char *user) - { - /* mtdids: "=, ...." */ -@@ -53,10 +57,12 @@ static void board_set_mtdparts(const char *dev, - strncat(mtdparts, ",", MTDPARTS_LEN); - } - -+#ifdef CONFIG_STM32MP15x_STM32IMAGE - if (tee) { - strncat(mtdparts, tee, MTDPARTS_LEN); - strncat(mtdparts, ",", MTDPARTS_LEN); - } -+#endif - - strncat(mtdparts, user, MTDPARTS_LEN); - } -@@ -68,7 +74,10 @@ void board_mtdparts_default(const char **mtdids, const char **mtdparts) - static char parts[3 * MTDPARTS_LEN + 1]; - static char ids[MTDIDS_LEN + 1]; - static bool mtd_initialized; -- bool tee, nor, nand, spinand, serial; -+ bool nor, nand, spinand, serial; -+#ifdef CONFIG_STM32MP15x_STM32IMAGE -+ bool tee = false; -+#endif - - if (mtd_initialized) { - *mtdids = ids; -@@ -76,7 +85,6 @@ void board_mtdparts_default(const char **mtdids, const char **mtdparts) - return; - } - -- tee = false; - nor = false; - nand = false; - spinand = false; -@@ -87,7 +95,9 @@ void board_mtdparts_default(const char **mtdids, const char **mtdparts) - case BOOT_SERIAL_USB: - serial = true; - if (CONFIG_IS_ENABLED(CMD_STM32PROG)) { -+#ifdef CONFIG_STM32MP15x_STM32IMAGE - tee = stm32prog_get_tee_partitions(); -+#endif - nor = stm32prog_get_fsbl_nor(); - } - nand = true; -@@ -106,9 +116,11 @@ void board_mtdparts_default(const char **mtdids, const char **mtdparts) - break; - } - -+#ifdef CONFIG_STM32MP15x_STM32IMAGE - if (!serial && CONFIG_IS_ENABLED(OPTEE) && - tee_find_device(NULL, NULL, NULL, NULL)) - tee = true; -+#endif - - memset(parts, 0, sizeof(parts)); - memset(ids, 0, sizeof(ids)); -@@ -120,29 +132,27 @@ void board_mtdparts_default(const char **mtdids, const char **mtdparts) - pr_debug("mtd device = %s\n", dev->name); - } - -- if (nor || nand) { -+ if (nand) { - mtd = get_mtd_device_nm("nand0"); - if (!IS_ERR_OR_NULL(mtd)) { -- const char *mtd_boot = CONFIG_MTDPARTS_NAND0_BOOT; -- const char *mtd_tee = CONFIG_MTDPARTS_NAND0_TEE; -- - board_set_mtdparts("nand0", ids, parts, -- !nor ? mtd_boot : NULL, -- !nor && tee ? mtd_tee : NULL, -+ CONFIG_MTDPARTS_NAND0_BOOT, -+#ifdef CONFIG_STM32MP15x_STM32IMAGE -+ !nor && tee ? CONFIG_MTDPARTS_NAND0_TEE : NULL, -+#endif - "-(UBI)"); - put_mtd_device(mtd); - } - } - -- if (nor || spinand) { -+ if (spinand) { - mtd = get_mtd_device_nm("spi-nand0"); - if (!IS_ERR_OR_NULL(mtd)) { -- const char *mtd_boot = CONFIG_MTDPARTS_SPINAND0_BOOT; -- const char *mtd_tee = CONFIG_MTDPARTS_SPINAND0_TEE; -- - board_set_mtdparts("spi-nand0", ids, parts, -- !nor ? mtd_boot : NULL, -- !nor && tee ? mtd_tee : NULL, -+ CONFIG_MTDPARTS_SPINAND0_BOOT, -+#ifdef CONFIG_STM32MP15x_STM32IMAGE -+ !nor && tee ? CONFIG_MTDPARTS_SPINAND0_TEE : NULL, -+#endif - "-(UBI)"); - put_mtd_device(mtd); - } -@@ -150,12 +160,11 @@ void board_mtdparts_default(const char **mtdids, const char **mtdparts) - - if (nor) { - if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) { -- const char *mtd_boot = CONFIG_MTDPARTS_NOR0_BOOT; -- const char *mtd_tee = CONFIG_MTDPARTS_NOR0_TEE; -- - board_set_mtdparts("nor0", ids, parts, -- mtd_boot, -- tee ? mtd_tee : NULL, -+ CONFIG_MTDPARTS_NOR0_BOOT, -+#ifdef CONFIG_STM32MP15x_STM32IMAGE -+ tee ? CONFIG_MTDPARTS_NOR0_TEE : NULL, -+#endif - "-(nor_user)"); - } - } -diff --git a/board/st/stm32mp1/fit_copro_kernel_dtb.its b/board/st/stm32mp1/fit_copro_kernel_dtb.its -index 3e08fd943e..dc43639af4 100644 ---- a/board/st/stm32mp1/fit_copro_kernel_dtb.its -+++ b/board/st/stm32mp1/fit_copro_kernel_dtb.its -@@ -1,6 +1,20 @@ - /* - * Compilation: - * mkimage -f fit_copro_kernel_dtb.its fit_copro_kernel_dtb.itb -+ * -+ * M4 firmware to load with remoteproc: rproc-m4-fw.elf -+ * -+ * Files in linux build dir: -+ * - arch/arm/boot/zImage -+ * - arch/arm/boot/dts/stm32mp157c-dk2.dtb -+ * - arch/arm/boot/dts/stm32mp157c-ev1.dtb -+ * -+ * load mmc 0:4 $kernel_addr_r fit_copro_kernel_dtb.itb -+ * bootm $kernel_addr_r -+ * bootm $kernel_addr_r#dk2 -+ * bootm $kernel_addr_r#ev1 -+ * bootm $kernel_addr_r#dk2-m4 -+ * bootm $kernel_addr_r#ev1-m4 - */ - - /dts-v1/; -@@ -29,8 +43,8 @@ - arch = "arm"; - os = "linux"; - compression = "none"; -- load = <0xC0008000>; -- entry = <0xC0008000>; -+ load = <0xC4000000>; -+ entry = <0xC4000000>; - hash-1 { - algo = "sha1"; - }; -diff --git a/board/st/stm32mp1/fit_kernel_dtb.its b/board/st/stm32mp1/fit_kernel_dtb.its -index 18d03ebf3c..8456a3c460 100644 ---- a/board/st/stm32mp1/fit_kernel_dtb.its -+++ b/board/st/stm32mp1/fit_kernel_dtb.its -@@ -3,7 +3,7 @@ - * mkimage -f fit_kernel_dtb.its fit_kernel_dtb.itb - * - * Files in linux build dir: -- * - arch/arm/boot/zImage -+ * - arch/arm/boot/Image (gzipped in Image.gz) - * - arch/arm/boot/dts/stm32mp157c-dk2.dtb - * - arch/arm/boot/dts/stm32mp157c-ev1.dtb - * -@@ -23,11 +23,11 @@ - images { - kernel { - description = "Linux kernel"; -- data = /incbin/("zImage"); -+ data = /incbin/("Image.gz"); - type = "kernel"; - arch = "arm"; - os = "linux"; -- compression = "none"; -+ compression = "gzip"; - load = <0xC0008000>; - entry = <0xC0008000>; - hash-1 { -diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c -index 3b677d339b..9a02e14ba5 100644 ---- a/board/st/stm32mp1/stm32mp1.c -+++ b/board/st/stm32mp1/stm32mp1.c -@@ -101,7 +101,9 @@ int checkboard(void) - const char *fdt_compat; - int fdt_compat_len; - -- if (IS_ENABLED(CONFIG_TFABOOT)) -+ if (IS_ENABLED(CONFIG_STM32MP15x_STM32IMAGE)) -+ mode = "trusted - stm32image"; -+ else if (IS_ENABLED(CONFIG_TFABOOT)) - mode = "trusted"; - else - mode = "basic"; -@@ -288,42 +290,13 @@ static void __maybe_unused led_error_blink(u32 nb_blink) - hang(); - } - --static int board_check_usb_power(void) -+static int adc_measurement(ofnode node, int adc_count, int *min_uV, int *max_uV) - { - struct ofnode_phandle_args adc_args; - struct udevice *adc; -- ofnode node; - unsigned int raw; -- int max_uV = 0; -- int min_uV = USB_START_HIGH_THRESHOLD_UV; -- int ret, uV, adc_count; -- u32 nb_blink; -- u8 i; -- -- if (!IS_ENABLED(CONFIG_ADC)) -- return -ENODEV; -- -- node = ofnode_path("/config"); -- if (!ofnode_valid(node)) { -- debug("%s: no /config node?\n", __func__); -- return -ENOENT; -- } -- -- /* -- * Retrieve the ADC channels devices and get measurement -- * for each of them -- */ -- adc_count = ofnode_count_phandle_with_args(node, "st,adc_usb_pd", -- "#io-channel-cells"); -- if (adc_count < 0) { -- if (adc_count == -ENOENT) -- return 0; -- -- pr_err("%s: can't find adc channel (%d)\n", __func__, -- adc_count); -- -- return adc_count; -- } -+ int ret, uV; -+ int i; - - for (i = 0; i < adc_count; i++) { - if (ofnode_parse_phandle_with_args(node, "st,adc_usb_pd", -@@ -352,10 +325,10 @@ static int board_check_usb_power(void) - } - /* Convert to uV */ - if (!adc_raw_to_uV(adc, raw, &uV)) { -- if (uV > max_uV) -- max_uV = uV; -- if (uV < min_uV) -- min_uV = uV; -+ if (uV > *max_uV) -+ *max_uV = uV; -+ if (uV < *min_uV) -+ *min_uV = uV; - pr_debug("%s: %s[%02d] = %u, %d uV\n", __func__, - adc->name, adc_args.args[0], raw, uV); - } else { -@@ -364,18 +337,66 @@ static int board_check_usb_power(void) - } - } - -+ return 0; -+} -+ -+static int board_check_usb_power(void) -+{ -+ ofnode node; -+ int max_uV = 0; -+ int min_uV = USB_START_HIGH_THRESHOLD_UV; -+ int adc_count, ret; -+ u32 nb_blink; -+ u8 i; -+ -+ if (!IS_ENABLED(CONFIG_ADC)) -+ return -ENODEV; -+ -+ node = ofnode_path("/config"); -+ if (!ofnode_valid(node)) { -+ debug("%s: no /config node?\n", __func__); -+ return -ENOENT; -+ } -+ - /* -- * If highest value is inside 1.23 Volts and 2.10 Volts, that means -- * board is plugged on an USB-C 3A power supply and boot process can -- * continue. -+ * Retrieve the ADC channels devices and get measurement -+ * for each of them - */ -- if (max_uV > USB_START_LOW_THRESHOLD_UV && -- max_uV <= USB_START_HIGH_THRESHOLD_UV && -- min_uV <= USB_LOW_THRESHOLD_UV) -- return 0; -+ adc_count = ofnode_count_phandle_with_args(node, "st,adc_usb_pd", -+ "#io-channel-cells"); -+ if (adc_count < 0) { -+ if (adc_count == -ENOENT) -+ return 0; - -- pr_err("****************************************************\n"); -+ pr_err("%s: can't find adc channel (%d)\n", __func__, -+ adc_count); -+ -+ return adc_count; -+ } -+ -+ /* perform maximum of 2 ADC measurement to detect power supply current */ -+ for (i = 0; i < 2; i++) { -+ ret = adc_measurement(node, adc_count, &min_uV, &max_uV); -+ if (ret) -+ return ret; -+ -+ /* -+ * If highest value is inside 1.23 Volts and 2.10 Volts, that means -+ * board is plugged on an USB-C 3A power supply and boot process can -+ * continue. -+ */ -+ if (max_uV > USB_START_LOW_THRESHOLD_UV && -+ max_uV <= USB_START_HIGH_THRESHOLD_UV && -+ min_uV <= USB_LOW_THRESHOLD_UV) -+ return 0; - -+ if (i == 0) { -+ pr_debug("Previous ADC measurements was not the one expected, retry in 20ms\n"); -+ mdelay(20); /* equal to max tPDDebounce duration (min 10ms - max 20ms) */ -+ } -+ } -+ -+ pr_err("****************************************************\n"); - /* - * If highest and lowest value are either both below - * USB_LOW_THRESHOLD_UV or both above USB_LOW_THRESHOLD_UV, that -@@ -583,7 +604,8 @@ error: - static bool board_is_dk2(void) - { - if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) && -- of_machine_is_compatible("st,stm32mp157c-dk2")) -+ (of_machine_is_compatible("st,stm32mp157c-dk2") || -+ of_machine_is_compatible("st,stm32mp157f-dk2"))) - return true; - - return false; -@@ -832,10 +854,17 @@ const char *env_ext4_get_dev_part(void) - - return dev_part[(bootmode & TAMP_BOOT_INSTANCE_MASK) - 1]; - } -+ - int mmc_get_env_dev(void) - { -- u32 bootmode = get_bootmode(); -+ u32 bootmode; -+ -+ if (CONFIG_SYS_MMC_ENV_DEV >= 0) -+ return CONFIG_SYS_MMC_ENV_DEV; - -+ bootmode = get_bootmode(); -+ -+ /* use boot instance to select the correct mmc device identifier */ - return (bootmode & TAMP_BOOT_INSTANCE_MASK) - 1; - } - -@@ -848,9 +877,14 @@ int ft_board_setup(void *blob, struct bd_info *bd) - { "st,stm32mp15-fmc2", MTD_DEV_TYPE_NAND, }, - { "st,stm32mp1-fmc2-nfc", MTD_DEV_TYPE_NAND, }, - }; -- -- if (IS_ENABLED(CONFIG_FDT_FIXUP_PARTITIONS)) -- fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); -+ char *boot_device; -+ -+ /* Check the boot-source and don't update MTD for serial or usb boot */ -+ boot_device = env_get("boot_device"); -+ if (!boot_device || -+ (strcmp(boot_device, "serial") && strcmp(boot_device, "usb"))) -+ if (IS_ENABLED(CONFIG_FDT_FIXUP_PARTITIONS)) -+ fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); - - return 0; - } -diff --git a/doc/board/st/stm32mp1.rst b/doc/board/st/stm32mp1.rst -index e74f7afdae..ad95e12068 100644 ---- a/doc/board/st/stm32mp1.rst -+++ b/doc/board/st/stm32mp1.rst -@@ -52,15 +52,23 @@ And the necessary drivers - Currently the following boards are supported: - - + stm32mp157a-dk1.dts -+ + stm32mp157a-ed1.dts -+ + stm32mp157a-ev1.dts - + stm32mp157c-dk2.dts - + stm32mp157c-ed1.dts - + stm32mp157c-ev1.dts -+ + stm32mp157d-dk1.dts -+ + stm32mp157d-ed1.dts -+ + stm32mp157d-ev1.dts -+ + stm32mp157f-dk2.dts -+ + stm32mp157f-ed1.dts -+ + stm32mp157f-ev1.dts - + stm32mp15xx-dhcor-avenger96.dts - - Boot Sequences - -------------- - --3 boot configurations are supported with: -+2 boot configurations are supported with: - - +----------+------------------------+-------------------------+--------------+ - | **ROM** | **FSBL** | **SSBL** | **OS** | -@@ -83,14 +91,10 @@ defconfig_file : stm32mp15_trusted_defconfig - | TrustZone |secure monitor | - +-------------+-------------------------+------------+-------+ - --TF-A performs a full initialization of Secure peripherals and installs a --secure monitor, BL32: -- -- * SPMin provided by TF-A or -- * OP-TEE from specific partitions (teeh, teed, teex). -- --U-Boot is running in normal world and uses the secure monitor to access --to secure resources. -+TF-A (BL2) initialize the DDR and loads the next stage binaries from a FIP file: -+ + BL32: a secure monitor BL32 = SPMin provided by TF-A or OP-TEE : performs a full initialization of Secure peripherals and provides service to normal world -+ + BL33: a non-trusted firmware = U-Boot, running in normal world and uses the secure monitor to access to secure resources. -+ + HW_CONFIG: The hardware configuration file = the U-Boot device tree - - The **Basic** boot chain - ```````````````````````` -@@ -123,19 +127,27 @@ the supported device trees for STM32MP15x are: - - + ev1: eval board with pmic stpmic1 (ev1 = mother board + daughter ed1) - -+ + stm32mp157a-ev1 - + stm32mp157c-ev1 -+ + stm32mp157d-ev1 -+ + stm32mp157f-ev1 - - + ed1: daughter board with pmic stpmic1 - -+ + stm32mp157a-ed1 - + stm32mp157c-ed1 -+ + stm32mp157d-ed1 -+ + stm32mp157f-ed1 - - + dk1: Discovery board - - + stm32mp157a-dk1 -+ + stm32mp157d-dk1 - - + dk2: Discovery board = dk1 with a BT/WiFI combo and a DSI panel - - + stm32mp157c-dk2 -+ + stm32mp157f-dk2 - - + avenger96: Avenger96 board from Arrow Electronics based on DH Elec. DHCOR SoM - -@@ -223,16 +235,24 @@ Build Procedure - - 6. Output files - -- BootRom and TF-A expect binaries with STM32 image header -- SPL expects file with U-Boot uImage header -+ The ROM code expects FSBL binaries with STM32 image header. -+ TF-A expect a FIP binary, with OS monitor (SPmin or OP-TEE) and with U-Boot binary + device tree. -+ SPL expects file with U-Boot uImage header. - - So in the output directory (selected by KBUILD_OUTPUT), - you can found the needed files: - - - For **Trusted** boot (with or without OP-TEE) - -- - FSBL = **tf-a.stm32** (provided by TF-A compilation) -- - SSBL = **u-boot.stm32** -+ - FSBL = **tf-a.stm32** and **tf-a-fip.bin** (provided by TF-A compilation) -+ - SSBL = **u-boot-nodtb.bin** and **u-boot.dtb** -+ -+ The file tf-a-fip.bin includes the 2 U-Boot files, u-boot-nodtb.bin and u-boot.dtb; -+ they are needed during the TF-A compilation(BL33=u-boot-nodtb.bin BL33_CFG=u-boot.dtb). -+ -+ You can also update a existing it with the tools provided by TF-A: -+ -+ # fiptool update --nt-fw u-boot-nodtb.bin --hw-config u-boot.dtb tf-a-fip-stm32mp157c-ev1.bin - - - For Basic boot - -@@ -298,22 +318,24 @@ Prepare an SD card - The minimal requirements for STMP32MP15x boot up to U-Boot are: - - - GPT partitioning (with gdisk or with sgdisk) --- 2 fsbl partitions, named fsbl1 and fsbl2, size at least 256KiB --- one ssbl partition for U-Boot -+- 2 fsbl partitions, named "fsbl1" and "fsbl2", size at least 256KiB -+- one partition named "fip" for FIP or U-Boot (TF-A search the "fip" -+ partition and SPL search the 3th partition, because -+ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=3) - - Then the minimal GPT partition is: - -- +-------+--------+---------+-------------+ -- | *Num* | *Name* | *Size* | *Content* | -- +=======+========+=========+=============+ -- | 1 | fsbl1 | 256 KiB | TF-A or SPL | -- +-------+--------+---------+-------------+ -- | 2 | fsbl2 | 256 KiB | TF-A or SPL | -- +-------+--------+---------+-------------+ -- | 3 | ssbl | enought | U-Boot | -- +-------+--------+---------+-------------+ -- | 4 | | | Rootfs | -- +-------+--------+---------+-------------+ -+ +-------+--------+---------+------------------------------+ -+ | *Num* | *Name* | *Size* | *Content* | -+ +=======+========+=========+==============================+ -+ | 1 | fsbl1 | 256 KiB | TF-A BL2 (tf-a.stm32) or SPL | -+ +-------+--------+---------+------------------------------+ -+ | 2 | fsbl2 | 256 KiB | TF-A BL2 (tf-a.stm32) or SPL | -+ +-------+--------+---------+------------------------------+ -+ | 3 | fip | enought | tf-a-fip.bin or u-boot.img | -+ +-------+--------+---------+------------------------------+ -+ | 4 | | | Rootfs | -+ +-------+--------+---------+------------------------------+ - - Add a 4th partition (Rootfs) marked bootable with a file extlinux.conf - following the Generic Distribution feature (doc/README.distro for use). -@@ -334,7 +356,7 @@ b) create minimal image:: - # sgdisk --resize-table=128 -a 1 \ - -n 1:34:545 -c 1:fsbl1 \ - -n 2:546:1057 -c 2:fsbl2 \ -- -n 3:1058:5153 -c 3:ssbl \ -+ -n 3:1058:5153 -c 3:fip \ - -n 4:5154: -c 4:rootfs \ - -p /dev/ - -@@ -353,7 +375,7 @@ c) copy the FSBL (2 times) and SSBL file on the correct partition. - - # dd if=tf-a.stm32 of=/dev/mmcblk0p1 - # dd if=tf-a.stm32 of=/dev/mmcblk0p2 -- # dd if=u-boot.stm32 of=/dev/mmcblk0p3 -+ # dd if=tf-a-fip.bin of=/dev/mmcblk0p3 - - To boot from SD card, select BootPinMode = 1 0 1 and reset. - -@@ -363,8 +385,8 @@ Prepare eMMC - You can use U-Boot to copy binary in eMMC. - - In the next example, you need to boot from SD card and the images --(u-boot-spl.stm32, u-boot.img) are presents on SD card (mmc 0) --in ext4 partition 4 (bootfs). -+(tf-a.stm32, tf-a-fip.bin / u-boot-spl.stm32, u-boot.img) are presents -+on SD card (mmc 0) in ext4 partition 4 (bootfs). - - To boot from SD card, select BootPinMode = 1 0 1 and reset. - -@@ -373,13 +395,16 @@ Then you update the eMMC with the next U-Boot command : - a) prepare GPT on eMMC, - example with 2 partitions, bootfs and roots:: - -- # setenv emmc_part "name=ssbl,size=2MiB;name=bootfs,type=linux,bootable,size=64MiB;name=rootfs,type=linux,size=512" -+ # setenv emmc_part "name=fip,size=2MiB;name=bootfs,type=linux,bootable,size=64MiB;name=rootfs,type=linux,size=512" - # gpt write mmc 1 ${emmc_part} - - b) copy SPL on eMMC on firts boot partition - (SPL max size is 256kB, with LBA 512, 0x200):: - -+ # ext4load mmc 0:4 0xC0000000 tf-a.stm32 -+ or - # ext4load mmc 0:4 0xC0000000 u-boot-spl.stm32 -+ - # mmc dev 1 - # mmc partconf 1 1 1 1 - # mmc write ${fileaddr} 0 200 -@@ -387,7 +412,10 @@ b) copy SPL on eMMC on firts boot partition - - c) copy U-Boot in first GPT partition of eMMC:: - -- # ext4load mmc 0:4 0xC0000000 u-boo t.img -+ # ext4load mmc 0:4 0xC0000000 tf-a-fip.bin -+ or -+ # ext4load mmc 0:4 0xC0000000 u-boot.img -+ - # mmc dev 1 - # part start mmc 1 1 partstart - # mmc write ${fileaddr} ${partstart} ${filesize} -@@ -520,14 +548,14 @@ On EV1 board, booting from SD card, without OP-TEE:: - dev: RAM alt: 2 name: uramdisk.image.gz layout: RAM_ADDR - dev: eMMC alt: 3 name: mmc0_fsbl1 layout: RAW_ADDR - dev: eMMC alt: 4 name: mmc0_fsbl2 layout: RAW_ADDR -- dev: eMMC alt: 5 name: mmc0_ssbl layout: RAW_ADDR -+ dev: eMMC alt: 5 name: mmc0_fip layout: RAW_ADDR - dev: eMMC alt: 6 name: mmc0_bootfs layout: RAW_ADDR - dev: eMMC alt: 7 name: mmc0_vendorfs layout: RAW_ADDR - dev: eMMC alt: 8 name: mmc0_rootfs layout: RAW_ADDR - dev: eMMC alt: 9 name: mmc0_userfs layout: RAW_ADDR - dev: eMMC alt: 10 name: mmc1_boot1 layout: RAW_ADDR - dev: eMMC alt: 11 name: mmc1_boot2 layout: RAW_ADDR -- dev: eMMC alt: 12 name: mmc1_ssbl layout: RAW_ADDR -+ dev: eMMC alt: 12 name: mmc1_fip layout: RAW_ADDR - dev: eMMC alt: 13 name: mmc1_bootfs layout: RAW_ADDR - dev: eMMC alt: 14 name: mmc1_vendorfs layout: RAW_ADDR - dev: eMMC alt: 15 name: mmc1_rootfs layout: RAW_ADDR -@@ -548,14 +576,14 @@ All the supported device are exported for dfu-util tool:: - Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=15, name="mmc1_rootfs", serial="002700333338511934383330" - Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=14, name="mmc1_vendorfs", serial="002700333338511934383330" - Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=13, name="mmc1_bootfs", serial="002700333338511934383330" -- Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=12, name="mmc1_ssbl", serial="002700333338511934383330" -+ Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=12, name="mmc1_fip", serial="002700333338511934383330" - Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=11, name="mmc1_boot2", serial="002700333338511934383330" - Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=10, name="mmc1_boot1", serial="002700333338511934383330" - Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=9, name="mmc0_userfs", serial="002700333338511934383330" - Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=8, name="mmc0_rootfs", serial="002700333338511934383330" - Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=7, name="mmc0_vendorfs", serial="002700333338511934383330" - Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=6, name="mmc0_bootfs", serial="002700333338511934383330" -- Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=5, name="mmc0_ssbl", serial="002700333338511934383330" -+ Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=5, name="mmc0_fip", serial="002700333338511934383330" - Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=4, name="mmc0_fsbl2", serial="002700333338511934383330" - Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=3, name="mmc0_fsbl1", serial="002700333338511934383330" - Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=2, name="uramdisk.image.gz", serial="002700333338511934383330" -@@ -566,9 +594,9 @@ You can update the boot device: - - - SD card (mmc0) :: - -- $> dfu-util -d 0483:5720 -a 3 -D tf-a-stm32mp157c-ev1-trusted.stm32 -- $> dfu-util -d 0483:5720 -a 4 -D tf-a-stm32mp157c-ev1-trusted.stm32 -- $> dfu-util -d 0483:5720 -a 5 -D u-boot-stm32mp157c-ev1-trusted.img -+ $> dfu-util -d 0483:5720 -a 3 -D tf-a-stm32mp157c-ev1.stm32 -+ $> dfu-util -d 0483:5720 -a 4 -D tf-a-stm32mp157c-ev1.stm32 -+ $> dfu-util -d 0483:5720 -a 5 -D tf-a-fip-stm32mp157c-ev1.bin - $> dfu-util -d 0483:5720 -a 6 -D st-image-bootfs-openstlinux-weston-stm32mp1.ext4 - $> dfu-util -d 0483:5720 -a 7 -D st-image-vendorfs-openstlinux-weston-stm32mp1.ext4 - $> dfu-util -d 0483:5720 -a 8 -D st-image-weston-openstlinux-weston-stm32mp1.ext4 -@@ -576,9 +604,9 @@ You can update the boot device: - - - EMMC (mmc1):: - -- $> dfu-util -d 0483:5720 -a 10 -D tf-a-stm32mp157c-ev1-trusted.stm32 -- $> dfu-util -d 0483:5720 -a 11 -D tf-a-stm32mp157c-ev1-trusted.stm32 -- $> dfu-util -d 0483:5720 -a 12 -D u-boot-stm32mp157c-ev1-trusted.img -+ $> dfu-util -d 0483:5720 -a 10 -D tf-a-stm32mp157c-ev1.stm32 -+ $> dfu-util -d 0483:5720 -a 11 -D tf-a-stm32mp157c-ev1.stm32 -+ $> dfu-util -d 0483:5720 -a 12 -D tf-a-fip-stm32mp157c-ev1.bin - $> dfu-util -d 0483:5720 -a 13 -D st-image-bootfs-openstlinux-weston-stm32mp1.ext4 - $> dfu-util -d 0483:5720 -a 14 -D st-image-vendorfs-openstlinux-weston-stm32mp1.ext4 - $> dfu-util -d 0483:5720 -a 15 -D st-image-weston-openstlinux-weston-stm32mp1.ext4 -@@ -595,14 +623,14 @@ only the MTD partition on the boot devices are available, for example: - - - NOR (nor0 = alt 20) & NAND (nand0 = alt 26) :: - -- $> dfu-util -d 0483:5720 -a 21 -D tf-a-stm32mp157c-ev1-trusted.stm32 -- $> dfu-util -d 0483:5720 -a 22 -D tf-a-stm32mp157c-ev1-trusted.stm32 -- $> dfu-util -d 0483:5720 -a 23 -D u-boot-stm32mp157c-ev1-trusted.img -+ $> dfu-util -d 0483:5720 -a 21 -D tf-a-stm32mp157c-ev1.stm32 -+ $> dfu-util -d 0483:5720 -a 22 -D tf-a-stm32mp157c-ev1.stm32 -+ $> dfu-util -d 0483:5720 -a 23 -D tf-a-fip-stm32mp157c-ev1.bin - $> dfu-util -d 0483:5720 -a 27 -D st-image-weston-openstlinux-weston-stm32mp1_nand_4_256_multivolume.ubi - - - NAND (nand0 = alt 21):: - -- $> dfu-util -d 0483:5720 -a 22 -D tf-a-stm32mp157c-ev1-trusted.stm32 -- $> dfu-util -d 0483:5720 -a 23 -D u-boot-stm32mp157c-ev1-trusted.img -- $> dfu-util -d 0483:5720 -a 24 -D u-boot-stm32mp157c-ev1-trusted.img -+ $> dfu-util -d 0483:5720 -a 22 -D tf-a-stm32mp157c-ev1.stm32 -+ $> dfu-util -d 0483:5720 -a 23 -D tf-a-fip-stm32mp157c-ev1.bin -+ $> dfu-util -d 0483:5720 -a 24 -D tf-a-fip-stm32mp157c-ev1.bin - $> dfu-util -d 0483:5720 -a 25 -D st-image-weston-openstlinux-weston-stm32mp1_nand_4_256_multivolume.ubi --- -2.17.1 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0002-ARM-v2021.10-stm32mp-r1-BOARD.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0002-ARM-v2021.10-stm32mp-r1-BOARD.patch new file mode 100644 index 0000000..fe34587 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0002-ARM-v2021.10-stm32mp-r1-BOARD.patch @@ -0,0 +1,1311 @@ +From 8d630ba5a94953808ee9c15241298f080f24f286 Mon Sep 17 00:00:00 2001 +From: Christophe Priouzeau +Date: Mon, 30 May 2022 09:44:55 +0200 +Subject: [PATCH 2/5] ARM-v2021.10-stm32mp-r1-BOARD + +--- + board/st/common/Kconfig | 14 +- + board/st/common/Makefile | 1 - + board/st/common/cmd_stboard.c | 22 +- + board/st/common/stm32mp_dfu.c | 6 +- + board/st/common/stusb160x.c | 48 -- + board/st/common/stusb160x.h | 10 - + .../stm32f429-discovery/stm32f429-discovery.c | 2 - + .../stm32f429-evaluation.c | 2 - + .../stm32f469-discovery/stm32f469-discovery.c | 2 - + board/st/stm32f746-disco/stm32f746-disco.c | 3 - + board/st/stm32h743-disco/stm32h743-disco.c | 1 - + board/st/stm32h743-eval/stm32h743-eval.c | 1 - + board/st/stm32h750-art-pi/stm32h750-art-pi.c | 1 - + board/st/stm32mp1/Kconfig | 15 + + board/st/stm32mp1/MAINTAINERS | 5 +- + board/st/stm32mp1/stm32mp1.c | 692 ++++++++++++++++-- + 16 files changed, 662 insertions(+), 163 deletions(-) + delete mode 100644 board/st/common/stusb160x.c + delete mode 100644 board/st/common/stusb160x.h + +diff --git a/board/st/common/Kconfig b/board/st/common/Kconfig +index 2f57118bb2..12abace091 100644 +--- a/board/st/common/Kconfig ++++ b/board/st/common/Kconfig +@@ -1,7 +1,7 @@ + config CMD_STBOARD + bool "stboard - command for OTP board information" + depends on ARCH_STM32MP +- default y if TARGET_ST_STM32MP15x ++ default y if TARGET_ST_STM32MP15x || TARGET_ST_STM32MP13x + help + This compile the stboard command to + read and write the board in the OTP. +@@ -10,7 +10,7 @@ config MTDPARTS_NAND0_BOOT + string "mtd boot partitions for nand0" + default "2m(fsbl),2m(ssbl1),2m(ssbl2)" if STM32MP15x_STM32IMAGE || \ + !TFABOOT +- default "2m(fsbl),4m(fip1),4m(fip2)" ++ default "512k(fsbl1),512k(fsbl2),512k(metadata1),512k(metadata2),4m(fip-a1),4m(fip-a2),4m(fip-b1),4m(fip-b2)" + depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP + help + This define the partitions of nand0 used to build mtparts dynamically +@@ -34,7 +34,7 @@ config MTDPARTS_NOR0_BOOT + string "mtd boot partitions for nor0" + default "256k(fsbl1),256k(fsbl2),2m(ssbl),512k(u-boot-env)" if STM32MP15x_STM32IMAGE || \ + !TFABOOT +- default "256k(fsbl1),256k(fsbl2),4m(fip),512k(u-boot-env)" ++ default "256k(fsbl1),256k(fsbl2),256k(metadata1),256k(metadata2),4m(fip-a),4m(fip-b),512k(u-boot-env)" + depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP + help + This define the partitions of nand0 used to build mtparts dynamically +@@ -54,7 +54,7 @@ config MTDPARTS_NOR0_TEE + config MTDPARTS_SPINAND0_BOOT + string "mtd boot partitions for spi-nand0" + default "2m(fsbl),2m(ssbl1),2m(ssbl2)" if STM32MP15x_STM32IMAGE || !TFABOOT +- default "2m(fsbl),4m(fip1),4m(fip2)" ++ default "512k(fsbl1),512k(fsbl2),512k(metadata1),512k(metadata2),4m(fip-a1),4m(fip-a2),4m(fip-b1),4m(fip-b2)" + depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP + help + This define the partitions of nand0 used to build mtparts dynamically +@@ -79,9 +79,3 @@ config DFU_ALT_RAM0 + help + This defines the partitions of ram used to build dfu dynamically. + +-config TYPEC_STUSB160X +- tristate "STMicroelectronics STUSB160X Type-C controller driver" +- depends on DM_I2C +- help +- Say Y if your system has STMicroelectronics STUSB160X Type-C port +- controller. +diff --git a/board/st/common/Makefile b/board/st/common/Makefile +index 65bbebd6ab..15a9a3550a 100644 +--- a/board/st/common/Makefile ++++ b/board/st/common/Makefile +@@ -11,4 +11,3 @@ obj-$(CONFIG_SYS_MTDPARTS_RUNTIME) += stm32mp_mtdparts.o + obj-$(CONFIG_SET_DFU_ALT_INFO) += stm32mp_dfu.o + endif + +-obj-$(CONFIG_TYPEC_STUSB160X) += stusb160x.o +diff --git a/board/st/common/cmd_stboard.c b/board/st/common/cmd_stboard.c +index 2fba383168..06280117a8 100644 +--- a/board/st/common/cmd_stboard.c ++++ b/board/st/common/cmd_stboard.c +@@ -3,7 +3,7 @@ + * Copyright (C) 2019, STMicroelectronics - All Rights Reserved + * + * the st command stboard supports the STMicroelectronics board identification +- * saved in OTP 59. ++ * saved in OTP_BOARD (59 on STM32MP15x). + * + * The ST product codification have several element + * - "Commercial Product Name" (CPN): type of product board (DKX, EVX) +@@ -18,7 +18,7 @@ + * - Finished Good = EVA32MP157A1$AU1 + * + * Both information are written on board and these information are also saved +- * in OTP59, with: ++ * in OTP_BOARD (59 for STM32MP15x), with: + * bit [31:16] (hex) => Board id, MBxxxx + * bit [15:12] (dec) => Variant CPN (1....15) + * bit [11:8] (dec) => Revision board (index with A = 1, Z = 26) +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -48,6 +49,7 @@ static bool check_stboard(u16 board) + 0x1298, + 0x1341, + 0x1497, ++ 0x1635, + }; + + for (i = 0; i < ARRAY_SIZE(st_board_id); i++) +@@ -91,15 +93,15 @@ static int do_stboard(struct cmd_tbl *cmdtp, int flag, int argc, + ret = misc_read(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD), + &otp, sizeof(otp)); + +- if (ret < 0) { +- puts("OTP read error"); ++ if (ret != sizeof(otp)) { ++ puts("OTP read error\n"); + return CMD_RET_FAILURE; + } + + ret = misc_read(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD), + &lock, sizeof(lock)); +- if (ret < 0) { +- puts("LOCK read error"); ++ if (ret != sizeof(lock)) { ++ puts("LOCK read error\n"); + return CMD_RET_FAILURE; + } + +@@ -109,7 +111,7 @@ static int do_stboard(struct cmd_tbl *cmdtp, int flag, int argc, + else + display_stboard(otp); + printf(" OTP %d %s locked !\n", BSEC_OTP_BOARD, +- lock == 1 ? "" : "NOT"); ++ lock & BSEC_LOCK_PERM ? "" : "NOT"); + return CMD_RET_SUCCESS; + } + +@@ -172,16 +174,16 @@ static int do_stboard(struct cmd_tbl *cmdtp, int flag, int argc, + ret = misc_write(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD), + &otp, sizeof(otp)); + +- if (ret < 0) { ++ if (ret != sizeof(otp)) { + puts("BOARD programming error\n"); + return CMD_RET_FAILURE; + } + + /* write persistent lock */ +- otp = 1; ++ otp = BSEC_LOCK_PERM; + ret = misc_write(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD), + &otp, sizeof(otp)); +- if (ret < 0) { ++ if (ret != sizeof(otp)) { + puts("BOARD lock error\n"); + return CMD_RET_FAILURE; + } +diff --git a/board/st/common/stm32mp_dfu.c b/board/st/common/stm32mp_dfu.c +index 00d1fb8f59..fa48b2a35e 100644 +--- a/board/st/common/stm32mp_dfu.c ++++ b/board/st/common/stm32mp_dfu.c +@@ -57,7 +57,7 @@ static void board_get_alt_info_mmc(struct udevice *dev, char *buf) + first = false; + } + +- for (p = 1; p < MAX_SEARCH_PARTITIONS; p++) { ++ for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { + if (part_get_info(desc, p, &info)) + continue; + if (!first) +@@ -132,6 +132,10 @@ void set_dfu_alt_info(char *interface, char *devstr) + mtd = get_mtd_device_nm("nor0"); + if (!IS_ERR_OR_NULL(mtd)) + board_get_alt_info_mtd(mtd, buf); ++ ++ mtd = get_mtd_device_nm("nor1"); ++ if (!IS_ERR_OR_NULL(mtd)) ++ board_get_alt_info_mtd(mtd, buf); + } + + mtd = get_mtd_device_nm("nand0"); +diff --git a/board/st/common/stusb160x.c b/board/st/common/stusb160x.c +deleted file mode 100644 +index f0385e5e38..0000000000 +--- a/board/st/common/stusb160x.c ++++ /dev/null +@@ -1,48 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +-/* +- * STMicroelectronics STUSB Type-C controller driver +- * based on Linux drivers/usb/typec/stusb160x.c +- * +- * Copyright (C) 2020, STMicroelectronics - All Rights Reserved +- */ +- +-#define LOG_CATEGORY UCLASS_I2C_GENERIC +- +-#include +-#include +-#include +- +-/* REGISTER */ +-#define STUSB160X_CC_CONNECTION_STATUS 0x0E +- +-/* STUSB160X_CC_CONNECTION_STATUS bitfields */ +-#define STUSB160X_CC_ATTACH BIT(0) +- +-int stusb160x_cable_connected(void) +-{ +- struct udevice *dev; +- int ret; +- +- ret = uclass_get_device_by_driver(UCLASS_I2C_GENERIC, +- DM_DRIVER_GET(stusb160x), +- &dev); +- if (ret < 0) +- return ret; +- +- ret = dm_i2c_reg_read(dev, STUSB160X_CC_CONNECTION_STATUS); +- if (ret < 0) +- return 0; +- +- return ret & STUSB160X_CC_ATTACH; +-} +- +-static const struct udevice_id stusb160x_ids[] = { +- { .compatible = "st,stusb1600" }, +- {} +-}; +- +-U_BOOT_DRIVER(stusb160x) = { +- .name = "stusb160x", +- .id = UCLASS_I2C_GENERIC, +- .of_match = stusb160x_ids, +-}; +diff --git a/board/st/common/stusb160x.h b/board/st/common/stusb160x.h +deleted file mode 100644 +index fe39840b41..0000000000 +--- a/board/st/common/stusb160x.h ++++ /dev/null +@@ -1,10 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * Copyright (C) 2020, STMicroelectronics +- */ +- +-#ifdef CONFIG_TYPEC_STUSB160X +-int stusb160x_cable_connected(void); +-#else +-int stusb160x_cable_connected(void) { return -ENODEV; } +-#endif +diff --git a/board/st/stm32f429-discovery/stm32f429-discovery.c b/board/st/stm32f429-discovery/stm32f429-discovery.c +index 46fcf907fc..5a50e98dd0 100644 +--- a/board/st/stm32f429-discovery/stm32f429-discovery.c ++++ b/board/st/stm32f429-discovery/stm32f429-discovery.c +@@ -53,8 +53,6 @@ u32 get_board_rev(void) + + int board_init(void) + { +- gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100; +- + return 0; + } + +diff --git a/board/st/stm32f429-evaluation/stm32f429-evaluation.c b/board/st/stm32f429-evaluation/stm32f429-evaluation.c +index 3b6df1f3ab..cf3056163c 100644 +--- a/board/st/stm32f429-evaluation/stm32f429-evaluation.c ++++ b/board/st/stm32f429-evaluation/stm32f429-evaluation.c +@@ -47,8 +47,6 @@ u32 get_board_rev(void) + + int board_init(void) + { +- gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100; +- + return 0; + } + +diff --git a/board/st/stm32f469-discovery/stm32f469-discovery.c b/board/st/stm32f469-discovery/stm32f469-discovery.c +index c5df9b0d9c..056c9dff2a 100644 +--- a/board/st/stm32f469-discovery/stm32f469-discovery.c ++++ b/board/st/stm32f469-discovery/stm32f469-discovery.c +@@ -47,8 +47,6 @@ u32 get_board_rev(void) + + int board_init(void) + { +- gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100; +- + return 0; + } + +diff --git a/board/st/stm32f746-disco/stm32f746-disco.c b/board/st/stm32f746-disco/stm32f746-disco.c +index efa38a0e26..82f1bf9b04 100644 +--- a/board/st/stm32f746-disco/stm32f746-disco.c ++++ b/board/st/stm32f746-disco/stm32f746-disco.c +@@ -21,7 +21,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -122,8 +121,6 @@ int board_late_init(void) + + int board_init(void) + { +- gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100; +- + #ifdef CONFIG_ETH_DESIGNWARE + const char *phy_mode; + int node; +diff --git a/board/st/stm32h743-disco/stm32h743-disco.c b/board/st/stm32h743-disco/stm32h743-disco.c +index 4091d5f9fd..e493786f11 100644 +--- a/board/st/stm32h743-disco/stm32h743-disco.c ++++ b/board/st/stm32h743-disco/stm32h743-disco.c +@@ -43,6 +43,5 @@ u32 get_board_rev(void) + + int board_init(void) + { +- gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100; + return 0; + } +diff --git a/board/st/stm32h743-eval/stm32h743-eval.c b/board/st/stm32h743-eval/stm32h743-eval.c +index 4091d5f9fd..e493786f11 100644 +--- a/board/st/stm32h743-eval/stm32h743-eval.c ++++ b/board/st/stm32h743-eval/stm32h743-eval.c +@@ -43,6 +43,5 @@ u32 get_board_rev(void) + + int board_init(void) + { +- gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100; + return 0; + } +diff --git a/board/st/stm32h750-art-pi/stm32h750-art-pi.c b/board/st/stm32h750-art-pi/stm32h750-art-pi.c +index 5785b2e575..bec26465d2 100644 +--- a/board/st/stm32h750-art-pi/stm32h750-art-pi.c ++++ b/board/st/stm32h750-art-pi/stm32h750-art-pi.c +@@ -53,6 +53,5 @@ int board_late_init(void) + + int board_init(void) + { +- gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100; + return 0; + } +diff --git a/board/st/stm32mp1/Kconfig b/board/st/stm32mp1/Kconfig +index c5ab7553d4..6ab8f80fa4 100644 +--- a/board/st/stm32mp1/Kconfig ++++ b/board/st/stm32mp1/Kconfig +@@ -7,7 +7,22 @@ config SYS_VENDOR + default "st" + + config SYS_CONFIG_NAME ++ default "stm32mp15_st_common" ++ ++source "board/st/common/Kconfig" ++endif ++ ++if TARGET_ST_STM32MP13x ++ ++config SYS_BOARD + default "stm32mp1" + ++config SYS_VENDOR ++ default "st" ++ ++config SYS_CONFIG_NAME ++ default "stm32mp13_st_common" ++ + source "board/st/common/Kconfig" ++ + endif +diff --git a/board/st/stm32mp1/MAINTAINERS b/board/st/stm32mp1/MAINTAINERS +index 0e6d80fb45..f5700d789b 100644 +--- a/board/st/stm32mp1/MAINTAINERS ++++ b/board/st/stm32mp1/MAINTAINERS +@@ -3,9 +3,12 @@ M: Patrick Delaunay + L: uboot-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers) + T: git https://source.denx.de/u-boot/custodians/u-boot-stm.git + S: Maintained ++F: arch/arm/dts/stm32mp13* + F: arch/arm/dts/stm32mp15* + F: board/st/stm32mp1/ ++F: configs/stm32mp13_defconfig + F: configs/stm32mp15_defconfig + F: configs/stm32mp15_basic_defconfig + F: configs/stm32mp15_trusted_defconfig +-F: include/configs/stm32mp1.h ++F: include/configs/stm32mp15_common.h ++F: include/configs/stm32mp15_st_common.h +diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c +index 032f08d795..c9b21a76eb 100644 +--- a/board/st/stm32mp1/stm32mp1.c ++++ b/board/st/stm32mp1/stm32mp1.c +@@ -13,11 +13,13 @@ + #include + #include + #include ++#include + #include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -30,6 +32,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -37,16 +40,17 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include + #include + #include + #include ++#include + #include + +-#include "../../st/common/stusb160x.h" +- + /* SYSCFG registers */ + #define SYSCFG_BOOTR 0x00 + #define SYSCFG_PMCSETR 0x04 +@@ -54,7 +58,8 @@ + #define SYSCFG_ICNR 0x1C + #define SYSCFG_CMPCR 0x20 + #define SYSCFG_CMPENSETR 0x24 +-#define SYSCFG_PMCCLRR 0x44 ++#define SYSCFG_PMCCLRR 0x08 ++#define SYSCFG_MP13_PMCCLRR 0x44 + + #define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0) + #define SYSCFG_BOOTR_BOOTPD_SHIFT 4 +@@ -70,15 +75,8 @@ + + #define SYSCFG_CMPENSETR_MPU_EN BIT(0) + +-#define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16) +-#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17) +- +-#define SYSCFG_PMCSETR_ETH_SELMII BIT(20) +- +-#define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21) +-#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0 +-#define SYSCFG_PMCSETR_ETH_SEL_RGMII BIT(21) +-#define SYSCFG_PMCSETR_ETH_SEL_RMII BIT(23) ++#define GOODIX_REG_ID 0x8140 ++#define GOODIX_ID_LEN 4 + + /* + * Get a global data pointer +@@ -189,6 +187,20 @@ static void board_key_check(void) + } + } + ++static int typec_usb_cable_connected(void) ++{ ++ struct udevice *dev; ++ int ret; ++ u8 connector = 0; ++ ++ ret = uclass_get_device(UCLASS_USB_TYPEC, 0, &dev); ++ if (ret < 0) ++ return ret; ++ ++ return (typec_is_attached(dev, connector) == TYPEC_ATTACHED) && ++ (typec_get_data_role(dev, connector) == TYPEC_DEVICE); ++} ++ + int g_dnl_board_usb_cable_connected(void) + { + struct udevice *dwc2_udc_otg; +@@ -197,8 +209,15 @@ int g_dnl_board_usb_cable_connected(void) + if (!IS_ENABLED(CONFIG_USB_GADGET_DWC2_OTG)) + return -ENODEV; + +- /* if typec stusb160x is present, means DK1 or DK2 board */ +- ret = stusb160x_cable_connected(); ++ /* ++ * In case of USB boot device is detected, consider USB cable is ++ * connected ++ */ ++ if ((get_bootmode() & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_USB) ++ return true; ++ ++ /* if Type-C is present, it means DK1 or DK2 board */ ++ ret = typec_usb_cable_connected(); + if (ret >= 0) + return ret; + +@@ -353,9 +372,6 @@ static int board_check_usb_power(void) + u32 nb_blink; + u8 i; + +- if (!IS_ENABLED(CONFIG_ADC)) +- return -ENODEV; +- + node = ofnode_path("/config"); + if (!ofnode_valid(node)) { + log_debug("no /config node?\n"); +@@ -545,8 +561,7 @@ static void sysconf_init(void) + clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); + } + +-/* Fix to make I2C1 usable on DK2 for touchscreen usage in kernel */ +-static int dk2_i2c1_fix(void) ++static int board_stm32mp15x_dk2_init(void) + { + ofnode node; + struct gpio_desc hdmi, audio; +@@ -555,6 +570,7 @@ static int dk2_i2c1_fix(void) + if (!IS_ENABLED(CONFIG_DM_REGULATOR)) + return -ENODEV; + ++ /* Fix to make I2C1 usable on DK2 for touchscreen usage in kernel */ + node = ofnode_path("/soc/i2c@40012000/hdmi-transmitter@39"); + if (!ofnode_valid(node)) { + log_debug("no hdmi-transmitter@39 ?\n"); +@@ -602,16 +618,27 @@ error: + return ret; + } + +-static bool board_is_dk2(void) ++static bool board_is_stm32mp13x_dk(void) ++{ ++ if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP13x) && ++ (of_machine_is_compatible("st,stm32mp135d-dk") || ++ of_machine_is_compatible("st,stm32mp135f-dk"))) ++ return true; ++ ++ return false; ++} ++ ++static bool board_is_stm32mp15x_dk2(void) + { + if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) && +- of_machine_is_compatible("st,stm32mp157c-dk2")) ++ (of_machine_is_compatible("st,stm32mp157c-dk2") || ++ of_machine_is_compatible("st,stm32mp157f-dk2"))) + return true; + + return false; + } + +-static bool board_is_ev1(void) ++static bool board_is_stm32mp15x_ev1(void) + { + if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) && + (of_machine_is_compatible("st,stm32mp157a-ev1") || +@@ -623,47 +650,224 @@ static bool board_is_ev1(void) + return false; + } + ++/* touchscreen driver: used for focaltech touchscreen detection */ ++static const struct udevice_id edt_ft6236_ids[] = { ++ { .compatible = "focaltech,ft6236", }, ++ { } ++}; ++ ++U_BOOT_DRIVER(edt_ft6236) = { ++ .name = "edt_ft6236", ++ .id = UCLASS_I2C_GENERIC, ++ .of_match = edt_ft6236_ids, ++}; ++ + /* touchscreen driver: only used for pincontrol configuration */ + static const struct udevice_id goodix_ids[] = { ++ { .compatible = "goodix,gt911", }, + { .compatible = "goodix,gt9147", }, + { } + }; + + U_BOOT_DRIVER(goodix) = { + .name = "goodix", +- .id = UCLASS_NOP, ++ .id = UCLASS_I2C_GENERIC, + .of_match = goodix_ids, + }; + +-static void board_ev1_init(void) ++static int goodix_i2c_read(struct udevice *dev, u16 reg, u8 *buf, int len) ++{ ++ struct i2c_msg msgs[2]; ++ __be16 wbuf = cpu_to_be16(reg); ++ int ret; ++ ++ msgs[0].flags = 0; ++ msgs[0].addr = 0x5d; ++ msgs[0].len = 2; ++ msgs[0].buf = (u8 *)&wbuf; ++ ++ msgs[1].flags = I2C_M_RD; ++ msgs[1].addr = 0x5d; ++ msgs[1].len = len; ++ msgs[1].buf = buf; ++ ++ ret = dm_i2c_xfer(dev, msgs, 2); ++ ++ return ret; ++} ++ ++/* HELPER: search detected driver */ ++struct detect_info_t { ++ bool (*detect)(void); ++ struct driver *drv; ++}; ++ ++static struct driver *detect_device(struct detect_info_t *info, u8 size) + { ++ struct driver *drv = NULL; ++ u8 i; ++ ++ for (i = 0; i < size && !drv; i++) ++ if (info[i].detect()) ++ drv = info[i].drv; ++ ++ return drv; ++} ++ ++/* HELPER: force new driver binding, replace the existing one */ ++static void bind_driver(struct driver *drv, const char *path) ++{ ++ ofnode node; + struct udevice *dev; ++ struct udevice *parent; ++ int ret; ++ ++ node = ofnode_path(path); ++ if (!ofnode_valid(node)) ++ return; ++ if (!ofnode_is_enabled(node)) ++ return; ++ ++ ret = device_find_global_by_ofnode(ofnode_get_parent(node), &parent); ++ if (!parent || ret) { ++ log_debug("Unable to found parent. err:%d\n", ret); ++ return; ++ } ++ ++ ret = device_find_global_by_ofnode(node, &dev); ++ /* remove the driver previously binded */ ++ if (dev && !ret) { ++ if (dev->driver == drv) { ++ log_debug("nothing to do, %s already binded.\n", drv->name); ++ return; ++ } ++ log_debug("%s unbind\n", dev->driver->name); ++ device_remove(dev, DM_REMOVE_NORMAL); ++ device_unbind(dev); ++ } ++ /* bind the new driver */ ++ ret = device_bind_with_driver_data(parent, drv, ofnode_get_name(node), ++ 0, node, &dev); ++ if (ret) ++ log_debug("Unable to bind %s, err:%d\n", drv->name, ret); ++} ++ ++bool stm32mp15x_ev1_rm68200(void) ++{ ++ struct udevice *dev; ++ struct udevice *bus; ++ struct dm_i2c_chip *chip; ++ char id[GOODIX_ID_LEN]; ++ int ret; ++ ++ ret = uclass_get_device_by_driver(UCLASS_I2C_GENERIC, DM_DRIVER_GET(goodix), &dev); ++ if (ret) ++ return false; ++ ++ bus = dev_get_parent(dev); ++ chip = dev_get_parent_plat(dev); ++ ret = dm_i2c_probe(bus, chip->chip_addr, 0, &dev); ++ if (ret) ++ return false; ++ ++ ret = goodix_i2c_read(dev, GOODIX_REG_ID, id, sizeof(id)); ++ if (ret) ++ return false; ++ ++ if (!strncmp(id, "9147", sizeof(id))) ++ return true; ++ ++ return false; ++} ++ ++bool stm32mp15x_ev1_hx8394(void) ++{ ++ return true; ++} ++ ++extern U_BOOT_DRIVER(rm68200_panel); ++extern U_BOOT_DRIVER(hx8394_panel); ++ ++struct detect_info_t stm32mp15x_ev1_panels[] = { ++ CONFIG_IS_ENABLED(VIDEO_LCD_RAYDIUM_RM68200, ++ ({ .detect = stm32mp15x_ev1_rm68200, ++ .drv = DM_DRIVER_REF(rm68200_panel) ++ }, ++ )) ++ CONFIG_IS_ENABLED(VIDEO_LCD_ROCKTECH_HX8394, ++ ({ .detect = stm32mp15x_ev1_hx8394, ++ .drv = DM_DRIVER_REF(hx8394_panel) ++ }, ++ )) ++}; ++ ++static void board_stm32mp15x_ev1_init(void) ++{ ++ struct udevice *dev; ++ struct driver *drv; ++ struct gpio_desc reset_gpio; ++ char path[40]; + + /* configure IRQ line on EV1 for touchscreen before LCD reset */ ++ uclass_get_device_by_driver(UCLASS_I2C_GENERIC, DM_DRIVER_GET(goodix), &dev); ++ ++ /* get & set reset gpio for panel */ ++ uclass_get_device_by_driver(UCLASS_PANEL, DM_DRIVER_GET(rm68200_panel), &dev); ++ ++ gpio_request_by_name(dev, "reset-gpios", 0, &reset_gpio, GPIOD_IS_OUT); ++ ++ if (!dm_gpio_is_valid(&reset_gpio)) ++ return; ++ ++ dm_gpio_set_value(&reset_gpio, true); ++ mdelay(1); ++ dm_gpio_set_value(&reset_gpio, false); ++ mdelay(10); ++ ++ /* auto detection of connected panel-dsi */ ++ drv = detect_device(stm32mp15x_ev1_panels, ARRAY_SIZE(stm32mp15x_ev1_panels)); ++ if (!drv) ++ return; ++ /* save the detected compatible in environment */ ++ env_set("panel-dsi", drv->of_match->compatible); ++ ++ dm_gpio_free(NULL, &reset_gpio); ++ ++ /* select the driver for the detected PANEL */ ++ ofnode_get_path(dev_ofnode(dev), path, sizeof(path)); ++ bind_driver(drv, path); ++} ++ ++static void board_stm32mp13x_dk_init(void) ++{ ++ struct udevice *dev; ++ ++ /* configure IRQ line on DK for touchscreen before LCD reset */ + uclass_get_device_by_driver(UCLASS_NOP, DM_DRIVER_GET(goodix), &dev); + } + + /* board dependent setup after realloc */ + int board_init(void) + { +- /* address of boot parameters */ +- gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100; ++ struct udevice *dev; ++ int ret; + +- if (CONFIG_IS_ENABLED(DM_GPIO_HOG)) +- gpio_hog_probe_all(); ++ /* probe RCC to avoid circular access with usbphyc probe as clk provider */ ++ if (IS_ENABLED(CONFIG_CLK_STM32MP13)) { ++ ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(stm32mp1_clock), &dev); ++ log_debug("Clock init failed: %d\n", ret); ++ } + + board_key_check(); + +- if (board_is_ev1()) +- board_ev1_init(); +- +- if (board_is_dk2()) +- dk2_i2c1_fix(); +- + if (IS_ENABLED(CONFIG_DM_REGULATOR)) + regulators_enable_boot_on(_DEBUG); + +- if (!IS_ENABLED(CONFIG_TFABOOT)) ++ /* ++ * sysconf initialisation done only when U-Boot is running in secure ++ * done in TF-A for TFABOOT. ++ */ ++ if (IS_ENABLED(CONFIG_ARMV7_NONSEC)) + sysconf_init(); + + if (CONFIG_IS_ENABLED(LED)) +@@ -685,6 +889,15 @@ int board_late_init(void) + char dtb_name[256]; + int buf_len; + ++ if (board_is_stm32mp13x_dk()) ++ board_stm32mp13x_dk_init(); ++ ++ if (board_is_stm32mp15x_ev1()) ++ board_stm32mp15x_ev1_init(); ++ ++ if (board_is_stm32mp15x_dk2()) ++ board_stm32mp15x_dk2_init(); ++ + if (IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)) { + fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible", + &fdt_compat_len); +@@ -718,8 +931,14 @@ int board_late_init(void) + } + } + +- /* for DK1/DK2 boards */ +- board_check_usb_power(); ++ if (IS_ENABLED(CONFIG_ADC)) { ++ /* probe all ADC for calibration */ ++ uclass_foreach_dev_probe(UCLASS_ADC, dev) { ++ log_debug("ACD probe for calibration: %s\n", dev->name); ++ } ++ /* for DK1/DK2 boards */ ++ board_check_usb_power(); ++ } + + return 0; + } +@@ -729,58 +948,114 @@ void board_quiesce_devices(void) + setup_led(LEDST_OFF); + } + ++/* CLOCK feed to PHY*/ ++#define ETH_CK_F_25M 25000000 ++#define ETH_CK_F_50M 50000000 ++#define ETH_CK_F_125M 125000000 ++ ++struct stm32_syscfg_pmcsetr { ++ u32 syscfg_clr_off; ++ u32 eth1_clk_sel; ++ u32 eth1_ref_clk_sel; ++ u32 eth1_sel_mii; ++ u32 eth1_sel_rgmii; ++ u32 eth1_sel_rmii; ++ u32 eth2_clk_sel; ++ u32 eth2_ref_clk_sel; ++ u32 eth2_sel_rgmii; ++ u32 eth2_sel_rmii; ++}; ++ ++const struct stm32_syscfg_pmcsetr stm32mp15_syscfg_pmcsetr = { ++ .syscfg_clr_off = 0x44, ++ .eth1_clk_sel = BIT(16), ++ .eth1_ref_clk_sel = BIT(17), ++ .eth1_sel_mii = BIT(20), ++ .eth1_sel_rgmii = BIT(21), ++ .eth1_sel_rmii = BIT(23), ++ .eth2_clk_sel = 0, ++ .eth2_ref_clk_sel = 0, ++ .eth2_sel_rgmii = 0, ++ .eth2_sel_rmii = 0 ++}; ++ ++const struct stm32_syscfg_pmcsetr stm32mp13_syscfg_pmcsetr = { ++ .syscfg_clr_off = 0x08, ++ .eth1_clk_sel = BIT(16), ++ .eth1_ref_clk_sel = BIT(17), ++ .eth1_sel_mii = 0, ++ .eth1_sel_rgmii = BIT(21), ++ .eth1_sel_rmii = BIT(23), ++ .eth2_clk_sel = BIT(24), ++ .eth2_ref_clk_sel = BIT(25), ++ .eth2_sel_rgmii = BIT(29), ++ .eth2_sel_rmii = BIT(31) ++}; ++ ++#define SYSCFG_PMCSETR_ETH_MASK GENMASK(23, 16) ++#define SYSCFG_PMCR_ETH_SEL_GMII 0 ++ + /* eth init function : weak called in eqos driver */ + int board_interface_eth_init(struct udevice *dev, +- phy_interface_t interface_type) ++ phy_interface_t interface_type, ulong rate) + { +- u8 *syscfg; ++ struct regmap *regmap; ++ uint regmap_mask; ++ int ret; + u32 value; +- bool eth_clk_sel_reg = false; +- bool eth_ref_clk_sel_reg = false; ++ bool ext_phyclk, eth_clk_sel_reg, eth_ref_clk_sel_reg; ++ const struct stm32_syscfg_pmcsetr *pmcsetr; ++ ++ /* Ethernet PHY have no crystal */ ++ ext_phyclk = dev_read_bool(dev, "st,ext-phyclk"); + + /* Gigabit Ethernet 125MHz clock selection. */ + 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"); ++ eth_ref_clk_sel_reg = dev_read_bool(dev, "st,eth-ref-clk-sel"); + +- syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); ++ if (device_is_compatible(dev, "st,stm32mp13-dwmac")) ++ pmcsetr = &stm32mp13_syscfg_pmcsetr; ++ else ++ pmcsetr = &stm32mp15_syscfg_pmcsetr; + +- if (!syscfg) ++ regmap = syscon_regmap_lookup_by_phandle(dev, "st,syscon"); ++ if (!IS_ERR(regmap)) { ++ u32 fmp[3]; ++ ++ ret = dev_read_u32_array(dev, "st,syscon", fmp, 3); ++ if (ret) ++ /* If no mask in DT, it is MP15 (backward compatibility) */ ++ regmap_mask = SYSCFG_PMCSETR_ETH_MASK; ++ else ++ regmap_mask = fmp[2]; ++ } else { + return -ENODEV; ++ } + + switch (interface_type) { + case PHY_INTERFACE_MODE_MII: +- value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | +- SYSCFG_PMCSETR_ETH_REF_CLK_SEL; ++ value = pmcsetr->eth1_sel_mii; + log_debug("PHY_INTERFACE_MODE_MII\n"); + break; + case PHY_INTERFACE_MODE_GMII: +- if (eth_clk_sel_reg) +- value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | +- SYSCFG_PMCSETR_ETH_CLK_SEL; +- else +- value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII; ++ value = SYSCFG_PMCR_ETH_SEL_GMII; + log_debug("PHY_INTERFACE_MODE_GMII\n"); + break; + case PHY_INTERFACE_MODE_RMII: +- if (eth_ref_clk_sel_reg) +- value = SYSCFG_PMCSETR_ETH_SEL_RMII | +- SYSCFG_PMCSETR_ETH_REF_CLK_SEL; +- else +- value = SYSCFG_PMCSETR_ETH_SEL_RMII; ++ value = pmcsetr->eth1_sel_rmii | pmcsetr->eth2_sel_rmii; ++ if (rate == ETH_CK_F_50M && (eth_clk_sel_reg || ext_phyclk)) ++ value |= pmcsetr->eth1_ref_clk_sel | pmcsetr->eth2_ref_clk_sel; + log_debug("PHY_INTERFACE_MODE_RMII\n"); + break; + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: +- if (eth_clk_sel_reg) +- value = SYSCFG_PMCSETR_ETH_SEL_RGMII | +- SYSCFG_PMCSETR_ETH_CLK_SEL; +- else +- value = SYSCFG_PMCSETR_ETH_SEL_RGMII; ++ value = pmcsetr->eth1_sel_rgmii | pmcsetr->eth2_sel_rgmii; ++ if (rate == ETH_CK_F_125M && (eth_clk_sel_reg || ext_phyclk)) ++ value |= pmcsetr->eth1_clk_sel | pmcsetr->eth2_clk_sel; + log_debug("PHY_INTERFACE_MODE_RGMII\n"); + break; + default: +@@ -790,13 +1065,12 @@ int board_interface_eth_init(struct udevice *dev, + return -EINVAL; + } + +- /* clear and set ETH configuration bits */ +- writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII | +- SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL, +- syscfg + SYSCFG_PMCCLRR); +- writel(value, syscfg + SYSCFG_PMCSETR); ++ /* Need to update PMCCLRR (clear register) */ ++ regmap_write(regmap, pmcsetr->syscfg_clr_off, regmap_mask); + +- return 0; ++ ret = regmap_update_bits(regmap, SYSCFG_PMCSETR, regmap_mask, value); ++ ++ return ret; + } + + enum env_location env_get_location(enum env_operation op, int prio) +@@ -890,14 +1164,277 @@ const char *env_ext4_get_dev_part(void) + + int mmc_get_env_dev(void) + { +- if (CONFIG_SYS_MMC_ENV_DEV >= 0) +- return CONFIG_SYS_MMC_ENV_DEV; ++ const int mmc_env_dev = CONFIG_IS_ENABLED(ENV_IS_IN_MMC, (CONFIG_SYS_MMC_ENV_DEV), (-1)); ++ ++ if (mmc_env_dev >= 0) ++ return mmc_env_dev; + + /* use boot instance to select the correct mmc device identifier */ + return mmc_get_boot(); + } + + #if defined(CONFIG_OF_BOARD_SETUP) ++ ++/* update scmi nodes with information provided by SP-MIN */ ++void stm32mp15_fdt_update_scmi_node(void *new_blob) ++{ ++ ofnode node; ++ int nodeoff = 0; ++ const char *name; ++ u32 val; ++ int ret; ++ ++ nodeoff = fdt_path_offset(new_blob, "/firmware/scmi"); ++ if (nodeoff < 0) ++ return; ++ ++ /* search scmi node in U-Boot device tree */ ++ node = ofnode_path("/firmware/scmi"); ++ if (!ofnode_valid(node)) { ++ log_warning("node not found"); ++ return; ++ } ++ if (!ofnode_device_is_compatible(node, "arm,scmi-smc")) { ++ name = ofnode_get_property(node, "compatible", NULL); ++ log_warning("invalid compatible %s", name); ++ return; ++ } ++ ++ /* read values updated by TF-A SP-MIN */ ++ ret = ofnode_read_u32(node, "arm,smc-id", &val); ++ if (ret) { ++ log_warning("arm,smc-id missing"); ++ return; ++ } ++ /* update kernel node */ ++ fdt_setprop_string(new_blob, nodeoff, "compatible", "arm,scmi-smc"); ++ fdt_delprop(new_blob, nodeoff, "linaro,optee-channel-id"); ++ fdt_setprop_u32(new_blob, nodeoff, "arm,smc-id", val); ++} ++ ++/* ++ * update the device tree to support boot with SP-MIN, using a device tree ++ * containing OPTE nodes: ++ * 1/ remove the OP-TEE related nodes ++ * 2/ copy SCMI nodes to kernel device tree to replace the OP-TEE agent ++ * ++ * SP-MIN boot is supported for STM32MP15 and it uses the SCMI SMC agent ++ * whereas Linux device tree defines an SCMI OP-TEE agent. ++ * ++ * This function allows to temporary support this legacy boot mode, ++ * with SP-MIN and without OP-TEE. ++ */ ++void stm32mp15_fdt_update_optee_nodes(void *new_blob) ++{ ++ ofnode node; ++ int nodeoff = 0, subnodeoff; ++ ++ /* only proceed if /firmware/optee node is not present in U-Boot DT */ ++ node = ofnode_path("/firmware/optee"); ++ if (ofnode_valid(node)) { ++ log_debug("OP-TEE firmware found, nothing to do"); ++ return; ++ } ++ ++ /* remove OP-TEE memory regions in reserved-memory node */ ++ nodeoff = fdt_path_offset(new_blob, "/reserved-memory"); ++ if (nodeoff >= 0) { ++ fdt_for_each_subnode(subnodeoff, new_blob, nodeoff) { ++ const char *name = fdt_get_name(new_blob, subnodeoff, NULL); ++ ++ /* only handle "optee" reservations */ ++ if (name && !strncmp(name, "optee", 5)) ++ fdt_del_node(new_blob, subnodeoff); ++ } ++ } ++ ++ /* remove OP-TEE node */ ++ nodeoff = fdt_path_offset(new_blob, "/firmware/optee"); ++ if (nodeoff >= 0) ++ fdt_del_node(new_blob, nodeoff); ++ ++ /* update the scmi node */ ++ stm32mp15_fdt_update_scmi_node(new_blob); ++} ++ ++/* Galaxycore GC2145 sensor detection */ ++static const struct udevice_id galaxycore_gc2145_ids[] = { ++ { .compatible = "galaxycore,gc2145", }, ++ { } ++}; ++ ++U_BOOT_DRIVER(galaxycore_gc2145) = { ++ .name = "galaxycore_gc2145", ++ .id = UCLASS_I2C_GENERIC, ++ .of_match = galaxycore_gc2145_ids, ++}; ++ ++#define GC2145_ID_REG_OFF 0xF0 ++#define GC2145_ID 0x2145 ++static bool stm32mp13x_is_gc2145_detected(void) ++{ ++ struct udevice *dev, *bus, *supply; ++ struct dm_i2c_chip *chip; ++ struct gpio_desc gpio; ++ bool gpio_found = false; ++ bool gc2145_detected = false; ++ u16 id; ++ int ret; ++ ++ /* Check if the GC2145 sensor is found */ ++ ret = uclass_get_device_by_driver(UCLASS_I2C_GENERIC, DM_DRIVER_GET(galaxycore_gc2145), ++ &dev); ++ if (ret) ++ return false; ++ ++ /* ++ * In order to get access to the sensor we need to enable regulators ++ * and disable powerdown GPIO ++ */ ++ ret = device_get_supply_regulator(dev, "IOVDD-supply", &supply); ++ if (!ret && supply) ++ regulator_autoset(supply); ++ ++ /* Request the powerdown GPIO */ ++ ret = gpio_request_by_name(dev, "powerdown-gpios", 0, &gpio, GPIOD_IS_OUT); ++ if (!ret) { ++ gpio_found = true; ++ dm_gpio_set_value(&gpio, 0); ++ } ++ ++ /* Wait a bit so that the device become visible on I2C */ ++ mdelay(10); ++ ++ bus = dev_get_parent(dev); ++ ++ /* Probe the i2c device */ ++ chip = dev_get_parent_plat(dev); ++ ret = dm_i2c_probe(bus, chip->chip_addr, 0, &dev); ++ if (ret) ++ goto out; ++ ++ /* Read the value at 0xF0 - 0xF1 */ ++ ret = dm_i2c_read(dev, GC2145_ID_REG_OFF, (uint8_t *)&id, sizeof(id)); ++ if (ret) ++ goto out; ++ ++ /* Check ID values - if GC2145 then nothing to do */ ++ gc2145_detected = (be16_to_cpu(id) == GC2145_ID); ++ ++out: ++ if (gpio_found) { ++ dm_gpio_set_value(&gpio, 1); ++ dm_gpio_free(NULL, &gpio); ++ } ++ ++ return gc2145_detected; ++} ++ ++void stm32mp13x_dk_fdt_update(void *new_blob) ++{ ++ int nodeoff_gc2145 = 0, nodeoff_ov5640 = 0; ++ int nodeoff_ov5640_ep = 0, nodeoff_stmipi_ep = 0; ++ int phandle_ov5640_ep, phandle_stmipi_ep; ++ ++ if (stm32mp13x_is_gc2145_detected()) ++ return; ++ ++ /* ++ * By default the DT is written with GC2145 enabled. If it isn't ++ * detected, disable it within the DT and instead enable the OV5640 ++ */ ++ nodeoff_gc2145 = fdt_path_offset(new_blob, "/soc/i2c@4c006000/gc2145@3c"); ++ if (nodeoff_gc2145 < 0) { ++ log_err("gc2145@3c node not found - DT update aborted\n"); ++ return; ++ } ++ fdt_setprop_string(new_blob, nodeoff_gc2145, "status", "disabled"); ++ ++ nodeoff_ov5640 = fdt_path_offset(new_blob, "/soc/i2c@4c006000/camera@3c"); ++ if (nodeoff_ov5640 < 0) { ++ log_err("camera@3c node not found - DT update aborted\n"); ++ return; ++ } ++ fdt_setprop_string(new_blob, nodeoff_ov5640, "status", "okay"); ++ ++ nodeoff_ov5640_ep = fdt_path_offset(new_blob, "/soc/i2c@4c006000/camera@3c/port/endpoint"); ++ if (nodeoff_ov5640_ep < 0) { ++ log_err("camera@3c/port/endpoint node not found - DT update aborted\n"); ++ return; ++ } ++ ++ phandle_ov5640_ep = fdt_get_phandle(new_blob, nodeoff_ov5640_ep); ++ ++ nodeoff_stmipi_ep = ++ fdt_path_offset(new_blob, "/soc/i2c@4c006000/stmipi@14/ports/port@0/endpoint"); ++ if (nodeoff_stmipi_ep < 0) { ++ log_err("stmipi@14/ports/port@0/endpoint node not found - DT update aborted\n"); ++ return; ++ } ++ ++ fdt_setprop_u32(new_blob, nodeoff_stmipi_ep, "remote-endpoint", phandle_ov5640_ep); ++ ++ /* ++ * The OV5640 endpoint doesn't have remote-endpoint property in order to avoid ++ * a device-tree warning due to non birectionnal graph connection. ++ * When enabling the OV5640, add the remote-endpoint property as well, pointing ++ * to the stmipi endpoint ++ */ ++ phandle_stmipi_ep = fdt_get_phandle(new_blob, nodeoff_stmipi_ep); ++ fdt_setprop_u32(new_blob, nodeoff_ov5640_ep, "remote-endpoint", phandle_stmipi_ep); ++} ++ ++void stm32mp15x_dk2_fdt_update(void *new_blob) ++{ ++ struct udevice *dev; ++ struct udevice *bus; ++ int nodeoff = 0; ++ int ret; ++ ++ ret = uclass_get_device_by_driver(UCLASS_I2C_GENERIC, DM_DRIVER_GET(edt_ft6236), &dev); ++ if (ret) ++ return; ++ ++ bus = dev_get_parent(dev); ++ ++ ret = dm_i2c_probe(bus, 0x38, 0, &dev); ++ if (ret < 0) { ++ nodeoff = fdt_path_offset(new_blob, "/soc/i2c@40012000/touchscreen@38"); ++ if (nodeoff < 0) { ++ log_warning("touchscreen@2a node not found\n"); ++ } else { ++ fdt_set_name(new_blob, nodeoff, "touchscreen@2a"); ++ fdt_setprop_u32(new_blob, nodeoff, "reg", 0x2a); ++ log_debug("touchscreen@38 node updated to @2a\n"); ++ } ++ } ++} ++ ++void fdt_update_panel_dsi(void *new_blob) ++{ ++ char const *panel = env_get("panel-dsi"); ++ int nodeoff = 0; ++ ++ if (!panel) ++ return; ++ ++ if (!strcmp(panel, "rocktech,hx8394")) { ++ nodeoff = fdt_node_offset_by_compatible(new_blob, -1, "raydium,rm68200"); ++ if (nodeoff < 0) { ++ log_warning("panel-dsi node not found"); ++ return; ++ } ++ fdt_setprop_string(new_blob, nodeoff, "compatible", panel); ++ ++ nodeoff = fdt_node_offset_by_compatible(new_blob, -1, "goodix,gt9147"); ++ if (nodeoff < 0) { ++ log_warning("touchscreen node not found"); ++ return; ++ } ++ fdt_setprop_string(new_blob, nodeoff, "compatible", "goodix,gt911"); ++ } ++} ++ + int ft_board_setup(void *blob, struct bd_info *bd) + { + static const struct node_info nodes[] = { +@@ -915,6 +1452,21 @@ 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_enable_and_mem_rsv(blob); ++ ++ if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x)) ++ stm32mp15_fdt_update_optee_nodes(blob); ++ ++ if (board_is_stm32mp13x_dk()) ++ stm32mp13x_dk_fdt_update(blob); ++ ++ if (board_is_stm32mp15x_dk2()) ++ stm32mp15x_dk2_fdt_update(blob); ++ ++ if (board_is_stm32mp15x_ev1()) ++ fdt_update_panel_dsi(blob); ++ + return 0; + } + #endif +-- +2.25.1 + diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0003-ARM-v2020.10-stm32mp-r1-MISC-DRIVERS.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0003-ARM-v2020.10-stm32mp-r1-MISC-DRIVERS.patch deleted file mode 100644 index 235985d..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0003-ARM-v2020.10-stm32mp-r1-MISC-DRIVERS.patch +++ /dev/null @@ -1,5003 +0,0 @@ -From 9e9811305959e8d853a54714eb43ae21fe5d3e1d Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Tue, 16 Mar 2021 08:17:59 +0100 -Subject: [PATCH 3/5] ARM v2020.10-stm32mp-r1 MISC-DRIVERS - -Signed-off-by: Romuald JEANNE ---- - common/Kconfig | 2 +- - common/cli_readline.c | 6 + - common/image-fdt.c | 23 +- - doc/device-tree-bindings/arm/arm,scmi.txt | 197 +++++++++ - .../phy/phy-stm32-usbphyc.txt | 2 + - drivers/clk/Kconfig | 8 + - drivers/clk/Makefile | 1 + - drivers/clk/clk_scmi.c | 99 +++++ - drivers/clk/clk_stm32mp1.c | 63 +-- - drivers/core/ofnode.c | 10 + - drivers/dfu/dfu_mtd.c | 9 +- - drivers/firmware/Kconfig | 2 + - drivers/firmware/Makefile | 1 + - drivers/firmware/scmi/Kconfig | 19 + - drivers/firmware/scmi/Makefile | 5 + - drivers/firmware/scmi/mailbox_agent.c | 102 +++++ - drivers/firmware/scmi/sandbox-scmi_agent.c | 410 ++++++++++++++++++ - drivers/firmware/scmi/sandbox-scmi_devices.c | 113 +++++ - drivers/firmware/scmi/scmi_agent-uclass.c | 119 +++++ - drivers/firmware/scmi/smccc_agent.c | 89 ++++ - drivers/firmware/scmi/smt.c | 139 ++++++ - drivers/firmware/scmi/smt.h | 86 ++++ - drivers/gpio/stm32_gpio.c | 28 +- - drivers/mtd/nand/core.c | 2 + - drivers/mtd/nand/spi/core.c | 3 + - drivers/mtd/spi/spi-nor-core.c | 3 + - drivers/phy/phy-stm32-usbphyc.c | 33 +- - drivers/pinctrl/pinctrl-stmfx.c | 12 +- - drivers/pinctrl/pinctrl_stm32.c | 37 +- - drivers/remoteproc/Kconfig | 8 + - drivers/remoteproc/Makefile | 1 + - drivers/remoteproc/rproc-optee.c | 219 ++++++++++ - drivers/remoteproc/stm32_copro.c | 207 ++++++--- - drivers/reset/Kconfig | 8 + - drivers/reset/Makefile | 1 + - drivers/reset/reset-scmi.c | 81 ++++ - drivers/reset/stm32-reset.c | 17 +- - drivers/spi/stm32_qspi.c | 2 + - drivers/usb/gadget/dwc2_udc_otg.c | 61 ++- - drivers/usb/gadget/dwc2_udc_otg_regs.h | 2 + - drivers/video/dw_mipi_dsi.c | 62 ++- - drivers/video/stm32/stm32_dsi.c | 3 + - env/ext4.c | 3 +- - env/mmc.c | 6 +- - env/sf.c | 32 +- - include/configs/10m50_devboard.h | 5 - - include/configs/3c120_devboard.h | 5 - - include/configs/sandbox.h | 2 - - include/configs/stm32mp1.h | 1 - - include/configs/x86-common.h | 2 - - include/dm/ofnode.h | 11 + - include/dm/uclass-id.h | 1 + - include/dt-bindings/clock/stm32mp1-clks.h | 33 ++ - include/dt-bindings/pinctrl/stm32-pinfunc.h | 1 + - include/dt-bindings/reset/stm32mp1-resets.h | 15 + - include/dt-bindings/rtc/rtc-stm32.h | 13 + - include/dt-bindings/soc/stm32-hdp.h | 108 +++++ - include/env_internal.h | 1 + - include/fdtdec.h | 5 +- - include/image.h | 2 +- - include/lmb.h | 29 +- - include/mipi_dsi.h | 17 + - include/rproc_optee.h | 127 ++++++ - include/scmi_agent-uclass.h | 24 + - include/scmi_agent.h | 68 +++ - include/scmi_protocols.h | 179 ++++++++ - include/usb/dwc2_udc.h | 1 + - lib/Kconfig | 23 + - lib/fdtdec.c | 10 +- - lib/lmb.c | 108 +++-- - lib/optee/optee.c | 2 +- - scripts/config_whitelist.txt | 1 - - test/dm/Makefile | 1 + - test/dm/fdtdec.c | 9 +- - test/dm/ofnode.c | 12 + - test/dm/scmi.c | 203 +++++++++ - test/lib/lmb.c | 89 ++++ - 77 files changed, 3162 insertions(+), 282 deletions(-) - create mode 100644 doc/device-tree-bindings/arm/arm,scmi.txt - create mode 100644 drivers/clk/clk_scmi.c - create mode 100644 drivers/firmware/scmi/Kconfig - create mode 100644 drivers/firmware/scmi/Makefile - create mode 100644 drivers/firmware/scmi/mailbox_agent.c - create mode 100644 drivers/firmware/scmi/sandbox-scmi_agent.c - create mode 100644 drivers/firmware/scmi/sandbox-scmi_devices.c - create mode 100644 drivers/firmware/scmi/scmi_agent-uclass.c - create mode 100644 drivers/firmware/scmi/smccc_agent.c - create mode 100644 drivers/firmware/scmi/smt.c - create mode 100644 drivers/firmware/scmi/smt.h - create mode 100644 drivers/remoteproc/rproc-optee.c - create mode 100644 drivers/reset/reset-scmi.c - create mode 100644 include/dt-bindings/rtc/rtc-stm32.h - create mode 100644 include/dt-bindings/soc/stm32-hdp.h - create mode 100644 include/rproc_optee.h - create mode 100644 include/scmi_agent-uclass.h - create mode 100644 include/scmi_agent.h - create mode 100644 include/scmi_protocols.h - create mode 100644 test/dm/scmi.c - -diff --git a/common/Kconfig b/common/Kconfig -index 9c20a9738e..7099bbf902 100644 ---- a/common/Kconfig -+++ b/common/Kconfig -@@ -416,7 +416,7 @@ config USE_PREBOOT - config PREBOOT - string "preboot default value" - depends on USE_PREBOOT && !USE_DEFAULT_ENV_FILE -- default "usb start" if USB_KEYBOARD || USB_STORAGE -+ default "usb start" if USB_KEYBOARD - default "" - help - This is the default of "preboot" environment variable. -diff --git a/common/cli_readline.c b/common/cli_readline.c -index 1f1e28c6d8..491863303a 100644 ---- a/common/cli_readline.c -+++ b/common/cli_readline.c -@@ -15,6 +15,12 @@ - #include - #include - -+#ifdef CONFIG_SPL_BUILD -+#undef CONFIG_CMDLINE_EDITING -+#undef CONFIG_AUTO_COMPLETE -+#undef CONFIG_SHOW_ACTIVITY -+#endif -+ - DECLARE_GLOBAL_DATA_PTR; - - static const char erase_seq[] = "\b \b"; /* erase sequence */ -diff --git a/common/image-fdt.c b/common/image-fdt.c -index 3d6935ad40..55b3593762 100644 ---- a/common/image-fdt.c -+++ b/common/image-fdt.c -@@ -74,18 +74,20 @@ static const image_header_t *image_get_fdt(ulong fdt_addr) - #endif - - static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr, -- uint64_t size) -+ uint64_t size, enum lmb_flags flags) - { - long ret; - -- ret = lmb_reserve(lmb, addr, size); -+ ret = lmb_reserve_flags(lmb, addr, size, flags); - if (ret >= 0) { -- debug(" reserving fdt memory region: addr=%llx size=%llx\n", -- (unsigned long long)addr, (unsigned long long)size); -+ debug(" reserving fdt memory region: addr=%llx size=%llx flags=%x\n", -+ (unsigned long long)addr, -+ (unsigned long long)size, flags); - } else { - puts("ERROR: reserving fdt memory region failed "); -- printf("(addr=%llx size=%llx)\n", -- (unsigned long long)addr, (unsigned long long)size); -+ printf("(addr=%llx size=%llx flags=%x)\n", -+ (unsigned long long)addr, -+ (unsigned long long)size, flags); - } - } - -@@ -105,6 +107,7 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) - int i, total, ret; - int nodeoffset, subnode; - struct fdt_resource res; -+ enum lmb_flags flags; - - if (fdt_check_header(fdt_blob) != 0) - return; -@@ -114,7 +117,7 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) - for (i = 0; i < total; i++) { - if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0) - continue; -- boot_fdt_reserve_region(lmb, addr, size); -+ boot_fdt_reserve_region(lmb, addr, size, LMB_NONE); - } - - /* process reserved-memory */ -@@ -126,9 +129,13 @@ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) - ret = fdt_get_resource(fdt_blob, subnode, "reg", 0, - &res); - if (!ret && fdtdec_get_is_enabled(fdt_blob, subnode)) { -+ flags = LMB_NONE; -+ if (fdtdec_get_bool(fdt_blob, subnode, -+ "no-map")) -+ flags = LMB_NOMAP; - addr = res.start; - size = res.end - res.start + 1; -- boot_fdt_reserve_region(lmb, addr, size); -+ boot_fdt_reserve_region(lmb, addr, size, flags); - } - - subnode = fdt_next_subnode(fdt_blob, subnode); -diff --git a/doc/device-tree-bindings/arm/arm,scmi.txt b/doc/device-tree-bindings/arm/arm,scmi.txt -new file mode 100644 -index 0000000000..1f293ea24c ---- /dev/null -+++ b/doc/device-tree-bindings/arm/arm,scmi.txt -@@ -0,0 +1,197 @@ -+System Control and Management Interface (SCMI) Message Protocol -+---------------------------------------------------------- -+ -+The SCMI is intended to allow agents such as OSPM to manage various functions -+that are provided by the hardware platform it is running on, including power -+and performance functions. -+ -+This binding is intended to define the interface the firmware implementing -+the SCMI as described in ARM document number ARM DEN 0056A ("ARM System Control -+and Management Interface Platform Design Document")[0] provide for OSPM in -+the device tree. -+ -+Required properties: -+ -+The scmi node with the following properties shall be under the /firmware/ node. -+ -+- compatible : shall be "arm,scmi" or "arm,scmi-smc" for smc/hvc transports -+- mboxes: List of phandle and mailbox channel specifiers. It should contain -+ exactly one or two mailboxes, one for transmitting messages("tx") -+ and another optional for receiving the notifications("rx") if -+ supported. -+- shmem : List of phandle pointing to the shared memory(SHM) area as per -+ generic mailbox client binding. -+- #address-cells : should be '1' if the device has sub-nodes, maps to -+ protocol identifier for a given sub-node. -+- #size-cells : should be '0' as 'reg' property doesn't have any size -+ associated with it. -+- arm,smc-id : SMC id required when using smc or hvc transports -+ -+Optional properties: -+ -+- mbox-names: shall be "tx" or "rx" depending on mboxes entries. -+ -+See Documentation/devicetree/bindings/mailbox/mailbox.txt for more details -+about the generic mailbox controller and client driver bindings. -+ -+The mailbox is the only permitted method of calling the SCMI firmware. -+Mailbox doorbell is used as a mechanism to alert the presence of a -+messages and/or notification. -+ -+Each protocol supported shall have a sub-node with corresponding compatible -+as described in the following sections. If the platform supports dedicated -+communication channel for a particular protocol, the 3 properties namely: -+mboxes, mbox-names and shmem shall be present in the sub-node corresponding -+to that protocol. -+ -+Clock/Performance bindings for the clocks/OPPs based on SCMI Message Protocol -+------------------------------------------------------------ -+ -+This binding uses the common clock binding[1]. -+ -+Required properties: -+- #clock-cells : Should be 1. Contains the Clock ID value used by SCMI commands. -+ -+Power domain bindings for the power domains based on SCMI Message Protocol -+------------------------------------------------------------ -+ -+This binding for the SCMI power domain providers uses the generic power -+domain binding[2]. -+ -+Required properties: -+ - #power-domain-cells : Should be 1. Contains the device or the power -+ domain ID value used by SCMI commands. -+ -+Sensor bindings for the sensors based on SCMI Message Protocol -+-------------------------------------------------------------- -+SCMI provides an API to access the various sensors on the SoC. -+ -+Required properties: -+- #thermal-sensor-cells: should be set to 1. This property follows the -+ thermal device tree bindings[3]. -+ -+ Valid cell values are raw identifiers (Sensor ID) -+ as used by the firmware. Refer to platform details -+ for your implementation for the IDs to use. -+ -+Reset signal bindings for the reset domains based on SCMI Message Protocol -+------------------------------------------------------------ -+ -+This binding for the SCMI reset domain providers uses the generic reset -+signal binding[5]. -+ -+Required properties: -+ - #reset-cells : Should be 1. Contains the reset domain ID value used -+ by SCMI commands. -+ -+SRAM and Shared Memory for SCMI -+------------------------------- -+ -+A small area of SRAM is reserved for SCMI communication between application -+processors and SCP. -+ -+The properties should follow the generic mmio-sram description found in [4] -+ -+Each sub-node represents the reserved area for SCMI. -+ -+Required sub-node properties: -+- reg : The base offset and size of the reserved area with the SRAM -+- compatible : should be "arm,scmi-shmem" for Non-secure SRAM based -+ shared memory -+ -+[0] http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/index.html -+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -+[2] Documentation/devicetree/bindings/power/power-domain.yaml -+[3] Documentation/devicetree/bindings/thermal/thermal.txt -+[4] Documentation/devicetree/bindings/sram/sram.yaml -+[5] Documentation/devicetree/bindings/reset/reset.txt -+ -+Example: -+ -+sram@50000000 { -+ compatible = "mmio-sram"; -+ reg = <0x0 0x50000000 0x0 0x10000>; -+ -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0x0 0x50000000 0x10000>; -+ -+ cpu_scp_lpri: scp-shmem@0 { -+ compatible = "arm,scmi-shmem"; -+ reg = <0x0 0x200>; -+ }; -+ -+ cpu_scp_hpri: scp-shmem@200 { -+ compatible = "arm,scmi-shmem"; -+ reg = <0x200 0x200>; -+ }; -+}; -+ -+mailbox@40000000 { -+ .... -+ #mbox-cells = <1>; -+ reg = <0x0 0x40000000 0x0 0x10000>; -+}; -+ -+firmware { -+ -+ ... -+ -+ scmi { -+ compatible = "arm,scmi"; -+ mboxes = <&mailbox 0 &mailbox 1>; -+ mbox-names = "tx", "rx"; -+ shmem = <&cpu_scp_lpri &cpu_scp_hpri>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ scmi_devpd: protocol@11 { -+ reg = <0x11>; -+ #power-domain-cells = <1>; -+ }; -+ -+ scmi_dvfs: protocol@13 { -+ reg = <0x13>; -+ #clock-cells = <1>; -+ }; -+ -+ scmi_clk: protocol@14 { -+ reg = <0x14>; -+ #clock-cells = <1>; -+ }; -+ -+ scmi_sensors0: protocol@15 { -+ reg = <0x15>; -+ #thermal-sensor-cells = <1>; -+ }; -+ -+ scmi_reset: protocol@16 { -+ reg = <0x16>; -+ #reset-cells = <1>; -+ }; -+ }; -+}; -+ -+cpu@0 { -+ ... -+ reg = <0 0>; -+ clocks = <&scmi_dvfs 0>; -+}; -+ -+hdlcd@7ff60000 { -+ ... -+ reg = <0 0x7ff60000 0 0x1000>; -+ clocks = <&scmi_clk 4>; -+ power-domains = <&scmi_devpd 1>; -+ resets = <&scmi_reset 10>; -+}; -+ -+thermal-zones { -+ soc_thermal { -+ polling-delay-passive = <100>; -+ polling-delay = <1000>; -+ /* sensor ID */ -+ thermal-sensors = <&scmi_sensors0 3>; -+ ... -+ }; -+}; -diff --git a/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt b/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt -index da98407403..edfe4b426c 100644 ---- a/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt -+++ b/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt -@@ -45,6 +45,8 @@ Required properties: - - #phy-cells: see phy-bindings.txt in the same directory, must be <0> for PHY - port#1 and must be <1> for PHY port#2, to select USB controller - -+Optional properties: -+- vbus-supply: phandle to the regulator providing 5V vbus to the USB connector - - Example: - usbphyc: usb-phy@5a006000 { -diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig -index 6003e140b5..4dfbad7986 100644 ---- a/drivers/clk/Kconfig -+++ b/drivers/clk/Kconfig -@@ -159,6 +159,14 @@ config CLK_CDCE9XX - Enable the clock synthesizer driver for CDCE913/925/937/949 - series of chips. - -+config CLK_SCMI -+ bool "Enable SCMI clock driver" -+ depends on SCMI_FIRMWARE -+ help -+ Enable this option if you want to support clock devices exposed -+ by a SCMI agent based on SCMI clock protocol communication -+ with a SCMI server. -+ - source "drivers/clk/analogbits/Kconfig" - source "drivers/clk/at91/Kconfig" - source "drivers/clk/exynos/Kconfig" -diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile -index cda4b4b605..d1e295ac7c 100644 ---- a/drivers/clk/Makefile -+++ b/drivers/clk/Makefile -@@ -32,6 +32,7 @@ obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o - obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o - obj-$(CONFIG_CLK_OWL) += owl/ - obj-$(CONFIG_CLK_RENESAS) += renesas/ -+obj-$(CONFIG_CLK_SCMI) += clk_scmi.o - obj-$(CONFIG_CLK_SIFIVE) += sifive/ - obj-$(CONFIG_ARCH_SUNXI) += sunxi/ - obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o -diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c -new file mode 100644 -index 0000000000..93a4819501 ---- /dev/null -+++ b/drivers/clk/clk_scmi.c -@@ -0,0 +1,99 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2019-2020 Linaro Limited -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static int scmi_clk_gate(struct clk *clk, int enable) -+{ -+ struct scmi_clk_state_in in = { -+ .clock_id = clk->id, -+ .attributes = enable, -+ }; -+ struct scmi_clk_state_out out; -+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK, -+ SCMI_CLOCK_CONFIG_SET, -+ in, out); -+ int ret; -+ -+ ret = devm_scmi_process_msg(clk->dev->parent, &msg); -+ if (ret) -+ return ret; -+ -+ return scmi_to_linux_errno(out.status); -+} -+ -+static int scmi_clk_enable(struct clk *clk) -+{ -+ return scmi_clk_gate(clk, 1); -+} -+ -+static int scmi_clk_disable(struct clk *clk) -+{ -+ return scmi_clk_gate(clk, 0); -+} -+ -+static ulong scmi_clk_get_rate(struct clk *clk) -+{ -+ struct scmi_clk_rate_get_in in = { -+ .clock_id = clk->id, -+ }; -+ struct scmi_clk_rate_get_out out; -+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK, -+ SCMI_CLOCK_RATE_GET, -+ in, out); -+ int ret; -+ -+ ret = devm_scmi_process_msg(clk->dev->parent, &msg); -+ if (ret < 0) -+ return ret; -+ -+ ret = scmi_to_linux_errno(out.status); -+ if (ret < 0) -+ return ret; -+ -+ return (ulong)(((u64)out.rate_msb << 32) | out.rate_lsb); -+} -+ -+static ulong scmi_clk_set_rate(struct clk *clk, ulong rate) -+{ -+ struct scmi_clk_rate_set_in in = { -+ .clock_id = clk->id, -+ .flags = SCMI_CLK_RATE_ROUND_CLOSEST, -+ .rate_lsb = (u32)rate, -+ .rate_msb = (u32)((u64)rate >> 32), -+ }; -+ struct scmi_clk_rate_set_out out; -+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK, -+ SCMI_CLOCK_RATE_SET, -+ in, out); -+ int ret; -+ -+ ret = devm_scmi_process_msg(clk->dev->parent, &msg); -+ if (ret < 0) -+ return ret; -+ -+ ret = scmi_to_linux_errno(out.status); -+ if (ret < 0) -+ return ret; -+ -+ return scmi_clk_get_rate(clk); -+} -+ -+static const struct clk_ops scmi_clk_ops = { -+ .enable = scmi_clk_enable, -+ .disable = scmi_clk_disable, -+ .get_rate = scmi_clk_get_rate, -+ .set_rate = scmi_clk_set_rate, -+}; -+ -+U_BOOT_DRIVER(scmi_clock) = { -+ .name = "scmi_clk", -+ .id = UCLASS_CLK, -+ .ops = &scmi_clk_ops, -+}; -diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c -index c8840b9e5f..efa402da52 100644 ---- a/drivers/clk/clk_stm32mp1.c -+++ b/drivers/clk/clk_stm32mp1.c -@@ -246,7 +246,7 @@ DECLARE_GLOBAL_DATA_PTR; - enum stm32mp1_parent_id { - /* - * _HSI, _HSE, _CSI, _LSI, _LSE should not be moved -- * they are used as index in osc[] as entry point -+ * they are used as index in osc_clk[] as clock reference - */ - _HSI, - _HSE, -@@ -426,8 +426,7 @@ struct stm32mp1_clk_data { - struct stm32mp1_clk_priv { - fdt_addr_t base; - const struct stm32mp1_clk_data *data; -- ulong osc[NB_OSC]; -- struct udevice *osc_dev[NB_OSC]; -+ struct clk osc_clk[NB_OSC]; - }; - - #define STM32MP1_CLK(off, b, idx, s) \ -@@ -546,6 +545,7 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { - STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 16, USBPHY_K, _USBPHY_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), - STM32MP1_CLK_SET_CLR(RCC_MP_APB5ENSETR, 20, STGEN_K, _STGEN_SEL), - -@@ -785,7 +785,7 @@ static ulong stm32mp1_clk_get_fixed(struct stm32mp1_clk_priv *priv, int idx) - return 0; - } - -- return priv->osc[idx]; -+ return clk_get_rate(&priv->osc_clk[idx]); - } - - static int stm32mp1_clk_get_id(struct stm32mp1_clk_priv *priv, unsigned long id) -@@ -1546,7 +1546,7 @@ static int stm32mp1_hsidiv(fdt_addr_t rcc, ulong hsifreq) - break; - - if (hsidiv == 4) { -- pr_err("clk-hsi frequency invalid"); -+ pr_err("hsi frequency invalid"); - return -1; - } - -@@ -1953,13 +1953,13 @@ static int stm32mp1_clktree(struct udevice *dev) - * switch ON oscillator found in device-tree, - * HSI already ON after bootrom - */ -- if (priv->osc[_LSI]) -+ if (clk_valid(&priv->osc_clk[_LSI])) - stm32mp1_lsi_set(rcc, 1); - -- if (priv->osc[_LSE]) { -+ if (clk_valid(&priv->osc_clk[_LSE])) { - int bypass, digbyp; - u32 lsedrv; -- struct udevice *dev = priv->osc_dev[_LSE]; -+ struct udevice *dev = priv->osc_clk[_LSE].dev; - - bypass = dev_read_bool(dev, "st,bypass"); - digbyp = dev_read_bool(dev, "st,digbypass"); -@@ -1970,9 +1970,9 @@ static int stm32mp1_clktree(struct udevice *dev) - stm32mp1_lse_enable(rcc, bypass, digbyp, lsedrv); - } - -- if (priv->osc[_HSE]) { -+ if (clk_valid(&priv->osc_clk[_HSE])) { - int bypass, digbyp, css; -- struct udevice *dev = priv->osc_dev[_HSE]; -+ struct udevice *dev = priv->osc_clk[_HSE].dev; - - bypass = dev_read_bool(dev, "st,bypass"); - digbyp = dev_read_bool(dev, "st,digbypass"); -@@ -1997,8 +1997,8 @@ static int stm32mp1_clktree(struct udevice *dev) - - /* configure HSIDIV */ - debug("configure HSIDIV\n"); -- if (priv->osc[_HSI]) { -- stm32mp1_hsidiv(rcc, priv->osc[_HSI]); -+ if (clk_valid(&priv->osc_clk[_HSI])) { -+ stm32mp1_hsidiv(rcc, clk_get_rate(&priv->osc_clk[_HSI])); - stgen_config(priv); - } - -@@ -2044,7 +2044,7 @@ static int stm32mp1_clktree(struct udevice *dev) - } - - /* wait LSE ready before to use it */ -- if (priv->osc[_LSE]) -+ if (clk_valid(&priv->osc_clk[_LSE])) - stm32mp1_lse_wait(rcc); - - /* configure with expected clock source */ -@@ -2083,7 +2083,7 @@ static int stm32mp1_clktree(struct udevice *dev) - - debug("oscillator off\n"); - /* switch OFF HSI if not found in device-tree */ -- if (!priv->osc[_HSI]) -+ if (!clk_valid(&priv->osc_clk[_HSI])) - stm32mp1_hsi_set(rcc, 0); - - /* Software Self-Refresh mode (SSR) during DDR initilialization */ -@@ -2181,40 +2181,25 @@ static ulong stm32mp1_clk_set_rate(struct clk *clk, unsigned long clk_rate) - return -EINVAL; - } - --static void stm32mp1_osc_clk_init(const char *name, -- struct stm32mp1_clk_priv *priv, -- int index) --{ -- struct clk clk; -- struct udevice *dev = NULL; -- -- priv->osc[index] = 0; -- clk.id = 0; -- if (!uclass_get_device_by_name(UCLASS_CLK, name, &dev)) { -- if (clk_request(dev, &clk)) -- pr_err("%s request", name); -- else -- priv->osc[index] = clk_get_rate(&clk); -- } -- priv->osc_dev[index] = dev; --} -- - static void stm32mp1_osc_init(struct udevice *dev) - { - struct stm32mp1_clk_priv *priv = dev_get_priv(dev); - int i; - const char *name[NB_OSC] = { -- [_LSI] = "clk-lsi", -- [_LSE] = "clk-lse", -- [_HSI] = "clk-hsi", -- [_HSE] = "clk-hse", -- [_CSI] = "clk-csi", -+ [_LSI] = "lsi", -+ [_LSE] = "lse", -+ [_HSI] = "hsi", -+ [_HSE] = "hse", -+ [_CSI] = "csi", - [_I2S_CKIN] = "i2s_ckin", - }; - - for (i = 0; i < NB_OSC; i++) { -- stm32mp1_osc_clk_init(name[i], priv, i); -- debug("%d: %s => %x\n", i, name[i], (u32)priv->osc[i]); -+ if (clk_get_by_name(dev, name[i], &priv->osc_clk[i])) -+ dev_dbg(dev, "No source clock \"%s\"", name[i]); -+ else -+ dev_dbg(dev, "%s clock rate: %luHz\n", -+ name[i], clk_get_rate(&priv->osc_clk[i])); - } - } - -diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c -index d02d8d33fe..2b848cc870 100644 ---- a/drivers/core/ofnode.c -+++ b/drivers/core/ofnode.c -@@ -226,6 +226,16 @@ int ofnode_read_u32_array(ofnode node, const char *propname, - } - } - -+bool ofnode_is_enabled(ofnode node) -+{ -+ if (ofnode_is_np(node)) { -+ return of_device_is_available(ofnode_to_np(node)); -+ } else { -+ return fdtdec_get_is_enabled(gd->fdt_blob, -+ ofnode_to_offset(node)); -+ } -+} -+ - ofnode ofnode_first_subnode(ofnode node) - { - assert(ofnode_valid(node)); -diff --git a/drivers/dfu/dfu_mtd.c b/drivers/dfu/dfu_mtd.c -index 36cd4e945b..8c6c342a75 100644 ---- a/drivers/dfu/dfu_mtd.c -+++ b/drivers/dfu/dfu_mtd.c -@@ -190,7 +190,7 @@ static int dfu_flush_medium_mtd(struct dfu_entity *dfu) - int ret; - - /* in case of ubi partition, erase rest of the partition */ -- if (dfu->data.nand.ubi) { -+ if (dfu->data.mtd.ubi) { - struct erase_info erase_op = {}; - - erase_op.mtd = dfu->data.mtd.info; -@@ -228,7 +228,7 @@ static unsigned int dfu_polltimeout_mtd(struct dfu_entity *dfu) - * ubi partition, as sectors which are not used need - * to be erased - */ -- if (dfu->data.nand.ubi) -+ if (dfu->data.mtd.ubi) - return DFU_MANIFEST_POLL_TIMEOUT; - - return DFU_DEFAULT_POLL_TIMEOUT; -@@ -238,7 +238,6 @@ int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char *s) - { - char *st; - struct mtd_info *mtd; -- bool has_pages; - int ret, part; - - mtd = get_mtd_device_nm(devstr); -@@ -248,9 +247,7 @@ int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char *s) - - dfu->dev_type = DFU_DEV_MTD; - dfu->data.mtd.info = mtd; -- -- has_pages = mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH; -- dfu->max_buf_size = has_pages ? mtd->erasesize : 0; -+ dfu->max_buf_size = mtd->erasesize; - - st = strsep(&s, " "); - if (!strcmp(st, "raw")) { -diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig -index b70a206355..ef958b3a7a 100644 ---- a/drivers/firmware/Kconfig -+++ b/drivers/firmware/Kconfig -@@ -36,3 +36,5 @@ config ZYNQMP_FIRMWARE - various platform management services. - Say yes to enable ZynqMP firmware interface driver. - If in doubt, say N. -+ -+source "drivers/firmware/scmi/Kconfig" -diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile -index a0c250a473..7ce83d72bd 100644 ---- a/drivers/firmware/Makefile -+++ b/drivers/firmware/Makefile -@@ -3,3 +3,4 @@ obj-$(CONFIG_$(SPL_)ARM_PSCI_FW) += psci.o - obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o - obj-$(CONFIG_SANDBOX) += firmware-sandbox.o - obj-$(CONFIG_ZYNQMP_FIRMWARE) += firmware-zynqmp.o -+obj-$(CONFIG_SCMI_FIRMWARE) += scmi/ -diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig -new file mode 100644 -index 0000000000..c3a109beac ---- /dev/null -+++ b/drivers/firmware/scmi/Kconfig -@@ -0,0 +1,19 @@ -+config SCMI_FIRMWARE -+ bool "Enable SCMI support" -+ select FIRMWARE -+ select OF_TRANSLATE -+ depends on SANDBOX || DM_MAILBOX || ARM_SMCCC -+ help -+ System Control and Management Interface (SCMI) is a communication -+ protocol that defines standard interfaces for power, performance -+ and system management. The SCMI specification is available at -+ https://developer.arm.com/architectures/system-architectures/software-standards/scmi -+ -+ An SCMI agent communicates with a related SCMI server firmware -+ located in another sub-system, as a companion micro controller -+ or a companion host in the CPU system. -+ -+ Communications between agent (client) and the SCMI server are -+ based on message exchange. Messages can be exchange over tranport -+ channels as a mailbox device or an Arm SMCCC service with some -+ piece of identified shared memory. -diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile -new file mode 100644 -index 0000000000..e1e0224066 ---- /dev/null -+++ b/drivers/firmware/scmi/Makefile -@@ -0,0 +1,5 @@ -+obj-y += scmi_agent-uclass.o -+obj-y += smt.o -+obj-$(CONFIG_ARM_SMCCC) += smccc_agent.o -+obj-$(CONFIG_DM_MAILBOX) += mailbox_agent.o -+obj-$(CONFIG_SANDBOX) += sandbox-scmi_agent.o sandbox-scmi_devices.o -diff --git a/drivers/firmware/scmi/mailbox_agent.c b/drivers/firmware/scmi/mailbox_agent.c -new file mode 100644 -index 0000000000..7d9fb3622e ---- /dev/null -+++ b/drivers/firmware/scmi/mailbox_agent.c -@@ -0,0 +1,102 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2020 Linaro Limited. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "smt.h" -+ -+#define TIMEOUT_US_10MS 10000 -+ -+/** -+ * struct scmi_mbox_channel - Description of an SCMI mailbox transport -+ * @smt: Shared memory buffer -+ * @mbox: Mailbox channel description -+ * @timeout_us: Timeout in microseconds for the mailbox transfer -+ */ -+struct scmi_mbox_channel { -+ struct scmi_smt smt; -+ struct mbox_chan mbox; -+ ulong timeout_us; -+}; -+ -+static int scmi_mbox_process_msg(struct udevice *dev, struct scmi_msg *msg) -+{ -+ struct scmi_mbox_channel *chan = dev_get_priv(dev); -+ int ret; -+ -+ ret = scmi_write_msg_to_smt(dev, &chan->smt, msg); -+ if (ret) -+ return ret; -+ -+ /* Give shm addr to mbox in case it is meaningful */ -+ ret = mbox_send(&chan->mbox, chan->smt.buf); -+ if (ret) { -+ dev_err(dev, "Message send failed: %d\n", ret); -+ goto out; -+ } -+ -+ /* Receive the response */ -+ ret = mbox_recv(&chan->mbox, chan->smt.buf, chan->timeout_us); -+ if (ret) { -+ dev_err(dev, "Response failed: %d, abort\n", ret); -+ goto out; -+ } -+ -+ ret = scmi_read_resp_from_smt(dev, &chan->smt, msg); -+ -+out: -+ scmi_clear_smt_channel(&chan->smt); -+ -+ return ret; -+} -+ -+int scmi_mbox_probe(struct udevice *dev) -+{ -+ struct scmi_mbox_channel *chan = dev_get_priv(dev); -+ int ret; -+ -+ chan->timeout_us = TIMEOUT_US_10MS; -+ -+ ret = mbox_get_by_index(dev, 0, &chan->mbox); -+ if (ret) { -+ dev_err(dev, "Failed to find mailbox: %d\n", ret); -+ goto out; -+ } -+ -+ ret = scmi_dt_get_smt_buffer(dev, &chan->smt); -+ if (ret) -+ dev_err(dev, "Failed to get shm resources: %d\n", ret); -+ -+out: -+ if (ret) -+ devm_kfree(dev, chan); -+ -+ return ret; -+} -+ -+static const struct udevice_id scmi_mbox_ids[] = { -+ { .compatible = "arm,scmi" }, -+ { } -+}; -+ -+static const struct scmi_agent_ops scmi_mbox_ops = { -+ .process_msg = scmi_mbox_process_msg, -+}; -+ -+U_BOOT_DRIVER(scmi_mbox) = { -+ .name = "scmi-over-mailbox", -+ .id = UCLASS_SCMI_AGENT, -+ .of_match = scmi_mbox_ids, -+ .priv_auto_alloc_size = sizeof(struct scmi_mbox_channel), -+ .probe = scmi_mbox_probe, -+ .ops = &scmi_mbox_ops, -+}; -diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c b/drivers/firmware/scmi/sandbox-scmi_agent.c -new file mode 100644 -index 0000000000..5b6a4232af ---- /dev/null -+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c -@@ -0,0 +1,410 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2020, Linaro Limited -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * The sandbox SCMI agent driver simulates to some extend a SCMI message -+ * processing. It simulates few of the SCMI services for some of the -+ * SCMI protocols embedded in U-Boot. Currently: -+ * - SCMI clock protocol: emulate 2 agents each exposing few clocks -+ * - SCMI reset protocol: emulate 1 agents each exposing a reset -+ * -+ * Agent #0 simulates 2 clocks and 1 reset domain. -+ * See IDs in scmi0_clk[]/scmi0_reset[] and "sandbox-scmi-agent@0" in test.dts. -+ * -+ * Agent #1 simulates 1 clock. -+ * See IDs in scmi1_clk[] and "sandbox-scmi-agent@1" in test.dts. -+ * -+ * All clocks are default disabled and reset levels down. -+ * -+ * This Driver exports sandbox_scmi_service_ct() for the test sequence to -+ * get the state of the simulated services (clock state, rate, ...) and -+ * check back-end device state reflects the request send through the -+ * various uclass devices, as clocks and reset controllers. -+ */ -+ -+#define SANDBOX_SCMI_AGENT_COUNT 2 -+ -+static struct sandbox_scmi_clk scmi0_clk[] = { -+ { .id = 7, .rate = 1000 }, -+ { .id = 3, .rate = 333 }, -+}; -+ -+static struct sandbox_scmi_reset scmi0_reset[] = { -+ { .id = 3 }, -+}; -+ -+static struct sandbox_scmi_clk scmi1_clk[] = { -+ { .id = 1, .rate = 44 }, -+}; -+ -+/* The list saves to simulted end devices references for test purpose */ -+struct sandbox_scmi_agent *sandbox_scmi_agent_list[SANDBOX_SCMI_AGENT_COUNT]; -+ -+static struct sandbox_scmi_service sandbox_scmi_service_state = { -+ .agent = sandbox_scmi_agent_list, -+ .agent_count = SANDBOX_SCMI_AGENT_COUNT, -+}; -+ -+struct sandbox_scmi_service *sandbox_scmi_service_ctx(void) -+{ -+ return &sandbox_scmi_service_state; -+} -+ -+static void debug_print_agent_state(struct udevice *dev, char *str) -+{ -+ struct sandbox_scmi_agent *agent = dev_get_priv(dev); -+ -+ dev_dbg(dev, "Dump sandbox_scmi_agent %u: %s\n", agent->idx, str); -+ dev_dbg(dev, " scmi%u_clk (%zu): %d/%ld, %d/%ld, %d/%ld, ...\n", -+ agent->idx, -+ agent->clk_count, -+ agent->clk_count ? agent->clk[0].enabled : -1, -+ agent->clk_count ? agent->clk[0].rate : -1, -+ agent->clk_count > 1 ? agent->clk[1].enabled : -1, -+ agent->clk_count > 1 ? agent->clk[1].rate : -1, -+ agent->clk_count > 2 ? agent->clk[2].enabled : -1, -+ agent->clk_count > 2 ? agent->clk[2].rate : -1); -+ dev_dbg(dev, " scmi%u_reset (%zu): %d, %d, ...\n", -+ agent->idx, -+ agent->reset_count, -+ agent->reset_count ? agent->reset[0].asserted : -1, -+ agent->reset_count > 1 ? agent->reset[1].asserted : -1); -+}; -+ -+static struct sandbox_scmi_clk *get_scmi_clk_state(uint agent_id, uint clock_id) -+{ -+ struct sandbox_scmi_clk *target = NULL; -+ size_t target_count = 0; -+ size_t n; -+ -+ switch (agent_id) { -+ case 0: -+ target = scmi0_clk; -+ target_count = ARRAY_SIZE(scmi0_clk); -+ break; -+ case 1: -+ target = scmi1_clk; -+ target_count = ARRAY_SIZE(scmi1_clk); -+ break; -+ default: -+ return NULL; -+ } -+ -+ for (n = 0; n < target_count; n++) -+ if (target[n].id == clock_id) -+ return target + n; -+ -+ return NULL; -+} -+ -+static struct sandbox_scmi_reset *get_scmi_reset_state(uint agent_id, -+ uint reset_id) -+{ -+ size_t n; -+ -+ if (agent_id == 0) { -+ for (n = 0; n < ARRAY_SIZE(scmi0_reset); n++) -+ if (scmi0_reset[n].id == reset_id) -+ return scmi0_reset + n; -+ } -+ -+ return NULL; -+} -+ -+/* -+ * Sandbox SCMI agent ops -+ */ -+ -+static int sandbox_scmi_clock_rate_set(struct udevice *dev, -+ struct scmi_msg *msg) -+{ -+ struct sandbox_scmi_agent *agent = dev_get_priv(dev); -+ struct scmi_clk_rate_set_in *in = NULL; -+ struct scmi_clk_rate_set_out *out = NULL; -+ struct sandbox_scmi_clk *clk_state = NULL; -+ -+ if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) || -+ !msg->out_msg || msg->out_msg_sz < sizeof(*out)) -+ return -EINVAL; -+ -+ in = (struct scmi_clk_rate_set_in *)msg->in_msg; -+ out = (struct scmi_clk_rate_set_out *)msg->out_msg; -+ -+ clk_state = get_scmi_clk_state(agent->idx, in->clock_id); -+ if (!clk_state) { -+ dev_err(dev, "Unexpected clock ID %u\n", in->clock_id); -+ -+ out->status = SCMI_NOT_FOUND; -+ } else { -+ u64 rate = ((u64)in->rate_msb << 32) + in->rate_lsb; -+ -+ clk_state->rate = (ulong)rate; -+ -+ out->status = SCMI_SUCCESS; -+ } -+ -+ return 0; -+} -+ -+static int sandbox_scmi_clock_rate_get(struct udevice *dev, -+ struct scmi_msg *msg) -+{ -+ struct sandbox_scmi_agent *agent = dev_get_priv(dev); -+ struct scmi_clk_rate_get_in *in = NULL; -+ struct scmi_clk_rate_get_out *out = NULL; -+ struct sandbox_scmi_clk *clk_state = NULL; -+ -+ if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) || -+ !msg->out_msg || msg->out_msg_sz < sizeof(*out)) -+ return -EINVAL; -+ -+ in = (struct scmi_clk_rate_get_in *)msg->in_msg; -+ out = (struct scmi_clk_rate_get_out *)msg->out_msg; -+ -+ clk_state = get_scmi_clk_state(agent->idx, in->clock_id); -+ if (!clk_state) { -+ dev_err(dev, "Unexpected clock ID %u\n", in->clock_id); -+ -+ out->status = SCMI_NOT_FOUND; -+ } else { -+ out->rate_msb = (u32)((u64)clk_state->rate >> 32); -+ out->rate_lsb = (u32)clk_state->rate; -+ -+ out->status = SCMI_SUCCESS; -+ } -+ -+ return 0; -+} -+ -+static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg) -+{ -+ struct sandbox_scmi_agent *agent = dev_get_priv(dev); -+ struct scmi_clk_state_in *in = NULL; -+ struct scmi_clk_state_out *out = NULL; -+ struct sandbox_scmi_clk *clk_state = NULL; -+ -+ if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) || -+ !msg->out_msg || msg->out_msg_sz < sizeof(*out)) -+ return -EINVAL; -+ -+ in = (struct scmi_clk_state_in *)msg->in_msg; -+ out = (struct scmi_clk_state_out *)msg->out_msg; -+ -+ clk_state = get_scmi_clk_state(agent->idx, in->clock_id); -+ if (!clk_state) { -+ dev_err(dev, "Unexpected clock ID %u\n", in->clock_id); -+ -+ out->status = SCMI_NOT_FOUND; -+ } else if (in->attributes > 1) { -+ out->status = SCMI_PROTOCOL_ERROR; -+ } else { -+ clk_state->enabled = in->attributes; -+ -+ out->status = SCMI_SUCCESS; -+ } -+ -+ return 0; -+} -+ -+static int sandbox_scmi_rd_attribs(struct udevice *dev, struct scmi_msg *msg) -+{ -+ struct sandbox_scmi_agent *agent = dev_get_priv(dev); -+ struct scmi_rd_attr_in *in = NULL; -+ struct scmi_rd_attr_out *out = NULL; -+ struct sandbox_scmi_reset *reset_state = NULL; -+ -+ if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) || -+ !msg->out_msg || msg->out_msg_sz < sizeof(*out)) -+ return -EINVAL; -+ -+ in = (struct scmi_rd_attr_in *)msg->in_msg; -+ out = (struct scmi_rd_attr_out *)msg->out_msg; -+ -+ reset_state = get_scmi_reset_state(agent->idx, in->domain_id); -+ if (!reset_state) { -+ dev_err(dev, "Unexpected reset domain ID %u\n", in->domain_id); -+ -+ out->status = SCMI_NOT_FOUND; -+ } else { -+ memset(out, 0, sizeof(*out)); -+ snprintf(out->name, sizeof(out->name), "rd%u", in->domain_id); -+ -+ out->status = SCMI_SUCCESS; -+ } -+ -+ return 0; -+} -+ -+static int sandbox_scmi_rd_reset(struct udevice *dev, struct scmi_msg *msg) -+{ -+ struct sandbox_scmi_agent *agent = dev_get_priv(dev); -+ struct scmi_rd_reset_in *in = NULL; -+ struct scmi_rd_reset_out *out = NULL; -+ struct sandbox_scmi_reset *reset_state = NULL; -+ -+ if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) || -+ !msg->out_msg || msg->out_msg_sz < sizeof(*out)) -+ return -EINVAL; -+ -+ in = (struct scmi_rd_reset_in *)msg->in_msg; -+ out = (struct scmi_rd_reset_out *)msg->out_msg; -+ -+ reset_state = get_scmi_reset_state(agent->idx, in->domain_id); -+ if (!reset_state) { -+ dev_err(dev, "Unexpected reset domain ID %u\n", in->domain_id); -+ -+ out->status = SCMI_NOT_FOUND; -+ } else if (in->reset_state > 1) { -+ dev_err(dev, "Invalid reset domain input attribute value\n"); -+ -+ out->status = SCMI_INVALID_PARAMETERS; -+ } else { -+ if (in->flags & SCMI_RD_RESET_FLAG_CYCLE) { -+ if (in->flags & SCMI_RD_RESET_FLAG_ASYNC) { -+ out->status = SCMI_NOT_SUPPORTED; -+ } else { -+ /* Ends deasserted whatever current state */ -+ reset_state->asserted = false; -+ out->status = SCMI_SUCCESS; -+ } -+ } else { -+ reset_state->asserted = in->flags & -+ SCMI_RD_RESET_FLAG_ASSERT; -+ -+ out->status = SCMI_SUCCESS; -+ } -+ } -+ -+ return 0; -+} -+ -+static int sandbox_scmi_test_process_msg(struct udevice *dev, -+ struct scmi_msg *msg) -+{ -+ switch (msg->protocol_id) { -+ case SCMI_PROTOCOL_ID_CLOCK: -+ switch (msg->message_id) { -+ case SCMI_CLOCK_RATE_SET: -+ return sandbox_scmi_clock_rate_set(dev, msg); -+ case SCMI_CLOCK_RATE_GET: -+ return sandbox_scmi_clock_rate_get(dev, msg); -+ case SCMI_CLOCK_CONFIG_SET: -+ return sandbox_scmi_clock_gate(dev, msg); -+ default: -+ break; -+ } -+ break; -+ case SCMI_PROTOCOL_ID_RESET_DOMAIN: -+ switch (msg->message_id) { -+ case SCMI_RESET_DOMAIN_ATTRIBUTES: -+ return sandbox_scmi_rd_attribs(dev, msg); -+ case SCMI_RESET_DOMAIN_RESET: -+ return sandbox_scmi_rd_reset(dev, msg); -+ default: -+ break; -+ } -+ break; -+ case SCMI_PROTOCOL_ID_BASE: -+ case SCMI_PROTOCOL_ID_POWER_DOMAIN: -+ case SCMI_PROTOCOL_ID_SYSTEM: -+ case SCMI_PROTOCOL_ID_PERF: -+ case SCMI_PROTOCOL_ID_SENSOR: -+ *(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED; -+ return 0; -+ default: -+ break; -+ } -+ -+ dev_err(dev, "%s(%s): Unhandled protocol_id %#x/message_id %#x\n", -+ __func__, dev->name, msg->protocol_id, msg->message_id); -+ -+ if (msg->out_msg_sz < sizeof(u32)) -+ return -EINVAL; -+ -+ /* Intentionnaly report unhandled IDs through the SCMI return code */ -+ *(u32 *)msg->out_msg = SCMI_PROTOCOL_ERROR; -+ return 0; -+} -+ -+static int sandbox_scmi_test_remove(struct udevice *dev) -+{ -+ struct sandbox_scmi_agent *agent = dev_get_priv(dev); -+ -+ debug_print_agent_state(dev, "removed"); -+ -+ /* We only need to dereference the agent in the context */ -+ sandbox_scmi_service_ctx()->agent[agent->idx] = NULL; -+ -+ return 0; -+} -+ -+static int sandbox_scmi_test_probe(struct udevice *dev) -+{ -+ static const char basename[] = "sandbox-scmi-agent@"; -+ struct sandbox_scmi_agent *agent = dev_get_priv(dev); -+ const size_t basename_size = sizeof(basename) - 1; -+ -+ if (strncmp(basename, dev->name, basename_size)) -+ return -ENOENT; -+ -+ switch (dev->name[basename_size]) { -+ case '0': -+ *agent = (struct sandbox_scmi_agent){ -+ .idx = 0, -+ .clk = scmi0_clk, -+ .clk_count = ARRAY_SIZE(scmi0_clk), -+ .reset = scmi0_reset, -+ .reset_count = ARRAY_SIZE(scmi0_reset), -+ }; -+ break; -+ case '1': -+ *agent = (struct sandbox_scmi_agent){ -+ .idx = 1, -+ .clk = scmi1_clk, -+ .clk_count = ARRAY_SIZE(scmi1_clk), -+ }; -+ break; -+ default: -+ dev_err(dev, "%s(): Unexpected agent ID %s\n", -+ __func__, dev->name + basename_size); -+ return -ENOENT; -+ } -+ -+ debug_print_agent_state(dev, "probed"); -+ -+ /* Save reference for tests purpose */ -+ sandbox_scmi_service_ctx()->agent[agent->idx] = agent; -+ -+ return 0; -+}; -+ -+static const struct udevice_id sandbox_scmi_test_ids[] = { -+ { .compatible = "sandbox,scmi-agent" }, -+ { } -+}; -+ -+struct scmi_agent_ops sandbox_scmi_test_ops = { -+ .process_msg = sandbox_scmi_test_process_msg, -+}; -+ -+U_BOOT_DRIVER(sandbox_scmi_agent) = { -+ .name = "sandbox-scmi_agent", -+ .id = UCLASS_SCMI_AGENT, -+ .of_match = sandbox_scmi_test_ids, -+ .priv_auto_alloc_size = sizeof(struct sandbox_scmi_agent), -+ .probe = sandbox_scmi_test_probe, -+ .remove = sandbox_scmi_test_remove, -+ .ops = &sandbox_scmi_test_ops, -+}; -diff --git a/drivers/firmware/scmi/sandbox-scmi_devices.c b/drivers/firmware/scmi/sandbox-scmi_devices.c -new file mode 100644 -index 0000000000..c69967bf69 ---- /dev/null -+++ b/drivers/firmware/scmi/sandbox-scmi_devices.c -@@ -0,0 +1,113 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2020, Linaro Limited -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * Simulate to some extent a SCMI exchange. -+ * This drivers gets SCMI resources and offers API function to the -+ * SCMI test sequence manipulate the resources, currently clock -+ * and reset controllers. -+ */ -+ -+#define SCMI_TEST_DEVICES_CLK_COUNT 3 -+#define SCMI_TEST_DEVICES_RD_COUNT 1 -+ -+/* -+ * struct sandbox_scmi_device_priv - Storage for device handles used by test -+ * @clk: Array of clock instances used by tests -+ * @reset_clt: Array of the reset controller instances used by tests -+ * @devices: Resources exposed by sandbox_scmi_devices_ctx() -+ */ -+struct sandbox_scmi_device_priv { -+ struct clk clk[SCMI_TEST_DEVICES_CLK_COUNT]; -+ struct reset_ctl reset_ctl[SCMI_TEST_DEVICES_RD_COUNT]; -+ struct sandbox_scmi_devices devices; -+}; -+ -+struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(struct udevice *dev) -+{ -+ struct sandbox_scmi_device_priv *priv = dev_get_priv(dev); -+ -+ if (priv) -+ return &priv->devices; -+ -+ return NULL; -+} -+ -+static int sandbox_scmi_devices_remove(struct udevice *dev) -+{ -+ struct sandbox_scmi_devices *devices = sandbox_scmi_devices_ctx(dev); -+ int ret = 0; -+ size_t n; -+ -+ for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) { -+ int ret2 = reset_free(devices->reset + n); -+ -+ if (ret2 && !ret) -+ ret = ret2; -+ } -+ -+ return ret; -+} -+ -+static int sandbox_scmi_devices_probe(struct udevice *dev) -+{ -+ struct sandbox_scmi_device_priv *priv = dev_get_priv(dev); -+ int ret; -+ size_t n; -+ -+ priv->devices = (struct sandbox_scmi_devices){ -+ .clk = priv->clk, -+ .clk_count = SCMI_TEST_DEVICES_CLK_COUNT, -+ .reset = priv->reset_ctl, -+ .reset_count = SCMI_TEST_DEVICES_RD_COUNT, -+ }; -+ -+ for (n = 0; n < SCMI_TEST_DEVICES_CLK_COUNT; n++) { -+ ret = clk_get_by_index(dev, n, priv->devices.clk + n); -+ if (ret) { -+ dev_err(dev, "%s: Failed on clk %zu\n", __func__, n); -+ return ret; -+ } -+ } -+ -+ for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) { -+ ret = reset_get_by_index(dev, n, priv->devices.reset + n); -+ if (ret) { -+ dev_err(dev, "%s: Failed on reset %zu\n", __func__, n); -+ goto err_reset; -+ } -+ } -+ -+ return 0; -+ -+err_reset: -+ for (; n > 0; n--) -+ reset_free(priv->devices.reset + n - 1); -+ -+ return ret; -+} -+ -+static const struct udevice_id sandbox_scmi_devices_ids[] = { -+ { .compatible = "sandbox,scmi-devices" }, -+ { } -+}; -+ -+U_BOOT_DRIVER(sandbox_scmi_devices) = { -+ .name = "sandbox-scmi_devices", -+ .id = UCLASS_MISC, -+ .of_match = sandbox_scmi_devices_ids, -+ .priv_auto_alloc_size = sizeof(struct sandbox_scmi_device_priv), -+ .remove = sandbox_scmi_devices_remove, -+ .probe = sandbox_scmi_devices_probe, -+}; -diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c -new file mode 100644 -index 0000000000..77160b1999 ---- /dev/null -+++ b/drivers/firmware/scmi/scmi_agent-uclass.c -@@ -0,0 +1,119 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2020 Linaro Limited. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/** -+ * struct error_code - Helper structure for SCMI error code conversion -+ * @scmi: SCMI error code -+ * @errno: Related standard error number -+ */ -+struct error_code { -+ int scmi; -+ int errno; -+}; -+ -+static const struct error_code scmi_linux_errmap[] = { -+ { .scmi = SCMI_NOT_SUPPORTED, .errno = -EOPNOTSUPP, }, -+ { .scmi = SCMI_INVALID_PARAMETERS, .errno = -EINVAL, }, -+ { .scmi = SCMI_DENIED, .errno = -EACCES, }, -+ { .scmi = SCMI_NOT_FOUND, .errno = -ENOENT, }, -+ { .scmi = SCMI_OUT_OF_RANGE, .errno = -ERANGE, }, -+ { .scmi = SCMI_BUSY, .errno = -EBUSY, }, -+ { .scmi = SCMI_COMMS_ERROR, .errno = -ECOMM, }, -+ { .scmi = SCMI_GENERIC_ERROR, .errno = -EIO, }, -+ { .scmi = SCMI_HARDWARE_ERROR, .errno = -EREMOTEIO, }, -+ { .scmi = SCMI_PROTOCOL_ERROR, .errno = -EPROTO, }, -+}; -+ -+int scmi_to_linux_errno(s32 scmi_code) -+{ -+ int n; -+ -+ if (!scmi_code) -+ return 0; -+ -+ for (n = 0; n < ARRAY_SIZE(scmi_linux_errmap); n++) -+ if (scmi_code == scmi_linux_errmap[n].scmi) -+ return scmi_linux_errmap[1].errno; -+ -+ return -EPROTO; -+} -+ -+/* -+ * SCMI agent devices binds devices of various uclasses depeding on -+ * the FDT description. scmi_bind_protocol() is a generic bind sequence -+ * called by the uclass at bind stage, that is uclass post_bind. -+ */ -+static int scmi_bind_protocols(struct udevice *dev) -+{ -+ int ret = 0; -+ ofnode node; -+ -+ dev_for_each_subnode(node, dev) { -+ struct driver *drv = NULL; -+ u32 protocol_id; -+ -+ if (!ofnode_is_available(node)) -+ continue; -+ -+ if (ofnode_read_u32(node, "reg", &protocol_id)) -+ continue; -+ -+ switch (protocol_id) { -+ case SCMI_PROTOCOL_ID_CLOCK: -+ if (IS_ENABLED(CONFIG_CLK_SCMI)) -+ drv = DM_GET_DRIVER(scmi_clock); -+ break; -+ case SCMI_PROTOCOL_ID_RESET_DOMAIN: -+ if (IS_ENABLED(CONFIG_RESET_SCMI)) -+ drv = DM_GET_DRIVER(scmi_reset_domain); -+ break; -+ default: -+ break; -+ } -+ -+ if (!drv) { -+ dev_dbg(dev, "Ignore unsupported SCMI protocol %#x\n", -+ protocol_id); -+ continue; -+ } -+ -+ ret = device_bind_ofnode(dev, drv, ofnode_get_name(node), -+ NULL, node, NULL); -+ if (ret) -+ break; -+ } -+ -+ return ret; -+} -+ -+static const struct scmi_agent_ops *transport_dev_ops(struct udevice *dev) -+{ -+ return (const struct scmi_agent_ops *)dev->driver->ops; -+} -+ -+int devm_scmi_process_msg(struct udevice *dev, struct scmi_msg *msg) -+{ -+ const struct scmi_agent_ops *ops = transport_dev_ops(dev); -+ -+ if (ops->process_msg) -+ return ops->process_msg(dev, msg); -+ -+ return -EPROTONOSUPPORT; -+} -+ -+UCLASS_DRIVER(scmi_agent) = { -+ .id = UCLASS_SCMI_AGENT, -+ .name = "scmi_agent", -+ .post_bind = scmi_bind_protocols, -+}; -diff --git a/drivers/firmware/scmi/smccc_agent.c b/drivers/firmware/scmi/smccc_agent.c -new file mode 100644 -index 0000000000..85dbf9195e ---- /dev/null -+++ b/drivers/firmware/scmi/smccc_agent.c -@@ -0,0 +1,89 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2020 Linaro Limited. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "smt.h" -+ -+#define SMCCC_RET_NOT_SUPPORTED ((unsigned long)-1) -+ -+/** -+ * struct scmi_smccc_channel - Description of an SCMI SMCCC transport -+ * @func_id: SMCCC function ID used by the SCMI transport -+ * @smt: Shared memory buffer -+ */ -+struct scmi_smccc_channel { -+ ulong func_id; -+ struct scmi_smt smt; -+}; -+ -+static int scmi_smccc_process_msg(struct udevice *dev, struct scmi_msg *msg) -+{ -+ struct scmi_smccc_channel *chan = dev_get_priv(dev); -+ struct arm_smccc_res res; -+ int ret; -+ -+ ret = scmi_write_msg_to_smt(dev, &chan->smt, msg); -+ if (ret) -+ return ret; -+ -+ arm_smccc_smc(chan->func_id, 0, 0, 0, 0, 0, 0, 0, &res); -+ if (res.a0 == SMCCC_RET_NOT_SUPPORTED) -+ ret = -ENXIO; -+ else -+ ret = scmi_read_resp_from_smt(dev, &chan->smt, msg); -+ -+ scmi_clear_smt_channel(&chan->smt); -+ -+ return ret; -+} -+ -+static int scmi_smccc_probe(struct udevice *dev) -+{ -+ struct scmi_smccc_channel *chan = dev_get_priv(dev); -+ u32 func_id; -+ int ret; -+ -+ if (dev_read_u32(dev, "arm,smc-id", &func_id)) { -+ dev_err(dev, "Missing property func-id\n"); -+ return -EINVAL; -+ } -+ -+ chan->func_id = func_id; -+ -+ ret = scmi_dt_get_smt_buffer(dev, &chan->smt); -+ if (ret) { -+ dev_err(dev, "Failed to get smt resources: %d\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static const struct udevice_id scmi_smccc_ids[] = { -+ { .compatible = "arm,scmi-smc" }, -+ { } -+}; -+ -+static const struct scmi_agent_ops scmi_smccc_ops = { -+ .process_msg = scmi_smccc_process_msg, -+}; -+ -+U_BOOT_DRIVER(scmi_smccc) = { -+ .name = "scmi-over-smccc", -+ .id = UCLASS_SCMI_AGENT, -+ .of_match = scmi_smccc_ids, -+ .priv_auto_alloc_size = sizeof(struct scmi_smccc_channel), -+ .probe = scmi_smccc_probe, -+ .ops = &scmi_smccc_ops, -+}; -diff --git a/drivers/firmware/scmi/smt.c b/drivers/firmware/scmi/smt.c -new file mode 100644 -index 0000000000..ce8fe49939 ---- /dev/null -+++ b/drivers/firmware/scmi/smt.c -@@ -0,0 +1,139 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (C) 2019-2020 Linaro Limited. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "smt.h" -+ -+/** -+ * Get shared memory configuration defined by the referred DT phandle -+ * Return with a errno compliant value. -+ */ -+int scmi_dt_get_smt_buffer(struct udevice *dev, struct scmi_smt *smt) -+{ -+ int ret; -+ struct ofnode_phandle_args args; -+ struct resource resource; -+ fdt32_t faddr; -+ phys_addr_t paddr; -+ -+ ret = dev_read_phandle_with_args(dev, "shmem", NULL, 0, 0, &args); -+ if (ret) -+ return ret; -+ -+ ret = ofnode_read_resource(args.node, 0, &resource); -+ if (ret) -+ return ret; -+ -+ faddr = cpu_to_fdt32(resource.start); -+ paddr = ofnode_translate_address(args.node, &faddr); -+ -+ smt->size = resource_size(&resource); -+ if (smt->size < sizeof(struct scmi_smt_header)) { -+ dev_err(dev, "Shared memory buffer too small\n"); -+ return -EINVAL; -+ } -+ -+ smt->buf = devm_ioremap(dev, paddr, smt->size); -+ if (!smt->buf) -+ return -ENOMEM; -+ -+#ifdef CONFIG_ARM -+ if (dcache_status()) -+ mmu_set_region_dcache_behaviour((uintptr_t)smt->buf, -+ smt->size, DCACHE_OFF); -+#endif -+ -+ return 0; -+} -+ -+/** -+ * Write SCMI message @msg into a SMT shared buffer @smt. -+ * Return 0 on success and with a negative errno in case of error. -+ */ -+int scmi_write_msg_to_smt(struct udevice *dev, struct scmi_smt *smt, -+ struct scmi_msg *msg) -+{ -+ struct scmi_smt_header *hdr = (void *)smt->buf; -+ -+ if ((!msg->in_msg && msg->in_msg_sz) || -+ (!msg->out_msg && msg->out_msg_sz)) -+ return -EINVAL; -+ -+ if (!(hdr->channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE)) { -+ dev_dbg(dev, "Channel busy\n"); -+ return -EBUSY; -+ } -+ -+ if (smt->size < (sizeof(*hdr) + msg->in_msg_sz) || -+ smt->size < (sizeof(*hdr) + msg->out_msg_sz)) { -+ dev_dbg(dev, "Buffer too small\n"); -+ return -ETOOSMALL; -+ } -+ -+ /* Load message in shared memory */ -+ hdr->channel_status &= ~SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE; -+ hdr->length = msg->in_msg_sz + sizeof(hdr->msg_header); -+ hdr->msg_header = SMT_HEADER_TOKEN(0) | -+ SMT_HEADER_MESSAGE_TYPE(0) | -+ SMT_HEADER_PROTOCOL_ID(msg->protocol_id) | -+ SMT_HEADER_MESSAGE_ID(msg->message_id); -+ -+ memcpy_toio(hdr->msg_payload, msg->in_msg, msg->in_msg_sz); -+ -+ return 0; -+} -+ -+/** -+ * Read SCMI message from a SMT shared buffer @smt and copy it into @msg. -+ * Return 0 on success and with a negative errno in case of error. -+ */ -+int scmi_read_resp_from_smt(struct udevice *dev, struct scmi_smt *smt, -+ struct scmi_msg *msg) -+{ -+ struct scmi_smt_header *hdr = (void *)smt->buf; -+ -+ if (!(hdr->channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE)) { -+ dev_err(dev, "Channel unexpectedly busy\n"); -+ return -EBUSY; -+ } -+ -+ if (hdr->channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR) { -+ dev_err(dev, "Channel error reported, reset channel\n"); -+ return -ECOMM; -+ } -+ -+ if (hdr->length > msg->out_msg_sz + sizeof(hdr->msg_header)) { -+ dev_err(dev, "Buffer to small\n"); -+ return -ETOOSMALL; -+ } -+ -+ /* Get the data */ -+ msg->out_msg_sz = hdr->length - sizeof(hdr->msg_header); -+ memcpy_fromio(msg->out_msg, hdr->msg_payload, msg->out_msg_sz); -+ -+ return 0; -+} -+ -+/** -+ * Clear SMT flags in shared buffer to allow further message exchange -+ */ -+void scmi_clear_smt_channel(struct scmi_smt *smt) -+{ -+ struct scmi_smt_header *hdr = (void *)smt->buf; -+ -+ hdr->channel_status &= ~SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR; -+} -diff --git a/drivers/firmware/scmi/smt.h b/drivers/firmware/scmi/smt.h -new file mode 100644 -index 0000000000..a8c0987bd3 ---- /dev/null -+++ b/drivers/firmware/scmi/smt.h -@@ -0,0 +1,86 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (C) 2019-2020 Linaro Limited. -+ */ -+#ifndef SCMI_SMT_H -+#define SCMI_SMT_H -+ -+#include -+ -+/** -+ * struct scmi_smt_header - Description of the shared memory message buffer -+ * -+ * SMT stands for Shared Memory based Transport. -+ * SMT uses 28 byte header prior message payload to handle the state of -+ * the communication channel realized by the shared memory area and -+ * to define SCMI protocol information the payload relates to. -+ */ -+struct scmi_smt_header { -+ __le32 reserved; -+ __le32 channel_status; -+#define SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR BIT(1) -+#define SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE BIT(0) -+ __le32 reserved1[2]; -+ __le32 flags; -+#define SCMI_SHMEM_FLAG_INTR_ENABLED BIT(0) -+ __le32 length; -+ __le32 msg_header; -+ u8 msg_payload[0]; -+}; -+ -+#define SMT_HEADER_TOKEN(token) (((token) << 18) & GENMASK(31, 18)) -+#define SMT_HEADER_PROTOCOL_ID(proto) (((proto) << 10) & GENMASK(17, 10)) -+#define SMT_HEADER_MESSAGE_TYPE(type) (((type) << 18) & GENMASK(9, 8)) -+#define SMT_HEADER_MESSAGE_ID(id) ((id) & GENMASK(7, 0)) -+ -+/** -+ * struct scmi_smt - Description of a SMT memory buffer -+ * @buf: Shared memory base address -+ * @size: Shared memory byte size -+ */ -+struct scmi_smt { -+ u8 *buf; -+ size_t size; -+}; -+ -+static inline bool scmi_smt_channel_is_free(struct scmi_smt *smt) -+{ -+ struct scmi_smt_header *hdr = (void *)smt->buf; -+ -+ return hdr->channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE; -+} -+ -+static inline bool scmi_smt_channel_reports_error(struct scmi_smt *smt) -+{ -+ struct scmi_smt_header *hdr = (void *)smt->buf; -+ -+ return hdr->channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR; -+} -+ -+static inline void scmi_smt_get_channel(struct scmi_smt *smt) -+{ -+ struct scmi_smt_header *hdr = (void *)smt->buf; -+ -+ hdr->channel_status &= ~SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE; -+} -+ -+static inline void scmi_smt_put_channel(struct scmi_smt *smt) -+{ -+ struct scmi_smt_header *hdr = (void *)smt->buf; -+ -+ hdr->channel_status |= SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE; -+ hdr->channel_status &= ~SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR; -+} -+ -+int scmi_dt_get_smt_buffer(struct udevice *dev, struct scmi_smt *smt); -+ -+int scmi_write_msg_to_smt(struct udevice *dev, struct scmi_smt *smt, -+ struct scmi_msg *msg); -+ -+int scmi_read_resp_from_smt(struct udevice *dev, struct scmi_smt *smt, -+ struct scmi_msg *msg); -+ -+void scmi_clear_smt_channel(struct scmi_smt *smt); -+ -+#endif /* SCMI_SMT_H */ -diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c -index 5bff27f75b..5597247164 100644 ---- a/drivers/gpio/stm32_gpio.c -+++ b/drivers/gpio/stm32_gpio.c -@@ -210,11 +210,11 @@ static int stm32_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, - - } else if (flags & GPIOD_IS_IN) { - stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN); -- if (flags & GPIOD_PULL_UP) -- stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_UP); -- else if (flags & GPIOD_PULL_DOWN) -- stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_DOWN); - } -+ if (flags & GPIOD_PULL_UP) -+ stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_UP); -+ else if (flags & GPIOD_PULL_DOWN) -+ stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_DOWN); - - return 0; - } -@@ -241,16 +241,16 @@ static int stm32_gpio_get_dir_flags(struct udevice *dev, unsigned int offset, - break; - case STM32_GPIO_MODE_IN: - dir_flags |= GPIOD_IS_IN; -- switch (stm32_gpio_get_pupd(regs, idx)) { -- case STM32_GPIO_PUPD_UP: -- dir_flags |= GPIOD_PULL_UP; -- break; -- case STM32_GPIO_PUPD_DOWN: -- dir_flags |= GPIOD_PULL_DOWN; -- break; -- default: -- break; -- } -+ break; -+ default: -+ break; -+ } -+ switch (stm32_gpio_get_pupd(regs, idx)) { -+ case STM32_GPIO_PUPD_UP: -+ dir_flags |= GPIOD_PULL_UP; -+ break; -+ case STM32_GPIO_PUPD_DOWN: -+ dir_flags |= GPIOD_PULL_DOWN; - break; - default: - break; -diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c -index 6fbd24ba74..ef7f5f07d5 100644 ---- a/drivers/mtd/nand/core.c -+++ b/drivers/mtd/nand/core.c -@@ -10,6 +10,7 @@ - #define pr_fmt(fmt) "nand: " fmt - - #include -+#include - #ifndef __UBOOT__ - #include - #include -@@ -164,6 +165,7 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo) - nanddev_offs_to_pos(nand, einfo->addr, &pos); - nanddev_offs_to_pos(nand, einfo->addr + einfo->len - 1, &last); - while (nanddev_pos_cmp(&pos, &last) <= 0) { -+ WATCHDOG_RESET(); - ret = nanddev_erase(nand, &pos); - if (ret) { - einfo->fail_addr = nanddev_pos_to_offs(nand, &pos); -diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c -index 93371fdde0..dbf2db6d00 100644 ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -578,6 +579,7 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from, - #endif - - nanddev_io_for_each_page(nand, from, ops, &iter) { -+ WATCHDOG_RESET(); - ret = spinand_select_target(spinand, iter.req.pos.target); - if (ret) - break; -@@ -629,6 +631,7 @@ static int spinand_mtd_write(struct mtd_info *mtd, loff_t to, - #endif - - nanddev_io_for_each_page(nand, to, ops, &iter) { -+ WATCHDOG_RESET(); - ret = spinand_select_target(spinand, iter.req.pos.target); - if (ret) - break; -diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c -index 0113e70037..81de0de0c5 100644 ---- a/drivers/mtd/spi/spi-nor-core.c -+++ b/drivers/mtd/spi/spi-nor-core.c -@@ -11,6 +11,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -565,6 +566,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) - len = instr->len; - - while (len) { -+ WATCHDOG_RESET(); - #ifdef CONFIG_SPI_FLASH_BAR - ret = write_bar(nor, addr); - if (ret < 0) -@@ -1249,6 +1251,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, - for (i = 0; i < len; ) { - ssize_t written; - loff_t addr = to + i; -+ WATCHDOG_RESET(); - - /* - * If page_size is a power of two, the offset can be quickly -diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c -index c6d3048602..d4a82f73f4 100644 ---- a/drivers/phy/phy-stm32-usbphyc.c -+++ b/drivers/phy/phy-stm32-usbphyc.c -@@ -59,6 +59,7 @@ struct stm32_usbphyc { - struct udevice *vdda1v8; - struct stm32_usbphyc_phy { - struct udevice *vdd; -+ struct udevice *vbus; - bool init; - bool powered; - } phys[MAX_PHYS]; -@@ -244,6 +245,11 @@ static int stm32_usbphyc_phy_power_on(struct phy *phy) - if (ret) - return ret; - } -+ if (usbphyc_phy->vbus) { -+ ret = regulator_set_enable(usbphyc_phy->vbus, true); -+ if (ret) -+ return ret; -+ } - - usbphyc_phy->powered = true; - -@@ -262,6 +268,11 @@ static int stm32_usbphyc_phy_power_off(struct phy *phy) - if (stm32_usbphyc_is_powered(usbphyc)) - return 0; - -+ if (usbphyc_phy->vbus) { -+ ret = regulator_set_enable(usbphyc_phy->vbus, false); -+ if (ret) -+ return ret; -+ } - if (usbphyc_phy->vdd) { - ret = regulator_set_enable_if_allowed(usbphyc_phy->vdd, false); - if (ret) -@@ -271,7 +282,7 @@ static int stm32_usbphyc_phy_power_off(struct phy *phy) - return 0; - } - --static int stm32_usbphyc_get_regulator(struct udevice *dev, ofnode node, -+static int stm32_usbphyc_get_regulator(ofnode node, - char *supply_name, - struct udevice **regulator) - { -@@ -281,19 +292,14 @@ static int stm32_usbphyc_get_regulator(struct udevice *dev, ofnode node, - ret = ofnode_parse_phandle_with_args(node, supply_name, - NULL, 0, 0, - ®ulator_phandle); -- if (ret) { -- dev_err(dev, "Can't find %s property (%d)\n", supply_name, ret); -+ if (ret) - return ret; -- } - - ret = uclass_get_device_by_ofnode(UCLASS_REGULATOR, - regulator_phandle.node, - regulator); -- -- if (ret) { -- dev_err(dev, "Can't get %s regulator (%d)\n", supply_name, ret); -+ if (ret) - return ret; -- } - - return 0; - } -@@ -380,10 +386,17 @@ static int stm32_usbphyc_probe(struct udevice *dev) - - usbphyc_phy->init = false; - usbphyc_phy->powered = false; -- ret = stm32_usbphyc_get_regulator(dev, node, "phy-supply", -+ ret = stm32_usbphyc_get_regulator(node, "phy-supply", - &usbphyc_phy->vdd); -- if (ret) -+ if (ret) { -+ dev_err(dev, "Can't get phy-supply regulator\n"); - 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); - } -diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c -index c2ea82770e..fbbd479575 100644 ---- a/drivers/pinctrl/pinctrl-stmfx.c -+++ b/drivers/pinctrl/pinctrl-stmfx.c -@@ -346,15 +346,14 @@ static int stmfx_pinctrl_get_pins_count(struct udevice *dev) - * STMFX pins[15:0] are called "gpio[15:0]" - * and STMFX pins[23:16] are called "agpio[7:0]" - */ --#define MAX_PIN_NAME_LEN 7 --static char pin_name[MAX_PIN_NAME_LEN]; -+static char pin_name[PINNAME_SIZE]; - static const char *stmfx_pinctrl_get_pin_name(struct udevice *dev, - unsigned int selector) - { - if (selector < STMFX_MAX_GPIO) -- snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector); -+ snprintf(pin_name, PINNAME_SIZE, "gpio%u", selector); - else -- snprintf(pin_name, MAX_PIN_NAME_LEN, "agpio%u", selector - 16); -+ snprintf(pin_name, PINNAME_SIZE, "agpio%u", selector - 16); - return pin_name; - } - -@@ -408,8 +407,11 @@ static int stmfx_pinctrl_bind(struct udevice *dev) - { - struct stmfx_pinctrl *plat = dev_get_platdata(dev); - -+ /* subnode name is not explicit: use father name */ -+ device_set_name(dev, dev->parent->name); -+ - return device_bind_driver_to_node(dev->parent, -- "stmfx-gpio", "stmfx-gpio", -+ "stmfx-gpio", dev->parent->name, - dev_ofnode(dev), &plat->gpio); - }; - -diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c -index 71fa29a389..35a6acbe2c 100644 ---- a/drivers/pinctrl/pinctrl_stm32.c -+++ b/drivers/pinctrl/pinctrl_stm32.c -@@ -45,15 +45,15 @@ static const char * const pinmux_mode[PINMUX_MODE_COUNT] = { - "alt function", - }; - --static const char * const pinmux_output[] = { -- [STM32_GPIO_PUPD_NO] = "bias-disable", -- [STM32_GPIO_PUPD_UP] = "bias-pull-up", -- [STM32_GPIO_PUPD_DOWN] = "bias-pull-down", -+static const char * const pinmux_bias[] = { -+ [STM32_GPIO_PUPD_NO] = "", -+ [STM32_GPIO_PUPD_UP] = "pull-up", -+ [STM32_GPIO_PUPD_DOWN] = "pull-down", - }; - --static const char * const pinmux_input[] = { -- [STM32_GPIO_OTYPE_PP] = "drive-push-pull", -- [STM32_GPIO_OTYPE_OD] = "drive-open-drain", -+static const char * const pinmux_otype[] = { -+ [STM32_GPIO_OTYPE_PP] = "push-pull", -+ [STM32_GPIO_OTYPE_OD] = "open-drain", - }; - - static int stm32_pinctrl_get_af(struct udevice *dev, unsigned int offset) -@@ -210,7 +210,8 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, - dev_dbg(dev, "selector = %d gpio_idx = %d mode = %d\n", - selector, gpio_idx, mode); - priv = dev_get_priv(gpio_dev); -- -+ pupd = (readl(&priv->regs->pupdr) >> (gpio_idx * 2)) & PUPD_MASK; -+ otype = (readl(&priv->regs->otyper) >> gpio_idx) & OTYPE_MSK; - - switch (mode) { - case GPIOF_UNKNOWN: -@@ -221,20 +222,17 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, - break; - case GPIOF_FUNC: - af_num = stm32_pinctrl_get_af(gpio_dev, gpio_idx); -- snprintf(buf, size, "%s %d", pinmux_mode[mode], af_num); -+ snprintf(buf, size, "%s %d %s %s", pinmux_mode[mode], af_num, -+ pinmux_otype[otype], pinmux_bias[pupd]); - break; - case GPIOF_OUTPUT: -- pupd = (readl(&priv->regs->pupdr) >> (gpio_idx * 2)) & -- PUPD_MASK; -- snprintf(buf, size, "%s %s %s", -- pinmux_mode[mode], pinmux_output[pupd], -- label ? label : ""); -+ snprintf(buf, size, "%s %s %s %s", -+ pinmux_mode[mode], pinmux_otype[otype], -+ pinmux_bias[pupd], label ? label : ""); - break; - case GPIOF_INPUT: -- otype = (readl(&priv->regs->otyper) >> gpio_idx) & OTYPE_MSK; -- snprintf(buf, size, "%s %s %s", -- pinmux_mode[mode], pinmux_input[otype], -- label ? label : ""); -+ snprintf(buf, size, "%s %s %s", pinmux_mode[mode], -+ pinmux_bias[pupd], label ? label : ""); - break; - } - -@@ -401,6 +399,9 @@ static int stm32_pinctrl_bind(struct udevice *dev) - dev_for_each_subnode(node, dev) { - debug("%s: bind %s\n", __func__, ofnode_get_name(node)); - -+ if (!ofnode_is_enabled(node)) -+ continue; -+ - ofnode_get_property(node, "gpio-controller", &ret); - if (ret < 0) - continue; -diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig -index 7c2e4804b5..3e1c9ed54f 100644 ---- a/drivers/remoteproc/Kconfig -+++ b/drivers/remoteproc/Kconfig -@@ -12,6 +12,14 @@ config REMOTEPROC - bool - depends on DM - -+config REMOTEPROC_OPTEE -+ bool "Support for the remoteproc in OPTEE" -+ depends on REMOTEPROC -+ depends on OPTEE -+ help -+ Say y here to support remote processor firmware management by the -+ trusted execution environment. -+ - # Please keep the configuration alphabetically sorted. - config K3_SYSTEM_CONTROLLER - bool "Support for TI' K3 System Controller" -diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile -index 69ae7bd1e8..d6c5f54fb7 100644 ---- a/drivers/remoteproc/Makefile -+++ b/drivers/remoteproc/Makefile -@@ -5,6 +5,7 @@ - # - - obj-$(CONFIG_$(SPL_)REMOTEPROC) += rproc-uclass.o rproc-elf-loader.o -+obj-$(CONFIG_REMOTEPROC_OPTEE) += rproc-optee.o - - # Remote proc drivers - Please keep this list alphabetically sorted. - obj-$(CONFIG_K3_SYSTEM_CONTROLLER) += k3_system_controller.o -diff --git a/drivers/remoteproc/rproc-optee.c b/drivers/remoteproc/rproc-optee.c -new file mode 100644 -index 0000000000..07d2811e22 ---- /dev/null -+++ b/drivers/remoteproc/rproc-optee.c -@@ -0,0 +1,219 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) STMicroelectronics 2020 - All Rights Reserved -+ * Authors: Arnaud Pouliquen -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define TA_REMOTEPROC_UUID { 0x80a4c275, 0x0a47, 0x4905, \ -+ { 0x82, 0x85, 0x14, 0x86, 0xa9, 0x77, 0x1a, 0x08} } -+ -+/* The function IDs implemented in the associated TA */ -+ -+/* -+ * Authentication of the firmware and load in the remote processor memory. -+ * -+ * [in] params[0].value.a: unique 32bit identifier of the firmware -+ * [in] params[1].memref: buffer containing the image of the firmware -+ */ -+#define TA_RPROC_FW_CMD_LOAD_FW 1 -+ -+/* -+ * Start the remote processor. -+ * -+ * [in] params[0].value.a: unique 32bit identifier of the firmware -+ */ -+#define TA_RPROC_FW_CMD_START_FW 2 -+ -+/* -+ * Stop the remote processor. -+ * -+ * [in] params[0].value.a: unique 32bit identifier of the firmware -+ */ -+#define TA_RPROC_FW_CMD_STOP_FW 3 -+ -+/* -+ * Return the physical address of the resource table, or 0 if not found -+ * No check is done to verify that the address returned is accessible by the -+ * non secure world. If the resource table is loaded in a protected memory, -+ * then accesses from non-secure world will likely fail. -+ * -+ * [in] params[0].value.a: unique 32bit identifier of the firmware -+ * [out] params[1].value.a: 32bit LSB resource table memory address -+ * [out] params[1].value.b: 32bit MSB resource table memory address -+ * [out] params[2].value.a: 32bit LSB resource table memory size -+ * [out] params[2].value.b: 32bit MSB resource table memory size -+ */ -+#define TA_RPROC_FW_CMD_GET_RSC_TABLE 4 -+ -+/* -+ * Get remote processor firmware core dump. If found, return either -+ * TEE_SUCCESS on successful completion or TEE_ERROR_SHORT_BUFFER if output -+ * buffer is too short to store the core dump. -+ * -+ * [in] params[0].value.a: unique 32bit identifier of the firmware -+ * [out] params[1].memref: Core dump, if found -+ */ -+#define TA_RPROC_FW_CMD_GET_COREDUMP 5 -+ -+static void prepare_args(struct rproc_optee *trproc, int cmd, -+ struct tee_invoke_arg *arg, uint num_param, -+ struct tee_param *param) -+{ -+ memset(arg, 0, sizeof(*arg)); -+ memset(param, 0, num_param * sizeof(*param)); -+ -+ arg->func = cmd; -+ arg->session = trproc->session; -+ -+ param[0] = (struct tee_param) { -+ .attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT, -+ .u.value.a = trproc->fw_id, -+ }; -+} -+ -+int rproc_optee_load(struct rproc_optee *trproc, ulong addr, ulong size) -+{ -+ struct tee_invoke_arg arg; -+ struct tee_param param[2]; -+ struct tee_shm *fw_shm; -+ int rc; -+ -+ rc = tee_shm_register(trproc->tee, (void *)addr, size, 0, &fw_shm); -+ if (rc) -+ return rc; -+ -+ prepare_args(trproc, TA_RPROC_FW_CMD_LOAD_FW, &arg, 2, param); -+ -+ /* Provide the address and size of the firmware image */ -+ param[1] = (struct tee_param){ -+ .attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT, -+ .u.memref = { -+ .shm = fw_shm, -+ .size = size, -+ .shm_offs = 0, -+ }, -+ }; -+ -+ rc = tee_invoke_func(trproc->tee, &arg, 2, param); -+ if (rc < 0 || arg.ret != 0) { -+ dev_err(trproc->tee, -+ "TA_RPROC_FW_CMD_LOAD_FW invoke failed TEE err: %x, err:%x\n", -+ arg.ret, rc); -+ if (!rc) -+ rc = -EIO; -+ } -+ -+ tee_shm_free(fw_shm); -+ -+ return rc; -+} -+ -+int rproc_optee_get_rsc_table(struct rproc_optee *trproc, phys_addr_t *rsc_addr, -+ phys_size_t *rsc_size) -+{ -+ struct tee_invoke_arg arg; -+ struct tee_param param[3]; -+ int rc; -+ -+ prepare_args(trproc, TA_RPROC_FW_CMD_GET_RSC_TABLE, &arg, 3, param); -+ -+ param[1].attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT; -+ param[2].attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT; -+ -+ rc = tee_invoke_func(trproc->tee, &arg, 3, param); -+ if (rc < 0 || arg.ret != 0) { -+ dev_err(trproc->tee, -+ "TA_RPROC_FW_CMD_GET_RSC_TABLE invoke failed TEE err: %x, err:%x\n", -+ arg.ret, rc); -+ if (!rc) -+ rc = -EIO; -+ -+ return rc; -+ } -+ -+ *rsc_size = (phys_size_t) -+ (param[2].u.value.b << 32 | param[2].u.value.a); -+ *rsc_addr = (phys_addr_t) -+ (param[1].u.value.b << 32 | param[1].u.value.a); -+ -+ return 0; -+} -+ -+int rproc_optee_start(struct rproc_optee *trproc) -+{ -+ struct tee_invoke_arg arg; -+ struct tee_param param; -+ int rc; -+ -+ prepare_args(trproc, TA_RPROC_FW_CMD_START_FW, &arg, 1, ¶m); -+ -+ rc = tee_invoke_func(trproc->tee, &arg, 1, ¶m); -+ if (rc < 0 || arg.ret != 0) { -+ dev_err(trproc->tee, -+ "TA_RPROC_FW_CMD_START_FW invoke failed TEE err: %x, err:%x\n", -+ arg.ret, rc); -+ if (!rc) -+ rc = -EIO; -+ } -+ -+ return rc; -+} -+ -+int rproc_optee_stop(struct rproc_optee *trproc) -+{ -+ struct tee_invoke_arg arg; -+ struct tee_param param; -+ int rc; -+ -+ prepare_args(trproc, TA_RPROC_FW_CMD_STOP_FW, &arg, 1, ¶m); -+ -+ rc = tee_invoke_func(trproc->tee, &arg, 1, ¶m); -+ if (rc < 0 || arg.ret != 0) { -+ dev_err(trproc->tee, -+ "TA_RPROC_FW_CMD_STOP_FW invoke failed TEE err: %x, err:%x\n", -+ arg.ret, rc); -+ if (!rc) -+ rc = -EIO; -+ } -+ -+ return rc; -+} -+ -+int rproc_optee_open(struct rproc_optee *trproc) -+{ -+ struct udevice *tee = NULL; -+ const struct tee_optee_ta_uuid uuid = TA_REMOTEPROC_UUID; -+ struct tee_open_session_arg arg = { }; -+ int rc; -+ -+ if (!trproc) -+ return -EINVAL; -+ -+ tee = tee_find_device(tee, NULL, NULL, NULL); -+ if (!tee) -+ return -ENODEV; -+ -+ 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; -+ } -+ -+ return 0; -+} -+ -+int rproc_optee_close(struct rproc_optee *trproc) -+{ -+ if (!trproc->tee) -+ return -ENODEV; -+ -+ return tee_close_session(trproc->tee, trproc->session); -+} -diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c -index 33b574b1bd..55d7303c55 100644 ---- a/drivers/remoteproc/stm32_copro.c -+++ b/drivers/remoteproc/stm32_copro.c -@@ -8,30 +8,24 @@ - #include - #include - #include --#include - #include -+#include - #include --#include - #include - #include - #include - --#define RCC_GCR_HOLD_BOOT 0 --#define RCC_GCR_RELEASE_BOOT 1 -+#define STM32MP15_M4_FW_ID 0 - - /** - * struct stm32_copro_privdata - power processor private data - * @reset_ctl: reset controller handle -- * @hold_boot_regmap: regmap for remote processor reset hold boot -- * @hold_boot_offset: offset of the register controlling the hold boot setting -- * @hold_boot_mask: bitmask of the register for the hold boot field -+ * @hold_boot: hold boot controller handle - * @rsc_table_addr: resource table address - */ - struct stm32_copro_privdata { - struct reset_ctl reset_ctl; -- struct regmap *hold_boot_regmap; -- uint hold_boot_offset; -- uint hold_boot_mask; -+ struct reset_ctl hold_boot; - ulong rsc_table_addr; - }; - -@@ -43,32 +37,19 @@ struct stm32_copro_privdata { - static int stm32_copro_probe(struct udevice *dev) - { - struct stm32_copro_privdata *priv; -- struct regmap *regmap; -- const fdt32_t *cell; -- int len, ret; -+ int ret; - - priv = dev_get_priv(dev); - -- regmap = syscon_regmap_lookup_by_phandle(dev, "st,syscfg-holdboot"); -- if (IS_ERR(regmap)) { -- dev_err(dev, "unable to find holdboot regmap (%ld)\n", -- PTR_ERR(regmap)); -- return PTR_ERR(regmap); -- } -- -- cell = dev_read_prop(dev, "st,syscfg-holdboot", &len); -- if (len < 3 * sizeof(fdt32_t)) { -- dev_err(dev, "holdboot offset and mask not available\n"); -- return -EINVAL; -+ ret = reset_get_by_name(dev, "mcu_rst", &priv->reset_ctl); -+ if (ret) { -+ dev_err(dev, "failed to get reset (%d)\n", ret); -+ return ret; - } - -- priv->hold_boot_regmap = regmap; -- priv->hold_boot_offset = fdtdec_get_number(cell + 1, 1); -- priv->hold_boot_mask = fdtdec_get_number(cell + 2, 1); -- -- ret = reset_get_by_index(dev, 0, &priv->reset_ctl); -+ ret = reset_get_by_name(dev, "hold_boot", &priv->hold_boot); - if (ret) { -- dev_err(dev, "failed to get reset (%d)\n", ret); -+ dev_err(dev, "failed to get hold boot (%d)\n", ret); - return ret; - } - -@@ -78,32 +59,29 @@ static int stm32_copro_probe(struct udevice *dev) - } - - /** -- * stm32_copro_set_hold_boot() - Hold boot bit management -+ * stm32_copro_optee_probe() - Open a session toward rproc trusted application - * @dev: corresponding STM32 remote processor device -- * @hold: hold boot value - * @return 0 if all went ok, else corresponding -ve error - */ --static int stm32_copro_set_hold_boot(struct udevice *dev, bool hold) -+static int stm32_copro_optee_probe(struct udevice *dev) - { -- struct stm32_copro_privdata *priv; -- uint val; -- int ret; -+ struct rproc_optee *trproc = dev_get_priv(dev); - -- priv = dev_get_priv(dev); -+ trproc->fw_id = (u32)dev_get_driver_data(dev); - -- val = hold ? RCC_GCR_HOLD_BOOT : RCC_GCR_RELEASE_BOOT; -+ return rproc_optee_open(trproc); -+} - -- /* -- * Note: shall run an SMC call (STM32_SMC_RCC) if platform is secured. -- * To be updated when the code for this SMC service is available which -- * is not the case for the time being. -- */ -- ret = regmap_update_bits(priv->hold_boot_regmap, priv->hold_boot_offset, -- priv->hold_boot_mask, val); -- if (ret) -- dev_err(dev, "failed to set hold boot\n"); -+/** -+ * 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) -+{ -+ struct rproc_optee *trproc = dev_get_priv(dev); - -- return ret; -+ return rproc_optee_close(trproc); - } - - /** -@@ -149,9 +127,11 @@ static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size) - - priv = dev_get_priv(dev); - -- ret = stm32_copro_set_hold_boot(dev, true); -- if (ret) -+ 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) { -@@ -168,6 +148,18 @@ 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 -@@ -180,23 +172,54 @@ static int stm32_copro_start(struct udevice *dev) - - priv = dev_get_priv(dev); - -- /* move hold boot from true to false start the copro */ -- ret = stm32_copro_set_hold_boot(dev, false); -- if (ret) -+ 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 -+ * rebooting autonomously (error should never occur) - */ -- ret = stm32_copro_set_hold_boot(dev, true); -- writel(ret ? TAMP_COPRO_STATE_OFF : TAMP_COPRO_STATE_CRUN, -- TAMP_COPRO_STATE); -- if (!ret) -- /* Store rsc_address in bkp register */ -- writel(priv->rsc_table_addr, TAMP_COPRO_RSC_TBL_ADDRESS); -- -- return ret; -+ 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 */ -+ writel(priv->rsc_table_addr, TAMP_COPRO_RSC_TBL_ADDRESS); -+ -+ 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; - } - - /** -@@ -211,9 +234,11 @@ static int stm32_copro_reset(struct udevice *dev) - - priv = dev_get_priv(dev); - -- ret = stm32_copro_set_hold_boot(dev, true); -- if (ret) -+ 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) { -@@ -236,6 +261,35 @@ 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 -@@ -268,3 +322,28 @@ U_BOOT_DRIVER(stm32_copro) = { - .probe = stm32_copro_probe, - .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/reset/Kconfig b/drivers/reset/Kconfig -index 253902ff57..ee5be0bc2f 100644 ---- a/drivers/reset/Kconfig -+++ b/drivers/reset/Kconfig -@@ -173,4 +173,12 @@ config RESET_RASPBERRYPI - relevant. This driver provides a reset controller capable of - interfacing with RPi4's co-processor and model these firmware - initialization routines as reset lines. -+ -+config RESET_SCMI -+ bool "Enable SCMI reset domain driver" -+ select SCMI_FIRMWARE -+ help -+ Enable this option if you want to support reset controller -+ devices exposed by a SCMI agent based on SCMI reset domain -+ protocol communication with a SCMI server. - endmenu -diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile -index 3c7f066ae3..625ec7168e 100644 ---- a/drivers/reset/Makefile -+++ b/drivers/reset/Makefile -@@ -26,3 +26,4 @@ obj-$(CONFIG_RESET_IMX7) += reset-imx7.o - obj-$(CONFIG_RESET_SIFIVE) += reset-sifive.o - obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o - obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o -+obj-$(CONFIG_RESET_SCMI) += reset-scmi.o -diff --git a/drivers/reset/reset-scmi.c b/drivers/reset/reset-scmi.c -new file mode 100644 -index 0000000000..1bff8075ee ---- /dev/null -+++ b/drivers/reset/reset-scmi.c -@@ -0,0 +1,81 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2019-2020 Linaro Limited -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static int scmi_reset_set_level(struct reset_ctl *rst, bool assert_not_deassert) -+{ -+ struct scmi_rd_reset_in in = { -+ .domain_id = rst->id, -+ .flags = assert_not_deassert ? SCMI_RD_RESET_FLAG_ASSERT : 0, -+ .reset_state = 0, -+ }; -+ struct scmi_rd_reset_out out; -+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_RESET_DOMAIN, -+ SCMI_RESET_DOMAIN_RESET, -+ in, out); -+ int ret; -+ -+ ret = devm_scmi_process_msg(rst->dev->parent, &msg); -+ if (ret) -+ return ret; -+ -+ return scmi_to_linux_errno(out.status); -+} -+ -+static int scmi_reset_assert(struct reset_ctl *rst) -+{ -+ return scmi_reset_set_level(rst, true); -+} -+ -+static int scmi_reset_deassert(struct reset_ctl *rst) -+{ -+ return scmi_reset_set_level(rst, false); -+} -+ -+static int scmi_reset_request(struct reset_ctl *rst) -+{ -+ struct scmi_rd_attr_in in = { -+ .domain_id = rst->id, -+ }; -+ struct scmi_rd_attr_out out; -+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_RESET_DOMAIN, -+ SCMI_RESET_DOMAIN_ATTRIBUTES, -+ in, out); -+ int ret; -+ -+ /* -+ * We don't really care about the attribute, just check -+ * the reset domain exists. -+ */ -+ ret = devm_scmi_process_msg(rst->dev->parent, &msg); -+ if (ret) -+ return ret; -+ -+ return scmi_to_linux_errno(out.status); -+} -+ -+static int scmi_reset_rfree(struct reset_ctl *rst) -+{ -+ return 0; -+} -+ -+static const struct reset_ops scmi_reset_domain_ops = { -+ .request = scmi_reset_request, -+ .rfree = scmi_reset_rfree, -+ .rst_assert = scmi_reset_assert, -+ .rst_deassert = scmi_reset_deassert, -+}; -+ -+U_BOOT_DRIVER(scmi_reset_domain) = { -+ .name = "scmi_reset_domain", -+ .id = UCLASS_RESET, -+ .ops = &scmi_reset_domain_ops, -+}; -diff --git a/drivers/reset/stm32-reset.c b/drivers/reset/stm32-reset.c -index 64a11cfcfc..20c36a99eb 100644 ---- a/drivers/reset/stm32-reset.c -+++ b/drivers/reset/stm32-reset.c -@@ -14,6 +14,9 @@ - #include - #include - -+/* offset of register without set/clear management */ -+#define RCC_MP_GCR_OFFSET 0x10C -+ - /* reset clear offset for STM32MP RCC */ - #define RCC_CL 0x4 - -@@ -40,8 +43,11 @@ static int stm32_reset_assert(struct reset_ctl *reset_ctl) - reset_ctl->id, bank, offset); - - if (dev_get_driver_data(reset_ctl->dev) == STM32MP1) -- /* reset assert is done in rcc set register */ -- writel(BIT(offset), priv->base + bank); -+ if (bank != RCC_MP_GCR_OFFSET) -+ /* reset assert is done in rcc set register */ -+ writel(BIT(offset), priv->base + bank); -+ else -+ clrbits_le32(priv->base + bank, BIT(offset)); - else - setbits_le32(priv->base + bank, BIT(offset)); - -@@ -57,8 +63,11 @@ static int stm32_reset_deassert(struct reset_ctl *reset_ctl) - reset_ctl->id, bank, offset); - - if (dev_get_driver_data(reset_ctl->dev) == STM32MP1) -- /* reset deassert is done in rcc clr register */ -- writel(BIT(offset), priv->base + bank + RCC_CL); -+ if (bank != RCC_MP_GCR_OFFSET) -+ /* reset deassert is done in rcc clr register */ -+ writel(BIT(offset), priv->base + bank + RCC_CL); -+ else -+ setbits_le32(priv->base + bank, BIT(offset)); - else - clrbits_le32(priv->base + bank, BIT(offset)); - -diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c -index a53b941410..72a169e196 100644 ---- a/drivers/spi/stm32_qspi.c -+++ b/drivers/spi/stm32_qspi.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -169,6 +170,7 @@ static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv *priv, - static void _stm32_qspi_read_fifo(u8 *val, void __iomem *addr) - { - *val = readb(addr); -+ WATCHDOG_RESET(); - } - - static void _stm32_qspi_write_fifo(u8 *val, void __iomem *addr) -diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c -index eaa5dcb9b1..a025b36400 100644 ---- a/drivers/usb/gadget/dwc2_udc_otg.c -+++ b/drivers/usb/gadget/dwc2_udc_otg.c -@@ -1014,6 +1014,9 @@ static int dwc2_udc_otg_ofdata_to_platdata(struct udevice *dev) - platdata->force_b_session_valid = - dev_read_bool(dev, "u-boot,force-b-session-valid"); - -+ platdata->force_vbus_detection = -+ dev_read_bool(dev, "u-boot,force-vbus-detection"); -+ - /* force platdata according compatible */ - drvdata = dev_get_driver_data(dev); - if (drvdata) { -@@ -1106,31 +1109,45 @@ static int dwc2_udc_otg_probe(struct udevice *dev) - if (ret) - return ret; - -- if (CONFIG_IS_ENABLED(DM_REGULATOR) && -- platdata->activate_stm_id_vb_detection && -- !platdata->force_b_session_valid) { -- ret = device_get_supply_regulator(dev, "usb33d-supply", -- &priv->usb33d_supply); -- if (ret) { -- dev_err(dev, "can't get voltage level detector supply\n"); -- return ret; -+ if (platdata->activate_stm_id_vb_detection) { -+ if (CONFIG_IS_ENABLED(DM_REGULATOR) && -+ (!platdata->force_b_session_valid || -+ platdata->force_vbus_detection)) { -+ ret = device_get_supply_regulator(dev, "usb33d-supply", -+ &priv->usb33d_supply); -+ if (ret) { -+ dev_err(dev, "can't get voltage level detector supply\n"); -+ return ret; -+ } -+ ret = regulator_set_enable(priv->usb33d_supply, true); -+ if (ret) { -+ dev_err(dev, "can't enable voltage level detector supply\n"); -+ return ret; -+ } - } -- ret = regulator_set_enable(priv->usb33d_supply, true); -- if (ret) { -- dev_err(dev, "can't enable voltage level detector supply\n"); -- return ret; -+ -+ if (platdata->force_b_session_valid && -+ !platdata->force_vbus_detection) { -+ /* Override VBUS detection: enable then value*/ -+ setbits_le32(&usbotg_reg->gotgctl, VB_VALOEN); -+ setbits_le32(&usbotg_reg->gotgctl, VB_VALOVAL); -+ } else { -+ /* Enable VBUS sensing */ -+ setbits_le32(&usbotg_reg->ggpio, -+ GGPIO_STM32_OTG_GCCFG_VBDEN); -+ } -+ if (platdata->force_b_session_valid) { -+ /* Override B session bits: enable then value */ -+ setbits_le32(&usbotg_reg->gotgctl, A_VALOEN | B_VALOEN); -+ setbits_le32(&usbotg_reg->gotgctl, -+ A_VALOVAL | B_VALOVAL); -+ } else { -+ /* Enable ID detection */ -+ setbits_le32(&usbotg_reg->ggpio, -+ GGPIO_STM32_OTG_GCCFG_IDEN); - } -- /* Enable vbus sensing */ -- setbits_le32(&usbotg_reg->ggpio, -- GGPIO_STM32_OTG_GCCFG_VBDEN | -- GGPIO_STM32_OTG_GCCFG_IDEN); - } - -- if (platdata->force_b_session_valid) -- /* Override B session bits : value and enable */ -- setbits_le32(&usbotg_reg->gotgctl, -- A_VALOEN | A_VALOVAL | B_VALOEN | B_VALOVAL); -- - ret = dwc2_udc_probe(platdata); - if (ret) - return ret; -@@ -1160,7 +1177,7 @@ static int dwc2_udc_otg_remove(struct udevice *dev) - static const struct udevice_id dwc2_udc_otg_ids[] = { - { .compatible = "snps,dwc2" }, - { .compatible = "brcm,bcm2835-usb" }, -- { .compatible = "st,stm32mp1-hsotg", -+ { .compatible = "st,stm32mp15-hsotg", - .data = (ulong)dwc2_set_stm32mp1_hsotg_params }, - {}, - }; -diff --git a/drivers/usb/gadget/dwc2_udc_otg_regs.h b/drivers/usb/gadget/dwc2_udc_otg_regs.h -index 2eda5c3720..9ca6f42375 100644 ---- a/drivers/usb/gadget/dwc2_udc_otg_regs.h -+++ b/drivers/usb/gadget/dwc2_udc_otg_regs.h -@@ -94,6 +94,8 @@ struct dwc2_usbotg_reg { - #define B_VALOEN BIT(6) - #define A_VALOVAL BIT(5) - #define A_VALOEN BIT(4) -+#define VB_VALOVAL BIT(3) -+#define VB_VALOEN BIT(2) - - /* DWC2_UDC_OTG_GOTINT */ - #define GOTGINT_SES_END_DET (1<<2) -diff --git a/drivers/video/dw_mipi_dsi.c b/drivers/video/dw_mipi_dsi.c -index b7bfbb5e50..1303d99e56 100644 ---- a/drivers/video/dw_mipi_dsi.c -+++ b/drivers/video/dw_mipi_dsi.c -@@ -314,7 +314,8 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val) - val, !(val & GEN_CMD_FULL), - CMD_PKT_STATUS_TIMEOUT_US); - if (ret) { -- dev_err(dsi->dev, "failed to get available command FIFO\n"); -+ dev_err(dsi->dsi_host.dev, -+ "failed to get available command FIFO\n"); - return ret; - } - -@@ -325,7 +326,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val) - val, (val & mask) == mask, - CMD_PKT_STATUS_TIMEOUT_US); - if (ret) { -- dev_err(dsi->dev, "failed to write command FIFO\n"); -+ dev_err(dsi->dsi_host.dev, "failed to write command FIFO\n"); - return ret; - } - -@@ -357,7 +358,7 @@ static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi, - val, !(val & GEN_PLD_W_FULL), - CMD_PKT_STATUS_TIMEOUT_US); - if (ret) { -- dev_err(dsi->dev, -+ dev_err(dsi->dsi_host.dev, - "failed to get available write payload FIFO\n"); - return ret; - } -@@ -380,7 +381,7 @@ static int dw_mipi_dsi_read(struct dw_mipi_dsi *dsi, - val, !(val & GEN_RD_CMD_BUSY), - CMD_PKT_STATUS_TIMEOUT_US); - if (ret) { -- dev_err(dsi->dev, "Timeout during read operation\n"); -+ dev_err(dsi->dsi_host.dev, "Timeout during read operation\n"); - return ret; - } - -@@ -390,7 +391,8 @@ static int dw_mipi_dsi_read(struct dw_mipi_dsi *dsi, - val, !(val & GEN_PLD_R_EMPTY), - CMD_PKT_STATUS_TIMEOUT_US); - if (ret) { -- dev_err(dsi->dev, "Read payload FIFO is empty\n"); -+ dev_err(dsi->dsi_host.dev, -+ "Read payload FIFO is empty\n"); - return ret; - } - -@@ -411,7 +413,7 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host, - - ret = mipi_dsi_create_packet(&packet, msg); - if (ret) { -- dev_err(dsi->dev, "failed to create packet: %d\n", ret); -+ dev_err(host->dev, "failed to create packet: %d\n", ret); - return ret; - } - -@@ -483,15 +485,27 @@ static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi, - - static void dw_mipi_dsi_init_pll(struct dw_mipi_dsi *dsi) - { -+ const struct mipi_dsi_phy_ops *phy_ops = dsi->phy_ops; -+ unsigned int esc_rate; -+ u32 esc_clk_division; -+ - /* - * The maximum permitted escape clock is 20MHz and it is derived from -- * lanebyteclk, which is running at "lane_mbps / 8". Thus we want: -+ * lanebyteclk, which is running at "lane_mbps / 8". -+ */ -+ if (phy_ops->get_esc_clk_rate) -+ phy_ops->get_esc_clk_rate(dsi->device, &esc_rate); -+ else -+ esc_rate = 20; /* Default to 20MHz */ -+ -+ /* -+ * We want: - * -- * (lane_mbps >> 3) / esc_clk_division < 20 -+ * (lane_mbps >> 3) / esc_clk_division < X - * which is: -- * (lane_mbps >> 3) / 20 > esc_clk_division -+ * (lane_mbps >> 3) / X > esc_clk_division - */ -- u32 esc_clk_division = (dsi->lane_mbps >> 3) / 20 + 1; -+ esc_clk_division = (dsi->lane_mbps >> 3) / esc_rate + 1; - - dsi_write(dsi, DSI_PWR_UP, RESET); - -@@ -643,8 +657,13 @@ static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi, - - static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi) - { -+ const struct mipi_dsi_phy_ops *phy_ops = dsi->phy_ops; -+ struct mipi_dsi_phy_timing timing = {0x40, 0x40, 0x40, 0x40}; - u32 hw_version; - -+ if (phy_ops->get_timing) -+ phy_ops->get_timing(dsi->device, dsi->lane_mbps, &timing); -+ - /* - * TODO dw drv improvements - * data & clock lane timers should be computed according to panel -@@ -656,16 +675,16 @@ static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi) - hw_version = dsi_read(dsi, DSI_VERSION) & VERSION; - - if (hw_version >= HWVER_131) { -- dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME_V131(0x40) | -- PHY_LP2HS_TIME_V131(0x40)); -+ dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME_V131(timing.data_hs2lp) | -+ PHY_LP2HS_TIME_V131(timing.data_lp2hs)); - dsi_write(dsi, DSI_PHY_TMR_RD_CFG, MAX_RD_TIME_V131(10000)); - } else { -- dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x40) | -- PHY_LP2HS_TIME(0x40) | MAX_RD_TIME(10000)); -+ dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(timing.data_hs2lp) | -+ PHY_LP2HS_TIME(timing.data_lp2hs) | MAX_RD_TIME(10000)); - } - -- dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40) -- | PHY_CLKLP2HS_TIME(0x40)); -+ dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(timing.clk_hs2lp) -+ | PHY_CLKLP2HS_TIME(timing.clk_lp2hs)); - } - - static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi) -@@ -702,13 +721,15 @@ static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi) - ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val, - val & PHY_LOCK, PHY_STATUS_TIMEOUT_US); - if (ret) -- dev_warn(dsi->dev, "failed to wait phy lock state\n"); -+ dev_dbg(dsi->dsi_host.dev, -+ "failed to wait phy lock state\n"); - - ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, - val, val & PHY_STOP_STATE_CLK_LANE, - PHY_STATUS_TIMEOUT_US); - if (ret) -- dev_warn(dsi->dev, "failed to wait phy clk lane stop state\n"); -+ dev_dbg(dsi->dsi_host.dev, -+ "failed to wait phy clk lane stop state\n"); - } - - static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi) -@@ -729,7 +750,7 @@ static void dw_mipi_dsi_bridge_set(struct dw_mipi_dsi *dsi, - ret = phy_ops->get_lane_mbps(dsi->device, timings, device->lanes, - device->format, &dsi->lane_mbps); - if (ret) -- dev_warn(dsi->dev, "Phy get_lane_mbps() failed\n"); -+ dev_warn(dsi->dsi_host.dev, "Phy get_lane_mbps() failed\n"); - - dw_mipi_dsi_init_pll(dsi); - dw_mipi_dsi_dpi_config(dsi, timings); -@@ -748,7 +769,7 @@ static void dw_mipi_dsi_bridge_set(struct dw_mipi_dsi *dsi, - - ret = phy_ops->init(dsi->device); - if (ret) -- dev_warn(dsi->dev, "Phy init() failed\n"); -+ dev_warn(dsi->dsi_host.dev, "Phy init() failed\n"); - - dw_mipi_dsi_dphy_enable(dsi); - -@@ -776,6 +797,7 @@ static int dw_mipi_dsi_init(struct udevice *dev, - dsi->phy_ops = phy_ops; - dsi->max_data_lanes = max_data_lanes; - dsi->device = device; -+ dsi->dsi_host.dev = (struct device *)dev; - dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; - device->host = &dsi->dsi_host; - -diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c -index 283151398b..6c027b6388 100644 ---- a/drivers/video/stm32/stm32_dsi.c -+++ b/drivers/video/stm32/stm32_dsi.c -@@ -482,6 +482,9 @@ static int stm32_dsi_probe(struct udevice *dev) - if (priv->hw_version != HWVER_130 && - priv->hw_version != HWVER_131) { - dev_err(dev, "DSI version 0x%x not supported\n", priv->hw_version); -+ dev_dbg(dev, "remove and unbind all DSI child\n"); -+ device_chld_remove(dev, NULL, DM_REMOVE_NORMAL); -+ device_chld_unbind(dev, NULL); - ret = -ENODEV; - goto err_clk; - } -diff --git a/env/ext4.c b/env/ext4.c -index f823b69409..e03aa9d7da 100644 ---- a/env/ext4.c -+++ b/env/ext4.c -@@ -173,6 +173,5 @@ U_BOOT_ENV_LOCATION(ext4) = { - ENV_NAME("EXT4") - .load = env_ext4_load, - .save = ENV_SAVE_PTR(env_ext4_save), -- .erase = CONFIG_IS_ENABLED(CMD_ERASEENV) ? env_ext4_erase : -- NULL, -+ .erase = ENV_ERASE_PTR(env_ext4_erase), - }; -diff --git a/env/mmc.c b/env/mmc.c -index ba872701b0..7838874f4d 100644 ---- a/env/mmc.c -+++ b/env/mmc.c -@@ -237,7 +237,6 @@ fini: - return ret; - } - --#if defined(CONFIG_CMD_ERASEENV) - static inline int erase_env(struct mmc *mmc, unsigned long size, - unsigned long offset) - { -@@ -283,7 +282,6 @@ static int env_mmc_erase(void) - - return ret; - } --#endif /* CONFIG_CMD_ERASEENV */ - #endif /* CONFIG_CMD_SAVEENV && !CONFIG_SPL_BUILD */ - - static inline int read_env(struct mmc *mmc, unsigned long size, -@@ -398,8 +396,6 @@ U_BOOT_ENV_LOCATION(mmc) = { - .load = env_mmc_load, - #ifndef CONFIG_SPL_BUILD - .save = env_save_ptr(env_mmc_save), --#if defined(CONFIG_CMD_ERASEENV) -- .erase = env_mmc_erase, --#endif -+ .erase = ENV_ERASE_PTR(env_mmc_erase) - #endif - }; -diff --git a/env/sf.c b/env/sf.c -index 937778aa37..5f31b9dd2f 100644 ---- a/env/sf.c -+++ b/env/sf.c -@@ -27,9 +27,18 @@ - #define INITENV - #endif - -+#define OFFSET_INVALID (~(u32)0) -+ - #ifdef CONFIG_ENV_OFFSET_REDUND -+#define ENV_OFFSET_REDUND CONFIG_ENV_OFFSET_REDUND -+ - static ulong env_offset = CONFIG_ENV_OFFSET; - static ulong env_new_offset = CONFIG_ENV_OFFSET_REDUND; -+ -+#else -+ -+#define ENV_OFFSET_REDUND OFFSET_INVALID -+ - #endif /* CONFIG_ENV_OFFSET_REDUND */ - - DECLARE_GLOBAL_DATA_PTR; -@@ -279,6 +288,26 @@ out: - } - #endif - -+static int env_sf_erase(void) -+{ -+ int ret; -+ env_t env; -+ -+ ret = setup_flash_device(); -+ if (ret) -+ return ret; -+ -+ memset(&env, 0, sizeof(env_t)); -+ ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, &env); -+ if (ret) -+ return ret; -+ -+ if (ENV_OFFSET_REDUND != OFFSET_INVALID) -+ ret = spi_flash_write(env_flash, ENV_OFFSET_REDUND, CONFIG_ENV_SIZE, &env); -+ -+ return ret; -+} -+ - #if CONFIG_ENV_ADDR != 0x0 - __weak void *env_sf_get_env_addr(void) - { -@@ -307,7 +336,8 @@ U_BOOT_ENV_LOCATION(sf) = { - .location = ENVL_SPI_FLASH, - ENV_NAME("SPIFlash") - .load = env_sf_load, -- .save = CONFIG_IS_ENABLED(SAVEENV) ? ENV_SAVE_PTR(env_sf_save) : NULL, -+ .save = ENV_SAVE_PTR(env_sf_save), -+ .erase = ENV_ERASE_PTR(env_sf_erase), - #if defined(INITENV) && (CONFIG_ENV_ADDR != 0x0) - .init = env_sf_init, - #endif -diff --git a/include/configs/10m50_devboard.h b/include/configs/10m50_devboard.h -index 768b4a6dfc..3ffc744928 100644 ---- a/include/configs/10m50_devboard.h -+++ b/include/configs/10m50_devboard.h -@@ -34,11 +34,6 @@ - */ - #define CONFIG_BOOTP_BOOTFILESIZE - --/* -- * FDT options -- */ --#define CONFIG_LMB -- - /* - * MEMORY ORGANIZATION - * -Monitor at top of sdram. -diff --git a/include/configs/3c120_devboard.h b/include/configs/3c120_devboard.h -index 30bbd716b2..3f065ff315 100644 ---- a/include/configs/3c120_devboard.h -+++ b/include/configs/3c120_devboard.h -@@ -34,11 +34,6 @@ - */ - #define CONFIG_BOOTP_BOOTFILESIZE - --/* -- * FDT options -- */ --#define CONFIG_LMB -- - /* - * MEMORY ORGANIZATION - * -Monitor at top of sdram. -diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h -index 5554313810..d0a8d9b9d5 100644 ---- a/include/configs/sandbox.h -+++ b/include/configs/sandbox.h -@@ -22,8 +22,6 @@ - #define CONFIG_SYS_TIMER_RATE 1000000 - #endif - --#define CONFIG_LMB -- - #define CONFIG_HOST_MAX_DEVICES 4 - - /* -diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h -index b937233797..32d0723d62 100644 ---- a/include/configs/stm32mp1.h -+++ b/include/configs/stm32mp1.h -@@ -148,7 +148,6 @@ - * and the ramdisk at the end. - */ - #define CONFIG_EXTRA_ENV_SETTINGS \ -- "bootdelay=1\0" \ - "kernel_addr_r=0xc2000000\0" \ - "fdt_addr_r=0xc4000000\0" \ - "scriptaddr=0xc4100000\0" \ -diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h -index 641ed2c5ec..f186dd6b82 100644 ---- a/include/configs/x86-common.h -+++ b/include/configs/x86-common.h -@@ -16,8 +16,6 @@ - */ - #define CONFIG_PHYSMEM - --#define CONFIG_LMB -- - #define CONFIG_SYS_BOOTM_LEN (16 << 20) - - /* SATA AHCI storage */ -diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h -index 8df2facf99..833b0be839 100644 ---- a/include/dm/ofnode.h -+++ b/include/dm/ofnode.h -@@ -344,6 +344,17 @@ const char *ofnode_read_string(ofnode node, const char *propname); - */ - int ofnode_read_u32_array(ofnode node, const char *propname, - u32 *out_values, size_t sz); -+/** -+ * ofnode_is_enabled() - Checks whether a node is enabled. -+ * This looks for a 'status' property. If this exists, then returns true if -+ * the status is 'okay' and false otherwise. If there is no status property, -+ * it returns true on the assumption that anything mentioned should be enabled -+ * by default. -+ * -+ * @node: node to examine -+ * @return false (not enabled) or true (enabled) -+ */ -+bool ofnode_is_enabled(ofnode node); - - /** - * ofnode_read_bool() - read a boolean value from a property -diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h -index 4ec5fa6670..88f10c4622 100644 ---- a/include/dm/uclass-id.h -+++ b/include/dm/uclass-id.h -@@ -94,6 +94,7 @@ enum uclass_id { - UCLASS_RESET, /* Reset controller device */ - UCLASS_RNG, /* Random Number Generator */ - UCLASS_RTC, /* Real time clock device */ -+ UCLASS_SCMI_AGENT, /* Interface with an SCMI server */ - UCLASS_SCSI, /* SCSI device */ - UCLASS_SERIAL, /* Serial UART */ - UCLASS_SIMPLE_BUS, /* Bus with child devices */ -diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h -index 4cdaf13582..ec7b1a9320 100644 ---- a/include/dt-bindings/clock/stm32mp1-clks.h -+++ b/include/dt-bindings/clock/stm32mp1-clks.h -@@ -179,6 +179,12 @@ - #define DAC12_K 168 - #define ETHPTP_K 169 - -+#define PCLK1 170 -+#define PCLK2 171 -+#define PCLK3 172 -+#define PCLK4 173 -+#define PCLK5 174 -+ - /* PLL */ - #define PLL1 176 - #define PLL2 177 -@@ -248,4 +254,31 @@ - - #define STM32MP1_LAST_CLK 232 - -+/* SCMI clock identifiers */ -+#define CK_SCMI0_HSE 0 -+#define CK_SCMI0_HSI 1 -+#define CK_SCMI0_CSI 2 -+#define CK_SCMI0_LSE 3 -+#define CK_SCMI0_LSI 4 -+#define CK_SCMI0_PLL2_Q 5 -+#define CK_SCMI0_PLL2_R 6 -+#define CK_SCMI0_MPU 7 -+#define CK_SCMI0_AXI 8 -+#define CK_SCMI0_BSEC 9 -+#define CK_SCMI0_CRYP1 10 -+#define CK_SCMI0_GPIOZ 11 -+#define CK_SCMI0_HASH1 12 -+#define CK_SCMI0_I2C4 13 -+#define CK_SCMI0_I2C6 14 -+#define CK_SCMI0_IWDG1 15 -+#define CK_SCMI0_RNG1 16 -+#define CK_SCMI0_RTC 17 -+#define CK_SCMI0_RTCAPB 18 -+#define CK_SCMI0_SPI6 19 -+#define CK_SCMI0_USART1 20 -+ -+#define CK_SCMI1_PLL3_Q 0 -+#define CK_SCMI1_PLL3_R 1 -+#define CK_SCMI1_MCU 2 -+ - #endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */ -diff --git a/include/dt-bindings/pinctrl/stm32-pinfunc.h b/include/dt-bindings/pinctrl/stm32-pinfunc.h -index e6fb8ada3f..370a25a936 100644 ---- a/include/dt-bindings/pinctrl/stm32-pinfunc.h -+++ b/include/dt-bindings/pinctrl/stm32-pinfunc.h -@@ -26,6 +26,7 @@ - #define AF14 0xf - #define AF15 0x10 - #define ANALOG 0x11 -+#define RSVD 0x12 - - /* define Pins number*/ - #define PIN_NO(port, line) (((port) - 'A') * 0x10 + (line)) -diff --git a/include/dt-bindings/reset/stm32mp1-resets.h b/include/dt-bindings/reset/stm32mp1-resets.h -index f0c3aaef67..f3a0ed3178 100644 ---- a/include/dt-bindings/reset/stm32mp1-resets.h -+++ b/include/dt-bindings/reset/stm32mp1-resets.h -@@ -7,6 +7,7 @@ - #ifndef _DT_BINDINGS_STM32MP1_RESET_H_ - #define _DT_BINDINGS_STM32MP1_RESET_H_ - -+#define MCU_HOLD_BOOT_R 2144 - #define LTDC_R 3072 - #define DSI_R 3076 - #define DDRPERFM_R 3080 -@@ -105,4 +106,18 @@ - #define GPIOJ_R 19785 - #define GPIOK_R 19786 - -+/* SCMI reset domain identifiers */ -+#define RST_SCMI0_SPI6 0 -+#define RST_SCMI0_I2C4 1 -+#define RST_SCMI0_I2C6 2 -+#define RST_SCMI0_USART1 3 -+#define RST_SCMI0_STGEN 4 -+#define RST_SCMI0_GPIOZ 5 -+#define RST_SCMI0_CRYP1 6 -+#define RST_SCMI0_HASH1 7 -+#define RST_SCMI0_RNG1 8 -+#define RST_SCMI0_MDMA 9 -+#define RST_SCMI0_MCU 10 -+#define RST_SCMI0_MCU_HOLD_BOOT 11 -+ - #endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */ -diff --git a/include/dt-bindings/rtc/rtc-stm32.h b/include/dt-bindings/rtc/rtc-stm32.h -new file mode 100644 -index 0000000000..4373c4dea5 ---- /dev/null -+++ b/include/dt-bindings/rtc/rtc-stm32.h -@@ -0,0 +1,13 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * This header provides constants for STM32_RTC bindings. -+ */ -+ -+#ifndef _DT_BINDINGS_RTC_RTC_STM32_H -+#define _DT_BINDINGS_RTC_RTC_STM32_H -+ -+#define RTC_OUT1 0 -+#define RTC_OUT2 1 -+#define RTC_OUT2_RMP 2 -+ -+#endif -diff --git a/include/dt-bindings/soc/stm32-hdp.h b/include/dt-bindings/soc/stm32-hdp.h -new file mode 100644 -index 0000000000..d986653272 ---- /dev/null -+++ b/include/dt-bindings/soc/stm32-hdp.h -@@ -0,0 +1,108 @@ -+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ -+/* -+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved -+ * Author: Roullier Christophe -+ * for STMicroelectronics. -+ */ -+ -+#ifndef _DT_BINDINGS_STM32_HDP_H -+#define _DT_BINDINGS_STM32_HDP_H -+ -+#define STM32_HDP(port, value) ((value) << ((port) * 4)) -+ -+/* define HDP Pins number*/ -+#define HDP0_PWR_PWRWAKE_SYS 0 -+#define HDP0_CM4_SLEEPDEEP 1 -+#define HDP0_PWR_STDBY_WKUP 2 -+#define HDP0_PWR_ENCOMP_VDDCORE 3 -+#define HDP0_BSEC_OUT_SEC_NIDEN 4 -+#define HDP0_RCC_CM4_SLEEPDEEP 6 -+#define HDP0_GPU_DBG7 7 -+#define HDP0_DDRCTRL_LP_REQ 8 -+#define HDP0_PWR_DDR_RET_ENABLE_N 9 -+#define HDP0_GPOVAL_0 15 -+ -+#define HDP1_PWR_PWRWAKE_MCU 0 -+#define HDP1_CM4_HALTED 1 -+#define HDP1_CA7_NAXIERRIRQ 2 -+#define HDP1_PWR_OKIN_MR 3 -+#define HDP1_BSEC_OUT_SEC_DBGEN 4 -+#define HDP1_EXTI_SYS_WAKEUP 5 -+#define HDP1_RCC_PWRDS_MPU 6 -+#define HDP1_GPU_DBG6 7 -+#define HDP1_DDRCTRL_DFI_CTRLUPD_REQ 8 -+#define HDP1_DDRCTRL_CACTIVE_DDRC_ASR 9 -+#define HDP1_GPOVAL_1 15 -+ -+#define HDP2_PWR_PWRWAKE_MPU 0 -+#define HDP2_CM4_RXEV 1 -+#define HDP2_CA7_NPMUIRQ1 2 -+#define HDP2_CA7_NFIQOUT1 3 -+#define HDP2_BSEC_IN_RSTCORE_N 4 -+#define HDP2_EXTI_C2_WAKEUP 5 -+#define HDP2_RCC_PWRDS_MCU 6 -+#define HDP2_GPU_DBG5 7 -+#define HDP2_DDRCTRL_DFI_INIT_COMPLETE 8 -+#define HDP2_DDRCTRL_PERF_OP_IS_REFRESH 9 -+#define HDP2_DDRCTRL_GSKP_DFI_LP_REQ 10 -+#define HDP2_GPOVAL_2 15 -+ -+#define HDP3_PWR_SEL_VTH_VDD_CORE 0 -+#define HDP3_CM4_TXEV 1 -+#define HDP3_CA7_NPMUIRQ0 2 -+#define HDP3_CA7_NFIQOUT0 3 -+#define HDP3_BSEC_OUT_SEC_DFTLOCK 4 -+#define HDP3_EXTI_C1_WAKEUP 5 -+#define HDP3_RCC_PWRDS_SYS 6 -+#define HDP3_GPU_DBG4 7 -+#define HDP3_DDRCTRL_STAT_DDRC_REG_SELREF_TYPE0 8 -+#define HDP3_DDRCTRL_CACTIVE_1 9 -+#define HDP3_GPOVAL_3 15 -+ -+#define HDP4_PWR_PDDS 0 -+#define HDP4_CM4_SLEEPING 1 -+#define HDP4_CA7_NRESET1 2 -+#define HDP4_CA7_NIRQOUT1 3 -+#define HDP4_BSEC_OUT_SEC_DFTEN 4 -+#define HDP4_BSEC_OUT_SEC_DBGSWENABLE 5 -+#define HDP4_ETH_OUT_PMT_INTR_O 6 -+#define HDP4_GPU_DBG3 7 -+#define HDP4_DDRCTRL_STAT_DDRC_REG_SELREF_TYPE1 8 -+#define HDP4_DDRCTRL_CACTIVE_0 9 -+#define HDP4_GPOVAL_4 15 -+ -+#define HDP5_CA7_STANDBYWFIL2 0 -+#define HDP5_PWR_VTH_VDDCORE_ACK 1 -+#define HDP5_CA7_NRESET0 2 -+#define HDP5_CA7_NIRQOUT0 3 -+#define HDP5_BSEC_IN_PWROK 4 -+#define HDP5_BSEC_OUT_SEC_DEVICEEN 5 -+#define HDP5_ETH_OUT_LPI_INTR_O 6 -+#define HDP5_GPU_DBG2 7 -+#define HDP5_DDRCTRL_CACTIVE_DDRC 8 -+#define HDP5_DDRCTRL_WR_CREDIT_CNT 9 -+#define HDP5_GPOVAL_5 15 -+ -+#define HDP6_CA7_STANDBYWFI1 0 -+#define HDP6_CA7_STANDBYWFE1 1 -+#define HDP6_CA7_EVENT0 2 -+#define HDP6_CA7_DBGACK1 3 -+#define HDP6_BSEC_OUT_SEC_SPNIDEN 5 -+#define HDP6_ETH_OUT_MAC_SPEED_O1 6 -+#define HDP6_GPU_DBG1 7 -+#define HDP6_DDRCTRL_CSYSACK_DDRC 8 -+#define HDP6_DDRCTRL_LPR_CREDIT_CNT 9 -+#define HDP6_GPOVAL_6 15 -+ -+#define HDP7_CA7_STANDBYWFI0 0 -+#define HDP7_CA7_STANDBYWFE0 1 -+#define HDP7_CA7_DBGACK0 3 -+#define HDP7_BSEC_OUT_FUSE_OK 4 -+#define HDP7_BSEC_OUT_SEC_SPIDEN 5 -+#define HDP7_ETH_OUT_MAC_SPEED_O0 6 -+#define HDP7_GPU_DBG0 7 -+#define HDP7_DDRCTRL_CSYSREQ_DDRC 8 -+#define HDP7_DDRCTRL_HPR_CREDIT_CNT 9 -+#define HDP7_GPOVAL_7 15 -+ -+#endif /* _DT_BINDINGS_STM32_HDP_H */ -diff --git a/include/env_internal.h b/include/env_internal.h -index b26dc6239c..67fd729ba0 100644 ---- a/include/env_internal.h -+++ b/include/env_internal.h -@@ -207,6 +207,7 @@ struct env_driver { - #endif - - #define ENV_SAVE_PTR(x) (CONFIG_IS_ENABLED(SAVEENV) ? (x) : NULL) -+#define ENV_ERASE_PTR(x) (CONFIG_IS_ENABLED(CMD_ERASEENV) ? (x) : NULL) - - extern struct hsearch_data env_htab; - -diff --git a/include/fdtdec.h b/include/fdtdec.h -index 152eb07b9e..62d1660973 100644 ---- a/include/fdtdec.h -+++ b/include/fdtdec.h -@@ -1029,7 +1029,7 @@ static inline int fdtdec_set_phandle(void *blob, int node, uint32_t phandle) - * }; - * uint32_t phandle; - * -- * fdtdec_add_reserved_memory(fdt, "framebuffer", &fb, &phandle); -+ * fdtdec_add_reserved_memory(fdt, "framebuffer", &fb, &phandle, false); - * - * This results in the following subnode being added to the top-level - * /reserved-memory node: -@@ -1056,11 +1056,12 @@ static inline int fdtdec_set_phandle(void *blob, int node, uint32_t phandle) - * @param carveout information about the carveout region - * @param phandlep return location for the phandle of the carveout region - * can be NULL if no phandle should be added -+ * @param no_map add "no-map" property if true - * @return 0 on success or a negative error code on failure - */ - int fdtdec_add_reserved_memory(void *blob, const char *basename, - const struct fdt_memory *carveout, -- uint32_t *phandlep); -+ uint32_t *phandlep, bool no_map); - - /** - * fdtdec_get_carveout() - reads a carveout from an FDT -diff --git a/include/image.h b/include/image.h -index 9a5a87dbf8..c2df0b3aa5 100644 ---- a/include/image.h -+++ b/include/image.h -@@ -430,7 +430,7 @@ typedef struct bootm_headers { - #define BOOTM_STATE_OS_GO (0x00000400) - int state; - --#ifdef CONFIG_LMB -+#if defined(CONFIG_LMB) && !defined(USE_HOSTCC) - struct lmb lmb; /* for memory mgmt */ - #endif - } bootm_headers_t; -diff --git a/include/lmb.h b/include/lmb.h -index e9f19b16ea..f839359178 100644 ---- a/include/lmb.h -+++ b/include/lmb.h -@@ -12,22 +12,33 @@ - * Copyright (C) 2001 Peter Bergner, IBM Corp. - */ - --#define MAX_LMB_REGIONS 8 -+/** -+ * enum lmb_flags - definition of memory region attributes -+ * @LMB_NONE: no special request -+ * @LMB_NOMAP: don't add to mmu configuration -+ */ -+enum lmb_flags { -+ LMB_NONE = 0x0, /* No special request */ -+ LMB_NOMAP = 0x4, /* don't add to mmu config */ -+}; - - struct lmb_property { - phys_addr_t base; - phys_size_t size; -+ enum lmb_flags flags; - }; - - struct lmb_region { -- unsigned long cnt; -- phys_size_t size; -- struct lmb_property region[MAX_LMB_REGIONS+1]; -+ unsigned long cnt; /* number of regions */ -+ unsigned long max; /* size of the allocated array */ -+ struct lmb_property *region; - }; - - struct lmb { - struct lmb_region memory; - struct lmb_region reserved; -+ struct lmb_property memory_regions[CONFIG_LMB_MEMORY_REGIONS + 1]; -+ struct lmb_property reserved_regions[CONFIG_LMB_RESERVED_REGIONS + 1]; - }; - - extern void lmb_init(struct lmb *lmb); -@@ -37,6 +48,8 @@ extern void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base, - phys_size_t size, void *fdt_blob); - extern long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size); - extern long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size); -+extern long lmb_reserve_flags(struct lmb *lmb, phys_addr_t base, -+ phys_size_t size, enum lmb_flags flags); - extern phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align); - extern phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, - phys_addr_t max_addr); -@@ -46,6 +59,7 @@ extern phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, - phys_size_t size); - extern phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr); - extern int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr); -+extern int lmb_is_reserved_flags(struct lmb *lmb, phys_addr_t addr, int flags); - extern long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size); - - extern void lmb_dump_all(struct lmb *lmb); -@@ -60,6 +74,13 @@ lmb_size_bytes(struct lmb_region *type, unsigned long region_nr) - void board_lmb_reserve(struct lmb *lmb); - void arch_lmb_reserve(struct lmb *lmb); - -+/* Low level functions */ -+ -+static inline bool lmb_is_nomap(struct lmb_property *m) -+{ -+ return !!(m->flags & LMB_NOMAP); -+} -+ - #endif /* __KERNEL__ */ - - #endif /* _LINUX_LMB_H */ -diff --git a/include/mipi_dsi.h b/include/mipi_dsi.h -index c8a7d3daef..4ca05f71e2 100644 ---- a/include/mipi_dsi.h -+++ b/include/mipi_dsi.h -@@ -96,6 +96,20 @@ struct mipi_dsi_host_ops { - const struct mipi_dsi_msg *msg); - }; - -+/** -+ * struct mipi_dsi_phy_timing - DSI host phy timings -+ * @data_hs2lp: High Speed to Low Speed Data Transition Time -+ * @data_lp2hs: Low Speed to High Speed Data Transition Time -+ * @clk_hs2lp: High Speed to Low Speed Clock Transition Time -+ * @clk_lp2hs: Low Speed to High Speed Clock Transition Time -+ */ -+struct mipi_dsi_phy_timing { -+ u16 data_hs2lp; -+ u16 data_lp2hs; -+ u16 clk_hs2lp; -+ u16 clk_lp2hs; -+}; -+ - /** - * struct mipi_dsi_phy_ops - DSI host physical operations - * @init: initialized host physical part -@@ -107,6 +121,9 @@ struct mipi_dsi_phy_ops { - int (*get_lane_mbps)(void *priv_data, struct display_timing *timings, - u32 lanes, u32 format, unsigned int *lane_mbps); - void (*post_set_mode)(void *priv_data, unsigned long mode_flags); -+ int (*get_timing)(void *priv_data, unsigned int lane_mbps, -+ struct mipi_dsi_phy_timing *timing); -+ void (*get_esc_clk_rate)(void *priv_data, unsigned int *esc_clk_rate); - }; - - /** -diff --git a/include/rproc_optee.h b/include/rproc_optee.h -new file mode 100644 -index 0000000000..13193bbe77 ---- /dev/null -+++ b/include/rproc_optee.h -@@ -0,0 +1,127 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ -+/* -+ * Copyright (C) STMicroelectronics 2020 - All Rights Reserved -+ */ -+ -+#ifndef _RPROC_OPTEE_H_ -+#define _RPROC_OPTEE_H_ -+ -+/** -+ * struct rproc_optee - TEE remoteproc structure -+ * @tee: TEE device -+ * @fw_id: Identifier of the target firmware -+ * @session: TEE session identifier -+ */ -+struct rproc_optee { -+ struct udevice *tee; -+ u32 fw_id; -+ u32 session; -+}; -+ -+#if IS_ENABLED(CONFIG_REMOTEPROC_OPTEE) -+ -+/** -+ * rproc_optee_open() - open a rproc tee session -+ * -+ * Open a session towards the trusted application in charge of the remote -+ * processor. -+ * -+ * @trproc: OPTEE remoteproc context structure -+ * -+ * @return 0 if the session is opened, or an appropriate error value. -+ */ -+int rproc_optee_open(struct rproc_optee *trproc); -+ -+/** -+ * rproc_optee_close() - close a rproc tee session -+ * -+ * Close the trusted application session in charge of the remote processor. -+ * -+ * @trproc: OPTEE remoteproc context structure -+ * -+ * @return 0 on success, or an appropriate error value. -+ */ -+int rproc_optee_close(struct rproc_optee *trproc); -+ -+/** -+ * rproc_optee_start() - Request OP-TEE to start a remote processor -+ * -+ * @trproc: OPTEE remoteproc context structure -+ * -+ * @return 0 on success, or an appropriate error value. -+ */ -+int rproc_optee_start(struct rproc_optee *trproc); -+ -+/** -+ * rproc_optee_stop() - Request OP-TEE to stop a remote processor -+ * -+ * @trproc: OPTEE remoteproc context structure -+ * -+ * @return 0 on success, or an appropriate error value. -+ */ -+int rproc_optee_stop(struct rproc_optee *trproc); -+ -+/** -+ * rproc_optee_get_rsc_table() - Request OP-TEE the resource table -+ * -+ * Get the address and the size of the resource table. If no resource table is -+ * found, the size and address are null. -+ * -+ * @trproc: OPTEE remoteproc context structure -+ * @rsc_addr: out the physical address of the resource table returned -+ * @rsc_size: out the size of the resource table -+ * -+ * @return 0 on success, or an appropriate error value. -+ */ -+int rproc_optee_get_rsc_table(struct rproc_optee *trproc, phys_addr_t *rsc_addr, -+ phys_size_t *rsc_size); -+ -+/** -+ * rproc_optee_load() - load an signed ELF image -+ * -+ * @trproc: OPTEE remoteproc context structure -+ * @addr: valid ELF image address -+ * @size: size of the image -+ * -+ * @return 0 if the image is successfully loaded, else appropriate error value. -+ */ -+int rproc_optee_load(struct rproc_optee *trproc, ulong addr, ulong size); -+ -+#else -+ -+static inline int rproc_optee_open(struct rproc_optee *trproc) -+{ -+ return -ENOSYS; -+} -+ -+static inline int rproc_optee_close(struct rproc_optee *trproc) -+{ -+ return -ENOSYS; -+} -+ -+static inline int rproc_optee_start(struct rproc_optee *trproc) -+{ -+ return -ENOSYS; -+} -+ -+static inline int rproc_optee_stop(struct rproc_optee *trproc) -+{ -+ return -ENOSYS; -+} -+ -+static inline int rproc_optee_get_rsc_table(struct rproc_optee *trproc, -+ phys_addr_t *rsc_addr, -+ phys_size_t *rsc_size) -+{ -+ return -ENOSYS; -+} -+ -+static inline int rproc_optee_load(struct rproc_optee *trproc, ulong addr, -+ ulong size) -+{ -+ return -ENOSYS; -+} -+ -+#endif -+ -+#endif /* _RPROC_OPTEE_H_ */ -diff --git a/include/scmi_agent-uclass.h b/include/scmi_agent-uclass.h -new file mode 100644 -index 0000000000..a501d1b482 ---- /dev/null -+++ b/include/scmi_agent-uclass.h -@@ -0,0 +1,24 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ -+/* -+ * Copyright (C) 2019-2020 Linaro Limited. -+ */ -+#ifndef _SCMI_AGENT_UCLASS_H -+#define _SCMI_AGENT_UCLASS_H -+ -+struct udevice; -+struct scmi_msg; -+ -+/** -+ * struct scmi_transport_ops - The functions that a SCMI transport layer must implement. -+ */ -+struct scmi_agent_ops { -+ /* -+ * process_msg - Request transport to get the SCMI message processed -+ * -+ * @agent: Agent using the transport -+ * @msg: SCMI message to be transmitted -+ */ -+ int (*process_msg)(struct udevice *dev, struct scmi_msg *msg); -+}; -+ -+#endif /* _SCMI_TRANSPORT_UCLASS_H */ -diff --git a/include/scmi_agent.h b/include/scmi_agent.h -new file mode 100644 -index 0000000000..f1be9ff209 ---- /dev/null -+++ b/include/scmi_agent.h -@@ -0,0 +1,68 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* -+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (C) 2019-2020, Linaro Limited -+ * -+ * An SCMI agent device represent on communication path from a -+ * device driver to the remote SCMI server which driver sends -+ * messages to and receives response messages from. -+ */ -+#ifndef SCMI_AGENT_H -+#define SCMI_AGENT_H -+ -+#include -+ -+struct udevice; -+ -+/* -+ * struct scmi_msg - Context of a SCMI message sent and the response received -+ * -+ * @protocol_id: SCMI protocol ID -+ * @message_id: SCMI message ID for a defined protocol ID -+ * @in_msg: Pointer to the message payload sent by the driver -+ * @in_msg_sz: Byte size of the message payload sent -+ * @out_msg: Pointer to buffer to store response message payload -+ * @out_msg_sz: Byte size of the response buffer and response payload -+ */ -+struct scmi_msg { -+ unsigned int protocol_id; -+ unsigned int message_id; -+ u8 *in_msg; -+ size_t in_msg_sz; -+ u8 *out_msg; -+ size_t out_msg_sz; -+}; -+ -+/* Helper macro to match a message on input/output array references */ -+#define SCMI_MSG_IN(_protocol, _message, _in_array, _out_array) \ -+ (struct scmi_msg){ \ -+ .protocol_id = (_protocol), \ -+ .message_id = (_message), \ -+ .in_msg = (uint8_t *)&(_in_array), \ -+ .in_msg_sz = sizeof(_in_array), \ -+ .out_msg = (uint8_t *)&(_out_array), \ -+ .out_msg_sz = sizeof(_out_array), \ -+ } -+ -+/** -+ * scmi_send_and_process_msg() - send and process a SCMI message -+ * -+ * Send a message to a SCMI server through a target SCMI agent device. -+ * Caller sets scmi_msg::out_msg_sz to the output message buffer size. -+ * On return, scmi_msg::out_msg_sz stores the response payload size. -+ * -+ * @dev: SCMI agent device -+ * @msg: Message structure reference -+ * @return 0 on success and a negative errno on failure -+ */ -+int devm_scmi_process_msg(struct udevice *dev, struct scmi_msg *msg); -+ -+/** -+ * scmi_to_linux_errno() - Convert an SCMI error code into a Linux errno code -+ * -+ * @scmi_errno: SCMI error code value -+ * @return 0 for successful status and a negative errno otherwise -+ */ -+int scmi_to_linux_errno(s32 scmi_errno); -+ -+#endif /* SCMI_H */ -diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h -new file mode 100644 -index 0000000000..ccab97c96c ---- /dev/null -+++ b/include/scmi_protocols.h -@@ -0,0 +1,179 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* -+ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. -+ * Copyright (C) 2019-2020, Linaro Limited -+ */ -+#ifndef _SCMI_PROTOCOLS_H -+#define _SCMI_PROTOCOLS_H -+ -+#include -+#include -+ -+/* -+ * Subset the SCMI protocols definition -+ * based on SCMI specification v2.0 (DEN0056B) -+ * https://developer.arm.com/docs/den0056/b -+ */ -+ -+enum scmi_std_protocol { -+ SCMI_PROTOCOL_ID_BASE = 0x10, -+ SCMI_PROTOCOL_ID_POWER_DOMAIN = 0x11, -+ SCMI_PROTOCOL_ID_SYSTEM = 0x12, -+ SCMI_PROTOCOL_ID_PERF = 0x13, -+ SCMI_PROTOCOL_ID_CLOCK = 0x14, -+ SCMI_PROTOCOL_ID_SENSOR = 0x15, -+ SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16, -+}; -+ -+enum scmi_status_code { -+ SCMI_SUCCESS = 0, -+ SCMI_NOT_SUPPORTED = -1, -+ SCMI_INVALID_PARAMETERS = -2, -+ SCMI_DENIED = -3, -+ SCMI_NOT_FOUND = -4, -+ SCMI_OUT_OF_RANGE = -5, -+ SCMI_BUSY = -6, -+ SCMI_COMMS_ERROR = -7, -+ SCMI_GENERIC_ERROR = -8, -+ SCMI_HARDWARE_ERROR = -9, -+ SCMI_PROTOCOL_ERROR = -10, -+}; -+ -+/* -+ * SCMI Clock Protocol -+ */ -+ -+enum scmi_clock_message_id { -+ SCMI_CLOCK_RATE_SET = 0x5, -+ SCMI_CLOCK_RATE_GET = 0x6, -+ SCMI_CLOCK_CONFIG_SET = 0x7, -+}; -+ -+#define SCMI_CLK_RATE_ASYNC_NOTIFY BIT(0) -+#define SCMI_CLK_RATE_ASYNC_NORESP (BIT(0) | BIT(1)) -+#define SCMI_CLK_RATE_ROUND_DOWN 0 -+#define SCMI_CLK_RATE_ROUND_UP BIT(2) -+#define SCMI_CLK_RATE_ROUND_CLOSEST BIT(3) -+ -+/** -+ * struct scmi_clk_state_in - Message payload for CLOCK_CONFIG_SET command -+ * @clock_id: SCMI clock ID -+ * @attributes: Attributes of the targets clock state -+ */ -+struct scmi_clk_state_in { -+ u32 clock_id; -+ u32 attributes; -+}; -+ -+/** -+ * struct scmi_clk_state_out - Response payload for CLOCK_CONFIG_SET command -+ * @status: SCMI command status -+ */ -+struct scmi_clk_state_out { -+ s32 status; -+}; -+ -+/** -+ * struct scmi_clk_state_in - Message payload for CLOCK_RATE_GET command -+ * @clock_id: SCMI clock ID -+ * @attributes: Attributes of the targets clock state -+ */ -+struct scmi_clk_rate_get_in { -+ u32 clock_id; -+}; -+ -+/** -+ * struct scmi_clk_rate_get_out - Response payload for CLOCK_RATE_GET command -+ * @status: SCMI command status -+ * @rate_lsb: 32bit LSB of the clock rate in Hertz -+ * @rate_msb: 32bit MSB of the clock rate in Hertz -+ */ -+struct scmi_clk_rate_get_out { -+ s32 status; -+ u32 rate_lsb; -+ u32 rate_msb; -+}; -+ -+/** -+ * struct scmi_clk_state_in - Message payload for CLOCK_RATE_SET command -+ * @clock_id: SCMI clock ID -+ * @flags: Flags for the clock rate set request -+ * @rate_lsb: 32bit LSB of the clock rate in Hertz -+ * @rate_msb: 32bit MSB of the clock rate in Hertz -+ */ -+struct scmi_clk_rate_set_in { -+ u32 clock_id; -+ u32 flags; -+ u32 rate_lsb; -+ u32 rate_msb; -+}; -+ -+/** -+ * struct scmi_clk_rate_set_out - Response payload for CLOCK_RATE_SET command -+ * @status: SCMI command status -+ */ -+struct scmi_clk_rate_set_out { -+ s32 status; -+}; -+ -+/* -+ * SCMI Reset Domain Protocol -+ */ -+ -+enum scmi_reset_domain_message_id { -+ SCMI_RESET_DOMAIN_ATTRIBUTES = 0x3, -+ SCMI_RESET_DOMAIN_RESET = 0x4, -+}; -+ -+#define SCMI_RD_NAME_LEN 16 -+ -+#define SCMI_RD_ATTRIBUTES_FLAG_ASYNC BIT(31) -+#define SCMI_RD_ATTRIBUTES_FLAG_NOTIF BIT(30) -+ -+#define SCMI_RD_RESET_FLAG_ASYNC BIT(2) -+#define SCMI_RD_RESET_FLAG_ASSERT BIT(1) -+#define SCMI_RD_RESET_FLAG_CYCLE BIT(0) -+ -+/** -+ * struct scmi_rd_attr_in - Payload for RESET_DOMAIN_ATTRIBUTES message -+ * @domain_id: SCMI reset domain ID -+ */ -+struct scmi_rd_attr_in { -+ u32 domain_id; -+}; -+ -+/** -+ * struct scmi_rd_attr_out - Payload for RESET_DOMAIN_ATTRIBUTES response -+ * @status: SCMI command status -+ * @attributes: Retrieved attributes of the reset domain -+ * @latency: Reset cycle max lantency -+ * @name: Reset domain name -+ */ -+struct scmi_rd_attr_out { -+ s32 status; -+ u32 attributes; -+ u32 latency; -+ char name[SCMI_RD_NAME_LEN]; -+}; -+ -+/** -+ * struct scmi_rd_reset_in - Message payload for RESET command -+ * @domain_id: SCMI reset domain ID -+ * @flags: Flags for the reset request -+ * @reset_state: Reset target state -+ */ -+struct scmi_rd_reset_in { -+ u32 domain_id; -+ u32 flags; -+ u32 reset_state; -+}; -+ -+/** -+ * struct scmi_rd_reset_out - Response payload for RESET command -+ * @status: SCMI command status -+ */ -+struct scmi_rd_reset_out { -+ s32 status; -+}; -+ -+#endif /* _SCMI_PROTOCOLS_H */ -diff --git a/include/usb/dwc2_udc.h b/include/usb/dwc2_udc.h -index a2af381a66..aa37e957b4 100644 ---- a/include/usb/dwc2_udc.h -+++ b/include/usb/dwc2_udc.h -@@ -28,6 +28,7 @@ struct dwc2_plat_otg_data { - unsigned int tx_fifo_sz_array[DWC2_MAX_HW_ENDPOINTS]; - unsigned char tx_fifo_sz_nb; - bool force_b_session_valid; -+ bool force_vbus_detection; - bool activate_stm_id_vb_detection; - }; - -diff --git a/lib/Kconfig b/lib/Kconfig -index 8efb154f73..c27204c520 100644 ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -684,4 +684,27 @@ config LIB_ELF - Supoort basic elf loading/validating functions. - This supports fir 32 bit and 64 bit versions. - -+config LMB -+ bool "Enable the logical memory blocks library (lmb)" -+ default y if ARC || ARM || M68K || MICROBLAZE || MIPS || NDS32 || \ -+ NIOS2 || PPC || RISCV || SANDBOX || SH || X86 || XTENSA -+ help -+ Support the library logical memory blocks. -+ -+config LMB_MEMORY_REGIONS -+ int "Number of memory regions in lmb lib" -+ depends on LMB -+ default 8 -+ help -+ Define the number of supported memory regions in the library logical -+ memory blocks. -+ -+config LMB_RESERVED_REGIONS -+ int "Number of reserved regions in lmb lib" -+ depends on LMB -+ default 8 -+ help -+ Define the number of supported reserved regions in the library logical -+ memory blocks. -+ - endmenu -diff --git a/lib/fdtdec.c b/lib/fdtdec.c -index 5f41f58a63..f16a85c8c5 100644 ---- a/lib/fdtdec.c -+++ b/lib/fdtdec.c -@@ -1319,7 +1319,7 @@ static int fdtdec_init_reserved_memory(void *blob) - - int fdtdec_add_reserved_memory(void *blob, const char *basename, - const struct fdt_memory *carveout, -- uint32_t *phandlep) -+ uint32_t *phandlep, bool no_map) - { - fdt32_t cells[4] = {}, *ptr = cells; - uint32_t upper, lower, phandle; -@@ -1419,6 +1419,12 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename, - if (err < 0) - return err; - -+ if (no_map) { -+ err = fdt_setprop(blob, node, "no-map", NULL, 0); -+ if (err < 0) -+ return err; -+ } -+ - /* return the phandle for the new node for the caller to use */ - if (phandlep) - *phandlep = phandle; -@@ -1484,7 +1490,7 @@ int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name, - fdt32_t value; - void *prop; - -- err = fdtdec_add_reserved_memory(blob, name, carveout, &phandle); -+ err = fdtdec_add_reserved_memory(blob, name, carveout, &phandle, false); - if (err < 0) { - debug("failed to add reserved memory: %d\n", err); - return err; -diff --git a/lib/lmb.c b/lib/lmb.c -index 75082f3559..6729c341b0 100644 ---- a/lib/lmb.c -+++ b/lib/lmb.c -@@ -14,32 +14,32 @@ - - #define LMB_ALLOC_ANYWHERE 0 - --void lmb_dump_all_force(struct lmb *lmb) -+static void lmb_dump_region(struct lmb_region *rgn, char *name) - { -- unsigned long i; -+ unsigned long long base, size, end; -+ enum lmb_flags flags; -+ int i; - -- printf("lmb_dump_all:\n"); -- printf(" memory.cnt = 0x%lx\n", lmb->memory.cnt); -- printf(" memory.size = 0x%llx\n", -- (unsigned long long)lmb->memory.size); -- for (i = 0; i < lmb->memory.cnt; i++) { -- printf(" memory.reg[0x%lx].base = 0x%llx\n", i, -- (unsigned long long)lmb->memory.region[i].base); -- printf(" .size = 0x%llx\n", -- (unsigned long long)lmb->memory.region[i].size); -- } -+ printf(" %s.cnt = 0x%lx\n", name, rgn->cnt); - -- printf("\n reserved.cnt = 0x%lx\n", lmb->reserved.cnt); -- printf(" reserved.size = 0x%llx\n", -- (unsigned long long)lmb->reserved.size); -- for (i = 0; i < lmb->reserved.cnt; i++) { -- printf(" reserved.reg[0x%lx].base = 0x%llx\n", i, -- (unsigned long long)lmb->reserved.region[i].base); -- printf(" .size = 0x%llx\n", -- (unsigned long long)lmb->reserved.region[i].size); -+ for (i = 0; i < rgn->cnt; i++) { -+ base = rgn->region[i].base; -+ size = rgn->region[i].size; -+ end = base + size - 1; -+ flags = rgn->region[i].flags; -+ -+ printf(" %s[%d]\t[0x%llx-0x%llx], 0x%08llx bytes flags: %x\n", -+ name, i, base, end, size, flags); - } - } - -+void lmb_dump_all_force(struct lmb *lmb) -+{ -+ printf("lmb_dump_all:\n"); -+ lmb_dump_region(&lmb->memory, "memory"); -+ lmb_dump_region(&lmb->reserved, "reserved"); -+} -+ - void lmb_dump_all(struct lmb *lmb) - { - #ifdef DEBUG -@@ -85,6 +85,7 @@ static void lmb_remove_region(struct lmb_region *rgn, unsigned long r) - for (i = r; i < rgn->cnt - 1; i++) { - rgn->region[i].base = rgn->region[i + 1].base; - rgn->region[i].size = rgn->region[i + 1].size; -+ rgn->region[i].flags = rgn->region[i + 1].flags; - } - rgn->cnt--; - } -@@ -99,10 +100,14 @@ static void lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, - - void lmb_init(struct lmb *lmb) - { -+ /* Hookup the initial arrays */ -+ lmb->memory.region = lmb->memory_regions; -+ lmb->memory.max = ARRAY_SIZE(lmb->memory_regions) - 1; - lmb->memory.cnt = 0; -- lmb->memory.size = 0; -+ -+ lmb->reserved.region = lmb->reserved_regions; -+ lmb->reserved.max = ARRAY_SIZE(lmb->reserved_regions) - 1; - lmb->reserved.cnt = 0; -- lmb->reserved.size = 0; - } - - static void lmb_reserve_common(struct lmb *lmb, void *fdt_blob) -@@ -146,7 +151,8 @@ void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base, - } - - /* This routine called with relocation disabled. */ --static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t size) -+static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, -+ phys_size_t size, enum lmb_flags flags) - { - unsigned long coalesced = 0; - long adjacent, i; -@@ -154,6 +160,7 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t - if (rgn->cnt == 0) { - rgn->region[0].base = base; - rgn->region[0].size = size; -+ rgn->region[0].flags = flags; - rgn->cnt = 1; - return 0; - } -@@ -162,18 +169,27 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t - for (i = 0; i < rgn->cnt; i++) { - phys_addr_t rgnbase = rgn->region[i].base; - phys_size_t rgnsize = rgn->region[i].size; -+ phys_size_t rgnflags = rgn->region[i].flags; - -- if ((rgnbase == base) && (rgnsize == size)) -- /* Already have this region, so we're done */ -- return 0; -+ if (rgnbase == base && rgnsize == size) { -+ if (flags == rgnflags) -+ /* Already have this region, so we're done */ -+ return 0; -+ else -+ return -1; /* regions with new flags */ -+ } - - adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); - if (adjacent > 0) { -+ if (flags != rgnflags) -+ break; - rgn->region[i].base -= size; - rgn->region[i].size += size; - coalesced++; - break; - } else if (adjacent < 0) { -+ if (flags != rgnflags) -+ break; - rgn->region[i].size += size; - coalesced++; - break; -@@ -184,13 +200,15 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t - } - - if ((i < rgn->cnt - 1) && lmb_regions_adjacent(rgn, i, i + 1)) { -- lmb_coalesce_regions(rgn, i, i + 1); -- coalesced++; -+ if (rgn->region[i].flags == rgn->region[i + 1].flags) { -+ lmb_coalesce_regions(rgn, i, i + 1); -+ coalesced++; -+ } - } - - if (coalesced) - return coalesced; -- if (rgn->cnt >= MAX_LMB_REGIONS) -+ if (rgn->cnt >= rgn->max) - return -1; - - /* Couldn't coalesce the LMB, so add it to the sorted table. */ -@@ -198,9 +216,11 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t - if (base < rgn->region[i].base) { - rgn->region[i + 1].base = rgn->region[i].base; - rgn->region[i + 1].size = rgn->region[i].size; -+ rgn->region[i + 1].flags = rgn->region[i].flags; - } else { - rgn->region[i + 1].base = base; - rgn->region[i + 1].size = size; -+ rgn->region[i + 1].flags = flags; - break; - } - } -@@ -208,6 +228,7 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t - if (base < rgn->region[0].base) { - rgn->region[0].base = base; - rgn->region[0].size = size; -+ rgn->region[0].flags = flags; - } - - rgn->cnt++; -@@ -215,6 +236,12 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t - return 0; - } - -+static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, -+ phys_size_t size) -+{ -+ return lmb_add_region_flags(rgn, base, size, LMB_NONE); -+} -+ - /* This routine may be called with relocation disabled. */ - long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size) - { -@@ -269,14 +296,21 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) - * beginging of the hole and add the region after hole. - */ - rgn->region[i].size = base - rgn->region[i].base; -- return lmb_add_region(rgn, end + 1, rgnend - end); -+ return lmb_add_region_flags(rgn, end + 1, rgnend - end, -+ rgn->region[i].flags); - } - --long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size) -+long lmb_reserve_flags(struct lmb *lmb, phys_addr_t base, phys_size_t size, -+ enum lmb_flags flags) - { - struct lmb_region *_rgn = &(lmb->reserved); - -- return lmb_add_region(_rgn, base, size); -+ return lmb_add_region_flags(_rgn, base, size, flags); -+} -+ -+long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size) -+{ -+ return lmb_reserve_flags(lmb, base, size, LMB_NONE); - } - - static long lmb_overlaps_region(struct lmb_region *rgn, phys_addr_t base, -@@ -411,7 +445,7 @@ phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr) - return 0; - } - --int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr) -+int lmb_is_reserved_flags(struct lmb *lmb, phys_addr_t addr, int flags) - { - int i; - -@@ -419,11 +453,17 @@ int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr) - phys_addr_t upper = lmb->reserved.region[i].base + - lmb->reserved.region[i].size - 1; - if ((addr >= lmb->reserved.region[i].base) && (addr <= upper)) -- return 1; -+ return !!((lmb->reserved.region[i].flags & flags) -+ == flags); - } - return 0; - } - -+int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr) -+{ -+ return lmb_is_reserved_flags(lmb, addr, LMB_NONE); -+} -+ - __weak void board_lmb_reserve(struct lmb *lmb) - { - /* please define platform specific board_lmb_reserve() */ -diff --git a/lib/optee/optee.c b/lib/optee/optee.c -index 457d4cca8a..9e6606568f 100644 ---- a/lib/optee/optee.c -+++ b/lib/optee/optee.c -@@ -192,7 +192,7 @@ int optee_copy_fdt_nodes(const void *old_blob, void *new_blob) - ret = fdtdec_add_reserved_memory(new_blob, - nodename, - &carveout, -- NULL); -+ NULL, true); - free(oldname); - - if (ret < 0) -diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt -index 093e432efc..bb6aef5ce4 100644 ---- a/scripts/config_whitelist.txt -+++ b/scripts/config_whitelist.txt -@@ -970,7 +970,6 @@ CONFIG_LG4573 - CONFIG_LINUX - CONFIG_LINUX_RESET_VEC - CONFIG_LITTLETON_LCD --CONFIG_LMB - CONFIG_LMS283GF05 - CONFIG_LOADADDR - CONFIG_LOADCMD -diff --git a/test/dm/Makefile b/test/dm/Makefile -index 864c8d0b4c..70ba1b6695 100644 ---- a/test/dm/Makefile -+++ b/test/dm/Makefile -@@ -80,4 +80,5 @@ obj-$(CONFIG_DM_RNG) += rng.o - obj-$(CONFIG_CLK_K210_SET_RATE) += k210_pll.o - obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o - obj-$(CONFIG_RESET_SYSCON) += syscon-reset.o -+obj-$(CONFIG_SCMI_FIRMWARE) += scmi.o - endif -diff --git a/test/dm/fdtdec.c b/test/dm/fdtdec.c -index 716993f706..017157a2ec 100644 ---- a/test/dm/fdtdec.c -+++ b/test/dm/fdtdec.c -@@ -80,7 +80,7 @@ static int dm_test_fdtdec_add_reserved_memory(struct unit_test_state *uts) - resv.start = 0x1000; - resv.end = 0x1fff; - ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region", -- &resv, &phandle)); -+ &resv, &phandle, false)); - - /* Test /reserve-memory and its subnode should exist */ - parent = fdt_path_offset(blob, "/reserved-memory"); -@@ -101,10 +101,13 @@ static int dm_test_fdtdec_add_reserved_memory(struct unit_test_state *uts) - resv.start = 0x2000; - resv.end = 0x2fff; - ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region1", -- &resv, &phandle1)); -+ &resv, &phandle1, true)); - subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region1"); - ut_assert(subnode > 0); - -+ /* check that no-map property is present */ -+ ut_assert(fdt_getprop(blob, subnode, "no-map", NULL) > 0); -+ - /* phandles must be different */ - ut_assert(phandle != phandle1); - -@@ -115,7 +118,7 @@ static int dm_test_fdtdec_add_reserved_memory(struct unit_test_state *uts) - resv.start = 0x1000; - resv.end = 0x1fff; - ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region2", -- &resv, &phandle1)); -+ &resv, &phandle1, false)); - subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region2"); - ut_assert(subnode < 0); - -diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c -index 8bfb706602..9a34fdd7a2 100644 ---- a/test/dm/ofnode.c -+++ b/test/dm/ofnode.c -@@ -136,3 +136,15 @@ static int dm_test_ofnode_get_child_count(struct unit_test_state *uts) - } - DM_TEST(dm_test_ofnode_get_child_count, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); -+ -+static int dm_test_ofnode_is_enabled(struct unit_test_state *uts) -+{ -+ ofnode root_node = ofnode_path("/"); -+ ofnode node = ofnode_path("/usb@0"); -+ -+ ut_assert(ofnode_is_enabled(root_node)); -+ ut_assert(!ofnode_is_enabled(node)); -+ -+ return 0; -+} -+DM_TEST(dm_test_ofnode_is_enabled, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); -diff --git a/test/dm/scmi.c b/test/dm/scmi.c -new file mode 100644 -index 0000000000..be60b44b3b ---- /dev/null -+++ b/test/dm/scmi.c -@@ -0,0 +1,203 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2020, Linaro Limited -+ * -+ * Tests scmi_agent uclass and the SCMI drivers implemented in other -+ * uclass devices probe when a SCMI server exposes resources. -+ * -+ * Note in test.dts the protocol@10 node in agent 1. Protocol 0x10 is not -+ * implemented in U-Boot SCMI components but the implementation is exepected -+ * to not complain on unknown protocol IDs, as long as it is not used. Note -+ * in test.dts tests that SCMI drivers probing does not fail for such an -+ * unknown SCMI protocol ID. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static int ut_assert_scmi_state_preprobe(struct unit_test_state *uts) -+{ -+ struct sandbox_scmi_service *scmi_ctx = sandbox_scmi_service_ctx(); -+ -+ ut_assertnonnull(scmi_ctx); -+ if (scmi_ctx->agent_count) -+ ut_asserteq(2, scmi_ctx->agent_count); -+ -+ return 0; -+} -+ -+static int ut_assert_scmi_state_postprobe(struct unit_test_state *uts, -+ struct udevice *dev) -+{ -+ struct sandbox_scmi_devices *scmi_devices; -+ struct sandbox_scmi_service *scmi_ctx; -+ -+ /* Device references to check context against test sequence */ -+ scmi_devices = sandbox_scmi_devices_ctx(dev); -+ -+ ut_assertnonnull(scmi_devices); -+ if (IS_ENABLED(CONFIG_CLK_SCMI)) -+ ut_asserteq(3, scmi_devices->clk_count); -+ if (IS_ENABLED(CONFIG_RESET_SCMI)) -+ ut_asserteq(1, scmi_devices->reset_count); -+ -+ /* State of the simulated SCMI server exposed */ -+ scmi_ctx = sandbox_scmi_service_ctx(); -+ -+ ut_asserteq(2, scmi_ctx->agent_count); -+ -+ ut_assertnonnull(scmi_ctx->agent[0]); -+ ut_asserteq(2, scmi_ctx->agent[0]->clk_count); -+ ut_assertnonnull(scmi_ctx->agent[0]->clk); -+ ut_asserteq(1, scmi_ctx->agent[0]->reset_count); -+ ut_assertnonnull(scmi_ctx->agent[0]->reset); -+ -+ ut_assertnonnull(scmi_ctx->agent[1]); -+ ut_assertnonnull(scmi_ctx->agent[1]->clk); -+ ut_asserteq(1, scmi_ctx->agent[1]->clk_count); -+ -+ return 0; -+} -+ -+static int load_sandbox_scmi_test_devices(struct unit_test_state *uts, -+ struct udevice **dev) -+{ -+ int ret; -+ -+ ret = ut_assert_scmi_state_preprobe(uts); -+ if (ret) -+ return ret; -+ -+ ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "sandbox_scmi", -+ dev)); -+ ut_assertnonnull(*dev); -+ -+ return ut_assert_scmi_state_postprobe(uts, *dev); -+} -+ -+static int release_sandbox_scmi_test_devices(struct unit_test_state *uts, -+ struct udevice *dev) -+{ -+ ut_assertok(device_remove(dev, DM_REMOVE_NORMAL)); -+ -+ /* Not sure test devices are fully removed, agent may not be visible */ -+ return 0; -+} -+ -+/* -+ * Test SCMI states when loading and releasing resources -+ * related to SCMI drivers. -+ */ -+static int dm_test_scmi_sandbox_agent(struct unit_test_state *uts) -+{ -+ struct udevice *dev = NULL; -+ int ret; -+ -+ ret = load_sandbox_scmi_test_devices(uts, &dev); -+ if (!ret) -+ ret = release_sandbox_scmi_test_devices(uts, dev); -+ -+ return ret; -+} -+ -+DM_TEST(dm_test_scmi_sandbox_agent, UT_TESTF_SCAN_FDT); -+ -+static int dm_test_scmi_clocks(struct unit_test_state *uts) -+{ -+ struct sandbox_scmi_devices *scmi_devices; -+ struct sandbox_scmi_service *scmi_ctx; -+ struct udevice *dev = NULL; -+ int ret_dev; -+ int ret; -+ -+ if (!IS_ENABLED(CONFIG_CLK_SCMI)) -+ return 0; -+ -+ ret = load_sandbox_scmi_test_devices(uts, &dev); -+ if (ret) -+ return ret; -+ -+ scmi_devices = sandbox_scmi_devices_ctx(dev); -+ scmi_ctx = sandbox_scmi_service_ctx(); -+ -+ /* Test SCMI clocks rate manipulation */ -+ ut_asserteq(1000, clk_get_rate(&scmi_devices->clk[0])); -+ ut_asserteq(333, clk_get_rate(&scmi_devices->clk[1])); -+ ut_asserteq(44, clk_get_rate(&scmi_devices->clk[2])); -+ -+ ret_dev = clk_set_rate(&scmi_devices->clk[1], 1088); -+ ut_assert(!ret_dev || ret_dev == 1088); -+ -+ ut_asserteq(1000, scmi_ctx->agent[0]->clk[0].rate); -+ ut_asserteq(1088, scmi_ctx->agent[0]->clk[1].rate); -+ ut_asserteq(44, scmi_ctx->agent[1]->clk[0].rate); -+ -+ ut_asserteq(1000, clk_get_rate(&scmi_devices->clk[0])); -+ ut_asserteq(1088, clk_get_rate(&scmi_devices->clk[1])); -+ ut_asserteq(44, clk_get_rate(&scmi_devices->clk[2])); -+ -+ /* restore original rate for further tests */ -+ ret_dev = clk_set_rate(&scmi_devices->clk[1], 333); -+ ut_assert(!ret_dev || ret_dev == 333); -+ -+ /* Test SCMI clocks gating manipulation */ -+ ut_assert(!scmi_ctx->agent[0]->clk[0].enabled); -+ ut_assert(!scmi_ctx->agent[0]->clk[1].enabled); -+ ut_assert(!scmi_ctx->agent[1]->clk[0].enabled); -+ -+ ut_asserteq(0, clk_enable(&scmi_devices->clk[1])); -+ ut_asserteq(0, clk_enable(&scmi_devices->clk[2])); -+ -+ ut_assert(!scmi_ctx->agent[0]->clk[0].enabled); -+ ut_assert(scmi_ctx->agent[0]->clk[1].enabled); -+ ut_assert(scmi_ctx->agent[1]->clk[0].enabled); -+ -+ ut_assertok(clk_disable(&scmi_devices->clk[1])); -+ ut_assertok(clk_disable(&scmi_devices->clk[2])); -+ -+ ut_assert(!scmi_ctx->agent[0]->clk[0].enabled); -+ ut_assert(!scmi_ctx->agent[0]->clk[1].enabled); -+ ut_assert(!scmi_ctx->agent[1]->clk[0].enabled); -+ -+ return release_sandbox_scmi_test_devices(uts, dev); -+} -+ -+DM_TEST(dm_test_scmi_clocks, UT_TESTF_SCAN_FDT); -+ -+static int dm_test_scmi_resets(struct unit_test_state *uts) -+{ -+ struct sandbox_scmi_devices *scmi_devices; -+ struct sandbox_scmi_service *scmi_ctx; -+ struct udevice *dev = NULL; -+ int ret; -+ -+ if (!IS_ENABLED(CONFIG_RESET_SCMI)) -+ return 0; -+ -+ ret = load_sandbox_scmi_test_devices(uts, &dev); -+ if (ret) -+ return ret; -+ -+ scmi_devices = sandbox_scmi_devices_ctx(dev); -+ scmi_ctx = sandbox_scmi_service_ctx(); -+ -+ /* Test SCMI resect controller manipulation */ -+ ut_assert(!scmi_ctx->agent[0]->reset[0].asserted) -+ -+ ut_assertok(reset_assert(&scmi_devices->reset[0])); -+ ut_assert(scmi_ctx->agent[0]->reset[0].asserted) -+ -+ ut_assertok(reset_deassert(&scmi_devices->reset[0])); -+ ut_assert(!scmi_ctx->agent[0]->reset[0].asserted); -+ -+ return release_sandbox_scmi_test_devices(uts, dev); -+} -+ -+DM_TEST(dm_test_scmi_resets, UT_TESTF_SCAN_FDT); -diff --git a/test/lib/lmb.c b/test/lib/lmb.c -index 644ee78758..d7bd826190 100644 ---- a/test/lib/lmb.c -+++ b/test/lib/lmb.c -@@ -659,3 +659,92 @@ static int lib_test_lmb_get_free_size(struct unit_test_state *uts) - - DM_TEST(lib_test_lmb_get_free_size, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); -+ -+static int lib_test_lmb_flags(struct unit_test_state *uts) -+{ -+ const phys_addr_t ram = 0x40000000; -+ const phys_size_t ram_size = 0x20000000; -+ struct lmb lmb; -+ long ret; -+ -+ lmb_init(&lmb); -+ -+ ret = lmb_add(&lmb, ram, ram_size); -+ ut_asserteq(ret, 0); -+ -+ /* reserve, same flag */ -+ ret = lmb_reserve_flags(&lmb, 0x40010000, 0x10000, LMB_NOMAP); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, -+ 0, 0, 0, 0); -+ -+ /* reserve again, same flag */ -+ ret = lmb_reserve_flags(&lmb, 0x40010000, 0x10000, LMB_NOMAP); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, -+ 0, 0, 0, 0); -+ -+ /* reserve again, new flag */ -+ ret = lmb_reserve_flags(&lmb, 0x40010000, 0x10000, LMB_NONE); -+ ut_asserteq(ret, -1); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000, -+ 0, 0, 0, 0); -+ -+ ut_asserteq(lmb_is_nomap(&lmb.reserved.region[0]), 1); -+ -+ /* merge after */ -+ ret = lmb_reserve_flags(&lmb, 0x40020000, 0x10000, LMB_NOMAP); -+ ut_asserteq(ret, 1); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x20000, -+ 0, 0, 0, 0); -+ -+ /* merge before */ -+ ret = lmb_reserve_flags(&lmb, 0x40000000, 0x10000, LMB_NOMAP); -+ ut_asserteq(ret, 1); -+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40000000, 0x30000, -+ 0, 0, 0, 0); -+ -+ ut_asserteq(lmb_is_nomap(&lmb.reserved.region[0]), 1); -+ -+ ret = lmb_reserve_flags(&lmb, 0x40030000, 0x10000, LMB_NONE); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40000000, 0x30000, -+ 0x40030000, 0x10000, 0, 0); -+ -+ ut_asserteq(lmb_is_nomap(&lmb.reserved.region[0]), 1); -+ ut_asserteq(lmb_is_nomap(&lmb.reserved.region[1]), 0); -+ -+ /* test that old API use LMB_NONE */ -+ ret = lmb_reserve(&lmb, 0x40040000, 0x10000); -+ ut_asserteq(ret, 1); -+ ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40000000, 0x30000, -+ 0x40030000, 0x20000, 0, 0); -+ -+ ut_asserteq(lmb_is_nomap(&lmb.reserved.region[0]), 1); -+ ut_asserteq(lmb_is_nomap(&lmb.reserved.region[1]), 0); -+ -+ ret = lmb_reserve_flags(&lmb, 0x40070000, 0x10000, LMB_NOMAP); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 3, 0x40000000, 0x30000, -+ 0x40030000, 0x20000, 0x40070000, 0x10000); -+ -+ ret = lmb_reserve_flags(&lmb, 0x40050000, 0x10000, LMB_NOMAP); -+ ut_asserteq(ret, 0); -+ ASSERT_LMB(&lmb, ram, ram_size, 4, 0x40000000, 0x30000, -+ 0x40030000, 0x20000, 0x40050000, 0x10000); -+ -+ /* merge with 2 adjacent regions */ -+ ret = lmb_reserve_flags(&lmb, 0x40060000, 0x10000, LMB_NOMAP); -+ ut_asserteq(ret, 2); -+ ASSERT_LMB(&lmb, ram, ram_size, 3, 0x40000000, 0x30000, -+ 0x40030000, 0x20000, 0x40050000, 0x30000); -+ -+ ut_asserteq(lmb_is_nomap(&lmb.reserved.region[0]), 1); -+ ut_asserteq(lmb_is_nomap(&lmb.reserved.region[1]), 0); -+ ut_asserteq(lmb_is_nomap(&lmb.reserved.region[2]), 1); -+ -+ return 0; -+} -+ -+DM_TEST(lib_test_lmb_flags, -+ UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); --- -2.17.1 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0003-ARM-v2021.10-stm32mp-r1-MISC-DRIVERS.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0003-ARM-v2021.10-stm32mp-r1-MISC-DRIVERS.patch new file mode 100644 index 0000000..837f774 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0003-ARM-v2021.10-stm32mp-r1-MISC-DRIVERS.patch @@ -0,0 +1,19344 @@ +From 1c09c131f67ca926d84733129dd3328eabd31039 Mon Sep 17 00:00:00 2001 +From: Christophe Priouzeau +Date: Mon, 30 May 2022 09:46:48 +0200 +Subject: [PATCH 3/5] ARM-v2021.10-stm32mp-r1-MISC-DRIVERS + +--- + CONTRIBUTING.md | 30 + + MAINTAINERS | 1 + + Makefile | 10 +- + SECURITY.md | 8 + + arch/arm/cpu/armv7/stv0991/timer.c | 6 +- + arch/arm/include/asm/arch-stm32f4/gpio.h | 15 - + arch/arm/include/asm/arch-stm32f7/gpio.h | 12 - + arch/arm/include/asm/arch-stm32h7/gpio.h | 12 - + .../include/asm/arch-stv0991/stv0991_gpt.h | 4 +- + arch/sandbox/dts/test.dts | 42 +- + arch/sandbox/include/asm/scmi_test.h | 13 +- + board/congatec/cgtqmx8/spl.c | 2 +- + board/dhelectronics/dh_stm32mp1/Kconfig | 2 +- + board/dhelectronics/dh_stm32mp1/MAINTAINERS | 2 +- + board/dhelectronics/dh_stm32mp1/Makefile | 1 - + board/dhelectronics/dh_stm32mp1/board.c | 22 +- + board/engicam/stm32mp1/Kconfig | 2 +- + board/engicam/stm32mp1/stm32mp1.c | 3 - + board/raspberrypi/rpi/rpi.c | 2 +- + cmd/bind.c | 2 +- + cmd/clk.c | 25 +- + cmd/onenand.c | 9 +- + common/Kconfig | 9 + + common/Makefile | 2 +- + common/{lcd_simplefb.c => fdt_simplefb.c} | 36 +- + common/usb_hub.c | 6 +- + configs/dh_imx6_defconfig | 2 + + configs/kp_imx6q_tpc_defconfig | 2 + + configs/mx53ppd_defconfig | 4 + + 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/sandbox_defconfig | 6 +- + configs/stih410-b2260_defconfig | 4 + + configs/stv0991_defconfig | 1 - + doc/board/st/stm32mp1.rst | 223 ++- + doc/device-tree-bindings/arm/arm,scmi.txt | 233 +-- + .../memory-controllers/st,stm32mp1-ddr.txt | 69 +- + drivers/adc/stm32-adc-core.c | 1 + + drivers/adc/stm32-adc.c | 493 ++++- + drivers/clk/Kconfig | 17 +- + drivers/clk/Makefile | 2 + + drivers/clk/clk-composite.c | 9 +- + drivers/clk/clk-divider.c | 6 +- + drivers/clk/clk-fixed-factor.c | 13 +- + drivers/clk/clk-gate.c | 15 +- + drivers/clk/clk-mux.c | 13 +- + drivers/clk/clk-stm32-core.c | 372 ++++ + drivers/clk/clk-stm32-core.h | 153 ++ + drivers/clk/clk-stm32mp13.c | 844 ++++++++ + drivers/clk/clk-uclass.c | 49 +- + drivers/clk/clk.c | 20 +- + drivers/clk/clk_fixed_factor.c | 3 + + drivers/clk/clk_fixed_rate.c | 3 + + drivers/clk/clk_scmi.c | 99 +- + drivers/clk/clk_stm32mp1.c | 39 +- + drivers/clk/stm32mp13_rcc.h | 1750 +++++++++++++++++ + drivers/core/device.c | 2 +- + drivers/core/lists.c | 4 +- + drivers/core/root.c | 2 +- + drivers/demo/demo-uclass.c | 9 +- + drivers/dfu/dfu_mtd.c | 22 +- + drivers/firmware/scmi/Kconfig | 28 +- + drivers/firmware/scmi/Makefile | 5 +- + drivers/firmware/scmi/mailbox_agent.c | 16 +- + drivers/firmware/scmi/optee_agent.c | 312 +++ + drivers/firmware/scmi/sandbox-scmi_agent.c | 255 +-- + drivers/firmware/scmi/sandbox-scmi_devices.c | 4 +- + drivers/firmware/scmi/scmi_agent-uclass.c | 17 +- + drivers/firmware/scmi/smccc_agent.c | 16 +- + drivers/gpio/stm32_gpio.c | 129 +- + .../gpio.h => drivers/gpio/stm32_gpio_priv.h | 13 +- + drivers/i2c/stm32f7_i2c.c | 96 +- + drivers/misc/imx8/scu.c | 2 +- + drivers/misc/stm32_rcc.c | 6 + + drivers/mmc/mmc_write.c | 2 +- + drivers/mmc/stm32_sdmmc2.c | 245 ++- + drivers/mtd/Kconfig | 7 + + drivers/mtd/altera_qspi.c | 3 - + drivers/mtd/cfi_mtd.c | 1 - + drivers/mtd/mtdconcat.c | 11 - + drivers/mtd/mtdcore.c | 8 - + drivers/mtd/mtdpart.c | 23 +- + drivers/mtd/nand/raw/nand_base.c | 4 - + drivers/mtd/nand/raw/stm32_fmc2_nand.c | 9 + + drivers/mtd/onenand/onenand_base.c | 3 - + drivers/mtd/spi/sf_mtd.c | 1 - + drivers/mtd/spi/spi-nor-core.c | 46 +- + drivers/mtd/ubi/io.c | 13 - + drivers/net/dwc_eth_qos.c | 154 +- + drivers/phy/phy-stm32-usbphyc.c | 355 +++- + drivers/pinctrl/Kconfig | 8 + + drivers/pinctrl/Makefile | 1 + + drivers/pinctrl/pinctrl-mcp23017.c | 411 ++++ + drivers/pinctrl/pinctrl-stmfx.c | 4 + + drivers/pinctrl/pinctrl_stm32.c | 103 +- + drivers/power/regulator/scmi_regulator.c | 125 +- + drivers/power/regulator/stm32-vrefbuf.c | 25 +- + drivers/ram/stm32mp1/Makefile | 1 - + drivers/ram/stm32mp1/stm32mp1_ddr.c | 69 +- + drivers/ram/stm32mp1/stm32mp1_ddr.h | 22 - + drivers/ram/stm32mp1/stm32mp1_ddr_regs.h | 66 +- + drivers/ram/stm32mp1/stm32mp1_interactive.c | 37 +- + drivers/ram/stm32mp1/stm32mp1_ram.c | 238 ++- + drivers/ram/stm32mp1/stm32mp1_tests.h | 3 - + drivers/ram/stm32mp1/stm32mp1_tuning.c | 1540 --------------- + drivers/reboot-mode/reboot-mode-uclass.c | 20 +- + drivers/remoteproc/Kconfig | 8 + + drivers/remoteproc/Makefile | 1 + + drivers/remoteproc/rproc-optee.c | 235 +++ + drivers/remoteproc/rproc-uclass.c | 16 +- + drivers/remoteproc/stm32_copro.c | 118 +- + drivers/reset/reset-scmi.c | 7 +- + drivers/rng/Kconfig | 9 + + drivers/rng/Makefile | 1 + + drivers/rng/optee_rng.c | 184 ++ + drivers/rng/stm32mp1_rng.c | 61 +- + drivers/serial/serial-uclass.c | 2 +- + drivers/spi/spi-uclass.c | 12 - + drivers/spi/stm32_qspi.c | 27 +- + drivers/spi/stm32_spi.c | 224 ++- + drivers/tee/optee/core.c | 13 + + drivers/tee/optee/optee_msg.h | 12 +- + drivers/timer/timer-uclass.c | 2 +- + drivers/usb/Kconfig | 2 + + drivers/usb/gadget/dwc2_udc_otg.c | 21 +- + drivers/usb/gadget/f_dfu.c | 2 + + drivers/usb/gadget/gadget_chips.h | 8 + + drivers/usb/host/usb-sandbox.c | 28 + + drivers/usb/typec/Kconfig | 24 + + drivers/usb/typec/Makefile | 5 + + drivers/usb/typec/typec-stusb160x.c | 130 ++ + drivers/usb/typec/typec-uclass.c | 127 ++ + drivers/usb/typec/ucsi/Kconfig | 26 + + drivers/usb/typec/ucsi/Makefile | 4 + + drivers/usb/typec/ucsi/ucsi-stm32g0.c | 117 ++ + drivers/usb/typec/ucsi/ucsi-uclass.c | 393 ++++ + drivers/video/Kconfig | 9 + + drivers/video/Makefile | 1 + + drivers/video/dw_mipi_dsi.c | 1 - + drivers/video/rocktech-hx8394.c | 250 +++ + drivers/video/stm32/stm32_dsi.c | 1 - + drivers/video/stm32/stm32_ltdc.c | 264 ++- + drivers/video/video-uclass.c | 14 + + env/mmc.c | 10 +- + env/onenand.c | 4 +- + fs/yaffs2/yaffs_mtdif.c | 1 - + include/configs/dh_imx6.h | 2 - + include/configs/dh_stm32mp1.h | 15 - + include/configs/kp_imx6q_tpc.h | 2 - + include/configs/mx53ppd.h | 4 - + include/configs/pm9263.h | 1 - + include/configs/rpi.h | 1 - + include/configs/stih410-b2260.h | 5 - + include/configs/stm32f429-discovery.h | 10 - + include/configs/stm32f429-evaluation.h | 7 - + include/configs/stm32f469-discovery.h | 7 - + include/configs/stm32f746-disco.h | 7 - + include/configs/stm32h743-disco.h | 5 - + include/configs/stm32h743-eval.h | 5 - + include/configs/stm32h750-art-pi.h | 5 - + include/configs/stm32mp13_common.h | 151 ++ + include/configs/stm32mp13_st_common.h | 55 + + .../{stm32mp1.h => stm32mp15_common.h} | 66 +- + include/configs/stm32mp15_dh_dhsom.h | 31 + + include/configs/stm32mp15_st_common.h | 56 + + include/dm/lists.h | 3 +- + include/dm/pinctrl.h | 2 +- + include/dm/uclass-id.h | 2 + + include/dt-bindings/clock/stm32mp1-clks.h | 29 + + include/dt-bindings/clock/stm32mp13-clks.h | 229 +++ + include/dt-bindings/pinctrl/stm32-pinfunc.h | 1 + + include/dt-bindings/reset/stm32mp1-resets.h | 14 + + include/dt-bindings/reset/stm32mp13-resets.h | 100 + + include/dt-bindings/rtc/rtc-stm32.h | 14 + + include/dt-bindings/soc/stm32-hdp.h | 108 + + include/dt-bindings/soc/stm32mp13-hdp.h | 133 ++ + include/fdt_simplefb.h | 5 +- + include/fdtdec.h | 5 +- + include/linux/mtd/mtd.h | 11 - + include/nand.h | 1 - + include/netdev.h | 2 +- + include/rproc_optee.h | 127 ++ + include/scmi_agent.h | 6 +- + include/scmi_protocols.h | 57 +- + include/spi_flash.h | 9 + + include/tee.h | 24 +- + include/typec.h | 154 ++ + include/ucsi.h | 112 ++ + include/video.h | 7 + + lib/uuid.c | 2 +- + scripts/config_whitelist.txt | 6 - + test/cmd/pinmux.c | 4 +- + test/dm/nop.c | 2 +- + test/dm/ofnode.c | 2 +- + test/dm/pci.c | 4 +- + test/dm/scmi.c | 132 +- + test/dm/test-fdt.c | 2 +- + test/py/tests/test_bind.py | 7 + + test/py/tests/test_log.py | 8 +- + test/py/tests/test_pinmux.py | 40 +- + 207 files changed, 10069 insertions(+), 3332 deletions(-) + create mode 100644 CONTRIBUTING.md + create mode 100644 SECURITY.md + delete mode 100644 arch/arm/include/asm/arch-stm32f4/gpio.h + delete mode 100644 arch/arm/include/asm/arch-stm32f7/gpio.h + delete mode 100644 arch/arm/include/asm/arch-stm32h7/gpio.h + rename common/{lcd_simplefb.c => fdt_simplefb.c} (66%) + create mode 100644 drivers/clk/clk-stm32-core.c + create mode 100644 drivers/clk/clk-stm32-core.h + create mode 100644 drivers/clk/clk-stm32mp13.c + create mode 100644 drivers/clk/stm32mp13_rcc.h + create mode 100644 drivers/firmware/scmi/optee_agent.c + rename arch/arm/include/asm/arch-stm32/gpio.h => drivers/gpio/stm32_gpio_priv.h (87%) + create mode 100644 drivers/pinctrl/pinctrl-mcp23017.c + delete mode 100644 drivers/ram/stm32mp1/stm32mp1_tuning.c + create mode 100644 drivers/remoteproc/rproc-optee.c + create mode 100644 drivers/rng/optee_rng.c + create mode 100644 drivers/usb/typec/Kconfig + create mode 100644 drivers/usb/typec/Makefile + create mode 100644 drivers/usb/typec/typec-stusb160x.c + create mode 100644 drivers/usb/typec/typec-uclass.c + create mode 100644 drivers/usb/typec/ucsi/Kconfig + create mode 100644 drivers/usb/typec/ucsi/Makefile + create mode 100644 drivers/usb/typec/ucsi/ucsi-stm32g0.c + create mode 100644 drivers/usb/typec/ucsi/ucsi-uclass.c + create mode 100644 drivers/video/rocktech-hx8394.c + delete mode 100644 include/configs/dh_stm32mp1.h + create mode 100644 include/configs/stm32mp13_common.h + create mode 100644 include/configs/stm32mp13_st_common.h + rename include/configs/{stm32mp1.h => stm32mp15_common.h} (76%) + create mode 100644 include/configs/stm32mp15_dh_dhsom.h + create mode 100644 include/configs/stm32mp15_st_common.h + create mode 100644 include/dt-bindings/clock/stm32mp13-clks.h + create mode 100644 include/dt-bindings/reset/stm32mp13-resets.h + create mode 100644 include/dt-bindings/rtc/rtc-stm32.h + create mode 100644 include/dt-bindings/soc/stm32-hdp.h + create mode 100644 include/dt-bindings/soc/stm32mp13-hdp.h + create mode 100644 include/rproc_optee.h + create mode 100644 include/typec.h + create mode 100644 include/ucsi.h + +diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md +new file mode 100644 +index 0000000000..3d1bacd78a +--- /dev/null ++++ b/CONTRIBUTING.md +@@ -0,0 +1,30 @@ ++# Contributing guide ++ ++This document serves as a checklist before contributing to this repository. It includes links to read up on if topics are unclear to you. ++ ++This guide mainly focuses on the proper use of Git. ++ ++## 1. Issues ++ ++STM32MPU projects do not activate "Github issues" feature for the time being. If you need to report an issue or question about this project deliverables, you can report them using [ ST Support Center ](https://my.st.com/ols#/ols/newrequest) or [ ST Community MPU Forum ](https://community.st.com/s/topic/0TO0X0000003u2AWAQ/stm32-mpus). ++ ++## 2. Pull Requests ++ ++STMicrolectronics is happy to receive contributions from the community, based on an initial Contributor License Agreement (CLA) procedure. ++ ++* If you are an individual writing original source code and you are sure **you own the intellectual property**, then you need to sign an Individual CLA (https://cla.st.com). ++* If you work for a company that wants also to allow you to contribute with your work, your company needs to provide a Corporate CLA (https://cla.st.com) mentioning your GitHub account name. ++* If you are not sure that a CLA (Individual or Corporate) has been signed for your GitHub account you can check here (https://cla.st.com). ++ ++Please note that: ++* The Corporate CLA will always take precedence over the Individual CLA. ++* One CLA submission is sufficient, for any project proposed by STMicroelectronics. ++ ++__How to proceed__ ++ ++* We recommend to fork the project in your GitHub account to further develop your contribution. Please use the latest commit version. ++* Please, submit one Pull Request for one new feature or proposal. This will ease the analysis and final merge if accepted. ++ ++__Note__ ++ ++Merge will not be done directly in GitHub but it will need first to follow internal integration process before public deliver in a standard release. The Pull request will stay open until it is merged and delivered. +diff --git a/MAINTAINERS b/MAINTAINERS +index 5370b55064..75969803d3 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -438,6 +438,7 @@ F: drivers/power/regulator/stpmic1.c + F: drivers/ram/stm32mp1/ + F: drivers/remoteproc/stm32_copro.c + F: drivers/reset/stm32-reset.c ++F: drivers/rng/optee_rng.c + F: drivers/rng/stm32mp1_rng.c + F: drivers/rtc/stm32_rtc.c + F: drivers/serial/serial_stm32.* +diff --git a/Makefile b/Makefile +index 20c1aa3f58..6203f40cb1 100644 +--- a/Makefile ++++ b/Makefile +@@ -3,7 +3,7 @@ + VERSION = 2021 + PATCHLEVEL = 10 + SUBLEVEL = +-EXTRAVERSION = ++EXTRAVERSION = -stm32mp-r1 + NAME = + + # *DOCUMENTATION* +@@ -843,6 +843,7 @@ libs-y += drivers/usb/mtu3/ + libs-y += drivers/usb/musb/ + libs-y += drivers/usb/musb-new/ + libs-y += drivers/usb/phy/ ++libs-y += drivers/usb/typec/ + libs-y += drivers/usb/ulpi/ + ifdef CONFIG_POST + libs-y += post/ +@@ -1123,6 +1124,13 @@ ifneq ($(CONFIG_DM),y) + @echo >&2 "Failure to update may result in board removal." + @echo >&2 "See doc/driver-model/migration.rst for more info." + @echo >&2 "====================================================" ++endif ++ifeq ($(CONFIG_STM32MP15x_STM32IMAGE),y) ++ @echo >&2 "===================== WARNING ======================" ++ @echo >&2 "This board uses CONFIG_STM32MP15x_STM32IMAGE for STM32 image" ++ @echo >&2 "support in TF-A and these configuration is deprecated." ++ @echo >&2 "Please migrate to FIP support in TF-A instead." ++ @echo >&2 "====================================================" + endif + $(call deprecated,CONFIG_WDT,DM watchdog,v2019.10,\ + $(CONFIG_WATCHDOG)$(CONFIG_HW_WATCHDOG)) +diff --git a/SECURITY.md b/SECURITY.md +new file mode 100644 +index 0000000000..4b3e4e6ba5 +--- /dev/null ++++ b/SECURITY.md +@@ -0,0 +1,8 @@ ++# Report potential product security vulnerabilities ++ST places a high priority on security, and our Product Security Incident Response Team (PSIRT) is committed to rapidly addressing potential security vulnerabilities affecting our products. PSIRT's long history and vast experience in security allows ST to perform clear analyses and provide appropriate guidance on mitigations and solutions when applicable. ++If you wish to report potential security vulnerabilities regarding our products, **please do not report them through public GitHub issues.** Instead, we encourage you to report them to our ST PSIRT following the process described at: **https://www.st.com/content/st_com/en/security/report-vulnerabilities.html** ++ ++### IMPORTANT - READ CAREFULLY: ++STMicroelectronics International N.V., on behalf of itself, its affiliates and subsidiaries, (collectively “ST”) takes all potential security vulnerability reports or other related communications (“Report(s)”) seriously. In order to review Your Report (the terms “You” and “Yours” include your employer, and all affiliates, subsidiaries and related persons or entities) and take actions as deemed appropriate, ST requires that we have the rights and Your permission to do so. ++As such, by submitting Your Report to ST, You agree that You have the right to do so, and You grant to ST the rights to use the Report for purposes related to security vulnerability analysis, testing, correction, patching, reporting and any other related purpose or function. ++By submitting Your Report, You agree that ST’s [Privacy Policy](https://www.st.com/content/st_com/en/common/privacy-portal.html) applies to all related communications. +diff --git a/arch/arm/cpu/armv7/stv0991/timer.c b/arch/arm/cpu/armv7/stv0991/timer.c +index 07033acb5c..67764ccf66 100644 +--- a/arch/arm/cpu/armv7/stv0991/timer.c ++++ b/arch/arm/cpu/armv7/stv0991/timer.c +@@ -18,7 +18,7 @@ static struct stv0991_cgu_regs *const stv0991_cgu_regs = \ + (struct stv0991_cgu_regs *) (CGU_BASE_ADDR); + + #define READ_TIMER() (readl(&gpt1_regs_ptr->cnt) & GPT_FREE_RUNNING) +-#define GPT_RESOLUTION (CONFIG_STV0991_HZ_CLOCK / CONFIG_STV0991_HZ) ++#define GPT_RESOLUTION (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ) + + DECLARE_GLOBAL_DATA_PTR; + +@@ -67,7 +67,7 @@ void __udelay(unsigned long usec) + { + ulong tmo; + ulong start = get_timer_masked(); +- ulong tenudelcnt = CONFIG_STV0991_HZ_CLOCK / (1000 * 100); ++ ulong tenudelcnt = CONFIG_SYS_HZ_CLOCK / (1000 * 100); + ulong rndoff; + + rndoff = (usec % 10) ? 1 : 0; +@@ -110,5 +110,5 @@ unsigned long long get_ticks(void) + */ + ulong get_tbclk(void) + { +- return CONFIG_STV0991_HZ; ++ return CONFIG_SYS_HZ; + } +diff --git a/arch/arm/include/asm/arch-stm32f4/gpio.h b/arch/arm/include/asm/arch-stm32f4/gpio.h +deleted file mode 100644 +index 490f686a85..0000000000 +--- a/arch/arm/include/asm/arch-stm32f4/gpio.h ++++ /dev/null +@@ -1,15 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0+ */ +-/* +- * (C) Copyright 2011 +- * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com +- * +- * (C) Copyright 2015 +- * Kamil Lulko, +- */ +- +-#ifndef _STM32_GPIO_H_ +-#define _STM32_GPIO_H_ +- +-#include +- +-#endif /* _STM32_GPIO_H_ */ +diff --git a/arch/arm/include/asm/arch-stm32f7/gpio.h b/arch/arm/include/asm/arch-stm32f7/gpio.h +deleted file mode 100644 +index 21f4e0fd27..0000000000 +--- a/arch/arm/include/asm/arch-stm32f7/gpio.h ++++ /dev/null +@@ -1,12 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0+ */ +-/* +- * Copyright (C) 2016, STMicroelectronics - All Rights Reserved +- * Author(s): Vikas Manocha, for STMicroelectronics. +- */ +- +-#ifndef _STM32_GPIO_H_ +-#define _STM32_GPIO_H_ +- +-#include +- +-#endif /* _STM32_GPIO_H_ */ +diff --git a/arch/arm/include/asm/arch-stm32h7/gpio.h b/arch/arm/include/asm/arch-stm32h7/gpio.h +deleted file mode 100644 +index 4f57f175ff..0000000000 +--- a/arch/arm/include/asm/arch-stm32h7/gpio.h ++++ /dev/null +@@ -1,12 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0+ */ +-/* +- * Copyright (C) 2017, STMicroelectronics - All Rights Reserved +- * Author(s): Patrice Chotard, for STMicroelectronics. +- */ +- +-#ifndef _STM32_GPIO_H_ +-#define _STM32_GPIO_H_ +- +-#include +- +-#endif /* _STM32_GPIO_H_ */ +diff --git a/arch/arm/include/asm/arch-stv0991/stv0991_gpt.h b/arch/arm/include/asm/arch-stv0991/stv0991_gpt.h +index cd27472ad7..f1d5667c32 100644 +--- a/arch/arm/include/asm/arch-stv0991/stv0991_gpt.h ++++ b/arch/arm/include/asm/arch-stv0991/stv0991_gpt.h +@@ -36,7 +36,7 @@ struct gpt_regs *const gpt1_regs_ptr = + #define GPT_FREE_RUNNING 0xFFFF + + /* Timer, HZ specific defines */ +-#define CONFIG_STV0991_HZ 1000 +-#define CONFIG_STV0991_HZ_CLOCK (27*1000*1000)/GPT_PRESCALER_128 ++#define CONFIG_SYS_HZ 1000 ++#define CONFIG_SYS_HZ_CLOCK ((27 * 1000 * 1000) / GPT_PRESCALER_128) + + #endif +diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts +index 962bdbe556..9cfd76658f 100644 +--- a/arch/sandbox/dts/test.dts ++++ b/arch/sandbox/dts/test.dts +@@ -557,17 +557,21 @@ + compatible = "sandbox,firmware"; + }; + +- sandbox-scmi-agent@0 { ++ scmi { + compatible = "sandbox,scmi-agent"; + #address-cells = <1>; + #size-cells = <0>; + +- clk_scmi0: protocol@14 { ++ protocol@10 { ++ reg = <0x10>; ++ }; ++ ++ clk_scmi: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + }; + +- reset_scmi0: protocol@16 { ++ reset_scmi: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; +@@ -579,35 +583,21 @@ + #address-cells = <1>; + #size-cells = <0>; + +- regul0_scmi0: reg@0 { ++ regul0_scmi: reg@0 { + reg = <0>; + regulator-name = "sandbox-voltd0"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <3300000>; + }; +- regul1_scmi0: reg@1 { +- reg = <0x1>; +- regulator-name = "sandbox-voltd1"; ++ regul6_scmi: reg@6 { ++ regulator-name = "sandbox-voltd6"; ++ voltd-name = "regu6"; + regulator-min-microvolt = <1800000>; ++ regulator-supply = <®ul0_scmi>; + }; + }; + }; + }; +- +- sandbox-scmi-agent@1 { +- compatible = "sandbox,scmi-agent"; +- #address-cells = <1>; +- #size-cells = <0>; +- +- clk_scmi1: protocol@14 { +- reg = <0x14>; +- #clock-cells = <1>; +- }; +- +- protocol@10 { +- reg = <0x10>; +- }; +- }; + }; + + pinctrl-gpio { +@@ -1364,10 +1354,10 @@ + + sandbox_scmi { + compatible = "sandbox,scmi-devices"; +- clocks = <&clk_scmi0 7>, <&clk_scmi0 3>, <&clk_scmi1 1>; +- resets = <&reset_scmi0 3>; +- regul0-supply = <®ul0_scmi0>; +- regul1-supply = <®ul1_scmi0>; ++ clocks = <&clk_scmi 2>, <&clk_scmi 0>; ++ resets = <&reset_scmi 3>; ++ regul0-supply = <®ul0_scmi>; ++ regul1-supply = <®ul6_scmi>; + }; + + pinctrl { +diff --git a/arch/sandbox/include/asm/scmi_test.h b/arch/sandbox/include/asm/scmi_test.h +index 2930e686d7..c72ec1e1cb 100644 +--- a/arch/sandbox/include/asm/scmi_test.h ++++ b/arch/sandbox/include/asm/scmi_test.h +@@ -17,7 +17,6 @@ struct sandbox_scmi_service; + * @rate: Clock rate in Hertz + */ + struct sandbox_scmi_clk { +- uint id; + bool enabled; + ulong rate; + }; +@@ -46,7 +45,6 @@ struct sandbox_scmi_voltd { + + /** + * struct sandbox_scmi_agent - Simulated SCMI service seen by SCMI agent +- * @idx: Identifier for the SCMI agent, its index + * @clk: Simulated clocks + * @clk_count: Simulated clocks array size + * @reset: Simulated reset domains +@@ -55,7 +53,6 @@ struct sandbox_scmi_voltd { + * @voltd_count: Simulated voltage domains array size + */ + struct sandbox_scmi_agent { +- uint idx; + struct sandbox_scmi_clk *clk; + size_t clk_count; + struct sandbox_scmi_reset *reset; +@@ -66,12 +63,10 @@ struct sandbox_scmi_agent { + + /** + * struct sandbox_scmi_service - Reference to simutaed SCMI agents/services +- * @agent: Pointer to SCMI sandbox agent pointers array +- * @agent_count: Number of emulated agents exposed in array @agent. ++ * @agent: Pointer to SCMI sandbox agent or NULL if not probed + */ + struct sandbox_scmi_service { +- struct sandbox_scmi_agent **agent; +- size_t agent_count; ++ struct sandbox_scmi_agent *agent; + }; + + /** +@@ -94,13 +89,13 @@ struct sandbox_scmi_devices { + + #ifdef CONFIG_SCMI_FIRMWARE + /** +- * sandbox_scmi_service_context - Get the simulated SCMI services context ++ * sandbox_scmi_service_ctx - Get the simulated SCMI services context + * @return: Reference to backend simulated resources state + */ + struct sandbox_scmi_service *sandbox_scmi_service_ctx(void); + + /** +- * sandbox_scmi_devices_get_ref - Get references to devices accessed through SCMI ++ * sandbox_scmi_devices_ctx - Get references to devices accessed through SCMI + * @dev: Reference to the test device used get test resources + * @return: Reference to the devices probed by the SCMI test + */ +diff --git a/board/congatec/cgtqmx8/spl.c b/board/congatec/cgtqmx8/spl.c +index 2a5d4c1bcd..37b7221c52 100644 +--- a/board/congatec/cgtqmx8/spl.c ++++ b/board/congatec/cgtqmx8/spl.c +@@ -32,7 +32,7 @@ void spl_board_init(void) + offset = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "nxp,imx8-pd"); + while (offset != -FDT_ERR_NOTFOUND) { + lists_bind_fdt(gd->dm_root, offset_to_ofnode(offset), +- NULL, true); ++ NULL, NULL, true); + offset = fdt_node_offset_by_compatible(gd->fdt_blob, offset, + "nxp,imx8-pd"); + } +diff --git a/board/dhelectronics/dh_stm32mp1/Kconfig b/board/dhelectronics/dh_stm32mp1/Kconfig +index 1fc792c9d1..dc707c2753 100644 +--- a/board/dhelectronics/dh_stm32mp1/Kconfig ++++ b/board/dhelectronics/dh_stm32mp1/Kconfig +@@ -7,7 +7,7 @@ config SYS_VENDOR + default "dhelectronics" + + config SYS_CONFIG_NAME +- default "dh_stm32mp1" ++ default "stm32mp15_dh_dhsom" + + config ENV_SECT_SIZE + default 0x10000 if ENV_IS_IN_SPI_FLASH +diff --git a/board/dhelectronics/dh_stm32mp1/MAINTAINERS b/board/dhelectronics/dh_stm32mp1/MAINTAINERS +index 9ce21c3ab2..865588f5b8 100644 +--- a/board/dhelectronics/dh_stm32mp1/MAINTAINERS ++++ b/board/dhelectronics/dh_stm32mp1/MAINTAINERS +@@ -6,4 +6,4 @@ F: arch/arm/dts/stm32mp15xx-dhcom* + F: board/dhelectronics/dh_stm32mp1/ + F: configs/stm32mp15_dhcom_basic_defconfig + F: configs/stm32mp15_dhcor_basic_defconfig +-F: include/configs/stm32mp1.h ++F: include/configs/stm32mp15_dh_dhsom.h +diff --git a/board/dhelectronics/dh_stm32mp1/Makefile b/board/dhelectronics/dh_stm32mp1/Makefile +index b368b396a4..30db1dee80 100644 +--- a/board/dhelectronics/dh_stm32mp1/Makefile ++++ b/board/dhelectronics/dh_stm32mp1/Makefile +@@ -5,5 +5,4 @@ + + obj-y += ../../st/common/stpmic1.o board.o + +-obj-$(CONFIG_SYS_MTDPARTS_RUNTIME) += ../../st/common/stm32mp_mtdparts.o + obj-$(CONFIG_SET_DFU_ALT_INFO) += ../../st/common/stm32mp_dfu.o +diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c +index d7c1857c16..8695b1b6fc 100644 +--- a/board/dhelectronics/dh_stm32mp1/board.c ++++ b/board/dhelectronics/dh_stm32mp1/board.c +@@ -211,34 +211,40 @@ static void board_get_coding_straps(void) + ofnode node; + int i, ret; + ++ brdcode = 0; ++ ddr3code = 0; ++ somcode = 0; ++ + node = ofnode_path("/config"); + if (!ofnode_valid(node)) { + printf("%s: no /config node?\n", __func__); + return; + } + +- brdcode = 0; +- ddr3code = 0; +- somcode = 0; +- + ret = gpio_request_list_by_name_nodev(node, "dh,som-coding-gpios", + gpio, ARRAY_SIZE(gpio), + GPIOD_IS_IN); + for (i = 0; i < ret; i++) + somcode |= !!dm_gpio_get_value(&(gpio[i])) << i; + ++ gpio_free_list_nodev(gpio, ret); ++ + ret = gpio_request_list_by_name_nodev(node, "dh,ddr3-coding-gpios", + gpio, ARRAY_SIZE(gpio), + GPIOD_IS_IN); + for (i = 0; i < ret; i++) + ddr3code |= !!dm_gpio_get_value(&(gpio[i])) << i; + ++ gpio_free_list_nodev(gpio, ret); ++ + ret = gpio_request_list_by_name_nodev(node, "dh,board-coding-gpios", + gpio, ARRAY_SIZE(gpio), + GPIOD_IS_IN); + for (i = 0; i < ret; i++) + brdcode |= !!dm_gpio_get_value(&(gpio[i])) << i; + ++ gpio_free_list_nodev(gpio, ret); ++ + printf("Code: SoM:rev=%d,ddr3=%d Board:rev=%d\n", + somcode, ddr3code, brdcode); + } +@@ -590,12 +596,6 @@ static void board_init_fmc2(void) + /* board dependent setup after realloc */ + 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 +@@ -652,7 +652,7 @@ void board_quiesce_devices(void) + + /* eth init function : weak called in eqos driver */ + int board_interface_eth_init(struct udevice *dev, +- phy_interface_t interface_type) ++ phy_interface_t interface_type, ulong rate) + { + u8 *syscfg; + u32 value; +diff --git a/board/engicam/stm32mp1/Kconfig b/board/engicam/stm32mp1/Kconfig +index c800fd4e60..3802d44cef 100644 +--- a/board/engicam/stm32mp1/Kconfig ++++ b/board/engicam/stm32mp1/Kconfig +@@ -7,6 +7,6 @@ config SYS_VENDOR + default "engicam" + + config SYS_CONFIG_NAME +- default "stm32mp1" ++ default "stm32mp15_common" + + endif +diff --git a/board/engicam/stm32mp1/stm32mp1.c b/board/engicam/stm32mp1/stm32mp1.c +index 8bf9c9c67d..20d8603c78 100644 +--- a/board/engicam/stm32mp1/stm32mp1.c ++++ b/board/engicam/stm32mp1/stm32mp1.c +@@ -40,9 +40,6 @@ int checkboard(void) + /* board dependent setup after realloc */ + int board_init(void) + { +- /* address of boot parameters */ +- gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100; +- + if (IS_ENABLED(CONFIG_DM_REGULATOR)) + regulators_enable_boot_on(_DEBUG); + +diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c +index 372b26b6f2..b2a17080c3 100644 +--- a/board/raspberrypi/rpi/rpi.c ++++ b/board/raspberrypi/rpi/rpi.c +@@ -501,7 +501,7 @@ int ft_board_setup(void *blob, struct bd_info *bd) + + node = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer"); + if (node < 0) +- lcd_dt_simplefb_add_node(blob); ++ fdt_simplefb_add_node(blob); + + #ifdef CONFIG_EFI_LOADER + /* Reserve the spin table */ +diff --git a/cmd/bind.c b/cmd/bind.c +index 07c629eff7..4d1b7885e6 100644 +--- a/cmd/bind.c ++++ b/cmd/bind.c +@@ -152,7 +152,7 @@ static int bind_by_node_path(const char *path, const char *drv_name) + } + + ofnode = ofnode_path(path); +- ret = lists_bind_fdt(parent, ofnode, &dev, false); ++ ret = lists_bind_fdt(parent, ofnode, &dev, drv, false); + + if (!dev || ret) { + printf("Unable to bind. err:%d\n", ret); +diff --git a/cmd/clk.c b/cmd/clk.c +index dbbdc31b35..a483fd8981 100644 +--- a/cmd/clk.c ++++ b/cmd/clk.c +@@ -99,20 +99,6 @@ static int do_clk_dump(struct cmd_tbl *cmdtp, int flag, int argc, + } + + #if CONFIG_IS_ENABLED(DM) && CONFIG_IS_ENABLED(CLK) +-struct udevice *clk_lookup(const char *name) +-{ +- int i = 0; +- struct udevice *dev; +- +- do { +- uclass_get_device(UCLASS_CLK, i++, &dev); +- if (!strcmp(name, dev->name)) +- return dev; +- } while (dev); +- +- return NULL; +-} +- + static int do_clk_setfreq(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) + { +@@ -120,16 +106,17 @@ static int do_clk_setfreq(struct cmd_tbl *cmdtp, int flag, int argc, + s32 freq; + struct udevice *dev; + +- freq = dectoul(argv[2], NULL); ++ if (argc != 3) ++ return CMD_RET_USAGE; + +- dev = clk_lookup(argv[1]); ++ freq = dectoul(argv[2], NULL); + +- if (dev) ++ if (!uclass_get_device_by_name(UCLASS_CLK, argv[1], &dev)) + clk = dev_get_clk_ptr(dev); + + if (!clk) { + printf("clock '%s' not found.\n", argv[1]); +- return -EINVAL; ++ return CMD_RET_FAILURE; + } + + freq = clk_set_rate(clk, freq); +@@ -173,7 +160,7 @@ static int do_clk(struct cmd_tbl *cmdtp, int flag, int argc, + #ifdef CONFIG_SYS_LONGHELP + static char clk_help_text[] = + "dump - Print clock frequencies\n" +- "setfreq [clk] [freq] - Set clock frequency"; ++ "clk setfreq [clk] [freq] - Set clock frequency"; + #endif + + U_BOOT_CMD(clk, 4, 1, do_clk, "CLK sub-system", clk_help_text); +diff --git a/cmd/onenand.c b/cmd/onenand.c +index 852ed5c7b2..592985a7ee 100644 +--- a/cmd/onenand.c ++++ b/cmd/onenand.c +@@ -186,9 +186,7 @@ next: + static int onenand_block_erase(u32 start, u32 size, int force) + { + struct onenand_chip *this = mtd->priv; +- struct erase_info instr = { +- .callback = NULL, +- }; ++ struct erase_info instr = {}; + loff_t ofs; + int ret; + int blocksize = 1 << this->erase_shift; +@@ -219,10 +217,7 @@ static int onenand_block_erase(u32 start, u32 size, int force) + static int onenand_block_test(u32 start, u32 size) + { + struct onenand_chip *this = mtd->priv; +- struct erase_info instr = { +- .callback = NULL, +- .priv = 0, +- }; ++ struct erase_info instr = {}; + + int blocks; + loff_t ofs; +diff --git a/common/Kconfig b/common/Kconfig +index ee14d3ad5b..6c2d2eda99 100644 +--- a/common/Kconfig ++++ b/common/Kconfig +@@ -767,3 +767,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 +diff --git a/common/Makefile b/common/Makefile +index ae0430c35f..3fb378ffc4 100644 +--- a/common/Makefile ++++ b/common/Makefile +@@ -27,6 +27,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 +@@ -49,7 +50,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_COMMON) += update.o +diff --git a/common/lcd_simplefb.c b/common/fdt_simplefb.c +similarity index 66% +rename from common/lcd_simplefb.c +rename to common/fdt_simplefb.c +index 1650615cdb..926696455b 100644 +--- a/common/lcd_simplefb.c ++++ b/common/fdt_simplefb.c +@@ -16,7 +16,7 @@ + + DECLARE_GLOBAL_DATA_PTR; + +-static int lcd_dt_simplefb_configure_node(void *blob, int off) ++static int fdt_simplefb_configure_node(void *blob, int off) + { + int xsize, ysize; + int bpix; /* log2 of bits per pixel */ +@@ -58,7 +58,7 @@ static int lcd_dt_simplefb_configure_node(void *blob, int off) + xsize * (1 << bpix) / 8, name); + } + +-int lcd_dt_simplefb_add_node(void *blob) ++int fdt_simplefb_add_node(void *blob) + { + static const char compat[] = "simple-framebuffer"; + static const char disabled[] = "disabled"; +@@ -76,10 +76,10 @@ int lcd_dt_simplefb_add_node(void *blob) + if (ret < 0) + return -1; + +- return lcd_dt_simplefb_configure_node(blob, off); ++ return fdt_simplefb_configure_node(blob, off); + } + +-int lcd_dt_simplefb_enable_existing_node(void *blob) ++int fdt_simplefb_enable_existing_node(void *blob) + { + int off; + +@@ -87,5 +87,31 @@ int lcd_dt_simplefb_enable_existing_node(void *blob) + if (off < 0) + return -1; + +- return lcd_dt_simplefb_configure_node(blob, off); ++ return fdt_simplefb_configure_node(blob, off); + } ++ ++#if CONFIG_IS_ENABLED(DM_VIDEO) ++int fdt_simplefb_enable_and_mem_rsv(void *blob) ++{ ++ struct fdt_memory mem; ++ int ret; ++ ++ /* nothing to do when video is not active */ ++ if (!video_is_active()) ++ return 0; ++ ++ ret = fdt_simplefb_enable_existing_node(blob); ++ if (ret) ++ return ret; ++ ++ /* nothing to do when the frame buffer is not defined */ ++ if (gd->video_bottom == gd->video_top) ++ return 0; ++ ++ /* 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 +diff --git a/common/usb_hub.c b/common/usb_hub.c +index ba11a188ca..e681f1b307 100644 +--- a/common/usb_hub.c ++++ b/common/usb_hub.c +@@ -47,6 +47,8 @@ + #define HUB_SHORT_RESET_TIME 20 + #define HUB_LONG_RESET_TIME 200 + ++#define HUB_DEBOUNCE_TIMEOUT 2000 ++ + #define PORT_OVERCURRENT_MAX_SCAN_COUNT 3 + + struct usb_device_scan { +@@ -208,10 +210,10 @@ static void usb_hub_power_on(struct usb_hub_device *hub) + * will be done based on this value in the USB port loop in + * usb_hub_configure() later. + */ +- hub->connect_timeout = hub->query_delay + 1000; ++ hub->connect_timeout = hub->query_delay + HUB_DEBOUNCE_TIMEOUT; + debug("devnum=%d poweron: query_delay=%d connect_timeout=%d\n", + dev->devnum, max(100, (int)pgood_delay), +- max(100, (int)pgood_delay) + 1000); ++ max(100, (int)pgood_delay) + HUB_DEBOUNCE_TIMEOUT); + } + + #if !CONFIG_IS_ENABLED(DM_USB) +diff --git a/configs/dh_imx6_defconfig b/configs/dh_imx6_defconfig +index ce966420f8..a1206d238e 100644 +--- a/configs/dh_imx6_defconfig ++++ b/configs/dh_imx6_defconfig +@@ -98,6 +98,8 @@ CONFIG_MXC_SPI=y + CONFIG_SYSRESET=y + CONFIG_SYSRESET_WATCHDOG=y + CONFIG_USB=y ++CONFIG_USB_HOST_ETHER=y ++CONFIG_USB_ETHER_ASIX=y + CONFIG_USB_GADGET=y + CONFIG_USB_GADGET_MANUFACTURER="dh" + CONFIG_USB_GADGET_VENDOR_NUM=0x0525 +diff --git a/configs/kp_imx6q_tpc_defconfig b/configs/kp_imx6q_tpc_defconfig +index 96c1061683..63c7b38755 100644 +--- a/configs/kp_imx6q_tpc_defconfig ++++ b/configs/kp_imx6q_tpc_defconfig +@@ -79,5 +79,7 @@ CONFIG_SYSRESET_WATCHDOG=y + CONFIG_IMX_THERMAL=y + CONFIG_USB=y + # CONFIG_SPL_DM_USB is not set ++CONFIG_USB_HOST_ETHER=y ++CONFIG_USB_ETHER_ASIX=y + CONFIG_WATCHDOG_TIMEOUT_MSECS=60000 + CONFIG_IMX_WATCHDOG=y +diff --git a/configs/mx53ppd_defconfig b/configs/mx53ppd_defconfig +index 4a8fa34c27..f879133e94 100644 +--- a/configs/mx53ppd_defconfig ++++ b/configs/mx53ppd_defconfig +@@ -69,6 +69,10 @@ CONFIG_SYSRESET=y + CONFIG_SYSRESET_WATCHDOG=y + CONFIG_USB=y + CONFIG_USB_EHCI_MX5=y ++CONFIG_USB_HOST_ETHER=y ++CONFIG_USB_ETHER_ASIX=y ++CONFIG_USB_ETHER_MCS7830=y ++CONFIG_USB_ETHER_SMSC95XX=y + CONFIG_DM_VIDEO=y + CONFIG_SYS_WHITE_ON_BLACK=y + CONFIG_VIDEO_IPUV3=y +diff --git a/configs/rpi_0_w_defconfig b/configs/rpi_0_w_defconfig +index d17e102052..c217a95ff3 100644 +--- a/configs/rpi_0_w_defconfig ++++ b/configs/rpi_0_w_defconfig +@@ -12,6 +12,7 @@ CONFIG_USE_PREBOOT=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set + CONFIG_MISC_INIT_R=y ++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 8b8affb777..82968a486d 100644 +--- a/configs/rpi_2_defconfig ++++ b/configs/rpi_2_defconfig +@@ -12,6 +12,7 @@ CONFIG_USE_PREBOOT=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set + CONFIG_MISC_INIT_R=y ++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 b867b7fa7b..9ccffef356 100644 +--- a/configs/rpi_3_32b_defconfig ++++ b/configs/rpi_3_32b_defconfig +@@ -13,6 +13,7 @@ CONFIG_USE_PREBOOT=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set + CONFIG_MISC_INIT_R=y ++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 043665c3d1..8d8e6cd03b 100644 +--- a/configs/rpi_3_b_plus_defconfig ++++ b/configs/rpi_3_b_plus_defconfig +@@ -13,6 +13,7 @@ CONFIG_USE_PREBOOT=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set + CONFIG_MISC_INIT_R=y ++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 3cebd657da..efd47bf924 100644 +--- a/configs/rpi_3_defconfig ++++ b/configs/rpi_3_defconfig +@@ -13,6 +13,7 @@ CONFIG_USE_PREBOOT=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set + CONFIG_MISC_INIT_R=y ++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 b813d04639..f1c5cb8787 100644 +--- a/configs/rpi_4_32b_defconfig ++++ b/configs/rpi_4_32b_defconfig +@@ -11,6 +11,7 @@ CONFIG_PREBOOT="pci enum; usb start;" + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set + CONFIG_MISC_INIT_R=y ++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 de2658ae88..1fe4bb23b4 100644 +--- a/configs/rpi_4_defconfig ++++ b/configs/rpi_4_defconfig +@@ -11,6 +11,7 @@ CONFIG_PREBOOT="pci enum; usb start;" + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set + CONFIG_MISC_INIT_R=y ++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 f90107e548..fc0739978f 100644 +--- a/configs/rpi_arm64_defconfig ++++ b/configs/rpi_arm64_defconfig +@@ -11,6 +11,7 @@ CONFIG_PREBOOT="pci enum; usb start;" + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set + CONFIG_MISC_INIT_R=y ++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 af2189b8fe..59ae0ed4a8 100644 +--- a/configs/rpi_defconfig ++++ b/configs/rpi_defconfig +@@ -12,6 +12,7 @@ CONFIG_USE_PREBOOT=y + # CONFIG_DISPLAY_CPUINFO is not set + # CONFIG_DISPLAY_BOARDINFO is not set + CONFIG_MISC_INIT_R=y ++CONFIG_FDT_SIMPLEFB=y + CONFIG_SYS_PROMPT="U-Boot> " + CONFIG_CMD_GPIO=y + CONFIG_CMD_MMC=y +diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig +index ea08a9e5bd..e16026d5f8 100644 +--- a/configs/sandbox_defconfig ++++ b/configs/sandbox_defconfig +@@ -28,7 +28,6 @@ CONFIG_AUTOBOOT_STOP_STR_CRYPT="$5$rounds=640000$HrpE65IkB8CM5nCL$BKT3QdF98Bo8fJ + CONFIG_CONSOLE_RECORD=y + CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000 + CONFIG_PRE_CONSOLE_BUFFER=y +-CONFIG_LOG=y + CONFIG_DISPLAY_BOARDINFO_LATE=y + CONFIG_MISC_INIT_F=y + CONFIG_STACKPROTECTOR=y +@@ -105,6 +104,7 @@ CONFIG_CMD_CRAMFS=y + CONFIG_CMD_EXT4_WRITE=y + CONFIG_CMD_SQUASHFS=y + CONFIG_CMD_MTDPARTS=y ++CONFIG_CMD_LOG=y + CONFIG_CMD_STACKPROTECTOR_TEST=y + CONFIG_MAC_PARTITION=y + CONFIG_AMIGA_PARTITION=y +@@ -266,6 +266,10 @@ CONFIG_SANDBOX_TIMER=y + CONFIG_USB=y + CONFIG_USB_EMUL=y + CONFIG_USB_KEYBOARD=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_DOWNLOAD=y ++CONFIG_USB_ETHER=y ++CONFIG_USB_ETH_CDC=y + CONFIG_DM_VIDEO=y + CONFIG_VIDEO_COPY=y + CONFIG_CONSOLE_ROTATION=y +diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig +index 071dac96af..3ce7ca1eb7 100644 +--- a/configs/stih410-b2260_defconfig ++++ b/configs/stih410-b2260_defconfig +@@ -50,6 +50,10 @@ CONFIG_USB_EHCI_GENERIC=y + CONFIG_USB_OHCI_HCD=y + CONFIG_USB_OHCI_GENERIC=y + CONFIG_USB_DWC3=y ++CONFIG_USB_HOST_ETHER=y ++CONFIG_USB_ETHER_ASIX=y ++CONFIG_USB_ETHER_MCS7830=y ++CONFIG_USB_ETHER_SMSC95XX=y + CONFIG_USB_GADGET=y + CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics" + CONFIG_USB_GADGET_VENDOR_NUM=0x483 +diff --git a/configs/stv0991_defconfig b/configs/stv0991_defconfig +index 7fe5f99f4d..f516272844 100644 +--- a/configs/stv0991_defconfig ++++ b/configs/stv0991_defconfig +@@ -10,7 +10,6 @@ CONFIG_ENV_SIZE=0x10000 + CONFIG_ENV_OFFSET=0x30000 + CONFIG_ENV_SECT_SIZE=0x10000 + CONFIG_DEFAULT_DEVICE_TREE="stv0991" +-CONFIG_SYS_EXTRA_OPTIONS="STV0991" + CONFIG_BOOTDELAY=3 + CONFIG_AUTOBOOT_KEYED=y + CONFIG_AUTOBOOT_PROMPT="Hit SPACE in %d seconds to stop autoboot.\n" +diff --git a/doc/board/st/stm32mp1.rst b/doc/board/st/stm32mp1.rst +index 42bb94148d..09187a2a88 100644 +--- a/doc/board/st/stm32mp1.rst ++++ b/doc/board/st/stm32mp1.rst +@@ -1,41 +1,31 @@ + .. SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause + .. sectionauthor:: Patrick Delaunay + +-STM32MP15x boards ++STM32MP1xx boards + ================= + +-This is a quick instruction for setup STM32MP15x boards. ++This is a quick instruction for setup STMicroelectronics STM32MP1xx boards. + + Futher information can be found in STMicrolectronics STM32 WIKI_. + + Supported devices + ----------------- + +-U-Boot supports STMP32MP15x SoCs: ++U-Boot supports all the STMicroelectronics MPU with the associated boards + +- - STM32MP157 +- - STM32MP153 +- - STM32MP151 ++ - STMP32MP15x SoCs: + +-The STM32MP15x is a Cortex-A MPU aimed at various applications. ++ - STM32MP157 ++ - STM32MP153 ++ - STM32MP151 + +-It features: +- +- - Dual core Cortex-A7 application core (Single on STM32MP151) +- - 2D/3D image composition with GPU (only on STM32MP157) +- - Standard memories interface support +- - Standard connectivity, widely inherited from the STM32 MCU family +- - Comprehensive security support ++ - STMP32MP13x SoCs: + +-Each line comes with a security option (cryptography & secure boot) and +-a Cortex-A frequency option: +- +- - A : Cortex-A7 @ 650 MHz +- - C : Secure Boot + HW Crypto + Cortex-A7 @ 650 MHz +- - D : Cortex-A7 @ 800 MHz +- - F : Secure Boot + HW Crypto + Cortex-A7 @ 800 MHz ++ - STM32MP135 ++ - STM32MP133 ++ - STM32MP131 + +-Everything is supported in Linux but U-Boot is limited to: ++Everything is supported in Linux but U-Boot is limited to the boot device: + + 1. UART + 2. SD card/MMC controller (SDMMC) +@@ -49,16 +39,63 @@ And the necessary drivers + 1. I2C + 2. STPMIC1 (PMIC and regulator) + 3. Clock, Reset, Sysreset +- 4. Fuse ++ 4. Fuse (BSEC) ++ 5. OP-TEE ++ 6. ETH ++ 7. USB host ++ 8. WATCHDOG ++ 9. RNG ++ 10. RTC ++ ++STM32MP15x ++`````````` ++ ++The STM32MP15x is a Cortex-A7 MPU aimed at various applications. ++ ++It features: ++ ++ - Dual core Cortex-A7 application core (Single on STM32MP151) ++ - 2D/3D image composition with GPU (only on STM32MP157) ++ - Standard memories interface support ++ - Standard connectivity, widely inherited from the STM32 MCU family ++ - Comprehensive security support ++ - Cortex M4 coprocessor ++ ++Each line comes with a security option (cryptography & secure boot) and ++a Cortex-A frequency option: ++ ++ - A : Cortex-A7 @ 650 MHz ++ - C : Secure Boot + HW Crypto + Cortex-A7 @ 650 MHz ++ - D : Cortex-A7 @ 800 MHz ++ - F : Secure Boot + HW Crypto + Cortex-A7 @ 800 MHz + + Currently the following boards are supported: + + + stm32mp157a-dk1.dts ++ + stm32mp157a-ed1.dts ++ + stm32mp157a-ev1.dts + + stm32mp157c-dk2.dts + + stm32mp157c-ed1.dts + + stm32mp157c-ev1.dts ++ + stm32mp157d-dk1.dts ++ + stm32mp157d-ed1.dts ++ + stm32mp157d-ev1.dts ++ + stm32mp157f-dk2.dts ++ + stm32mp157f-ed1.dts ++ + stm32mp157f-ev1.dts + + stm32mp15xx-dhcor-avenger96.dts + ++STM32MP13x ++`````````` ++ ++The STM32MP13x is a single Cortex-A7 MPU aimed at various applications. ++ ++Currently the following boards are supported: ++ ++ + stm32mp135d-dk.dts ++ + stm32mp135f-dk.dts ++ ++ + Boot Sequences + -------------- + +@@ -71,12 +108,22 @@ Boot Sequences + + +------------------------+-------------------------+--------------+ + | | embedded RAM | DDR | + +----------+------------------------+-------------------------+--------------+ ++| TrustZone| secure monitor | +++----------+------------------------+-------------------------+--------------+ ++ ++The trusted boot chain is recommended with: ++ ++- FSBL = **TF-A BL2** ++- Secure monitor = **OP-TEE** ++- SSBL = **U-Boot** ++ ++It is the only supported boot chain for STM32MP13x family. + + The **Trusted** boot chain with TF-A_ + ````````````````````````````````````` + + defconfig_file : +- + **stm32mp15_defconfig** (for TF-A_ with FIP support) ++ + **stm32mp15_defconfig** and **stm32mp13_defconfig** (for TF-A_ with FIP support) + + **stm32mp15_trusted_defconfig** (for TF-A_ without FIP support) + + +-------------+--------------------------+------------+-------+ +@@ -98,8 +145,8 @@ TF-A_ (BL2) initialize the DDR and loads the next stage binaries from a FIP file + the secure monitor to access to secure resources. + + HW_CONFIG: The hardware configuration file = the U-Boot device tree + +-The **Basic** boot chain with SPL +-````````````````````````````````` ++The **Basic** boot chain with SPL (for STM32MP15x) ++`````````````````````````````````````````````````` + + defconfig_file : + + **stm32mp15_basic_defconfig** +@@ -117,37 +164,58 @@ SPL has limited security initialization. + U-Boot is running in secure mode and provide a secure monitor to the kernel + with only PSCI support (Power State Coordination Interface defined by ARM). + +-All the STM32MP15x boards supported by U-Boot use the same generic board +-stm32mp1 which support all the bootable devices. ++.. warning:: This alternate **basic** boot chain with SPL is not supported/promoted by STMicroelectronics to make product. ++ ++Device Tree ++----------- + +-Each board is configured only with the associated device tree. ++All the STM32MP15x and STM32MP13x boards supported by U-Boot use the same generic board ++stm32mp1 which supports all the bootable devices. + +-Device Tree Selection +---------------------- ++Each STMicroelectronics board is only configured with the associated device tree. + +-You need to select the appropriate device tree for your board, +-the supported device trees for STM32MP15x are: ++STM32MP15x device Tree Selection ++```````````````````````````````` ++The supported device trees for STM32MP15x (stm32mp15_trusted_defconfig and stm32mp15_basic_defconfig) are: + + + ev1: eval board with pmic stpmic1 (ev1 = mother board + daughter ed1) + ++ + stm32mp157a-ev1 + + stm32mp157c-ev1 ++ + stm32mp157d-ev1 ++ + stm32mp157f-ev1 + + + ed1: daughter board with pmic stpmic1 + ++ + stm32mp157a-ed1 + + stm32mp157c-ed1 ++ + stm32mp157d-ed1 ++ + stm32mp157f-ed1 + + + dk1: Discovery board + + + stm32mp157a-dk1 ++ + stm32mp157d-dk1 + + + dk2: Discovery board = dk1 with a BT/WiFI combo and a DSI panel + + + stm32mp157c-dk2 ++ + stm32mp157f-dk2 + + + avenger96: Avenger96 board from Arrow Electronics based on DH Elec. DHCOR SoM + + + stm32mp15xx-dhcor-avenger96 + ++STM32MP13x device Tree Selection ++```````````````````````````````` ++The supported device trees for STM32MP13x (stm32mp13_defconfig) are: ++ +++ dk: Discovery board ++ ++ + stm32mp135d-dk ++ + stm32mp135f-dk ++ ++ + Build Procedure + --------------- + +@@ -170,6 +238,7 @@ Build Procedure + + for example: use one output directory for each configuration:: + ++ # export KBUILD_OUTPUT=stm32mp13 + # export KBUILD_OUTPUT=stm32mp15 + # export KBUILD_OUTPUT=stm32mp15_trusted + # export KBUILD_OUTPUT=stm32mp15_basic +@@ -184,9 +253,10 @@ Build Procedure + + with : + +- - For **trusted** boot mode : **stm32mp15_defconfig** or +- stm32mp15_trusted_defconfig +- - For basic boot mode: stm32mp15_basic_defconfig ++ - For **trusted** boot mode : ++ - For STM32MP13x: **stm32mp13_defconfig** ++ - For STM32MP15x: **stm32mp15_defconfig** or stm32mp15_trusted_defconfig ++ - For STM32MP15x basic boot mode: stm32mp15_basic_defconfig + + 5. Configure the device-tree and build the U-Boot image:: + +@@ -194,37 +264,42 @@ Build Procedure + + Examples: + +- a) trusted boot with FIP on ev1:: ++ a) trusted boot with FIP on STM32MP15x ev1:: + + # export KBUILD_OUTPUT=stm32mp15 + # make stm32mp15_defconfig + # make DEVICE_TREE=stm32mp157c-ev1 all + +- b) trusted boot without FIP on dk2:: ++ b) trusted boot on STM32MP13x discovery board:: + +- # export KBUILD_OUTPUT=stm32mp15_trusted +- # make stm32mp15_trusted_defconfig +- # make DEVICE_TREE=stm32mp157c-dk2 all ++ # export KBUILD_OUTPUT=stm32mp13 ++ # make stm32mp13_defconfig ++ # make DEVICE_TREE=stm32mp135d-dk all + +- c) basic boot on ev1:: ++ DEVICE_TEE selection is optional as stm32mp135f-dk is the default board of the defconfig:: ++ ++ # make stm32mp13_defconfig ++ # make all ++ ++ c) basic boot on STM32MP15x ev1:: + + # export KBUILD_OUTPUT=stm32mp15_basic + # make stm32mp15_basic_defconfig + # make DEVICE_TREE=stm32mp157c-ev1 all + +- d) basic boot on ed1:: ++ d) basic boot on STM32MP15x ed1:: + + # export KBUILD_OUTPUT=stm32mp15_basic + # make stm32mp15_basic_defconfig + # make DEVICE_TREE=stm32mp157c-ed1 all + +- e) basic boot on dk1:: ++ e) basic boot on STM32MP15x dk1:: + + # export KBUILD_OUTPUT=stm32mp15_basic + # make stm32mp15_basic_defconfig + # make DEVICE_TREE=stm32mp157a-dk1 all + +- f) basic boot on avenger96:: ++ f) basic boot on STM32MP15x avenger96:: + + # export KBUILD_OUTPUT=stm32mp15_basic + # make stm32mp15_basic_defconfig +@@ -235,6 +310,7 @@ Build Procedure + So in the output directory (selected by KBUILD_OUTPUT), + you can found the needed U-Boot files: + ++ - stm32mp13_defconfig = **u-boot-nodtb.bin** and **u-boot.dtb** + - stm32mp15_defconfig = **u-boot-nodtb.bin** and **u-boot.dtb** + + - stm32mp15_trusted_defconfig = u-boot.stm32 +@@ -325,9 +401,9 @@ the boot pin values = BOOT0, BOOT1, BOOT2 + | SPI-NAND | 1 | 1 | 1 | + +-------------+---------+---------+---------+ + +-- on the **daugther board ed1 = MB1263** with the switch SW1 +-- on **Avenger96** with switch S3 (NOR and SPI-NAND are not applicable) +-- on board **DK1/DK2** with the switch SW1 = BOOT0, BOOT2 ++- on the STM32MP15x **daugther board ed1 = MB1263** with the switch SW1 ++- on STM32MP15x **Avenger96** with switch S3 (NOR and SPI-NAND are not applicable) ++- on board STM32MP15x **DK1/DK2** with the switch SW1 = BOOT0, BOOT2 + with only 2 pins available (BOOT1 is forced to 0 and NOR not supported), + the possible value becomes: + +@@ -355,7 +431,7 @@ The communication between HOST and board is based on + Prepare an SD card + ------------------ + +-The minimal requirements for STMP32MP15x boot up to U-Boot are: ++The minimal requirements for STMP32MP15x and STM32MP13x boot up to U-Boot are: + + - GPT partitioning (with gdisk or with sgdisk) + - 2 fsbl partitions, named "fsbl1" and "fsbl2", size at least 256KiB +@@ -511,14 +587,25 @@ MAC Address + Please read doc/README.enetaddr for the implementation guidelines for mac id + usage. Basically, environment has precedence over board specific storage. + +-For STMicroelectonics board, it is retrieved in STM32MP15x OTP : ++For STMicroelectonics board, it is retrieved in: ++ ++ - STM32MP15x OTP: + +- - OTP_57[31:0] = MAC_ADDR[31:0] +- - OTP_58[15:0] = MAC_ADDR[47:32] ++ - OTP_57[31:0] = MAC_ADDR[31:0] ++ - OTP_58[15:0] = MAC_ADDR[47:32] + +-To program a MAC address on virgin OTP words above, you can use the fuse command ++ - STM32MP13x OTP: ++ ++ - OTP_57[31:0] = MAC_ADDR0[31:0] ++ - OTP_58[15:0] = MAC_ADDR0[47:32] ++ - OTP_58[31:16] = MAC_ADDR1[15:0] ++ - OTP_59[31:0] = MAC_ADDR1[47:16] ++ ++To program a MAC address on virgin STM32MP15x OTP words above, you can use the fuse command + on bank 0 to access to internal OTP and lock them: + ++In the next example we are using the 2 OTPs used on STM32MP15x. ++ + Prerequisite: check if a MAC address isn't yet programmed in OTP + + 1) check OTP: their value must be equal to 0:: +@@ -532,7 +619,7 @@ Prerequisite: check if a MAC address isn't yet programmed in OTP + STM32MP> env print ethaddr + ## Error: "ethaddr" not defined + +-3) check lock status of fuse 57 & 58 (at 0x39, 0=unlocked, 1=locked):: ++3) check lock status of fuse 57 & 58 (at 0x39, 0=unlocked, 0x40000000=locked):: + + STM32MP> fuse sense 0 0x10000039 2 + Sensing bank 0: +@@ -552,11 +639,11 @@ Example to set mac address "12:34:56:78:9a:bc" + + 3) Lock OTP:: + +- STM32MP> fuse prog 0 0x10000039 1 1 ++ STM32MP> fuse prog 0 0x10000039 0x40000000 0x40000000 + + STM32MP> fuse sense 0 0x10000039 2 + Sensing bank 0: +- Word 0x10000039: 00000001 00000001 ++ Word 0x10000039: 40000000 40000000 + + 4) next REBOOT, in the trace:: + +@@ -571,8 +658,8 @@ Example to set mac address "12:34:56:78:9a:bc" + OTP are protected. It is already done for the board + provided by STMicroelectronics. + +-Coprocessor firmware +--------------------- ++Coprocessor firmware on STM32MP15x ++---------------------------------- + + U-Boot can boot the coprocessor before the kernel (coprocessor early boot). + +@@ -645,16 +732,18 @@ On EV1 board, booting from SD card, without OP-TEE_:: + dev: eMMC alt: 15 name: mmc1_rootfs layout: RAW_ADDR + dev: eMMC alt: 16 name: mmc1_userfs layout: RAW_ADDR + dev: MTD alt: 17 name: nor0 layout: RAW_ADDR +- dev: MTD alt: 18 name: nand0 layout: RAW_ADDR +- dev: VIRT alt: 19 name: OTP layout: RAW_ADDR +- dev: VIRT alt: 20 name: PMIC layout: RAW_ADDR ++ dev: MTD alt: 18 name: nor1 layout: RAW_ADDR ++ dev: MTD alt: 19 name: nand0 layout: RAW_ADDR ++ dev: VIRT alt: 20 name: OTP layout: RAW_ADDR ++ dev: VIRT alt: 21 name: PMIC layout: RAW_ADDR + + All the supported device are exported for dfu-util tool:: + + $> dfu-util -l +- Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=20, name="PMIC", serial="002700333338511934383330" +- Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=19, name="OTP", serial="002700333338511934383330" +- Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=18, name="nand0", serial="002700333338511934383330" ++ Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=21, name="PMIC", serial="002700333338511934383330" ++ Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=20, name="OTP", serial="002700333338511934383330" ++ Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=19, name="nand0", serial="002700333338511934383330" ++ Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=18, name="nor1", serial="002700333338511934383330" + Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=17, name="nor0", serial="002700333338511934383330" + Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=16, name="mmc1_userfs", serial="002700333338511934383330" + Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=15, name="mmc1_rootfs", serial="002700333338511934383330" +@@ -676,7 +765,7 @@ All the supported device are exported for dfu-util tool:: + + You can update the boot device: + +-- SD card (mmc0) :: ++- SD card (mmc0):: + + $> dfu-util -d 0483:5720 -a 3 -D tf-a-stm32mp157c-ev1.stm32 + $> dfu-util -d 0483:5720 -a 4 -D tf-a-stm32mp157c-ev1.stm32 +@@ -705,12 +794,12 @@ You can update the boot device: + When the board is booting for nor0 or nand0, + only the MTD partition on the boot devices are available, for example: + +-- NOR (nor0 = alt 20) & NAND (nand0 = alt 26) :: ++- NOR (nor0 = alt 20, nor1 = alt 26) & NAND (nand0 = alt 27) : + + $> dfu-util -d 0483:5720 -a 21 -D tf-a-stm32mp157c-ev1.stm32 + $> dfu-util -d 0483:5720 -a 22 -D tf-a-stm32mp157c-ev1.stm32 + $> dfu-util -d 0483:5720 -a 23 -D fip-stm32mp157c-ev1.bin +- $> dfu-util -d 0483:5720 -a 27 -D st-image-weston-openstlinux-weston-stm32mp1_nand_4_256_multivolume.ubi ++ $> dfu-util -d 0483:5720 -a 28 -D st-image-weston-openstlinux-weston-stm32mp1_nand_4_256_multivolume.ubi + + - NAND (nand0 = alt 21):: + +diff --git a/doc/device-tree-bindings/arm/arm,scmi.txt b/doc/device-tree-bindings/arm/arm,scmi.txt +index a76124f4a3..0a7886da24 100644 +--- a/doc/device-tree-bindings/arm/arm,scmi.txt ++++ b/doc/device-tree-bindings/arm/arm,scmi.txt +@@ -1,231 +1,2 @@ +-System Control and Management Interface (SCMI) Message Protocol +----------------------------------------------------------- +- +-The SCMI is intended to allow agents such as OSPM to manage various functions +-that are provided by the hardware platform it is running on, including power +-and performance functions. +- +-This binding is intended to define the interface the firmware implementing +-the SCMI as described in ARM document number ARM DEN 0056A ("ARM System Control +-and Management Interface Platform Design Document")[0] provide for OSPM in +-the device tree. +- +-Required properties: +- +-The scmi node with the following properties shall be under the /firmware/ node. +- +-- compatible : shall be "arm,scmi" or "arm,scmi-smc" for smc/hvc transports +-- mboxes: List of phandle and mailbox channel specifiers. It should contain +- exactly one or two mailboxes, one for transmitting messages("tx") +- and another optional for receiving the notifications("rx") if +- supported. +-- shmem : List of phandle pointing to the shared memory(SHM) area as per +- generic mailbox client binding. +-- #address-cells : should be '1' if the device has sub-nodes, maps to +- protocol identifier for a given sub-node. +-- #size-cells : should be '0' as 'reg' property doesn't have any size +- associated with it. +-- arm,smc-id : SMC id required when using smc or hvc transports +- +-Optional properties: +- +-- mbox-names: shall be "tx" or "rx" depending on mboxes entries. +- +-See Documentation/devicetree/bindings/mailbox/mailbox.txt for more details +-about the generic mailbox controller and client driver bindings. +- +-The mailbox is the only permitted method of calling the SCMI firmware. +-Mailbox doorbell is used as a mechanism to alert the presence of a +-messages and/or notification. +- +-Each protocol supported shall have a sub-node with corresponding compatible +-as described in the following sections. If the platform supports dedicated +-communication channel for a particular protocol, the 3 properties namely: +-mboxes, mbox-names and shmem shall be present in the sub-node corresponding +-to that protocol. +- +-Clock/Performance bindings for the clocks/OPPs based on SCMI Message Protocol +------------------------------------------------------------- +- +-This binding uses the common clock binding[1]. +- +-Required properties: +-- #clock-cells : Should be 1. Contains the Clock ID value used by SCMI commands. +- +-Power domain bindings for the power domains based on SCMI Message Protocol +------------------------------------------------------------- +- +-This binding for the SCMI power domain providers uses the generic power +-domain binding[2]. +- +-Required properties: +- - #power-domain-cells : Should be 1. Contains the device or the power +- domain ID value used by SCMI commands. +- +-Regulator bindings for the SCMI Regulator based on SCMI Message Protocol +------------------------------------------------------------- +-An SCMI Regulator is permanently bound to a well defined SCMI Voltage Domain, +-and should be always positioned as a root regulator. +-It does not support any current operation. +- +-SCMI Regulators are grouped under a 'regulators' node which in turn is a child +-of the SCMI Voltage protocol node inside the desired SCMI instance node. +- +-This binding uses the common regulator binding[6]. +- +-Required properties: +- - reg : shall identify an existent SCMI Voltage Domain. +- +-Sensor bindings for the sensors based on SCMI Message Protocol +--------------------------------------------------------------- +-SCMI provides an API to access the various sensors on the SoC. +- +-Required properties: +-- #thermal-sensor-cells: should be set to 1. This property follows the +- thermal device tree bindings[3]. +- +- Valid cell values are raw identifiers (Sensor ID) +- as used by the firmware. Refer to platform details +- for your implementation for the IDs to use. +- +-Reset signal bindings for the reset domains based on SCMI Message Protocol +------------------------------------------------------------- +- +-This binding for the SCMI reset domain providers uses the generic reset +-signal binding[5]. +- +-Required properties: +- - #reset-cells : Should be 1. Contains the reset domain ID value used +- by SCMI commands. +- +-SRAM and Shared Memory for SCMI +-------------------------------- +- +-A small area of SRAM is reserved for SCMI communication between application +-processors and SCP. +- +-The properties should follow the generic mmio-sram description found in [4] +- +-Each sub-node represents the reserved area for SCMI. +- +-Required sub-node properties: +-- reg : The base offset and size of the reserved area with the SRAM +-- compatible : should be "arm,scmi-shmem" for Non-secure SRAM based +- shared memory +- +-[0] http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/index.html +-[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +-[2] Documentation/devicetree/bindings/power/power-domain.yaml +-[3] Documentation/devicetree/bindings/thermal/thermal.txt +-[4] Documentation/devicetree/bindings/sram/sram.yaml +-[5] Documentation/devicetree/bindings/reset/reset.txt +-[6] Documentation/devicetree/bindings/regulator/regulator.yaml +- +-Example: +- +-sram@50000000 { +- compatible = "mmio-sram"; +- reg = <0x0 0x50000000 0x0 0x10000>; +- +- #address-cells = <1>; +- #size-cells = <1>; +- ranges = <0 0x0 0x50000000 0x10000>; +- +- cpu_scp_lpri: scp-shmem@0 { +- compatible = "arm,scmi-shmem"; +- reg = <0x0 0x200>; +- }; +- +- cpu_scp_hpri: scp-shmem@200 { +- compatible = "arm,scmi-shmem"; +- reg = <0x200 0x200>; +- }; +-}; +- +-mailbox@40000000 { +- .... +- #mbox-cells = <1>; +- reg = <0x0 0x40000000 0x0 0x10000>; +-}; +- +-firmware { +- +- ... +- +- scmi { +- compatible = "arm,scmi"; +- mboxes = <&mailbox 0 &mailbox 1>; +- mbox-names = "tx", "rx"; +- shmem = <&cpu_scp_lpri &cpu_scp_hpri>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- scmi_devpd: protocol@11 { +- reg = <0x11>; +- #power-domain-cells = <1>; +- }; +- +- scmi_dvfs: protocol@13 { +- reg = <0x13>; +- #clock-cells = <1>; +- }; +- +- scmi_clk: protocol@14 { +- reg = <0x14>; +- #clock-cells = <1>; +- }; +- +- scmi_sensors0: protocol@15 { +- reg = <0x15>; +- #thermal-sensor-cells = <1>; +- }; +- +- scmi_reset: protocol@16 { +- reg = <0x16>; +- #reset-cells = <1>; +- }; +- +- scmi_voltage: protocol@17 { +- reg = <0x17>; +- +- regulators { +- regulator_devX: regulator@0 { +- reg = <0x0>; +- regulator-max-microvolt = <3300000>; +- }; +- +- regulator_devY: regulator@9 { +- reg = <0x9>; +- regulator-min-microvolt = <500000>; +- regulator-max-microvolt = <4200000>; +- }; +- +- ... +- }; +- }; +- }; +-}; +- +-cpu@0 { +- ... +- reg = <0 0>; +- clocks = <&scmi_dvfs 0>; +-}; +- +-hdlcd@7ff60000 { +- ... +- reg = <0 0x7ff60000 0 0x1000>; +- clocks = <&scmi_clk 4>; +- power-domains = <&scmi_devpd 1>; +- resets = <&scmi_reset 10>; +-}; +- +-thermal-zones { +- soc_thermal { +- polling-delay-passive = <100>; +- polling-delay = <1000>; +- /* sensor ID */ +- thermal-sensors = <&scmi_sensors0 3>; +- ... +- }; +-}; ++See Binding in Linux documentation: ++Documentation/devicetree/bindings/firmware/arm,scmi.yaml +diff --git a/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt b/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt +index ac6a7df432..e6ea8d0ef5 100644 +--- a/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt ++++ b/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt +@@ -3,7 +3,8 @@ ST,stm32mp1 DDR3/LPDDR2/LPDDR3 Controller (DDRCTRL and DDRPHYC) + -------------------- + Required properties: + -------------------- +-- compatible : Should be "st,stm32mp1-ddr" ++- compatible : Should be "st,stm32mp1-ddr" for STM32MP15x ++ Should be "st,stm32mp13-ddr" for STM32MP13x + - reg : controleur (DDRCTRL) and phy (DDRPHYC) base address + - clocks : controller clocks handle + - clock-names : associated controller clock names +@@ -13,6 +14,8 @@ Required properties: + the next attributes are DDR parameters, they are generated by DDR tools + included in STM32 Cube tool + ++They are required only in SPL, when TFABOOT is not activated. ++ + info attributes: + ---------------- + - st,mem-name : name for DDR configuration, simple string for information +@@ -24,7 +27,7 @@ controlleur attributes: + ----------------------- + - st,ctl-reg : controleur values depending of the DDR type + (DDR3/LPDDR2/LPDDR3) +- for STM32MP15x: 25 values are requested in this order ++ for STM32MP15x and STM32MP13x: 25 values are requested in this order + MSTR + MRCTRL0 + MRCTRL1 +@@ -53,7 +56,7 @@ controlleur attributes: + + - st,ctl-timing : controleur values depending of frequency and timing parameter + of DDR +- for STM32MP15x: 12 values are requested in this order ++ for STM32MP15x and STM32MP13x: 12 values are requested in this order + RFSHTMG + DRAMTMG0 + DRAMTMG1 +@@ -68,7 +71,7 @@ controlleur attributes: + ODTCFG + + - st,ctl-map : controleur values depending of address mapping +- for STM32MP15x: 9 values are requested in this order ++ for STM32MP15x and STM32MP13x: 9 values are requested in this order + ADDRMAP1 + ADDRMAP2 + ADDRMAP3 +@@ -99,6 +102,19 @@ controlleur attributes: + PCFGWQOS0_1 + PCFGWQOS1_1 + ++ for STM32MP13x: 11 values are requested in this order ++ SCHED ++ SCHED1 ++ PERFHPR1 ++ PERFLPR1 ++ PERFWR1 ++ PCFGR_0 ++ PCFGW_0 ++ PCFGQOS0_0 ++ PCFGQOS1_0 ++ PCFGWQOS0_0 ++ PCFGWQOS1_0 ++ + phyc attributes: + ---------------- + - st,phy-reg : phy values depending of the DDR type (DDR3/LPDDR2/LPDDR3) +@@ -115,8 +131,19 @@ phyc attributes: + DX2GCR + DX3GCR + ++ for STM32MP13x: 9 values are requested in this order ++ PGCR ++ ACIOCR ++ DXCCR ++ DSGCR ++ DCR ++ ODTCR ++ ZQ0CR1 ++ DX0GCR ++ DX1GCR ++ + - st,phy-timing : phy values depending of frequency and timing parameter of DDR +- for STM32MP15x: 10 values are requested in this order ++ for STM32MP15x and STM32MP13x: 10 values are requested in this order + PTR0 + PTR1 + PTR2 +@@ -128,33 +155,18 @@ phyc attributes: + MR2 + MR3 + +-- st,phy-cal : phy cal depending of calibration or tuning of DDR +- This parameter is optional; when it is absent the built-in PHY +- calibration is done. +- for STM32MP15x: 12 values are requested in this order ++ for STM32MP13x: 6 values are requested in this order + DX0DLLCR + DX0DQTR + DX0DQSTR + DX1DLLCR + DX1DQTR + DX1DQSTR +- DX2DLLCR +- DX2DQTR +- DX2DQSTR +- DX3DLLCR +- DX3DQTR +- DX3DQSTR +- + Example: + + / { + soc { +- u-boot,dm-spl; +- + ddr: ddr@0x5A003000{ +- u-boot,dm-spl; +- u-boot,dm-pre-reloc; +- + compatible = "st,stm32mp1-ddr"; + + reg = <0x5A003000 0x550 +@@ -280,21 +292,6 @@ Example: + 0x00000000 /*MR3*/ + >; + +- st,phy-cal = < +- 0x40000000 /*DX0DLLCR*/ +- 0xFFFFFFFF /*DX0DQTR*/ +- 0x3DB02000 /*DX0DQSTR*/ +- 0x40000000 /*DX1DLLCR*/ +- 0xFFFFFFFF /*DX1DQTR*/ +- 0x3DB02000 /*DX1DQSTR*/ +- 0x40000000 /*DX2DLLCR*/ +- 0xFFFFFFFF /*DX2DQTR*/ +- 0x3DB02000 /*DX2DQSTR*/ +- 0x40000000 /*DX3DLLCR*/ +- 0xFFFFFFFF /*DX3DQTR*/ +- 0x3DB02000 /*DX3DQSTR*/ +- >; +- + status = "okay"; + }; + }; +diff --git a/drivers/adc/stm32-adc-core.c b/drivers/adc/stm32-adc-core.c +index 6c176961f1..bca030891c 100644 +--- a/drivers/adc/stm32-adc-core.c ++++ b/drivers/adc/stm32-adc-core.c +@@ -201,6 +201,7 @@ err_aclk_disable: + static const struct udevice_id stm32_adc_core_ids[] = { + { .compatible = "st,stm32h7-adc-core" }, + { .compatible = "st,stm32mp1-adc-core" }, ++ { .compatible = "st,stm32mp13-adc-core" }, + {} + }; + +diff --git a/drivers/adc/stm32-adc.c b/drivers/adc/stm32-adc.c +index ad8d1a32cd..334a7358e8 100644 +--- a/drivers/adc/stm32-adc.c ++++ b/drivers/adc/stm32-adc.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -26,6 +27,8 @@ + #define STM32H7_ADC_SQR1 0x30 + #define STM32H7_ADC_DR 0x40 + #define STM32H7_ADC_DIFSEL 0xC0 ++#define STM32H7_ADC_CALFACT 0xC4 ++#define STM32H7_ADC_CALFACT2 0xC8 + + /* STM32H7_ADC_ISR - bit fields */ + #define STM32MP1_VREGREADY BIT(12) +@@ -33,13 +36,27 @@ + #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_LINCALRDYW6 BIT(27) ++#define STM32H7_LINCALRDYW5 BIT(26) ++#define STM32H7_LINCALRDYW4 BIT(25) ++#define STM32H7_LINCALRDYW3 BIT(24) ++#define STM32H7_LINCALRDYW2 BIT(23) ++#define STM32H7_LINCALRDYW1 BIT(22) ++#define STM32H7_ADCALLIN BIT(16) + #define STM32H7_BOOST BIT(8) ++#define STM32H7_ADSTP BIT(4) + #define STM32H7_ADSTART BIT(2) + #define STM32H7_ADDIS BIT(1) + #define STM32H7_ADEN BIT(0) + ++/* STM32H7_ADC_CALFACT2 - bit fields */ ++#define STM32H7_LINCALFACT_SHIFT 0 ++#define STM32H7_LINCALFACT_MASK GENMASK(29, 0) ++ + /* STM32H7_ADC_CFGR bit fields */ + #define STM32H7_EXTEN GENMASK(11, 10) + #define STM32H7_DMNGT GENMASK(1, 0) +@@ -47,80 +64,155 @@ + /* STM32H7_ADC_SQR1 - bit fields */ + #define STM32H7_SQ1_SHIFT 6 + ++/* STM32H7_ADC_DIFSEL - bit fields */ ++#define STM32H7_DIFSEL_SHIFT 0 ++#define STM32H7_DIFSEL_MASK GENMASK(19, 0) ++ + /* BOOST bit must be set on STM32H7 when ADC clock is above 20MHz */ + #define STM32H7_BOOST_CLKRATE 20000000UL + ++/* STM32MP13 - Registers for each ADC instance */ ++#define STM32MP13_ADC_DIFSEL 0xB0 ++ ++/* STM32MP13_ADC_CFGR specific bit fields */ ++#define STM32MP13_DMAEN BIT(0) ++#define STM32MP13_DMACFG BIT(1) ++ ++/* STM32MP13_ADC_DIFSEL - bit fields */ ++#define STM32MP13_DIFSEL_SHIFT 0 ++#define STM32MP13_DIFSEL_MASK GENMASK(18, 0) ++ + #define STM32_ADC_CH_MAX 20 /* max number of channels */ + #define STM32_ADC_TIMEOUT_US 100000 ++/* Number of linear calibration shadow registers / LINCALRDYW control bits */ ++#define STM32H7_LINCALFACT_NUM 6 ++#define STM32H7_LINCAL_NAME_LEN 32 + + struct stm32_adc_cfg { ++ const struct stm32_adc_regspec *regs; + unsigned int max_channels; + unsigned int num_bits; + bool has_vregready; ++ bool has_boostmode; ++ bool has_linearcal; ++ bool has_presel; + }; + + struct stm32_adc { + void __iomem *regs; + int active_channel; + const struct stm32_adc_cfg *cfg; ++ u32 lincalfact[STM32H7_LINCALFACT_NUM]; + }; + +-static int stm32_adc_stop(struct udevice *dev) ++struct stm32_adc_regs { ++ int reg; ++ int mask; ++ int shift; ++}; ++ ++struct stm32_adc_regspec { ++ const struct stm32_adc_regs difsel; ++}; ++ ++static const struct stm32_adc_regspec stm32h7_adc_regspec = { ++ .difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK }, ++}; ++ ++static const struct stm32_adc_regspec stm32mp13_adc_regspec = { ++ .difsel = { STM32MP13_ADC_DIFSEL, STM32MP13_DIFSEL_MASK }, ++}; ++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_plat *uc_pdata = dev_get_uclass_plat(dev); + struct stm32_adc_common *common = dev_get_priv(dev_get_parent(dev)); + struct stm32_adc *adc = dev_get_priv(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) ++ if (adc->cfg->has_boostmode && 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; + } + +- /* Only use single ended channels */ +- writel(0, adc->regs + STM32H7_ADC_DIFSEL); ++ 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_enable(struct udevice *dev) ++{ ++ struct stm32_adc *adc = dev_get_priv(dev); ++ int ret; ++ u32 val; + +- /* Enable ADC, Poll for ADRDY to be set (after adc startup time) */ + setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADEN); + ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val, + val & STM32H7_ADRDY, STM32_ADC_TIMEOUT_US); + if (ret < 0) { + stm32_adc_stop(dev); + dev_err(dev, "Failed to enable ADC: %d\n", ret); +- return ret; + } + ++ return ret; ++} ++ ++static int stm32_adc_start_channel(struct udevice *dev, int channel) ++{ ++ struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); ++ struct stm32_adc *adc = dev_get_priv(dev); ++ int ret; ++ ++ ret = stm32_adc_exit_pwr_down(dev); ++ if (ret < 0) ++ return ret; ++ ++ /* Only use single ended channels */ ++ clrbits_le32(adc->regs + adc->cfg->regs->difsel.reg, adc->cfg->regs->difsel.mask); ++ ++ ret = stm32_adc_enable(dev); ++ if (ret) ++ return ret; ++ + /* Preselect channels */ +- writel(uc_pdata->channel_mask, adc->regs + STM32H7_ADC_PCSEL); ++ if (adc->cfg->has_presel) ++ writel(uc_pdata->channel_mask, adc->regs + STM32H7_ADC_PCSEL); + + /* Set sampling time to max value by default */ + writel(0xffffffff, adc->regs + STM32H7_ADC_SMPR1); +@@ -129,9 +221,11 @@ static int stm32_adc_start_channel(struct udevice *dev, int channel) + /* Program regular sequence: chan in SQ1 & len = 0 for one channel */ + writel(channel << STM32H7_SQ1_SHIFT, adc->regs + STM32H7_ADC_SQR1); + +- /* Trigger detection disabled (conversion can be launched in SW) */ +- clrbits_le32(adc->regs + STM32H7_ADC_CFGR, STM32H7_EXTEN | +- STM32H7_DMNGT); ++ /* ++ * Trigger detection disabled (conversion can be launched in SW) ++ * STM32H7_DMNGT is equivalent to STM32MP13_DMAEN & STM32MP13_DMACFG ++ */ ++ clrbits_le32(adc->regs + STM32H7_ADC_CFGR, STM32H7_EXTEN | STM32H7_DMNGT); + adc->active_channel = channel; + + return 0; +@@ -159,15 +253,247 @@ static int stm32_adc_channel_data(struct udevice *dev, int channel, + + *data = readl(adc->regs + STM32H7_ADC_DR); + ++ ret = readl_poll_timeout(adc->regs + STM32H7_ADC_CR, val, ++ !(val & (STM32H7_ADSTART)), STM32_ADC_TIMEOUT_US); ++ if (ret) ++ dev_warn(dev, "conversion stop timed out\n"); ++ ++ if (adc->cfg->has_presel) ++ setbits_le32(adc->regs + STM32H7_ADC_PCSEL, 0); ++ ++ return ret; ++} ++ ++/** ++ * 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_run_selfcalib(struct udevice *dev, int do_lincal) ++{ ++ struct stm32_adc *adc = dev_get_priv(dev); ++ int ret; ++ u32 val, mask; ++ ++ /* ++ * Select calibration mode: ++ * - Offset calibration for single ended inputs ++ * - No linearity calibration. ++ */ ++ 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 (offset single-ended) failed\n"); ++ goto out; ++ } ++ ++ /* ++ * Select calibration mode, then start calibration: ++ * - Offset calibration for differential input ++ * - Linearity calibration if not already done. ++ * will run simultaneously with offset calibration. ++ */ ++ mask = STM32H7_ADCALDIF; ++ if (adc->cfg->has_linearcal && do_lincal) ++ mask |= STM32H7_ADCALLIN; ++ setbits_le32(adc->regs + STM32H7_ADC_CR, mask); ++ ++ /* 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 (offset diff%s) failed\n", ++ (mask & STM32H7_ADCALLIN) ? "+linear" : ""); ++ ++out: ++ clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADCALDIF | STM32H7_ADCALLIN); ++ ++ return ret; ++} ++ ++/* Retrieve calibration data from env variables */ ++static bool stm32_adc_getenv_selfcalib(struct udevice *dev) ++{ ++ struct stm32_adc *adc = dev_get_priv(dev); ++ char env_name[STM32H7_LINCAL_NAME_LEN]; ++ char *env; ++ int i; ++ ++ memset(&adc->lincalfact, 0, STM32H7_LINCALFACT_NUM * sizeof(u32)); ++ for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { ++ /* ++ * Save ADC linear calibration factors in U-boot environment variables ++ * Variables are instantiated according to the adc address through ++ * adcx_ prefix. ++ */ ++ snprintf(env_name, sizeof(env_name), "adc%x_lincalfact%d", (u32)adc->regs, i + 1); ++ env = env_get(env_name); ++ if (!env) ++ return false; ++ adc->lincalfact[i] = env_get_hex(env_name, 0); ++ } ++ return true; ++} ++ ++/* Save calibration data to env variables */ ++static void stm32_adc_save_selfcalib(struct udevice *dev) ++{ ++ struct stm32_adc *adc = dev_get_priv(dev); ++ char env_name[STM32H7_LINCAL_NAME_LEN]; ++ int i; ++ ++ for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { ++ snprintf(env_name, sizeof(env_name), "adc%x_lincalfact%d", (u32)adc->regs, i + 1); ++ if (env_set_hex(env_name, adc->lincalfact[i])) ++ dev_warn(dev, "Failed to save %s\n", env_name); ++ } ++} ++ ++/* Read calibration data from ADC */ ++static int stm32_adc_read_selfcalib(struct udevice *dev) ++{ ++ struct stm32_adc *adc = dev_get_priv(dev); ++ u32 lincalrdyw_mask, val; ++ int i, ret; ++ ++ /* Read linearity calibration */ ++ lincalrdyw_mask = STM32H7_LINCALRDYW6; ++ for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { ++ /* Clear STM32H7_LINCALRDYW[6..1]: transfer calib to CALFACT2 */ ++ clrbits_le32(adc->regs + STM32H7_ADC_CR, lincalrdyw_mask); ++ ++ /* Poll: wait calib data to be ready in CALFACT2 register */ ++ ret = readl_poll_sleep_timeout(adc->regs + STM32H7_ADC_CR, val, ++ !(val & lincalrdyw_mask), 100, ++ STM32_ADC_TIMEOUT_US); ++ if (ret) { ++ dev_err(dev, "Failed to read calfact\n"); ++ return ret; ++ } ++ ++ val = readl(adc->regs + STM32H7_ADC_CALFACT2); ++ adc->lincalfact[i] = (val & STM32H7_LINCALFACT_MASK); ++ adc->lincalfact[i] >>= STM32H7_LINCALFACT_SHIFT; ++ ++ lincalrdyw_mask >>= 1; ++ } ++ + return 0; + } + +-static int stm32_adc_chan_of_init(struct udevice *dev) ++/* Write calibration data to ADC */ ++static int stm32_adc_write_selfcalib(struct udevice *dev) + { +- struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); + struct stm32_adc *adc = dev_get_priv(dev); +- u32 chans[STM32_ADC_CH_MAX]; +- unsigned int i, num_channels; ++ u32 lincalrdyw_mask, val; ++ int i, ret; ++ ++ lincalrdyw_mask = STM32H7_LINCALRDYW6; ++ for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { ++ /* ++ * Write saved calibration data to shadow registers: ++ * Write CALFACT2, and set LINCALRDYW[6..1] bit to trigger ++ * data write. Then poll to wait for complete transfer. ++ */ ++ val = adc->lincalfact[i] << STM32H7_LINCALFACT_SHIFT; ++ writel(val, adc->regs + STM32H7_ADC_CALFACT2); ++ setbits_le32(adc->regs + STM32H7_ADC_CR, lincalrdyw_mask); ++ ret = readl_poll_sleep_timeout(adc->regs + STM32H7_ADC_CR, val, ++ val & lincalrdyw_mask, ++ 100, STM32_ADC_TIMEOUT_US); ++ if (ret) { ++ dev_err(dev, "Failed to write calfact\n"); ++ return ret; ++ } ++ ++ lincalrdyw_mask >>= 1; ++ } ++ ++ return 0; ++} ++ ++static int stm32_adc_selfcalib(struct udevice *dev) ++{ ++ struct stm32_adc *adc = dev_get_priv(dev); ++ int ret; ++ bool lincal_done = false; ++ ++ /* Try to restore linear calibration */ ++ if (adc->cfg->has_linearcal) ++ lincal_done = stm32_adc_getenv_selfcalib(dev); ++ ++ /* ++ * Run offset calibration unconditionally. ++ * Run linear calibration if not already available. ++ */ ++ ret = stm32_adc_run_selfcalib(dev, !lincal_done); ++ if (ret) ++ return ret; ++ ++ ret = stm32_adc_enable(dev); ++ if (ret) ++ return ret; ++ ++ if (adc->cfg->has_linearcal) { ++ if (!lincal_done) { ++ ret = stm32_adc_read_selfcalib(dev); ++ if (ret) ++ goto disable; ++ ++ stm32_adc_save_selfcalib(dev); ++ } ++ ++ /* ++ * Always write linear calibration data to ADC. ++ * This allows to ensure that LINCALRDYWx bits are set when entering kernel ++ * ++ * - First boot: ++ * U-boot performs ADC linear calibration (& offset calibration) ++ * U-boot reads & saves linear calibration result in environment variable ++ * (Here LINCALRDYWx have been cleared due to the read procedure) ++ * U-boot writes back ADC linear calibration to set LINCALRDYWx bits, ++ * making the linear calibration available for the kernel. ++ * ++ * - Subsequent boot (environment set earlier): ++ * U-boot performs ADC offset calibration only ++ * U-boot reads ADC linear calibration from environment variable ++ * and writes back ADC linear calibration. ++ * ++ * - All boot: kernel steps ++ * * Case1: ADC calibrated by U-boot (LINCALRDYWx bits set) ++ * Read back the linear calibration from ADC registers and save it. ++ * * Case2: ADC not calibrated by U-boot ++ * Run a linear calibration and save it. ++ */ ++ ret = stm32_adc_write_selfcalib(dev); ++ if (ret) ++ goto disable; ++ } ++ ++ return ret; ++ ++disable: ++ stm32_adc_stop(dev); ++ return ret; ++} ++ ++static int stm32_adc_get_legacy_chan_count(struct udevice *dev) ++{ + int ret; + + /* Retrieve single ended channels listed in device tree */ +@@ -176,12 +502,16 @@ static int stm32_adc_chan_of_init(struct udevice *dev) + dev_err(dev, "can't get st,adc-channels: %d\n", ret); + return ret; + } +- num_channels = ret / sizeof(u32); + +- if (num_channels > adc->cfg->max_channels) { +- dev_err(dev, "too many st,adc-channels: %d\n", num_channels); +- return -EINVAL; +- } ++ return (ret / sizeof(u32)); ++} ++ ++static int stm32_adc_legacy_chan_init(struct udevice *dev, unsigned int num_channels) ++{ ++ struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); ++ struct stm32_adc *adc = dev_get_priv(dev); ++ u32 chans[STM32_ADC_CH_MAX]; ++ int i, ret; + + ret = dev_read_u32_array(dev, "st,adc-channels", chans, num_channels); + if (ret < 0) { +@@ -197,6 +527,69 @@ static int stm32_adc_chan_of_init(struct udevice *dev) + uc_pdata->channel_mask |= 1 << chans[i]; + } + ++ return ret; ++} ++ ++static int stm32_adc_generic_chan_init(struct udevice *dev, unsigned int num_channels) ++{ ++ struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); ++ struct stm32_adc *adc = dev_get_priv(dev); ++ ofnode child; ++ int val, ret; ++ ++ ofnode_for_each_subnode(child, dev_ofnode(dev)) { ++ ret = ofnode_read_u32(child, "reg", &val); ++ if (ret) { ++ dev_err(dev, "Missing channel index %d\n", ret); ++ return ret; ++ } ++ ++ if (val >= adc->cfg->max_channels) { ++ dev_err(dev, "Invalid channel %d\n", val); ++ return -EINVAL; ++ } ++ ++ uc_pdata->channel_mask |= 1 << val; ++ } ++ ++ return 0; ++} ++ ++static int stm32_adc_chan_of_init(struct udevice *dev) ++{ ++ struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); ++ struct stm32_adc *adc = dev_get_priv(dev); ++ unsigned int num_channels; ++ int ret; ++ bool legacy = false; ++ ++ num_channels = dev_get_child_count(dev); ++ /* If no channels have been found, fallback to channels legacy properties. */ ++ if (!num_channels) { ++ legacy = true; ++ ++ ret = stm32_adc_get_legacy_chan_count(dev); ++ if (!ret) { ++ dev_err(dev, "No channel found\n"); ++ return -ENODATA; ++ } else if (ret < 0) { ++ return ret; ++ } ++ num_channels = ret; ++ } ++ ++ if (num_channels > adc->cfg->max_channels) { ++ dev_err(dev, "too many st,adc-channels: %d\n", num_channels); ++ return -EINVAL; ++ } ++ ++ if (legacy) ++ ret = stm32_adc_legacy_chan_init(dev, num_channels); ++ else ++ ret = stm32_adc_generic_chan_init(dev, num_channels); ++ if (ret < 0) ++ return ret; ++ + uc_pdata->data_mask = (1 << adc->cfg->num_bits) - 1; + uc_pdata->data_format = ADC_DATA_FORMAT_BIN; + uc_pdata->data_timeout_us = 100000; +@@ -209,7 +602,7 @@ static int stm32_adc_probe(struct udevice *dev) + struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(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 +617,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 = { +@@ -234,14 +639,28 @@ static const struct adc_ops stm32_adc_ops = { + }; + + static const struct stm32_adc_cfg stm32h7_adc_cfg = { ++ .regs = &stm32h7_adc_regspec, + .num_bits = 16, + .max_channels = STM32_ADC_CH_MAX, ++ .has_boostmode = true, ++ .has_linearcal = true, ++ .has_presel = true, + }; + + static const struct stm32_adc_cfg stm32mp1_adc_cfg = { ++ .regs = &stm32h7_adc_regspec, + .num_bits = 16, + .max_channels = STM32_ADC_CH_MAX, + .has_vregready = true, ++ .has_boostmode = true, ++ .has_linearcal = true, ++ .has_presel = true, ++}; ++ ++static const struct stm32_adc_cfg stm32mp13_adc_cfg = { ++ .regs = &stm32mp13_adc_regspec, ++ .num_bits = 12, ++ .max_channels = STM32_ADC_CH_MAX - 1, + }; + + static const struct udevice_id stm32_adc_ids[] = { +@@ -249,6 +668,8 @@ static const struct udevice_id stm32_adc_ids[] = { + .data = (ulong)&stm32h7_adc_cfg }, + { .compatible = "st,stm32mp1-adc", + .data = (ulong)&stm32mp1_adc_cfg }, ++ { .compatible = "st,stm32mp13-adc", ++ .data = (ulong)&stm32mp13_adc_cfg }, + {} + }; + +diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig +index baac8d281e..3769e75760 100644 +--- a/drivers/clk/Kconfig ++++ b/drivers/clk/Kconfig +@@ -147,14 +147,29 @@ config CLK_ZYNQMP + This clock driver adds support for clock realted settings for + ZynqMP platform. + ++config CLK_STM32_CORE ++ bool "Enable RCC clock core driver for STM32MP" ++ depends on ARCH_STM32MP && CLK ++ + config CLK_STM32MP1 + bool "Enable RCC clock driver for STM32MP1" + depends on ARCH_STM32MP && CLK +- default y ++ default y if STM32MP15x + help + Enable the STM32 clock (RCC) driver. Enable support for + manipulating STM32MP1's on-SoC clocks. + ++config CLK_STM32MP13 ++ bool "Enable RCC clock driver for STM32MP13" ++ depends on ARCH_STM32MP && CLK ++ default y if STM32MP13x ++ select CLK_CCF ++ select CLK_COMPOSITE_CCF ++ select CLK_STM32_CORE ++ help ++ Enable the STM32 clock (RCC) driver. Enable support for ++ manipulating STM32MP13's on-SoC clocks. ++ + config CLK_CDCE9XX + bool "Enable CDCD9XX clock driver" + depends on CLK +diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile +index 711ae5bc29..4954ebf220 100644 +--- a/drivers/clk/Makefile ++++ b/drivers/clk/Makefile +@@ -37,8 +37,10 @@ obj-$(CONFIG_CLK_RENESAS) += renesas/ + obj-$(CONFIG_CLK_SCMI) += clk_scmi.o + obj-$(CONFIG_CLK_SIFIVE) += sifive/ + obj-$(CONFIG_ARCH_SUNXI) += sunxi/ ++obj-$(CONFIG_CLK_STM32_CORE) += clk-stm32-core.o + obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o + obj-$(CONFIG_CLK_STM32MP1) += clk_stm32mp1.o ++obj-$(CONFIG_CLK_STM32MP13) += clk-stm32mp13.o + obj-$(CONFIG_CLK_UNIPHIER) += uniphier/ + obj-$(CONFIG_CLK_VEXPRESS_OSC) += clk_vexpress_osc.o + obj-$(CONFIG_CLK_ZYNQ) += clk_zynq.o +diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c +index bb5351ebc0..6eb2b8133a 100644 +--- a/drivers/clk/clk-composite.c ++++ b/drivers/clk/clk-composite.c +@@ -4,14 +4,17 @@ + * Copyright 2019 NXP + */ + ++#define LOG_CATEGORY UCLASS_CLK ++ + #include +-#include +-#include ++#include + #include ++#include ++#include ++#include + #include + #include + #include +-#include + #include + + #include "clk.h" +diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c +index 9df50a5e72..7e8e62feee 100644 +--- a/drivers/clk/clk-divider.c ++++ b/drivers/clk/clk-divider.c +@@ -9,14 +9,18 @@ + * + */ + ++#define LOG_CATEGORY UCLASS_CLK ++ + #include + #include + #include + #include ++#include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -190,7 +194,7 @@ static struct clk *_register_divider(struct device *dev, const char *name, + + if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { + if (width + shift > 16) { +- pr_warn("divider value exceeds LOWORD field\n"); ++ dev_warn(dev, "divider value exceeds LOWORD field\n"); + return ERR_PTR(-EINVAL); + } + } +diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c +index 8d9823bdab..2a446788e1 100644 +--- a/drivers/clk/clk-fixed-factor.c ++++ b/drivers/clk/clk-fixed-factor.c +@@ -5,17 +5,22 @@ + * + * Copyright (C) 2011 Sascha Hauer, Pengutronix + */ ++ ++#define LOG_CATEGORY UCLASS_CLK ++ + #include +-#include ++#include + #include ++#include ++#include ++#include + #include + #include + #include +-#include +-#include +-#include "clk.h" + #include + ++#include "clk.h" ++ + #define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor" + + static ulong clk_factor_recalc_rate(struct clk *clk) +diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c +index 006d3b6629..aa40daf3d7 100644 +--- a/drivers/clk/clk-gate.c ++++ b/drivers/clk/clk-gate.c +@@ -7,18 +7,23 @@ + * Gated clock implementation + */ + ++#define LOG_CATEGORY UCLASS_CLK ++ + #include +-#include +-#include ++#include ++#include + #include ++#include ++#include + #include ++#include + #include + #include + #include +-#include +-#include "clk.h" + #include + ++#include "clk.h" ++ + #define UBOOT_DM_CLK_GATE "clk_gate" + + /** +@@ -123,7 +128,7 @@ struct clk *clk_register_gate(struct device *dev, const char *name, + + if (clk_gate_flags & CLK_GATE_HIWORD_MASK) { + if (bit_idx > 15) { +- pr_err("gate bit exceeds LOWORD field\n"); ++ dev_err(dev, "gate bit exceeds LOWORD field\n"); + return ERR_PTR(-EINVAL); + } + } +diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c +index f1becd20d8..b49946fbcd 100644 +--- a/drivers/clk/clk-mux.c ++++ b/drivers/clk/clk-mux.c +@@ -21,17 +21,22 @@ + * clock. + */ + ++#define LOG_CATEGORY UCLASS_CLK ++ + #include + #include + #include ++#include ++#include ++#include + #include ++#include + #include + #include + #include +-#include +-#include + #include + #include ++ + #include "clk.h" + + #define UBOOT_DM_CLK_CCF_MUX "ccf_clk_mux" +@@ -123,7 +128,7 @@ static int clk_mux_set_parent(struct clk *clk, struct clk *parent) + + index = clk_fetch_parent_index(clk, parent); + if (index < 0) { +- printf("Could not fetch index\n"); ++ log_err("Could not fetch index\n"); + return index; + } + +@@ -169,7 +174,7 @@ struct clk *clk_hw_register_mux_table(struct device *dev, const char *name, + if (clk_mux_flags & CLK_MUX_HIWORD_MASK) { + width = fls(mask) - ffs(mask) + 1; + if (width + shift > 16) { +- pr_err("mux value exceeds LOWORD field\n"); ++ dev_err(dev, "mux value exceeds LOWORD field\n"); + return ERR_PTR(-EINVAL); + } + } +diff --git a/drivers/clk/clk-stm32-core.c b/drivers/clk/clk-stm32-core.c +new file mode 100644 +index 0000000000..9df1025002 +--- /dev/null ++++ b/drivers/clk/clk-stm32-core.c +@@ -0,0 +1,372 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved ++ * Author: Gabriel Fernandez for STMicroelectronics. ++ */ ++ ++#define LOG_CATEGORY UCLASS_CLK ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "clk-stm32-core.h" ++ ++int stm32_rcc_init(struct device *dev, ++ const struct stm32_clock_match_data *data, ++ void __iomem *base) ++{ ++ int i; ++ ++ for (i = 0; i < data->num_clocks; i++) { ++ const struct clock_config *cfg = &data->tab_clocks[i]; ++ struct clk *clk = ERR_PTR(-ENOENT); ++ ++ if (data->check_security) { ++ if ((*data->check_security)(base, cfg)) ++ continue; ++ } ++ ++ if (cfg->func) ++ clk = (*cfg->func)(NULL, data, base, NULL, cfg); ++ ++ if (IS_ERR(clk)) { ++ log_err("%s: failed to register clock %s\n", __func__, ++ cfg->name); ++ ++ return PTR_ERR(clk); ++ } ++ ++ clk->id = cfg->id; ++ } ++ ++ return 0; ++} ++ ++static const struct clk_ops *clk_dev_ops(struct udevice *dev) ++{ ++ return (const struct clk_ops *)dev->driver->ops; ++} ++ ++static int stm32_clk_enable(struct clk *clk) ++{ ++ const struct clk_ops *ops; ++ struct clk *clkp = NULL; ++ ++ if (!clk->id || clk_get_by_id(clk->id, &clkp)) ++ return -ENOENT; ++ ++ ops = clk_dev_ops(clkp->dev); ++ if (!ops->enable) ++ return 0; ++ ++ return ops->enable(clkp); ++} ++ ++static int stm32_clk_disable(struct clk *clk) ++{ ++ const struct clk_ops *ops; ++ struct clk *clkp = NULL; ++ ++ if (!clk->id || clk_get_by_id(clk->id, &clkp)) ++ return -ENOENT; ++ ++ ops = clk_dev_ops(clkp->dev); ++ if (!ops->disable) ++ return 0; ++ ++ return ops->disable(clkp); ++} ++ ++static ulong stm32_clk_get_rate(struct clk *clk) ++{ ++ const struct clk_ops *ops; ++ struct clk *clkp = NULL; ++ ++ if (!clk->id || clk_get_by_id(clk->id, &clkp)) ++ return -ENOENT; ++ ++ ops = clk_dev_ops(clkp->dev); ++ if (!ops->get_rate) ++ return -ENOSYS; ++ ++ return ops->get_rate(clkp); ++} ++ ++ulong stm32_clk_set_rate(struct clk *clk, unsigned long clk_rate) ++{ ++ const struct clk_ops *ops; ++ struct clk *clkp = NULL; ++ ++ if (!clk->id || clk_get_by_id(clk->id, &clkp)) ++ return -ENOENT; ++ ++ ops = clk_dev_ops(clkp->dev); ++ if (!ops->set_rate) ++ return -ENOSYS; ++ ++ return ops->set_rate(clkp, clk_rate); ++} ++ ++int clk_stm32_get_by_name(const char *name, struct clk **clkp) ++{ ++ struct udevice *dev; ++ struct uclass *uc; ++ int ret; ++ ++ ret = uclass_get(UCLASS_CLK, &uc); ++ if (ret) ++ return ret; ++ ++ uclass_foreach_dev(dev, uc) { ++ if (!strcmp(name, dev->name)) { ++ struct clk *clk = dev_get_clk_ptr(dev); ++ ++ if (clk) { ++ *clkp = clk; ++ return 0; ++ } ++ break; ++ } ++ } ++ ++ return -ENOENT; ++} ++ ++ulong clk_stm32_get_rate_by_name(const char *name) ++{ ++ struct clk *clk; ++ ++ if (!clk_stm32_get_by_name(name, &clk)) ++ return clk_get_rate(clk); ++ ++ return 0; ++} ++ ++const struct clk_ops stm32_clk_ops = { ++ .enable = stm32_clk_enable, ++ .disable = stm32_clk_disable, ++ .get_rate = stm32_clk_get_rate, ++ .set_rate = stm32_clk_set_rate, ++}; ++ ++#define UBOOT_DM_CLK_STM32_SETCLR_GATE "clk_stm32_setclr_gate" ++ ++#define RCC_MP_ENCLRR_OFFSET 4 ++ ++static void clk_setclr_gate_endisable(struct clk *clk, int enable) ++{ ++ struct clk_gate *gate = to_clk_gate(clk); ++ ++ if (enable) ++ writel(BIT(gate->bit_idx), gate->reg); ++ else ++ writel(BIT(gate->bit_idx), gate->reg + RCC_MP_ENCLRR_OFFSET); ++} ++ ++static int clk_setclr_gate_enable(struct clk *clk) ++{ ++ clk_setclr_gate_endisable(clk, 1); ++ ++ return 0; ++} ++ ++static int clk_setclr_gate_disable(struct clk *clk) ++{ ++ clk_setclr_gate_endisable(clk, 0); ++ ++ return 0; ++} ++ ++const struct clk_ops clk_stm32_setclr_gate_ops = { ++ .enable = clk_setclr_gate_enable, ++ .disable = clk_setclr_gate_disable, ++ .get_rate = clk_generic_get_rate, ++}; ++ ++struct clk *clk_stm32_register_setclr_gate(struct device *dev, ++ const char *name, ++ const char *parent_name, ++ unsigned long flags, ++ void __iomem *reg, u8 bit_idx, ++ u8 clk_gate_flags, spinlock_t *lock) ++{ ++ struct clk_gate *gate; ++ struct clk *clk; ++ int ret; ++ ++ /* allocate the gate */ ++ gate = kzalloc(sizeof(*gate), GFP_KERNEL); ++ if (!gate) ++ return ERR_PTR(-ENOMEM); ++ ++ /* struct clk_gate assignments */ ++ gate->reg = reg; ++ gate->bit_idx = bit_idx; ++ gate->flags = clk_gate_flags; ++ ++ clk = &gate->clk; ++ clk->flags = flags; ++ ++ ret = clk_register(clk, UBOOT_DM_CLK_STM32_SETCLR_GATE, name, ++ parent_name); ++ if (ret) { ++ kfree(gate); ++ return ERR_PTR(ret); ++ } ++ ++ return clk; ++} ++ ++U_BOOT_DRIVER(clk_stm32_setclr_gate) = { ++ .name = UBOOT_DM_CLK_STM32_SETCLR_GATE, ++ .id = UCLASS_CLK, ++ .ops = &clk_stm32_setclr_gate_ops, ++}; ++ ++struct clk *clk_stm32_register_composite(const char *name, ++ const char * const *parent_names, ++ int num_parents, ++ unsigned long flags, ++ void __iomem *base, ++ const struct stm32_mux_cfg *pcfg, ++ const struct stm32_div_cfg *dcfg, ++ const struct stm32_gate_cfg *gcfg) ++{ ++ struct clk *clk = ERR_PTR(-ENOMEM); ++ struct clk_mux *mux = NULL; ++ struct clk_gate *gate = NULL; ++ struct clk_divider *div = NULL; ++ struct clk *mux_clk = NULL; ++ const struct clk_ops *mux_ops = NULL; ++ struct clk *gate_clk = NULL; ++ const struct clk_ops *gate_ops = NULL; ++ struct clk *div_clk = NULL; ++ const struct clk_ops *div_ops = NULL; ++ ++ if (pcfg) { ++ mux = kzalloc(sizeof(*mux), GFP_KERNEL); ++ if (!mux) ++ goto fail; ++ ++ mux->reg = base + pcfg->reg_off; ++ mux->shift = pcfg->shift; ++ mux->mask = BIT(pcfg->width) - 1; ++ mux->num_parents = pcfg->num_parents; ++ mux->flags = 0; ++ mux->parent_names = pcfg->parent_names; ++ ++ mux_clk = &mux->clk; ++ mux_ops = &clk_mux_ops; ++ } ++ ++ if (dcfg) { ++ div = kzalloc(sizeof(*div), GFP_KERNEL); ++ if (!div) ++ goto fail; ++ ++ div->reg = base + dcfg->reg_off; ++ div->shift = dcfg->shift; ++ div->width = dcfg->width; ++ div->width = dcfg->width; ++ div->flags = dcfg->div_flags; ++ div->table = dcfg->table; ++ } ++ ++ if (gcfg) { ++ gate = kzalloc(sizeof(*gate), GFP_KERNEL); ++ if (!gate) ++ goto fail; ++ ++ gate->reg = base + gcfg->reg_off; ++ gate->bit_idx = gcfg->bit_idx; ++ gate->flags = gcfg->gate_flags; ++ ++ gate_clk = &gate->clk; ++ gate_ops = &clk_gate_ops; ++ ++ if (gcfg->set_clr) ++ gate_ops = &clk_stm32_setclr_gate_ops; ++ } ++ ++ clk = clk_register_composite(NULL, name, ++ parent_names, num_parents, ++ mux_clk, mux_ops, ++ div_clk, div_ops, ++ gate_clk, gate_ops, ++ flags); ++ if (IS_ERR(clk)) ++ goto fail; ++ ++ return clk; ++ ++fail: ++ kfree(gate); ++ kfree(div); ++ kfree(mux); ++ return ERR_CAST(clk); ++} ++ ++struct clk *_clk_stm32_gate_register(struct device *dev, ++ const struct stm32_clock_match_data *data, ++ void __iomem *base, ++ spinlock_t *lock, ++ const struct clock_config *cfg) ++{ ++ struct stm32_clk_gate_cfg *clk_cfg = cfg->clock_cfg; ++ const struct stm32_gate_cfg *gate_cfg = &data->gates[clk_cfg->gate_id]; ++ struct clk *clk; ++ ++ if (gate_cfg->set_clr) { ++ clk = clk_stm32_register_setclr_gate(dev, cfg->name, ++ cfg->parent_name, ++ cfg->flags, ++ base + gate_cfg->reg_off, ++ gate_cfg->bit_idx, ++ gate_cfg->gate_flags, ++ lock); ++ } else { ++ clk = clk_register_gate(dev, cfg->name, cfg->parent_name, ++ cfg->flags, ++ base + gate_cfg->reg_off, ++ gate_cfg->bit_idx, ++ gate_cfg->gate_flags, ++ lock); ++ } ++ return clk; ++} ++ ++struct clk * ++_clk_stm32_register_composite(struct device *dev, ++ const struct stm32_clock_match_data *data, ++ void __iomem *base, spinlock_t *lock, ++ const struct clock_config *cfg) ++{ ++ struct stm32_clk_composite_cfg *composite = cfg->clock_cfg; ++ const struct stm32_mux_cfg *mux_cfg = NULL; ++ const struct stm32_gate_cfg *gate_cfg = NULL; ++ const struct stm32_div_cfg *div_cfg = NULL; ++ const char *const *parent_names; ++ int num_parents; ++ ++ if (composite->mux_id != NO_STM32_MUX) { ++ mux_cfg = &data->muxes[composite->mux_id]; ++ parent_names = mux_cfg->parent_names; ++ num_parents = mux_cfg->num_parents; ++ } else { ++ parent_names = &cfg->parent_name; ++ num_parents = 1; ++ } ++ ++ if (composite->gate_id != NO_STM32_GATE) ++ gate_cfg = &data->gates[composite->gate_id]; ++ ++ if (composite->div_id != NO_STM32_DIV) ++ div_cfg = &data->dividers[composite->div_id]; ++ ++ return clk_stm32_register_composite(cfg->name, parent_names, ++ num_parents, cfg->flags, base, ++ mux_cfg, div_cfg, gate_cfg); ++} +diff --git a/drivers/clk/clk-stm32-core.h b/drivers/clk/clk-stm32-core.h +new file mode 100644 +index 0000000000..9233b02c04 +--- /dev/null ++++ b/drivers/clk/clk-stm32-core.h +@@ -0,0 +1,153 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (C) STMicroelectronics 2020 - All Rights Reserved ++ * Author: Gabriel Fernandez for STMicroelectronics. ++ */ ++ ++struct stm32_clock_match_data; ++ ++struct stm32_mux_cfg { ++ const char * const *parent_names; ++ u8 num_parents; ++ u32 reg_off; ++ u8 shift; ++ u8 width; ++ u8 mux_flags; ++ u32 *table; ++}; ++ ++struct stm32_gate_cfg { ++ u32 reg_off; ++ u8 bit_idx; ++ u8 gate_flags; ++ u8 set_clr; ++}; ++ ++struct stm32_div_cfg { ++ u32 reg_off; ++ u8 shift; ++ u8 width; ++ u8 div_flags; ++ const struct clk_div_table *table; ++}; ++ ++struct stm32_composite_cfg { ++ int mux; ++ int gate; ++ int div; ++}; ++ ++struct clock_config { ++ unsigned long id; ++ const char *name; ++ const char *parent_name; ++ unsigned long flags; ++ int sec_id; ++ void *clock_cfg; ++ ++ struct clk *(*func)(struct device *dev, ++ const struct stm32_clock_match_data *data, ++ void __iomem *base, ++ spinlock_t *lock, ++ const struct clock_config *cfg); ++}; ++ ++struct stm32_clock_match_data { ++ unsigned int num_clocks; ++ const struct clock_config *tab_clocks; ++ unsigned int maxbinding; ++ const struct stm32_gate_cfg *gates; ++ const struct stm32_mux_cfg *muxes; ++ const struct stm32_div_cfg *dividers; ++ ++ int (*check_security)(void __iomem *base, ++ const struct clock_config *cfg); ++}; ++ ++int stm32_rcc_init(struct device *dev, ++ const struct stm32_clock_match_data *data, ++ void __iomem *base); ++ ++#define NO_ID 0xFFFF0000 ++ ++#define NO_STM32_MUX -1 ++#define NO_STM32_DIV -1 ++#define NO_STM32_GATE -1 ++ ++struct clk * ++_clk_stm32_gate_register(struct device *dev, ++ const struct stm32_clock_match_data *data, ++ void __iomem *base, spinlock_t *lock, ++ const struct clock_config *cfg); ++ ++struct clk * ++_clk_stm32_register_composite(struct device *dev, ++ const struct stm32_clock_match_data *data, ++ void __iomem *base, spinlock_t *lock, ++ const struct clock_config *cfg); ++ ++struct stm32_clk_gate_cfg { ++ int gate_id; ++}; ++ ++#define STM32_GATE(_id, _name, _parent, _flags, _gate_id, _sec_id)\ ++{\ ++ .id = _id,\ ++ .sec_id = _sec_id,\ ++ .name = _name,\ ++ .parent_name = _parent,\ ++ .flags = _flags,\ ++ .clock_cfg = &(struct stm32_clk_gate_cfg) {\ ++ .gate_id = _gate_id,\ ++ },\ ++ .func = _clk_stm32_gate_register,\ ++} ++ ++struct stm32_clk_composite_cfg { ++ int gate_id; ++ int mux_id; ++ int div_id; ++}; ++ ++#define STM32_COMPOSITE(_id, _name, _flags, _sec_id,\ ++ _gate_id, _mux_id, _div_id)\ ++{\ ++ .id = _id,\ ++ .name = _name,\ ++ .sec_id = _sec_id,\ ++ .flags = _flags,\ ++ .clock_cfg = &(struct stm32_clk_composite_cfg) {\ ++ .gate_id = _gate_id,\ ++ .mux_id = _mux_id,\ ++ .div_id = _div_id,\ ++ },\ ++ .func = _clk_stm32_register_composite,\ ++} ++ ++#define STM32_COMPOSITE_NOMUX(_id, _name, _parent, _flags, _sec_id,\ ++ _gate_id, _div_id)\ ++{\ ++ .id = _id,\ ++ .name = _name,\ ++ .parent_name = _parent,\ ++ .sec_id = _sec_id,\ ++ .flags = _flags,\ ++ .clock_cfg = &(struct stm32_clk_composite_cfg) {\ ++ .gate_id = _gate_id,\ ++ .mux_id = NO_STM32_MUX,\ ++ .div_id = _div_id,\ ++ },\ ++ .func = _clk_stm32_register_composite,\ ++} ++ ++extern const struct clk_ops stm32_clk_ops; ++extern const struct clk_ops clk_stm32_setclr_gate_ops; ++ulong clk_stm32_get_rate_by_name(const char *name); ++int clk_stm32_get_by_name(const char *name, struct clk **clkp); ++struct clk *clk_stm32_register_setclr_gate(struct device *dev, ++ const char *name, ++ const char *parent_name, ++ unsigned long flags, ++ void __iomem *reg, u8 bit_idx, ++ u8 clk_gate_flags, spinlock_t *lock); ++ +diff --git a/drivers/clk/clk-stm32mp13.c b/drivers/clk/clk-stm32mp13.c +new file mode 100644 +index 0000000000..bd82200e55 +--- /dev/null ++++ b/drivers/clk/clk-stm32mp13.c +@@ -0,0 +1,844 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved ++ * Author: Gabriel Fernandez for STMicroelectronics. ++ */ ++ ++#define LOG_CATEGORY UCLASS_CLK ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "clk-stm32-core.h" ++#include "stm32mp13_rcc.h" ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++struct stm32mp1_clk_priv { ++ fdt_addr_t base; ++}; ++ ++static const char * const adc12_src[] = { ++ "pll4_r", "ck_per", "pll3_q" ++}; ++ ++static const char * const dcmipp_src[] = { ++ "ck_axi", "pll2_q", "pll4_p", "ck_per", ++}; ++ ++static const char * const eth12_src[] = { ++ "pll4_p", "pll3_q" ++}; ++ ++static const char * const fdcan_src[] = { ++ "ck_hse", "pll3_q", "pll4_q", "pll4_r" ++}; ++ ++static const char * const fmc_src[] = { ++ "ck_axi", "pll3_r", "pll4_p", "ck_per" ++}; ++ ++static const char * const i2c12_src[] = { ++ "pclk1", "pll4_r", "ck_hsi", "ck_csi" ++}; ++ ++static const char * const i2c345_src[] = { ++ "pclk6", "pll4_r", "ck_hsi", "ck_csi" ++}; ++ ++static const char * const lptim1_src[] = { ++ "pclk1", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per" ++}; ++ ++static const char * const lptim23_src[] = { ++ "pclk3", "pll4_q", "ck_per", "ck_lse", "ck_lsi" ++}; ++ ++static const char * const lptim45_src[] = { ++ "pclk3", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per" ++}; ++ ++static const char * const mco1_src[] = { ++ "ck_hsi", "ck_hse", "ck_csi", "ck_lsi", "ck_lse" ++}; ++ ++static const char * const mco2_src[] = { ++ "ck_mpu", "ck_axi", "ck_mlahb", "pll4_p", "ck_hse", "ck_hsi" ++}; ++ ++static const char * const qspi_src[] = { ++ "ck_axi", "pll3_r", "pll4_p", "ck_per" ++}; ++ ++static const char * const rng1_src[] = { ++ "ck_csi", "pll4_r", "reserved", "ck_lsi" ++}; ++ ++static const char * const saes_src[] = { ++ "ck_axi", "ck_per", "pll4_r", "ck_lsi" ++}; ++ ++static const char * const sai1_src[] = { ++ "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "pll3_r" ++}; ++ ++static const char * const sai2_src[] = { ++ "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb", "pll3_r" ++}; ++ ++static const char * const sdmmc12_src[] = { ++ "ck_axi", "pll3_r", "pll4_p", "ck_hsi" ++}; ++ ++static const char * const spdif_src[] = { ++ "pll4_p", "pll3_q", "ck_hsi" ++}; ++ ++static const char * const spi123_src[] = { ++ "pll4_p", "pll3_q", "i2s_ckin", "ck_per", "pll3_r" ++}; ++ ++static const char * const spi4_src[] = { ++ "pclk6", "pll4_q", "ck_hsi", "ck_csi", "ck_hse", "i2s_ckin" ++}; ++ ++static const char * const spi5_src[] = { ++ "pclk6", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" ++}; ++ ++static const char * const stgen_src[] = { ++ "ck_hsi", "ck_hse" ++}; ++ ++static const char * const usart12_src[] = { ++ "pclk6", "pll3_q", "ck_hsi", "ck_csi", "pll4_q", "ck_hse" ++}; ++ ++static const char * const usart34578_src[] = { ++ "pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" ++}; ++ ++static const char * const usart6_src[] = { ++ "pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" ++}; ++ ++static const char * const usbo_src[] = { ++ "pll4_r", "ck_usbo_48m" ++}; ++ ++static const char * const usbphy_src[] = { ++ "ck_hse", "pll4_r", "clk-hse-div2" ++}; ++ ++enum enum_mux_cfg { ++ MUX_I2C12, ++ MUX_LPTIM45, ++ MUX_SPI23, ++ MUX_UART35, ++ MUX_UART78, ++ MUX_ADC1, ++ MUX_ADC2, ++ MUX_DCMIPP, ++ MUX_ETH1, ++ MUX_ETH2, ++ MUX_FDCAN, ++ MUX_FMC, ++ MUX_I2C3, ++ MUX_I2C4, ++ MUX_I2C5, ++ MUX_LPTIM1, ++ MUX_LPTIM2, ++ MUX_LPTIM3, ++ MUX_QSPI, ++ MUX_RNG1, ++ MUX_SAES, ++ MUX_SAI1, ++ MUX_SAI2, ++ MUX_SDMMC1, ++ MUX_SDMMC2, ++ MUX_SPDIF, ++ MUX_SPI1, ++ MUX_SPI4, ++ MUX_SPI5, ++ MUX_STGEN, ++ MUX_UART1, ++ MUX_UART2, ++ MUX_UART4, ++ MUX_UART6, ++ MUX_USBO, ++ MUX_USBPHY, ++ MUX_MCO1, ++ MUX_MCO2 ++}; ++ ++#define MUX_CFG(id, src, _offset, _shift, _witdh)[id] = {\ ++ .num_parents = ARRAY_SIZE(src),\ ++ .parent_names = src,\ ++ .reg_off = (_offset),\ ++ .shift = (_shift),\ ++ .width = (_witdh),\ ++} ++ ++static const struct stm32_mux_cfg stm32mp13_muxes[] = { ++ MUX_CFG(MUX_I2C12, i2c12_src, RCC_I2C12CKSELR, 0, 3), ++ MUX_CFG(MUX_LPTIM45, lptim45_src, RCC_LPTIM45CKSELR, 0, 3), ++ MUX_CFG(MUX_SPI23, spi123_src, RCC_SPI2S23CKSELR, 0, 3), ++ MUX_CFG(MUX_UART35, usart34578_src, RCC_UART35CKSELR, 0, 3), ++ MUX_CFG(MUX_UART78, usart34578_src, RCC_UART78CKSELR, 0, 3), ++ MUX_CFG(MUX_ADC1, adc12_src, RCC_ADC12CKSELR, 0, 2), ++ MUX_CFG(MUX_ADC2, adc12_src, RCC_ADC12CKSELR, 2, 2), ++ MUX_CFG(MUX_DCMIPP, dcmipp_src, RCC_DCMIPPCKSELR, 0, 2), ++ MUX_CFG(MUX_ETH1, eth12_src, RCC_ETH12CKSELR, 0, 2), ++ MUX_CFG(MUX_ETH2, eth12_src, RCC_ETH12CKSELR, 8, 2), ++ MUX_CFG(MUX_FDCAN, fdcan_src, RCC_FDCANCKSELR, 0, 2), ++ MUX_CFG(MUX_FMC, fmc_src, RCC_FMCCKSELR, 0, 2), ++ MUX_CFG(MUX_I2C3, i2c345_src, RCC_I2C345CKSELR, 0, 3), ++ MUX_CFG(MUX_I2C4, i2c345_src, RCC_I2C345CKSELR, 3, 3), ++ MUX_CFG(MUX_I2C5, i2c345_src, RCC_I2C345CKSELR, 6, 3), ++ MUX_CFG(MUX_LPTIM1, lptim1_src, RCC_LPTIM1CKSELR, 0, 3), ++ MUX_CFG(MUX_LPTIM2, lptim23_src, RCC_LPTIM23CKSELR, 0, 3), ++ MUX_CFG(MUX_LPTIM3, lptim23_src, RCC_LPTIM23CKSELR, 3, 3), ++ MUX_CFG(MUX_MCO1, mco1_src, RCC_MCO1CFGR, 0, 3), ++ MUX_CFG(MUX_MCO2, mco2_src, RCC_MCO2CFGR, 0, 3), ++ MUX_CFG(MUX_QSPI, qspi_src, RCC_QSPICKSELR, 0, 2), ++ MUX_CFG(MUX_RNG1, rng1_src, RCC_RNG1CKSELR, 0, 2), ++ MUX_CFG(MUX_SAES, saes_src, RCC_SAESCKSELR, 0, 2), ++ MUX_CFG(MUX_SAI1, sai1_src, RCC_SAI1CKSELR, 0, 3), ++ MUX_CFG(MUX_SAI2, sai2_src, RCC_SAI2CKSELR, 0, 3), ++ MUX_CFG(MUX_SDMMC1, sdmmc12_src, RCC_SDMMC12CKSELR, 0, 3), ++ MUX_CFG(MUX_SDMMC2, sdmmc12_src, RCC_SDMMC12CKSELR, 3, 3), ++ MUX_CFG(MUX_SPDIF, spdif_src, RCC_SPDIFCKSELR, 0, 2), ++ MUX_CFG(MUX_SPI1, spi123_src, RCC_SPI2S1CKSELR, 0, 3), ++ MUX_CFG(MUX_SPI4, spi4_src, RCC_SPI45CKSELR, 0, 3), ++ MUX_CFG(MUX_SPI5, spi5_src, RCC_SPI45CKSELR, 3, 3), ++ MUX_CFG(MUX_STGEN, stgen_src, RCC_STGENCKSELR, 0, 2), ++ MUX_CFG(MUX_UART1, usart12_src, RCC_UART12CKSELR, 0, 3), ++ MUX_CFG(MUX_UART2, usart12_src, RCC_UART12CKSELR, 3, 3), ++ MUX_CFG(MUX_UART4, usart34578_src, RCC_UART4CKSELR, 0, 3), ++ MUX_CFG(MUX_UART6, usart6_src, RCC_UART6CKSELR, 0, 3), ++ MUX_CFG(MUX_USBO, usbo_src, RCC_USBCKSELR, 4, 1), ++ MUX_CFG(MUX_USBPHY, usbphy_src, RCC_USBCKSELR, 0, 2), ++}; ++ ++enum enum_gate_cfg { ++ GATE_ZERO, /* reserved for no gate */ ++ GATE_MCO1, ++ GATE_MCO2, ++ GATE_DBGCK, ++ GATE_TRACECK, ++ GATE_DDRC1, ++ GATE_DDRC1LP, ++ GATE_DDRPHYC, ++ GATE_DDRPHYCLP, ++ GATE_DDRCAPB, ++ GATE_DDRCAPBLP, ++ GATE_AXIDCG, ++ GATE_DDRPHYCAPB, ++ GATE_DDRPHYCAPBLP, ++ GATE_TIM2, ++ GATE_TIM3, ++ GATE_TIM4, ++ GATE_TIM5, ++ GATE_TIM6, ++ GATE_TIM7, ++ GATE_LPTIM1, ++ GATE_SPI2, ++ GATE_SPI3, ++ GATE_USART3, ++ GATE_UART4, ++ GATE_UART5, ++ GATE_UART7, ++ GATE_UART8, ++ GATE_I2C1, ++ GATE_I2C2, ++ GATE_SPDIF, ++ GATE_TIM1, ++ GATE_TIM8, ++ GATE_SPI1, ++ GATE_USART6, ++ GATE_SAI1, ++ GATE_SAI2, ++ GATE_DFSDM, ++ GATE_ADFSDM, ++ GATE_FDCAN, ++ GATE_LPTIM2, ++ GATE_LPTIM3, ++ GATE_LPTIM4, ++ GATE_LPTIM5, ++ GATE_VREF, ++ GATE_DTS, ++ GATE_PMBCTRL, ++ GATE_HDP, ++ GATE_SYSCFG, ++ GATE_DCMIPP, ++ GATE_DDRPERFM, ++ GATE_IWDG2APB, ++ GATE_USBPHY, ++ GATE_STGENRO, ++ GATE_LTDC, ++ GATE_TZC, ++ GATE_ETZPC, ++ GATE_IWDG1APB, ++ GATE_BSEC, ++ GATE_STGENC, ++ GATE_USART1, ++ GATE_USART2, ++ GATE_SPI4, ++ GATE_SPI5, ++ GATE_I2C3, ++ GATE_I2C4, ++ GATE_I2C5, ++ GATE_TIM12, ++ GATE_TIM13, ++ GATE_TIM14, ++ GATE_TIM15, ++ GATE_TIM16, ++ GATE_TIM17, ++ GATE_DMA1, ++ GATE_DMA2, ++ GATE_DMAMUX1, ++ GATE_DMA3, ++ GATE_DMAMUX2, ++ GATE_ADC1, ++ GATE_ADC2, ++ GATE_USBO, ++ GATE_TSC, ++ GATE_GPIOA, ++ GATE_GPIOB, ++ GATE_GPIOC, ++ GATE_GPIOD, ++ GATE_GPIOE, ++ GATE_GPIOF, ++ GATE_GPIOG, ++ GATE_GPIOH, ++ GATE_GPIOI, ++ GATE_PKA, ++ GATE_SAES, ++ GATE_CRYP1, ++ GATE_HASH1, ++ GATE_RNG1, ++ GATE_BKPSRAM, ++ GATE_AXIMC, ++ GATE_MCE, ++ GATE_ETH1CK, ++ GATE_ETH1TX, ++ GATE_ETH1RX, ++ GATE_ETH1MAC, ++ GATE_FMC, ++ GATE_QSPI, ++ GATE_SDMMC1, ++ GATE_SDMMC2, ++ GATE_CRC1, ++ GATE_USBH, ++ GATE_ETH2CK, ++ GATE_ETH2TX, ++ GATE_ETH2RX, ++ GATE_ETH2MAC, ++ GATE_ETH1STP, ++ GATE_ETH2STP, ++ GATE_MDMA ++}; ++ ++#define GATE_CFG(id, _offset, _bit_idx, _offset_clr)[id] = {\ ++ .reg_off = (_offset),\ ++ .bit_idx = (_bit_idx),\ ++ .set_clr = (_offset_clr),\ ++} ++ ++static const struct stm32_gate_cfg stm32mp13_gates[] = { ++ GATE_CFG(GATE_MCO1, RCC_MCO1CFGR, 12, 0), ++ GATE_CFG(GATE_MCO2, RCC_MCO2CFGR, 12, 0), ++ GATE_CFG(GATE_DBGCK, RCC_DBGCFGR, 8, 0), ++ GATE_CFG(GATE_TRACECK, RCC_DBGCFGR, 9, 0), ++ GATE_CFG(GATE_DDRC1, RCC_DDRITFCR, 0, 0), ++ GATE_CFG(GATE_DDRC1LP, RCC_DDRITFCR, 1, 0), ++ GATE_CFG(GATE_DDRPHYC, RCC_DDRITFCR, 4, 0), ++ GATE_CFG(GATE_DDRPHYCLP, RCC_DDRITFCR, 5, 0), ++ GATE_CFG(GATE_DDRCAPB, RCC_DDRITFCR, 6, 0), ++ GATE_CFG(GATE_DDRCAPBLP, RCC_DDRITFCR, 7, 0), ++ GATE_CFG(GATE_AXIDCG, RCC_DDRITFCR, 8, 0), ++ GATE_CFG(GATE_DDRPHYCAPB, RCC_DDRITFCR, 9, 0), ++ GATE_CFG(GATE_DDRPHYCAPBLP, RCC_DDRITFCR, 10, 0), ++ GATE_CFG(GATE_TIM2, RCC_MP_APB1ENSETR, 0, 1), ++ GATE_CFG(GATE_TIM3, RCC_MP_APB1ENSETR, 1, 1), ++ GATE_CFG(GATE_TIM4, RCC_MP_APB1ENSETR, 2, 1), ++ GATE_CFG(GATE_TIM5, RCC_MP_APB1ENSETR, 3, 1), ++ GATE_CFG(GATE_TIM6, RCC_MP_APB1ENSETR, 4, 1), ++ GATE_CFG(GATE_TIM7, RCC_MP_APB1ENSETR, 5, 1), ++ GATE_CFG(GATE_LPTIM1, RCC_MP_APB1ENSETR, 9, 1), ++ GATE_CFG(GATE_SPI2, RCC_MP_APB1ENSETR, 11, 1), ++ GATE_CFG(GATE_SPI3, RCC_MP_APB1ENSETR, 12, 1), ++ GATE_CFG(GATE_USART3, RCC_MP_APB1ENSETR, 15, 1), ++ GATE_CFG(GATE_UART4, RCC_MP_APB1ENSETR, 16, 1), ++ GATE_CFG(GATE_UART5, RCC_MP_APB1ENSETR, 17, 1), ++ GATE_CFG(GATE_UART7, RCC_MP_APB1ENSETR, 18, 1), ++ GATE_CFG(GATE_UART8, RCC_MP_APB1ENSETR, 19, 1), ++ GATE_CFG(GATE_I2C1, RCC_MP_APB1ENSETR, 21, 1), ++ GATE_CFG(GATE_I2C2, RCC_MP_APB1ENSETR, 22, 1), ++ GATE_CFG(GATE_SPDIF, RCC_MP_APB1ENSETR, 26, 1), ++ GATE_CFG(GATE_TIM1, RCC_MP_APB2ENSETR, 0, 1), ++ GATE_CFG(GATE_TIM8, RCC_MP_APB2ENSETR, 1, 1), ++ GATE_CFG(GATE_SPI1, RCC_MP_APB2ENSETR, 8, 1), ++ GATE_CFG(GATE_USART6, RCC_MP_APB2ENSETR, 13, 1), ++ GATE_CFG(GATE_SAI1, RCC_MP_APB2ENSETR, 16, 1), ++ GATE_CFG(GATE_SAI2, RCC_MP_APB2ENSETR, 17, 1), ++ GATE_CFG(GATE_DFSDM, RCC_MP_APB2ENSETR, 20, 1), ++ GATE_CFG(GATE_ADFSDM, RCC_MP_APB2ENSETR, 21, 1), ++ GATE_CFG(GATE_FDCAN, RCC_MP_APB2ENSETR, 24, 1), ++ GATE_CFG(GATE_LPTIM2, RCC_MP_APB3ENSETR, 0, 1), ++ GATE_CFG(GATE_LPTIM3, RCC_MP_APB3ENSETR, 1, 1), ++ GATE_CFG(GATE_LPTIM4, RCC_MP_APB3ENSETR, 2, 1), ++ GATE_CFG(GATE_LPTIM5, RCC_MP_APB3ENSETR, 3, 1), ++ GATE_CFG(GATE_VREF, RCC_MP_APB3ENSETR, 13, 1), ++ GATE_CFG(GATE_DTS, RCC_MP_APB3ENSETR, 16, 1), ++ GATE_CFG(GATE_PMBCTRL, RCC_MP_APB3ENSETR, 17, 1), ++ GATE_CFG(GATE_HDP, RCC_MP_APB3ENSETR, 20, 1), ++ GATE_CFG(GATE_SYSCFG, RCC_MP_NS_APB3ENSETR, 0, 1), ++ GATE_CFG(GATE_DCMIPP, RCC_MP_APB4ENSETR, 1, 1), ++ GATE_CFG(GATE_DDRPERFM, RCC_MP_APB4ENSETR, 8, 1), ++ GATE_CFG(GATE_IWDG2APB, RCC_MP_APB4ENSETR, 15, 1), ++ GATE_CFG(GATE_USBPHY, RCC_MP_APB4ENSETR, 16, 1), ++ GATE_CFG(GATE_STGENRO, RCC_MP_APB4ENSETR, 20, 1), ++ GATE_CFG(GATE_LTDC, RCC_MP_NS_APB4ENSETR, 0, 1), ++ GATE_CFG(GATE_TZC, RCC_MP_APB5ENSETR, 11, 1), ++ GATE_CFG(GATE_ETZPC, RCC_MP_APB5ENSETR, 13, 1), ++ GATE_CFG(GATE_IWDG1APB, RCC_MP_APB5ENSETR, 15, 1), ++ GATE_CFG(GATE_BSEC, RCC_MP_APB5ENSETR, 16, 1), ++ GATE_CFG(GATE_STGENC, RCC_MP_APB5ENSETR, 20, 1), ++ GATE_CFG(GATE_USART1, RCC_MP_APB6ENSETR, 0, 1), ++ GATE_CFG(GATE_USART2, RCC_MP_APB6ENSETR, 1, 1), ++ GATE_CFG(GATE_SPI4, RCC_MP_APB6ENSETR, 2, 1), ++ GATE_CFG(GATE_SPI5, RCC_MP_APB6ENSETR, 3, 1), ++ GATE_CFG(GATE_I2C3, RCC_MP_APB6ENSETR, 4, 1), ++ GATE_CFG(GATE_I2C4, RCC_MP_APB6ENSETR, 5, 1), ++ GATE_CFG(GATE_I2C5, RCC_MP_APB6ENSETR, 6, 1), ++ GATE_CFG(GATE_TIM12, RCC_MP_APB6ENSETR, 7, 1), ++ GATE_CFG(GATE_TIM13, RCC_MP_APB6ENSETR, 8, 1), ++ GATE_CFG(GATE_TIM14, RCC_MP_APB6ENSETR, 9, 1), ++ GATE_CFG(GATE_TIM15, RCC_MP_APB6ENSETR, 10, 1), ++ GATE_CFG(GATE_TIM16, RCC_MP_APB6ENSETR, 11, 1), ++ GATE_CFG(GATE_TIM17, RCC_MP_APB6ENSETR, 12, 1), ++ GATE_CFG(GATE_DMA1, RCC_MP_AHB2ENSETR, 0, 1), ++ GATE_CFG(GATE_DMA2, RCC_MP_AHB2ENSETR, 1, 1), ++ GATE_CFG(GATE_DMAMUX1, RCC_MP_AHB2ENSETR, 2, 1), ++ GATE_CFG(GATE_DMA3, RCC_MP_AHB2ENSETR, 3, 1), ++ GATE_CFG(GATE_DMAMUX2, RCC_MP_AHB2ENSETR, 4, 1), ++ GATE_CFG(GATE_ADC1, RCC_MP_AHB2ENSETR, 5, 1), ++ GATE_CFG(GATE_ADC2, RCC_MP_AHB2ENSETR, 6, 1), ++ GATE_CFG(GATE_USBO, RCC_MP_AHB2ENSETR, 8, 1), ++ GATE_CFG(GATE_TSC, RCC_MP_AHB4ENSETR, 15, 1), ++ GATE_CFG(GATE_GPIOA, RCC_MP_NS_AHB4ENSETR, 0, 1), ++ GATE_CFG(GATE_GPIOB, RCC_MP_NS_AHB4ENSETR, 1, 1), ++ GATE_CFG(GATE_GPIOC, RCC_MP_NS_AHB4ENSETR, 2, 1), ++ GATE_CFG(GATE_GPIOD, RCC_MP_NS_AHB4ENSETR, 3, 1), ++ GATE_CFG(GATE_GPIOE, RCC_MP_NS_AHB4ENSETR, 4, 1), ++ GATE_CFG(GATE_GPIOF, RCC_MP_NS_AHB4ENSETR, 5, 1), ++ GATE_CFG(GATE_GPIOG, RCC_MP_NS_AHB4ENSETR, 6, 1), ++ GATE_CFG(GATE_GPIOH, RCC_MP_NS_AHB4ENSETR, 7, 1), ++ GATE_CFG(GATE_GPIOI, RCC_MP_NS_AHB4ENSETR, 8, 1), ++ GATE_CFG(GATE_PKA, RCC_MP_AHB5ENSETR, 2, 1), ++ GATE_CFG(GATE_SAES, RCC_MP_AHB5ENSETR, 3, 1), ++ GATE_CFG(GATE_CRYP1, RCC_MP_AHB5ENSETR, 4, 1), ++ GATE_CFG(GATE_HASH1, RCC_MP_AHB5ENSETR, 5, 1), ++ GATE_CFG(GATE_RNG1, RCC_MP_AHB5ENSETR, 6, 1), ++ GATE_CFG(GATE_BKPSRAM, RCC_MP_AHB5ENSETR, 8, 1), ++ GATE_CFG(GATE_AXIMC, RCC_MP_AHB5ENSETR, 16, 1), ++ GATE_CFG(GATE_MCE, RCC_MP_AHB6ENSETR, 1, 1), ++ GATE_CFG(GATE_ETH1CK, RCC_MP_AHB6ENSETR, 7, 1), ++ GATE_CFG(GATE_ETH1TX, RCC_MP_AHB6ENSETR, 8, 1), ++ GATE_CFG(GATE_ETH1RX, RCC_MP_AHB6ENSETR, 9, 1), ++ GATE_CFG(GATE_ETH1MAC, RCC_MP_AHB6ENSETR, 10, 1), ++ GATE_CFG(GATE_FMC, RCC_MP_AHB6ENSETR, 12, 1), ++ GATE_CFG(GATE_QSPI, RCC_MP_AHB6ENSETR, 14, 1), ++ GATE_CFG(GATE_SDMMC1, RCC_MP_AHB6ENSETR, 16, 1), ++ GATE_CFG(GATE_SDMMC2, RCC_MP_AHB6ENSETR, 17, 1), ++ GATE_CFG(GATE_CRC1, RCC_MP_AHB6ENSETR, 20, 1), ++ GATE_CFG(GATE_USBH, RCC_MP_AHB6ENSETR, 24, 1), ++ GATE_CFG(GATE_ETH2CK, RCC_MP_AHB6ENSETR, 27, 1), ++ GATE_CFG(GATE_ETH2TX, RCC_MP_AHB6ENSETR, 28, 1), ++ GATE_CFG(GATE_ETH2RX, RCC_MP_AHB6ENSETR, 29, 1), ++ GATE_CFG(GATE_ETH2MAC, RCC_MP_AHB6ENSETR, 30, 1), ++ GATE_CFG(GATE_ETH1STP, RCC_MP_AHB6LPENSETR, 11, 1), ++ GATE_CFG(GATE_ETH2STP, RCC_MP_AHB6LPENSETR, 31, 1), ++ GATE_CFG(GATE_MDMA, RCC_MP_NS_AHB6ENSETR, 0, 1), ++}; ++ ++static const struct clk_div_table ck_trace_div_table[] = { ++ { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, ++ { 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 }, ++ { 0 }, ++}; ++ ++enum enum_div_cfg { ++ DIV_MCO1, ++ DIV_MCO2, ++ DIV_TRACE, ++ DIV_ETH1PTP, ++ DIV_ETH2PTP, ++ LAST_DIV ++}; ++ ++#define DIV_CFG(id, _offset, _shift, _width, _flags, _table)[id] = {\ ++ .reg_off = _offset,\ ++ .shift = _shift,\ ++ .width = _width,\ ++ .div_flags = _flags,\ ++ .table = _table,\ ++} ++ ++static const struct stm32_div_cfg stm32mp13_dividers[LAST_DIV] = { ++ DIV_CFG(DIV_MCO1, RCC_MCO1CFGR, 4, 4, 0, NULL), ++ DIV_CFG(DIV_MCO2, RCC_MCO2CFGR, 4, 4, 0, NULL), ++ DIV_CFG(DIV_TRACE, RCC_DBGCFGR, 0, 3, 0, ck_trace_div_table), ++ DIV_CFG(DIV_ETH1PTP, RCC_ETH12CKSELR, 4, 4, 0, NULL), ++ DIV_CFG(DIV_ETH2PTP, RCC_ETH12CKSELR, 12, 4, 0, NULL), ++}; ++ ++struct clk_stm32_securiy { ++ u16 offset; ++ u8 bit_idx; ++}; ++ ++enum securit_clk { ++ SECF_NONE, ++ SECF_LPTIM2, ++ SECF_LPTIM3, ++ SECF_VREF, ++ SECF_DCMIPP, ++ SECF_USBPHY, ++ SECF_RTC, ++ SECF_TZC, ++ SECF_ETZPC, ++ SECF_IWDG1, ++ SECF_BSEC, ++ SECF_STGENC, ++ SECF_STGENRO, ++ SECF_USART1, ++ SECF_USART2, ++ SECF_SPI4, ++ SECF_SPI5, ++ SECF_I2C3, ++ SECF_I2C4, ++ SECF_I2C5, ++ SECF_TIM12, ++ SECF_TIM13, ++ SECF_TIM14, ++ SECF_TIM15, ++ SECF_TIM16, ++ SECF_TIM17, ++ SECF_DMA3, ++ SECF_DMAMUX2, ++ SECF_ADC1, ++ SECF_ADC2, ++ SECF_USBO, ++ SECF_TSC, ++ SECF_PKA, ++ SECF_SAES, ++ SECF_CRYP1, ++ SECF_HASH1, ++ SECF_RNG1, ++ SECF_BKPSRAM, ++ SECF_MCE, ++ SECF_FMC, ++ SECF_QSPI, ++ SECF_SDMMC1, ++ SECF_SDMMC2, ++ SECF_ETH1CK, ++ SECF_ETH1TX, ++ SECF_ETH1RX, ++ SECF_ETH1MAC, ++ SECF_ETH1STP, ++ SECF_ETH2CK, ++ SECF_ETH2TX, ++ SECF_ETH2RX, ++ SECF_ETH2MAC, ++ SECF_ETH2STP, ++ SECF_MCO1, ++ SECF_MCO2 ++}; ++ ++#define SECF(_sec_id, _offset, _bit_idx)[_sec_id] = {\ ++ .offset = _offset,\ ++ .bit_idx = _bit_idx,\ ++} ++ ++static const struct clk_stm32_securiy stm32mp13_security[] = { ++ SECF(SECF_LPTIM2, RCC_APB3SECSR, RCC_APB3SECSR_LPTIM2SECF), ++ SECF(SECF_LPTIM3, RCC_APB3SECSR, RCC_APB3SECSR_LPTIM3SECF), ++ SECF(SECF_VREF, RCC_APB3SECSR, RCC_APB3SECSR_VREFSECF), ++ SECF(SECF_DCMIPP, RCC_APB4SECSR, RCC_APB4SECSR_DCMIPPSECF), ++ SECF(SECF_USBPHY, RCC_APB4SECSR, RCC_APB4SECSR_USBPHYSECF), ++ SECF(SECF_RTC, RCC_APB5SECSR, RCC_APB5SECSR_RTCSECF), ++ SECF(SECF_TZC, RCC_APB5SECSR, RCC_APB5SECSR_TZCSECF), ++ SECF(SECF_ETZPC, RCC_APB5SECSR, RCC_APB5SECSR_ETZPCSECF), ++ SECF(SECF_IWDG1, RCC_APB5SECSR, RCC_APB5SECSR_IWDG1SECF), ++ SECF(SECF_BSEC, RCC_APB5SECSR, RCC_APB5SECSR_BSECSECF), ++ SECF(SECF_STGENC, RCC_APB5SECSR, RCC_APB5SECSR_STGENCSECF), ++ SECF(SECF_STGENRO, RCC_APB5SECSR, RCC_APB5SECSR_STGENROSECF), ++ SECF(SECF_USART1, RCC_APB6SECSR, RCC_APB6SECSR_USART1SECF), ++ SECF(SECF_USART2, RCC_APB6SECSR, RCC_APB6SECSR_USART2SECF), ++ SECF(SECF_SPI4, RCC_APB6SECSR, RCC_APB6SECSR_SPI4SECF), ++ SECF(SECF_SPI5, RCC_APB6SECSR, RCC_APB6SECSR_SPI5SECF), ++ SECF(SECF_I2C3, RCC_APB6SECSR, RCC_APB6SECSR_I2C3SECF), ++ SECF(SECF_I2C4, RCC_APB6SECSR, RCC_APB6SECSR_I2C4SECF), ++ SECF(SECF_I2C5, RCC_APB6SECSR, RCC_APB6SECSR_I2C5SECF), ++ SECF(SECF_TIM12, RCC_APB6SECSR, RCC_APB6SECSR_TIM12SECF), ++ SECF(SECF_TIM13, RCC_APB6SECSR, RCC_APB6SECSR_TIM13SECF), ++ SECF(SECF_TIM14, RCC_APB6SECSR, RCC_APB6SECSR_TIM14SECF), ++ SECF(SECF_TIM15, RCC_APB6SECSR, RCC_APB6SECSR_TIM15SECF), ++ SECF(SECF_TIM16, RCC_APB6SECSR, RCC_APB6SECSR_TIM16SECF), ++ SECF(SECF_TIM17, RCC_APB6SECSR, RCC_APB6SECSR_TIM17SECF), ++ SECF(SECF_DMA3, RCC_AHB2SECSR, RCC_AHB2SECSR_DMA3SECF), ++ SECF(SECF_DMAMUX2, RCC_AHB2SECSR, RCC_AHB2SECSR_DMAMUX2SECF), ++ SECF(SECF_ADC1, RCC_AHB2SECSR, RCC_AHB2SECSR_ADC1SECF), ++ SECF(SECF_ADC2, RCC_AHB2SECSR, RCC_AHB2SECSR_ADC2SECF), ++ SECF(SECF_USBO, RCC_AHB2SECSR, RCC_AHB2SECSR_USBOSECF), ++ SECF(SECF_TSC, RCC_AHB4SECSR, RCC_AHB4SECSR_TSCSECF), ++ SECF(SECF_PKA, RCC_AHB5SECSR, RCC_AHB5SECSR_PKASECF), ++ SECF(SECF_SAES, RCC_AHB5SECSR, RCC_AHB5SECSR_SAESSECF), ++ SECF(SECF_CRYP1, RCC_AHB5SECSR, RCC_AHB5SECSR_CRYP1SECF), ++ SECF(SECF_HASH1, RCC_AHB5SECSR, RCC_AHB5SECSR_HASH1SECF), ++ SECF(SECF_RNG1, RCC_AHB5SECSR, RCC_AHB5SECSR_RNG1SECF), ++ SECF(SECF_BKPSRAM, RCC_AHB5SECSR, RCC_AHB5SECSR_BKPSRAMSECF), ++ SECF(SECF_MCE, RCC_AHB6SECSR, RCC_AHB6SECSR_MCESECF), ++ SECF(SECF_FMC, RCC_AHB6SECSR, RCC_AHB6SECSR_FMCSECF), ++ SECF(SECF_QSPI, RCC_AHB6SECSR, RCC_AHB6SECSR_QSPISECF), ++ SECF(SECF_SDMMC1, RCC_AHB6SECSR, RCC_AHB6SECSR_SDMMC1SECF), ++ SECF(SECF_SDMMC2, RCC_AHB6SECSR, RCC_AHB6SECSR_SDMMC2SECF), ++ SECF(SECF_ETH1CK, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1CKSECF), ++ SECF(SECF_ETH1TX, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1TXSECF), ++ SECF(SECF_ETH1RX, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1RXSECF), ++ SECF(SECF_ETH1MAC, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1MACSECF), ++ SECF(SECF_ETH1STP, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1STPSECF), ++ SECF(SECF_ETH2CK, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2CKSECF), ++ SECF(SECF_ETH2TX, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2TXSECF), ++ SECF(SECF_ETH2RX, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2RXSECF), ++ SECF(SECF_ETH2MAC, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2MACSECF), ++ SECF(SECF_ETH2STP, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2STPSECF), ++ SECF(SECF_MCO1, RCC_SECCFGR, RCC_SECCFGR_MCO1SECF), ++ SECF(SECF_MCO2, RCC_SECCFGR, RCC_SECCFGR_MCO2SECF), ++}; ++ ++#define PCLK(_id, _name, _parent, _flags, _gate_id, _sec_id)\ ++ STM32_GATE(_id, _name, _parent, _flags, _gate_id, _sec_id) ++ ++#define TIMER(_id, _name, _parent, _flags, _gate_id, _sec_id)\ ++ STM32_GATE(_id, _name, _parent, ((_flags) | CLK_SET_RATE_PARENT),\ ++ _gate_id, _sec_id) ++ ++#define KCLK(_id, _name, _flags, _gate_id, _mux_id, _sec_id)\ ++ STM32_COMPOSITE(_id, _name, _flags, _sec_id,\ ++ _gate_id, _mux_id, NO_STM32_DIV) ++ ++static const struct clock_config stm32mp13_clock_cfg[] = { ++ TIMER(TIM2_K, "tim2_k", "timg1_ck", 0, GATE_TIM2, SECF_NONE), ++ TIMER(TIM3_K, "tim3_k", "timg1_ck", 0, GATE_TIM3, SECF_NONE), ++ TIMER(TIM4_K, "tim4_k", "timg1_ck", 0, GATE_TIM4, SECF_NONE), ++ TIMER(TIM5_K, "tim5_k", "timg1_ck", 0, GATE_TIM5, SECF_NONE), ++ TIMER(TIM6_K, "tim6_k", "timg1_ck", 0, GATE_TIM6, SECF_NONE), ++ TIMER(TIM7_K, "tim7_k", "timg1_ck", 0, GATE_TIM7, SECF_NONE), ++ TIMER(TIM1_K, "tim1_k", "timg2_ck", 0, GATE_TIM1, SECF_NONE), ++ TIMER(TIM8_K, "tim8_k", "timg2_ck", 0, GATE_TIM8, SECF_NONE), ++ TIMER(TIM12_K, "tim12_k", "timg3_ck", 0, GATE_TIM12, SECF_TIM12), ++ TIMER(TIM13_K, "tim13_k", "timg3_ck", 0, GATE_TIM13, SECF_TIM13), ++ TIMER(TIM14_K, "tim14_k", "timg3_ck", 0, GATE_TIM14, SECF_TIM14), ++ TIMER(TIM15_K, "tim15_k", "timg3_ck", 0, GATE_TIM15, SECF_TIM15), ++ TIMER(TIM16_K, "tim16_k", "timg3_ck", 0, GATE_TIM16, SECF_TIM16), ++ TIMER(TIM17_K, "tim17_k", "timg3_ck", 0, GATE_TIM17, SECF_TIM17), ++ ++ /* Peripheral clocks */ ++ PCLK(SYSCFG, "syscfg", "pclk3", 0, GATE_SYSCFG, SECF_NONE), ++ PCLK(VREF, "vref", "pclk3", 0, GATE_VREF, SECF_VREF), ++ PCLK(PMBCTRL, "pmbctrl", "pclk3", 0, GATE_PMBCTRL, SECF_NONE), ++ PCLK(HDP, "hdp", "pclk3", 0, GATE_HDP, SECF_NONE), ++ PCLK(IWDG2, "iwdg2", "pclk4", 0, GATE_IWDG2APB, SECF_NONE), ++ PCLK(STGENRO, "stgenro", "pclk4", 0, GATE_STGENRO, SECF_STGENRO), ++ PCLK(TZPC, "tzpc", "pclk5", 0, GATE_TZC, SECF_TZC), ++ PCLK(IWDG1, "iwdg1", "pclk5", 0, GATE_IWDG1APB, SECF_IWDG1), ++ PCLK(BSEC, "bsec", "pclk5", 0, GATE_BSEC, SECF_BSEC), ++ PCLK(DMA1, "dma1", "ck_mlahb", 0, GATE_DMA1, SECF_NONE), ++ PCLK(DMA2, "dma2", "ck_mlahb", 0, GATE_DMA2, SECF_NONE), ++ PCLK(DMAMUX1, "dmamux1", "ck_mlahb", 0, GATE_DMAMUX1, SECF_NONE), ++ PCLK(DMAMUX2, "dmamux2", "ck_mlahb", 0, GATE_DMAMUX2, SECF_DMAMUX2), ++ PCLK(ADC1, "adc1", "ck_mlahb", 0, GATE_ADC1, SECF_ADC1), ++ PCLK(ADC2, "adc2", "ck_mlahb", 0, GATE_ADC2, SECF_ADC2), ++ PCLK(GPIOA, "gpioa", "pclk4", 0, GATE_GPIOA, SECF_NONE), ++ PCLK(GPIOB, "gpiob", "pclk4", 0, GATE_GPIOB, SECF_NONE), ++ PCLK(GPIOC, "gpioc", "pclk4", 0, GATE_GPIOC, SECF_NONE), ++ PCLK(GPIOD, "gpiod", "pclk4", 0, GATE_GPIOD, SECF_NONE), ++ PCLK(GPIOE, "gpioe", "pclk4", 0, GATE_GPIOE, SECF_NONE), ++ PCLK(GPIOF, "gpiof", "pclk4", 0, GATE_GPIOF, SECF_NONE), ++ PCLK(GPIOG, "gpiog", "pclk4", 0, GATE_GPIOG, SECF_NONE), ++ PCLK(GPIOH, "gpioh", "pclk4", 0, GATE_GPIOH, SECF_NONE), ++ PCLK(GPIOI, "gpioi", "pclk4", 0, GATE_GPIOI, SECF_NONE), ++ PCLK(TSC, "tsc", "pclk4", 0, GATE_TSC, SECF_TZC), ++ PCLK(PKA, "pka", "ck_axi", 0, GATE_PKA, SECF_PKA), ++ PCLK(CRYP1, "cryp1", "ck_axi", 0, GATE_CRYP1, SECF_CRYP1), ++ PCLK(HASH1, "hash1", "ck_axi", 0, GATE_HASH1, SECF_HASH1), ++ PCLK(BKPSRAM, "bkpsram", "ck_axi", 0, GATE_BKPSRAM, SECF_BKPSRAM), ++ PCLK(MDMA, "mdma", "ck_axi", 0, GATE_MDMA, SECF_NONE), ++ PCLK(ETH1TX, "eth1tx", "ck_axi", 0, GATE_ETH1TX, SECF_ETH1TX), ++ PCLK(ETH1RX, "eth1rx", "ck_axi", 0, GATE_ETH1RX, SECF_ETH1RX), ++ PCLK(ETH1MAC, "eth1mac", "ck_axi", 0, GATE_ETH1MAC, SECF_ETH1MAC), ++ PCLK(ETH2TX, "eth2tx", "ck_axi", 0, GATE_ETH2TX, SECF_ETH2TX), ++ PCLK(ETH2RX, "eth2rx", "ck_axi", 0, GATE_ETH2RX, SECF_ETH2RX), ++ PCLK(ETH2MAC, "eth2mac", "ck_axi", 0, GATE_ETH2MAC, SECF_ETH2MAC), ++ PCLK(CRC1, "crc1", "ck_axi", 0, GATE_CRC1, SECF_NONE), ++ PCLK(USBH, "usbh", "ck_axi", 0, GATE_USBH, SECF_NONE), ++ PCLK(DDRPERFM, "ddrperfm", "pclk4", 0, GATE_DDRPERFM, SECF_NONE), ++ PCLK(ETH1STP, "eth1stp", "ck_axi", 0, GATE_ETH1STP, SECF_ETH1STP), ++ PCLK(ETH2STP, "eth2stp", "ck_axi", 0, GATE_ETH2STP, SECF_ETH2STP), ++ ++ /* Kernel clocks */ ++ KCLK(SDMMC1_K, "sdmmc1_k", 0, GATE_SDMMC1, MUX_SDMMC1, SECF_SDMMC1), ++ KCLK(SDMMC2_K, "sdmmc2_k", 0, GATE_SDMMC2, MUX_SDMMC2, SECF_SDMMC2), ++ KCLK(FMC_K, "fmc_k", 0, GATE_FMC, MUX_FMC, SECF_FMC), ++ KCLK(QSPI_K, "qspi_k", 0, GATE_QSPI, MUX_QSPI, SECF_QSPI), ++ KCLK(SPI2_K, "spi2_k", 0, GATE_SPI2, MUX_SPI23, SECF_NONE), ++ KCLK(SPI3_K, "spi3_k", 0, GATE_SPI3, MUX_SPI23, SECF_NONE), ++ KCLK(I2C1_K, "i2c1_k", 0, GATE_I2C1, MUX_I2C12, SECF_NONE), ++ KCLK(I2C2_K, "i2c2_k", 0, GATE_I2C2, MUX_I2C12, SECF_NONE), ++ KCLK(LPTIM4_K, "lptim4_k", 0, GATE_LPTIM4, MUX_LPTIM45, SECF_NONE), ++ KCLK(LPTIM5_K, "lptim5_k", 0, GATE_LPTIM5, MUX_LPTIM45, SECF_NONE), ++ KCLK(USART3_K, "usart3_k", 0, GATE_USART3, MUX_UART35, SECF_NONE), ++ KCLK(UART5_K, "uart5_k", 0, GATE_UART5, MUX_UART35, SECF_NONE), ++ KCLK(UART7_K, "uart7_k", 0, GATE_UART7, MUX_UART78, SECF_NONE), ++ KCLK(UART8_K, "uart8_k", 0, GATE_UART8, MUX_UART78, SECF_NONE), ++ KCLK(RNG1_K, "rng1_k", 0, GATE_RNG1, MUX_RNG1, SECF_RNG1), ++ KCLK(USBPHY_K, "usbphy_k", 0, GATE_USBPHY, MUX_USBPHY, SECF_USBPHY), ++ KCLK(STGEN_K, "stgen_k", 0, GATE_STGENC, MUX_STGEN, SECF_STGENC), ++ KCLK(SPDIF_K, "spdif_k", 0, GATE_SPDIF, MUX_SPDIF, SECF_NONE), ++ KCLK(SPI1_K, "spi1_k", 0, GATE_SPI1, MUX_SPI1, SECF_NONE), ++ KCLK(SPI4_K, "spi4_k", 0, GATE_SPI4, MUX_SPI4, SECF_SPI4), ++ KCLK(SPI5_K, "spi5_k", 0, GATE_SPI5, MUX_SPI5, SECF_SPI5), ++ KCLK(I2C3_K, "i2c3_k", 0, GATE_I2C3, MUX_I2C3, SECF_I2C3), ++ KCLK(I2C4_K, "i2c4_k", 0, GATE_I2C4, MUX_I2C4, SECF_I2C4), ++ KCLK(I2C5_K, "i2c5_k", 0, GATE_I2C5, MUX_I2C5, SECF_I2C5), ++ KCLK(LPTIM1_K, "lptim1_k", 0, GATE_LPTIM1, MUX_LPTIM1, SECF_NONE), ++ KCLK(LPTIM2_K, "lptim2_k", 0, GATE_LPTIM2, MUX_LPTIM2, SECF_LPTIM2), ++ KCLK(LPTIM3_K, "lptim3_k", 0, GATE_LPTIM3, MUX_LPTIM3, SECF_LPTIM3), ++ KCLK(USART1_K, "usart1_k", 0, GATE_USART1, MUX_UART1, SECF_USART1), ++ KCLK(USART2_K, "usart2_k", 0, GATE_USART2, MUX_UART2, SECF_USART2), ++ KCLK(UART4_K, "uart4_k", 0, GATE_UART4, MUX_UART4, SECF_NONE), ++ KCLK(USART6_K, "uart6_k", 0, GATE_USART6, MUX_UART6, SECF_NONE), ++ KCLK(FDCAN_K, "fdcan_k", 0, GATE_FDCAN, MUX_FDCAN, SECF_NONE), ++ KCLK(SAI1_K, "sai1_k", 0, GATE_SAI1, MUX_SAI1, SECF_NONE), ++ KCLK(SAI2_K, "sai2_k", 0, GATE_SAI2, MUX_SAI2, SECF_NONE), ++ KCLK(ADC1_K, "adc1_k", 0, GATE_ADC1, MUX_ADC1, SECF_ADC1), ++ KCLK(ADC2_K, "adc2_k", 0, GATE_ADC2, MUX_ADC2, SECF_ADC2), ++ KCLK(DCMIPP_K, "dcmipp_k", 0, GATE_DCMIPP, MUX_DCMIPP, SECF_DCMIPP), ++ KCLK(ADFSDM_K, "adfsdm_k", 0, GATE_ADFSDM, MUX_SAI1, SECF_NONE), ++ KCLK(USBO_K, "usbo_k", 0, GATE_USBO, MUX_USBO, SECF_USBO), ++ KCLK(ETH1CK_K, "eth1ck_k", 0, GATE_ETH1CK, MUX_ETH1, SECF_ETH1CK), ++ KCLK(ETH2CK_K, "eth2ck_k", 0, GATE_ETH2CK, MUX_ETH2, SECF_ETH2CK), ++ KCLK(SAES_K, "saes_k", 0, GATE_SAES, MUX_SAES, SECF_SAES), ++ ++ STM32_GATE(DFSDM_K, "dfsdm_k", "ck_mlahb", 0, GATE_DFSDM, SECF_NONE), ++ STM32_GATE(LTDC_PX, "ltdc_px", "pll4_q", CLK_SET_RATE_PARENT, ++ GATE_LTDC, SECF_NONE), ++ ++ STM32_GATE(DTS_K, "dts_k", "ck_lse", 0, GATE_DTS, SECF_NONE), ++ ++ STM32_COMPOSITE(ETH1PTP_K, "eth1ptp_k", CLK_OPS_PARENT_ENABLE | ++ CLK_SET_RATE_NO_REPARENT, SECF_ETH1CK, ++ NO_STM32_GATE, MUX_ETH1, DIV_ETH1PTP), ++ ++ STM32_COMPOSITE(ETH2PTP_K, "eth2ptp_k", CLK_OPS_PARENT_ENABLE | ++ CLK_SET_RATE_NO_REPARENT, SECF_ETH2CK, ++ NO_STM32_GATE, MUX_ETH2, DIV_ETH2PTP), ++ ++ /* MCO clocks */ ++ STM32_COMPOSITE(CK_MCO1, "ck_mco1", CLK_OPS_PARENT_ENABLE | ++ CLK_SET_RATE_NO_REPARENT, SECF_MCO1, ++ GATE_MCO1, MUX_MCO1, DIV_MCO1), ++ ++ STM32_COMPOSITE(CK_MCO2, "ck_mco2", CLK_OPS_PARENT_ENABLE | ++ CLK_SET_RATE_NO_REPARENT, SECF_MCO2, ++ GATE_MCO2, MUX_MCO2, DIV_MCO2), ++ ++ /* Debug clocks */ ++ STM32_GATE(CK_DBG, "ck_sys_dbg", "ck_axi", CLK_IGNORE_UNUSED, ++ GATE_DBGCK, SECF_NONE), ++ ++ STM32_COMPOSITE_NOMUX(CK_TRACE, "ck_trace", "ck_axi", ++ CLK_OPS_PARENT_ENABLE, SECF_NONE, ++ GATE_TRACECK, DIV_TRACE), ++}; ++ ++static int stm32mp13_check_security(void __iomem *base, ++ const struct clock_config *cfg) ++{ ++ int sec_id = cfg->sec_id; ++ int secured = 0; ++ ++ if (sec_id != SECF_NONE) { ++ const struct clk_stm32_securiy *secf; ++ ++ secf = &stm32mp13_security[sec_id]; ++ secured = !!(readl(base + secf->offset) & BIT(secf->bit_idx)); ++ } ++ ++ return secured; ++} ++ ++static const struct stm32_clock_match_data stm32mp13_data = { ++ .tab_clocks = stm32mp13_clock_cfg, ++ .num_clocks = ARRAY_SIZE(stm32mp13_clock_cfg), ++ .gates = stm32mp13_gates, ++ .muxes = stm32mp13_muxes, ++ .dividers = stm32mp13_dividers, ++ .check_security = &stm32mp13_check_security ++}; ++ ++static int stm32mp1_clk_probe(struct udevice *dev) ++{ ++ fdt_addr_t base = dev_read_addr(dev->parent); ++ struct udevice *scmi; ++ ++ if (base == FDT_ADDR_T_NONE) ++ return -EINVAL; ++ ++ /* force SCMI probe to register all SCMI clocks */ ++ uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(scmi_clock), &scmi); ++ ++ stm32_rcc_init(NULL, &stm32mp13_data, (void __iomem *)base); ++ ++#if defined(DEBUG) ++ /* display debug information for probe after relocation */ ++ if (gd->flags & GD_FLG_RELOC) ++ stm32mp1_clk_dump(priv); ++#endif ++ gd->cpu_clk = clk_stm32_get_rate_by_name("ck_mpu"); ++ gd->bus_clk = clk_stm32_get_rate_by_name("ck_axi"); ++ ++ /* DDRPHYC father */ ++ gd->mem_clk = clk_stm32_get_rate_by_name("pll2_r"); ++ ++#if defined(CONFIG_DISPLAY_CPUINFO) ++ if (gd->flags & GD_FLG_RELOC) { ++ char buf[32]; ++ ++ log_info("Clocks:\n"); ++ log_info("- MPU : %s MHz\n", strmhz(buf, gd->cpu_clk)); ++ log_info("- AXI : %s MHz\n", strmhz(buf, gd->bus_clk)); ++ log_info("- PER : %s MHz\n", ++ strmhz(buf, clk_stm32_get_rate_by_name("ck_per"))); ++ log_info("- DDR : %s MHz\n", strmhz(buf, gd->mem_clk)); ++ } ++#endif /* CONFIG_DISPLAY_CPUINFO */ ++ ++ return 0; ++} ++ ++U_BOOT_DRIVER(stm32mp1_clock) = { ++ .name = "stm32mp13_clk", ++ .id = UCLASS_CLK, ++ .ops = &stm32_clk_ops, ++ .priv_auto = sizeof(struct stm32mp1_clk_priv), ++ .probe = stm32mp1_clk_probe, ++}; +diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c +index cea38a4c6e..a5f4142f6f 100644 +--- a/drivers/clk/clk-uclass.c ++++ b/drivers/clk/clk-uclass.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -23,7 +24,6 @@ + #include + #include + #include +-#include + + static inline const struct clk_ops *clk_dev_ops(struct udevice *dev) + { +@@ -577,6 +577,19 @@ ulong clk_round_rate(struct clk *clk, ulong rate) + return ops->round_rate(clk, rate); + } + ++static void clk_get_priv(struct clk *clk, struct clk **clkp) ++{ ++ *clkp = clk; ++ ++ /* get private clock struct associated to the provided clock */ ++ if (CONFIG_IS_ENABLED(CLK_CCF)) { ++ /* Take id 0 as a non-valid clk, such as dummy */ ++ if (clk->id) ++ clk_get_by_id(clk->id, clkp); ++ } ++} ++ ++/* clean cache, called with private clock struct */ + static void clk_clean_rate_cache(struct clk *clk) + { + struct udevice *child_dev; +@@ -596,19 +609,39 @@ static void clk_clean_rate_cache(struct clk *clk) + ulong clk_set_rate(struct clk *clk, ulong rate) + { + const struct clk_ops *ops; ++ struct clk *clkp; + + debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate); + if (!clk_valid(clk)) + return 0; +- ops = clk_dev_ops(clk->dev); + +- if (!ops->set_rate) +- return -ENOSYS; ++ /* get private clock struct*/ ++ clk_get_priv(clk, &clkp); ++ ++ ops = clk_dev_ops(clkp->dev); ++ ++ if (!ops->set_rate) { ++ struct clk *pclk = NULL; ++ ++ if ((clkp->flags & CLK_SET_RATE_PARENT) == 0) ++ return -ENOSYS; ++ ++ pclk = clk_get_parent(clkp); ++ if (IS_ERR(pclk)) ++ return -ENODEV; ++ ++ ops = clk_dev_ops(pclk->dev); ++ ++ /* Clean up cached rates for us and all child clocks */ ++ clk_clean_rate_cache(pclk); ++ ++ return ops->set_rate(pclk, rate); ++ } + + /* Clean up cached rates for us and all child clocks */ +- clk_clean_rate_cache(clk); ++ clk_clean_rate_cache(clkp); + +- return ops->set_rate(clk, rate); ++ return ops->set_rate(clkp, rate); + } + + int clk_set_parent(struct clk *clk, struct clk *parent) +@@ -653,7 +686,7 @@ int clk_enable(struct clk *clk) + return 0; + } + if (clkp->dev->parent && +- device_get_uclass_id(clkp->dev) == UCLASS_CLK) { ++ device_get_uclass_id(clkp->dev->parent) == UCLASS_CLK) { + ret = clk_enable(dev_get_clk_ptr(clkp->dev->parent)); + if (ret) { + printf("Enable %s failed\n", +@@ -727,7 +760,7 @@ int clk_disable(struct clk *clk) + } + + if (clkp && clkp->dev->parent && +- device_get_uclass_id(clkp->dev) == UCLASS_CLK) { ++ device_get_uclass_id(clkp->dev->parent) == UCLASS_CLK) { + ret = clk_disable(dev_get_clk_ptr(clkp->dev->parent)); + if (ret) { + printf("Disable %s failed\n", +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 1efb7fe9f3..eff0fa134f 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -4,14 +4,16 @@ + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + */ + ++#define LOG_CATEGORY UCLASS_CLK ++ + #include ++#include + #include + #include + #include + #include + #include + #include +-#include + + int clk_register(struct clk *clk, const char *drv_name, + const char *name, const char *parent_name) +@@ -22,24 +24,24 @@ int clk_register(struct clk *clk, const char *drv_name, + + ret = uclass_get_device_by_name(UCLASS_CLK, parent_name, &parent); + if (ret) { +- printf("%s: failed to get %s device (parent of %s)\n", +- __func__, parent_name, name); ++ log_err("%s: failed to get %s device (parent of %s)\n", ++ __func__, parent_name, name); + } else { +- debug("%s: name: %s parent: %s [0x%p]\n", __func__, name, +- parent->name, parent); ++ log_debug("%s: name: %s parent: %s [0x%p]\n", __func__, name, ++ parent->name, parent); + } + + drv = lists_driver_lookup_name(drv_name); + if (!drv) { +- printf("%s: %s is not a valid driver name\n", +- __func__, drv_name); ++ log_err("%s: %s is not a valid driver name\n", ++ __func__, drv_name); + return -ENOENT; + } + + ret = device_bind(parent, drv, name, NULL, ofnode_null(), &clk->dev); + if (ret) { +- printf("%s: CLK: %s driver bind error [%d]!\n", __func__, name, +- ret); ++ log_err("%s: CLK: %s driver bind error [%d]!\n", __func__, name, ++ ret); + return ret; + } + +diff --git a/drivers/clk/clk_fixed_factor.c b/drivers/clk/clk_fixed_factor.c +index e51f94a937..1379992d56 100644 +--- a/drivers/clk/clk_fixed_factor.c ++++ b/drivers/clk/clk_fixed_factor.c +@@ -5,10 +5,13 @@ + * Author: Anup Patel + */ + ++#define LOG_CATEGORY UCLASS_CLK ++ + #include + #include + #include + #include ++#include + #include + + struct clk_fixed_factor { +diff --git a/drivers/clk/clk_fixed_rate.c b/drivers/clk/clk_fixed_rate.c +index 325a9b2dcf..01a6d59af9 100644 +--- a/drivers/clk/clk_fixed_rate.c ++++ b/drivers/clk/clk_fixed_rate.c +@@ -3,9 +3,12 @@ + * Copyright (C) 2016 Masahiro Yamada + */ + ++#define LOG_CATEGORY UCLASS_CLK ++ + #include + #include + #include ++#include + #include + #include + +diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c +index 93a4819501..57022685e2 100644 +--- a/drivers/clk/clk_scmi.c ++++ b/drivers/clk/clk_scmi.c +@@ -2,12 +2,61 @@ + /* + * Copyright (C) 2019-2020 Linaro Limited + */ ++ ++#define LOG_CATEGORY UCLASS_CLK ++ + #include + #include + #include + #include + #include + #include ++#include ++ ++static int scmi_clk_get_num_clock(struct udevice *dev, size_t *num_clocks) ++{ ++ struct scmi_clk_protocol_attr_out out; ++ struct scmi_msg msg = { ++ .protocol_id = SCMI_PROTOCOL_ID_CLOCK, ++ .message_id = SCMI_PROTOCOL_ATTRIBUTES, ++ .out_msg = (u8 *)&out, ++ .out_msg_sz = sizeof(out), ++ }; ++ int ret; ++ ++ ret = devm_scmi_process_msg(dev, &msg); ++ if (ret) ++ return ret; ++ ++ *num_clocks = out.attributes & SCMI_CLK_PROTO_ATTR_COUNT_MASK; ++ ++ return 0; ++} ++ ++static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name) ++{ ++ struct scmi_clk_attribute_in in = { ++ .clock_id = clkid, ++ }; ++ struct scmi_clk_attribute_out out; ++ struct scmi_msg msg = { ++ .protocol_id = SCMI_PROTOCOL_ID_CLOCK, ++ .message_id = SCMI_CLOCK_ATTRIBUTES, ++ .in_msg = (u8 *)&in, ++ .in_msg_sz = sizeof(in), ++ .out_msg = (u8 *)&out, ++ .out_msg_sz = sizeof(out), ++ }; ++ int ret; ++ ++ ret = devm_scmi_process_msg(dev, &msg); ++ if (ret) ++ return ret; ++ ++ *name = out.clock_name; ++ ++ return 0; ++} + + static int scmi_clk_gate(struct clk *clk, int enable) + { +@@ -21,7 +70,7 @@ static int scmi_clk_gate(struct clk *clk, int enable) + in, out); + int ret; + +- ret = devm_scmi_process_msg(clk->dev->parent, &msg); ++ ret = devm_scmi_process_msg(clk->dev, &msg); + if (ret) + return ret; + +@@ -49,7 +98,7 @@ static ulong scmi_clk_get_rate(struct clk *clk) + in, out); + int ret; + +- ret = devm_scmi_process_msg(clk->dev->parent, &msg); ++ ret = devm_scmi_process_msg(clk->dev, &msg); + if (ret < 0) + return ret; + +@@ -74,7 +123,7 @@ static ulong scmi_clk_set_rate(struct clk *clk, ulong rate) + in, out); + int ret; + +- ret = devm_scmi_process_msg(clk->dev->parent, &msg); ++ ret = devm_scmi_process_msg(clk->dev, &msg); + if (ret < 0) + return ret; + +@@ -85,6 +134,49 @@ static ulong scmi_clk_set_rate(struct clk *clk, ulong rate) + return scmi_clk_get_rate(clk); + } + ++static int scmi_clk_probe(struct udevice *dev) ++{ ++ struct clk *clk; ++ size_t num_clocks, i; ++ int ret; ++ ++ if (!CONFIG_IS_ENABLED(CLK_CCF)) ++ return 0; ++ ++ /* register CCF children: CLK UCLASS, no probed again */ ++ if (device_get_uclass_id(dev->parent) == UCLASS_CLK) ++ return 0; ++ ++ ret = scmi_clk_get_num_clock(dev, &num_clocks); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < num_clocks; i++) { ++ char *name; ++ ++ if (!scmi_clk_get_attibute(dev, i, &name)) { ++ char *clock_name = strdup(name); ++ ++ clk = kzalloc(sizeof(*clk), GFP_KERNEL); ++ if (!clk || !clock_name) ++ ret = -ENOMEM; ++ else ++ ret = clk_register(clk, dev->driver->name, ++ clock_name, dev->name); ++ ++ if (ret) { ++ free(clk); ++ free(clock_name); ++ return ret; ++ } ++ ++ clk_dm(i, clk); ++ } ++ } ++ ++ return 0; ++} ++ + static const struct clk_ops scmi_clk_ops = { + .enable = scmi_clk_enable, + .disable = scmi_clk_disable, +@@ -96,4 +188,5 @@ U_BOOT_DRIVER(scmi_clock) = { + .name = "scmi_clk", + .id = UCLASS_CLK, + .ops = &scmi_clk_ops, ++ .probe = &scmi_clk_probe, + }; +diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c +index 114192bb32..a02921c43a 100644 +--- a/drivers/clk/clk_stm32mp1.c ++++ b/drivers/clk/clk_stm32mp1.c +@@ -27,12 +27,10 @@ + + DECLARE_GLOBAL_DATA_PTR; + +-#ifndef CONFIG_TFABOOT +-#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) ++#if defined(CONFIG_SPL_BUILD) + /* activate clock tree initialization in the driver */ + #define STM32MP1_CLOCK_TREE_INIT + #endif +-#endif + + #define MAX_HSI_HZ 64000000 + +@@ -964,6 +962,24 @@ static ulong stm32mp1_read_pll_freq(struct stm32mp1_clk_priv *priv, + return dfout; + } + ++static ulong stm32mp1_clk_get_by_name(const char *name) ++{ ++ struct clk clk; ++ struct udevice *dev = NULL; ++ ulong clock = 0; ++ ++ if (!uclass_get_device_by_name(UCLASS_CLK, name, &dev)) { ++ if (clk_request(dev, &clk)) { ++ log_err("%s request", name); ++ } else { ++ clk.id = 0; ++ clock = clk_get_rate(&clk); ++ } ++ } ++ ++ return clock; ++} ++ + static ulong stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p) + { + u32 reg; +@@ -1129,24 +1145,11 @@ static ulong stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p) + break; + /* other */ + case _USB_PHY_48: +- clock = 48000000; ++ clock = stm32mp1_clk_get_by_name("ck_usbo_48m"); + break; + case _DSI_PHY: +- { +- struct clk clk; +- struct udevice *dev = NULL; +- +- if (!uclass_get_device_by_name(UCLASS_CLK, "ck_dsi_phy", +- &dev)) { +- if (clk_request(dev, &clk)) { +- log_err("ck_dsi_phy request"); +- } else { +- clk.id = 0; +- clock = clk_get_rate(&clk); +- } +- } ++ clock = stm32mp1_clk_get_by_name("ck_dsi_phy"); + break; +- } + default: + break; + } +diff --git a/drivers/clk/stm32mp13_rcc.h b/drivers/clk/stm32mp13_rcc.h +new file mode 100644 +index 0000000000..61b2293a9b +--- /dev/null ++++ b/drivers/clk/stm32mp13_rcc.h +@@ -0,0 +1,1750 @@ ++/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ ++/* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ * ++ * Configuration settings for the STM32MP13x CPU ++ */ ++ ++#ifndef STM32MP13_RCC_H ++#define STM32MP13_RCC_H ++/* RCC registers */ ++#define RCC_SECCFGR 0x0 ++#define RCC_MP_SREQSETR 0x100 ++#define RCC_MP_SREQCLRR 0x104 ++#define RCC_MP_APRSTCR 0x108 ++#define RCC_MP_APRSTSR 0x10c ++#define RCC_PWRLPDLYCR 0x110 ++#define RCC_MP_GRSTCSETR 0x114 ++#define RCC_BR_RSTSCLRR 0x118 ++#define RCC_MP_RSTSSETR 0x11c ++#define RCC_MP_RSTSCLRR 0x120 ++#define RCC_MP_IWDGFZSETR 0x124 ++#define RCC_MP_IWDGFZCLRR 0x128 ++#define RCC_MP_CIER 0x200 ++#define RCC_MP_CIFR 0x204 ++#define RCC_BDCR 0x400 ++#define RCC_RDLSICR 0x404 ++#define RCC_OCENSETR 0x420 ++#define RCC_OCENCLRR 0x424 ++#define RCC_OCRDYR 0x428 ++#define RCC_HSICFGR 0x440 ++#define RCC_CSICFGR 0x444 ++#define RCC_MCO1CFGR 0x460 ++#define RCC_MCO2CFGR 0x464 ++#define RCC_DBGCFGR 0x468 ++#define RCC_RCK12SELR 0x480 ++#define RCC_RCK3SELR 0x484 ++#define RCC_RCK4SELR 0x488 ++#define RCC_PLL1CR 0x4a0 ++#define RCC_PLL1CFGR1 0x4a4 ++#define RCC_PLL1CFGR2 0x4a8 ++#define RCC_PLL1FRACR 0x4ac ++#define RCC_PLL1CSGR 0x4b0 ++#define RCC_PLL2CR 0x4d0 ++#define RCC_PLL2CFGR1 0x4d4 ++#define RCC_PLL2CFGR2 0x4d8 ++#define RCC_PLL2FRACR 0x4dc ++#define RCC_PLL2CSGR 0x4e0 ++#define RCC_PLL3CR 0x500 ++#define RCC_PLL3CFGR1 0x504 ++#define RCC_PLL3CFGR2 0x508 ++#define RCC_PLL3FRACR 0x50c ++#define RCC_PLL3CSGR 0x510 ++#define RCC_PLL4CR 0x520 ++#define RCC_PLL4CFGR1 0x524 ++#define RCC_PLL4CFGR2 0x528 ++#define RCC_PLL4FRACR 0x52c ++#define RCC_PLL4CSGR 0x530 ++#define RCC_MPCKSELR 0x540 ++#define RCC_ASSCKSELR 0x544 ++#define RCC_MSSCKSELR 0x548 ++#define RCC_CPERCKSELR 0x54c ++#define RCC_RTCDIVR 0x560 ++#define RCC_MPCKDIVR 0x564 ++#define RCC_AXIDIVR 0x568 ++#define RCC_MLAHBDIVR 0x56c ++#define RCC_APB1DIVR 0x570 ++#define RCC_APB2DIVR 0x574 ++#define RCC_APB3DIVR 0x578 ++#define RCC_APB4DIVR 0x57c ++#define RCC_APB5DIVR 0x580 ++#define RCC_APB6DIVR 0x584 ++#define RCC_TIMG1PRER 0x5a0 ++#define RCC_TIMG2PRER 0x5a4 ++#define RCC_TIMG3PRER 0x5a8 ++#define RCC_DDRITFCR 0x5c0 ++#define RCC_I2C12CKSELR 0x600 ++#define RCC_I2C345CKSELR 0x604 ++#define RCC_SPI2S1CKSELR 0x608 ++#define RCC_SPI2S23CKSELR 0x60c ++#define RCC_SPI45CKSELR 0x610 ++#define RCC_UART12CKSELR 0x614 ++#define RCC_UART35CKSELR 0x618 ++#define RCC_UART4CKSELR 0x61c ++#define RCC_UART6CKSELR 0x620 ++#define RCC_UART78CKSELR 0x624 ++#define RCC_LPTIM1CKSELR 0x628 ++#define RCC_LPTIM23CKSELR 0x62c ++#define RCC_LPTIM45CKSELR 0x630 ++#define RCC_SAI1CKSELR 0x634 ++#define RCC_SAI2CKSELR 0x638 ++#define RCC_FDCANCKSELR 0x63c ++#define RCC_SPDIFCKSELR 0x640 ++#define RCC_ADC12CKSELR 0x644 ++#define RCC_SDMMC12CKSELR 0x648 ++#define RCC_ETH12CKSELR 0x64c ++#define RCC_USBCKSELR 0x650 ++#define RCC_QSPICKSELR 0x654 ++#define RCC_FMCCKSELR 0x658 ++#define RCC_RNG1CKSELR 0x65c ++#define RCC_STGENCKSELR 0x660 ++#define RCC_DCMIPPCKSELR 0x664 ++#define RCC_SAESCKSELR 0x668 ++#define RCC_APB1RSTSETR 0x6a0 ++#define RCC_APB1RSTCLRR 0x6a4 ++#define RCC_APB2RSTSETR 0x6a8 ++#define RCC_APB2RSTCLRR 0x6ac ++#define RCC_APB3RSTSETR 0x6b0 ++#define RCC_APB3RSTCLRR 0x6b4 ++#define RCC_APB4RSTSETR 0x6b8 ++#define RCC_APB4RSTCLRR 0x6bc ++#define RCC_APB5RSTSETR 0x6c0 ++#define RCC_APB5RSTCLRR 0x6c4 ++#define RCC_APB6RSTSETR 0x6c8 ++#define RCC_APB6RSTCLRR 0x6cc ++#define RCC_AHB2RSTSETR 0x6d0 ++#define RCC_AHB2RSTCLRR 0x6d4 ++#define RCC_AHB4RSTSETR 0x6e0 ++#define RCC_AHB4RSTCLRR 0x6e4 ++#define RCC_AHB5RSTSETR 0x6e8 ++#define RCC_AHB5RSTCLRR 0x6ec ++#define RCC_AHB6RSTSETR 0x6f0 ++#define RCC_AHB6RSTCLRR 0x6f4 ++#define RCC_MP_APB1ENSETR 0x700 ++#define RCC_MP_APB1ENCLRR 0x704 ++#define RCC_MP_APB2ENSETR 0x708 ++#define RCC_MP_APB2ENCLRR 0x70c ++#define RCC_MP_APB3ENSETR 0x710 ++#define RCC_MP_APB3ENCLRR 0x714 ++#define RCC_MP_S_APB3ENSETR 0x718 ++#define RCC_MP_S_APB3ENCLRR 0x71c ++#define RCC_MP_NS_APB3ENSETR 0x720 ++#define RCC_MP_NS_APB3ENCLRR 0x724 ++#define RCC_MP_APB4ENSETR 0x728 ++#define RCC_MP_APB4ENCLRR 0x72c ++#define RCC_MP_S_APB4ENSETR 0x730 ++#define RCC_MP_S_APB4ENCLRR 0x734 ++#define RCC_MP_NS_APB4ENSETR 0x738 ++#define RCC_MP_NS_APB4ENCLRR 0x73c ++#define RCC_MP_APB5ENSETR 0x740 ++#define RCC_MP_APB5ENCLRR 0x744 ++#define RCC_MP_APB6ENSETR 0x748 ++#define RCC_MP_APB6ENCLRR 0x74c ++#define RCC_MP_AHB2ENSETR 0x750 ++#define RCC_MP_AHB2ENCLRR 0x754 ++#define RCC_MP_AHB4ENSETR 0x760 ++#define RCC_MP_AHB4ENCLRR 0x764 ++#define RCC_MP_S_AHB4ENSETR 0x768 ++#define RCC_MP_S_AHB4ENCLRR 0x76c ++#define RCC_MP_NS_AHB4ENSETR 0x770 ++#define RCC_MP_NS_AHB4ENCLRR 0x774 ++#define RCC_MP_AHB5ENSETR 0x778 ++#define RCC_MP_AHB5ENCLRR 0x77c ++#define RCC_MP_AHB6ENSETR 0x780 ++#define RCC_MP_AHB6ENCLRR 0x784 ++#define RCC_MP_S_AHB6ENSETR 0x788 ++#define RCC_MP_S_AHB6ENCLRR 0x78c ++#define RCC_MP_NS_AHB6ENSETR 0x790 ++#define RCC_MP_NS_AHB6ENCLRR 0x794 ++#define RCC_MP_APB1LPENSETR 0x800 ++#define RCC_MP_APB1LPENCLRR 0x804 ++#define RCC_MP_APB2LPENSETR 0x808 ++#define RCC_MP_APB2LPENCLRR 0x80c ++#define RCC_MP_APB3LPENSETR 0x810 ++#define RCC_MP_APB3LPENCLRR 0x814 ++#define RCC_MP_S_APB3LPENSETR 0x818 ++#define RCC_MP_S_APB3LPENCLRR 0x81c ++#define RCC_MP_NS_APB3LPENSETR 0x820 ++#define RCC_MP_NS_APB3LPENCLRR 0x824 ++#define RCC_MP_APB4LPENSETR 0x828 ++#define RCC_MP_APB4LPENCLRR 0x82c ++#define RCC_MP_S_APB4LPENSETR 0x830 ++#define RCC_MP_S_APB4LPENCLRR 0x834 ++#define RCC_MP_NS_APB4LPENSETR 0x838 ++#define RCC_MP_NS_APB4LPENCLRR 0x83c ++#define RCC_MP_APB5LPENSETR 0x840 ++#define RCC_MP_APB5LPENCLRR 0x844 ++#define RCC_MP_APB6LPENSETR 0x848 ++#define RCC_MP_APB6LPENCLRR 0x84c ++#define RCC_MP_AHB2LPENSETR 0x850 ++#define RCC_MP_AHB2LPENCLRR 0x854 ++#define RCC_MP_AHB4LPENSETR 0x858 ++#define RCC_MP_AHB4LPENCLRR 0x85c ++#define RCC_MP_S_AHB4LPENSETR 0x868 ++#define RCC_MP_S_AHB4LPENCLRR 0x86c ++#define RCC_MP_NS_AHB4LPENSETR 0x870 ++#define RCC_MP_NS_AHB4LPENCLRR 0x874 ++#define RCC_MP_AHB5LPENSETR 0x878 ++#define RCC_MP_AHB5LPENCLRR 0x87c ++#define RCC_MP_AHB6LPENSETR 0x880 ++#define RCC_MP_AHB6LPENCLRR 0x884 ++#define RCC_MP_S_AHB6LPENSETR 0x888 ++#define RCC_MP_S_AHB6LPENCLRR 0x88c ++#define RCC_MP_NS_AHB6LPENSETR 0x890 ++#define RCC_MP_NS_AHB6LPENCLRR 0x894 ++#define RCC_MP_S_AXIMLPENSETR 0x898 ++#define RCC_MP_S_AXIMLPENCLRR 0x89c ++#define RCC_MP_NS_AXIMLPENSETR 0x8a0 ++#define RCC_MP_NS_AXIMLPENCLRR 0x8a4 ++#define RCC_MP_MLAHBLPENSETR 0x8a8 ++#define RCC_MP_MLAHBLPENCLRR 0x8ac ++#define RCC_APB3SECSR 0x8c0 ++#define RCC_APB4SECSR 0x8c4 ++#define RCC_APB5SECSR 0x8c8 ++#define RCC_APB6SECSR 0x8cc ++#define RCC_AHB2SECSR 0x8d0 ++#define RCC_AHB4SECSR 0x8d4 ++#define RCC_AHB5SECSR 0x8d8 ++#define RCC_AHB6SECSR 0x8dc ++#define RCC_VERR 0xff4 ++#define RCC_IDR 0xff8 ++#define RCC_SIDR 0xffc ++ ++/* RCC_SECCFGR register fields */ ++#define RCC_SECCFGR_HSISEC BIT(0) ++#define RCC_SECCFGR_CSISEC BIT(1) ++#define RCC_SECCFGR_HSESEC BIT(2) ++#define RCC_SECCFGR_LSISEC BIT(3) ++#define RCC_SECCFGR_LSESEC BIT(4) ++#define RCC_SECCFGR_PLL12SEC BIT(8) ++#define RCC_SECCFGR_PLL3SEC BIT(9) ++#define RCC_SECCFGR_PLL4SEC BIT(10) ++#define RCC_SECCFGR_MPUSEC BIT(11) ++#define RCC_SECCFGR_AXISEC BIT(12) ++#define RCC_SECCFGR_MLAHBSEC BIT(13) ++#define RCC_SECCFGR_APB3DIVSEC BIT(16) ++#define RCC_SECCFGR_APB4DIVSEC BIT(17) ++#define RCC_SECCFGR_APB5DIVSEC BIT(18) ++#define RCC_SECCFGR_APB6DIVSEC BIT(19) ++#define RCC_SECCFGR_TIMG3SEC BIT(20) ++#define RCC_SECCFGR_CPERSEC BIT(21) ++#define RCC_SECCFGR_MCO1SEC BIT(22) ++#define RCC_SECCFGR_MCO2SEC BIT(23) ++#define RCC_SECCFGR_STPSEC BIT(24) ++#define RCC_SECCFGR_RSTSEC BIT(25) ++#define RCC_SECCFGR_PWRSEC BIT(31) ++ ++#define RCC_SECCFGR_MCO1SECF 22 ++#define RCC_SECCFGR_MCO2SECF 23 ++ ++/* RCC_MP_SREQSETR register fields */ ++#define RCC_MP_SREQSETR_STPREQ_P0 BIT(0) ++ ++/* RCC_MP_SREQCLRR register fields */ ++#define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0) ++ ++/* RCC_MP_APRSTCR register fields */ ++#define RCC_MP_APRSTCR_RDCTLEN BIT(0) ++#define RCC_MP_APRSTCR_RSTTO_MASK GENMASK(14, 8) ++#define RCC_MP_APRSTCR_RSTTO_SHIFT 8 ++ ++/* RCC_MP_APRSTSR register fields */ ++#define RCC_MP_APRSTSR_RSTTOV_MASK GENMASK(14, 8) ++#define RCC_MP_APRSTSR_RSTTOV_SHIFT 8 ++ ++/* RCC_PWRLPDLYCR register fields */ ++#define RCC_PWRLPDLYCR_PWRLP_DLY_MASK GENMASK(21, 0) ++#define RCC_PWRLPDLYCR_PWRLP_DLY_SHIFT 0 ++ ++/* RCC_MP_GRSTCSETR register fields */ ++#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0) ++#define RCC_MP_GRSTCSETR_MPUP0RST BIT(4) ++ ++/* RCC_BR_RSTSCLRR register fields */ ++#define RCC_BR_RSTSCLRR_PORRSTF BIT(0) ++#define RCC_BR_RSTSCLRR_BORRSTF BIT(1) ++#define RCC_BR_RSTSCLRR_PADRSTF BIT(2) ++#define RCC_BR_RSTSCLRR_HCSSRSTF BIT(3) ++#define RCC_BR_RSTSCLRR_VCORERSTF BIT(4) ++#define RCC_BR_RSTSCLRR_VCPURSTF BIT(5) ++#define RCC_BR_RSTSCLRR_MPSYSRSTF BIT(6) ++#define RCC_BR_RSTSCLRR_IWDG1RSTF BIT(8) ++#define RCC_BR_RSTSCLRR_IWDG2RSTF BIT(9) ++#define RCC_BR_RSTSCLRR_MPUP0RSTF BIT(13) ++ ++/* RCC_MP_RSTSSETR register fields */ ++#define RCC_MP_RSTSSETR_PORRSTF BIT(0) ++#define RCC_MP_RSTSSETR_BORRSTF BIT(1) ++#define RCC_MP_RSTSSETR_PADRSTF BIT(2) ++#define RCC_MP_RSTSSETR_HCSSRSTF BIT(3) ++#define RCC_MP_RSTSSETR_VCORERSTF BIT(4) ++#define RCC_MP_RSTSSETR_VCPURSTF BIT(5) ++#define RCC_MP_RSTSSETR_MPSYSRSTF BIT(6) ++#define RCC_MP_RSTSSETR_IWDG1RSTF BIT(8) ++#define RCC_MP_RSTSSETR_IWDG2RSTF BIT(9) ++#define RCC_MP_RSTSSETR_STP2RSTF BIT(10) ++#define RCC_MP_RSTSSETR_STDBYRSTF BIT(11) ++#define RCC_MP_RSTSSETR_CSTDBYRSTF BIT(12) ++#define RCC_MP_RSTSSETR_MPUP0RSTF BIT(13) ++#define RCC_MP_RSTSSETR_SPARE BIT(15) ++ ++/* RCC_MP_RSTSCLRR register fields */ ++#define RCC_MP_RSTSCLRR_PORRSTF BIT(0) ++#define RCC_MP_RSTSCLRR_BORRSTF BIT(1) ++#define RCC_MP_RSTSCLRR_PADRSTF BIT(2) ++#define RCC_MP_RSTSCLRR_HCSSRSTF BIT(3) ++#define RCC_MP_RSTSCLRR_VCORERSTF BIT(4) ++#define RCC_MP_RSTSCLRR_VCPURSTF BIT(5) ++#define RCC_MP_RSTSCLRR_MPSYSRSTF BIT(6) ++#define RCC_MP_RSTSCLRR_IWDG1RSTF BIT(8) ++#define RCC_MP_RSTSCLRR_IWDG2RSTF BIT(9) ++#define RCC_MP_RSTSCLRR_STP2RSTF BIT(10) ++#define RCC_MP_RSTSCLRR_STDBYRSTF BIT(11) ++#define RCC_MP_RSTSCLRR_CSTDBYRSTF BIT(12) ++#define RCC_MP_RSTSCLRR_MPUP0RSTF BIT(13) ++#define RCC_MP_RSTSCLRR_SPARE BIT(15) ++ ++/* RCC_MP_IWDGFZSETR register fields */ ++#define RCC_MP_IWDGFZSETR_FZ_IWDG1 BIT(0) ++#define RCC_MP_IWDGFZSETR_FZ_IWDG2 BIT(1) ++ ++/* RCC_MP_IWDGFZCLRR register fields */ ++#define RCC_MP_IWDGFZCLRR_FZ_IWDG1 BIT(0) ++#define RCC_MP_IWDGFZCLRR_FZ_IWDG2 BIT(1) ++ ++/* RCC_MP_CIER register fields */ ++#define RCC_MP_CIER_LSIRDYIE BIT(0) ++#define RCC_MP_CIER_LSERDYIE BIT(1) ++#define RCC_MP_CIER_HSIRDYIE BIT(2) ++#define RCC_MP_CIER_HSERDYIE BIT(3) ++#define RCC_MP_CIER_CSIRDYIE BIT(4) ++#define RCC_MP_CIER_PLL1DYIE BIT(8) ++#define RCC_MP_CIER_PLL2DYIE BIT(9) ++#define RCC_MP_CIER_PLL3DYIE BIT(10) ++#define RCC_MP_CIER_PLL4DYIE BIT(11) ++#define RCC_MP_CIER_LSECSSIE BIT(16) ++#define RCC_MP_CIER_WKUPIE BIT(20) ++ ++/* RCC_MP_CIFR register fields */ ++#define RCC_MP_CIFR_LSIRDYF BIT(0) ++#define RCC_MP_CIFR_LSERDYF BIT(1) ++#define RCC_MP_CIFR_HSIRDYF BIT(2) ++#define RCC_MP_CIFR_HSERDYF BIT(3) ++#define RCC_MP_CIFR_CSIRDYF BIT(4) ++#define RCC_MP_CIFR_PLL1DYF BIT(8) ++#define RCC_MP_CIFR_PLL2DYF BIT(9) ++#define RCC_MP_CIFR_PLL3DYF BIT(10) ++#define RCC_MP_CIFR_PLL4DYF BIT(11) ++#define RCC_MP_CIFR_LSECSSF BIT(16) ++#define RCC_MP_CIFR_WKUPF BIT(20) ++ ++/* RCC_BDCR register fields */ ++#define RCC_BDCR_LSEON BIT(0) ++#define RCC_BDCR_LSEBYP BIT(1) ++#define RCC_BDCR_LSERDY BIT(2) ++#define RCC_BDCR_DIGBYP BIT(3) ++#define RCC_BDCR_LSEDRV_MASK GENMASK(5, 4) ++#define RCC_BDCR_LSECSSON BIT(8) ++#define RCC_BDCR_LSECSSD BIT(9) ++#define RCC_BDCR_RTCSRC_MASK GENMASK(17, 16) ++#define RCC_BDCR_RTCCKEN BIT(20) ++#define RCC_BDCR_VSWRST BIT(31) ++#define RCC_BDCR_LSEDRV_SHIFT 4 ++#define RCC_BDCR_RTCSRC_SHIFT 16 ++ ++/* RCC_RDLSICR register fields */ ++#define RCC_RDLSICR_LSION BIT(0) ++#define RCC_RDLSICR_LSIRDY BIT(1) ++#define RCC_RDLSICR_MRD_MASK GENMASK(20, 16) ++#define RCC_RDLSICR_EADLY_MASK GENMASK(26, 24) ++#define RCC_RDLSICR_SPARE_MASK GENMASK(31, 27) ++#define RCC_RDLSICR_MRD_SHIFT 16 ++#define RCC_RDLSICR_EADLY_SHIFT 24 ++#define RCC_RDLSICR_SPARE_SHIFT 27 ++ ++/* RCC_OCENSETR register fields */ ++#define RCC_OCENSETR_HSION BIT(0) ++#define RCC_OCENSETR_HSIKERON BIT(1) ++#define RCC_OCENSETR_CSION BIT(4) ++#define RCC_OCENSETR_CSIKERON BIT(5) ++#define RCC_OCENSETR_DIGBYP BIT(7) ++#define RCC_OCENSETR_HSEON BIT(8) ++#define RCC_OCENSETR_HSEKERON BIT(9) ++#define RCC_OCENSETR_HSEBYP BIT(10) ++#define RCC_OCENSETR_HSECSSON BIT(11) ++ ++/* RCC_OCENCLRR register fields */ ++#define RCC_OCENCLRR_HSION BIT(0) ++#define RCC_OCENCLRR_HSIKERON BIT(1) ++#define RCC_OCENCLRR_CSION BIT(4) ++#define RCC_OCENCLRR_CSIKERON BIT(5) ++#define RCC_OCENCLRR_DIGBYP BIT(7) ++#define RCC_OCENCLRR_HSEON BIT(8) ++#define RCC_OCENCLRR_HSEKERON BIT(9) ++#define RCC_OCENCLRR_HSEBYP BIT(10) ++ ++/* RCC_OCRDYR register fields */ ++#define RCC_OCRDYR_HSIRDY BIT(0) ++#define RCC_OCRDYR_HSIDIVRDY BIT(2) ++#define RCC_OCRDYR_CSIRDY BIT(4) ++#define RCC_OCRDYR_HSERDY BIT(8) ++#define RCC_OCRDYR_MPUCKRDY BIT(23) ++#define RCC_OCRDYR_AXICKRDY BIT(24) ++ ++/* RCC_HSICFGR register fields */ ++#define RCC_HSICFGR_HSIDIV_MASK GENMASK(1, 0) ++#define RCC_HSICFGR_HSITRIM_MASK GENMASK(14, 8) ++#define RCC_HSICFGR_HSICAL_MASK GENMASK(27, 16) ++#define RCC_HSICFGR_HSIDIV_SHIFT 0 ++#define RCC_HSICFGR_HSITRIM_SHIFT 8 ++#define RCC_HSICFGR_HSICAL_SHIFT 16 ++ ++/* RCC_CSICFGR register fields */ ++#define RCC_CSICFGR_CSITRIM_MASK GENMASK(12, 8) ++#define RCC_CSICFGR_CSICAL_MASK GENMASK(23, 16) ++#define RCC_CSICFGR_CSITRIM_SHIFT 8 ++#define RCC_CSICFGR_CSICAL_SHIFT 16 ++ ++/* RCC_MCO1CFGR register fields */ ++#define RCC_MCO1CFGR_MCO1SEL_MASK GENMASK(2, 0) ++#define RCC_MCO1CFGR_MCO1DIV_MASK GENMASK(7, 4) ++#define RCC_MCO1CFGR_MCO1ON BIT(12) ++#define RCC_MCO1CFGR_MCO1SEL_SHIFT 0 ++#define RCC_MCO1CFGR_MCO1DIV_SHIFT 4 ++ ++/* RCC_MCO2CFGR register fields */ ++#define RCC_MCO2CFGR_MCO2SEL_MASK GENMASK(2, 0) ++#define RCC_MCO2CFGR_MCO2DIV_MASK GENMASK(7, 4) ++#define RCC_MCO2CFGR_MCO2ON BIT(12) ++#define RCC_MCO2CFGR_MCO2SEL_SHIFT 0 ++#define RCC_MCO2CFGR_MCO2DIV_SHIFT 4 ++ ++/* RCC_DBGCFGR register fields */ ++#define RCC_DBGCFGR_TRACEDIV_MASK GENMASK(2, 0) ++#define RCC_DBGCFGR_DBGCKEN BIT(8) ++#define RCC_DBGCFGR_TRACECKEN BIT(9) ++#define RCC_DBGCFGR_DBGRST BIT(12) ++#define RCC_DBGCFGR_TRACEDIV_SHIFT 0 ++ ++/* RCC_RCK12SELR register fields */ ++#define RCC_RCK12SELR_PLL12SRC_MASK GENMASK(1, 0) ++#define RCC_RCK12SELR_PLL12SRCRDY BIT(31) ++#define RCC_RCK12SELR_PLL12SRC_SHIFT 0 ++ ++/* RCC_RCK3SELR register fields */ ++#define RCC_RCK3SELR_PLL3SRC_MASK GENMASK(1, 0) ++#define RCC_RCK3SELR_PLL3SRCRDY BIT(31) ++#define RCC_RCK3SELR_PLL3SRC_SHIFT 0 ++ ++/* RCC_RCK4SELR register fields */ ++#define RCC_RCK4SELR_PLL4SRC_MASK GENMASK(1, 0) ++#define RCC_RCK4SELR_PLL4SRCRDY BIT(31) ++#define RCC_RCK4SELR_PLL4SRC_SHIFT 0 ++ ++/* RCC_PLL1CR register fields */ ++#define RCC_PLL1CR_PLLON BIT(0) ++#define RCC_PLL1CR_PLL1RDY BIT(1) ++#define RCC_PLL1CR_SSCG_CTRL BIT(2) ++#define RCC_PLL1CR_DIVPEN BIT(4) ++#define RCC_PLL1CR_DIVQEN BIT(5) ++#define RCC_PLL1CR_DIVREN BIT(6) ++ ++/* RCC_PLL1CFGR1 register fields */ ++#define RCC_PLL1CFGR1_DIVN_MASK GENMASK(8, 0) ++#define RCC_PLL1CFGR1_DIVM1_MASK GENMASK(21, 16) ++#define RCC_PLL1CFGR1_DIVN_SHIFT 0 ++#define RCC_PLL1CFGR1_DIVM1_SHIFT 16 ++ ++/* RCC_PLL1CFGR2 register fields */ ++#define RCC_PLL1CFGR2_DIVP_MASK GENMASK(6, 0) ++#define RCC_PLL1CFGR2_DIVQ_MASK GENMASK(14, 8) ++#define RCC_PLL1CFGR2_DIVR_MASK GENMASK(22, 16) ++#define RCC_PLL1CFGR2_DIVP_SHIFT 0 ++#define RCC_PLL1CFGR2_DIVQ_SHIFT 8 ++#define RCC_PLL1CFGR2_DIVR_SHIFT 16 ++ ++/* RCC_PLL1FRACR register fields */ ++#define RCC_PLL1FRACR_FRACV_MASK GENMASK(15, 3) ++#define RCC_PLL1FRACR_FRACLE BIT(16) ++#define RCC_PLL1FRACR_FRACV_SHIFT 3 ++ ++/* RCC_PLL1CSGR register fields */ ++#define RCC_PLL1CSGR_MOD_PER_MASK GENMASK(12, 0) ++#define RCC_PLL1CSGR_TPDFN_DIS BIT(13) ++#define RCC_PLL1CSGR_RPDFN_DIS BIT(14) ++#define RCC_PLL1CSGR_SSCG_MODE BIT(15) ++#define RCC_PLL1CSGR_INC_STEP_MASK GENMASK(30, 16) ++#define RCC_PLL1CSGR_MOD_PER_SHIFT 0 ++#define RCC_PLL1CSGR_INC_STEP_SHIFT 16 ++ ++/* RCC_PLL2CR register fields */ ++#define RCC_PLL2CR_PLLON BIT(0) ++#define RCC_PLL2CR_PLL2RDY BIT(1) ++#define RCC_PLL2CR_SSCG_CTRL BIT(2) ++#define RCC_PLL2CR_DIVPEN BIT(4) ++#define RCC_PLL2CR_DIVQEN BIT(5) ++#define RCC_PLL2CR_DIVREN BIT(6) ++ ++/* RCC_PLL2CFGR1 register fields */ ++#define RCC_PLL2CFGR1_DIVN_MASK GENMASK(8, 0) ++#define RCC_PLL2CFGR1_DIVM2_MASK GENMASK(21, 16) ++#define RCC_PLL2CFGR1_DIVN_SHIFT 0 ++#define RCC_PLL2CFGR1_DIVM2_SHIFT 16 ++ ++/* RCC_PLL2CFGR2 register fields */ ++#define RCC_PLL2CFGR2_DIVP_MASK GENMASK(6, 0) ++#define RCC_PLL2CFGR2_DIVQ_MASK GENMASK(14, 8) ++#define RCC_PLL2CFGR2_DIVR_MASK GENMASK(22, 16) ++#define RCC_PLL2CFGR2_DIVP_SHIFT 0 ++#define RCC_PLL2CFGR2_DIVQ_SHIFT 8 ++#define RCC_PLL2CFGR2_DIVR_SHIFT 16 ++ ++/* RCC_PLL2FRACR register fields */ ++#define RCC_PLL2FRACR_FRACV_MASK GENMASK(15, 3) ++#define RCC_PLL2FRACR_FRACLE BIT(16) ++#define RCC_PLL2FRACR_FRACV_SHIFT 3 ++ ++/* RCC_PLL2CSGR register fields */ ++#define RCC_PLL2CSGR_MOD_PER_MASK GENMASK(12, 0) ++#define RCC_PLL2CSGR_TPDFN_DIS BIT(13) ++#define RCC_PLL2CSGR_RPDFN_DIS BIT(14) ++#define RCC_PLL2CSGR_SSCG_MODE BIT(15) ++#define RCC_PLL2CSGR_INC_STEP_MASK GENMASK(30, 16) ++#define RCC_PLL2CSGR_MOD_PER_SHIFT 0 ++#define RCC_PLL2CSGR_INC_STEP_SHIFT 16 ++ ++/* RCC_PLL3CR register fields */ ++#define RCC_PLL3CR_PLLON BIT(0) ++#define RCC_PLL3CR_PLL3RDY BIT(1) ++#define RCC_PLL3CR_SSCG_CTRL BIT(2) ++#define RCC_PLL3CR_DIVPEN BIT(4) ++#define RCC_PLL3CR_DIVQEN BIT(5) ++#define RCC_PLL3CR_DIVREN BIT(6) ++ ++/* RCC_PLL3CFGR1 register fields */ ++#define RCC_PLL3CFGR1_DIVN_MASK GENMASK(8, 0) ++#define RCC_PLL3CFGR1_DIVM3_MASK GENMASK(21, 16) ++#define RCC_PLL3CFGR1_IFRGE_MASK GENMASK(25, 24) ++#define RCC_PLL3CFGR1_DIVN_SHIFT 0 ++#define RCC_PLL3CFGR1_DIVM3_SHIFT 16 ++#define RCC_PLL3CFGR1_IFRGE_SHIFT 24 ++ ++/* RCC_PLL3CFGR2 register fields */ ++#define RCC_PLL3CFGR2_DIVP_MASK GENMASK(6, 0) ++#define RCC_PLL3CFGR2_DIVQ_MASK GENMASK(14, 8) ++#define RCC_PLL3CFGR2_DIVR_MASK GENMASK(22, 16) ++#define RCC_PLL3CFGR2_DIVP_SHIFT 0 ++#define RCC_PLL3CFGR2_DIVQ_SHIFT 8 ++#define RCC_PLL3CFGR2_DIVR_SHIFT 16 ++ ++/* RCC_PLL3FRACR register fields */ ++#define RCC_PLL3FRACR_FRACV_MASK GENMASK(15, 3) ++#define RCC_PLL3FRACR_FRACLE BIT(16) ++#define RCC_PLL3FRACR_FRACV_SHIFT 3 ++ ++/* RCC_PLL3CSGR register fields */ ++#define RCC_PLL3CSGR_MOD_PER_MASK GENMASK(12, 0) ++#define RCC_PLL3CSGR_TPDFN_DIS BIT(13) ++#define RCC_PLL3CSGR_RPDFN_DIS BIT(14) ++#define RCC_PLL3CSGR_SSCG_MODE BIT(15) ++#define RCC_PLL3CSGR_INC_STEP_MASK GENMASK(30, 16) ++#define RCC_PLL3CSGR_MOD_PER_SHIFT 0 ++#define RCC_PLL3CSGR_INC_STEP_SHIFT 16 ++ ++/* RCC_PLL4CR register fields */ ++#define RCC_PLL4CR_PLLON BIT(0) ++#define RCC_PLL4CR_PLL4RDY BIT(1) ++#define RCC_PLL4CR_SSCG_CTRL BIT(2) ++#define RCC_PLL4CR_DIVPEN BIT(4) ++#define RCC_PLL4CR_DIVQEN BIT(5) ++#define RCC_PLL4CR_DIVREN BIT(6) ++ ++/* RCC_PLL4CFGR1 register fields */ ++#define RCC_PLL4CFGR1_DIVN_MASK GENMASK(8, 0) ++#define RCC_PLL4CFGR1_DIVM4_MASK GENMASK(21, 16) ++#define RCC_PLL4CFGR1_IFRGE_MASK GENMASK(25, 24) ++#define RCC_PLL4CFGR1_DIVN_SHIFT 0 ++#define RCC_PLL4CFGR1_DIVM4_SHIFT 16 ++#define RCC_PLL4CFGR1_IFRGE_SHIFT 24 ++ ++/* RCC_PLL4CFGR2 register fields */ ++#define RCC_PLL4CFGR2_DIVP_MASK GENMASK(6, 0) ++#define RCC_PLL4CFGR2_DIVQ_MASK GENMASK(14, 8) ++#define RCC_PLL4CFGR2_DIVR_MASK GENMASK(22, 16) ++#define RCC_PLL4CFGR2_DIVP_SHIFT 0 ++#define RCC_PLL4CFGR2_DIVQ_SHIFT 8 ++#define RCC_PLL4CFGR2_DIVR_SHIFT 16 ++ ++/* RCC_PLL4FRACR register fields */ ++#define RCC_PLL4FRACR_FRACV_MASK GENMASK(15, 3) ++#define RCC_PLL4FRACR_FRACLE BIT(16) ++#define RCC_PLL4FRACR_FRACV_SHIFT 3 ++ ++/* RCC_PLL4CSGR register fields */ ++#define RCC_PLL4CSGR_MOD_PER_MASK GENMASK(12, 0) ++#define RCC_PLL4CSGR_TPDFN_DIS BIT(13) ++#define RCC_PLL4CSGR_RPDFN_DIS BIT(14) ++#define RCC_PLL4CSGR_SSCG_MODE BIT(15) ++#define RCC_PLL4CSGR_INC_STEP_MASK GENMASK(30, 16) ++#define RCC_PLL4CSGR_MOD_PER_SHIFT 0 ++#define RCC_PLL4CSGR_INC_STEP_SHIFT 16 ++ ++/* RCC_MPCKSELR register fields */ ++#define RCC_MPCKSELR_MPUSRC_MASK GENMASK(1, 0) ++#define RCC_MPCKSELR_MPUSRCRDY BIT(31) ++#define RCC_MPCKSELR_MPUSRC_SHIFT 0 ++ ++/* RCC_ASSCKSELR register fields */ ++#define RCC_ASSCKSELR_AXISSRC_MASK GENMASK(2, 0) ++#define RCC_ASSCKSELR_AXISSRCRDY BIT(31) ++#define RCC_ASSCKSELR_AXISSRC_SHIFT 0 ++ ++/* RCC_MSSCKSELR register fields */ ++#define RCC_MSSCKSELR_MLAHBSSRC_MASK GENMASK(1, 0) ++#define RCC_MSSCKSELR_MLAHBSSRCRDY BIT(31) ++#define RCC_MSSCKSELR_MLAHBSSRC_SHIFT 0 ++ ++/* RCC_CPERCKSELR register fields */ ++#define RCC_CPERCKSELR_CKPERSRC_MASK GENMASK(1, 0) ++#define RCC_CPERCKSELR_CKPERSRC_SHIFT 0 ++ ++/* RCC_RTCDIVR register fields */ ++#define RCC_RTCDIVR_RTCDIV_MASK GENMASK(5, 0) ++#define RCC_RTCDIVR_RTCDIV_SHIFT 0 ++ ++/* RCC_MPCKDIVR register fields */ ++#define RCC_MPCKDIVR_MPUDIV_MASK GENMASK(3, 0) ++#define RCC_MPCKDIVR_MPUDIVRDY BIT(31) ++#define RCC_MPCKDIVR_MPUDIV_SHIFT 0 ++ ++/* RCC_AXIDIVR register fields */ ++#define RCC_AXIDIVR_AXIDIV_MASK GENMASK(2, 0) ++#define RCC_AXIDIVR_AXIDIVRDY BIT(31) ++#define RCC_AXIDIVR_AXIDIV_SHIFT 0 ++ ++/* RCC_MLAHBDIVR register fields */ ++#define RCC_MLAHBDIVR_MLAHBDIV_MASK GENMASK(3, 0) ++#define RCC_MLAHBDIVR_MLAHBDIVRDY BIT(31) ++#define RCC_MLAHBDIVR_MLAHBDIV_SHIFT 0 ++ ++/* RCC_APB1DIVR register fields */ ++#define RCC_APB1DIVR_APB1DIV_MASK GENMASK(2, 0) ++#define RCC_APB1DIVR_APB1DIVRDY BIT(31) ++#define RCC_APB1DIVR_APB1DIV_SHIFT 0 ++ ++/* RCC_APB2DIVR register fields */ ++#define RCC_APB2DIVR_APB2DIV_MASK GENMASK(2, 0) ++#define RCC_APB2DIVR_APB2DIVRDY BIT(31) ++#define RCC_APB2DIVR_APB2DIV_SHIFT 0 ++ ++/* RCC_APB3DIVR register fields */ ++#define RCC_APB3DIVR_APB3DIV_MASK GENMASK(2, 0) ++#define RCC_APB3DIVR_APB3DIVRDY BIT(31) ++#define RCC_APB3DIVR_APB3DIV_SHIFT 0 ++ ++/* RCC_APB4DIVR register fields */ ++#define RCC_APB4DIVR_APB4DIV_MASK GENMASK(2, 0) ++#define RCC_APB4DIVR_APB4DIVRDY BIT(31) ++#define RCC_APB4DIVR_APB4DIV_SHIFT 0 ++ ++/* RCC_APB5DIVR register fields */ ++#define RCC_APB5DIVR_APB5DIV_MASK GENMASK(2, 0) ++#define RCC_APB5DIVR_APB5DIVRDY BIT(31) ++#define RCC_APB5DIVR_APB5DIV_SHIFT 0 ++ ++/* RCC_APB6DIVR register fields */ ++#define RCC_APB6DIVR_APB6DIV_MASK GENMASK(2, 0) ++#define RCC_APB6DIVR_APB6DIVRDY BIT(31) ++#define RCC_APB6DIVR_APB6DIV_SHIFT 0 ++ ++/* RCC_TIMG1PRER register fields */ ++#define RCC_TIMG1PRER_TIMG1PRE BIT(0) ++#define RCC_TIMG1PRER_TIMG1PRERDY BIT(31) ++ ++/* RCC_TIMG2PRER register fields */ ++#define RCC_TIMG2PRER_TIMG2PRE BIT(0) ++#define RCC_TIMG2PRER_TIMG2PRERDY BIT(31) ++ ++/* RCC_TIMG3PRER register fields */ ++#define RCC_TIMG3PRER_TIMG3PRE BIT(0) ++#define RCC_TIMG3PRER_TIMG3PRERDY BIT(31) ++ ++/* RCC_DDRITFCR register fields */ ++#define RCC_DDRITFCR_DDRC1EN BIT(0) ++#define RCC_DDRITFCR_DDRC1LPEN BIT(1) ++#define RCC_DDRITFCR_DDRPHYCEN BIT(4) ++#define RCC_DDRITFCR_DDRPHYCLPEN BIT(5) ++#define RCC_DDRITFCR_DDRCAPBEN BIT(6) ++#define RCC_DDRITFCR_DDRCAPBLPEN BIT(7) ++#define RCC_DDRITFCR_AXIDCGEN BIT(8) ++#define RCC_DDRITFCR_DDRPHYCAPBEN BIT(9) ++#define RCC_DDRITFCR_DDRPHYCAPBLPEN BIT(10) ++#define RCC_DDRITFCR_KERDCG_DLY_MASK GENMASK(13, 11) ++#define RCC_DDRITFCR_DDRCAPBRST BIT(14) ++#define RCC_DDRITFCR_DDRCAXIRST BIT(15) ++#define RCC_DDRITFCR_DDRCORERST BIT(16) ++#define RCC_DDRITFCR_DPHYAPBRST BIT(17) ++#define RCC_DDRITFCR_DPHYRST BIT(18) ++#define RCC_DDRITFCR_DPHYCTLRST BIT(19) ++#define RCC_DDRITFCR_DDRCKMOD_MASK GENMASK(22, 20) ++#define RCC_DDRITFCR_GSKPMOD BIT(23) ++#define RCC_DDRITFCR_GSKPCTRL BIT(24) ++#define RCC_DDRITFCR_DFILP_WIDTH_MASK GENMASK(27, 25) ++#define RCC_DDRITFCR_GSKP_DUR_MASK GENMASK(31, 28) ++#define RCC_DDRITFCR_KERDCG_DLY_SHIFT 11 ++#define RCC_DDRITFCR_DDRCKMOD_SHIFT 20 ++#define RCC_DDRITFCR_DFILP_WIDTH_SHIFT 25 ++#define RCC_DDRITFCR_GSKP_DUR_SHIFT 28 ++ ++/* RCC_I2C12CKSELR register fields */ ++#define RCC_I2C12CKSELR_I2C12SRC_MASK GENMASK(2, 0) ++#define RCC_I2C12CKSELR_I2C12SRC_SHIFT 0 ++ ++/* RCC_I2C345CKSELR register fields */ ++#define RCC_I2C345CKSELR_I2C3SRC_MASK GENMASK(2, 0) ++#define RCC_I2C345CKSELR_I2C4SRC_MASK GENMASK(5, 3) ++#define RCC_I2C345CKSELR_I2C5SRC_MASK GENMASK(8, 6) ++#define RCC_I2C345CKSELR_I2C3SRC_SHIFT 0 ++#define RCC_I2C345CKSELR_I2C4SRC_SHIFT 3 ++#define RCC_I2C345CKSELR_I2C5SRC_SHIFT 6 ++ ++/* RCC_SPI2S1CKSELR register fields */ ++#define RCC_SPI2S1CKSELR_SPI1SRC_MASK GENMASK(2, 0) ++#define RCC_SPI2S1CKSELR_SPI1SRC_SHIFT 0 ++ ++/* RCC_SPI2S23CKSELR register fields */ ++#define RCC_SPI2S23CKSELR_SPI23SRC_MASK GENMASK(2, 0) ++#define RCC_SPI2S23CKSELR_SPI23SRC_SHIFT 0 ++ ++/* RCC_SPI45CKSELR register fields */ ++#define RCC_SPI45CKSELR_SPI4SRC_MASK GENMASK(2, 0) ++#define RCC_SPI45CKSELR_SPI5SRC_MASK GENMASK(5, 3) ++#define RCC_SPI45CKSELR_SPI4SRC_SHIFT 0 ++#define RCC_SPI45CKSELR_SPI5SRC_SHIFT 3 ++ ++/* RCC_UART12CKSELR register fields */ ++#define RCC_UART12CKSELR_UART1SRC_MASK GENMASK(2, 0) ++#define RCC_UART12CKSELR_UART2SRC_MASK GENMASK(5, 3) ++#define RCC_UART12CKSELR_UART1SRC_SHIFT 0 ++#define RCC_UART12CKSELR_UART2SRC_SHIFT 3 ++ ++/* RCC_UART35CKSELR register fields */ ++#define RCC_UART35CKSELR_UART35SRC_MASK GENMASK(2, 0) ++#define RCC_UART35CKSELR_UART35SRC_SHIFT 0 ++ ++/* RCC_UART4CKSELR register fields */ ++#define RCC_UART4CKSELR_UART4SRC_MASK GENMASK(2, 0) ++#define RCC_UART4CKSELR_UART4SRC_SHIFT 0 ++ ++/* RCC_UART6CKSELR register fields */ ++#define RCC_UART6CKSELR_UART6SRC_MASK GENMASK(2, 0) ++#define RCC_UART6CKSELR_UART6SRC_SHIFT 0 ++ ++/* RCC_UART78CKSELR register fields */ ++#define RCC_UART78CKSELR_UART78SRC_MASK GENMASK(2, 0) ++#define RCC_UART78CKSELR_UART78SRC_SHIFT 0 ++ ++/* RCC_LPTIM1CKSELR register fields */ ++#define RCC_LPTIM1CKSELR_LPTIM1SRC_MASK GENMASK(2, 0) ++#define RCC_LPTIM1CKSELR_LPTIM1SRC_SHIFT 0 ++ ++/* RCC_LPTIM23CKSELR register fields */ ++#define RCC_LPTIM23CKSELR_LPTIM2SRC_MASK GENMASK(2, 0) ++#define RCC_LPTIM23CKSELR_LPTIM3SRC_MASK GENMASK(5, 3) ++#define RCC_LPTIM23CKSELR_LPTIM2SRC_SHIFT 0 ++#define RCC_LPTIM23CKSELR_LPTIM3SRC_SHIFT 3 ++ ++/* RCC_LPTIM45CKSELR register fields */ ++#define RCC_LPTIM45CKSELR_LPTIM45SRC_MASK GENMASK(2, 0) ++#define RCC_LPTIM45CKSELR_LPTIM45SRC_SHIFT 0 ++ ++/* RCC_SAI1CKSELR register fields */ ++#define RCC_SAI1CKSELR_SAI1SRC_MASK GENMASK(2, 0) ++#define RCC_SAI1CKSELR_SAI1SRC_SHIFT 0 ++ ++/* RCC_SAI2CKSELR register fields */ ++#define RCC_SAI2CKSELR_SAI2SRC_MASK GENMASK(2, 0) ++#define RCC_SAI2CKSELR_SAI2SRC_SHIFT 0 ++ ++/* RCC_FDCANCKSELR register fields */ ++#define RCC_FDCANCKSELR_FDCANSRC_MASK GENMASK(1, 0) ++#define RCC_FDCANCKSELR_FDCANSRC_SHIFT 0 ++ ++/* RCC_SPDIFCKSELR register fields */ ++#define RCC_SPDIFCKSELR_SPDIFSRC_MASK GENMASK(1, 0) ++#define RCC_SPDIFCKSELR_SPDIFSRC_SHIFT 0 ++ ++/* RCC_ADC12CKSELR register fields */ ++#define RCC_ADC12CKSELR_ADC1SRC_MASK GENMASK(1, 0) ++#define RCC_ADC12CKSELR_ADC2SRC_MASK GENMASK(3, 2) ++#define RCC_ADC12CKSELR_ADC1SRC_SHIFT 0 ++#define RCC_ADC12CKSELR_ADC2SRC_SHIFT 2 ++ ++/* RCC_SDMMC12CKSELR register fields */ ++#define RCC_SDMMC12CKSELR_SDMMC1SRC_MASK GENMASK(2, 0) ++#define RCC_SDMMC12CKSELR_SDMMC2SRC_MASK GENMASK(5, 3) ++#define RCC_SDMMC12CKSELR_SDMMC1SRC_SHIFT 0 ++#define RCC_SDMMC12CKSELR_SDMMC2SRC_SHIFT 3 ++ ++/* RCC_ETH12CKSELR register fields */ ++#define RCC_ETH12CKSELR_ETH1SRC_MASK GENMASK(1, 0) ++#define RCC_ETH12CKSELR_ETH1PTPDIV_MASK GENMASK(7, 4) ++#define RCC_ETH12CKSELR_ETH2SRC_MASK GENMASK(9, 8) ++#define RCC_ETH12CKSELR_ETH2PTPDIV_MASK GENMASK(15, 12) ++#define RCC_ETH12CKSELR_ETH1SRC_SHIFT 0 ++#define RCC_ETH12CKSELR_ETH1PTPDIV_SHIFT 4 ++#define RCC_ETH12CKSELR_ETH2SRC_SHIFT 8 ++#define RCC_ETH12CKSELR_ETH2PTPDIV_SHIFT 12 ++ ++/* RCC_USBCKSELR register fields */ ++#define RCC_USBCKSELR_USBPHYSRC_MASK GENMASK(1, 0) ++#define RCC_USBCKSELR_USBOSRC BIT(4) ++#define RCC_USBCKSELR_USBPHYSRC_SHIFT 0 ++ ++/* RCC_QSPICKSELR register fields */ ++#define RCC_QSPICKSELR_QSPISRC_MASK GENMASK(1, 0) ++#define RCC_QSPICKSELR_QSPISRC_SHIFT 0 ++ ++/* RCC_FMCCKSELR register fields */ ++#define RCC_FMCCKSELR_FMCSRC_MASK GENMASK(1, 0) ++#define RCC_FMCCKSELR_FMCSRC_SHIFT 0 ++ ++/* RCC_RNG1CKSELR register fields */ ++#define RCC_RNG1CKSELR_RNG1SRC_MASK GENMASK(1, 0) ++#define RCC_RNG1CKSELR_RNG1SRC_SHIFT 0 ++ ++/* RCC_STGENCKSELR register fields */ ++#define RCC_STGENCKSELR_STGENSRC_MASK GENMASK(1, 0) ++#define RCC_STGENCKSELR_STGENSRC_SHIFT 0 ++ ++/* RCC_DCMIPPCKSELR register fields */ ++#define RCC_DCMIPPCKSELR_DCMIPPSRC_MASK GENMASK(1, 0) ++#define RCC_DCMIPPCKSELR_DCMIPPSRC_SHIFT 0 ++ ++/* RCC_SAESCKSELR register fields */ ++#define RCC_SAESCKSELR_SAESSRC_MASK GENMASK(1, 0) ++#define RCC_SAESCKSELR_SAESSRC_SHIFT 0 ++ ++/* RCC_APB1RSTSETR register fields */ ++#define RCC_APB1RSTSETR_TIM2RST BIT(0) ++#define RCC_APB1RSTSETR_TIM3RST BIT(1) ++#define RCC_APB1RSTSETR_TIM4RST BIT(2) ++#define RCC_APB1RSTSETR_TIM5RST BIT(3) ++#define RCC_APB1RSTSETR_TIM6RST BIT(4) ++#define RCC_APB1RSTSETR_TIM7RST BIT(5) ++#define RCC_APB1RSTSETR_LPTIM1RST BIT(9) ++#define RCC_APB1RSTSETR_SPI2RST BIT(11) ++#define RCC_APB1RSTSETR_SPI3RST BIT(12) ++#define RCC_APB1RSTSETR_USART3RST BIT(15) ++#define RCC_APB1RSTSETR_UART4RST BIT(16) ++#define RCC_APB1RSTSETR_UART5RST BIT(17) ++#define RCC_APB1RSTSETR_UART7RST BIT(18) ++#define RCC_APB1RSTSETR_UART8RST BIT(19) ++#define RCC_APB1RSTSETR_I2C1RST BIT(21) ++#define RCC_APB1RSTSETR_I2C2RST BIT(22) ++#define RCC_APB1RSTSETR_SPDIFRST BIT(26) ++ ++/* RCC_APB1RSTCLRR register fields */ ++#define RCC_APB1RSTCLRR_TIM2RST BIT(0) ++#define RCC_APB1RSTCLRR_TIM3RST BIT(1) ++#define RCC_APB1RSTCLRR_TIM4RST BIT(2) ++#define RCC_APB1RSTCLRR_TIM5RST BIT(3) ++#define RCC_APB1RSTCLRR_TIM6RST BIT(4) ++#define RCC_APB1RSTCLRR_TIM7RST BIT(5) ++#define RCC_APB1RSTCLRR_LPTIM1RST BIT(9) ++#define RCC_APB1RSTCLRR_SPI2RST BIT(11) ++#define RCC_APB1RSTCLRR_SPI3RST BIT(12) ++#define RCC_APB1RSTCLRR_USART3RST BIT(15) ++#define RCC_APB1RSTCLRR_UART4RST BIT(16) ++#define RCC_APB1RSTCLRR_UART5RST BIT(17) ++#define RCC_APB1RSTCLRR_UART7RST BIT(18) ++#define RCC_APB1RSTCLRR_UART8RST BIT(19) ++#define RCC_APB1RSTCLRR_I2C1RST BIT(21) ++#define RCC_APB1RSTCLRR_I2C2RST BIT(22) ++#define RCC_APB1RSTCLRR_SPDIFRST BIT(26) ++ ++/* RCC_APB2RSTSETR register fields */ ++#define RCC_APB2RSTSETR_TIM1RST BIT(0) ++#define RCC_APB2RSTSETR_TIM8RST BIT(1) ++#define RCC_APB2RSTSETR_SPI1RST BIT(8) ++#define RCC_APB2RSTSETR_USART6RST BIT(13) ++#define RCC_APB2RSTSETR_SAI1RST BIT(16) ++#define RCC_APB2RSTSETR_SAI2RST BIT(17) ++#define RCC_APB2RSTSETR_DFSDMRST BIT(20) ++#define RCC_APB2RSTSETR_FDCANRST BIT(24) ++ ++/* RCC_APB2RSTCLRR register fields */ ++#define RCC_APB2RSTCLRR_TIM1RST BIT(0) ++#define RCC_APB2RSTCLRR_TIM8RST BIT(1) ++#define RCC_APB2RSTCLRR_SPI1RST BIT(8) ++#define RCC_APB2RSTCLRR_USART6RST BIT(13) ++#define RCC_APB2RSTCLRR_SAI1RST BIT(16) ++#define RCC_APB2RSTCLRR_SAI2RST BIT(17) ++#define RCC_APB2RSTCLRR_DFSDMRST BIT(20) ++#define RCC_APB2RSTCLRR_FDCANRST BIT(24) ++ ++/* RCC_APB3RSTSETR register fields */ ++#define RCC_APB3RSTSETR_LPTIM2RST BIT(0) ++#define RCC_APB3RSTSETR_LPTIM3RST BIT(1) ++#define RCC_APB3RSTSETR_LPTIM4RST BIT(2) ++#define RCC_APB3RSTSETR_LPTIM5RST BIT(3) ++#define RCC_APB3RSTSETR_SYSCFGRST BIT(11) ++#define RCC_APB3RSTSETR_VREFRST BIT(13) ++#define RCC_APB3RSTSETR_DTSRST BIT(16) ++#define RCC_APB3RSTSETR_PMBCTRLRST BIT(17) ++ ++/* RCC_APB3RSTCLRR register fields */ ++#define RCC_APB3RSTCLRR_LPTIM2RST BIT(0) ++#define RCC_APB3RSTCLRR_LPTIM3RST BIT(1) ++#define RCC_APB3RSTCLRR_LPTIM4RST BIT(2) ++#define RCC_APB3RSTCLRR_LPTIM5RST BIT(3) ++#define RCC_APB3RSTCLRR_SYSCFGRST BIT(11) ++#define RCC_APB3RSTCLRR_VREFRST BIT(13) ++#define RCC_APB3RSTCLRR_DTSRST BIT(16) ++#define RCC_APB3RSTCLRR_PMBCTRLRST BIT(17) ++ ++/* RCC_APB4RSTSETR register fields */ ++#define RCC_APB4RSTSETR_LTDCRST BIT(0) ++#define RCC_APB4RSTSETR_DCMIPPRST BIT(1) ++#define RCC_APB4RSTSETR_DDRPERFMRST BIT(8) ++#define RCC_APB4RSTSETR_USBPHYRST BIT(16) ++ ++/* RCC_APB4RSTCLRR register fields */ ++#define RCC_APB4RSTCLRR_LTDCRST BIT(0) ++#define RCC_APB4RSTCLRR_DCMIPPRST BIT(1) ++#define RCC_APB4RSTCLRR_DDRPERFMRST BIT(8) ++#define RCC_APB4RSTCLRR_USBPHYRST BIT(16) ++ ++/* RCC_APB5RSTSETR register fields */ ++#define RCC_APB5RSTSETR_STGENRST BIT(20) ++ ++/* RCC_APB5RSTCLRR register fields */ ++#define RCC_APB5RSTCLRR_STGENRST BIT(20) ++ ++/* RCC_APB6RSTSETR register fields */ ++#define RCC_APB6RSTSETR_USART1RST BIT(0) ++#define RCC_APB6RSTSETR_USART2RST BIT(1) ++#define RCC_APB6RSTSETR_SPI4RST BIT(2) ++#define RCC_APB6RSTSETR_SPI5RST BIT(3) ++#define RCC_APB6RSTSETR_I2C3RST BIT(4) ++#define RCC_APB6RSTSETR_I2C4RST BIT(5) ++#define RCC_APB6RSTSETR_I2C5RST BIT(6) ++#define RCC_APB6RSTSETR_TIM12RST BIT(7) ++#define RCC_APB6RSTSETR_TIM13RST BIT(8) ++#define RCC_APB6RSTSETR_TIM14RST BIT(9) ++#define RCC_APB6RSTSETR_TIM15RST BIT(10) ++#define RCC_APB6RSTSETR_TIM16RST BIT(11) ++#define RCC_APB6RSTSETR_TIM17RST BIT(12) ++ ++/* RCC_APB6RSTCLRR register fields */ ++#define RCC_APB6RSTCLRR_USART1RST BIT(0) ++#define RCC_APB6RSTCLRR_USART2RST BIT(1) ++#define RCC_APB6RSTCLRR_SPI4RST BIT(2) ++#define RCC_APB6RSTCLRR_SPI5RST BIT(3) ++#define RCC_APB6RSTCLRR_I2C3RST BIT(4) ++#define RCC_APB6RSTCLRR_I2C4RST BIT(5) ++#define RCC_APB6RSTCLRR_I2C5RST BIT(6) ++#define RCC_APB6RSTCLRR_TIM12RST BIT(7) ++#define RCC_APB6RSTCLRR_TIM13RST BIT(8) ++#define RCC_APB6RSTCLRR_TIM14RST BIT(9) ++#define RCC_APB6RSTCLRR_TIM15RST BIT(10) ++#define RCC_APB6RSTCLRR_TIM16RST BIT(11) ++#define RCC_APB6RSTCLRR_TIM17RST BIT(12) ++ ++/* RCC_AHB2RSTSETR register fields */ ++#define RCC_AHB2RSTSETR_DMA1RST BIT(0) ++#define RCC_AHB2RSTSETR_DMA2RST BIT(1) ++#define RCC_AHB2RSTSETR_DMAMUX1RST BIT(2) ++#define RCC_AHB2RSTSETR_DMA3RST BIT(3) ++#define RCC_AHB2RSTSETR_DMAMUX2RST BIT(4) ++#define RCC_AHB2RSTSETR_ADC1RST BIT(5) ++#define RCC_AHB2RSTSETR_ADC2RST BIT(6) ++#define RCC_AHB2RSTSETR_USBORST BIT(8) ++ ++/* RCC_AHB2RSTCLRR register fields */ ++#define RCC_AHB2RSTCLRR_DMA1RST BIT(0) ++#define RCC_AHB2RSTCLRR_DMA2RST BIT(1) ++#define RCC_AHB2RSTCLRR_DMAMUX1RST BIT(2) ++#define RCC_AHB2RSTCLRR_DMA3RST BIT(3) ++#define RCC_AHB2RSTCLRR_DMAMUX2RST BIT(4) ++#define RCC_AHB2RSTCLRR_ADC1RST BIT(5) ++#define RCC_AHB2RSTCLRR_ADC2RST BIT(6) ++#define RCC_AHB2RSTCLRR_USBORST BIT(8) ++ ++/* RCC_AHB4RSTSETR register fields */ ++#define RCC_AHB4RSTSETR_GPIOARST BIT(0) ++#define RCC_AHB4RSTSETR_GPIOBRST BIT(1) ++#define RCC_AHB4RSTSETR_GPIOCRST BIT(2) ++#define RCC_AHB4RSTSETR_GPIODRST BIT(3) ++#define RCC_AHB4RSTSETR_GPIOERST BIT(4) ++#define RCC_AHB4RSTSETR_GPIOFRST BIT(5) ++#define RCC_AHB4RSTSETR_GPIOGRST BIT(6) ++#define RCC_AHB4RSTSETR_GPIOHRST BIT(7) ++#define RCC_AHB4RSTSETR_GPIOIRST BIT(8) ++#define RCC_AHB4RSTSETR_TSCRST BIT(15) ++ ++/* RCC_AHB4RSTCLRR register fields */ ++#define RCC_AHB4RSTCLRR_GPIOARST BIT(0) ++#define RCC_AHB4RSTCLRR_GPIOBRST BIT(1) ++#define RCC_AHB4RSTCLRR_GPIOCRST BIT(2) ++#define RCC_AHB4RSTCLRR_GPIODRST BIT(3) ++#define RCC_AHB4RSTCLRR_GPIOERST BIT(4) ++#define RCC_AHB4RSTCLRR_GPIOFRST BIT(5) ++#define RCC_AHB4RSTCLRR_GPIOGRST BIT(6) ++#define RCC_AHB4RSTCLRR_GPIOHRST BIT(7) ++#define RCC_AHB4RSTCLRR_GPIOIRST BIT(8) ++#define RCC_AHB4RSTCLRR_TSCRST BIT(15) ++ ++/* RCC_AHB5RSTSETR register fields */ ++#define RCC_AHB5RSTSETR_PKARST BIT(2) ++#define RCC_AHB5RSTSETR_SAESRST BIT(3) ++#define RCC_AHB5RSTSETR_CRYP1RST BIT(4) ++#define RCC_AHB5RSTSETR_HASH1RST BIT(5) ++#define RCC_AHB5RSTSETR_RNG1RST BIT(6) ++#define RCC_AHB5RSTSETR_AXIMCRST BIT(16) ++ ++/* RCC_AHB5RSTCLRR register fields */ ++#define RCC_AHB5RSTCLRR_PKARST BIT(2) ++#define RCC_AHB5RSTCLRR_SAESRST BIT(3) ++#define RCC_AHB5RSTCLRR_CRYP1RST BIT(4) ++#define RCC_AHB5RSTCLRR_HASH1RST BIT(5) ++#define RCC_AHB5RSTCLRR_RNG1RST BIT(6) ++#define RCC_AHB5RSTCLRR_AXIMCRST BIT(16) ++ ++/* RCC_AHB6RSTSETR register fields */ ++#define RCC_AHB6RSTSETR_MDMARST BIT(0) ++#define RCC_AHB6RSTSETR_MCERST BIT(1) ++#define RCC_AHB6RSTSETR_ETH1MACRST BIT(10) ++#define RCC_AHB6RSTSETR_FMCRST BIT(12) ++#define RCC_AHB6RSTSETR_QSPIRST BIT(14) ++#define RCC_AHB6RSTSETR_SDMMC1RST BIT(16) ++#define RCC_AHB6RSTSETR_SDMMC2RST BIT(17) ++#define RCC_AHB6RSTSETR_CRC1RST BIT(20) ++#define RCC_AHB6RSTSETR_USBHRST BIT(24) ++#define RCC_AHB6RSTSETR_ETH2MACRST BIT(30) ++ ++/* RCC_AHB6RSTCLRR register fields */ ++#define RCC_AHB6RSTCLRR_MDMARST BIT(0) ++#define RCC_AHB6RSTCLRR_MCERST BIT(1) ++#define RCC_AHB6RSTCLRR_ETH1MACRST BIT(10) ++#define RCC_AHB6RSTCLRR_FMCRST BIT(12) ++#define RCC_AHB6RSTCLRR_QSPIRST BIT(14) ++#define RCC_AHB6RSTCLRR_SDMMC1RST BIT(16) ++#define RCC_AHB6RSTCLRR_SDMMC2RST BIT(17) ++#define RCC_AHB6RSTCLRR_CRC1RST BIT(20) ++#define RCC_AHB6RSTCLRR_USBHRST BIT(24) ++#define RCC_AHB6RSTCLRR_ETH2MACRST BIT(30) ++ ++/* RCC_MP_APB1ENSETR register fields */ ++#define RCC_MP_APB1ENSETR_TIM2EN BIT(0) ++#define RCC_MP_APB1ENSETR_TIM3EN BIT(1) ++#define RCC_MP_APB1ENSETR_TIM4EN BIT(2) ++#define RCC_MP_APB1ENSETR_TIM5EN BIT(3) ++#define RCC_MP_APB1ENSETR_TIM6EN BIT(4) ++#define RCC_MP_APB1ENSETR_TIM7EN BIT(5) ++#define RCC_MP_APB1ENSETR_LPTIM1EN BIT(9) ++#define RCC_MP_APB1ENSETR_SPI2EN BIT(11) ++#define RCC_MP_APB1ENSETR_SPI3EN BIT(12) ++#define RCC_MP_APB1ENSETR_USART3EN BIT(15) ++#define RCC_MP_APB1ENSETR_UART4EN BIT(16) ++#define RCC_MP_APB1ENSETR_UART5EN BIT(17) ++#define RCC_MP_APB1ENSETR_UART7EN BIT(18) ++#define RCC_MP_APB1ENSETR_UART8EN BIT(19) ++#define RCC_MP_APB1ENSETR_I2C1EN BIT(21) ++#define RCC_MP_APB1ENSETR_I2C2EN BIT(22) ++#define RCC_MP_APB1ENSETR_SPDIFEN BIT(26) ++ ++/* RCC_MP_APB1ENCLRR register fields */ ++#define RCC_MP_APB1ENCLRR_TIM2EN BIT(0) ++#define RCC_MP_APB1ENCLRR_TIM3EN BIT(1) ++#define RCC_MP_APB1ENCLRR_TIM4EN BIT(2) ++#define RCC_MP_APB1ENCLRR_TIM5EN BIT(3) ++#define RCC_MP_APB1ENCLRR_TIM6EN BIT(4) ++#define RCC_MP_APB1ENCLRR_TIM7EN BIT(5) ++#define RCC_MP_APB1ENCLRR_LPTIM1EN BIT(9) ++#define RCC_MP_APB1ENCLRR_SPI2EN BIT(11) ++#define RCC_MP_APB1ENCLRR_SPI3EN BIT(12) ++#define RCC_MP_APB1ENCLRR_USART3EN BIT(15) ++#define RCC_MP_APB1ENCLRR_UART4EN BIT(16) ++#define RCC_MP_APB1ENCLRR_UART5EN BIT(17) ++#define RCC_MP_APB1ENCLRR_UART7EN BIT(18) ++#define RCC_MP_APB1ENCLRR_UART8EN BIT(19) ++#define RCC_MP_APB1ENCLRR_I2C1EN BIT(21) ++#define RCC_MP_APB1ENCLRR_I2C2EN BIT(22) ++#define RCC_MP_APB1ENCLRR_SPDIFEN BIT(26) ++ ++/* RCC_MP_APB2ENSETR register fields */ ++#define RCC_MP_APB2ENSETR_TIM1EN BIT(0) ++#define RCC_MP_APB2ENSETR_TIM8EN BIT(1) ++#define RCC_MP_APB2ENSETR_SPI1EN BIT(8) ++#define RCC_MP_APB2ENSETR_USART6EN BIT(13) ++#define RCC_MP_APB2ENSETR_SAI1EN BIT(16) ++#define RCC_MP_APB2ENSETR_SAI2EN BIT(17) ++#define RCC_MP_APB2ENSETR_DFSDMEN BIT(20) ++#define RCC_MP_APB2ENSETR_ADFSDMEN BIT(21) ++#define RCC_MP_APB2ENSETR_FDCANEN BIT(24) ++ ++/* RCC_MP_APB2ENCLRR register fields */ ++#define RCC_MP_APB2ENCLRR_TIM1EN BIT(0) ++#define RCC_MP_APB2ENCLRR_TIM8EN BIT(1) ++#define RCC_MP_APB2ENCLRR_SPI1EN BIT(8) ++#define RCC_MP_APB2ENCLRR_USART6EN BIT(13) ++#define RCC_MP_APB2ENCLRR_SAI1EN BIT(16) ++#define RCC_MP_APB2ENCLRR_SAI2EN BIT(17) ++#define RCC_MP_APB2ENCLRR_DFSDMEN BIT(20) ++#define RCC_MP_APB2ENCLRR_ADFSDMEN BIT(21) ++#define RCC_MP_APB2ENCLRR_FDCANEN BIT(24) ++ ++/* RCC_MP_APB3ENSETR register fields */ ++#define RCC_MP_APB3ENSETR_LPTIM2EN BIT(0) ++#define RCC_MP_APB3ENSETR_LPTIM3EN BIT(1) ++#define RCC_MP_APB3ENSETR_LPTIM4EN BIT(2) ++#define RCC_MP_APB3ENSETR_LPTIM5EN BIT(3) ++#define RCC_MP_APB3ENSETR_VREFEN BIT(13) ++#define RCC_MP_APB3ENSETR_DTSEN BIT(16) ++#define RCC_MP_APB3ENSETR_PMBCTRLEN BIT(17) ++#define RCC_MP_APB3ENSETR_HDPEN BIT(20) ++ ++/* RCC_MP_APB3ENCLRR register fields */ ++#define RCC_MP_APB3ENCLRR_LPTIM2EN BIT(0) ++#define RCC_MP_APB3ENCLRR_LPTIM3EN BIT(1) ++#define RCC_MP_APB3ENCLRR_LPTIM4EN BIT(2) ++#define RCC_MP_APB3ENCLRR_LPTIM5EN BIT(3) ++#define RCC_MP_APB3ENCLRR_VREFEN BIT(13) ++#define RCC_MP_APB3ENCLRR_DTSEN BIT(16) ++#define RCC_MP_APB3ENCLRR_PMBCTRLEN BIT(17) ++#define RCC_MP_APB3ENCLRR_HDPEN BIT(20) ++ ++/* RCC_MP_S_APB3ENSETR register fields */ ++#define RCC_MP_S_APB3ENSETR_SYSCFGEN BIT(0) ++ ++/* RCC_MP_S_APB3ENCLRR register fields */ ++#define RCC_MP_S_APB3ENCLRR_SYSCFGEN BIT(0) ++ ++/* RCC_MP_NS_APB3ENSETR register fields */ ++#define RCC_MP_NS_APB3ENSETR_SYSCFGEN BIT(0) ++ ++/* RCC_MP_NS_APB3ENCLRR register fields */ ++#define RCC_MP_NS_APB3ENCLRR_SYSCFGEN BIT(0) ++ ++/* RCC_MP_APB4ENSETR register fields */ ++#define RCC_MP_APB4ENSETR_DCMIPPEN BIT(1) ++#define RCC_MP_APB4ENSETR_DDRPERFMEN BIT(8) ++#define RCC_MP_APB4ENSETR_IWDG2APBEN BIT(15) ++#define RCC_MP_APB4ENSETR_USBPHYEN BIT(16) ++#define RCC_MP_APB4ENSETR_STGENROEN BIT(20) ++ ++/* RCC_MP_APB4ENCLRR register fields */ ++#define RCC_MP_APB4ENCLRR_DCMIPPEN BIT(1) ++#define RCC_MP_APB4ENCLRR_DDRPERFMEN BIT(8) ++#define RCC_MP_APB4ENCLRR_IWDG2APBEN BIT(15) ++#define RCC_MP_APB4ENCLRR_USBPHYEN BIT(16) ++#define RCC_MP_APB4ENCLRR_STGENROEN BIT(20) ++ ++/* RCC_MP_S_APB4ENSETR register fields */ ++#define RCC_MP_S_APB4ENSETR_LTDCEN BIT(0) ++ ++/* RCC_MP_S_APB4ENCLRR register fields */ ++#define RCC_MP_S_APB4ENCLRR_LTDCEN BIT(0) ++ ++/* RCC_MP_NS_APB4ENSETR register fields */ ++#define RCC_MP_NS_APB4ENSETR_LTDCEN BIT(0) ++ ++/* RCC_MP_NS_APB4ENCLRR register fields */ ++#define RCC_MP_NS_APB4ENCLRR_LTDCEN BIT(0) ++ ++/* RCC_MP_APB5ENSETR register fields */ ++#define RCC_MP_APB5ENSETR_RTCAPBEN BIT(8) ++#define RCC_MP_APB5ENSETR_TZCEN BIT(11) ++#define RCC_MP_APB5ENSETR_ETZPCEN BIT(13) ++#define RCC_MP_APB5ENSETR_IWDG1APBEN BIT(15) ++#define RCC_MP_APB5ENSETR_BSECEN BIT(16) ++#define RCC_MP_APB5ENSETR_STGENCEN BIT(20) ++ ++/* RCC_MP_APB5ENCLRR register fields */ ++#define RCC_MP_APB5ENCLRR_RTCAPBEN BIT(8) ++#define RCC_MP_APB5ENCLRR_TZCEN BIT(11) ++#define RCC_MP_APB5ENCLRR_ETZPCEN BIT(13) ++#define RCC_MP_APB5ENCLRR_IWDG1APBEN BIT(15) ++#define RCC_MP_APB5ENCLRR_BSECEN BIT(16) ++#define RCC_MP_APB5ENCLRR_STGENCEN BIT(20) ++ ++/* RCC_MP_APB6ENSETR register fields */ ++#define RCC_MP_APB6ENSETR_USART1EN BIT(0) ++#define RCC_MP_APB6ENSETR_USART2EN BIT(1) ++#define RCC_MP_APB6ENSETR_SPI4EN BIT(2) ++#define RCC_MP_APB6ENSETR_SPI5EN BIT(3) ++#define RCC_MP_APB6ENSETR_I2C3EN BIT(4) ++#define RCC_MP_APB6ENSETR_I2C4EN BIT(5) ++#define RCC_MP_APB6ENSETR_I2C5EN BIT(6) ++#define RCC_MP_APB6ENSETR_TIM12EN BIT(7) ++#define RCC_MP_APB6ENSETR_TIM13EN BIT(8) ++#define RCC_MP_APB6ENSETR_TIM14EN BIT(9) ++#define RCC_MP_APB6ENSETR_TIM15EN BIT(10) ++#define RCC_MP_APB6ENSETR_TIM16EN BIT(11) ++#define RCC_MP_APB6ENSETR_TIM17EN BIT(12) ++ ++/* RCC_MP_APB6ENCLRR register fields */ ++#define RCC_MP_APB6ENCLRR_USART1EN BIT(0) ++#define RCC_MP_APB6ENCLRR_USART2EN BIT(1) ++#define RCC_MP_APB6ENCLRR_SPI4EN BIT(2) ++#define RCC_MP_APB6ENCLRR_SPI5EN BIT(3) ++#define RCC_MP_APB6ENCLRR_I2C3EN BIT(4) ++#define RCC_MP_APB6ENCLRR_I2C4EN BIT(5) ++#define RCC_MP_APB6ENCLRR_I2C5EN BIT(6) ++#define RCC_MP_APB6ENCLRR_TIM12EN BIT(7) ++#define RCC_MP_APB6ENCLRR_TIM13EN BIT(8) ++#define RCC_MP_APB6ENCLRR_TIM14EN BIT(9) ++#define RCC_MP_APB6ENCLRR_TIM15EN BIT(10) ++#define RCC_MP_APB6ENCLRR_TIM16EN BIT(11) ++#define RCC_MP_APB6ENCLRR_TIM17EN BIT(12) ++ ++/* RCC_MP_AHB2ENSETR register fields */ ++#define RCC_MP_AHB2ENSETR_DMA1EN BIT(0) ++#define RCC_MP_AHB2ENSETR_DMA2EN BIT(1) ++#define RCC_MP_AHB2ENSETR_DMAMUX1EN BIT(2) ++#define RCC_MP_AHB2ENSETR_DMA3EN BIT(3) ++#define RCC_MP_AHB2ENSETR_DMAMUX2EN BIT(4) ++#define RCC_MP_AHB2ENSETR_ADC1EN BIT(5) ++#define RCC_MP_AHB2ENSETR_ADC2EN BIT(6) ++#define RCC_MP_AHB2ENSETR_USBOEN BIT(8) ++ ++/* RCC_MP_AHB2ENCLRR register fields */ ++#define RCC_MP_AHB2ENCLRR_DMA1EN BIT(0) ++#define RCC_MP_AHB2ENCLRR_DMA2EN BIT(1) ++#define RCC_MP_AHB2ENCLRR_DMAMUX1EN BIT(2) ++#define RCC_MP_AHB2ENCLRR_DMA3EN BIT(3) ++#define RCC_MP_AHB2ENCLRR_DMAMUX2EN BIT(4) ++#define RCC_MP_AHB2ENCLRR_ADC1EN BIT(5) ++#define RCC_MP_AHB2ENCLRR_ADC2EN BIT(6) ++#define RCC_MP_AHB2ENCLRR_USBOEN BIT(8) ++ ++/* RCC_MP_AHB4ENSETR register fields */ ++#define RCC_MP_AHB4ENSETR_TSCEN BIT(15) ++ ++/* RCC_MP_AHB4ENCLRR register fields */ ++#define RCC_MP_AHB4ENCLRR_TSCEN BIT(15) ++ ++/* RCC_MP_S_AHB4ENSETR register fields */ ++#define RCC_MP_S_AHB4ENSETR_GPIOAEN BIT(0) ++#define RCC_MP_S_AHB4ENSETR_GPIOBEN BIT(1) ++#define RCC_MP_S_AHB4ENSETR_GPIOCEN BIT(2) ++#define RCC_MP_S_AHB4ENSETR_GPIODEN BIT(3) ++#define RCC_MP_S_AHB4ENSETR_GPIOEEN BIT(4) ++#define RCC_MP_S_AHB4ENSETR_GPIOFEN BIT(5) ++#define RCC_MP_S_AHB4ENSETR_GPIOGEN BIT(6) ++#define RCC_MP_S_AHB4ENSETR_GPIOHEN BIT(7) ++#define RCC_MP_S_AHB4ENSETR_GPIOIEN BIT(8) ++ ++/* RCC_MP_S_AHB4ENCLRR register fields */ ++#define RCC_MP_S_AHB4ENCLRR_GPIOAEN BIT(0) ++#define RCC_MP_S_AHB4ENCLRR_GPIOBEN BIT(1) ++#define RCC_MP_S_AHB4ENCLRR_GPIOCEN BIT(2) ++#define RCC_MP_S_AHB4ENCLRR_GPIODEN BIT(3) ++#define RCC_MP_S_AHB4ENCLRR_GPIOEEN BIT(4) ++#define RCC_MP_S_AHB4ENCLRR_GPIOFEN BIT(5) ++#define RCC_MP_S_AHB4ENCLRR_GPIOGEN BIT(6) ++#define RCC_MP_S_AHB4ENCLRR_GPIOHEN BIT(7) ++#define RCC_MP_S_AHB4ENCLRR_GPIOIEN BIT(8) ++ ++/* RCC_MP_NS_AHB4ENSETR register fields */ ++#define RCC_MP_NS_AHB4ENSETR_GPIOAEN BIT(0) ++#define RCC_MP_NS_AHB4ENSETR_GPIOBEN BIT(1) ++#define RCC_MP_NS_AHB4ENSETR_GPIOCEN BIT(2) ++#define RCC_MP_NS_AHB4ENSETR_GPIODEN BIT(3) ++#define RCC_MP_NS_AHB4ENSETR_GPIOEEN BIT(4) ++#define RCC_MP_NS_AHB4ENSETR_GPIOFEN BIT(5) ++#define RCC_MP_NS_AHB4ENSETR_GPIOGEN BIT(6) ++#define RCC_MP_NS_AHB4ENSETR_GPIOHEN BIT(7) ++#define RCC_MP_NS_AHB4ENSETR_GPIOIEN BIT(8) ++ ++/* RCC_MP_NS_AHB4ENCLRR register fields */ ++#define RCC_MP_NS_AHB4ENCLRR_GPIOAEN BIT(0) ++#define RCC_MP_NS_AHB4ENCLRR_GPIOBEN BIT(1) ++#define RCC_MP_NS_AHB4ENCLRR_GPIOCEN BIT(2) ++#define RCC_MP_NS_AHB4ENCLRR_GPIODEN BIT(3) ++#define RCC_MP_NS_AHB4ENCLRR_GPIOEEN BIT(4) ++#define RCC_MP_NS_AHB4ENCLRR_GPIOFEN BIT(5) ++#define RCC_MP_NS_AHB4ENCLRR_GPIOGEN BIT(6) ++#define RCC_MP_NS_AHB4ENCLRR_GPIOHEN BIT(7) ++#define RCC_MP_NS_AHB4ENCLRR_GPIOIEN BIT(8) ++ ++/* RCC_MP_AHB5ENSETR register fields */ ++#define RCC_MP_AHB5ENSETR_PKAEN BIT(2) ++#define RCC_MP_AHB5ENSETR_SAESEN BIT(3) ++#define RCC_MP_AHB5ENSETR_CRYP1EN BIT(4) ++#define RCC_MP_AHB5ENSETR_HASH1EN BIT(5) ++#define RCC_MP_AHB5ENSETR_RNG1EN BIT(6) ++#define RCC_MP_AHB5ENSETR_BKPSRAMEN BIT(8) ++#define RCC_MP_AHB5ENSETR_AXIMCEN BIT(16) ++ ++/* RCC_MP_AHB5ENCLRR register fields */ ++#define RCC_MP_AHB5ENCLRR_PKAEN BIT(2) ++#define RCC_MP_AHB5ENCLRR_SAESEN BIT(3) ++#define RCC_MP_AHB5ENCLRR_CRYP1EN BIT(4) ++#define RCC_MP_AHB5ENCLRR_HASH1EN BIT(5) ++#define RCC_MP_AHB5ENCLRR_RNG1EN BIT(6) ++#define RCC_MP_AHB5ENCLRR_BKPSRAMEN BIT(8) ++#define RCC_MP_AHB5ENCLRR_AXIMCEN BIT(16) ++ ++/* RCC_MP_AHB6ENSETR register fields */ ++#define RCC_MP_AHB6ENSETR_MCEEN BIT(1) ++#define RCC_MP_AHB6ENSETR_ETH1CKEN BIT(7) ++#define RCC_MP_AHB6ENSETR_ETH1TXEN BIT(8) ++#define RCC_MP_AHB6ENSETR_ETH1RXEN BIT(9) ++#define RCC_MP_AHB6ENSETR_ETH1MACEN BIT(10) ++#define RCC_MP_AHB6ENSETR_FMCEN BIT(12) ++#define RCC_MP_AHB6ENSETR_QSPIEN BIT(14) ++#define RCC_MP_AHB6ENSETR_SDMMC1EN BIT(16) ++#define RCC_MP_AHB6ENSETR_SDMMC2EN BIT(17) ++#define RCC_MP_AHB6ENSETR_CRC1EN BIT(20) ++#define RCC_MP_AHB6ENSETR_USBHEN BIT(24) ++#define RCC_MP_AHB6ENSETR_ETH2CKEN BIT(27) ++#define RCC_MP_AHB6ENSETR_ETH2TXEN BIT(28) ++#define RCC_MP_AHB6ENSETR_ETH2RXEN BIT(29) ++#define RCC_MP_AHB6ENSETR_ETH2MACEN BIT(30) ++ ++/* RCC_MP_AHB6ENCLRR register fields */ ++#define RCC_MP_AHB6ENCLRR_MCEEN BIT(1) ++#define RCC_MP_AHB6ENCLRR_ETH1CKEN BIT(7) ++#define RCC_MP_AHB6ENCLRR_ETH1TXEN BIT(8) ++#define RCC_MP_AHB6ENCLRR_ETH1RXEN BIT(9) ++#define RCC_MP_AHB6ENCLRR_ETH1MACEN BIT(10) ++#define RCC_MP_AHB6ENCLRR_FMCEN BIT(12) ++#define RCC_MP_AHB6ENCLRR_QSPIEN BIT(14) ++#define RCC_MP_AHB6ENCLRR_SDMMC1EN BIT(16) ++#define RCC_MP_AHB6ENCLRR_SDMMC2EN BIT(17) ++#define RCC_MP_AHB6ENCLRR_CRC1EN BIT(20) ++#define RCC_MP_AHB6ENCLRR_USBHEN BIT(24) ++#define RCC_MP_AHB6ENCLRR_ETH2CKEN BIT(27) ++#define RCC_MP_AHB6ENCLRR_ETH2TXEN BIT(28) ++#define RCC_MP_AHB6ENCLRR_ETH2RXEN BIT(29) ++#define RCC_MP_AHB6ENCLRR_ETH2MACEN BIT(30) ++ ++/* RCC_MP_S_AHB6ENSETR register fields */ ++#define RCC_MP_S_AHB6ENSETR_MDMAEN BIT(0) ++ ++/* RCC_MP_S_AHB6ENCLRR register fields */ ++#define RCC_MP_S_AHB6ENCLRR_MDMAEN BIT(0) ++ ++/* RCC_MP_NS_AHB6ENSETR register fields */ ++#define RCC_MP_NS_AHB6ENSETR_MDMAEN BIT(0) ++ ++/* RCC_MP_NS_AHB6ENCLRR register fields */ ++#define RCC_MP_NS_AHB6ENCLRR_MDMAEN BIT(0) ++ ++/* RCC_MP_APB1LPENSETR register fields */ ++#define RCC_MP_APB1LPENSETR_TIM2LPEN BIT(0) ++#define RCC_MP_APB1LPENSETR_TIM3LPEN BIT(1) ++#define RCC_MP_APB1LPENSETR_TIM4LPEN BIT(2) ++#define RCC_MP_APB1LPENSETR_TIM5LPEN BIT(3) ++#define RCC_MP_APB1LPENSETR_TIM6LPEN BIT(4) ++#define RCC_MP_APB1LPENSETR_TIM7LPEN BIT(5) ++#define RCC_MP_APB1LPENSETR_LPTIM1LPEN BIT(9) ++#define RCC_MP_APB1LPENSETR_SPI2LPEN BIT(11) ++#define RCC_MP_APB1LPENSETR_SPI3LPEN BIT(12) ++#define RCC_MP_APB1LPENSETR_USART3LPEN BIT(15) ++#define RCC_MP_APB1LPENSETR_UART4LPEN BIT(16) ++#define RCC_MP_APB1LPENSETR_UART5LPEN BIT(17) ++#define RCC_MP_APB1LPENSETR_UART7LPEN BIT(18) ++#define RCC_MP_APB1LPENSETR_UART8LPEN BIT(19) ++#define RCC_MP_APB1LPENSETR_I2C1LPEN BIT(21) ++#define RCC_MP_APB1LPENSETR_I2C2LPEN BIT(22) ++#define RCC_MP_APB1LPENSETR_SPDIFLPEN BIT(26) ++ ++/* RCC_MP_APB1LPENCLRR register fields */ ++#define RCC_MP_APB1LPENCLRR_TIM2LPEN BIT(0) ++#define RCC_MP_APB1LPENCLRR_TIM3LPEN BIT(1) ++#define RCC_MP_APB1LPENCLRR_TIM4LPEN BIT(2) ++#define RCC_MP_APB1LPENCLRR_TIM5LPEN BIT(3) ++#define RCC_MP_APB1LPENCLRR_TIM6LPEN BIT(4) ++#define RCC_MP_APB1LPENCLRR_TIM7LPEN BIT(5) ++#define RCC_MP_APB1LPENCLRR_LPTIM1LPEN BIT(9) ++#define RCC_MP_APB1LPENCLRR_SPI2LPEN BIT(11) ++#define RCC_MP_APB1LPENCLRR_SPI3LPEN BIT(12) ++#define RCC_MP_APB1LPENCLRR_USART3LPEN BIT(15) ++#define RCC_MP_APB1LPENCLRR_UART4LPEN BIT(16) ++#define RCC_MP_APB1LPENCLRR_UART5LPEN BIT(17) ++#define RCC_MP_APB1LPENCLRR_UART7LPEN BIT(18) ++#define RCC_MP_APB1LPENCLRR_UART8LPEN BIT(19) ++#define RCC_MP_APB1LPENCLRR_I2C1LPEN BIT(21) ++#define RCC_MP_APB1LPENCLRR_I2C2LPEN BIT(22) ++#define RCC_MP_APB1LPENCLRR_SPDIFLPEN BIT(26) ++ ++/* RCC_MP_APB2LPENSETR register fields */ ++#define RCC_MP_APB2LPENSETR_TIM1LPEN BIT(0) ++#define RCC_MP_APB2LPENSETR_TIM8LPEN BIT(1) ++#define RCC_MP_APB2LPENSETR_SPI1LPEN BIT(8) ++#define RCC_MP_APB2LPENSETR_USART6LPEN BIT(13) ++#define RCC_MP_APB2LPENSETR_SAI1LPEN BIT(16) ++#define RCC_MP_APB2LPENSETR_SAI2LPEN BIT(17) ++#define RCC_MP_APB2LPENSETR_DFSDMLPEN BIT(20) ++#define RCC_MP_APB2LPENSETR_ADFSDMLPEN BIT(21) ++#define RCC_MP_APB2LPENSETR_FDCANLPEN BIT(24) ++ ++/* RCC_MP_APB2LPENCLRR register fields */ ++#define RCC_MP_APB2LPENCLRR_TIM1LPEN BIT(0) ++#define RCC_MP_APB2LPENCLRR_TIM8LPEN BIT(1) ++#define RCC_MP_APB2LPENCLRR_SPI1LPEN BIT(8) ++#define RCC_MP_APB2LPENCLRR_USART6LPEN BIT(13) ++#define RCC_MP_APB2LPENCLRR_SAI1LPEN BIT(16) ++#define RCC_MP_APB2LPENCLRR_SAI2LPEN BIT(17) ++#define RCC_MP_APB2LPENCLRR_DFSDMLPEN BIT(20) ++#define RCC_MP_APB2LPENCLRR_ADFSDMLPEN BIT(21) ++#define RCC_MP_APB2LPENCLRR_FDCANLPEN BIT(24) ++ ++/* RCC_MP_APB3LPENSETR register fields */ ++#define RCC_MP_APB3LPENSETR_LPTIM2LPEN BIT(0) ++#define RCC_MP_APB3LPENSETR_LPTIM3LPEN BIT(1) ++#define RCC_MP_APB3LPENSETR_LPTIM4LPEN BIT(2) ++#define RCC_MP_APB3LPENSETR_LPTIM5LPEN BIT(3) ++#define RCC_MP_APB3LPENSETR_VREFLPEN BIT(13) ++#define RCC_MP_APB3LPENSETR_DTSLPEN BIT(16) ++#define RCC_MP_APB3LPENSETR_PMBCTRLLPEN BIT(17) ++ ++/* RCC_MP_APB3LPENCLRR register fields */ ++#define RCC_MP_APB3LPENCLRR_LPTIM2LPEN BIT(0) ++#define RCC_MP_APB3LPENCLRR_LPTIM3LPEN BIT(1) ++#define RCC_MP_APB3LPENCLRR_LPTIM4LPEN BIT(2) ++#define RCC_MP_APB3LPENCLRR_LPTIM5LPEN BIT(3) ++#define RCC_MP_APB3LPENCLRR_VREFLPEN BIT(13) ++#define RCC_MP_APB3LPENCLRR_DTSLPEN BIT(16) ++#define RCC_MP_APB3LPENCLRR_PMBCTRLLPEN BIT(17) ++ ++/* RCC_MP_S_APB3LPENSETR register fields */ ++#define RCC_MP_S_APB3LPENSETR_SYSCFGLPEN BIT(0) ++ ++/* RCC_MP_S_APB3LPENCLRR register fields */ ++#define RCC_MP_S_APB3LPENCLRR_SYSCFGLPEN BIT(0) ++ ++/* RCC_MP_NS_APB3LPENSETR register fields */ ++#define RCC_MP_NS_APB3LPENSETR_SYSCFGLPEN BIT(0) ++ ++/* RCC_MP_NS_APB3LPENCLRR register fields */ ++#define RCC_MP_NS_APB3LPENCLRR_SYSCFGLPEN BIT(0) ++ ++/* RCC_MP_APB4LPENSETR register fields */ ++#define RCC_MP_APB4LPENSETR_DCMIPPLPEN BIT(1) ++#define RCC_MP_APB4LPENSETR_DDRPERFMLPEN BIT(8) ++#define RCC_MP_APB4LPENSETR_IWDG2APBLPEN BIT(15) ++#define RCC_MP_APB4LPENSETR_USBPHYLPEN BIT(16) ++#define RCC_MP_APB4LPENSETR_STGENROLPEN BIT(20) ++#define RCC_MP_APB4LPENSETR_STGENROSTPEN BIT(21) ++ ++/* RCC_MP_APB4LPENCLRR register fields */ ++#define RCC_MP_APB4LPENCLRR_DCMIPPLPEN BIT(1) ++#define RCC_MP_APB4LPENCLRR_DDRPERFMLPEN BIT(8) ++#define RCC_MP_APB4LPENCLRR_IWDG2APBLPEN BIT(15) ++#define RCC_MP_APB4LPENCLRR_USBPHYLPEN BIT(16) ++#define RCC_MP_APB4LPENCLRR_STGENROLPEN BIT(20) ++#define RCC_MP_APB4LPENCLRR_STGENROSTPEN BIT(21) ++ ++/* RCC_MP_S_APB4LPENSETR register fields */ ++#define RCC_MP_S_APB4LPENSETR_LTDCLPEN BIT(0) ++ ++/* RCC_MP_S_APB4LPENCLRR register fields */ ++#define RCC_MP_S_APB4LPENCLRR_LTDCLPEN BIT(0) ++ ++/* RCC_MP_NS_APB4LPENSETR register fields */ ++#define RCC_MP_NS_APB4LPENSETR_LTDCLPEN BIT(0) ++ ++/* RCC_MP_NS_APB4LPENCLRR register fields */ ++#define RCC_MP_NS_APB4LPENCLRR_LTDCLPEN BIT(0) ++ ++/* RCC_MP_APB5LPENSETR register fields */ ++#define RCC_MP_APB5LPENSETR_RTCAPBLPEN BIT(8) ++#define RCC_MP_APB5LPENSETR_TZCLPEN BIT(11) ++#define RCC_MP_APB5LPENSETR_ETZPCLPEN BIT(13) ++#define RCC_MP_APB5LPENSETR_IWDG1APBLPEN BIT(15) ++#define RCC_MP_APB5LPENSETR_BSECLPEN BIT(16) ++#define RCC_MP_APB5LPENSETR_STGENCLPEN BIT(20) ++#define RCC_MP_APB5LPENSETR_STGENCSTPEN BIT(21) ++ ++/* RCC_MP_APB5LPENCLRR register fields */ ++#define RCC_MP_APB5LPENCLRR_RTCAPBLPEN BIT(8) ++#define RCC_MP_APB5LPENCLRR_TZCLPEN BIT(11) ++#define RCC_MP_APB5LPENCLRR_ETZPCLPEN BIT(13) ++#define RCC_MP_APB5LPENCLRR_IWDG1APBLPEN BIT(15) ++#define RCC_MP_APB5LPENCLRR_BSECLPEN BIT(16) ++#define RCC_MP_APB5LPENCLRR_STGENCLPEN BIT(20) ++#define RCC_MP_APB5LPENCLRR_STGENCSTPEN BIT(21) ++ ++/* RCC_MP_APB6LPENSETR register fields */ ++#define RCC_MP_APB6LPENSETR_USART1LPEN BIT(0) ++#define RCC_MP_APB6LPENSETR_USART2LPEN BIT(1) ++#define RCC_MP_APB6LPENSETR_SPI4LPEN BIT(2) ++#define RCC_MP_APB6LPENSETR_SPI5LPEN BIT(3) ++#define RCC_MP_APB6LPENSETR_I2C3LPEN BIT(4) ++#define RCC_MP_APB6LPENSETR_I2C4LPEN BIT(5) ++#define RCC_MP_APB6LPENSETR_I2C5LPEN BIT(6) ++#define RCC_MP_APB6LPENSETR_TIM12LPEN BIT(7) ++#define RCC_MP_APB6LPENSETR_TIM13LPEN BIT(8) ++#define RCC_MP_APB6LPENSETR_TIM14LPEN BIT(9) ++#define RCC_MP_APB6LPENSETR_TIM15LPEN BIT(10) ++#define RCC_MP_APB6LPENSETR_TIM16LPEN BIT(11) ++#define RCC_MP_APB6LPENSETR_TIM17LPEN BIT(12) ++ ++/* RCC_MP_APB6LPENCLRR register fields */ ++#define RCC_MP_APB6LPENCLRR_USART1LPEN BIT(0) ++#define RCC_MP_APB6LPENCLRR_USART2LPEN BIT(1) ++#define RCC_MP_APB6LPENCLRR_SPI4LPEN BIT(2) ++#define RCC_MP_APB6LPENCLRR_SPI5LPEN BIT(3) ++#define RCC_MP_APB6LPENCLRR_I2C3LPEN BIT(4) ++#define RCC_MP_APB6LPENCLRR_I2C4LPEN BIT(5) ++#define RCC_MP_APB6LPENCLRR_I2C5LPEN BIT(6) ++#define RCC_MP_APB6LPENCLRR_TIM12LPEN BIT(7) ++#define RCC_MP_APB6LPENCLRR_TIM13LPEN BIT(8) ++#define RCC_MP_APB6LPENCLRR_TIM14LPEN BIT(9) ++#define RCC_MP_APB6LPENCLRR_TIM15LPEN BIT(10) ++#define RCC_MP_APB6LPENCLRR_TIM16LPEN BIT(11) ++#define RCC_MP_APB6LPENCLRR_TIM17LPEN BIT(12) ++ ++/* RCC_MP_AHB2LPENSETR register fields */ ++#define RCC_MP_AHB2LPENSETR_DMA1LPEN BIT(0) ++#define RCC_MP_AHB2LPENSETR_DMA2LPEN BIT(1) ++#define RCC_MP_AHB2LPENSETR_DMAMUX1LPEN BIT(2) ++#define RCC_MP_AHB2LPENSETR_DMA3LPEN BIT(3) ++#define RCC_MP_AHB2LPENSETR_DMAMUX2LPEN BIT(4) ++#define RCC_MP_AHB2LPENSETR_ADC1LPEN BIT(5) ++#define RCC_MP_AHB2LPENSETR_ADC2LPEN BIT(6) ++#define RCC_MP_AHB2LPENSETR_USBOLPEN BIT(8) ++ ++/* RCC_MP_AHB2LPENCLRR register fields */ ++#define RCC_MP_AHB2LPENCLRR_DMA1LPEN BIT(0) ++#define RCC_MP_AHB2LPENCLRR_DMA2LPEN BIT(1) ++#define RCC_MP_AHB2LPENCLRR_DMAMUX1LPEN BIT(2) ++#define RCC_MP_AHB2LPENCLRR_DMA3LPEN BIT(3) ++#define RCC_MP_AHB2LPENCLRR_DMAMUX2LPEN BIT(4) ++#define RCC_MP_AHB2LPENCLRR_ADC1LPEN BIT(5) ++#define RCC_MP_AHB2LPENCLRR_ADC2LPEN BIT(6) ++#define RCC_MP_AHB2LPENCLRR_USBOLPEN BIT(8) ++ ++/* RCC_MP_AHB4LPENSETR register fields */ ++#define RCC_MP_AHB4LPENSETR_TSCLPEN BIT(15) ++ ++/* RCC_MP_AHB4LPENCLRR register fields */ ++#define RCC_MP_AHB4LPENCLRR_TSCLPEN BIT(15) ++ ++/* RCC_MP_S_AHB4LPENSETR register fields */ ++#define RCC_MP_S_AHB4LPENSETR_GPIOALPEN BIT(0) ++#define RCC_MP_S_AHB4LPENSETR_GPIOBLPEN BIT(1) ++#define RCC_MP_S_AHB4LPENSETR_GPIOCLPEN BIT(2) ++#define RCC_MP_S_AHB4LPENSETR_GPIODLPEN BIT(3) ++#define RCC_MP_S_AHB4LPENSETR_GPIOELPEN BIT(4) ++#define RCC_MP_S_AHB4LPENSETR_GPIOFLPEN BIT(5) ++#define RCC_MP_S_AHB4LPENSETR_GPIOGLPEN BIT(6) ++#define RCC_MP_S_AHB4LPENSETR_GPIOHLPEN BIT(7) ++#define RCC_MP_S_AHB4LPENSETR_GPIOILPEN BIT(8) ++ ++/* RCC_MP_S_AHB4LPENCLRR register fields */ ++#define RCC_MP_S_AHB4LPENCLRR_GPIOALPEN BIT(0) ++#define RCC_MP_S_AHB4LPENCLRR_GPIOBLPEN BIT(1) ++#define RCC_MP_S_AHB4LPENCLRR_GPIOCLPEN BIT(2) ++#define RCC_MP_S_AHB4LPENCLRR_GPIODLPEN BIT(3) ++#define RCC_MP_S_AHB4LPENCLRR_GPIOELPEN BIT(4) ++#define RCC_MP_S_AHB4LPENCLRR_GPIOFLPEN BIT(5) ++#define RCC_MP_S_AHB4LPENCLRR_GPIOGLPEN BIT(6) ++#define RCC_MP_S_AHB4LPENCLRR_GPIOHLPEN BIT(7) ++#define RCC_MP_S_AHB4LPENCLRR_GPIOILPEN BIT(8) ++ ++/* RCC_MP_NS_AHB4LPENSETR register fields */ ++#define RCC_MP_NS_AHB4LPENSETR_GPIOALPEN BIT(0) ++#define RCC_MP_NS_AHB4LPENSETR_GPIOBLPEN BIT(1) ++#define RCC_MP_NS_AHB4LPENSETR_GPIOCLPEN BIT(2) ++#define RCC_MP_NS_AHB4LPENSETR_GPIODLPEN BIT(3) ++#define RCC_MP_NS_AHB4LPENSETR_GPIOELPEN BIT(4) ++#define RCC_MP_NS_AHB4LPENSETR_GPIOFLPEN BIT(5) ++#define RCC_MP_NS_AHB4LPENSETR_GPIOGLPEN BIT(6) ++#define RCC_MP_NS_AHB4LPENSETR_GPIOHLPEN BIT(7) ++#define RCC_MP_NS_AHB4LPENSETR_GPIOILPEN BIT(8) ++ ++/* RCC_MP_NS_AHB4LPENCLRR register fields */ ++#define RCC_MP_NS_AHB4LPENCLRR_GPIOALPEN BIT(0) ++#define RCC_MP_NS_AHB4LPENCLRR_GPIOBLPEN BIT(1) ++#define RCC_MP_NS_AHB4LPENCLRR_GPIOCLPEN BIT(2) ++#define RCC_MP_NS_AHB4LPENCLRR_GPIODLPEN BIT(3) ++#define RCC_MP_NS_AHB4LPENCLRR_GPIOELPEN BIT(4) ++#define RCC_MP_NS_AHB4LPENCLRR_GPIOFLPEN BIT(5) ++#define RCC_MP_NS_AHB4LPENCLRR_GPIOGLPEN BIT(6) ++#define RCC_MP_NS_AHB4LPENCLRR_GPIOHLPEN BIT(7) ++#define RCC_MP_NS_AHB4LPENCLRR_GPIOILPEN BIT(8) ++ ++/* RCC_MP_AHB5LPENSETR register fields */ ++#define RCC_MP_AHB5LPENSETR_PKALPEN BIT(2) ++#define RCC_MP_AHB5LPENSETR_SAESLPEN BIT(3) ++#define RCC_MP_AHB5LPENSETR_CRYP1LPEN BIT(4) ++#define RCC_MP_AHB5LPENSETR_HASH1LPEN BIT(5) ++#define RCC_MP_AHB5LPENSETR_RNG1LPEN BIT(6) ++#define RCC_MP_AHB5LPENSETR_BKPSRAMLPEN BIT(8) ++ ++/* RCC_MP_AHB5LPENCLRR register fields */ ++#define RCC_MP_AHB5LPENCLRR_PKALPEN BIT(2) ++#define RCC_MP_AHB5LPENCLRR_SAESLPEN BIT(3) ++#define RCC_MP_AHB5LPENCLRR_CRYP1LPEN BIT(4) ++#define RCC_MP_AHB5LPENCLRR_HASH1LPEN BIT(5) ++#define RCC_MP_AHB5LPENCLRR_RNG1LPEN BIT(6) ++#define RCC_MP_AHB5LPENCLRR_BKPSRAMLPEN BIT(8) ++ ++/* RCC_MP_AHB6LPENSETR register fields */ ++#define RCC_MP_AHB6LPENSETR_MCELPEN BIT(1) ++#define RCC_MP_AHB6LPENSETR_ETH1CKLPEN BIT(7) ++#define RCC_MP_AHB6LPENSETR_ETH1TXLPEN BIT(8) ++#define RCC_MP_AHB6LPENSETR_ETH1RXLPEN BIT(9) ++#define RCC_MP_AHB6LPENSETR_ETH1MACLPEN BIT(10) ++#define RCC_MP_AHB6LPENSETR_ETH1STPEN BIT(11) ++#define RCC_MP_AHB6LPENSETR_FMCLPEN BIT(12) ++#define RCC_MP_AHB6LPENSETR_QSPILPEN BIT(14) ++#define RCC_MP_AHB6LPENSETR_SDMMC1LPEN BIT(16) ++#define RCC_MP_AHB6LPENSETR_SDMMC2LPEN BIT(17) ++#define RCC_MP_AHB6LPENSETR_CRC1LPEN BIT(20) ++#define RCC_MP_AHB6LPENSETR_USBHLPEN BIT(24) ++#define RCC_MP_AHB6LPENSETR_ETH2CKLPEN BIT(27) ++#define RCC_MP_AHB6LPENSETR_ETH2TXLPEN BIT(28) ++#define RCC_MP_AHB6LPENSETR_ETH2RXLPEN BIT(29) ++#define RCC_MP_AHB6LPENSETR_ETH2MACLPEN BIT(30) ++#define RCC_MP_AHB6LPENSETR_ETH2STPEN BIT(31) ++ ++/* RCC_MP_AHB6LPENCLRR register fields */ ++#define RCC_MP_AHB6LPENCLRR_MCELPEN BIT(1) ++#define RCC_MP_AHB6LPENCLRR_ETH1CKLPEN BIT(7) ++#define RCC_MP_AHB6LPENCLRR_ETH1TXLPEN BIT(8) ++#define RCC_MP_AHB6LPENCLRR_ETH1RXLPEN BIT(9) ++#define RCC_MP_AHB6LPENCLRR_ETH1MACLPEN BIT(10) ++#define RCC_MP_AHB6LPENCLRR_ETH1STPEN BIT(11) ++#define RCC_MP_AHB6LPENCLRR_FMCLPEN BIT(12) ++#define RCC_MP_AHB6LPENCLRR_QSPILPEN BIT(14) ++#define RCC_MP_AHB6LPENCLRR_SDMMC1LPEN BIT(16) ++#define RCC_MP_AHB6LPENCLRR_SDMMC2LPEN BIT(17) ++#define RCC_MP_AHB6LPENCLRR_CRC1LPEN BIT(20) ++#define RCC_MP_AHB6LPENCLRR_USBHLPEN BIT(24) ++#define RCC_MP_AHB6LPENCLRR_ETH2CKLPEN BIT(27) ++#define RCC_MP_AHB6LPENCLRR_ETH2TXLPEN BIT(28) ++#define RCC_MP_AHB6LPENCLRR_ETH2RXLPEN BIT(29) ++#define RCC_MP_AHB6LPENCLRR_ETH2MACLPEN BIT(30) ++#define RCC_MP_AHB6LPENCLRR_ETH2STPEN BIT(31) ++ ++/* RCC_MP_S_AHB6LPENSETR register fields */ ++#define RCC_MP_S_AHB6LPENSETR_MDMALPEN BIT(0) ++ ++/* RCC_MP_S_AHB6LPENCLRR register fields */ ++#define RCC_MP_S_AHB6LPENCLRR_MDMALPEN BIT(0) ++ ++/* RCC_MP_NS_AHB6LPENSETR register fields */ ++#define RCC_MP_NS_AHB6LPENSETR_MDMALPEN BIT(0) ++ ++/* RCC_MP_NS_AHB6LPENCLRR register fields */ ++#define RCC_MP_NS_AHB6LPENCLRR_MDMALPEN BIT(0) ++ ++/* RCC_MP_S_AXIMLPENSETR register fields */ ++#define RCC_MP_S_AXIMLPENSETR_SYSRAMLPEN BIT(0) ++ ++/* RCC_MP_S_AXIMLPENCLRR register fields */ ++#define RCC_MP_S_AXIMLPENCLRR_SYSRAMLPEN BIT(0) ++ ++/* RCC_MP_NS_AXIMLPENSETR register fields */ ++#define RCC_MP_NS_AXIMLPENSETR_SYSRAMLPEN BIT(0) ++ ++/* RCC_MP_NS_AXIMLPENCLRR register fields */ ++#define RCC_MP_NS_AXIMLPENCLRR_SYSRAMLPEN BIT(0) ++ ++/* RCC_MP_MLAHBLPENSETR register fields */ ++#define RCC_MP_MLAHBLPENSETR_SRAM1LPEN BIT(0) ++#define RCC_MP_MLAHBLPENSETR_SRAM2LPEN BIT(1) ++#define RCC_MP_MLAHBLPENSETR_SRAM3LPEN BIT(2) ++ ++/* RCC_MP_MLAHBLPENCLRR register fields */ ++#define RCC_MP_MLAHBLPENCLRR_SRAM1LPEN BIT(0) ++#define RCC_MP_MLAHBLPENCLRR_SRAM2LPEN BIT(1) ++#define RCC_MP_MLAHBLPENCLRR_SRAM3LPEN BIT(2) ++ ++/* RCC_APB3SECSR register fields */ ++#define RCC_APB3SECSR_LPTIM2SECF 0 ++#define RCC_APB3SECSR_LPTIM3SECF 1 ++#define RCC_APB3SECSR_VREFSECF 13 ++ ++/* RCC_APB4SECSR register fields */ ++#define RCC_APB4SECSR_DCMIPPSECF 1 ++#define RCC_APB4SECSR_USBPHYSECF 16 ++ ++/* RCC_APB5SECSR register fields */ ++#define RCC_APB5SECSR_RTCSECF 8 ++#define RCC_APB5SECSR_TZCSECF 11 ++#define RCC_APB5SECSR_ETZPCSECF 13 ++#define RCC_APB5SECSR_IWDG1SECF 15 ++#define RCC_APB5SECSR_BSECSECF 16 ++#define RCC_APB5SECSR_STGENCSECF_MASK GENMASK(21, 20) ++#define RCC_APB5SECSR_STGENCSECF 20 ++#define RCC_APB5SECSR_STGENROSECF 21 ++ ++/* RCC_APB6SECSR register fields */ ++#define RCC_APB6SECSR_USART1SECF 0 ++#define RCC_APB6SECSR_USART2SECF 1 ++#define RCC_APB6SECSR_SPI4SECF 2 ++#define RCC_APB6SECSR_SPI5SECF 3 ++#define RCC_APB6SECSR_I2C3SECF 4 ++#define RCC_APB6SECSR_I2C4SECF 5 ++#define RCC_APB6SECSR_I2C5SECF 6 ++#define RCC_APB6SECSR_TIM12SECF 7 ++#define RCC_APB6SECSR_TIM13SECF 8 ++#define RCC_APB6SECSR_TIM14SECF 9 ++#define RCC_APB6SECSR_TIM15SECF 10 ++#define RCC_APB6SECSR_TIM16SECF 11 ++#define RCC_APB6SECSR_TIM17SECF 12 ++ ++/* RCC_AHB2SECSR register fields */ ++#define RCC_AHB2SECSR_DMA3SECF 3 ++#define RCC_AHB2SECSR_DMAMUX2SECF 4 ++#define RCC_AHB2SECSR_ADC1SECF 5 ++#define RCC_AHB2SECSR_ADC2SECF 6 ++#define RCC_AHB2SECSR_USBOSECF 8 ++ ++/* RCC_AHB4SECSR register fields */ ++#define RCC_AHB4SECSR_TSCSECF 15 ++ ++/* RCC_AHB5SECSR register fields */ ++#define RCC_AHB5SECSR_PKASECF 2 ++#define RCC_AHB5SECSR_SAESSECF 3 ++#define RCC_AHB5SECSR_CRYP1SECF 4 ++#define RCC_AHB5SECSR_HASH1SECF 5 ++#define RCC_AHB5SECSR_RNG1SECF 6 ++#define RCC_AHB5SECSR_BKPSRAMSECF 8 ++ ++/* RCC_AHB6SECSR register fields */ ++#define RCC_AHB6SECSR_MCESECF 1 ++#define RCC_AHB6SECSR_FMCSECF 12 ++#define RCC_AHB6SECSR_QSPISECF 14 ++#define RCC_AHB6SECSR_SDMMC1SECF 16 ++#define RCC_AHB6SECSR_SDMMC2SECF 17 ++ ++#define RCC_AHB6SECSR_ETH1SECF_MASK GENMASK(11, 7) ++#define RCC_AHB6SECSR_ETH2SECF_MASK GENMASK(31, 27) ++#define RCC_AHB6SECSR_ETH1SECF_SHIFT 7 ++#define RCC_AHB6SECSR_ETH2SECF_SHIFT 27 ++ ++#define RCC_AHB6SECSR_ETH1CKSECF 7 ++#define RCC_AHB6SECSR_ETH1TXSECF 8 ++#define RCC_AHB6SECSR_ETH1RXSECF 9 ++#define RCC_AHB6SECSR_ETH1MACSECF 10 ++#define RCC_AHB6SECSR_ETH1STPSECF 11 ++ ++#define RCC_AHB6SECSR_ETH2CKSECF 27 ++#define RCC_AHB6SECSR_ETH2TXSECF 28 ++#define RCC_AHB6SECSR_ETH2RXSECF 29 ++#define RCC_AHB6SECSR_ETH2MACSECF 30 ++#define RCC_AHB6SECSR_ETH2STPSECF 31 ++ ++/* RCC_VERR register fields */ ++#define RCC_VERR_MINREV_MASK GENMASK(3, 0) ++#define RCC_VERR_MAJREV_MASK GENMASK(7, 4) ++#define RCC_VERR_MINREV_SHIFT 0 ++#define RCC_VERR_MAJREV_SHIFT 4 ++ ++/* RCC_IDR register fields */ ++#define RCC_IDR_ID_MASK GENMASK(31, 0) ++#define RCC_IDR_ID_SHIFT 0 ++ ++/* RCC_SIDR register fields */ ++#define RCC_SIDR_SID_MASK GENMASK(31, 0) ++#define RCC_SIDR_SID_SHIFT 0 ++ ++#endif /* STM32MP13_RCC_H */ +diff --git a/drivers/core/device.c b/drivers/core/device.c +index 29668f6fb3..6f84762ebd 100644 +--- a/drivers/core/device.c ++++ b/drivers/core/device.c +@@ -1135,7 +1135,7 @@ int dev_enable_by_path(const char *path) + if (ret) + return ret; + +- return lists_bind_fdt(parent, node, NULL, false); ++ return lists_bind_fdt(parent, node, NULL, NULL, false); + } + #endif + +diff --git a/drivers/core/lists.c b/drivers/core/lists.c +index e214306b90..c9cd74a484 100644 +--- a/drivers/core/lists.c ++++ b/drivers/core/lists.c +@@ -182,7 +182,7 @@ static int driver_check_compatible(const struct udevice_id *of_match, + } + + int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp, +- bool pre_reloc_only) ++ struct driver *drv, bool pre_reloc_only) + { + struct driver *driver = ll_entry_start(struct driver, driver); + const int n_ents = ll_entry_count(struct driver, driver); +@@ -225,6 +225,8 @@ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp, + for (entry = driver; entry != driver + n_ents; entry++) { + ret = driver_check_compatible(entry->of_match, &id, + compat); ++ if ((drv) && (drv == entry)) ++ break; + if (!ret) + break; + } +diff --git a/drivers/core/root.c b/drivers/core/root.c +index 78eee082c9..86f9776733 100644 +--- a/drivers/core/root.c ++++ b/drivers/core/root.c +@@ -276,7 +276,7 @@ static int dm_scan_fdt_node(struct udevice *parent, ofnode parent_node, + pr_debug(" - ignoring disabled device\n"); + continue; + } +- err = lists_bind_fdt(parent, node, NULL, pre_reloc_only); ++ err = lists_bind_fdt(parent, node, NULL, NULL, pre_reloc_only); + if (err && !ret) { + ret = err; + debug("%s: ret=%d\n", node_name, ret); +diff --git a/drivers/demo/demo-uclass.c b/drivers/demo/demo-uclass.c +index 815f8de645..09f9a47d4d 100644 +--- a/drivers/demo/demo-uclass.c ++++ b/drivers/demo/demo-uclass.c +@@ -10,15 +10,11 @@ + #include + #include + #include +-#include + #include + #include +-#include + #include + #include + +-DECLARE_GLOBAL_DATA_PTR; +- + UCLASS_DRIVER(demo) = { + .name = "demo", + .id = UCLASS_DEMO, +@@ -67,10 +63,9 @@ int demo_set_light(struct udevice *dev, int light) + int demo_parse_dt(struct udevice *dev) + { + struct dm_demo_pdata *pdata = dev_get_plat(dev); +- int dn = dev_of_offset(dev); + +- pdata->sides = fdtdec_get_int(gd->fdt_blob, dn, "sides", 0); +- pdata->colour = fdt_getprop(gd->fdt_blob, dn, "colour", NULL); ++ pdata->sides = dev_read_s32_default(dev, "sides", 0); ++ pdata->colour = dev_read_string(dev, "colour"); + if (!pdata->sides || !pdata->colour) { + debug("%s: Invalid device tree data\n", __func__); + return -EINVAL; +diff --git a/drivers/dfu/dfu_mtd.c b/drivers/dfu/dfu_mtd.c +index 0b7f17761f..cce9ce0845 100644 +--- a/drivers/dfu/dfu_mtd.c ++++ b/drivers/dfu/dfu_mtd.c +@@ -18,6 +18,20 @@ static bool mtd_is_aligned_with_block_size(struct mtd_info *mtd, u64 size) + return !do_div(size, mtd->erasesize); + } + ++/* Logic taken from cmd/mtd.c:mtd_oob_write_is_empty() */ ++static bool mtd_page_is_empty(struct mtd_oob_ops *op) ++{ ++ int i; ++ ++ for (i = 0; i < op->len; i++) ++ if (op->datbuf[i] != 0xff) ++ return false; ++ ++ /* oob is not used, with MTD_OPS_AUTO_OOB & ooblen=0 */ ++ ++ return true; ++} ++ + static int mtd_block_op(enum dfu_op op, struct dfu_entity *dfu, + u64 offset, void *buf, long *len) + { +@@ -129,8 +143,14 @@ static int mtd_block_op(enum dfu_op op, struct dfu_entity *dfu, + + if (op == DFU_OP_READ) + ret = mtd_read_oob(mtd, off, &io_op); +- else ++ else if (has_pages && dfu->data.mtd.ubi && mtd_page_is_empty(&io_op)) { ++ /* in case of ubi partition, do not write an empty page, only skip it */ ++ ret = 0; ++ io_op.retlen = mtd->writesize; ++ io_op.oobretlen = mtd->oobsize; ++ } else { + ret = mtd_write_oob(mtd, off, &io_op); ++ } + + if (ret) { + printf("Failure while %s at offset 0x%llx\n", +diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig +index c3a109beac..8cf85f0d7a 100644 +--- a/drivers/firmware/scmi/Kconfig ++++ b/drivers/firmware/scmi/Kconfig +@@ -2,7 +2,7 @@ config SCMI_FIRMWARE + bool "Enable SCMI support" + select FIRMWARE + select OF_TRANSLATE +- depends on SANDBOX || DM_MAILBOX || ARM_SMCCC ++ depends on SANDBOX || DM_MAILBOX || ARM_SMCCC || OPTEE + help + System Control and Management Interface (SCMI) is a communication + protocol that defines standard interfaces for power, performance +@@ -14,6 +14,30 @@ config SCMI_FIRMWARE + or a companion host in the CPU system. + + Communications between agent (client) and the SCMI server are +- based on message exchange. Messages can be exchange over tranport ++ based on message exchange. Messages can be exchanged over transport + channels as a mailbox device or an Arm SMCCC service with some + piece of identified shared memory. ++ ++config SCMI_AGENT_MAILBOX ++ bool "Enable SCMI agent mailbox" ++ depends on SCMI_FIRMWARE && DM_MAILBOX ++ default y ++ help ++ Enable the SCMI communication channel based on mailbox ++ for compatible "arm,scmi". ++ ++config SCMI_AGENT_SMCCC ++ bool "Enable SCMI agent SMCCC" ++ depends on SCMI_FIRMWARE && ARM_SMCCC ++ default y ++ help ++ Enable the SCMI communication channel based on Arm SMCCC service for ++ compatible "arm,scmi-smc". ++ ++config SCMI_AGENT_OPTEE ++ bool "Enable SCMI agent OP-TEE" ++ depends on SCMI_FIRMWARE && OPTEE ++ default y ++ help ++ Enable the SCMI communication channel based on OP-TEE transport ++ for compatible "linaro,scmi-optee". +diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile +index e1e0224066..b2ff483c75 100644 +--- a/drivers/firmware/scmi/Makefile ++++ b/drivers/firmware/scmi/Makefile +@@ -1,5 +1,6 @@ + obj-y += scmi_agent-uclass.o + obj-y += smt.o +-obj-$(CONFIG_ARM_SMCCC) += smccc_agent.o +-obj-$(CONFIG_DM_MAILBOX) += mailbox_agent.o ++obj-$(CONFIG_SCMI_AGENT_SMCCC) += smccc_agent.o ++obj-$(CONFIG_SCMI_AGENT_MAILBOX) += mailbox_agent.o ++obj-$(CONFIG_SCMI_AGENT_OPTEE) += optee_agent.o + obj-$(CONFIG_SANDBOX) += sandbox-scmi_agent.o sandbox-scmi_devices.o +diff --git a/drivers/firmware/scmi/mailbox_agent.c b/drivers/firmware/scmi/mailbox_agent.c +index ea35e7e09e..8e4af0c8fa 100644 +--- a/drivers/firmware/scmi/mailbox_agent.c ++++ b/drivers/firmware/scmi/mailbox_agent.c +@@ -33,7 +33,7 @@ struct scmi_mbox_channel { + + static int scmi_mbox_process_msg(struct udevice *dev, struct scmi_msg *msg) + { +- struct scmi_mbox_channel *chan = dev_get_priv(dev); ++ struct scmi_mbox_channel *chan = dev_get_plat(dev); + int ret; + + ret = scmi_write_msg_to_smt(dev, &chan->smt, msg); +@@ -62,9 +62,9 @@ out: + return ret; + } + +-int scmi_mbox_probe(struct udevice *dev) ++int scmi_mbox_of_to_plat(struct udevice *dev) + { +- struct scmi_mbox_channel *chan = dev_get_priv(dev); ++ struct scmi_mbox_channel *chan = dev_get_plat(dev); + int ret; + + chan->timeout_us = TIMEOUT_US_10MS; +@@ -72,17 +72,13 @@ int scmi_mbox_probe(struct udevice *dev) + ret = mbox_get_by_index(dev, 0, &chan->mbox); + if (ret) { + dev_err(dev, "Failed to find mailbox: %d\n", ret); +- goto out; ++ return ret; + } + + ret = scmi_dt_get_smt_buffer(dev, &chan->smt); + if (ret) + dev_err(dev, "Failed to get shm resources: %d\n", ret); + +-out: +- if (ret) +- devm_kfree(dev, chan); +- + return ret; + } + +@@ -99,7 +95,7 @@ U_BOOT_DRIVER(scmi_mbox) = { + .name = "scmi-over-mailbox", + .id = UCLASS_SCMI_AGENT, + .of_match = scmi_mbox_ids, +- .priv_auto = sizeof(struct scmi_mbox_channel), +- .probe = scmi_mbox_probe, ++ .plat_auto = sizeof(struct scmi_mbox_channel), ++ .of_to_plat = scmi_mbox_of_to_plat, + .ops = &scmi_mbox_ops, + }; +diff --git a/drivers/firmware/scmi/optee_agent.c b/drivers/firmware/scmi/optee_agent.c +new file mode 100644 +index 0000000000..1f26592234 +--- /dev/null ++++ b/drivers/firmware/scmi/optee_agent.c +@@ -0,0 +1,312 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2020-2021 Linaro Limited. ++ */ ++ ++#define LOG_CATEGORY UCLASS_SCMI_AGENT ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "smt.h" ++ ++#define SCMI_SHM_SIZE 128 ++ ++/** ++ * struct scmi_optee_channel - Description of an SCMI OP-TEE transport ++ * @channel_id: Channel identifier ++ * @smt: Shared memory buffer with synchronisation protocol ++ * @dyn_shm: True if using dynamically allocated shared memory ++ */ ++struct scmi_optee_channel { ++ unsigned int channel_id; ++ struct scmi_smt smt; ++ bool dyn_shm; ++}; ++ ++/** ++ * struct channel_session - Aggreates SCMI service session context references ++ * @tee: OP-TEE device to invoke ++ * @tee_session: OP-TEE session identifier ++ * @tee_shm: Dynamically allocated OP-TEE shared memory, or NULL ++ * @channel_hdl: Channel handle provided by OP-TEE SCMI service ++ */ ++struct channel_session { ++ struct udevice *tee; ++ u32 tee_session; ++ struct tee_shm *tee_shm; ++ u32 channel_hdl; ++}; ++ ++#define TA_SCMI_UUID { 0xa8cfe406, 0xd4f5, 0x4a2e, \ ++ { 0x9f, 0x8d, 0xa2, 0x5d, 0xc7, 0x54, 0xc0, 0x99 } } ++ ++enum optee_smci_pta_cmd { ++ /* ++ * PTA_SCMI_CMD_CAPABILITIES - Get channel capabilities ++ * ++ * [out] value[0].a: Capability bit mask (enum pta_scmi_caps) ++ * [out] value[0].b: Extended capabilities or 0 ++ */ ++ PTA_SCMI_CMD_CAPABILITIES = 0, ++ ++ /* ++ * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL - Process SCMI message in SMT buffer ++ * ++ * [in] value[0].a: Channel handle ++ * ++ * Shared memory used for SCMI message/response exhange is expected ++ * already identified and bound to channel handle in both SCMI agent ++ * and SCMI server (OP-TEE) parts. ++ * The memory uses SMT header to carry SCMI meta-data (protocol ID and ++ * protocol message ID). ++ */ ++ PTA_SCMI_CMD_PROCESS_SMT_CHANNEL = 1, ++ ++ /* ++ * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE - Process SMT/SCMI message ++ * ++ * [in] value[0].a: Channel handle ++ * [in/out] memref[1]: Message/response buffer (SMT and SCMI payload) ++ * ++ * Shared memory used for SCMI message/response is a SMT buffer ++ * referenced by param[1]. It shall be 128 bytes large to fit response ++ * payload whatever message playload size. ++ * The memory uses SMT header to carry SCMI meta-data (protocol ID and ++ * protocol message ID). ++ */ ++ PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE = 2, ++ ++ /* ++ * PTA_SCMI_CMD_GET_CHANNEL - Get channel handle ++ * ++ * SCMI shm information are 0 if agent expects to use OP-TEE regular SHM ++ * ++ * [in] value[0].a: Channel identifier ++ * [out] value[0].a: Returned channel handle ++ * [in] value[0].b: Requested capabilities mask (enum pta_scmi_caps) ++ */ ++ PTA_SCMI_CMD_GET_CHANNEL = 3, ++}; ++ ++/* ++ * OP-TEE SCMI service capabilities bit flags (32bit) ++ * ++ * PTA_SCMI_CAPS_SMT_HEADER ++ * When set, OP-TEE supports command using SMT header protocol (SCMI shmem) in ++ * shared memory buffers to carry SCMI protocol synchronisation information. ++ */ ++#define PTA_SCMI_CAPS_NONE 0 ++#define PTA_SCMI_CAPS_SMT_HEADER BIT(0) ++ ++static int open_channel(struct udevice *dev, struct channel_session *sess) ++{ ++ const struct tee_optee_ta_uuid uuid = TA_SCMI_UUID; ++ struct scmi_optee_channel *chan = dev_get_plat(dev); ++ struct tee_open_session_arg sess_arg = { }; ++ struct tee_invoke_arg cmd_arg = { }; ++ struct tee_param param[1] = { }; ++ int ret; ++ ++ memset(sess, 0, sizeof(sess)); ++ ++ sess->tee = tee_find_device(NULL, NULL, NULL, NULL); ++ if (!sess->tee) ++ return -ENODEV; ++ ++ sess_arg.clnt_login = TEE_LOGIN_REE_KERNEL; ++ tee_optee_ta_uuid_to_octets(sess_arg.uuid, &uuid); ++ ++ ret = tee_open_session(sess->tee, &sess_arg, 0, NULL); ++ if (ret) { ++ dev_err(dev, "can't open session: %d\n", ret); ++ return ret; ++ } ++ ++ cmd_arg.func = PTA_SCMI_CMD_GET_CHANNEL; ++ cmd_arg.session = sess_arg.session; ++ ++ param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INOUT; ++ param[0].u.value.a = chan->channel_id; ++ param[0].u.value.b = PTA_SCMI_CAPS_SMT_HEADER; ++ ++ ret = tee_invoke_func(sess->tee, &cmd_arg, ARRAY_SIZE(param), param); ++ if (ret || cmd_arg.ret) { ++ dev_err(dev, "Invoke failed: %d, 0x%x\n", ret, cmd_arg.ret); ++ if (!ret) ++ ret = -EPROTO; ++ ++ tee_close_session(sess->tee, sess_arg.session); ++ return ret; ++ } ++ ++ sess->tee_session = sess_arg.session; ++ sess->channel_hdl = param[0].u.value.a; ++ ++ return 0; ++} ++ ++static void close_channel(struct channel_session *sess) ++{ ++ tee_close_session(sess->tee, sess->tee_session); ++} ++ ++static int invoke_cmd(struct udevice *dev, struct channel_session *sess, ++ struct scmi_msg *msg) ++{ ++ struct scmi_optee_channel *chan = dev_get_plat(dev); ++ struct tee_invoke_arg arg = { }; ++ struct tee_param param[2] = { }; ++ int ret; ++ ++ scmi_write_msg_to_smt(dev, &chan->smt, msg); ++ ++ arg.session = sess->tee_session; ++ param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT; ++ param[0].u.value.a = sess->channel_hdl; ++ ++ if (chan->dyn_shm) { ++ arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE; ++ param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT; ++ param[1].u.memref.shm = sess->tee_shm; ++ param[1].u.memref.size = SCMI_SHM_SIZE; ++ } else { ++ arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL; ++ } ++ ++ ret = tee_invoke_func(sess->tee, &arg, ARRAY_SIZE(param), param); ++ if (ret || arg.ret) { ++ if (!ret) ++ ret = -EPROTO; ++ } else { ++ ret = scmi_read_resp_from_smt(dev, &chan->smt, msg); ++ } ++ ++ scmi_clear_smt_channel(&chan->smt); ++ ++ return ret; ++} ++ ++static int prepare_shm(struct udevice *dev, struct channel_session *sess) ++{ ++ struct scmi_optee_channel *chan = dev_get_plat(dev); ++ int ret; ++ ++ /* Static shm is already prepared by the firmware: nothing to do */ ++ if (!chan->dyn_shm) ++ return 0; ++ ++ chan->smt.size = SCMI_SHM_SIZE; ++ ++ ret = tee_shm_alloc(sess->tee, chan->smt.size, 0, &sess->tee_shm); ++ if (ret) { ++ dev_err(dev, "Failed to allocated shmem: %d\n", ret); ++ return ret; ++ } ++ ++ chan->smt.buf = sess->tee_shm->addr; ++ ++ /* Initialize shm buffer for message exchanges */ ++ scmi_clear_smt_channel(&chan->smt); ++ ++ return 0; ++} ++ ++static void release_shm(struct udevice *dev, struct channel_session *sess) ++{ ++ struct scmi_optee_channel *chan = dev_get_plat(dev); ++ ++ if (chan->dyn_shm) ++ tee_shm_free(sess->tee_shm); ++} ++ ++static int scmi_optee_process_msg(struct udevice *dev, struct scmi_msg *msg) ++{ ++ struct channel_session sess; ++ int ret; ++ ++ ret = open_channel(dev, &sess); ++ if (ret) ++ return ret; ++ ++ ret = prepare_shm(dev, &sess); ++ if (ret) ++ goto out; ++ ++ ret = invoke_cmd(dev, &sess, msg); ++ ++ release_shm(dev, &sess); ++ ++out: ++ close_channel(&sess); ++ ++ return ret; ++} ++ ++static int scmi_optee_of_to_plat(struct udevice *dev) ++{ ++ struct scmi_optee_channel *chan = dev_get_plat(dev); ++ int ret; ++ ++ if (dev_read_u32(dev, "linaro,optee-channel-id", &chan->channel_id)) { ++ dev_err(dev, "Missing property linaro,optee-channel-id\n"); ++ return -EINVAL; ++ } ++ ++ if (dev_read_prop(dev, "shmem", NULL)) { ++ ret = scmi_dt_get_smt_buffer(dev, &chan->smt); ++ if (ret) { ++ dev_err(dev, "Failed to get smt resources: %d\n", ret); ++ return ret; ++ } ++ chan->dyn_shm = false; ++ } else { ++ chan->dyn_shm = true; ++ } ++ ++ return 0; ++} ++ ++static int scmi_optee_probe(struct udevice *dev) ++{ ++ struct channel_session sess; ++ int ret; ++ ++ /* Check OP-TEE service acknowledges the SCMI channel */ ++ ret = open_channel(dev, &sess); ++ if (!ret) ++ close_channel(&sess); ++ ++ return ret; ++} ++ ++static const struct udevice_id scmi_optee_ids[] = { ++ { .compatible = "linaro,scmi-optee" }, ++ { } ++}; ++ ++static const struct scmi_agent_ops scmi_optee_ops = { ++ .process_msg = scmi_optee_process_msg, ++}; ++ ++U_BOOT_DRIVER(scmi_optee) = { ++ .name = "scmi-over-optee", ++ .id = UCLASS_SCMI_AGENT, ++ .of_match = scmi_optee_ids, ++ .plat_auto = sizeof(struct scmi_optee_channel), ++ .of_to_plat = scmi_optee_of_to_plat, ++ .probe = scmi_optee_probe, ++ .flags = DM_FLAG_OS_PREPARE, ++ .ops = &scmi_optee_ops, ++}; +diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c b/drivers/firmware/scmi/sandbox-scmi_agent.c +index 4b968205c2..f7fda101e4 100644 +--- a/drivers/firmware/scmi/sandbox-scmi_agent.c ++++ b/drivers/firmware/scmi/sandbox-scmi_agent.c +@@ -19,51 +19,45 @@ + * The sandbox SCMI agent driver simulates to some extend a SCMI message + * processing. It simulates few of the SCMI services for some of the + * SCMI protocols embedded in U-Boot. Currently: +- * - SCMI clock protocol: emulate 2 agents each exposing few clocks +- * - SCMI reset protocol: emulate 1 agent exposing a reset controller +- * - SCMI voltage domain protocol: emulate 1 agent exposing 2 regulators ++ * - SCMI clock protocol emulates an agent exposing 2 clocks ++ * - SCMI reset protocol emulates an agent exposing a reset controller ++ * - SCMI voltage domain protocol emulates an agent exposing 2 regulators + * +- * Agent #0 simulates 2 clocks, 1 reset domain and 1 voltage domain. +- * See IDs in scmi0_clk[]/scmi0_reset[] and "sandbox-scmi-agent@0" in test.dts. +- * +- * Agent #1 simulates 1 clock. +- * See IDs in scmi1_clk[] and "sandbox-scmi-agent@1" in test.dts. ++ * As per DT bindings, the device node name shall be scmi. + * + * All clocks and regulators are default disabled and reset controller down. + * +- * This Driver exports sandbox_scmi_service_ctx() for the test sequence to ++ * This driver exports sandbox_scmi_service_ctx() for the test sequence to + * get the state of the simulated services (clock state, rate, ...) and + * check back-end device state reflects the request send through the + * various uclass devices, as clocks and reset controllers. + */ + +-#define SANDBOX_SCMI_AGENT_COUNT 2 +- +-static struct sandbox_scmi_clk scmi0_clk[] = { +- { .id = 7, .rate = 1000 }, +- { .id = 3, .rate = 333 }, ++static struct sandbox_scmi_clk scmi_clk[] = { ++ { .rate = 333 }, ++ { .rate = 200 }, ++ { .rate = 1000 }, + }; + +-static struct sandbox_scmi_reset scmi0_reset[] = { ++static struct sandbox_scmi_reset scmi_reset[] = { + { .id = 3 }, + }; + +-static struct sandbox_scmi_voltd scmi0_voltd[] = { ++static struct sandbox_scmi_voltd scmi_voltd[] = { + { .id = 0, .voltage_uv = 3300000 }, +- { .id = 1, .voltage_uv = 1800000 }, +-}; +- +-static struct sandbox_scmi_clk scmi1_clk[] = { +- { .id = 1, .rate = 44 }, ++ { .id = 6, .voltage_uv = 1800000 }, ++ /* ++ * Dummy unused regulators needed to be abled to ++ * expose voltage domain of highest ID (6). ++ */ ++ { .id = 1 }, ++ { .id = 2 }, ++ { .id = 3 }, ++ { .id = 4 }, ++ { .id = 5 }, + }; + +-/* The list saves to simulted end devices references for test purpose */ +-struct sandbox_scmi_agent *sandbox_scmi_agent_list[SANDBOX_SCMI_AGENT_COUNT]; +- +-static struct sandbox_scmi_service sandbox_scmi_service_state = { +- .agent = sandbox_scmi_agent_list, +- .agent_count = SANDBOX_SCMI_AGENT_COUNT, +-}; ++static struct sandbox_scmi_service sandbox_scmi_service_state; + + struct sandbox_scmi_service *sandbox_scmi_service_ctx(void) + { +@@ -74,9 +68,8 @@ static void debug_print_agent_state(struct udevice *dev, char *str) + { + struct sandbox_scmi_agent *agent = dev_get_priv(dev); + +- dev_dbg(dev, "Dump sandbox_scmi_agent %u: %s\n", agent->idx, str); +- dev_dbg(dev, " scmi%u_clk (%zu): %d/%ld, %d/%ld, %d/%ld, ...\n", +- agent->idx, ++ dev_dbg(dev, "Dump sandbox_scmi_agent: %s\n", str); ++ dev_dbg(dev, " scmi_clk (%zu): %d/%ld, %d/%ld, %d/%ld, ...\n", + agent->clk_count, + agent->clk_count ? agent->clk[0].enabled : -1, + agent->clk_count ? agent->clk[0].rate : -1, +@@ -84,13 +77,11 @@ static void debug_print_agent_state(struct udevice *dev, char *str) + agent->clk_count > 1 ? agent->clk[1].rate : -1, + agent->clk_count > 2 ? agent->clk[2].enabled : -1, + agent->clk_count > 2 ? agent->clk[2].rate : -1); +- dev_dbg(dev, " scmi%u_reset (%zu): %d, %d, ...\n", +- agent->idx, ++ dev_dbg(dev, " scmi_reset (%zu): %d, %d, ...\n", + agent->reset_count, + agent->reset_count ? agent->reset[0].asserted : -1, + agent->reset_count > 1 ? agent->reset[1].asserted : -1); +- dev_dbg(dev, " scmi%u_voltd (%zu): %u/%d, %u/%d, ...\n", +- agent->idx, ++ dev_dbg(dev, " scmi_voltd (%zu): %u/%d, %u/%d, ...\n", + agent->voltd_count, + agent->voltd_count ? agent->voltd[0].enabled : -1, + agent->voltd_count ? agent->voltd[0].voltage_uv : -1, +@@ -98,56 +89,32 @@ static void debug_print_agent_state(struct udevice *dev, char *str) + agent->voltd_count ? agent->voltd[1].voltage_uv : -1); + }; + +-static struct sandbox_scmi_clk *get_scmi_clk_state(uint agent_id, uint clock_id) ++static struct sandbox_scmi_clk *get_scmi_clk_state(uint clock_id) + { +- struct sandbox_scmi_clk *target = NULL; +- size_t target_count = 0; +- size_t n; +- +- switch (agent_id) { +- case 0: +- target = scmi0_clk; +- target_count = ARRAY_SIZE(scmi0_clk); +- break; +- case 1: +- target = scmi1_clk; +- target_count = ARRAY_SIZE(scmi1_clk); +- break; +- default: +- return NULL; +- } +- +- for (n = 0; n < target_count; n++) +- if (target[n].id == clock_id) +- return target + n; ++ if (clock_id < ARRAY_SIZE(scmi_clk)) ++ return scmi_clk + clock_id; + + return NULL; + } + +-static struct sandbox_scmi_reset *get_scmi_reset_state(uint agent_id, +- uint reset_id) ++static struct sandbox_scmi_reset *get_scmi_reset_state(uint reset_id) + { + size_t n; + +- if (agent_id == 0) { +- for (n = 0; n < ARRAY_SIZE(scmi0_reset); n++) +- if (scmi0_reset[n].id == reset_id) +- return scmi0_reset + n; +- } ++ for (n = 0; n < ARRAY_SIZE(scmi_reset); n++) ++ if (scmi_reset[n].id == reset_id) ++ return scmi_reset + n; + + return NULL; + } + +-static struct sandbox_scmi_voltd *get_scmi_voltd_state(uint agent_id, +- uint domain_id) ++static struct sandbox_scmi_voltd *get_scmi_voltd_state(uint domain_id) + { + size_t n; + +- if (agent_id == 0) { +- for (n = 0; n < ARRAY_SIZE(scmi0_voltd); n++) +- if (scmi0_voltd[n].id == domain_id) +- return scmi0_voltd + n; +- } ++ for (n = 0; n < ARRAY_SIZE(scmi_voltd); n++) ++ if (scmi_voltd[n].id == domain_id) ++ return scmi_voltd + n; + + return NULL; + } +@@ -156,10 +123,58 @@ static struct sandbox_scmi_voltd *get_scmi_voltd_state(uint agent_id, + * Sandbox SCMI agent ops + */ + ++static int sandbox_scmi_clock_protocol_attribs(struct udevice *dev, ++ struct scmi_msg *msg) ++{ ++ struct scmi_clk_protocol_attr_out *out = NULL; ++ ++ if (!msg->out_msg || msg->out_msg_sz < sizeof(*out)) ++ return -EINVAL; ++ ++ out = (struct scmi_clk_protocol_attr_out *)msg->out_msg; ++ out->attributes = ARRAY_SIZE(scmi_clk); ++ out->status = SCMI_SUCCESS; ++ ++ return 0; ++} ++ ++static int sandbox_scmi_clock_attribs(struct udevice *dev, struct scmi_msg *msg) ++{ ++ struct scmi_clk_attribute_in *in = NULL; ++ struct scmi_clk_attribute_out *out = NULL; ++ struct sandbox_scmi_clk *clk_state = NULL; ++ int ret; ++ ++ if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) || ++ !msg->out_msg || msg->out_msg_sz < sizeof(*out)) ++ return -EINVAL; ++ ++ in = (struct scmi_clk_attribute_in *)msg->in_msg; ++ out = (struct scmi_clk_attribute_out *)msg->out_msg; ++ ++ clk_state = get_scmi_clk_state(in->clock_id); ++ if (!clk_state) { ++ dev_err(dev, "Unexpected clock ID %u\n", in->clock_id); ++ ++ out->status = SCMI_NOT_FOUND; ++ } else { ++ memset(out, 0, sizeof(*out)); ++ ++ if (clk_state->enabled) ++ out->attributes = 1; ++ ++ ret = snprintf(out->clock_name, sizeof(out->clock_name), ++ "clk%u", in->clock_id); ++ assert(ret > 0 && ret < sizeof(out->clock_name)); ++ ++ out->status = SCMI_SUCCESS; ++ } ++ ++ return 0; ++} + static int sandbox_scmi_clock_rate_set(struct udevice *dev, + struct scmi_msg *msg) + { +- struct sandbox_scmi_agent *agent = dev_get_priv(dev); + struct scmi_clk_rate_set_in *in = NULL; + struct scmi_clk_rate_set_out *out = NULL; + struct sandbox_scmi_clk *clk_state = NULL; +@@ -171,7 +186,7 @@ static int sandbox_scmi_clock_rate_set(struct udevice *dev, + in = (struct scmi_clk_rate_set_in *)msg->in_msg; + out = (struct scmi_clk_rate_set_out *)msg->out_msg; + +- clk_state = get_scmi_clk_state(agent->idx, in->clock_id); ++ clk_state = get_scmi_clk_state(in->clock_id); + if (!clk_state) { + dev_err(dev, "Unexpected clock ID %u\n", in->clock_id); + +@@ -190,7 +205,6 @@ static int sandbox_scmi_clock_rate_set(struct udevice *dev, + static int sandbox_scmi_clock_rate_get(struct udevice *dev, + struct scmi_msg *msg) + { +- struct sandbox_scmi_agent *agent = dev_get_priv(dev); + struct scmi_clk_rate_get_in *in = NULL; + struct scmi_clk_rate_get_out *out = NULL; + struct sandbox_scmi_clk *clk_state = NULL; +@@ -202,7 +216,7 @@ static int sandbox_scmi_clock_rate_get(struct udevice *dev, + in = (struct scmi_clk_rate_get_in *)msg->in_msg; + out = (struct scmi_clk_rate_get_out *)msg->out_msg; + +- clk_state = get_scmi_clk_state(agent->idx, in->clock_id); ++ clk_state = get_scmi_clk_state(in->clock_id); + if (!clk_state) { + dev_err(dev, "Unexpected clock ID %u\n", in->clock_id); + +@@ -219,7 +233,6 @@ static int sandbox_scmi_clock_rate_get(struct udevice *dev, + + static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg) + { +- struct sandbox_scmi_agent *agent = dev_get_priv(dev); + struct scmi_clk_state_in *in = NULL; + struct scmi_clk_state_out *out = NULL; + struct sandbox_scmi_clk *clk_state = NULL; +@@ -231,7 +244,7 @@ static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg) + in = (struct scmi_clk_state_in *)msg->in_msg; + out = (struct scmi_clk_state_out *)msg->out_msg; + +- clk_state = get_scmi_clk_state(agent->idx, in->clock_id); ++ clk_state = get_scmi_clk_state(in->clock_id); + if (!clk_state) { + dev_err(dev, "Unexpected clock ID %u\n", in->clock_id); + +@@ -249,7 +262,6 @@ static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg) + + static int sandbox_scmi_rd_attribs(struct udevice *dev, struct scmi_msg *msg) + { +- struct sandbox_scmi_agent *agent = dev_get_priv(dev); + struct scmi_rd_attr_in *in = NULL; + struct scmi_rd_attr_out *out = NULL; + struct sandbox_scmi_reset *reset_state = NULL; +@@ -261,7 +273,7 @@ static int sandbox_scmi_rd_attribs(struct udevice *dev, struct scmi_msg *msg) + in = (struct scmi_rd_attr_in *)msg->in_msg; + out = (struct scmi_rd_attr_out *)msg->out_msg; + +- reset_state = get_scmi_reset_state(agent->idx, in->domain_id); ++ reset_state = get_scmi_reset_state(in->domain_id); + if (!reset_state) { + dev_err(dev, "Unexpected reset domain ID %u\n", in->domain_id); + +@@ -278,7 +290,6 @@ static int sandbox_scmi_rd_attribs(struct udevice *dev, struct scmi_msg *msg) + + static int sandbox_scmi_rd_reset(struct udevice *dev, struct scmi_msg *msg) + { +- struct sandbox_scmi_agent *agent = dev_get_priv(dev); + struct scmi_rd_reset_in *in = NULL; + struct scmi_rd_reset_out *out = NULL; + struct sandbox_scmi_reset *reset_state = NULL; +@@ -290,7 +301,7 @@ static int sandbox_scmi_rd_reset(struct udevice *dev, struct scmi_msg *msg) + in = (struct scmi_rd_reset_in *)msg->in_msg; + out = (struct scmi_rd_reset_out *)msg->out_msg; + +- reset_state = get_scmi_reset_state(agent->idx, in->domain_id); ++ reset_state = get_scmi_reset_state(in->domain_id); + if (!reset_state) { + dev_err(dev, "Unexpected reset domain ID %u\n", in->domain_id); + +@@ -319,9 +330,24 @@ static int sandbox_scmi_rd_reset(struct udevice *dev, struct scmi_msg *msg) + return 0; + } + ++static int sandbox_scmi_voltd_protocol_attribs(struct udevice *dev, ++ struct scmi_msg *msg) ++{ ++ struct scmi_voltd_protocol_attr_out *out = NULL; ++ ++ if (!msg->out_msg || msg->out_msg_sz < sizeof(*out)) ++ return -EINVAL; ++ ++ out = (struct scmi_voltd_protocol_attr_out *)msg->out_msg; ++ ++ out->attributes = ARRAY_SIZE(scmi_voltd); ++ out->status = SCMI_SUCCESS; ++ ++ return 0; ++} ++ + static int sandbox_scmi_voltd_attribs(struct udevice *dev, struct scmi_msg *msg) + { +- struct sandbox_scmi_agent *agent = dev_get_priv(dev); + struct scmi_voltd_attr_in *in = NULL; + struct scmi_voltd_attr_out *out = NULL; + struct sandbox_scmi_voltd *voltd_state = NULL; +@@ -333,7 +359,7 @@ static int sandbox_scmi_voltd_attribs(struct udevice *dev, struct scmi_msg *msg) + in = (struct scmi_voltd_attr_in *)msg->in_msg; + out = (struct scmi_voltd_attr_out *)msg->out_msg; + +- voltd_state = get_scmi_voltd_state(agent->idx, in->domain_id); ++ voltd_state = get_scmi_voltd_state(in->domain_id); + if (!voltd_state) { + dev_err(dev, "Unexpected domain ID %u\n", in->domain_id); + +@@ -351,7 +377,6 @@ static int sandbox_scmi_voltd_attribs(struct udevice *dev, struct scmi_msg *msg) + static int sandbox_scmi_voltd_config_set(struct udevice *dev, + struct scmi_msg *msg) + { +- struct sandbox_scmi_agent *agent = dev_get_priv(dev); + struct scmi_voltd_config_set_in *in = NULL; + struct scmi_voltd_config_set_out *out = NULL; + struct sandbox_scmi_voltd *voltd_state = NULL; +@@ -363,7 +388,7 @@ static int sandbox_scmi_voltd_config_set(struct udevice *dev, + in = (struct scmi_voltd_config_set_in *)msg->in_msg; + out = (struct scmi_voltd_config_set_out *)msg->out_msg; + +- voltd_state = get_scmi_voltd_state(agent->idx, in->domain_id); ++ voltd_state = get_scmi_voltd_state(in->domain_id); + if (!voltd_state) { + dev_err(dev, "Unexpected domain ID %u\n", in->domain_id); + +@@ -388,7 +413,6 @@ static int sandbox_scmi_voltd_config_set(struct udevice *dev, + static int sandbox_scmi_voltd_config_get(struct udevice *dev, + struct scmi_msg *msg) + { +- struct sandbox_scmi_agent *agent = dev_get_priv(dev); + struct scmi_voltd_config_get_in *in = NULL; + struct scmi_voltd_config_get_out *out = NULL; + struct sandbox_scmi_voltd *voltd_state = NULL; +@@ -400,7 +424,7 @@ static int sandbox_scmi_voltd_config_get(struct udevice *dev, + in = (struct scmi_voltd_config_get_in *)msg->in_msg; + out = (struct scmi_voltd_config_get_out *)msg->out_msg; + +- voltd_state = get_scmi_voltd_state(agent->idx, in->domain_id); ++ voltd_state = get_scmi_voltd_state(in->domain_id); + if (!voltd_state) { + dev_err(dev, "Unexpected domain ID %u\n", in->domain_id); + +@@ -420,7 +444,6 @@ static int sandbox_scmi_voltd_config_get(struct udevice *dev, + static int sandbox_scmi_voltd_level_set(struct udevice *dev, + struct scmi_msg *msg) + { +- struct sandbox_scmi_agent *agent = dev_get_priv(dev); + struct scmi_voltd_level_set_in *in = NULL; + struct scmi_voltd_level_set_out *out = NULL; + struct sandbox_scmi_voltd *voltd_state = NULL; +@@ -432,7 +455,7 @@ static int sandbox_scmi_voltd_level_set(struct udevice *dev, + in = (struct scmi_voltd_level_set_in *)msg->in_msg; + out = (struct scmi_voltd_level_set_out *)msg->out_msg; + +- voltd_state = get_scmi_voltd_state(agent->idx, in->domain_id); ++ voltd_state = get_scmi_voltd_state(in->domain_id); + if (!voltd_state) { + dev_err(dev, "Unexpected domain ID %u\n", in->domain_id); + +@@ -448,7 +471,6 @@ static int sandbox_scmi_voltd_level_set(struct udevice *dev, + static int sandbox_scmi_voltd_level_get(struct udevice *dev, + struct scmi_msg *msg) + { +- struct sandbox_scmi_agent *agent = dev_get_priv(dev); + struct scmi_voltd_level_get_in *in = NULL; + struct scmi_voltd_level_get_out *out = NULL; + struct sandbox_scmi_voltd *voltd_state = NULL; +@@ -460,7 +482,7 @@ static int sandbox_scmi_voltd_level_get(struct udevice *dev, + in = (struct scmi_voltd_level_get_in *)msg->in_msg; + out = (struct scmi_voltd_level_get_out *)msg->out_msg; + +- voltd_state = get_scmi_voltd_state(agent->idx, in->domain_id); ++ voltd_state = get_scmi_voltd_state(in->domain_id); + if (!voltd_state) { + dev_err(dev, "Unexpected domain ID %u\n", in->domain_id); + +@@ -479,6 +501,10 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev, + switch (msg->protocol_id) { + case SCMI_PROTOCOL_ID_CLOCK: + switch (msg->message_id) { ++ case SCMI_PROTOCOL_ATTRIBUTES: ++ return sandbox_scmi_clock_protocol_attribs(dev, msg); ++ case SCMI_CLOCK_ATTRIBUTES: ++ return sandbox_scmi_clock_attribs(dev, msg); + case SCMI_CLOCK_RATE_SET: + return sandbox_scmi_clock_rate_set(dev, msg); + case SCMI_CLOCK_RATE_GET: +@@ -501,6 +527,8 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev, + break; + case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN: + switch (msg->message_id) { ++ case SCMI_PROTOCOL_ATTRIBUTES: ++ return sandbox_scmi_voltd_protocol_attribs(dev, msg); + case SCMI_VOLTAGE_DOMAIN_ATTRIBUTES: + return sandbox_scmi_voltd_attribs(dev, msg); + case SCMI_VOLTAGE_DOMAIN_CONFIG_SET: +@@ -541,52 +569,41 @@ static int sandbox_scmi_test_remove(struct udevice *dev) + { + struct sandbox_scmi_agent *agent = dev_get_priv(dev); + ++ if (agent != sandbox_scmi_service_ctx()->agent) ++ return -EINVAL; ++ + debug_print_agent_state(dev, "removed"); + + /* We only need to dereference the agent in the context */ +- sandbox_scmi_service_ctx()->agent[agent->idx] = NULL; ++ sandbox_scmi_service_ctx()->agent = NULL; + + return 0; + } + + static int sandbox_scmi_test_probe(struct udevice *dev) + { +- static const char basename[] = "sandbox-scmi-agent@"; ++ static const char basename[] = "scmi"; + struct sandbox_scmi_agent *agent = dev_get_priv(dev); +- const size_t basename_size = sizeof(basename) - 1; + +- if (strncmp(basename, dev->name, basename_size)) ++ if (strcmp(basename, dev->name)) + return -ENOENT; + +- switch (dev->name[basename_size]) { +- case '0': +- *agent = (struct sandbox_scmi_agent){ +- .idx = 0, +- .clk = scmi0_clk, +- .clk_count = ARRAY_SIZE(scmi0_clk), +- .reset = scmi0_reset, +- .reset_count = ARRAY_SIZE(scmi0_reset), +- .voltd = scmi0_voltd, +- .voltd_count = ARRAY_SIZE(scmi0_voltd), +- }; +- break; +- case '1': +- *agent = (struct sandbox_scmi_agent){ +- .idx = 1, +- .clk = scmi1_clk, +- .clk_count = ARRAY_SIZE(scmi1_clk), +- }; +- break; +- default: +- dev_err(dev, "%s(): Unexpected agent ID %s\n", +- __func__, dev->name + basename_size); +- return -ENOENT; +- } ++ if (sandbox_scmi_service_ctx()->agent) ++ return -EINVAL; ++ ++ *agent = (struct sandbox_scmi_agent){ ++ .clk = scmi_clk, ++ .clk_count = ARRAY_SIZE(scmi_clk), ++ .reset = scmi_reset, ++ .reset_count = ARRAY_SIZE(scmi_reset), ++ .voltd = scmi_voltd, ++ .voltd_count = ARRAY_SIZE(scmi_voltd), ++ }; + + debug_print_agent_state(dev, "probed"); + + /* Save reference for tests purpose */ +- sandbox_scmi_service_ctx()->agent[agent->idx] = agent; ++ sandbox_scmi_service_ctx()->agent = agent; + + return 0; + }; +diff --git a/drivers/firmware/scmi/sandbox-scmi_devices.c b/drivers/firmware/scmi/sandbox-scmi_devices.c +index 66a6792881..9baeb469ec 100644 +--- a/drivers/firmware/scmi/sandbox-scmi_devices.c ++++ b/drivers/firmware/scmi/sandbox-scmi_devices.c +@@ -23,7 +23,7 @@ + * and reset controllers. + */ + +-#define SCMI_TEST_DEVICES_CLK_COUNT 3 ++#define SCMI_TEST_DEVICES_CLK_COUNT 2 + #define SCMI_TEST_DEVICES_RD_COUNT 1 + #define SCMI_TEST_DEVICES_VOLTD_COUNT 2 + +@@ -135,7 +135,7 @@ U_BOOT_DRIVER(sandbox_scmi_devices) = { + .name = "sandbox-scmi_devices", + .id = UCLASS_MISC, + .of_match = sandbox_scmi_devices_ids, +- .priv_auto = sizeof(struct sandbox_scmi_device_priv), ++ .priv_auto = sizeof(struct sandbox_scmi_device_priv), + .remove = sandbox_scmi_devices_remove, + .probe = sandbox_scmi_devices_probe, + }; +diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c +index 4f5870b483..3819f2fa99 100644 +--- a/drivers/firmware/scmi/scmi_agent-uclass.c ++++ b/drivers/firmware/scmi/scmi_agent-uclass.c +@@ -116,10 +116,23 @@ static const struct scmi_agent_ops *transport_dev_ops(struct udevice *dev) + + int devm_scmi_process_msg(struct udevice *dev, struct scmi_msg *msg) + { +- const struct scmi_agent_ops *ops = transport_dev_ops(dev); ++ const struct scmi_agent_ops *ops; ++ struct udevice *parent = dev; ++ ++ /* Find related SCMI agent device */ ++ do { ++ parent = dev_get_parent(parent); ++ } while (parent && device_get_uclass_id(parent) != UCLASS_SCMI_AGENT); ++ ++ if (!parent) { ++ dev_err(dev, "Invalid SCMI device, agent not found\n"); ++ return -ENODEV; ++ } ++ ++ ops = transport_dev_ops(parent); + + if (ops->process_msg) +- return ops->process_msg(dev, msg); ++ return ops->process_msg(parent, msg); + + return -EPROTONOSUPPORT; + } +diff --git a/drivers/firmware/scmi/smccc_agent.c b/drivers/firmware/scmi/smccc_agent.c +index f185891e8f..5e166ca93e 100644 +--- a/drivers/firmware/scmi/smccc_agent.c ++++ b/drivers/firmware/scmi/smccc_agent.c +@@ -32,7 +32,7 @@ struct scmi_smccc_channel { + + static int scmi_smccc_process_msg(struct udevice *dev, struct scmi_msg *msg) + { +- struct scmi_smccc_channel *chan = dev_get_priv(dev); ++ struct scmi_smccc_channel *chan = dev_get_plat(dev); + struct arm_smccc_res res; + int ret; + +@@ -51,9 +51,9 @@ static int scmi_smccc_process_msg(struct udevice *dev, struct scmi_msg *msg) + return ret; + } + +-static int scmi_smccc_probe(struct udevice *dev) ++static int scmi_smccc_of_to_plat(struct udevice *dev) + { +- struct scmi_smccc_channel *chan = dev_get_priv(dev); ++ struct scmi_smccc_channel *chan = dev_get_plat(dev); + u32 func_id; + int ret; + +@@ -65,12 +65,10 @@ static int scmi_smccc_probe(struct udevice *dev) + chan->func_id = func_id; + + ret = scmi_dt_get_smt_buffer(dev, &chan->smt); +- if (ret) { ++ if (ret) + dev_err(dev, "Failed to get smt resources: %d\n", ret); +- return ret; +- } + +- return 0; ++ return ret; + } + + static const struct udevice_id scmi_smccc_ids[] = { +@@ -86,7 +84,7 @@ U_BOOT_DRIVER(scmi_smccc) = { + .name = "scmi-over-smccc", + .id = UCLASS_SCMI_AGENT, + .of_match = scmi_smccc_ids, +- .priv_auto = sizeof(struct scmi_smccc_channel), +- .probe = scmi_smccc_probe, ++ .plat_auto = sizeof(struct scmi_smccc_channel), ++ .of_to_plat = scmi_smccc_of_to_plat, + .ops = &scmi_smccc_ops, + }; +diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c +index 125c237551..e150fe3429 100644 +--- a/drivers/gpio/stm32_gpio.c ++++ b/drivers/gpio/stm32_gpio.c +@@ -11,7 +11,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -20,6 +19,8 @@ + #include + #include + ++#include "stm32_gpio_priv.h" ++ + #define STM32_GPIOS_PER_BANK 16 + + #define MODE_BITS(gpio_pin) ((gpio_pin) * 2) +@@ -32,6 +33,9 @@ + #define OTYPE_BITS(gpio_pin) (gpio_pin) + #define OTYPE_MSK 1 + ++#define SECCFG_BITS(gpio_pin) (gpio_pin) ++#define SECCFG_MSK 1 ++ + static void stm32_gpio_set_moder(struct stm32_gpio_regs *regs, + int idx, + int mode) +@@ -82,38 +86,43 @@ static enum stm32_gpio_pupd stm32_gpio_get_pupd(struct stm32_gpio_regs *regs, + return (readl(®s->pupdr) >> PUPD_BITS(idx)) & PUPD_MASK; + } + +-/* +- * convert gpio offset to gpio index taking into account gpio holes +- * into gpio bank +- */ +-int stm32_offset_to_index(struct udevice *dev, unsigned int offset) ++static bool stm32_gpio_is_mapped(struct udevice *dev, int offset) ++{ ++ struct stm32_gpio_priv *priv = dev_get_priv(dev); ++ ++ return !!(priv->gpio_range & BIT(offset)); ++} ++ ++static int stm32_gpio_request(struct udevice *dev, unsigned offset, const char *label) + { + struct stm32_gpio_priv *priv = dev_get_priv(dev); +- unsigned int idx = 0; +- int i; +- +- for (i = 0; i < STM32_GPIOS_PER_BANK; i++) { +- if (priv->gpio_range & BIT(i)) { +- if (idx == offset) +- return idx; +- idx++; +- } ++ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); ++ struct stm32_gpio_regs *regs = priv->regs; ++ ulong drv_data = dev_get_driver_data(dev); ++ ++ if (!stm32_gpio_is_mapped(dev, offset)) ++ return -ENXIO; ++ ++ /* Deny request access if IO is secured */ ++ if ((drv_data & STM32_GPIO_FLAG_SEC_CTRL) && ++ ((readl(®s->seccfgr) >> SECCFG_BITS(offset)) & SECCFG_MSK)) { ++ dev_err(dev, "Failed to get secure IO %s %d @ %p\n", ++ uc_priv->bank_name, offset, regs); ++ return -EACCES; + } +- /* shouldn't happen */ +- return -EINVAL; ++ ++ return 0; + } + + static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset) + { + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; +- int idx; + +- idx = stm32_offset_to_index(dev, offset); +- if (idx < 0) +- return idx; ++ if (!stm32_gpio_is_mapped(dev, offset)) ++ return -ENXIO; + +- stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN); ++ stm32_gpio_set_moder(regs, offset, STM32_GPIO_MODE_IN); + + return 0; + } +@@ -123,15 +132,13 @@ static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset, + { + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; +- int idx; + +- idx = stm32_offset_to_index(dev, offset); +- if (idx < 0) +- return idx; ++ if (!stm32_gpio_is_mapped(dev, offset)) ++ return -ENXIO; + +- stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT); ++ stm32_gpio_set_moder(regs, offset, STM32_GPIO_MODE_OUT); + +- writel(BSRR_BIT(idx, value), ®s->bsrr); ++ writel(BSRR_BIT(offset, value), ®s->bsrr); + + return 0; + } +@@ -140,26 +147,22 @@ static int stm32_gpio_get_value(struct udevice *dev, unsigned offset) + { + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; +- int idx; + +- idx = stm32_offset_to_index(dev, offset); +- if (idx < 0) +- return idx; ++ if (!stm32_gpio_is_mapped(dev, offset)) ++ return -ENXIO; + +- return readl(®s->idr) & BIT(idx) ? 1 : 0; ++ return readl(®s->idr) & BIT(offset) ? 1 : 0; + } + + static int stm32_gpio_set_value(struct udevice *dev, unsigned offset, int value) + { + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; +- int idx; + +- idx = stm32_offset_to_index(dev, offset); +- if (idx < 0) +- return idx; ++ if (!stm32_gpio_is_mapped(dev, offset)) ++ return -ENXIO; + +- writel(BSRR_BIT(idx, value), ®s->bsrr); ++ writel(BSRR_BIT(offset, value), ®s->bsrr); + + return 0; + } +@@ -170,14 +173,12 @@ static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset) + struct stm32_gpio_regs *regs = priv->regs; + int bits_index; + int mask; +- int idx; + u32 mode; + +- idx = stm32_offset_to_index(dev, offset); +- if (idx < 0) +- return idx; ++ if (!stm32_gpio_is_mapped(dev, offset)) ++ return GPIOF_UNKNOWN; + +- bits_index = MODE_BITS(idx); ++ bits_index = MODE_BITS(offset); + mask = MODE_BITS_MASK << bits_index; + + mode = (readl(®s->moder) & mask) >> bits_index; +@@ -196,30 +197,28 @@ static int stm32_gpio_set_flags(struct udevice *dev, unsigned int offset, + { + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; +- int idx; + +- idx = stm32_offset_to_index(dev, offset); +- if (idx < 0) +- return idx; ++ if (!stm32_gpio_is_mapped(dev, offset)) ++ return -ENXIO; + + if (flags & GPIOD_IS_OUT) { + bool value = flags & GPIOD_IS_OUT_ACTIVE; + + if (flags & GPIOD_OPEN_DRAIN) +- stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD); ++ stm32_gpio_set_otype(regs, offset, STM32_GPIO_OTYPE_OD); + else +- stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP); ++ stm32_gpio_set_otype(regs, offset, STM32_GPIO_OTYPE_PP); + +- stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT); +- writel(BSRR_BIT(idx, value), ®s->bsrr); ++ stm32_gpio_set_moder(regs, offset, STM32_GPIO_MODE_OUT); ++ writel(BSRR_BIT(offset, value), ®s->bsrr); + + } else if (flags & GPIOD_IS_IN) { +- stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN); ++ stm32_gpio_set_moder(regs, offset, STM32_GPIO_MODE_IN); + } + if (flags & GPIOD_PULL_UP) +- stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_UP); ++ stm32_gpio_set_pupd(regs, offset, STM32_GPIO_PUPD_UP); + else if (flags & GPIOD_PULL_DOWN) +- stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_DOWN); ++ stm32_gpio_set_pupd(regs, offset, STM32_GPIO_PUPD_DOWN); + + return 0; + } +@@ -229,19 +228,17 @@ static int stm32_gpio_get_flags(struct udevice *dev, unsigned int offset, + { + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; +- int idx; + ulong dir_flags = 0; + +- idx = stm32_offset_to_index(dev, offset); +- if (idx < 0) +- return idx; ++ if (!stm32_gpio_is_mapped(dev, offset)) ++ return -ENXIO; + +- switch (stm32_gpio_get_moder(regs, idx)) { ++ switch (stm32_gpio_get_moder(regs, offset)) { + case STM32_GPIO_MODE_OUT: + dir_flags |= GPIOD_IS_OUT; +- if (stm32_gpio_get_otype(regs, idx) == STM32_GPIO_OTYPE_OD) ++ if (stm32_gpio_get_otype(regs, offset) == STM32_GPIO_OTYPE_OD) + dir_flags |= GPIOD_OPEN_DRAIN; +- if (readl(®s->idr) & BIT(idx)) ++ if (readl(®s->idr) & BIT(offset)) + dir_flags |= GPIOD_IS_OUT_ACTIVE; + break; + case STM32_GPIO_MODE_IN: +@@ -250,7 +247,7 @@ static int stm32_gpio_get_flags(struct udevice *dev, unsigned int offset, + default: + break; + } +- switch (stm32_gpio_get_pupd(regs, idx)) { ++ switch (stm32_gpio_get_pupd(regs, offset)) { + case STM32_GPIO_PUPD_UP: + dir_flags |= GPIOD_PULL_UP; + break; +@@ -266,6 +263,7 @@ static int stm32_gpio_get_flags(struct udevice *dev, unsigned int offset, + } + + static const struct dm_gpio_ops gpio_stm32_ops = { ++ .request = stm32_gpio_request, + .direction_input = stm32_gpio_direction_input, + .direction_output = stm32_gpio_direction_output, + .get_value = stm32_gpio_get_value, +@@ -303,17 +301,14 @@ static int gpio_stm32_probe(struct udevice *dev) + if (!ret && args.args_count < 3) + return -EINVAL; + +- if (ret == -ENOENT) { +- uc_priv->gpio_count = STM32_GPIOS_PER_BANK; ++ uc_priv->gpio_count = STM32_GPIOS_PER_BANK; ++ if (ret == -ENOENT) + priv->gpio_range = GENMASK(STM32_GPIOS_PER_BANK - 1, 0); +- } + + while (ret != -ENOENT) { + priv->gpio_range |= GENMASK(args.args[2] + args.args[0] - 1, + args.args[0]); + +- uc_priv->gpio_count += args.args[2]; +- + ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3, + ++i, &args); + if (!ret && args.args_count < 3) +diff --git a/arch/arm/include/asm/arch-stm32/gpio.h b/drivers/gpio/stm32_gpio_priv.h +similarity index 87% +rename from arch/arm/include/asm/arch-stm32/gpio.h +rename to drivers/gpio/stm32_gpio_priv.h +index 233ce278a7..d89e9b8ed6 100644 +--- a/arch/arm/include/asm/arch-stm32/gpio.h ++++ b/drivers/gpio/stm32_gpio_priv.h +@@ -4,8 +4,8 @@ + * Author(s): Vikas Manocha, for STMicroelectronics. + */ + +-#ifndef _GPIO_H_ +-#define _GPIO_H_ ++#ifndef _STM32_GPIO_PRIV_H_ ++#define _STM32_GPIO_PRIV_H_ + + enum stm32_gpio_mode { + STM32_GPIO_MODE_IN = 0, +@@ -51,6 +51,8 @@ enum stm32_gpio_af { + STM32_GPIO_AF15 + }; + ++#define STM32_GPIO_FLAG_SEC_CTRL BIT(0) ++ + struct stm32_gpio_dsc { + u8 port; + u8 pin; +@@ -74,6 +76,9 @@ struct stm32_gpio_regs { + u32 bsrr; /* GPIO port bit set/reset */ + u32 lckr; /* GPIO port configuration lock */ + u32 afr[2]; /* GPIO alternate function */ ++ u32 brr; /* GPIO port bit reset */ ++ u32 rfu; /* Reserved */ ++ u32 seccfgr; /* GPIO secure configuration */ + }; + + struct stm32_gpio_priv { +@@ -81,6 +86,4 @@ struct stm32_gpio_priv { + unsigned int gpio_range; + }; + +-int stm32_offset_to_index(struct udevice *dev, unsigned int offset); +- +-#endif /* _GPIO_H_ */ ++#endif /* _STM32_GPIO_PRIV_H_ */ +diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c +index 7b04a09de0..bf2a6c9b4b 100644 +--- a/drivers/i2c/stm32f7_i2c.c ++++ b/drivers/i2c/stm32f7_i2c.c +@@ -45,6 +45,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) +@@ -105,10 +107,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 */ + +@@ -156,9 +156,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; +@@ -167,6 +166,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; + }; + +@@ -197,16 +203,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[] = { +@@ -251,21 +259,18 @@ 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, + }; + ++static const struct stm32_i2c_data stm32mp13_data = { ++ .fmp_clr_offset = 0x4, ++}; ++ + static int stm32_i2c_check_device_busy(struct stm32_i2c_priv *i2c_priv) + { + struct stm32_i2c_regs *regs = i2c_priv->regs; +@@ -506,14 +511,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; +@@ -581,7 +585,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) +@@ -590,8 +595,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; +@@ -678,12 +681,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); +@@ -701,6 +705,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) { + log_err("DNF out of bound %d/%d\n", + setup->dnf, STM32_I2C_DNF_MAX); +@@ -708,11 +714,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; + +@@ -745,7 +751,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; +@@ -757,7 +763,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) { + log_debug("failed to compute I2C timings.\n"); + if (setup->speed_freq > I2C_SPEED_STANDARD_RATE) { +@@ -839,10 +845,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 +914,26 @@ clk_free: + + static int stm32_of_to_plat(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 +946,7 @@ static int stm32_of_to_plat(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 +959,9 @@ 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 }, ++ { .compatible = "st,stm32mp13-i2c", .data = (ulong)&stm32mp13_data }, + {} + }; + +diff --git a/drivers/misc/imx8/scu.c b/drivers/misc/imx8/scu.c +index 035a600f71..4ab5cb4bf1 100644 +--- a/drivers/misc/imx8/scu.c ++++ b/drivers/misc/imx8/scu.c +@@ -219,7 +219,7 @@ static int imx8_scu_bind(struct udevice *dev) + + debug("%s(dev=%p)\n", __func__, dev); + ofnode_for_each_subnode(node, dev_ofnode(dev)) { +- ret = lists_bind_fdt(dev, node, &child, true); ++ ret = lists_bind_fdt(dev, node, &child, NULL, true); + if (ret) + return ret; + debug("bind child dev %s\n", child->name); +diff --git a/drivers/misc/stm32_rcc.c b/drivers/misc/stm32_rcc.c +index f14d6e26d9..b816503bfa 100644 +--- a/drivers/misc/stm32_rcc.c ++++ b/drivers/misc/stm32_rcc.c +@@ -39,6 +39,11 @@ struct stm32_rcc_clk stm32_rcc_clk_mp1 = { + .soc = STM32MP1, + }; + ++struct stm32_rcc_clk stm32_rcc_clk_mp13 = { ++ .drv_name = "stm32mp13_clk", ++ .soc = STM32MP1, ++}; ++ + static int stm32_rcc_bind(struct udevice *dev) + { + struct udevice *child; +@@ -79,6 +84,7 @@ static const struct udevice_id stm32_rcc_ids[] = { + {.compatible = "st,stm32f746-rcc", .data = (ulong)&stm32_rcc_clk_f7 }, + {.compatible = "st,stm32h743-rcc", .data = (ulong)&stm32_rcc_clk_h7 }, + {.compatible = "st,stm32mp1-rcc", .data = (ulong)&stm32_rcc_clk_mp1 }, ++ {.compatible = "st,stm32mp13-rcc", .data = (ulong)&stm32_rcc_clk_mp13 }, + { } + }; + +diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c +index d23b7d9729..eab94c7b60 100644 +--- a/drivers/mmc/mmc_write.c ++++ b/drivers/mmc/mmc_write.c +@@ -102,7 +102,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) + "The erase range would be change to " + "0x" LBAF "~0x" LBAF "\n\n", + mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1), +- ((start + blkcnt + mmc->erase_grp_size) ++ ((start + blkcnt + mmc->erase_grp_size - 1) + & ~(mmc->erase_grp_size - 1)) - 1); + + while (blk < blkcnt) { +diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c +index a3cdf7bcd9..1bfe82a0ba 100644 +--- a/drivers/mmc/stm32_sdmmc2.c ++++ b/drivers/mmc/stm32_sdmmc2.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -29,9 +30,6 @@ + struct stm32_sdmmc2_plat { + struct mmc_config cfg; + struct mmc mmc; +-}; +- +-struct stm32_sdmmc2_priv { + fdt_addr_t base; + struct clk clk; + struct reset_ctl reset_ctl; +@@ -207,7 +205,7 @@ static void stm32_sdmmc2_start_data(struct udevice *dev, + struct mmc_data *data, + struct stm32_sdmmc2_ctx *ctx) + { +- struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); ++ struct stm32_sdmmc2_plat *plat = dev_get_plat(dev); + u32 data_ctrl, idmabase0; + + /* Configure the SDMMC DPSM (Data Path State Machine) */ +@@ -223,10 +221,10 @@ static void stm32_sdmmc2_start_data(struct udevice *dev, + } + + /* Set the SDMMC DataLength value */ +- writel(ctx->data_length, priv->base + SDMMC_DLEN); ++ writel(ctx->data_length, plat->base + SDMMC_DLEN); + + /* Write to SDMMC DCTRL */ +- writel(data_ctrl, priv->base + SDMMC_DCTRL); ++ writel(data_ctrl, plat->base + SDMMC_DCTRL); + + /* Cache align */ + ctx->cache_start = rounddown(idmabase0, ARCH_DMA_MINALIGN); +@@ -241,19 +239,19 @@ static void stm32_sdmmc2_start_data(struct udevice *dev, + flush_dcache_range(ctx->cache_start, ctx->cache_end); + + /* Enable internal DMA */ +- writel(idmabase0, priv->base + SDMMC_IDMABASE0); +- writel(SDMMC_IDMACTRL_IDMAEN, priv->base + SDMMC_IDMACTRL); ++ writel(idmabase0, plat->base + SDMMC_IDMABASE0); ++ writel(SDMMC_IDMACTRL_IDMAEN, plat->base + SDMMC_IDMACTRL); + } + + static void stm32_sdmmc2_start_cmd(struct udevice *dev, + struct mmc_cmd *cmd, u32 cmd_param, + struct stm32_sdmmc2_ctx *ctx) + { +- struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); ++ struct stm32_sdmmc2_plat *plat = dev_get_plat(dev); + u32 timeout = 0; + +- if (readl(priv->base + SDMMC_CMD) & SDMMC_CMD_CPSMEN) +- writel(0, priv->base + SDMMC_CMD); ++ if (readl(plat->base + SDMMC_CMD) & SDMMC_CMD_CPSMEN) ++ writel(0, plat->base + SDMMC_CMD); + + cmd_param |= cmd->cmdidx | SDMMC_CMD_CPSMEN; + if (cmd->resp_type & MMC_RSP_PRESENT) { +@@ -276,30 +274,30 @@ static void stm32_sdmmc2_start_cmd(struct udevice *dev, + if (ctx->data_length) { + timeout = SDMMC_CMD_TIMEOUT; + } else { +- writel(0, priv->base + SDMMC_DCTRL); ++ writel(0, plat->base + SDMMC_DCTRL); + + if (cmd->resp_type & MMC_RSP_BUSY) + timeout = SDMMC_CMD_TIMEOUT; + } + + /* Set the SDMMC Data TimeOut value */ +- writel(timeout, priv->base + SDMMC_DTIMER); ++ writel(timeout, plat->base + SDMMC_DTIMER); + + /* Clear flags */ +- writel(SDMMC_ICR_STATIC_FLAGS, priv->base + SDMMC_ICR); ++ writel(SDMMC_ICR_STATIC_FLAGS, plat->base + SDMMC_ICR); + + /* Set SDMMC argument value */ +- writel(cmd->cmdarg, priv->base + SDMMC_ARG); ++ writel(cmd->cmdarg, plat->base + SDMMC_ARG); + + /* Set SDMMC command parameters */ +- writel(cmd_param, priv->base + SDMMC_CMD); ++ writel(cmd_param, plat->base + SDMMC_CMD); + } + + static int stm32_sdmmc2_end_cmd(struct udevice *dev, + struct mmc_cmd *cmd, + struct stm32_sdmmc2_ctx *ctx) + { +- struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); ++ struct stm32_sdmmc2_plat *plat = dev_get_plat(dev); + u32 mask = SDMMC_STA_CTIMEOUT; + u32 status; + int ret; +@@ -313,7 +311,7 @@ static int stm32_sdmmc2_end_cmd(struct udevice *dev, + } + + /* Polling status register */ +- ret = readl_poll_timeout(priv->base + SDMMC_STA, status, status & mask, ++ ret = readl_poll_timeout(plat->base + SDMMC_STA, status, status & mask, + 10000); + + if (ret < 0) { +@@ -338,11 +336,11 @@ static int stm32_sdmmc2_end_cmd(struct udevice *dev, + } + + if (status & SDMMC_STA_CMDREND && cmd->resp_type & MMC_RSP_PRESENT) { +- cmd->response[0] = readl(priv->base + SDMMC_RESP1); ++ cmd->response[0] = readl(plat->base + SDMMC_RESP1); + if (cmd->resp_type & MMC_RSP_136) { +- cmd->response[1] = readl(priv->base + SDMMC_RESP2); +- cmd->response[2] = readl(priv->base + SDMMC_RESP3); +- cmd->response[3] = readl(priv->base + SDMMC_RESP4); ++ cmd->response[1] = readl(plat->base + SDMMC_RESP2); ++ cmd->response[2] = readl(plat->base + SDMMC_RESP3); ++ cmd->response[3] = readl(plat->base + SDMMC_RESP4); + } + + /* Wait for BUSYD0END flag if busy status is detected */ +@@ -351,7 +349,7 @@ static int stm32_sdmmc2_end_cmd(struct udevice *dev, + mask = SDMMC_STA_DTIMEOUT | SDMMC_STA_BUSYD0END; + + /* Polling status register */ +- ret = readl_poll_timeout(priv->base + SDMMC_STA, ++ ret = readl_poll_timeout(plat->base + SDMMC_STA, + status, status & mask, + SDMMC_BUSYD0END_TIMEOUT_US); + +@@ -379,7 +377,7 @@ static int stm32_sdmmc2_end_data(struct udevice *dev, + struct mmc_data *data, + struct stm32_sdmmc2_ctx *ctx) + { +- struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); ++ struct stm32_sdmmc2_plat *plat = dev_get_plat(dev); + u32 mask = SDMMC_STA_DCRCFAIL | SDMMC_STA_DTIMEOUT | + SDMMC_STA_IDMATE | SDMMC_STA_DATAEND; + u32 status; +@@ -389,9 +387,9 @@ static int stm32_sdmmc2_end_data(struct udevice *dev, + else + mask |= SDMMC_STA_TXUNDERR; + +- status = readl(priv->base + SDMMC_STA); ++ status = readl(plat->base + SDMMC_STA); + while (!(status & mask)) +- status = readl(priv->base + SDMMC_STA); ++ status = readl(plat->base + SDMMC_STA); + + /* + * Need invalidate the dcache again to avoid any +@@ -403,7 +401,7 @@ static int stm32_sdmmc2_end_data(struct udevice *dev, + if (status & SDMMC_STA_DCRCFAIL) { + dev_dbg(dev, "error SDMMC_STA_DCRCFAIL (0x%x) for cmd %d\n", + status, cmd->cmdidx); +- if (readl(priv->base + SDMMC_DCOUNT)) ++ if (readl(plat->base + SDMMC_DCOUNT)) + ctx->dpsm_abort = true; + return -EILSEQ; + } +@@ -442,7 +440,7 @@ static int stm32_sdmmc2_end_data(struct udevice *dev, + static int stm32_sdmmc2_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) + { +- struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); ++ struct stm32_sdmmc2_plat *plat = dev_get_plat(dev); + struct stm32_sdmmc2_ctx ctx; + u32 cmdat = data ? SDMMC_CMD_CMDTRANS : 0; + int ret, retry = 3; +@@ -469,9 +467,9 @@ retry_cmd: + ret = stm32_sdmmc2_end_data(dev, cmd, data, &ctx); + + /* Clear flags */ +- writel(SDMMC_ICR_STATIC_FLAGS, priv->base + SDMMC_ICR); ++ writel(SDMMC_ICR_STATIC_FLAGS, plat->base + SDMMC_ICR); + if (data) +- writel(0x0, priv->base + SDMMC_IDMACTRL); ++ writel(0x0, plat->base + SDMMC_IDMACTRL); + + /* + * To stop Data Path State Machine, a stop_transmission command +@@ -492,7 +490,7 @@ retry_cmd: + SDMMC_CMD_CMDSTOP, &ctx); + stm32_sdmmc2_end_cmd(dev, &stop_cmd, &ctx); + +- writel(SDMMC_ICR_STATIC_FLAGS, priv->base + SDMMC_ICR); ++ writel(SDMMC_ICR_STATIC_FLAGS, plat->base + SDMMC_ICR); + } + + if ((ret != -ETIMEDOUT) && (ret != 0) && retry) { +@@ -511,15 +509,15 @@ retry_cmd: + * This will reset the SDMMC to the reset state and the CPSM and DPSM + * to the Idle state. SDMMC is disabled, Signals Hiz. + */ +-static void stm32_sdmmc2_reset(struct stm32_sdmmc2_priv *priv) ++static void stm32_sdmmc2_reset(struct stm32_sdmmc2_plat *plat) + { + /* Reset */ +- reset_assert(&priv->reset_ctl); ++ reset_assert(&plat->reset_ctl); + udelay(2); +- reset_deassert(&priv->reset_ctl); ++ reset_deassert(&plat->reset_ctl); + + /* init the needed SDMMC register after reset */ +- writel(priv->pwr_reg_msk, priv->base + SDMMC_POWER); ++ writel(plat->pwr_reg_msk, plat->base + SDMMC_POWER); + } + + /* +@@ -528,13 +526,13 @@ static void stm32_sdmmc2_reset(struct stm32_sdmmc2_priv *priv) + * SDMMC_CMD and SDMMC_CK are driven low, to prevent the card from being + * supplied through the signal lines. + */ +-static void stm32_sdmmc2_pwrcycle(struct stm32_sdmmc2_priv *priv) ++static void stm32_sdmmc2_pwrcycle(struct stm32_sdmmc2_plat *plat) + { +- if ((readl(priv->base + SDMMC_POWER) & SDMMC_POWER_PWRCTRL_MASK) == ++ if ((readl(plat->base + SDMMC_POWER) & SDMMC_POWER_PWRCTRL_MASK) == + SDMMC_POWER_PWRCTRL_CYCLE) + return; + +- stm32_sdmmc2_reset(priv); ++ stm32_sdmmc2_reset(plat); + } + + /* +@@ -543,10 +541,10 @@ static void stm32_sdmmc2_pwrcycle(struct stm32_sdmmc2_priv *priv) + * Reset => Power-Cycle => Power-Off => Power + * PWRCTRL=10 PWCTRL=00 PWCTRL=11 + */ +-static void stm32_sdmmc2_pwron(struct stm32_sdmmc2_priv *priv) ++static void stm32_sdmmc2_pwron(struct stm32_sdmmc2_plat *plat) + { + u32 pwrctrl = +- readl(priv->base + SDMMC_POWER) & SDMMC_POWER_PWRCTRL_MASK; ++ readl(plat->base + SDMMC_POWER) & SDMMC_POWER_PWRCTRL_MASK; + + if (pwrctrl == SDMMC_POWER_PWRCTRL_ON) + return; +@@ -555,21 +553,21 @@ static void stm32_sdmmc2_pwron(struct stm32_sdmmc2_priv *priv) + * it is the reset state here = the only managed by the driver + */ + if (pwrctrl == SDMMC_POWER_PWRCTRL_OFF) { +- writel(SDMMC_POWER_PWRCTRL_CYCLE | priv->pwr_reg_msk, +- priv->base + SDMMC_POWER); ++ writel(SDMMC_POWER_PWRCTRL_CYCLE | plat->pwr_reg_msk, ++ plat->base + SDMMC_POWER); + } + + /* + * the remaining case is SDMMC_POWER_PWRCTRL_CYCLE + * switch to Power-Off state: SDMCC disable, signals drive 1 + */ +- writel(SDMMC_POWER_PWRCTRL_OFF | priv->pwr_reg_msk, +- priv->base + SDMMC_POWER); ++ writel(SDMMC_POWER_PWRCTRL_OFF | plat->pwr_reg_msk, ++ plat->base + SDMMC_POWER); + + /* After the 1ms delay set the SDMMC to power-on */ + mdelay(1); +- writel(SDMMC_POWER_PWRCTRL_ON | priv->pwr_reg_msk, +- priv->base + SDMMC_POWER); ++ writel(SDMMC_POWER_PWRCTRL_ON | plat->pwr_reg_msk, ++ plat->base + SDMMC_POWER); + + /* during the first 74 SDMMC_CK cycles the SDMMC is still disabled. */ + } +@@ -578,18 +576,18 @@ static void stm32_sdmmc2_pwron(struct stm32_sdmmc2_priv *priv) + static int stm32_sdmmc2_set_ios(struct udevice *dev) + { + struct mmc *mmc = mmc_get_mmc_dev(dev); +- struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); ++ struct stm32_sdmmc2_plat *plat = dev_get_plat(dev); + u32 desired = mmc->clock; +- u32 sys_clock = clk_get_rate(&priv->clk); ++ u32 sys_clock = clk_get_rate(&plat->clk); + u32 clk = 0; + + dev_dbg(dev, "bus_with = %d, clock = %d\n", + mmc->bus_width, mmc->clock); + + if (mmc->clk_disable) +- stm32_sdmmc2_pwrcycle(priv); ++ stm32_sdmmc2_pwrcycle(plat); + else +- stm32_sdmmc2_pwron(priv); ++ stm32_sdmmc2_pwron(plat); + + /* + * clk_div = 0 => command and data generated on SDMMCCLK falling edge +@@ -599,7 +597,7 @@ static int stm32_sdmmc2_set_ios(struct udevice *dev) + * SDMMCCLK falling edge + */ + if (desired && ((sys_clock > desired) || +- IS_RISING_EDGE(priv->clk_reg_msk))) { ++ IS_RISING_EDGE(plat->clk_reg_msk))) { + clk = DIV_ROUND_UP(sys_clock, 2 * desired); + if (clk > SDMMC_CLKCR_CLKDIV_MAX) + clk = SDMMC_CLKCR_CLKDIV_MAX; +@@ -610,30 +608,30 @@ static int stm32_sdmmc2_set_ios(struct udevice *dev) + if (mmc->bus_width == 8) + clk |= SDMMC_CLKCR_WIDBUS_8; + +- writel(clk | priv->clk_reg_msk | SDMMC_CLKCR_HWFC_EN, +- priv->base + SDMMC_CLKCR); ++ writel(clk | plat->clk_reg_msk | SDMMC_CLKCR_HWFC_EN, ++ plat->base + SDMMC_CLKCR); + + return 0; + } + + static int stm32_sdmmc2_getcd(struct udevice *dev) + { +- struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); ++ struct stm32_sdmmc2_plat *plat = dev_get_plat(dev); + + dev_dbg(dev, "%s called\n", __func__); + +- if (dm_gpio_is_valid(&priv->cd_gpio)) +- return dm_gpio_get_value(&priv->cd_gpio); ++ if (dm_gpio_is_valid(&plat->cd_gpio)) ++ return dm_gpio_get_value(&plat->cd_gpio); + + return 1; + } + + static int stm32_sdmmc2_host_power_cycle(struct udevice *dev) + { +- struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); ++ struct stm32_sdmmc2_plat *plat = dev_get_plat(dev); + +- writel(SDMMC_POWER_PWRCTRL_CYCLE | priv->pwr_reg_msk, +- priv->base + SDMMC_POWER); ++ writel(SDMMC_POWER_PWRCTRL_CYCLE | plat->pwr_reg_msk, ++ plat->base + SDMMC_POWER); + + return 0; + } +@@ -645,64 +643,127 @@ static const struct dm_mmc_ops stm32_sdmmc2_ops = { + .host_power_cycle = stm32_sdmmc2_host_power_cycle, + }; + +-static int stm32_sdmmc2_probe(struct udevice *dev) ++static int stm32_sdmmc2_of_to_plat(struct udevice *dev) + { +- struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct stm32_sdmmc2_plat *plat = dev_get_plat(dev); +- struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); + struct mmc_config *cfg = &plat->cfg; + int ret; + +- priv->base = dev_read_addr(dev); +- if (priv->base == FDT_ADDR_T_NONE) ++ plat->base = dev_read_addr(dev); ++ if (plat->base == FDT_ADDR_T_NONE) + return -EINVAL; + + if (dev_read_bool(dev, "st,neg-edge")) +- priv->clk_reg_msk |= SDMMC_CLKCR_NEGEDGE; ++ plat->clk_reg_msk |= SDMMC_CLKCR_NEGEDGE; + if (dev_read_bool(dev, "st,sig-dir")) +- priv->pwr_reg_msk |= SDMMC_POWER_DIRPOL; ++ plat->pwr_reg_msk |= SDMMC_POWER_DIRPOL; + if (dev_read_bool(dev, "st,use-ckin")) +- priv->clk_reg_msk |= SDMMC_CLKCR_SELCLKRX_CKIN; ++ plat->clk_reg_msk |= SDMMC_CLKCR_SELCLKRX_CKIN; + +- ret = clk_get_by_index(dev, 0, &priv->clk); ++ cfg->f_min = 400000; ++ cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; ++ cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; ++ cfg->name = "STM32 SD/MMC"; ++ cfg->host_caps = 0; ++ cfg->f_max = 52000000; ++ ret = mmc_of_parse(dev, cfg); + if (ret) + return ret; + +- ret = clk_enable(&priv->clk); ++ ret = clk_get_by_index(dev, 0, &plat->clk); + if (ret) +- goto clk_free; ++ return ret; + +- ret = reset_get_by_index(dev, 0, &priv->reset_ctl); +- if (ret) +- goto clk_disable; ++ ret = reset_get_by_index(dev, 0, &plat->reset_ctl); ++ if (ret) { ++ clk_free(&plat->clk); ++ return ret; ++ } + +- gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, ++ gpio_request_by_name(dev, "cd-gpios", 0, &plat->cd_gpio, + GPIOD_IS_IN); + +- cfg->f_min = 400000; +- cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; +- cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; +- cfg->name = "STM32 SD/MMC"; ++ return 0; ++} + +- cfg->host_caps = 0; +- cfg->f_max = 52000000; +- mmc_of_parse(dev, cfg); ++static int stm32_sdmmc2_probe_level_translator(struct udevice *dev) ++{ ++ struct stm32_sdmmc2_plat *plat = dev_get_plat(dev); ++ struct gpio_desc cmd_gpio; ++ struct gpio_desc ck_gpio; ++ struct gpio_desc ckin_gpio; ++ int clk_hi, clk_lo, ret; + +- upriv->mmc = &plat->mmc; ++ ret = gpio_request_by_name(dev, "st,cmd-gpios", 0, &cmd_gpio, ++ GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); ++ if (ret) ++ goto exit_cmd; ++ ++ ret = gpio_request_by_name(dev, "st,ck-gpios", 0, &ck_gpio, ++ GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); ++ if (ret) ++ goto exit_ck; ++ ++ ret = gpio_request_by_name(dev, "st,ckin-gpios", 0, &ckin_gpio, ++ GPIOD_IS_IN); ++ if (ret) ++ goto exit_ckin; ++ ++ /* All GPIOs are valid, test whether level translator works */ ++ ++ /* Sample CKIN */ ++ clk_hi = !!dm_gpio_get_value(&ckin_gpio); ++ ++ /* Set CK low */ ++ dm_gpio_set_value(&ck_gpio, 0); ++ ++ /* Sample CKIN */ ++ clk_lo = !!dm_gpio_get_value(&ckin_gpio); ++ ++ /* Tristate all */ ++ dm_gpio_set_dir_flags(&cmd_gpio, GPIOD_IS_IN); ++ dm_gpio_set_dir_flags(&ck_gpio, GPIOD_IS_IN); ++ ++ /* Level translator is present if CK signal is propagated to CKIN */ ++ if (!clk_hi || clk_lo) ++ plat->clk_reg_msk &= ~SDMMC_CLKCR_SELCLKRX_CKIN; ++ ++ dm_gpio_free(dev, &ckin_gpio); ++ ++exit_ckin: ++ dm_gpio_free(dev, &ck_gpio); ++exit_ck: ++ dm_gpio_free(dev, &cmd_gpio); ++exit_cmd: ++ pinctrl_select_state(dev, "default"); + +- /* SDMMC init */ +- stm32_sdmmc2_reset(priv); + return 0; ++} + +-clk_disable: +- clk_disable(&priv->clk); +-clk_free: +- clk_free(&priv->clk); ++static int stm32_sdmmc2_probe(struct udevice *dev) ++{ ++ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); ++ struct stm32_sdmmc2_plat *plat = dev_get_plat(dev); ++ int ret; + +- return ret; ++ ret = clk_enable(&plat->clk); ++ if (ret) { ++ clk_free(&plat->clk); ++ return ret; ++ } ++ ++ upriv->mmc = &plat->mmc; ++ ++ if (plat->clk_reg_msk & SDMMC_CLKCR_SELCLKRX_CKIN) ++ stm32_sdmmc2_probe_level_translator(dev); ++ ++ /* SDMMC init */ ++ stm32_sdmmc2_reset(plat); ++ ++ return 0; + } + +-static int stm32_sdmmc_bind(struct udevice *dev) ++static int stm32_sdmmc2_bind(struct udevice *dev) + { + struct stm32_sdmmc2_plat *plat = dev_get_plat(dev); + +@@ -720,7 +781,7 @@ U_BOOT_DRIVER(stm32_sdmmc2) = { + .of_match = stm32_sdmmc2_ids, + .ops = &stm32_sdmmc2_ops, + .probe = stm32_sdmmc2_probe, +- .bind = stm32_sdmmc_bind, +- .priv_auto = sizeof(struct stm32_sdmmc2_priv), ++ .bind = stm32_sdmmc2_bind, ++ .of_to_plat = stm32_sdmmc2_of_to_plat, + .plat_auto = sizeof(struct stm32_sdmmc2_plat), + }; +diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig +index b303fabe0f..ed69ea114e 100644 +--- a/drivers/mtd/Kconfig ++++ b/drivers/mtd/Kconfig +@@ -109,6 +109,13 @@ config HBMC_AM654 + This is the driver for HyperBus controller on TI's AM65x and + other SoCs + ++config STM32_FLASH ++ bool "STM32 MCU Flash driver" ++ depends on ARCH_STM32 ++ help ++ This is the driver of embedded flash for some STMicroelectronics ++ STM32 MCU. ++ + source "drivers/mtd/nand/Kconfig" + + source "drivers/mtd/spi/Kconfig" +diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c +index 7bac599a54..d31391f36a 100644 +--- a/drivers/mtd/altera_qspi.c ++++ b/drivers/mtd/altera_qspi.c +@@ -153,7 +153,6 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct erase_info *instr) + putc('\n'); + instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; + instr->state = MTD_ERASE_FAILED; +- mtd_erase_callback(instr); + return -EIO; + } + flash = pdata->base + addr; +@@ -177,7 +176,6 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct erase_info *instr) + writel(stat, ®s->isr); /* clear isr */ + instr->fail_addr = addr; + instr->state = MTD_ERASE_FAILED; +- mtd_erase_callback(instr); + return -EIO; + } + if (flash_verbose) +@@ -189,7 +187,6 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct erase_info *instr) + addr += mtd->erasesize; + } + instr->state = MTD_ERASE_DONE; +- mtd_erase_callback(instr); + + return 0; + } +diff --git a/drivers/mtd/cfi_mtd.c b/drivers/mtd/cfi_mtd.c +index 78293caa2f..2295bb7220 100644 +--- a/drivers/mtd/cfi_mtd.c ++++ b/drivers/mtd/cfi_mtd.c +@@ -58,7 +58,6 @@ static int cfi_mtd_erase(struct mtd_info *mtd, struct erase_info *instr) + } + + instr->state = MTD_ERASE_DONE; +- mtd_erase_callback(instr); + return 0; + } + +diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c +index 684bc94998..af3c4765c4 100644 +--- a/drivers/mtd/mtdconcat.c ++++ b/drivers/mtd/mtdconcat.c +@@ -338,14 +338,6 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) + return -EINVAL; + } + +-static void concat_erase_callback(struct erase_info *instr) +-{ +- /* Nothing to do here in U-Boot */ +-#ifndef __UBOOT__ +- wake_up((wait_queue_head_t *) instr->priv); +-#endif +-} +- + static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase) + { + int err; +@@ -358,7 +350,6 @@ static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase) + init_waitqueue_head(&waitq); + + erase->mtd = mtd; +- erase->callback = concat_erase_callback; + erase->priv = (unsigned long) &waitq; + + /* +@@ -498,8 +489,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) + if (err) + return err; + +- if (instr->callback) +- instr->callback(instr); + return 0; + } + +diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c +index 582129d0df..37c5b6386e 100644 +--- a/drivers/mtd/mtdcore.c ++++ b/drivers/mtd/mtdcore.c +@@ -906,13 +906,6 @@ void __put_mtd_device(struct mtd_info *mtd) + } + EXPORT_SYMBOL_GPL(__put_mtd_device); + +-/* +- * Erase is an asynchronous operation. Device drivers are supposed +- * to call instr->callback() whenever the operation completes, even +- * if it completes with a failure. +- * Callers are supposed to pass a callback function and wait for it +- * to be called before writing to the block. +- */ + int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) + { + if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr) +@@ -922,7 +915,6 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) + instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; + if (!instr->len) { + instr->state = MTD_ERASE_DONE; +- mtd_erase_callback(instr); + return 0; + } + return mtd->_erase(mtd, instr); +diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c +index aa58f722da..a435ce6d07 100644 +--- a/drivers/mtd/mtdpart.c ++++ b/drivers/mtd/mtdpart.c +@@ -446,26 +446,15 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr) + int ret; + + instr->addr += mtd->offset; ++ + ret = mtd->parent->_erase(mtd->parent, instr); +- if (ret) { +- if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) +- instr->fail_addr -= mtd->offset; +- instr->addr -= mtd->offset; +- } +- return ret; +-} ++ if (ret && instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) ++ instr->fail_addr -= mtd->offset; + +-void mtd_erase_callback(struct erase_info *instr) +-{ +- if (instr->mtd->_erase == part_erase) { +- if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) +- instr->fail_addr -= instr->mtd->offset; +- instr->addr -= instr->mtd->offset; +- } +- if (instr->callback) +- instr->callback(instr); ++ instr->addr -= mtd->offset; ++ ++ return ret; + } +-EXPORT_SYMBOL_GPL(mtd_erase_callback); + + static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) + { +diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c +index b1fd779884..10fb1ea654 100644 +--- a/drivers/mtd/nand/raw/nand_base.c ++++ b/drivers/mtd/nand/raw/nand_base.c +@@ -3602,10 +3602,6 @@ erase_exit: + chip->select_chip(mtd, -1); + nand_release_device(mtd); + +- /* Do call back function */ +- if (!ret) +- mtd_erase_callback(instr); +- + /* Return more or less happy */ + return ret; + } +diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c +index e17f1f8975..4c4ded1def 100644 +--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c ++++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -148,6 +149,7 @@ struct stm32_fmc2_timings { + struct stm32_fmc2_nand { + struct nand_chip chip; + struct stm32_fmc2_timings timings; ++ struct gpio_desc wp_gpio; + int ncs; + int cs_used[FMC2_MAX_CE]; + }; +@@ -823,6 +825,9 @@ static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc, ofnode node) + nand->cs_used[i] = cs[i]; + } + ++ gpio_request_by_name_nodev(node, "wp-gpios", 0, &nand->wp_gpio, ++ GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); ++ + nand->chip.flash_node = node; + + return 0; +@@ -971,6 +976,10 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev) + chip->ecc.size = FMC2_ECC_STEP_SIZE; + chip->ecc.strength = FMC2_ECC_BCH8; + ++ /* Disable Write Protect */ ++ if (dm_gpio_is_valid(&nand->wp_gpio)) ++ dm_gpio_set_value(&nand->wp_gpio, 0); ++ + ret = nand_scan_ident(mtd, nand->ncs, NULL); + if (ret) + return ret; +diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c +index 09daa0dd36..bb93a9a1e9 100644 +--- a/drivers/mtd/onenand/onenand_base.c ++++ b/drivers/mtd/onenand/onenand_base.c +@@ -1836,9 +1836,6 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) + erase_exit: + + ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; +- /* Do call back function */ +- if (!ret) +- mtd_erase_callback(instr); + + /* Deselect and wake up anyone waiting on the device */ + onenand_release_device(mtd); +diff --git a/drivers/mtd/spi/sf_mtd.c b/drivers/mtd/spi/sf_mtd.c +index 04de868080..0aed28a52b 100644 +--- a/drivers/mtd/spi/sf_mtd.c ++++ b/drivers/mtd/spi/sf_mtd.c +@@ -46,7 +46,6 @@ static int spi_flash_mtd_erase(struct mtd_info *mtd, struct erase_info *instr) + } + + instr->state = MTD_ERASE_DONE; +- mtd_erase_callback(instr); + + return 0; + } +diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c +index f1b4e5ea8e..ef846a8ced 100644 +--- a/drivers/mtd/spi/spi-nor-core.c ++++ b/drivers/mtd/spi/spi-nor-core.c +@@ -908,30 +908,40 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) + static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) + { + struct spi_nor *nor = mtd_to_spi_nor(mtd); ++ bool addr_known = false; + u32 addr, len, rem; +- int ret; ++ int ret, err; + + dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr, + (long long)instr->len); + +- if (!instr->len) +- return 0; +- + div_u64_rem(instr->len, mtd->erasesize, &rem); +- if (rem) +- return -EINVAL; ++ if (rem) { ++ ret = -EINVAL; ++ goto err; ++ } + + addr = instr->addr; + len = instr->len; + ++ instr->state = MTD_ERASING; ++ addr_known = true; ++ + while (len) { + WATCHDOG_RESET(); ++ if (ctrlc()) { ++ addr_known = false; ++ ret = -EINTR; ++ goto erase_err; ++ } + #ifdef CONFIG_SPI_FLASH_BAR + ret = write_bar(nor, addr); + if (ret < 0) +- return ret; ++ goto erase_err; + #endif +- write_enable(nor); ++ ret = write_enable(nor); ++ if (ret < 0) ++ goto erase_err; + + ret = spi_nor_erase_sector(nor, addr); + if (ret < 0) +@@ -945,11 +955,24 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) + goto erase_err; + } + ++ addr_known = false; + erase_err: + #ifdef CONFIG_SPI_FLASH_BAR +- ret = clean_bar(nor); ++ err = clean_bar(nor); ++ if (!ret) ++ ret = err; + #endif +- write_disable(nor); ++ err = write_disable(nor); ++ if (!ret) ++ ret = err; ++ ++err: ++ if (ret) { ++ instr->fail_addr = addr_known ? addr : MTD_FAIL_ADDR_UNKNOWN; ++ instr->state = MTD_ERASE_FAILED; ++ } else { ++ instr->state = MTD_ERASE_DONE; ++ } + + return ret; + } +@@ -1665,9 +1688,6 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, + + dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len); + +- if (!len) +- return 0; +- + for (i = 0; i < len; ) { + ssize_t written; + loff_t addr = to + i; +diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c +index b8b878b918..14be95b74b 100644 +--- a/drivers/mtd/ubi/io.c ++++ b/drivers/mtd/ubi/io.c +@@ -304,18 +304,6 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, + return err; + } + +-/** +- * erase_callback - MTD erasure call-back. +- * @ei: MTD erase information object. +- * +- * Note, even though MTD erase interface is asynchronous, all the current +- * implementations are synchronous anyway. +- */ +-static void erase_callback(struct erase_info *ei) +-{ +- wake_up_interruptible((wait_queue_head_t *)ei->priv); +-} +- + /** + * do_sync_erase - synchronously erase a physical eraseblock. + * @ubi: UBI device description object +@@ -346,7 +334,6 @@ retry: + ei.mtd = ubi->mtd; + ei.addr = (loff_t)pnum * ubi->peb_size; + ei.len = ubi->peb_size; +- ei.callback = erase_callback; + ei.priv = (unsigned long)&wq; + + err = mtd_erase(ubi->mtd, &ei); +diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c +index 585101804d..21bb0c47e1 100644 +--- a/drivers/net/dwc_eth_qos.c ++++ b/drivers/net/dwc_eth_qos.c +@@ -46,6 +46,7 @@ + #include + #include + #include ++#include + #include + #ifdef CONFIG_ARCH_IMX8M + #include +@@ -53,6 +54,7 @@ + #endif + #include + #include ++#include + + /* Core registers */ + +@@ -210,6 +212,7 @@ struct eqos_dma_regs { + #define EQOS_DMA_SYSBUS_MODE_BLEN4 BIT(1) + + #define EQOS_DMA_CH0_CONTROL_DSL_SHIFT 18 ++#define EQOS_DMA_CH0_CONTROL_DSL_MAX 7 + #define EQOS_DMA_CH0_CONTROL_PBLX8 BIT(16) + + #define EQOS_DMA_CH0_TX_CONTROL_TXPBL_SHIFT 16 +@@ -274,9 +277,11 @@ struct eqos_config { + struct eqos_ops *ops; + }; + ++struct eqos_priv; ++ + struct eqos_ops { +- void (*eqos_inval_desc)(void *desc); +- void (*eqos_flush_desc)(void *desc); ++ void (*eqos_inval_desc)(struct eqos_priv *eqos, void *desc); ++ void (*eqos_flush_desc)(struct eqos_priv *eqos, void *desc); + void (*eqos_inval_buffer)(void *buf, size_t size); + void (*eqos_flush_buffer)(void *buf, size_t size); + int (*eqos_probe_resources)(struct udevice *dev); +@@ -286,6 +291,7 @@ struct eqos_ops { + int (*eqos_stop_clks)(struct udevice *dev); + int (*eqos_start_clks)(struct udevice *dev); + int (*eqos_calibrate_pads)(struct udevice *dev); ++ int (*eqos_phy_power_on)(struct udevice *dev); + int (*eqos_disable_calibration)(struct udevice *dev); + int (*eqos_set_tx_clk_speed)(struct udevice *dev); + ulong (*eqos_get_tick_clk_rate)(struct udevice *dev); +@@ -319,6 +325,10 @@ struct eqos_priv { + bool started; + bool reg_access_ok; + bool clk_ck_enabled; ++ bool use_cached_mem; ++#ifdef CONFIG_DM_REGULATOR ++ struct udevice *phy_supply; ++#endif + }; + + /* +@@ -341,15 +351,38 @@ struct eqos_priv { + */ + static void *eqos_alloc_descs(struct eqos_priv *eqos, unsigned int num) + { ++ void *descs = NULL; ++ ulong desc_pad; ++ ++ /* ++ * if descriptors can to be cache-line aligned with the DSL = ++ * "Descriptor Skip Length" field of the DMA channel control register ++ */ + eqos->desc_size = ALIGN(sizeof(struct eqos_desc), + (unsigned int)ARCH_DMA_MINALIGN); ++ desc_pad = (eqos->desc_size - sizeof(struct eqos_desc)) / ++ eqos->config->axi_bus_width; ++ if (desc_pad <= EQOS_DMA_CH0_CONTROL_DSL_MAX) { ++ eqos->use_cached_mem = true; ++ descs = memalign(eqos->desc_size, num * eqos->desc_size); ++ } else { ++ eqos->use_cached_mem = false; ++ eqos->desc_size = sizeof(struct eqos_desc); ++#ifdef CONFIG_SYS_NONCACHED_MEMORY ++ descs = (void *)noncached_alloc(num * eqos->desc_size, ARCH_DMA_MINALIGN); ++#else ++ log_err("DMA descriptors with cached memory."); ++#endif ++ } + +- return memalign(eqos->desc_size, num * eqos->desc_size); ++ return descs; + } + +-static void eqos_free_descs(void *descs) ++static void eqos_free_descs(struct eqos_priv *eqos) + { +- free(descs); ++ if (eqos->use_cached_mem) ++ free(eqos->descs); ++ /* memory allocated by noncached_alloc() can't be freed */ + } + + static struct eqos_desc *eqos_get_desc(struct eqos_priv *eqos, +@@ -359,22 +392,24 @@ static struct eqos_desc *eqos_get_desc(struct eqos_priv *eqos, + ((rx ? EQOS_DESCRIPTORS_TX : 0) + num) * eqos->desc_size; + } + +-static void eqos_inval_desc_generic(void *desc) ++static void eqos_inval_desc_generic(struct eqos_priv *eqos, void *desc) + { + unsigned long start = (unsigned long)desc; + unsigned long end = ALIGN(start + sizeof(struct eqos_desc), + ARCH_DMA_MINALIGN); + +- invalidate_dcache_range(start, end); ++ if (eqos->use_cached_mem) ++ invalidate_dcache_range(start, end); + } + +-static void eqos_flush_desc_generic(void *desc) ++static void eqos_flush_desc_generic(struct eqos_priv *eqos, void *desc) + { + unsigned long start = (unsigned long)desc; + unsigned long end = ALIGN(start + sizeof(struct eqos_desc), + ARCH_DMA_MINALIGN); + +- flush_dcache_range(start, end); ++ if (eqos->use_cached_mem) ++ flush_dcache_range(start, end); + } + + static void eqos_inval_buffer_tegra186(void *buf, size_t size) +@@ -649,6 +684,27 @@ static int eqos_stop_clks_stm32(struct udevice *dev) + return 0; + } + ++static int eqos_phy_power_on_stm32(struct udevice *dev) ++{ ++ struct eqos_priv *eqos = dev_get_priv(dev); ++ int ret; ++ ++ debug("%s(dev=%p):\n", __func__, dev); ++ ++#ifdef CONFIG_DM_REGULATOR ++ if (eqos->phy_supply) { ++ ret = regulator_set_enable(eqos->phy_supply, true); ++ if (ret) { ++ printf("%s: Error enabling phy supply\n", dev->name); ++ return ret; ++ } ++ } ++#endif ++ ++ debug("%s: OK\n", __func__); ++ return 0; ++} ++ + static int eqos_start_resets_tegra186(struct udevice *dev) + { + struct eqos_priv *eqos = dev_get_priv(dev); +@@ -1045,6 +1101,12 @@ static int eqos_start(struct udevice *dev) + eqos->tx_desc_idx = 0; + eqos->rx_desc_idx = 0; + ++ ret = eqos->config->ops->eqos_phy_power_on(dev); ++ if (ret < 0) { ++ pr_err("eqos_phy_power_on() failed: %d", ret); ++ goto err; ++ } ++ + ret = eqos->config->ops->eqos_start_clks(dev); + if (ret < 0) { + pr_err("eqos_start_clks() failed: %d", ret); +@@ -1268,12 +1330,17 @@ static int eqos_start(struct udevice *dev) + EQOS_MAX_PACKET_SIZE << + EQOS_DMA_CH0_RX_CONTROL_RBSZ_SHIFT); + +- desc_pad = (eqos->desc_size - sizeof(struct eqos_desc)) / +- eqos->config->axi_bus_width; ++ setbits_le32(&eqos->dma_regs->ch0_control, EQOS_DMA_CH0_CONTROL_PBLX8); + +- setbits_le32(&eqos->dma_regs->ch0_control, +- EQOS_DMA_CH0_CONTROL_PBLX8 | +- (desc_pad << EQOS_DMA_CH0_CONTROL_DSL_SHIFT)); ++ /* "Descriptor Skip Length" field of the DMA channel control register */ ++ if (eqos->use_cached_mem) { ++ desc_pad = (eqos->desc_size - sizeof(struct eqos_desc)) / ++ eqos->config->axi_bus_width; ++ setbits_le32(&eqos->dma_regs->ch0_control, ++ desc_pad << EQOS_DMA_CH0_CONTROL_DSL_SHIFT); ++ if (desc_pad > EQOS_DMA_CH0_CONTROL_DSL_MAX) ++ dev_dbg(dev, "DMA_CH0_CONTROL.DSL overflow"); ++ } + + /* + * Burst length must be < 1/2 FIFO size. +@@ -1306,7 +1373,7 @@ static int eqos_start(struct udevice *dev) + + for (i = 0; i < EQOS_DESCRIPTORS_TX; i++) { + struct eqos_desc *tx_desc = eqos_get_desc(eqos, i, false); +- eqos->config->ops->eqos_flush_desc(tx_desc); ++ eqos->config->ops->eqos_flush_desc(eqos, tx_desc); + } + + for (i = 0; i < EQOS_DESCRIPTORS_RX; i++) { +@@ -1315,7 +1382,7 @@ static int eqos_start(struct udevice *dev) + (i * EQOS_MAX_PACKET_SIZE)); + rx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_BUF1V; + mb(); +- eqos->config->ops->eqos_flush_desc(rx_desc); ++ eqos->config->ops->eqos_flush_desc(eqos, rx_desc); + eqos->config->ops->eqos_inval_buffer(eqos->rx_dma_buf + + (i * EQOS_MAX_PACKET_SIZE), + EQOS_MAX_PACKET_SIZE); +@@ -1446,13 +1513,13 @@ static int eqos_send(struct udevice *dev, void *packet, int length) + */ + mb(); + tx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_FD | EQOS_DESC3_LD | length; +- eqos->config->ops->eqos_flush_desc(tx_desc); ++ eqos->config->ops->eqos_flush_desc(eqos, tx_desc); + + writel((ulong)eqos_get_desc(eqos, eqos->tx_desc_idx, false), + &eqos->dma_regs->ch0_txdesc_tail_pointer); + + for (i = 0; i < 1000000; i++) { +- eqos->config->ops->eqos_inval_desc(tx_desc); ++ eqos->config->ops->eqos_inval_desc(eqos, tx_desc); + if (!(readl(&tx_desc->des3) & EQOS_DESC3_OWN)) + return 0; + udelay(1); +@@ -1472,7 +1539,7 @@ static int eqos_recv(struct udevice *dev, int flags, uchar **packetp) + debug("%s(dev=%p, flags=%x):\n", __func__, dev, flags); + + rx_desc = eqos_get_desc(eqos, eqos->rx_desc_idx, true); +- eqos->config->ops->eqos_inval_desc(rx_desc); ++ eqos->config->ops->eqos_inval_desc(eqos, rx_desc); + if (rx_desc->des3 & EQOS_DESC3_OWN) { + debug("%s: RX packet not available\n", __func__); + return -EAGAIN; +@@ -1510,7 +1577,7 @@ static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) + + rx_desc->des0 = 0; + mb(); +- eqos->config->ops->eqos_flush_desc(rx_desc); ++ eqos->config->ops->eqos_flush_desc(eqos, rx_desc); + eqos->config->ops->eqos_inval_buffer(packet, length); + rx_desc->des0 = (u32)(ulong)packet; + rx_desc->des1 = 0; +@@ -1521,7 +1588,7 @@ static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) + */ + mb(); + rx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_BUF1V; +- eqos->config->ops->eqos_flush_desc(rx_desc); ++ eqos->config->ops->eqos_flush_desc(eqos, rx_desc); + + writel((ulong)rx_desc, &eqos->dma_regs->ch0_rxdesc_tail_pointer); + +@@ -1596,7 +1663,7 @@ static int eqos_remove_resources_core(struct udevice *dev) + free(eqos->rx_pkt); + free(eqos->rx_dma_buf); + free(eqos->tx_dma_buf); +- eqos_free_descs(eqos->descs); ++ eqos_free_descs(eqos); + + debug("%s: OK\n", __func__); + return 0; +@@ -1676,7 +1743,7 @@ err_free_reset_eqos: + + /* board-specific Ethernet Interface initializations. */ + __weak int board_interface_eth_init(struct udevice *dev, +- phy_interface_t interface_type) ++ phy_interface_t interface_type, ulong rate) + { + return 0; + } +@@ -1686,6 +1753,7 @@ static int eqos_probe_resources_stm32(struct udevice *dev) + struct eqos_priv *eqos = dev_get_priv(dev); + int ret; + phy_interface_t interface; ++ ulong rate = 0; + + debug("%s(dev=%p):\n", __func__, dev); + +@@ -1696,7 +1764,15 @@ static int eqos_probe_resources_stm32(struct udevice *dev) + return -EINVAL; + } + +- ret = board_interface_eth_init(dev, interface); ++ /* Get ETH_CLK clocks (optional) */ ++ ret = clk_get_by_name(dev, "eth-ck", &eqos->clk_ck); ++ if (ret) ++ debug("No phy clock provided %d", ret); ++ else ++ rate = clk_get_rate(&eqos->clk_ck); ++ ++ /* Initialize the soc for the PHY configuration */ ++ ret = board_interface_eth_init(dev, interface, rate); + if (ret) + return -EINVAL; + +@@ -1720,10 +1796,14 @@ static int eqos_probe_resources_stm32(struct udevice *dev) + goto err_free_clk_rx; + } + +- /* Get ETH_CLK clocks (optional) */ +- ret = clk_get_by_name(dev, "eth-ck", &eqos->clk_ck); +- if (ret) +- pr_warn("No phy clock provided %d", ret); ++#ifdef CONFIG_DM_REGULATOR ++ /* check presence of optional regulator */ ++ ret = device_get_supply_regulator(dev, "phy-supply", &eqos->phy_supply); ++ if (ret && ret != -ENOENT) { ++ pr_err("device_get_supply_regulator failed: %d", ret); ++ goto err_free_clk_rx; ++ } ++#endif + + debug("%s: OK\n", __func__); + return 0; +@@ -1945,6 +2025,7 @@ static struct eqos_ops eqos_tegra186_ops = { + .eqos_stop_clks = eqos_stop_clks_tegra186, + .eqos_start_clks = eqos_start_clks_tegra186, + .eqos_calibrate_pads = eqos_calibrate_pads_tegra186, ++ .eqos_phy_power_on = eqos_null_ops, + .eqos_disable_calibration = eqos_disable_calibration_tegra186, + .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_tegra186, + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_tegra186 +@@ -1973,6 +2054,7 @@ static struct eqos_ops eqos_stm32_ops = { + .eqos_stop_clks = eqos_stop_clks_stm32, + .eqos_start_clks = eqos_start_clks_stm32, + .eqos_calibrate_pads = eqos_null_ops, ++ .eqos_phy_power_on = eqos_phy_power_on_stm32, + .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 +@@ -1989,6 +2071,17 @@ static const struct eqos_config __maybe_unused eqos_stm32_config = { + .ops = &eqos_stm32_ops + }; + ++static const struct eqos_config eqos_stm32mp13_config = { ++ .reg_access_always_ok = false, ++ .mdio_wait = 10000, ++ .swr_wait = 50, ++ .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, ++ .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, ++ .axi_bus_width = EQOS_AXI_WIDTH_32, ++ .interface = eqos_get_interface_stm32, ++ .ops = &eqos_stm32_ops ++}; ++ + static struct eqos_ops eqos_imx_ops = { + .eqos_inval_desc = eqos_inval_desc_generic, + .eqos_flush_desc = eqos_flush_desc_generic, +@@ -2001,6 +2094,7 @@ static struct eqos_ops eqos_imx_ops = { + .eqos_stop_clks = eqos_null_ops, + .eqos_start_clks = eqos_null_ops, + .eqos_calibrate_pads = eqos_null_ops, ++ .eqos_phy_power_on = 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 +@@ -2029,6 +2123,10 @@ static const struct udevice_id eqos_ids[] = { + .compatible = "st,stm32mp1-dwmac", + .data = (ulong)&eqos_stm32_config + }, ++ { ++ .compatible = "st,stm32mp13-dwmac", ++ .data = (ulong)&eqos_stm32mp13_config ++ }, + #endif + #if IS_ENABLED(CONFIG_DWC_ETH_QOS_IMX) + { +diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c +index 02d859a039..bd185d9994 100644 +--- a/drivers/phy/phy-stm32-usbphyc.c ++++ b/drivers/phy/phy-stm32-usbphyc.c +@@ -7,6 +7,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -17,6 +18,9 @@ + #include + #include + #include ++#include ++#include ++#include + #include + #include + #include +@@ -24,6 +28,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) +@@ -40,6 +45,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 */ +@@ -49,6 +74,62 @@ + #define PLL_INFF_MIN_RATE 19200000 /* in Hz */ + #define PLL_INFF_MAX_RATE 38400000 /* in Hz */ + ++enum boosting_vals { ++ BOOST_1000_UA = 1000, ++ BOOST_2000_UA = 2000, ++}; ++ ++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; +@@ -65,6 +146,7 @@ struct stm32_usbphyc { + bool init; + bool powered; + } phys[MAX_PHYS]; ++ int n_pll_cons; + }; + + static void stm32_usbphyc_get_pll_params(u32 clk_rate, +@@ -124,18 +206,6 @@ static int stm32_usbphyc_pll_init(struct stm32_usbphyc *usbphyc) + return 0; + } + +-static bool stm32_usbphyc_is_init(struct stm32_usbphyc *usbphyc) +-{ +- int i; +- +- for (i = 0; i < MAX_PHYS; i++) { +- if (usbphyc->phys[i].init) +- return true; +- } +- +- return false; +-} +- + static bool stm32_usbphyc_is_powered(struct stm32_usbphyc *usbphyc) + { + int i; +@@ -148,18 +218,17 @@ static bool stm32_usbphyc_is_powered(struct stm32_usbphyc *usbphyc) + return false; + } + +-static int stm32_usbphyc_phy_init(struct phy *phy) ++static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc) + { +- struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev); +- struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id; + bool pllen = readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN ? + true : false; + int ret; + +- dev_dbg(phy->dev, "phy ID = %lu\n", phy->id); +- /* Check if one phy port has already configured the pll */ +- if (pllen && stm32_usbphyc_is_init(usbphyc)) +- goto initialized; ++ /* Check if one consumer has already configured the pll */ ++ if (pllen && usbphyc->n_pll_cons) { ++ usbphyc->n_pll_cons++; ++ return 0; ++ } + + if (usbphyc->vdda1v1) { + ret = regulator_set_enable(usbphyc->vdda1v1, true); +@@ -190,23 +259,19 @@ static int stm32_usbphyc_phy_init(struct phy *phy) + if (!(readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN)) + return -EIO; + +-initialized: +- usbphyc_phy->init = true; ++ usbphyc->n_pll_cons++; + + return 0; + } + +-static int stm32_usbphyc_phy_exit(struct phy *phy) ++static int stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc) + { +- struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev); +- struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id; + int ret; + +- dev_dbg(phy->dev, "phy ID = %lu\n", phy->id); +- usbphyc_phy->init = false; ++ usbphyc->n_pll_cons--; + +- /* Check if other phy port requires pllen */ +- if (stm32_usbphyc_is_init(usbphyc)) ++ /* Check if other consumer requires pllen */ ++ if (usbphyc->n_pll_cons) + return 0; + + clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN); +@@ -235,6 +300,42 @@ static int stm32_usbphyc_phy_exit(struct phy *phy) + return 0; + } + ++static int stm32_usbphyc_phy_init(struct phy *phy) ++{ ++ struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev); ++ struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id; ++ int ret; ++ ++ dev_dbg(phy->dev, "phy ID = %lu\n", phy->id); ++ if (usbphyc_phy->init) ++ return 0; ++ ++ ret = stm32_usbphyc_pll_enable(usbphyc); ++ if (ret) ++ return log_ret(ret); ++ ++ usbphyc_phy->init = true; ++ ++ return 0; ++} ++ ++static int stm32_usbphyc_phy_exit(struct phy *phy) ++{ ++ struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev); ++ struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id; ++ int ret; ++ ++ dev_dbg(phy->dev, "phy ID = %lu\n", phy->id); ++ if (!usbphyc_phy->init) ++ return 0; ++ ++ ret = stm32_usbphyc_pll_disable(usbphyc); ++ ++ usbphyc_phy->init = false; ++ ++ return log_ret(ret); ++} ++ + static int stm32_usbphyc_phy_power_on(struct phy *phy) + { + struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev); +@@ -271,7 +372,7 @@ static int stm32_usbphyc_phy_power_off(struct phy *phy) + return 0; + + if (usbphyc_phy->vbus) { +- ret = regulator_set_enable(usbphyc_phy->vbus, false); ++ ret = regulator_set_enable_if_allowed(usbphyc_phy->vbus, false); + if (ret) + return ret; + } +@@ -327,6 +428,90 @@ 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); ++ u32 reg = STM32_USBPHYC_TUNE(index); ++ u32 otpcomp, val, tune = 0; ++ int ret; ++ ++ /* Backup OTP compensation code */ ++ otpcomp = FIELD_GET(OTPCOMP, readl(usbphyc->base + reg)); ++ ++ ret = ofnode_read_u32(node, "st,current-boost-microamp", &val); ++ if (!ret && (val == BOOST_1000_UA || val == BOOST_2000_UA)) { ++ val = (val == BOOST_2000_UA) ? 1 : 0; ++ tune |= INCURREN | FIELD_PREP(INCURRINT, val); ++ } else if (ret != -EINVAL) { ++ dev_warn(dev, "phy%d: invalid st,current-boost-microamp value\n", index); ++ } ++ ++ if (!ofnode_read_bool(node, "st,no-lsfs-fb-cap")) ++ tune |= LFSCAPEN; ++ ++ if (ofnode_read_bool(node, "st,decrease-hs-slew-rate")) ++ tune |= HSDRVSLEW; ++ ++ ret = ofnode_read_u32(node, "st,tune-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,tune-hs-dc-level value\n", index); ++ } ++ ++ if (ofnode_read_bool(node, "st,enable-fs-rftime-tuning")) ++ tune |= FSDRVRFADJ; ++ ++ if (ofnode_read_bool(node, "st,enable-hs-rftime-reduction")) ++ tune |= HSDRVRFRED; ++ ++ ret = ofnode_read_u32(node, "st,trim-hs-current", &val); ++ if (!ret && val < CUR_MAX) ++ tune |= FIELD_PREP(HSDRVCHKITRM, val); ++ else if (ret != -EINVAL) ++ dev_warn(dev, "phy%d: invalid st,trim-hs-current value\n", index); ++ ++ ret = ofnode_read_u32(node, "st,trim-hs-impedance", &val); ++ if (!ret && val < IMP_MAX) ++ tune |= FIELD_PREP(HSDRVCHKZTRM, val); ++ else if (ret != -EINVAL) ++ dev_warn(dev, "phy%d: invalid trim-hs-impedance value\n", index); ++ ++ ret = ofnode_read_u32(node, "st,tune-squelch-level", &val); ++ if (!ret && val < SQLCH_MAX) ++ tune |= FIELD_PREP(SQLCHCTL, val); ++ else if (ret != -EINVAL) ++ dev_warn(dev, "phy%d: invalid st,tune-squelch-level value\n", index); ++ ++ if (ofnode_read_bool(node, "st,enable-hs-rx-gain-eq")) ++ tune |= HDRXGNEQEN; ++ ++ ret = ofnode_read_u32(node, "st,tune-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,tune-hs-rx-offset value\n", index); ++ ++ if (ofnode_read_bool(node, "st,no-hs-ftime-ctrl")) ++ tune |= HSFALLPREEM; ++ ++ if (!ofnode_read_bool(node, "st,no-lsfs-sc")) ++ tune |= SHTCCTCTLPROT; ++ ++ if (ofnode_read_bool(node, "st,enable-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, +@@ -335,12 +520,22 @@ static const struct phy_ops stm32_usbphyc_phy_ops = { + .of_xlate = stm32_usbphyc_of_xlate, + }; + ++static int stm32_usbphyc_bind(struct udevice *dev) ++{ ++ int ret; ++ ++ ret = device_bind_driver_to_node(dev, "stm32-usbphyc-clk", "ck_usbo_48m", ++ dev_ofnode(dev), NULL); ++ ++ return log_ret(ret); ++} ++ + 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) +@@ -378,14 +573,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", +@@ -395,12 +598,12 @@ 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); ++ } + } + + /* Check if second port has to be used for host controller */ +@@ -420,6 +623,70 @@ U_BOOT_DRIVER(stm32_usb_phyc) = { + .id = UCLASS_PHY, + .of_match = stm32_usbphyc_of_match, + .ops = &stm32_usbphyc_phy_ops, ++ .bind = stm32_usbphyc_bind, + .probe = stm32_usbphyc_probe, + .priv_auto = sizeof(struct stm32_usbphyc), + }; ++ ++struct stm32_usbphyc_clk { ++ bool enable; ++}; ++ ++static ulong stm32_usbphyc_clk48_get_rate(struct clk *clk) ++{ ++ return 48000000; ++} ++ ++static int stm32_usbphyc_clk48_enable(struct clk *clk) ++{ ++ struct stm32_usbphyc_clk *usbphyc_clk = dev_get_priv(clk->dev); ++ struct stm32_usbphyc *usbphyc; ++ int ret; ++ ++ if (usbphyc_clk->enable) ++ return 0; ++ ++ usbphyc = dev_get_priv(clk->dev->parent); ++ ++ /* ck_usbo_48m is generated by usbphyc PLL */ ++ ret = stm32_usbphyc_pll_enable(usbphyc); ++ if (ret) ++ return ret; ++ ++ usbphyc_clk->enable = true; ++ ++ return 0; ++} ++ ++static int stm32_usbphyc_clk48_disable(struct clk *clk) ++{ ++ struct stm32_usbphyc_clk *usbphyc_clk = dev_get_priv(clk->dev); ++ struct stm32_usbphyc *usbphyc; ++ int ret; ++ ++ if (!usbphyc_clk->enable) ++ return 0; ++ ++ usbphyc = dev_get_priv(clk->dev->parent); ++ ++ ret = stm32_usbphyc_pll_disable(usbphyc); ++ if (ret) ++ return ret; ++ ++ usbphyc_clk->enable = false; ++ ++ return 0; ++} ++ ++const struct clk_ops usbphyc_clk48_ops = { ++ .get_rate = stm32_usbphyc_clk48_get_rate, ++ .enable = stm32_usbphyc_clk48_enable, ++ .disable = stm32_usbphyc_clk48_disable, ++}; ++ ++U_BOOT_DRIVER(stm32_usb_phyc_clk) = { ++ .name = "stm32-usbphyc-clk", ++ .id = UCLASS_CLK, ++ .ops = &usbphyc_clk48_ops, ++ .priv_auto = sizeof(struct stm32_usbphyc_clk), ++}; +diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig +index 30eaa376c8..96c661f5fb 100644 +--- a/drivers/pinctrl/Kconfig ++++ b/drivers/pinctrl/Kconfig +@@ -185,6 +185,14 @@ config PINCTRL_INTEL + driver which must be separately enabled. The driver supports setting + pins on start-up and changing the GPIO attributes. + ++config PINCTRL_MCP23017 ++ bool "Microchip MCP23017 pinctrl driver" ++ help ++ I2C driver for Microchip MCP23017 16-Bit I/O Expander. ++ The driver is controlled by a device tree node which contains both ++ the GPIO definitions and pin control functions for each available ++ multiplex function. ++ + config PINCTRL_PIC32 + bool "Microchip PIC32 pin-control and pin-mux driver" + depends on DM && MACH_PIC32 +diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile +index 05b71f2f13..dbc83db058 100644 +--- a/drivers/pinctrl/Makefile ++++ b/drivers/pinctrl/Makefile +@@ -18,6 +18,7 @@ obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/ + obj-$(CONFIG_PINCTRL_PIC32) += pinctrl_pic32.o + obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/ + obj-$(CONFIG_PINCTRL_K210) += pinctrl-kendryte.o ++obj-$(CONFIG_PINCTRL_MCP23017) += pinctrl-mcp23017.o + obj-$(CONFIG_PINCTRL_MESON) += meson/ + obj-$(CONFIG_PINCTRL_MTK) += mediatek/ + obj-$(CONFIG_PINCTRL_MSCC) += mscc/ +diff --git a/drivers/pinctrl/pinctrl-mcp23017.c b/drivers/pinctrl/pinctrl-mcp23017.c +new file mode 100644 +index 0000000000..78eb9086c0 +--- /dev/null ++++ b/drivers/pinctrl/pinctrl-mcp23017.c +@@ -0,0 +1,411 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2021, STMicroelectronics - All Rights Reserved ++ * ++ * Driver for Microchip MCP23017 16-Bit I/O Expander with I2C interface ++ */ ++ ++#define LOG_CATEGORY UCLASS_PINCTRL ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* register offset for IOCON.BANK = 0, the normal mode at reset */ ++#define MCP_REG_IODIR 0x00 /* init/reset: all ones */ ++#define MCP_REG_IOCON 0x0A ++#define IOCON_SEQOP BIT(5) ++#define MCP_REG_GPPU 0x0C ++#define MCP_REG_GPIO 0x12 ++ ++#define MCP_REG_SIZE 8 ++#define MCP_MAX_GPIO 16 ++ ++static int mcp23017_read(struct udevice *dev, uint offset) ++{ ++ return dm_i2c_reg_read(dev_get_parent(dev), offset); ++} ++ ++static int mcp23017_write(struct udevice *dev, uint reg, unsigned int val) ++{ ++ dev_dbg(dev, "%s reg = 0x%x val = 0x%x\n", __func__, reg, val); ++ ++ return dm_i2c_reg_write(dev_get_parent(dev), reg, val); ++} ++ ++static int mcp23017_read_reg(struct udevice *dev, u8 reg, uint offset) ++{ ++ u8 mask = BIT(offset); ++ int ret; ++ ++ ret = mcp23017_read(dev, reg); ++ ++ dev_dbg(dev, "%s reg = 0x%x offset = %d ret = 0x%x mask = 0x%x\n", ++ __func__, reg, offset, ret, mask); ++ ++ return ret < 0 ? ret : !!(ret & mask); ++} ++ ++static int mcp23017_write_reg(struct udevice *dev, u8 reg, uint offset, ++ uint val) ++{ ++ u8 mask = BIT(offset); ++ int ret; ++ ++ ret = mcp23017_read(dev, reg); ++ if (ret < 0) ++ return ret; ++ ret = (ret & ~mask) | (val ? mask : 0); ++ ++ return mcp23017_write(dev, reg, ret); ++} ++ ++static int mcp23017_conf_set_gppu(struct udevice *dev, unsigned int offset, ++ uint pupd) ++{ ++ int reg = MCP_REG_GPPU + offset / MCP_REG_SIZE; ++ int bit = offset % MCP_REG_SIZE; ++ ++ return mcp23017_write_reg(dev, reg, bit, pupd); ++} ++ ++static int mcp23017_conf_get_gppu(struct udevice *dev, unsigned int offset) ++{ ++ int reg = MCP_REG_GPPU + offset / MCP_REG_SIZE; ++ int bit = offset % MCP_REG_SIZE; ++ int ret = mcp23017_read_reg(dev, reg, bit); ++ ++ return ret; ++} ++ ++static int mcp23017_gpio_get(struct udevice *dev, unsigned int offset) ++{ ++ int reg = MCP_REG_GPIO + offset / MCP_REG_SIZE; ++ int bit = offset % MCP_REG_SIZE; ++ int ret = mcp23017_read_reg(dev, reg, bit); ++ ++ return ret; ++} ++ ++static int mcp23017_gpio_set(struct udevice *dev, unsigned int offset, int value) ++{ ++ int reg = MCP_REG_GPIO + offset / MCP_REG_SIZE; ++ int bit = offset % MCP_REG_SIZE; ++ ++ return mcp23017_write_reg(dev, reg, bit, value); ++} ++ ++static int mcp23017_gpio_get_function(struct udevice *dev, unsigned int offset) ++{ ++ int ret; ++ int reg = MCP_REG_IODIR + offset / MCP_REG_SIZE; ++ int bit = offset % MCP_REG_SIZE; ++ ++ ret = mcp23017_read_reg(dev, reg, bit); ++ ++ if (ret < 0) ++ return ret; ++ /* On mcp23017, gpio pins direction is (0)output, (1)input. */ ++ return ret ? GPIOF_INPUT : GPIOF_OUTPUT; ++} ++ ++static int mcp23017_gpio_direction_input(struct udevice *dev, unsigned int offset) ++{ ++ int reg = MCP_REG_IODIR + offset / MCP_REG_SIZE; ++ int bit = offset % MCP_REG_SIZE; ++ ++ return mcp23017_write_reg(dev, reg, bit, 1); ++} ++ ++static int mcp23017_gpio_direction_output(struct udevice *dev, ++ unsigned int offset, int value) ++{ ++ int reg = MCP_REG_IODIR + offset / MCP_REG_SIZE; ++ int bit = offset % MCP_REG_SIZE; ++ int ret = mcp23017_gpio_set(dev, offset, value); ++ ++ if (ret < 0) ++ return ret; ++ ++ return mcp23017_write_reg(dev, reg, bit, 0); ++} ++ ++static int mcp23017_gpio_set_flags(struct udevice *dev, unsigned int offset, ++ ulong flags) ++{ ++ int ret = -ENOTSUPP; ++ ++ if (flags & GPIOD_IS_OUT) { ++ bool value = flags & GPIOD_IS_OUT_ACTIVE; ++ ++ if (flags & GPIOD_OPEN_SOURCE) ++ return -ENOTSUPP; ++ if (flags & GPIOD_OPEN_DRAIN) ++ return -ENOTSUPP; ++ ret = mcp23017_gpio_direction_output(dev, offset, value); ++ } else if (flags & GPIOD_IS_IN) { ++ ret = mcp23017_gpio_direction_input(dev, offset); ++ if (ret) ++ return ret; ++ if (flags & GPIOD_PULL_UP) { ++ ret = mcp23017_conf_set_gppu(dev, offset, 1); ++ if (ret) ++ return ret; ++ } else { ++ ret = mcp23017_conf_set_gppu(dev, offset, 0); ++ if (ret) ++ return ret; ++ } ++ } ++ ++ return ret; ++} ++ ++static int mcp23017_gpio_get_flags(struct udevice *dev, unsigned int offset, ++ ulong *flags) ++{ ++ ulong dir_flags = 0; ++ int ret; ++ ++ if (mcp23017_gpio_get_function(dev, offset) == GPIOF_OUTPUT) { ++ dir_flags |= GPIOD_IS_OUT; ++ ++ ret = mcp23017_gpio_get(dev, offset); ++ if (ret < 0) ++ return ret; ++ if (ret) ++ dir_flags |= GPIOD_IS_OUT_ACTIVE; ++ } else { ++ dir_flags |= GPIOD_IS_IN; ++ ++ ret = mcp23017_conf_get_gppu(dev, offset); ++ if (ret < 0) ++ return ret; ++ if (ret == 1) ++ dir_flags |= GPIOD_PULL_UP; ++ } ++ *flags = dir_flags; ++ ++ return 0; ++} ++ ++static int mcp23017_gpio_probe(struct udevice *dev) ++{ ++ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); ++ ++ uc_priv->bank_name = "mcp_gpio"; ++ uc_priv->gpio_count = MCP_MAX_GPIO; ++ ++ return 0; ++} ++ ++static const struct dm_gpio_ops mcp23017_gpio_ops = { ++ .set_value = mcp23017_gpio_set, ++ .get_value = mcp23017_gpio_get, ++ .get_function = mcp23017_gpio_get_function, ++ .direction_input = mcp23017_gpio_direction_input, ++ .direction_output = mcp23017_gpio_direction_output, ++ .set_flags = mcp23017_gpio_set_flags, ++ .get_flags = mcp23017_gpio_get_flags, ++}; ++ ++U_BOOT_DRIVER(mcp23017_gpio) = { ++ .name = "mcp23017-gpio", ++ .id = UCLASS_GPIO, ++ .probe = mcp23017_gpio_probe, ++ .ops = &mcp23017_gpio_ops, ++}; ++ ++#if CONFIG_IS_ENABLED(PINCONF) ++static const struct pinconf_param mcp23017_pinctrl_conf_params[] = { ++ { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 0 }, ++ { "output-high", PIN_CONFIG_OUTPUT, 1 }, ++ { "output-low", PIN_CONFIG_OUTPUT, 0 }, ++}; ++ ++static int mcp23017_pinctrl_conf_set(struct udevice *dev, unsigned int pin, ++ unsigned int param, unsigned int arg) ++{ ++ int ret, dir; ++ ++ /* directly call the generic gpio function, only based on i2c parent */ ++ dir = mcp23017_gpio_get_function(dev, pin); ++ ++ if (dir < 0) ++ return dir; ++ ++ switch (param) { ++ case PIN_CONFIG_BIAS_PULL_UP: ++ ret = mcp23017_conf_set_gppu(dev, pin, 1); ++ break; ++ case PIN_CONFIG_OUTPUT: ++ ret = mcp23017_gpio_direction_output(dev, pin, arg); ++ break; ++ default: ++ return -ENOTSUPP; ++ } ++ ++ return ret; ++} ++#endif ++ ++static int mcp23017_pinctrl_get_pins_count(struct udevice *dev) ++{ ++ return MCP_MAX_GPIO; ++} ++ ++static char pin_name[PINNAME_SIZE]; ++static const char *mcp23017_pinctrl_get_pin_name(struct udevice *dev, ++ unsigned int selector) ++{ ++ snprintf(pin_name, PINNAME_SIZE, "mcp_gpio%u", selector); ++ ++ return pin_name; ++} ++ ++static const char *mcp23017_pinctrl_get_pin_conf(struct udevice *dev, ++ unsigned int pin, int func) ++{ ++ int pupd; ++ ++ pupd = mcp23017_conf_get_gppu(dev, pin); ++ if (pupd < 0) ++ return ""; ++ ++ if (pupd) ++ return "bias-pull-up"; ++ else ++ return ""; ++} ++ ++static int mcp23017_pinctrl_get_pin_muxing(struct udevice *dev, ++ unsigned int selector, ++ char *buf, int size) ++{ ++ int func; ++ ++ func = mcp23017_gpio_get_function(dev, selector); ++ if (func < 0) ++ return func; ++ ++ snprintf(buf, size, "%s ", func == GPIOF_INPUT ? "input" : "output"); ++ ++ strlcat(buf, mcp23017_pinctrl_get_pin_conf(dev, selector, func), size); ++ ++ return 0; ++} ++ ++const struct pinctrl_ops mcp23017_pinctrl_ops = { ++ .get_pins_count = mcp23017_pinctrl_get_pins_count, ++ .get_pin_name = mcp23017_pinctrl_get_pin_name, ++ .set_state = pinctrl_generic_set_state, ++ .get_pin_muxing = mcp23017_pinctrl_get_pin_muxing, ++#if CONFIG_IS_ENABLED(PINCONF) ++ .pinconf_set = mcp23017_pinctrl_conf_set, ++ .pinconf_num_params = ARRAY_SIZE(mcp23017_pinctrl_conf_params), ++ .pinconf_params = mcp23017_pinctrl_conf_params, ++#endif ++}; ++ ++U_BOOT_DRIVER(mcp23017_pinctrl) = { ++ .name = "mcp23017-pinctrl", ++ .id = UCLASS_PINCTRL, ++ .ops = &mcp23017_pinctrl_ops, ++}; ++ ++static int mcp23017_bind(struct udevice *dev) ++{ ++ int ret; ++ ++ ret = device_bind_driver_to_node(dev, "mcp23017-pinctrl", "mcp23017-pinctrl", ++ dev_ofnode(dev), NULL); ++ if (ret) ++ return ret; ++ ++ return device_bind_driver_to_node(dev, "mcp23017-gpio", "mcp23017-gpio", ++ dev_ofnode(dev), NULL); ++} ++ ++static int mcp23017_chip_init(struct udevice *dev) ++{ ++ int ret, iocon; ++ ++ ret = dm_i2c_reg_read(dev, MCP_REG_IOCON); ++ dev_dbg(dev, "reg = 0x%x val = 0x%x\n", MCP_REG_IOCON, ret); ++ if (ret < 0) { ++ dev_err(dev, "Can't read MCP23017 IOCON register (%d)\n", ret); ++ return ret; ++ } ++ ++ /* deactivate Sequential mode if activated */ ++ if (ret & IOCON_SEQOP) { ++ iocon = ret & ~IOCON_SEQOP; ++ ++ ret = dm_i2c_reg_write(dev, MCP_REG_IOCON, iocon); ++ if (ret < 0) { ++ dev_err(dev, "can't write IOCON register (%d)\n", ret); ++ } else { ++ /* mcp23017 has IOCON twice, make sure they are in sync */ ++ ret = dm_i2c_reg_write(dev, MCP_REG_IOCON + 1, iocon); ++ if (ret < 0) ++ dev_err(dev, "can't write IOCON register (%d)\n", ret); ++ } ++ } ++ ++ return ret; ++} ++ ++static int mcp23017_probe(struct udevice *dev) ++{ ++ struct udevice *vdd; ++ struct reset_ctl reset; ++ int ret; ++ ++ if (CONFIG_IS_ENABLED(DM_REGULATOR)) { ++ ret = device_get_supply_regulator(dev, "vdd-supply", &vdd); ++ if (ret && ret != -ENOENT) { ++ dev_err(dev, "vdd regulator error:%d\n", ret); ++ return ret; ++ } ++ if (!ret) { ++ ret = regulator_set_enable(vdd, true); ++ if (ret) { ++ dev_err(dev, "vdd enable failed: %d\n", ret); ++ return ret; ++ } ++ } ++ } ++ ++ ret = reset_get_by_index(dev, 0, &reset); ++ if (!ret) { ++ reset_assert(&reset); ++ udelay(2); ++ reset_deassert(&reset); ++ } ++ ++ return mcp23017_chip_init(dev); ++} ++ ++static const struct udevice_id mcp23017_match[] = { ++ { .compatible = "microchip,mcp23017", }, ++}; ++ ++U_BOOT_DRIVER(mcp23017) = { ++ .name = "mcp23017", ++ .id = UCLASS_I2C_GENERIC, ++ .of_match = of_match_ptr(mcp23017_match), ++ .probe = mcp23017_probe, ++ .bind = mcp23017_bind, ++}; +diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c +index fe7a59d431..509e2a80e9 100644 +--- a/drivers/pinctrl/pinctrl-stmfx.c ++++ b/drivers/pinctrl/pinctrl-stmfx.c +@@ -5,8 +5,12 @@ + * Driver for STMicroelectronics Multi-Function eXpander (STMFX) GPIO expander + * based on Linux driver : pinctrl/pinctrl-stmfx.c + */ ++ ++#define LOG_CATEGORY UCLASS_PINCTRL ++ + #include + #include ++#include + #include + #include + #include +diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c +index 6c98538f56..9c88101145 100644 +--- a/drivers/pinctrl/pinctrl_stm32.c ++++ b/drivers/pinctrl/pinctrl_stm32.c +@@ -10,9 +10,9 @@ + #include + #include + #include +-#include + #include + #include ++#include + #include + #include + #include +@@ -20,12 +20,15 @@ + #include + #include + ++#include "../gpio/stm32_gpio_priv.h" ++ + #define MAX_PINS_ONE_IP 70 + #define MODE_BITS_MASK 3 + #define OSPEED_MASK 3 + #define PUPD_MASK 3 + #define OTYPE_MSK 1 + #define AFR_MASK 0xF ++#define SECCFG_MSK 1 + + struct stm32_pinctrl_priv { + struct hwspinlock hws; +@@ -38,16 +41,21 @@ struct stm32_gpio_bank { + struct list_head list; + }; + ++struct stm32_pinctrl_data { ++ bool secure_control; ++}; ++ ++static int stm32_pinctrl_get_access(struct udevice *gpio_dev, unsigned int gpio_idx); ++ + #ifndef CONFIG_SPL_BUILD + + static char pin_name[PINNAME_SIZE]; +-#define PINMUX_MODE_COUNT 5 +-static const char * const pinmux_mode[PINMUX_MODE_COUNT] = { +- "gpio input", +- "gpio output", +- "analog", +- "unknown", +- "alt function", ++static const char * const pinmux_mode[GPIOF_COUNT] = { ++ [GPIOF_INPUT] = "gpio input", ++ [GPIOF_OUTPUT] = "gpio output", ++ [GPIOF_UNUSED] = "analog", ++ [GPIOF_UNKNOWN] = "unknown", ++ [GPIOF_FUNC] = "alt function", + }; + + static const char * const pinmux_bias[] = { +@@ -157,10 +165,7 @@ static struct udevice *stm32_pinctrl_get_gpio_dev(struct udevice *dev, + * we found the bank, convert pin selector to + * gpio bank index + */ +- *idx = stm32_offset_to_index(gpio_bank->gpio_dev, +- selector - pin_count); +- if (IS_ERR_VALUE(*idx)) +- return NULL; ++ *idx = selector - pin_count; + + return gpio_bank->gpio_dev; + } +@@ -211,6 +216,12 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, + if (!gpio_dev) + return -ENODEV; + ++ /* Check access protection */ ++ if (stm32_pinctrl_get_access(gpio_dev, gpio_idx)) { ++ snprintf(buf, size, "NO ACCESS"); ++ return 0; ++ } ++ + mode = gpio_get_raw_function(gpio_dev, gpio_idx, &label); + dev_dbg(dev, "selector = %d gpio_idx = %d mode = %d\n", + selector, gpio_idx, mode); +@@ -220,8 +231,6 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, + + switch (mode) { + case GPIOF_UNKNOWN: +- /* should never happen */ +- return -EINVAL; + case GPIOF_UNUSED: + snprintf(buf, size, "%s", pinmux_mode[mode]); + break; +@@ -246,6 +255,20 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, + + #endif + ++static int stm32_pinctrl_get_access(struct udevice *gpio_dev, unsigned int gpio_idx) ++{ ++ struct stm32_gpio_priv *priv = dev_get_priv(gpio_dev); ++ struct stm32_gpio_regs *regs = priv->regs; ++ ulong drv_data = dev_get_driver_data(gpio_dev); ++ ++ /* Deny request access if IO is secured */ ++ if ((drv_data & STM32_GPIO_FLAG_SEC_CTRL) && ++ ((readl(®s->seccfgr) >> gpio_idx) & SECCFG_MSK)) ++ return -EACCES; ++ ++ return 0; ++} ++ + static int stm32_pinctrl_probe(struct udevice *dev) + { + struct stm32_pinctrl_priv *priv = dev_get_priv(dev); +@@ -266,11 +289,20 @@ static int stm32_gpio_config(struct gpio_desc *desc, + const struct stm32_gpio_ctl *ctl) + { + struct stm32_gpio_priv *priv = dev_get_priv(desc->dev); ++ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc->dev); + struct stm32_gpio_regs *regs = priv->regs; + struct stm32_pinctrl_priv *ctrl_priv; + int ret; + u32 index; + ++ /* Check access protection */ ++ ret = stm32_pinctrl_get_access(desc->dev, desc->offset); ++ if (ret) { ++ dev_err(desc->dev, "Failed to get secure IO %s %d @ %p\n", ++ uc_priv->bank_name, desc->offset, regs); ++ return ret; ++ } ++ + if (!ctl || ctl->af > 15 || ctl->mode > 3 || ctl->otype > 1 || + ctl->pupd > 2 || ctl->speed > 3) + return -EINVAL; +@@ -404,8 +436,25 @@ static int stm32_pinctrl_bind(struct udevice *dev) + { + ofnode node; + const char *name; ++ struct driver *drv; ++ const struct stm32_pinctrl_data *drv_data; ++ ulong gpio_data = 0; + int ret; + ++ drv = lists_driver_lookup_name("gpio_stm32"); ++ if (!drv) { ++ debug("Cannot find driver 'gpio_stm32'\n"); ++ return -ENOENT; ++ } ++ ++ drv_data = (const struct stm32_pinctrl_data *)dev_get_driver_data(dev); ++ if (!drv_data) { ++ debug("Cannot find driver data\n"); ++ return -EINVAL; ++ } ++ if (drv_data->secure_control) ++ gpio_data = STM32_GPIO_FLAG_SEC_CTRL; ++ + dev_for_each_subnode(node, dev) { + dev_dbg(dev, "bind %s\n", ofnode_get_name(node)); + +@@ -421,8 +470,7 @@ static int stm32_pinctrl_bind(struct udevice *dev) + return -EINVAL; + + /* Bind each gpio node */ +- ret = device_bind_driver_to_node(dev, "gpio_stm32", +- name, node, NULL); ++ ret = device_bind_with_driver_data(dev, drv, name, gpio_data, node, NULL); + if (ret) + return ret; + +@@ -485,14 +533,23 @@ static struct pinctrl_ops stm32_pinctrl_ops = { + #endif + }; + ++static const struct stm32_pinctrl_data stm32_pinctrl_no_sec = { ++ .secure_control = false, ++}; ++ ++static const struct stm32_pinctrl_data stm32_pinctrl_with_sec = { ++ .secure_control = true, ++}; ++ + static const struct udevice_id stm32_pinctrl_ids[] = { +- { .compatible = "st,stm32f429-pinctrl" }, +- { .compatible = "st,stm32f469-pinctrl" }, +- { .compatible = "st,stm32f746-pinctrl" }, +- { .compatible = "st,stm32f769-pinctrl" }, +- { .compatible = "st,stm32h743-pinctrl" }, +- { .compatible = "st,stm32mp157-pinctrl" }, +- { .compatible = "st,stm32mp157-z-pinctrl" }, ++ { .compatible = "st,stm32f429-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, ++ { .compatible = "st,stm32f469-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, ++ { .compatible = "st,stm32f746-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, ++ { .compatible = "st,stm32f769-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, ++ { .compatible = "st,stm32h743-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, ++ { .compatible = "st,stm32mp157-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, ++ { .compatible = "st,stm32mp157-z-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, ++ { .compatible = "st,stm32mp135-pinctrl", .data = (ulong)&stm32_pinctrl_with_sec }, + { } + }; + +diff --git a/drivers/power/regulator/scmi_regulator.c b/drivers/power/regulator/scmi_regulator.c +index b3142bf4e1..5e2eb6e365 100644 +--- a/drivers/power/regulator/scmi_regulator.c ++++ b/drivers/power/regulator/scmi_regulator.c +@@ -2,6 +2,9 @@ + /* + * Copyright (C) 2020-2021 Linaro Limited + */ ++ ++#define LOG_CATEGORY UCLASS_REGULATOR ++ + #include + #include + #include +@@ -14,12 +17,19 @@ + #include + #include + ++/* Voltage domain IDs must fit in 16bit */ ++#define VOLTD_INVALID_DOMAIN_ID UINT32_MAX ++ + /** + * struct scmi_regulator_platdata - Platform data for a scmi voltage domain regulator + * @domain_id: ID representing the regulator for the related SCMI agent ++ * @voltd_name: String ID representing the regulator in the SCMI server ++ * @supply: Regulator supply or NULL + */ + struct scmi_regulator_platdata { + u32 domain_id; ++ const char *voltd_name; ++ struct udevice *supply; + }; + + static int scmi_voltd_set_enable(struct udevice *dev, bool enable) +@@ -35,7 +45,13 @@ static int scmi_voltd_set_enable(struct udevice *dev, bool enable) + in, out); + int ret; + +- ret = devm_scmi_process_msg(dev->parent->parent, &msg); ++ if (pdata->supply && enable) { ++ ret = regulator_set_enable(pdata->supply, true); ++ if (ret) ++ return ret; ++ } ++ ++ ret = devm_scmi_process_msg(dev, &msg); + if (ret) + return ret; + +@@ -58,7 +74,7 @@ static int scmi_voltd_get_enable(struct udevice *dev) + in, out); + int ret; + +- ret = devm_scmi_process_msg(dev->parent->parent, &msg); ++ ret = devm_scmi_process_msg(dev, &msg); + if (ret < 0) + return ret; + +@@ -82,7 +98,7 @@ static int scmi_voltd_set_voltage_level(struct udevice *dev, int uV) + in, out); + int ret; + +- ret = devm_scmi_process_msg(dev->parent->parent, &msg); ++ ret = devm_scmi_process_msg(dev, &msg); + if (ret < 0) + return ret; + +@@ -101,7 +117,7 @@ static int scmi_voltd_get_voltage_level(struct udevice *dev) + in, out); + int ret; + +- ret = devm_scmi_process_msg(dev->parent->parent, &msg); ++ ret = devm_scmi_process_msg(dev, &msg); + if (ret < 0) + return ret; + +@@ -112,6 +128,11 @@ static int scmi_voltd_get_voltage_level(struct udevice *dev) + return out.voltage_level; + } + ++static bool voltd_name_is_valid(char *name) ++{ ++ return strnlen(name, SCMI_VOLTD_NAME_LEN) < SCMI_VOLTD_NAME_LEN; ++} ++ + static int scmi_regulator_of_to_plat(struct udevice *dev) + { + struct scmi_regulator_platdata *pdata = dev_get_plat(dev); +@@ -119,13 +140,81 @@ static int scmi_regulator_of_to_plat(struct udevice *dev) + + reg = dev_read_addr(dev); + if (reg == FDT_ADDR_T_NONE) ++ pdata->domain_id = VOLTD_INVALID_DOMAIN_ID; ++ else ++ pdata->domain_id = (u32)reg; ++ ++ pdata->voltd_name = dev_read_string(dev, "voltd-name"); ++ if (pdata->voltd_name && ++ !voltd_name_is_valid((char *)pdata->voltd_name)) { ++ dev_dbg(dev, "oversized voltd-name\n"); + return -EINVAL; ++ } + +- pdata->domain_id = (u32)reg; ++ if (!pdata->voltd_name && pdata->domain_id == VOLTD_INVALID_DOMAIN_ID) { ++ dev_dbg(dev, "OF node %s: missing reg or voltd-name property\n", ++ dev->name); ++ return -EINVAL; ++ } + + return 0; + } + ++static int voltd_count(struct udevice *dev, size_t *count) ++{ ++ struct scmi_voltd_protocol_attr_out out = { 0 }; ++ struct scmi_msg scmi_msg = { ++ .protocol_id = SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN, ++ .message_id = SCMI_PROTOCOL_ATTRIBUTES, ++ .out_msg = (u8 *)&out, ++ .out_msg_sz = sizeof(out), ++ }; ++ int ret; ++ ++ ret = devm_scmi_process_msg(dev, &scmi_msg); ++ if (ret < 0) ++ return ret; ++ ++ *count = out.attributes; ++ ++ return 0; ++} ++ ++static int voltd_name_to_domain_id(struct udevice *dev, ++ struct scmi_regulator_platdata *pdata) ++{ ++ struct scmi_voltd_attr_in in = { 0 }; ++ struct scmi_voltd_attr_out out = { 0 }; ++ struct scmi_msg scmi_msg = { ++ .protocol_id = SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN, ++ .message_id = SCMI_VOLTAGE_DOMAIN_ATTRIBUTES, ++ .in_msg = (u8 *)&in, ++ .in_msg_sz = sizeof(in), ++ .out_msg = (u8 *)&out, ++ .out_msg_sz = sizeof(out), ++ }; ++ int ret; ++ size_t count, n; ++ ++ ret = voltd_count(dev, &count); ++ if (ret) ++ return ret; ++ ++ for (n = 0; n < count; n++) { ++ in.domain_id = n; ++ scmi_msg.out_msg_sz = sizeof(out); ++ ++ ret = devm_scmi_process_msg(dev, &scmi_msg); ++ if (!ret && voltd_name_is_valid(out.name) && ++ !strcmp(pdata->voltd_name, out.name)) { ++ pdata->domain_id = n; ++ return 0; ++ } ++ } ++ ++ return -ENOENT; ++} ++ + static int scmi_regulator_probe(struct udevice *dev) + { + struct scmi_regulator_platdata *pdata = dev_get_plat(dev); +@@ -139,19 +228,41 @@ static int scmi_regulator_probe(struct udevice *dev) + .out_msg = (u8 *)&out, + .out_msg_sz = sizeof(out), + }; ++ struct udevice *supply; + int ret; + ++ if (pdata->domain_id == VOLTD_INVALID_DOMAIN_ID) { ++ ret = voltd_name_to_domain_id(dev, pdata); ++ if (ret) ++ return ret; ++ } ++ + /* Check voltage domain is known from SCMI server */ + in.domain_id = pdata->domain_id; + +- ret = devm_scmi_process_msg(dev->parent->parent, &scmi_msg); ++ ret = devm_scmi_process_msg(dev, &scmi_msg); + if (ret) { + dev_err(dev, "Failed to query voltage domain %u: %d\n", + pdata->domain_id, ret); + return -ENXIO; + } + +- return 0; ++ if (!pdata->voltd_name) { ++ if (!voltd_name_is_valid(out.name)) ++ return -EINVAL; ++ ++ pdata->voltd_name = strdup(out.name); ++ } ++ ++ dev_dbg(dev, "voltd %u: \"%s\"\n", pdata->domain_id, pdata->voltd_name); ++ ++ ret = device_get_supply_regulator(dev, "regulator-supply", &supply); ++ if (!ret) ++ pdata->supply = supply; ++ if (ret == -ENOENT) ++ ret = 0; ++ ++ return ret; + } + + static const struct dm_regulator_ops scmi_voltd_ops = { +diff --git a/drivers/power/regulator/stm32-vrefbuf.c b/drivers/power/regulator/stm32-vrefbuf.c +index c37998a4ba..b49dbe84ea 100644 +--- a/drivers/power/regulator/stm32-vrefbuf.c ++++ b/drivers/power/regulator/stm32-vrefbuf.c +@@ -32,13 +32,21 @@ struct stm32_vrefbuf { + void __iomem *base; + struct clk clk; + struct udevice *vdda_supply; ++ const int *voltages; + }; + +-static const int stm32_vrefbuf_voltages[] = { ++#define STM32_VOLTAGE_TABLE_SIZE 4 ++ ++static const int stm32_vrefbuf_voltages[STM32_VOLTAGE_TABLE_SIZE] = { + /* Matches resp. VRS = 000b, 001b, 010b, 011b */ + 2500000, 2048000, 1800000, 1500000, + }; + ++static const int stm32mp13_vrefbuf_voltages[STM32_VOLTAGE_TABLE_SIZE] = { ++ /* Matches resp. VRS = 000b, 001b, 010b, 011b */ ++ 2500000, 2048000, 1800000, 1650000, ++}; ++ + static int stm32_vrefbuf_set_enable(struct udevice *dev, bool enable) + { + struct stm32_vrefbuf *priv = dev_get_priv(dev); +@@ -92,8 +100,8 @@ static int stm32_vrefbuf_set_value(struct udevice *dev, int uV) + struct stm32_vrefbuf *priv = dev_get_priv(dev); + unsigned int i; + +- for (i = 0; i < ARRAY_SIZE(stm32_vrefbuf_voltages); i++) { +- if (uV == stm32_vrefbuf_voltages[i]) { ++ for (i = 0; i < STM32_VOLTAGE_TABLE_SIZE; i++) { ++ if (uV == priv->voltages[i]) { + clrsetbits_le32(priv->base + STM32_VREFBUF_CSR, + STM32_VRS, i << STM32_VRS_SHIFT); + return 0; +@@ -111,7 +119,7 @@ static int stm32_vrefbuf_get_value(struct udevice *dev) + val = readl(priv->base + STM32_VREFBUF_CSR) & STM32_VRS; + val >>= STM32_VRS_SHIFT; + +- return stm32_vrefbuf_voltages[val]; ++ return priv->voltages[val]; + } + + static const struct dm_regulator_ops stm32_vrefbuf_ops = { +@@ -128,6 +136,12 @@ static int stm32_vrefbuf_probe(struct udevice *dev) + + priv->base = dev_read_addr_ptr(dev); + ++ priv->voltages = (const int *)dev_get_driver_data(dev); ++ if (!priv->voltages) { ++ debug("Cannot find driver data\n"); ++ return -EINVAL; ++ } ++ + ret = clk_get_by_index(dev, 0, &priv->clk); + if (ret) { + dev_err(dev, "Can't get clock: %d\n", ret); +@@ -157,7 +171,8 @@ static int stm32_vrefbuf_probe(struct udevice *dev) + } + + static const struct udevice_id stm32_vrefbuf_ids[] = { +- { .compatible = "st,stm32-vrefbuf" }, ++ { .compatible = "st,stm32-vrefbuf", .data = (ulong)&stm32_vrefbuf_voltages }, ++ { .compatible = "st,stm32mp13-vrefbuf", .data = (ulong)&stm32mp13_vrefbuf_voltages }, + { } + }; + +diff --git a/drivers/ram/stm32mp1/Makefile b/drivers/ram/stm32mp1/Makefile +index e1e9135603..71ded6bed4 100644 +--- a/drivers/ram/stm32mp1/Makefile ++++ b/drivers/ram/stm32mp1/Makefile +@@ -8,7 +8,6 @@ obj-y += stm32mp1_ddr.o + + obj-$(CONFIG_STM32MP1_DDR_INTERACTIVE) += stm32mp1_interactive.o + obj-$(CONFIG_STM32MP1_DDR_TESTS) += stm32mp1_tests.o +-obj-$(CONFIG_STM32MP1_DDR_TUNING) += stm32mp1_tuning.o + + ifneq ($(DDR_INTERACTIVE),) + CFLAGS_stm32mp1_interactive.o += -DCONFIG_STM32MP1_DDR_INTERACTIVE_FORCE=y +diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c +index 0457166b12..4d78aa5cb1 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_ddr.c ++++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c +@@ -68,7 +68,6 @@ struct reg_desc { + + #define DDRPHY_REG_REG_SIZE 11 /* st,phy-reg */ + #define DDRPHY_REG_TIMING_SIZE 10 /* st,phy-timing */ +-#define DDRPHY_REG_CAL_SIZE 12 /* st,phy-cal */ + + #define DDRCTL_REG_REG(x) DDRCTL_REG(x, stm32mp1_ddrctrl_reg) + static const struct reg_desc ddr_reg[DDRCTL_REG_REG_SIZE] = { +@@ -178,22 +177,6 @@ static const struct reg_desc ddrphy_timing[DDRPHY_REG_TIMING_SIZE] = { + DDRPHY_REG_TIMING(mr3), + }; + +-#define DDRPHY_REG_CAL(x) DDRPHY_REG(x, stm32mp1_ddrphy_cal) +-static const struct reg_desc ddrphy_cal[DDRPHY_REG_CAL_SIZE] = { +- DDRPHY_REG_CAL(dx0dllcr), +- DDRPHY_REG_CAL(dx0dqtr), +- DDRPHY_REG_CAL(dx0dqstr), +- DDRPHY_REG_CAL(dx1dllcr), +- DDRPHY_REG_CAL(dx1dqtr), +- DDRPHY_REG_CAL(dx1dqstr), +- DDRPHY_REG_CAL(dx2dllcr), +- DDRPHY_REG_CAL(dx2dqtr), +- DDRPHY_REG_CAL(dx2dqstr), +- DDRPHY_REG_CAL(dx3dllcr), +- DDRPHY_REG_CAL(dx3dqtr), +- DDRPHY_REG_CAL(dx3dqstr), +-}; +- + /************************************************************** + * DYNAMIC REGISTERS: only used for debug purpose (read/modify) + **************************************************************/ +@@ -218,12 +201,24 @@ static const struct reg_desc ddrphy_dyn[] = { + DDRPHY_REG_DYN(zq0sr1), + DDRPHY_REG_DYN(dx0gsr0), + DDRPHY_REG_DYN(dx0gsr1), ++ DDRPHY_REG_DYN(dx0dllcr), ++ DDRPHY_REG_DYN(dx0dqtr), ++ DDRPHY_REG_DYN(dx0dqstr), + DDRPHY_REG_DYN(dx1gsr0), + DDRPHY_REG_DYN(dx1gsr1), ++ DDRPHY_REG_DYN(dx1dllcr), ++ DDRPHY_REG_DYN(dx1dqtr), ++ DDRPHY_REG_DYN(dx1dqstr), + DDRPHY_REG_DYN(dx2gsr0), + DDRPHY_REG_DYN(dx2gsr1), ++ DDRPHY_REG_DYN(dx2dllcr), ++ DDRPHY_REG_DYN(dx2dqtr), ++ DDRPHY_REG_DYN(dx2dqstr), + DDRPHY_REG_DYN(dx3gsr0), + DDRPHY_REG_DYN(dx3gsr1), ++ DDRPHY_REG_DYN(dx3dllcr), ++ DDRPHY_REG_DYN(dx3dqtr), ++ DDRPHY_REG_DYN(dx3dqstr), + }; + + #define DDRPHY_REG_DYN_SIZE ARRAY_SIZE(ddrphy_dyn) +@@ -240,7 +235,6 @@ enum reg_type { + REG_MAP, + REGPHY_REG, + REGPHY_TIMING, +- REGPHY_CAL, + #ifdef CONFIG_STM32MP1_DDR_INTERACTIVE + /* dynamic registers => managed in driver or not changed, + * can be dumped in interactive mode +@@ -264,8 +258,6 @@ struct ddr_reg_info { + enum base_type base; + }; + +-#define DDRPHY_REG_CAL(x) DDRPHY_REG(x, stm32mp1_ddrphy_cal) +- + const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = { + [REG_REG] = { + "static", ddr_reg, DDRCTL_REG_REG_SIZE, DDR_BASE}, +@@ -279,8 +271,6 @@ const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = { + "static", ddrphy_reg, DDRPHY_REG_REG_SIZE, DDRPHY_BASE}, + [REGPHY_TIMING] = { + "timing", ddrphy_timing, DDRPHY_REG_TIMING_SIZE, DDRPHY_BASE}, +-[REGPHY_CAL] = { +- "cal", ddrphy_cal, DDRPHY_REG_CAL_SIZE, DDRPHY_BASE}, + #ifdef CONFIG_STM32MP1_DDR_INTERACTIVE + [REG_DYN] = { + "dyn", ddr_dyn, DDR_REG_DYN_SIZE, DDR_BASE}, +@@ -456,9 +446,6 @@ static u32 get_par_addr(const struct stm32mp1_ddr_config *config, + case REGPHY_TIMING: + par_addr = (u32)&config->p_timing; + break; +- case REGPHY_CAL: +- par_addr = (u32)&config->p_cal; +- break; + case REG_DYN: + case REGPHY_DYN: + case REG_TYPE_NB: +@@ -570,7 +557,7 @@ static void ddrphy_idone_wait(struct stm32mp1_ddrphy *phy) + (u32)&phy->pgsr, pgsr, ret); + } + +-void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, u32 pir) ++static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, u32 pir) + { + pir |= DDRPHYC_PIR_INIT; + writel(pir, &phy->pir); +@@ -639,7 +626,7 @@ static void wait_operating_mode(struct ddr_info *priv, int mode) + log_debug("[0x%08x] stat = 0x%08x\n", (u32)&priv->ctl->stat, stat); + } + +-void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl) ++static void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl) + { + start_sw_done(ctl); + /* quasi-dynamic register update*/ +@@ -650,8 +637,8 @@ void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl) + wait_sw_done_ack(ctl); + } + +-void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl, +- u32 rfshctl3, u32 pwrctl) ++static void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl, ++ u32 rfshctl3, u32 pwrctl) + { + start_sw_done(ctl); + if (!(rfshctl3 & DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH)) +@@ -774,8 +761,6 @@ start: + */ + set_reg(priv, REGPHY_REG, &config->p_reg); + set_reg(priv, REGPHY_TIMING, &config->p_timing); +- if (config->p_cal_present) +- set_reg(priv, REGPHY_CAL, &config->p_cal); + + if (INTERACTIVE(STEP_PHY_INIT)) + goto start; +@@ -810,32 +795,32 @@ start: + + wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL); + +- if (config->p_cal_present) { +- log_debug("DDR DQS training skipped.\n"); +- } else { +- log_debug("DDR DQS training : "); ++ log_debug("DDR DQS training : "); + /* 8. Disable Auto refresh and power down by setting + * - RFSHCTL3.dis_au_refresh = 1 + * - PWRCTL.powerdown_en = 0 + * - DFIMISC.dfiinit_complete_en = 0 + */ +- stm32mp1_refresh_disable(priv->ctl); ++ stm32mp1_refresh_disable(priv->ctl); + + /* 9. Program PUBL PGCR to enable refresh during training and rank to train + * not done => keep the programed value in PGCR + */ + + /* 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 excuted 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); ++ ddrphy_idone_wait(priv->phy); + + /* 12. set back registers in step 8 to the orginal values if desidered */ +- stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3, +- config->c_reg.pwrctl); +- } /* if (config->p_cal_present) */ ++ stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3, ++ config->c_reg.pwrctl); + + /* enable uMCTL2 AXI port 0 and 1 */ + setbits_le32(&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN); +diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.h b/drivers/ram/stm32mp1/stm32mp1_ddr.h +index 4998f04439..861efff92b 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_ddr.h ++++ b/drivers/ram/stm32mp1/stm32mp1_ddr.h +@@ -140,21 +140,6 @@ struct stm32mp1_ddrphy_timing { + u32 mr3; + }; + +-struct stm32mp1_ddrphy_cal { +- u32 dx0dllcr; +- u32 dx0dqtr; +- u32 dx0dqstr; +- u32 dx1dllcr; +- u32 dx1dqtr; +- u32 dx1dqstr; +- u32 dx2dllcr; +- u32 dx2dqtr; +- u32 dx2dqstr; +- u32 dx3dllcr; +- u32 dx3dqtr; +- u32 dx3dqstr; +-}; +- + struct stm32mp1_ddr_info { + const char *name; + u32 speed; /* in kHZ */ +@@ -169,16 +154,9 @@ struct stm32mp1_ddr_config { + struct stm32mp1_ddrctrl_perf c_perf; + struct stm32mp1_ddrphy_reg p_reg; + struct stm32mp1_ddrphy_timing p_timing; +- struct stm32mp1_ddrphy_cal p_cal; +- bool p_cal_present; + }; + + int stm32mp1_ddr_clk_enable(struct ddr_info *priv, u32 mem_speed); +-void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, u32 pir); +-void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl); +-void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl, +- u32 rfshctl3, +- u32 pwrctl); + + void stm32mp1_ddr_init( + struct ddr_info *priv, +diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h +index 3c8885a965..f1a26e31f6 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h ++++ b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h +@@ -6,8 +6,9 @@ + #ifndef _RAM_STM32MP1_DDR_REGS_H + #define _RAM_STM32MP1_DDR_REGS_H + +-/* DDR3/LPDDR2/LPDDR3 Controller (DDRCTRL) registers */ + #include ++ ++/* DDR3/LPDDR2/LPDDR3 Controller (DDRCTRL) registers */ + struct stm32mp1_ddrctl { + u32 mstr ; /* 0x0 Master*/ + u32 stat; /* 0x4 Operating Mode Status*/ +@@ -238,6 +239,7 @@ struct stm32mp1_ddrphy { + #define DDRCTRL_MSTR_LPDDR2 BIT(2) + #define DDRCTRL_MSTR_LPDDR3 BIT(3) + #define DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK GENMASK(13, 12) ++#define DDRCTRL_MSTR_DATA_BUS_WIDTH_SHIFT 12 + #define DDRCTRL_MSTR_DATA_BUS_WIDTH_FULL (0 << 12) + #define DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF (1 << 12) + #define DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER (2 << 12) +@@ -275,25 +277,6 @@ struct stm32mp1_ddrphy { + + #define DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN BIT(0) + +-#define DDRCTRL_DBG1_DIS_HIF BIT(1) +- +-#define DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY BIT(29) +-#define DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY BIT(28) +-#define DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY BIT(26) +-#define DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH GENMASK(12, 8) +-#define DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH GENMASK(4, 0) +-#define DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY \ +- (DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY | \ +- DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY) +-#define DDRCTRL_DBGCAM_DBG_Q_DEPTH \ +- (DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY | \ +- DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH | \ +- DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH) +- +-#define DDRCTRL_DBGCMD_RANK0_REFRESH BIT(0) +- +-#define DDRCTRL_DBGSTAT_RANK0_REFRESH_BUSY BIT(0) +- + #define DDRCTRL_SWCTL_SW_DONE BIT(0) + + #define DDRCTRL_SWSTAT_SW_DONE_ACK BIT(0) +@@ -309,13 +292,9 @@ 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) +- +-#define DDRPHYC_PGCR_DFTCMP BIT(2) +-#define DDRPHYC_PGCR_PDDISDX BIT(24) +-#define DDRPHYC_PGCR_RFSHDT_MASK GENMASK(28, 25) + + #define DDRPHYC_PGSR_IDONE BIT(0) + #define DDRPHYC_PGSR_DTERR BIT(5) +@@ -324,43 +303,6 @@ struct stm32mp1_ddrphy { + #define DDRPHYC_PGSR_RVERR BIT(8) + #define DDRPHYC_PGSR_RVEIRR BIT(9) + +-#define DDRPHYC_DLLGCR_BPS200 BIT(23) +- +-#define DDRPHYC_ACDLLCR_DLLDIS BIT(31) +- +-#define DDRPHYC_ZQ0CRN_ZDATA_MASK GENMASK(27, 0) +-#define DDRPHYC_ZQ0CRN_ZDATA_SHIFT 0 +-#define DDRPHYC_ZQ0CRN_ZDEN BIT(28) +- +-#define DDRPHYC_DXNGCR_DXEN BIT(0) +- +-#define DDRPHYC_DXNDLLCR_DLLSRST BIT(30) +-#define DDRPHYC_DXNDLLCR_DLLDIS BIT(31) +-#define DDRPHYC_DXNDLLCR_SDPHASE_MASK GENMASK(17, 14) +-#define DDRPHYC_DXNDLLCR_SDPHASE_SHIFT 14 +- +-#define DDRPHYC_DXNDQTR_DQDLY_SHIFT(bit) (4 * (bit)) +-#define DDRPHYC_DXNDQTR_DQDLY_MASK GENMASK(3, 0) +-#define DDRPHYC_DXNDQTR_DQDLY_LOW_MASK GENMASK(1, 0) +-#define DDRPHYC_DXNDQTR_DQDLY_HIGH_MASK GENMASK(3, 2) +- +-#define DDRPHYC_DXNDQSTR_DQSDLY_MASK GENMASK(22, 20) +-#define DDRPHYC_DXNDQSTR_DQSDLY_SHIFT 20 +-#define DDRPHYC_DXNDQSTR_DQSNDLY_MASK GENMASK(25, 23) +-#define DDRPHYC_DXNDQSTR_DQSNDLY_SHIFT 23 +-#define DDRPHYC_DXNDQSTR_R0DGSL_MASK GENMASK(2, 0) +-#define DDRPHYC_DXNDQSTR_R0DGSL_SHIFT 0 +-#define DDRPHYC_DXNDQSTR_R0DGPS_MASK GENMASK(13, 12) +-#define DDRPHYC_DXNDQSTR_R0DGPS_SHIFT 12 +- +-#define DDRPHYC_BISTRR_BDXSEL_MASK GENMASK(22, 19) +-#define DDRPHYC_BISTRR_BDXSEL_SHIFT 19 +- +-#define DDRPHYC_BISTGSR_BDDONE BIT(0) +-#define DDRPHYC_BISTGSR_BDXERR BIT(2) +- +-#define DDRPHYC_BISTWCSR_DXWCNT_SHIFT 16 +- + /* PWR registers */ + #define PWR_CR3 0x00C + #define PWR_CR3_DDRSRDIS BIT(11) +diff --git a/drivers/ram/stm32mp1/stm32mp1_interactive.c b/drivers/ram/stm32mp1/stm32mp1_interactive.c +index 8c2310ac90..f0fe7e61e3 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_interactive.c ++++ b/drivers/ram/stm32mp1/stm32mp1_interactive.c +@@ -32,7 +32,6 @@ enum ddr_command { + DDR_CMD_NEXT, + DDR_CMD_GO, + DDR_CMD_TEST, +- DDR_CMD_TUNING, + DDR_CMD_UNKNOWN, + }; + +@@ -59,9 +58,6 @@ enum ddr_command stm32mp1_get_command(char *cmd, int argc) + [DDR_CMD_GO] = "go", + #ifdef CONFIG_STM32MP1_DDR_TESTS + [DDR_CMD_TEST] = "test", +-#endif +-#ifdef CONFIG_STM32MP1_DDR_TUNING +- [DDR_CMD_TUNING] = "tuning", + #endif + }; + /* min and max number of argument */ +@@ -78,9 +74,6 @@ enum ddr_command stm32mp1_get_command(char *cmd, int argc) + [DDR_CMD_GO] = { 0, 0 }, + #ifdef CONFIG_STM32MP1_DDR_TESTS + [DDR_CMD_TEST] = { 0, 255 }, +-#endif +-#ifdef CONFIG_STM32MP1_DDR_TUNING +- [DDR_CMD_TUNING] = { 0, 255 }, + #endif + }; + int i; +@@ -111,7 +104,7 @@ static void stm32mp1_do_usage(void) + "help displays help\n" + "info displays DDR information\n" + "info changes DDR information\n" +- " with = step, name, size, speed or cal\n" ++ " with = step, name, size or speed\n" + "freq displays the DDR PHY frequency in kHz\n" + "freq changes the DDR PHY frequency\n" + "param [type|reg] prints input parameters\n" +@@ -125,14 +118,11 @@ static void stm32mp1_do_usage(void) + "reset reboots machine\n" + #ifdef CONFIG_STM32MP1_DDR_TESTS + "test [help] | [...] lists (with help) or executes test \n" +-#endif +-#ifdef CONFIG_STM32MP1_DDR_TUNING +- "tuning [help] | [...] lists (with help) or execute tuning \n" + #endif + "\nwith for [type|reg]:\n" + " all registers if absent\n" + " = ctl, phy\n" +- " or one category (static, timing, map, perf, cal, dyn)\n" ++ " or one category (static, timing, map, perf, dyn)\n" + " = name of the register\n" + }; + +@@ -165,7 +155,6 @@ static void stm32mp1_do_info(struct ddr_info *priv, + printf("name = %s\n", config->info.name); + printf("size = 0x%x\n", config->info.size); + printf("speed = %d kHz\n", config->info.speed); +- printf("cal = %d\n", config->p_cal_present); + return; + } + +@@ -214,16 +203,6 @@ static void stm32mp1_do_info(struct ddr_info *priv, + } + return; + } +- if (!strcmp(argv[1], "cal")) { +- if (strict_strtoul(argv[2], 10, &value) < 0 || +- (value != 0 && value != 1)) { +- printf("invalid value %s\n", argv[2]); +- } else { +- config->p_cal_present = value; +- printf("cal = %d\n", config->p_cal_present); +- } +- return; +- } + printf("argument %s invalid\n", argv[1]); + } + +@@ -322,7 +301,7 @@ end: + return step; + } + +-#if defined(CONFIG_STM32MP1_DDR_TESTS) || defined(CONFIG_STM32MP1_DDR_TUNING) ++#if defined(CONFIG_STM32MP1_DDR_TESTS) + static const char * const s_result[] = { + [TEST_PASSED] = "Pass", + [TEST_FAILED] = "Failed", +@@ -479,16 +458,6 @@ bool stm32mp1_ddr_interactive(void *priv, + stm32mp1_ddr_subcmd(priv, argc, argv, test, test_nb); + break; + #endif +- +-#ifdef CONFIG_STM32MP1_DDR_TUNING +- case DDR_CMD_TUNING: +- if (!stm32mp1_check_step(step, STEP_DDR_READY)) +- continue; +- stm32mp1_ddr_subcmd(priv, argc, argv, +- tuning, tuning_nb); +- break; +-#endif +- + default: + break; + } +diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c b/drivers/ram/stm32mp1/stm32mp1_ram.c +index 26f0b4f1ea..a6c19af972 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_ram.c ++++ b/drivers/ram/stm32mp1/stm32mp1_ram.c +@@ -16,6 +16,12 @@ + #include + #include + #include "stm32mp1_ddr.h" ++#include "stm32mp1_ddr_regs.h" ++ ++/* DDR subsystem configuration */ ++struct stm32mp1_ddr_cfg { ++ u8 nb_bytes; /* MEMC_DRAM_DATA_WIDTH */ ++}; + + static const char *const clkname[] = { + "ddrc1", +@@ -82,7 +88,7 @@ static ofnode stm32mp1_ddr_get_ofnode(struct udevice *dev) + return dev_ofnode(dev); + } + +-static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) ++static int stm32mp1_ddr_setup(struct udevice *dev) + { + struct ddr_info *priv = dev_get_priv(dev); + int ret; +@@ -95,26 +101,22 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) + { .name = x, \ + .offset = offsetof(struct stm32mp1_ddr_config, y), \ + .size = sizeof(config.y) / sizeof(u32), \ +- .present = z, \ + } + + #define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x, NULL) + #define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x, NULL) +-#define PHY_PARAM_OPT(x) PARAM("st,phy-"#x, p_##x, &config.p_##x##_present) + + const struct { + const char *name; /* name in DT */ + const u32 offset; /* offset in config struct */ + const u32 size; /* size of parameters */ +- bool * const present; /* presence indication for opt */ + } param[] = { + CTL_PARAM(reg), + CTL_PARAM(timing), + CTL_PARAM(map), + CTL_PARAM(perf), + PHY_PARAM(reg), +- PHY_PARAM(timing), +- PHY_PARAM_OPT(cal) ++ PHY_PARAM(timing) + }; + + config.info.speed = ofnode_read_u32_default(node, "st,mem-speed", 0); +@@ -133,25 +135,11 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) + param[idx].size); + dev_dbg(dev, "%s: %s[0x%x] = %d\n", __func__, + param[idx].name, param[idx].size, ret); +- if (ret && +- (ret != -FDT_ERR_NOTFOUND || !param[idx].present)) { ++ if (ret) { + dev_err(dev, "Cannot read %s, error=%d\n", + param[idx].name, ret); + return -EINVAL; + } +- if (param[idx].present) { +- /* save presence of optional parameters */ +- *param[idx].present = true; +- if (ret == -FDT_ERR_NOTFOUND) { +- *param[idx].present = false; +-#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE +- /* reset values if used later */ +- memset((void *)((u32)&config + +- param[idx].offset), +- 0, param[idx].size * sizeof(u32)); +-#endif +- } +- } + } + + ret = clk_get_by_name(dev, "axidcg", &axidcg); +@@ -183,6 +171,186 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) + return 0; + } + ++static u8 get_data_bus_width(struct stm32mp1_ddrctl *ctl) ++{ ++ u32 reg = readl(&ctl->mstr) & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK; ++ u8 data_bus_width = reg >> DDRCTRL_MSTR_DATA_BUS_WIDTH_SHIFT; ++ ++ return data_bus_width; ++} ++ ++static u8 get_nb_bank(struct stm32mp1_ddrctl *ctl) ++{ ++ /* Count bank address bits */ ++ u8 bits = 0; ++ u32 reg, val; ++ ++ reg = readl(&ctl->addrmap1); ++ /* addrmap1.addrmap_bank_b1 */ ++ val = (reg & GENMASK(5, 0)) >> 0; ++ if (val <= 31) ++ bits++; ++ /* addrmap1.addrmap_bank_b2 */ ++ val = (reg & GENMASK(13, 8)) >> 8; ++ if (val <= 31) ++ bits++; ++ /* addrmap1.addrmap_bank_b3 */ ++ val = (reg & GENMASK(21, 16)) >> 16; ++ if (val <= 31) ++ bits++; ++ ++ return bits; ++} ++ ++static u8 get_nb_col(struct stm32mp1_ddrctl *ctl, u8 data_bus_width) ++{ ++ u8 bits; ++ u32 reg, val; ++ ++ /* Count column address bits, start at 2 for b0 and b1 (fixed) */ ++ bits = 2; ++ ++ reg = readl(&ctl->addrmap2); ++ /* addrmap2.addrmap_col_b2 */ ++ val = (reg & GENMASK(3, 0)) >> 0; ++ if (val <= 7) ++ bits++; ++ /* addrmap2.addrmap_col_b3 */ ++ val = (reg & GENMASK(11, 8)) >> 8; ++ if (val <= 7) ++ bits++; ++ /* addrmap2.addrmap_col_b4 */ ++ val = (reg & GENMASK(19, 16)) >> 16; ++ if (val <= 7) ++ bits++; ++ /* addrmap2.addrmap_col_b5 */ ++ val = (reg & GENMASK(27, 24)) >> 24; ++ if (val <= 7) ++ bits++; ++ ++ reg = readl(&ctl->addrmap3); ++ /* addrmap3.addrmap_col_b6 */ ++ val = (reg & GENMASK(4, 0)) >> 0; ++ if (val <= 7) ++ bits++; ++ /* addrmap3.addrmap_col_b7 */ ++ val = (reg & GENMASK(12, 8)) >> 8; ++ if (val <= 7) ++ bits++; ++ /* addrmap3.addrmap_col_b8 */ ++ val = (reg & GENMASK(20, 16)) >> 16; ++ if (val <= 7) ++ bits++; ++ /* addrmap3.addrmap_col_b9 */ ++ val = (reg & GENMASK(28, 24)) >> 24; ++ if (val <= 7) ++ bits++; ++ ++ reg = readl(&ctl->addrmap4); ++ /* addrmap4.addrmap_col_b10 */ ++ val = (reg & GENMASK(4, 0)) >> 0; ++ if (val <= 7) ++ bits++; ++ /* addrmap4.addrmap_col_b11 */ ++ val = (reg & GENMASK(12, 8)) >> 8; ++ if (val <= 7) ++ bits++; ++ ++ /* ++ * column bits shift up: ++ * 1 when half the data bus is used (data_bus_width = 1) ++ * 2 when a quarter the data bus is used (data_bus_width = 2) ++ * nothing to do for full data bus (data_bus_width = 0) ++ */ ++ bits += data_bus_width; ++ ++ return bits; ++} ++ ++static u8 get_nb_row(struct stm32mp1_ddrctl *ctl) ++{ ++ /* Count row address bits */ ++ u8 bits = 0; ++ u32 reg, val; ++ ++ reg = readl(&ctl->addrmap5); ++ /* addrmap5.addrmap_row_b0 */ ++ val = (reg & GENMASK(3, 0)) >> 0; ++ if (val <= 11) ++ bits++; ++ /* addrmap5.addrmap_row_b1 */ ++ val = (reg & GENMASK(11, 8)) >> 8; ++ if (val <= 11) ++ bits++; ++ /* addrmap5.addrmap_row_b2_10 */ ++ val = (reg & GENMASK(19, 16)) >> 16; ++ if (val <= 11) ++ bits += 9; ++ else ++ printf("warning: addrmap5.addrmap_row_b2_10 not supported\n"); ++ /* addrmap5.addrmap_row_b11 */ ++ val = (reg & GENMASK(27, 24)) >> 24; ++ if (val <= 11) ++ bits++; ++ ++ reg = readl(&ctl->addrmap6); ++ /* addrmap6.addrmap_row_b12 */ ++ val = (reg & GENMASK(3, 0)) >> 0; ++ if (val <= 11) ++ bits++; ++ /* addrmap6.addrmap_row_b13 */ ++ val = (reg & GENMASK(11, 8)) >> 8; ++ if (val <= 11) ++ bits++; ++ /* addrmap6.addrmap_row_b14 */ ++ val = (reg & GENMASK(19, 16)) >> 16; ++ if (val <= 11) ++ bits++; ++ /* addrmap6.addrmap_row_b15 */ ++ val = (reg & GENMASK(27, 24)) >> 24; ++ if (val <= 11) ++ bits++; ++ ++ if (reg & BIT(31)) ++ printf("warning: LPDDR3_6GB_12GB is not supported\n"); ++ ++ return bits; ++} ++ ++/* ++ * stm32mp1_ddr_size ++ * ++ * Get the current DRAM size from the DDR CTL registers ++ * ++ * @return: DRAM size ++ */ ++u32 stm32mp1_ddr_size(struct udevice *dev) ++{ ++ u8 nb_bit; ++ u32 ddr_size; ++ u8 data_bus_width; ++ struct ddr_info *priv = dev_get_priv(dev); ++ struct stm32mp1_ddrctl *ctl = priv->ctl; ++ struct stm32mp1_ddr_cfg *cfg = (struct stm32mp1_ddr_cfg *)dev_get_driver_data(dev); ++ const u8 nb_bytes = cfg->nb_bytes; ++ ++ data_bus_width = get_data_bus_width(ctl); ++ nb_bit = get_nb_bank(ctl) + get_nb_col(ctl, data_bus_width) + ++ get_nb_row(ctl); ++ if (nb_bit > 32) { ++ nb_bit = 32; ++ debug("invalid DDR configuration: %d bits\n", nb_bit); ++ } ++ ++ ddr_size = (nb_bytes >> data_bus_width) << nb_bit; ++ if (ddr_size > STM32_DDR_SIZE) { ++ ddr_size = STM32_DDR_SIZE; ++ debug("invalid DDR configuration: size = %x\n", ddr_size); ++ } ++ ++ return ddr_size; ++} ++ + static int stm32mp1_ddr_probe(struct udevice *dev) + { + struct ddr_info *priv = dev_get_priv(dev); +@@ -202,17 +370,16 @@ static int stm32mp1_ddr_probe(struct udevice *dev) + + priv->info.base = STM32_DDR_BASE; + +-#if !defined(CONFIG_TFABOOT) && \ +- (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) +- priv->info.size = 0; +- ret = stm32mp1_ddr_setup(dev); ++ if (IS_ENABLED(CONFIG_SPL_BUILD)) { ++ priv->info.size = 0; ++ ret = stm32mp1_ddr_setup(dev); ++ ++ return log_ret(ret); ++ } ++ ++ priv->info.size = stm32mp1_ddr_size(dev); + +- return log_ret(ret); +-#else +- ofnode node = stm32mp1_ddr_get_ofnode(dev); +- priv->info.size = ofnode_read_u32_default(node, "st,mem-size", 0); + return 0; +-#endif + } + + static int stm32mp1_ddr_get_info(struct udevice *dev, struct ram_info *info) +@@ -228,8 +395,17 @@ static struct ram_ops stm32mp1_ddr_ops = { + .get_info = stm32mp1_ddr_get_info, + }; + ++static const struct stm32mp1_ddr_cfg stm32mp13x_ddr_cfg = { ++ .nb_bytes = 2, ++}; ++ ++static const struct stm32mp1_ddr_cfg stm32mp15x_ddr_cfg = { ++ .nb_bytes = 4, ++}; ++ + static const struct udevice_id stm32mp1_ddr_ids[] = { +- { .compatible = "st,stm32mp1-ddr" }, ++ { .compatible = "st,stm32mp1-ddr", .data = (ulong)&stm32mp15x_ddr_cfg}, ++ { .compatible = "st,stm32mp13-ddr", .data = (ulong)&stm32mp13x_ddr_cfg}, + { } + }; + +diff --git a/drivers/ram/stm32mp1/stm32mp1_tests.h b/drivers/ram/stm32mp1/stm32mp1_tests.h +index 55f5d6d93b..8436780790 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_tests.h ++++ b/drivers/ram/stm32mp1/stm32mp1_tests.h +@@ -28,7 +28,4 @@ struct test_desc { + extern const struct test_desc test[]; + extern const int test_nb; + +-extern const struct test_desc tuning[]; +-extern const int tuning_nb; +- + #endif +diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c +deleted file mode 100644 +index c8cd7c3cea..0000000000 +--- a/drivers/ram/stm32mp1/stm32mp1_tuning.c ++++ /dev/null +@@ -1,1540 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +-/* +- * Copyright (C) 2019, STMicroelectronics - All Rights Reserved +- */ +- +-#define LOG_CATEGORY UCLASS_RAM +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "stm32mp1_ddr_regs.h" +-#include "stm32mp1_ddr.h" +-#include "stm32mp1_tests.h" +- +-#define MAX_DQS_PHASE_IDX _144deg +-#define MAX_DQS_UNIT_IDX 7 +-#define MAX_GSL_IDX 5 +-#define MAX_GPS_IDX 3 +- +-/* Number of bytes used in this SW. ( min 1--> max 4). */ +-#define NUM_BYTES 4 +- +-enum dqs_phase_enum { +- _36deg = 0, +- _54deg = 1, +- _72deg = 2, +- _90deg = 3, +- _108deg = 4, +- _126deg = 5, +- _144deg = 6 +-}; +- +-/* BIST Result struct */ +-struct BIST_result { +- /* Overall test result: +- * 0 Fail (any bit failed) , +- * 1 Success (All bits success) +- */ +- bool test_result; +- /* 1: true, all fail / 0: False, not all bits fail */ +- bool all_bits_fail; +- bool bit_i_test_result[8]; /* 0 fail / 1 success */ +-}; +- +-/* a struct that defines tuning parameters of a byte. */ +-struct tuning_position { +- u8 phase; /* DQS phase */ +- u8 unit; /* DQS unit delay */ +- u32 bits_delay; /* Bits deskew in this byte */ +-}; +- +-/* 36deg, 54deg, 72deg, 90deg, 108deg, 126deg, 144deg */ +-const u8 dx_dll_phase[7] = {3, 2, 1, 0, 14, 13, 12}; +- +-static u8 BIST_error_max = 1; +-static u32 BIST_seed = 0x1234ABCD; +- +-static u8 get_nb_bytes(struct stm32mp1_ddrctl *ctl) +-{ +- u32 data_bus = readl(&ctl->mstr) & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK; +- u8 nb_bytes = NUM_BYTES; +- +- switch (data_bus) { +- case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF: +- nb_bytes /= 2; +- break; +- case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER: +- nb_bytes /= 4; +- break; +- default: +- break; +- } +- +- return nb_bytes; +-} +- +-static u8 get_nb_bank(struct stm32mp1_ddrctl *ctl) +-{ +- /* Count bank address bits */ +- u8 bits = 0; +- u32 reg, val; +- +- reg = readl(&ctl->addrmap1); +- /* addrmap1.addrmap_bank_b1 */ +- val = (reg & GENMASK(5, 0)) >> 0; +- if (val <= 31) +- bits++; +- /* addrmap1.addrmap_bank_b2 */ +- val = (reg & GENMASK(13, 8)) >> 8; +- if (val <= 31) +- bits++; +- /* addrmap1.addrmap_bank_b3 */ +- val = (reg & GENMASK(21, 16)) >> 16; +- if (val <= 31) +- bits++; +- +- return bits; +-} +- +-static u8 get_nb_col(struct stm32mp1_ddrctl *ctl) +-{ +- u8 bits; +- u32 reg, val; +- +- /* Count column address bits, start at 2 for b0 and b1 (fixed) */ +- bits = 2; +- +- reg = readl(&ctl->addrmap2); +- /* addrmap2.addrmap_col_b2 */ +- val = (reg & GENMASK(3, 0)) >> 0; +- if (val <= 7) +- bits++; +- /* addrmap2.addrmap_col_b3 */ +- val = (reg & GENMASK(11, 8)) >> 8; +- if (val <= 7) +- bits++; +- /* addrmap2.addrmap_col_b4 */ +- val = (reg & GENMASK(19, 16)) >> 16; +- if (val <= 7) +- bits++; +- /* addrmap2.addrmap_col_b5 */ +- val = (reg & GENMASK(27, 24)) >> 24; +- if (val <= 7) +- bits++; +- +- reg = readl(&ctl->addrmap3); +- /* addrmap3.addrmap_col_b6 */ +- val = (reg & GENMASK(3, 0)) >> 0; +- if (val <= 7) +- bits++; +- /* addrmap3.addrmap_col_b7 */ +- val = (reg & GENMASK(11, 8)) >> 8; +- if (val <= 7) +- bits++; +- /* addrmap3.addrmap_col_b8 */ +- val = (reg & GENMASK(19, 16)) >> 16; +- if (val <= 7) +- bits++; +- /* addrmap3.addrmap_col_b9 */ +- val = (reg & GENMASK(27, 24)) >> 24; +- if (val <= 7) +- bits++; +- +- reg = readl(&ctl->addrmap4); +- /* addrmap4.addrmap_col_b10 */ +- val = (reg & GENMASK(3, 0)) >> 0; +- if (val <= 7) +- bits++; +- /* addrmap4.addrmap_col_b11 */ +- val = (reg & GENMASK(11, 8)) >> 8; +- if (val <= 7) +- bits++; +- +- return bits; +-} +- +-static u8 get_nb_row(struct stm32mp1_ddrctl *ctl) +-{ +- /* Count row address bits */ +- u8 bits = 0; +- u32 reg, val; +- +- reg = readl(&ctl->addrmap5); +- /* addrmap5.addrmap_row_b0 */ +- val = (reg & GENMASK(3, 0)) >> 0; +- if (val <= 11) +- bits++; +- /* addrmap5.addrmap_row_b1 */ +- val = (reg & GENMASK(11, 8)) >> 8; +- if (val <= 11) +- bits++; +- /* addrmap5.addrmap_row_b2_10 */ +- val = (reg & GENMASK(19, 16)) >> 16; +- if (val <= 11) +- bits += 9; +- else +- printf("warning: addrmap5.addrmap_row_b2_10 not supported\n"); +- /* addrmap5.addrmap_row_b11 */ +- val = (reg & GENMASK(27, 24)) >> 24; +- if (val <= 11) +- bits++; +- +- reg = readl(&ctl->addrmap6); +- /* addrmap6.addrmap_row_b12 */ +- val = (reg & GENMASK(3, 0)) >> 0; +- if (val <= 7) +- bits++; +- /* addrmap6.addrmap_row_b13 */ +- val = (reg & GENMASK(11, 8)) >> 8; +- if (val <= 7) +- bits++; +- /* addrmap6.addrmap_row_b14 */ +- val = (reg & GENMASK(19, 16)) >> 16; +- if (val <= 7) +- bits++; +- /* addrmap6.addrmap_row_b15 */ +- val = (reg & GENMASK(27, 24)) >> 24; +- if (val <= 7) +- bits++; +- +- return bits; +-} +- +-static void itm_soft_reset(struct stm32mp1_ddrphy *phy) +-{ +- stm32mp1_ddrphy_init(phy, DDRPHYC_PIR_ITMSRST); +-} +- +-/* Read DQ unit delay register and provides the retrieved value for DQS +- * We are assuming that we have the same delay when clocking +- * by DQS and when clocking by DQSN +- */ +-static u8 DQ_unit_index(struct stm32mp1_ddrphy *phy, u8 byte, u8 bit) +-{ +- u32 index; +- u32 addr = DXNDQTR(phy, byte); +- +- /* We are assuming that we have the same delay when clocking by DQS +- * and when clocking by DQSN : use only the low bits +- */ +- index = (readl(addr) >> DDRPHYC_DXNDQTR_DQDLY_SHIFT(bit)) +- & DDRPHYC_DXNDQTR_DQDLY_LOW_MASK; +- +- log_debug("[%x]: %x => DQ unit index = %x\n", addr, readl(addr), index); +- +- return index; +-} +- +-/* Sets the DQS phase delay for a byte lane. +- *phase delay is specified by giving the index of the desired delay +- * in the dx_dll_phase array. +- */ +-static void DQS_phase_delay(struct stm32mp1_ddrphy *phy, u8 byte, u8 phase_idx) +-{ +- u8 sdphase_val = 0; +- +- /* Write DXNDLLCR.SDPHASE = dx_dll_phase(phase_index); */ +- sdphase_val = dx_dll_phase[phase_idx]; +- clrsetbits_le32(DXNDLLCR(phy, byte), +- DDRPHYC_DXNDLLCR_SDPHASE_MASK, +- sdphase_val << DDRPHYC_DXNDLLCR_SDPHASE_SHIFT); +-} +- +-/* Sets the DQS unit delay for a byte lane. +- * unit delay is specified by giving the index of the desired delay +- * for dgsdly and dqsndly (same value). +- */ +-static void DQS_unit_delay(struct stm32mp1_ddrphy *phy, +- u8 byte, u8 unit_dly_idx) +-{ +- /* Write the same value in DXNDQSTR.DQSDLY and DXNDQSTR.DQSNDLY */ +- clrsetbits_le32(DXNDQSTR(phy, byte), +- DDRPHYC_DXNDQSTR_DQSDLY_MASK | +- DDRPHYC_DXNDQSTR_DQSNDLY_MASK, +- (unit_dly_idx << DDRPHYC_DXNDQSTR_DQSDLY_SHIFT) | +- (unit_dly_idx << DDRPHYC_DXNDQSTR_DQSNDLY_SHIFT)); +- +- /* After changing this value, an ITM soft reset (PIR.ITMSRST=1, +- * plus PIR.INIT=1) must be issued. +- */ +- stm32mp1_ddrphy_init(phy, DDRPHYC_PIR_ITMSRST); +-} +- +-/* Sets the DQ unit delay for a bit line in particular byte lane. +- * unit delay is specified by giving the desired delay +- */ +-static void set_DQ_unit_delay(struct stm32mp1_ddrphy *phy, +- u8 byte, u8 bit, +- u8 dq_delay_index) +-{ +- u8 dq_bit_delay_val = dq_delay_index | (dq_delay_index << 2); +- +- /* same value on delay for clock DQ an DQS_b */ +- clrsetbits_le32(DXNDQTR(phy, byte), +- DDRPHYC_DXNDQTR_DQDLY_MASK +- << DDRPHYC_DXNDQTR_DQDLY_SHIFT(bit), +- dq_bit_delay_val << DDRPHYC_DXNDQTR_DQDLY_SHIFT(bit)); +-} +- +-static void set_r0dgsl_delay(struct stm32mp1_ddrphy *phy, +- u8 byte, u8 r0dgsl_idx) +-{ +- clrsetbits_le32(DXNDQSTR(phy, byte), +- DDRPHYC_DXNDQSTR_R0DGSL_MASK, +- r0dgsl_idx << DDRPHYC_DXNDQSTR_R0DGSL_SHIFT); +-} +- +-static void set_r0dgps_delay(struct stm32mp1_ddrphy *phy, +- u8 byte, u8 r0dgps_idx) +-{ +- clrsetbits_le32(DXNDQSTR(phy, byte), +- DDRPHYC_DXNDQSTR_R0DGPS_MASK, +- r0dgps_idx << DDRPHYC_DXNDQSTR_R0DGPS_SHIFT); +-} +- +-/* Basic BIST configuration for data lane tests. */ +-static void config_BIST(struct stm32mp1_ddrctl *ctl, +- struct stm32mp1_ddrphy *phy) +-{ +- u8 nb_bank = get_nb_bank(ctl); +- u8 nb_row = get_nb_row(ctl); +- u8 nb_col = get_nb_col(ctl); +- +- /* Selects the SDRAM bank address to be used during BIST. */ +- u32 bbank = 0; +- /* Selects the SDRAM row address to be used during BIST. */ +- u32 brow = 0; +- /* Selects the SDRAM column address to be used during BIST. */ +- u32 bcol = 0; +- /* Selects the value by which the SDRAM address is incremented +- * for each write/read access. +- */ +- u32 bainc = 0x00000008; +- /* Specifies the maximum SDRAM rank to be used during BIST. +- * The default value is set to maximum ranks minus 1. +- * must be 0 with single rank +- */ +- u32 bmrank = 0; +- /* Selects the SDRAM rank to be used during BIST. +- * must be 0 with single rank +- */ +- u32 brank = 0; +- +- /* Specifies the maximum SDRAM bank address to be used during +- * BIST before the address & increments to the next rank. +- */ +- u32 bmbank = (1 << nb_bank) - 1; +- /* Specifies the maximum SDRAM row address to be used during +- * BIST before the address & increments to the next bank. +- */ +- u32 bmrow = (1 << nb_row) - 1; +- /* Specifies the maximum SDRAM column address to be used during +- * BIST before the address & increments to the next row. +- */ +- u32 bmcol = (1 << nb_col) - 1; +- +- u32 bmode_conf = 0x00000001; /* DRam mode */ +- u32 bdxen_conf = 0x00000001; /* BIST on Data byte */ +- u32 bdpat_conf = 0x00000002; /* Select LFSR pattern */ +- +- /*Setup BIST for DRAM mode, and LFSR-random data pattern.*/ +- /*Write BISTRR.BMODE = 1?b1;*/ +- /*Write BISTRR.BDXEN = 1?b1;*/ +- /*Write BISTRR.BDPAT = 2?b10;*/ +- +- /* reset BIST */ +- writel(0x3, &phy->bistrr); +- +- writel((bmode_conf << 3) | (bdxen_conf << 14) | (bdpat_conf << 17), +- &phy->bistrr); +- +- /*Setup BIST Word Count*/ +- /*Write BISTWCR.BWCNT = 16?b0008;*/ +- writel(0x00000200, &phy->bistwcr); /* A multiple of BL/2 */ +- +- writel(bcol | (brow << 12) | (bbank << 28), &phy->bistar0); +- writel(brank | (bmrank << 2) | (bainc << 4), &phy->bistar1); +- writel(bmcol | (bmrow << 12) | (bmbank << 28), &phy->bistar2); +-} +- +-/* Select the Byte lane to be tested by BIST. */ +-static void BIST_datx8_sel(struct stm32mp1_ddrphy *phy, u8 datx8) +-{ +- clrsetbits_le32(&phy->bistrr, +- DDRPHYC_BISTRR_BDXSEL_MASK, +- datx8 << DDRPHYC_BISTRR_BDXSEL_SHIFT); +- +- /*(For example, selecting Byte Lane 3, BISTRR.BDXSEL = 4?b0011)*/ +- /* Write BISTRR.BDXSEL = datx8; */ +-} +- +-/* Perform BIST Write_Read test on a byte lane and return test result. */ +-static void BIST_test(struct stm32mp1_ddrphy *phy, u8 byte, +- struct BIST_result *bist) +-{ +- bool result = true; /* BIST_SUCCESS */ +- u32 cnt = 0; +- u32 error = 0; +- u32 val; +- int ret; +- +- bist->test_result = true; +- +-run: +- itm_soft_reset(phy); +- +- /*Perform BIST Reset*/ +- /* Write BISTRR.BINST = 3?b011; */ +- clrsetbits_le32(&phy->bistrr, +- 0x00000007, +- 0x00000003); +- +- /*Re-seed LFSR*/ +- /* Write BISTLSR.SEED = 32'h1234ABCD; */ +- if (BIST_seed) +- writel(BIST_seed, &phy->bistlsr); +- else +- writel(rand(), &phy->bistlsr); +- +- /* some delay to reset BIST */ +- udelay(10); +- +- /*Perform BIST Run*/ +- clrsetbits_le32(&phy->bistrr, +- 0x00000007, +- 0x00000001); +- /* Write BISTRR.BINST = 3?b001; */ +- +- /* poll on BISTGSR.BDONE and wait max 1000 us */ +- ret = readl_poll_timeout(&phy->bistgsr, val, +- val & DDRPHYC_BISTGSR_BDDONE, 1000); +- +- if (ret < 0) { +- printf("warning: BIST timeout\n"); +- result = false; /* BIST_FAIL; */ +- /*Perform BIST Stop */ +- clrsetbits_le32(&phy->bistrr, 0x00000007, 0x00000002); +- } else { +- /*Check if received correct number of words*/ +- /* if (Read BISTWCSR.DXWCNT = Read BISTWCR.BWCNT) */ +- if (((readl(&phy->bistwcsr)) >> DDRPHYC_BISTWCSR_DXWCNT_SHIFT) +- == readl(&phy->bistwcr)) { +- /*Determine if there is a data comparison error*/ +- /* if (Read BISTGSR.BDXERR = 1?b0) */ +- if (readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDXERR) +- result = false; /* BIST_FAIL; */ +- else +- result = true; /* BIST_SUCCESS; */ +- } else { +- result = false; /* BIST_FAIL; */ +- } +- } +- +- /* loop while success */ +- cnt++; +- if (result && cnt != 1000) +- goto run; +- +- if (!result) +- error++; +- +- if (error < BIST_error_max) { +- if (cnt != 1000) +- goto run; +- bist->test_result = true; +- } else { +- bist->test_result = false; +- } +-} +- +-/* After running the deskew algo, this function applies the new DQ delays +- * by reading them from the array "deskew_delay"and writing in PHY registers. +- * The bits that are not deskewed parfectly (too much skew on them, +- * or data eye very wide) are marked in the array deskew_non_converge. +- */ +-static void apply_deskew_results(struct stm32mp1_ddrphy *phy, u8 byte, +- u8 deskew_delay[NUM_BYTES][8], +- u8 deskew_non_converge[NUM_BYTES][8]) +-{ +- u8 bit_i; +- u8 index; +- +- for (bit_i = 0; bit_i < 8; bit_i++) { +- set_DQ_unit_delay(phy, byte, bit_i, deskew_delay[byte][bit_i]); +- index = DQ_unit_index(phy, byte, bit_i); +- log_debug("Byte %d ; bit %d : The new DQ delay (%d) index=%d [delta=%d, 3 is the default]", +- byte, bit_i, deskew_delay[byte][bit_i], +- index, index - 3); +- printf("Byte %d, bit %d, DQ delay = %d", +- byte, bit_i, deskew_delay[byte][bit_i]); +- if (deskew_non_converge[byte][bit_i] == 1) +- log_debug(" - not converged : still more skew"); +- printf("\n"); +- } +-} +- +-/* DQ Bit de-skew algorithm. +- * Deskews data lines as much as possible. +- * 1. Add delay to DQS line until finding the failure +- * (normally a hold time violation) +- * 2. Reduce DQS line by small steps until finding the very first time +- * we go back to "Pass" condition. +- * 3. For each DQ line, Reduce DQ delay until finding the very first failure +- * (normally a hold time fail) +- * 4. When all bits are at their first failure delay, we can consider them +- * aligned. +- * Handle conrer situation (Can't find Pass-fail, or fail-pass transitions +- * at any step) +- * TODO Provide a return Status. Improve doc +- */ +-static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, +- struct stm32mp1_ddrphy *phy, char *string) +-{ +- /* New DQ delay value (index), set during Deskew algo */ +- u8 deskew_delay[NUM_BYTES][8]; +- /*If there is still skew on a bit, mark this bit. */ +- u8 deskew_non_converge[NUM_BYTES][8]; +- struct BIST_result result; +- s8 dqs_unit_delay_index = 0; +- u8 datx8 = 0; +- u8 bit_i = 0; +- s8 phase_idx = 0; +- s8 bit_i_delay_index = 0; +- u8 success = 0; +- struct tuning_position last_right_ok; +- u8 force_stop = 0; +- u8 fail_found; +- u8 error = 0; +- u8 nb_bytes = get_nb_bytes(ctl); +- /* u8 last_pass_dqs_unit = 0; */ +- +- memset(deskew_delay, 0, sizeof(deskew_delay)); +- memset(deskew_non_converge, 0, sizeof(deskew_non_converge)); +- +- /*Disable DQS Drift Compensation*/ +- clrbits_le32(&phy->pgcr, DDRPHYC_PGCR_DFTCMP); +- /*Disable all bytes*/ +- /* Disable automatic power down of DLL and IOs when disabling +- * a byte (To avoid having to add programming and delay +- * for a DLL re-lock when later re-enabling a disabled Byte Lane) +- */ +- clrbits_le32(&phy->pgcr, DDRPHYC_PGCR_PDDISDX); +- +- /* Disable all data bytes */ +- clrbits_le32(&phy->dx0gcr, DDRPHYC_DXNGCR_DXEN); +- clrbits_le32(&phy->dx1gcr, DDRPHYC_DXNGCR_DXEN); +- clrbits_le32(&phy->dx2gcr, DDRPHYC_DXNGCR_DXEN); +- clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN); +- +- /* Config the BIST block */ +- config_BIST(ctl, phy); +- log_debug("BIST Config done.\n"); +- +- /* Train each byte */ +- for (datx8 = 0; datx8 < nb_bytes; datx8++) { +- if (ctrlc()) { +- sprintf(string, "interrupted at byte %d/%d, error=%d", +- datx8 + 1, nb_bytes, error); +- return TEST_FAILED; +- } +- log_debug("\n======================\n"); +- log_debug("Start deskew byte %d .\n", datx8); +- log_debug("======================\n"); +- /* Enable Byte (DXNGCR, bit DXEN) */ +- setbits_le32(DXNGCR(phy, datx8), DDRPHYC_DXNGCR_DXEN); +- +- /* Select the byte lane for comparison of read data */ +- BIST_datx8_sel(phy, datx8); +- +- /* Set all DQDLYn to maximum value. All bits within the byte +- * will be delayed with DQSTR = 2 instead of max = 3 +- * to avoid inter bits fail influence +- */ +- writel(0xAAAAAAAA, DXNDQTR(phy, datx8)); +- +- /* Set the DQS phase delay to 90 DEG (default). +- * What is defined here is the index of the desired config +- * in the PHASE array. +- */ +- phase_idx = _90deg; +- +- /* Set DQS unit delay to the max value. */ +- dqs_unit_delay_index = MAX_DQS_UNIT_IDX; +- DQS_unit_delay(phy, datx8, dqs_unit_delay_index); +- DQS_phase_delay(phy, datx8, phase_idx); +- +- /* Issue a DLL soft reset */ +- clrbits_le32(DXNDLLCR(phy, datx8), DDRPHYC_DXNDLLCR_DLLSRST); +- setbits_le32(DXNDLLCR(phy, datx8), DDRPHYC_DXNDLLCR_DLLSRST); +- +- /* Test this typical init condition */ +- BIST_test(phy, datx8, &result); +- success = result.test_result; +- +- /* If the test pass in this typical condition, +- * start the algo with it. +- * Else, look for Pass init condition +- */ +- if (!success) { +- log_debug("Fail at init condtion. Let's look for a good init condition.\n"); +- success = 0; /* init */ +- /* Make sure we start with a PASS condition before +- * looking for a fail condition. +- * Find the first PASS PHASE condition +- */ +- +- /* escape if we find a PASS */ +- log_debug("increase Phase idx\n"); +- while (!success && (phase_idx <= MAX_DQS_PHASE_IDX)) { +- DQS_phase_delay(phy, datx8, phase_idx); +- BIST_test(phy, datx8, &result); +- success = result.test_result; +- phase_idx++; +- } +- /* if ended with success +- * ==>> Restore the fist success condition +- */ +- if (success) +- phase_idx--; /* because it ended with ++ */ +- } +- if (ctrlc()) { +- sprintf(string, "interrupted at byte %d/%d, error=%d", +- datx8 + 1, nb_bytes, error); +- return TEST_FAILED; +- } +- /* We couldn't find a successful condition, its seems +- * we have hold violation, lets try reduce DQS_unit Delay +- */ +- if (!success) { +- /* We couldn't find a successful condition, its seems +- * we have hold violation, lets try reduce DQS_unit +- * Delay +- */ +- log_debug("Still fail. Try decrease DQS Unit delay\n"); +- +- phase_idx = 0; +- dqs_unit_delay_index = 0; +- DQS_phase_delay(phy, datx8, phase_idx); +- +- /* escape if we find a PASS */ +- while (!success && +- (dqs_unit_delay_index <= +- MAX_DQS_UNIT_IDX)) { +- DQS_unit_delay(phy, datx8, +- dqs_unit_delay_index); +- BIST_test(phy, datx8, &result); +- success = result.test_result; +- dqs_unit_delay_index++; +- } +- if (success) { +- /* Restore the first success condition*/ +- dqs_unit_delay_index--; +- /* last_pass_dqs_unit = dqs_unit_delay_index;*/ +- DQS_unit_delay(phy, datx8, +- dqs_unit_delay_index); +- } else { +- /* No need to continue, +- * there is no pass region. +- */ +- force_stop = 1; +- } +- } +- +- /* There is an initial PASS condition +- * Look for the first failing condition by PHASE stepping. +- * This part of the algo can finish without converging. +- */ +- if (force_stop) { +- printf("Result: Failed "); +- printf("[Cannot Deskew lines, "); +- printf("there is no PASS region]\n"); +- error++; +- continue; +- } +- if (ctrlc()) { +- sprintf(string, "interrupted at byte %d/%d, error=%d", +- datx8 + 1, nb_bytes, error); +- return TEST_FAILED; +- } +- +- log_debug("there is a pass region for phase idx %d\n", +- phase_idx); +- log_debug("Step1: Find the first failing condition\n"); +- /* Look for the first failing condition by PHASE stepping. +- * This part of the algo can finish without converging. +- */ +- +- /* escape if we find a fail (hold time violation) +- * condition at any bit or if out of delay range. +- */ +- while (success && (phase_idx <= MAX_DQS_PHASE_IDX)) { +- DQS_phase_delay(phy, datx8, phase_idx); +- BIST_test(phy, datx8, &result); +- success = result.test_result; +- phase_idx++; +- } +- if (ctrlc()) { +- sprintf(string, "interrupted at byte %d/%d, error=%d", +- datx8 + 1, nb_bytes, error); +- return TEST_FAILED; +- } +- +- /* if the loop ended with a failing condition at any bit, +- * lets look for the first previous success condition by unit +- * stepping (minimal delay) +- */ +- if (!success) { +- log_debug("Fail region (PHASE) found phase idx %d\n", +- phase_idx); +- log_debug("Let's look for first success by DQS Unit steps\n"); +- /* This part, the algo always converge */ +- phase_idx--; +- +- /* escape if we find a success condition +- * or if out of delay range. +- */ +- while (!success && dqs_unit_delay_index >= 0) { +- DQS_unit_delay(phy, datx8, +- dqs_unit_delay_index); +- BIST_test(phy, datx8, &result); +- success = result.test_result; +- dqs_unit_delay_index--; +- } +- /* if the loop ended with a success condition, +- * the last delay Right OK (before hold violation) +- * condition is then defined as following: +- */ +- if (success) { +- /* Hold the dely parameters of the the last +- * delay Right OK condition. +- * -1 to get back to current condition +- */ +- last_right_ok.phase = phase_idx; +- /*+1 to get back to current condition */ +- last_right_ok.unit = dqs_unit_delay_index + 1; +- last_right_ok.bits_delay = 0xFFFFFFFF; +- log_debug("Found %d\n", dqs_unit_delay_index); +- } else { +- /* the last OK condition is then with the +- * previous phase_idx. +- * -2 instead of -1 because at the last +- * iteration of the while(), +- * we incremented phase_idx +- */ +- last_right_ok.phase = phase_idx - 1; +- /* Nominal+1. Because we want the previous +- * delay after reducing the phase delay. +- */ +- last_right_ok.unit = 1; +- last_right_ok.bits_delay = 0xFFFFFFFF; +- log_debug("Not Found : try previous phase %d\n", +- phase_idx - 1); +- +- DQS_phase_delay(phy, datx8, phase_idx - 1); +- dqs_unit_delay_index = 0; +- success = true; +- while (success && +- (dqs_unit_delay_index < +- MAX_DQS_UNIT_IDX)) { +- DQS_unit_delay(phy, datx8, +- dqs_unit_delay_index); +- BIST_test(phy, datx8, &result); +- success = result.test_result; +- dqs_unit_delay_index++; +- log_debug("dqs_unit_delay_index = %d, result = %d\n", +- dqs_unit_delay_index, success); +- } +- +- if (!success) { +- last_right_ok.unit = +- dqs_unit_delay_index - 1; +- } else { +- last_right_ok.unit = 0; +- log_debug("ERROR: failed region not FOUND"); +- } +- } +- } else { +- /* we can't find a failing condition at all bits +- * ==> Just hold the last test condition +- * (the max DQS delay) +- * which is the most likely, +- * the closest to a hold violation +- * If we can't find a Fail condition after +- * the Pass region, stick at this position +- * In order to have max chances to find a fail +- * when reducing DQ delays. +- */ +- last_right_ok.phase = MAX_DQS_PHASE_IDX; +- last_right_ok.unit = MAX_DQS_UNIT_IDX; +- last_right_ok.bits_delay = 0xFFFFFFFF; +- log_debug("Can't find the a fail condition\n"); +- } +- +- /* step 2: +- * if we arrive at this stage, it means that we found the last +- * Right OK condition (by tweeking the DQS delay). Or we simply +- * pushed DQS delay to the max +- * This means that by reducing the delay on some DQ bits, +- * we should find a failing condition. +- */ +- printf("Byte %d, DQS unit = %d, phase = %d\n", +- datx8, last_right_ok.unit, last_right_ok.phase); +- log_debug("Step2, unit = %d, phase = %d, bits delay=%x\n", +- last_right_ok.unit, last_right_ok.phase, +- last_right_ok.bits_delay); +- +- /* Restore the last_right_ok condtion. */ +- DQS_unit_delay(phy, datx8, last_right_ok.unit); +- DQS_phase_delay(phy, datx8, last_right_ok.phase); +- writel(last_right_ok.bits_delay, DXNDQTR(phy, datx8)); +- +- /* train each bit +- * reduce delay on each bit, and perform a write/read test +- * and stop at the very first time it fails. +- * the goal is the find the first failing condition +- * for each bit. +- * When we achieve this condition< for all the bits, +- * we are sure they are aligned (+/- step resolution) +- */ +- fail_found = 0; +- for (bit_i = 0; bit_i < 8; bit_i++) { +- if (ctrlc()) { +- sprintf(string, +- "interrupted at byte %d/%d, error=%d", +- datx8 + 1, nb_bytes, error); +- return error; +- } +- log_debug("deskewing bit %d:\n", bit_i); +- success = 1; /* init */ +- /* Set all DQDLYn to maximum value. +- * Only bit_i will be down-delayed +- * ==> if we have a fail, it will be definitely +- * from bit_i +- */ +- writel(0xFFFFFFFF, DXNDQTR(phy, datx8)); +- /* Arriving at this stage, +- * we have a success condition with delay = 3; +- */ +- bit_i_delay_index = 3; +- +- /* escape if bit delay is out of range or +- * if a fatil occurs +- */ +- while ((bit_i_delay_index >= 0) && success) { +- set_DQ_unit_delay(phy, datx8, +- bit_i, +- bit_i_delay_index); +- BIST_test(phy, datx8, &result); +- success = result.test_result; +- bit_i_delay_index--; +- } +- +- /* if escape with a fail condition +- * ==> save this position for bit_i +- */ +- if (!success) { +- /* save the delay position. +- * Add 1 because the while loop ended with a --, +- * and that we need to hold the last success +- * delay +- */ +- deskew_delay[datx8][bit_i] = +- bit_i_delay_index + 2; +- if (deskew_delay[datx8][bit_i] > 3) +- deskew_delay[datx8][bit_i] = 3; +- +- /* A flag that states we found at least a fail +- * at one bit. +- */ +- fail_found = 1; +- log_debug("Fail found on bit %d, for delay = %d => deskew[%d][%d] = %d\n", +- bit_i, bit_i_delay_index + 1, +- datx8, bit_i, +- deskew_delay[datx8][bit_i]); +- } else { +- /* if we can find a success condition by +- * back-delaying this bit, just set the delay +- * to 0 (the best deskew +- * possible) and mark the bit. +- */ +- deskew_delay[datx8][bit_i] = 0; +- /* set a flag that will be used later +- * in the report. +- */ +- deskew_non_converge[datx8][bit_i] = 1; +- log_debug("Fail not found on bit %d => deskew[%d][%d] = %d\n", +- bit_i, datx8, bit_i, +- deskew_delay[datx8][bit_i]); +- } +- } +- log_debug("**********byte %d tuning complete************\n", +- datx8); +- /* If we can't find any failure by back delaying DQ lines, +- * hold the default values +- */ +- if (!fail_found) { +- for (bit_i = 0; bit_i < 8; bit_i++) +- deskew_delay[datx8][bit_i] = 0; +- log_debug("The Deskew algorithm can't converge, there is too much margin in your design. Good job!\n"); +- } +- +- apply_deskew_results(phy, datx8, deskew_delay, +- deskew_non_converge); +- /* Restore nominal value for DQS delay */ +- DQS_phase_delay(phy, datx8, 3); +- DQS_unit_delay(phy, datx8, 3); +- /* disable byte after byte bits deskew */ +- clrbits_le32(DXNGCR(phy, datx8), DDRPHYC_DXNGCR_DXEN); +- } /* end of byte deskew */ +- +- /* re-enable all data bytes */ +- setbits_le32(&phy->dx0gcr, DDRPHYC_DXNGCR_DXEN); +- setbits_le32(&phy->dx1gcr, DDRPHYC_DXNGCR_DXEN); +- setbits_le32(&phy->dx2gcr, DDRPHYC_DXNGCR_DXEN); +- setbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN); +- +- if (error) { +- sprintf(string, "error = %d", error); +- return TEST_FAILED; +- } +- +- return TEST_PASSED; +-} /* end function */ +- +-/* Trim DQS timings and set it in the centre of data eye. +- * Look for a PPPPF region, then look for a FPPP region and finally select +- * the mid of the FPPPPPF region +- */ +-static enum test_result eye_training(struct stm32mp1_ddrctl *ctl, +- struct stm32mp1_ddrphy *phy, char *string) +-{ +- /*Stores the DQS trim values (PHASE index, unit index) */ +- u8 eye_training_val[NUM_BYTES][2]; +- u8 byte = 0; +- struct BIST_result result; +- s8 dqs_unit_delay_index = 0; +- s8 phase_idx = 0; +- s8 dqs_unit_delay_index_pass = 0; +- s8 phase_idx_pass = 0; +- u8 success = 0; +- u8 left_phase_bound_found, right_phase_bound_found; +- u8 left_unit_bound_found, right_unit_bound_found; +- u8 left_bound_found, right_bound_found; +- struct tuning_position left_bound, right_bound; +- u8 error = 0; +- u8 nb_bytes = get_nb_bytes(ctl); +- +- /*Disable DQS Drift Compensation*/ +- clrbits_le32(&phy->pgcr, DDRPHYC_PGCR_DFTCMP); +- /*Disable all bytes*/ +- /* Disable automatic power down of DLL and IOs when disabling a byte +- * (To avoid having to add programming and delay +- * for a DLL re-lock when later re-enabling a disabled Byte Lane) +- */ +- clrbits_le32(&phy->pgcr, DDRPHYC_PGCR_PDDISDX); +- +- /*Disable all data bytes */ +- clrbits_le32(&phy->dx0gcr, DDRPHYC_DXNGCR_DXEN); +- clrbits_le32(&phy->dx1gcr, DDRPHYC_DXNGCR_DXEN); +- clrbits_le32(&phy->dx2gcr, DDRPHYC_DXNGCR_DXEN); +- clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN); +- +- /* Config the BIST block */ +- config_BIST(ctl, phy); +- +- for (byte = 0; byte < nb_bytes; byte++) { +- if (ctrlc()) { +- sprintf(string, "interrupted at byte %d/%d, error=%d", +- byte + 1, nb_bytes, error); +- return TEST_FAILED; +- } +- right_bound.phase = 0; +- right_bound.unit = 0; +- +- left_bound.phase = 0; +- left_bound.unit = 0; +- +- left_phase_bound_found = 0; +- right_phase_bound_found = 0; +- +- left_unit_bound_found = 0; +- right_unit_bound_found = 0; +- +- left_bound_found = 0; +- right_bound_found = 0; +- +- /* Enable Byte (DXNGCR, bit DXEN) */ +- setbits_le32(DXNGCR(phy, byte), DDRPHYC_DXNGCR_DXEN); +- +- /* Select the byte lane for comparison of read data */ +- BIST_datx8_sel(phy, byte); +- +- /* Set DQS phase delay to the nominal value. */ +- phase_idx = _90deg; +- phase_idx_pass = phase_idx; +- +- /* Set DQS unit delay to the nominal value. */ +- dqs_unit_delay_index = 3; +- dqs_unit_delay_index_pass = dqs_unit_delay_index; +- success = 0; +- +- log_debug("STEP0: Find Init delay\n"); +- /* STEP0: Find Init delay: a delay that put the system +- * in a "Pass" condition then (TODO) update +- * dqs_unit_delay_index_pass & phase_idx_pass +- */ +- DQS_unit_delay(phy, byte, dqs_unit_delay_index); +- DQS_phase_delay(phy, byte, phase_idx); +- BIST_test(phy, byte, &result); +- success = result.test_result; +- /* If we have a fail in the nominal condition */ +- if (!success) { +- /* Look at the left */ +- while (phase_idx >= 0 && !success) { +- phase_idx--; +- DQS_phase_delay(phy, byte, phase_idx); +- BIST_test(phy, byte, &result); +- success = result.test_result; +- } +- } +- if (!success) { +- /* if we can't find pass condition, +- * then look at the right +- */ +- phase_idx = _90deg; +- while (phase_idx <= MAX_DQS_PHASE_IDX && +- !success) { +- phase_idx++; +- DQS_phase_delay(phy, byte, +- phase_idx); +- BIST_test(phy, byte, &result); +- success = result.test_result; +- } +- } +- /* save the pass condition */ +- if (success) { +- phase_idx_pass = phase_idx; +- } else { +- printf("Result: Failed "); +- printf("[Cannot DQS timings, "); +- printf("there is no PASS region]\n"); +- error++; +- continue; +- } +- +- if (ctrlc()) { +- sprintf(string, "interrupted at byte %d/%d, error=%d", +- byte + 1, nb_bytes, error); +- return TEST_FAILED; +- } +- log_debug("STEP1: Find LEFT PHASE DQS Bound\n"); +- /* STEP1: Find LEFT PHASE DQS Bound */ +- while ((phase_idx >= 0) && +- (phase_idx <= MAX_DQS_PHASE_IDX) && +- !left_phase_bound_found) { +- DQS_unit_delay(phy, byte, +- dqs_unit_delay_index); +- DQS_phase_delay(phy, byte, +- phase_idx); +- BIST_test(phy, byte, &result); +- success = result.test_result; +- +- /*TODO: Manage the case were at the beginning +- * there is already a fail +- */ +- if (!success) { +- /* the last pass condition */ +- left_bound.phase = ++phase_idx; +- left_phase_bound_found = 1; +- } else if (success) { +- phase_idx--; +- } +- } +- if (!left_phase_bound_found) { +- left_bound.phase = 0; +- phase_idx = 0; +- } +- /* If not found, lets take 0 */ +- +- if (ctrlc()) { +- sprintf(string, "interrupted at byte %d/%d, error=%d", +- byte + 1, nb_bytes, error); +- return TEST_FAILED; +- } +- log_debug("STEP2: Find UNIT left bound\n"); +- /* STEP2: Find UNIT left bound */ +- while ((dqs_unit_delay_index >= 0) && +- !left_unit_bound_found) { +- DQS_unit_delay(phy, byte, +- dqs_unit_delay_index); +- DQS_phase_delay(phy, byte, phase_idx); +- BIST_test(phy, byte, &result); +- success = result.test_result; +- if (!success) { +- left_bound.unit = +- ++dqs_unit_delay_index; +- left_unit_bound_found = 1; +- left_bound_found = 1; +- } else if (success) { +- dqs_unit_delay_index--; +- } +- } +- +- /* If not found, lets take 0 */ +- if (!left_unit_bound_found) +- left_bound.unit = 0; +- +- if (ctrlc()) { +- sprintf(string, "interrupted at byte %d/%d, error=%d", +- byte + 1, nb_bytes, error); +- return TEST_FAILED; +- } +- log_debug("STEP3: Find PHase right bound\n"); +- /* STEP3: Find PHase right bound, start with "pass" +- * condition +- */ +- +- /* Set DQS phase delay to the pass value. */ +- phase_idx = phase_idx_pass; +- +- /* Set DQS unit delay to the pass value. */ +- dqs_unit_delay_index = dqs_unit_delay_index_pass; +- +- while ((phase_idx <= MAX_DQS_PHASE_IDX) && +- !right_phase_bound_found) { +- DQS_unit_delay(phy, byte, +- dqs_unit_delay_index); +- DQS_phase_delay(phy, byte, phase_idx); +- BIST_test(phy, byte, &result); +- success = result.test_result; +- if (!success) { +- /* the last pass condition */ +- right_bound.phase = --phase_idx; +- right_phase_bound_found = 1; +- } else if (success) { +- phase_idx++; +- } +- } +- +- /* If not found, lets take the max value */ +- if (!right_phase_bound_found) { +- right_bound.phase = MAX_DQS_PHASE_IDX; +- phase_idx = MAX_DQS_PHASE_IDX; +- } +- +- if (ctrlc()) { +- sprintf(string, "interrupted at byte %d/%d, error=%d", +- byte + 1, nb_bytes, error); +- return TEST_FAILED; +- } +- log_debug("STEP4: Find UNIT right bound\n"); +- /* STEP4: Find UNIT right bound */ +- while ((dqs_unit_delay_index <= MAX_DQS_UNIT_IDX) && +- !right_unit_bound_found) { +- DQS_unit_delay(phy, byte, +- dqs_unit_delay_index); +- DQS_phase_delay(phy, byte, phase_idx); +- BIST_test(phy, byte, &result); +- success = result.test_result; +- if (!success) { +- right_bound.unit = +- --dqs_unit_delay_index; +- right_unit_bound_found = 1; +- right_bound_found = 1; +- } else if (success) { +- dqs_unit_delay_index++; +- } +- } +- /* If not found, lets take the max value */ +- if (!right_unit_bound_found) +- right_bound.unit = MAX_DQS_UNIT_IDX; +- +- /* If we found a regular FAil Pass FAil pattern +- * FFPPPPPPFF +- * OR PPPPPFF Or FFPPPPP +- */ +- +- if (left_bound_found || right_bound_found) { +- eye_training_val[byte][0] = (right_bound.phase + +- left_bound.phase) / 2; +- eye_training_val[byte][1] = (right_bound.unit + +- left_bound.unit) / 2; +- +- /* If we already lost 1/2PHASE Tuning, +- * let's try to recover by ++ on unit +- */ +- if (((right_bound.phase + left_bound.phase) % 2 == 1) && +- eye_training_val[byte][1] != MAX_DQS_UNIT_IDX) +- eye_training_val[byte][1]++; +- log_debug("** found phase : %d - %d & unit %d - %d\n", +- right_bound.phase, left_bound.phase, +- right_bound.unit, left_bound.unit); +- log_debug("** calculating mid region: phase: %d unit: %d (nominal is 3)\n", +- eye_training_val[byte][0], +- eye_training_val[byte][1]); +- } else { +- /* PPPPPPPPPP, we're already good. +- * Set nominal values. +- */ +- eye_training_val[byte][0] = 3; +- eye_training_val[byte][1] = 3; +- } +- DQS_phase_delay(phy, byte, eye_training_val[byte][0]); +- DQS_unit_delay(phy, byte, eye_training_val[byte][1]); +- +- printf("Byte %d, DQS unit = %d, phase = %d\n", +- byte, +- eye_training_val[byte][1], +- eye_training_val[byte][0]); +- } +- +- if (error) { +- sprintf(string, "error = %d", error); +- return TEST_FAILED; +- } +- +- return TEST_PASSED; +-} +- +-static void display_reg_results(struct stm32mp1_ddrphy *phy, u8 byte) +-{ +- u8 i = 0; +- +- printf("Byte %d Dekew result, bit0 delay, bit1 delay...bit8 delay\n ", +- byte); +- +- for (i = 0; i < 8; i++) +- printf("%d ", DQ_unit_index(phy, byte, i)); +- printf("\n"); +- +- printf("dxndllcr: [%08x] val:%08x\n", +- DXNDLLCR(phy, byte), +- readl(DXNDLLCR(phy, byte))); +- printf("dxnqdstr: [%08x] val:%08x\n", +- DXNDQSTR(phy, byte), +- readl(DXNDQSTR(phy, byte))); +- printf("dxndqtr: [%08x] val:%08x\n", +- DXNDQTR(phy, byte), +- readl(DXNDQTR(phy, byte))); +-} +- +-/* analyse the dgs gating log table, and determine the midpoint.*/ +-static u8 set_midpoint_read_dqs_gating(struct stm32mp1_ddrphy *phy, u8 byte, +- u8 dqs_gating[NUM_BYTES] +- [MAX_GSL_IDX + 1] +- [MAX_GPS_IDX + 1]) +-{ +- /* stores the dqs gate values (gsl index, gps index) */ +- u8 dqs_gate_values[NUM_BYTES][2]; +- u8 gsl_idx, gps_idx = 0; +- u8 left_bound_idx[2] = {0, 0}; +- u8 right_bound_idx[2] = {0, 0}; +- u8 left_bound_found = 0; +- u8 right_bound_found = 0; +- u8 intermittent = 0; +- u8 value; +- +- for (gsl_idx = 0; gsl_idx <= MAX_GSL_IDX; gsl_idx++) { +- for (gps_idx = 0; gps_idx <= MAX_GPS_IDX; gps_idx++) { +- value = dqs_gating[byte][gsl_idx][gps_idx]; +- if (value == 1 && left_bound_found == 0) { +- left_bound_idx[0] = gsl_idx; +- left_bound_idx[1] = gps_idx; +- left_bound_found = 1; +- } else if (value == 0 && +- left_bound_found == 1 && +- !right_bound_found) { +- if (gps_idx == 0) { +- right_bound_idx[0] = gsl_idx - 1; +- right_bound_idx[1] = MAX_GPS_IDX; +- } else { +- right_bound_idx[0] = gsl_idx; +- right_bound_idx[1] = gps_idx - 1; +- } +- right_bound_found = 1; +- } else if (value == 1 && +- right_bound_found == 1) { +- intermittent = 1; +- } +- } +- } +- +- /* if only ppppppp is found, there is no mid region. */ +- if (left_bound_idx[0] == 0 && left_bound_idx[1] == 0 && +- right_bound_idx[0] == 0 && right_bound_idx[1] == 0) +- intermittent = 1; +- +- /*if we found a regular fail pass fail pattern ffppppppff +- * or pppppff or ffppppp +- */ +- if (!intermittent) { +- /*if we found a regular fail pass fail pattern ffppppppff +- * or pppppff or ffppppp +- */ +- if (left_bound_found || right_bound_found) { +- log_debug("idx0(%d): %d %d idx1(%d) : %d %d\n", +- left_bound_found, +- right_bound_idx[0], left_bound_idx[0], +- right_bound_found, +- right_bound_idx[1], left_bound_idx[1]); +- dqs_gate_values[byte][0] = +- (right_bound_idx[0] + left_bound_idx[0]) / 2; +- dqs_gate_values[byte][1] = +- (right_bound_idx[1] + left_bound_idx[1]) / 2; +- /* if we already lost 1/2gsl tuning, +- * let's try to recover by ++ on gps +- */ +- if (((right_bound_idx[0] + +- left_bound_idx[0]) % 2 == 1) && +- dqs_gate_values[byte][1] != MAX_GPS_IDX) +- dqs_gate_values[byte][1]++; +- /* if we already lost 1/2gsl tuning and gps is on max*/ +- else if (((right_bound_idx[0] + +- left_bound_idx[0]) % 2 == 1) && +- dqs_gate_values[byte][1] == MAX_GPS_IDX) { +- dqs_gate_values[byte][1] = 0; +- dqs_gate_values[byte][0]++; +- } +- /* if we have gsl left and write limit too close +- * (difference=1) +- */ +- if (((right_bound_idx[0] - left_bound_idx[0]) == 1)) { +- dqs_gate_values[byte][1] = (left_bound_idx[1] + +- right_bound_idx[1] + +- 4) / 2; +- if (dqs_gate_values[byte][1] >= 4) { +- dqs_gate_values[byte][0] = +- right_bound_idx[0]; +- dqs_gate_values[byte][1] -= 4; +- } else { +- dqs_gate_values[byte][0] = +- left_bound_idx[0]; +- } +- } +- log_debug("*******calculating mid region: system latency: %d phase: %d********\n", +- dqs_gate_values[byte][0], +- dqs_gate_values[byte][1]); +- log_debug("*******the nominal values were system latency: 0 phase: 2*******\n"); +- } +- } else { +- /* if intermitant, restore defaut values */ +- log_debug("dqs gating:no regular fail/pass/fail found. defaults values restored.\n"); +- dqs_gate_values[byte][0] = 0; +- dqs_gate_values[byte][1] = 2; +- } +- set_r0dgsl_delay(phy, byte, dqs_gate_values[byte][0]); +- set_r0dgps_delay(phy, byte, dqs_gate_values[byte][1]); +- printf("Byte %d, R0DGSL = %d, R0DGPS = %d\n", +- byte, dqs_gate_values[byte][0], dqs_gate_values[byte][1]); +- +- /* return 0 if intermittent or if both left_bound +- * and right_bound are not found +- */ +- return !(intermittent || (left_bound_found && right_bound_found)); +-} +- +-static enum test_result read_dqs_gating(struct stm32mp1_ddrctl *ctl, +- struct stm32mp1_ddrphy *phy, +- char *string) +-{ +- /* stores the log of pass/fail */ +- u8 dqs_gating[NUM_BYTES][MAX_GSL_IDX + 1][MAX_GPS_IDX + 1]; +- u8 byte, gsl_idx, gps_idx = 0; +- struct BIST_result result; +- u8 success = 0; +- u8 nb_bytes = get_nb_bytes(ctl); +- +- memset(dqs_gating, 0x0, sizeof(dqs_gating)); +- +- /*disable dqs drift compensation*/ +- clrbits_le32(&phy->pgcr, DDRPHYC_PGCR_DFTCMP); +- /*disable all bytes*/ +- /* disable automatic power down of dll and ios when disabling a byte +- * (to avoid having to add programming and delay +- * for a dll re-lock when later re-enabling a disabled byte lane) +- */ +- clrbits_le32(&phy->pgcr, DDRPHYC_PGCR_PDDISDX); +- +- /* disable all data bytes */ +- clrbits_le32(&phy->dx0gcr, DDRPHYC_DXNGCR_DXEN); +- clrbits_le32(&phy->dx1gcr, DDRPHYC_DXNGCR_DXEN); +- clrbits_le32(&phy->dx2gcr, DDRPHYC_DXNGCR_DXEN); +- clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN); +- +- /* config the bist block */ +- config_BIST(ctl, phy); +- +- for (byte = 0; byte < nb_bytes; byte++) { +- if (ctrlc()) { +- sprintf(string, "interrupted at byte %d/%d", +- byte + 1, nb_bytes); +- return TEST_FAILED; +- } +- /* enable byte x (dxngcr, bit dxen) */ +- setbits_le32(DXNGCR(phy, byte), DDRPHYC_DXNGCR_DXEN); +- +- /* select the byte lane for comparison of read data */ +- BIST_datx8_sel(phy, byte); +- for (gsl_idx = 0; gsl_idx <= MAX_GSL_IDX; gsl_idx++) { +- for (gps_idx = 0; gps_idx <= MAX_GPS_IDX; gps_idx++) { +- if (ctrlc()) { +- sprintf(string, +- "interrupted at byte %d/%d", +- byte + 1, nb_bytes); +- return TEST_FAILED; +- } +- /* write cfg to dxndqstr */ +- set_r0dgsl_delay(phy, byte, gsl_idx); +- set_r0dgps_delay(phy, byte, gps_idx); +- +- BIST_test(phy, byte, &result); +- success = result.test_result; +- if (success) +- dqs_gating[byte][gsl_idx][gps_idx] = 1; +- itm_soft_reset(phy); +- } +- } +- set_midpoint_read_dqs_gating(phy, byte, dqs_gating); +- /* dummy reads */ +- readl(0xc0000000); +- readl(0xc0000000); +- } +- +- /* re-enable drift compensation */ +- /* setbits_le32(&phy->pgcr, DDRPHYC_PGCR_DFTCMP); */ +- return TEST_PASSED; +-} +- +-/**************************************************************** +- * TEST +- **************************************************************** +- */ +-static enum test_result do_read_dqs_gating(struct stm32mp1_ddrctl *ctl, +- struct stm32mp1_ddrphy *phy, +- char *string, int argc, +- char *argv[]) +-{ +- u32 rfshctl3 = readl(&ctl->rfshctl3); +- u32 pwrctl = readl(&ctl->pwrctl); +- u32 derateen = readl(&ctl->derateen); +- enum test_result res; +- +- writel(0x0, &ctl->derateen); +- stm32mp1_refresh_disable(ctl); +- +- res = read_dqs_gating(ctl, phy, string); +- +- stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl); +- writel(derateen, &ctl->derateen); +- +- return res; +-} +- +-static enum test_result do_bit_deskew(struct stm32mp1_ddrctl *ctl, +- struct stm32mp1_ddrphy *phy, +- char *string, int argc, char *argv[]) +-{ +- u32 rfshctl3 = readl(&ctl->rfshctl3); +- u32 pwrctl = readl(&ctl->pwrctl); +- u32 derateen = readl(&ctl->derateen); +- enum test_result res; +- +- writel(0x0, &ctl->derateen); +- stm32mp1_refresh_disable(ctl); +- +- res = bit_deskew(ctl, phy, string); +- +- stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl); +- writel(derateen, &ctl->derateen); +- +- return res; +-} +- +-static enum test_result do_eye_training(struct stm32mp1_ddrctl *ctl, +- struct stm32mp1_ddrphy *phy, +- char *string, int argc, char *argv[]) +-{ +- u32 rfshctl3 = readl(&ctl->rfshctl3); +- u32 pwrctl = readl(&ctl->pwrctl); +- u32 derateen = readl(&ctl->derateen); +- enum test_result res; +- +- writel(0x0, &ctl->derateen); +- stm32mp1_refresh_disable(ctl); +- +- res = eye_training(ctl, phy, string); +- +- stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl); +- writel(derateen, &ctl->derateen); +- +- return res; +-} +- +-static enum test_result do_display(struct stm32mp1_ddrctl *ctl, +- struct stm32mp1_ddrphy *phy, +- char *string, int argc, char *argv[]) +-{ +- int byte; +- u8 nb_bytes = get_nb_bytes(ctl); +- +- for (byte = 0; byte < nb_bytes; byte++) +- display_reg_results(phy, byte); +- +- return TEST_PASSED; +-} +- +-static enum test_result do_bist_config(struct stm32mp1_ddrctl *ctl, +- struct stm32mp1_ddrphy *phy, +- char *string, int argc, char *argv[]) +-{ +- unsigned long value; +- +- if (argc > 0) { +- if (strict_strtoul(argv[0], 0, &value) < 0) { +- sprintf(string, "invalid nbErr %s", argv[0]); +- return TEST_FAILED; +- } +- BIST_error_max = value; +- } +- if (argc > 1) { +- if (strict_strtoul(argv[1], 0, &value) < 0) { +- sprintf(string, "invalid Seed %s", argv[1]); +- return TEST_FAILED; +- } +- BIST_seed = value; +- } +- printf("Bist.nbErr = %d\n", BIST_error_max); +- if (BIST_seed) +- printf("Bist.Seed = 0x%x\n", BIST_seed); +- else +- printf("Bist.Seed = random\n"); +- +- return TEST_PASSED; +-} +- +-/**************************************************************** +- * TEST Description +- **************************************************************** +- */ +- +-const struct test_desc tuning[] = { +- {do_read_dqs_gating, "Read DQS gating", +- "software read DQS Gating", "", 0 }, +- {do_bit_deskew, "Bit de-skew", "", "", 0 }, +- {do_eye_training, "Eye Training", "or DQS training", "", 0 }, +- {do_display, "Display registers", "", "", 0 }, +- {do_bist_config, "Bist config", "[nbErr] [seed]", +- "configure Bist test", 2}, +-}; +- +-const int tuning_nb = ARRAY_SIZE(tuning); +diff --git a/drivers/reboot-mode/reboot-mode-uclass.c b/drivers/reboot-mode/reboot-mode-uclass.c +index bb7a355fbf..2b38aa26b8 100644 +--- a/drivers/reboot-mode/reboot-mode-uclass.c ++++ b/drivers/reboot-mode/reboot-mode-uclass.c +@@ -10,8 +10,6 @@ + #include + #include + +-DECLARE_GLOBAL_DATA_PTR; +- + int dm_reboot_mode_update(struct udevice *dev) + { + struct reboot_mode_ops *ops = reboot_mode_get_ops(dev); +@@ -66,25 +64,20 @@ int dm_reboot_mode_pre_probe(struct udevice *dev) + return -EINVAL; + + #if CONFIG_IS_ENABLED(OF_CONTROL) +- const int node = dev_of_offset(dev); + const char *mode_prefix = "mode-"; + const int mode_prefix_len = strlen(mode_prefix); +- int property; ++ struct ofprop property; + const u32 *propvalue; + const char *propname; + +- plat_data->env_variable = fdt_getprop(gd->fdt_blob, +- node, +- "u-boot,env-variable", +- NULL); ++ plat_data->env_variable = dev_read_string(dev, "u-boot,env-variable"); + if (!plat_data->env_variable) + plat_data->env_variable = "reboot-mode"; + + plat_data->count = 0; + +- fdt_for_each_property_offset(property, gd->fdt_blob, node) { +- propvalue = fdt_getprop_by_offset(gd->fdt_blob, +- property, &propname, NULL); ++ dev_for_each_property(property, dev) { ++ propvalue = dev_read_prop_by_prop(&property, &propname, NULL); + if (!propvalue) { + dev_err(dev, "Could not get the value for property %s\n", + propname); +@@ -100,9 +93,8 @@ int dm_reboot_mode_pre_probe(struct udevice *dev) + + struct reboot_mode_mode *next = plat_data->modes; + +- fdt_for_each_property_offset(property, gd->fdt_blob, node) { +- propvalue = fdt_getprop_by_offset(gd->fdt_blob, +- property, &propname, NULL); ++ dev_for_each_property(property, dev) { ++ propvalue = dev_read_prop_by_prop(&property, &propname, NULL); + if (!propvalue) { + dev_err(dev, "Could not get the value for property %s\n", + propname); +diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig +index 24e536463b..a911da84b3 100644 +--- a/drivers/remoteproc/Kconfig ++++ b/drivers/remoteproc/Kconfig +@@ -12,6 +12,14 @@ config REMOTEPROC + bool + depends on DM + ++config REMOTEPROC_OPTEE ++ bool "Support for the remoteproc in OPTEE" ++ depends on REMOTEPROC ++ depends on OPTEE ++ help ++ Say y here to support remote processor firmware management by the ++ trusted execution environment. ++ + # Please keep the configuration alphabetically sorted. + config K3_SYSTEM_CONTROLLER + bool "Support for TI' K3 System Controller" +diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile +index f0e83451d6..ad260acd66 100644 +--- a/drivers/remoteproc/Makefile ++++ b/drivers/remoteproc/Makefile +@@ -5,6 +5,7 @@ + # + + obj-$(CONFIG_$(SPL_)REMOTEPROC) += rproc-uclass.o rproc-elf-loader.o ++obj-$(CONFIG_REMOTEPROC_OPTEE) += rproc-optee.o + + # Remote proc drivers - Please keep this list alphabetically sorted. + obj-$(CONFIG_K3_SYSTEM_CONTROLLER) += k3_system_controller.o +diff --git a/drivers/remoteproc/rproc-optee.c b/drivers/remoteproc/rproc-optee.c +new file mode 100644 +index 0000000000..6d33b9fd4a +--- /dev/null ++++ b/drivers/remoteproc/rproc-optee.c +@@ -0,0 +1,235 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) STMicroelectronics 2020 - All Rights Reserved ++ * Authors: Arnaud Pouliquen ++ */ ++ ++#define LOG_CATEGORY UCLASS_REMOTEPROC ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define TA_REMOTEPROC_UUID { 0x80a4c275, 0x0a47, 0x4905, \ ++ { 0x82, 0x85, 0x14, 0x86, 0xa9, 0x77, 0x1a, 0x08} } ++ ++/* The function IDs implemented in the associated TA */ ++ ++/* ++ * Authentication of the firmware and load in the remote processor memory. ++ * ++ * [in] params[0].value.a: unique 32bit identifier of the firmware ++ * [in] params[1].memref: buffer containing the image of the firmware ++ */ ++#define TA_RPROC_FW_CMD_LOAD_FW 1 ++ ++/* ++ * Start the remote processor. ++ * ++ * [in] params[0].value.a: unique 32bit identifier of the firmware ++ */ ++#define TA_RPROC_FW_CMD_START_FW 2 ++ ++/* ++ * Stop the remote processor. ++ * ++ * [in] params[0].value.a: unique 32bit identifier of the firmware ++ */ ++#define TA_RPROC_FW_CMD_STOP_FW 3 ++ ++/* ++ * Return the physical address of the resource table, or 0 if not found ++ * No check is done to verify that the address returned is accessible by the ++ * non secure world. If the resource table is loaded in a protected memory, ++ * then accesses from non-secure world will likely fail. ++ * ++ * [in] params[0].value.a: unique 32bit identifier of the firmware ++ * [out] params[1].value.a: 32bit LSB resource table memory address ++ * [out] params[1].value.b: 32bit MSB resource table memory address ++ * [out] params[2].value.a: 32bit LSB resource table memory size ++ * [out] params[2].value.b: 32bit MSB resource table memory size ++ */ ++#define TA_RPROC_FW_CMD_GET_RSC_TABLE 4 ++ ++/* ++ * Get remote processor firmware core dump. If found, return either ++ * TEE_SUCCESS on successful completion or TEE_ERROR_SHORT_BUFFER if output ++ * buffer is too short to store the core dump. ++ * ++ * [in] params[0].value.a: unique 32bit identifier of the firmware ++ * [out] params[1].memref: Core dump, if found ++ */ ++#define TA_RPROC_FW_CMD_GET_COREDUMP 5 ++ ++static void prepare_args(struct rproc_optee *trproc, int cmd, ++ struct tee_invoke_arg *arg, uint num_param, ++ struct tee_param *param) ++{ ++ memset(arg, 0, sizeof(*arg)); ++ memset(param, 0, num_param * sizeof(*param)); ++ ++ arg->func = cmd; ++ arg->session = trproc->session; ++ ++ param[0] = (struct tee_param) { ++ .attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT, ++ .u.value.a = trproc->fw_id, ++ }; ++} ++ ++int rproc_optee_load(struct rproc_optee *trproc, ulong addr, ulong size) ++{ ++ struct tee_invoke_arg arg; ++ struct tee_param param[2]; ++ struct tee_shm *fw_shm; ++ int rc; ++ ++ rc = tee_shm_register(trproc->tee, (void *)addr, size, 0, &fw_shm); ++ if (rc) ++ return rc; ++ ++ prepare_args(trproc, TA_RPROC_FW_CMD_LOAD_FW, &arg, 2, param); ++ ++ /* Provide the address and size of the firmware image */ ++ param[1] = (struct tee_param){ ++ .attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT, ++ .u.memref = { ++ .shm = fw_shm, ++ .size = size, ++ .shm_offs = 0, ++ }, ++ }; ++ ++ rc = tee_invoke_func(trproc->tee, &arg, 2, param); ++ if (rc < 0 || arg.ret != 0) { ++ dev_err(trproc->tee, ++ "TA_RPROC_FW_CMD_LOAD_FW invoke failed TEE err: %x, err:%x\n", ++ arg.ret, rc); ++ if (!rc) ++ rc = -EIO; ++ } ++ ++ tee_shm_free(fw_shm); ++ ++ return rc; ++} ++ ++int rproc_optee_get_rsc_table(struct rproc_optee *trproc, phys_addr_t *rsc_addr, ++ phys_size_t *rsc_size) ++{ ++ struct tee_invoke_arg arg; ++ struct tee_param param[3]; ++ int rc; ++ ++ prepare_args(trproc, TA_RPROC_FW_CMD_GET_RSC_TABLE, &arg, 3, param); ++ ++ param[1].attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT; ++ param[2].attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT; ++ ++ rc = tee_invoke_func(trproc->tee, &arg, 3, param); ++ if (rc < 0 || arg.ret != 0) { ++ dev_err(trproc->tee, ++ "TA_RPROC_FW_CMD_GET_RSC_TABLE invoke failed TEE err: %x, err:%x\n", ++ arg.ret, rc); ++ if (!rc) ++ rc = -EIO; ++ ++ return rc; ++ } ++ ++ *rsc_size = (phys_size_t) ++ (param[2].u.value.b << 32 | param[2].u.value.a); ++ *rsc_addr = (phys_addr_t) ++ (param[1].u.value.b << 32 | param[1].u.value.a); ++ ++ return 0; ++} ++ ++int rproc_optee_start(struct rproc_optee *trproc) ++{ ++ struct tee_invoke_arg arg; ++ struct tee_param param; ++ int rc; ++ ++ prepare_args(trproc, TA_RPROC_FW_CMD_START_FW, &arg, 1, ¶m); ++ ++ rc = tee_invoke_func(trproc->tee, &arg, 1, ¶m); ++ if (rc < 0 || arg.ret != 0) { ++ dev_err(trproc->tee, ++ "TA_RPROC_FW_CMD_START_FW invoke failed TEE err: %x, err:%x\n", ++ arg.ret, rc); ++ if (!rc) ++ rc = -EIO; ++ } ++ ++ return rc; ++} ++ ++int rproc_optee_stop(struct rproc_optee *trproc) ++{ ++ struct tee_invoke_arg arg; ++ struct tee_param param; ++ int rc; ++ ++ prepare_args(trproc, TA_RPROC_FW_CMD_STOP_FW, &arg, 1, ¶m); ++ ++ rc = tee_invoke_func(trproc->tee, &arg, 1, ¶m); ++ if (rc < 0 || arg.ret != 0) { ++ dev_err(trproc->tee, ++ "TA_RPROC_FW_CMD_STOP_FW invoke failed TEE err: %x, err:%x\n", ++ arg.ret, rc); ++ if (!rc) ++ rc = -EIO; ++ } ++ ++ return rc; ++} ++ ++int rproc_optee_open(struct rproc_optee *trproc) ++{ ++ struct udevice *tee = NULL; ++ const struct tee_optee_ta_uuid uuid = TA_REMOTEPROC_UUID; ++ struct tee_open_session_arg arg = { }; ++ int rc; ++ ++ if (!trproc) ++ return -EINVAL; ++ ++ tee = tee_find_device(tee, NULL, NULL, NULL); ++ if (!tee) ++ return -ENODEV; ++ ++ tee_optee_ta_uuid_to_octets(arg.uuid, &uuid); ++ rc = tee_open_session(tee, &arg, 0, NULL); ++ 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; ++ ++ 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/rproc-uclass.c b/drivers/remoteproc/rproc-uclass.c +index 64c47c1e72..87e1ec7ad7 100644 +--- a/drivers/remoteproc/rproc-uclass.c ++++ b/drivers/remoteproc/rproc-uclass.c +@@ -9,19 +9,15 @@ + #define pr_fmt(fmt) "%s: " fmt, __func__ + #include + #include +-#include + #include + #include + #include +-#include + #include + #include + #include + #include + #include + +-DECLARE_GLOBAL_DATA_PTR; +- + /** + * for_each_remoteproc_device() - iterate through the list of rproc devices + * @fn: check function to call per match, if this function returns fail, +@@ -121,21 +117,13 @@ static int rproc_pre_probe(struct udevice *dev) + + if (!dev_get_plat(dev)) { + #if CONFIG_IS_ENABLED(OF_CONTROL) +- int node = dev_of_offset(dev); +- const void *blob = gd->fdt_blob; + bool tmp; +- if (!blob) { +- debug("'%s' no dt?\n", dev->name); +- return -EINVAL; +- } + debug("'%s': using fdt\n", dev->name); +- uc_pdata->name = fdt_getprop(blob, node, +- "remoteproc-name", NULL); ++ uc_pdata->name = dev_read_string(dev, "remoteproc-name"); + + /* Default is internal memory mapped */ + uc_pdata->mem_type = RPROC_INTERNAL_MEMORY_MAPPED; +- tmp = fdtdec_get_bool(blob, node, +- "remoteproc-internal-memory-mapped"); ++ tmp = dev_read_bool(dev, "remoteproc-internal-memory-mapped"); + if (tmp) + uc_pdata->mem_type = RPROC_INTERNAL_MEMORY_MAPPED; + #else +diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c +index 4c5f24857e..0dd46ee951 100644 +--- a/drivers/remoteproc/stm32_copro.c ++++ b/drivers/remoteproc/stm32_copro.c +@@ -10,11 +10,14 @@ + #include + #include + #include ++#include + #include + #include + #include + #include + ++#define STM32MP15_M4_FW_ID 0 ++ + /** + * struct stm32_copro_privdata - power processor private data + * @reset_ctl: reset controller handle +@@ -25,6 +28,7 @@ struct stm32_copro_privdata { + struct reset_ctl reset_ctl; + struct reset_ctl hold_boot; + ulong rsc_table_addr; ++ struct rproc_optee trproc; + }; + + /** +@@ -34,10 +38,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) { +@@ -56,6 +66,22 @@ static int stm32_copro_probe(struct udevice *dev) + return 0; + } + ++/** ++ * 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_remove(struct udevice *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 0; ++} ++ + /** + * stm32_copro_device_to_virt() - Convert device address to virtual address + * @dev: corresponding STM32 remote processor device +@@ -93,11 +119,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) { +@@ -127,25 +155,39 @@ static int stm32_copro_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 */ +@@ -161,21 +203,29 @@ static int stm32_copro_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); +@@ -213,7 +263,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 }, + {} + }; + +@@ -223,5 +273,7 @@ U_BOOT_DRIVER(stm32_copro) = { + .id = UCLASS_REMOTEPROC, + .ops = &stm32_copro_ops, + .probe = stm32_copro_probe, +- .priv_auto = sizeof(struct stm32_copro_privdata), ++ .remove = stm32_copro_remove, ++ .priv_auto = sizeof(struct stm32_copro_privdata), ++ .flags = DM_FLAG_OS_PREPARE, + }; +diff --git a/drivers/reset/reset-scmi.c b/drivers/reset/reset-scmi.c +index 1bff8075ee..850cb18886 100644 +--- a/drivers/reset/reset-scmi.c ++++ b/drivers/reset/reset-scmi.c +@@ -2,6 +2,9 @@ + /* + * Copyright (C) 2019-2020 Linaro Limited + */ ++ ++#define LOG_CATEGORY UCLASS_RESET ++ + #include + #include + #include +@@ -23,7 +26,7 @@ static int scmi_reset_set_level(struct reset_ctl *rst, bool assert_not_deassert) + in, out); + int ret; + +- ret = devm_scmi_process_msg(rst->dev->parent, &msg); ++ ret = devm_scmi_process_msg(rst->dev, &msg); + if (ret) + return ret; + +@@ -55,7 +58,7 @@ static int scmi_reset_request(struct reset_ctl *rst) + * We don't really care about the attribute, just check + * the reset domain exists. + */ +- ret = devm_scmi_process_msg(rst->dev->parent, &msg); ++ ret = devm_scmi_process_msg(rst->dev, &msg); + if (ret) + return ret; + +diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig +index 94915d45b3..34fb9993f2 100644 +--- a/drivers/rng/Kconfig ++++ b/drivers/rng/Kconfig +@@ -31,6 +31,15 @@ config RNG_MSM + This driver provides support for the Random Number + Generator hardware found on Qualcomm SoCs. + ++config RNG_OPTEE ++ bool "OP-TEE based Random Number Generator support" ++ depends on DM_RNG && OPTEE ++ help ++ This driver provides support for the OP-TEE based Random Number ++ Generator on ARM SoCs where hardware entropy sources are not ++ accessible to normal world but reserved and used by the OP-TEE ++ to avoid the weakness of a software PRNG. ++ + config RNG_STM32MP1 + bool "Enable random number generator for STM32MP1" + depends on ARCH_STM32MP +diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile +index 39f7ee3f03..435b3b965a 100644 +--- a/drivers/rng/Makefile ++++ b/drivers/rng/Makefile +@@ -7,6 +7,7 @@ obj-$(CONFIG_DM_RNG) += rng-uclass.o + obj-$(CONFIG_RNG_MESON) += meson-rng.o + obj-$(CONFIG_RNG_SANDBOX) += sandbox_rng.o + obj-$(CONFIG_RNG_MSM) += msm_rng.o ++obj-$(CONFIG_RNG_OPTEE) += optee_rng.o + obj-$(CONFIG_RNG_STM32MP1) += stm32mp1_rng.o + obj-$(CONFIG_RNG_ROCKCHIP) += rockchip_rng.o + obj-$(CONFIG_RNG_IPROC200) += iproc_rng200.o +diff --git a/drivers/rng/optee_rng.c b/drivers/rng/optee_rng.c +new file mode 100644 +index 0000000000..aa8ce864d3 +--- /dev/null ++++ b/drivers/rng/optee_rng.c +@@ -0,0 +1,184 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause ++/* ++ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved ++ */ ++#define LOG_CATEGORY UCLASS_RNG ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 ++ ++/* ++ * TA_CMD_GET_ENTROPY - Get Entropy from RNG ++ * ++ * param[0] (inout memref) - Entropy buffer memory reference ++ * param[1] unused ++ * param[2] unused ++ * param[3] unused ++ * ++ * Result: ++ * TEE_SUCCESS - Invoke command success ++ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param ++ * TEE_ERROR_NOT_SUPPORTED - Requested entropy size greater than size of pool ++ * TEE_ERROR_HEALTH_TEST_FAIL - Continuous health testing failed ++ */ ++#define TA_CMD_GET_ENTROPY 0x0 ++ ++#define MAX_ENTROPY_REQ_SZ SZ_4K ++ ++#define TA_HWRNG_UUID { 0xab7a617c, 0xb8e7, 0x4d8f, \ ++ { 0x83, 0x01, 0xd0, 0x9b, 0x61, 0x03, 0x6b, 0x64 } } ++ ++/** open_session_ta_hwrng() - Open session with hwrng Trusted App ++ * ++ * @dev: device ++ * @session_id: return the RNG TA session identifier ++ * Return: 0 if ok ++ */ ++static int open_session_ta_hwrng(struct udevice *dev, u32 *session_id) ++{ ++ const struct tee_optee_ta_uuid uuid = TA_HWRNG_UUID; ++ struct tee_open_session_arg sess_arg = {0}; ++ int ret; ++ ++ /* Open session with hwrng Trusted App */ ++ tee_optee_ta_uuid_to_octets(sess_arg.uuid, &uuid); ++ sess_arg.clnt_login = TEE_LOGIN_PUBLIC; ++ ++ ret = tee_open_session(dev->parent, &sess_arg, 0, NULL); ++ if (ret || sess_arg.ret) { ++ if (!ret) ++ ret = -EIO; ++ return ret; ++ } ++ ++ *session_id = sess_arg.session; ++ return 0; ++} ++ ++/** ++ * get_optee_rng_data() - read RNG data from OP-TEE TA ++ * ++ * @dev: device ++ * @session_id: the RNG TA session identifier ++ * @entropy_shm_pool: shared memory pool used for TEE message ++ * @buf: buffer to receive data ++ * @size: size of buffer, limited by entropy_shm_pool size ++ * Return: 0 if ok ++ */ ++static int get_optee_rng_data(struct udevice *dev, u32 session_id, ++ struct tee_shm *entropy_shm_pool, ++ void *buf, size_t *size) ++{ ++ int ret = 0; ++ struct tee_invoke_arg arg = {0}; ++ struct tee_param param = {0}; ++ ++ /* Invoke TA_CMD_GET_ENTROPY function of Trusted App */ ++ arg.func = TA_CMD_GET_ENTROPY; ++ arg.session = session_id; ++ ++ /* Fill invoke cmd params */ ++ param.attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT; ++ param.u.memref.shm = entropy_shm_pool; ++ param.u.memref.size = *size; ++ ++ ret = tee_invoke_func(dev->parent, &arg, 1, ¶m); ++ if (ret || arg.ret) { ++ if (!ret) ++ ret = -EPROTO; ++ dev_err(dev, "TA_CMD_GET_ENTROPY invoke err: %d 0x%x\n", ret, arg.ret); ++ *size = 0; ++ ++ return ret; ++ } ++ ++ memcpy(buf, param.u.memref.shm->addr, param.u.memref.size); ++ *size = param.u.memref.size; ++ ++ return 0; ++} ++ ++/** ++ * optee_rng_read() - rng read ops for OP-TEE RNG device ++ * ++ * @dev: device ++ * @buf: buffer to receive data ++ * @len: size of buffer ++ * Return: 0 if ok ++ */ ++static int optee_rng_read(struct udevice *dev, void *buf, size_t len) ++{ ++ size_t read = 0, rng_size = 0; ++ struct tee_shm *entropy_shm_pool; ++ u8 *data = buf; ++ int ret; ++ u32 session_id = 0; ++ ++ ret = open_session_ta_hwrng(dev, &session_id); ++ if (ret) { ++ dev_err(dev, "can't open session: %d\n", ret); ++ return ret; ++ } ++ ++ ret = tee_shm_alloc(dev->parent, MAX_ENTROPY_REQ_SZ, 0, &entropy_shm_pool); ++ if (ret) { ++ dev_err(dev, "tee_shm_alloc failed: %d\n", ret); ++ goto session_close; ++ } ++ ++ while (read < len) { ++ rng_size = min(len - read, (size_t)MAX_ENTROPY_REQ_SZ); ++ ret = get_optee_rng_data(dev, session_id, entropy_shm_pool, data, &rng_size); ++ if (ret) ++ goto shm_free; ++ data += rng_size; ++ read += rng_size; ++ } ++ ++shm_free: ++ tee_shm_free(entropy_shm_pool); ++ ++session_close: ++ tee_close_session(dev->parent, session_id); ++ ++ return ret; ++} ++ ++/** ++ * optee_rng_probe() - probe function for OP-TEE RNG device ++ * ++ * @dev: device ++ * Return: 0 if ok ++ */ ++static int optee_rng_probe(struct udevice *dev) ++{ ++ int ret; ++ u32 session_id; ++ ++ ret = open_session_ta_hwrng(dev, &session_id); ++ if (ret) { ++ dev_err(dev, "can't open session: %d\n", ret); ++ return ret; ++ } ++ tee_close_session(dev->parent, session_id); ++ ++ return 0; ++} ++ ++static const struct dm_rng_ops optee_rng_ops = { ++ .read = optee_rng_read, ++}; ++ ++U_BOOT_DRIVER(optee_rng) = { ++ .name = "optee-rng", ++ .id = UCLASS_RNG, ++ .ops = &optee_rng_ops, ++ .probe = optee_rng_probe, ++}; +diff --git a/drivers/rng/stm32mp1_rng.c b/drivers/rng/stm32mp1_rng.c +index 8ea00e3e89..89da78c6c8 100644 +--- a/drivers/rng/stm32mp1_rng.c ++++ b/drivers/rng/stm32mp1_rng.c +@@ -18,22 +18,28 @@ + #include + #include + +-#define RNG_CR 0x00 +-#define RNG_CR_RNGEN BIT(2) +-#define RNG_CR_CED BIT(5) ++#define RNG_CR 0x00 ++#define RNG_CR_RNGEN BIT(2) ++#define RNG_CR_CED BIT(5) ++#define RNG_CR_CONDRST BIT(30) + +-#define RNG_SR 0x04 +-#define RNG_SR_SEIS BIT(6) +-#define RNG_SR_CEIS BIT(5) +-#define RNG_SR_SECS BIT(2) +-#define RNG_SR_DRDY BIT(0) ++#define RNG_SR 0x04 ++#define RNG_SR_SEIS BIT(6) ++#define RNG_SR_CEIS BIT(5) ++#define RNG_SR_SECS BIT(2) ++#define RNG_SR_DRDY BIT(0) + +-#define RNG_DR 0x08 ++#define RNG_DR 0x08 ++ ++struct stm32_rng_data { ++ bool has_cond_reset; ++}; + + struct stm32_rng_plat { + fdt_addr_t base; + struct clk clk; + struct reset_ctl rst; ++ const struct stm32_rng_data *data; + }; + + static int stm32_rng_read(struct udevice *dev, void *data, size_t len) +@@ -83,18 +89,36 @@ static int stm32_rng_read(struct udevice *dev, void *data, size_t len) + static int stm32_rng_init(struct stm32_rng_plat *pdata) + { + int err; ++ u32 cr, sr; + + err = clk_enable(&pdata->clk); + if (err) + return err; + ++ cr = readl(pdata->base + RNG_CR); ++ + /* Disable CED */ +- writel(RNG_CR_RNGEN | RNG_CR_CED, pdata->base + RNG_CR); ++ cr |= RNG_CR_CED; ++ if (pdata->data->has_cond_reset) { ++ cr |= RNG_CR_CONDRST; ++ writel(cr, pdata->base + RNG_CR); ++ cr &= ~RNG_CR_CONDRST; ++ writel(cr, pdata->base + RNG_CR); ++ err = readl_poll_timeout(pdata->base + RNG_CR, cr, ++ (!(cr & RNG_CR_CONDRST)), 10000); ++ if (err) ++ return err; ++ } + + /* clear error indicators */ + writel(0, pdata->base + RNG_SR); + +- return 0; ++ cr |= RNG_CR_RNGEN; ++ writel(cr, pdata->base + RNG_CR); ++ ++ err = readl_poll_timeout(pdata->base + RNG_SR, sr, ++ sr & RNG_SR_DRDY, 10000); ++ return err; + } + + static int stm32_rng_cleanup(struct stm32_rng_plat *pdata) +@@ -108,6 +132,8 @@ static int stm32_rng_probe(struct udevice *dev) + { + struct stm32_rng_plat *pdata = dev_get_plat(dev); + ++ pdata->data = (struct stm32_rng_data *)dev_get_driver_data(dev); ++ + reset_assert(&pdata->rst); + udelay(20); + reset_deassert(&pdata->rst); +@@ -146,10 +172,17 @@ static const struct dm_rng_ops stm32_rng_ops = { + .read = stm32_rng_read, + }; + ++static const struct stm32_rng_data stm32mp13_rng_data = { ++ .has_cond_reset = true, ++}; ++ ++static const struct stm32_rng_data stm32_rng_data = { ++ .has_cond_reset = false, ++}; ++ + static const struct udevice_id stm32_rng_match[] = { +- { +- .compatible = "st,stm32-rng", +- }, ++ {.compatible = "st,stm32mp13-rng", .data = (ulong)&stm32mp13_rng_data}, ++ {.compatible = "st,stm32-rng", .data = (ulong)&stm32_rng_data}, + {}, + }; + +diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c +index 8171b17faf..01387c1119 100644 +--- a/drivers/serial/serial-uclass.c ++++ b/drivers/serial/serial-uclass.c +@@ -69,7 +69,7 @@ static int serial_check_stdout(const void *blob, struct udevice **devp) + * anyway. + */ + if (node > 0 && !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node), +- devp, false)) { ++ devp, NULL, false)) { + if (!device_probe(*devp)) + return 0; + } +diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c +index d867b27806..ee30110b56 100644 +--- a/drivers/spi/spi-uclass.c ++++ b/drivers/spi/spi-uclass.c +@@ -391,8 +391,6 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, + } else if (ret) { + dev_err(bus, "Invalid chip select %d:%d (err=%d)\n", busnum, cs, ret); + return ret; +- } else if (dev) { +- plat = dev_get_parent_plat(dev); + } + + if (!device_active(dev)) { +@@ -418,22 +416,12 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, + goto err; + } + +- /* In case bus frequency or mode changed, update it. */ +- if ((speed && bus_data->speed && bus_data->speed != speed) || +- (plat && plat->mode != mode)) { +- ret = spi_set_speed_mode(bus, speed, mode); +- if (ret) +- goto err_speed_mode; +- } +- + *busp = bus; + *devp = slave; + log_debug("%s: bus=%p, slave=%p\n", __func__, bus, *devp); + + return 0; + +-err_speed_mode: +- spi_release_bus(slave); + err: + log_debug("%s: Error path, created=%d, device '%s'\n", __func__, + created, dev->name); +diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c +index 8f4aabc3d1..ceba413727 100644 +--- a/drivers/spi/stm32_qspi.c ++++ b/drivers/spi/stm32_qspi.c +@@ -150,20 +150,19 @@ static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv *priv, + u32 sr; + int ret = 0; + +- if (op->data.nbytes) { +- ret = readl_poll_timeout(&priv->regs->sr, sr, +- sr & STM32_QSPI_SR_TCF, +- STM32_QSPI_CMD_TIMEOUT_US); +- if (ret) { +- log_err("cmd timeout (stat:%#x)\n", sr); +- } else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) { +- log_err("transfer error (stat:%#x)\n", sr); +- ret = -EIO; +- } +- /* clear flags */ +- writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, &priv->regs->fcr); ++ ret = readl_poll_timeout(&priv->regs->sr, sr, ++ sr & STM32_QSPI_SR_TCF, ++ STM32_QSPI_CMD_TIMEOUT_US); ++ if (ret) { ++ log_err("cmd timeout (stat:%#x)\n", sr); ++ } else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) { ++ log_err("transfer error (stat:%#x)\n", sr); ++ ret = -EIO; + } + ++ /* clear flags */ ++ writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, &priv->regs->fcr); ++ + if (!ret) + ret = _stm32_qspi_wait_for_not_busy(priv); + +@@ -256,10 +255,6 @@ static int stm32_qspi_exec_op(struct spi_slave *slave, + op->dummy.buswidth, op->data.buswidth, + op->addr.val, op->data.nbytes); + +- ret = _stm32_qspi_wait_for_not_busy(priv); +- if (ret) +- return ret; +- + addr_max = op->addr.val + op->data.nbytes + 1; + + if (op->data.dir == SPI_MEM_DATA_IN && op->data.nbytes) { +diff --git a/drivers/spi/stm32_spi.c b/drivers/spi/stm32_spi.c +index bd8514033d..fe5419e851 100644 +--- a/drivers/spi/stm32_spi.c ++++ b/drivers/spi/stm32_spi.c +@@ -97,11 +97,14 @@ + #define SPI_SIMPLEX_RX 2 + #define SPI_HALF_DUPLEX 3 + +-struct stm32_spi_priv { ++struct stm32_spi_plat { + 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; +@@ -115,28 +118,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_plat *plat = dev_get_plat(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); + } + } +@@ -144,9 +151,12 @@ static void stm32_spi_write_txfifo(struct stm32_spi_priv *priv) + log_debug("%d bytes left\n", 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_plat *plat = dev_get_plat(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) && +@@ -158,7 +168,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) || +@@ -166,38 +176,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; + } + + log_debug("%d bytes left\n", priv->rx_len); + } + +-static int stm32_spi_enable(struct stm32_spi_priv *priv) ++static int stm32_spi_enable(void __iomem *base) + { + log_debug("\n"); + + /* 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) + { + log_debug("\n"); + + /* 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; + } +@@ -205,45 +215,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_plat *plat = dev_get_plat(bus); ++ void __iomem *base = plat->base; + + dev_dbg(slave, "\n"); + + /* 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_plat *plat = dev_get_plat(bus); ++ void __iomem *base = plat->base; + + dev_dbg(slave, "\n"); + + /* 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_plat *plat = dev_get_plat(dev); ++ void __iomem *base = plat->base; + u32 cr1, sr; + int ret; + + dev_dbg(dev, "\n"); + +- 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"); +@@ -251,11 +264,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_plat *plat = dev_get_plat(dev); + struct stm32_spi_priv *priv = dev_get_priv(dev); + + dev_dbg(dev, "cs=%d enable=%d\n", cs, enable); +@@ -263,18 +277,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_plat *plat = dev_get_plat(bus); ++ void __iomem *base = plat->base; + u32 cfg2_clrb = 0, cfg2_setb = 0; + + dev_dbg(bus, "mode=%d\n", mode); +@@ -295,7 +311,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) +@@ -308,6 +324,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_plat *plat = dev_get_plat(dev); ++ void __iomem *base = plat->base; + u32 fthlv, half_fifo; + + /* data packet should not exceed 1/2 of fifo space */ +@@ -321,7 +339,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; +@@ -330,6 +348,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_plat *plat = dev_get_plat(bus); ++ void __iomem *base = plat->base; + u32 mbrdiv; + long div; + +@@ -353,7 +373,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; +@@ -367,6 +387,8 @@ static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen, + struct udevice *bus = dev_get_parent(slave); + struct dm_spi_slave_plat *slave_plat; + struct stm32_spi_priv *priv = dev_get_priv(bus); ++ struct stm32_spi_plat *plat = dev_get_plat(bus); ++ void __iomem *base = plat->base; + u32 sr; + u32 ifcr = 0; + u32 xferlen; +@@ -376,7 +398,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; + +@@ -396,15 +418,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); + } + + dev_dbg(bus, "priv->tx_len=%d priv->rx_len=%d\n", +@@ -416,12 +438,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"); +@@ -433,7 +455,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; + } +@@ -443,23 +465,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) +@@ -470,42 +492,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_plat *plat = dev_get_plat(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); + + dev_dbg(dev, "%d x 8-bit fifo size\n", count); + + return count; + } + ++static int stm32_spi_of_to_plat(struct udevice *dev) ++{ ++ struct stm32_spi_plat *plat = dev_get_plat(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_plat *plat = dev_get_plat(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; +@@ -514,46 +566,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) { +- dev_err(dev, "Can't get cs gpios: %d", 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); + + /* +@@ -562,40 +602,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_plat *plat = dev_get_plat(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; + }; +@@ -618,7 +656,9 @@ U_BOOT_DRIVER(stm32_spi) = { + .id = UCLASS_SPI, + .of_match = stm32_spi_ids, + .ops = &stm32_spi_ops, +- .priv_auto = sizeof(struct stm32_spi_priv), ++ .of_to_plat = stm32_spi_of_to_plat, ++ .plat_auto = sizeof(struct stm32_spi_plat), ++ .priv_auto = sizeof(struct stm32_spi_priv), + .probe = stm32_spi_probe, + .remove = stm32_spi_remove, + }; +diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c +index dad46aa388..a89d62aaf0 100644 +--- a/drivers/tee/optee/core.c ++++ b/drivers/tee/optee/core.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -641,6 +642,8 @@ static int optee_probe(struct udevice *dev) + { + struct optee_pdata *pdata = dev_get_plat(dev); + u32 sec_caps; ++ struct udevice *child; ++ int ret; + + if (!is_optee_api(pdata->invoke_fn)) { + dev_err(dev, "OP-TEE api uid mismatch\n"); +@@ -665,6 +668,16 @@ static int optee_probe(struct udevice *dev) + return -ENOENT; + } + ++ /* ++ * in U-Boot, the discovery of TA on the TEE bus is not supported: ++ * only bind the drivers associated to the supported OP-TEE TA ++ */ ++ if (IS_ENABLED(CONFIG_RNG_OPTEE)) { ++ ret = device_bind_driver(dev, "optee-rng", "optee-rng", &child); ++ if (ret) ++ return ret; ++ } ++ + return 0; + } + +diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h +index 8d40ce60c2..a8ef926a48 100644 +--- a/drivers/tee/optee/optee_msg.h ++++ b/drivers/tee/optee/optee_msg.h +@@ -86,16 +86,6 @@ + #define OPTEE_MSG_ATTR_CACHE_MASK GENMASK(2, 0) + #define OPTEE_MSG_ATTR_CACHE_PREDEFINED 0 + +-/* +- * Same values as TEE_LOGIN_* from TEE Internal API +- */ +-#define OPTEE_MSG_LOGIN_PUBLIC 0x00000000 +-#define OPTEE_MSG_LOGIN_USER 0x00000001 +-#define OPTEE_MSG_LOGIN_GROUP 0x00000002 +-#define OPTEE_MSG_LOGIN_APPLICATION 0x00000004 +-#define OPTEE_MSG_LOGIN_APPLICATION_USER 0x00000005 +-#define OPTEE_MSG_LOGIN_APPLICATION_GROUP 0x00000006 +- + /* + * Page size used in non-contiguous buffer entries + */ +@@ -279,7 +269,7 @@ struct optee_msg_arg { + * parameters to pass the following information: + * param[0].u.value.a-b uuid of Trusted Application + * param[1].u.value.a-b uuid of Client +- * param[1].u.value.c Login class of client OPTEE_MSG_LOGIN_* ++ * param[1].u.value.c Login class of client TEE_LOGIN_* + * + * OPTEE_MSG_CMD_INVOKE_COMMAND invokes a command a previously opened + * session to a Trusted Application. struct optee_msg_arg::func is Trusted +diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c +index c8e8419b22..ebea168789 100644 +--- a/drivers/timer/timer-uclass.c ++++ b/drivers/timer/timer-uclass.c +@@ -146,7 +146,7 @@ int notrace dm_timer_init(void) + * If the timer is not marked to be bound before + * relocation, bind it anyway. + */ +- if (!lists_bind_fdt(dm_root(), node, &dev, false)) { ++ if (!lists_bind_fdt(dm_root(), node, &dev, NULL, false)) { + ret = device_probe(dev); + if (ret) + return ret; +diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig +index ab1d061bd0..a362c96811 100644 +--- a/drivers/usb/Kconfig ++++ b/drivers/usb/Kconfig +@@ -82,6 +82,8 @@ source "drivers/usb/emul/Kconfig" + + source "drivers/usb/phy/Kconfig" + ++source "drivers/usb/typec/Kconfig" ++ + source "drivers/usb/ulpi/Kconfig" + + if USB_HOST +diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c +index 2f31814442..c96a3f248c 100644 +--- a/drivers/usb/gadget/dwc2_udc_otg.c ++++ b/drivers/usb/gadget/dwc2_udc_otg.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -979,6 +980,7 @@ static void dwc2_phy_shutdown(struct udevice *dev, struct phy_bulk *phys) + static int dwc2_udc_otg_of_to_plat(struct udevice *dev) + { + struct dwc2_plat_otg_data *plat = dev_get_plat(dev); ++ struct udevice *typec; + ulong drvdata; + void (*set_params)(struct dwc2_plat_otg_data *data); + int ret; +@@ -1006,11 +1008,20 @@ static int dwc2_udc_otg_of_to_plat(struct udevice *dev) + return ret; + } + +- plat->force_b_session_valid = +- dev_read_bool(dev, "u-boot,force-b-session-valid"); +- +- plat->force_vbus_detection = +- dev_read_bool(dev, "u-boot,force-vbus-detection"); ++ /* ++ * check for High speed port/endpoint subnode presence and retrieve Type-C ++ * device if exist. HS port subnode is always port number 0 => port@0 ++ */ ++ ret = typec_get_device_from_usb(dev, &typec, 0); ++ if (!ret) { ++ ret = typec_get_data_role(typec, 0); ++ plat->force_b_session_valid = (ret == TYPEC_DEVICE); ++ } else { ++ plat->force_b_session_valid = ++ dev_read_bool(dev, "u-boot,force-b-session-valid"); ++ plat->force_vbus_detection = ++ dev_read_bool(dev, "u-boot,force-vbus-detection"); ++ } + + /* force plat according compatible */ + drvdata = dev_get_driver_data(dev); +diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c +index 4bedc7d3a1..e9340ff5cb 100644 +--- a/drivers/usb/gadget/f_dfu.c ++++ b/drivers/usb/gadget/f_dfu.c +@@ -336,6 +336,8 @@ static int state_dfu_idle(struct f_dfu *f_dfu, + f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE; + f_dfu->blk_seq_num = 0; + value = handle_upload(req, len); ++ if (value >= 0 && value < len) ++ f_dfu->dfu_state = DFU_STATE_dfuIDLE; + break; + case USB_REQ_DFU_ABORT: + /* no zlp? */ +diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h +index 0cdf47c2dd..06e6a48949 100644 +--- a/drivers/usb/gadget/gadget_chips.h ++++ b/drivers/usb/gadget/gadget_chips.h +@@ -167,6 +167,12 @@ + #define gadget_is_mtu3(g) 0 + #endif + ++#ifdef CONFIG_USB_GADGET_DWC2_OTG ++#define gadget_is_dwc2(g) (!strcmp("dwc2-udc", (g)->name)) ++#else ++#define gadget_is_dwc2(g) 0 ++#endif ++ + /** + * usb_gadget_controller_number - support bcdDevice id convention + * @gadget: the controller being driven +@@ -232,5 +238,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) + return 0x25; + else if (gadget_is_mtu3(gadget)) + return 0x26; ++ else if (gadget_is_dwc2(gadget)) ++ return 0x27; + return -ENOENT; + } +diff --git a/drivers/usb/host/usb-sandbox.c b/drivers/usb/host/usb-sandbox.c +index d7cc92aa54..d1103dcb2e 100644 +--- a/drivers/usb/host/usb-sandbox.c ++++ b/drivers/usb/host/usb-sandbox.c +@@ -9,6 +9,13 @@ + #include + #include + #include ++#include ++ ++struct sandbox_udc { ++ struct usb_gadget gadget; ++}; ++ ++struct sandbox_udc *this_controller; + + struct sandbox_usb_ctrl { + int rootdev; +@@ -117,6 +124,27 @@ static int sandbox_submit_int(struct udevice *bus, struct usb_device *udev, + return ret; + } + ++int usb_gadget_handle_interrupts(int index) ++{ ++ return 0; ++} ++ ++int usb_gadget_register_driver(struct usb_gadget_driver *driver) ++{ ++ struct sandbox_udc *dev = this_controller; ++ ++ return driver->bind(&dev->gadget); ++} ++ ++int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) ++{ ++ struct sandbox_udc *dev = this_controller; ++ ++ driver->unbind(&dev->gadget); ++ ++ return 0; ++} ++ + static int sandbox_alloc_device(struct udevice *dev, struct usb_device *udev) + { + struct sandbox_usb_ctrl *ctrl = dev_get_priv(dev); +diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig +new file mode 100644 +index 0000000000..c9930320ca +--- /dev/null ++++ b/drivers/usb/typec/Kconfig +@@ -0,0 +1,24 @@ ++menuconfig TYPEC ++ bool "USB Type-C support" ++ depends on DM ++ help ++ Enable this configurations option if you have USB Type-C connectors on ++ your system and 1) you know your USB Type-C hardware requires OS ++ control (a driver) to function, or 2) if you need to be able to read ++ the status of the USB Type-C ports in your system, or 3) if you need ++ to be able to swap the power role (decide are you supplying or ++ consuming power over the cable) or data role (host or device) when ++ both roles are supported. ++ ++if TYPEC ++ ++config TYPEC_STUSB160X ++ bool "STMicroelectronics STUSB160x Type-C controller driver" ++ depends on DM && DM_I2C ++ help ++ Say Y or M here if your system has STMicroelectronics STUSB160x ++ Type-C port controller. ++ ++source "drivers/usb/typec/ucsi/Kconfig" ++ ++endif +diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile +new file mode 100644 +index 0000000000..e0b66ae8ef +--- /dev/null ++++ b/drivers/usb/typec/Makefile +@@ -0,0 +1,5 @@ ++# SPDX-License-Identifier: GPL-2.0+ ++ ++obj-$(CONFIG_TYPEC) += typec-uclass.o ++obj-$(CONFIG_TYPEC_STUSB160X) += typec-stusb160x.o ++obj-$(CONFIG_TYPEC_UCSI) += ucsi/ +diff --git a/drivers/usb/typec/typec-stusb160x.c b/drivers/usb/typec/typec-stusb160x.c +new file mode 100644 +index 0000000000..28e9bf1c74 +--- /dev/null ++++ b/drivers/usb/typec/typec-stusb160x.c +@@ -0,0 +1,130 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2021, STMicroelectronics - All Rights Reserved ++ */ ++ ++#define LOG_CATEGORY UCLASS_USB_TYPEC ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define STUSB160X_ALERT_STATUS 0x0B /* RC */ ++#define STUSB160X_CC_CONNECTION BIT(6) ++ ++#define STUSB160X_CC_CONNECTION_STATUS_TRANS 0x0D /* RC */ ++#define STUSB160X_CC_ATTACH_TRANS BIT(0) ++ ++#define STUSB160X_CC_CONNECTION_STATUS 0x0E /* RO */ ++#define STUSB160X_CC_ATTACH BIT(0) ++#define STUSB160X_CC_DATA_ROLE BIT(2) ++ ++#define STUSB160X_CC_POWER_MODE_CTRL 0x28 /* RW */ ++#define STUSB160X_DUAL_WITH_ACCESSORY 3 ++ ++struct stusb160x_priv { ++ enum typec_state attached; ++ enum typec_data_role data_role; ++}; ++ ++static int stusb160x_get_status(struct udevice *dev, bool force) ++{ ++ struct stusb160x_priv *priv = dev_get_priv(dev); ++ int alert, trans, status; ++ ++ alert = dm_i2c_reg_read(dev, STUSB160X_ALERT_STATUS); ++ if (alert < 0) ++ return alert; ++ ++ /* If no update, exit */ ++ if ((!(alert & STUSB160X_CC_CONNECTION)) && !force) ++ goto exit; ++ ++ trans = dm_i2c_reg_read(dev, STUSB160X_CC_CONNECTION_STATUS_TRANS); ++ if (trans < 0) ++ return trans; ++ ++ status = dm_i2c_reg_read(dev, STUSB160X_CC_CONNECTION_STATUS); ++ if (status < 0) ++ return status; ++ ++ priv->data_role = status & STUSB160X_CC_DATA_ROLE ? TYPEC_HOST : TYPEC_DEVICE; ++ priv->attached = status & STUSB160X_CC_ATTACH ? TYPEC_ATTACHED : TYPEC_UNATTACHED; ++exit: ++ dev_dbg(dev, "status: %s data role: %s\n", ++ priv->attached == TYPEC_ATTACHED ? "Attached" : "Unattached", ++ priv->data_role == TYPEC_HOST ? "Host" : "Device"); ++ ++ return 0; ++} ++ ++static int stusb160x_get_data_role(struct udevice *dev, u8 con_idx) ++{ ++ struct stusb160x_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ ret = stusb160x_get_status(dev, false); ++ if (ret < 0) ++ return ret; ++ ++ return priv->data_role; ++} ++ ++static int stusb160x_is_attached(struct udevice *dev, u8 con_idx) ++{ ++ struct stusb160x_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ ret = stusb160x_get_status(dev, false); ++ if (ret < 0) ++ return ret; ++ ++ return priv->attached; ++} ++ ++static u8 stusb160x_get_nb_connector(struct udevice *dev) ++{ ++ /* only one connector supported */ ++ return 1; ++} ++ ++static int stusb160x_probe(struct udevice *dev) ++{ ++ int power_mode_ctrl; ++ int ret; ++ ++ /* configure STUSB160X_CC_POWER_MODE_CTRL */ ++ power_mode_ctrl = dm_i2c_reg_read(dev, STUSB160X_CC_POWER_MODE_CTRL); ++ if (power_mode_ctrl < 0) ++ return power_mode_ctrl; ++ ++ power_mode_ctrl |= STUSB160X_DUAL_WITH_ACCESSORY; ++ ret = dm_i2c_reg_write(dev, STUSB160X_CC_POWER_MODE_CTRL, power_mode_ctrl); ++ if (ret < 0) ++ return ret; ++ ++ /* get current status : attached/unattached, device/host */ ++ return stusb160x_get_status(dev, true); ++} ++ ++static const struct typec_ops stusb160x_typec_ops = { ++ .is_attached = stusb160x_is_attached, ++ .get_data_role = stusb160x_get_data_role, ++ .get_nb_connector = stusb160x_get_nb_connector, ++}; ++ ++static const struct udevice_id typec_of_match[] = { ++ { .compatible = "st,stusb1600"}, ++ {} ++}; ++ ++U_BOOT_DRIVER(typec_stusb160x) = { ++ .id = UCLASS_USB_TYPEC, ++ .name = "typec_stusb160x", ++ .of_match = typec_of_match, ++ .ops = &stusb160x_typec_ops, ++ .priv_auto = sizeof(struct stusb160x_priv), ++ .probe = stusb160x_probe, ++}; +diff --git a/drivers/usb/typec/typec-uclass.c b/drivers/usb/typec/typec-uclass.c +new file mode 100644 +index 0000000000..6b870c7ff6 +--- /dev/null ++++ b/drivers/usb/typec/typec-uclass.c +@@ -0,0 +1,127 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2021, STMicroelectronics - All Rights Reserved ++ */ ++ ++#define LOG_CATEGORY UCLASS_USB_TYPEC ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++int typec_get_device_from_usb(struct udevice *dev, struct udevice **typec, u8 index) ++{ ++ ofnode node, child; ++ u32 endpoint_phandle; ++ u32 reg; ++ int ret; ++ ++ /* 'port' nodes can be grouped under an optional 'ports' node */ ++ node = dev_read_subnode(dev, "ports"); ++ if (!ofnode_valid(node)) { ++ node = dev_read_subnode(dev, "port"); ++ } else { ++ /* several 'port' nodes, found the requested port@index one */ ++ ofnode_for_each_subnode(child, node) { ++ ofnode_read_u32(child, "reg", ®); ++ if (index == reg) { ++ node = child; ++ break; ++ } ++ } ++ node = child; ++ } ++ ++ if (!ofnode_valid(node)) { ++ dev_dbg(dev, "connector port or port@%d subnode not found\n", index); ++ return -ENODEV; ++ } ++ ++ /* get endpoint node */ ++ node = ofnode_first_subnode(node); ++ if (!ofnode_valid(node)) ++ return -EINVAL; ++ ++ ret = ofnode_read_u32(node, "remote-endpoint", &endpoint_phandle); ++ if (ret) ++ return ret; ++ ++ /* retrieve connector endpoint phandle */ ++ node = ofnode_get_by_phandle(endpoint_phandle); ++ if (!ofnode_valid(node)) ++ return -EINVAL; ++ /* ++ * Use a while to retrieve an USB Type-C device either at connector ++ * level or just above (depending if UCSI uclass is used or not) ++ */ ++ while (ofnode_valid(node)) { ++ node = ofnode_get_parent(node); ++ if (!ofnode_valid(node)) { ++ dev_err(dev, "No UCLASS_USB_TYPEC for remote-endpoint\n"); ++ return -EINVAL; ++ } ++ ++ uclass_find_device_by_ofnode(UCLASS_USB_TYPEC, node, typec); ++ if (*typec) ++ break; ++ } ++ ++ ret = device_probe(*typec); ++ if (ret) { ++ dev_err(dev, "Type-C won't probe (ret=%d)\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int typec_get_data_role(struct udevice *dev, u8 con_idx) ++{ ++ const struct typec_ops *ops = device_get_ops(dev); ++ int ret; ++ ++ if (!ops->get_data_role) ++ return -ENOSYS; ++ ++ ret = ops->get_data_role(dev, con_idx); ++ dev_dbg(dev, "%s\n", ret == TYPEC_HOST ? "Host" : "Device"); ++ ++ return ret; ++} ++ ++int typec_is_attached(struct udevice *dev, u8 con_idx) ++{ ++ const struct typec_ops *ops = device_get_ops(dev); ++ int ret; ++ ++ if (!ops->is_attached) ++ return -ENOSYS; ++ ++ ret = ops->is_attached(dev, con_idx); ++ dev_dbg(dev, "%s\n", ret == TYPEC_ATTACHED ? "Attached" : "Not attached"); ++ ++ return ret; ++} ++ ++int typec_get_nb_connector(struct udevice *dev) ++{ ++ const struct typec_ops *ops = device_get_ops(dev); ++ int ret; ++ ++ if (!ops->get_nb_connector) ++ return -ENOSYS; ++ ++ ret = ops->get_nb_connector(dev); ++ dev_dbg(dev, "%d connector(s)\n", ret); ++ ++ return ret; ++} ++ ++UCLASS_DRIVER(typec) = { ++ .id = UCLASS_USB_TYPEC, ++ .name = "typec", ++}; +diff --git a/drivers/usb/typec/ucsi/Kconfig b/drivers/usb/typec/ucsi/Kconfig +new file mode 100644 +index 0000000000..928106b1db +--- /dev/null ++++ b/drivers/usb/typec/ucsi/Kconfig +@@ -0,0 +1,26 @@ ++menuconfig TYPEC_UCSI ++ bool "USB Type-C Connector System Software Interface (UCSI)" ++ depends on DM && TYPEC ++ help ++ USB Type-C Connector System Software Interface (UCSI) is a ++ specification for an interface that allows the operating system to ++ control the USB Type-C ports. On UCSI system the USB Type-C ports ++ function autonomously by default, but in order to get the status of ++ the ports and support basic operations like role swapping, the driver ++ is required. UCSI is available on most of the new Intel based systems ++ that are equipped with Embedded Controller and USB Type-C ports. ++ ++ UCSI specification does not define the interface method, so depending ++ on the platform, ACPI, PCI, I2C, etc. may be used. Therefore this ++ driver only provides the core part, and separate drivers are needed ++ for every supported interface method. ++ ++ The UCSI specification can be downloaded from: ++ https://www.intel.com/content/www/us/en/io/universal-serial-bus/usb-type-c-ucsi-spec.html ++ ++config UCSI_STM32G0 ++ bool "Support for STM32G0 UCSI controller" ++ depends on TYPEC_UCSI && DM_I2C ++ help ++ This driver enables UCSI support on platforms that expose a STM32G0 ++ Type-C controller over I2C interface. +diff --git a/drivers/usb/typec/ucsi/Makefile b/drivers/usb/typec/ucsi/Makefile +new file mode 100644 +index 0000000000..043000e238 +--- /dev/null ++++ b/drivers/usb/typec/ucsi/Makefile +@@ -0,0 +1,4 @@ ++# SPDX-License-Identifier: GPL-2.0+ ++ ++obj-y += ucsi-uclass.o ++obj-$(CONFIG_UCSI_STM32G0) += ucsi-stm32g0.o +diff --git a/drivers/usb/typec/ucsi/ucsi-stm32g0.c b/drivers/usb/typec/ucsi/ucsi-stm32g0.c +new file mode 100644 +index 0000000000..e3a1bc4889 +--- /dev/null ++++ b/drivers/usb/typec/ucsi/ucsi-stm32g0.c +@@ -0,0 +1,117 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2021, STMicroelectronics - All Rights Reserved ++ */ ++ ++#define LOG_CATEGORY UCLASS_UCSI ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int stm32_ucsi_read(struct udevice *dev, unsigned int offset, void *val, size_t len) ++{ ++ struct dm_i2c_chip *chip = dev_get_parent_plat(dev); ++ u8 reg = offset; ++ struct i2c_msg msg[] = { ++ { ++ .addr = chip->chip_addr, ++ .flags = 0, ++ .len = 1, ++ .buf = ®, ++ }, ++ { ++ .addr = chip->chip_addr, ++ .flags = I2C_M_RD, ++ .len = len, ++ .buf = val, ++ }, ++ }; ++ int ret; ++ ++ ret = dm_i2c_xfer(dev, msg, ARRAY_SIZE(msg)); ++ if (ret) ++ dev_err(dev, "i2c read failed @offset 0x%x (%d)\n", offset, ret); ++ ++ /* ++ * Add this delay to ensure that PPM has completed the current command, ++ * before sending it another one. ++ */ ++ udelay(20); ++ ++ return ret; ++} ++ ++static int stm32_ucsi_write(struct udevice *dev, unsigned int offset, ++ const void *val, size_t len) ++{ ++ struct dm_i2c_chip *chip = dev_get_parent_plat(dev); ++ struct i2c_msg msg[] = { ++ { ++ .addr = chip->chip_addr, ++ .flags = 0, ++ } ++ }; ++ unsigned char *buf; ++ int ret; ++ ++ buf = kzalloc(len + 1, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ buf[0] = offset; ++ memcpy(&buf[1], val, len); ++ msg[0].len = len + 1; ++ msg[0].buf = buf; ++ ++ ret = dm_i2c_xfer(dev, msg, ARRAY_SIZE(msg)); ++ kfree(buf); ++ if (ret) ++ dev_err(dev, "i2c write failed @offset 0x%x (%d)\n", offset, ret); ++ ++ /* ++ * Add this delay to ensure that PPM has completed the current command, ++ * before sending it another one. ++ */ ++ mdelay(2); ++ ++ return ret; ++} ++ ++int stm32_ucsi_probe(struct udevice *dev) ++{ ++ u16 ucsi_version; ++ int ret; ++ ++ ret = stm32_ucsi_read(dev, UCSI_VERSION, &ucsi_version, sizeof(ucsi_version)); ++ if (ret < 0) ++ return ret; ++ ++ dev_dbg(dev, "STM32G0 version 0x%x\n", ucsi_version); ++ ++ return 0; ++} ++ ++static const struct ucsi_ops stm32_ucsi_ops = { ++ .read = stm32_ucsi_read, ++ .write = stm32_ucsi_write, ++}; ++ ++static const struct udevice_id stm32_ucsi_of_match[] = { ++ { .compatible = "st,stm32g0-typec"}, ++ {} ++}; ++ ++U_BOOT_DRIVER(ucsi_stm32g0) = { ++ .id = UCLASS_UCSI, ++ .name = "ucsi-stm32g0", ++ .of_match = stm32_ucsi_of_match, ++ .probe = stm32_ucsi_probe, ++ .ops = &stm32_ucsi_ops, ++ .bind = dm_scan_fdt_dev, ++}; +diff --git a/drivers/usb/typec/ucsi/ucsi-uclass.c b/drivers/usb/typec/ucsi/ucsi-uclass.c +new file mode 100644 +index 0000000000..8744497ebf +--- /dev/null ++++ b/drivers/usb/typec/ucsi/ucsi-uclass.c +@@ -0,0 +1,393 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2021, STMicroelectronics - All Rights Reserved ++ * ++ * Code inspired from kernel drivers/usb/typec/ucsi/ucsi.c ++ * ++ */ ++ ++#define LOG_CATEGORY UCLASS_UCSI ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * UCSI_TIMEOUT_US - PPM communication timeout ++ * ++ * Ideally we could use MIN_TIME_TO_RESPOND_WITH_BUSY (which is defined in UCSI ++ * specification) here as reference, but unfortunately we can't. It is very ++ * difficult to estimate the time it takes for the system to process the command ++ * before it is actually passed to the PPM. ++ */ ++#define UCSI_TIMEOUT_US 50000000 ++ ++struct connector { ++ enum typec_state attached; ++ enum typec_data_role data_role; ++}; ++ ++struct ucsi_priv { ++ struct connector *con; ++ u8 nb_connector; ++}; ++ ++static int ucsi_read(struct udevice *dev, int offset, void *buf, int size) ++{ ++ const struct ucsi_ops *ops = device_get_ops(dev); ++ ++ if (!ops->read) ++ return -ENOSYS; ++ ++ return ops->read(dev, offset, buf, size); ++} ++ ++static int ucsi_write(struct udevice *dev, int offset, void *buf, int size) ++{ ++ const struct ucsi_ops *ops = device_get_ops(dev); ++ ++ if (!ops->write) ++ return -ENOSYS; ++ ++ return ops->write(dev, offset, buf, size); ++} ++ ++static int ucsi_acknowledge_command(struct udevice *dev) ++{ ++ u64 ctrl; ++ ++ ctrl = UCSI_ACK_CC_CI; ++ ctrl |= UCSI_ACK_COMMAND_COMPLETE; ++ ++ return ucsi_write(dev, UCSI_CONTROL, &ctrl, sizeof(ctrl)); ++} ++ ++static int ucsi_acknowledge_connector_change(struct udevice *dev) ++{ ++ u64 ctrl; ++ ++ ctrl = UCSI_ACK_CC_CI; ++ ctrl |= UCSI_ACK_CONNECTOR_CHANGE; ++ ++ return ucsi_write(dev, UCSI_CONTROL, &ctrl, sizeof(ctrl)); ++} ++ ++static int ucsi_exec_command(struct udevice *dev, u64 command); ++ ++static int ucsi_read_error(struct udevice *dev) ++{ ++ u16 error; ++ int ret; ++ ++ /* Acknowlege the command that failed */ ++ ret = ucsi_acknowledge_command(dev); ++ ++ if (ret) ++ return ret; ++ ++ ret = ucsi_exec_command(dev, UCSI_GET_ERROR_STATUS); ++ ++ if (ret < 0) ++ return ret; ++ ++ ret = ucsi_read(dev, UCSI_MESSAGE_IN, &error, sizeof(error)); ++ if (ret) ++ return ret; ++ ++ switch (error) { ++ case UCSI_ERROR_INCOMPATIBLE_PARTNER: ++ return -EOPNOTSUPP; ++ case UCSI_ERROR_CC_COMMUNICATION_ERR: ++ return -ECOMM; ++ case UCSI_ERROR_CONTRACT_NEGOTIATION_FAIL: ++ return -EPROTO; ++ case UCSI_ERROR_DEAD_BATTERY: ++ dev_warn(dev, "Dead battery condition!\n"); ++ return -EPERM; ++ case UCSI_ERROR_INVALID_CON_NUM: ++ case UCSI_ERROR_UNREGONIZED_CMD: ++ case UCSI_ERROR_INVALID_CMD_ARGUMENT: ++ dev_err(dev, "possible UCSI driver bug %u\n", error); ++ return -EINVAL; ++ case UCSI_ERROR_OVERCURRENT: ++ dev_warn(dev, "Overcurrent condition\n"); ++ break; ++ case UCSI_ERROR_PARTNER_REJECTED_SWAP: ++ dev_warn(dev, "Partner rejected swap\n"); ++ break; ++ case UCSI_ERROR_HARD_RESET: ++ dev_warn(dev, "Hard reset occurred\n"); ++ break; ++ case UCSI_ERROR_PPM_POLICY_CONFLICT: ++ dev_warn(dev, "PPM Policy conflict\n"); ++ break; ++ case UCSI_ERROR_SWAP_REJECTED: ++ dev_warn(dev, "Swap rejected\n"); ++ break; ++ case UCSI_ERROR_UNDEFINED: ++ default: ++ dev_err(dev, "unknown error %u\n", error); ++ break; ++ } ++ ++ return -EIO; ++} ++ ++static int ucsi_exec_command(struct udevice *dev, u64 cmd) ++{ ++ u32 cci; ++ int ret; ++ ++ ret = ucsi_write(dev, UCSI_CONTROL, &cmd, sizeof(cmd)); ++ if (ret) ++ return ret; ++ ++ ret = ucsi_read(dev, UCSI_CCI, &cci, sizeof(cci)); ++ if (ret) ++ return ret; ++ ++ if (cci & UCSI_CCI_BUSY) ++ return -EBUSY; ++ ++ if (!(cci & UCSI_CCI_COMMAND_COMPLETE)) ++ return -EIO; ++ ++ if (cci & UCSI_CCI_NOT_SUPPORTED) ++ return -EOPNOTSUPP; ++ ++ if (cci & UCSI_CCI_ERROR) { ++ if (cmd == UCSI_GET_ERROR_STATUS) ++ return -EIO; ++ return ucsi_read_error(dev); ++ } ++ ++ return UCSI_CCI_LENGTH(cci); ++} ++ ++static int ucsi_send_command(struct udevice *dev, u64 command, ++ void *data, size_t size) ++{ ++ u8 length; ++ int ret; ++ ++ ret = ucsi_exec_command(dev, command); ++ if (ret < 0) ++ goto out; ++ ++ length = ret; ++ ++ if (data) { ++ ret = ucsi_read(dev, UCSI_MESSAGE_IN, data, size); ++ if (ret) ++ goto out; ++ } ++ ++ ret = ucsi_acknowledge_command(dev); ++ if (ret) ++ goto out; ++ ++ ret = length; ++out: ++ ++ return ret; ++} ++ ++static int ucsi_reset_ppm(struct udevice *dev) ++{ ++ u64 command = UCSI_PPM_RESET; ++ unsigned long tmo; ++ u32 cci; ++ int ret; ++ ++ ret = ucsi_write(dev, UCSI_CONTROL, &command, sizeof(command)); ++ if (ret < 0) ++ goto out; ++ ++ tmo = timer_get_us() + UCSI_TIMEOUT_US; ++ ++ do { ++ if (time_before(tmo, timer_get_us())) { ++ ret = -ETIMEDOUT; ++ goto out; ++ } ++ ++ ret = ucsi_read(dev, UCSI_CCI, &cci, sizeof(cci)); ++ if (ret) ++ goto out; ++ ++ /* If the PPM is still doing something else, reset it again. */ ++ if (cci & ~UCSI_CCI_RESET_COMPLETE) { ++ ret = ucsi_write(dev, UCSI_CONTROL, &command, ++ sizeof(command)); ++ if (ret < 0) ++ goto out; ++ } ++ ++ mdelay(20); ++ } while (!(cci & UCSI_CCI_RESET_COMPLETE)); ++ ++out: ++ return ret; ++} ++ ++static int ucsi_get_status(struct udevice *child, u8 con_idx, bool force) ++{ ++ struct udevice *parent = dev_get_parent(child); ++ struct ucsi_priv *priv = dev_get_priv(child); ++ struct ucsi_connector_status status; ++ u64 command; ++ u32 cci; ++ int ret = 0; ++ ++ if (con_idx > (priv->nb_connector - 1)) ++ return -EINVAL; ++ ++ ret = ucsi_read(parent, UCSI_CCI, &cci, sizeof(cci)); ++ if (ret) ++ return ret; ++ ++ /* is there any change ? */ ++ if (!UCSI_CCI_CONNECTOR(cci) && !force) ++ goto exit; ++ ++ command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con_idx + 1); ++ ret = ucsi_send_command(parent, command, &status, sizeof(status)); ++ if (ret < 0) ++ return ret; ++ ++ priv->con[con_idx].attached = status.flags & UCSI_CONSTAT_CONNECTED ? ++ TYPEC_ATTACHED : TYPEC_UNATTACHED; ++ ++ switch (UCSI_CONSTAT_PARTNER_TYPE(status.flags)) { ++ case UCSI_CONSTAT_PARTNER_TYPE_UFP: ++ case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP: ++ case UCSI_CONSTAT_PARTNER_TYPE_CABLE: ++ priv->con[con_idx].data_role = TYPEC_HOST; ++ break; ++ case UCSI_CONSTAT_PARTNER_TYPE_DFP: ++ priv->con[con_idx].data_role = TYPEC_DEVICE; ++ break; ++ } ++ ++ ret = ucsi_acknowledge_connector_change(parent); ++exit: ++ dev_dbg(child, "connector[%d] status: %s data role: %s\n", ++ con_idx, ++ priv->con[con_idx].attached == TYPEC_ATTACHED ? "Attached" : "Unattached", ++ priv->con[con_idx].data_role == TYPEC_HOST ? "Host" : "Device"); ++ ++ return ret; ++} ++ ++int ucsi_post_probe(struct udevice *dev) ++{ ++ struct connector *con; ++ struct ucsi_priv *priv; ++ struct udevice *child; ++ struct ucsi_capability cap; ++ u64 command; ++ int ret; ++ u8 i; ++ ++ /* Reset the PPM */ ++ ret = ucsi_reset_ppm(dev); ++ if (ret) { ++ dev_err(dev, "failed to reset PPM!\n"); ++ return ret; ++ } ++ ++ /* enable connector change notification */ ++ command = UCSI_SET_NOTIFICATION_ENABLE | UCSI_ENABLE_NTFY_CONNECTOR_CHANGE; ++ ret = ucsi_send_command(dev, command, NULL, 0); ++ if (ret < 0) ++ return ret; ++ ++ /* get current status : attached/unattached, device/host */ ++ ret = device_get_child(dev, 0, &child); ++ if (ret < 0) ++ return ret; ++ ++ /* Get PPM capabilities */ ++ command = UCSI_GET_CAPABILITY; ++ ret = ucsi_send_command(dev, command, &cap, sizeof(cap)); ++ if (ret < 0) ++ return ret; ++ ++ if (!cap.num_connectors) ++ return -ENODEV; ++ ++ priv = dev_get_priv(child); ++ priv->nb_connector = cap.num_connectors; ++ priv->con = kcalloc(priv->nb_connector, sizeof(*con), GFP_KERNEL); ++ if (!priv->con) ++ return -ENOMEM; ++ ++ for (i = 0; i < priv->nb_connector; i++) { ++ ret = ucsi_get_status(child, i, true); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++UCLASS_DRIVER(ucsi) = { ++ .id = UCLASS_UCSI, ++ .name = "ucsi", ++ .post_probe = ucsi_post_probe, ++}; ++ ++static int ucsi_is_attached(struct udevice *dev, u8 con_idx) ++{ ++ struct ucsi_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ ret = ucsi_get_status(dev, con_idx, false); ++ if (ret < 0) ++ return ret; ++ ++ return priv->con[con_idx].attached; ++} ++ ++static int ucsi_get_data_role(struct udevice *dev, u8 con_idx) ++{ ++ struct ucsi_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ ret = ucsi_get_status(dev, con_idx, false); ++ if (ret < 0) ++ return ret; ++ ++ return priv->con[con_idx].data_role; ++} ++ ++static u8 usci_get_nb_connector(struct udevice *dev) ++{ ++ struct ucsi_priv *priv = dev_get_priv(dev); ++ ++ return priv->nb_connector; ++} ++ ++static const struct typec_ops ucsi_typec_ops = { ++ .is_attached = ucsi_is_attached, ++ .get_data_role = ucsi_get_data_role, ++ .get_nb_connector = usci_get_nb_connector, ++}; ++ ++static const struct udevice_id typec_of_match[] = { ++ { .compatible = "usb-c-connector"}, ++ {} ++}; ++ ++U_BOOT_DRIVER(typec_ucsi) = { ++ .id = UCLASS_USB_TYPEC, ++ .name = "typec_ucsi", ++ .of_match = typec_of_match, ++ .ops = &ucsi_typec_ops, ++ .priv_auto = sizeof(struct ucsi_priv), ++}; +diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig +index 8b940d70eb..1dd7d232c4 100644 +--- a/drivers/video/Kconfig ++++ b/drivers/video/Kconfig +@@ -430,6 +430,15 @@ config VIDEO_LCD_RAYDIUM_RM68200 + Say Y here if you want to enable support for Raydium RM68200 + 720x1280 DSI video mode panel. + ++config VIDEO_LCD_ROCKTECH_HX8394 ++ bool "ROCKTECH HX8394 DSI LCD panel support" ++ depends on DM_VIDEO ++ select VIDEO_MIPI_DSI ++ default n ++ help ++ Say Y here if you want to enable support for Rocktech HX8394 ++ 720x1280 DSI video mode panel. ++ + config VIDEO_LCD_SSD2828 + bool "SSD2828 bridge chip" + default n +diff --git a/drivers/video/Makefile b/drivers/video/Makefile +index 7ae0ab2b35..d4f9323ace 100644 +--- a/drivers/video/Makefile ++++ b/drivers/video/Makefile +@@ -56,6 +56,7 @@ obj-$(CONFIG_VIDEO_LCD_ANX9804) += anx9804.o + obj-$(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM) += hitachi_tx18d42vm_lcd.o + obj-$(CONFIG_VIDEO_LCD_ORISETECH_OTM8009A) += orisetech_otm8009a.o + obj-$(CONFIG_VIDEO_LCD_RAYDIUM_RM68200) += raydium-rm68200.o ++obj-$(CONFIG_VIDEO_LCD_ROCKTECH_HX8394) += rocktech-hx8394.o + obj-$(CONFIG_VIDEO_LCD_SSD2828) += ssd2828.o + obj-$(CONFIG_VIDEO_LCD_TDO_TL070WSH30) += tdo-tl070wsh30.o + obj-$(CONFIG_VIDEO_MCDE_SIMPLE) += mcde_simple.o +diff --git a/drivers/video/dw_mipi_dsi.c b/drivers/video/dw_mipi_dsi.c +index 9ae09eec12..a5b38acabd 100644 +--- a/drivers/video/dw_mipi_dsi.c ++++ b/drivers/video/dw_mipi_dsi.c +@@ -17,7 +17,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/drivers/video/rocktech-hx8394.c b/drivers/video/rocktech-hx8394.c +new file mode 100644 +index 0000000000..9a2689600b +--- /dev/null ++++ b/drivers/video/rocktech-hx8394.c +@@ -0,0 +1,250 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2022 STMicroelectronics - All Rights Reserved ++ * Author: Yannick Fertre for STMicroelectronics. ++ * ++ * This hx8394 panel driver is inspired from the Linux Kernel driver ++ * drivers/gpu/drm/panel/panel-rocktech-hx8394.c. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MCS_SETPOWER 0xB1 ++#define MCS_SETDISP 0xB2 ++#define MCS_SETCYC 0xB4 ++#define MCS_SETVCOM 0xB6 ++#define MCS_SETEXTC 0xB9 ++#define MCS_SETMIPI 0xBA ++#define MCS_SET_BANK 0xBD ++#define MCS_NO_DOC1 0xBF ++#define MCS_NO_DOC2 0xC0 ++#define MCS_NO_DOC3 0xC6 ++#define MCS_NO_DOC4 0xD8 ++#define MCS_NO_DOC5 0xD4 ++#define MCS_SETPANEL 0xCC ++#define MCS_SETGIP_0 0xD3 ++#define MCS_SETGIP_1 0xD5 ++#define MCS_SETGIP_2 0xD6 ++ ++#define MCS_SETGAMMA 0xE0 ++#define MCS_READ_ID1 0xDA ++#define MCS_READ_ID2 0xDB ++#define MCS_READ_ID3 0xDC ++ ++#define MY BIT(7) /* Row Address Order */ ++#define MX BIT(6) /* Column Address Order */ ++#define MV BIT(5) /* Row/Column Exchange */ ++#define ML BIT(4) /* Vertical Refresh Order */ ++#define RGB BIT(3) /* RGB-BGR Order */ ++#define DDL BIT(2) /* Display Data Latch Order */ ++#define FH BIT(1) /* Flip Horizontal */ ++#define FV BIT(0) /* Flip Vertical */ ++ ++struct hx8394_panel_priv { ++ struct udevice *reg; ++ struct udevice *backlight; ++ struct gpio_desc reset; ++}; ++ ++static const struct display_timing default_timing = { ++ .pixelclock.typ = 54000000, ++ .hactive.typ = 720, ++ .hfront_porch.typ = 48, ++ .hback_porch.typ = 48, ++ .hsync_len.typ = 9, ++ .vactive.typ = 1280, ++ .vfront_porch.typ = 12, ++ .vback_porch.typ = 12, ++ .vsync_len.typ = 5, ++}; ++ ++static void hx8394_dcs_write_buf(struct udevice *dev, const void *data, ++ size_t len) ++{ ++ struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); ++ struct mipi_dsi_device *device = plat->device; ++ int err; ++ ++ err = mipi_dsi_dcs_write_buffer(device, data, len); ++ if (err < 0) ++ dev_err(dev, "MIPI DSI DCS write buffer failed: %d\n", err); ++} ++ ++#define dcs_write_seq(dev, seq...) \ ++({ \ ++ static const u8 d[] = { seq }; \ ++ \ ++ hx8394_dcs_write_buf(dev, d, ARRAY_SIZE(d)); \ ++}) ++ ++#define dcs_write_cmd_seq(dev, cmd, seq...) \ ++({ \ ++ static const u8 d[] = { seq }; \ ++ struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); \ ++ struct mipi_dsi_device *device = plat->device; \ ++ int err; \ ++ err = mipi_dsi_dcs_write(device, cmd, d, ARRAY_SIZE(d)); \ ++ if (err < 0) \ ++ dev_err(dev, "MIPI DSI DCS write failed: %d\n", err); \ ++}) ++ ++static void hx8394_init_sequence(struct udevice *dev) ++{ ++ dcs_write_cmd_seq(dev, MCS_SETEXTC, 0xFF, 0x83, 0x94); ++ dcs_write_cmd_seq(dev, MCS_SETMIPI, 0x61, 0x03, 0x68, 0x6B, 0xB2, 0xC0); ++ dcs_write_seq(dev, MCS_SETPOWER, 0x48, 0x12, 0x72, 0x09, 0x32, 0x54, 0x71, 0x71, 0x57, ++ 0x47); ++ dcs_write_cmd_seq(dev, MCS_SETDISP, 0x00, 0x80, 0x64, 0x0C, 0x0D, 0x2F); ++ dcs_write_seq(dev, MCS_SETCYC, 0x73, 0x74, 0x73, 0x74, 0x73, 0x74, 0x01, 0x0C, 0x86, 0x75, ++ 0x00, 0x3F, 0x73, 0x74, 0x73, 0x74, 0x73, 0x74, 0x01, 0x0C, 0x86); ++ dcs_write_seq(dev, MCS_SETGIP_0, 0x00, 0x00, 0x07, 0x07, 0x40, 0x07, 0x0C, 0x00, 0x08, 0x10, ++ 0x08, 0x00, 0x08, 0x54, 0x15, 0x0A, 0x05, 0x0A, 0x02, 0x15, 0x06, 0x05, 0x06, ++ 0x47, 0x44, 0x0A, 0x0A, 0x4B, 0x10, 0x07, 0x07, 0x0C, 0x40); ++ dcs_write_seq(dev, MCS_SETGIP_1, 0x1C, 0x1C, 0x1D, 0x1D, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, ++ 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x24, 0x25, 0x18, 0x18, 0x26, 0x27, 0x18, ++ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, ++ 0x18, 0x18, 0x20, 0x21, 0x18, 0x18, 0x18, 0x18); ++ dcs_write_seq(dev, MCS_SETGIP_2, 0x1C, 0x1C, 0x1D, 0x1D, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, ++ 0x01, 0x00, 0x0B, 0x0A, 0x09, 0x08, 0x21, 0x20, 0x18, 0x18, 0x27, 0x26, 0x18, ++ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, ++ 0x18, 0x18, 0x25, 0x24, 0x18, 0x18, 0x18, 0x18); ++ dcs_write_cmd_seq(dev, MCS_SETVCOM, 0x92, 0x92); ++ dcs_write_seq(dev, MCS_SETGAMMA, 0x00, 0x0A, 0x15, 0x1B, 0x1E, 0x21, 0x24, 0x22, 0x47, 0x56, ++ 0x65, 0x66, 0x6E, 0x82, 0x88, 0x8B, 0x9A, 0x9D, 0x98, 0xA8, 0xB9, 0x5D, 0x5C, ++ 0x61, 0x66, 0x6A, 0x6F, 0x7F, 0x7F, 0x00, 0x0A, 0x15, 0x1B, 0x1E, 0x21, 0x24, ++ 0x22, 0x47, 0x56, 0x65, 0x65, 0x6E, 0x81, 0x87, 0x8B, 0x98, 0x9D, 0x99, 0xA8, ++ 0xBA, 0x5D, 0x5D, 0x62, 0x67, 0x6B, 0x72, 0x7F, 0x7F); ++ dcs_write_cmd_seq(dev, MCS_NO_DOC2, 0x1F, 0x31); ++ dcs_write_cmd_seq(dev, MCS_SETPANEL, 0x03); ++ dcs_write_cmd_seq(dev, MCS_NO_DOC5, 0x02); ++ dcs_write_cmd_seq(dev, MCS_SET_BANK, 0x02); ++ dcs_write_seq(dev, MCS_NO_DOC4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0xFF, 0xFF); ++ dcs_write_cmd_seq(dev, MCS_SET_BANK, 0x00); ++ dcs_write_cmd_seq(dev, MCS_SET_BANK, 0x01); ++ dcs_write_cmd_seq(dev, MCS_SETPOWER, 0x00); ++ dcs_write_cmd_seq(dev, MCS_SET_BANK, 0x00); ++ dcs_write_cmd_seq(dev, MCS_NO_DOC1, 0x40, 0x81, 0x50, 0x00, 0x1A, 0xFC, 0x01); ++ dcs_write_cmd_seq(dev, MCS_NO_DOC3, 0xED); ++ dcs_write_cmd_seq(dev, MIPI_DCS_SET_ADDRESS_MODE, FH); ++} ++ ++static int hx8394_panel_enable_backlight(struct udevice *dev) ++{ ++ struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); ++ struct mipi_dsi_device *device = plat->device; ++ struct hx8394_panel_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ ret = mipi_dsi_attach(device); ++ if (ret < 0) ++ return ret; ++ ++ hx8394_init_sequence(dev); ++ ++ ret = mipi_dsi_dcs_exit_sleep_mode(device); ++ if (ret) ++ return ret; ++ ++ mdelay(120); ++ ++ ret = mipi_dsi_dcs_set_display_on(device); ++ if (ret) ++ return ret; ++ ++ mdelay(50); ++ ++ ret = backlight_enable(priv->backlight); ++ ++ return ret; ++} ++ ++static int hx8394_panel_get_display_timing(struct udevice *dev, ++ struct display_timing *timings) ++{ ++ memcpy(timings, &default_timing, sizeof(*timings)); ++ ++ return 0; ++} ++ ++static int hx8394_panel_of_to_plat(struct udevice *dev) ++{ ++ struct hx8394_panel_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ ret = device_get_supply_regulator(dev, "power-supply", ++ &priv->reg); ++ if (ret) { ++ dev_err(dev, "Warning: cannot get power supply\n"); ++ return ret; ++ } ++ ++ ret = gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset, ++ GPIOD_IS_OUT); ++ if (ret) { ++ dev_err(dev, "Warning: cannot get reset GPIO\n"); ++ if (ret != -ENOENT) ++ return ret; ++ } ++ ++ ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev, ++ "backlight", &priv->backlight); ++ if (ret) ++ dev_err(dev, "Cannot get backlight: ret=%d\n", ret); ++ ++ return ret; ++} ++ ++static int hx8394_panel_probe(struct udevice *dev) ++{ ++ struct hx8394_panel_priv *priv = dev_get_priv(dev); ++ struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); ++ int ret; ++ ++ ret = regulator_set_enable(priv->reg, true); ++ if (ret) ++ return ret; ++ ++ /* reset panel */ ++ dm_gpio_set_value(&priv->reset, true); ++ mdelay(1); ++ dm_gpio_set_value(&priv->reset, false); ++ mdelay(50); ++ ++ /* fill characteristics of DSI data link */ ++ plat->lanes = 2; ++ plat->format = MIPI_DSI_FMT_RGB888; ++ plat->mode_flags = MIPI_DSI_MODE_VIDEO | ++ MIPI_DSI_MODE_VIDEO_BURST | ++ MIPI_DSI_MODE_LPM; ++ ++ return 0; ++} ++ ++static const struct panel_ops hx8394_panel_ops = { ++ .enable_backlight = hx8394_panel_enable_backlight, ++ .get_display_timing = hx8394_panel_get_display_timing, ++}; ++ ++static const struct udevice_id hx8394_panel_ids[] = { ++ { .compatible = "rocktech,hx8394" }, ++ { } ++}; ++ ++U_BOOT_DRIVER(hx8394_panel) = { ++ .name = "hx8394_panel", ++ .id = UCLASS_PANEL, ++ .of_match = hx8394_panel_ids, ++ .ops = &hx8394_panel_ops, ++ .of_to_plat = hx8394_panel_of_to_plat, ++ .probe = hx8394_panel_probe, ++ .plat_auto = sizeof(struct mipi_dsi_panel_plat), ++ .priv_auto = sizeof(struct hx8394_panel_priv), ++}; +diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c +index 4027e978c8..134abd93e1 100644 +--- a/drivers/video/stm32/stm32_dsi.c ++++ b/drivers/video/stm32/stm32_dsi.c +@@ -21,7 +21,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/drivers/video/stm32/stm32_ltdc.c b/drivers/video/stm32/stm32_ltdc.c +index f55a39498e..58b6434a48 100644 +--- a/drivers/video/stm32/stm32_ltdc.c ++++ b/drivers/video/stm32/stm32_ltdc.c +@@ -17,7 +17,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -26,8 +25,114 @@ struct stm32_ltdc_priv { + void __iomem *regs; + enum video_log2_bpp l2bpp; + u32 bg_col_argb; ++ const u32 *layer_regs; ++ const u32 *pix_fmt_hw; + u32 crop_x, crop_y, crop_w, crop_h; + u32 alpha; ++ u32 hw_version; ++}; ++ ++/* Layer register offsets */ ++static const u32 layer_regs_a0[] = { ++ 0x80, /* L1 configuration 0 */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x84, /* L1 control register */ ++ 0x88, /* L1 window horizontal position configuration */ ++ 0x8c, /* L1 window vertical position configuration */ ++ 0x90, /* L1 color keying configuration */ ++ 0x94, /* L1 pixel format configuration */ ++ 0x98, /* L1 constant alpha configuration */ ++ 0x9c, /* L1 default color configuration */ ++ 0xa0, /* L1 blending factors configuration */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0xac, /* L1 color frame buffer address */ ++ 0xb0, /* L1 color frame buffer length */ ++ 0xb4, /* L1 color frame buffer line number */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0xc4, /* L1 CLUT write */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00 /* not available */ ++}; ++ ++static const u32 layer_regs_a1[] = { ++ 0x80, /* L1 configuration 0 */ ++ 0x84, /* L1 configuration 1 */ ++ 0x00, /* L1 reload control */ ++ 0x88, /* L1 control register */ ++ 0x8c, /* L1 window horizontal position configuration */ ++ 0x90, /* L1 window vertical position configuration */ ++ 0x94, /* L1 color keying configuration */ ++ 0x98, /* L1 pixel format configuration */ ++ 0x9c, /* L1 constant alpha configuration */ ++ 0xa0, /* L1 default color configuration */ ++ 0xa4, /* L1 blending factors configuration */ ++ 0xa8, /* L1 burst length configuration */ ++ 0x00, /* not available */ ++ 0xac, /* L1 color frame buffer address */ ++ 0xb0, /* L1 color frame buffer length */ ++ 0xb4, /* L1 color frame buffer line number */ ++ 0xb8, /* L1 auxiliary frame buffer address 0 */ ++ 0xbc, /* L1 auxiliary frame buffer address 1 */ ++ 0xc0, /* L1 auxiliary frame buffer length */ ++ 0xc4, /* L1 auxiliary frame buffer line number */ ++ 0xc8, /* L1 CLUT write */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00, /* not available */ ++ 0x00 /* not available */ ++}; ++ ++static const u32 layer_regs_a2[] = { ++ 0x100, /* L1 configuration 0 */ ++ 0x104, /* L1 configuration 1 */ ++ 0x108, /* L1 reload control */ ++ 0x10c, /* L1 control register */ ++ 0x110, /* L1 window horizontal position configuration */ ++ 0x114, /* L1 window vertical position configuration */ ++ 0x118, /* L1 color keying configuration */ ++ 0x11c, /* L1 pixel format configuration */ ++ 0x120, /* L1 constant alpha configuration */ ++ 0x124, /* L1 default color configuration */ ++ 0x128, /* L1 blending factors configuration */ ++ 0x12c, /* L1 burst length configuration */ ++ 0x130, /* L1 planar configuration */ ++ 0x134, /* L1 color frame buffer address */ ++ 0x138, /* L1 color frame buffer length */ ++ 0x13c, /* L1 color frame buffer line number */ ++ 0x140, /* L1 auxiliary frame buffer address 0 */ ++ 0x144, /* L1 auxiliary frame buffer address 1 */ ++ 0x148, /* L1 auxiliary frame buffer length */ ++ 0x14c, /* L1 auxiliary frame buffer line number */ ++ 0x150, /* L1 CLUT write */ ++ 0x154, /* not available */ ++ 0x158, /* not available */ ++ 0x15c, /* not available */ ++ 0x160, /* not available */ ++ 0x164, /* not available */ ++ 0x168, /* not available */ ++ 0x16c, /* L1 Conversion YCbCr RGB 0 */ ++ 0x170, /* L1 Conversion YCbCr RGB 1 */ ++ 0x174, /* L1 Flexible Pixel Format 0 */ ++ 0x178 /* L1 Flexible Pixel Format 1 */ + }; + + /* LTDC main registers */ +@@ -50,26 +155,32 @@ struct stm32_ltdc_priv { + #define LTDC_CPSR 0x44 /* Current Position Status */ + #define LTDC_CDSR 0x48 /* Current Display Status */ + +-/* LTDC layer 1 registers */ +-#define LTDC_L1LC1R 0x80 /* L1 Layer Configuration 1 */ +-#define LTDC_L1LC2R 0x84 /* L1 Layer Configuration 2 */ +-#define LTDC_L1CR 0x84 /* L1 Control */ +-#define LTDC_L1WHPCR 0x88 /* L1 Window Hor Position Config */ +-#define LTDC_L1WVPCR 0x8C /* L1 Window Vert Position Config */ +-#define LTDC_L1CKCR 0x90 /* L1 Color Keying Configuration */ +-#define LTDC_L1PFCR 0x94 /* L1 Pixel Format Configuration */ +-#define LTDC_L1CACR 0x98 /* L1 Constant Alpha Config */ +-#define LTDC_L1DCCR 0x9C /* L1 Default Color Configuration */ +-#define LTDC_L1BFCR 0xA0 /* L1 Blend Factors Configuration */ +-#define LTDC_L1FBBCR 0xA4 /* L1 FrameBuffer Bus Control */ +-#define LTDC_L1AFBCR 0xA8 /* L1 AuxFB Control */ +-#define LTDC_L1CFBAR 0xAC /* L1 Color FrameBuffer Address */ +-#define LTDC_L1CFBLR 0xB0 /* L1 Color FrameBuffer Length */ +-#define LTDC_L1CFBLNR 0xB4 /* L1 Color FrameBuffer Line Nb */ +-#define LTDC_L1AFBAR 0xB8 /* L1 AuxFB Address */ +-#define LTDC_L1AFBLR 0xBC /* L1 AuxFB Length */ +-#define LTDC_L1AFBLNR 0xC0 /* L1 AuxFB Line Number */ +-#define LTDC_L1CLUTWR 0xC4 /* L1 CLUT Write */ ++/* Layer register offsets */ ++#define LTDC_L1C0R (priv->layer_regs[0]) /* L1 configuration 0 */ ++#define LTDC_L1C1R (priv->layer_regs[1]) /* L1 configuration 1 */ ++#define LTDC_L1RCR (priv->layer_regs[2]) /* L1 reload control */ ++#define LTDC_L1CR (priv->layer_regs[3]) /* L1 control register */ ++#define LTDC_L1WHPCR (priv->layer_regs[4]) /* L1 window horizontal position configuration */ ++#define LTDC_L1WVPCR (priv->layer_regs[5]) /* L1 window vertical position configuration */ ++#define LTDC_L1CKCR (priv->layer_regs[6]) /* L1 color keying configuration */ ++#define LTDC_L1PFCR (priv->layer_regs[7]) /* L1 pixel format configuration */ ++#define LTDC_L1CACR (priv->layer_regs[8]) /* L1 constant alpha configuration */ ++#define LTDC_L1DCCR (priv->layer_regs[9]) /* L1 default color configuration */ ++#define LTDC_L1BFCR (priv->layer_regs[10]) /* L1 blending factors configuration */ ++#define LTDC_L1BLCR (priv->layer_regs[11]) /* L1 burst length configuration */ ++#define LTDC_L1PCR (priv->layer_regs[12]) /* L1 planar configuration */ ++#define LTDC_L1CFBAR (priv->layer_regs[13]) /* L1 color frame buffer address */ ++#define LTDC_L1CFBLR (priv->layer_regs[14]) /* L1 color frame buffer length */ ++#define LTDC_L1CFBLNR (priv->layer_regs[15]) /* L1 color frame buffer line number */ ++#define LTDC_L1AFBA0R (priv->layer_regs[16]) /* L1 auxiliary frame buffer address 0 */ ++#define LTDC_L1AFBA1R (priv->layer_regs[17]) /* L1 auxiliary frame buffer address 1 */ ++#define LTDC_L1AFBLR (priv->layer_regs[18]) /* L1 auxiliary frame buffer length */ ++#define LTDC_L1AFBLNR (priv->layer_regs[19]) /* L1 auxiliary frame buffer line number */ ++#define LTDC_L1CLUTWR (priv->layer_regs[20]) /* L1 CLUT write */ ++#define LTDC_L1CYR0R (priv->layer_regs[27]) /* L1 Conversion YCbCr RGB 0 */ ++#define LTDC_L1CYR1R (priv->layer_regs[28]) /* L1 Conversion YCbCr RGB 1 */ ++#define LTDC_L1FPF0R (priv->layer_regs[29]) /* L1 Flexible Pixel Format 0 */ ++#define LTDC_L1FPF1R (priv->layer_regs[30]) /* L1 Flexible Pixel Format 1 */ + + /* Bit definitions */ + #define SSCR_VSH GENMASK(10, 0) /* Vertical Synchronization Height */ +@@ -145,15 +256,60 @@ struct stm32_ltdc_priv { + #define BF2_1PAXCA 0x007 /* 1 - (Pixel Alpha x Constant Alpha) */ + #define BF2_1CA 0x005 /* 1 - Constant Alpha */ + ++#define NB_PF 8 /* Max nb of HW pixel format */ ++ ++#define HWVER_10200 0x010200 ++#define HWVER_10300 0x010300 ++#define HWVER_20101 0x020101 ++#define HWVER_40100 0x040100 ++ + enum stm32_ltdc_pix_fmt { +- PF_ARGB8888 = 0, +- PF_RGB888, +- PF_RGB565, +- PF_ARGB1555, +- PF_ARGB4444, +- PF_L8, +- PF_AL44, +- PF_AL88 ++ PF_ARGB8888 = 0, /* ARGB [32 bits] */ ++ PF_ABGR8888, /* ABGR [32 bits] */ ++ PF_BGRA8888, /* BGRA [32 bits] */ ++ PF_RGBA8888, /* RGBA [32 bits] */ ++ PF_RGB888, /* RGB [24 bits] */ ++ PF_BGR565, /* RGB [16 bits] */ ++ PF_RGB565, /* RGB [16 bits] */ ++ PF_ARGB1555, /* ARGB A:1 bit RGB:15 bits [16 bits] */ ++ PF_ARGB4444, /* ARGB A:4 bits R/G/B: 4 bits each [16 bits] */ ++ PF_AL44, /* Alpha:4 bits + indexed 4 bits [8 bits] */ ++ PF_AL88, /* Alpha:8 bits + indexed 8 bits [16 bits] */ ++ PF_L8, /* Indexed 8 bits [8 bits] */ ++ PF_NONE ++}; ++ ++static const enum stm32_ltdc_pix_fmt pix_fmt_a0[NB_PF] = { ++ PF_ARGB8888, /* 0x00 */ ++ PF_RGB888, /* 0x01 */ ++ PF_RGB565, /* 0x02 */ ++ PF_ARGB1555, /* 0x03 */ ++ PF_ARGB4444, /* 0x04 */ ++ PF_L8, /* 0x05 */ ++ PF_AL44, /* 0x06 */ ++ PF_AL88 /* 0x07 */ ++}; ++ ++static const enum stm32_ltdc_pix_fmt pix_fmt_a1[NB_PF] = { ++ PF_ARGB8888, /* 0x00 */ ++ PF_RGB888, /* 0x01 */ ++ PF_RGB565, /* 0x02 */ ++ PF_RGBA8888, /* 0x03 */ ++ PF_AL44, /* 0x04 */ ++ PF_L8, /* 0x05 */ ++ PF_ARGB1555, /* 0x06 */ ++ PF_ARGB4444 /* 0x07 */ ++}; ++ ++static const enum stm32_ltdc_pix_fmt pix_fmt_a2[NB_PF] = { ++ PF_ARGB8888, /* 0x00 */ ++ PF_ABGR8888, /* 0x01 */ ++ PF_RGBA8888, /* 0x02 */ ++ PF_BGRA8888, /* 0x03 */ ++ PF_RGB565, /* 0x04 */ ++ PF_BGR565, /* 0x05 */ ++ PF_RGB888, /* 0x06 */ ++ PF_NONE /* 0x07 (flexible pixel format) */ + }; + + /* TODO add more color format support */ +@@ -256,7 +412,7 @@ static void stm32_ltdc_set_mode(struct stm32_ltdc_priv *priv, + val |= GCR_HSPOL; + if (timings->flags & DISPLAY_FLAGS_VSYNC_HIGH) + val |= GCR_VSPOL; +- if (timings->flags & DISPLAY_FLAGS_DE_HIGH) ++ if (timings->flags & DISPLAY_FLAGS_DE_LOW) + val |= GCR_DEPOL; + if (timings->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) + val |= GCR_PCPOL; +@@ -307,7 +463,16 @@ static void stm32_ltdc_set_layer1(struct stm32_ltdc_priv *priv, ulong fb_addr) + + /* Pixel format */ + format = stm32_ltdc_get_pixel_format(priv->l2bpp); +- clrsetbits_le32(regs + LTDC_L1PFCR, LXPFCR_PF, format); ++ for (val = 0; val < NB_PF; val++) ++ if (priv->pix_fmt_hw[val] == format) ++ break; ++ ++ if (val >= NB_PF) { ++ log_err("invalid pixel format\n"); ++ return; ++ } ++ ++ clrsetbits_le32(regs + LTDC_L1PFCR, LXPFCR_PF, val); + + /* Constant alpha value */ + clrsetbits_le32(regs + LTDC_L1CACR, LXCACR_CONSTA, priv->alpha); +@@ -339,6 +504,7 @@ static int stm32_ltdc_probe(struct udevice *dev) + struct display_timing timings; + struct clk pclk; + struct reset_ctl rst; ++ ulong rate; + int ret; + + priv->regs = (void *)dev_read_addr(dev); +@@ -359,6 +525,27 @@ static int stm32_ltdc_probe(struct udevice *dev) + return ret; + } + ++ priv->hw_version = readl(priv->regs + LTDC_IDR); ++ debug("%s: LTDC hardware 0x%x\n", __func__, priv->hw_version); ++ ++ switch (priv->hw_version) { ++ case HWVER_10200: ++ case HWVER_10300: ++ priv->layer_regs = layer_regs_a0; ++ priv->pix_fmt_hw = pix_fmt_a0; ++ break; ++ case HWVER_20101: ++ priv->layer_regs = layer_regs_a1; ++ priv->pix_fmt_hw = pix_fmt_a1; ++ break; ++ case HWVER_40100: ++ priv->layer_regs = layer_regs_a2; ++ priv->pix_fmt_hw = pix_fmt_a2; ++ break; ++ default: ++ return -ENODEV; ++ } ++ + ret = uclass_first_device_err(UCLASS_PANEL, &panel); + if (ret) { + if (ret != -ENODEV) +@@ -376,13 +563,13 @@ static int stm32_ltdc_probe(struct udevice *dev) + } + } + +- ret = clk_set_rate(&pclk, timings.pixelclock.typ); +- if (ret) +- dev_warn(dev, "fail to set pixel clock %d hz\n", +- timings.pixelclock.typ); ++ rate = clk_set_rate(&pclk, timings.pixelclock.typ); ++ if (IS_ERR_VALUE(rate)) ++ dev_warn(dev, "fail to set pixel clock %d hz, ret=%ld\n", ++ timings.pixelclock.typ, rate); + + dev_dbg(dev, "Set pixel clock req %d hz get %ld hz\n", +- timings.pixelclock.typ, clk_get_rate(&pclk)); ++ timings.pixelclock.typ, rate); + + ret = reset_get_by_index(dev, 0, &rst); + if (ret) { +@@ -460,7 +647,10 @@ static int stm32_ltdc_bind(struct udevice *dev) + uc_plat->size = CONFIG_VIDEO_STM32_MAX_XRES * + CONFIG_VIDEO_STM32_MAX_YRES * + (CONFIG_VIDEO_STM32_MAX_BPP >> 3); +- dev_dbg(dev, "frame buffer max size %d bytes\n", uc_plat->size); ++ /* align framebuffer on kernel MMU_SECTION_SIZE = max 2MB for LPAE */ ++ uc_plat->align = SZ_2M; ++ dev_dbg(dev, "frame buffer max size %d bytes align %x\n", ++ uc_plat->size, uc_plat->align); + + return 0; + } +diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c +index 9f8cf6ef2a..43ebb3c565 100644 +--- a/drivers/video/video-uclass.c ++++ b/drivers/video/video-uclass.c +@@ -228,6 +228,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/env/mmc.c b/env/mmc.c +index 09e94f0bd3..090382d4a3 100644 +--- a/env/mmc.c ++++ b/env/mmc.c +@@ -238,12 +238,15 @@ static inline int erase_env(struct mmc *mmc, unsigned long size, + { + uint blk_start, blk_cnt, n; + struct blk_desc *desc = mmc_get_blk_desc(mmc); ++ u32 erase_size; + +- blk_start = ALIGN(offset, mmc->write_bl_len) / mmc->write_bl_len; +- blk_cnt = ALIGN(size, mmc->write_bl_len) / mmc->write_bl_len; ++ erase_size = mmc->erase_grp_size * desc->blksz; ++ blk_start = ALIGN_DOWN(offset, erase_size) / desc->blksz; ++ blk_cnt = ALIGN(size, erase_size) / desc->blksz; + + n = blk_derase(desc, blk_start, blk_cnt); +- printf("%d blocks erased: %s\n", n, (n == blk_cnt) ? "OK" : "ERROR"); ++ printf("%d blocks erased at 0x%x: %s\n", n, blk_start, ++ (n == blk_cnt) ? "OK" : "ERROR"); + + return (n == blk_cnt) ? 0 : 1; + } +@@ -265,6 +268,7 @@ static int env_mmc_erase(void) + if (mmc_get_env_addr(mmc, copy, &offset)) + return CMD_RET_FAILURE; + ++ printf("\n"); + ret = erase_env(mmc, CONFIG_ENV_SIZE, offset); + + #ifdef CONFIG_ENV_OFFSET_REDUND +diff --git a/env/onenand.c b/env/onenand.c +index c8da3ff811..1faa2cb62a 100644 +--- a/env/onenand.c ++++ b/env/onenand.c +@@ -73,9 +73,7 @@ static int env_onenand_save(void) + #endif + loff_t env_addr = CONFIG_ENV_ADDR; + size_t retlen; +- struct erase_info instr = { +- .callback = NULL, +- }; ++ struct erase_info instr = {}; + + ret = env_export(&env_new); + if (ret) +diff --git a/fs/yaffs2/yaffs_mtdif.c b/fs/yaffs2/yaffs_mtdif.c +index d338f9aa91..50fed2d4b1 100644 +--- a/fs/yaffs2/yaffs_mtdif.c ++++ b/fs/yaffs2/yaffs_mtdif.c +@@ -145,7 +145,6 @@ int nandmtd_EraseBlockInNAND(struct yaffs_dev *dev, int blockNumber) + ei.len = dev->data_bytes_per_chunk * dev->param.chunks_per_block; + ei.time = 1000; + ei.retries = 2; +- ei.callback = NULL; + ei.priv = (u_long) dev; + + /* Todo finish off the ei if required */ +diff --git a/include/configs/dh_imx6.h b/include/configs/dh_imx6.h +index d9be1c38c4..0198126de5 100644 +--- a/include/configs/dh_imx6.h ++++ b/include/configs/dh_imx6.h +@@ -58,8 +58,6 @@ + /* USB Configs */ + #ifdef CONFIG_CMD_USB + #define CONFIG_EHCI_HCD_INIT_AFTER_RESET +-#define CONFIG_USB_HOST_ETHER +-#define CONFIG_USB_ETHER_ASIX + #define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW) + #define CONFIG_MXC_USB_FLAGS 0 + #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 /* Enabled USB controller number */ +diff --git a/include/configs/dh_stm32mp1.h b/include/configs/dh_stm32mp1.h +deleted file mode 100644 +index 89d317ba2b..0000000000 +--- a/include/configs/dh_stm32mp1.h ++++ /dev/null +@@ -1,15 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +-/* +- * Copyright (C) 2020 Marek Vasut +- * +- * Configuration settings for the DH STM32MP15x SoMs +- */ +- +-#ifndef __CONFIG_DH_STM32MP1_H__ +-#define __CONFIG_DH_STM32MP1_H__ +- +-#include +- +-#define CONFIG_SPL_TARGET "u-boot.itb" +- +-#endif +diff --git a/include/configs/kp_imx6q_tpc.h b/include/configs/kp_imx6q_tpc.h +index 749e880f36..7216939265 100644 +--- a/include/configs/kp_imx6q_tpc.h ++++ b/include/configs/kp_imx6q_tpc.h +@@ -30,8 +30,6 @@ + /* USB Configs */ + #ifdef CONFIG_CMD_USB + #define CONFIG_EHCI_HCD_INIT_AFTER_RESET +-#define CONFIG_USB_HOST_ETHER +-#define CONFIG_USB_ETHER_ASIX + #define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW) + #define CONFIG_MXC_USB_FLAGS 0 + #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 /* Enabled USB controller number */ +diff --git a/include/configs/mx53ppd.h b/include/configs/mx53ppd.h +index b1e6a5638b..c9fecc3f9b 100644 +--- a/include/configs/mx53ppd.h ++++ b/include/configs/mx53ppd.h +@@ -23,10 +23,6 @@ + #define CONFIG_REVISION_TAG + + /* USB Configs */ +-#define CONFIG_USB_HOST_ETHER +-#define CONFIG_USB_ETHER_ASIX +-#define CONFIG_USB_ETHER_MCS7830 +-#define CONFIG_USB_ETHER_SMSC95XX + #define CONFIG_MXC_USB_PORT 1 + #define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW) + #define CONFIG_MXC_USB_FLAGS 0 +diff --git a/include/configs/pm9263.h b/include/configs/pm9263.h +index e825270de8..8d11759aa0 100644 +--- a/include/configs/pm9263.h ++++ b/include/configs/pm9263.h +@@ -145,7 +145,6 @@ + #define CONFIG_INITRD_TAG 1 + + #undef CONFIG_SKIP_LOWLEVEL_INIT +-#define CONFIG_USER_LOWLEVEL_INIT 1 + + /* + * Hardware drivers +diff --git a/include/configs/rpi.h b/include/configs/rpi.h +index 522b41c02d..709af64c4b 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 + + /* DFU over USB/UDC */ +diff --git a/include/configs/stih410-b2260.h b/include/configs/stih410-b2260.h +index 33b34ee0cd..f35d26aa2e 100644 +--- a/include/configs/stih410-b2260.h ++++ b/include/configs/stih410-b2260.h +@@ -65,11 +65,6 @@ + #define CONFIG_USB_OHCI_NEW + #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2 + +-#define CONFIG_USB_HOST_ETHER +-#define CONFIG_USB_ETHER_ASIX +-#define CONFIG_USB_ETHER_MCS7830 +-#define CONFIG_USB_ETHER_SMSC95XX +- + /* NET Configs */ + + #endif /* __CONFIG_H */ +diff --git a/include/configs/stm32f429-discovery.h b/include/configs/stm32f429-discovery.h +index 9d029fbcc6..d0ef18779f 100644 +--- a/include/configs/stm32f429-discovery.h ++++ b/include/configs/stm32f429-discovery.h +@@ -23,22 +23,12 @@ + #define CONFIG_RED_LED 110 + #define CONFIG_GREEN_LED 109 + +-#define CONFIG_STM32_FLASH +- + #define CONFIG_SYS_HZ_CLOCK 1000000 /* Timer is clocked at 1MHz */ + +-#define CONFIG_CMDLINE_TAG +-#define CONFIG_SETUP_MEMORY_TAGS +-#define CONFIG_INITRD_TAG +-#define CONFIG_REVISION_TAG +- + #define CONFIG_SYS_CBSIZE 1024 + + #define CONFIG_SYS_MALLOC_LEN (2 << 20) + +-#define CONFIG_BOOTCOMMAND \ +- "run bootcmd_romfs" +- + #define CONFIG_EXTRA_ENV_SETTINGS \ + "bootargs_romfs=uclinux.physaddr=0x08180000 root=/dev/mtdblock0\0" \ + "bootcmd_romfs=setenv bootargs ${bootargs} ${bootargs_romfs};" \ +diff --git a/include/configs/stm32f429-evaluation.h b/include/configs/stm32f429-evaluation.h +index fefdb2dd15..3b6223d737 100644 +--- a/include/configs/stm32f429-evaluation.h ++++ b/include/configs/stm32f429-evaluation.h +@@ -25,15 +25,8 @@ + #define CONFIG_SYS_MAX_FLASH_SECT 12 + #define CONFIG_SYS_MAX_FLASH_BANKS 2 + +-#define CONFIG_STM32_FLASH +- + #define CONFIG_SYS_HZ_CLOCK 1000000 /* Timer is clocked at 1MHz */ + +-#define CONFIG_CMDLINE_TAG +-#define CONFIG_SETUP_MEMORY_TAGS +-#define CONFIG_INITRD_TAG +-#define CONFIG_REVISION_TAG +- + #define CONFIG_SYS_CBSIZE 1024 + + #define CONFIG_SYS_MALLOC_LEN (1 * 1024 * 1024) +diff --git a/include/configs/stm32f469-discovery.h b/include/configs/stm32f469-discovery.h +index ba9f05a61b..6a0fa02451 100644 +--- a/include/configs/stm32f469-discovery.h ++++ b/include/configs/stm32f469-discovery.h +@@ -25,15 +25,8 @@ + #define CONFIG_SYS_MAX_FLASH_SECT 12 + #define CONFIG_SYS_MAX_FLASH_BANKS 2 + +-#define CONFIG_STM32_FLASH +- + #define CONFIG_SYS_HZ_CLOCK 1000000 /* Timer is clocked at 1MHz */ + +-#define CONFIG_CMDLINE_TAG +-#define CONFIG_SETUP_MEMORY_TAGS +-#define CONFIG_INITRD_TAG +-#define CONFIG_REVISION_TAG +- + #define CONFIG_SYS_CBSIZE 1024 + + #define CONFIG_SYS_MALLOC_LEN (1 * 1024 * 1024) +diff --git a/include/configs/stm32f746-disco.h b/include/configs/stm32f746-disco.h +index 08d050adfa..247191a475 100644 +--- a/include/configs/stm32f746-disco.h ++++ b/include/configs/stm32f746-disco.h +@@ -29,18 +29,11 @@ + #define CONFIG_SYS_MAX_FLASH_SECT 8 + #define CONFIG_SYS_MAX_FLASH_BANKS 1 + +-#define CONFIG_STM32_FLASH +- + #define CONFIG_DW_GMAC_DEFAULT_DMA_PBL (8) + #define CONFIG_DW_ALTDESCRIPTOR + + #define CONFIG_SYS_HZ_CLOCK 1000000 /* Timer is clocked at 1MHz */ + +-#define CONFIG_CMDLINE_TAG +-#define CONFIG_SETUP_MEMORY_TAGS +-#define CONFIG_INITRD_TAG +-#define CONFIG_REVISION_TAG +- + #define CONFIG_SYS_CBSIZE 1024 + + #define CONFIG_SYS_MALLOC_LEN (1 * 1024 * 1024) +diff --git a/include/configs/stm32h743-disco.h b/include/configs/stm32h743-disco.h +index 6e10dbdfe9..e5bb08eec7 100644 +--- a/include/configs/stm32h743-disco.h ++++ b/include/configs/stm32h743-disco.h +@@ -24,11 +24,6 @@ + + #define CONFIG_SYS_HZ_CLOCK 1000000 + +-#define CONFIG_CMDLINE_TAG +-#define CONFIG_SETUP_MEMORY_TAGS +-#define CONFIG_INITRD_TAG +-#define CONFIG_REVISION_TAG +- + #define CONFIG_SYS_MAXARGS 16 + #define CONFIG_SYS_MALLOC_LEN (1 * 1024 * 1024) + +diff --git a/include/configs/stm32h743-eval.h b/include/configs/stm32h743-eval.h +index 268d39c7ad..89169f85d5 100644 +--- a/include/configs/stm32h743-eval.h ++++ b/include/configs/stm32h743-eval.h +@@ -24,11 +24,6 @@ + + #define CONFIG_SYS_HZ_CLOCK 1000000 + +-#define CONFIG_CMDLINE_TAG +-#define CONFIG_SETUP_MEMORY_TAGS +-#define CONFIG_INITRD_TAG +-#define CONFIG_REVISION_TAG +- + #define CONFIG_SYS_MAXARGS 16 + #define CONFIG_SYS_MALLOC_LEN (1 * 1024 * 1024) + +diff --git a/include/configs/stm32h750-art-pi.h b/include/configs/stm32h750-art-pi.h +index 3fd5461167..a9006e224a 100644 +--- a/include/configs/stm32h750-art-pi.h ++++ b/include/configs/stm32h750-art-pi.h +@@ -24,11 +24,6 @@ + + #define CONFIG_SYS_HZ_CLOCK 1000000 + +-#define CONFIG_CMDLINE_TAG +-#define CONFIG_SETUP_MEMORY_TAGS +-#define CONFIG_INITRD_TAG +-#define CONFIG_REVISION_TAG +- + #define CONFIG_SYS_MAXARGS 16 + #define CONFIG_SYS_MALLOC_LEN (1 * 1024 * 1024) + +diff --git a/include/configs/stm32mp13_common.h b/include/configs/stm32mp13_common.h +new file mode 100644 +index 0000000000..a0e90762af +--- /dev/null ++++ b/include/configs/stm32mp13_common.h +@@ -0,0 +1,151 @@ ++/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ ++/* ++ * Copyright (C) 2021, STMicroelectronics - All Rights Reserved ++ * ++ * Configuration settings for the STM32MP15x CPU ++ */ ++ ++#ifndef __CONFIG_STM32MP13_COMMMON_H ++#define __CONFIG_STM32MP13_COMMMON_H ++#include ++#include ++ ++/* ++ * Configuration of the external SRAM memory used by U-Boot ++ */ ++#define CONFIG_SYS_SDRAM_BASE STM32_DDR_BASE ++#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + SZ_4M) ++ ++/* ++ * Console I/O buffer size ++ */ ++#define CONFIG_SYS_CBSIZE SZ_1K ++ ++/* ++ * default load address used for command tftp, bootm , loadb, ... ++ */ ++#define CONFIG_LOADADDR 0xc2000000 ++#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR ++ ++/* ++ * For booting Linux, use the first 256 MB of memory, since this is ++ * the maximum mapped by the Linux kernel during initialization. ++ */ ++#define CONFIG_SYS_BOOTMAPSZ SZ_256M ++ ++/* Extend size of kernel image for uncompression */ ++#define CONFIG_SYS_BOOTM_LEN SZ_32M ++ ++/*MMC SD*/ ++#define CONFIG_SYS_MMC_MAX_DEVICE 2 ++ ++/* NAND support */ ++#define CONFIG_SYS_NAND_ONFI_DETECTION ++#define CONFIG_SYS_MAX_NAND_DEVICE 1 ++ ++/* Ethernet need */ ++#ifdef CONFIG_DWC_ETH_QOS ++#define CONFIG_SYS_NONCACHED_MEMORY (1 * SZ_1M) ++#define CONFIG_SERVERIP 192.168.1.1 ++#define CONFIG_BOOTP_SERVERIP ++#define CONFIG_SYS_AUTOLOAD "no" ++#endif ++ ++/*****************************************************************************/ ++#ifdef CONFIG_DISTRO_DEFAULTS ++/*****************************************************************************/ ++ ++#ifdef CONFIG_CMD_MMC ++#define BOOT_TARGET_MMC0(func) func(MMC, mmc, 0) ++#define BOOT_TARGET_MMC1(func) func(MMC, mmc, 1) ++#else ++#define BOOT_TARGET_MMC0(func) ++#define BOOT_TARGET_MMC1(func) ++#endif ++ ++#ifdef CONFIG_NET ++#define BOOT_TARGET_PXE(func) func(PXE, pxe, na) ++#else ++#define BOOT_TARGET_PXE(func) ++#endif ++ ++#ifdef CONFIG_CMD_UBIFS ++#define BOOT_TARGET_UBIFS(func) func(UBIFS, ubifs, 0) ++#else ++#define BOOT_TARGET_UBIFS(func) ++#endif ++ ++#ifdef CONFIG_CMD_USB ++#define BOOT_TARGET_USB(func) func(USB, usb, 0) ++#else ++#define BOOT_TARGET_USB(func) ++#endif ++ ++#define BOOT_TARGET_DEVICES(func) \ ++ BOOT_TARGET_MMC1(func) \ ++ BOOT_TARGET_UBIFS(func) \ ++ BOOT_TARGET_MMC0(func) \ ++ BOOT_TARGET_USB(func) \ ++ BOOT_TARGET_PXE(func) ++ ++/* ++ * default bootcmd for stm32mp13: ++ * for serial/usb: execute the stm32prog command ++ * for mmc boot (eMMC, SD card), distro boot on the same mmc device ++ * for nand or spi-nand boot, distro boot with ubifs on UBI partition ++ * for nor boot, use the default distro order in ${boot_targets} ++ */ ++#define STM32MP_BOOTCMD "bootcmd_stm32mp=" \ ++ "echo \"Boot over ${boot_device}${boot_instance}!\";" \ ++ "if test ${boot_device} = serial || test ${boot_device} = usb;" \ ++ "then stm32prog ${boot_device} ${boot_instance}; " \ ++ "else " \ ++ "run env_check;" \ ++ "if test ${boot_device} = mmc;" \ ++ "then env set boot_targets \"mmc${boot_instance}\"; fi;" \ ++ "if test ${boot_device} = nand ||" \ ++ " test ${boot_device} = spi-nand ;" \ ++ "then env set boot_targets ubifs0; fi;" \ ++ "run distro_bootcmd;" \ ++ "fi;\0" ++ ++#define STM32MP_EXTRA \ ++ "env_check=if env info -p -d -q; then env save; fi\0" \ ++ "boot_net_usb_start=true\0" ++ ++#ifndef STM32MP_BOARD_EXTRA_ENV ++#define STM32MP_BOARD_EXTRA_ENV ++#endif ++ ++#include ++ ++/* ++ * memory layout for 32M uncompressed/compressed kernel, ++ * 1M fdt, 1M script, 1M pxe and 1M for overlay ++ * and the ramdisk at the end. ++ */ ++#define __KERNEL_ADDR_R __stringify(0xc2000000) ++#define __FDT_ADDR_R __stringify(0xc4000000) ++#define __SCRIPT_ADDR_R __stringify(0xc4100000) ++#define __PXEFILE_ADDR_R __stringify(0xc4200000) ++#define __FDTOVERLAY_ADDR_R __stringify(0xc4300000) ++#define __RAMDISK_ADDR_R __stringify(0xc4400000) ++ ++#define STM32MP_MEM_LAYOUT \ ++ "kernel_addr_r=" __KERNEL_ADDR_R "\0" \ ++ "fdt_addr_r=" __FDT_ADDR_R "\0" \ ++ "scriptaddr=" __SCRIPT_ADDR_R "\0" \ ++ "pxefile_addr_r=" __PXEFILE_ADDR_R "\0" \ ++ "fdtoverlay_addr_r=" __FDTOVERLAY_ADDR_R "\0" \ ++ "ramdisk_addr_r=" __RAMDISK_ADDR_R "\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ STM32MP_MEM_LAYOUT \ ++ STM32MP_BOOTCMD \ ++ BOOTENV \ ++ STM32MP_EXTRA \ ++ STM32MP_BOARD_EXTRA_ENV ++ ++#endif /* ifdef CONFIG_DISTRO_DEFAULTS*/ ++ ++#endif /* __CONFIG_STM32MP13_COMMMON_H */ +diff --git a/include/configs/stm32mp13_st_common.h b/include/configs/stm32mp13_st_common.h +new file mode 100644 +index 0000000000..41681537a2 +--- /dev/null ++++ b/include/configs/stm32mp13_st_common.h +@@ -0,0 +1,55 @@ ++/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ ++/* ++ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved ++ * ++ * Configuration settings for the STMicroelectonics STM32MP15x boards ++ */ ++ ++#ifndef __CONFIG_STM32MP13_ST_COMMON_H__ ++#define __CONFIG_STM32MP13_ST_COMMON_H__ ++ ++#define STM32MP_BOARD_EXTRA_ENV \ ++ "usb_pgood_delay=1000\0" \ ++ "console=ttySTM0\0" ++ ++#include ++ ++/* uart with on-board st-link */ ++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ ++ 230400, 460800, 921600, \ ++ 1000000, 2000000, 4000000} ++ ++#ifdef CONFIG_EXTRA_ENV_SETTINGS ++/* ++ * default bootcmd for stm32mp13 STMicroelectronics boards: ++ * for serial/usb: execute the stm32prog command ++ * for mmc boot (eMMC, SD card), distro boot on the same mmc device ++ * for nand or spi-nand boot, distro boot with ubifs on UBI partition ++ * for nor boot, distro boot on SD card = mmc0 ONLY ! ++ */ ++#define ST_STM32MP13_BOOTCMD "bootcmd_stm32mp=" \ ++ "echo \"Boot over ${boot_device}${boot_instance}!\";" \ ++ "if test ${boot_device} = serial || test ${boot_device} = usb;" \ ++ "then stm32prog ${boot_device} ${boot_instance}; " \ ++ "else " \ ++ "run env_check;" \ ++ "if test ${boot_device} = mmc;" \ ++ "then env set boot_targets \"mmc${boot_instance}\"; fi;" \ ++ "if test ${boot_device} = nand ||" \ ++ " test ${boot_device} = spi-nand ;" \ ++ "then env set boot_targets ubifs0; fi;" \ ++ "if test ${boot_device} = nor;" \ ++ "then env set boot_targets mmc0; fi;" \ ++ "run distro_bootcmd;" \ ++ "fi;\0" ++ ++#undef CONFIG_EXTRA_ENV_SETTINGS ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ STM32MP_MEM_LAYOUT \ ++ ST_STM32MP13_BOOTCMD \ ++ BOOTENV \ ++ STM32MP_EXTRA \ ++ STM32MP_BOARD_EXTRA_ENV ++ ++#endif ++#endif +diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp15_common.h +similarity index 76% +rename from include/configs/stm32mp1.h +rename to include/configs/stm32mp15_common.h +index b372838be8..58971cc656 100644 +--- a/include/configs/stm32mp1.h ++++ b/include/configs/stm32mp15_common.h +@@ -5,12 +5,12 @@ + * Configuration settings for the STM32MP15x CPU + */ + +-#ifndef __CONFIG_H +-#define __CONFIG_H ++#ifndef __CONFIG_STM32MP15_COMMMON_H ++#define __CONFIG_STM32MP15_COMMMON_H + #include + #include + +-#ifndef CONFIG_TFABOOT ++#ifdef CONFIG_ARMV7_PSCI + /* PSCI support */ + #define CONFIG_ARMV7_SECURE_BASE STM32_SYSRAM_BASE + #define CONFIG_ARMV7_SECURE_MAX_SIZE STM32_SYSRAM_SIZE +@@ -20,7 +20,7 @@ + * Configuration of the external SRAM memory used by U-Boot + */ + #define CONFIG_SYS_SDRAM_BASE STM32_DDR_BASE +-#define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_TEXT_BASE ++#define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_TEXT_BASE + + /* + * Console I/O buffer size +@@ -33,11 +33,6 @@ + #define CONFIG_LOADADDR 0xc2000000 + #define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR + +-/* ATAGs */ +-#define CONFIG_CMDLINE_TAG +-#define CONFIG_SETUP_MEMORY_TAGS +-#define CONFIG_INITRD_TAG +- + /* + * For booting Linux, use the first 256 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. +@@ -116,11 +111,11 @@ + BOOT_TARGET_PXE(func) + + /* +- * bootcmd for stm32mp1: ++ * default bootcmd for stm32mp15: + * for serial/usb: execute the stm32prog command +- * for mmc boot (eMMC, SD card), boot only on the same device +- * for nand or spi-nand boot, boot with on ubifs partition on UBI partition +- * for nor boot, use SD card = mmc0 ++ * for mmc boot (eMMC, SD card), distro boot on the same mmc device ++ * for nand or spi-nand boot, distro boot with ubifs on UBI partition ++ * for nor boot, use the default distro order in ${boot_targets} + */ + #define STM32MP_BOOTCMD "bootcmd_stm32mp=" \ + "echo \"Boot over ${boot_device}${boot_instance}!\";" \ +@@ -133,14 +128,12 @@ + "if test ${boot_device} = nand ||" \ + " test ${boot_device} = spi-nand ;" \ + "then env set boot_targets ubifs0; fi;" \ +- "if test ${boot_device} = nor;" \ +- "then env set boot_targets mmc0; fi;" \ + "run distro_bootcmd;" \ + "fi;\0" + + #ifdef CONFIG_FASTBOOT_CMD_OEM_FORMAT + /* eMMC default partitions for fastboot command: oem format */ +-#define PARTS_DEFAULT \ ++#define STM32MP_PARTS_DEFAULT \ + "partitions=" \ + "name=ssbl,size=2M;" \ + "name=bootfs,size=64MB,bootable;" \ +@@ -148,7 +141,15 @@ + "name=rootfs,size=746M;" \ + "name=userfs,size=-\0" + #else +-#define PARTS_DEFAULT ++#define STM32MP_PARTS_DEFAULT ++#endif ++ ++#define STM32MP_EXTRA \ ++ "env_check=if env info -p -d -q; then env save; fi\0" \ ++ "boot_net_usb_start=true\0" ++ ++#ifndef STM32MP_BOARD_EXTRA_ENV ++#define STM32MP_BOARD_EXTRA_ENV + #endif + + #include +@@ -158,21 +159,30 @@ + * 1M fdt, 1M script, 1M pxe and 1M for overlay + * and the ramdisk at the end. + */ ++#define __KERNEL_ADDR_R __stringify(0xc2000000) ++#define __FDT_ADDR_R __stringify(0xc4000000) ++#define __SCRIPT_ADDR_R __stringify(0xc4100000) ++#define __PXEFILE_ADDR_R __stringify(0xc4200000) ++#define __FDTOVERLAY_ADDR_R __stringify(0xc4300000) ++#define __RAMDISK_ADDR_R __stringify(0xc4400000) ++ ++#define STM32MP_MEM_LAYOUT \ ++ "kernel_addr_r=" __KERNEL_ADDR_R "\0" \ ++ "fdt_addr_r=" __FDT_ADDR_R "\0" \ ++ "scriptaddr=" __SCRIPT_ADDR_R "\0" \ ++ "pxefile_addr_r=" __PXEFILE_ADDR_R "\0" \ ++ "fdtoverlay_addr_r=" __FDTOVERLAY_ADDR_R "\0" \ ++ "ramdisk_addr_r=" __RAMDISK_ADDR_R "\0" ++ + #define CONFIG_EXTRA_ENV_SETTINGS \ +- "kernel_addr_r=0xc2000000\0" \ +- "fdt_addr_r=0xc4000000\0" \ +- "scriptaddr=0xc4100000\0" \ +- "pxefile_addr_r=0xc4200000\0" \ +- "fdtoverlay_addr_r=0xc4300000\0" \ +- "ramdisk_addr_r=0xc4400000\0" \ +- "altbootcmd=run bootcmd\0" \ +- "env_check=if env info -p -d -q; then env save; fi\0" \ ++ STM32MP_MEM_LAYOUT \ + STM32MP_BOOTCMD \ +- PARTS_DEFAULT \ ++ STM32MP_PARTS_DEFAULT \ + BOOTENV \ +- "boot_net_usb_start=true\0" ++ STM32MP_EXTRA \ ++ STM32MP_BOARD_EXTRA_ENV + + #endif /* ifndef CONFIG_SPL_BUILD */ + #endif /* ifdef CONFIG_DISTRO_DEFAULTS*/ + +-#endif /* __CONFIG_H */ ++#endif /* __CONFIG_STM32MP15_COMMMON_H */ +diff --git a/include/configs/stm32mp15_dh_dhsom.h b/include/configs/stm32mp15_dh_dhsom.h +new file mode 100644 +index 0000000000..c79f0272cb +--- /dev/null ++++ b/include/configs/stm32mp15_dh_dhsom.h +@@ -0,0 +1,31 @@ ++/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ ++/* ++ * Copyright (C) 2020 Marek Vasut ++ * ++ * Configuration settings for the DH STM32MP15x SoMs ++ */ ++ ++#ifndef __CONFIG_STM32MP15_DH_DHSOM_H__ ++#define __CONFIG_STM32MP15_DH_DHSOM_H__ ++ ++/* PHY needs a longer autoneg timeout */ ++#define PHY_ANEG_TIMEOUT 20000 ++ ++#define STM32MP_BOARD_EXTRA_ENV \ ++ "usb_pgood_delay=1000\0" \ ++ "update_sf=" /* Erase SPI NOR and install U-Boot from SD */ \ ++ "setexpr loadaddr1 ${loadaddr} + 0x1000000 && " \ ++ "load mmc 0:4 ${loadaddr1} /boot/u-boot-spl.stm32 && " \ ++ "env set filesize1 ${filesize} && " \ ++ "load mmc 0:4 ${loadaddr} /boot/u-boot.itb && " \ ++ "sf probe && sf erase 0 0x200000 && " \ ++ "sf update ${loadaddr1} 0 ${filesize1} && " \ ++ "sf update ${loadaddr1} 0x40000 ${filesize1} && " \ ++ "sf update ${loadaddr} 0x80000 ${filesize} && " \ ++ "env set filesize1 && env set loadaddr1\0" ++ ++#include ++ ++#define CONFIG_SPL_TARGET "u-boot.itb" ++ ++#endif +diff --git a/include/configs/stm32mp15_st_common.h b/include/configs/stm32mp15_st_common.h +new file mode 100644 +index 0000000000..c395f7f986 +--- /dev/null ++++ b/include/configs/stm32mp15_st_common.h +@@ -0,0 +1,56 @@ ++/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ ++/* ++ * Copyright (C) 2021, STMicroelectronics - All Rights Reserved ++ * ++ * Configuration settings for the STMicroelectonics STM32MP15x boards ++ */ ++ ++#ifndef __CONFIG_STM32MP15_ST_COMMON_H__ ++#define __CONFIG_STM32MP15_ST_COMMON_H__ ++ ++#define STM32MP_BOARD_EXTRA_ENV \ ++ "usb_pgood_delay=1000\0" \ ++ "console=ttySTM0\0" ++ ++#include ++ ++/* uart with on-board st-link */ ++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ ++ 230400, 460800, 921600, \ ++ 1000000, 2000000 } ++ ++#ifdef CONFIG_EXTRA_ENV_SETTINGS ++/* ++ * default bootcmd for stm32mp1 STMicroelectronics boards: ++ * for serial/usb: execute the stm32prog command ++ * for mmc boot (eMMC, SD card), distro boot on the same mmc device ++ * for nand or spi-nand boot, distro boot with ubifs on UBI partition ++ * for nor boot, distro boot on SD card = mmc0 ONLY ! ++ */ ++#define ST_STM32MP1_BOOTCMD "bootcmd_stm32mp=" \ ++ "echo \"Boot over ${boot_device}${boot_instance}!\";" \ ++ "if test ${boot_device} = serial || test ${boot_device} = usb;" \ ++ "then stm32prog ${boot_device} ${boot_instance}; " \ ++ "else " \ ++ "run env_check;" \ ++ "if test ${boot_device} = mmc;" \ ++ "then env set boot_targets \"mmc${boot_instance}\"; fi;" \ ++ "if test ${boot_device} = nand ||" \ ++ " test ${boot_device} = spi-nand ;" \ ++ "then env set boot_targets ubifs0; fi;" \ ++ "if test ${boot_device} = nor;" \ ++ "then env set boot_targets mmc0; fi;" \ ++ "run distro_bootcmd;" \ ++ "fi;\0" ++ ++#undef CONFIG_EXTRA_ENV_SETTINGS ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ STM32MP_MEM_LAYOUT \ ++ ST_STM32MP1_BOOTCMD \ ++ STM32MP_PARTS_DEFAULT \ ++ BOOTENV \ ++ STM32MP_EXTRA \ ++ STM32MP_BOARD_EXTRA_ENV ++ ++#endif ++#endif +diff --git a/include/dm/lists.h b/include/dm/lists.h +index 1a86552546..5896ae3658 100644 +--- a/include/dm/lists.h ++++ b/include/dm/lists.h +@@ -53,13 +53,14 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only); + * @parent: parent device (root) + * @node: device tree node to bind + * @devp: if non-NULL, returns a pointer to the bound device ++ * @drv: if non-NULL, force this driver to be bound + * @pre_reloc_only: If true, bind only nodes with special devicetree properties, + * or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers. + * @return 0 if device was bound, -EINVAL if the device tree is invalid, + * other -ve value on error + */ + int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp, +- bool pre_reloc_only); ++ struct driver *drv, bool pre_reloc_only); + + /** + * device_bind_driver() - bind a device to a driver +diff --git a/include/dm/pinctrl.h b/include/dm/pinctrl.h +index 695e78ad0d..137533cebc 100644 +--- a/include/dm/pinctrl.h ++++ b/include/dm/pinctrl.h +@@ -6,7 +6,7 @@ + #ifndef __PINCTRL_H + #define __PINCTRL_H + +-#define PINNAME_SIZE 10 ++#define PINNAME_SIZE 16 + #define PINMUX_SIZE 40 + + /** +diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h +index e7edd409f3..62ad7a5300 100644 +--- a/include/dm/uclass-id.h ++++ b/include/dm/uclass-id.h +@@ -118,10 +118,12 @@ enum uclass_id { + UCLASS_TIMER, /* Timer device */ + UCLASS_TPM, /* Trusted Platform Module TIS interface */ + UCLASS_UFS, /* Universal Flash Storage */ ++ UCLASS_UCSI, /* USB Type-C Connector System Software Interface */ + UCLASS_USB, /* USB bus */ + UCLASS_USB_DEV_GENERIC, /* USB generic device */ + UCLASS_USB_HUB, /* USB hub */ + UCLASS_USB_GADGET_GENERIC, /* USB generic device */ ++ UCLASS_USB_TYPEC, /* USB Type-C */ + UCLASS_VIDEO, /* Video or LCD device */ + UCLASS_VIDEO_BRIDGE, /* Video bridge, e.g. DisplayPort to LVDS */ + UCLASS_VIDEO_CONSOLE, /* Text console driver for video device */ +diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h +index 4cdaf13582..2e23e0384b 100644 +--- a/include/dt-bindings/clock/stm32mp1-clks.h ++++ b/include/dt-bindings/clock/stm32mp1-clks.h +@@ -179,6 +179,12 @@ + #define DAC12_K 168 + #define ETHPTP_K 169 + ++#define PCLK1 170 ++#define PCLK2 171 ++#define PCLK3 172 ++#define PCLK4 173 ++#define PCLK5 174 ++ + /* PLL */ + #define PLL1 176 + #define PLL2 177 +@@ -248,4 +254,27 @@ + + #define STM32MP1_LAST_CLK 232 + ++/* SCMI clock identifiers */ ++#define CK_SCMI_HSE 0 ++#define CK_SCMI_HSI 1 ++#define CK_SCMI_CSI 2 ++#define CK_SCMI_LSE 3 ++#define CK_SCMI_LSI 4 ++#define CK_SCMI_PLL2_Q 5 ++#define CK_SCMI_PLL2_R 6 ++#define CK_SCMI_MPU 7 ++#define CK_SCMI_AXI 8 ++#define CK_SCMI_BSEC 9 ++#define CK_SCMI_CRYP1 10 ++#define CK_SCMI_GPIOZ 11 ++#define CK_SCMI_HASH1 12 ++#define CK_SCMI_I2C4 13 ++#define CK_SCMI_I2C6 14 ++#define CK_SCMI_IWDG1 15 ++#define CK_SCMI_RNG1 16 ++#define CK_SCMI_RTC 17 ++#define CK_SCMI_RTCAPB 18 ++#define CK_SCMI_SPI6 19 ++#define CK_SCMI_USART1 20 ++ + #endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */ +diff --git a/include/dt-bindings/clock/stm32mp13-clks.h b/include/dt-bindings/clock/stm32mp13-clks.h +new file mode 100644 +index 0000000000..02befd25ed +--- /dev/null ++++ b/include/dt-bindings/clock/stm32mp13-clks.h +@@ -0,0 +1,229 @@ ++/* SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause */ ++/* ++ * Copyright (C) STMicroelectronics 2020 - All Rights Reserved ++ * Author: Gabriel Fernandez for STMicroelectronics. ++ */ ++ ++#ifndef _DT_BINDINGS_STM32MP13_CLKS_H_ ++#define _DT_BINDINGS_STM32MP13_CLKS_H_ ++ ++/* OSCILLATOR clocks */ ++#define CK_HSE 0 ++#define CK_CSI 1 ++#define CK_LSI 2 ++#define CK_LSE 3 ++#define CK_HSI 4 ++#define CK_HSE_DIV2 5 ++ ++/* PLL */ ++#define PLL1 6 ++#define PLL2 7 ++#define PLL3 8 ++#define PLL4 9 ++ ++/* ODF */ ++#define PLL1_P 10 ++#define PLL1_Q 11 ++#define PLL1_R 12 ++#define PLL2_P 13 ++#define PLL2_Q 14 ++#define PLL2_R 15 ++#define PLL3_P 16 ++#define PLL3_Q 17 ++#define PLL3_R 18 ++#define PLL4_P 19 ++#define PLL4_Q 20 ++#define PLL4_R 21 ++ ++#define PCLK1 22 ++#define PCLK2 23 ++#define PCLK3 24 ++#define PCLK4 25 ++#define PCLK5 26 ++#define PCLK6 27 ++ ++/* SYSTEM CLOCK */ ++#define CK_PER 28 ++#define CK_MPU 29 ++#define CK_AXI 30 ++#define CK_MLAHB 31 ++ ++/* BASE TIMER */ ++#define CK_TIMG1 32 ++#define CK_TIMG2 33 ++#define CK_TIMG3 34 ++ ++/* AUX */ ++#define RTC 35 ++ ++/* TRACE & DEBUG clocks */ ++#define CK_DBG 36 ++#define CK_TRACE 37 ++ ++/* MCO clocks */ ++#define CK_MCO1 38 ++#define CK_MCO2 39 ++ ++/* IP clocks */ ++#define SYSCFG 40 ++#define VREF 41 ++#define DTS 42 ++#define PMBCTRL 43 ++#define HDP 44 ++#define IWDG2 45 ++#define STGENRO 46 ++#define USART1 47 ++#define RTCAPB 48 ++#define TZC 49 ++#define TZPC 50 ++#define IWDG1 51 ++#define BSEC 52 ++#define DMA1 53 ++#define DMA2 54 ++#define DMAMUX1 55 ++#define DMAMUX2 56 ++#define GPIOA 57 ++#define GPIOB 58 ++#define GPIOC 59 ++#define GPIOD 60 ++#define GPIOE 61 ++#define GPIOF 62 ++#define GPIOG 63 ++#define GPIOH 64 ++#define GPIOI 65 ++#define CRYP1 66 ++#define HASH1 67 ++#define BKPSRAM 68 ++#define MDMA 69 ++#define CRC1 70 ++#define USBH 71 ++#define DMA3 72 ++#define TSC 73 ++#define PKA 74 ++#define AXIMC 75 ++#define MCE 76 ++#define ETH1TX 77 ++#define ETH2TX 78 ++#define ETH1RX 79 ++#define ETH2RX 80 ++#define ETH1MAC 81 ++#define ETH2MAC 82 ++#define ETH1STP 83 ++#define ETH2STP 84 ++ ++/* IP clocks with parents */ ++#define SDMMC1_K 85 ++#define SDMMC2_K 86 ++#define ADC1_K 87 ++#define ADC2_K 88 ++#define FMC_K 89 ++#define QSPI_K 90 ++#define RNG1_K 91 ++#define USBPHY_K 92 ++#define STGEN_K 93 ++#define SPDIF_K 94 ++#define SPI1_K 95 ++#define SPI2_K 96 ++#define SPI3_K 97 ++#define SPI4_K 98 ++#define SPI5_K 99 ++#define I2C1_K 100 ++#define I2C2_K 101 ++#define I2C3_K 102 ++#define I2C4_K 103 ++#define I2C5_K 104 ++#define TIM2_K 105 ++#define TIM3_K 106 ++#define TIM4_K 107 ++#define TIM5_K 108 ++#define TIM6_K 109 ++#define TIM7_K 110 ++#define TIM12_K 111 ++#define TIM13_K 112 ++#define TIM14_K 113 ++#define TIM1_K 114 ++#define TIM8_K 115 ++#define TIM15_K 116 ++#define TIM16_K 117 ++#define TIM17_K 118 ++#define LPTIM1_K 119 ++#define LPTIM2_K 120 ++#define LPTIM3_K 121 ++#define LPTIM4_K 122 ++#define LPTIM5_K 123 ++#define USART1_K 124 ++#define USART2_K 125 ++#define USART3_K 126 ++#define UART4_K 127 ++#define UART5_K 128 ++#define USART6_K 129 ++#define UART7_K 130 ++#define UART8_K 131 ++#define DFSDM_K 132 ++#define FDCAN_K 133 ++#define SAI1_K 134 ++#define SAI2_K 135 ++#define ADFSDM_K 136 ++#define USBO_K 137 ++#define LTDC_PX 138 ++#define ETH1CK_K 139 ++#define ETH1PTP_K 140 ++#define ETH2CK_K 141 ++#define ETH2PTP_K 142 ++#define DCMIPP_K 143 ++#define SAES_K 144 ++#define DTS_K 145 ++ ++/* DDR */ ++#define DDRC1 146 ++#define DDRC1LP 147 ++#define DDRC2 148 ++#define DDRC2LP 149 ++#define DDRPHYC 150 ++#define DDRPHYCLP 151 ++#define DDRCAPB 152 ++#define DDRCAPBLP 153 ++#define AXIDCG 154 ++#define DDRPHYCAPB 155 ++#define DDRPHYCAPBLP 156 ++#define DDRPERFM 157 ++ ++#define ADC1 158 ++#define ADC2 159 ++#define SAI1 160 ++#define SAI2 161 ++ ++#define STM32MP1_LAST_CLK 162 ++ ++/* SCMI clock identifiers */ ++#define CK_SCMI_HSE 0 ++#define CK_SCMI_HSI 1 ++#define CK_SCMI_CSI 2 ++#define CK_SCMI_LSE 3 ++#define CK_SCMI_LSI 4 ++#define CK_SCMI_HSE_DIV2 5 ++#define CK_SCMI_PLL2_Q 6 ++#define CK_SCMI_PLL2_R 7 ++#define CK_SCMI_PLL3_P 8 ++#define CK_SCMI_PLL3_Q 9 ++#define CK_SCMI_PLL3_R 10 ++#define CK_SCMI_PLL4_P 11 ++#define CK_SCMI_PLL4_Q 12 ++#define CK_SCMI_PLL4_R 13 ++#define CK_SCMI_MPU 14 ++#define CK_SCMI_AXI 15 ++#define CK_SCMI_MLAHB 16 ++#define CK_SCMI_CKPER 17 ++#define CK_SCMI_PCLK1 18 ++#define CK_SCMI_PCLK2 19 ++#define CK_SCMI_PCLK3 20 ++#define CK_SCMI_PCLK4 21 ++#define CK_SCMI_PCLK5 22 ++#define CK_SCMI_PCLK6 23 ++#define CK_SCMI_CKTIMG1 24 ++#define CK_SCMI_CKTIMG2 25 ++#define CK_SCMI_CKTIMG3 26 ++#define CK_SCMI_RTC 27 ++#define CK_SCMI_RTCAPB 28 ++ ++#endif /* _DT_BINDINGS_STM32MP13_CLKS_H_ */ +diff --git a/include/dt-bindings/pinctrl/stm32-pinfunc.h b/include/dt-bindings/pinctrl/stm32-pinfunc.h +index e6fb8ada3f..370a25a936 100644 +--- a/include/dt-bindings/pinctrl/stm32-pinfunc.h ++++ b/include/dt-bindings/pinctrl/stm32-pinfunc.h +@@ -26,6 +26,7 @@ + #define AF14 0xf + #define AF15 0x10 + #define ANALOG 0x11 ++#define RSVD 0x12 + + /* define Pins number*/ + #define PIN_NO(port, line) (((port) - 'A') * 0x10 + (line)) +diff --git a/include/dt-bindings/reset/stm32mp1-resets.h b/include/dt-bindings/reset/stm32mp1-resets.h +index 702da37a2e..bdbf9e2530 100644 +--- a/include/dt-bindings/reset/stm32mp1-resets.h ++++ b/include/dt-bindings/reset/stm32mp1-resets.h +@@ -106,4 +106,18 @@ + #define GPIOJ_R 19785 + #define GPIOK_R 19786 + ++/* SCMI reset domain identifiers */ ++#define RST_SCMI_SPI6 0 ++#define RST_SCMI_I2C4 1 ++#define RST_SCMI_I2C6 2 ++#define RST_SCMI_USART1 3 ++#define RST_SCMI_STGEN 4 ++#define RST_SCMI_GPIOZ 5 ++#define RST_SCMI_CRYP1 6 ++#define RST_SCMI_HASH1 7 ++#define RST_SCMI_RNG1 8 ++#define RST_SCMI_MDMA 9 ++#define RST_SCMI_MCU 10 ++#define RST_SCMI_MCU_HOLD_BOOT 11 ++ + #endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */ +diff --git a/include/dt-bindings/reset/stm32mp13-resets.h b/include/dt-bindings/reset/stm32mp13-resets.h +new file mode 100644 +index 0000000000..934864e90d +--- /dev/null ++++ b/include/dt-bindings/reset/stm32mp13-resets.h +@@ -0,0 +1,100 @@ ++/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */ ++/* ++ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved ++ * Author: Gabriel Fernandez for STMicroelectronics. ++ */ ++ ++#ifndef _DT_BINDINGS_STM32MP13_RESET_H_ ++#define _DT_BINDINGS_STM32MP13_RESET_H_ ++ ++#define TIM2_R 13568 ++#define TIM3_R 13569 ++#define TIM4_R 13570 ++#define TIM5_R 13571 ++#define TIM6_R 13572 ++#define TIM7_R 13573 ++#define LPTIM1_R 13577 ++#define SPI2_R 13579 ++#define SPI3_R 13580 ++#define USART3_R 13583 ++#define UART4_R 13584 ++#define UART5_R 13585 ++#define UART7_R 13586 ++#define UART8_R 13587 ++#define I2C1_R 13589 ++#define I2C2_R 13590 ++#define SPDIF_R 13594 ++#define TIM1_R 13632 ++#define TIM8_R 13633 ++#define SPI1_R 13640 ++#define USART6_R 13645 ++#define SAI1_R 13648 ++#define SAI2_R 13649 ++#define DFSDM_R 13652 ++#define FDCAN_R 13656 ++#define LPTIM2_R 13696 ++#define LPTIM3_R 13697 ++#define LPTIM4_R 13698 ++#define LPTIM5_R 13699 ++#define SYSCFG_R 13707 ++#define VREF_R 13709 ++#define DTS_R 13712 ++#define PMBCTRL_R 13713 ++#define LTDC_R 13760 ++#define DCMIPP_R 13761 ++#define DDRPERFM_R 13768 ++#define USBPHY_R 13776 ++#define STGEN_R 13844 ++#define USART1_R 13888 ++#define USART2_R 13889 ++#define SPI4_R 13890 ++#define SPI5_R 13891 ++#define I2C3_R 13892 ++#define I2C4_R 13893 ++#define I2C5_R 13894 ++#define TIM12_R 13895 ++#define TIM13_R 13896 ++#define TIM14_R 13897 ++#define TIM15_R 13898 ++#define TIM16_R 13899 ++#define TIM17_R 13900 ++#define DMA1_R 13952 ++#define DMA2_R 13953 ++#define DMAMUX1_R 13954 ++#define DMA3_R 13955 ++#define DMAMUX2_R 13956 ++#define ADC1_R 13957 ++#define ADC2_R 13958 ++#define USBO_R 13960 ++#define GPIOA_R 14080 ++#define GPIOB_R 14081 ++#define GPIOC_R 14082 ++#define GPIOD_R 14083 ++#define GPIOE_R 14084 ++#define GPIOF_R 14085 ++#define GPIOG_R 14086 ++#define GPIOH_R 14087 ++#define GPIOI_R 14088 ++#define TSC_R 14095 ++#define PKA_R 14146 ++#define SAES_R 14147 ++#define CRYP1_R 14148 ++#define HASH1_R 14149 ++#define RNG1_R 14150 ++#define AXIMC_R 14160 ++#define MDMA_R 14208 ++#define MCE_R 14209 ++#define ETH1MAC_R 14218 ++#define FMC_R 14220 ++#define QSPI_R 14222 ++#define SDMMC1_R 14224 ++#define SDMMC2_R 14225 ++#define CRC1_R 14228 ++#define USBH_R 14232 ++#define ETH2MAC_R 14238 ++ ++/* SCMI reset domain identifiers */ ++#define RST_SCMI_LTDC 0 ++#define RST_SCMI_MDMA 1 ++ ++#endif /* _DT_BINDINGS_STM32MP13_RESET_H_ */ +diff --git a/include/dt-bindings/rtc/rtc-stm32.h b/include/dt-bindings/rtc/rtc-stm32.h +new file mode 100644 +index 0000000000..2fd78c2e62 +--- /dev/null ++++ b/include/dt-bindings/rtc/rtc-stm32.h +@@ -0,0 +1,14 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * This header provides constants for STM32_RTC bindings. ++ */ ++ ++#ifndef _DT_BINDINGS_RTC_RTC_STM32_H ++#define _DT_BINDINGS_RTC_RTC_STM32_H ++ ++#define RTC_NO_OUT 0 ++#define RTC_OUT1 1 ++#define RTC_OUT2 2 ++#define RTC_OUT2_RMP 3 ++ ++#endif +diff --git a/include/dt-bindings/soc/stm32-hdp.h b/include/dt-bindings/soc/stm32-hdp.h +new file mode 100644 +index 0000000000..d986653272 +--- /dev/null ++++ b/include/dt-bindings/soc/stm32-hdp.h +@@ -0,0 +1,108 @@ ++/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ ++/* ++ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved ++ * Author: Roullier Christophe ++ * for STMicroelectronics. ++ */ ++ ++#ifndef _DT_BINDINGS_STM32_HDP_H ++#define _DT_BINDINGS_STM32_HDP_H ++ ++#define STM32_HDP(port, value) ((value) << ((port) * 4)) ++ ++/* define HDP Pins number*/ ++#define HDP0_PWR_PWRWAKE_SYS 0 ++#define HDP0_CM4_SLEEPDEEP 1 ++#define HDP0_PWR_STDBY_WKUP 2 ++#define HDP0_PWR_ENCOMP_VDDCORE 3 ++#define HDP0_BSEC_OUT_SEC_NIDEN 4 ++#define HDP0_RCC_CM4_SLEEPDEEP 6 ++#define HDP0_GPU_DBG7 7 ++#define HDP0_DDRCTRL_LP_REQ 8 ++#define HDP0_PWR_DDR_RET_ENABLE_N 9 ++#define HDP0_GPOVAL_0 15 ++ ++#define HDP1_PWR_PWRWAKE_MCU 0 ++#define HDP1_CM4_HALTED 1 ++#define HDP1_CA7_NAXIERRIRQ 2 ++#define HDP1_PWR_OKIN_MR 3 ++#define HDP1_BSEC_OUT_SEC_DBGEN 4 ++#define HDP1_EXTI_SYS_WAKEUP 5 ++#define HDP1_RCC_PWRDS_MPU 6 ++#define HDP1_GPU_DBG6 7 ++#define HDP1_DDRCTRL_DFI_CTRLUPD_REQ 8 ++#define HDP1_DDRCTRL_CACTIVE_DDRC_ASR 9 ++#define HDP1_GPOVAL_1 15 ++ ++#define HDP2_PWR_PWRWAKE_MPU 0 ++#define HDP2_CM4_RXEV 1 ++#define HDP2_CA7_NPMUIRQ1 2 ++#define HDP2_CA7_NFIQOUT1 3 ++#define HDP2_BSEC_IN_RSTCORE_N 4 ++#define HDP2_EXTI_C2_WAKEUP 5 ++#define HDP2_RCC_PWRDS_MCU 6 ++#define HDP2_GPU_DBG5 7 ++#define HDP2_DDRCTRL_DFI_INIT_COMPLETE 8 ++#define HDP2_DDRCTRL_PERF_OP_IS_REFRESH 9 ++#define HDP2_DDRCTRL_GSKP_DFI_LP_REQ 10 ++#define HDP2_GPOVAL_2 15 ++ ++#define HDP3_PWR_SEL_VTH_VDD_CORE 0 ++#define HDP3_CM4_TXEV 1 ++#define HDP3_CA7_NPMUIRQ0 2 ++#define HDP3_CA7_NFIQOUT0 3 ++#define HDP3_BSEC_OUT_SEC_DFTLOCK 4 ++#define HDP3_EXTI_C1_WAKEUP 5 ++#define HDP3_RCC_PWRDS_SYS 6 ++#define HDP3_GPU_DBG4 7 ++#define HDP3_DDRCTRL_STAT_DDRC_REG_SELREF_TYPE0 8 ++#define HDP3_DDRCTRL_CACTIVE_1 9 ++#define HDP3_GPOVAL_3 15 ++ ++#define HDP4_PWR_PDDS 0 ++#define HDP4_CM4_SLEEPING 1 ++#define HDP4_CA7_NRESET1 2 ++#define HDP4_CA7_NIRQOUT1 3 ++#define HDP4_BSEC_OUT_SEC_DFTEN 4 ++#define HDP4_BSEC_OUT_SEC_DBGSWENABLE 5 ++#define HDP4_ETH_OUT_PMT_INTR_O 6 ++#define HDP4_GPU_DBG3 7 ++#define HDP4_DDRCTRL_STAT_DDRC_REG_SELREF_TYPE1 8 ++#define HDP4_DDRCTRL_CACTIVE_0 9 ++#define HDP4_GPOVAL_4 15 ++ ++#define HDP5_CA7_STANDBYWFIL2 0 ++#define HDP5_PWR_VTH_VDDCORE_ACK 1 ++#define HDP5_CA7_NRESET0 2 ++#define HDP5_CA7_NIRQOUT0 3 ++#define HDP5_BSEC_IN_PWROK 4 ++#define HDP5_BSEC_OUT_SEC_DEVICEEN 5 ++#define HDP5_ETH_OUT_LPI_INTR_O 6 ++#define HDP5_GPU_DBG2 7 ++#define HDP5_DDRCTRL_CACTIVE_DDRC 8 ++#define HDP5_DDRCTRL_WR_CREDIT_CNT 9 ++#define HDP5_GPOVAL_5 15 ++ ++#define HDP6_CA7_STANDBYWFI1 0 ++#define HDP6_CA7_STANDBYWFE1 1 ++#define HDP6_CA7_EVENT0 2 ++#define HDP6_CA7_DBGACK1 3 ++#define HDP6_BSEC_OUT_SEC_SPNIDEN 5 ++#define HDP6_ETH_OUT_MAC_SPEED_O1 6 ++#define HDP6_GPU_DBG1 7 ++#define HDP6_DDRCTRL_CSYSACK_DDRC 8 ++#define HDP6_DDRCTRL_LPR_CREDIT_CNT 9 ++#define HDP6_GPOVAL_6 15 ++ ++#define HDP7_CA7_STANDBYWFI0 0 ++#define HDP7_CA7_STANDBYWFE0 1 ++#define HDP7_CA7_DBGACK0 3 ++#define HDP7_BSEC_OUT_FUSE_OK 4 ++#define HDP7_BSEC_OUT_SEC_SPIDEN 5 ++#define HDP7_ETH_OUT_MAC_SPEED_O0 6 ++#define HDP7_GPU_DBG0 7 ++#define HDP7_DDRCTRL_CSYSREQ_DDRC 8 ++#define HDP7_DDRCTRL_HPR_CREDIT_CNT 9 ++#define HDP7_GPOVAL_7 15 ++ ++#endif /* _DT_BINDINGS_STM32_HDP_H */ +diff --git a/include/dt-bindings/soc/stm32mp13-hdp.h b/include/dt-bindings/soc/stm32mp13-hdp.h +new file mode 100644 +index 0000000000..091c1c8358 +--- /dev/null ++++ b/include/dt-bindings/soc/stm32mp13-hdp.h +@@ -0,0 +1,133 @@ ++/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ ++/* ++ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved ++ * Author: Roullier Christophe ++ * for STMicroelectronics. ++ */ ++ ++#ifndef _DT_BINDINGS_STM32_HDP_H ++#define _DT_BINDINGS_STM32_HDP_H ++ ++#define STM32_HDP(port, value) ((value) << ((port) * 4)) ++ ++/* define HDP Pins number*/ ++#define HDP0_PWR_PWRWAKE_SYS 0 ++#define HDP0_PWR_STOP_FORBIDDEN 1 ++#define HDP0_PWR_STDBY_WKUP 2 ++#define HDP0_PWR_ENCOMP_VDDCORE 3 ++#define HDP0_BSEC_OUT_SEC_NIDEN 4 ++#define HDP0_AIEC_SYS_WAKEUP 5 ++#define HDP0_DDRCTRL_LP_REQ 8 ++#define HDP0_PWR_DDR_RET_ENABLE_N 9 ++#define HDP0_DTS_CLK_PTAT 10 ++#define HDP0_SRAM3CTRL_TAMP_ERASE_ACT 12 ++#define HDP0_GPOVAL_0 15 ++ ++#define HDP1_PWR_SEL_VTH_VDDCPU 0 ++#define HDP1_PWR_MPU_RAM_LOWSPEED 1 ++#define HDP1_CA7_NAXIERRIRQ 2 ++#define HDP1_PWR_OKIN_MR 3 ++#define HDP1_BSEC_OUT_SEC_DBGEN 4 ++#define HDP1_AIEC_C1_WAKEUP 5 ++#define HDP1_RCC_PWRDS_MPU 6 ++#define HDP1_DDRCTRL_DFI_CTRLUPD_REQ 8 ++#define HDP1_DDRCTRL_CACTIVE_DDRC_ASR 9 ++#define HDP1_SRAM3CTRL_HW_ERASE_ACT 12 ++#define HDP1_NIC400_S0_BREADY 13 ++#define HDP1_GPOVAL_1 15 ++ ++#define HDP2_PWR_PWRWAKE_MPU 0 ++#define HDP2_PWR_MPU_CLOCK_DISABLE_ACK 1 ++#define HDP2_CA7_NDGBRESET_I 2 ++#define HDP2_BSEC_IN_RSTCORE_N 4 ++#define HDP2_BSEC_OUT_SEC_BSC_DIS 5 ++#define HDP2_DDRCTRL_DFI_INIT_COMPLETE 8 ++#define HDP2_DDRCTRL_PERF_OP_IS_REFRESH 9 ++#define HDP2_DDRCTRL_GSKP_DFI_LP_REQ 10 ++#define HDP2_SRAM3CTRL_SW_ERASE_ACT 12 ++#define HDP2_NIC400_S0_BVALID 13 ++#define HDP2_GPOVAL_2 15 ++ ++#define HDP3_PWR_SEL_VTH_VDD_CORE 0 ++#define HDP3_PWR_MPU_CLOCK_DISABLE_REQ 1 ++#define HDP3_CA7_NPMUIRQ0 2 ++#define HDP3_CA7_NFIQOUT0 3 ++#define HDP3_BSEC_OUT_SEC_DFTLOCK 4 ++#define HDP3_BSEC_OUT_SEC_JTAG_DIS 5 ++#define HDP3_RCC_PWRDS_SYS 6 ++#define HDP3_SRAM3CTRL_TAMP_ERASE_REQ 7 ++#define HDP3_DDRCTRL_STAT_DDRC_REG_SELREF_TYPE0 8 ++#define HDP3_DTS_VALOBUS1_0 10 ++#define HDP3_DTS_VALOBUS2_0 11 ++#define HDP3_TAMP_POTENTIAL_TAMP_ERFCFG 12 ++#define HDP3_NIC400_S0_WREADY 13 ++#define HDP3_NIC400_S0_RREADY 14 ++#define HDP3_GPOVAL_3 15 ++ ++#define HDP4_PWR_STOP2_ACTIVE 1 ++#define HDP4_CA7_NL2RESET1 2 ++#define HDP4_CA7_NPORESET_VARM_I 3 ++#define HDP4_BSEC_OUT_SEC_DFTEN 4 ++#define HDP4_BSEC_OUT_SEC_DBGSWENABLE 5 ++#define HDP4_ETH1_OUT_PMT_INTR_O 6 ++#define HDP4_ETH2_OUT_PMT_INTR_O 7 ++#define HDP4_DDRCTRL_STAT_DDRC_REG_SELREF_TYPE1 8 ++#define HDP4_DDRCTRL_CACTIVE_0 9 ++#define HDP4_DTS_VALOBUS1_1 10 ++#define HDP4_DTS_VALOBUS2_1 11 ++#define HDP4_TAMP_NRESET_SRAM_ERCFG 12 ++#define HDP4_NIC400_S0_WLAST 13 ++#define HDP4_NIC400_S0_RLAST 14 ++#define HDP4_GPOVAL_4 15 ++ ++#define HDP5_CA7_STANDBYWFIL2 0 ++#define HDP5_PWR_VTH_VDDCORE_ACK 1 ++#define HDP5_CA7_NCORERESET_I 2 ++#define HDP5_CA7_NIRQOUT0 3 ++#define HDP5_BSEC_IN_PWROK 4 ++#define HDP5_BSEC_OUT_SEC_DEVICEEN 5 ++#define HDP5_ETH1_OUT_LPI_INTR_O 6 ++#define HDP5_ETH2_OUT_LPI_INTR_O 7 ++#define HDP5_DDRCTRL_CACTIVE_DDRC 8 ++#define HDP5_DDRCTRL_WR_CREDIT_CNT 9 ++#define HDP5_DTS_VALOBUS1_2 10 ++#define HDP5_DTS_VALOBUS2_2 11 ++#define HDP5_PKA_PKA_ITAMP_OUT 12 ++#define HDP5_NIC400_S0_WVALID 13 ++#define HDP5_NIC400_S0_RVALID 14 ++#define HDP5_GPOVAL_5 15 ++ ++#define HDP6_CA7_STANDBYWFE0 0 ++#define HDP6_PWR_VTH_VDDCPU_ACK 1 ++#define HDP6_CA7_EVENT0 2 ++#define HDP6_BSEC_IN_TAMPER_DET 4 ++#define HDP6_BSEC_OUT_SEC_SPNIDEN 5 ++#define HDP6_ETH1_OUT_MAC_SPEED_O1 6 ++#define HDP6_ETH2_OUT_MAC_SPEED_O1 7 ++#define HDP6_DDRCTRL_CSYSACK_DDRC 8 ++#define HDP6_DDRCTRL_LPR_CREDIT_CNT 9 ++#define HDP6_DTS_VALOBUS1_3 10 ++#define HDP6_DTS_VALOBUS2_3 11 ++#define HDP6_SAES_TAMPER_OUT 12 ++#define HDP6_NIC400_S0_AWREADY 13 ++#define HDP6_NIC400_S0_ARREADY 14 ++#define HDP6_GPOVAL_6 15 ++ ++#define HDP7_CA7_STANDBYWFI0 0 ++#define HDP7_PWR_RCC_VCPU_RDY 1 ++#define HDP7_CA7_EVENTI 2 ++#define HDP7_CA7_DBGACK0 3 ++#define HDP7_BSEC_OUT_FUSE_OK 4 ++#define HDP7_BSEC_OUT_SEC_SPIDEN 5 ++#define HDP7_ETH1_OUT_MAC_SPEED_O0 6 ++#define HDP7_ETH2_OUT_MAC_SPEED_O0 7 ++#define HDP7_DDRCTRL_CSYSREQ_DDRC 8 ++#define HDP7_DDRCTRL_HPR_CREDIT_CNT 9 ++#define HDP7_DTS_VALOBUS1_4 10 ++#define HDP7_DTS_VALOBUS2_4 11 ++#define HDP7_RNG_TAMPER_OUT 12 ++#define HDP7_NIC400_S0_AWVALID 13 ++#define HDP7_NIC400_S0_ARVALID 14 ++#define HDP7_GPOVAL_7 15 ++ ++#endif /* _DT_BINDINGS_STM32_HDP_H */ +diff --git a/include/fdt_simplefb.h b/include/fdt_simplefb.h +index 7cc305e1fd..41cd740ac0 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_enable_existing_node(void *blob); ++int fdt_simplefb_enable_and_mem_rsv(void *blob); + #endif +diff --git a/include/fdtdec.h b/include/fdtdec.h +index 8ac20c9a64..ecbdac2760 100644 +--- a/include/fdtdec.h ++++ b/include/fdtdec.h +@@ -24,16 +24,19 @@ + typedef phys_addr_t fdt_addr_t; + typedef phys_size_t fdt_size_t; + +-#define FDT_ADDR_T_NONE (-1U) + #define FDT_SIZE_T_NONE (-1U) + + #ifdef CONFIG_PHYS_64BIT ++#define FDT_ADDR_T_NONE ((ulong)(-1)) ++ + #define fdt_addr_to_cpu(reg) be64_to_cpu(reg) + #define fdt_size_to_cpu(reg) be64_to_cpu(reg) + #define cpu_to_fdt_addr(reg) cpu_to_be64(reg) + #define cpu_to_fdt_size(reg) cpu_to_be64(reg) + typedef fdt64_t fdt_val_t; + #else ++#define FDT_ADDR_T_NONE (-1U) ++ + #define fdt_addr_to_cpu(reg) be32_to_cpu(reg) + #define fdt_size_to_cpu(reg) be32_to_cpu(reg) + #define cpu_to_fdt_addr(reg) cpu_to_be32(reg) +diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h +index 3b302fb8c3..7455400981 100644 +--- a/include/linux/mtd/mtd.h ++++ b/include/linux/mtd/mtd.h +@@ -51,7 +51,6 @@ struct erase_info { + u_long retries; + unsigned dev; + unsigned cell; +- void (*callback) (struct erase_info *self); + u_long priv; + u_char state; + struct erase_info *next; +@@ -535,16 +534,6 @@ extern int unregister_mtd_user (struct mtd_notifier *old); + #endif + void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size); + +-#ifdef CONFIG_MTD_PARTITIONS +-void mtd_erase_callback(struct erase_info *instr); +-#else +-static inline void mtd_erase_callback(struct erase_info *instr) +-{ +- if (instr->callback) +- instr->callback(instr); +-} +-#endif +- + static inline int mtd_is_bitflip(int err) { + return err == -EUCLEAN; + } +diff --git a/include/nand.h b/include/nand.h +index 80dd6469bc..efe193078b 100644 +--- a/include/nand.h ++++ b/include/nand.h +@@ -68,7 +68,6 @@ static inline int nand_erase(struct mtd_info *info, loff_t off, size_t size) + instr.mtd = info; + instr.addr = off; + instr.len = size; +- instr.callback = 0; + + return mtd_erase(info, &instr); + } +diff --git a/include/netdev.h b/include/netdev.h +index 00a0993a83..24ff243567 100644 +--- a/include/netdev.h ++++ b/include/netdev.h +@@ -25,7 +25,7 @@ struct udevice; + + int board_eth_init(struct bd_info *bis); + int board_interface_eth_init(struct udevice *dev, +- phy_interface_t interface_type); ++ phy_interface_t interface_type, ulong rate); + int cpu_eth_init(struct bd_info *bis); + + /* Driver initialization prototypes */ +diff --git a/include/rproc_optee.h b/include/rproc_optee.h +new file mode 100644 +index 0000000000..13193bbe77 +--- /dev/null ++++ b/include/rproc_optee.h +@@ -0,0 +1,127 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) STMicroelectronics 2020 - All Rights Reserved ++ */ ++ ++#ifndef _RPROC_OPTEE_H_ ++#define _RPROC_OPTEE_H_ ++ ++/** ++ * struct rproc_optee - TEE remoteproc structure ++ * @tee: TEE device ++ * @fw_id: Identifier of the target firmware ++ * @session: TEE session identifier ++ */ ++struct rproc_optee { ++ struct udevice *tee; ++ u32 fw_id; ++ u32 session; ++}; ++ ++#if IS_ENABLED(CONFIG_REMOTEPROC_OPTEE) ++ ++/** ++ * rproc_optee_open() - open a rproc tee session ++ * ++ * Open a session towards the trusted application in charge of the remote ++ * processor. ++ * ++ * @trproc: OPTEE remoteproc context structure ++ * ++ * @return 0 if the session is opened, or an appropriate error value. ++ */ ++int rproc_optee_open(struct rproc_optee *trproc); ++ ++/** ++ * rproc_optee_close() - close a rproc tee session ++ * ++ * Close the trusted application session in charge of the remote processor. ++ * ++ * @trproc: OPTEE remoteproc context structure ++ * ++ * @return 0 on success, or an appropriate error value. ++ */ ++int rproc_optee_close(struct rproc_optee *trproc); ++ ++/** ++ * rproc_optee_start() - Request OP-TEE to start a remote processor ++ * ++ * @trproc: OPTEE remoteproc context structure ++ * ++ * @return 0 on success, or an appropriate error value. ++ */ ++int rproc_optee_start(struct rproc_optee *trproc); ++ ++/** ++ * rproc_optee_stop() - Request OP-TEE to stop a remote processor ++ * ++ * @trproc: OPTEE remoteproc context structure ++ * ++ * @return 0 on success, or an appropriate error value. ++ */ ++int rproc_optee_stop(struct rproc_optee *trproc); ++ ++/** ++ * rproc_optee_get_rsc_table() - Request OP-TEE the resource table ++ * ++ * Get the address and the size of the resource table. If no resource table is ++ * found, the size and address are null. ++ * ++ * @trproc: OPTEE remoteproc context structure ++ * @rsc_addr: out the physical address of the resource table returned ++ * @rsc_size: out the size of the resource table ++ * ++ * @return 0 on success, or an appropriate error value. ++ */ ++int rproc_optee_get_rsc_table(struct rproc_optee *trproc, phys_addr_t *rsc_addr, ++ phys_size_t *rsc_size); ++ ++/** ++ * rproc_optee_load() - load an signed ELF image ++ * ++ * @trproc: OPTEE remoteproc context structure ++ * @addr: valid ELF image address ++ * @size: size of the image ++ * ++ * @return 0 if the image is successfully loaded, else appropriate error value. ++ */ ++int rproc_optee_load(struct rproc_optee *trproc, ulong addr, ulong size); ++ ++#else ++ ++static inline int rproc_optee_open(struct rproc_optee *trproc) ++{ ++ return -ENOSYS; ++} ++ ++static inline int rproc_optee_close(struct rproc_optee *trproc) ++{ ++ return -ENOSYS; ++} ++ ++static inline int rproc_optee_start(struct rproc_optee *trproc) ++{ ++ return -ENOSYS; ++} ++ ++static inline int rproc_optee_stop(struct rproc_optee *trproc) ++{ ++ return -ENOSYS; ++} ++ ++static inline int rproc_optee_get_rsc_table(struct rproc_optee *trproc, ++ phys_addr_t *rsc_addr, ++ phys_size_t *rsc_size) ++{ ++ return -ENOSYS; ++} ++ ++static inline int rproc_optee_load(struct rproc_optee *trproc, ulong addr, ++ ulong size) ++{ ++ return -ENOSYS; ++} ++ ++#endif ++ ++#endif /* _RPROC_OPTEE_H_ */ +diff --git a/include/scmi_agent.h b/include/scmi_agent.h +index f1be9ff209..83af4c7809 100644 +--- a/include/scmi_agent.h ++++ b/include/scmi_agent.h +@@ -45,13 +45,13 @@ struct scmi_msg { + } + + /** +- * scmi_send_and_process_msg() - send and process a SCMI message ++ * devm_scmi_process_msg() - Send and process an SCMI message + * +- * Send a message to a SCMI server through a target SCMI agent device. ++ * Send a message to an SCMI server through a target SCMI agent device. + * Caller sets scmi_msg::out_msg_sz to the output message buffer size. + * On return, scmi_msg::out_msg_sz stores the response payload size. + * +- * @dev: SCMI agent device ++ * @dev: SCMI device + * @msg: Message structure reference + * @return 0 on success and a negative errno on failure + */ +diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h +index 2db71697e8..d4843f3619 100644 +--- a/include/scmi_protocols.h ++++ b/include/scmi_protocols.h +@@ -40,22 +40,65 @@ enum scmi_status_code { + SCMI_PROTOCOL_ERROR = -10, + }; + ++/* ++ * Generic message IDs ++ */ ++enum scmi_discovery_id { ++ SCMI_PROTOCOL_VERSION = 0x0, ++ SCMI_PROTOCOL_ATTRIBUTES = 0x1, ++ SCMI_PROTOCOL_MESSAGE_ATTRIBUTES = 0x2, ++}; ++ + /* + * SCMI Clock Protocol + */ + + enum scmi_clock_message_id { ++ SCMI_CLOCK_ATTRIBUTES = 0x3, + SCMI_CLOCK_RATE_SET = 0x5, + SCMI_CLOCK_RATE_GET = 0x6, + SCMI_CLOCK_CONFIG_SET = 0x7, + }; + ++#define SCMI_CLK_PROTO_ATTR_COUNT_MASK GENMASK(15, 0) + #define SCMI_CLK_RATE_ASYNC_NOTIFY BIT(0) + #define SCMI_CLK_RATE_ASYNC_NORESP (BIT(0) | BIT(1)) + #define SCMI_CLK_RATE_ROUND_DOWN 0 + #define SCMI_CLK_RATE_ROUND_UP BIT(2) + #define SCMI_CLK_RATE_ROUND_CLOSEST BIT(3) + ++#define SCMI_CLOCK_NAME_LENGTH_MAX 16 ++ ++/** ++ * struct scmi_clk_get_nb_out - Response for SCMI_PROTOCOL_ATTRIBUTES command ++ * @status: SCMI command status ++ * @attributes: Attributes of the clock protocol, mainly number of clocks exposed ++ */ ++struct scmi_clk_protocol_attr_out { ++ s32 status; ++ u32 attributes; ++}; ++ ++/** ++ * struct scmi_clk_attribute_in - Message payload for SCMI_CLOCK_ATTRIBUTES command ++ * @clock_id: SCMI clock ID ++ */ ++struct scmi_clk_attribute_in { ++ u32 clock_id; ++}; ++ ++/** ++ * struct scmi_clk_get_nb_out - Response payload for SCMI_CLOCK_ATTRIBUTES command ++ * @status: SCMI command status ++ * @attributes: clock attributes ++ * @clock_name: name of the clock ++ */ ++struct scmi_clk_attribute_out { ++ s32 status; ++ u32 attributes; ++ char clock_name[SCMI_CLOCK_NAME_LENGTH_MAX]; ++}; ++ + /** + * struct scmi_clk_state_in - Message payload for CLOCK_CONFIG_SET command + * @clock_id: SCMI clock ID +@@ -97,14 +140,14 @@ struct scmi_clk_rate_get_out { + + /** + * struct scmi_clk_state_in - Message payload for CLOCK_RATE_SET command +- * @clock_id: SCMI clock ID + * @flags: Flags for the clock rate set request ++ * @clock_id: SCMI clock ID + * @rate_lsb: 32bit LSB of the clock rate in Hertz + * @rate_msb: 32bit MSB of the clock rate in Hertz + */ + struct scmi_clk_rate_set_in { +- u32 clock_id; + u32 flags; ++ u32 clock_id; + u32 rate_lsb; + u32 rate_msb; + }; +@@ -195,6 +238,16 @@ enum scmi_voltage_domain_message_id { + #define SCMI_VOLTD_CONFIG_OFF 0 + #define SCMI_VOLTD_CONFIG_ON 0x7 + ++/** ++ * struct scmi_clk_state_in - Message payload for CLOCK_CONFIG_SET command ++ * @status: SCMI command status ++ * @attributes: Attributes of the voltage domain protocol ++ */ ++struct scmi_voltd_protocol_attr_out { ++ s32 status; ++ u32 attributes; ++}; ++ + /** + * struct scmi_voltd_attr_in - Payload for VOLTAGE_DOMAIN_ATTRIBUTES message + * @domain_id: SCMI voltage domain ID +diff --git a/include/spi_flash.h b/include/spi_flash.h +index 3d747c925b..4d4ae89c19 100644 +--- a/include/spi_flash.h ++++ b/include/spi_flash.h +@@ -165,6 +165,9 @@ static inline int spi_flash_read(struct spi_flash *flash, u32 offset, + struct mtd_info *mtd = &flash->mtd; + size_t retlen; + ++ if (!len) ++ return 0; ++ + return mtd->_read(mtd, offset, len, &retlen, buf); + } + +@@ -174,6 +177,9 @@ static inline int spi_flash_write(struct spi_flash *flash, u32 offset, + struct mtd_info *mtd = &flash->mtd; + size_t retlen; + ++ if (!len) ++ return 0; ++ + return mtd->_write(mtd, offset, len, &retlen, buf); + } + +@@ -188,6 +194,9 @@ static inline int spi_flash_erase(struct spi_flash *flash, u32 offset, + return -EINVAL; + } + ++ if (!len) ++ return 0; ++ + memset(&instr, 0, sizeof(instr)); + instr.addr = offset; + instr.len = len; +diff --git a/include/tee.h b/include/tee.h +index 2ef29bfc8f..3d76ae66cd 100644 +--- a/include/tee.h ++++ b/include/tee.h +@@ -31,6 +31,25 @@ + #define TEE_PARAM_ATTR_MASK (TEE_PARAM_ATTR_TYPE_MASK | \ + TEE_PARAM_ATTR_META) + ++/* ++ * Global Platform login identifiers for tee_open_session_arg::clnt_login ++ */ ++#define TEE_LOGIN_PUBLIC 0x00000000 ++#define TEE_LOGIN_USER 0x00000001 ++#define TEE_LOGIN_GROUP 0x00000002 ++#define TEE_LOGIN_APPLICATION 0x00000004 ++#define TEE_LOGIN_APPLICATION_USER 0x00000005 ++#define TEE_LOGIN_APPLICATION_GROUP 0x00000006 ++/* ++ * Reserve use of GP implementation specific login method range ++ * (0x80000000 - 0xBFFFFFFF). This range is rather being used ++ * for REE kernel clients or TEE implementation. ++ */ ++#define TEE_LOGIN_REE_KERNEL_MIN 0x80000000 ++#define TEE_LOGIN_REE_KERNEL_MAX 0xBFFFFFFF ++/* Private login method for REE kernel/privileged clients */ ++#define TEE_LOGIN_REE_KERNEL 0x80000000 ++ + /* + * Some Global Platform error codes which has a meaning if the + * TEE_GEN_CAP_GP bit is returned by the driver in +@@ -45,6 +64,7 @@ + #define TEE_ERROR_NOT_SUPPORTED 0xffff000a + #define TEE_ERROR_COMMUNICATION 0xffff000e + #define TEE_ERROR_SECURITY 0xffff000f ++#define TEE_ERROR_SHORT_BUFFER 0xffff0010 + #define TEE_ERROR_OUT_OF_MEMORY 0xffff000c + #define TEE_ERROR_OVERFLOW 0xffff300f + #define TEE_ERROR_TARGET_DEAD 0xffff3024 +@@ -135,8 +155,8 @@ struct tee_param { + /** + * struct tee_open_session_arg - extra arguments for tee_open_session() + * @uuid: [in] UUID of the Trusted Application +- * @clnt_uuid: [in] Normally zeroes +- * @clnt_login: [in] Normally 0 ++ * @clnt_uuid: [in] UUID of client, zeroes for PUBLIC/REE_KERNEL ++ * @clnt_login: [in] Class of client TEE_LOGIN_* + * @session: [out] Session id + * @ret: [out] return value + * @ret_origin: [out] origin of the return value +diff --git a/include/typec.h b/include/typec.h +new file mode 100644 +index 0000000000..9241da4614 +--- /dev/null ++++ b/include/typec.h +@@ -0,0 +1,154 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (C) 2021, STMicroelectronics - All Rights Reserved ++ */ ++ ++enum typec_state { ++ TYPEC_UNATTACHED, ++ TYPEC_ATTACHED, ++}; ++ ++enum typec_data_role { ++ TYPEC_DEVICE, ++ TYPEC_HOST, ++}; ++ ++/** ++ * struct typec_ops - driver I/O operations for TYPEC uclass ++ * ++ * Drivers should support 2 operations. These operations is intended ++ * to be used by uclass code, not directly from other code. ++ */ ++struct typec_ops { ++ /** ++ * is_attached() - Return if cable is attached ++ * ++ * @dev: TYPEC device to read from ++ * @con_idx: connector index (0 is the first one) ++ * @return TYPEC_UNATTACHED if not attached, TYPEC_ATTACHED if attached, -ve on error ++ */ ++ int (*is_attached)(struct udevice *dev, u8 con_idx); ++ ++ /** ++ * get_data_role() - Return data role (HOST or DEVICE) ++ * ++ * @dev: TYPEC device to read from ++ * @con_idx: connector index (0 is the first one) ++ * @return: TYPEC_DEVICE if device role, TYPEC_HOST if host role, -ve on error ++ */ ++ int (*get_data_role)(struct udevice *dev, u8 con_idx); ++ ++ /** ++ * get_nb_connector() - Return connector number managed by TypeC controller. ++ * ++ * @dev: TYPEC device to read from ++ * @return: number of connector managed by TypeC controller, -ve on error ++ */ ++ u8 (*get_nb_connector)(struct udevice *dev); ++}; ++ ++#ifdef CONFIG_TYPEC ++/** ++ * typec_is_attached() - Test if Type-C connector is attached ++ * ++ * @return TYPEC_ATTACHED if attached, TYPEC_UNATTACHED is not attached, ++ * or -ve on error. ++ */ ++int typec_is_attached(struct udevice *dev, u8 con_idx); ++ ++/** ++ * typec_get_data_role() - Return current Type-C data role ++ * ++ * @return TYPEC_DEVICE if attached to a host, TYPEC_HOST is attached to a ++ * device or -ve on error. ++ */ ++int typec_get_data_role(struct udevice *dev, u8 con_idx); ++ ++/** ++ * typec_get_nb_connector() - Return Type-C connector supported by controller ++ * ++ * @return Type-C connector number or -ve on error. ++ */ ++int typec_get_nb_connector(struct udevice *dev); ++ ++/** ++ * typec_get_device_from_usb() - Allows to retrieve a Type-C device from ++ * an USB device. typec_get_driver_from_usb() checks in USB device node ++ * for port and endpoint sub-node, if exist, retrieve the connector node, ++ * probe the associated Type-C device and return it (see DT example below). ++ * See Documentation/devicetree/bindings/connector/usb-connector.yaml for more ++ * details ++ * ++ * @dev: USB device ++ * @typec: Type-C device ++ * @index: USB controller port number ++ * @return -ve on error. ++ * ++ * usb_dwc3_0: usb@10000000 { ++ * ... ++ * port@0 { ++ * reg = <0>; ++ * typec_hs: endpoint { ++ * remote-endpoint = <&usb_con_hs>; ++ * }; ++ * }; ++ * ++ * port@1 { ++ * reg = <1>; ++ * typec_ss: endpoint { ++ * remote-endpoint = <&usb_con_ss>; ++ * }; ++ * }; ++ * }; ++ * ++ * usb-typec@1 { ++ * ... ++ * connector { ++ * compatible = "usb-c-connector"; ++ * label = "USB-C"; ++ * ++ * ports { ++ * #address-cells = <1>; ++ * #size-cells = <0>; ++ * ++ * port@0 { ++ * reg = <0>; ++ * usb_con_hs: endpoint { ++ * remote-endpoint = <&typec_hs>; ++ * }; ++ * }; ++ * ++ * port@1 { ++ * reg = <1>; ++ * usb_con_ss: endpoint { ++ * remote-endpoint = <&typec_ss>; ++ * }; ++ * }; ++ * }; ++ * }; ++ * }; ++ */ ++int typec_get_device_from_usb(struct udevice *dev, struct udevice **typec, u8 ++ index); ++#else ++static inline int typec_is_attached(struct udevice *dev, u8 con_idx) ++{ ++ return -ENODEV; ++} ++ ++static inline int typec_get_data_role(struct udevice *dev, u8 con_idx) ++{ ++ return -EINVAL; ++} ++ ++static inline int typec_get_nb_connector(struct udevice *dev) ++{ ++ return -EINVAL; ++} ++ ++static inline int typec_get_device_from_usb(struct udevice *dev, struct udevice **typec, ++ u8 index) ++{ ++ return -ENODEV; ++} ++#endif +diff --git a/include/ucsi.h b/include/ucsi.h +new file mode 100644 +index 0000000000..1c46e05481 +--- /dev/null ++++ b/include/ucsi.h +@@ -0,0 +1,112 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++ ++#ifndef _UCSI_H_ ++#define _UCSI_H_ ++ ++/* UCSI offsets (Bytes) */ ++#define UCSI_VERSION 0 ++#define UCSI_CCI 4 ++#define UCSI_CONTROL 8 ++#define UCSI_MESSAGE_IN 16 ++ ++/* Commands */ ++#define UCSI_PPM_RESET 0x01 ++#define UCSI_ACK_CC_CI 0x04 ++#define UCSI_SET_NOTIFICATION_ENABLE 0x05 ++#define UCSI_GET_CAPABILITY 0x06 ++#define UCSI_GET_ALTERNATE_MODES 0x0c ++#define UCSI_GET_CONNECTOR_STATUS 0x12 ++#define UCSI_GET_ERROR_STATUS 0x13 ++ ++#define UCSI_CONNECTOR_NUMBER(_num_) ((u64)(_num_) << 16) ++ ++/* ACK_CC_CI bits */ ++#define UCSI_ACK_CONNECTOR_CHANGE BIT(16) ++#define UCSI_ACK_COMMAND_COMPLETE BIT(17) ++ ++/* SET_NOTIFICATION_ENABLE command bits */ ++#define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE BIT(30) ++ ++/* Command Status and Connector Change Indication (CCI) bits */ ++#define UCSI_CCI_CONNECTOR(_c_) (((_c_) & GENMASK(7, 1)) >> 1) ++#define UCSI_CCI_LENGTH(_c_) (((_c_) & GENMASK(15, 8)) >> 8) ++#define UCSI_CCI_NOT_SUPPORTED BIT(25) ++#define UCSI_CCI_RESET_COMPLETE BIT(27) ++#define UCSI_CCI_BUSY BIT(28) ++#define UCSI_CCI_ERROR BIT(30) ++#define UCSI_CCI_COMMAND_COMPLETE BIT(31) ++ ++/* Error information returned by PPM in response to GET_ERROR_STATUS command. */ ++#define UCSI_ERROR_UNREGONIZED_CMD BIT(0) ++#define UCSI_ERROR_INVALID_CON_NUM BIT(1) ++#define UCSI_ERROR_INVALID_CMD_ARGUMENT BIT(2) ++#define UCSI_ERROR_INCOMPATIBLE_PARTNER BIT(3) ++#define UCSI_ERROR_CC_COMMUNICATION_ERR BIT(4) ++#define UCSI_ERROR_DEAD_BATTERY BIT(5) ++#define UCSI_ERROR_CONTRACT_NEGOTIATION_FAIL BIT(6) ++#define UCSI_ERROR_OVERCURRENT BIT(7) ++#define UCSI_ERROR_UNDEFINED BIT(8) ++#define UCSI_ERROR_PARTNER_REJECTED_SWAP BIT(9) ++#define UCSI_ERROR_HARD_RESET BIT(10) ++#define UCSI_ERROR_PPM_POLICY_CONFLICT BIT(11) ++#define UCSI_ERROR_SWAP_REJECTED BIT(12) ++ ++/* Data structure filled by PPM in response to GET_CAPABILITY command. */ ++struct ucsi_capability { ++ u32 attributes; ++ u8 num_connectors; ++ u8 features; ++ u16 reserved_1; ++ u8 num_alt_modes; ++ u8 reserved_2; ++ u16 bc_version; ++ u16 pd_version; ++ u16 typec_version; ++} __packed; ++ ++/* Data structure filled by PPM in response to GET_CONNECTOR_STATUS command. */ ++struct ucsi_connector_status { ++ u16 change; ++ u16 flags; ++#define UCSI_CONSTAT_CONNECTED BIT(3) ++#define UCSI_CONSTAT_PARTNER_TYPE(_f_) (((_f_) & GENMASK(15, 13)) >> 13) ++#define UCSI_CONSTAT_PARTNER_TYPE_DFP 1 ++#define UCSI_CONSTAT_PARTNER_TYPE_UFP 2 ++#define UCSI_CONSTAT_PARTNER_TYPE_CABLE 3 /* Powered Cable */ ++#define UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP 4 /* Powered Cable */ ++#define UCSI_CONSTAT_PARTNER_TYPE_DEBUG 5 ++#define UCSI_CONSTAT_PARTNER_TYPE_AUDIO 6 ++ u32 request_data_obj; ++ u8 pwr_status; ++} __packed; ++ ++/** ++ * struct ucsi_ops - driver I/O operations for UCSI uclass ++ * ++ * Drivers should support 2 operations. These operations are intended to be used ++ * by uclass code, not directly from other code. ++ */ ++struct ucsi_ops { ++ /** ++ * read() - Read operation ++ * ++ * @ucsi: UCSI device to read from ++ * @offset: UCSI data structure offset ++ * @buf: Buffer to receive the data ++ * @len Number of bytes to read ++ * @return 0 on success, -ve on failure ++ */ ++ int (*read)(struct udevice *ucsi, unsigned int offset, void *val, size_t len); ++ ++ /** ++ * write() - Write operation ++ * ++ * @ucsi: UCSI device to write to ++ * @offset: UCSI data structure offset ++ * @buf: Buffer data to write ++ * @len Number of bytes to write ++ * @return 0 on success, -ve on failure ++ */ ++ int (*write)(struct udevice *ucsi, unsigned int offset, const void *val, size_t len); ++}; ++#endif /* _UCSI_H_ */ +diff --git a/include/video.h b/include/video.h +index 827733305e..82da364a30 100644 +--- a/include/video.h ++++ b/include/video.h +@@ -267,6 +267,13 @@ static inline int video_sync_copy_all(struct udevice *dev) + + #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); ++ + #ifndef CONFIG_DM_VIDEO + + /* Video functions */ +diff --git a/lib/uuid.c b/lib/uuid.c +index 67267c66a3..e4703dce2b 100644 +--- a/lib/uuid.c ++++ b/lib/uuid.c +@@ -257,7 +257,7 @@ void gen_rand_uuid(unsigned char *uuid_bin) + + if (IS_ENABLED(CONFIG_DM_RNG)) { + ret = uclass_get_device(UCLASS_RNG, 0, &devp); +- if (ret) { ++ if (!ret) { + ret = dm_rng_read(devp, &randv, sizeof(randv)); + if (ret < 0) + randv = 0; +diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt +index a9c2380d17..a466bf1e00 100644 +--- a/scripts/config_whitelist.txt ++++ b/scripts/config_whitelist.txt +@@ -847,7 +847,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 +@@ -1423,10 +1422,6 @@ CONFIG_STACKBASE + CONFIG_STANDALONE_LOAD_ADDR + CONFIG_STATIC_BOARD_REV + CONFIG_STD_DEVICES_SETTINGS +-CONFIG_STM32_FLASH +-CONFIG_STV0991 +-CONFIG_STV0991_HZ +-CONFIG_STV0991_HZ_CLOCK + CONFIG_SXNI855T + CONFIG_SYSFS + CONFIG_SYSMGR_ISWGRP_HANDOFF +@@ -3414,7 +3409,6 @@ CONFIG_USB_TUSB_OMAP_DMA + CONFIG_USB_ULPI_TIMEOUT + CONFIG_USB_XHCI_EXYNOS + CONFIG_USB_XHCI_OMAP +-CONFIG_USER_LOWLEVEL_INIT + CONFIG_USE_INTERRUPT + CONFIG_USE_ONENAND_BOARD_INIT + CONFIG_UTBIPAR_INIT_TBIPA +diff --git a/test/cmd/pinmux.c b/test/cmd/pinmux.c +index 8ae807b537..64392af506 100644 +--- a/test/cmd/pinmux.c ++++ b/test/cmd/pinmux.c +@@ -16,12 +16,12 @@ static int dm_test_cmd_pinmux_status_pinname(struct unit_test_state *uts) + /* Test that 'pinmux status ' displays the selected pin. */ + console_record_reset(); + run_command("pinmux status a5", 0); +- ut_assert_nextline("a5 : gpio input . "); ++ ut_assert_nextline("a5 : gpio input . "); + ut_assert_console_end(); + + console_record_reset(); + run_command("pinmux status P7", 0); +- ut_assert_nextline("P7 : GPIO2 bias-pull-down input-enable. "); ++ ut_assert_nextline("P7 : GPIO2 bias-pull-down input-enable. "); + ut_assert_console_end(); + + console_record_reset(); +diff --git a/test/dm/nop.c b/test/dm/nop.c +index 2cd92c5240..75b9e7b6cc 100644 +--- a/test/dm/nop.c ++++ b/test/dm/nop.c +@@ -25,7 +25,7 @@ static int noptest_bind(struct udevice *parent) + const char *bind_flag = ofnode_read_string(ofnode, "bind"); + + if (bind_flag && (strcmp(bind_flag, "True") == 0)) +- lists_bind_fdt(parent, ofnode, &dev, false); ++ lists_bind_fdt(parent, ofnode, &dev, NULL, false); + ofnode = dev_read_next_subnode(ofnode); + } + +diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c +index 44e51de085..421459835d 100644 +--- a/test/dm/ofnode.c ++++ b/test/dm/ofnode.c +@@ -286,7 +286,7 @@ static int dm_test_ofnode_get_reg(struct unit_test_state *uts) + ut_assert(ofnode_valid(node)); + addr = ofnode_get_addr(node); + size = ofnode_get_size(node); +- ut_asserteq(FDT_ADDR_T_NONE, addr); ++ ut_asserteq_64(FDT_ADDR_T_NONE, addr); + ut_asserteq(FDT_SIZE_T_NONE, size); + + node = ofnode_path("/translation-test@8000/noxlatebus@3,300/dev@42"); +diff --git a/test/dm/pci.c b/test/dm/pci.c +index fa2e4a8559..00e4440a9d 100644 +--- a/test/dm/pci.c ++++ b/test/dm/pci.c +@@ -331,10 +331,10 @@ static int dm_test_pci_addr_live(struct unit_test_state *uts) + struct udevice *swap1f, *swap1; + + ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap1f)); +- ut_asserteq(FDT_ADDR_T_NONE, dev_read_addr_pci(swap1f)); ++ ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr_pci(swap1f)); + + ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1, 0), &swap1)); +- ut_asserteq(FDT_ADDR_T_NONE, dev_read_addr_pci(swap1)); ++ ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr_pci(swap1)); + + return 0; + } +diff --git a/test/dm/scmi.c b/test/dm/scmi.c +index c938e6d4fc..2149904585 100644 +--- a/test/dm/scmi.c ++++ b/test/dm/scmi.c +@@ -5,7 +5,7 @@ + * Tests scmi_agent uclass and the SCMI drivers implemented in other + * uclass devices probe when a SCMI server exposes resources. + * +- * Note in test.dts the protocol@10 node in agent 1. Protocol 0x10 is not ++ * Note in test.dts the protocol@10 node in scmi node. Protocol 0x10 is not + * implemented in U-Boot SCMI components but the implementation is exepected + * to not complain on unknown protocol IDs, as long as it is not used. Note + * in test.dts tests that SCMI drivers probing does not fail for such an +@@ -28,8 +28,7 @@ static int ut_assert_scmi_state_preprobe(struct unit_test_state *uts) + struct sandbox_scmi_service *scmi_ctx = sandbox_scmi_service_ctx(); + + ut_assertnonnull(scmi_ctx); +- if (scmi_ctx->agent_count) +- ut_asserteq(2, scmi_ctx->agent_count); ++ ut_assertnull(scmi_ctx->agent); + + return 0; + } +@@ -39,35 +38,28 @@ static int ut_assert_scmi_state_postprobe(struct unit_test_state *uts, + { + struct sandbox_scmi_devices *scmi_devices; + struct sandbox_scmi_service *scmi_ctx; +- struct sandbox_scmi_agent *agent0; +- struct sandbox_scmi_agent *agent1; ++ struct sandbox_scmi_agent *agent; + + /* Device references to check context against test sequence */ + scmi_devices = sandbox_scmi_devices_ctx(dev); +- + ut_assertnonnull(scmi_devices); +- ut_asserteq(3, scmi_devices->clk_count); ++ ++ ut_asserteq(2, scmi_devices->clk_count); + ut_asserteq(1, scmi_devices->reset_count); + ut_asserteq(2, scmi_devices->regul_count); + + /* State of the simulated SCMI server exposed */ + scmi_ctx = sandbox_scmi_service_ctx(); +- agent0 = scmi_ctx->agent[0]; +- agent1 = scmi_ctx->agent[1]; +- +- ut_asserteq(2, scmi_ctx->agent_count); +- +- ut_assertnonnull(agent0); +- ut_asserteq(2, agent0->clk_count); +- ut_assertnonnull(agent0->clk); +- ut_asserteq(1, agent0->reset_count); +- ut_assertnonnull(agent0->reset); +- ut_asserteq(2, agent0->voltd_count); +- ut_assertnonnull(agent0->voltd); ++ ut_assertnonnull(scmi_ctx); ++ agent = scmi_ctx->agent; ++ ut_assertnonnull(agent); + +- ut_assertnonnull(agent1); +- ut_assertnonnull(agent1->clk); +- ut_asserteq(1, agent1->clk_count); ++ ut_asserteq(3, agent->clk_count); ++ ut_assertnonnull(agent->clk); ++ ut_asserteq(1, agent->reset_count); ++ ut_assertnonnull(agent->reset); ++ ut_asserteq(7, agent->voltd_count); ++ ut_assertnonnull(agent->voltd); + + return 0; + } +@@ -118,9 +110,8 @@ static int dm_test_scmi_clocks(struct unit_test_state *uts) + { + struct sandbox_scmi_devices *scmi_devices; + struct sandbox_scmi_service *scmi_ctx; +- struct sandbox_scmi_agent *agent0; +- struct sandbox_scmi_agent *agent1; +- struct udevice *dev = NULL; ++ struct sandbox_scmi_agent *agent; ++ struct udevice *dev; + int ret_dev; + int ret; + +@@ -129,48 +120,51 @@ static int dm_test_scmi_clocks(struct unit_test_state *uts) + return ret; + + scmi_devices = sandbox_scmi_devices_ctx(dev); ++ ut_assertnonnull(scmi_devices); ++ + scmi_ctx = sandbox_scmi_service_ctx(); +- agent0 = scmi_ctx->agent[0]; +- agent1 = scmi_ctx->agent[1]; ++ ut_assertnonnull(scmi_ctx); ++ agent = scmi_ctx->agent; ++ ut_assertnonnull(agent); + + /* Test SCMI clocks rate manipulation */ ++ ut_asserteq(333, agent->clk[0].rate); ++ ut_asserteq(200, agent->clk[1].rate); ++ ut_asserteq(1000, agent->clk[2].rate); ++ + ut_asserteq(1000, clk_get_rate(&scmi_devices->clk[0])); + ut_asserteq(333, clk_get_rate(&scmi_devices->clk[1])); +- ut_asserteq(44, clk_get_rate(&scmi_devices->clk[2])); + + ret_dev = clk_set_rate(&scmi_devices->clk[1], 1088); + ut_assert(!ret_dev || ret_dev == 1088); + +- ut_asserteq(1000, agent0->clk[0].rate); +- ut_asserteq(1088, agent0->clk[1].rate); +- ut_asserteq(44, agent1->clk[0].rate); ++ ut_asserteq(1088, agent->clk[0].rate); ++ ut_asserteq(200, agent->clk[1].rate); ++ ut_asserteq(1000, agent->clk[2].rate); + + ut_asserteq(1000, clk_get_rate(&scmi_devices->clk[0])); + ut_asserteq(1088, clk_get_rate(&scmi_devices->clk[1])); +- ut_asserteq(44, clk_get_rate(&scmi_devices->clk[2])); + + /* restore original rate for further tests */ + ret_dev = clk_set_rate(&scmi_devices->clk[1], 333); + ut_assert(!ret_dev || ret_dev == 333); + + /* Test SCMI clocks gating manipulation */ +- ut_assert(!agent0->clk[0].enabled); +- ut_assert(!agent0->clk[1].enabled); +- ut_assert(!agent1->clk[0].enabled); ++ ut_assert(!agent->clk[0].enabled); ++ ut_assert(!agent->clk[1].enabled); ++ ut_assert(!agent->clk[2].enabled); + + ut_asserteq(0, clk_enable(&scmi_devices->clk[1])); +- ut_asserteq(0, clk_enable(&scmi_devices->clk[2])); + +- ut_assert(!agent0->clk[0].enabled); +- ut_assert(agent0->clk[1].enabled); +- ut_assert(agent1->clk[0].enabled); ++ ut_assert(agent->clk[0].enabled); ++ ut_assert(!agent->clk[1].enabled); ++ ut_assert(!agent->clk[2].enabled); + + ut_assertok(clk_disable(&scmi_devices->clk[1])); +- ut_assertok(clk_disable(&scmi_devices->clk[2])); + +- ut_assert(!agent0->clk[0].enabled); +- ut_assert(!agent0->clk[1].enabled); +- ut_assert(!agent1->clk[0].enabled); ++ ut_assert(!agent->clk[0].enabled); ++ ut_assert(!agent->clk[1].enabled); ++ ut_assert(!agent->clk[2].enabled); + + return release_sandbox_scmi_test_devices(uts, dev); + } +@@ -180,7 +174,7 @@ static int dm_test_scmi_resets(struct unit_test_state *uts) + { + struct sandbox_scmi_devices *scmi_devices; + struct sandbox_scmi_service *scmi_ctx; +- struct sandbox_scmi_agent *agent0; ++ struct sandbox_scmi_agent *agent; + struct udevice *dev = NULL; + int ret; + +@@ -189,17 +183,21 @@ static int dm_test_scmi_resets(struct unit_test_state *uts) + return ret; + + scmi_devices = sandbox_scmi_devices_ctx(dev); ++ ut_assertnonnull(scmi_devices); ++ + scmi_ctx = sandbox_scmi_service_ctx(); +- agent0 = scmi_ctx->agent[0]; ++ ut_assertnonnull(scmi_ctx); ++ agent = scmi_ctx->agent; ++ ut_assertnonnull(agent); + + /* Test SCMI resect controller manipulation */ +- ut_assert(!agent0->reset[0].asserted) ++ ut_assert(!agent->reset[0].asserted) + + ut_assertok(reset_assert(&scmi_devices->reset[0])); +- ut_assert(agent0->reset[0].asserted) ++ ut_assert(agent->reset[0].asserted) + + ut_assertok(reset_deassert(&scmi_devices->reset[0])); +- ut_assert(!agent0->reset[0].asserted); ++ ut_assert(!agent->reset[0].asserted); + + return release_sandbox_scmi_test_devices(uts, dev); + } +@@ -209,7 +207,7 @@ static int dm_test_scmi_voltage_domains(struct unit_test_state *uts) + { + struct sandbox_scmi_devices *scmi_devices; + struct sandbox_scmi_service *scmi_ctx; +- struct sandbox_scmi_agent *agent0; ++ struct sandbox_scmi_agent *agent; + struct dm_regulator_uclass_plat *uc_pdata; + struct udevice *dev; + struct udevice *regul0_dev; +@@ -217,8 +215,12 @@ static int dm_test_scmi_voltage_domains(struct unit_test_state *uts) + ut_assertok(load_sandbox_scmi_test_devices(uts, &dev)); + + scmi_devices = sandbox_scmi_devices_ctx(dev); ++ ut_assertnonnull(scmi_devices); ++ + scmi_ctx = sandbox_scmi_service_ctx(); +- agent0 = scmi_ctx->agent[0]; ++ ut_assertnonnull(scmi_ctx); ++ agent = scmi_ctx->agent; ++ ut_assertnonnull(agent); + + /* Set/Get an SCMI voltage domain level */ + regul0_dev = scmi_devices->regul[0]; +@@ -228,32 +230,38 @@ static int dm_test_scmi_voltage_domains(struct unit_test_state *uts) + ut_assert(uc_pdata); + + ut_assertok(regulator_set_value(regul0_dev, uc_pdata->min_uV)); +- ut_asserteq(agent0->voltd[0].voltage_uv, uc_pdata->min_uV); ++ ut_asserteq(agent->voltd[0].voltage_uv, uc_pdata->min_uV); + + ut_assert(regulator_get_value(regul0_dev) == uc_pdata->min_uV); + + ut_assertok(regulator_set_value(regul0_dev, uc_pdata->max_uV)); +- ut_asserteq(agent0->voltd[0].voltage_uv, uc_pdata->max_uV); ++ ut_asserteq(agent->voltd[0].voltage_uv, uc_pdata->max_uV); + + ut_assert(regulator_get_value(regul0_dev) == uc_pdata->max_uV); + + /* Enable/disable SCMI voltage domains */ ++ /* ++ * Note: regul[0] supplies regul[1], as defined in the DT. Supply ++ * is considered only on regulator enable requests since U-Boot ++ * does not make any reference count on enable/disable requests ++ * from consumers. ++ */ + ut_assertok(regulator_set_enable(scmi_devices->regul[0], false)); + ut_assertok(regulator_set_enable(scmi_devices->regul[1], false)); +- ut_assert(!agent0->voltd[0].enabled); +- ut_assert(!agent0->voltd[1].enabled); +- +- ut_assertok(regulator_set_enable(scmi_devices->regul[0], true)); +- ut_assert(agent0->voltd[0].enabled); +- ut_assert(!agent0->voltd[1].enabled); ++ ut_assert(!agent->voltd[0].enabled); ++ ut_assert(!agent->voltd[1].enabled); + + ut_assertok(regulator_set_enable(scmi_devices->regul[1], true)); +- ut_assert(agent0->voltd[0].enabled); +- ut_assert(agent0->voltd[1].enabled); ++ ut_assert(agent->voltd[0].enabled); ++ ut_assert(agent->voltd[1].enabled); ++ ++ ut_assertok(regulator_set_enable(scmi_devices->regul[1], false)); ++ ut_assert(agent->voltd[0].enabled); ++ ut_assert(!agent->voltd[1].enabled); + + ut_assertok(regulator_set_enable(scmi_devices->regul[0], false)); +- ut_assert(!agent0->voltd[0].enabled); +- ut_assert(agent0->voltd[1].enabled); ++ ut_assert(!agent->voltd[0].enabled); ++ ut_assert(!agent->voltd[1].enabled); + + return release_sandbox_scmi_test_devices(uts, dev); + } +diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c +index 8866d4d959..e1de066226 100644 +--- a/test/dm/test-fdt.c ++++ b/test/dm/test-fdt.c +@@ -768,7 +768,7 @@ static int dm_test_fdt_livetree_writing(struct unit_test_state *uts) + /* Test setting generic properties */ + + /* Non-existent in DTB */ +- ut_asserteq(FDT_ADDR_T_NONE, dev_read_addr(dev)); ++ ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr(dev)); + /* reg = 0x42, size = 0x100 */ + ut_assertok(ofnode_write_prop(node, "reg", 8, + "\x00\x00\x00\x42\x00\x00\x01\x00")); +diff --git a/test/py/tests/test_bind.py b/test/py/tests/test_bind.py +index 6703325c0b..9f234fb635 100644 +--- a/test/py/tests/test_bind.py ++++ b/test/py/tests/test_bind.py +@@ -33,6 +33,13 @@ def test_bind_unbind_with_node(u_boot_console): + assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False) + assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True) + ++ #bind usb_ether driver (which has no compatible) to usb@1 node. ++ ##New entry usb_ether should appear in the dm tree ++ response = u_boot_console.run_command('bind /usb@1 usb_ether') ++ assert response == '' ++ tree = u_boot_console.run_command('dm tree') ++ assert in_tree(tree, 'usb@1', 'ethernet', 'usb_ether', 1, True) ++ + #Unbind child #1. No error expected and all devices should be there except for bind-test-child1 + response = u_boot_console.run_command('unbind /bind-test/bind-test-child1') + assert response == '' +diff --git a/test/py/tests/test_log.py b/test/py/tests/test_log.py +index 140dcb9aa2..20a3e56301 100644 +--- a/test/py/tests/test_log.py ++++ b/test/py/tests/test_log.py +@@ -27,13 +27,13 @@ def test_log_format(u_boot_console): + + cons = u_boot_console + with cons.log.section('format'): +- run_with_format('all', 'NOTICE.arch,file.c:123-func() msg') ++ run_with_format('all', 'NOTICE.arch,file.c:123- func() msg') + output = cons.run_command('log format') + assert output == 'Log format: clFLfm' + +- run_with_format('fm', 'func() msg') +- run_with_format('clfm', 'NOTICE.arch,func() msg') +- run_with_format('FLfm', 'file.c:123-func() msg') ++ run_with_format('fm', ' func() msg') ++ run_with_format('clfm', 'NOTICE.arch, func() msg') ++ run_with_format('FLfm', 'file.c:123- func() msg') + run_with_format('lm', 'NOTICE. msg') + run_with_format('m', 'msg') + +diff --git a/test/py/tests/test_pinmux.py b/test/py/tests/test_pinmux.py +index b3ae2ab024..2411937773 100644 +--- a/test/py/tests/test_pinmux.py ++++ b/test/py/tests/test_pinmux.py +@@ -24,19 +24,19 @@ def test_pinmux_status_all(u_boot_console): + output = u_boot_console.run_command('pinmux status -a') + + assert ('pinctrl-gpio:' in output) +- assert ('a5 : gpio output .' in output) +- assert ('a6 : gpio output .' in output) ++ assert ('a5 : gpio output .' in output) ++ assert ('a6 : gpio output .' in output) + + assert ('pinctrl:' in output) +- assert ('P0 : UART TX.' in output) +- assert ('P1 : UART RX.' in output) +- assert ('P2 : I2S SCK.' in output) +- assert ('P3 : I2S SD.' in output) +- assert ('P4 : I2S WS.' in output) +- assert ('P5 : GPIO0 bias-pull-up input-disable.' in output) +- assert ('P6 : GPIO1 drive-open-drain.' in output) +- assert ('P7 : GPIO2 bias-pull-down input-enable.' in output) +- assert ('P8 : GPIO3 bias-disable.' in output) ++ assert ('P0 : UART TX.' in output) ++ assert ('P1 : UART RX.' in output) ++ assert ('P2 : I2S SCK.' in output) ++ assert ('P3 : I2S SD.' in output) ++ assert ('P4 : I2S WS.' in output) ++ assert ('P5 : GPIO0 bias-pull-up input-disable.' in output) ++ assert ('P6 : GPIO1 drive-open-drain.' in output) ++ assert ('P7 : GPIO2 bias-pull-down input-enable.' in output) ++ assert ('P8 : GPIO3 bias-disable.' in output) + + @pytest.mark.buildconfigspec('cmd_pinmux') + @pytest.mark.boardspec('sandbox') +@@ -73,12 +73,12 @@ def test_pinmux_status(u_boot_console): + assert (not 'pinctrl-gpio:' in output) + assert (not 'pinctrl:' in output) + +- assert ('P0 : UART TX.' in output) +- assert ('P1 : UART RX.' in output) +- assert ('P2 : I2S SCK.' in output) +- assert ('P3 : I2S SD.' in output) +- assert ('P4 : I2S WS.' in output) +- assert ('P5 : GPIO0 bias-pull-up input-disable.' in output) +- assert ('P6 : GPIO1 drive-open-drain.' in output) +- assert ('P7 : GPIO2 bias-pull-down input-enable.' in output) +- assert ('P8 : GPIO3 bias-disable.' in output) ++ assert ('P0 : UART TX.' in output) ++ assert ('P1 : UART RX.' in output) ++ assert ('P2 : I2S SCK.' in output) ++ assert ('P3 : I2S SD.' in output) ++ assert ('P4 : I2S WS.' in output) ++ assert ('P5 : GPIO0 bias-pull-up input-disable.' in output) ++ assert ('P6 : GPIO1 drive-open-drain.' in output) ++ assert ('P7 : GPIO2 bias-pull-down input-enable.' in output) ++ assert ('P8 : GPIO3 bias-disable.' in output) +-- +2.25.1 + diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0004-ARM-v2020.10-stm32mp-r1-DEVICETREE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0004-ARM-v2021.10-stm32mp-r1-DEVICETREE.patch similarity index 51% rename from recipes-bsp/u-boot/u-boot-stm32mp/0004-ARM-v2020.10-stm32mp-r1-DEVICETREE.patch rename to recipes-bsp/u-boot/u-boot-stm32mp/0004-ARM-v2021.10-stm32mp-r1-DEVICETREE.patch index 8f55b7c..0b973d7 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0004-ARM-v2020.10-stm32mp-r1-DEVICETREE.patch +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0004-ARM-v2021.10-stm32mp-r1-DEVICETREE.patch @@ -1,56 +1,97 @@ -From 4b29a8f65f3b9cf38b49f716b1f1bee094048be8 Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Tue, 16 Mar 2021 08:14:20 +0100 -Subject: [PATCH 4/5] ARM v2020.10-stm32mp-r1 DEVICETREE +From e28e03b91ec6d89fdf9463ca581510dff6b091ac Mon Sep 17 00:00:00 2001 +From: Christophe Priouzeau +Date: Mon, 30 May 2022 09:47:18 +0200 +Subject: [PATCH 4/5] ARM-v2021.10-stm32mp-r1-DEVICETREE -Signed-off-by: Romuald JEANNE --- - arch/arm/dts/Makefile | 10 +- - arch/arm/dts/stm32mp15-ddr.dtsi | 3 +- - .../dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi | 2 +- - .../dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi | 2 +- - arch/arm/dts/stm32mp15-m4-srm-pinctrl.dtsi | 524 +++++++++++++ - arch/arm/dts/stm32mp15-m4-srm.dtsi | 442 +++++++++++ - arch/arm/dts/stm32mp15-no-scmi.dtsi | 157 ++++ - arch/arm/dts/stm32mp15-pinctrl.dtsi | 428 +++++++++-- - arch/arm/dts/stm32mp15-u-boot.dtsi | 141 ++-- - arch/arm/dts/stm32mp151.dtsi | 631 +++++++++++----- - arch/arm/dts/stm32mp153.dtsi | 14 +- - arch/arm/dts/stm32mp157.dtsi | 3 +- - arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi | 21 +- - arch/arm/dts/stm32mp157a-dk1.dts | 4 +- - arch/arm/dts/stm32mp157a-ed1-u-boot.dtsi | 228 ++++++ - arch/arm/dts/stm32mp157a-ed1.dts | 32 + - arch/arm/dts/stm32mp157a-ev1-u-boot.dtsi | 62 ++ - arch/arm/dts/stm32mp157a-ev1.dts | 88 +++ - arch/arm/dts/stm32mp157c-dk2.dts | 77 +- - arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi | 215 +----- - arch/arm/dts/stm32mp157c-ed1.dts | 355 +-------- - arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi | 49 +- - arch/arm/dts/stm32mp157c-ev1.dts | 317 +------- - .../dts/stm32mp157c-odyssey-som-u-boot.dtsi | 4 + - arch/arm/dts/stm32mp157d-dk1-u-boot.dtsi | 6 + - arch/arm/dts/stm32mp157d-dk1.dts | 28 + - arch/arm/dts/stm32mp157d-ed1-u-boot.dtsi | 6 + - arch/arm/dts/stm32mp157d-ed1.dts | 33 + - arch/arm/dts/stm32mp157d-ev1-u-boot.dtsi | 6 + - arch/arm/dts/stm32mp157d-ev1.dts | 88 +++ - arch/arm/dts/stm32mp157f-dk2-u-boot.dtsi | 6 + - arch/arm/dts/stm32mp157f-dk2.dts | 157 ++++ - arch/arm/dts/stm32mp157f-ed1-u-boot.dtsi | 6 + - arch/arm/dts/stm32mp157f-ed1.dts | 37 + - arch/arm/dts/stm32mp157f-ev1-u-boot.dtsi | 6 + - arch/arm/dts/stm32mp157f-ev1.dts | 89 +++ - arch/arm/dts/stm32mp15xa.dtsi | 13 + - arch/arm/dts/stm32mp15xc.dtsi | 6 +- - arch/arm/dts/stm32mp15xd.dtsi | 42 ++ - arch/arm/dts/stm32mp15xf.dtsi | 20 + - arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi | 2 + - arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi | 2 + - arch/arm/dts/stm32mp15xx-dkx.dtsi | 165 ++++- - arch/arm/dts/stm32mp15xx-edx.dtsi | 413 +++++++++++ - arch/arm/dts/stm32mp15xx-evx.dtsi | 686 ++++++++++++++++++ - 45 files changed, 4407 insertions(+), 1219 deletions(-) + arch/arm/dts/Makefile | 14 +- + arch/arm/dts/stm32429i-eval-u-boot.dtsi | 2 +- + arch/arm/dts/stm32746g-eval-u-boot.dtsi | 2 +- + arch/arm/dts/stm32f429-disco-u-boot.dtsi | 2 +- + arch/arm/dts/stm32f469-disco-u-boot.dtsi | 6 +- + arch/arm/dts/stm32f7-u-boot.dtsi | 4 +- + arch/arm/dts/stm32f746-disco-u-boot.dtsi | 2 +- + arch/arm/dts/stm32f746.dtsi | 4 + + arch/arm/dts/stm32f769-disco-u-boot.dtsi | 6 +- + arch/arm/dts/stm32h743.dtsi | 4 + + arch/arm/dts/stm32mp13-pinctrl.dtsi | 644 +++++++ + arch/arm/dts/stm32mp13-u-boot.dtsi | 131 ++ + arch/arm/dts/stm32mp131.dtsi | 1664 +++++++++++++++++ + arch/arm/dts/stm32mp133.dtsi | 87 + + arch/arm/dts/stm32mp135.dtsi | 32 + + arch/arm/dts/stm32mp135d-dk-u-boot.dtsi | 70 + + arch/arm/dts/stm32mp135d-dk.dts | 687 +++++++ + arch/arm/dts/stm32mp135f-dk-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp135f-dk.dts | 689 +++++++ + arch/arm/dts/stm32mp13xa.dtsi | 5 + + arch/arm/dts/stm32mp13xc.dtsi | 18 + + arch/arm/dts/stm32mp13xd.dtsi | 5 + + arch/arm/dts/stm32mp13xf.dtsi | 18 + + arch/arm/dts/stm32mp15-ddr.dtsi | 47 +- + .../dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi | 12 - + .../dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi | 12 - + .../stm32mp15-ddr3-dhsom-2x1Gb-1066-binG.dtsi | 12 - + .../stm32mp15-ddr3-dhsom-2x2Gb-1066-binG.dtsi | 12 - + .../stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi | 12 - + .../stm32mp15-ddr3-icore-1x4Gb-1066-binG.dtsi | 12 - + arch/arm/dts/stm32mp15-m4-srm-pinctrl.dtsi | 524 ++++++ + arch/arm/dts/stm32mp15-m4-srm.dtsi | 447 +++++ + arch/arm/dts/stm32mp15-no-scmi.dtsi | 152 ++ + arch/arm/dts/stm32mp15-pinctrl.dtsi | 184 +- + arch/arm/dts/stm32mp15-u-boot.dtsi | 181 +- + arch/arm/dts/stm32mp151.dtsi | 576 ++++-- + arch/arm/dts/stm32mp153.dtsi | 15 +- + arch/arm/dts/stm32mp157.dtsi | 3 +- + arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi | 29 +- + arch/arm/dts/stm32mp157a-dk1.dts | 8 +- + arch/arm/dts/stm32mp157a-ed1-u-boot.dtsi | 211 +++ + arch/arm/dts/stm32mp157a-ed1.dts | 32 + + arch/arm/dts/stm32mp157a-ev1-u-boot.dtsi | 61 + + arch/arm/dts/stm32mp157a-ev1.dts | 103 + + .../stm32mp157a-icore-stm32mp1-u-boot.dtsi | 2 + + .../stm32mp157a-microgea-stm32mp1-u-boot.dtsi | 2 + + arch/arm/dts/stm32mp157c-dk2.dts | 65 +- + arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi | 222 +-- + arch/arm/dts/stm32mp157c-ed1.dts | 382 +--- + arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi | 49 +- + arch/arm/dts/stm32mp157c-ev1.dts | 326 +--- + .../dts/stm32mp157c-odyssey-som-u-boot.dtsi | 4 + + arch/arm/dts/stm32mp157d-dk1-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp157d-dk1.dts | 26 + + arch/arm/dts/stm32mp157d-ed1-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp157d-ed1.dts | 32 + + arch/arm/dts/stm32mp157d-ev1-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp157d-ev1.dts | 103 + + arch/arm/dts/stm32mp157f-dk2-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp157f-dk2.dts | 152 ++ + arch/arm/dts/stm32mp157f-ed1-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp157f-ed1.dts | 36 + + arch/arm/dts/stm32mp157f-ev1-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp157f-ev1.dts | 99 + + arch/arm/dts/stm32mp15xa.dtsi | 13 + + arch/arm/dts/stm32mp15xc.dtsi | 6 +- + arch/arm/dts/stm32mp15xd.dtsi | 42 + + arch/arm/dts/stm32mp15xf.dtsi | 20 + + arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi | 15 +- + .../stm32mp15xx-dhcor-avenger96-u-boot.dtsi | 15 + + arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi | 11 +- + arch/arm/dts/stm32mp15xx-dkx.dtsi | 144 +- + arch/arm/dts/stm32mp15xx-edx.dtsi | 419 +++++ + arch/arm/dts/stm32mp15xx-evx.dtsi | 690 +++++++ + 74 files changed, 8228 insertions(+), 1430 deletions(-) + create mode 100644 arch/arm/dts/stm32mp13-pinctrl.dtsi + create mode 100644 arch/arm/dts/stm32mp13-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp131.dtsi + create mode 100644 arch/arm/dts/stm32mp133.dtsi + create mode 100644 arch/arm/dts/stm32mp135.dtsi + create mode 100644 arch/arm/dts/stm32mp135d-dk-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp135d-dk.dts + create mode 100644 arch/arm/dts/stm32mp135f-dk-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp135f-dk.dts + create mode 100644 arch/arm/dts/stm32mp13xa.dtsi + create mode 100644 arch/arm/dts/stm32mp13xc.dtsi + create mode 100644 arch/arm/dts/stm32mp13xd.dtsi + create mode 100644 arch/arm/dts/stm32mp13xf.dtsi create mode 100644 arch/arm/dts/stm32mp15-m4-srm-pinctrl.dtsi create mode 100644 arch/arm/dts/stm32mp15-m4-srm.dtsi create mode 100644 arch/arm/dts/stm32mp15-no-scmi.dtsi @@ -77,20 +118,27 @@ Signed-off-by: Romuald JEANNE create mode 100644 arch/arm/dts/stm32mp15xx-evx.dtsi diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile -index f8f529435b..83677c3d4f 100644 +index fc16a57e60..cb6e07726e 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile -@@ -943,13 +943,21 @@ dtb-$(CONFIG_ARCH_ASPEED) += ast2500-evb.dtb +@@ -1074,9 +1074,15 @@ dtb-$(CONFIG_ASPEED_AST2600) += ast2600-evb.dtb + dtb-$(CONFIG_ARCH_STI) += stih410-b2260.dtb ++dtb-$(CONFIG_STM32MP13x) += \ ++ stm32mp135d-dk.dtb \ ++ stm32mp135f-dk.dtb ++ dtb-$(CONFIG_STM32MP15x) += \ - stm32mp157a-dk1.dtb \ stm32mp157a-avenger96.dtb \ + stm32mp157a-dk1.dtb \ + stm32mp157a-ed1.dtb \ + stm32mp157a-ev1.dtb \ - stm32mp157c-dk2.dtb \ - stm32mp157c-ed1.dtb \ + stm32mp157a-icore-stm32mp1-ctouch2.dtb \ + stm32mp157a-icore-stm32mp1-edimm2.2.dtb \ + stm32mp157a-microgea-stm32mp1-microdev2.0.dtb \ +@@ -1086,6 +1092,12 @@ dtb-$(CONFIG_STM32MP15x) += \ stm32mp157c-ev1.dtb \ stm32mp157c-odyssey.dtb \ stm32mp15xx-dhcom-drc02.dtb \ @@ -101,55 +149,4572 @@ index f8f529435b..83677c3d4f 100644 + stm32mp157f-ed1.dtb \ + stm32mp157f-ev1.dtb \ stm32mp15xx-dhcom-pdk2.dtb \ + stm32mp15xx-dhcom-picoitx.dtb \ stm32mp15xx-dhcor-avenger96.dtb +diff --git a/arch/arm/dts/stm32429i-eval-u-boot.dtsi b/arch/arm/dts/stm32429i-eval-u-boot.dtsi +index 09d9d9ab9b..fcab9ae977 100644 +--- a/arch/arm/dts/stm32429i-eval-u-boot.dtsi ++++ b/arch/arm/dts/stm32429i-eval-u-boot.dtsi +@@ -33,7 +33,7 @@ + fmc: fmc@A0000000 { + compatible = "st,stm32-fmc"; +- reg = <0xA0000000 0x1000>; ++ reg = <0xa0000000 0x1000>; + clocks = <&rcc 0 STM32F4_AHB3_CLOCK(FMC)>; + st,syscfg = <&syscfg>; + pinctrl-0 = <&fmc_pins_d32>; +diff --git a/arch/arm/dts/stm32746g-eval-u-boot.dtsi b/arch/arm/dts/stm32746g-eval-u-boot.dtsi +index f2195a6c51..8550ef7863 100644 +--- a/arch/arm/dts/stm32746g-eval-u-boot.dtsi ++++ b/arch/arm/dts/stm32746g-eval-u-boot.dtsi +@@ -177,7 +177,7 @@ + }; + + &qspi { +- reg = <0xA0001000 0x1000>, <0x90000000 0x4000000>; ++ reg = <0xa0001000 0x1000>, <0x90000000 0x4000000>; + qflash0: n25q512a@0 { + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/dts/stm32f429-disco-u-boot.dtsi b/arch/arm/dts/stm32f429-disco-u-boot.dtsi +index 297cc56144..c993f86be8 100644 +--- a/arch/arm/dts/stm32f429-disco-u-boot.dtsi ++++ b/arch/arm/dts/stm32f429-disco-u-boot.dtsi +@@ -33,7 +33,7 @@ + + fmc: fmc@A0000000 { + compatible = "st,stm32-fmc"; +- reg = <0xA0000000 0x1000>; ++ reg = <0xa0000000 0x1000>; + clocks = <&rcc 0 STM32F4_AHB3_CLOCK(FMC)>; + pinctrl-0 = <&fmc_pins>; + pinctrl-names = "default"; +diff --git a/arch/arm/dts/stm32f469-disco-u-boot.dtsi b/arch/arm/dts/stm32f469-disco-u-boot.dtsi +index 9eda8f535b..cd173623ef 100644 +--- a/arch/arm/dts/stm32f469-disco-u-boot.dtsi ++++ b/arch/arm/dts/stm32f469-disco-u-boot.dtsi +@@ -34,7 +34,7 @@ + + fmc: fmc@A0000000 { + compatible = "st,stm32-fmc"; +- reg = <0xA0000000 0x1000>; ++ reg = <0xa0000000 0x1000>; + clocks = <&rcc 0 STM32F4_AHB3_CLOCK(FMC)>; + st,syscfg = <&syscfg>; + pinctrl-0 = <&fmc_pins_d32>; +@@ -70,7 +70,7 @@ + compatible = "st,stm32f469-qspi"; + #address-cells = <1>; + #size-cells = <0>; +- reg = <0xA0001000 0x1000>, <0x90000000 0x10000000>; ++ reg = <0xa0001000 0x1000>, <0x90000000 0x10000000>; + reg-names = "qspi", "qspi_mm"; + interrupts = <91>; + spi-max-frequency = <108000000>; +@@ -236,7 +236,7 @@ + }; + + &qspi { +- reg = <0xA0001000 0x1000>, <0x90000000 0x1000000>; ++ reg = <0xa0001000 0x1000>, <0x90000000 0x1000000>; + flash0: n25q128a@0 { + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/dts/stm32f7-u-boot.dtsi b/arch/arm/dts/stm32f7-u-boot.dtsi +index 46bd1102df..c1b2ac25c3 100644 +--- a/arch/arm/dts/stm32f7-u-boot.dtsi ++++ b/arch/arm/dts/stm32f7-u-boot.dtsi +@@ -7,7 +7,7 @@ + + fmc: fmc@A0000000 { + compatible = "st,stm32-fmc"; +- reg = <0xA0000000 0x1000>; ++ reg = <0xa0000000 0x1000>; + clocks = <&rcc 0 STM32F7_AHB3_CLOCK(FMC)>; + pinctrl-0 = <&fmc_pins>; + pinctrl-names = "default"; +@@ -46,7 +46,7 @@ + compatible = "st,stm32f469-qspi"; + #address-cells = <1>; + #size-cells = <0>; +- reg = <0xA0001000 0x1000>, <0x90000000 0x10000000>; ++ reg = <0xa0001000 0x1000>, <0x90000000 0x10000000>; + reg-names = "qspi", "qspi_mm"; + interrupts = <92>; + spi-max-frequency = <108000000>; +diff --git a/arch/arm/dts/stm32f746-disco-u-boot.dtsi b/arch/arm/dts/stm32f746-disco-u-boot.dtsi +index 4f34fc9a8c..f88466fa60 100644 +--- a/arch/arm/dts/stm32f746-disco-u-boot.dtsi ++++ b/arch/arm/dts/stm32f746-disco-u-boot.dtsi +@@ -228,7 +228,7 @@ + }; + + &qspi { +- reg = <0xA0001000 0x1000>, <0x90000000 0x1000000>; ++ reg = <0xa0001000 0x1000>, <0x90000000 0x1000000>; + qflash0: n25q128a@0 { + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/dts/stm32f746.dtsi b/arch/arm/dts/stm32f746.dtsi +index ba9b3cd03c..78facde2b5 100644 +--- a/arch/arm/dts/stm32f746.dtsi ++++ b/arch/arm/dts/stm32f746.dtsi +@@ -313,6 +313,7 @@ + clocks = <&rcc 1 CLK_I2C1>; + #address-cells = <1>; + #size-cells = <0>; ++ i2c-analog-filter; + status = "disabled"; + }; + +@@ -325,6 +326,7 @@ + clocks = <&rcc 1 CLK_I2C2>; + #address-cells = <1>; + #size-cells = <0>; ++ i2c-analog-filter; + status = "disabled"; + }; + +@@ -337,6 +339,7 @@ + clocks = <&rcc 1 CLK_I2C3>; + #address-cells = <1>; + #size-cells = <0>; ++ i2c-analog-filter; + status = "disabled"; + }; + +@@ -349,6 +352,7 @@ + clocks = <&rcc 1 CLK_I2C4>; + #address-cells = <1>; + #size-cells = <0>; ++ i2c-analog-filter; + status = "disabled"; + }; + +diff --git a/arch/arm/dts/stm32f769-disco-u-boot.dtsi b/arch/arm/dts/stm32f769-disco-u-boot.dtsi +index 7dfe430a40..5589b41652 100644 +--- a/arch/arm/dts/stm32f769-disco-u-boot.dtsi ++++ b/arch/arm/dts/stm32f769-disco-u-boot.dtsi +@@ -53,9 +53,9 @@ + soc { + dsi: dsi@40016c00 { + compatible = "st,stm32-dsi"; +- reg = <0x40016C00 0x800>; ++ reg = <0x40016c00 0x800>; + resets = <&rcc STM32F7_APB2_RESET(DSI)>; +- clocks = <&rcc 0 STM32F7_APB2_CLOCK(DSI)>, ++ clocks = <&rcc 0 STM32F7_APB2_CLOCK(DSI)>, + <&rcc 0 STM32F7_APB2_CLOCK(LTDC)>, + <&clk_hse>; + clock-names = "pclk", "px_clk", "ref"; +@@ -227,7 +227,7 @@ + }; + + &qspi { +- reg = <0xA0001000 0x1000>, <0x90000000 0x4000000>; ++ reg = <0xa0001000 0x1000>, <0x90000000 0x4000000>; + flash0: mx66l51235l@0 { + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/dts/stm32h743.dtsi b/arch/arm/dts/stm32h743.dtsi +index ed6857512f..dbfebf07f2 100644 +--- a/arch/arm/dts/stm32h743.dtsi ++++ b/arch/arm/dts/stm32h743.dtsi +@@ -124,6 +124,7 @@ + <32>; + resets = <&rcc STM32H7_APB1L_RESET(I2C1)>; + clocks = <&rcc I2C1_CK>; ++ i2c-analog-filter; + status = "disabled"; + }; + +@@ -136,6 +137,7 @@ + <34>; + resets = <&rcc STM32H7_APB1L_RESET(I2C2)>; + clocks = <&rcc I2C2_CK>; ++ i2c-analog-filter; + status = "disabled"; + }; + +@@ -148,6 +150,7 @@ + <73>; + resets = <&rcc STM32H7_APB1L_RESET(I2C3)>; + clocks = <&rcc I2C3_CK>; ++ i2c-analog-filter; + status = "disabled"; + }; + +@@ -395,6 +398,7 @@ + <96>; + resets = <&rcc STM32H7_APB4_RESET(I2C4)>; + clocks = <&rcc I2C4_CK>; ++ i2c-analog-filter; + status = "disabled"; + }; + +diff --git a/arch/arm/dts/stm32mp13-pinctrl.dtsi b/arch/arm/dts/stm32mp13-pinctrl.dtsi +new file mode 100644 +index 0000000000..b8d53065ae +--- /dev/null ++++ b/arch/arm/dts/stm32mp13-pinctrl.dtsi +@@ -0,0 +1,644 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2021 - All Rights Reserved ++ * Author: Alexandre Torgue ++ */ ++#include ++ ++&pinctrl { ++ adc1_usb_cc_pins_a: adc1-usb-cc-pins-0 { ++ pins { ++ pinmux = , /* ADC1 in6 */ ++ ; /* ADC1 in12 */ ++ }; ++ }; ++ ++ dcmipp_pins_a: dcmi-0 { ++ pins1 { ++ pinmux = ,/* DCMI_HSYNC */ ++ ,/* DCMI_VSYNC */ ++ ,/* DCMI_PIXCLK */ ++ ,/* DCMI_D0 */ ++ ,/* DCMI_D1 */ ++ ,/* DCMI_D2 */ ++ ,/* DCMI_D3 */ ++ ,/* DCMI_D4 */ ++ ,/* DCMI_D5 */ ++ ,/* DCMI_D6 */ ++ ;/* DCMI_D7 */ ++ bias-disable; ++ }; ++ }; ++ ++ dcmipp_sleep_pins_a: dcmi-sleep-0 { ++ pins1 { ++ pinmux = ,/* DCMI_HSYNC */ ++ ,/* DCMI_VSYNC */ ++ ,/* DCMI_PIXCLK */ ++ ,/* DCMI_D0 */ ++ ,/* DCMI_D1 */ ++ ,/* DCMI_D2 */ ++ ,/* DCMI_D3 */ ++ ,/* DCMI_D4 */ ++ ,/* DCMI_D5 */ ++ ,/* DCMI_D6 */ ++ ;/* DCMI_D7 */ ++ }; ++ }; ++ ++ dfsdm_clkout_pins_a: dfsdm-clkout-pins-0 { ++ pins { ++ pinmux = ; /* DFSDM_CKOUT */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ dfsdm_clkout_sleep_pins_a: dfsdm-clkout-sleep-pins-0 { ++ pins { ++ pinmux = ; /* DFSDM_CKOUT */ ++ }; ++ }; ++ ++ dfsdm_datin1_pins_a: dfsdm-datin1-pins-0 { ++ pins { ++ pinmux = ; /* DFSDM_DATIN1 */ ++ }; ++ }; ++ ++ dfsdm_datin1_sleep_pins_a: dfsdm-datin1-sleep-pins-0 { ++ pins { ++ pinmux = ; /* DFSDM_DATIN1 */ ++ }; ++ }; ++ ++ dfsdm_datin3_pins_a: dfsdm-datin3-pins-0 { ++ pins { ++ pinmux = ; /* DFSDM_DATIN3 */ ++ }; ++ }; ++ ++ dfsdm_datin3_sleep_pins_a: dfsdm-datin3-sleep-pins-0 { ++ pins { ++ pinmux = ; /* DFSDM_DATIN3 */ ++ }; ++ }; ++ ++ eth1_rmii_pins_a: eth1-rmii-1 { ++ pins1 { ++ pinmux = , /* ETH_RMII_TXD0 */ ++ , /* ETH_RMII_TXD1 */ ++ , /* ETH_RMII_TX_EN */ ++ , /* ETH_RMII_REF_CLK */ ++ , /* ETH_MDIO */ ++ ; /* ETH_MDC */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <1>; ++ }; ++ ++ pins2 { ++ pinmux = , /* ETH_RMII_RXD0 */ ++ , /* ETH_RMII_RXD1 */ ++ ; /* ETH_RMII_CRS_DV */ ++ bias-disable; ++ }; ++ ++ }; ++ ++ eth1_rmii_sleep_pins_a: eth1-rmii-sleep-1 { ++ pins1 { ++ pinmux = , /* ETH_RMII_TXD0 */ ++ , /* ETH_RMII_TXD1 */ ++ , /* ETH_RMII_TX_EN */ ++ , /* ETH_RMII_REF_CLK */ ++ , /* ETH_MDIO */ ++ , /* ETH_MDC */ ++ , /* ETH_RMII_RXD0 */ ++ , /* ETH_RMII_RXD1 */ ++ ; /* ETH_RMII_CRS_DV */ ++ }; ++ }; ++ ++ eth2_rmii_pins_a: eth2-rmii-2 { ++ pins1 { ++ pinmux = , /* ETH_RMII_TXD0 */ ++ , /* ETH_RMII_TXD1 */ ++ , /* ETH_RMII_ETHCK */ ++ , /* ETH_RMII_TX_EN */ ++ , /* ETH_MDIO */ ++ ; /* ETH_MDC */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <1>; ++ }; ++ ++ pins2 { ++ pinmux = , /* ETH_RMII_RXD0 */ ++ , /* ETH_RMII_RXD1 */ ++ ; /* ETH_RMII_CRS_DV */ ++ bias-disable; ++ }; ++ }; ++ ++ eth2_rmii_sleep_pins_a: eth2-rmii-sleep-2 { ++ pins1 { ++ pinmux = , /* ETH_RMII_TXD0 */ ++ , /* ETH_RMII_TXD1 */ ++ , /* ETH_RMII_ETHCK */ ++ , /* ETH_RMII_TX_EN */ ++ , /* ETH_MDIO */ ++ , /* ETH_MDC */ ++ , /* ETH_RMII_RXD0 */ ++ , /* ETH_RMII_RXD1 */ ++ ; /* ETH_RMII_CRS_DV */ ++ }; ++ }; ++ ++ goodix_pins_a: goodix-0 { ++ pins { ++ pinmux = ; ++ bias-pull-down; ++ }; ++ }; ++ ++ i2c1_pins_a: i2c1-0 { ++ pins { ++ pinmux = , /* I2C1_SCL */ ++ ; /* I2C1_SDA */ ++ bias-disable; ++ drive-open-drain; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ i2c1_sleep_pins_a: i2c1-sleep-0 { ++ pins { ++ pinmux = , /* I2C1_SCL */ ++ ; /* I2C1_SDA */ ++ }; ++ }; ++ ++ i2c5_pins_a: i2c5-0 { ++ pins { ++ pinmux = , /* I2C5_SCL */ ++ ; /* I2C5_SDA */ ++ bias-disable; ++ drive-open-drain; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ i2c5_sleep_pins_a: i2c5-sleep-0 { ++ pins { ++ pinmux = , /* I2C5_SCL */ ++ ; /* I2C5_SDA */ ++ }; ++ }; ++ ++ ltdc_pins_a: ltdc-0 { ++ pins { ++ pinmux = , /* LCD_CLK */ ++ , /* LCD_HSYNC */ ++ , /* LCD_VSYNC */ ++ , /* LCD_DE */ ++ , /* LCD_R2 */ ++ , /* LCD_R3 */ ++ , /* LCD_R4 */ ++ , /* LCD_R5 */ ++ , /* LCD_R6 */ ++ , /* LCD_R7 */ ++ , /* LCD_G2 */ ++ , /* LCD_G3 */ ++ , /* LCD_G4 */ ++ , /* LCD_G5 */ ++ , /* LCD_G6 */ ++ , /* LCD_G7 */ ++ , /* LCD_B2 */ ++ , /* LCD_B3 */ ++ , /* LCD_B4 */ ++ , /* LCD_B5 */ ++ , /* LCD_B6 */ ++ ; /* LCD_B7 */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ ltdc_sleep_pins_a: ltdc-sleep-0 { ++ pins { ++ pinmux = , /* LCD_CLK */ ++ , /* LCD_HSYNC */ ++ , /* LCD_VSYNC */ ++ , /* LCD_DE */ ++ , /* LCD_R2 */ ++ , /* LCD_R3 */ ++ , /* LCD_R4 */ ++ , /* LCD_R5 */ ++ , /* LCD_R6 */ ++ , /* LCD_R7 */ ++ , /* LCD_G2 */ ++ , /* LCD_G3 */ ++ , /* LCD_G4 */ ++ , /* LCD_G5 */ ++ , /* LCD_G6 */ ++ , /* LCD_G7 */ ++ , /* LCD_B2 */ ++ , /* LCD_B3 */ ++ , /* LCD_B4 */ ++ , /* LCD_B5 */ ++ , /* LCD_B6 */ ++ ; /* LCD_B7 */ ++ }; ++ }; ++ ++ mcp23017_pins_a: mcp23017-0 { ++ pins { ++ pinmux = ; ++ bias-pull-up; ++ }; ++ }; ++ ++ m_can2_pins_a: m-can2-0 { ++ pins1 { ++ pinmux = ; /* CAN2_TX */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ pins2 { ++ pinmux = ; /* CAN2_RX */ ++ bias-disable; ++ }; ++ }; ++ ++ m_can2_sleep_pins_a: m_can2-sleep-0 { ++ pins { ++ pinmux = , /* CAN2_TX */ ++ ; /* CAN2_RX */ ++ }; ++ }; ++ ++ pwm3_pins_a: pwm3-0 { ++ pins { ++ pinmux = ; /* TIM3_CH4 */ ++ bias-pull-down; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ pwm3_sleep_pins_a: pwm3-sleep-0 { ++ pins { ++ pinmux = ; /* TIM3_CH4 */ ++ }; ++ }; ++ ++ pwm4_pins_a: pwm4-0 { ++ pins { ++ pinmux = ; /* TIM4_CH2 */ ++ bias-pull-down; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ pwm4_sleep_pins_a: pwm4-sleep-0 { ++ pins { ++ pinmux = ; /* TIM4_CH2 */ ++ }; ++ }; ++ ++ pwm8_pins_a: pwm8-0 { ++ pins { ++ pinmux = ; /* TIM8_CH3 */ ++ bias-pull-down; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ pwm8_sleep_pins_a: pwm8-sleep-0 { ++ pins { ++ pinmux = ; /* TIM8_CH3 */ ++ }; ++ }; ++ ++ pwm14_pins_a: pwm12-0 { ++ pins { ++ pinmux = ; /* TIM14_CH1 */ ++ bias-pull-down; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ pwm14_sleep_pins_a: pwm12-sleep-0 { ++ pins { ++ pinmux = ; /* TIM14_CH1 */ ++ }; ++ }; ++ ++ rtc_out2_rmp_pins_a: rtc-out2-rmp-pins-0 { ++ pins { ++ pinmux = ; /* RTC_OUT2_RMP */ ++ }; ++ }; ++ ++ sai1_pins_a: sai1-0 { ++ pins { ++ pinmux = , /* SAI1_SCK_A */ ++ , /* SAI1_SD_B */ ++ , /* SAI1_SD_A */ ++ ; /* SAI1_FS_A */ ++ slew-rate = <0>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ }; ++ ++ sai1_sleep_pins_a: sai1-sleep-0 { ++ pins { ++ pinmux = , /* SAI1_SCK_A */ ++ , /* SAI1_SD_B */ ++ , /* SAI1_SD_A */ ++ ; /* SAI1_FS_A */ ++ }; ++ }; ++ ++ sdmmc1_b4_pins_a: sdmmc1-b4-0 { ++ pins { ++ pinmux = , /* SDMMC1_D0 */ ++ , /* SDMMC1_D1 */ ++ , /* SDMMC1_D2 */ ++ , /* SDMMC1_D3 */ ++ ; /* SDMMC1_CMD */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ }; ++ ++ sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 { ++ pins1 { ++ pinmux = , /* SDMMC1_D0 */ ++ , /* SDMMC1_D1 */ ++ , /* SDMMC1_D2 */ ++ ; /* SDMMC1_D3 */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ pins2 { ++ pinmux = ; /* SDMMC1_CMD */ ++ slew-rate = <1>; ++ drive-open-drain; ++ bias-disable; ++ }; ++ }; ++ ++ sdmmc1_b4_sleep_pins_a: sdmmc1-b4-sleep-0 { ++ pins { ++ pinmux = , /* SDMMC1_D0 */ ++ , /* SDMMC1_D1 */ ++ , /* SDMMC1_D2 */ ++ , /* SDMMC1_D3 */ ++ , /* SDMMC1_CK */ ++ ; /* SDMMC1_CMD */ ++ }; ++ }; ++ ++ sdmmc1_clk_pins_a: sdmmc1-clk-0 { ++ pins { ++ pinmux = ; /* SDMMC1_CK */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ }; ++ ++ sdmmc2_b4_pins_a: sdmmc2-b4-0 { ++ pins { ++ pinmux = , /* SDMMC2_D0 */ ++ , /* SDMMC2_D1 */ ++ , /* SDMMC2_D2 */ ++ , /* SDMMC2_D3 */ ++ ; /* SDMMC2_CMD */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-pull-up; ++ }; ++ }; ++ ++ sdmmc2_b4_od_pins_a: sdmmc2-b4-od-0 { ++ pins1 { ++ pinmux = , /* SDMMC2_D0 */ ++ , /* SDMMC2_D1 */ ++ , /* SDMMC2_D2 */ ++ ; /* SDMMC2_D3 */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-pull-up; ++ }; ++ pins2 { ++ pinmux = ; /* SDMMC2_CMD */ ++ slew-rate = <1>; ++ drive-open-drain; ++ bias-pull-up; ++ }; ++ }; ++ ++ sdmmc2_b4_sleep_pins_a: sdmmc2-b4-sleep-0 { ++ pins { ++ pinmux = , /* SDMMC2_D0 */ ++ , /* SDMMC2_D1 */ ++ , /* SDMMC2_D2 */ ++ , /* SDMMC2_D3 */ ++ , /* SDMMC2_CK */ ++ ; /* SDMMC2_CMD */ ++ }; ++ }; ++ ++ sdmmc2_clk_pins_a: sdmmc2-clk-0 { ++ pins { ++ pinmux = ; /* SDMMC2_CK */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-pull-up; ++ }; ++ }; ++ ++ spi5_pins_a: spi5-0 { ++ pins1 { ++ pinmux = , /* SPI5_SCK */ ++ ; /* SPI5_MOSI */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <1>; ++ }; ++ ++ pins2 { ++ pinmux = ; /* SPI5_MISO */ ++ bias-disable; ++ }; ++ }; ++ ++ spi5_sleep_pins_a: spi5-sleep-0 { ++ pins { ++ pinmux = , /* SPI5_SCK */ ++ , /* SPI5_MISO */ ++ ; /* SPI5_MOSI */ ++ }; ++ }; ++ ++ stm32g0_intn_pins_a: stm32g0-intn-0 { ++ pins { ++ pinmux = ; ++ bias-pull-up; ++ }; ++ }; ++ ++ uart4_pins_a: uart4-0 { ++ pins1 { ++ pinmux = ; /* UART4_TX */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ pins2 { ++ pinmux = ; /* UART4_RX */ ++ bias-disable; ++ }; ++ }; ++ ++ uart4_idle_pins_a: uart4-idle-0 { ++ pins1 { ++ pinmux = ; /* UART4_TX */ ++ }; ++ pins2 { ++ pinmux = ; /* UART4_RX */ ++ bias-disable; ++ }; ++ }; ++ ++ uart4_sleep_pins_a: uart4-sleep-0 { ++ pins { ++ pinmux = , /* UART4_TX */ ++ ; /* UART4_RX */ ++ }; ++ }; ++ ++ uart8_pins_a: uart8-0 { ++ pins1 { ++ pinmux = ; /* UART8_TX */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ pins2 { ++ pinmux = ; /* UART8_RX */ ++ bias-pull-up; ++ }; ++ }; ++ ++ uart8_idle_pins_a: uart8-idle-0 { ++ pins1 { ++ pinmux = ; /* UART8_TX */ ++ }; ++ pins2 { ++ pinmux = ; /* UART8_RX */ ++ bias-pull-up; ++ }; ++ }; ++ ++ uart8_sleep_pins_a: uart8-sleep-0 { ++ pins { ++ pinmux = , /* UART8_TX */ ++ ; /* UART8_RX */ ++ }; ++ }; ++ ++ usart1_pins_a: usart1-0 { ++ pins1 { ++ pinmux = , /* USART1_TX */ ++ ; /* USART1_RTS */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ pins2 { ++ pinmux = , /* USART1_RX */ ++ ; /* USART1_CTS_NSS */ ++ bias-pull-up; ++ }; ++ }; ++ ++ usart1_idle_pins_a: usart1-idle-0 { ++ pins1 { ++ pinmux = , /* USART1_TX */ ++ ; /* USART1_CTS_NSS */ ++ }; ++ pins2 { ++ pinmux = ; /* USART1_RTS */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ pins3 { ++ pinmux = ; /* USART1_RX */ ++ bias-pull-up; ++ }; ++ }; ++ ++ usart1_sleep_pins_a: usart1-sleep-0 { ++ pins { ++ pinmux = , /* USART1_TX */ ++ , /* USART1_RTS */ ++ , /* USART1_CTS_NSS */ ++ ; /* USART1_RX */ ++ }; ++ }; ++ ++ usart2_pins_a: usart2-0 { ++ pins1 { ++ pinmux = , /* USART2_TX */ ++ ; /* USART2_RTS */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ pins2 { ++ pinmux = , /* USART2_RX */ ++ ; /* USART2_CTS_NSS */ ++ bias-disable; ++ }; ++ }; ++ ++ usart2_idle_pins_a: usart2-idle-0 { ++ pins1 { ++ pinmux = , /* USART2_TX */ ++ ; /* USART2_CTS_NSS */ ++ }; ++ pins2 { ++ pinmux = ; /* USART2_RTS */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ pins3 { ++ pinmux = ; /* USART2_RX */ ++ bias-disable; ++ }; ++ }; ++ ++ usart2_sleep_pins_a: usart2-sleep-0 { ++ pins { ++ pinmux = , /* USART2_TX */ ++ , /* USART2_RTS */ ++ , /* USART2_RX */ ++ ; /* USART2_CTS_NSS */ ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp13-u-boot.dtsi b/arch/arm/dts/stm32mp13-u-boot.dtsi +new file mode 100644 +index 0000000000..4a6d261638 +--- /dev/null ++++ b/arch/arm/dts/stm32mp13-u-boot.dtsi +@@ -0,0 +1,131 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright : STMicroelectronics 2020 ++ */ ++ ++/ { ++ aliases { ++ gpio0 = &gpioa; ++ gpio1 = &gpiob; ++ gpio2 = &gpioc; ++ gpio3 = &gpiod; ++ gpio4 = &gpioe; ++ gpio5 = &gpiof; ++ gpio6 = &gpiog; ++ gpio7 = &gpioh; ++ gpio8 = &gpioi; ++ pinctrl0 = &pinctrl; ++ }; ++ ++ firmware { ++ optee { ++ u-boot,dm-pre-reloc; ++ }; ++ }; ++ ++ /* need PSCI for sysreset during board_f */ ++ psci { ++ u-boot,dm-pre-proper; ++ }; ++ ++ soc { ++ u-boot,dm-pre-reloc; ++ ++ ddr: ddr@5a003000 { ++ u-boot,dm-pre-reloc; ++ ++ compatible = "st,stm32mp13-ddr"; ++ ++ reg = <0x5A003000 0x550 ++ 0x5A004000 0x234>; ++ ++ status = "okay"; ++ }; ++ }; ++}; ++ ++&bsec { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpioa { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpiob { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpioc { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpiod { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpioe { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpiof { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpiog { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpioh { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpioi { ++ u-boot,dm-pre-reloc; ++}; ++ ++&iwdg2 { ++ u-boot,dm-pre-reloc; ++}; ++ ++/* pre-reloc probe = reserve video frame buffer in video_reserve() */ ++<dc { ++ u-boot,dm-pre-proper; ++}; ++ ++&pinctrl { ++ u-boot,dm-pre-reloc; ++}; ++ ++&rcc { ++ u-boot,dm-pre-reloc; ++}; ++ ++&scmi { ++ u-boot,dm-pre-reloc; ++}; ++ ++&scmi_clk { ++ u-boot,dm-pre-reloc; ++}; ++ ++&scmi_reset { ++ u-boot,dm-pre-reloc; ++}; ++ ++&scmi_shm { ++ u-boot,dm-pre-reloc; ++}; ++ ++&scmi_sram { ++ u-boot,dm-pre-reloc; ++}; ++ ++&syscfg { ++ u-boot,dm-pre-reloc; ++}; ++ ++&usbphyc { ++ /* stm32-usbphyc-clk = ck_usbo_48m is a source clock of RCC CCF */ ++ u-boot,dm-pre-reloc; ++}; +diff --git a/arch/arm/dts/stm32mp131.dtsi b/arch/arm/dts/stm32mp131.dtsi +new file mode 100644 +index 0000000000..d19cf69401 +--- /dev/null ++++ b/arch/arm/dts/stm32mp131.dtsi +@@ -0,0 +1,1664 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2021 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++#include ++#include ++#include ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ compatible = "arm,cortex-a7"; ++ device_type = "cpu"; ++ reg = <0>; ++ clocks = <&scmi_perf 0>; ++ clock-names = "cpu"; ++ nvmem-cells = <&part_number_otp>; ++ nvmem-cell-names = "part_number"; ++ }; ++ }; ++ ++ arm-pmu { ++ compatible = "arm,cortex-a7-pmu"; ++ interrupts = ; ++ interrupt-affinity = <&cpu0>; ++ interrupt-parent = <&intc>; ++ }; ++ ++ scmi_sram: sram@2ffff000 { ++ compatible = "mmio-sram"; ++ reg = <0x2ffff000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0x2ffff000 0x1000>; ++ ++ scmi_shm: scmi_shm@0 { ++ compatible = "arm,scmi-shmem"; ++ reg = <0 0x80>; ++ }; ++ }; ++ ++ firmware { ++ optee { ++ method = "smc"; ++ compatible = "linaro,optee-tz"; ++ interrupt-parent = <&intc>; ++ interrupts = ; ++ }; ++ ++ scmi: scmi { ++ compatible = "linaro,scmi-optee"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ linaro,optee-channel-id = <0>; ++ shmem = <&scmi_shm>; ++ ++ scmi_perf: protocol@13 { ++ reg = <0x13>; ++ #clock-cells = <1>; ++ }; ++ ++ scmi_clk: protocol@14 { ++ reg = <0x14>; ++ #clock-cells = <1>; ++ }; ++ ++ scmi_reset: protocol@16 { ++ reg = <0x16>; ++ #reset-cells = <1>; ++ }; ++ ++ scmi_voltd: protocol@17 { ++ reg = <0x17>; ++ ++ scmi_regu: regulators { ++ scmi_reg11: voltd-reg11 { ++ voltd-name = "reg11"; ++ regulator-name = "reg11"; ++ }; ++ scmi_reg18: voltd-reg18 { ++ voltd-name = "reg18"; ++ regulator-name = "reg18"; ++ }; ++ scmi_usb33: voltd-usb33 { ++ voltd-name = "usb33"; ++ regulator-name = "usb33"; ++ }; ++ }; ++ }; ++ }; ++ }; ++ ++ intc: interrupt-controller@a0021000 { ++ compatible = "arm,cortex-a7-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0xa0021000 0x1000>, ++ <0xa0022000 0x2000>; ++ }; ++ ++ psci { ++ compatible = "arm,psci-1.0"; ++ method = "smc"; ++ }; ++ ++ timer { ++ compatible = "arm,armv7-timer"; ++ interrupts = , ++ , ++ , ++ ; ++ interrupt-parent = <&intc>; ++ always-on; ++ }; ++ ++ pm_domain { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32mp157c-pd"; ++ ++ pd_core_ret: core-ret-power-domain@1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <1>; ++ #power-domain-cells = <0>; ++ label = "CORE-RETENTION"; ++ ++ pd_core: core-power-domain@2 { ++ reg = <2>; ++ #power-domain-cells = <0>; ++ label = "CORE"; ++ }; ++ }; ++ }; ++ ++ thermal-zones { ++ cpu_thermal: cpu-thermal { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&dts>; ++ ++ trips { ++ cpu-crit { ++ temperature = <120000>; ++ hysteresis = <0>; ++ type = "critical"; ++ }; ++ }; ++ ++ cooling-maps { ++ }; ++ }; ++ }; ++ ++ soc { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ interrupt-parent = <&intc>; ++ ranges; ++ ++ sram: sram@30000000 { ++ compatible = "mmio-sram"; ++ reg = <0x30000000 0x8000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0x30000000 0x8000>; ++ }; ++ ++ timers2: timer@40000000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x40000000 0x400>; ++ clocks = <&rcc TIM2_K>; ++ clock-names = "int"; ++ dmas = <&dmamux1 18 0x400 0x80000001>, ++ <&dmamux1 19 0x400 0x80000001>, ++ <&dmamux1 20 0x400 0x80000001>, ++ <&dmamux1 21 0x400 0x80000001>, ++ <&dmamux1 22 0x400 0x80000001>; ++ dma-names = "ch1", "ch2", "ch3", "ch4", "up"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer@1 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <1>; ++ status = "disabled"; ++ }; ++ ++ counter { ++ compatible = "st,stm32-timer-counter"; ++ status = "disabled"; ++ }; ++ }; ++ ++ timers3: timer@40001000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x40001000 0x400>; ++ clocks = <&rcc TIM3_K>; ++ clock-names = "int"; ++ dmas = <&dmamux1 23 0x400 0x80000001>, ++ <&dmamux1 24 0x400 0x80000001>, ++ <&dmamux1 25 0x400 0x80000001>, ++ <&dmamux1 26 0x400 0x80000001>, ++ <&dmamux1 27 0x400 0x80000001>, ++ <&dmamux1 28 0x400 0x80000001>; ++ dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer@2 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <2>; ++ status = "disabled"; ++ }; ++ ++ counter { ++ compatible = "st,stm32-timer-counter"; ++ status = "disabled"; ++ }; ++ }; ++ ++ timers4: timer@40002000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x40002000 0x400>; ++ clocks = <&rcc TIM4_K>; ++ clock-names = "int"; ++ dmas = <&dmamux1 29 0x400 0x80000001>, ++ <&dmamux1 30 0x400 0x80000001>, ++ <&dmamux1 31 0x400 0x80000001>, ++ <&dmamux1 32 0x400 0x80000001>; ++ dma-names = "ch1", "ch2", "ch3", "up"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer@3 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <3>; ++ status = "disabled"; ++ }; ++ ++ counter { ++ compatible = "st,stm32-timer-counter"; ++ status = "disabled"; ++ }; ++ }; ++ ++ timers5: timer@40003000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x40003000 0x400>; ++ clocks = <&rcc TIM5_K>; ++ clock-names = "int"; ++ dmas = <&dmamux1 55 0x400 0x80000001>, ++ <&dmamux1 56 0x400 0x80000001>, ++ <&dmamux1 57 0x400 0x80000001>, ++ <&dmamux1 58 0x400 0x80000001>, ++ <&dmamux1 59 0x400 0x80000001>, ++ <&dmamux1 60 0x400 0x80000001>; ++ dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer@4 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <4>; ++ status = "disabled"; ++ }; ++ ++ counter { ++ compatible = "st,stm32-timer-counter"; ++ status = "disabled"; ++ }; ++ }; ++ ++ timers6: timer@40004000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x40004000 0x400>; ++ clocks = <&rcc TIM6_K>; ++ clock-names = "int"; ++ dmas = <&dmamux1 69 0x400 0x80000001>; ++ dma-names = "up"; ++ status = "disabled"; ++ ++ timer@5 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <5>; ++ status = "disabled"; ++ }; ++ }; ++ ++ timers7: timer@40005000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x40005000 0x400>; ++ clocks = <&rcc TIM7_K>; ++ clock-names = "int"; ++ dmas = <&dmamux1 70 0x400 0x80000001>; ++ dma-names = "up"; ++ status = "disabled"; ++ ++ timer@6 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <6>; ++ status = "disabled"; ++ }; ++ }; ++ ++ lptimer1: timer@40009000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-lptimer"; ++ reg = <0x40009000 0x400>; ++ interrupts-extended = <&exti 47 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc LPTIM1_K>; ++ clock-names = "mux"; ++ power-domains = <&pd_core_ret>; ++ wakeup-source; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm-lp"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ trigger@0 { ++ compatible = "st,stm32-lptimer-trigger"; ++ reg = <0>; ++ status = "disabled"; ++ }; ++ ++ counter { ++ compatible = "st,stm32-lptimer-counter"; ++ status = "disabled"; ++ }; ++ ++ timer { ++ compatible = "st,stm32-lptimer-timer"; ++ status = "disabled"; ++ }; ++ }; ++ ++ i2s2: audio-controller@4000b000 { ++ compatible = "st,stm32h7-i2s"; ++ #sound-dai-cells = <0>; ++ reg = <0x4000b000 0x400>; ++ interrupts = ; ++ dmas = <&dmamux1 39 0x400 0x01>, ++ <&dmamux1 40 0x400 0x01>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ spi2: spi@4000b000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32h7-spi"; ++ reg = <0x4000b000 0x400>; ++ interrupts = ; ++ clocks = <&rcc SPI2_K>; ++ resets = <&rcc SPI2_R>; ++ dmas = <&dmamux1 39 0x400 0x01>, ++ <&dmamux1 40 0x400 0x01>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ i2s3: audio-controller@4000c000 { ++ compatible = "st,stm32h7-i2s"; ++ #sound-dai-cells = <0>; ++ reg = <0x4000c000 0x400>; ++ interrupts = ; ++ dmas = <&dmamux1 61 0x400 0x01>, ++ <&dmamux1 62 0x400 0x01>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ spi3: spi@4000c000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32h7-spi"; ++ reg = <0x4000c000 0x400>; ++ interrupts = ; ++ clocks = <&rcc SPI3_K>; ++ resets = <&rcc SPI3_R>; ++ dmas = <&dmamux1 61 0x400 0x01>, ++ <&dmamux1 62 0x400 0x01>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ spdifrx: audio-controller@4000d000 { ++ compatible = "st,stm32h7-spdifrx"; ++ #sound-dai-cells = <0>; ++ reg = <0x4000d000 0x400>; ++ clocks = <&rcc SPDIF_K>; ++ clock-names = "kclk"; ++ interrupts = ; ++ dmas = <&dmamux1 93 0x400 0x01>, ++ <&dmamux1 94 0x400 0x01>; ++ dma-names = "rx", "rx-ctrl"; ++ status = "disabled"; ++ }; ++ ++ usart3: serial@4000f000 { ++ compatible = "st,stm32h7-uart"; ++ reg = <0x4000f000 0x400>; ++ interrupts-extended = <&exti 28 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc USART3_K>; ++ resets = <&rcc USART3_R>; ++ wakeup-source; ++ power-domains = <&pd_core_ret>; ++ dmas = <&dmamux1 45 0x400 0x5>, ++ <&dmamux1 46 0x400 0x1>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ uart4: serial@40010000 { ++ compatible = "st,stm32h7-uart"; ++ reg = <0x40010000 0x400>; ++ interrupts-extended = <&exti 30 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc UART4_K>; ++ resets = <&rcc UART4_R>; ++ wakeup-source; ++ power-domains = <&pd_core_ret>; ++ dmas = <&dmamux1 63 0x400 0x5>, ++ <&dmamux1 64 0x400 0x1>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ uart5: serial@40011000 { ++ compatible = "st,stm32h7-uart"; ++ reg = <0x40011000 0x400>; ++ interrupts-extended = <&exti 31 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc UART5_K>; ++ resets = <&rcc UART5_R>; ++ wakeup-source; ++ power-domains = <&pd_core_ret>; ++ dmas = <&dmamux1 65 0x400 0x5>, ++ <&dmamux1 66 0x400 0x1>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@40012000 { ++ compatible = "st,stm32mp13-i2c"; ++ reg = <0x40012000 0x400>; ++ interrupt-names = "event", "error"; ++ interrupts-extended = <&exti 21 IRQ_TYPE_LEVEL_HIGH>, ++ <&intc GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc I2C1_K>; ++ resets = <&rcc I2C1_R>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ dmas = <&dmamux1 33 0x400 0x80000001>, ++ <&dmamux1 34 0x400 0x80000001>; ++ dma-names = "rx", "tx"; ++ st,syscfg-fmp = <&syscfg 0x4 0x1>; ++ i2c-analog-filter; ++ power-domains = <&pd_core_ret>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ i2c2: i2c@40013000 { ++ compatible = "st,stm32mp13-i2c"; ++ reg = <0x40013000 0x400>; ++ interrupt-names = "event", "error"; ++ interrupts-extended = <&exti 22 IRQ_TYPE_LEVEL_HIGH>, ++ <&intc GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc I2C2_K>; ++ resets = <&rcc I2C2_R>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ dmas = <&dmamux1 35 0x400 0x80000001>, ++ <&dmamux1 36 0x400 0x80000001>; ++ dma-names = "rx", "tx"; ++ st,syscfg-fmp = <&syscfg 0x4 0x2>; ++ i2c-analog-filter; ++ power-domains = <&pd_core_ret>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ uart7: serial@40018000 { ++ compatible = "st,stm32h7-uart"; ++ reg = <0x40018000 0x400>; ++ interrupts-extended = <&exti 32 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc UART7_K>; ++ resets = <&rcc UART7_R>; ++ wakeup-source; ++ power-domains = <&pd_core_ret>; ++ dmas = <&dmamux1 79 0x400 0x5>, ++ <&dmamux1 80 0x400 0x1>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ uart8: serial@40019000 { ++ compatible = "st,stm32h7-uart"; ++ reg = <0x40019000 0x400>; ++ interrupts-extended = <&exti 33 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc UART8_K>; ++ resets = <&rcc UART8_R>; ++ wakeup-source; ++ power-domains = <&pd_core_ret>; ++ dmas = <&dmamux1 81 0x400 0x5>, ++ <&dmamux1 82 0x400 0x1>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ timers1: timer@44000000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x44000000 0x400>; ++ clocks = <&rcc TIM1_K>; ++ clock-names = "int"; ++ dmas = <&dmamux1 11 0x400 0x80000001>, ++ <&dmamux1 12 0x400 0x80000001>, ++ <&dmamux1 13 0x400 0x80000001>, ++ <&dmamux1 14 0x400 0x80000001>, ++ <&dmamux1 15 0x400 0x80000001>, ++ <&dmamux1 16 0x400 0x80000001>, ++ <&dmamux1 17 0x400 0x80000001>; ++ dma-names = "ch1", "ch2", "ch3", "ch4", ++ "up", "trig", "com"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer@0 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <0>; ++ status = "disabled"; ++ }; ++ ++ counter { ++ compatible = "st,stm32-timer-counter"; ++ status = "disabled"; ++ }; ++ }; ++ ++ timers8: timer@44001000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x44001000 0x400>; ++ clocks = <&rcc TIM8_K>; ++ clock-names = "int"; ++ dmas = <&dmamux1 47 0x400 0x80000001>, ++ <&dmamux1 48 0x400 0x80000001>, ++ <&dmamux1 49 0x400 0x80000001>, ++ <&dmamux1 50 0x400 0x80000001>, ++ <&dmamux1 51 0x400 0x80000001>, ++ <&dmamux1 52 0x400 0x80000001>, ++ <&dmamux1 53 0x400 0x80000001>; ++ dma-names = "ch1", "ch2", "ch3", "ch4", ++ "up", "trig", "com"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer@7 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <7>; ++ status = "disabled"; ++ }; ++ ++ counter { ++ compatible = "st,stm32-timer-counter"; ++ status = "disabled"; ++ }; ++ }; ++ ++ usart6: serial@44003000 { ++ compatible = "st,stm32h7-uart"; ++ reg = <0x44003000 0x400>; ++ interrupts-extended = <&exti 29 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc USART6_K>; ++ resets = <&rcc USART6_R>; ++ wakeup-source; ++ power-domains = <&pd_core_ret>; ++ dmas = <&dmamux1 71 0x400 0x5>, ++ <&dmamux1 72 0x400 0x1>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ i2s1: audio-controller@44004000 { ++ compatible = "st,stm32h7-i2s"; ++ #sound-dai-cells = <0>; ++ reg = <0x44004000 0x400>; ++ interrupts = ; ++ dmas = <&dmamux1 37 0x400 0x01>, ++ <&dmamux1 38 0x400 0x01>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ spi1: spi@44004000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32h7-spi"; ++ reg = <0x44004000 0x400>; ++ interrupts = ; ++ clocks = <&rcc SPI1_K>; ++ resets = <&rcc SPI1_R>; ++ dmas = <&dmamux1 37 0x400 0x01>, ++ <&dmamux1 38 0x400 0x01>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ sai1: sai@4400a000 { ++ compatible = "st,stm32h7-sai"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0x4400a000 0x400>; ++ reg = <0x4400a000 0x4>, <0x4400a3f0 0x10>; ++ interrupts = ; ++ resets = <&rcc SAI1_R>; ++ status = "disabled"; ++ ++ sai1a: audio-controller@4400a004 { ++ #sound-dai-cells = <0>; ++ ++ compatible = "st,stm32-sai-sub-a"; ++ reg = <0x4 0x20>; ++ clocks = <&rcc SAI1_K>; ++ clock-names = "sai_ck"; ++ dmas = <&dmamux1 87 0x400 0x01>; ++ status = "disabled"; ++ }; ++ ++ sai1b: audio-controller@4400a024 { ++ #sound-dai-cells = <0>; ++ compatible = "st,stm32-sai-sub-b"; ++ reg = <0x24 0x20>; ++ clocks = <&rcc SAI1_K>; ++ clock-names = "sai_ck"; ++ dmas = <&dmamux1 88 0x400 0x01>; ++ status = "disabled"; ++ }; ++ }; ++ ++ sai2: sai@4400b000 { ++ compatible = "st,stm32h7-sai"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0x4400b000 0x400>; ++ reg = <0x4400b000 0x4>, <0x4400b3f0 0x10>; ++ interrupts = ; ++ resets = <&rcc SAI2_R>; ++ status = "disabled"; ++ ++ sai2a: audio-controller@4400b004 { ++ #sound-dai-cells = <0>; ++ compatible = "st,stm32-sai-sub-a"; ++ reg = <0x4 0x20>; ++ clocks = <&rcc SAI2_K>; ++ clock-names = "sai_ck"; ++ dmas = <&dmamux1 89 0x400 0x01>; ++ status = "disabled"; ++ }; ++ ++ sai2b: audio-controller@4400b024 { ++ #sound-dai-cells = <0>; ++ compatible = "st,stm32-sai-sub-b"; ++ reg = <0x24 0x20>; ++ clocks = <&rcc SAI2_K>; ++ clock-names = "sai_ck"; ++ dmas = <&dmamux1 90 0x400 0x01>; ++ status = "disabled"; ++ }; ++ }; ++ ++ dfsdm: dfsdm@4400d000 { ++ compatible = "st,stm32mp1-dfsdm"; ++ reg = <0x4400d000 0x800>; ++ clocks = <&rcc DFSDM_K>; ++ clock-names = "dfsdm"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ dfsdm0: filter@0 { ++ compatible = "st,stm32-dfsdm-adc"; ++ #io-channel-cells = <1>; ++ reg = <0>; ++ interrupts = ; ++ dmas = <&dmamux1 101 0x400 0x01>; ++ dma-names = "rx"; ++ status = "disabled"; ++ }; ++ ++ dfsdm1: filter@1 { ++ compatible = "st,stm32-dfsdm-adc"; ++ #io-channel-cells = <1>; ++ reg = <1>; ++ interrupts = ; ++ dmas = <&dmamux1 102 0x400 0x01>; ++ dma-names = "rx"; ++ status = "disabled"; ++ }; ++ }; ++ ++ dma1: dma-controller@48000000 { ++ compatible = "st,stm32-dma"; ++ reg = <0x48000000 0x400>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ clocks = <&rcc DMA1>; ++ resets = <&rcc DMA1_R>; ++ #dma-cells = <4>; ++ st,mem2mem; ++ dma-requests = <8>; ++ dmas = <&mdma 0 0x3 0x1200000a 0x48000008 0x00000020 1>, ++ <&mdma 1 0x3 0x1200000a 0x48000008 0x00000800 1>, ++ <&mdma 2 0x3 0x1200000a 0x48000008 0x00200000 1>, ++ <&mdma 3 0x3 0x1200000a 0x48000008 0x08000000 1>, ++ <&mdma 4 0x3 0x1200000a 0x4800000C 0x00000020 1>, ++ <&mdma 5 0x3 0x1200000a 0x4800000C 0x00000800 1>, ++ <&mdma 6 0x3 0x1200000a 0x4800000C 0x00200000 1>, ++ <&mdma 7 0x3 0x1200000a 0x4800000C 0x08000000 1>; ++ dma-names = "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7"; ++ }; ++ ++ dma2: dma-controller@48001000 { ++ compatible = "st,stm32-dma"; ++ reg = <0x48001000 0x400>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ clocks = <&rcc DMA2>; ++ resets = <&rcc DMA2_R>; ++ #dma-cells = <4>; ++ st,mem2mem; ++ dma-requests = <8>; ++ dmas = <&mdma 8 0x3 0x1200000a 0x48001008 0x00000020 1>, ++ <&mdma 9 0x3 0x1200000a 0x48001008 0x00000800 1>, ++ <&mdma 10 0x3 0x1200000a 0x48001008 0x00200000 1>, ++ <&mdma 11 0x3 0x1200000a 0x48001008 0x08000000 1>, ++ <&mdma 12 0x3 0x1200000a 0x4800100C 0x00000020 1>, ++ <&mdma 13 0x3 0x1200000a 0x4800100C 0x00000800 1>, ++ <&mdma 14 0x3 0x1200000a 0x4800100C 0x00200000 1>, ++ <&mdma 15 0x3 0x1200000a 0x4800100C 0x08000000 1>; ++ dma-names = "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7"; ++ }; ++ ++ dmamux1: dma-router@48002000 { ++ compatible = "st,stm32h7-dmamux"; ++ reg = <0x48002000 0x40>; ++ clocks = <&rcc DMAMUX1>; ++ resets = <&rcc DMAMUX1_R>; ++ #dma-cells = <3>; ++ dma-masters = <&dma1 &dma2>; ++ dma-requests = <128>; ++ dma-channels = <16>; ++ }; ++ ++ adc_2: adc@48004000 { ++ reg = <0x48004000 0x400>; ++ compatible = "st,stm32mp13-adc-core"; ++ interrupts = ; ++ clocks = <&rcc ADC2>, <&rcc ADC2_K>; ++ clock-names = "bus", "adc"; ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ adc2: adc@0 { ++ compatible = "st,stm32mp13-adc"; ++ #io-channel-cells = <1>; ++ reg = <0x0>; ++ interrupt-parent = <&adc_2>; ++ interrupts = <0>; ++ dmas = <&dmamux1 10 0x400 0x80000001>; ++ dma-names = "rx"; ++ nvmem-cells = <&vrefint>; ++ nvmem-cell-names = "vrefint"; ++ status = "disabled"; ++ }; ++ }; ++ ++ usbotg_hs: usb-otg@49000000 { ++ compatible = "st,stm32mp15-hsotg", "snps,dwc2"; ++ reg = <0x49000000 0x40000>; ++ clocks = <&rcc USBO_K>; ++ clock-names = "otg"; ++ resets = <&rcc USBO_R>; ++ reset-names = "dwc2"; ++ interrupts-extended = <&exti 44 IRQ_TYPE_LEVEL_HIGH>; ++ g-rx-fifo-size = <512>; ++ 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 = <&scmi_usb33>; ++ power-domains = <&pd_core>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ usart1: serial@4c000000 { ++ compatible = "st,stm32h7-uart"; ++ reg = <0x4c000000 0x400>; ++ interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc USART1_K>; ++ resets = <&rcc USART1_R>; ++ wakeup-source; ++ power-domains = <&pd_core_ret>; ++ dmas = <&dmamux1 41 0x400 0x5>, ++ <&dmamux1 42 0x400 0x1>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ usart2: serial@4c001000 { ++ compatible = "st,stm32h7-uart"; ++ reg = <0x4c001000 0x400>; ++ interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc USART2_K>; ++ resets = <&rcc USART2_R>; ++ wakeup-source; ++ power-domains = <&pd_core_ret>; ++ dmas = <&dmamux1 43 0x400 0x5>, ++ <&dmamux1 44 0x400 0x1>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ i2s4: audio-controller@4c002000 { ++ compatible = "st,stm32h7-i2s"; ++ #sound-dai-cells = <0>; ++ reg = <0x4c002000 0x400>; ++ interrupts = ; ++ dmas = <&dmamux1 83 0x400 0x01>, ++ <&dmamux1 84 0x400 0x01>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ spi4: spi@4c002000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32h7-spi"; ++ reg = <0x4c002000 0x400>; ++ interrupts = ; ++ clocks = <&rcc SPI4_K>; ++ resets = <&rcc SPI4_R>; ++ dmas = <&dmamux1 83 0x400 0x01>, ++ <&dmamux1 84 0x400 0x01>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ spi5: spi@4c003000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32h7-spi"; ++ reg = <0x4c003000 0x400>; ++ interrupts = ; ++ clocks = <&rcc SPI5_K>; ++ resets = <&rcc SPI5_R>; ++ dmas = <&dmamux1 85 0x400 0x01>, ++ <&dmamux1 86 0x400 0x01>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ i2c3: i2c@4c004000 { ++ compatible = "st,stm32mp13-i2c"; ++ reg = <0x4c004000 0x400>; ++ interrupt-names = "event", "error"; ++ interrupts-extended = <&exti 23 IRQ_TYPE_LEVEL_HIGH>, ++ <&intc GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc I2C3_K>; ++ resets = <&rcc I2C3_R>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ dmas = <&dmamux1 73 0x400 0x80000001>, ++ <&dmamux1 74 0x400 0x80000001>; ++ dma-names = "rx", "tx"; ++ st,syscfg-fmp = <&syscfg 0x4 0x4>; ++ i2c-analog-filter; ++ power-domains = <&pd_core_ret>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ i2c4: i2c@4c005000 { ++ compatible = "st,stm32mp13-i2c"; ++ reg = <0x4c005000 0x400>; ++ interrupt-names = "event", "error"; ++ interrupts-extended = <&exti 24 IRQ_TYPE_LEVEL_HIGH>, ++ <&intc GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc I2C4_K>; ++ resets = <&rcc I2C4_R>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ dmas = <&dmamux1 75 0x400 0x80000001>, ++ <&dmamux1 76 0x400 0x80000001>; ++ dma-names = "rx", "tx"; ++ st,syscfg-fmp = <&syscfg 0x4 0x8>; ++ i2c-analog-filter; ++ power-domains = <&pd_core_ret>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ i2c5: i2c@4c006000 { ++ compatible = "st,stm32mp13-i2c"; ++ reg = <0x4c006000 0x400>; ++ interrupt-names = "event", "error"; ++ interrupts-extended = <&exti 25 IRQ_TYPE_LEVEL_HIGH>, ++ <&intc GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc I2C5_K>; ++ resets = <&rcc I2C5_R>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ dmas = <&dmamux1 115 0x400 0x80000001>, ++ <&dmamux1 116 0x400 0x80000001>; ++ dma-names = "rx", "tx"; ++ st,syscfg-fmp = <&syscfg 0x4 0x10>; ++ i2c-analog-filter; ++ power-domains = <&pd_core_ret>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ timers12: timer@4c007000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x4c007000 0x400>; ++ clocks = <&rcc TIM12_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer@11 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <11>; ++ status = "disabled"; ++ }; ++ }; ++ ++ timers13: timer@4c008000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x4c008000 0x400>; ++ clocks = <&rcc TIM13_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer@12 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <12>; ++ status = "disabled"; ++ }; ++ }; ++ ++ timers14: timer@4c009000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x4c009000 0x400>; ++ clocks = <&rcc TIM14_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer@13 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <13>; ++ status = "disabled"; ++ }; ++ }; ++ ++ timers15: timer@4c00a000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x4c00a000 0x400>; ++ clocks = <&rcc TIM15_K>; ++ clock-names = "int"; ++ dmas = <&dmamux1 105 0x400 0x80000001>, ++ <&dmamux1 106 0x400 0x80000001>, ++ <&dmamux1 107 0x400 0x80000001>, ++ <&dmamux1 108 0x400 0x80000001>; ++ dma-names = "ch1", "up", "trig", "com"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer@14 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <14>; ++ status = "disabled"; ++ }; ++ }; ++ ++ timers16: timer@4c00b000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x4c00b000 0x400>; ++ clocks = <&rcc TIM16_K>; ++ clock-names = "int"; ++ dmas = <&dmamux1 109 0x400 0x80000001>, ++ <&dmamux1 110 0x400 0x80000001>; ++ dma-names = "ch1", "up"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer@15 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <15>; ++ status = "disabled"; ++ }; ++ }; ++ ++ timers17: timer@4c00c000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x4c00c000 0x400>; ++ clocks = <&rcc TIM17_K>; ++ clock-names = "int"; ++ dmas = <&dmamux1 111 0x400 0x80000001>, ++ <&dmamux1 112 0x400 0x80000001>; ++ dma-names = "ch1", "up"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer@16 { ++ compatible = "st,stm32h7-timer-trigger"; ++ reg = <16>; ++ status = "disabled"; ++ }; ++ }; ++ ++ rcc: rcc@50000000 { ++ compatible = "st,stm32mp13-rcc", "syscon"; ++ reg = <0x50000000 0x1000>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ interrupts = ; ++ ++ clock-names = "hse", "hsi", "csi", "lse", "lsi"; ++ clocks = <&scmi_clk CK_SCMI_HSE>, ++ <&scmi_clk CK_SCMI_HSI>, ++ <&scmi_clk CK_SCMI_CSI>, ++ <&scmi_clk CK_SCMI_LSE>, ++ <&scmi_clk CK_SCMI_LSI>; ++ }; ++ ++ exti: interrupt-controller@5000d000 { ++ compatible = "st,stm32mp13-exti", "syscon"; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x5000d000 0x400>; ++ }; ++ ++ syscfg: syscon@50020000 { ++ compatible = "st,stm32mp157-syscfg", "syscon"; ++ reg = <0x50020000 0x400>; ++ clocks = <&rcc SYSCFG>; ++ }; ++ ++ lptimer2: timer@50021000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-lptimer"; ++ reg = <0x50021000 0x400>; ++ interrupts-extended = <&exti 48 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc LPTIM2_K>; ++ clock-names = "mux"; ++ power-domains = <&pd_core_ret>; ++ wakeup-source; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm-lp"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ trigger@1 { ++ compatible = "st,stm32-lptimer-trigger"; ++ reg = <1>; ++ status = "disabled"; ++ }; ++ ++ counter { ++ compatible = "st,stm32-lptimer-counter"; ++ status = "disabled"; ++ }; ++ ++ timer { ++ compatible = "st,stm32-lptimer-timer"; ++ status = "disabled"; ++ }; ++ }; ++ ++ lptimer3: timer@50022000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-lptimer"; ++ reg = <0x50022000 0x400>; ++ interrupts-extended = <&exti 50 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc LPTIM3_K>; ++ clock-names = "mux"; ++ power-domains = <&pd_core_ret>; ++ wakeup-source; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm-lp"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ trigger@2 { ++ compatible = "st,stm32-lptimer-trigger"; ++ reg = <2>; ++ status = "disabled"; ++ }; ++ ++ timer { ++ compatible = "st,stm32-lptimer-timer"; ++ status = "disabled"; ++ }; ++ }; ++ ++ lptimer4: timer@50023000 { ++ compatible = "st,stm32-lptimer"; ++ reg = <0x50023000 0x400>; ++ interrupts-extended = <&exti 52 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc LPTIM4_K>; ++ clock-names = "mux"; ++ power-domains = <&pd_core_ret>; ++ wakeup-source; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm-lp"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer { ++ compatible = "st,stm32-lptimer-timer"; ++ status = "disabled"; ++ }; ++ }; ++ ++ lptimer5: timer@50024000 { ++ compatible = "st,stm32-lptimer"; ++ reg = <0x50024000 0x400>; ++ interrupts-extended = <&exti 53 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc LPTIM5_K>; ++ clock-names = "mux"; ++ power-domains = <&pd_core_ret>; ++ wakeup-source; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm-lp"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ timer { ++ compatible = "st,stm32-lptimer-timer"; ++ status = "disabled"; ++ }; ++ }; ++ ++ dts: thermal@50028000 { ++ compatible = "st,stm32-thermal"; ++ interrupts = ; ++ clocks = <&rcc DTS>; ++ clock-names = "pclk"; ++ #thermal-sensor-cells = <0>; ++ reg = <0x50028000 0x100>; ++ status = "disabled"; ++ }; ++ ++ hdp: hdp@5002a000 { ++ compatible = "st,stm32mp1-hdp"; ++ reg = <0x5002a000 0x400>; ++ clocks = <&rcc HDP>; ++ clock-names = "hdp"; ++ status = "disabled"; ++ }; ++ ++ hash: hash@54003000 { ++ compatible = "st,stm32mp13-hash"; ++ reg = <0x54003000 0x400>; ++ interrupts = ; ++ clocks = <&rcc HASH1>; ++ resets = <&rcc HASH1_R>; ++ dmas = <&mdma 30 0x2 0x1000A02 0x0 0x0 0x0>; ++ dma-names = "in"; ++ status = "disabled"; ++ }; ++ ++ rng: rng@54004000 { ++ compatible = "st,stm32mp13-rng"; ++ reg = <0x54004000 0x400>; ++ clocks = <&rcc RNG1_K>; ++ resets = <&rcc RNG1_R>; ++ status = "disabled"; ++ }; ++ ++ mdma: dma-controller@58000000 { ++ compatible = "st,stm32h7-mdma"; ++ reg = <0x58000000 0x1000>; ++ interrupts = ; ++ clocks = <&rcc MDMA>; ++ #dma-cells = <6>; ++ dma-channels = <32>; ++ dma-requests = <48>; ++ }; ++ ++ fmc: memory-controller@58002000 { ++ #address-cells = <2>; ++ #size-cells = <1>; ++ compatible = "st,stm32mp1-fmc2-ebi"; ++ reg = <0x58002000 0x1000>; ++ clocks = <&rcc FMC_K>; ++ resets = <&rcc FMC_R>; ++ status = "disabled"; ++ ++ ranges = <0 0 0x60000000 0x04000000>, /* EBI CS 1 */ ++ <1 0 0x64000000 0x04000000>, /* EBI CS 2 */ ++ <2 0 0x68000000 0x04000000>, /* EBI CS 3 */ ++ <3 0 0x6c000000 0x04000000>, /* EBI CS 4 */ ++ <4 0 0x80000000 0x10000000>; /* NAND */ ++ ++ nand-controller@4,0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32mp1-fmc2-nfc"; ++ reg = <4 0x00000000 0x1000>, ++ <4 0x08010000 0x1000>, ++ <4 0x08020000 0x1000>, ++ <4 0x01000000 0x1000>, ++ <4 0x09010000 0x1000>, ++ <4 0x09020000 0x1000>; ++ interrupts = ; ++ dmas = <&mdma 24 0x2 0x12000a02 0x0 0x0 0x0>, ++ <&mdma 24 0x2 0x12000a08 0x0 0x0 0x0>, ++ <&mdma 25 0x2 0x12000a0a 0x0 0x0 0x0>; ++ dma-names = "tx", "rx", "ecc"; ++ status = "disabled"; ++ }; ++ }; ++ ++ qspi: spi@58003000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32f469-qspi"; ++ reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; ++ reg-names = "qspi", "qspi_mm"; ++ interrupts = ; ++ dmas = <&mdma 26 0x2 0x10100002 0x0 0x0 0x0>, ++ <&mdma 26 0x2 0x10100008 0x0 0x0 0x0>; ++ dma-names = "tx", "rx"; ++ clocks = <&rcc QSPI_K>; ++ resets = <&rcc QSPI_R>; ++ status = "disabled"; ++ }; ++ ++ sdmmc1: mmc@58005000 { ++ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; ++ arm,primecell-periphid = <0x20253180>; ++ reg = <0x58005000 0x1000>, <0x58006000 0x1000>; ++ interrupts = ; ++ interrupt-names = "cmd_irq"; ++ clocks = <&rcc SDMMC1_K>; ++ clock-names = "apb_pclk"; ++ resets = <&rcc SDMMC1_R>; ++ cap-sd-highspeed; ++ cap-mmc-highspeed; ++ max-frequency = <130000000>; ++ status = "disabled"; ++ }; ++ ++ sdmmc2: mmc@58007000 { ++ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; ++ arm,primecell-periphid = <0x20253180>; ++ reg = <0x58007000 0x1000>, <0x58008000 0x1000>; ++ interrupts = ; ++ interrupt-names = "cmd_irq"; ++ clocks = <&rcc SDMMC2_K>; ++ clock-names = "apb_pclk"; ++ resets = <&rcc SDMMC2_R>; ++ cap-sd-highspeed; ++ cap-mmc-highspeed; ++ max-frequency = <130000000>; ++ status = "disabled"; ++ }; ++ ++ crc1: crc@58009000 { ++ compatible = "st,stm32f7-crc"; ++ reg = <0x58009000 0x400>; ++ clocks = <&rcc CRC1>; ++ 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>; ++ }; ++ ++ eth1: eth1@5800a000 { ++ compatible = "snps,dwmac-4.20a", "st,stm32mp13-dwmac"; ++ reg = <0x5800a000 0x2000>; ++ reg-names = "stmmaceth"; ++ interrupts-extended = <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>, ++ <&exti 68 1>; ++ interrupt-names = "macirq", "eth_wake_irq"; ++ clock-names = "stmmaceth", ++ "mac-clk-tx", ++ "mac-clk-rx", ++ "ethstp", ++ "eth-ck"; ++ clocks = <&rcc ETH1MAC>, ++ <&rcc ETH1TX>, ++ <&rcc ETH1RX>, ++ <&rcc ETH1STP>, ++ <&rcc ETH1CK_K>; ++ st,syscon = <&syscfg 0x4 0xff0000>; ++ snps,mixed-burst; ++ snps,pbl = <2>; ++ snps,axi-config = <&stmmac_axi_config_0>; ++ snps,tso; ++ power-domains = <&pd_core>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ usbh_ohci: usbh-ohci@5800c000 { ++ compatible = "generic-ohci"; ++ reg = <0x5800c000 0x1000>; ++ clocks = <&usbphyc>, <&rcc USBH>; ++ resets = <&rcc USBH_R>; ++ interrupts = ; ++ power-domains = <&pd_core>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ usbh_ehci: usbh-ehci@5800d000 { ++ compatible = "generic-ehci"; ++ reg = <0x5800d000 0x1000>; ++ clocks = <&usbphyc>, <&rcc USBH>; ++ resets = <&rcc USBH_R>; ++ interrupts = ; ++ companion = <&usbh_ohci>; ++ power-domains = <&pd_core>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ iwdg2: watchdog@5a002000 { ++ compatible = "st,stm32mp1-iwdg"; ++ reg = <0x5a002000 0x400>; ++ clocks = <&rcc IWDG2>, <&scmi_clk CK_SCMI_LSI>; ++ clock-names = "pclk", "lsi"; ++ status = "disabled"; ++ }; ++ ++ usbphyc: usbphyc@5a006000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #clock-cells = <0>; ++ compatible = "st,stm32mp1-usbphyc"; ++ reg = <0x5a006000 0x1000>; ++ clocks = <&rcc USBPHY_K>; ++ resets = <&rcc USBPHY_R>; ++ vdda1v1-supply = <&scmi_reg11>; ++ vdda1v8-supply = <&scmi_reg18>; ++ status = "disabled"; ++ ++ usbphyc_port0: usb-phy@0 { ++ #phy-cells = <0>; ++ reg = <0>; ++ interrupts-extended = <&exti 42 IRQ_TYPE_LEVEL_HIGH>; ++ }; ++ ++ usbphyc_port1: usb-phy@1 { ++ #phy-cells = <1>; ++ reg = <1>; ++ interrupts-extended = <&exti 43 IRQ_TYPE_LEVEL_HIGH>; ++ }; ++ }; ++ ++ ddrperfm: perf@5a007000 { ++ compatible = "st,stm32-ddr-pmu"; ++ reg = <0x5a007000 0x400>; ++ clocks = <&rcc DDRPERFM>; ++ resets = <&rcc DDRPERFM_R>; ++ status = "disabled"; ++ }; ++ ++ rtc: rtc@5c004000 { ++ compatible = "st,stm32mp1-rtc"; ++ reg = <0x5c004000 0x400>; ++ clocks = <&scmi_clk CK_SCMI_RTCAPB>, ++ <&scmi_clk CK_SCMI_RTC>; ++ clock-names = "pclk", "rtc_ck"; ++ interrupts-extended = <&exti 19 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ bsec: efuse@5c005000 { ++ compatible = "st,stm32mp13-bsec"; ++ reg = <0x5c005000 0x400>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ part_number_otp: part_number_otp@4 { ++ reg = <0x4 0x2>; ++ }; ++ vrefint: vrefin_cal@52 { ++ reg = <0x52 0x2>; ++ }; ++ ts_cal1: calib@5c { ++ reg = <0x5c 0x2>; ++ }; ++ ts_cal2: calib@5e { ++ reg = <0x5e 0x2>; ++ }; ++ ethernet_mac1_address: mac1@e4 { ++ reg = <0xe4 0x6>; ++ }; ++ ethernet_mac2_address: mac2@ea { ++ reg = <0xea 0x6>; ++ }; ++ }; ++ ++ /* ++ * Break node order to solve dependency probe issue between ++ * pinctrl and exti. ++ */ ++ pinctrl: pin-controller@50002000 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "st,stm32mp135-pinctrl"; ++ ranges = <0 0x50002000 0x8400>; ++ interrupt-parent = <&exti>; ++ st,syscfg = <&exti 0x60 0xff>; ++ pins-are-numbered; ++ ++ gpioa: gpio@50002000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x0 0x400>; ++ clocks = <&rcc GPIOA>; ++ st,bank-name = "GPIOA"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 0 16>; ++ }; ++ ++ gpiob: gpio@50003000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x1000 0x400>; ++ clocks = <&rcc GPIOB>; ++ st,bank-name = "GPIOB"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 16 16>; ++ }; ++ ++ gpioc: gpio@50004000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x2000 0x400>; ++ clocks = <&rcc GPIOC>; ++ st,bank-name = "GPIOC"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 32 16>; ++ }; ++ ++ gpiod: gpio@50005000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x3000 0x400>; ++ clocks = <&rcc GPIOD>; ++ st,bank-name = "GPIOD"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 48 16>; ++ }; ++ ++ gpioe: gpio@50006000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x4000 0x400>; ++ clocks = <&rcc GPIOE>; ++ st,bank-name = "GPIOE"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 64 16>; ++ }; ++ ++ gpiof: gpio@50007000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x5000 0x400>; ++ clocks = <&rcc GPIOF>; ++ st,bank-name = "GPIOF"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 80 16>; ++ }; ++ ++ gpiog: gpio@50008000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x6000 0x400>; ++ clocks = <&rcc GPIOG>; ++ st,bank-name = "GPIOG"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 96 16>; ++ }; ++ ++ gpioh: gpio@50009000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x7000 0x400>; ++ clocks = <&rcc GPIOH>; ++ st,bank-name = "GPIOH"; ++ ngpios = <15>; ++ gpio-ranges = <&pinctrl 0 112 15>; ++ }; ++ ++ gpioi: gpio@5000a000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x8000 0x400>; ++ clocks = <&rcc GPIOI>; ++ st,bank-name = "GPIOI"; ++ ngpios = <8>; ++ gpio-ranges = <&pinctrl 0 128 8>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp133.dtsi b/arch/arm/dts/stm32mp133.dtsi +new file mode 100644 +index 0000000000..e00c30cb6e +--- /dev/null ++++ b/arch/arm/dts/stm32mp133.dtsi +@@ -0,0 +1,87 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2021 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++#include "stm32mp131.dtsi" ++ ++/ { ++ soc { ++ adc_1: adc@48003000 { ++ compatible = "st,stm32mp13-adc-core"; ++ reg = <0x48003000 0x400>; ++ interrupts = ; ++ clocks = <&rcc ADC1>, <&rcc ADC1_K>; ++ clock-names = "bus", "adc"; ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ adc1: adc@0 { ++ compatible = "st,stm32mp13-adc"; ++ #io-channel-cells = <1>; ++ reg = <0x0>; ++ interrupt-parent = <&adc_1>; ++ interrupts = <0>; ++ dmas = <&dmamux1 9 0x400 0x80000001>; ++ dma-names = "rx"; ++ nvmem-cells = <&vrefint>; ++ nvmem-cell-names = "vrefint"; ++ status = "disabled"; ++ }; ++ }; ++ ++ m_can1: can@4400e000 { ++ compatible = "bosch,m_can"; ++ reg = <0x4400e000 0x400>, <0x44011000 0x1400>; ++ reg-names = "m_can", "message_ram"; ++ interrupts = , ++ ; ++ interrupt-names = "int0", "int1"; ++ clocks = <&scmi_clk CK_SCMI_HSE>, <&rcc FDCAN_K>; ++ clock-names = "hclk", "cclk"; ++ bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>; ++ status = "disabled"; ++ }; ++ ++ m_can2: can@4400f000 { ++ compatible = "bosch,m_can"; ++ reg = <0x4400f000 0x400>, <0x44011000 0x2800>; ++ reg-names = "m_can", "message_ram"; ++ interrupts = , ++ ; ++ interrupt-names = "int0", "int1"; ++ clocks = <&scmi_clk CK_SCMI_HSE>, <&rcc FDCAN_K>; ++ clock-names = "hclk", "cclk"; ++ bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>; ++ status = "disabled"; ++ }; ++ ++ eth2: eth2@5800e000 { ++ compatible = "snps,dwmac-4.20a", "st,stm32mp13-dwmac"; ++ reg = <0x5800e000 0x2000>; ++ reg-names = "stmmaceth"; ++ interrupts-extended = <&intc GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "macirq"; ++ clock-names = "stmmaceth", ++ "mac-clk-tx", ++ "mac-clk-rx", ++ "ethstp", ++ "eth-ck"; ++ clocks = <&rcc ETH2MAC>, ++ <&rcc ETH2TX>, ++ <&rcc ETH2RX>, ++ <&rcc ETH2STP>, ++ <&rcc ETH2CK_K>; ++ st,syscon = <&syscfg 0x4 0xff000000>; ++ snps,mixed-burst; ++ snps,pbl = <2>; ++ snps,axi-config = <&stmmac_axi_config_0>; ++ snps,tso; ++ status = "disabled"; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp135.dtsi b/arch/arm/dts/stm32mp135.dtsi +new file mode 100644 +index 0000000000..61052a87d5 +--- /dev/null ++++ b/arch/arm/dts/stm32mp135.dtsi +@@ -0,0 +1,32 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2021 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++#include "stm32mp133.dtsi" ++ ++/ { ++ soc { ++ dcmipp: dcmipp@5a000000 { ++ compatible = "st,stm32mp13-dcmipp"; ++ reg = <0x5a000000 0x400>; ++ interrupts = ; ++ resets = <&rcc DCMIPP_R>; ++ clocks = <&rcc DCMIPP_K>; ++ clock-names = "kclk"; ++ status = "disabled"; ++ }; ++ ++ ltdc: display-controller@5a001000 { ++ compatible = "st,stm32-ltdc"; ++ reg = <0x5a001000 0x400>; ++ interrupts = , ++ ; ++ clocks = <&rcc LTDC_PX>; ++ clock-names = "lcd"; ++ resets = <&scmi_reset RST_SCMI_LTDC>; ++ status = "disabled"; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp135d-dk-u-boot.dtsi b/arch/arm/dts/stm32mp135d-dk-u-boot.dtsi +new file mode 100644 +index 0000000000..b969add65c +--- /dev/null ++++ b/arch/arm/dts/stm32mp135d-dk-u-boot.dtsi +@@ -0,0 +1,70 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause ++/* ++ * Copyright (C) STMicroelectronics 2021 - All Rights Reserved ++ */ ++ ++#include "stm32mp13-u-boot.dtsi" ++ ++/ { ++ aliases { ++ mmc0 = &sdmmc1; ++ usb0 = &usbotg_hs; ++ }; ++ ++ config { ++ u-boot,boot-led = "led-blue"; ++ u-boot,error-led = "led-red"; ++ u-boot,mmc-env-partition = "u-boot-env"; ++ st,adc_usb_pd = <&adc1 6>, <&adc1 12>; ++ st,fastboot-gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ st,stm32prog-gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ }; ++ ++ leds { ++ led-red { ++ color = ; ++ gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ }; ++}; ++ ++&adc_1 { ++ status = "okay"; ++}; ++ ++&panel_rgb { ++ compatible = "rocktech,rk043fn48h","simple-panel"; ++ ++ display-timings { ++ timing@0 { ++ clock-frequency = <10000000>; ++ hactive = <480>; ++ vactive = <272>; ++ hfront-porch = <10>; ++ hback-porch = <10>; ++ hsync-len = <52>; ++ vfront-porch = <10>; ++ vback-porch = <10>; ++ vsync-len = <10>; ++ hsync-active = <0>; ++ vsync-active = <0>; ++ de-active = <1>; ++ pixelclk-active = <1>; ++ }; ++ }; ++}; ++ ++&uart4 { ++ u-boot,dm-pre-reloc; ++}; ++ ++&uart4_pins_a { ++ u-boot,dm-pre-reloc; ++ pins1 { ++ u-boot,dm-pre-reloc; ++ }; ++ pins2 { ++ u-boot,dm-pre-reloc; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp135d-dk.dts b/arch/arm/dts/stm32mp135d-dk.dts +new file mode 100644 +index 0000000000..d56874fb3d +--- /dev/null ++++ b/arch/arm/dts/stm32mp135d-dk.dts +@@ -0,0 +1,687 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include ++#include "stm32mp135.dtsi" ++#include "stm32mp13xd.dtsi" ++#include "stm32mp13-pinctrl.dtsi" ++ ++/ { ++ model = "STMicroelectronics STM32MP135D-DK Discovery Board"; ++ compatible = "st,stm32mp135d-dk", "st,stm32mp135"; ++ ++ aliases { ++ ethernet0 = ð1; ++ ethernet1 = ð2; ++ serial0 = &uart4; ++ serial1 = &usart1; ++ serial2 = &uart8; ++ serial3 = &usart2; ++ }; ++ ++ chosen { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ stdout-path = "serial0:115200n8"; ++ ++ framebuffer { ++ compatible = "simple-framebuffer"; ++ clocks = <&rcc LTDC_PX>; ++ status = "disabled"; ++ }; ++ }; ++ ++ clocks { ++ clk_ext_camera: clk-ext-camera { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <24000000>; ++ }; ++ ++ clk_mco1: clk-mco1 { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <24000000>; ++ }; ++ }; ++ ++ memory@c0000000 { ++ device_type = "memory"; ++ reg = <0xc0000000 0x20000000>; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ ++ user-pa13 { ++ label = "User-PA13"; ++ linux,code = ; ++ gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-blue { ++ function = LED_FUNCTION_HEARTBEAT; ++ color = ; ++ gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "heartbeat"; ++ default-state = "off"; ++ }; ++ }; ++ ++ reserved-memory { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ optee_framebuffer@dd000000 { ++ reg = <0xdd000000 0x1000000>; ++ no-map; ++ }; ++ ++ optee@de000000 { ++ reg = <0xde000000 0x2000000>; ++ no-map; ++ }; ++ }; ++ ++ v3v3_ao: v3v3_ao { ++ compatible = "regulator-fixed"; ++ regulator-name = "v3v3_ao"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; ++ ++ panel_backlight: panel-backlight { ++ compatible = "gpio-backlight"; ++ gpios = <&gpioe 12 GPIO_ACTIVE_HIGH>; ++ default-on; ++ default-brightness-level = <0>; ++ status = "okay"; ++ }; ++ ++ panel_rgb: panel-rgb { ++ compatible = "rocktech,rk043fn48h", "panel-dpi"; ++ enable-gpios = <&gpioi 7 GPIO_ACTIVE_HIGH>; ++ backlight = <&panel_backlight>; ++ power-supply = <&scmi_v3v3_sw>; ++ data-mapping = "bgr666"; ++ status = "okay"; ++ ++ width-mm = <105>; ++ height-mm = <67>; ++ ++ port { ++ panel_in_rgb: endpoint { ++ remote-endpoint = <<dc_out_rgb>; ++ }; ++ }; ++ ++ panel-timing { ++ clock-frequency = <10000000>; ++ hactive = <480>; ++ vactive = <272>; ++ hsync-len = <52>; ++ hfront-porch = <10>; ++ hback-porch = <10>; ++ vsync-len = <10>; ++ vfront-porch = <10>; ++ vback-porch = <10>; ++ hsync-active = <0>; ++ vsync-active = <0>; ++ de-active = <1>; ++ pixelclk-active = <1>; ++ }; ++ }; ++ ++ wifi_pwrseq: wifi-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ reset-gpios = <&mcp23017 11 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&adc_1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&adc1_usb_cc_pins_a>; ++ vdda-supply = <&scmi_vdd_adc>; ++ vref-supply = <&scmi_vdd_adc>; ++ status = "okay"; ++ adc1: adc@0 { ++ /* ++ * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in6 & in12. ++ * Use at least 5 * RC time, e.g. 5 * (Rp + Rd) * C: ++ * 5 * (5.1 + 47kOhms) * 5pF => 1.3us. ++ * Use arbitrary margin here (e.g. 5us). ++ */ ++ st,min-sample-time-nsecs = <5000>; ++ /* USB Type-C CC1 & CC2 */ ++ st,adc-channels = <6 12>; ++ status = "okay"; ++ }; ++}; ++ ++&crc1 { ++ status = "okay"; ++}; ++ ++&dcmipp { ++ status = "okay"; ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&dcmipp_pins_a>; ++ pinctrl-1 = <&dcmipp_sleep_pins_a>; ++ port { ++ dcmipp_0: endpoint { ++ remote-endpoint = <&mipid02_2>; ++ bus-width = <8>; ++ hsync-active = <0>; ++ vsync-active = <0>; ++ pclk-sample = <0>; ++ pclk-max-frequency = <120000000>; ++ }; ++ }; ++}; ++ ++&dma1 { ++ sram = <&dma_pool>; ++}; ++ ++&dma2 { ++ sram = <&dma_pool>; ++}; ++ ++&dts { ++ status = "okay"; ++}; ++ ++ð1 { ++ status = "okay"; ++ pinctrl-0 = <ð1_rmii_pins_a>; ++ pinctrl-1 = <ð1_rmii_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ phy-mode = "rmii"; ++ max-speed = <100>; ++ phy-handle = <&phy0_eth1>; ++ nvmem-cells = <ðernet_mac1_address>; ++ nvmem-cell-names = "mac-address"; ++ ++ mdio1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "snps,dwmac-mdio"; ++ ++ phy0_eth1: ethernet-phy@0 { ++ compatible = "ethernet-phy-id0007.c131"; ++ reset-gpios = <&mcp23017 9 GPIO_ACTIVE_LOW>; ++ reg = <0>; ++ interrupt-parent = <&gpioi>; ++ interrupts = <3 IRQ_TYPE_EDGE_RISING>; ++ }; ++ }; ++}; ++ ++ð2 { ++ status = "okay"; ++ pinctrl-0 = <ð2_rmii_pins_a>; ++ pinctrl-1 = <ð2_rmii_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ phy-mode = "rmii"; ++ max-speed = <100>; ++ phy-handle = <&phy0_eth2>; ++ st,ext-phyclk; ++ phy-supply = <&scmi_v3v3_sw>; ++ nvmem-cells = <ðernet_mac2_address>; ++ nvmem-cell-names = "mac-address"; ++ ++ mdio1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "snps,dwmac-mdio"; ++ phy0_eth2: ethernet-phy@0 { ++ compatible = "ethernet-phy-id0007.c131"; ++ reset-gpios = <&mcp23017 10 GPIO_ACTIVE_LOW>; ++ reg = <0>; ++ }; ++ }; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&i2c1_pins_a>; ++ pinctrl-1 = <&i2c1_sleep_pins_a>; ++ i2c-scl-rising-time-ns = <96>; ++ i2c-scl-falling-time-ns = <3>; ++ clock-frequency = <1000000>; ++ status = "okay"; ++ /* spare dmas for other usage */ ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ ++ mcp23017: pinctrl@21 { ++ compatible = "microchip,mcp23017"; ++ reg = <0x21>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupts = <12 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpiog>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mcp23017_pins_a>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ microchip,irq-mirror; ++ }; ++ ++ stm32g0@53 { ++ compatible = "st,stm32g0-typec"; ++ reg = <0x53>; ++ /* Alert pin on PI2 */ ++ interrupts = <2 IRQ_TYPE_EDGE_FALLING>; ++ interrupt-parent = <&gpioi>; ++ /* Internal pull-up on PI2 */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&stm32g0_intn_pins_a>; ++ firmware-name = "stm32g0-ucsi.mp135f-dk.fw"; ++ power-domains = <&pd_core>; ++ wakeup-source; ++ connector { ++ compatible = "usb-c-connector"; ++ label = "USB-C"; ++ ++ port { ++ con_usb_c_g0_ep: endpoint { ++ remote-endpoint = <&usbotg_hs_ep>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2c5 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&i2c5_pins_a>; ++ pinctrl-1 = <&i2c5_sleep_pins_a>; ++ i2c-scl-rising-time-ns = <170>; ++ i2c-scl-falling-time-ns = <5>; ++ clock-frequency = <400000>; ++ status = "okay"; ++ /* spare dmas for other usage */ ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ ++ gc2145: gc2145@3c { ++ compatible = "galaxycore,gc2145"; ++ reg = <0x3c>; ++ clocks = <&clk_ext_camera>; ++ IOVDD-supply = <&scmi_v3v3_sw>; ++ AVDD-supply = <&scmi_v3v3_sw>; ++ DVDD-supply = <&scmi_v3v3_sw>; ++ powerdown-gpios = <&mcp23017 3 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; ++ reset-gpios = <&mcp23017 4 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; ++ status = "okay"; ++ ++ port { ++ gc2145_ep: endpoint { ++ remote-endpoint = <&mipid02_0>; ++ clock-lanes = <0>; ++ data-lanes = <1 2>; ++ }; ++ }; ++ }; ++ ++ goodix: goodix_ts@5d { ++ compatible = "goodix,gt911"; ++ reg = <0x5d>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&goodix_pins_a>; ++ interrupt-parent = <&gpiof>; ++ interrupts = <5 IRQ_TYPE_EDGE_FALLING>; ++ reset-gpios = <&gpioh 2 GPIO_ACTIVE_LOW>; ++ AVDD28-supply = <&scmi_v3v3_sw>; ++ VDDIO-supply = <&scmi_v3v3_sw>; ++ touchscreen-size-x = <480>; ++ touchscreen-size-y = <272>; ++ status = "okay" ; ++ }; ++ ++ ov5640: camera@3c { ++ compatible = "ovti,ov5640"; ++ reg = <0x3c>; ++ clocks = <&clk_ext_camera>; ++ clock-names = "xclk"; ++ DOVDD-supply = <&scmi_v3v3_sw>; ++ status = "disabled"; ++ powerdown-gpios = <&mcp23017 3 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; ++ reset-gpios = <&mcp23017 4 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; ++ ++ port { ++ ov5640_0: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2>; ++ }; ++ }; ++ }; ++ ++ stmipi: stmipi@14 { ++ compatible = "st,st-mipid02"; ++ reg = <0x14>; ++ status = "okay"; ++ clocks = <&clk_mco1>; ++ clock-names = "xclk"; ++ VDDE-supply = <&scmi_v1v8_periph>; ++ VDDIN-supply = <&scmi_v1v8_periph>; ++ reset-gpios = <&mcp23017 2 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ ++ mipid02_0: endpoint { ++ data-lanes = <1 2>; ++ lane-polarities = <0 0 0>; ++ remote-endpoint = <&gc2145_ep>; ++ }; ++ }; ++ port@2 { ++ reg = <2>; ++ ++ mipid02_2: endpoint { ++ bus-width = <8>; ++ hsync-active = <0>; ++ vsync-active = <0>; ++ pclk-sample = <0>; ++ remote-endpoint = <&dcmipp_0>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&iwdg2 { ++ timeout-sec = <32>; ++ status = "okay"; ++}; ++ ++<dc { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <<dc_pins_a>; ++ pinctrl-1 = <<dc_sleep_pins_a>; ++ status = "okay"; ++ ++ port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ltdc_out_rgb: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&panel_in_rgb>; ++ }; ++ }; ++}; ++ ++&rtc { ++ st,lsco = ; ++ pinctrl-0 = <&rtc_out2_rmp_pins_a>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&scmi_regu { ++ scmi_vddcpu: voltd-vddcpu { ++ voltd-name = "vddcpu"; ++ regulator-name = "vddcpu"; ++ }; ++ scmi_vdd: voltd-vdd { ++ voltd-name = "vdd"; ++ regulator-name = "vdd"; ++ }; ++ scmi_vddcore: voltd-vddcore { ++ voltd-name = "vddcore"; ++ regulator-name = "vddcore"; ++ }; ++ scmi_vdd_adc: voltd-vdd_adc { ++ voltd-name = "vdd_adc"; ++ regulator-name = "vdd_adc"; ++ }; ++ scmi_vdd_usb: voltd-vdd_usb { ++ voltd-name = "vdd_usb"; ++ regulator-name = "vdd_usb"; ++ }; ++ scmi_vdd_sd: voltd-vdd_sd { ++ voltd-name = "vdd_sd"; ++ regulator-name = "vdd_sd"; ++ }; ++ scmi_v1v8_periph: voltd-v1v8_periph { ++ voltd-name = "v1v8_periph"; ++ regulator-name = "v1v8_periph"; ++ }; ++ scmi_v3v3_sw: voltd-v3v3_sw { ++ voltd-name = "v3v3_sw"; ++ regulator-name = "v3v3_sw"; ++ }; ++}; ++ ++&sdmmc1 { ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_clk_pins_a>; ++ pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_clk_pins_a>; ++ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; ++ cd-gpios = <&gpioh 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ disable-wp; ++ st,neg-edge; ++ bus-width = <4>; ++ vmmc-supply = <&scmi_vdd_sd>; ++ status = "okay"; ++}; ++ ++/* Wifi */ ++&sdmmc2 { ++ arm,primecell-periphid = <0x10153180>; ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_clk_pins_a>; ++ pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_clk_pins_a>; ++ pinctrl-2 = <&sdmmc2_b4_sleep_pins_a>; ++ non-removable; ++ st,neg-edge; ++ bus-width = <4>; ++ vmmc-supply = <&v3v3_ao>; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ brcmf: bcrmf@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ }; ++}; ++ ++&spi5 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&spi5_pins_a>; ++ pinctrl-1 = <&spi5_sleep_pins_a>; ++ status = "disabled"; ++}; ++ ++&sram { ++ dma_pool: dma-sram@0 { ++ reg = <0x0 0x4000>; ++ pool; ++ }; ++}; ++ ++&timers3 { ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm3_pins_a>; ++ pinctrl-1 = <&pwm3_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@2 { ++ status = "okay"; ++ }; ++}; ++ ++&timers4 { ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm4_pins_a>; ++ pinctrl-1 = <&pwm4_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@3 { ++ status = "okay"; ++ }; ++}; ++ ++&timers8 { ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm8_pins_a>; ++ pinctrl-1 = <&pwm8_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@7 { ++ status = "okay"; ++ }; ++}; ++ ++&timers14 { ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm14_pins_a>; ++ pinctrl-1 = <&pwm14_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@13 { ++ status = "okay"; ++ }; ++}; ++ ++&uart4 { ++ pinctrl-names = "default", "sleep", "idle"; ++ pinctrl-0 = <&uart4_pins_a>; ++ pinctrl-1 = <&uart4_sleep_pins_a>; ++ pinctrl-2 = <&uart4_idle_pins_a>; ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "okay"; ++}; ++ ++&uart8 { ++ pinctrl-names = "default", "sleep", "idle"; ++ pinctrl-0 = <&uart8_pins_a>; ++ pinctrl-1 = <&uart8_sleep_pins_a>; ++ pinctrl-2 = <&uart8_idle_pins_a>; ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++}; ++ ++&usart1 { ++ pinctrl-names = "default", "sleep", "idle"; ++ pinctrl-0 = <&usart1_pins_a>; ++ pinctrl-1 = <&usart1_sleep_pins_a>; ++ pinctrl-2 = <&usart1_idle_pins_a>; ++ uart-has-rtscts; ++ status = "disabled"; ++}; ++ ++/* Bluetooth */ ++&usart2 { ++ pinctrl-names = "default", "sleep", "idle"; ++ pinctrl-0 = <&usart2_pins_a>; ++ pinctrl-1 = <&usart2_sleep_pins_a>; ++ pinctrl-2 = <&usart2_idle_pins_a>; ++ uart-has-rtscts; ++ status = "okay"; ++ ++ bluetooth { ++ shutdown-gpios = <&mcp23017 13 GPIO_ACTIVE_HIGH>; ++ compatible = "brcm,bcm43438-bt"; ++ max-speed = <3000000>; ++ vbat-supply = <&v3v3_ao>; ++ vddio-supply = <&v3v3_ao>; ++ }; ++}; ++ ++&usbh_ehci { ++ phys = <&usbphyc_port0>; ++ status = "okay"; ++}; ++ ++&usbotg_hs { ++ phys = <&usbphyc_port1 0>; ++ phy-names = "usb2-phy"; ++ usb-role-switch; ++ status = "okay"; ++ port { ++ usbotg_hs_ep: endpoint { ++ remote-endpoint = <&con_usb_c_g0_ep>; ++ }; ++ }; ++}; ++ ++&usbphyc { ++ status = "okay"; ++}; ++ ++&usbphyc_port0 { ++ phy-supply = <&scmi_vdd_usb>; ++ st,current-boost-microamp = <1000>; ++ st,decrease-hs-slew-rate; ++ st,tune-hs-dc-level = <2>; ++ st,enable-hs-rftime-reduction; ++ st,trim-hs-current = <11>; ++ st,trim-hs-impedance = <2>; ++ st,tune-squelch-level = <1>; ++ st,enable-hs-rx-gain-eq; ++ st,no-hs-ftime-ctrl; ++ st,no-lsfs-sc; ++ ++ /* ++ * Hack to keep hub active if wakeup source is enabled ++ * otherwise the hub will wakeup the port0 as soon as the v3v3_sw is disabled ++ */ ++ connector { ++ compatible = "usb-a-connector"; ++ vbus-supply = <&scmi_v3v3_sw>; ++ }; ++}; ++ ++&usbphyc_port1 { ++ phy-supply = <&scmi_vdd_usb>; ++ st,current-boost-microamp = <1000>; ++ st,decrease-hs-slew-rate; ++ st,tune-hs-dc-level = <2>; ++ st,enable-hs-rftime-reduction; ++ st,trim-hs-current = <11>; ++ st,trim-hs-impedance = <2>; ++ st,tune-squelch-level = <1>; ++ st,enable-hs-rx-gain-eq; ++ st,no-hs-ftime-ctrl; ++ st,no-lsfs-sc; ++}; +diff --git a/arch/arm/dts/stm32mp135f-dk-u-boot.dtsi b/arch/arm/dts/stm32mp135f-dk-u-boot.dtsi +new file mode 100644 +index 0000000000..2b21966ece +--- /dev/null ++++ b/arch/arm/dts/stm32mp135f-dk-u-boot.dtsi +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause ++/* ++ * Copyright (C) STMicroelectronics 2021 - All Rights Reserved ++ */ ++ ++#include "stm32mp135d-dk-u-boot.dtsi" +diff --git a/arch/arm/dts/stm32mp135f-dk.dts b/arch/arm/dts/stm32mp135f-dk.dts +new file mode 100644 +index 0000000000..ef2d9f1374 +--- /dev/null ++++ b/arch/arm/dts/stm32mp135f-dk.dts +@@ -0,0 +1,689 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2021 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++/dts-v1/; ++ ++#include ++#include ++#include ++#include ++#include "stm32mp135.dtsi" ++#include "stm32mp13xf.dtsi" ++#include "stm32mp13-pinctrl.dtsi" ++ ++/ { ++ model = "STMicroelectronics STM32MP135F-DK Discovery Board"; ++ compatible = "st,stm32mp135f-dk", "st,stm32mp135"; ++ ++ aliases { ++ ethernet0 = ð1; ++ ethernet1 = ð2; ++ serial0 = &uart4; ++ serial1 = &usart1; ++ serial2 = &uart8; ++ serial3 = &usart2; ++ }; ++ ++ chosen { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ stdout-path = "serial0:115200n8"; ++ ++ framebuffer { ++ compatible = "simple-framebuffer"; ++ clocks = <&rcc LTDC_PX>; ++ status = "disabled"; ++ }; ++ }; ++ ++ clocks { ++ clk_ext_camera: clk-ext-camera { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <24000000>; ++ }; ++ ++ clk_mco1: clk-mco1 { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <24000000>; ++ }; ++ }; ++ ++ memory@c0000000 { ++ device_type = "memory"; ++ reg = <0xc0000000 0x20000000>; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ ++ user-pa13 { ++ label = "User-PA13"; ++ linux,code = ; ++ gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-blue { ++ function = LED_FUNCTION_HEARTBEAT; ++ color = ; ++ gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "heartbeat"; ++ default-state = "off"; ++ }; ++ }; ++ ++ reserved-memory { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ optee_framebuffer@dd000000 { ++ reg = <0xdd000000 0x1000000>; ++ no-map; ++ }; ++ ++ optee@de000000 { ++ reg = <0xde000000 0x2000000>; ++ no-map; ++ }; ++ }; ++ ++ v3v3_ao: v3v3_ao { ++ compatible = "regulator-fixed"; ++ regulator-name = "v3v3_ao"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; ++ ++ panel_backlight: panel-backlight { ++ compatible = "gpio-backlight"; ++ gpios = <&gpioe 12 GPIO_ACTIVE_HIGH>; ++ default-on; ++ default-brightness-level = <0>; ++ status = "okay"; ++ }; ++ ++ panel_rgb: panel-rgb { ++ compatible = "rocktech,rk043fn48h", "panel-dpi"; ++ enable-gpios = <&gpioi 7 GPIO_ACTIVE_HIGH>; ++ backlight = <&panel_backlight>; ++ power-supply = <&scmi_v3v3_sw>; ++ data-mapping = "bgr666"; ++ status = "okay"; ++ ++ width-mm = <105>; ++ height-mm = <67>; ++ ++ port { ++ panel_in_rgb: endpoint { ++ remote-endpoint = <<dc_out_rgb>; ++ }; ++ }; ++ ++ panel-timing { ++ clock-frequency = <10000000>; ++ hactive = <480>; ++ vactive = <272>; ++ hsync-len = <52>; ++ hfront-porch = <10>; ++ hback-porch = <10>; ++ vsync-len = <10>; ++ vfront-porch = <10>; ++ vback-porch = <10>; ++ hsync-active = <0>; ++ vsync-active = <0>; ++ de-active = <1>; ++ pixelclk-active = <1>; ++ }; ++ }; ++ ++ wifi_pwrseq: wifi-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ reset-gpios = <&mcp23017 11 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&adc_1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&adc1_usb_cc_pins_a>; ++ vdda-supply = <&scmi_vdd_adc>; ++ vref-supply = <&scmi_vdd_adc>; ++ status = "okay"; ++ adc1: adc@0 { ++ /* ++ * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in6 & in12. ++ * Use at least 5 * RC time, e.g. 5 * (Rp + Rd) * C: ++ * 5 * (5.1 + 47kOhms) * 5pF => 1.3us. ++ * Use arbitrary margin here (e.g. 5us). ++ */ ++ st,min-sample-time-nsecs = <5000>; ++ /* USB Type-C CC1 & CC2 */ ++ st,adc-channels = <6 12>; ++ status = "okay"; ++ }; ++}; ++ ++&crc1 { ++ status = "okay"; ++}; ++ ++&cryp { ++ status = "okay"; ++}; ++ ++&dcmipp { ++ status = "okay"; ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&dcmipp_pins_a>; ++ pinctrl-1 = <&dcmipp_sleep_pins_a>; ++ port { ++ dcmipp_0: endpoint { ++ remote-endpoint = <&mipid02_2>; ++ bus-width = <8>; ++ hsync-active = <0>; ++ vsync-active = <0>; ++ pclk-sample = <0>; ++ pclk-max-frequency = <120000000>; ++ }; ++ }; ++}; ++ ++&dma1 { ++ sram = <&dma_pool>; ++}; ++ ++&dma2 { ++ sram = <&dma_pool>; ++}; ++ ++&dts { ++ status = "okay"; ++}; ++ ++ð1 { ++ status = "okay"; ++ pinctrl-0 = <ð1_rmii_pins_a>; ++ pinctrl-1 = <ð1_rmii_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ phy-mode = "rmii"; ++ max-speed = <100>; ++ phy-handle = <&phy0_eth1>; ++ nvmem-cells = <ðernet_mac1_address>; ++ nvmem-cell-names = "mac-address"; ++ ++ mdio1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "snps,dwmac-mdio"; ++ ++ phy0_eth1: ethernet-phy@0 { ++ compatible = "ethernet-phy-id0007.c131"; ++ reset-gpios = <&mcp23017 9 GPIO_ACTIVE_LOW>; ++ reg = <0>; ++ }; ++ }; ++}; ++ ++ð2 { ++ status = "okay"; ++ pinctrl-0 = <ð2_rmii_pins_a>; ++ pinctrl-1 = <ð2_rmii_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ phy-mode = "rmii"; ++ max-speed = <100>; ++ phy-handle = <&phy0_eth2>; ++ st,ext-phyclk; ++ phy-supply = <&scmi_v3v3_sw>; ++ nvmem-cells = <ðernet_mac2_address>; ++ nvmem-cell-names = "mac-address"; ++ ++ mdio1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "snps,dwmac-mdio"; ++ phy0_eth2: ethernet-phy@0 { ++ compatible = "ethernet-phy-id0007.c131"; ++ reset-gpios = <&mcp23017 10 GPIO_ACTIVE_LOW>; ++ reg = <0>; ++ }; ++ }; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&i2c1_pins_a>; ++ pinctrl-1 = <&i2c1_sleep_pins_a>; ++ i2c-scl-rising-time-ns = <96>; ++ i2c-scl-falling-time-ns = <3>; ++ clock-frequency = <1000000>; ++ status = "okay"; ++ /* spare dmas for other usage */ ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ ++ mcp23017: pinctrl@21 { ++ compatible = "microchip,mcp23017"; ++ reg = <0x21>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupts = <12 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpiog>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mcp23017_pins_a>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ microchip,irq-mirror; ++ }; ++ ++ stm32g0@53 { ++ compatible = "st,stm32g0-typec"; ++ reg = <0x53>; ++ /* Alert pin on PI2 */ ++ interrupts = <2 IRQ_TYPE_EDGE_FALLING>; ++ interrupt-parent = <&gpioi>; ++ /* Internal pull-up on PI2 */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&stm32g0_intn_pins_a>; ++ firmware-name = "stm32g0-ucsi.mp135f-dk.fw"; ++ power-domains = <&pd_core>; ++ wakeup-source; ++ connector { ++ compatible = "usb-c-connector"; ++ label = "USB-C"; ++ ++ port { ++ con_usb_c_g0_ep: endpoint { ++ remote-endpoint = <&usbotg_hs_ep>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2c5 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&i2c5_pins_a>; ++ pinctrl-1 = <&i2c5_sleep_pins_a>; ++ i2c-scl-rising-time-ns = <170>; ++ i2c-scl-falling-time-ns = <5>; ++ clock-frequency = <400000>; ++ status = "okay"; ++ /* spare dmas for other usage */ ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ ++ gc2145: gc2145@3c { ++ compatible = "galaxycore,gc2145"; ++ reg = <0x3c>; ++ clocks = <&clk_ext_camera>; ++ IOVDD-supply = <&scmi_v3v3_sw>; ++ AVDD-supply = <&scmi_v3v3_sw>; ++ DVDD-supply = <&scmi_v3v3_sw>; ++ powerdown-gpios = <&mcp23017 3 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; ++ reset-gpios = <&mcp23017 4 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; ++ status = "okay"; ++ ++ port { ++ gc2145_ep: endpoint { ++ remote-endpoint = <&mipid02_0>; ++ clock-lanes = <0>; ++ data-lanes = <1 2>; ++ }; ++ }; ++ }; ++ ++ goodix: goodix_ts@5d { ++ compatible = "goodix,gt911"; ++ reg = <0x5d>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&goodix_pins_a>; ++ interrupt-parent = <&gpiof>; ++ interrupts = <5 IRQ_TYPE_EDGE_FALLING>; ++ reset-gpios = <&gpioh 2 GPIO_ACTIVE_LOW>; ++ AVDD28-supply = <&scmi_v3v3_sw>; ++ VDDIO-supply = <&scmi_v3v3_sw>; ++ touchscreen-size-x = <480>; ++ touchscreen-size-y = <272>; ++ status = "okay" ; ++ }; ++ ++ ov5640: camera@3c { ++ compatible = "ovti,ov5640"; ++ reg = <0x3c>; ++ clocks = <&clk_ext_camera>; ++ clock-names = "xclk"; ++ DOVDD-supply = <&scmi_v3v3_sw>; ++ status = "disabled"; ++ powerdown-gpios = <&mcp23017 3 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; ++ reset-gpios = <&mcp23017 4 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; ++ ++ port { ++ ov5640_0: endpoint { ++ clock-lanes = <0>; ++ data-lanes = <1 2>; ++ }; ++ }; ++ }; ++ ++ stmipi: stmipi@14 { ++ compatible = "st,st-mipid02"; ++ reg = <0x14>; ++ status = "okay"; ++ clocks = <&clk_mco1>; ++ clock-names = "xclk"; ++ VDDE-supply = <&scmi_v1v8_periph>; ++ VDDIN-supply = <&scmi_v1v8_periph>; ++ reset-gpios = <&mcp23017 2 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ ++ mipid02_0: endpoint { ++ data-lanes = <1 2>; ++ lane-polarities = <0 0 0>; ++ remote-endpoint = <&gc2145_ep>; ++ }; ++ }; ++ port@2 { ++ reg = <2>; ++ ++ mipid02_2: endpoint { ++ bus-width = <8>; ++ hsync-active = <0>; ++ vsync-active = <0>; ++ pclk-sample = <0>; ++ remote-endpoint = <&dcmipp_0>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&iwdg2 { ++ timeout-sec = <32>; ++ status = "okay"; ++}; ++ ++<dc { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <<dc_pins_a>; ++ pinctrl-1 = <<dc_sleep_pins_a>; ++ status = "okay"; ++ ++ port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ltdc_out_rgb: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&panel_in_rgb>; ++ }; ++ }; ++}; ++ ++&rtc { ++ st,lsco = ; ++ pinctrl-0 = <&rtc_out2_rmp_pins_a>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&scmi_regu { ++ scmi_vddcpu: voltd-vddcpu { ++ voltd-name = "vddcpu"; ++ regulator-name = "vddcpu"; ++ }; ++ scmi_vdd: voltd-vdd { ++ voltd-name = "vdd"; ++ regulator-name = "vdd"; ++ }; ++ scmi_vddcore: voltd-vddcore { ++ voltd-name = "vddcore"; ++ regulator-name = "vddcore"; ++ }; ++ scmi_vdd_adc: voltd-vdd_adc { ++ voltd-name = "vdd_adc"; ++ regulator-name = "vdd_adc"; ++ }; ++ scmi_vdd_usb: voltd-vdd_usb { ++ voltd-name = "vdd_usb"; ++ regulator-name = "vdd_usb"; ++ }; ++ scmi_vdd_sd: voltd-vdd_sd { ++ voltd-name = "vdd_sd"; ++ regulator-name = "vdd_sd"; ++ }; ++ scmi_v1v8_periph: voltd-v1v8_periph { ++ voltd-name = "v1v8_periph"; ++ regulator-name = "v1v8_periph"; ++ }; ++ scmi_v3v3_sw: voltd-v3v3_sw { ++ voltd-name = "v3v3_sw"; ++ regulator-name = "v3v3_sw"; ++ }; ++}; ++ ++&sdmmc1 { ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_clk_pins_a>; ++ pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_clk_pins_a>; ++ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; ++ cd-gpios = <&gpioh 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ disable-wp; ++ st,neg-edge; ++ bus-width = <4>; ++ vmmc-supply = <&scmi_vdd_sd>; ++ status = "okay"; ++}; ++ ++/* Wifi */ ++&sdmmc2 { ++ arm,primecell-periphid = <0x10153180>; ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_clk_pins_a>; ++ pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_clk_pins_a>; ++ pinctrl-2 = <&sdmmc2_b4_sleep_pins_a>; ++ non-removable; ++ st,neg-edge; ++ bus-width = <4>; ++ vmmc-supply = <&v3v3_ao>; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ brcmf: bcrmf@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ }; ++}; ++ ++&spi5 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&spi5_pins_a>; ++ pinctrl-1 = <&spi5_sleep_pins_a>; ++ status = "disabled"; ++}; ++ ++&sram { ++ dma_pool: dma-sram@0 { ++ reg = <0x0 0x4000>; ++ pool; ++ }; ++}; ++ ++&timers3 { ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm3_pins_a>; ++ pinctrl-1 = <&pwm3_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@2 { ++ status = "okay"; ++ }; ++}; ++ ++&timers4 { ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm4_pins_a>; ++ pinctrl-1 = <&pwm4_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@3 { ++ status = "okay"; ++ }; ++}; ++ ++&timers8 { ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm8_pins_a>; ++ pinctrl-1 = <&pwm8_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@7 { ++ status = "okay"; ++ }; ++}; ++ ++&timers14 { ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm14_pins_a>; ++ pinctrl-1 = <&pwm14_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@13 { ++ status = "okay"; ++ }; ++}; ++ ++&uart4 { ++ pinctrl-names = "default", "sleep", "idle"; ++ pinctrl-0 = <&uart4_pins_a>; ++ pinctrl-1 = <&uart4_sleep_pins_a>; ++ pinctrl-2 = <&uart4_idle_pins_a>; ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "okay"; ++}; ++ ++&uart8 { ++ pinctrl-names = "default", "sleep", "idle"; ++ pinctrl-0 = <&uart8_pins_a>; ++ pinctrl-1 = <&uart8_sleep_pins_a>; ++ pinctrl-2 = <&uart8_idle_pins_a>; ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++}; ++ ++&usart1 { ++ pinctrl-names = "default", "sleep", "idle"; ++ pinctrl-0 = <&usart1_pins_a>; ++ pinctrl-1 = <&usart1_sleep_pins_a>; ++ pinctrl-2 = <&usart1_idle_pins_a>; ++ uart-has-rtscts; ++ status = "disabled"; ++}; ++ ++/* Bluetooth */ ++&usart2 { ++ pinctrl-names = "default", "sleep", "idle"; ++ pinctrl-0 = <&usart2_pins_a>; ++ pinctrl-1 = <&usart2_sleep_pins_a>; ++ pinctrl-2 = <&usart2_idle_pins_a>; ++ uart-has-rtscts; ++ status = "okay"; ++ ++ bluetooth { ++ shutdown-gpios = <&mcp23017 13 GPIO_ACTIVE_HIGH>; ++ compatible = "brcm,bcm43438-bt"; ++ max-speed = <3000000>; ++ vbat-supply = <&v3v3_ao>; ++ vddio-supply = <&v3v3_ao>; ++ }; ++}; ++ ++&usbh_ehci { ++ phys = <&usbphyc_port0>; ++ status = "okay"; ++}; ++ ++&usbotg_hs { ++ phys = <&usbphyc_port1 0>; ++ phy-names = "usb2-phy"; ++ usb-role-switch; ++ status = "okay"; ++ port { ++ usbotg_hs_ep: endpoint { ++ remote-endpoint = <&con_usb_c_g0_ep>; ++ }; ++ }; ++}; ++ ++&usbphyc { ++ status = "okay"; ++}; ++ ++&usbphyc_port0 { ++ phy-supply = <&scmi_vdd_usb>; ++ st,current-boost-microamp = <1000>; ++ st,decrease-hs-slew-rate; ++ st,tune-hs-dc-level = <2>; ++ st,enable-hs-rftime-reduction; ++ st,trim-hs-current = <11>; ++ st,trim-hs-impedance = <2>; ++ st,tune-squelch-level = <1>; ++ st,enable-hs-rx-gain-eq; ++ st,no-hs-ftime-ctrl; ++ st,no-lsfs-sc; ++ ++ /* ++ * Hack to keep hub active if wakeup source is enabled ++ * otherwise the hub will wakeup the port0 as soon as the v3v3_sw is disabled ++ */ ++ connector { ++ compatible = "usb-a-connector"; ++ vbus-supply = <&scmi_v3v3_sw>; ++ }; ++}; ++ ++&usbphyc_port1 { ++ phy-supply = <&scmi_vdd_usb>; ++ st,current-boost-microamp = <1000>; ++ st,decrease-hs-slew-rate; ++ st,tune-hs-dc-level = <2>; ++ st,enable-hs-rftime-reduction; ++ st,trim-hs-current = <11>; ++ st,trim-hs-impedance = <2>; ++ st,tune-squelch-level = <1>; ++ st,enable-hs-rx-gain-eq; ++ st,no-hs-ftime-ctrl; ++ st,no-lsfs-sc; ++}; +diff --git a/arch/arm/dts/stm32mp13xa.dtsi b/arch/arm/dts/stm32mp13xa.dtsi +new file mode 100644 +index 0000000000..20e52cd271 +--- /dev/null ++++ b/arch/arm/dts/stm32mp13xa.dtsi +@@ -0,0 +1,5 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ +diff --git a/arch/arm/dts/stm32mp13xc.dtsi b/arch/arm/dts/stm32mp13xc.dtsi +new file mode 100644 +index 0000000000..4d00e75928 +--- /dev/null ++++ b/arch/arm/dts/stm32mp13xc.dtsi +@@ -0,0 +1,18 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2021 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++/ { ++ soc { ++ cryp: crypto@54002000 { ++ compatible = "st,stm32mp1-cryp"; ++ reg = <0x54002000 0x400>; ++ interrupts = ; ++ clocks = <&rcc CRYP1>; ++ resets = <&rcc CRYP1_R>; ++ status = "disabled"; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp13xd.dtsi b/arch/arm/dts/stm32mp13xd.dtsi +new file mode 100644 +index 0000000000..aa8e235686 +--- /dev/null ++++ b/arch/arm/dts/stm32mp13xd.dtsi +@@ -0,0 +1,5 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2021 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ +diff --git a/arch/arm/dts/stm32mp13xf.dtsi b/arch/arm/dts/stm32mp13xf.dtsi +new file mode 100644 +index 0000000000..4d00e75928 +--- /dev/null ++++ b/arch/arm/dts/stm32mp13xf.dtsi +@@ -0,0 +1,18 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2021 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++/ { ++ soc { ++ cryp: crypto@54002000 { ++ compatible = "st,stm32mp1-cryp"; ++ reg = <0x54002000 0x400>; ++ interrupts = ; ++ clocks = <&rcc CRYP1>; ++ resets = <&rcc CRYP1_R>; ++ status = "disabled"; ++ }; ++ }; ++}; diff --git a/arch/arm/dts/stm32mp15-ddr.dtsi b/arch/arm/dts/stm32mp15-ddr.dtsi -index 2a139c54e9..25898fa8ad 100644 +index 2a139c54e9..e760da8dca 100644 --- a/arch/arm/dts/stm32mp15-ddr.dtsi +++ b/arch/arm/dts/stm32mp15-ddr.dtsi -@@ -14,6 +14,7 @@ - st,mem-speed = ; - st,mem-size = ; +@@ -4,10 +4,24 @@ + */ + #include -+#ifndef CONFIG_TFABOOT - st,ctl-reg = < - DDR_MSTR - DDR_MRCTRL0 -@@ -133,7 +134,7 @@ ++#ifdef CONFIG_SPL + &ddr { ++ clocks = <&rcc AXIDCG>, ++ <&rcc DDRC1>, ++ <&rcc DDRC2>, ++ <&rcc DDRPHYC>, ++ <&rcc DDRCAPB>, ++ <&rcc DDRPHYCAPB>; ++ ++ clock-names = "axidcg", ++ "ddrc1", ++ "ddrc2", ++ "ddrphyc", ++ "ddrcapb", ++ "ddrphycapb"; ++ + config-DDR_MEM_COMPATIBLE { + u-boot,dm-pre-reloc; +- + compatible = __stringify(st,DDR_MEM_COMPATIBLE); + + st,mem-name = DDR_MEM_NAME; +@@ -116,27 +130,10 @@ + DDR_MR3 >; - #endif +-#ifdef DDR_PHY_CAL_SKIP +- st,phy-cal = < +- DDR_DX0DLLCR +- DDR_DX0DQTR +- DDR_DX0DQSTR +- DDR_DX1DLLCR +- DDR_DX1DQTR +- DDR_DX1DQSTR +- DDR_DX2DLLCR +- DDR_DX2DQTR +- DDR_DX2DQSTR +- DDR_DX3DLLCR +- DDR_DX3DQTR +- DDR_DX3DQSTR +- >; +- +-#endif - -+#endif status = "okay"; }; }; ++#endif + + #undef DDR_MEM_COMPATIBLE + #undef DDR_MEM_NAME +@@ -224,18 +221,6 @@ + #undef DDR_ODTCR + #undef DDR_ZQ0CR1 + #undef DDR_DX0GCR +-#undef DDR_DX0DLLCR +-#undef DDR_DX0DQTR +-#undef DDR_DX0DQSTR + #undef DDR_DX1GCR +-#undef DDR_DX1DLLCR +-#undef DDR_DX1DQTR +-#undef DDR_DX1DQSTR + #undef DDR_DX2GCR +-#undef DDR_DX2DLLCR +-#undef DDR_DX2DQTR +-#undef DDR_DX2DQSTR + #undef DDR_DX3GCR +-#undef DDR_DX3DLLCR +-#undef DDR_DX3DQTR +-#undef DDR_DX3DQSTR diff --git a/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi -index b4787c4735..978331b279 100644 +index 978331b279..e60d0ae606 100644 --- a/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi +++ b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi -@@ -15,7 +15,7 @@ - * Save Date: 2020.02.20, save Time: 18:45:20 - */ - #define DDR_MEM_COMPATIBLE ddr3-1066-888-bin-g-1x4gb-533mhz --#define DDR_MEM_NAME "DDR3-DDR3L 16bits 533000Khz" -+#define DDR_MEM_NAME "DDR3-DDR3L 16bits 533000kHz" - #define DDR_MEM_SPEED 533000 - #define DDR_MEM_SIZE 0x20000000 +@@ -100,20 +100,8 @@ + #define DDR_ODTCR 0x00010000 + #define DDR_ZQ0CR1 0x00000038 + #define DDR_DX0GCR 0x0000CE81 +-#define DDR_DX0DLLCR 0x40000000 +-#define DDR_DX0DQTR 0xFFFFFFFF +-#define DDR_DX0DQSTR 0x3DB02000 + #define DDR_DX1GCR 0x0000CE81 +-#define DDR_DX1DLLCR 0x40000000 +-#define DDR_DX1DQTR 0xFFFFFFFF +-#define DDR_DX1DQSTR 0x3DB02000 + #define DDR_DX2GCR 0x0000CE80 +-#define DDR_DX2DLLCR 0x40000000 +-#define DDR_DX2DQTR 0xFFFFFFFF +-#define DDR_DX2DQSTR 0x3DB02000 + #define DDR_DX3GCR 0x0000CE80 +-#define DDR_DX3DLLCR 0x40000000 +-#define DDR_DX3DQTR 0xFFFFFFFF +-#define DDR_DX3DQSTR 0x3DB02000 + #include "stm32mp15-ddr.dtsi" diff --git a/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi -index dc2875ca08..426be21f42 100644 +index 426be21f42..1a6fa80edf 100644 --- a/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi +++ b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi -@@ -15,7 +15,7 @@ - * Save Date: 2020.02.20, save Time: 18:49:33 - */ - #define DDR_MEM_COMPATIBLE ddr3-1066-888-bin-g-2x4gb-533mhz --#define DDR_MEM_NAME "DDR3-DDR3L 32bits 533000Khz" -+#define DDR_MEM_NAME "DDR3-DDR3L 32bits 533000kHz" - #define DDR_MEM_SPEED 533000 - #define DDR_MEM_SIZE 0x40000000 +@@ -100,20 +100,8 @@ + #define DDR_ODTCR 0x00010000 + #define DDR_ZQ0CR1 0x00000038 + #define DDR_DX0GCR 0x0000CE81 +-#define DDR_DX0DLLCR 0x40000000 +-#define DDR_DX0DQTR 0xFFFFFFFF +-#define DDR_DX0DQSTR 0x3DB02000 + #define DDR_DX1GCR 0x0000CE81 +-#define DDR_DX1DLLCR 0x40000000 +-#define DDR_DX1DQTR 0xFFFFFFFF +-#define DDR_DX1DQSTR 0x3DB02000 + #define DDR_DX2GCR 0x0000CE81 +-#define DDR_DX2DLLCR 0x40000000 +-#define DDR_DX2DQTR 0xFFFFFFFF +-#define DDR_DX2DQSTR 0x3DB02000 + #define DDR_DX3GCR 0x0000CE81 +-#define DDR_DX3DLLCR 0x40000000 +-#define DDR_DX3DQTR 0xFFFFFFFF +-#define DDR_DX3DQSTR 0x3DB02000 + #include "stm32mp15-ddr.dtsi" +diff --git a/arch/arm/dts/stm32mp15-ddr3-dhsom-2x1Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-dhsom-2x1Gb-1066-binG.dtsi +index b3eb280f96..0a277cd675 100644 +--- a/arch/arm/dts/stm32mp15-ddr3-dhsom-2x1Gb-1066-binG.dtsi ++++ b/arch/arm/dts/stm32mp15-ddr3-dhsom-2x1Gb-1066-binG.dtsi +@@ -101,20 +101,8 @@ + #define DDR_ODTCR 0x00010000 + #define DDR_ZQ0CR1 0x00000038 + #define DDR_DX0GCR 0x0000CE81 +-#define DDR_DX0DLLCR 0x40000000 +-#define DDR_DX0DQTR 0xFFFFFFFF +-#define DDR_DX0DQSTR 0x3DB02000 + #define DDR_DX1GCR 0x0000CE81 +-#define DDR_DX1DLLCR 0x40000000 +-#define DDR_DX1DQTR 0xFFFFFFFF +-#define DDR_DX1DQSTR 0x3DB02000 + #define DDR_DX2GCR 0x0000CE81 +-#define DDR_DX2DLLCR 0x40000000 +-#define DDR_DX2DQTR 0xFFFFFFFF +-#define DDR_DX2DQSTR 0x3DB02000 + #define DDR_DX3GCR 0x0000CE81 +-#define DDR_DX3DLLCR 0x40000000 +-#define DDR_DX3DQTR 0xFFFFFFFF +-#define DDR_DX3DQSTR 0x3DB02000 + + #include "stm32mp15-ddr.dtsi" +diff --git a/arch/arm/dts/stm32mp15-ddr3-dhsom-2x2Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-dhsom-2x2Gb-1066-binG.dtsi +index ed3a5248f8..92774fffb9 100644 +--- a/arch/arm/dts/stm32mp15-ddr3-dhsom-2x2Gb-1066-binG.dtsi ++++ b/arch/arm/dts/stm32mp15-ddr3-dhsom-2x2Gb-1066-binG.dtsi +@@ -101,20 +101,8 @@ + #define DDR_ODTCR 0x00010000 + #define DDR_ZQ0CR1 0x00000038 + #define DDR_DX0GCR 0x0000CE81 +-#define DDR_DX0DLLCR 0x40000000 +-#define DDR_DX0DQTR 0xFFFFFFFF +-#define DDR_DX0DQSTR 0x3DB02000 + #define DDR_DX1GCR 0x0000CE81 +-#define DDR_DX1DLLCR 0x40000000 +-#define DDR_DX1DQTR 0xFFFFFFFF +-#define DDR_DX1DQSTR 0x3DB02000 + #define DDR_DX2GCR 0x0000CE81 +-#define DDR_DX2DLLCR 0x40000000 +-#define DDR_DX2DQTR 0xFFFFFFFF +-#define DDR_DX2DQSTR 0x3DB02000 + #define DDR_DX3GCR 0x0000CE81 +-#define DDR_DX3DLLCR 0x40000000 +-#define DDR_DX3DQTR 0xFFFFFFFF +-#define DDR_DX3DQSTR 0x3DB02000 + + #include "stm32mp15-ddr.dtsi" +diff --git a/arch/arm/dts/stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi +index d5813d64b0..e53ab18a69 100644 +--- a/arch/arm/dts/stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi ++++ b/arch/arm/dts/stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi +@@ -101,20 +101,8 @@ + #define DDR_ODTCR 0x00010000 + #define DDR_ZQ0CR1 0x00000038 + #define DDR_DX0GCR 0x0000CE81 +-#define DDR_DX0DLLCR 0x40000000 +-#define DDR_DX0DQTR 0xFFFFFFFF +-#define DDR_DX0DQSTR 0x3DB02000 + #define DDR_DX1GCR 0x0000CE81 +-#define DDR_DX1DLLCR 0x40000000 +-#define DDR_DX1DQTR 0xFFFFFFFF +-#define DDR_DX1DQSTR 0x3DB02000 + #define DDR_DX2GCR 0x0000CE81 +-#define DDR_DX2DLLCR 0x40000000 +-#define DDR_DX2DQTR 0xFFFFFFFF +-#define DDR_DX2DQSTR 0x3DB02000 + #define DDR_DX3GCR 0x0000CE81 +-#define DDR_DX3DLLCR 0x40000000 +-#define DDR_DX3DQTR 0xFFFFFFFF +-#define DDR_DX3DQSTR 0x3DB02000 + + #include "stm32mp15-ddr.dtsi" +diff --git a/arch/arm/dts/stm32mp15-ddr3-icore-1x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-icore-1x4Gb-1066-binG.dtsi +index 24c81269b0..ff582ac6af 100644 +--- a/arch/arm/dts/stm32mp15-ddr3-icore-1x4Gb-1066-binG.dtsi ++++ b/arch/arm/dts/stm32mp15-ddr3-icore-1x4Gb-1066-binG.dtsi +@@ -100,20 +100,8 @@ + #define DDR_ODTCR 0x00010000 + #define DDR_ZQ0CR1 0x00000038 + #define DDR_DX0GCR 0x0000CE81 +-#define DDR_DX0DLLCR 0x40000000 +-#define DDR_DX0DQTR 0xFFFFFFFF +-#define DDR_DX0DQSTR 0x3DB02000 + #define DDR_DX1GCR 0x0000CE81 +-#define DDR_DX1DLLCR 0x40000000 +-#define DDR_DX1DQTR 0xFFFFFFFF +-#define DDR_DX1DQSTR 0x3DB02000 + #define DDR_DX2GCR 0x0000CE81 +-#define DDR_DX2DLLCR 0x40000000 +-#define DDR_DX2DQTR 0xFFFFFFFF +-#define DDR_DX2DQSTR 0x3DB02000 + #define DDR_DX3GCR 0x0000CE81 +-#define DDR_DX3DLLCR 0x40000000 +-#define DDR_DX3DQTR 0xFFFFFFFF +-#define DDR_DX3DQSTR 0x3DB02000 + + #include "stm32mp15-ddr.dtsi" diff --git a/arch/arm/dts/stm32mp15-m4-srm-pinctrl.dtsi b/arch/arm/dts/stm32mp15-m4-srm-pinctrl.dtsi new file mode 100644 index 0000000000..b4030e5c94 @@ -682,10 +5247,10 @@ index 0000000000..b4030e5c94 +}; diff --git a/arch/arm/dts/stm32mp15-m4-srm.dtsi b/arch/arm/dts/stm32mp15-m4-srm.dtsi new file mode 100644 -index 0000000000..60454aee41 +index 0000000000..7fa3ca411a --- /dev/null +++ b/arch/arm/dts/stm32mp15-m4-srm.dtsi -@@ -0,0 +1,442 @@ +@@ -0,0 +1,447 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -865,7 +5430,7 @@ index 0000000000..60454aee41 + 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"; + }; @@ -989,14 +5554,14 @@ index 0000000000..60454aee41 + m4_m_can1: can@4400e000 { + compatible = "rproc-srm-dev"; + reg = <0x4400e000 0x400>, <0x44011000 0x2800>; -+ clocks = <&scmi0_clk CK_SCMI0_HSE>, <&rcc FDCAN_K>; ++ clocks = <&scmi_clk CK_SCMI_HSE>, <&rcc FDCAN_K>; + clock-names = "hclk", "cclk"; + status = "disabled"; + }; + m4_m_can2: can@4400f000 { + compatible = "rproc-srm-dev"; + reg = <0x4400f000 0x400>, <0x44011000 0x2800>; -+ clocks = <&scmi0_clk CK_SCMI0_HSE>, <&rcc FDCAN_K>; ++ clocks = <&scmi_clk CK_SCMI_HSE>, <&rcc FDCAN_K>; + clock-names = "hclk", "cclk"; + status = "disabled"; + }; @@ -1103,6 +5668,12 @@ index 0000000000..60454aee41 + 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"; @@ -1127,13 +5698,12 @@ index 0000000000..60454aee41 + }; + }; +}; -+ diff --git a/arch/arm/dts/stm32mp15-no-scmi.dtsi b/arch/arm/dts/stm32mp15-no-scmi.dtsi new file mode 100644 -index 0000000000..94a10b86a1 +index 0000000000..43b8a17230 --- /dev/null +++ b/arch/arm/dts/stm32mp15-no-scmi.dtsi -@@ -0,0 +1,157 @@ +@@ -0,0 +1,152 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2020 - All Rights Reserved @@ -1215,10 +5785,6 @@ index 0000000000..94a10b86a1 + 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>; + }; @@ -1231,14 +5797,13 @@ index 0000000000..94a10b86a1 + }; + + firmware { -+ /delete-node/ scmi0; -+ /delete-node/ scmi1; ++ /delete-node/ scmi; + }; + /delete-node/ sram@2ffff000; +}; + -+&cec { -+ clocks = <&rcc CEC_K>, <&clk_lse>; ++&bsec { ++ clocks = <&rcc BSEC>; +}; + +&gpioz { @@ -1292,10 +5857,10 @@ index 0000000000..94a10b86a1 + clocks = <&rcc USART1_K>; +}; diff --git a/arch/arm/dts/stm32mp15-pinctrl.dtsi b/arch/arm/dts/stm32mp15-pinctrl.dtsi -index e9525b5d06..a0b76e238c 100644 +index 5b60ecbd71..d2f2cc8f36 100644 --- a/arch/arm/dts/stm32mp15-pinctrl.dtsi +++ b/arch/arm/dts/stm32mp15-pinctrl.dtsi -@@ -118,6 +118,45 @@ +@@ -151,6 +151,45 @@ }; }; @@ -1341,7 +5906,7 @@ index e9525b5d06..a0b76e238c 100644 ethernet0_rgmii_pins_a: rgmii-0 { pins1 { pinmux = , /* ETH_RGMII_CLK125 */ -@@ -349,6 +388,51 @@ +@@ -437,6 +476,51 @@ }; }; @@ -1393,7 +5958,7 @@ index e9525b5d06..a0b76e238c 100644 i2c1_pins_a: i2c1-0 { pins { pinmux = , /* I2C1_SCL */ -@@ -1051,6 +1135,12 @@ +@@ -1139,6 +1223,12 @@ }; }; @@ -1406,58 +5971,45 @@ index e9525b5d06..a0b76e238c 100644 sai2a_pins_a: sai2a-0 { pins { pinmux = , /* SAI2_SCK_A */ -@@ -1147,7 +1237,7 @@ +@@ -1179,7 +1269,7 @@ + }; + }; + +- sai2a_pins_c: sai2a-4 { ++ sai2a_pins_c: sai2a-2 { + pins { + pinmux = , /* SAI2_SCK_A */ + , /* SAI2_SD_A */ +@@ -1190,7 +1280,7 @@ + }; + }; + +- sai2a_sleep_pins_c: sai2a-5 { ++ sai2a_sleep_pins_c: sai2a-2 { + pins { + pinmux = , /* SAI2_SCK_A */ + , /* SAI2_SD_A */ +@@ -1235,14 +1325,14 @@ }; }; - sai2b_pins_c: sai2a-4 { -+ sai2b_pins_c: sai2b-4 { ++ sai2b_pins_c: sai2b-2 { pins1 { pinmux = ; /* SAI2_SD_B */ bias-disable; -@@ -1437,6 +1527,24 @@ }; }; -+ sdmmc2_d47_pins_d: sdmmc2-d47-3 { -+ pins { -+ pinmux = , /* SDMMC2_D4 */ -+ , /* SDMMC2_D5 */ -+ , /* SDMMC2_D6 */ -+ ; /* SDMMC2_D7 */ -+ }; -+ }; -+ -+ sdmmc2_d47_sleep_pins_d: sdmmc2-d47-sleep-3 { -+ pins { -+ pinmux = , /* SDMMC2_D4 */ -+ , /* SDMMC2_D5 */ -+ , /* SDMMC2_D6 */ -+ ; /* SDMMC2_D7 */ -+ }; -+ }; -+ - sdmmc3_b4_pins_a: sdmmc3-b4-0 { - pins1 { - pinmux = , /* SDMMC3_D0 */ -@@ -1573,10 +1681,205 @@ +- sai2b_sleep_pins_c: sai2a-sleep-5 { ++ sai2b_sleep_pins_c: sai2b-sleep-2 { + pins { + pinmux = ; /* SAI2_SD_B */ + }; +@@ -1716,9 +1806,55 @@ }; }; -+ spi4_pins_a: spi4-0 { -+ pins { -+ pinmux = , /* SPI4_SCK */ -+ ; /* SPI4_MOSI */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ pins2 { -+ pinmux = ; /* SPI4_MISO */ -+ bias-disable; -+ }; -+ }; -+ + spi4_pins_b: spi4-1 { + pins1 { + pinmux = , /* SPI4_SCK */ @@ -1505,29 +6057,23 @@ index e9525b5d06..a0b76e238c 100644 + }; + stusb1600_pins_a: stusb1600-0 { -- pins { -- pinmux = ; -- bias-pull-up; -+ pins { -+ pinmux = ; -+ bias-pull-up; -+ }; -+ }; -+ -+ uart4_pins_a: uart4-0 { -+ pins1 { -+ pinmux = ; /* UART4_TX */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ pins2 { -+ pinmux = ; /* UART4_RX */ -+ bias-disable; -+ }; -+ }; -+ -+ uart4_idle_pins_a: uart4-idle-0 { + pins { +- pinmux = ; ++ pinmux = ; + bias-pull-up; + }; + }; +@@ -1737,20 +1873,20 @@ + }; + + uart4_idle_pins_a: uart4-idle-0 { +- pins1 { +- pinmux = ; /* UART4_TX */ +- }; +- pins2 { +- pinmux = ; /* UART4_RX */ +- bias-disable; +- }; + pins1 { + pinmux = ; /* UART4_TX */ + }; @@ -1535,326 +6081,107 @@ index e9525b5d06..a0b76e238c 100644 + pinmux = ; /* UART4_RX */ + bias-disable; + }; -+ }; -+ -+ uart4_sleep_pins_a: uart4-sleep-0 { -+ pins { -+ pinmux = , /* UART4_TX */ -+ ; /* UART4_RX */ -+ }; -+ }; -+ -+ uart4_pins_b: uart4-1 { -+ pins1 { -+ pinmux = ; /* UART4_TX */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ pins2 { -+ pinmux = ; /* UART4_RX */ -+ bias-disable; -+ }; -+ }; -+ -+ uart4_pins_c: uart4-2 { -+ pins1 { -+ pinmux = ; /* UART4_TX */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ pins2 { -+ pinmux = ; /* UART4_RX */ -+ bias-disable; -+ }; -+ }; -+ -+ uart7_pins_a: uart7-0 { -+ pins1 { -+ pinmux = ; /* UART7_TX */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ pins2 { -+ pinmux = , /* UART7_RX */ -+ , /* UART7_CTS */ -+ ; /* UART7_RTS */ -+ bias-disable; -+ }; -+ }; -+ -+ uart7_pins_b: uart7-1 { -+ pins1 { -+ pinmux = ; /* UART7_TX */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ pins2 { -+ pinmux = ; /* UART7_RX */ -+ bias-disable; -+ }; -+ }; -+ -+ uart7_pins_c: uart7-2 { -+ pins1 { -+ pinmux = ; /* UART7_TX */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ pins2 { -+ pinmux = ; /* UART7_RX */ -+ bias-pull-up; -+ }; -+ }; -+ -+ uart7_idle_pins_c: uart7-idle-2 { -+ pins1 { -+ pinmux = ; /* UART7_TX */ -+ }; -+ pins2 { -+ pinmux = ; /* UART7_RX */ -+ bias-pull-up; -+ }; -+ }; -+ -+ uart7_sleep_pins_c: uart7-sleep-2 { -+ pins { -+ pinmux = , /* UART7_TX */ -+ ; /* UART7_RX */ -+ }; -+ }; -+ -+ uart8_pins_a: uart8-0 { -+ pins1 { -+ pinmux = ; /* UART8_TX */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ pins2 { -+ pinmux = ; /* UART8_RX */ -+ bias-disable; -+ }; -+ }; -+ -+ uart8_rtscts_pins_a: uart8rtscts-0 { -+ pins { -+ pinmux = , /* UART8_RTS */ -+ ; /* UART8_CTS */ -+ bias-disable; - }; }; -@@ -1628,96 +1931,139 @@ - }; + uart4_sleep_pins_a: uart4-sleep-0 { +- pins { ++ pins { + pinmux = , /* UART4_TX */ + ; /* UART4_RX */ +- }; ++ }; }; -- usart3_pins_a: usart3-0 { -+ usart2_pins_c: usart2-2 { - pins1 { -- pinmux = ; /* USART3_TX */ -+ pinmux = , /* USART2_TX */ -+ ; /* USART2_RTS */ - bias-disable; - drive-push-pull; -- slew-rate = <0>; -+ slew-rate = <3>; + uart4_pins_b: uart4-1 { +@@ -1816,7 +1952,7 @@ }; pins2 { -- pinmux = ; /* USART3_RX */ -+ pinmux = , /* USART2_RX */ -+ ; /* USART2_CTS_NSS */ - bias-disable; - }; - }; - -- uart4_pins_a: uart4-0 { -+ usart2_idle_pins_c: usart2-idle-2 { - pins1 { -- pinmux = ; /* UART4_TX */ -+ pinmux = , /* USART2_TX */ -+ ; /* USART2_CTS_NSS */ -+ }; -+ pins2 { -+ pinmux = ; /* USART2_RTS */ - bias-disable; - drive-push-pull; -- slew-rate = <0>; -+ slew-rate = <3>; - }; -- pins2 { -- pinmux = ; /* UART4_RX */ -+ pins3 { -+ pinmux = ; /* USART2_RX */ - bias-disable; - }; - }; - -- uart4_pins_b: uart4-1 { -+ usart2_sleep_pins_c: usart2-sleep-2 { -+ pins { -+ pinmux = , /* USART2_TX */ -+ , /* USART2_RTS */ -+ , /* USART2_RX */ -+ ; /* USART2_CTS_NSS */ -+ }; -+ }; -+ -+ usart3_pins_a: usart3-0 { - pins1 { -- pinmux = ; /* UART4_TX */ -+ pinmux = ; /* USART3_TX */ - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { -- pinmux = ; /* UART4_RX */ -+ pinmux = ; /* USART3_RX */ - bias-disable; - }; - }; - -- uart4_pins_c: uart4-2 { -+ usart3_pins_b: usart3-1 { - pins1 { -- pinmux = ; /* UART4_TX */ -+ pinmux = , /* USART3_TX */ -+ ; /* USART3_RTS */ - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { -- pinmux = ; /* UART4_RX */ -+ pinmux = , /* USART3_RX */ -+ ; /* USART3_CTS_NSS */ - bias-disable; - }; - }; - -- uart7_pins_a: uart7-0 { -+ usart3_idle_pins_b: usart3-idle-1 { - pins1 { -- pinmux = ; /* UART4_TX */ -+ pinmux = , /* USART3_TX */ -+ ; /* USART3_CTS_NSS */ -+ }; -+ pins2 { -+ pinmux = ; /* USART3_RTS */ - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; -- pins2 { -- pinmux = , /* UART4_RX */ -- , /* UART4_CTS */ -- ; /* UART4_RTS */ -+ pins3 { -+ pinmux = ; /* USART3_RX */ - bias-disable; - }; - }; - -- uart7_pins_b: uart7-1 { -+ usart3_sleep_pins_b: usart3-sleep-1 { -+ pins { -+ pinmux = , /* USART3_TX */ -+ , /* USART3_RTS */ -+ , /* USART3_CTS_NSS */ -+ ; /* USART3_RX */ -+ }; -+ }; -+ -+ usart3_pins_c: usart3-2 { - pins1 { -- pinmux = ; /* UART7_TX */ -+ pinmux = , /* USART3_TX */ -+ ; /* USART3_RTS */ - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { -- pinmux = ; /* UART7_RX */ + pinmux = ; /* UART7_RX */ - bias-disable; -+ pinmux = , /* USART3_RX */ -+ ; /* USART3_CTS_NSS */ + bias-pull-up; }; }; -- uart8_pins_a: uart8-0 { -+ usart3_idle_pins_c: usart3-idle-2 { - pins1 { -- pinmux = ; /* UART8_TX */ -+ pinmux = , /* USART3_TX */ -+ ; /* USART3_CTS_NSS */ -+ }; -+ pins2 { -+ pinmux = ; /* USART3_RTS */ +@@ -1826,7 +1962,7 @@ + }; + pins2 { + pinmux = ; /* UART7_RX */ +- bias-disable; ++ bias-pull-up; + }; + }; + +@@ -1912,7 +2048,7 @@ + ; /* USART2_RTS */ bias-disable; drive-push-pull; - slew-rate = <0>; +- slew-rate = <3>; ++ slew-rate = <0>; }; -- pins2 { -- pinmux = ; /* UART8_RX */ + pins2 { + pinmux = , /* USART2_RX */ +@@ -1930,7 +2066,7 @@ + pinmux = ; /* USART2_RTS */ + bias-disable; + drive-push-pull; +- slew-rate = <3>; ++ slew-rate = <0>; + }; + pins3 { + pinmux = ; /* USART2_RX */ +@@ -2012,7 +2148,7 @@ + pins2 { + pinmux = , /* USART3_RX */ + ; /* USART3_CTS_NSS */ - bias-disable; -+ pins3 { -+ pinmux = ; /* USART3_RX */ + bias-pull-up; -+ }; -+ }; + }; + }; + +@@ -2029,7 +2165,7 @@ + }; + pins3 { + pinmux = ; /* USART3_RX */ +- bias-disable; ++ bias-pull-up; + }; + }; + +@@ -2120,4 +2256,12 @@ + bias-disable; + }; + }; + -+ usart3_sleep_pins_c: usart3-sleep-2 { -+ pins { -+ pinmux = , /* USART3_TX */ -+ , /* USART3_RTS */ -+ , /* USART3_CTS_NSS */ -+ ; /* USART3_RX */ - }; - }; - -@@ -1783,17 +2129,11 @@ - }; - }; - -- spi4_pins_a: spi4-0 { + spi1_sleep_pins_a: spi1-sleep-0 { - pins { -- pinmux = , /* SPI4_SCK */ -- ; /* SPI4_MOSI */ -- bias-disable; -- drive-push-pull; -- slew-rate = <1>; -- }; -- pins2 { -- pinmux = ; /* SPI4_MISO */ -- bias-disable; ++ pins { + pinmux = , /* SPI1_SCK */ + , /* SPI1_MISO */ + ; /* SPI1_MOSI */ - }; - }; ++ }; ++ }; }; diff --git a/arch/arm/dts/stm32mp15-u-boot.dtsi b/arch/arm/dts/stm32mp15-u-boot.dtsi -index 7ec90fe4a3..038ae25530 100644 +index 43a7909978..b684ff550d 100644 --- a/arch/arm/dts/stm32mp15-u-boot.dtsi +++ b/arch/arm/dts/stm32mp15-u-boot.dtsi -@@ -21,23 +21,11 @@ +@@ -21,8 +21,14 @@ pinctrl1 = &pinctrl_z; }; - clocks { - u-boot,dm-pre-reloc; -- }; -- ++ binman: binman { ++ multiple-images; ++ }; ++ ++ firmware { ++ optee { ++ u-boot,dm-pre-reloc; ++ }; + }; + /* need PSCI for sysreset during board_f */ - psci { +@@ -30,14 +36,6 @@ u-boot,dm-pre-proper; }; @@ -1869,7 +6196,28 @@ index 7ec90fe4a3..038ae25530 100644 soc { u-boot,dm-pre-reloc; -@@ -72,36 +60,6 @@ +@@ -49,20 +47,6 @@ + reg = <0x5A003000 0x550 + 0x5A004000 0x234>; + +- clocks = <&rcc AXIDCG>, +- <&rcc DDRC1>, +- <&rcc DDRC2>, +- <&rcc DDRPHYC>, +- <&rcc DDRCAPB>, +- <&rcc DDRPHYCAPB>; +- +- clock-names = "axidcg", +- "ddrc1", +- "ddrc2", +- "ddrphyc", +- "ddrcapb", +- "ddrphycapb"; +- + status = "okay"; + }; + }; +@@ -72,36 +56,6 @@ u-boot,dm-pre-reloc; }; @@ -1906,7 +6254,21 @@ index 7ec90fe4a3..038ae25530 100644 &gpioa { u-boot,dm-pre-reloc; }; -@@ -167,16 +125,44 @@ +@@ -159,13 +113,6 @@ + u-boot,dm-pre-proper; + }; + +-/* temp = waiting kernel update */ +-&m4_rproc { +- resets = <&rcc MCU_R>, +- <&rcc MCU_HOLD_BOOT_R>; +- reset-names = "mcu_rst", "hold_boot"; +-}; +- + &pinctrl { + u-boot,dm-pre-reloc; + }; +@@ -174,30 +121,34 @@ u-boot,dm-pre-reloc; }; @@ -1917,59 +6279,71 @@ index 7ec90fe4a3..038ae25530 100644 -&rcc { +#ifdef CONFIG_TFABOOT -+&scmi0 { ++&scmi { u-boot,dm-pre-reloc; - #address-cells = <1>; - #size-cells = <0>; }; -+&scmi0_clk { +-&sdmmc1 { +- compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; ++&scmi_clk { + u-boot,dm-pre-reloc; -+}; -+ -+&scmi0_reset { + }; + +-&sdmmc2 { +- compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; ++&scmi_reset { + u-boot,dm-pre-reloc; -+}; -+ -+&scmi0_shm { + }; + +-&sdmmc3 { +- compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; ++&scmi_shm { + u-boot,dm-pre-reloc; -+}; -+ -+&scmi1 { -+ u-boot,dm-pre-reloc; -+}; -+ -+&scmi1_clk { -+ u-boot,dm-pre-reloc; -+}; -+ -+&scmi1_shm { -+ u-boot,dm-pre-reloc; -+}; -+ + }; + +&scmi_sram { + u-boot,dm-pre-reloc; +}; +#endif + - &sdmmc1 { - compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; - }; -@@ -190,7 +176,7 @@ - }; - &usart1 { - resets = <&rcc USART1_R>; -+ resets = <&scmi0_reset RST_SCMI0_USART1>; ++ resets = <&scmi_reset RST_SCMI_USART1>; }; &usart2 { -@@ -221,6 +207,63 @@ +@@ -228,3 +179,89 @@ resets = <&rcc UART8_R>; }; --&usbotg_hs { -- compatible = "st,stm32mp1-hsotg", "snps,dwc2"; ++#if defined(CONFIG_STM32MP15x_STM32IMAGE) ++&binman { ++ u-boot-stm32 { ++ filename = "u-boot.stm32"; ++ mkimage { ++ args = "-T stm32image -a 0xC0100000 -e 0xC0100000"; ++ u-boot { ++ }; ++ }; ++ }; ++}; ++#endif ++ ++#if defined(CONFIG_SPL) ++&binman { ++ spl-stm32 { ++ filename = "u-boot-spl.stm32"; ++ mkimage { ++ args = "-T stm32image -a 0x2FFC2500 -e 0x2FFC2500"; ++ u-boot-spl { ++ }; ++ }; ++ }; ++}; ++#endif ++ +/* NO MORE USE SCMI SUPPORT for BASIC boot chain */ +#ifndef CONFIG_TFABOOT + @@ -2013,7 +6387,7 @@ index 7ec90fe4a3..038ae25530 100644 + opp-800000000 { + u-boot,dm-spl; + }; - }; ++}; + +/* only for vdd-supply in sysconf_init() */ +&pwr_regulators { @@ -2031,28 +6405,25 @@ index 7ec90fe4a3..038ae25530 100644 + +#endif /* CONFIG_TFABOOT */ diff --git a/arch/arm/dts/stm32mp151.dtsi b/arch/arm/dts/stm32mp151.dtsi -index 39d9e545ed..ca71139f3a 100644 +index 8e0a0bc1dd..2d403bb090 100644 --- a/arch/arm/dts/stm32mp151.dtsi +++ b/arch/arm/dts/stm32mp151.dtsi -@@ -5,7 +5,10 @@ +@@ -5,6 +5,7 @@ */ #include #include +#include #include -+#include -+ / { - #address-cells = <1>; -@@ -17,27 +20,76 @@ +@@ -17,35 +18,65 @@ cpu0: cpu@0 { compatible = "arm,cortex-a7"; - clock-frequency = <650000000>; device_type = "cpu"; reg = <0>; -+ clocks = <&scmi0_clk CK_SCMI0_MPU>; ++ clocks = <&scmi_clk CK_SCMI_MPU>; + clock-names = "cpu"; operating-points-v2 = <&cpu0_opp_table>; nvmem-cells = <&part_number_otp>; @@ -2075,6 +6446,11 @@ index 39d9e545ed..ca71139f3a 100644 - opp-hz = /bits/ 64 <650000000>; - opp-microvolt = <1200000>; - opp-supported-hw = <0x1>; +- }; +- opp-800000000 { +- opp-hz = /bits/ 64 <800000000>; +- opp-microvolt = <1350000>; +- opp-supported-hw = <0x2>; + }; + + scmi_sram: sram@2ffff000 { @@ -2084,59 +6460,58 @@ index 39d9e545ed..ca71139f3a 100644 + #size-cells = <1>; + ranges = <0 0x2ffff000 0x1000>; + -+ scmi0_shm: scmi_shm@0 { ++ scmi_shm: scmi_shm@0 { ++ compatible = "arm,scmi-shmem"; + reg = <0 0x80>; -+ }; -+ -+ scmi1_shm: scmi_shm@200 { -+ reg = <0x200 0x80>; -+ }; -+ }; -+ -+ firmware { -+ scmi0: scmi0 { -+ compatible = "arm,scmi-smc"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ arm,smc-id = <0x82002000>; -+ shmem = <&scmi0_shm>; -+ -+ scmi0_clk: protocol@14 { -+ reg = <0x14>; -+ #clock-cells = <1>; -+ }; -+ -+ scmi0_reset: protocol@16 { -+ reg = <0x16>; -+ #reset-cells = <1>; -+ }; - }; -- opp-800000000 { -- opp-hz = /bits/ 64 <800000000>; -- opp-microvolt = <1350000>; -- opp-supported-hw = <0x2>; -+ -+ scmi1: scmi1 { -+ compatible = "arm,scmi-smc"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ arm,smc-id = <0x82002001>; -+ shmem = <&scmi1_shm>; -+ status = "disabled"; -+ -+ scmi1_clk: protocol@14 { -+ reg = <0x14>; -+ #clock-cells = <1>; -+ }; }; }; -@@ -61,38 +113,7 @@ - , - ; +- arm-pmu { +- compatible = "arm,cortex-a7-pmu"; +- interrupts = ; +- interrupt-affinity = <&cpu0>; +- interrupt-parent = <&intc>; ++ firmware { ++ optee { ++ compatible = "linaro,optee-tz"; ++ method = "smc"; ++ }; ++ ++ scmi: scmi { ++ compatible = "linaro,scmi-optee"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ linaro,optee-channel-id = <0>; ++ shmem = <&scmi_shm>; ++ ++ scmi_clk: protocol@14 { ++ reg = <0x14>; ++ #clock-cells = <1>; ++ }; ++ ++ scmi_reset: protocol@16 { ++ reg = <0x16>; ++ #reset-cells = <1>; ++ }; ++ }; + }; + + psci { +@@ -63,45 +94,13 @@ + + timer { + compatible = "arm,armv7-timer"; +- interrupts = , +- , +- , +- ; ++ interrupts = , ++ , ++ , ++ ; interrupt-parent = <&intc>; -- }; -- + }; + - clocks { - clk_hse: clk-hse { - #clock-cells = <0>; @@ -2167,11 +6542,12 @@ index 39d9e545ed..ca71139f3a 100644 - compatible = "fixed-clock"; - clock-frequency = <4000000>; - }; -+ always-on; - }; - +- }; +- thermal-zones { -@@ -102,12 +123,6 @@ + cpu_thermal: cpu-thermal { + polling-delay-passive = <0>; +@@ -109,12 +108,6 @@ thermal-sensors = <&dts>; trips { @@ -2184,7 +6560,7 @@ index 39d9e545ed..ca71139f3a 100644 cpu-crit { temperature = <120000>; hysteresis = <0>; -@@ -126,6 +141,26 @@ +@@ -133,6 +126,26 @@ status = "disabled"; }; @@ -2211,7 +6587,7 @@ index 39d9e545ed..ca71139f3a 100644 soc { compatible = "simple-bus"; #address-cells = <1>; -@@ -133,6 +168,14 @@ +@@ -140,6 +153,14 @@ interrupt-parent = <&intc>; ranges; @@ -2226,7 +6602,7 @@ index 39d9e545ed..ca71139f3a 100644 timers2: timer@40000000 { #address-cells = <1>; #size-cells = <0>; -@@ -140,11 +183,11 @@ +@@ -147,11 +168,11 @@ reg = <0x40000000 0x400>; clocks = <&rcc TIM2_K>; clock-names = "int"; @@ -2243,7 +6619,7 @@ index 39d9e545ed..ca71139f3a 100644 dma-names = "ch1", "ch2", "ch3", "ch4", "up"; status = "disabled"; -@@ -173,12 +216,12 @@ +@@ -180,12 +201,12 @@ reg = <0x40001000 0x400>; clocks = <&rcc TIM3_K>; clock-names = "int"; @@ -2262,7 +6638,7 @@ index 39d9e545ed..ca71139f3a 100644 dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig"; status = "disabled"; -@@ -207,10 +250,10 @@ +@@ -214,10 +235,10 @@ reg = <0x40002000 0x400>; clocks = <&rcc TIM4_K>; clock-names = "int"; @@ -2277,7 +6653,7 @@ index 39d9e545ed..ca71139f3a 100644 dma-names = "ch1", "ch2", "ch3", "ch4"; status = "disabled"; -@@ -239,12 +282,12 @@ +@@ -246,12 +267,12 @@ reg = <0x40003000 0x400>; clocks = <&rcc TIM5_K>; clock-names = "int"; @@ -2296,7 +6672,7 @@ index 39d9e545ed..ca71139f3a 100644 dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig"; status = "disabled"; -@@ -273,7 +316,7 @@ +@@ -280,7 +301,7 @@ reg = <0x40004000 0x400>; clocks = <&rcc TIM6_K>; clock-names = "int"; @@ -2305,7 +6681,7 @@ index 39d9e545ed..ca71139f3a 100644 dma-names = "up"; status = "disabled"; -@@ -291,7 +334,7 @@ +@@ -298,7 +319,7 @@ reg = <0x40005000 0x400>; clocks = <&rcc TIM7_K>; clock-names = "int"; @@ -2314,19 +6690,15 @@ index 39d9e545ed..ca71139f3a 100644 dma-names = "up"; status = "disabled"; -@@ -373,8 +416,11 @@ - #size-cells = <0>; - compatible = "st,stm32-lptimer"; - reg = <0x40009000 0x400>; -+ interrupts-extended = <&exti 47 IRQ_TYPE_LEVEL_HIGH>; +@@ -383,6 +404,7 @@ + interrupts-extended = <&exti 47 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc LPTIM1_K>; clock-names = "mux"; + power-domains = <&pd_core>; -+ wakeup-source; + wakeup-source; status = "disabled"; - pwm { -@@ -393,6 +439,11 @@ +@@ -402,6 +424,11 @@ compatible = "st,stm32-lptimer-counter"; status = "disabled"; }; @@ -2338,7 +6710,7 @@ index 39d9e545ed..ca71139f3a 100644 }; spi2: spi@4000b000 { -@@ -403,9 +454,10 @@ +@@ -412,8 +439,8 @@ interrupts = ; clocks = <&rcc SPI2_K>; resets = <&rcc SPI2_R>; @@ -2347,11 +6719,9 @@ index 39d9e545ed..ca71139f3a 100644 + dmas = <&dmamux1 39 0x400 0x01>, + <&dmamux1 40 0x400 0x01>; dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; status = "disabled"; }; - -@@ -428,9 +480,10 @@ +@@ -437,8 +464,8 @@ interrupts = ; clocks = <&rcc SPI3_K>; resets = <&rcc SPI3_R>; @@ -2360,18 +6730,12 @@ index 39d9e545ed..ca71139f3a 100644 + dmas = <&dmamux1 61 0x400 0x01>, + <&dmamux1 62 0x400 0x01>; dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; status = "disabled"; }; - -@@ -461,32 +514,52 @@ - usart2: serial@4000e000 { - compatible = "st,stm32h7-uart"; - reg = <0x4000e000 0x400>; -- interrupts = ; -+ interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>; +@@ -473,6 +500,10 @@ + interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc USART2_K>; -+ wakeup-source; + wakeup-source; + power-domains = <&pd_core>; + dmas = <&dmamux1 43 0x400 0x15>, + <&dmamux1 44 0x400 0x11>; @@ -2379,13 +6743,10 @@ index 39d9e545ed..ca71139f3a 100644 status = "disabled"; }; - usart3: serial@4000f000 { - compatible = "st,stm32h7-uart"; - reg = <0x4000f000 0x400>; -- interrupts = ; -+ interrupts-extended = <&exti 28 IRQ_TYPE_LEVEL_HIGH>; +@@ -482,6 +513,10 @@ + interrupts-extended = <&exti 28 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc USART3_K>; -+ wakeup-source; + wakeup-source; + power-domains = <&pd_core>; + dmas = <&dmamux1 45 0x400 0x15>, + <&dmamux1 46 0x400 0x11>; @@ -2393,13 +6754,10 @@ index 39d9e545ed..ca71139f3a 100644 status = "disabled"; }; - uart4: serial@40010000 { - compatible = "st,stm32h7-uart"; - reg = <0x40010000 0x400>; -- interrupts = ; -+ interrupts-extended = <&exti 30 IRQ_TYPE_LEVEL_HIGH>; +@@ -491,6 +526,10 @@ + interrupts-extended = <&exti 30 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc UART4_K>; -+ wakeup-source; + wakeup-source; + power-domains = <&pd_core>; + dmas = <&dmamux1 63 0x400 0x15>, + <&dmamux1 64 0x400 0x11>; @@ -2407,13 +6765,10 @@ index 39d9e545ed..ca71139f3a 100644 status = "disabled"; }; - uart5: serial@40011000 { - compatible = "st,stm32h7-uart"; - reg = <0x40011000 0x400>; -- interrupts = ; -+ interrupts-extended = <&exti 31 IRQ_TYPE_LEVEL_HIGH>; +@@ -500,6 +539,10 @@ + interrupts-extended = <&exti 31 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc UART5_K>; -+ wakeup-source; + wakeup-source; + power-domains = <&pd_core>; + dmas = <&dmamux1 65 0x400 0x15>, + <&dmamux1 66 0x400 0x11>; @@ -2421,7 +6776,7 @@ index 39d9e545ed..ca71139f3a 100644 status = "disabled"; }; -@@ -494,14 +567,19 @@ +@@ -507,12 +550,16 @@ compatible = "st,stm32mp15-i2c"; reg = <0x40012000 0x400>; interrupt-names = "event", "error"; @@ -2439,11 +6794,8 @@ index 39d9e545ed..ca71139f3a 100644 + power-domains = <&pd_core>; st,syscfg-fmp = <&syscfg 0x4 0x1>; wakeup-source; -+ i2c-analog-filter; - status = "disabled"; - }; - -@@ -509,14 +587,19 @@ + i2c-analog-filter; +@@ -523,12 +570,16 @@ compatible = "st,stm32mp15-i2c"; reg = <0x40013000 0x400>; interrupt-names = "event", "error"; @@ -2461,11 +6813,8 @@ index 39d9e545ed..ca71139f3a 100644 + power-domains = <&pd_core>; st,syscfg-fmp = <&syscfg 0x4 0x2>; wakeup-source; -+ i2c-analog-filter; - status = "disabled"; - }; - -@@ -524,14 +607,19 @@ + i2c-analog-filter; +@@ -539,12 +590,16 @@ compatible = "st,stm32mp15-i2c"; reg = <0x40014000 0x400>; interrupt-names = "event", "error"; @@ -2483,11 +6832,8 @@ index 39d9e545ed..ca71139f3a 100644 + power-domains = <&pd_core>; st,syscfg-fmp = <&syscfg 0x4 0x4>; wakeup-source; -+ i2c-analog-filter; - status = "disabled"; - }; - -@@ -539,14 +627,19 @@ + i2c-analog-filter; +@@ -555,12 +610,16 @@ compatible = "st,stm32mp15-i2c"; reg = <0x40015000 0x400>; interrupt-names = "event", "error"; @@ -2505,27 +6851,20 @@ index 39d9e545ed..ca71139f3a 100644 + power-domains = <&pd_core>; st,syscfg-fmp = <&syscfg 0x4 0x10>; wakeup-source; -+ i2c-analog-filter; - status = "disabled"; - }; - -@@ -554,7 +647,7 @@ + i2c-analog-filter; +@@ -571,7 +630,7 @@ compatible = "st,stm32-cec"; reg = <0x40016000 0x400>; interrupts = ; - clocks = <&rcc CEC_K>, <&clk_lse>; -+ clocks = <&rcc CEC_K>, <&scmi0_clk CK_SCMI0_LSE>; ++ clocks = <&rcc CEC_K>, <&rcc CEC>; clock-names = "cec", "hdmi-cec"; status = "disabled"; }; -@@ -586,16 +679,26 @@ - uart7: serial@40018000 { - compatible = "st,stm32h7-uart"; - reg = <0x40018000 0x400>; -- interrupts = ; -+ interrupts-extended = <&exti 32 IRQ_TYPE_LEVEL_HIGH>; +@@ -606,6 +665,10 @@ + interrupts-extended = <&exti 32 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc UART7_K>; -+ wakeup-source; + wakeup-source; + power-domains = <&pd_core>; + dmas = <&dmamux1 79 0x400 0x15>, + <&dmamux1 80 0x400 0x11>; @@ -2533,13 +6872,10 @@ index 39d9e545ed..ca71139f3a 100644 status = "disabled"; }; - uart8: serial@40019000 { - compatible = "st,stm32h7-uart"; - reg = <0x40019000 0x400>; -- interrupts = ; -+ interrupts-extended = <&exti 33 IRQ_TYPE_LEVEL_HIGH>; +@@ -615,6 +678,10 @@ + interrupts-extended = <&exti 33 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc UART8_K>; -+ wakeup-source; + wakeup-source; + power-domains = <&pd_core>; + dmas = <&dmamux1 81 0x400 0x15>, + <&dmamux1 82 0x400 0x11>; @@ -2547,7 +6883,7 @@ index 39d9e545ed..ca71139f3a 100644 status = "disabled"; }; -@@ -606,13 +709,13 @@ +@@ -625,13 +692,13 @@ reg = <0x44000000 0x400>; clocks = <&rcc TIM1_K>; clock-names = "int"; @@ -2568,7 +6904,7 @@ index 39d9e545ed..ca71139f3a 100644 dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig", "com"; status = "disabled"; -@@ -642,13 +745,13 @@ +@@ -661,13 +728,13 @@ reg = <0x44001000 0x400>; clocks = <&rcc TIM8_K>; clock-names = "int"; @@ -2589,14 +6925,10 @@ index 39d9e545ed..ca71139f3a 100644 dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig", "com"; status = "disabled"; -@@ -674,8 +777,13 @@ - usart6: serial@44003000 { - compatible = "st,stm32h7-uart"; - reg = <0x44003000 0x400>; -- interrupts = ; -+ interrupts-extended = <&exti 29 IRQ_TYPE_LEVEL_HIGH>; +@@ -696,6 +763,10 @@ + interrupts-extended = <&exti 29 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc USART6_K>; -+ wakeup-source; + wakeup-source; + power-domains = <&pd_core>; + dmas = <&dmamux1 71 0x400 0x15>, + <&dmamux1 72 0x400 0x11>; @@ -2604,7 +6936,7 @@ index 39d9e545ed..ca71139f3a 100644 status = "disabled"; }; -@@ -687,9 +795,10 @@ +@@ -707,8 +778,8 @@ interrupts = ; clocks = <&rcc SPI1_K>; resets = <&rcc SPI1_R>; @@ -2613,11 +6945,9 @@ index 39d9e545ed..ca71139f3a 100644 + dmas = <&dmamux1 37 0x400 0x01>, + <&dmamux1 38 0x400 0x01>; dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; status = "disabled"; }; - -@@ -712,9 +821,10 @@ +@@ -732,8 +803,8 @@ interrupts = ; clocks = <&rcc SPI4_K>; resets = <&rcc SPI4_R>; @@ -2626,11 +6956,9 @@ index 39d9e545ed..ca71139f3a 100644 + dmas = <&dmamux1 83 0x400 0x01>, + <&dmamux1 84 0x400 0x01>; dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; status = "disabled"; }; - -@@ -725,10 +835,10 @@ +@@ -745,10 +816,10 @@ reg = <0x44006000 0x400>; clocks = <&rcc TIM15_K>; clock-names = "int"; @@ -2645,7 +6973,7 @@ index 39d9e545ed..ca71139f3a 100644 dma-names = "ch1", "up", "trig", "com"; status = "disabled"; -@@ -752,8 +862,8 @@ +@@ -772,8 +843,8 @@ reg = <0x44007000 0x400>; clocks = <&rcc TIM16_K>; clock-names = "int"; @@ -2656,7 +6984,7 @@ index 39d9e545ed..ca71139f3a 100644 dma-names = "ch1", "up"; status = "disabled"; -@@ -776,8 +886,8 @@ +@@ -796,8 +867,8 @@ reg = <0x44008000 0x400>; clocks = <&rcc TIM17_K>; clock-names = "int"; @@ -2667,7 +6995,7 @@ index 39d9e545ed..ca71139f3a 100644 dma-names = "ch1", "up"; status = "disabled"; -@@ -802,9 +912,10 @@ +@@ -822,8 +893,8 @@ interrupts = ; clocks = <&rcc SPI5_K>; resets = <&rcc SPI5_R>; @@ -2676,11 +7004,9 @@ index 39d9e545ed..ca71139f3a 100644 + dmas = <&dmamux1 85 0x400 0x01>, + <&dmamux1 86 0x400 0x01>; dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; status = "disabled"; }; - -@@ -822,7 +933,7 @@ +@@ -842,7 +913,7 @@ #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-a"; @@ -2689,7 +7015,7 @@ index 39d9e545ed..ca71139f3a 100644 clocks = <&rcc SAI1_K>; clock-names = "sai_ck"; dmas = <&dmamux1 87 0x400 0x01>; -@@ -832,7 +943,7 @@ +@@ -852,7 +923,7 @@ sai1b: audio-controller@4400a024 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-b"; @@ -2698,7 +7024,7 @@ index 39d9e545ed..ca71139f3a 100644 clocks = <&rcc SAI1_K>; clock-names = "sai_ck"; dmas = <&dmamux1 88 0x400 0x01>; -@@ -853,7 +964,7 @@ +@@ -873,7 +944,7 @@ sai2a: audio-controller@4400b004 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-a"; @@ -2707,7 +7033,7 @@ index 39d9e545ed..ca71139f3a 100644 clocks = <&rcc SAI2_K>; clock-names = "sai_ck"; dmas = <&dmamux1 89 0x400 0x01>; -@@ -863,7 +974,7 @@ +@@ -883,7 +954,7 @@ sai2b: audio-controller@4400b024 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-b"; @@ -2716,7 +7042,7 @@ index 39d9e545ed..ca71139f3a 100644 clocks = <&rcc SAI2_K>; clock-names = "sai_ck"; dmas = <&dmamux1 90 0x400 0x01>; -@@ -884,7 +995,7 @@ +@@ -904,7 +975,7 @@ sai3a: audio-controller@4400c004 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-a"; @@ -2725,7 +7051,7 @@ index 39d9e545ed..ca71139f3a 100644 clocks = <&rcc SAI3_K>; clock-names = "sai_ck"; dmas = <&dmamux1 113 0x400 0x01>; -@@ -894,7 +1005,7 @@ +@@ -914,7 +985,7 @@ sai3b: audio-controller@4400c024 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-b"; @@ -2734,7 +7060,7 @@ index 39d9e545ed..ca71139f3a 100644 clocks = <&rcc SAI3_K>; clock-names = "sai_ck"; dmas = <&dmamux1 114 0x400 0x01>; -@@ -988,6 +1099,15 @@ +@@ -1008,6 +1079,15 @@ #dma-cells = <4>; st,mem2mem; dma-requests = <8>; @@ -2750,7 +7076,7 @@ index 39d9e545ed..ca71139f3a 100644 }; dma2: dma-controller@48001000 { -@@ -1006,11 +1126,20 @@ +@@ -1026,6 +1106,15 @@ #dma-cells = <4>; st,mem2mem; dma-requests = <8>; @@ -2766,13 +7092,7 @@ index 39d9e545ed..ca71139f3a 100644 }; dmamux1: dma-router@48002000 { - compatible = "st,stm32h7-dmamux"; -- reg = <0x48002000 0x1c>; -+ reg = <0x48002000 0x40>; - #dma-cells = <3>; - dma-requests = <128>; - dma-masters = <&dma1 &dma2>; -@@ -1039,7 +1168,7 @@ +@@ -1059,7 +1148,7 @@ reg = <0x0>; interrupt-parent = <&adc>; interrupts = <0>; @@ -2781,36 +7101,36 @@ index 39d9e545ed..ca71139f3a 100644 dma-names = "rx"; status = "disabled"; }; -@@ -1050,7 +1179,7 @@ +@@ -1070,14 +1159,16 @@ reg = <0x100>; interrupt-parent = <&adc>; interrupts = <1>; - dmas = <&dmamux1 10 0x400 0x01>; + dmas = <&dmamux1 10 0x400 0x80000001>; dma-names = "rx"; ++ nvmem-cells = <&vrefint>; ++ nvmem-cell-names = "vrefint"; status = "disabled"; }; -@@ -1058,7 +1187,7 @@ + }; - sdmmc3: sdmmc@48004000 { - compatible = "arm,pl18x", "arm,primecell"; -- arm,primecell-periphid = <0x10153180>; -+ arm,primecell-periphid = <0x00253180>; + sdmmc3: mmc@48004000 { +- compatible = "arm,pl18x", "arm,primecell"; ++ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x00253180>; reg = <0x48004000 0x400>; interrupts = ; - interrupt-names = "cmd_irq"; -@@ -1078,21 +1207,23 @@ +@@ -1098,21 +1189,24 @@ clock-names = "otg"; resets = <&rcc USBO_R>; reset-names = "dwc2"; - interrupts = ; -- g-rx-fifo-size = <256>; + interrupts-extended = <&exti 44 IRQ_TYPE_LEVEL_HIGH>; -+ g-rx-fifo-size = <512>; + g-rx-fifo-size = <512>; g-np-tx-fifo-size = <32>; -- g-tx-fifo-size = <128 128 64 64 64 64 32 32>; -+ g-tx-fifo-size = <256 16 16 16 16 16 16 16>; + 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; @@ -2829,7 +7149,7 @@ index 39d9e545ed..ca71139f3a 100644 }; ipcc: mailbox@4c001000 { -@@ -1101,12 +1232,12 @@ +@@ -1121,12 +1215,12 @@ reg = <0x4c001000 0x400>; st,proc-id = <0>; interrupts-extended = @@ -2846,11 +7166,11 @@ index 39d9e545ed..ca71139f3a 100644 status = "disabled"; }; -@@ -1117,21 +1248,30 @@ +@@ -1137,25 +1231,29 @@ resets = <&rcc CAMITF_R>; clocks = <&rcc DCMI>; clock-names = "mclk"; -- dmas = <&dmamux1 75 0x400 0x0d>; +- dmas = <&dmamux1 75 0x400 0x01>; + dmas = <&dmamux1 75 0x400 0xe0000001>; dma-names = "tx"; status = "disabled"; @@ -2862,14 +7182,15 @@ index 39d9e545ed..ca71139f3a 100644 reg = <0x50000000 0x1000>; #clock-cells = <1>; #reset-cells = <1>; -+ interrupts = ; -+ -+ clock-names = "hse", "hsi", "csi", "lse", "lsi"; -+ clocks = <&scmi0_clk CK_SCMI0_HSE>, -+ <&scmi0_clk CK_SCMI0_HSI>, -+ <&scmi0_clk CK_SCMI0_CSI>, -+ <&scmi0_clk CK_SCMI0_LSE>, -+ <&scmi0_clk CK_SCMI0_LSI>; + + clock-names = "hse", "hsi", "csi", "lse", "lsi"; +- clocks = <&clk_hse>, <&clk_hsi>, <&clk_csi>, +- <&clk_lse>, <&clk_lsi>; ++ clocks = <&scmi_clk CK_SCMI_HSE>, ++ <&scmi_clk CK_SCMI_HSI>, ++ <&scmi_clk CK_SCMI_CSI>, ++ <&scmi_clk CK_SCMI_LSE>, ++ <&scmi_clk CK_SCMI_LSI>; }; pwr_regulators: pwr@50001000 { @@ -2879,12 +7200,7 @@ index 39d9e545ed..ca71139f3a 100644 reg11: reg11 { regulator-name = "reg11"; -@@ -1153,15 +1293,42 @@ - }; - - pwr_mcu: pwr_mcu@50001014 { -- compatible = "syscon"; -+ compatible = "st,stm32mp151-pwr-mcu", "syscon"; +@@ -1181,11 +1279,38 @@ reg = <0x50001014 0x4>; }; @@ -2895,12 +7211,12 @@ index 39d9e545ed..ca71139f3a 100644 + interrupt-controller; + #interrupt-cells = <3>; + -+ wakeup-gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>, -+ <&gpioa 2 GPIO_ACTIVE_HIGH>, -+ <&gpioc 13 GPIO_ACTIVE_HIGH>, -+ <&gpioi 8 GPIO_ACTIVE_HIGH>, -+ <&gpioi 11 GPIO_ACTIVE_HIGH>, -+ <&gpioc 1 GPIO_ACTIVE_HIGH>; ++ st,wakeup-pins = <&gpioa 0 GPIO_ACTIVE_HIGH>, ++ <&gpioa 2 GPIO_ACTIVE_HIGH>, ++ <&gpioc 13 GPIO_ACTIVE_HIGH>, ++ <&gpioi 8 GPIO_ACTIVE_HIGH>, ++ <&gpioi 11 GPIO_ACTIVE_HIGH>, ++ <&gpioc 1 GPIO_ACTIVE_HIGH>; + }; + exti: interrupt-controller@5000d000 { @@ -2923,19 +7239,15 @@ index 39d9e545ed..ca71139f3a 100644 }; syscfg: syscon@50020000 { -@@ -1175,8 +1342,11 @@ - #size-cells = <0>; - compatible = "st,stm32-lptimer"; - reg = <0x50021000 0x400>; -+ interrupts-extended = <&exti 48 IRQ_TYPE_LEVEL_HIGH>; +@@ -1202,6 +1327,7 @@ + interrupts-extended = <&exti 48 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc LPTIM2_K>; clock-names = "mux"; + power-domains = <&pd_core>; -+ wakeup-source; + wakeup-source; status = "disabled"; - pwm { -@@ -1195,6 +1365,11 @@ +@@ -1221,6 +1347,11 @@ compatible = "st,stm32-lptimer-counter"; status = "disabled"; }; @@ -2947,19 +7259,15 @@ index 39d9e545ed..ca71139f3a 100644 }; lptimer3: timer@50022000 { -@@ -1202,8 +1377,11 @@ - #size-cells = <0>; - compatible = "st,stm32-lptimer"; - reg = <0x50022000 0x400>; -+ interrupts-extended = <&exti 50 IRQ_TYPE_LEVEL_HIGH>; +@@ -1231,6 +1362,7 @@ + interrupts-extended = <&exti 50 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc LPTIM3_K>; clock-names = "mux"; + power-domains = <&pd_core>; -+ wakeup-source; + wakeup-source; status = "disabled"; - pwm { -@@ -1217,13 +1395,21 @@ +@@ -1245,6 +1377,11 @@ reg = <2>; status = "disabled"; }; @@ -2971,17 +7279,15 @@ index 39d9e545ed..ca71139f3a 100644 }; lptimer4: timer@50023000 { - compatible = "st,stm32-lptimer"; - reg = <0x50023000 0x400>; -+ interrupts-extended = <&exti 52 IRQ_TYPE_LEVEL_HIGH>; +@@ -1253,6 +1390,7 @@ + interrupts-extended = <&exti 52 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc LPTIM4_K>; clock-names = "mux"; + power-domains = <&pd_core>; -+ wakeup-source; + wakeup-source; status = "disabled"; - pwm { -@@ -1231,13 +1417,21 @@ +@@ -1261,6 +1399,11 @@ #pwm-cells = <3>; status = "disabled"; }; @@ -2993,17 +7299,15 @@ index 39d9e545ed..ca71139f3a 100644 }; lptimer5: timer@50024000 { - compatible = "st,stm32-lptimer"; - reg = <0x50024000 0x400>; -+ interrupts-extended = <&exti 53 IRQ_TYPE_LEVEL_HIGH>; +@@ -1269,6 +1412,7 @@ + interrupts-extended = <&exti 53 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc LPTIM5_K>; clock-names = "mux"; + power-domains = <&pd_core>; -+ wakeup-source; + wakeup-source; status = "disabled"; - pwm { -@@ -1245,6 +1439,11 @@ +@@ -1277,6 +1421,11 @@ #pwm-cells = <3>; status = "disabled"; }; @@ -3015,7 +7319,7 @@ index 39d9e545ed..ca71139f3a 100644 }; vrefbuf: vrefbuf@50025000 { -@@ -1269,7 +1468,7 @@ +@@ -1301,7 +1450,7 @@ sai4a: audio-controller@50027004 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-a"; @@ -3024,7 +7328,7 @@ index 39d9e545ed..ca71139f3a 100644 clocks = <&rcc SAI4_K>; clock-names = "sai_ck"; dmas = <&dmamux1 99 0x400 0x01>; -@@ -1279,7 +1478,7 @@ +@@ -1311,7 +1460,7 @@ sai4b: audio-controller@50027024 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-b"; @@ -3033,7 +7337,7 @@ index 39d9e545ed..ca71139f3a 100644 clocks = <&rcc SAI4_K>; clock-names = "sai_ck"; dmas = <&dmamux1 100 0x400 0x01>; -@@ -1297,13 +1496,21 @@ +@@ -1329,13 +1478,21 @@ status = "disabled"; }; @@ -3051,36 +7355,36 @@ index 39d9e545ed..ca71139f3a 100644 interrupts = ; - clocks = <&rcc HASH1>; - resets = <&rcc HASH1_R>; -- dmas = <&mdma1 31 0x10 0x1000A02 0x0 0x0>; -+ clocks = <&scmi0_clk CK_SCMI0_HASH1>; -+ resets = <&scmi0_reset RST_SCMI0_HASH1>; +- dmas = <&mdma1 31 0x2 0x1000A02 0x0 0x0>; ++ clocks = <&scmi_clk CK_SCMI_HASH1>; ++ resets = <&scmi_reset RST_SCMI_HASH1>; + dmas = <&mdma1 31 0x2 0x1000A02 0x0 0x0 0x0>; dma-names = "in"; dma-maxburst = <2>; status = "disabled"; -@@ -1312,8 +1519,8 @@ +@@ -1344,8 +1501,8 @@ rng1: rng@54003000 { compatible = "st,stm32-rng"; reg = <0x54003000 0x400>; - clocks = <&rcc RNG1_K>; - resets = <&rcc RNG1_R>; -+ clocks = <&scmi0_clk CK_SCMI0_RNG1>; -+ resets = <&scmi0_reset RST_SCMI0_RNG1>; ++ clocks = <&scmi_clk CK_SCMI_RNG1>; ++ resets = <&scmi_reset RST_SCMI_RNG1>; status = "disabled"; }; -@@ -1322,8 +1529,8 @@ +@@ -1354,8 +1511,8 @@ reg = <0x58000000 0x1000>; interrupts = ; clocks = <&rcc MDMA>; - resets = <&rcc MDMA_R>; - #dma-cells = <5>; -+ resets = <&scmi0_reset RST_SCMI0_MDMA>; ++ resets = <&scmi_reset RST_SCMI_MDMA>; + #dma-cells = <6>; dma-channels = <32>; dma-requests = <48>; }; -@@ -1354,9 +1561,9 @@ +@@ -1386,9 +1543,9 @@ <4 0x09010000 0x1000>, <4 0x09020000 0x1000>; interrupts = ; @@ -3093,39 +7397,36 @@ index 39d9e545ed..ca71139f3a 100644 dma-names = "tx", "rx", "ecc"; status = "disabled"; }; -@@ -1367,17 +1574,19 @@ +@@ -1399,8 +1556,8 @@ reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; reg-names = "qspi", "qspi_mm"; interrupts = ; -- dmas = <&mdma1 22 0x10 0x100002 0x0 0x0>, -- <&mdma1 22 0x10 0x100008 0x0 0x0>; -+ dmas = <&mdma1 22 0x2 0x100002 0x0 0x0 0x0>, -+ <&mdma1 22 0x2 0x100008 0x0 0x0 0x0>; +- dmas = <&mdma1 22 0x2 0x10100002 0x0 0x0>, +- <&mdma1 22 0x2 0x10100008 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>; -+ #address-cells = <1>; -+ #size-cells = <0>; - status = "disabled"; +@@ -1410,7 +1567,7 @@ }; - sdmmc1: sdmmc@58005000 { - compatible = "arm,pl18x", "arm,primecell"; -- arm,primecell-periphid = <0x10153180>; -+ arm,primecell-periphid = <0x00253180>; + sdmmc1: mmc@58005000 { +- compatible = "arm,pl18x", "arm,primecell"; ++ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x00253180>; reg = <0x58005000 0x1000>; interrupts = ; - interrupt-names = "cmd_irq"; -@@ -1392,7 +1601,7 @@ +@@ -1425,7 +1582,7 @@ + }; - sdmmc2: sdmmc@58007000 { - compatible = "arm,pl18x", "arm,primecell"; -- arm,primecell-periphid = <0x10153180>; -+ arm,primecell-periphid = <0x00253180>; + sdmmc2: mmc@58007000 { +- compatible = "arm,pl18x", "arm,primecell"; ++ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x00253180>; reg = <0x58007000 0x1000>; interrupts = ; - interrupt-names = "cmd_irq"; -@@ -1422,8 +1631,10 @@ +@@ -1450,8 +1607,10 @@ compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; reg = <0x5800a000 0x2000>; reg-names = "stmmaceth"; @@ -3138,17 +7439,29 @@ index 39d9e545ed..ca71139f3a 100644 clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", -@@ -1440,6 +1651,7 @@ - snps,en-tx-lpi-clockgating; +@@ -1471,6 +1630,7 @@ snps,axi-config = <&stmmac_axi_config_0>; snps,tso; -+ power-domains = <&pd_core>; status = "disabled"; - }; ++ power-domains = <&pd_core>; -@@ -1457,8 +1669,10 @@ + stmmac_axi_config_0: stmmac-axi-config { + snps,wr_osr_lmt = <0x7>; +@@ -1482,7 +1642,7 @@ + usbh_ohci: usb@5800c000 { + compatible = "generic-ohci"; + reg = <0x5800c000 0x1000>; +- clocks = <&rcc USBH>; ++ clocks = <&usbphyc>, <&rcc USBH>; + resets = <&rcc USBH_R>; + interrupts = ; + status = "disabled"; +@@ -1491,10 +1651,12 @@ + usbh_ehci: usb@5800d000 { + compatible = "generic-ehci"; reg = <0x5800d000 0x1000>; - clocks = <&rcc USBH>; +- clocks = <&rcc USBH>; ++ clocks = <&usbphyc>, <&rcc USBH>; resets = <&rcc USBH_R>; - interrupts = ; + interrupts-extended = <&exti 43 IRQ_TYPE_LEVEL_HIGH>; @@ -3158,24 +7471,16 @@ index 39d9e545ed..ca71139f3a 100644 status = "disabled"; }; -@@ -1481,7 +1695,7 @@ +@@ -1517,7 +1679,7 @@ iwdg2: watchdog@5a002000 { compatible = "st,stm32mp1-iwdg"; reg = <0x5a002000 0x400>; - clocks = <&rcc IWDG2>, <&rcc CK_LSI>; -+ clocks = <&rcc IWDG2>, <&scmi0_clk CK_SCMI0_LSI>; ++ clocks = <&rcc IWDG2>, <&scmi_clk CK_SCMI_LSI>; clock-names = "pclk", "lsi"; status = "disabled"; }; -@@ -1489,6 +1703,7 @@ - usbphyc: usbphyc@5a006000 { - #address-cells = <1>; - #size-cells = <0>; -+ #clock-cells = <0>; - compatible = "st,stm32mp1-usbphyc"; - reg = <0x5a006000 0x1000>; - clocks = <&rcc USBPHY_K>; -@@ -1508,11 +1723,21 @@ +@@ -1545,12 +1707,22 @@ }; }; @@ -3184,22 +7489,22 @@ index 39d9e545ed..ca71139f3a 100644 + reg = <0x5a007000 0x400>; + clocks = <&rcc DDRPERFM>; + resets = <&rcc DDRPERFM_R>; ++ status = "disabled"; + }; + usart1: serial@5c000000 { compatible = "st,stm32h7-uart"; reg = <0x5c000000 0x400>; -- interrupts = ; + interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&rcc USART1_K>; -+ interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>; -+ clocks = <&scmi0_clk CK_SCMI0_USART1>; -+ resets = <&scmi0_reset RST_SCMI0_USART1>; -+ wakeup-source; ++ clocks = <&scmi_clk CK_SCMI_USART1>; ++ resets = <&scmi_reset RST_SCMI_USART1>; + wakeup-source; + power-domains = <&pd_core>; status = "disabled"; }; -@@ -1522,11 +1747,12 @@ +@@ -1560,10 +1732,10 @@ compatible = "st,stm32h7-spi"; reg = <0x5c001000 0x400>; interrupts = ; @@ -3207,16 +7512,14 @@ index 39d9e545ed..ca71139f3a 100644 - resets = <&rcc SPI6_R>; - dmas = <&mdma1 34 0x0 0x40008 0x0 0x0>, - <&mdma1 35 0x0 0x40002 0x0 0x0>; -+ clocks = <&scmi0_clk CK_SCMI0_SPI6>; -+ resets = <&scmi0_reset RST_SCMI0_SPI6>; ++ clocks = <&scmi_clk CK_SCMI_SPI6>; ++ resets = <&scmi_reset RST_SCMI_SPI6>; + dmas = <&mdma1 34 0x0 0x40008 0x0 0x0 0x0>, + <&mdma1 35 0x0 0x40002 0x0 0x0 0x0>; dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; status = "disabled"; }; - -@@ -1534,23 +1760,29 @@ +@@ -1572,12 +1744,16 @@ compatible = "st,stm32mp15-i2c"; reg = <0x5c002000 0x400>; interrupt-names = "event", "error"; @@ -3226,8 +7529,8 @@ index 39d9e545ed..ca71139f3a 100644 - resets = <&rcc I2C4_R>; + interrupts-extended = <&exti 24 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; -+ clocks = <&scmi0_clk CK_SCMI0_I2C4>; -+ resets = <&scmi0_reset RST_SCMI0_I2C4>; ++ clocks = <&scmi_clk CK_SCMI_I2C4>; ++ resets = <&scmi_reset RST_SCMI_I2C4>; #address-cells = <1>; #size-cells = <0>; + dmas = <&mdma1 36 0x0 0x40008 0x0 0x0 0>, @@ -3236,23 +7539,35 @@ index 39d9e545ed..ca71139f3a 100644 + power-domains = <&pd_core>; st,syscfg-fmp = <&syscfg 0x4 0x8>; wakeup-source; -+ i2c-analog-filter; - status = "disabled"; - }; - + i2c-analog-filter; +@@ -1587,38 +1763,50 @@ rtc: rtc@5c004000 { compatible = "st,stm32mp1-rtc"; reg = <0x5c004000 0x400>; - clocks = <&rcc RTCAPB>, <&rcc RTC>; -+ clocks = <&scmi0_clk CK_SCMI0_RTCAPB>, -+ <&scmi0_clk CK_SCMI0_RTC>; ++ clocks = <&scmi_clk CK_SCMI_RTCAPB>, ++ <&scmi_clk CK_SCMI_RTC>; clock-names = "pclk", "rtc_ck"; - interrupts = ; + interrupts-extended = <&exti 19 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; -@@ -1568,20 +1800,28 @@ + bsec: efuse@5c005000 { + compatible = "st,stm32mp15-bsec"; + reg = <0x5c005000 0x400>; ++ clocks = <&scmi_clk CK_SCMI_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>; + }; ts_cal2: calib@5e { reg = <0x5e 0x2>; }; @@ -3271,8 +7586,8 @@ index 39d9e545ed..ca71139f3a 100644 - resets = <&rcc I2C6_R>; + interrupts-extended = <&exti 54 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; -+ clocks = <&scmi0_clk CK_SCMI0_I2C6>; -+ resets = <&scmi0_reset RST_SCMI0_I2C6>; ++ clocks = <&scmi_clk CK_SCMI_I2C6>; ++ resets = <&scmi_reset RST_SCMI_I2C6>; #address-cells = <1>; #size-cells = <0>; + dmas = <&mdma1 38 0x0 0x40008 0x0 0x0 0>, @@ -3281,43 +7596,11 @@ index 39d9e545ed..ca71139f3a 100644 + power-domains = <&pd_core>; st,syscfg-fmp = <&syscfg 0x4 0x20>; wakeup-source; -+ i2c-analog-filter; - status = "disabled"; - }; - -@@ -1596,7 +1836,7 @@ - ranges = <0 0x50002000 0xa400>; - interrupt-parent = <&exti>; - st,syscfg = <&exti 0x60 0xff>; -- hwlocks = <&hwspinlock 0>; -+ hwlocks = <&hsem 0 1>; - pins-are-numbered; - - gpioa: gpio@50002000 { -@@ -1729,7 +1969,7 @@ - pins-are-numbered; - interrupt-parent = <&exti>; - st,syscfg = <&exti 0x60 0xff>; -- hwlocks = <&hwspinlock 0>; -+ hwlocks = <&hsem 0 1>; - - gpioz: gpio@54004000 { - gpio-controller; -@@ -1737,12 +1977,30 @@ - interrupt-controller; - #interrupt-cells = <2>; - reg = <0 0x400>; -- clocks = <&rcc GPIOZ>; -+ clocks = <&scmi0_clk CK_SCMI0_GPIOZ>; - st,bank-name = "GPIOZ"; - st,bank-ioport = <11>; - status = "disabled"; - }; - }; -+ -+ tamp: tamp@5c00a000 { -+ compatible = "simple-bus", "syscon", "simple-mfd"; -+ reg = <0x5c00a000 0x400>; + i2c-analog-filter; +@@ -1628,6 +1816,19 @@ + tamp: tamp@5c00a000 { + compatible = "st,stm32-tamp", "syscon", "simple-mfd"; + reg = <0x5c00a000 0x400>; + + reboot-mode { + compatible = "syscon-reboot-mode"; @@ -3331,23 +7614,49 @@ index 39d9e545ed..ca71139f3a 100644 + mode-ums_mmc1 = <0x11>; + mode-ums_mmc2 = <0x12>; + }; -+ }; - }; + }; - mlahb: ahb { -@@ -1759,11 +2017,18 @@ + /* +@@ -1641,7 +1842,7 @@ + ranges = <0 0x50002000 0xa400>; + interrupt-parent = <&exti>; + st,syscfg = <&exti 0x60 0xff>; +- hwlocks = <&hwspinlock 0>; ++ hwlocks = <&hsem 0 1>; + pins-are-numbered; + + gpioa: gpio@50002000 { +@@ -1774,7 +1975,7 @@ + pins-are-numbered; + interrupt-parent = <&exti>; + st,syscfg = <&exti 0x60 0xff>; +- hwlocks = <&hwspinlock 0>; ++ hwlocks = <&hsem 0 1>; + + gpioz: gpio@54004000 { + gpio-controller; +@@ -1782,7 +1983,7 @@ + interrupt-controller; + #interrupt-cells = <2>; + reg = <0 0x400>; +- clocks = <&rcc GPIOZ>; ++ clocks = <&scmi_clk CK_SCMI_GPIOZ>; + st,bank-name = "GPIOZ"; + st,bank-ioport = <11>; + status = "disabled"; +@@ -1804,13 +2005,18 @@ reg = <0x10000000 0x40000>, <0x30000000 0x40000>, <0x38000000 0x10000>; - resets = <&rcc MCU_R>; - st,syscfg-holdboot = <&rcc 0x10C 0x1>; - st,syscfg-tz = <&rcc 0x000 0x1>; -+ resets = <&scmi0_reset RST_SCMI0_MCU>, -+ <&scmi0_reset RST_SCMI0_MCU_HOLD_BOOT>; ++ resets = <&scmi_reset RST_SCMI_MCU>, ++ <&scmi_reset RST_SCMI_MCU_HOLD_BOOT>; + reset-names = "mcu_rst", "hold_boot"; st,syscfg-pdds = <&pwr_mcu 0x0 0x1>; -+ st,syscfg-rsc-tbl = <&tamp 0x144 0xFFFFFFFF>; -+ st,syscfg-m4-state = <&tamp 0x148 0xFFFFFFFF>; + st,syscfg-rsc-tbl = <&tamp 0x144 0xFFFFFFFF>; + st,syscfg-m4-state = <&tamp 0x148 0xFFFFFFFF>; status = "disabled"; + + m4_system_resources { @@ -3358,51 +7667,56 @@ index 39d9e545ed..ca71139f3a 100644 }; }; diff --git a/arch/arm/dts/stm32mp153.dtsi b/arch/arm/dts/stm32mp153.dtsi -index 6d9ab08667..cf16b843c6 100644 +index 1c1889b194..56ff32b4a4 100644 --- a/arch/arm/dts/stm32mp153.dtsi +++ b/arch/arm/dts/stm32mp153.dtsi -@@ -10,12 +10,20 @@ +@@ -10,9 +10,11 @@ cpus { cpu1: cpu@1 { compatible = "arm,cortex-a7"; - clock-frequency = <650000000>; device_type = "cpu"; reg = <1>; -+ clocks = <&scmi0_clk CK_SCMI0_MPU>; ++ clocks = <&scmi_clk CK_SCMI_MPU>; + clock-names = "cpu"; + operating-points-v2 = <&cpu0_opp_table>; }; }; -+ arm-pmu { -+ interrupts = , -+ ; -+ interrupt-affinity = <&cpu0>, <&cpu1>; +@@ -22,6 +24,13 @@ + interrupt-affinity = <&cpu0>, <&cpu1>; + }; + ++ timer { ++ interrupts = , ++ , ++ , ++ ; + }; + soc { m_can1: can@4400e000 { compatible = "bosch,m_can"; -@@ -24,7 +32,7 @@ +@@ -30,7 +39,7 @@ interrupts = , ; interrupt-names = "int0", "int1"; - clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; -+ clocks = <&scmi0_clk CK_SCMI0_HSE>, <&rcc FDCAN_K>; ++ clocks = <&scmi_clk CK_SCMI_HSE>, <&rcc FDCAN_K>; clock-names = "hclk", "cclk"; bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>; status = "disabled"; -@@ -37,7 +45,7 @@ +@@ -43,7 +52,7 @@ interrupts = , ; interrupt-names = "int0", "int1"; - clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; -+ clocks = <&scmi0_clk CK_SCMI0_HSE>, <&rcc FDCAN_K>; ++ clocks = <&scmi_clk CK_SCMI_HSE>, <&rcc FDCAN_K>; clock-names = "hclk", "cclk"; bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>; status = "disabled"; diff --git a/arch/arm/dts/stm32mp157.dtsi b/arch/arm/dts/stm32mp157.dtsi -index 54e73ccea4..8a34964b9d 100644 +index 54e73ccea4..1d82868f36 100644 --- a/arch/arm/dts/stm32mp157.dtsi +++ b/arch/arm/dts/stm32mp157.dtsi @@ -20,7 +20,8 @@ @@ -3411,39 +7725,46 @@ index 54e73ccea4..8a34964b9d 100644 reg = <0x5a000000 0x800>; - clocks = <&rcc DSI_K>, <&clk_hse>, <&rcc DSI_PX>; + phy-dsi-supply = <®18>; -+ clocks = <&rcc DSI_K>, <&scmi0_clk CK_SCMI0_HSE>, <&rcc DSI_PX>; ++ clocks = <&rcc DSI_K>, <&scmi_clk CK_SCMI_HSE>, <&rcc DSI_PX>; clock-names = "pclk", "ref", "px_clk"; resets = <&rcc DSI_R>; reset-names = "apb"; diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi -index 6787619290..8553570642 100644 +index 15a04ae927..a8573b94d2 100644 --- a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi -@@ -16,12 +16,18 @@ +@@ -15,7 +15,7 @@ config { u-boot,boot-led = "heartbeat"; u-boot,error-led = "error"; -- u-boot,mmc-env-partition = "ssbl"; -+ u-boot,mmc-env-partition = "fip"; +- u-boot,mmc-env-partition = "fip"; ++ u-boot,mmc-env-partition = "u-boot-env"; 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)>; +@@ -27,28 +27,16 @@ }; + #endif -+#ifdef CONFIG_STM32MP15x_STM32IMAGE -+ config { -+ u-boot,mmc-env-partition = "ssbl"; -+ }; -+ -+ /* only needed for boot with TF-A, witout FIP support */ - firmware { - optee { - compatible = "linaro,optee-tz"; -@@ -35,9 +41,10 @@ - no-map; +-#ifdef CONFIG_STM32MP15x_STM32IMAGE +- /* only needed for boot with TF-A, witout FIP support */ +- firmware { +- optee { +- compatible = "linaro,optee-tz"; +- method = "smc"; +- }; +- }; +- + reserved-memory { + u-boot,dm-spl; + + optee@de000000 { +- reg = <0xde000000 0x02000000>; +- no-map; + u-boot,dm-spl; }; }; -+#endif +-#endif led { - red { @@ -3451,7 +7772,7 @@ index 6787619290..8553570642 100644 label = "error"; gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; default-state = "off"; -@@ -50,6 +57,7 @@ +@@ -61,6 +49,7 @@ status = "okay"; }; @@ -3459,7 +7780,7 @@ index 6787619290..8553570642 100644 &clk_hse { st,digbypass; }; -@@ -65,6 +73,10 @@ +@@ -76,6 +65,10 @@ }; }; @@ -3470,7 +7791,7 @@ index 6787619290..8553570642 100644 &pmic { u-boot,dm-pre-reloc; }; -@@ -161,6 +173,10 @@ +@@ -172,6 +165,10 @@ }; }; @@ -3481,7 +7802,7 @@ index 6787619290..8553570642 100644 &sdmmc1 { u-boot,dm-spl; }; -@@ -174,6 +190,7 @@ +@@ -185,6 +182,7 @@ u-boot,dm-spl; }; }; @@ -3489,8 +7810,15 @@ index 6787619290..8553570642 100644 &uart4 { u-boot,dm-pre-reloc; +@@ -202,6 +200,3 @@ + }; + }; + +-&usbotg_hs { +- u-boot,force-b-session-valid; +-}; diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts -index d03d4cd260..f415e581a6 100644 +index 4c8be9c8eb..f48207dad5 100644 --- a/arch/arm/dts/stm32mp157a-dk1.dts +++ b/arch/arm/dts/stm32mp157a-dk1.dts @@ -7,6 +7,7 @@ @@ -3501,23 +7829,26 @@ index d03d4cd260..f415e581a6 100644 #include "stm32mp15-pinctrl.dtsi" #include "stm32mp15xxac-pinctrl.dtsi" #include "stm32mp15xx-dkx.dtsi" -@@ -16,8 +17,9 @@ +@@ -15,13 +16,6 @@ + model = "STMicroelectronics STM32MP157A-DK1 Discovery Board"; compatible = "st,stm32mp157a-dk1", "st,stm32mp157"; - aliases { +- aliases { - ethernet0 = ðernet0; - serial0 = &uart4; -+ serial1 = &usart3; -+ serial2 = &uart7; - }; - +- 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 new file mode 100644 -index 0000000000..f0761901a6 +index 0000000000..bbcd5053df --- /dev/null +++ b/arch/arm/dts/stm32mp157a-ed1-u-boot.dtsi -@@ -0,0 +1,228 @@ +@@ -0,0 +1,211 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright : STMicroelectronics 2018 @@ -3530,16 +7861,14 @@ index 0000000000..f0761901a6 +/ { + aliases { + i2c3 = &i2c4; -+ mmc0 = &sdmmc1; -+ mmc1 = &sdmmc2; + }; + + config { + 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>; ++ u-boot,mmc-env-partition = "u-boot-env"; ++ st,fastboot-gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ st,stm32prog-gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + }; + + led { @@ -3551,25 +7880,10 @@ index 0000000000..f0761901a6 + }; + }; + -+#ifdef CONFIG_STM32MP15x_STM32IMAGE ++#if defined(CONFIG_STM32MP15x_STM32IMAGE) || defined(CONFIG_SPL) + config { + u-boot,mmc-env-partition = "ssbl"; + }; -+ -+ /* only needed for boot with TF-A, witout FIP support */ -+ firmware { -+ optee { -+ compatible = "linaro,optee-tz"; -+ method = "smc"; -+ }; -+ }; -+ -+ reserved-memory { -+ optee@fe000000 { -+ reg = <0xfe000000 0x02000000>; -+ no-map; -+ }; -+ }; +#endif +}; + @@ -3786,10 +8100,10 @@ index 0000000000..0213ca5c17 +}; diff --git a/arch/arm/dts/stm32mp157a-ev1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-ev1-u-boot.dtsi new file mode 100644 -index 0000000000..0dd2243157 +index 0000000000..e18d71dbef --- /dev/null +++ b/arch/arm/dts/stm32mp157a-ev1-u-boot.dtsi -@@ -0,0 +1,62 @@ +@@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright : STMicroelectronics 2018 @@ -3851,13 +8165,12 @@ index 0000000000..0dd2243157 + clocks = <&rcc SAI4>, <&rcc PLL3_Q>, <&rcc PLL3_R>; +}; +#endif -+ diff --git a/arch/arm/dts/stm32mp157a-ev1.dts b/arch/arm/dts/stm32mp157a-ev1.dts new file mode 100644 -index 0000000000..11bd88a82f +index 0000000000..a96fbc8406 --- /dev/null +++ b/arch/arm/dts/stm32mp157a-ev1.dts -@@ -0,0 +1,88 @@ +@@ -0,0 +1,103 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -3873,23 +8186,27 @@ index 0000000000..11bd88a82f + compatible = "st,stm32mp157a-ev1", "st,stm32mp157a-ed1", "st,stm32mp157"; + + chosen { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; + stdout-path = "serial0:115200n8"; ++ ++ framebuffer { ++ compatible = "simple-framebuffer"; ++ clocks = <&rcc LTDC_PX>; ++ status = "disabled"; ++ }; + }; + + aliases { -+ serial0 = &uart4; -+ serial1 = &usart3; ++ ethernet0 = ðernet0; + }; -+}; + -+<dc { -+ status = "okay"; -+ -+ port { -+ ltdc_ep0_out: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&dsi_in>; -+ }; ++ panel_backlight: panel-backlight { ++ compatible = "gpio-backlight"; ++ gpios = <&gpiod 13 GPIO_ACTIVE_LOW>; ++ default-on; ++ status = "okay"; + }; +}; + @@ -3946,11 +8263,56 @@ index 0000000000..11bd88a82f + interrupt-parent = <&stmfx_pinctrl>; + }; +}; ++ ++<dc { ++ status = "okay"; ++ ++ port { ++ ltdc_ep0_out: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&dsi_in>; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp157a-icore-stm32mp1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-icore-stm32mp1-u-boot.dtsi +index d62c24d4ce..6e02b966cf 100644 +--- a/arch/arm/dts/stm32mp157a-icore-stm32mp1-u-boot.dtsi ++++ b/arch/arm/dts/stm32mp157a-icore-stm32mp1-u-boot.dtsi +@@ -53,6 +53,7 @@ + u-boot,dm-pre-reloc; + }; + ++#ifndef CONFIG_TFABOOT + &rcc { + st,clksrc = < + CLK_MPU_PLL1P +@@ -144,3 +145,4 @@ + u-boot,dm-pre-reloc; + }; + }; ++#endif +diff --git a/arch/arm/dts/stm32mp157a-microgea-stm32mp1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-microgea-stm32mp1-u-boot.dtsi +index 836df6f746..b7c6d3e821 100644 +--- a/arch/arm/dts/stm32mp157a-microgea-stm32mp1-u-boot.dtsi ++++ b/arch/arm/dts/stm32mp157a-microgea-stm32mp1-u-boot.dtsi +@@ -25,6 +25,7 @@ + u-boot,dm-pre-reloc; + }; + ++#ifndef CONFIG_TFABOOT + &rcc { + st,clksrc = < + CLK_MPU_PLL1P +@@ -116,3 +117,4 @@ + u-boot,dm-pre-reloc; + }; + }; ++#endif diff --git a/arch/arm/dts/stm32mp157c-dk2.dts b/arch/arm/dts/stm32mp157c-dk2.dts -index 9a8a26710a..1c894f288c 100644 +index 2bc92ef3ae..a46941d6f7 100644 --- a/arch/arm/dts/stm32mp157c-dk2.dts +++ b/arch/arm/dts/stm32mp157c-dk2.dts -@@ -11,24 +11,35 @@ +@@ -11,21 +11,32 @@ #include "stm32mp15-pinctrl.dtsi" #include "stm32mp15xxac-pinctrl.dtsi" #include "stm32mp15xx-dkx.dtsi" @@ -3962,33 +8324,40 @@ index 9a8a26710a..1c894f288c 100644 aliases { - ethernet0 = ðernet0; - serial0 = &uart4; -+ serial1 = &usart3; -+ serial2 = &uart7; -+ serial3 = &usart2; +- serial0 = &uart4; +- serial1 = &usart3; +- serial2 = &uart7; + serial3 = &usart2; }; chosen { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; stdout-path = "serial0:115200n8"; - }; ++ ++ framebuffer { ++ compatible = "simple-framebuffer"; ++ clocks = <&rcc LTDC_PX>; ++ status = "disabled"; ++ }; ++ }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&gpioh 4 GPIO_ACTIVE_LOW>; -+ }; -+}; -+ -+&cryp1 { -+ status = "okay"; + }; }; +@@ -35,7 +46,6 @@ + &dsi { status = "okay"; - phy-dsi-supply = <®18>; ports { port@0 { -@@ -46,7 +57,7 @@ +@@ -53,7 +63,7 @@ }; }; @@ -3997,39 +8366,20 @@ index 9a8a26710a..1c894f288c 100644 compatible = "orisetech,otm8009a"; reg = <0>; reset-gpios = <&gpioe 4 GPIO_ACTIVE_LOW>; -@@ -62,6 +73,18 @@ - }; - - &i2c1 { -+ touchscreen@2a { -+ compatible = "focaltech,ft6236"; -+ reg = <0x2a>; -+ interrupts = <2 2>; -+ interrupt-parent = <&gpiof>; -+ interrupt-controller; -+ touchscreen-size-x = <480>; -+ touchscreen-size-y = <800>; -+ panel = <&panel_otm8009a>; -+ vcc-supply = <&v3v3>; -+ status = "okay"; -+ }; - touchscreen@38 { - compatible = "focaltech,ft6236"; - reg = <0x38>; -@@ -70,6 +93,8 @@ +@@ -77,6 +87,9 @@ interrupt-controller; touchscreen-size-x = <480>; touchscreen-size-y = <800>; + panel = <&panel_otm8009a>; + vcc-supply = <&v3v3>; ++ iovcc-supply = <&v3v3>; status = "okay"; }; }; -@@ -84,3 +109,49 @@ - }; +@@ -92,10 +105,48 @@ }; }; -+ + +&rtc { + st,lsco = ; + pinctrl-0 = <&rtc_out2_rmp_pins_a>; @@ -4059,11 +8409,12 @@ index 9a8a26710a..1c894f288c 100644 +}; + +/* Bluetooth */ -+&usart2 { -+ pinctrl-names = "default", "sleep", "idle"; -+ pinctrl-0 = <&usart2_pins_c>; -+ pinctrl-1 = <&usart2_sleep_pins_c>; -+ pinctrl-2 = <&usart2_idle_pins_c>; + &usart2 { + pinctrl-names = "default", "sleep", "idle"; + pinctrl-0 = <&usart2_pins_c>; + pinctrl-1 = <&usart2_sleep_pins_c>; + pinctrl-2 = <&usart2_idle_pins_c>; +- status = "disabled"; + uart-has-rtscts; + status = "okay"; + @@ -4074,12 +8425,12 @@ index 9a8a26710a..1c894f288c 100644 + vbat-supply = <&v3v3>; + vddio-supply = <&v3v3>; + }; -+}; + }; diff --git a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi -index f3002e995b..44a689bbec 100644 +index 408abaf52f..44a689bbec 100644 --- a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi -@@ -3,217 +3,4 @@ +@@ -3,224 +3,4 @@ * Copyright : STMicroelectronics 2018 */ @@ -4090,18 +8441,24 @@ index f3002e995b..44a689bbec 100644 -/ { - aliases { - i2c3 = &i2c4; -- mmc0 = &sdmmc1; -- mmc1 = &sdmmc2; - }; - - config { - u-boot,boot-led = "heartbeat"; - u-boot,error-led = "error"; -- u-boot,mmc-env-partition = "ssbl"; -- st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; -- st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; +- u-boot,mmc-env-partition = "fip"; +- st,fastboot-gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; +- st,stm32prog-gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; - }; - +-#if defined(CONFIG_STM32MP15x_STM32IMAGE) || defined(CONFIG_SPL) +- config { +- u-boot,mmc-env-partition = "ssbl"; +- }; +-#endif +- +-#ifdef CONFIG_STM32MP15x_STM32IMAGE +- /* only needed for boot with TF-A, witout FIP support */ - firmware { - optee { - compatible = "linaro,optee-tz"; @@ -4115,6 +8472,7 @@ index f3002e995b..44a689bbec 100644 - no-map; - }; - }; +-#endif - - led { - red { @@ -4299,7 +8657,7 @@ index f3002e995b..44a689bbec 100644 -}; +#include "stm32mp157a-ed1-u-boot.dtsi" diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts -index 072d646379..d2c24803b9 100644 +index 6e89f88a17..d2c24803b9 100644 --- a/arch/arm/dts/stm32mp157c-ed1.dts +++ b/arch/arm/dts/stm32mp157c-ed1.dts @@ -1,7 +1,7 @@ @@ -4322,7 +8680,7 @@ index 072d646379..d2c24803b9 100644 / { model = "STMicroelectronics STM32MP157C eval daughter"; -@@ -20,360 +19,18 @@ +@@ -20,389 +19,18 @@ stdout-path = "serial0:115200n8"; }; @@ -4339,10 +8697,8 @@ index 072d646379..d2c24803b9 100644 - mcuram2: mcuram2@10000000 { - compatible = "shared-dma-pool"; - reg = <0x10000000 0x40000>; -+ gpu_reserved: gpu@f6000000 { -+ reg = <0xf6000000 0x8000000>; - no-map; - }; +- no-map; +- }; - - vdev0vring0: vdev0vring0@10040000 { - compatible = "shared-dma-pool"; @@ -4376,9 +8732,11 @@ index 072d646379..d2c24803b9 100644 - - gpu_reserved: gpu@e8000000 { - reg = <0xe8000000 0x8000000>; -- no-map; -- }; -- }; ++ gpu_reserved: gpu@f6000000 { ++ reg = <0xf6000000 0x8000000>; + no-map; + }; + }; - - aliases { - serial0 = &uart4; @@ -4397,6 +8755,14 @@ index 072d646379..d2c24803b9 100644 - states = <1800000 0x1>, - <2900000 0x0>; - }; +- +- vin: vin { +- compatible = "regulator-fixed"; +- regulator-name = "vin"; +- regulator-min-microvolt = <5000000>; +- regulator-max-microvolt = <5000000>; +- regulator-always-on; +- }; -}; - -&adc { @@ -4423,6 +8789,14 @@ index 072d646379..d2c24803b9 100644 - cpu-supply = <&vddcore>; -}; - +-&crc1 { +- status = "okay"; + }; + + &cryp1 { + status = "okay"; + }; + -&dac { - pinctrl-names = "default"; - pinctrl-0 = <&dac_ch1_pins_a &dac_ch2_pins_a>; @@ -4433,18 +8807,21 @@ index 072d646379..d2c24803b9 100644 - }; - dac2: dac@2 { - status = "okay"; - }; - }; - +- }; +-}; +- -&dts { -+&cryp1 { - status = "okay"; - }; - +- status = "okay"; +-}; +- &gpu { contiguous-area = <&gpu_reserved>; }; - +-&hash1 { +- status = "okay"; +-}; +- -&i2c4 { - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&i2c4_pins_a>; @@ -4467,11 +8844,18 @@ index 072d646379..d2c24803b9 100644 - - regulators { - compatible = "st,stpmic1-regulators"; +- buck1-supply = <&vin>; +- buck2-supply = <&vin>; +- buck3-supply = <&vin>; +- buck4-supply = <&vin>; - ldo1-supply = <&v3v3>; - ldo2-supply = <&v3v3>; - ldo3-supply = <&vdd_ddr>; +- ldo4-supply = <&vin>; - ldo5-supply = <&v3v3>; - ldo6-supply = <&v3v3>; +- vref_ddr-supply = <&vin>; +- boost-supply = <&vin>; - pwr_sw1-supply = <&bst_out>; - pwr_sw2-supply = <&bst_out>; - @@ -4670,8 +9054,10 @@ index 072d646379..d2c24803b9 100644 -}; - -&uart4 { -- pinctrl-names = "default"; +- pinctrl-names = "default", "sleep", "idle"; - pinctrl-0 = <&uart4_pins_a>; +- pinctrl-1 = <&uart4_sleep_pins_a>; +- pinctrl-2 = <&uart4_idle_pins_a>; - status = "okay"; -}; - @@ -4744,10 +9130,10 @@ index ec60486f41..cc028066ec 100644 - +#include "stm32mp157a-ev1-u-boot.dtsi" diff --git a/arch/arm/dts/stm32mp157c-ev1.dts b/arch/arm/dts/stm32mp157c-ev1.dts -index 46f81ce92e..e84897ef44 100644 +index 5c5b1ddf7b..17434d903f 100644 --- a/arch/arm/dts/stm32mp157c-ev1.dts +++ b/arch/arm/dts/stm32mp157c-ev1.dts -@@ -1,13 +1,12 @@ +@@ -1,69 +1,27 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright (C) STMicroelectronics 2017 - All Rights Reserved @@ -4764,10 +9150,18 @@ index 46f81ce92e..e84897ef44 100644 / { model = "STMicroelectronics STM32MP157C eval daughter on eval mother"; -@@ -19,89 +18,30 @@ + compatible = "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", "st,stm32mp157"; - aliases { - serial0 = &uart4; + chosen { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; + stdout-path = "serial0:115200n8"; +- }; +- +- aliases { +- serial0 = &uart4; +- serial1 = &usart3; - ethernet0 = ðernet0; - }; - @@ -4778,7 +9172,7 @@ index 46f81ce92e..e84897ef44 100644 - clock-frequency = <24000000>; - }; - }; -- + - joystick { - compatible = "gpio-keys"; - pinctrl-0 = <&joystick_pins>; @@ -4812,15 +9206,14 @@ index 46f81ce92e..e84897ef44 100644 - linux,code = ; - interrupt-parent = <&stmfx_pinctrl>; - interrupts = <4 IRQ_TYPE_EDGE_RISING>; -- }; -- }; -- -- panel_backlight: panel-backlight { -- compatible = "gpio-backlight"; -- gpios = <&gpiod 13 GPIO_ACTIVE_LOW>; -- default-on; -- status = "okay"; -+ serial1 = &usart3; ++ framebuffer { ++ compatible = "simple-framebuffer"; ++ clocks = <&rcc LTDC_PX>; ++ status = "disabled"; + }; + }; + +@@ -75,35 +33,15 @@ }; }; @@ -4831,26 +9224,23 @@ index 46f81ce92e..e84897ef44 100644 -}; - -&dcmi { -+<dc { - status = "okay"; +- status = "okay"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&dcmi_pins_a>; - pinctrl-1 = <&dcmi_sleep_pins_a>; - - port { +- +- port { - dcmi_0: endpoint { - remote-endpoint = <&ov5640_0>; +- bus-type = <5>; - bus-width = <8>; - hsync-active = <0>; - vsync-active = <0>; - pclk-sample = <1>; -+ ltdc_ep0_out: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&dsi_in>; - }; - }; - }; - +- }; +- }; +-}; +- &dsi { - phy-dsi-supply = <®18>; + #address-cells = <1>; @@ -4864,7 +9254,7 @@ index 46f81ce92e..e84897ef44 100644 port@0 { reg = <0>; dsi_in: endpoint { -@@ -117,7 +57,7 @@ +@@ -119,7 +57,7 @@ }; }; @@ -4873,7 +9263,7 @@ index 46f81ce92e..e84897ef44 100644 compatible = "raydium,rm68200"; reg = <0>; reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>; -@@ -133,229 +73,16 @@ +@@ -135,106 +73,20 @@ }; }; @@ -4931,8 +9321,14 @@ index 46f81ce92e..e84897ef44 100644 - powerdown-gpios = <&stmfx_pinctrl 18 (GPIO_ACTIVE_HIGH | GPIO_PUSH_PULL)>; - reset-gpios = <&stmfx_pinctrl 19 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; - rotation = <180>; -- status = "okay"; -- ++ gt9147: goodix_ts@5d { ++ compatible = "goodix,gt9147"; ++ reg = <0x5d>; ++ panel = <&panel_dsi>; ++ pinctrl-0 = <&goodix_pins>; ++ pinctrl-names = "default"; + status = "okay"; + - port { - ov5640_0: endpoint { - remote-endpoint = <&dcmi_0>; @@ -4965,9 +9361,11 @@ index 46f81ce92e..e84897ef44 100644 - bias-pull-down; - }; - }; -- }; --}; -- ++ interrupts = <14 IRQ_TYPE_EDGE_RISING>; ++ interrupt-parent = <&stmfx_pinctrl>; + }; + }; + -&i2c5 { - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&i2c5_pins_a>; @@ -4977,16 +9375,13 @@ index 46f81ce92e..e84897ef44 100644 - status = "okay"; -}; - --<dc { -- status = "okay"; -- -- port { -- ltdc_ep0_out: endpoint@0 { -- reg = <0>; -- remote-endpoint = <&dsi_in>; -- }; -- }; --}; + <dc { + status = "okay"; + +@@ -245,133 +97,3 @@ + }; + }; + }; - -&m_can1 { - pinctrl-names = "default", "sleep"; @@ -5053,16 +9448,10 @@ index 46f81ce92e..e84897ef44 100644 - status = "okay"; - }; - timer@1 { -+ gt9147: goodix_ts@5d { -+ compatible = "goodix,gt9147"; -+ reg = <0x5d>; -+ panel = <&panel_dsi>; -+ pinctrl-0 = <&goodix_pins>; -+ pinctrl-names = "default"; - status = "okay"; +- status = "okay"; - }; -}; - +- -&timers8 { - /delete-property/dmas; - /delete-property/dma-names; @@ -5072,9 +9461,7 @@ index 46f81ce92e..e84897ef44 100644 - pinctrl-1 = <&pwm8_sleep_pins_a>; - pinctrl-names = "default", "sleep"; - status = "okay"; -+ interrupts = <14 IRQ_TYPE_EDGE_RISING>; -+ interrupt-parent = <&stmfx_pinctrl>; - }; +- }; - timer@7 { - status = "okay"; - }; @@ -5095,6 +9482,20 @@ index 46f81ce92e..e84897ef44 100644 - }; -}; - +-&usart3 { +- pinctrl-names = "default", "sleep", "idle"; +- pinctrl-0 = <&usart3_pins_b>; +- pinctrl-1 = <&usart3_sleep_pins_b>; +- pinctrl-2 = <&usart3_idle_pins_b>; +- /* +- * HW flow control USART3_RTS is optional, and isn't default wired to +- * the connector. SB23 needs to be soldered in order to use it, and R77 +- * (ETH_CLK) should be removed. +- */ +- uart-has-rtscts; +- status = "disabled"; +-}; +- -&usbh_ehci { - phys = <&usbphyc_port0>; - status = "okay"; @@ -5110,9 +9511,9 @@ index 46f81ce92e..e84897ef44 100644 - -&usbphyc { - status = "okay"; - }; +-}; diff --git a/arch/arm/dts/stm32mp157c-odyssey-som-u-boot.dtsi b/arch/arm/dts/stm32mp157c-odyssey-som-u-boot.dtsi -index 6be728846e..042656a773 100644 +index 4ff848350d..8ae679bf90 100644 --- a/arch/arm/dts/stm32mp157c-odyssey-som-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157c-odyssey-som-u-boot.dtsi @@ -13,9 +13,11 @@ @@ -5135,8 +9536,8 @@ index 6be728846e..042656a773 100644 &rcc { st,clksrc = < CLK_MPU_PLL1P -@@ -123,3 +126,4 @@ - u-boot,dm-pre-reloc; +@@ -144,3 +147,4 @@ + u-boot,dm-spl; }; }; +#endif @@ -5154,10 +9555,10 @@ index 0000000000..4f9b7a99ce +#include "stm32mp157a-dk1-u-boot.dtsi" diff --git a/arch/arm/dts/stm32mp157d-dk1.dts b/arch/arm/dts/stm32mp157d-dk1.dts new file mode 100644 -index 0000000000..bcc012cfff +index 0000000000..99a4e0f9c4 --- /dev/null +++ b/arch/arm/dts/stm32mp157d-dk1.dts -@@ -0,0 +1,28 @@ +@@ -0,0 +1,26 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -5177,9 +9578,7 @@ index 0000000000..bcc012cfff + compatible = "st,stm32mp157d-dk1", "st,stm32mp157"; + + aliases { -+ serial0 = &uart4; -+ serial1 = &usart3; -+ serial2 = &uart7; ++ ethernet0 = ðernet0; + }; + + chosen { @@ -5200,10 +9599,10 @@ index 0000000000..70d9afc6b9 +#include "stm32mp157a-ed1-u-boot.dtsi" diff --git a/arch/arm/dts/stm32mp157d-ed1.dts b/arch/arm/dts/stm32mp157d-ed1.dts new file mode 100644 -index 0000000000..5aa383d3b5 +index 0000000000..18d8074376 --- /dev/null +++ b/arch/arm/dts/stm32mp157d-ed1.dts -@@ -0,0 +1,33 @@ +@@ -0,0 +1,32 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -5235,7 +9634,6 @@ index 0000000000..5aa383d3b5 + +&gpu { + contiguous-area = <&gpu_reserved>; -+ status = "okay"; +}; diff --git a/arch/arm/dts/stm32mp157d-ev1-u-boot.dtsi b/arch/arm/dts/stm32mp157d-ev1-u-boot.dtsi new file mode 100644 @@ -5251,10 +9649,10 @@ index 0000000000..77168a4cdb +#include "stm32mp157a-ev1-u-boot.dtsi" diff --git a/arch/arm/dts/stm32mp157d-ev1.dts b/arch/arm/dts/stm32mp157d-ev1.dts new file mode 100644 -index 0000000000..5cb08c7079 +index 0000000000..f19ca6ada2 --- /dev/null +++ b/arch/arm/dts/stm32mp157d-ev1.dts -@@ -0,0 +1,88 @@ +@@ -0,0 +1,103 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -5270,23 +9668,27 @@ index 0000000000..5cb08c7079 + compatible = "st,stm32mp157d-ev1", "st,stm32mp157d-ed1", "st,stm32mp157"; + + chosen { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; + stdout-path = "serial0:115200n8"; ++ ++ framebuffer { ++ compatible = "simple-framebuffer"; ++ clocks = <&rcc LTDC_PX>; ++ status = "disabled"; ++ }; + }; + + aliases { -+ serial0 = &uart4; -+ serial1 = &usart3; ++ ethernet0 = ðernet0; + }; -+}; + -+<dc { -+ status = "okay"; -+ -+ port { -+ ltdc_ep0_out: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&dsi_in>; -+ }; ++ panel_backlight: panel-backlight { ++ compatible = "gpio-backlight"; ++ gpios = <&gpiod 13 GPIO_ACTIVE_LOW>; ++ default-on; ++ status = "okay"; + }; +}; + @@ -5343,6 +9745,17 @@ index 0000000000..5cb08c7079 + interrupt-parent = <&stmfx_pinctrl>; + }; +}; ++ ++<dc { ++ status = "okay"; ++ ++ port { ++ ltdc_ep0_out: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&dsi_in>; ++ }; ++ }; ++}; diff --git a/arch/arm/dts/stm32mp157f-dk2-u-boot.dtsi b/arch/arm/dts/stm32mp157f-dk2-u-boot.dtsi new file mode 100644 index 0000000000..1bed79cdf4 @@ -5357,10 +9770,10 @@ index 0000000000..1bed79cdf4 +#include "stm32mp157c-dk2-u-boot.dtsi" diff --git a/arch/arm/dts/stm32mp157f-dk2.dts b/arch/arm/dts/stm32mp157f-dk2.dts new file mode 100644 -index 0000000000..15a397c4cf +index 0000000000..3cd2e73034 --- /dev/null +++ b/arch/arm/dts/stm32mp157f-dk2.dts -@@ -0,0 +1,157 @@ +@@ -0,0 +1,152 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -5381,14 +9794,20 @@ index 0000000000..15a397c4cf + compatible = "st,stm32mp157f-dk2", "st,stm32mp157"; + + aliases { -+ serial0 = &uart4; -+ serial1 = &usart3; -+ serial2 = &uart7; + serial3 = &usart2; + }; + + chosen { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; + stdout-path = "serial0:115200n8"; ++ ++ framebuffer { ++ compatible = "simple-framebuffer"; ++ clocks = <&rcc LTDC_PX>; ++ status = "disabled"; ++ }; + }; + + wifi_pwrseq: wifi-pwrseq { @@ -5436,18 +9855,6 @@ index 0000000000..15a397c4cf +}; + +&i2c1 { -+ touchscreen@2a { -+ compatible = "focaltech,ft6236"; -+ reg = <0x2a>; -+ interrupts = <2 2>; -+ interrupt-parent = <&gpiof>; -+ interrupt-controller; -+ touchscreen-size-x = <480>; -+ touchscreen-size-y = <800>; -+ panel = <&panel_otm8009a>; -+ vcc-supply = <&v3v3>; -+ status = "okay"; -+ }; + touchscreen@38 { + compatible = "focaltech,ft6236"; + reg = <0x38>; @@ -5458,6 +9865,7 @@ index 0000000000..15a397c4cf + touchscreen-size-y = <800>; + panel = <&panel_otm8009a>; + vcc-supply = <&v3v3>; ++ iovcc-supply = <&v3v3>; + status = "okay"; + }; +}; @@ -5532,10 +9940,10 @@ index 0000000000..2b8d2afd55 +#include "stm32mp157c-ed1-u-boot.dtsi" diff --git a/arch/arm/dts/stm32mp157f-ed1.dts b/arch/arm/dts/stm32mp157f-ed1.dts new file mode 100644 -index 0000000000..29c6833e28 +index 0000000000..bb3f8dfdcb --- /dev/null +++ b/arch/arm/dts/stm32mp157f-ed1.dts -@@ -0,0 +1,37 @@ +@@ -0,0 +1,36 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -5571,7 +9979,6 @@ index 0000000000..29c6833e28 + +&gpu { + contiguous-area = <&gpu_reserved>; -+ status = "okay"; +}; diff --git a/arch/arm/dts/stm32mp157f-ev1-u-boot.dtsi b/arch/arm/dts/stm32mp157f-ev1-u-boot.dtsi new file mode 100644 @@ -5587,10 +9994,10 @@ index 0000000000..0e415a141d +#include "stm32mp157c-ev1-u-boot.dtsi" diff --git a/arch/arm/dts/stm32mp157f-ev1.dts b/arch/arm/dts/stm32mp157f-ev1.dts new file mode 100644 -index 0000000000..6fe600f813 +index 0000000000..b831f04532 --- /dev/null +++ b/arch/arm/dts/stm32mp157f-ev1.dts -@@ -0,0 +1,89 @@ +@@ -0,0 +1,99 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -5600,31 +10007,30 @@ index 0000000000..6fe600f813 + +#include "stm32mp157f-ed1.dts" +#include "stm32mp15xx-evx.dtsi" -+#include + +/ { + model = "STMicroelectronics STM32MP157F eval daughter on eval mother"; + compatible = "st,stm32mp157f-ev1", "st,stm32mp157f-ed1", "st,stm32mp157"; + + chosen { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; + stdout-path = "serial0:115200n8"; -+ }; + -+ aliases { -+ serial0 = &uart4; -+ serial1 = &usart3; -+ }; -+}; -+ -+<dc { -+ status = "okay"; -+ -+ port { -+ ltdc_ep0_out: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&dsi_in>; ++ framebuffer { ++ compatible = "simple-framebuffer"; ++ clocks = <&rcc LTDC_PX>; ++ status = "disabled"; + }; + }; ++ ++ panel_backlight: panel-backlight { ++ compatible = "gpio-backlight"; ++ gpios = <&gpiod 13 GPIO_ACTIVE_LOW>; ++ default-on; ++ status = "okay"; ++ }; +}; + +&dsi { @@ -5680,6 +10086,17 @@ index 0000000000..6fe600f813 + interrupt-parent = <&stmfx_pinctrl>; + }; +}; ++ ++<dc { ++ status = "okay"; ++ ++ port { ++ ltdc_ep0_out: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&dsi_in>; ++ }; ++ }; ++}; diff --git a/arch/arm/dts/stm32mp15xa.dtsi b/arch/arm/dts/stm32mp15xa.dtsi new file mode 100644 index 0000000000..5ed7e594f4 @@ -5700,7 +10117,7 @@ index 0000000000..5ed7e594f4 + }; +}; diff --git a/arch/arm/dts/stm32mp15xc.dtsi b/arch/arm/dts/stm32mp15xc.dtsi -index b06a55a2fa..adc1568a72 100644 +index b06a55a2fa..67d38d1333 100644 --- a/arch/arm/dts/stm32mp15xc.dtsi +++ b/arch/arm/dts/stm32mp15xc.dtsi @@ -4,14 +4,16 @@ @@ -5717,8 +10134,8 @@ index b06a55a2fa..adc1568a72 100644 interrupts = ; - clocks = <&rcc CRYP1>; - resets = <&rcc CRYP1_R>; -+ clocks = <&scmi0_clk CK_SCMI0_CRYP1>; -+ resets = <&scmi0_reset RST_SCMI0_CRYP1>; ++ clocks = <&scmi_clk CK_SCMI_CRYP1>; ++ resets = <&scmi_reset RST_SCMI_CRYP1>; status = "disabled"; }; }; @@ -5772,7 +10189,7 @@ index 0000000000..e2f8b1297c +}; diff --git a/arch/arm/dts/stm32mp15xf.dtsi b/arch/arm/dts/stm32mp15xf.dtsi new file mode 100644 -index 0000000000..77f50b9bda +index 0000000000..f4a77bf9a4 --- /dev/null +++ b/arch/arm/dts/stm32mp15xf.dtsi @@ -0,0 +1,20 @@ @@ -5790,17 +10207,33 @@ index 0000000000..77f50b9bda + compatible = "st,stm32mp1-cryp"; + reg = <0x54001000 0x400>; + interrupts = ; -+ clocks = <&scmi0_clk CK_SCMI0_CRYP1>; -+ resets = <&scmi0_reset RST_SCMI0_CRYP1>; ++ clocks = <&scmi_clk CK_SCMI_CRYP1>; ++ resets = <&scmi_reset RST_SCMI_CRYP1>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi -index 92345b7ba3..c3727a0c4d 100644 +index 11bc247065..1ec4702585 100644 --- a/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi +++ b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi -@@ -171,6 +171,7 @@ +@@ -50,15 +50,6 @@ + }; + }; + +-&gpiof { +- snor-nwp { +- gpio-hog; +- gpios = <7 0>; +- output-high; +- line-name = "spi-nor-nwp"; +- }; +-}; +- + &i2c4 { + u-boot,dm-pre-reloc; + }; +@@ -131,6 +122,7 @@ }; }; @@ -5808,7 +10241,7 @@ index 92345b7ba3..c3727a0c4d 100644 &rcc { st,clksrc = < CLK_MPU_PLL1P -@@ -262,6 +263,7 @@ +@@ -222,9 +214,14 @@ u-boot,dm-pre-reloc; }; }; @@ -5816,11 +10249,62 @@ index 92345b7ba3..c3727a0c4d 100644 &sdmmc1 { u-boot,dm-spl; ++ st,use-ckin; ++ st,cmd-gpios = <&gpiod 2 0>; ++ st,ck-gpios = <&gpioc 12 0>; ++ st,ckin-gpios = <&gpioe 4 0>; + }; + + &sdmmc1_b4_pins_a { +diff --git a/arch/arm/dts/stm32mp15xx-dhcor-avenger96-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcor-avenger96-u-boot.dtsi +index 8b275e4950..c96eba99c5 100644 +--- a/arch/arm/dts/stm32mp15xx-dhcor-avenger96-u-boot.dtsi ++++ b/arch/arm/dts/stm32mp15xx-dhcor-avenger96-u-boot.dtsi +@@ -19,8 +19,23 @@ + }; + }; + ++ ++ðernet0 { ++ mdio0 { ++ ethernet-phy@7 { ++ reset-gpios = <&gpioz 2 GPIO_ACTIVE_LOW>; ++ reset-assert-us = <11000>; ++ reset-deassert-us = <1000>; ++ }; ++ }; ++}; ++ + &sdmmc1 { + u-boot,dm-spl; ++ st,use-ckin; ++ st,cmd-gpios = <&gpiod 2 0>; ++ st,ck-gpios = <&gpioc 12 0>; ++ st,ckin-gpios = <&gpioe 4 0>; + }; + + &sdmmc1_b4_pins_a { diff --git a/arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi -index 9d3db20876..e9c5e5adf2 100644 +index 9d3db20876..48a046ecc6 100644 --- a/arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi +++ b/arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi -@@ -70,6 +70,7 @@ +@@ -25,15 +25,6 @@ + u-boot,dm-spl; + }; + +-&gpiof { +- snor-nwp { +- gpio-hog; +- gpios = <7 0>; +- output-high; +- line-name = "spi-nor-nwp"; +- }; +-}; +- + &i2c4 { + u-boot,dm-pre-reloc; + }; +@@ -70,6 +61,7 @@ }; }; @@ -5828,17 +10312,16 @@ index 9d3db20876..e9c5e5adf2 100644 &rcc { st,clksrc = < CLK_MPU_PLL1P -@@ -161,3 +162,4 @@ +@@ -161,3 +153,4 @@ u-boot,dm-pre-reloc; }; }; +#endif -\ No newline at end of file diff --git a/arch/arm/dts/stm32mp15xx-dkx.dtsi b/arch/arm/dts/stm32mp15xx-dkx.dtsi -index d660dfb74e..acff8755d3 100644 +index 68987f64c5..d5abbfd510 100644 --- a/arch/arm/dts/stm32mp15xx-dkx.dtsi +++ b/arch/arm/dts/stm32mp15xx-dkx.dtsi -@@ -4,10 +4,16 @@ +@@ -4,10 +4,19 @@ * Author: Alexandre Torgue for STMicroelectronics. */ @@ -5850,90 +10333,119 @@ index d660dfb74e..acff8755d3 100644 / { + aliases { + ethernet0 = ðernet0; ++ serial0 = &uart4; ++ serial1 = &usart3; ++ serial2 = &uart7; + }; + memory@c0000000 { device_type = "memory"; reg = <0xc0000000 0x20000000>; -@@ -62,7 +68,7 @@ +@@ -42,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>; +@@ -58,6 +73,11 @@ + reg = <0xd4000000 0x4000000>; + no-map; + }; ++ ++ optee@de000000 { ++ reg = <0xde000000 0x2000000>; ++ no-map; ++ }; + }; led { - compatible = "gpio-leds"; -- blue { -+ led-blue { - label = "heartbeat"; - gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; -@@ -72,7 +78,7 @@ +@@ -70,9 +90,9 @@ + }; + }; - sound { +- sound { ++ sound: sound { compatible = "audio-graph-card"; - label = "STM32MP1-DK"; + label = "STM32MP15-DK"; routing = "Playback" , "MCLK", "Capture" , "MCLK", -@@ -80,6 +86,25 @@ - dais = <&sai2a_port &sai2b_port &i2s2_port>; - status = "okay"; - }; -+ -+ usb_phy_tuning: usb-phy-tuning { -+ st,hs-dc-level = <2>; -+ st,fs-rftime-tuning; -+ st,hs-rftime-reduction; -+ st,hs-current-trim = <15>; -+ st,hs-impedance-trim = <1>; -+ st,squelch-level = <3>; -+ st,hs-rx-offset = <2>; -+ st,no-lsfs-sc; -+ }; -+ -+ vin: vin { -+ compatible = "regulator-fixed"; -+ regulator-name = "vin"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-always-on; -+ }; - }; +@@ -92,11 +112,11 @@ &adc { -@@ -116,10 +141,6 @@ + pinctrl-names = "default"; +- pinctrl-0 = <&adc12_ain_pins_a>, <&adc12_usb_cc_pins_a>; ++ pinctrl-0 = <&adc12_usb_cc_pins_a>; + vdd-supply = <&vdd>; + vdda-supply = <&vdd>; + vref-supply = <&vrefbuf>; +- status = "disabled"; ++ status = "okay"; + adc1: adc@0 { + /* + * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in18 & in19. +@@ -105,13 +125,13 @@ + * Use arbitrary margin here (e.g. 5us). + */ + st,min-sample-time-nsecs = <5000>; +- /* AIN connector, USB Type-C CC1 & CC2 */ +- st,adc-channels = <0 1 6 13 18 19>; ++ /* USB Type-C CC1 & CC2 */ ++ st,adc-channels = <18 19>; + status = "okay"; + }; + adc2: adc@100 { +- /* AIN connector, USB Type-C CC1 & CC2 */ +- st,adc-channels = <0 1 2 6 18 19>; ++ /* USB Type-C CC1 & CC2 */ ++ st,adc-channels = <18 19>; + st,min-sample-time-nsecs = <5000>; + status = "okay"; + }; +@@ -124,20 +144,28 @@ + status = "okay"; + }; + ++&cpu0{ ++ cpu-supply = <&vddcore>; ++}; ++ ++&cpu1{ ++ cpu-supply = <&vddcore>; ++}; ++ + &crc1 { status = "okay"; }; -&dts { - status = "okay"; --}; -- - &cpu0{ - cpu-supply = <&vddcore>; - }; -@@ -128,6 +149,22 @@ - cpu-supply = <&vddcore>; - }; - -+&crc1 { -+ status = "okay"; -+}; -+ +&dma1 { + sram = <&dma_pool>; -+}; -+ + }; + +-&cpu0{ +- cpu-supply = <&vddcore>; +&dma2 { + sram = <&dma_pool>; -+}; -+ + }; + +-&cpu1{ +- cpu-supply = <&vddcore>; +&dts { + status = "okay"; -+}; -+ + }; + ðernet0 { - status = "okay"; - pinctrl-0 = <ðernet0_rgmii_pins_a>; -@@ -136,6 +173,8 @@ +@@ -148,6 +176,8 @@ phy-mode = "rgmii-id"; max-speed = <1000>; phy-handle = <&phy0>; @@ -5942,50 +10454,36 @@ index d660dfb74e..acff8755d3 100644 mdio0 { #address-cells = <1>; -@@ -151,6 +190,10 @@ - contiguous-area = <&gpu_reserved>; - }; +@@ -228,15 +258,15 @@ + cs42l51_tx_endpoint: endpoint@0 { + reg = <0>; + remote-endpoint = <&sai2a_endpoint>; +- frame-master; +- bitclock-master; ++ frame-master = <&cs42l51_tx_endpoint>; ++ bitclock-master = <&cs42l51_tx_endpoint>; + }; -+&hash1 { -+ status = "okay"; -+}; -+ - &i2c1 { - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&i2c1_pins_a>; -@@ -238,37 +281,52 @@ - /delete-property/dmas; - /delete-property/dma-names; - -- typec: stusb1600@28 { -+ stusb1600@28 { + cs42l51_rx_endpoint: endpoint@1 { + reg = <1>; + remote-endpoint = <&sai2b_endpoint>; +- frame-master; +- bitclock-master; ++ frame-master = <&cs42l51_rx_endpoint>; ++ bitclock-master = <&cs42l51_rx_endpoint>; + }; + }; + }; +@@ -257,7 +287,7 @@ + stusb1600@28 { compatible = "st,stusb1600"; reg = <0x28>; - interrupts = <11 IRQ_TYPE_EDGE_FALLING>; +- interrupts = <11 IRQ_TYPE_EDGE_FALLING>; ++ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&gpioi>; pinctrl-names = "default"; pinctrl-0 = <&stusb1600_pins_a>; -- - status = "okay"; -+ vdd-supply = <&vin>; - -- typec_con: connector { -+ connector { - compatible = "usb-c-connector"; - label = "USB-C"; -- power-role = "sink"; -- power-opmode = "default"; -+ power-role = "dual"; -+ typec-power-opmode = "default"; -+ -+ port { -+ con_usbotg_hs_ep: endpoint { -+ remote-endpoint = <&usbotg_hs_ep>; -+ }; -+ }; - }; - }; - +@@ -281,7 +311,7 @@ pmic: stpmic@33 { compatible = "st,stpmic1"; reg = <0x33>; @@ -5994,29 +10492,8 @@ index d660dfb74e..acff8755d3 100644 interrupt-controller; #interrupt-cells = <2>; status = "okay"; - - regulators { - compatible = "st,stpmic1-regulators"; -+ buck1-supply = <&vin>; -+ buck2-supply = <&vin>; -+ buck3-supply = <&vin>; -+ buck4-supply = <&vin>; - ldo1-supply = <&v3v3>; -+ ldo2-supply = <&vin>; - ldo3-supply = <&vdd_ddr>; -+ ldo4-supply = <&vin>; -+ ldo5-supply = <&vin>; - ldo6-supply = <&v3v3>; -+ vref_ddr-supply = <&vin>; -+ boost-supply = <&vin>; - pwr_sw1-supply = <&bst_out>; - pwr_sw2-supply = <&bst_out>; - -@@ -357,23 +415,24 @@ - vref_ddr: vref_ddr { - regulator-name = "vref_ddr"; +@@ -390,21 +420,21 @@ regulator-always-on; -+ regulator-over-current-protection; }; - bst_out: boost { @@ -6042,35 +10519,34 @@ index d660dfb74e..acff8755d3 100644 }; onkey { -@@ -391,6 +450,19 @@ - }; - }; +@@ -477,11 +507,12 @@ -+&i2c5 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&i2c5_pins_a>; -+ pinctrl-1 = <&i2c5_sleep_pins_a>; -+ i2c-scl-rising-time-ns = <185>; -+ i2c-scl-falling-time-ns = <20>; -+ clock-frequency = <400000>; -+ /* spare dmas for other usage */ -+ /delete-property/dmas; -+ /delete-property/dma-names; -+ status = "disabled"; -+}; -+ - &i2s2 { - clocks = <&rcc SPI2>, <&rcc SPI2_K>, <&rcc PLL3_Q>, <&rcc PLL3_R>; - clock-names = "pclk", "i2sclk", "x8k", "x11k"; -@@ -438,6 +510,7 @@ - mbox-names = "vq0", "vq1", "shutdown"; + &m4_rproc { + memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, +- <&vdev0vring1>, <&vdev0buffer>; +- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; +- mbox-names = "vq0", "vq1", "shutdown"; ++ <&vdev0vring1>, <&vdev0buffer>, <&mcu_rsc_table>; ++ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>; ++ mbox-names = "vq0", "vq1", "shutdown", "detach"; interrupt-parent = <&exti>; interrupts = <68 1>; + wakeup-source; status = "okay"; }; -@@ -465,8 +538,6 @@ +@@ -490,10 +521,6 @@ + vdd_3v3_usbfs-supply = <&vdd_usb>; + }; + +-&rng1 { +- status = "okay"; +-}; +- + &rtc { + status = "okay"; + }; +@@ -509,8 +536,6 @@ sai2a: audio-controller@4400b004 { #clock-cells = <0>; dma-names = "tx"; @@ -6079,7 +10555,7 @@ index d660dfb74e..acff8755d3 100644 status = "okay"; sai2a_port: port { -@@ -524,6 +595,27 @@ +@@ -568,6 +593,27 @@ status = "disabled"; }; @@ -6107,78 +10583,67 @@ index d660dfb74e..acff8755d3 100644 &timers1 { /* spare dmas for other usage */ /delete-property/dmas; -@@ -610,21 +702,50 @@ - }; - - &uart4 { -- pinctrl-names = "default"; -+ pinctrl-names = "default", "sleep", "idle"; +@@ -658,6 +704,8 @@ pinctrl-0 = <&uart4_pins_a>; -+ pinctrl-1 = <&uart4_sleep_pins_a>; -+ pinctrl-2 = <&uart4_idle_pins_a>; + pinctrl-1 = <&uart4_sleep_pins_a>; + pinctrl-2 = <&uart4_idle_pins_a>; + /delete-property/dmas; + /delete-property/dma-names; status = "okay"; }; -+&uart7 { -+ pinctrl-names = "default", "sleep", "idle"; -+ pinctrl-0 = <&uart7_pins_c>; -+ pinctrl-1 = <&uart7_sleep_pins_c>; -+ pinctrl-2 = <&uart7_idle_pins_c>; +@@ -666,6 +714,8 @@ + pinctrl-0 = <&uart7_pins_c>; + pinctrl-1 = <&uart7_sleep_pins_c>; + pinctrl-2 = <&uart7_idle_pins_c>; + /delete-property/dmas; + /delete-property/dma-names; -+ status = "disabled"; -+}; -+ -+&usart3 { -+ pinctrl-names = "default", "sleep", "idle"; -+ pinctrl-0 = <&usart3_pins_c>; -+ pinctrl-1 = <&usart3_sleep_pins_c>; -+ pinctrl-2 = <&usart3_idle_pins_c>; -+ uart-has-rtscts; -+ status = "disabled"; -+}; -+ - &usbh_ehci { - phys = <&usbphyc_port0>; - status = "okay"; + status = "disabled"; }; - &usbotg_hs { -- dr_mode = "peripheral"; - phys = <&usbphyc_port1 0>; - phy-names = "usb2-phy"; -+ usb-role-switch; - status = "okay"; -+ -+ port { -+ usbotg_hs_ep: endpoint { -+ remote-endpoint = <&con_usbotg_hs_ep>; -+ }; -+ }; - }; - - &usbphyc { -@@ -633,10 +754,12 @@ +@@ -702,10 +752,36 @@ &usbphyc_port0 { phy-supply = <&vdd_usb>; -+ st,phy-tuning = <&usb_phy_tuning>; ++ st,tune-hs-dc-level = <2>; ++ st,enable-fs-rftime-tuning; ++ st,enable-hs-rftime-reduction; ++ st,trim-hs-current = <15>; ++ st,trim-hs-impedance = <1>; ++ st,tune-squelch-level = <3>; ++ st,tune-hs-rx-offset = <2>; ++ st,no-lsfs-sc; ++ ++ /* ++ * 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 { phy-supply = <&vdd_usb>; -+ st,phy-tuning = <&usb_phy_tuning>; ++ st,tune-hs-dc-level = <2>; ++ st,enable-fs-rftime-tuning; ++ st,enable-hs-rftime-reduction; ++ st,trim-hs-current = <15>; ++ st,trim-hs-impedance = <1>; ++ st,tune-squelch-level = <3>; ++ st,tune-hs-rx-offset = <2>; ++ st,no-lsfs-sc; }; &vrefbuf { diff --git a/arch/arm/dts/stm32mp15xx-edx.dtsi b/arch/arm/dts/stm32mp15xx-edx.dtsi new file mode 100644 -index 0000000000..3662f449de +index 0000000000..db0f911353 --- /dev/null +++ b/arch/arm/dts/stm32mp15xx-edx.dtsi -@@ -0,0 +1,413 @@ +@@ -0,0 +1,419 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2017 - All Rights Reserved @@ -6225,6 +10690,12 @@ index 0000000000..3662f449de + 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>; @@ -6236,6 +10707,11 @@ index 0000000000..3662f449de + reg = <0x38000000 0x10000>; + no-map; + }; ++ ++ optee@fe000000 { ++ reg = <0xfe000000 0x2000000>; ++ no-map; ++ }; + }; + + aliases { @@ -6450,7 +10926,6 @@ index 0000000000..3662f449de + vref_ddr: vref_ddr { + regulator-name = "vref_ddr"; + regulator-always-on; -+ regulator-over-current-protection; + }; + + bst_out: boost { @@ -6496,9 +10971,9 @@ index 0000000000..3662f449de + +&m4_rproc { + memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, -+ <&vdev0vring1>, <&vdev0buffer>; -+ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; -+ mbox-names = "vq0", "vq1", "shutdown"; ++ <&vdev0vring1>, <&vdev0buffer>, <&mcu_rsc_table>; ++ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>; ++ mbox-names = "vq0", "vq1", "shutdown", "detach"; + interrupt-parent = <&exti>; + interrupts = <68 1>; + wakeup-source; @@ -6510,10 +10985,6 @@ index 0000000000..3662f449de + vdd_3v3_usbfs-supply = <&vdd_usb>; +}; + -+&rng1 { -+ status = "okay"; -+}; -+ +&rtc { + status = "okay"; +}; @@ -6594,10 +11065,10 @@ index 0000000000..3662f449de +}; diff --git a/arch/arm/dts/stm32mp15xx-evx.dtsi b/arch/arm/dts/stm32mp15xx-evx.dtsi new file mode 100644 -index 0000000000..47a2c8e5ea +index 0000000000..fa453817aa --- /dev/null +++ b/arch/arm/dts/stm32mp15xx-evx.dtsi -@@ -0,0 +1,686 @@ +@@ -0,0 +1,690 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2017 - All Rights Reserved @@ -6610,6 +11081,7 @@ index 0000000000..47a2c8e5ea +/ { + aliases { + ethernet0 = ðernet0; ++ serial1 = &usart3; + }; + + clocks { @@ -6622,7 +11094,6 @@ index 0000000000..47a2c8e5ea + + joystick { + compatible = "gpio-keys"; -+ #size-cells = <0>; + pinctrl-0 = <&joystick_pins>; + pinctrl-names = "default"; + button-0 { @@ -6657,13 +11128,6 @@ index 0000000000..47a2c8e5ea + }; + }; + -+ panel_backlight: panel-backlight { -+ compatible = "gpio-backlight"; -+ gpios = <&gpiod 13 GPIO_ACTIVE_LOW>; -+ default-on; -+ status = "okay"; -+ }; -+ + spdif_out: spdif-out { + #sound-dai-cells = <0>; + compatible = "linux,spdif-dit"; @@ -6688,7 +11152,7 @@ index 0000000000..47a2c8e5ea + }; + }; + -+ sound { ++ sound: sound { + compatible = "audio-graph-card"; + label = "STM32MP15-EV"; + routing = @@ -6754,16 +11218,6 @@ index 0000000000..47a2c8e5ea + }; + }; + -+ usb_phy_tuning: usb-phy-tuning { -+ st,hs-dc-level = <2>; -+ st,fs-rftime-tuning; -+ st,hs-rftime-reduction; -+ st,hs-current-trim = <15>; -+ st,hs-impedance-trim = <1>; -+ st,squelch-level = <3>; -+ st,hs-rx-offset = <2>; -+ st,no-lsfs-sc; -+ }; +}; + +&cec { @@ -6906,8 +11360,6 @@ index 0000000000..47a2c8e5ea + phy-mode = "rgmii-id"; + max-speed = <1000>; + phy-handle = <&phy0>; -+ nvmem-cells = <ðernet_mac_address>; -+ nvmem-cell-names = "mac-address"; + + mdio0 { + #address-cells = <1>; @@ -7277,13 +11729,36 @@ index 0000000000..47a2c8e5ea +}; + +&usbphyc_port0 { -+ st,phy-tuning = <&usb_phy_tuning>; -+ vbus-supply = <&vbus_sw>; ++ st,tune-hs-dc-level = <2>; ++ st,enable-fs-rftime-tuning; ++ st,enable-hs-rftime-reduction; ++ st,trim-hs-current = <15>; ++ st,trim-hs-impedance = <1>; ++ st,tune-squelch-level = <3>; ++ st,tune-hs-rx-offset = <2>; ++ st,no-lsfs-sc; ++ ++ /* ++ * 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 { -+ st,phy-tuning = <&usb_phy_tuning>; ++ st,tune-hs-dc-level = <2>; ++ st,enable-fs-rftime-tuning; ++ st,enable-hs-rftime-reduction; ++ st,trim-hs-current = <15>; ++ st,trim-hs-impedance = <1>; ++ st,tune-squelch-level = <3>; ++ st,tune-hs-rx-offset = <2>; ++ st,no-lsfs-sc; +}; -- -2.17.1 +2.25.1 diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0005-ARM-v2020.10-stm32mp-r1-CONFIG.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0005-ARM-v2020.10-stm32mp-r1-CONFIG.patch deleted file mode 100644 index b115b74..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0005-ARM-v2020.10-stm32mp-r1-CONFIG.patch +++ /dev/null @@ -1,165 +0,0 @@ -From b5b052fb24a4d593ad0e3facfd365e1d33e4083f Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Tue, 16 Mar 2021 08:14:57 +0100 -Subject: [PATCH 5/5] ARM v2020.10-stm32mp-r1 CONFIG - ---- - configs/sandbox_defconfig | 4 ++++ - configs/stm32mp15_basic_defconfig | 6 ++++-- - configs/stm32mp15_dhcom_basic_defconfig | 1 + - configs/stm32mp15_dhcor_basic_defconfig | 1 + - configs/stm32mp15_trusted_defconfig | 12 ++++++++---- - 5 files changed, 18 insertions(+), 6 deletions(-) - -diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig -index 6e9f029cc9..a2ebb3c971 100644 ---- a/configs/sandbox_defconfig -+++ b/configs/sandbox_defconfig -@@ -122,6 +122,7 @@ CONFIG_BUTTON=y - CONFIG_BUTTON_GPIO=y - CONFIG_CLK=y - CONFIG_CLK_COMPOSITE_CCF=y -+CONFIG_CLK_SCMI=y - CONFIG_SANDBOX_CLK_CCF=y - CONFIG_CPU=y - CONFIG_DM_DEMO=y -@@ -132,6 +133,8 @@ CONFIG_BOARD_SANDBOX=y - CONFIG_DMA=y - CONFIG_DMA_CHANNELS=y - CONFIG_SANDBOX_DMA=y -+CONFIG_FIRMWARE=y -+CONFIG_SCMI_FIRMWARE=y - CONFIG_GPIO_HOG=y - CONFIG_DM_GPIO_LOOKUP_LABEL=y - CONFIG_PM8916_GPIO=y -@@ -217,6 +220,7 @@ CONFIG_REMOTEPROC_SANDBOX=y - CONFIG_DM_RESET=y - CONFIG_SANDBOX_RESET=y - CONFIG_RESET_SYSCON=y -+CONFIG_RESET_SCMI=y - CONFIG_DM_RNG=y - CONFIG_DM_RTC=y - CONFIG_RTC_RV8803=y -diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig -index a8c4112dbe..c08d06474b 100644 ---- a/configs/stm32mp15_basic_defconfig -+++ b/configs/stm32mp15_basic_defconfig -@@ -18,6 +18,7 @@ CONFIG_SPL_SPI_SUPPORT=y - CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" - CONFIG_DISTRO_DEFAULTS=y - CONFIG_FIT=y -+CONFIG_BOOTDELAY=1 - CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" - CONFIG_BOARD_EARLY_INIT_F=y - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y -@@ -31,8 +32,6 @@ CONFIG_SPL_SPI_FLASH_MTD=y - CONFIG_SYS_PROMPT="STM32MP> " - CONFIG_CMD_ADTIMG=y - # CONFIG_CMD_ELF is not set --# CONFIG_CMD_EXPORTENV is not set --# CONFIG_CMD_IMPORTENV is not set - CONFIG_CMD_ERASEENV=y - CONFIG_CMD_MEMINFO=y - CONFIG_CMD_MEMTEST=y -@@ -69,6 +68,7 @@ CONFIG_ENV_UBI_PART="UBI" - CONFIG_ENV_UBI_VOLUME="uboot_config" - CONFIG_ENV_UBI_VOLUME_REDUND="uboot_config_r" - CONFIG_SYS_RELOC_GD_ENV_ADDR=y -+CONFIG_SYS_MMC_ENV_DEV=-1 - # CONFIG_SPL_ENV_IS_NOWHERE is not set - # CONFIG_SPL_ENV_IS_IN_SPI_FLASH is not set - CONFIG_STM32_ADC=y -@@ -121,6 +121,7 @@ CONFIG_DM_REGULATOR_FIXED=y - CONFIG_DM_REGULATOR_GPIO=y - CONFIG_DM_REGULATOR_STM32_VREFBUF=y - CONFIG_DM_REGULATOR_STPMIC1=y -+CONFIG_STM32MP1_DDR_INTERACTIVE=y - CONFIG_REMOTEPROC_STM32_COPRO=y - CONFIG_DM_RNG=y - CONFIG_RNG_STM32MP1=y -@@ -153,3 +154,4 @@ CONFIG_WDT=y - CONFIG_WDT_STM32MP=y - CONFIG_ERRNO_STR=y - CONFIG_FDT_FIXUP_PARTITIONS=y -+CONFIG_LMB_RESERVED_REGIONS=16 -diff --git a/configs/stm32mp15_dhcom_basic_defconfig b/configs/stm32mp15_dhcom_basic_defconfig -index 7668fd01cd..c0282fa9fb 100644 ---- a/configs/stm32mp15_dhcom_basic_defconfig -+++ b/configs/stm32mp15_dhcom_basic_defconfig -@@ -17,6 +17,7 @@ CONFIG_FIT=y - CONFIG_SPL_LOAD_FIT=y - CONFIG_SPL_FIT_SOURCE="board/dhelectronics/dh_stm32mp1/u-boot-dhcom.its" - # CONFIG_USE_SPL_FIT_GENERATOR is not set -+CONFIG_BOOTDELAY=1 - CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" - CONFIG_BOARD_EARLY_INIT_F=y - CONFIG_SPL_LEGACY_IMAGE_SUPPORT=y -diff --git a/configs/stm32mp15_dhcor_basic_defconfig b/configs/stm32mp15_dhcor_basic_defconfig -index aa384517c3..ba1be446e7 100644 ---- a/configs/stm32mp15_dhcor_basic_defconfig -+++ b/configs/stm32mp15_dhcor_basic_defconfig -@@ -17,6 +17,7 @@ CONFIG_FIT=y - CONFIG_SPL_LOAD_FIT=y - CONFIG_SPL_FIT_SOURCE="board/dhelectronics/dh_stm32mp1/u-boot-dhcor.its" - # CONFIG_USE_SPL_FIT_GENERATOR is not set -+CONFIG_BOOTDELAY=1 - CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" - CONFIG_BOARD_EARLY_INIT_F=y - CONFIG_SPL_LEGACY_IMAGE_SUPPORT=y -diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig -index 0792884a9d..5b4cfc4ca3 100644 ---- a/configs/stm32mp15_trusted_defconfig -+++ b/configs/stm32mp15_trusted_defconfig -@@ -2,21 +2,20 @@ CONFIG_ARM=y - CONFIG_ARCH_STM32MP=y - CONFIG_TFABOOT=y - CONFIG_SYS_MALLOC_F_LEN=0x3000 --CONFIG_ENV_OFFSET=0x280000 -+CONFIG_ENV_OFFSET=0x480000 - CONFIG_ENV_SECT_SIZE=0x40000 - CONFIG_TARGET_ST_STM32MP15x=y - CONFIG_CMD_STM32PROG=y - CONFIG_TYPEC_STUSB160X=y --CONFIG_ENV_OFFSET_REDUND=0x2C0000 -+CONFIG_ENV_OFFSET_REDUND=0x4C0000 - CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" - CONFIG_DISTRO_DEFAULTS=y - CONFIG_FIT=y -+CONFIG_BOOTDELAY=1 - CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" - CONFIG_SYS_PROMPT="STM32MP> " - CONFIG_CMD_ADTIMG=y - # CONFIG_CMD_ELF is not set --# CONFIG_CMD_EXPORTENV is not set --# CONFIG_CMD_IMPORTENV is not set - CONFIG_CMD_ERASEENV=y - CONFIG_CMD_MEMINFO=y - CONFIG_CMD_MEMTEST=y -@@ -51,7 +50,9 @@ CONFIG_ENV_UBI_PART="UBI" - CONFIG_ENV_UBI_VOLUME="uboot_config" - CONFIG_ENV_UBI_VOLUME_REDUND="uboot_config_r" - CONFIG_SYS_RELOC_GD_ENV_ADDR=y -+CONFIG_SYS_MMC_ENV_DEV=-1 - CONFIG_STM32_ADC=y -+CONFIG_CLK_SCMI=y - CONFIG_SET_DFU_ALT_INFO=y - CONFIG_USB_FUNCTION_FASTBOOT=y - CONFIG_FASTBOOT_BUF_ADDR=0xC0000000 -@@ -99,7 +100,9 @@ CONFIG_DM_REGULATOR_FIXED=y - CONFIG_DM_REGULATOR_GPIO=y - CONFIG_DM_REGULATOR_STM32_VREFBUF=y - CONFIG_DM_REGULATOR_STPMIC1=y -+CONFIG_REMOTEPROC_OPTEE=y - CONFIG_REMOTEPROC_STM32_COPRO=y -+CONFIG_RESET_SCMI=y - CONFIG_DM_RNG=y - CONFIG_RNG_STM32MP1=y - CONFIG_DM_RTC=y -@@ -134,3 +137,4 @@ CONFIG_WDT=y - CONFIG_WDT_STM32MP=y - CONFIG_ERRNO_STR=y - CONFIG_FDT_FIXUP_PARTITIONS=y -+CONFIG_LMB_RESERVED_REGIONS=16 --- -2.17.1 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0005-ARM-v2021.10-stm32mp-r1-CONFIG.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0005-ARM-v2021.10-stm32mp-r1-CONFIG.patch new file mode 100644 index 0000000..146fc8f --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0005-ARM-v2021.10-stm32mp-r1-CONFIG.patch @@ -0,0 +1,779 @@ +From a6c6f91e2e0f60984a8572ab960e305da4b87b21 Mon Sep 17 00:00:00 2001 +From: Christophe Priouzeau +Date: Mon, 30 May 2022 09:47:32 +0200 +Subject: [PATCH 5/5] ARM-v2021.10-stm32mp-r1-CONFIG + +--- + configs/stm32f429-discovery_defconfig | 2 + + configs/stm32f429-evaluation_defconfig | 1 + + configs/stm32f469-discovery_defconfig | 1 + + configs/stm32f746-disco_defconfig | 1 + + configs/stm32f769-disco_defconfig | 1 + + configs/stm32mp13_defconfig | 143 ++++++++++++++++++ + ...stm32mp15-icore-stm32mp1-ctouch2_defconfig | 4 +- + ...tm32mp15-icore-stm32mp1-edimm2.2_defconfig | 4 +- + ...-microgea-stm32mp1-microdev2-of7_defconfig | 4 +- + ...mp15-microgea-stm32mp1-microdev2_defconfig | 4 +- + configs/stm32mp15_basic_defconfig | 15 +- + configs/stm32mp15_defconfig | 21 ++- + configs/stm32mp15_dhcom_basic_defconfig | 31 ++-- + configs/stm32mp15_dhcor_basic_defconfig | 32 ++-- + configs/stm32mp15_trusted_defconfig | 19 ++- + 15 files changed, 223 insertions(+), 60 deletions(-) + create mode 100644 configs/stm32mp13_defconfig + +diff --git a/configs/stm32f429-discovery_defconfig b/configs/stm32f429-discovery_defconfig +index b0dcb38b3b..06e4631d9f 100644 +--- a/configs/stm32f429-discovery_defconfig ++++ b/configs/stm32f429-discovery_defconfig +@@ -10,6 +10,7 @@ CONFIG_STM32F4=y + CONFIG_TARGET_STM32F429_DISCOVERY=y + CONFIG_ENV_VARS_UBOOT_CONFIG=y + CONFIG_BOOTDELAY=3 ++CONFIG_BOOTCOMMAND="run bootcmd_romfs" + CONFIG_USE_BOOTARGS=y + CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel" + # CONFIG_DISPLAY_CPUINFO is not set +@@ -26,3 +27,4 @@ CONFIG_ENV_ADDR=0x8040000 + # CONFIG_NET is not set + # CONFIG_MMC is not set + CONFIG_MTD_NOR_FLASH=y ++CONFIG_STM32_FLASH=y +diff --git a/configs/stm32f429-evaluation_defconfig b/configs/stm32f429-evaluation_defconfig +index b614182b4f..a15a68cee7 100644 +--- a/configs/stm32f429-evaluation_defconfig ++++ b/configs/stm32f429-evaluation_defconfig +@@ -26,3 +26,4 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y + # CONFIG_NET is not set + CONFIG_ARM_PL180_MMCI=y + CONFIG_MTD_NOR_FLASH=y ++CONFIG_STM32_FLASH=y +diff --git a/configs/stm32f469-discovery_defconfig b/configs/stm32f469-discovery_defconfig +index 7960618d46..0b33e0b3c8 100644 +--- a/configs/stm32f469-discovery_defconfig ++++ b/configs/stm32f469-discovery_defconfig +@@ -28,6 +28,7 @@ CONFIG_ARM_PL180_MMCI=y + CONFIG_MTD=y + CONFIG_DM_MTD=y + CONFIG_MTD_NOR_FLASH=y ++CONFIG_STM32_FLASH=y + CONFIG_DM_SPI_FLASH=y + CONFIG_SPI_FLASH_STMICRO=y + # CONFIG_PINCTRL_FULL is not set +diff --git a/configs/stm32f746-disco_defconfig b/configs/stm32f746-disco_defconfig +index 05d7ec2d79..f13d714230 100644 +--- a/configs/stm32f746-disco_defconfig ++++ b/configs/stm32f746-disco_defconfig +@@ -43,6 +43,7 @@ CONFIG_ARM_PL180_MMCI=y + CONFIG_MTD=y + CONFIG_DM_MTD=y + CONFIG_MTD_NOR_FLASH=y ++CONFIG_STM32_FLASH=y + CONFIG_DM_SPI_FLASH=y + CONFIG_SPI_FLASH_MACRONIX=y + CONFIG_SPI_FLASH_STMICRO=y +diff --git a/configs/stm32f769-disco_defconfig b/configs/stm32f769-disco_defconfig +index 40f94ac772..2706d41956 100644 +--- a/configs/stm32f769-disco_defconfig ++++ b/configs/stm32f769-disco_defconfig +@@ -42,6 +42,7 @@ CONFIG_ARM_PL180_MMCI=y + CONFIG_MTD=y + CONFIG_DM_MTD=y + CONFIG_MTD_NOR_FLASH=y ++CONFIG_STM32_FLASH=y + CONFIG_DM_SPI_FLASH=y + CONFIG_SPI_FLASH_MACRONIX=y + CONFIG_SPI_FLASH_STMICRO=y +diff --git a/configs/stm32mp13_defconfig b/configs/stm32mp13_defconfig +new file mode 100644 +index 0000000000..2429c3f411 +--- /dev/null ++++ b/configs/stm32mp13_defconfig +@@ -0,0 +1,143 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_STM32MP=y ++CONFIG_TFABOOT=y ++CONFIG_SYS_MALLOC_F_LEN=0x180000 ++CONFIG_SYS_MEMTEST_START=0xc0000000 ++CONFIG_SYS_MEMTEST_END=0xc4000000 ++CONFIG_ENV_OFFSET=0x900000 ++CONFIG_ENV_SECT_SIZE=0x40000 ++CONFIG_DEFAULT_DEVICE_TREE="stm32mp135f-dk" ++CONFIG_STM32MP13x=y ++CONFIG_DDR_CACHEABLE_SIZE=0x10000000 ++CONFIG_CMD_STM32KEY=y ++CONFIG_TARGET_ST_STM32MP13x=y ++CONFIG_ENV_OFFSET_REDUND=0x940000 ++CONFIG_CMD_STM32PROG=y ++# CONFIG_ARMV7_NONSEC is not set ++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_ERASEENV=y ++CONFIG_CMD_NVEDIT_EFI=y ++CONFIG_CMD_MEMINFO=y ++CONFIG_CMD_MEMTEST=y ++CONFIG_CMD_UNZIP=y ++CONFIG_CMD_ADC=y ++CONFIG_CMD_CLK=y ++CONFIG_CMD_DFU=y ++CONFIG_CMD_FUSE=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_I2C=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_SPI=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_USB_MASS_STORAGE=y ++CONFIG_CMD_BMP=y ++CONFIG_CMD_CACHE=y ++CONFIG_CMD_EFIDEBUG=y ++CONFIG_CMD_TIME=y ++CONFIG_CMD_RNG=y ++CONFIG_CMD_TIMER=y ++CONFIG_CMD_REGULATOR=y ++CONFIG_CMD_EXT4_WRITE=y ++CONFIG_CMD_MTDPARTS=y ++CONFIG_CMD_LOG=y ++CONFIG_CMD_UBI=y ++CONFIG_OF_LIVE=y ++CONFIG_ENV_IS_NOWHERE=y ++CONFIG_ENV_IS_IN_MMC=y ++CONFIG_ENV_IS_IN_SPI_FLASH=y ++CONFIG_ENV_IS_IN_UBI=y ++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y ++CONFIG_ENV_UBI_PART="UBI" ++CONFIG_ENV_UBI_VOLUME="uboot_config" ++CONFIG_ENV_UBI_VOLUME_REDUND="uboot_config_r" ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_SYS_MMC_ENV_DEV=-1 ++CONFIG_STM32_ADC=y ++CONFIG_CLK_SCMI=y ++CONFIG_SET_DFU_ALT_INFO=y ++CONFIG_USB_FUNCTION_FASTBOOT=y ++CONFIG_FASTBOOT_BUF_ADDR=0xC0000000 ++CONFIG_FASTBOOT_BUF_SIZE=0x02000000 ++CONFIG_FASTBOOT_USB_DEV=1 ++CONFIG_FASTBOOT_FLASH=y ++CONFIG_FASTBOOT_FLASH_MMC_DEV=1 ++CONFIG_GPIO_HOG=y ++CONFIG_DM_I2C=y ++CONFIG_SYS_I2C_STM32F7=y ++CONFIG_LED=y ++CONFIG_LED_GPIO=y ++CONFIG_STM32_FMC2_EBI=y ++CONFIG_SUPPORT_EMMC_BOOT=y ++CONFIG_STM32_SDMMC2=y ++CONFIG_MTD=y ++CONFIG_DM_MTD=y ++CONFIG_SYS_MTDPARTS_RUNTIME=y ++CONFIG_MTD_RAW_NAND=y ++CONFIG_NAND_STM32_FMC2=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_DM_SPI_FLASH=y ++CONFIG_SPI_FLASH_MACRONIX=y ++CONFIG_SPI_FLASH_SPANSION=y ++CONFIG_SPI_FLASH_STMICRO=y ++CONFIG_SPI_FLASH_WINBOND=y ++# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set ++CONFIG_SPI_FLASH_MTD=y ++CONFIG_PHY_REALTEK=y ++CONFIG_DM_ETH=y ++CONFIG_DWC_ETH_QOS=y ++CONFIG_PHY=y ++CONFIG_PHY_STM32_USBPHYC=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MCP23017=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_DM_REGULATOR_SCMI=y ++CONFIG_RESET_SCMI=y ++CONFIG_DM_RNG=y ++CONFIG_RNG_OPTEE=y ++CONFIG_DM_RTC=y ++CONFIG_RTC_STM32=y ++CONFIG_SERIAL_RX_BUFFER=y ++CONFIG_SPI=y ++CONFIG_DM_SPI=y ++CONFIG_STM32_QSPI=y ++CONFIG_STM32_SPI=y ++CONFIG_SYSRESET_PSCI=y ++CONFIG_TEE=y ++CONFIG_OPTEE=y ++# CONFIG_OPTEE_TA_AVB is not set ++CONFIG_USB=y ++CONFIG_DM_USB_GADGET=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_TYPEC=y ++CONFIG_TYPEC_UCSI=y ++CONFIG_UCSI_STM32G0=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics" ++CONFIG_USB_GADGET_VENDOR_NUM=0x0483 ++CONFIG_USB_GADGET_PRODUCT_NUM=0x5720 ++CONFIG_USB_GADGET_DWC2_OTG=y ++CONFIG_DM_VIDEO=y ++CONFIG_BACKLIGHT_GPIO=y ++CONFIG_VIDEO_STM32=y ++CONFIG_VIDEO_STM32_MAX_XRES=480 ++CONFIG_VIDEO_STM32_MAX_YRES=272 ++CONFIG_VIDEO_BMP_RLE8=y ++CONFIG_BMP_16BPP=y ++CONFIG_BMP_24BPP=y ++CONFIG_BMP_32BPP=y ++CONFIG_WDT=y ++CONFIG_WDT_STM32MP=y ++CONFIG_ERRNO_STR=y ++CONFIG_FDT_FIXUP_PARTITIONS=y ++# CONFIG_LMB_USE_MAX_REGIONS is not set ++CONFIG_LMB_MEMORY_REGIONS=2 ++CONFIG_LMB_RESERVED_REGIONS=16 +diff --git a/configs/stm32mp15-icore-stm32mp1-ctouch2_defconfig b/configs/stm32mp15-icore-stm32mp1-ctouch2_defconfig +index a7e5f566b0..f1120b8b64 100644 +--- a/configs/stm32mp15-icore-stm32mp1-ctouch2_defconfig ++++ b/configs/stm32mp15-icore-stm32mp1-ctouch2_defconfig +@@ -50,8 +50,6 @@ CONFIG_DM_I2C=y + CONFIG_SYS_I2C_STM32F7=y + CONFIG_LED=y + CONFIG_LED_GPIO=y +-CONFIG_DM_MAILBOX=y +-CONFIG_STM32_IPCC=y + CONFIG_STM32_FMC2_EBI=y + CONFIG_SUPPORT_EMMC_BOOT=y + CONFIG_STM32_SDMMC2=y +@@ -72,7 +70,9 @@ CONFIG_REMOTEPROC_STM32_COPRO=y + CONFIG_DM_RTC=y + CONFIG_RTC_STM32=y + CONFIG_SERIAL_RX_BUFFER=y ++CONFIG_SYSRESET_SYSCON=y + CONFIG_WDT=y + CONFIG_WDT_STM32MP=y ++# CONFIG_BINMAN_FDT is not set + CONFIG_LZO=y + CONFIG_ERRNO_STR=y +diff --git a/configs/stm32mp15-icore-stm32mp1-edimm2.2_defconfig b/configs/stm32mp15-icore-stm32mp1-edimm2.2_defconfig +index 4860ae4451..3de88ac9f7 100644 +--- a/configs/stm32mp15-icore-stm32mp1-edimm2.2_defconfig ++++ b/configs/stm32mp15-icore-stm32mp1-edimm2.2_defconfig +@@ -50,8 +50,6 @@ CONFIG_DM_I2C=y + CONFIG_SYS_I2C_STM32F7=y + CONFIG_LED=y + CONFIG_LED_GPIO=y +-CONFIG_DM_MAILBOX=y +-CONFIG_STM32_IPCC=y + CONFIG_STM32_FMC2_EBI=y + CONFIG_SUPPORT_EMMC_BOOT=y + CONFIG_STM32_SDMMC2=y +@@ -72,7 +70,9 @@ CONFIG_REMOTEPROC_STM32_COPRO=y + CONFIG_DM_RTC=y + CONFIG_RTC_STM32=y + CONFIG_SERIAL_RX_BUFFER=y ++CONFIG_SYSRESET_SYSCON=y + CONFIG_WDT=y + CONFIG_WDT_STM32MP=y ++# CONFIG_BINMAN_FDT is not set + CONFIG_LZO=y + CONFIG_ERRNO_STR=y +diff --git a/configs/stm32mp15-microgea-stm32mp1-microdev2-of7_defconfig b/configs/stm32mp15-microgea-stm32mp1-microdev2-of7_defconfig +index b075365182..6ff354dd18 100644 +--- a/configs/stm32mp15-microgea-stm32mp1-microdev2-of7_defconfig ++++ b/configs/stm32mp15-microgea-stm32mp1-microdev2-of7_defconfig +@@ -50,8 +50,6 @@ CONFIG_DM_I2C=y + CONFIG_SYS_I2C_STM32F7=y + CONFIG_LED=y + CONFIG_LED_GPIO=y +-CONFIG_DM_MAILBOX=y +-CONFIG_STM32_IPCC=y + CONFIG_STM32_FMC2_EBI=y + CONFIG_SUPPORT_EMMC_BOOT=y + CONFIG_STM32_SDMMC2=y +@@ -72,7 +70,9 @@ CONFIG_REMOTEPROC_STM32_COPRO=y + CONFIG_DM_RTC=y + CONFIG_RTC_STM32=y + CONFIG_SERIAL_RX_BUFFER=y ++CONFIG_SYSRESET_SYSCON=y + CONFIG_WDT=y + CONFIG_WDT_STM32MP=y ++# CONFIG_BINMAN_FDT is not set + CONFIG_LZO=y + CONFIG_ERRNO_STR=y +diff --git a/configs/stm32mp15-microgea-stm32mp1-microdev2_defconfig b/configs/stm32mp15-microgea-stm32mp1-microdev2_defconfig +index be68c8a397..d51ceb7e47 100644 +--- a/configs/stm32mp15-microgea-stm32mp1-microdev2_defconfig ++++ b/configs/stm32mp15-microgea-stm32mp1-microdev2_defconfig +@@ -50,8 +50,6 @@ CONFIG_DM_I2C=y + CONFIG_SYS_I2C_STM32F7=y + CONFIG_LED=y + CONFIG_LED_GPIO=y +-CONFIG_DM_MAILBOX=y +-CONFIG_STM32_IPCC=y + CONFIG_STM32_FMC2_EBI=y + CONFIG_SUPPORT_EMMC_BOOT=y + CONFIG_STM32_SDMMC2=y +@@ -72,7 +70,9 @@ CONFIG_REMOTEPROC_STM32_COPRO=y + CONFIG_DM_RTC=y + CONFIG_RTC_STM32=y + CONFIG_SERIAL_RX_BUFFER=y ++CONFIG_SYSRESET_SYSCON=y + CONFIG_WDT=y + CONFIG_WDT_STM32MP=y ++# CONFIG_BINMAN_FDT is not set + CONFIG_LZO=y + CONFIG_ERRNO_STR=y +diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig +index 9cf6ab1f0f..9cd37aa722 100644 +--- a/configs/stm32mp15_basic_defconfig ++++ b/configs/stm32mp15_basic_defconfig +@@ -1,6 +1,6 @@ + CONFIG_ARM=y + CONFIG_ARCH_STM32MP=y +-CONFIG_SYS_MALLOC_F_LEN=0x3000 ++CONFIG_SYS_MALLOC_F_LEN=0x10000 + CONFIG_SYS_MEMTEST_START=0xc0000000 + CONFIG_SYS_MEMTEST_END=0xc4000000 + CONFIG_ENV_OFFSET=0x280000 +@@ -10,11 +10,10 @@ CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" + CONFIG_SPL_TEXT_BASE=0x2FFC2500 + CONFIG_SPL_MMC_SUPPORT=y + CONFIG_SPL=y +-CONFIG_TARGET_ST_STM32MP15x=y + CONFIG_CMD_STM32KEY=y +-CONFIG_CMD_STM32PROG=y ++CONFIG_TARGET_ST_STM32MP15x=y + CONFIG_ENV_OFFSET_REDUND=0x2C0000 +-CONFIG_TYPEC_STUSB160X=y ++CONFIG_CMD_STM32PROG=y + CONFIG_SPL_SPI_FLASH_SUPPORT=y + CONFIG_SPL_SPI_SUPPORT=y + # CONFIG_ARMV7_VIRT is not set +@@ -33,6 +32,7 @@ CONFIG_SPL_DM_SPI_FLASH=y + CONFIG_SPL_POWER=y + CONFIG_SPL_SPI_FLASH_MTD=y + CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000 ++CONFIG_FDT_SIMPLEFB=y + CONFIG_SYS_PROMPT="STM32MP> " + CONFIG_CMD_ADTIMG=y + CONFIG_CMD_ERASEENV=y +@@ -101,8 +101,6 @@ CONFIG_DM_I2C=y + CONFIG_SYS_I2C_STM32F7=y + CONFIG_LED=y + CONFIG_LED_GPIO=y +-CONFIG_DM_MAILBOX=y +-CONFIG_STM32_IPCC=y + CONFIG_STM32_FMC2_EBI=y + CONFIG_SUPPORT_EMMC_BOOT=y + CONFIG_STM32_SDMMC2=y +@@ -145,10 +143,13 @@ CONFIG_SPI=y + CONFIG_DM_SPI=y + CONFIG_STM32_QSPI=y + CONFIG_STM32_SPI=y ++CONFIG_SYSRESET_SYSCON=y + CONFIG_USB=y + CONFIG_DM_USB_GADGET=y + CONFIG_USB_EHCI_HCD=y + CONFIG_USB_EHCI_GENERIC=y ++CONFIG_TYPEC=y ++CONFIG_TYPEC_STUSB160X=y + CONFIG_USB_GADGET=y + CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics" + CONFIG_USB_GADGET_VENDOR_NUM=0x0483 +@@ -158,6 +159,7 @@ CONFIG_DM_VIDEO=y + CONFIG_BACKLIGHT_GPIO=y + CONFIG_VIDEO_LCD_ORISETECH_OTM8009A=y + CONFIG_VIDEO_LCD_RAYDIUM_RM68200=y ++CONFIG_VIDEO_LCD_ROCKTECH_HX8394=y + CONFIG_VIDEO_STM32=y + CONFIG_VIDEO_STM32_DSI=y + CONFIG_VIDEO_STM32_MAX_XRES=1280 +@@ -168,6 +170,7 @@ CONFIG_BMP_24BPP=y + CONFIG_BMP_32BPP=y + CONFIG_WDT=y + CONFIG_WDT_STM32MP=y ++# CONFIG_BINMAN_FDT is not set + CONFIG_ERRNO_STR=y + CONFIG_FDT_FIXUP_PARTITIONS=y + # CONFIG_LMB_USE_MAX_REGIONS is not set +diff --git a/configs/stm32mp15_defconfig b/configs/stm32mp15_defconfig +index e725b916b9..b4b2954273 100644 +--- a/configs/stm32mp15_defconfig ++++ b/configs/stm32mp15_defconfig +@@ -1,21 +1,23 @@ + CONFIG_ARM=y + CONFIG_ARCH_STM32MP=y + CONFIG_TFABOOT=y +-CONFIG_SYS_MALLOC_F_LEN=0x3000 ++CONFIG_SYS_MALLOC_F_LEN=0x80000 + CONFIG_SYS_MEMTEST_START=0xc0000000 + CONFIG_SYS_MEMTEST_END=0xc4000000 +-CONFIG_ENV_OFFSET=0x480000 ++CONFIG_ENV_OFFSET=0x900000 + CONFIG_ENV_SECT_SIZE=0x40000 + CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" +-CONFIG_TARGET_ST_STM32MP15x=y ++CONFIG_DDR_CACHEABLE_SIZE=0x10000000 + CONFIG_CMD_STM32KEY=y ++CONFIG_TARGET_ST_STM32MP15x=y ++CONFIG_ENV_OFFSET_REDUND=0x940000 + CONFIG_CMD_STM32PROG=y +-CONFIG_ENV_OFFSET_REDUND=0x4C0000 +-CONFIG_TYPEC_STUSB160X=y ++# CONFIG_ARMV7_NONSEC is not set + 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_ERASEENV=y +@@ -81,8 +83,6 @@ CONFIG_DM_I2C=y + CONFIG_SYS_I2C_STM32F7=y + CONFIG_LED=y + CONFIG_LED_GPIO=y +-CONFIG_DM_MAILBOX=y +-CONFIG_STM32_IPCC=y + CONFIG_STM32_FMC2_EBI=y + CONFIG_SUPPORT_EMMC_BOOT=y + CONFIG_STM32_SDMMC2=y +@@ -113,9 +113,11 @@ CONFIG_DM_REGULATOR_FIXED=y + CONFIG_DM_REGULATOR_GPIO=y + CONFIG_DM_REGULATOR_STM32_VREFBUF=y + CONFIG_DM_REGULATOR_STPMIC1=y ++CONFIG_REMOTEPROC_OPTEE=y + CONFIG_REMOTEPROC_STM32_COPRO=y + CONFIG_RESET_SCMI=y + CONFIG_DM_RNG=y ++CONFIG_RNG_OPTEE=y + CONFIG_RNG_STM32MP1=y + CONFIG_DM_RTC=y + CONFIG_RTC_STM32=y +@@ -124,6 +126,7 @@ CONFIG_SPI=y + CONFIG_DM_SPI=y + CONFIG_STM32_QSPI=y + CONFIG_STM32_SPI=y ++CONFIG_SYSRESET_PSCI=y + CONFIG_TEE=y + CONFIG_OPTEE=y + # CONFIG_OPTEE_TA_AVB is not set +@@ -131,6 +134,8 @@ CONFIG_USB=y + CONFIG_DM_USB_GADGET=y + CONFIG_USB_EHCI_HCD=y + CONFIG_USB_EHCI_GENERIC=y ++CONFIG_TYPEC=y ++CONFIG_TYPEC_STUSB160X=y + CONFIG_USB_GADGET=y + CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics" + CONFIG_USB_GADGET_VENDOR_NUM=0x0483 +@@ -140,6 +145,7 @@ CONFIG_DM_VIDEO=y + CONFIG_BACKLIGHT_GPIO=y + CONFIG_VIDEO_LCD_ORISETECH_OTM8009A=y + CONFIG_VIDEO_LCD_RAYDIUM_RM68200=y ++CONFIG_VIDEO_LCD_ROCKTECH_HX8394=y + CONFIG_VIDEO_STM32=y + CONFIG_VIDEO_STM32_DSI=y + CONFIG_VIDEO_STM32_MAX_XRES=1280 +@@ -150,6 +156,7 @@ CONFIG_BMP_24BPP=y + CONFIG_BMP_32BPP=y + CONFIG_WDT=y + CONFIG_WDT_STM32MP=y ++# CONFIG_BINMAN_FDT is not set + CONFIG_ERRNO_STR=y + CONFIG_FDT_FIXUP_PARTITIONS=y + # CONFIG_LMB_USE_MAX_REGIONS is not set +diff --git a/configs/stm32mp15_dhcom_basic_defconfig b/configs/stm32mp15_dhcom_basic_defconfig +index c2227c06b0..81d83c58d5 100644 +--- a/configs/stm32mp15_dhcom_basic_defconfig ++++ b/configs/stm32mp15_dhcom_basic_defconfig +@@ -21,6 +21,7 @@ CONFIG_SPL_FIT_SOURCE="board/dhelectronics/dh_stm32mp1/u-boot-dhcom.its" + # CONFIG_USE_SPL_FIT_GENERATOR is not set + CONFIG_BOOTDELAY=1 + CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" ++CONFIG_CONSOLE_MUX=y + CONFIG_BOARD_EARLY_INIT_F=y + CONFIG_SPL_LEGACY_IMAGE_SUPPORT=y + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y +@@ -51,7 +52,6 @@ CONFIG_CMD_REMOTEPROC=y + CONFIG_CMD_SPI=y + CONFIG_CMD_USB=y + CONFIG_CMD_USB_MASS_STORAGE=y +-CONFIG_CMD_BMP=y + CONFIG_CMD_CACHE=y + CONFIG_CMD_TIME=y + CONFIG_CMD_TIMER=y +@@ -59,7 +59,11 @@ CONFIG_CMD_PMIC=y + CONFIG_CMD_REGULATOR=y + CONFIG_CMD_EXT4_WRITE=y + CONFIG_CMD_MTDPARTS=y ++CONFIG_MTDIDS_DEFAULT="nor0=nor0" ++CONFIG_MTDPARTS_DEFAULT="mtdparts=nor0:256k(fsbl1),256k(fsbl2),1408k(uboot),64k(env1),64k(env2)" + # CONFIG_SPL_DOS_PARTITION is not set ++# CONFIG_ISO_PARTITION is not set ++# CONFIG_SPL_PARTITION_UUIDS is not set + CONFIG_OF_LIST="stm32mp15xx-dhcom-pdk2 stm32mp15xx-dhcom-drc02 stm32mp15xx-dhcom-picoitx" + CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-names interrupts-extended interrupt-controller \\\#interrupt-cells interrupt-parent dmas dma-names assigned-clocks assigned-clock-rates assigned-clock-parents hwlocks" + CONFIG_ENV_IS_IN_SPI_FLASH=y +@@ -68,7 +72,7 @@ CONFIG_ENV_SPI_BUS=0 + CONFIG_USE_ENV_SPI_CS=y + CONFIG_ENV_SPI_CS=0 + CONFIG_USE_ENV_SPI_MAX_HZ=y +-CONFIG_ENV_SPI_MAX_HZ=10000000 ++CONFIG_ENV_SPI_MAX_HZ=50000000 + CONFIG_USE_ENV_SPI_MODE=y + CONFIG_ENV_SPI_MODE=0x0 + CONFIG_SYS_REDUNDAND_ENVIRONMENT=y +@@ -80,6 +84,7 @@ CONFIG_STM32_ADC=y + CONFIG_SPL_BLOCK_CACHE=y + CONFIG_DFU_MMC=y + CONFIG_DFU_RAM=y ++CONFIG_DFU_MTD=y + CONFIG_DFU_VIRT=y + CONFIG_SET_DFU_ALT_INFO=y + CONFIG_GPIO_HOG=y +@@ -89,16 +94,16 @@ CONFIG_DM_I2C=y + CONFIG_SYS_I2C_STM32F7=y + CONFIG_LED=y + CONFIG_LED_GPIO=y +-CONFIG_DM_MAILBOX=y +-CONFIG_STM32_IPCC=y + CONFIG_I2C_EEPROM=y + CONFIG_SYS_I2C_EEPROM_ADDR=0x50 + CONFIG_SYS_I2C_EEPROM_BUS=3 + CONFIG_SUPPORT_EMMC_BOOT=y + CONFIG_STM32_SDMMC2=y + CONFIG_MTD=y +-CONFIG_SYS_MTDPARTS_RUNTIME=y ++CONFIG_DM_MTD=y + CONFIG_DM_SPI_FLASH=y ++CONFIG_SF_DEFAULT_SPEED=50000000 ++CONFIG_SPI_FLASH_SFDP_SUPPORT=y + CONFIG_SPI_FLASH_MACRONIX=y + CONFIG_SPI_FLASH_SPANSION=y + CONFIG_SPI_FLASH_STMICRO=y +@@ -128,6 +133,7 @@ CONFIG_SPI=y + CONFIG_DM_SPI=y + CONFIG_STM32_QSPI=y + CONFIG_STM32_SPI=y ++CONFIG_SYSRESET_SYSCON=y + CONFIG_USB=y + CONFIG_DM_USB_GADGET=y + CONFIG_USB_EHCI_HCD=y +@@ -140,17 +146,8 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0483 + CONFIG_USB_GADGET_PRODUCT_NUM=0x5720 + CONFIG_USB_GADGET_DWC2_OTG=y + CONFIG_USB_GADGET_DOWNLOAD=y +-CONFIG_DM_VIDEO=y +-CONFIG_BACKLIGHT_GPIO=y +-CONFIG_VIDEO_LCD_ORISETECH_OTM8009A=y +-CONFIG_VIDEO_LCD_RAYDIUM_RM68200=y +-CONFIG_VIDEO_STM32=y +-CONFIG_VIDEO_STM32_DSI=y +-CONFIG_VIDEO_STM32_MAX_XRES=1280 +-CONFIG_VIDEO_STM32_MAX_YRES=800 +-CONFIG_VIDEO_BMP_RLE8=y +-CONFIG_BMP_16BPP=y +-CONFIG_BMP_24BPP=y +-CONFIG_BMP_32BPP=y ++CONFIG_FAT_WRITE=y ++# CONFIG_BINMAN_FDT is not set + CONFIG_LZO=y + CONFIG_FDT_FIXUP_PARTITIONS=y ++# CONFIG_EFI_LOADER is not set +diff --git a/configs/stm32mp15_dhcor_basic_defconfig b/configs/stm32mp15_dhcor_basic_defconfig +index 11750cb67b..e0c25015cc 100644 +--- a/configs/stm32mp15_dhcor_basic_defconfig ++++ b/configs/stm32mp15_dhcor_basic_defconfig +@@ -19,6 +19,7 @@ CONFIG_SPL_FIT_SOURCE="board/dhelectronics/dh_stm32mp1/u-boot-dhcor.its" + # CONFIG_USE_SPL_FIT_GENERATOR is not set + CONFIG_BOOTDELAY=1 + CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" ++CONFIG_CONSOLE_MUX=y + CONFIG_BOARD_EARLY_INIT_F=y + CONFIG_SPL_LEGACY_IMAGE_SUPPORT=y + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y +@@ -49,7 +50,6 @@ CONFIG_CMD_REMOTEPROC=y + CONFIG_CMD_SPI=y + CONFIG_CMD_USB=y + CONFIG_CMD_USB_MASS_STORAGE=y +-CONFIG_CMD_BMP=y + CONFIG_CMD_CACHE=y + CONFIG_CMD_TIME=y + CONFIG_CMD_TIMER=y +@@ -57,7 +57,11 @@ CONFIG_CMD_PMIC=y + CONFIG_CMD_REGULATOR=y + CONFIG_CMD_EXT4_WRITE=y + CONFIG_CMD_MTDPARTS=y ++CONFIG_MTDIDS_DEFAULT="nor0=nor0" ++CONFIG_MTDPARTS_DEFAULT="mtdparts=nor0:256k(fsbl1),256k(fsbl2),1408k(uboot),64k(env1),64k(env2)" + # CONFIG_SPL_DOS_PARTITION is not set ++# CONFIG_ISO_PARTITION is not set ++# CONFIG_SPL_PARTITION_UUIDS is not set + CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-names interrupts-extended interrupt-controller \\\#interrupt-cells interrupt-parent dmas dma-names assigned-clocks assigned-clock-rates assigned-clock-parents hwlocks" + CONFIG_ENV_IS_IN_SPI_FLASH=y + CONFIG_USE_ENV_SPI_BUS=y +@@ -65,7 +69,7 @@ CONFIG_ENV_SPI_BUS=0 + CONFIG_USE_ENV_SPI_CS=y + CONFIG_ENV_SPI_CS=0 + CONFIG_USE_ENV_SPI_MAX_HZ=y +-CONFIG_ENV_SPI_MAX_HZ=10000000 ++CONFIG_ENV_SPI_MAX_HZ=50000000 + CONFIG_USE_ENV_SPI_MODE=y + CONFIG_ENV_SPI_MODE=0x0 + CONFIG_SYS_REDUNDAND_ENVIRONMENT=y +@@ -77,6 +81,7 @@ CONFIG_STM32_ADC=y + CONFIG_SPL_BLOCK_CACHE=y + CONFIG_DFU_MMC=y + CONFIG_DFU_RAM=y ++CONFIG_DFU_MTD=y + CONFIG_DFU_VIRT=y + CONFIG_GPIO_HOG=y + CONFIG_DM_HWSPINLOCK=y +@@ -85,20 +90,23 @@ CONFIG_DM_I2C=y + CONFIG_SYS_I2C_STM32F7=y + CONFIG_LED=y + CONFIG_LED_GPIO=y +-CONFIG_DM_MAILBOX=y +-CONFIG_STM32_IPCC=y + CONFIG_I2C_EEPROM=y + CONFIG_SYS_I2C_EEPROM_ADDR=0x53 + CONFIG_SYS_I2C_EEPROM_BUS=2 + CONFIG_SUPPORT_EMMC_BOOT=y + CONFIG_STM32_SDMMC2=y + CONFIG_MTD=y ++CONFIG_DM_MTD=y + CONFIG_DM_SPI_FLASH=y ++CONFIG_SF_DEFAULT_SPEED=50000000 ++CONFIG_SPI_FLASH_SFDP_SUPPORT=y + CONFIG_SPI_FLASH_MACRONIX=y + CONFIG_SPI_FLASH_SPANSION=y + CONFIG_SPI_FLASH_STMICRO=y + CONFIG_SPI_FLASH_WINBOND=y + CONFIG_SPI_FLASH_MTD=y ++CONFIG_PHY_MICREL=y ++CONFIG_PHY_MICREL_KSZ90X1=y + CONFIG_DM_ETH=y + CONFIG_DWC_ETH_QOS=y + CONFIG_PHY=y +@@ -122,6 +130,7 @@ CONFIG_SPI=y + CONFIG_DM_SPI=y + CONFIG_STM32_QSPI=y + CONFIG_STM32_SPI=y ++CONFIG_SYSRESET_SYSCON=y + CONFIG_USB=y + CONFIG_DM_USB_GADGET=y + CONFIG_USB_EHCI_HCD=y +@@ -134,17 +143,8 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0483 + CONFIG_USB_GADGET_PRODUCT_NUM=0x5720 + CONFIG_USB_GADGET_DWC2_OTG=y + CONFIG_USB_GADGET_DOWNLOAD=y +-CONFIG_DM_VIDEO=y +-CONFIG_BACKLIGHT_GPIO=y +-CONFIG_VIDEO_LCD_ORISETECH_OTM8009A=y +-CONFIG_VIDEO_LCD_RAYDIUM_RM68200=y +-CONFIG_VIDEO_STM32=y +-CONFIG_VIDEO_STM32_DSI=y +-CONFIG_VIDEO_STM32_MAX_XRES=1280 +-CONFIG_VIDEO_STM32_MAX_YRES=800 +-CONFIG_VIDEO_BMP_RLE8=y +-CONFIG_BMP_16BPP=y +-CONFIG_BMP_24BPP=y +-CONFIG_BMP_32BPP=y ++CONFIG_FAT_WRITE=y ++# CONFIG_BINMAN_FDT is not set + CONFIG_LZO=y + CONFIG_FDT_FIXUP_PARTITIONS=y ++# CONFIG_EFI_LOADER is not set +diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig +index 2e2f0c76ca..17233a596f 100644 +--- a/configs/stm32mp15_trusted_defconfig ++++ b/configs/stm32mp15_trusted_defconfig +@@ -1,22 +1,24 @@ + CONFIG_ARM=y + CONFIG_ARCH_STM32MP=y + CONFIG_TFABOOT=y +-CONFIG_SYS_MALLOC_F_LEN=0x3000 ++CONFIG_SYS_MALLOC_F_LEN=0x10000 + CONFIG_SYS_MEMTEST_START=0xc0000000 + CONFIG_SYS_MEMTEST_END=0xc4000000 + CONFIG_ENV_OFFSET=0x280000 + CONFIG_ENV_SECT_SIZE=0x40000 + CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" ++CONFIG_DDR_CACHEABLE_SIZE=0x10000000 ++CONFIG_CMD_STM32KEY=y + CONFIG_STM32MP15x_STM32IMAGE=y + CONFIG_TARGET_ST_STM32MP15x=y +-CONFIG_CMD_STM32KEY=y +-CONFIG_CMD_STM32PROG=y + CONFIG_ENV_OFFSET_REDUND=0x2C0000 +-CONFIG_TYPEC_STUSB160X=y ++CONFIG_CMD_STM32PROG=y ++# CONFIG_ARMV7_NONSEC is not set + 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_ERASEENV=y +@@ -82,8 +84,6 @@ CONFIG_DM_I2C=y + CONFIG_SYS_I2C_STM32F7=y + CONFIG_LED=y + CONFIG_LED_GPIO=y +-CONFIG_DM_MAILBOX=y +-CONFIG_STM32_IPCC=y + CONFIG_STM32_FMC2_EBI=y + CONFIG_SUPPORT_EMMC_BOOT=y + CONFIG_STM32_SDMMC2=y +@@ -114,9 +114,11 @@ CONFIG_DM_REGULATOR_FIXED=y + CONFIG_DM_REGULATOR_GPIO=y + CONFIG_DM_REGULATOR_STM32_VREFBUF=y + CONFIG_DM_REGULATOR_STPMIC1=y ++CONFIG_REMOTEPROC_OPTEE=y + CONFIG_REMOTEPROC_STM32_COPRO=y + CONFIG_RESET_SCMI=y + CONFIG_DM_RNG=y ++CONFIG_RNG_OPTEE=y + CONFIG_RNG_STM32MP1=y + CONFIG_DM_RTC=y + CONFIG_RTC_STM32=y +@@ -125,6 +127,7 @@ CONFIG_SPI=y + CONFIG_DM_SPI=y + CONFIG_STM32_QSPI=y + CONFIG_STM32_SPI=y ++CONFIG_SYSRESET_PSCI=y + CONFIG_TEE=y + CONFIG_OPTEE=y + # CONFIG_OPTEE_TA_AVB is not set +@@ -132,6 +135,8 @@ CONFIG_USB=y + CONFIG_DM_USB_GADGET=y + CONFIG_USB_EHCI_HCD=y + CONFIG_USB_EHCI_GENERIC=y ++CONFIG_TYPEC=y ++CONFIG_TYPEC_STUSB160X=y + CONFIG_USB_GADGET=y + CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics" + CONFIG_USB_GADGET_VENDOR_NUM=0x0483 +@@ -141,6 +146,7 @@ CONFIG_DM_VIDEO=y + CONFIG_BACKLIGHT_GPIO=y + CONFIG_VIDEO_LCD_ORISETECH_OTM8009A=y + CONFIG_VIDEO_LCD_RAYDIUM_RM68200=y ++CONFIG_VIDEO_LCD_ROCKTECH_HX8394=y + CONFIG_VIDEO_STM32=y + CONFIG_VIDEO_STM32_DSI=y + CONFIG_VIDEO_STM32_MAX_XRES=1280 +@@ -151,6 +157,7 @@ CONFIG_BMP_24BPP=y + CONFIG_BMP_32BPP=y + CONFIG_WDT=y + CONFIG_WDT_STM32MP=y ++# CONFIG_BINMAN_FDT is not set + CONFIG_ERRNO_STR=y + CONFIG_FDT_FIXUP_PARTITIONS=y + # CONFIG_LMB_USE_MAX_REGIONS is not set +-- +2.25.1 + 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 deleted file mode 100644 index c94b803..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0006-ARM-v2020.10-stm32mp-r1.1.patch +++ /dev/null @@ -1,340 +0,0 @@ -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 deleted file mode 100644 index f417a9c..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0007-ARM-v2020.10-stm32mp-r2-MACHINE.patch +++ /dev/null @@ -1,946 +0,0 @@ -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 deleted file mode 100644 index b491b92..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0008-ARM-v2020.10-stm32mp-r2-BOARD.patch +++ /dev/null @@ -1,117 +0,0 @@ -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 deleted file mode 100644 index d8f5f27..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0009-ARM-v2020.10-stm32mp-r2-MISC-DRIVERS.patch +++ /dev/null @@ -1,2957 +0,0 @@ -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 deleted file mode 100644 index 77299e2..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0010-ARM-v2020.10-stm32mp-r2-DEVICETREE.patch +++ /dev/null @@ -1,573 +0,0 @@ -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 deleted file mode 100644 index 88a211f..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0011-ARM-v2020.10-stm32mp-r2-CONFIG.patch +++ /dev/null @@ -1,186 +0,0 @@ -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 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/README.HOW_TO.txt b/recipes-bsp/u-boot/u-boot-stm32mp/README.HOW_TO.txt index 9177e5f..d8bcbbd 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp/README.HOW_TO.txt +++ b/recipes-bsp/u-boot/u-boot-stm32mp/README.HOW_TO.txt @@ -1,13 +1,14 @@ Compilation of U-Boot: 1. Pre-requisite -2. Initialise cross-compilation via SDK +2. Initialize cross-compilation via SDK 3. Prepare U-Boot source code -4. Management of U-Boot source code +4. Manage of U-Boot source code with GIT 5. Compile U-Boot source code 6. Update software on board -1. Pre-requisite: ------------------ +---------------- +1. Pre-requisite +---------------- OpenSTLinux SDK must be installed. For U-Boot build you need to install: @@ -22,7 +23,8 @@ If you have never configured you git configuration: $ git config --global user.name "your_name" $ git config --global user.email "your_email@example.com" -2. Initialize cross-compilation via SDK: +--------------------------------------- +2. Initialize cross-compilation via SDK --------------------------------------- * Source SDK environment: $ source /environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi @@ -34,34 +36,38 @@ If you have never configured you git configuration: Warning: the environment are valid only on the shell session where you have sourced the sdk environment. -3. Prepare U-Boot source: ------------------------ - -Extract the sources from tarball, for example: -$ tar xfJ SOURCES-st-image-weston-openstlinux-weston-stm32mp1-*.tar.xz +3. Prepare U-Boot source +------------------------ +If not already done, extract the sources from Developer Package tarball, for example: +$ tar xfJ en.SOURCES-stm32mp1-*.tar.xz In the U-Boot source directory (sources/*/##BP##-##PR##), you have one U-Boot source tarball, the patches and one Makefile: - - ##BP##-##PR##.tar.gz - - 000*.patch + - ##BP##-##PR##.tar.xz + - 00*.patch - Makefile.sdk -NB: if you would like to have a git management on the code see - section 4 [Management of U-Boot source code with GIT] +If you would like to have a git management for the source code move to +to section 4 [Management of U-Boot source code with GIT]. -Then you must extract the tarball and apply the patch: +Otherwise, to manage U-Boot source code without git, you must extract the +tarball now and apply the patch: - $> tar xfz ##BP##-##PR##.tar.gz + $> tar xf ##BP##-##PR##.tar.xz $> cd ##BP## $> for p in `ls -1 ../*.patch`; do patch -p1 < $p; done -4. Management of U-Boot source code with GIT --------------------------------------------- +You can now move to section 5 [Compile U-Boot source code]. + +------------------------------------- +4. Manage U-Boot source code with GIT +------------------------------------- If you like to have a better management of change made on U-Boot source, you have 3 solutions to use git 4.1 Get STMicroelectronics U-Boot source from GitHub - +---------------------------------------------------- URL: https://github.com/STMicroelectronics/u-boot.git Branch: ##ARCHIVER_ST_BRANCH## Revision: ##ARCHIVER_ST_REVISION## @@ -70,15 +76,15 @@ you have 3 solutions to use git $ git checkout -b WORKING ##ARCHIVER_ST_REVISION## 4.2 Create Git from tarball - - $ tar xfz ##BP##-##PR##.tar.gz +--------------------------- + $ tar xf ##BP##-##PR##.tar.xz $ cd ##BP## $ test -d .git || git init . && git add . && git commit -m "U-Boot source code" && git gc $ git checkout -b WORKING $ for p in `ls -1 ../*.patch`; do git am $p; done -4.3 Get Git from community and apply STMicroelectronics patches - +4.3 Get Git from DENX community and apply STMicroelectronics patches +--------------------------------------------------------------- URL: git://git.denx.de/u-boot.git Branch: ##ARCHIVER_COMMUNITY_BRANCH## Revision: ##ARCHIVER_COMMUNITY_REVISION## @@ -89,38 +95,53 @@ or $ cd u-boot $ git checkout -b WORKING ##ARCHIVER_COMMUNITY_REVISION## - $ for p in `ls -1 ../*.patch`; do git am $p; done + $ for p in `ls -1 /*.patch`; do git am $p; done -5. Compilation U-Boot source code: ----------------------------------- +----------------------------- +5. Compile U-Boot source code +----------------------------- To compile U-Boot source code, first move to U-Boot source: $ cd ##BP## or $ cd u-boot -5.1 Compilation for one target (one defconfig, one device tree) - and no FIP +5.1 Compilation for one target +------------------------------ + STM32MP series is selected by defconfig: stm32mp13_defconfig or stm32mp15_defconfig + Board is selected by the device tree name to use - see /board/st/stm32mp1/README for details + see /doc/board/st/stm32mp1.rst for details - $ make stm32mp15__defconfig + $ make _defconfig $ make DEVICE_TREE= all example: - a) trusted boot on ev1 - $ make stm32mp15_trusted_defconfig - $ make DEVICE_TREE=stm32mp157c-ev1 all + a) trusted boot on STM32MP157C-EV1 + $ make stm32mp15_defconfig + $ make DEVICE_TREE=stm32mp157c-ev1 all - b) basic boot on dk2 - $ make stm32mp15_basic_defconfig - $ make DEVICE_TREE=stm32mp157c-dk2 all + b) trusted boot on STM32MP135F-DK + $ make stm32mp13_defconfig + $ make DEVICE_TREE=stm32mp135f-dk all + + then u-boot.dtb and u-boot-nodtb.bin can be added in the an existing FIP file with: + $ fiptool update --verbose \ + --nt-fw u-boot-nodtb.bin \ + -hw-config u-boot.dtb \ + + + or used to create a FIP, see command in TF-A readme. + + warning: 'fiptool update' is not possible for signed FIP 5.2 Compilation for several targets: use Makefile.sdk (with FIP) +---------------------------------------------------------------- Calls the specific 'Makefile.sdk' provided to compile U-Boot: - Display 'Makefile.sdk' file default configuration and targets: $ make -f $PWD/../Makefile.sdk help -As mentionned in help, OpenSTLinux has activated FIP by default, so the FIP_artifacts should be specified - - In case of using SOURCES-xxxx.tar.gz of Developer package the FIP_DEPLOYDIR_ROOT should be set as below: +Since OpenSTLinux activates FIP by default, FIP_artifacts directory path must be specified before launching compilation + - In case of using SOURCES-xxxx.tar.gz of Developer package the FIP_DEPLOYDIR_ROOT must be set as below: $> export FIP_DEPLOYDIR_ROOT=$PWD/../../FIP_artifacts - Compile default U-Boot configuration: @@ -137,6 +158,10 @@ Default U-Boot configuration is done in 'Makefile.sdk' file through specific var - 'UBOOT_DEVICETREE' is a list of device tree to build, using 'space' as separator. ex: UBOOT_DEVICETREE=" " +By default, the build results for this component are available in $PWD/../deploy directory. +If needed, this deploy directory can be specified by added "DEPLOYDIR=" compilation option to the build command line above. +In case DEPLOYDIR=$FIP_DEPLOYDIR_ROOT/u-boot it overwrites files directly in FIP artifacts directory. + The generated FIP images are available in $FIP_DEPLOYDIR_ROOT/fip You can override the default U-Boot configuration if you specify these variables: @@ -145,7 +170,8 @@ You can override the default U-Boot configuration if you specify these variables - Compile for a specific U-Boot configuration: $ make -f $PWD/../Makefile.sdk all UBOOT_CONFIG=trusted UBOOT_DEFCONFIG=stm32mp15_trusted_defconfig UBOOT_BINARY=u-boot.dtb DEVICETREE=stm32mp157f-dk2 -6. Update software on board: ----------------------------- +--------------------------- +6. Update software on board +--------------------------- Please use STM32CubeProgrammer and only tick the ssbl-boot and fip partition (more informations on the wiki website http://wiki.st.com/stm32mpu) diff --git a/recipes-bsp/u-boot/u-boot-stm32mp_2020.10.bb b/recipes-bsp/u-boot/u-boot-stm32mp_2021.10.bb similarity index 100% rename from recipes-bsp/u-boot/u-boot-stm32mp_2020.10.bb rename to recipes-bsp/u-boot/u-boot-stm32mp_2021.10.bb