diff --git a/recipes-bsp/u-boot/u-boot-stm32mp-archiver.inc b/recipes-bsp/u-boot/u-boot-stm32mp-archiver.inc index cc301a2..5faf149 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp-archiver.inc +++ b/recipes-bsp/u-boot/u-boot-stm32mp-archiver.inc @@ -43,8 +43,6 @@ archiver_create_makefile_for_sdk() { echo "LOCAL_PATH=\$(PWD)" >> ${ARCHIVER_OUTDIR}/Makefile.sdk echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo -n "EXTRA_OEMAKE=" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "${EXTRA_OEMAKE}" | sed "s|HOSTCC=${BUILD_CC}||" | sed "s|STAGING_INCDIR=${STAGING_INCDIR_NATIVE}||" | sed "s|STAGING_LIBDIR=${STAGING_LIBDIR_NATIVE}||" | sed "s|${BUILD_CFLAGS} ||" | sed "s|${BUILD_LDFLAGS}||" |sed "s|CC=\([^ ]*\) --sysroot=[^ ]* |CC=\"\1 \$(KCFLAGS)\" |" >> ${ARCHIVER_OUTDIR}/Makefile.sdk echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk echo "UBOOT_LOCALVERSION=${UBOOT_LOCALVERSION}" >> ${ARCHIVER_OUTDIR}/Makefile.sdk echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk @@ -93,11 +91,11 @@ archiver_create_makefile_for_sdk() { echo " if [ ! -d \$(LOCAL_PATH)/../build\$\$uboot_type ]; then \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk echo " mkdir -p \$(LOCAL_PATH)/../build\$\$uboot_type ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk echo " echo \$(UBOOT_LOCALVERSION) > \$(LOCAL_PATH)/../build\$\$uboot_type/.scmversion ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " \$(MAKE) \$(EXTRA_OEMAKE) -C \$(LOCAL_PATH) O=\$(LOCAL_PATH)/../build\$\$uboot_type \$\$uboot_config ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " \$(MAKE) -C \$(LOCAL_PATH) O=\$(LOCAL_PATH)/../build\$\$uboot_type \$\$uboot_config ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk echo " fi ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk # Build binaries echo " if [ -z \"\$(DEVICE_TREE)\" ]; then \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " \$(MAKE) \$(EXTRA_OEMAKE) -C \$(LOCAL_PATH) O=\$(LOCAL_PATH)/../build\$\$uboot_type ${UBOOT_MAKE_TARGET} ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " \$(MAKE) -C \$(LOCAL_PATH) O=\$(LOCAL_PATH)/../build\$\$uboot_type ${UBOOT_MAKE_TARGET} ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk # Copy binary files with explicit name echo " cp -f \$(LOCAL_PATH)/../build\$\$uboot_type/\$\$uboot_binary \$(LOCAL_PATH)/../build\$\$uboot_type/u-boot\$\$uboot_type.\$\$uboot_suffix ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk echo " cp -f \$(LOCAL_PATH)/../build\$\$uboot_type/${UBOOT_ELF} \$(LOCAL_PATH)/../build\$\$uboot_type/u-boot\$\$uboot_type.${UBOOT_ELF_SUFFIX} ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk @@ -107,7 +105,7 @@ archiver_create_makefile_for_sdk() { echo " fi ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk echo " else \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk echo " for devicetree in \$(DEVICE_TREE); do \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " \$(MAKE) \$(EXTRA_OEMAKE) -C \$(LOCAL_PATH) O=\$(LOCAL_PATH)/../build\$\$uboot_type ${UBOOT_MAKE_TARGET} DEVICE_TREE=\$\$devicetree ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " \$(MAKE) -C \$(LOCAL_PATH) O=\$(LOCAL_PATH)/../build\$\$uboot_type ${UBOOT_MAKE_TARGET} DEVICE_TREE=\$\$devicetree DEVICE_TREE_EXT=\$\$devicetree.dtb; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk # Copy binary files with explicit name echo " cp -f \$(LOCAL_PATH)/../build\$\$uboot_type/\$\$uboot_binary \$(LOCAL_PATH)/../build\$\$uboot_type/u-boot-\$\$devicetree\$\$uboot_type.\$\$uboot_suffix ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk echo " cp -f \$(LOCAL_PATH)/../build\$\$uboot_type/${UBOOT_ELF} \$(LOCAL_PATH)/../build\$\$uboot_type/u-boot-\$\$devicetree\$\$uboot_type.${UBOOT_ELF_SUFFIX} ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk diff --git a/recipes-bsp/u-boot/u-boot-stm32mp-common_2018.11.inc b/recipes-bsp/u-boot/u-boot-stm32mp-common_2018.11.inc deleted file mode 100644 index 620e61b..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp-common_2018.11.inc +++ /dev/null @@ -1,58 +0,0 @@ -# Adaptation from u-boot-common_${PV}.inc - -HOMEPAGE = "http://www.denx.de/wiki/U-Boot/WebHome" -SECTION = "bootloaders" - -LICENSE = "GPLv2+" -LIC_FILES_CHKSUM = "file://Licenses/README;md5=30503fd321432fc713238f582193b78e" - -DEPENDS += "dtc-native bc-native" -DEPENDS += "flex-native bison-native" - -COMPATIBLE_MACHINE = "(stm32mpcommon)" - -SRC_URI = "https://github.com/u-boot/u-boot/archive/v${PV}.tar.gz" -SRC_URI[md5sum] = "7ee14909d5d4d701fd3a6b12aad4d762" -SRC_URI[sha256sum] = "33b5cf99bac91d678ed6708be7b7cbbed36c45eb071e6228f83c25ad3a1de13a" - -SRC_URI += " \ - file://0001-ARM-v2018.11-stm32mp-r1-MACHINE.patch \ - file://0002-ARM-v2018.11-stm32mp-r1-BOARD.patch \ - file://0003-ARM-v2018.11-stm32mp-r1-DEVICETREE.patch \ - file://0004-ARM-v2018.11-stm32mp-r1-CONFIG.patch \ - file://0005-ARM-v2018.11-stm32mp-r1-MISC.patch \ - file://0006-ARM-v2018.11-stm32mp-r2-MACHINE.patch \ - file://0007-ARM-v2018.11-stm32mp-r2-DEVICETREE.patch \ - file://0008-ARM-v2018.11-stm32mp-r2-MISC.patch \ - file://0009-ARM-v2018.11-stm32mp-r3-MACHINE.patch \ - file://0010-ARM-v2018.11-stm32mp-r3-BOARD.patch \ - file://0011-ARM-v2018.11-stm32mp-r3-DEVICETREE.patch \ - file://0012-ARM-v2018.11-stm32mp-r3-CONFIG.patch \ - file://0013-ARM-v2018.11-stm32mp-r3-MISC.patch \ - file://0014-ARM-v2018.11-stm32mp-r4-MACHINE.patch \ - file://0015-ARM-v2018.11-stm32mp-r4-BOARD.patch \ - file://0016-ARM-v2018.11-stm32mp-r4-DEVICETREE.patch \ - file://0017-ARM-v2018.11-stm32mp-r4-MISC.patch \ - " - -U_BOOT_VERSION = "2018.11" -PV = "${U_BOOT_VERSION}" - -S = "${WORKDIR}/u-boot-${PV}" - -# --------------------------------- -# Configure devupstream class usage -# --------------------------------- -BBCLASSEXTEND = "devupstream:target" - -SRC_URI_class-devupstream = "git://github.com/STMicroelectronics/u-boot.git;name=uboot;protocol=https;branch=v2018.11-stm32mp" -SRCREV_class-devupstream = "fd915f073fe23fea3eb509dbc26ac9da1893692a" -SRCREV_FORMAT_class-devupstream = "uboot" -PV_class-devupstream = "${U_BOOT_VERSION}+github+${SRCPV}" - -# --------------------------------- -# Configure default preference to manage dynamic selection between tarball and github -# --------------------------------- -STM32MP_SOURCE_SELECTION ?= "tarball" - -DEFAULT_PREFERENCE = "${@bb.utils.contains('STM32MP_SOURCE_SELECTION', 'github', '-1', '1', d)}" diff --git a/recipes-bsp/u-boot/u-boot-stm32mp-common_2020.01.inc b/recipes-bsp/u-boot/u-boot-stm32mp-common_2020.01.inc new file mode 100644 index 0000000..5bfead6 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp-common_2020.01.inc @@ -0,0 +1,47 @@ +# Adaptation from u-boot-common_${PV}.inc + +HOMEPAGE = "http://www.denx.de/wiki/U-Boot/WebHome" +SECTION = "bootloaders" + +LICENSE = "GPLv2+" +LIC_FILES_CHKSUM = "file://Licenses/README;md5=30503fd321432fc713238f582193b78e" + +DEPENDS += "dtc-native bc-native" +DEPENDS += "flex-native bison-native" + +COMPATIBLE_MACHINE = "(stm32mpcommon)" + +SRC_URI = "git://github.com/u-boot/u-boot.git;protocol=https" +SRCREV = "0b0c6af38738f2c132cfd41a240889acaa031c8f" + +SRC_URI += "\ + file://0001-ARM-v2020.01-stm32mp-r1-MACHINE.patch \ + file://0002-ARM-v2020.01-stm32mp-r1-BOARD.patch \ + file://0003-ARM-v2020.01-stm32mp-r1-MISC-DRIVERS.patch \ + file://0004-ARM-v2020.01-stm32mp-r1-DEVICETREE.patch \ + file://0005-ARM-v2020.01-stm32mp-r1-CONFIG.patch \ + \ + file://0099-Add-external-var-to-allow-build-of-new-devicetree-fi.patch \ +" + +U_BOOT_VERSION = "2020.01" +PV = "${U_BOOT_VERSION}" + +S = "${WORKDIR}/git" + +# --------------------------------- +# Configure devupstream class usage +# --------------------------------- +#BBCLASSEXTEND = "devupstream:target" + +#SRC_URI_class-devupstream = "git://github.com/STMicroelectronics/u-boot.git;name=uboot;protocol=https;branch=v2018.11-stm32mp" +#SRCREV_class-devupstream = "a120b9bdb3e656bb2f0485924d77d58e2281311a" +#SRCREV_FORMAT_class-devupstream = "uboot" +#PV_class-devupstream = "${U_BOOT_VERSION}+github+${SRCPV}" + +# --------------------------------- +# Configure default preference to manage dynamic selection between tarball and github +# --------------------------------- +#STM32MP_SOURCE_SELECTION ?= "tarball" + +#DEFAULT_PREFERENCE = "${@bb.utils.contains('STM32MP_SOURCE_SELECTION', 'github', '-1', '1', d)}" diff --git a/recipes-bsp/u-boot/u-boot-stm32mp.inc b/recipes-bsp/u-boot/u-boot-stm32mp.inc index b1029e7..e05948e 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp.inc +++ b/recipes-bsp/u-boot/u-boot-stm32mp.inc @@ -2,11 +2,9 @@ require recipes-bsp/u-boot/u-boot.inc FILESEXTRAPATHS_prepend := "${THISDIR}/u-boot-stm32mp:" -PROVIDES += "u-boot" -RPROVIDES_${PN} += "u-boot" - # Configure build dir for externalsrc class usage through devtool EXTERNALSRC_BUILD_pn-${PN} = "${WORKDIR}/build" +B = "${WORKDIR}/build" # Define dedicated var to configure SPL binary name to override U-Boot default # configuration. By this way we allow to mix configuration with and without SPL @@ -74,7 +72,7 @@ do_compile_append() { then rm ${B}/${config}/dts/dt.dtb fi - oe_runmake -C ${S} O=${B}/${config} DEVICE_TREE=${devicetree} + oe_runmake -C ${S} O=${B}/${config} DEVICE_TREE=${devicetree} DEVICE_TREE_EXT=${devicetree}.dtb for binary in ${UBOOT_BINARIES}; do binarysuffix=$(echo ${binary} | cut -d'.' -f2) k=$(expr $k + 1); @@ -109,6 +107,7 @@ do_compile_append() { # ----------------------------------------------------------------------------- # Append deploy to handle specific device tree binary deployement # +do_deploy[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}/bootloader" do_deploy_append() { if [ -n "${UBOOT_DEVICETREE}" ]; then # Clean deploydir from any available binary first diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0001-ARM-v2018.11-stm32mp-r1-MACHINE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0001-ARM-v2020.01-stm32mp-r1-MACHINE.patch similarity index 52% rename from recipes-bsp/u-boot/u-boot-stm32mp/0001-ARM-v2018.11-stm32mp-r1-MACHINE.patch rename to recipes-bsp/u-boot/u-boot-stm32mp/0001-ARM-v2020.01-stm32mp-r1-MACHINE.patch index 29c68b0..8888864 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0001-ARM-v2018.11-stm32mp-r1-MACHINE.patch +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0001-ARM-v2020.01-stm32mp-r1-MACHINE.patch @@ -1,211 +1,265 @@ -From 5851da1728ac705c8fa9079c68c883a73a32fae8 Mon Sep 17 00:00:00 2001 -From: christophe montaud -Date: Fri, 4 Jan 2019 15:02:23 +0100 -Subject: [PATCH 1/5] ARM v2018.11 stm32mp r1 MACHINE +From c4b103412f1a8cd3472b9d82f7d73737803cf7e7 Mon Sep 17 00:00:00 2001 +From: Romuald JEANNE +Date: Fri, 5 Jun 2020 13:41:19 +0200 +Subject: [PATCH 1/5] ARM v2020.01-stm32mp-r1 MACHINE --- - arch/arm/Kconfig | 10 +- - arch/arm/cpu/armv7/arch_timer.c | 3 + - arch/arm/include/asm/arch-stm32/gpio.h | 5 + - arch/arm/mach-stm32mp/Kconfig | 108 +- - arch/arm/mach-stm32mp/Makefile | 8 +- - arch/arm/mach-stm32mp/bsec.c | 64 +- - arch/arm/mach-stm32mp/cmd_poweroff.c | 24 + - arch/arm/mach-stm32mp/cmd_stm32key.c | 100 ++ + .gitignore | 3 + + CONTRIBUTING.md | 30 + + MAINTAINERS | 1 + + Makefile | 2 +- + arch/arm/lib/bootm.c | 3 + + arch/arm/lib/crt0.S | 3 +- + arch/arm/mach-stm32mp/Kconfig | 79 +- + arch/arm/mach-stm32mp/Makefile | 4 +- + arch/arm/mach-stm32mp/boot_params.c | 45 + + arch/arm/mach-stm32mp/bsec.c | 121 +- arch/arm/mach-stm32mp/cmd_stm32prog/Makefile | 9 + - .../arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c | 80 + - arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 1647 ++++++++++++++++++++ - arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h | 202 +++ - .../mach-stm32mp/cmd_stm32prog/stm32prog_serial.c | 972 ++++++++++++ - .../arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c | 278 ++++ - arch/arm/mach-stm32mp/config.mk | 16 +- - arch/arm/mach-stm32mp/cpu.c | 236 ++- - arch/arm/mach-stm32mp/include/mach/ddr.h | 9 +- - arch/arm/mach-stm32mp/include/mach/gpio.h | 6 + - arch/arm/mach-stm32mp/include/mach/stm32.h | 37 +- - arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h | 75 + - arch/arm/mach-stm32mp/include/mach/sys_proto.h | 10 +- - arch/arm/mach-stm32mp/psci.c | 8 +- - arch/arm/mach-stm32mp/pwr_regulator.c | 8 + - arch/arm/mach-stm32mp/spl.c | 47 +- - arch/arm/mach-stm32mp/stm32-etzpc.c | 199 +++ - arch/arm/mach-stm32mp/syscon.c | 9 +- - 26 files changed, 4103 insertions(+), 67 deletions(-) - create mode 100644 arch/arm/mach-stm32mp/cmd_poweroff.c - create mode 100644 arch/arm/mach-stm32mp/cmd_stm32key.c + .../arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c | 191 +++ + arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 1743 ++++++++++++++++++++ + arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h | 185 +++ + .../mach-stm32mp/cmd_stm32prog/stm32prog_serial.c | 993 +++++++++++ + .../arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c | 232 +++ + arch/arm/mach-stm32mp/cpu.c | 107 +- + arch/arm/mach-stm32mp/dram_init.c | 18 + + arch/arm/mach-stm32mp/fdt.c | 132 +- + arch/arm/mach-stm32mp/include/mach/bsec.h | 7 + + arch/arm/mach-stm32mp/include/mach/ddr.h | 6 +- + arch/arm/mach-stm32mp/include/mach/stm32.h | 24 +- + arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h | 13 +- + arch/arm/mach-stm32mp/include/mach/stm32prog.h | 16 + + arch/arm/mach-stm32mp/include/mach/sys_proto.h | 24 +- + arch/arm/mach-stm32mp/psci.c | 22 + + arch/arm/mach-stm32mp/pwr_regulator.c | 31 +- + arch/arm/mach-stm32mp/spl.c | 43 +- + arch/arm/mach-stm32mp/syscon.c | 1 - + arch/sandbox/dts/test.dts | 85 +- + arch/sandbox/include/asm/gpio.h | 38 +- + 31 files changed, 4044 insertions(+), 167 deletions(-) + create mode 100644 CONTRIBUTING.md + create mode 100644 arch/arm/mach-stm32mp/boot_params.c create mode 100644 arch/arm/mach-stm32mp/cmd_stm32prog/Makefile create mode 100644 arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c create mode 100644 arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c create mode 100644 arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h create mode 100644 arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c create mode 100644 arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c - create mode 100644 arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h - create mode 100644 arch/arm/mach-stm32mp/stm32-etzpc.c + create mode 100644 arch/arm/mach-stm32mp/include/mach/bsec.h + create mode 100644 arch/arm/mach-stm32mp/include/mach/stm32prog.h -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 1f3fa15..e9eac9d 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -1313,21 +1313,27 @@ config ARCH_STM32MP - select DM_GPIO - select DM_RESET - select DM_SERIAL -+ select ENV_VARS_UBOOT_RUNTIME_CONFIG - select MISC - select OF_CONTROL - select OF_LIBFDT -+ imply OF_LIBFDT_OVERLAY -+ select OF_SYSTEM_SETUP - select PINCTRL - select REGMAP - select SUPPORT_SPL - select SYSCON - select SYSRESET -+ select SYS_ARCH_TIMER - select SYS_THUMB_BUILD - imply CMD_DM -+ imply CMD_POWEROFF - help - Support for STM32MP SoC family developed by STMicroelectronics, - MPUs based on ARM cortex A core -- U-BOOT is running in DDR and SPL support is the unsecure First Stage -- BootLoader (FSBL) -+ U-BOOT is running in DDR, loaded by the First Stage BootLoader (FSBL). -+ FBSL can be TF-A: Trusted Firmware for Cortex A, for trusted boot chain. -+ SPL is the unsecure FSBL for the basic boot chain. - - config ARCH_ROCKCHIP - bool "Support Rockchip SoCs" -diff --git a/arch/arm/cpu/armv7/arch_timer.c b/arch/arm/cpu/armv7/arch_timer.c -index 3db31c0..5de6305 100644 ---- a/arch/arm/cpu/armv7/arch_timer.c -+++ b/arch/arm/cpu/armv7/arch_timer.c -@@ -49,6 +49,9 @@ unsigned long long get_ticks(void) - - ulong timer_get_boot_us(void) - { -+ if (!gd->arch.timer_rate_hz) -+ timer_init(); +diff --git a/.gitignore b/.gitignore +index 2e1c8bf..bb2dfee 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -92,3 +92,6 @@ GTAGS + *.orig + *~ + \#*# + - return lldiv(get_ticks(), gd->arch.timer_rate_hz / 1000000); - } - -diff --git a/arch/arm/include/asm/arch-stm32/gpio.h b/arch/arm/include/asm/arch-stm32/gpio.h -index 84859b1..570e80a 100644 ---- a/arch/arm/include/asm/arch-stm32/gpio.h -+++ b/arch/arm/include/asm/arch-stm32/gpio.h -@@ -7,6 +7,8 @@ - #ifndef _GPIO_H_ - #define _GPIO_H_ - -+#define STM32_GPIOS_PER_BANK 16 ++/oe-* ++bitbake-cookerdaemon.log +diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md +new file mode 100644 +index 0000000..3d1bacd +--- /dev/null ++++ b/CONTRIBUTING.md +@@ -0,0 +1,30 @@ ++# Contributing guide + - enum stm32_gpio_port { - STM32_GPIO_PORT_A = 0, - STM32_GPIO_PORT_B, -@@ -109,6 +111,9 @@ struct stm32_gpio_regs { - - struct stm32_gpio_priv { - struct stm32_gpio_regs *regs; -+ unsigned int gpio_range; - }; - -+int stm32_offset_to_index(struct udevice *dev, unsigned int offset); ++This document serves as a checklist before contributing to this repository. It includes links to read up on if topics are unclear to you. + - #endif /* _GPIO_H_ */ ++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 438fb22..afc2f19 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -337,6 +337,7 @@ L: uboot-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers) + T: git https://gitlab.denx.de/u-boot/custodians/u-boot-stm.git + S: Maintained + F: arch/arm/mach-stm32mp/ ++F: doc/board/st/ + F: drivers/adc/stm32-adc* + F: drivers/clk/clk_stm32mp1.c + F: drivers/gpio/stm32_gpio.c +diff --git a/Makefile b/Makefile +index 1766f5a..8b390bc 100644 +--- a/Makefile ++++ b/Makefile +@@ -3,7 +3,7 @@ + VERSION = 2020 + PATCHLEVEL = 01 + SUBLEVEL = +-EXTRAVERSION = ++EXTRAVERSION = -stm32mp-r1 + NAME = + + # *DOCUMENTATION* +diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c +index 769a642..9453c09 100644 +--- a/arch/arm/lib/bootm.c ++++ b/arch/arm/lib/bootm.c +@@ -74,6 +74,9 @@ void arch_lmb_reserve(struct lmb *lmb) + gd->bd->bi_dram[bank].size - 1; + if (sp > bank_end) + continue; ++ if (bank_end > gd->ram_top) ++ bank_end = gd->ram_top - 1; ++ + lmb_reserve(lmb, sp, bank_end - sp + 1); + break; + } +diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S +index fb6c37c..df9dd83 100644 +--- a/arch/arm/lib/crt0.S ++++ b/arch/arm/lib/crt0.S +@@ -127,8 +127,7 @@ ENTRY(_main) + ldr r0, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */ + bic r0, r0, #7 /* 8-byte alignment for ABI compliance */ + mov sp, r0 +- ldr r9, [r9, #GD_BD] /* r9 = gd->bd */ +- sub r9, r9, #GD_SIZE /* new GD is below bd */ ++ ldr r9, [r9, #GD_NEW_GD] /* r9 <- gd->new_gd */ + + adr lr, here + ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */ diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig -index 8a929fa..0c68c24 100644 +index ae28f6e..f9f7943 100644 --- a/arch/arm/mach-stm32mp/Kconfig +++ b/arch/arm/mach-stm32mp/Kconfig -@@ -16,8 +16,12 @@ config SPL - select SPL_REGMAP - select SPL_DM_RESET - select SPL_SERIAL_SUPPORT -+ select SPL_SPI_LOAD - select SPL_SYSCON -- select SPL_DRIVERS_MISC_SUPPORT -+ select SPL_WATCHDOG_SUPPORT -+ imply BOOTSTAGE_STASH if SPL_BOOTSTAGE -+ imply SPL_BOOTSTAGE -+ imply SPL_DISPLAY_PRINT - imply SPL_LIBDISK_SUPPORT +@@ -33,8 +33,8 @@ config SYS_MALLOC_LEN + config ENV_SIZE + default 0x2000 - config SYS_SOC -@@ -25,18 +29,87 @@ config SYS_SOC - - config TARGET_STM32MP1 - bool "Support stm32mp1xx" -- select ARCH_SUPPORT_PSCI -+ select ARCH_SUPPORT_PSCI if !STM32MP1_TRUSTED +-config TARGET_STM32MP1 +- bool "Support stm32mp1xx" ++config STM32MP15x ++ bool "Support STMicroelectronics STM32MP15x Soc" + select ARCH_SUPPORT_PSCI if !STM32MP1_TRUSTED select CPU_V7A -- select CPU_V7_HAS_NONSEC -+ select CPU_V7_HAS_NONSEC if !STM32MP1_TRUSTED - select CPU_V7_HAS_VIRT -+ select OF_BOARD_SETUP - select PINCTRL_STM32 - select STM32_RCC + select CPU_V7_HAS_NONSEC if !STM32MP1_TRUSTED +@@ -45,19 +45,47 @@ config TARGET_STM32MP1 select STM32_RESET -- select SYS_ARCH_TIMER -- select SYSRESET_SYSCON -+ select STM32_SERIAL -+ imply BOOTCOUNT_LIMIT + select STM32_SERIAL + select SYS_ARCH_TIMER ++ imply CMD_NVEDIT_INFO + imply SYSRESET_PSCI if STM32MP1_TRUSTED + imply SYSRESET_SYSCON if !STM32MP1_TRUSTED ++ 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 ++ ++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 +- imply SYSRESET_PSCI if STM32MP1_TRUSTED +- imply SYSRESET_SYSCON if !STM32MP1_TRUSTED ++ imply VERSION_VARIABLE help - target STMicroelectronics SOC STM32MP1 family -+ STM32MP153 or STM32MP151 - STMicroelectronics MPU with core ARMv7 -+ dual core A7 for STM32MP153, monocore for STM32MP151 +- target STMicroelectronics SOC STM32MP1 family +- STM32MP157, STM32MP153 or STM32MP151 +- STMicroelectronics MPU with core ARMv7 +- dual core A7 for STM32MP157/3, monocore for STM32MP151 ++ 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 STM32MP1_TRUSTED -+ bool "Support trusted boot with TF-A" -+ default y if !SPL -+ select ARM_SMCCC ++config TARGET_DH_STM32MP1_PDK2 ++ bool "DH STM32MP1 PDK2" ++ select STM32MP15x ++ imply BOOTCOUNT_LIMIT ++ imply CMD_BOOTCOUNT + help -+ Say Y here to enable boot with TF-A -+ Trusted boot chain is : -+ BootRom => TF-A.stm32 (clock & DDR) => U-Boot.stm32 -+ TF-A monitor provide ST smc to manage secure devices -+ -+config STM32MP1_OPTEE -+ bool "Support trusted boot with TF-A and OPTEE" -+ depends on STM32MP1_TRUSTED -+ default n -+ help -+ Say Y here to enable boot with TF-A and OPTEE -+ Trusted boot chain is : -+ BootRom => TF-A.stm32 (clock & DDR) => OPTEE => U-Boot.stm32 -+ OPTEE monitor provide ST smc to manage secure devices -+ -+config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2 -+ hex "Partition to use for MMC2 to load U-Boot from" -+ depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION && TARGET_STM32MP1 -+ default 1 -+ help -+ Partition on the MMC2 to load U-Boot from when the MMC2 is being -+ used in raw mode -+ -+config STM32_ETZPC -+ bool "STM32 Extended TrustZone Protection" -+ depends on TARGET_STM32MP1 -+ default y -+ help -+ Say y to enable STM32 Extended TrustZone Protection -+ Controller (ETZPC) -+ -+source "board/st/stm32mp1/Kconfig" ++ Target the DH PDK2 development kit with STM32MP15x SoM. + ++endchoice + + config STM32MP1_TRUSTED + bool "Support trusted boot with TF-A" +@@ -69,23 +97,8 @@ config STM32MP1_TRUSTED + BootRom => TF-A.stm32 (clock & DDR) => U-Boot.stm32 + TF-A monitor provides proprietary SMC to manage secure devices + +-config STM32MP1_OPTEE +- bool "Support trusted boot with TF-A and OP-TEE" +- depends on STM32MP1_TRUSTED +- default n +- help +- Say Y here to enable boot with TF-A and OP-TEE +- Trusted boot chain is : +- BootRom => TF-A.stm32 (clock & DDR) => OP-TEE => U-Boot.stm32 +- OP-TEE monitor provides ST SMC to access to secure resources +- + config SYS_TEXT_BASE +- prompt "U-Boot base address" + default 0xC0100000 +- help +- configure the U-Boot base address +- when DDR driver is used: +- DDR + 1MB (0xC0100000) + + config NR_DRAM_BANKS + default 1 +@@ -100,11 +113,28 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2 + + config STM32_ETZPC + bool "STM32 Extended TrustZone Protection" +- depends on TARGET_STM32MP1 ++ depends on STM32MP15x + default y + help + Say y to enable STM32 Extended TrustZone Protection + +config CMD_STM32PROG + bool "command stm32prog for STM32CudeProgrammer" -+ default y -+ depends on CMD_DFU -+ imply CMD_GPT if MMC -+ imply DFU_MMC if MMC -+ imply DFU_NAND if NAND ++ select DFU + select DFU_RAM -+ imply DFU_SF if DM_SPI_FLASH + 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, @@ -213,370 +267,348 @@ index 8a929fa..0c68c24 100644 + 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 -+ depends on CMD_FUSE -+ help -+ fuse public key hash in corresponding fuse used to authenticate -+ binary. - - config SYS_TEXT_BASE - prompt "U-Boot base address" -@@ -46,22 +119,23 @@ config SYS_TEXT_BASE - when DDR driver is used: - DDR + 1MB (0xC0100000) - --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 -+config NR_DRAM_BANKS - default 1 -- help -- Partition on the second MMC to load U-Boot from when the MMC is being -- used in raw mode - --source "board/st/stm32mp1/Kconfig" -+config BOOTSTAGE_STASH_ADDR -+ default 0xC3000000 - --# currently activated for debug / should be deactivated for real product --if DEBUG_UART - --config DEBUG_UART_BOARD_INIT -+if BOOTCOUNT_LIMIT -+config SYS_BOOTCOUNT_SINGLEWORD + config CMD_STM32KEY + bool "command stm32key to fuse public key hash" default y - -+# TAMP_BOOTCOUNT = TAMP_BACKUP_REGISTER(21) -+config SYS_BOOTCOUNT_ADDR -+ default 0x5C00A154 -+endif -+ -+if DEBUG_UART - # debug on UART4 by default - config DEBUG_UART_BASE - default 0x40010000 -@@ -69,6 +143,10 @@ config DEBUG_UART_BASE - # clock source is HSI on reset - config DEBUG_UART_CLOCK - default 64000000 -+ -+# currently activated for debug / should be deactivated for real product -+config DEBUG_UART_BOARD_INIT -+ default y +@@ -147,5 +177,6 @@ config DEBUG_UART_CLOCK endif + source "board/st/stm32mp1/Kconfig" ++source "board/dhelectronics/dh_stm32mp1/Kconfig" + endif diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile -index f59ced5..09636db 100644 +index eee39c2..1fdacf4 100644 --- a/arch/arm/mach-stm32mp/Makefile +++ b/arch/arm/mach-stm32mp/Makefile -@@ -10,7 +10,13 @@ obj-y += syscon.o +@@ -6,13 +6,15 @@ + obj-y += cpu.o + obj-y += dram_init.o + obj-y += syscon.o ++obj-y += bsec.o + ifdef CONFIG_SPL_BUILD obj-y += spl.o else +-obj-y += bsec.o +obj-$(CONFIG_CMD_STM32PROG) += cmd_stm32prog/ -+obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o -+ -+obj-$(CONFIG_ARMV7_PSCI) += psci.o - obj-y += bsec.o -+obj-y += cmd_poweroff.o + obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o + obj-$(CONFIG_ARMV7_PSCI) += psci.o ++obj-$(CONFIG_STM32MP1_TRUSTED) += boot_params.o endif --obj-$(CONFIG_ARMV7_PSCI) += psci.o -+ + obj-$(CONFIG_$(SPL_)DM_REGULATOR) += pwr_regulator.o -+obj-$(CONFIG_STM32_ETZPC) += stm32-etzpc.o +diff --git a/arch/arm/mach-stm32mp/boot_params.c b/arch/arm/mach-stm32mp/boot_params.c +new file mode 100644 +index 0000000..e4351de +--- /dev/null ++++ b/arch/arm/mach-stm32mp/boot_params.c +@@ -0,0 +1,45 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include ++#include ++#include ++ ++/* ++ * Force data-section, as .bss will not be valid ++ * when save_boot_params is invoked. ++ */ ++static unsigned long nt_fw_dtb __section(".data"); ++ ++/* ++ * Save the FDT address provided by TF-A in r2 at boot time ++ * This function is called from start.S ++ */ ++void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2, ++ unsigned long r3) ++{ ++ nt_fw_dtb = r2; ++ ++ save_boot_params_ret(); ++} ++ ++/* ++ * Use the saved FDT address provided by TF-A at boot time (NT_FW_CONFIG = ++ * Non Trusted Firmware configuration file) when the pointer is valid ++ */ ++void *board_fdt_blob_setup(void) ++{ ++ debug("%s: nt_fw_dtb=%lx\n", __func__, nt_fw_dtb); ++ ++ /* use external device tree only if address is valid */ ++ if (nt_fw_dtb >= STM32_DDR_BASE) { ++ if (fdt_magic(nt_fw_dtb) == FDT_MAGIC) ++ return (void *)nt_fw_dtb; ++ debug("%s: DTB not found.\n", __func__); ++ } ++ debug("%s: fall back to builtin DTB, %p\n", __func__, &_end); ++ ++ return (void *)&_end; ++} diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c -index 0e152ef..913dbef 100644 +index a77c706..7e04ddd 100644 --- a/arch/arm/mach-stm32mp/bsec.c +++ b/arch/arm/mach-stm32mp/bsec.c -@@ -1,4 +1,4 @@ --// SPDX-License-Identifier: GPL-2.0+ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause - /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved - */ -@@ -7,10 +7,14 @@ +@@ -7,13 +7,12 @@ #include #include #include -+#include -+#include ++#include + #include + #include #include #define BSEC_OTP_MAX_VALUE 95 - -+#ifndef CONFIG_STM32MP1_TRUSTED -+ +- +-#ifndef CONFIG_STM32MP1_TRUSTED #define BSEC_TIMEOUT_US 10000 /* BSEC REGISTER OFFSET (base relative) */ -@@ -168,7 +172,7 @@ static int bsec_shadow_register(u32 base, u32 otp) - ret = bsec_power_safmem(base, true); - if (ret) - return ret; -- power_up = 1; -+ power_up = true; - } - /* set BSEC_OTP_CTRL_OFF with the otp value*/ - writel(otp | BSEC_READ, base + BSEC_OTP_CTRL_OFF); -@@ -270,6 +274,7 @@ static int bsec_program_otp(long base, u32 val, u32 otp) +@@ -22,11 +21,13 @@ + #define BSEC_OTP_WRDATA_OFF 0x008 + #define BSEC_OTP_STATUS_OFF 0x00C + #define BSEC_OTP_LOCK_OFF 0x010 ++#define BSEC_DENABLE_OFF 0x014 + #define BSEC_DISTURBED_OFF 0x01C + #define BSEC_ERROR_OFF 0x034 +-#define BSEC_SPLOCK_OFF 0x064 /* Program safmem sticky lock */ +-#define BSEC_SWLOCK_OFF 0x07C /* write in OTP sticky lock */ +-#define BSEC_SRLOCK_OFF 0x094 /* shadowing sticky lock */ ++#define BSEC_WRLOCK_OFF 0x04C /* OTP write permananet lock */ ++#define BSEC_SPLOCK_OFF 0x064 /* OTP write sticky lock */ ++#define BSEC_SWLOCK_OFF 0x07C /* shadow write sticky lock */ ++#define BSEC_SRLOCK_OFF 0x094 /* shadow read sticky lock */ + #define BSEC_OTP_DATA_OFF 0x200 - return ret; - } -+#endif /* CONFIG_STM32MP1_TRUSTED */ + /* BSEC_CONFIGURATION Register MASK */ +@@ -46,6 +47,9 @@ + #define BSEC_MODE_PROGFAIL_MASK 0x10 + #define BSEC_MODE_PWR_MASK 0x20 - /* BSEC MISC driver *******************************************************/ - struct stm32mp_bsec_platdata { -@@ -278,6 +283,11 @@ struct stm32mp_bsec_platdata { ++/* DENABLE Register */ ++#define BSEC_DENABLE_DBGSWENABLE BIT(10) ++ + /* + * OTP Lock services definition + * Value must corresponding to the bit number in the register +@@ -53,12 +57,12 @@ + #define BSEC_LOCK_PROGRAM 0x04 - static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp) + /** +- * bsec_check_error() - Check status of one otp +- * @base: base address of bsec IP ++ * bsec_lock() - manage lock for each type SR/SP/SW ++ * @address: address of bsec IP register + * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) +- * Return: 0 if no error, -EAGAIN or -ENOTSUPP ++ * Return: true if locked else false + */ +-static u32 bsec_check_error(u32 base, u32 otp) ++static bool bsec_read_lock(u32 address, u32 otp) { -+#ifdef CONFIG_STM32MP1_TRUSTED -+ return stm32_smc(STM32_SMC_BSEC, -+ STM32_SMC_READ_OTP, -+ otp, 0, val); -+#else - struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); - u32 tmp_data = 0; - int ret; -@@ -299,27 +309,46 @@ static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp) - /* restore shadow value */ - ret = bsec_write_shadow(plat->base, tmp_data, otp); - return ret; -+#endif + u32 bit; + u32 bank; +@@ -66,21 +70,17 @@ static u32 bsec_check_error(u32 base, u32 otp) + bit = 1 << (otp & OTP_LOCK_MASK); + bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32); + +- if (readl(base + BSEC_DISTURBED_OFF + bank) & bit) +- return -EAGAIN; +- else if (readl(base + BSEC_ERROR_OFF + bank) & bit) +- return -ENOTSUPP; +- +- return 0; ++ return !!(readl(address + bank) & bit); } - static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp) ++#ifndef CONFIG_STM32MP1_TRUSTED + /** +- * bsec_lock() - manage lock for each type SR/SP/SW +- * @address: address of bsec IP register ++ * bsec_check_error() - Check status of one otp ++ * @base: base address of bsec IP + * @otp: otp number (0 - BSEC_OTP_MAX_VALUE) +- * Return: true if locked else false ++ * Return: 0 if no error, -EAGAIN or -ENOTSUPP + */ +-static bool bsec_read_lock(u32 address, u32 otp) ++static u32 bsec_check_error(u32 base, u32 otp) { -+#ifdef CONFIG_STM32MP1_TRUSTED -+ return stm32_smc(STM32_SMC_BSEC, -+ STM32_SMC_READ_SHADOW, -+ otp, 0, val); -+#else - struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); + u32 bit; + u32 bank; +@@ -88,7 +88,12 @@ static bool bsec_read_lock(u32 address, u32 otp) + bit = 1 << (otp & OTP_LOCK_MASK); + bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32); - return bsec_read_shadow(plat->base, val, otp); -+#endif +- return !!(readl(address + bank) & bit); ++ if (readl(base + BSEC_DISTURBED_OFF + bank) & bit) ++ return -EAGAIN; ++ else if (readl(base + BSEC_ERROR_OFF + bank) & bit) ++ return -ENOTSUPP; ++ ++ return 0; } + /** +@@ -324,6 +329,16 @@ static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp) + #endif + } + ++static int stm32mp_bsec_read_lock(struct udevice *dev, u32 *val, u32 otp) ++{ ++ struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); ++ ++ /* return OTP permanent write lock status */ ++ *val = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp); ++ ++ return 0; ++} ++ static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp) { -+#ifdef CONFIG_STM32MP1_TRUSTED -+ return stm32_smc_exec(STM32_SMC_BSEC, -+ STM32_SMC_PROG_OTP, -+ otp, val); -+#else - struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); - - return bsec_program_otp(plat->base, val, otp); -+#endif + #ifdef CONFIG_STM32MP1_TRUSTED +@@ -350,22 +365,41 @@ static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp) + #endif } - 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) ++{ +#ifdef CONFIG_STM32MP1_TRUSTED -+ return stm32_smc_exec(STM32_SMC_BSEC, -+ STM32_SMC_WRITE_SHADOW, -+ otp, val); ++ if (val == 1) ++ return stm32_smc_exec(STM32_SMC_BSEC, ++ STM32_SMC_WRLOCK_OTP, ++ otp, 0); ++ if (val == 0) ++ return 0; /* nothing to do */ ++ ++ return -EINVAL; +#else - struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); - - return bsec_write_shadow(plat->base, val, otp); ++ return -ENOTSUPP; +#endif - } - ++} ++ static int stm32mp_bsec_read(struct udevice *dev, int offset, -@@ -405,8 +434,23 @@ static int stm32mp_bsec_ofdata_to_platdata(struct udevice *dev) + void *buf, int size) + { + int ret; + int i; +- bool shadow = true; ++ bool shadow = true, lock = false; + int nb_otp = size / sizeof(u32); + int otp; + unsigned int offs = offset; + +- if (offs >= STM32_BSEC_OTP_OFFSET) { ++ if (offs >= STM32_BSEC_LOCK_OFFSET) { ++ offs -= STM32_BSEC_LOCK_OFFSET; ++ lock = true; ++ } else if (offs >= STM32_BSEC_OTP_OFFSET) { + offs -= STM32_BSEC_OTP_OFFSET; + shadow = false; + } + +- if (offs < 0 || (offs % 4) || (size % 4)) ++ if ((offs % 4) || (size % 4)) + return -EINVAL; + + otp = offs / sizeof(u32); +@@ -373,7 +407,9 @@ static int stm32mp_bsec_read(struct udevice *dev, int offset, + for (i = otp; i < (otp + nb_otp) && i <= BSEC_OTP_MAX_VALUE; i++) { + u32 *addr = &((u32 *)buf)[i - otp]; + +- if (shadow) ++ if (lock) ++ ret = stm32mp_bsec_read_lock(dev, addr, i); ++ else if (shadow) + ret = stm32mp_bsec_read_shadow(dev, addr, i); + else + ret = stm32mp_bsec_read_otp(dev, addr, i); +@@ -392,17 +428,20 @@ static int stm32mp_bsec_write(struct udevice *dev, int offset, + { + int ret = 0; + int i; +- bool shadow = true; ++ bool shadow = true, lock = false; + int nb_otp = size / sizeof(u32); + int otp; + unsigned int offs = offset; + +- if (offs >= STM32_BSEC_OTP_OFFSET) { ++ if (offs >= STM32_BSEC_LOCK_OFFSET) { ++ offs -= STM32_BSEC_LOCK_OFFSET; ++ lock = true; ++ } else if (offs >= STM32_BSEC_OTP_OFFSET) { + offs -= STM32_BSEC_OTP_OFFSET; + shadow = false; + } + +- if (offs < 0 || (offs % 4) || (size % 4)) ++ if ((offs % 4) || (size % 4)) + return -EINVAL; + + otp = offs / sizeof(u32); +@@ -410,7 +449,9 @@ static int stm32mp_bsec_write(struct udevice *dev, int offset, + for (i = otp; i < otp + nb_otp && i <= BSEC_OTP_MAX_VALUE; i++) { + u32 *val = &((u32 *)buf)[i - otp]; + +- if (shadow) ++ if (lock) ++ ret = stm32mp_bsec_write_lock(dev, *val, i); ++ else if (shadow) + ret = stm32mp_bsec_write_shadow(dev, *val, i); + else + ret = stm32mp_bsec_write_otp(dev, *val, i); +@@ -437,7 +478,7 @@ static int stm32mp_bsec_ofdata_to_platdata(struct udevice *dev) return 0; } -+#ifndef CONFIG_STM32MP1_TRUSTED -+static int stm32mp_bsec_probe(struct udevice *dev) -+{ -+ int otp; -+ struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); -+ -+ /* update unlocked shadow for OTP cleared by the rom code */ -+ for (otp = 57; otp <= BSEC_OTP_MAX_VALUE; otp++) -+ if (!bsec_read_SR_lock(plat->base, otp)) -+ bsec_shadow_register(plat->base, otp); -+ -+ return 0; -+} -+#endif -+ - static const struct udevice_id stm32mp_bsec_ids[] = { -- { .compatible = "st,stm32mp-bsec" }, -+ { .compatible = "st,stm32mp15-bsec" }, - {} - }; - -@@ -417,15 +461,7 @@ U_BOOT_DRIVER(stm32mp_bsec) = { +-#ifndef CONFIG_STM32MP1_TRUSTED ++#if !defined(CONFIG_STM32MP1_TRUSTED) && !defined(CONFIG_SPL_BUILD) + static int stm32mp_bsec_probe(struct udevice *dev) + { + int otp; +@@ -464,7 +505,27 @@ U_BOOT_DRIVER(stm32mp_bsec) = { .ofdata_to_platdata = stm32mp_bsec_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct stm32mp_bsec_platdata), .ops = &stm32mp_bsec_ops, -- .flags = DM_FLAG_PRE_RELOC, --}; -- --/* bsec IP is not present in device tee, manage IP address by platdata */ --static struct stm32mp_bsec_platdata stm32_bsec_platdata = { -- .base = STM32_BSEC_BASE, --}; -- --U_BOOT_DEVICE(stm32mp_bsec) = { -- .name = "stm32mp_bsec", -- .platdata = &stm32_bsec_platdata, -+#ifndef CONFIG_STM32MP1_TRUSTED -+ .probe = stm32mp_bsec_probe, -+#endif +-#ifndef CONFIG_STM32MP1_TRUSTED ++#if !defined(CONFIG_STM32MP1_TRUSTED) && !defined(CONFIG_SPL_BUILD) + .probe = stm32mp_bsec_probe, + #endif }; -diff --git a/arch/arm/mach-stm32mp/cmd_poweroff.c b/arch/arm/mach-stm32mp/cmd_poweroff.c -new file mode 100644 -index 0000000..a6fdc79 ---- /dev/null -+++ b/arch/arm/mach-stm32mp/cmd_poweroff.c -@@ -0,0 +1,24 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ + -+#include -+#include -+#include -+ -+int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -+{ -+ int ret; -+ -+ puts("poweroff ...\n"); -+ mdelay(100); -+ -+ ret = sysreset_walk(SYSRESET_POWER); -+ -+ if (ret == -EINPROGRESS) -+ mdelay(1000); -+ -+ /*NOTREACHED when power off*/ -+ return CMD_RET_FAILURE; -+} -diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c -new file mode 100644 -index 0000000..4245e6f ---- /dev/null -+++ b/arch/arm/mach-stm32mp/cmd_stm32key.c -@@ -0,0 +1,100 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define STM32_OTP_HASH_KEY_START 24 -+#define STM32_OTP_HASH_KEY_SIZE 8 -+ -+static void read_hash_value(u32 addr) -+{ -+ int i; -+ -+ 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)); -+ addr += 4; -+ } -+} -+ -+static void fuse_hash_value(u32 addr, bool print) ++bool bsec_dbgswenable(void) +{ + struct udevice *dev; -+ u32 word, val; -+ int i, ret; ++ struct stm32mp_bsec_platdata *plat; ++ 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; ++ DM_GET_DRIVER(stm32mp_bsec), &dev); ++ if (ret || !dev) { ++ pr_debug("bsec driver not available\n"); ++ return false; + } + -+ for (i = 0; i < STM32_OTP_HASH_KEY_SIZE; i++) { -+ if (print) -+ printf("Fuse OTP %i : %x\n", -+ STM32_OTP_HASH_KEY_START + i, -+ __be32_to_cpu(*(u32 *)addr)); ++ plat = dev_get_platdata(dev); ++ if (readl(plat->base + BSEC_DENABLE_OFF) & BSEC_DENABLE_DBGSWENABLE) ++ return true; + -+ word = STM32_OTP_HASH_KEY_START + i; -+ val = __be32_to_cpu(*(u32 *)addr); -+ misc_write(dev, STM32_BSEC_OTP(word), &val, 4); -+ -+ addr += 4; -+ } ++ return false; +} -+ -+static int confirm_prog(void) -+{ -+ puts("Warning: Programming fuses is an irreversible operation!\n" -+ " This may brick your system.\n" -+ " Use this command only if you are sure of what you are doing!\n" -+ "\nReally perform this fuse programming? \n"); -+ -+ if (confirm_yesno()) -+ return 1; -+ -+ puts("Fuse programming aborted\n"); -+ return 0; -+} -+ -+int do_stm32key(cmd_tbl_t *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) -+ return CMD_RET_USAGE; -+ -+ addr = simple_strtoul(argv[0], NULL, 16); -+ if (!addr) -+ return CMD_RET_USAGE; -+ -+ if (!strcmp(op, "read")) -+ read_hash_value(addr); -+ -+ if (!strcmp(op, "fuse")) { -+ if (!confirmed && !confirm_prog()) -+ return CMD_RET_FAILURE; -+ fuse_hash_value(addr, !confirmed); -+ } -+ -+ 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"); diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/Makefile b/arch/arm/mach-stm32mp/cmd_stm32prog/Makefile new file mode 100644 -index 0000000..bb7b7e7 +index 0000000..548a378 --- /dev/null +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0+ +# -+# Copyright (C) 2018, STMicroelectronics - All Rights Reserved ++# Copyright (C) 2020, STMicroelectronics - All Rights Reserved +# + +obj-y += cmd_stm32prog.o @@ -585,44 +617,74 @@ index 0000000..bb7b7e7 +obj-y += 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 new file mode 100644 -index 0000000..d1c07dc +index 0000000..db1f3a7 --- /dev/null +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c -@@ -0,0 +1,80 @@ +@@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +#include +#include +#include ++#include ++#include +#include "stm32prog.h" + -+DECLARE_GLOBAL_DATA_PTR; ++struct stm32prog_data *stm32prog_data; ++ ++static void enable_vidconsole(void) ++{ ++#ifdef CONFIG_DM_VIDEO ++ char *stdname; ++ char buf[64]; ++ ++ stdname = env_get("stdout"); ++ if (!stdname || !strstr(stdname, "vidconsole")) { ++ if (!stdname) ++ snprintf(buf, sizeof(buf), "serial,vidconsole"); ++ else ++ snprintf(buf, sizeof(buf), "%s,vidconsole", stdname); ++ env_set("stdout", buf); ++ } ++ ++ stdname = env_get("stderr"); ++ if (!stdname || !strstr(stdname, "vidconsole")) { ++ if (!stdname) ++ snprintf(buf, sizeof(buf), "serial,vidconsole"); ++ else ++ snprintf(buf, sizeof(buf), "%s,vidconsole", stdname); ++ env_set("stderr", buf); ++ } ++#endif ++} + +static int do_stm32prog(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ -+ struct stm32prog_data *data; + ulong addr, size; -+ int dev; ++ int dev, ret; + enum stm32prog_link_t link = LINK_UNDEFINED; + bool reset = false; ++ struct image_header_s header; ++ struct stm32prog_data *data; ++ u32 uimage, dtb; + + if (argc < 3 || argc > 5) + return CMD_RET_USAGE; + -+ if (!strcmp(argv[1], "serial")) { ++ if (!strcmp(argv[1], "usb")) ++ link = LINK_USB; ++ else if (!strcmp(argv[1], "serial")) + link = LINK_SERIAL; -+ } else { -+ if (!strcmp(argv[1], "usb")) { -+ link = LINK_USB; -+ } else { -+ pr_err("not supported link=%s\n", argv[1]); -+ return CMD_RET_USAGE; -+ } ++ ++ if (link == LINK_UNDEFINED) { ++ pr_err("not supported link=%s\n", argv[1]); ++ return CMD_RET_USAGE; + } ++ + dev = (int)simple_strtoul(argv[2], NULL, 10); + + addr = STM32_DDR_BASE; @@ -635,30 +697,95 @@ index 0000000..d1c07dc + if (argc > 4) + size = simple_strtoul(argv[4], NULL, 16); + -+ data = stm32prog_init(link, dev, addr, size); -+ if (!data) ++ /* 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 source(addr + BL_HEADER_SIZE, "script@1"); ++ } ++ ++ enable_vidconsole(); ++ ++ data = (struct stm32prog_data *)malloc(sizeof(*data)); ++ ++ if (!data) { ++ pr_err("Alloc failed."); + return CMD_RET_FAILURE; ++ } ++ stm32prog_data = data; ++ ++ ret = stm32prog_init(data, addr, size); ++ if (ret) ++ printf("Invalid or missing layout file."); ++ ++ /* prepare DFU for device read/write */ ++ ret = stm32prog_dfu_init(data); ++ if (ret) ++ goto cleanup; + + switch (link) { + case LINK_SERIAL: ++ ret = stm32prog_serial_init(data, dev); ++ if (ret) ++ goto cleanup; + reset = stm32prog_serial_loop(data); + break; + case LINK_USB: + reset = stm32prog_usb_loop(data, dev); + break; + default: -+ break; ++ goto cleanup; + } + ++ uimage = data->uimage; ++ dtb = data->dtb; ++ + stm32prog_clean(data); ++ free(stm32prog_data); ++ stm32prog_data = NULL; + + puts("Download done\n"); ++ ++ if (uimage) { ++ char boot_addr_start[20]; ++ char dtb_addr[20]; ++ char *bootm_argv[5] = { ++ "bootm", boot_addr_start, "-", dtb_addr, NULL ++ }; ++ if (!dtb) ++ bootm_argv[3] = env_get("fdtcontroladdr"); ++ else ++ snprintf(dtb_addr, sizeof(dtb_addr) - 1, ++ "0x%x", dtb); ++ ++ 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]); ++ /* Try bootm for legacy and FIT format image */ ++ if (genimg_get_format((void *)uimage) != IMAGE_FORMAT_INVALID) ++ do_bootm(cmdtp, 0, 4, bootm_argv); ++ else if CONFIG_IS_ENABLED(CMD_BOOTZ) ++ do_bootz(cmdtp, 0, 4, bootm_argv); ++ } ++ + if (reset) { + puts("Reset...\n"); + run_command("reset", 0); + } + + return CMD_RET_SUCCESS; ++ ++cleanup: ++ stm32prog_clean(data); ++ free(stm32prog_data); ++ stm32prog_data = NULL; ++ ++ return CMD_RET_FAILURE; +} + +U_BOOT_CMD(stm32prog, 5, 0, do_stm32prog, @@ -669,34 +796,47 @@ index 0000000..d1c07dc + " = address of flashlayout\n" + " = size of flashlayout\n" +); ++ ++bool stm32prog_get_tee_partitions(void) ++{ ++ if (stm32prog_data) ++ return stm32prog_data->tee_detected; ++ ++ return false; ++} ++ ++bool stm32prog_get_fsbl_nor(void) ++{ ++ if (stm32prog_data) ++ return stm32prog_data->fsbl_nor_detected; ++ ++ return false; ++} diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c new file mode 100644 -index 0000000..d263b38 +index 0000000..f2f9ed9 --- /dev/null +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c -@@ -0,0 +1,1647 @@ +@@ -0,0 +1,1743 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +#include +#include +#include +#include ++#include +#include -+#include +#include -+#include +#include +#include +#include -+#include +#include +#include +#include +#include -+#include + +#include "stm32prog.h" + @@ -707,9 +847,11 @@ index 0000000..d263b38 +#define OPT_EMPTY BIT(1) +#define OPT_DELETE BIT(2) + -+#define IS_SELECT(part) (part->option & OPT_SELECT) -+#define IS_EMPTY(part) (part->option & OPT_EMPTY) -+#define IS_DELETE(part) (part->option & OPT_DELETE) ++#define IS_SELECT(part) ((part)->option & OPT_SELECT) ++#define IS_EMPTY(part) ((part)->option & OPT_EMPTY) ++#define IS_DELETE(part) ((part)->option & OPT_DELETE) ++ ++#define ALT_BUF_LEN SZ_1K + +#define ROOTFS_MMC0_UUID \ + EFI_GUID(0xE91C4E10, 0x16E6, 0x4C0E, \ @@ -723,19 +865,21 @@ index 0000000..d263b38 + EFI_GUID(0xFD58F1C7, 0xBE0D, 0x4338, \ + 0x88, 0xE9, 0xAD, 0x8F, 0x05, 0x0A, 0xEB, 0x18) + ++/* RAW parttion (binary / bootloader) used Linux - reserved UUID */ ++#define LINUX_RESERVED_UUID "8DA63339-0007-60C0-C436-083AC8230908" ++ +/* + * unique partition guid (uuid) for partition named "rootfs" + * on each MMC instance = SD Card or eMMC + * allow fixed kernel bootcmd: "rootf=PARTUID=e91c4e10-..." + */ -+const static efi_guid_t uuid_mmc[3] = { ++static const efi_guid_t uuid_mmc[3] = { + ROOTFS_MMC0_UUID, + ROOTFS_MMC1_UUID, + ROOTFS_MMC2_UUID +}; + +DECLARE_GLOBAL_DATA_PTR; -+#define ENV_BUF_LEN SZ_1K + +/* order of column in flash layout file */ +enum stm32prog_col_t { @@ -755,7 +899,7 @@ index 0000000..d263b38 + +char *stm32prog_get_error(struct stm32prog_data *data) +{ -+ const char error_msg[] = "Unspecified"; ++ static const char error_msg[] = "Unspecified"; + + if (strlen(data->error) == 0) + strcpy(data->error, error_msg); @@ -766,13 +910,12 @@ index 0000000..d263b38 +u8 stm32prog_header_check(struct raw_header_s *raw_header, + struct image_header_s *header) +{ -+ int i; ++ unsigned int i; + + header->present = 0; + header->image_checksum = 0x0; + header->image_length = 0x0; + -+ /*pr_debug("%s entry\n", __func__);*/ + if (!raw_header || !header) { + pr_debug("%s:no header data\n", __func__); + return -1; @@ -803,8 +946,6 @@ index 0000000..d263b38 + header->image_checksum = le32_to_cpu(raw_header->image_checksum); + header->image_length = le32_to_cpu(raw_header->image_length); + -+ /*pr_debug("%s exit\n", __func__);*/ -+ + return 0; +} + @@ -824,7 +965,7 @@ index 0000000..d263b38 + +/* FLASHLAYOUT PARSING *****************************************/ +static int parse_option(struct stm32prog_data *data, -+ char *p, struct stm32prog_part_t *part) ++ int i, char *p, struct stm32prog_part_t *part) +{ + int result = 0; + char *c = p; @@ -846,24 +987,22 @@ index 0000000..d263b38 + break; + default: + result = -EINVAL; -+ stm32prog_err("Layout: invalid option '%c' in %s)", -+ *c, p); ++ stm32prog_err("Layout line %d: invalid option '%c' in %s)", ++ i, *c, p); + return -EINVAL; + } + c++; + } + if (!(part->option & OPT_SELECT)) { -+ stm32prog_err("Layout: missing 'P' in option %s", p); ++ stm32prog_err("Layout line %d: missing 'P' in option %s", i, p); + return -EINVAL; + } + -+ /* pr_debug("option : %x\n", part->option); */ -+ + return result; +} + +static int parse_id(struct stm32prog_data *data, -+ char *p, struct stm32prog_part_t *part) ++ int i, char *p, struct stm32prog_part_t *part) +{ + int result = 0; + unsigned long value; @@ -871,33 +1010,31 @@ index 0000000..d263b38 + result = strict_strtoul(p, 0, &value); + part->id = value; + if (result || value > PHASE_LAST_USER) { -+ stm32prog_err("Layout: invalid phase value = %s", p); ++ stm32prog_err("Layout line %d: invalid phase value = %s", i, p); + result = -EINVAL; + } -+ /* pr_debug("phase : %x\n", part->id); */ + + return result; +} + +static int parse_name(struct stm32prog_data *data, -+ char *p, struct stm32prog_part_t *part) ++ int i, char *p, struct stm32prog_part_t *part) +{ + int result = 0; + + if (strlen(p) < sizeof(part->name)) { + strcpy(part->name, p); + } else { -+ stm32prog_err("Layout: partition name too long [%d] : %s", -+ strlen(p), p); ++ stm32prog_err("Layout line %d: partition name too long [%d]: %s", ++ i, strlen(p), p); + result = -EINVAL; + } -+ /* pr_debug("name : %s\n", part->name); */ + + return result; +} + +static int parse_type(struct stm32prog_data *data, -+ char *p, struct stm32prog_part_t *part) ++ int i, char *p, struct stm32prog_part_t *part) +{ + int result = 0; + int len = 0; @@ -928,30 +1065,36 @@ index 0000000..d263b38 + result = -EINVAL; + } + if (result) -+ stm32prog_err("Layout: type parsing error : '%s'", p); -+ /* pr_debug("type : %d\n", part->part_type); */ ++ stm32prog_err("Layout line %d: type parsing error : '%s'", ++ i, p); + + return result; +} + +static int parse_ip(struct stm32prog_data *data, -+ char *p, struct stm32prog_part_t *part) ++ int i, char *p, struct stm32prog_part_t *part) +{ + int result = 0; -+ int len = 0; ++ unsigned int len = 0; + + part->dev_id = 0; + if (!strcmp(p, "none")) { -+ part->dev_type = DFU_DEV_VIRT; ++ part->target = STM32PROG_NONE; + } else if (!strncmp(p, "mmc", 3)) { -+ part->dev_type = DFU_DEV_MMC; ++ part->target = STM32PROG_MMC; + len = 3; + } else if (!strncmp(p, "nor", 3)) { -+ part->dev_type = DFU_DEV_SF; ++ part->target = STM32PROG_NOR; + len = 3; + } else if (!strncmp(p, "nand", 4)) { -+ part->dev_type = DFU_DEV_NAND; ++ part->target = STM32PROG_NAND; + len = 4; ++ } else if (!strncmp(p, "spi-nand", 8)) { ++ part->target = STM32PROG_SPI_NAND; ++ len = 8; ++ } else if (!strncmp(p, "ram", 3)) { ++ part->target = STM32PROG_RAM; ++ len = 0; + } else { + result = -EINVAL; + } @@ -966,14 +1109,13 @@ index 0000000..d263b38 + } + } + if (result) -+ stm32prog_err("Layout: ip parsing error : '%s'", p); -+ /* pr_debug("dev : %d\n", part->dev_id); */ ++ stm32prog_err("Layout line %d: ip parsing error: '%s'", i, p); + + return result; +} + +static int parse_offset(struct stm32prog_data *data, -+ char *p, struct stm32prog_part_t *part) ++ int i, char *p, struct stm32prog_part_t *part) +{ + int result = 0; + char *tail; @@ -983,30 +1125,33 @@ index 0000000..d263b38 + part->size = 0; + /* eMMC boot parttion */ + if (!strncmp(p, "boot", 4)) { -+ if (p[4] == '1') { -+ part->part_id = -1; -+ } else if (p[4] == '2') { -+ part->part_id = -2; -+ } else { -+ stm32prog_err("Layout: invalid part '%s'", p); ++ if (strlen(p) != 5) { + result = -EINVAL; ++ } else { ++ if (p[4] == '1') ++ part->part_id = -1; ++ else if (p[4] == '2') ++ part->part_id = -2; ++ else ++ result = -EINVAL; + } ++ if (result) ++ stm32prog_err("Layout line %d: invalid part '%s'", ++ i, p); + } else { + part->addr = simple_strtoull(p, &tail, 0); + if (tail == p || *tail != '\0') { -+ stm32prog_err("Layout: invalid offset '%s'", p); ++ stm32prog_err("Layout line %d: invalid offset '%s'", ++ i, p); + result = -EINVAL; + } + } -+ /* pr_debug("addr : 0x%llx, part_id : %d\n", part->addr, -+ * part->part_id); -+ */ + + return result; +} + +static -+int (* const parse[COL_NB_STM32])(struct stm32prog_data *data, char *p, ++int (* const parse[COL_NB_STM32])(struct stm32prog_data *data, int i, char *p, + struct stm32prog_part_t *part) = { + [COL_OPTION] = parse_option, + [COL_ID] = parse_id, @@ -1025,7 +1170,7 @@ index 0000000..d263b38 + char *p, *start, *last, *col; + struct stm32prog_part_t *part; + int part_list_size; -+ bool stm32image = false; ++ int i; + + data->part_nb = 0; + @@ -1036,7 +1181,6 @@ index 0000000..d263b38 + + addr = addr + BL_HEADER_SIZE; + size = data->header.image_length; -+ stm32image = true; + + checksum = stm32prog_header_checksum(addr, &data->header); + if (checksum != data->header.image_checksum) { @@ -1065,7 +1209,8 @@ index 0000000..d263b38 + } + } + if (part_list_size > PHASE_LAST_USER) { -+ stm32prog_err("Layout: too many line"); ++ stm32prog_err("Layout: too many partition (%d)", ++ part_list_size); + return -1; + } + part = calloc(sizeof(struct stm32prog_part_t), part_list_size); @@ -1076,18 +1221,18 @@ index 0000000..d263b38 + data->part_array = part; + + /* main parsing loop */ ++ i = 1; + eof = false; + p = start; + col = start; /* 1st column */ ++ end_of_line = false; + while (!eof) { -+ end_of_line = false; + switch (*p) { -+ /* CR is ignored and replaced by NULL chararc*/ ++ /* CR is ignored and replaced by NULL character */ + case '\r': + *p = '\0'; + p++; + continue; -+ /* end of column detected */ + case '\0': + end_of_line = true; + eof = true; @@ -1104,38 +1249,41 @@ index 0000000..d263b38 + if (*p++ == '\n') + break; + col = p; -+ if (p >= last || !*p) ++ i++; ++ if (p >= last || !*p) { + eof = true; ++ end_of_line = true; ++ } + continue; + } -+ /* no break */ ++ /* fall through */ + /* by default continue with the next character */ + default: + p++; + continue; + } + -+ /* replace by \0 to allow string parsing */ ++ /* replace by \0: allow string parsing for each column */ + *p = '\0'; + p++; + if (p >= last) { + eof = true; + end_of_line = true; + } -+ /*pr_debug("%d:%d = '%s' => ", part_nb, column, col);*/ ++ ++ /* skip empty line and multiple TAB in tsv file */ + if (strlen(col) == 0) { + col = p; + /* skip empty line */ -+ if (column == 0 && end_of_line) -+ continue; -+ /* multiple TAB allowed in tsv file */ -+ if (!stm32image) -+ continue; -+ stm32prog_err("empty field for line %d", part_nb); -+ return -1; ++ if (column == 0 && end_of_line) { ++ end_of_line = false; ++ i++; ++ } ++ continue; + } ++ + if (column < COL_NB_STM32) { -+ ret = parse[column](data, col, part); ++ ret = parse[column](data, i, col, part); + if (ret) + return ret; + } @@ -1148,14 +1296,16 @@ index 0000000..d263b38 + continue; + + /* end of the line detected */ ++ end_of_line = false; ++ + if (column < COL_NB_STM32) { -+ stm32prog_err("Layout: no enought column for line %d", -+ part_nb); ++ stm32prog_err("Layout line %d: no enought column", i); + return -EINVAL; + } + column = 0; + part_nb++; + part++; ++ i++; + if (part_nb >= part_list_size) { + part = NULL; + if (!eof) { @@ -1187,25 +1337,48 @@ index 0000000..d263b38 + return parta->addr > partb->addr ? 1 : -1; +} + ++static void get_mtd_by_target(char *string, enum stm32prog_target target, ++ int dev_id) ++{ ++ const char *dev_str; ++ ++ switch (target) { ++ case STM32PROG_NOR: ++ dev_str = "nor"; ++ break; ++ case STM32PROG_NAND: ++ dev_str = "nand"; ++ break; ++ case STM32PROG_SPI_NAND: ++ dev_str = "spi-nand"; ++ break; ++ default: ++ dev_str = "invalid"; ++ break; ++ } ++ sprintf(string, "%s%d", dev_str, dev_id); ++} ++ +static int init_device(struct stm32prog_data *data, + struct stm32prog_dev_t *dev) +{ + struct mmc *mmc = NULL; -+#ifdef CONFIG_MTD_PARTITIONS + struct blk_desc *block_dev = NULL; ++#ifdef CONFIG_MTD + struct mtd_info *mtd = NULL; + char mtd_id[16]; -+ char cmdbuf[40]; +#endif + int part_id; + int ret; + u64 first_addr = 0, last_addr = 0; + struct stm32prog_part_t *part, *next_part; + u64 part_addr, part_size; ++ bool part_found; ++ const char *part_name; + -+ dev->lba_blk_size = MMC_MAX_BLOCK_LEN; -+ switch (dev->dev_type) { -+ case DFU_DEV_MMC: ++ switch (dev->target) { ++#ifdef CONFIG_MMC ++ case STM32PROG_MMC: + mmc = find_mmc_device(dev->dev_id); + if (mmc_init(mmc)) { + stm32prog_err("mmc device %d not found", dev->dev_id); @@ -1216,8 +1389,8 @@ index 0000000..d263b38 + stm32prog_err("mmc device %d not probed", dev->dev_id); + return -ENODEV; + } -+ dev->lba_blk_size = mmc->read_bl_len; + dev->erase_size = mmc->erase_grp_size * block_dev->blksz; ++ dev->mmc = mmc; + + /* reserve a full erase group for each GTP headers */ + if (mmc->erase_grp_size > GPT_HEADER_SZ) { @@ -1234,49 +1407,16 @@ index 0000000..d263b38 + block_dev->lba, block_dev->blksz); + pr_debug(" available address = 0x%llx..0x%llx\n", + first_addr, last_addr); ++ pr_debug(" full_update = %d\n", dev->full_update); + break; -+#ifdef CONFIG_MTD_PARTITIONS -+ case DFU_DEV_SF: -+#ifdef CONFIG_SPI_FLASH -+ sprintf(cmdbuf, "sf probe %d", dev->dev_id); -+ if (run_command(cmdbuf, 0)) { -+ stm32prog_err("invalid device : %s", cmdbuf); -+ return -ENODEV; -+ } -+ sprintf(mtd_id, "nor%d", dev->dev_id); ++#endif ++#ifdef CONFIG_MTD ++ case STM32PROG_NOR: ++ case STM32PROG_NAND: ++ case STM32PROG_SPI_NAND: ++ get_mtd_by_target(mtd_id, dev->target, dev->dev_id); + pr_debug("%s\n", mtd_id); -+ break; -+#else -+ stm32prog_err("device SF nor supported"); -+ return -ENODEV; -+#endif -+ case DFU_DEV_NAND: -+ sprintf(cmdbuf, "nand device %d", dev->dev_id); -+ if (run_command(cmdbuf, 0)) { -+ stm32prog_err("invalid device : %s", cmdbuf); -+ return -ENODEV; -+ } -+ sprintf(mtd_id, "nand%d", dev->dev_id); -+ pr_debug("%s\n", mtd_id); -+ break; -+#endif -+ default: -+ stm32prog_err("unknown device type = %d", dev->dev_type); -+ return -ENODEV; -+ } -+#ifdef CONFIG_MTD_PARTITIONS -+ if (dev->dev_type == DFU_DEV_SF || -+ dev->dev_type == DFU_DEV_NAND) { -+#ifdef CONFIG_SPI_FLASH -+ if (dev->dev_type == DFU_DEV_NAND) { -+ /* sf probe is needed for mtdparts -+ * because mtdids can use nor0 and nor driver -+ * is not probed by default as nand -+ */ -+ sprintf(cmdbuf, "sf probe %d", dev->dev_id); -+ run_command(cmdbuf, 0); -+ } -+#endif ++ + mtdparts_init(); + mtd = get_mtd_device_nm(mtd_id); + if (IS_ERR(mtd)) { @@ -1286,28 +1426,38 @@ index 0000000..d263b38 + first_addr = 0; + last_addr = mtd->size; + dev->erase_size = mtd->erasesize; -+ pr_debug("MTD device %s : size=%lld erasesize=%d\n", ++ pr_debug("MTD device %s: size=%lld erasesize=%d\n", + mtd_id, mtd->size, mtd->erasesize); + pr_debug(" available address = 0x%llx..0x%llx\n", + first_addr, last_addr); -+ } -+ dev->mtd = mtd; ++ dev->mtd = mtd; ++ break; +#endif ++ case STM32PROG_RAM: ++ first_addr = gd->bd->bi_dram[0].start; ++ last_addr = first_addr + gd->bd->bi_dram[0].size; ++ dev->erase_size = 1; ++ break; ++ default: ++ stm32prog_err("unknown device type = %d", dev->target); ++ return -ENODEV; ++ } + pr_debug(" erase size = 0x%x\n", dev->erase_size); -+ dev->block_dev = block_dev; ++ pr_debug(" full_update = %d\n", dev->full_update); + + /* order partition list in offset order */ + list_sort(NULL, &dev->part_list, &part_cmp); + part_id = 1; -+ pr_debug("id : Opt Phase Name type.n dev.n addr size part_off part_size\n"); ++ pr_debug("id : Opt Phase Name target.n dev.n addr size part_off part_size\n"); + list_for_each_entry(part, &dev->part_list, list) { + if (part->bin_nb > 1) { -+ if (dev->dev_type != DFU_DEV_NAND || ++ if ((dev->target != STM32PROG_NAND && ++ dev->target != STM32PROG_SPI_NAND) || + part->id >= PHASE_FIRST_USER || + strncmp(part->name, "fsbl", 4)) { -+ stm32prog_err("%s: multiple binary %d not supported for phase %d", -+ part->name, part->bin_nb, -+ part->id); ++ stm32prog_err("%s (0x%x): multiple binary %d not supported", ++ part->name, part->id, ++ part->bin_nb); + return -EINVAL; + } + } @@ -1320,7 +1470,7 @@ index 0000000..d263b38 + part->size = last_addr; + pr_debug("-- : %1d %02x %14s %02d.%d %02d.%02d %08llx %08llx\n", + part->option, part->id, part->name, -+ part->part_type, part->bin_nb, part->dev_type, ++ part->part_type, part->bin_nb, part->target, + part->dev_id, part->addr, part->size); + continue; + } @@ -1328,8 +1478,9 @@ index 0000000..d263b38 + if (mmc) { + part->size = mmc->capacity_boot; + } else { -+ stm32prog_err("%s: hw partition not expected : %d", -+ part->name, part->part_id); ++ stm32prog_err("%s (0x%x): hw partition not expected : %d", ++ part->name, part->id, ++ part->part_id); + return -ENODEV; + } + } else { @@ -1345,8 +1496,11 @@ index 0000000..d263b38 + part->size = next_part->addr - + part->addr; + } else { -+ stm32prog_err("%s: invalid address : 0x%llx >= 0x%llx", -+ part->name, part->addr, ++ stm32prog_err("%s (0x%x): same address : 0x%llx == %s (0x%x): 0x%llx", ++ part->name, part->id, ++ part->addr, ++ next_part->name, ++ next_part->id, + next_part->addr); + return -EINVAL; + } @@ -1354,55 +1508,63 @@ index 0000000..d263b38 + if (part->addr <= last_addr) { + part->size = last_addr - part->addr; + } else { -+ stm32prog_err("%s: invalid address 0x%llx (max=0x%llx)", -+ part->name, part->addr, -+ last_addr); ++ stm32prog_err("%s (0x%x): invalid address 0x%llx (max=0x%llx)", ++ part->name, part->id, ++ part->addr, last_addr); + return -EINVAL; + } + } + if (part->addr < first_addr) { -+ stm32prog_err("%s: invalid address 0x%llx (min=0x%llx)", -+ part->name, part->addr, -+ first_addr); ++ stm32prog_err("%s (0x%x): invalid address 0x%llx (min=0x%llx)", ++ part->name, part->id, ++ part->addr, first_addr); + return -EINVAL; + } + } + if ((part->addr & ((u64)part->dev->erase_size - 1)) != 0) { -+ stm32prog_err("%s: not aligned address : 0x%llx on erase size 0x%x", -+ part->name, part->addr, ++ stm32prog_err("%s (0x%x): not aligned address : 0x%llx on erase size 0x%x", ++ part->name, part->id, part->addr, + part->dev->erase_size); + return -EINVAL; + } + pr_debug("%02d : %1d %02x %14s %02d.%d %02d.%02d %08llx %08llx", + part->part_id, part->option, part->id, part->name, -+ part->part_type, part->bin_nb, part->dev_type, ++ part->part_type, part->bin_nb, part->target, + part->dev_id, part->addr, part->size); + + part_addr = 0; + part_size = 0; ++ part_found = false; ++ + /* check coherency with existing partition */ + if (block_dev) { -+ disk_partition_t partinfo; -+ -+ /* only check partition size for partial update */ -+ if (data->full_update || part->part_id < 0) { ++ /* ++ * block devices with GPT: check user partition size ++ * only for partial update, the GPT partions are be ++ * created for full update ++ */ ++ if (dev->full_update || part->part_id < 0) { + pr_debug("\n"); + continue; + } ++ disk_partition_t partinfo; + + ret = part_get_info(block_dev, part->part_id, + &partinfo); + + if (ret) { -+ stm32prog_err("Couldn't find part %d on device mmc %d", ++ stm32prog_err("%s (0x%x):Couldn't find part %d on device mmc %d", ++ part->name, part->id, + part_id, part->dev_id); + return -ENODEV; + } + part_addr = (u64)partinfo.start * partinfo.blksz; + part_size = (u64)partinfo.size * partinfo.blksz; ++ part_name = (char *)partinfo.name; ++ part_found = true; + } + -+#ifdef CONFIG_MTD_PARTITIONS ++#ifdef CONFIG_MTD + if (mtd) { + char mtd_part_id[32]; + struct part_info *mtd_part; @@ -1414,25 +1576,36 @@ index 0000000..d263b38 + ret = find_dev_and_part(mtd_part_id, &mtd_dev, + &part_num, &mtd_part); + if (ret != 0) { -+ stm32prog_err("Invalid partition %s", ++ stm32prog_err("%s (0x%x): Invalid MTD partition %s", ++ part->name, part->id, + mtd_part_id); + return -ENODEV; + } + part_addr = mtd_part->offset; + part_size = mtd_part->size; ++ part_name = mtd_part->name; ++ part_found = true; + } +#endif ++ ++ /* no partition for this device */ ++ if (!part_found) { ++ pr_debug("\n"); ++ continue; ++ } ++ + pr_debug(" %08llx %08llx\n", part_addr, part_size); + + if (part->addr != part_addr) { -+ stm32prog_err("%s: Bad address requested for partition %d = 0x%llx <> 0x%llx", -+ part->name, part->part_id, part->addr, -+ part_addr); ++ stm32prog_err("%s (0x%x): Bad address for partition %d (%s) = 0x%llx <> 0x%llx expected", ++ part->name, part->id, part->part_id, ++ part_name, part->addr, part_addr); + return -ENODEV; + } + if (part->size != part_size) { -+ stm32prog_err("%s: Bad size requested for partition %d = 0x%llx <> 0x%llx", -+ part->name, part->part_id, part->size, ++ stm32prog_err("%s (0x%x): Bad size for partition %d (%s) at 0x%llx = 0x%llx <> 0x%llx expected", ++ part->name, part->id, part->part_id, ++ part_name, part->addr, part->size, + part_size); + return -ENODEV; + } @@ -1446,18 +1619,18 @@ index 0000000..d263b38 + struct stm32prog_part_t *part; + + for (j = 0; j < STM32PROG_MAX_DEV; j++) { -+ data->dev[j].dev_type = -1; ++ data->dev[j].target = STM32PROG_NONE; + INIT_LIST_HEAD(&data->dev[j].part_list); + } + -+ data->full_update = 1; -+ /*pr_debug("id : S Phase Name type dev.n addr id\n");*/ ++ data->tee_detected = false; ++ data->fsbl_nor_detected = false; + for (i = 0; i < data->part_nb; i++) { + part = &data->part_array[i]; + part->alt_id = -1; + + /* skip partition with IP="none" */ -+ if (part->dev_type == DFU_DEV_VIRT) { ++ if (part->target == STM32PROG_NONE) { + if (IS_SELECT(part)) { + stm32prog_err("Layout: selected none phase = 0x%x", + part->id); @@ -1466,15 +1639,6 @@ index 0000000..d263b38 + continue; + } + -+ /* -+ * pr_debug("%02d : %1d %02x %14s %02d %02d.%02d 0x%08llx %d\n", -+ * i, part->option, part->id, part->name, -+ * part->part_type, part->dev_id_type, part->dev_id, -+ * part->addr, part->part_id); -+ */ -+ if (!IS_SELECT(part) && part->part_type != RAW_IMAGE) -+ data->full_update = 0; -+ + if (part->id == PHASE_FLASHLAYOUT || + part->id > PHASE_LAST_USER) { + stm32prog_err("Layout: invalid phase = 0x%x", @@ -1483,19 +1647,20 @@ index 0000000..d263b38 + } + for (j = i + 1; j < data->part_nb; j++) { + if (part->id == data->part_array[j].id) { -+ stm32prog_err("Layout: duplicated phase %d at line %d and %d", ++ stm32prog_err("Layout: duplicated phase 0x%x at line %d and %d", + part->id, i, j); + return -EINVAL; + } + } + for (j = 0; j < STM32PROG_MAX_DEV; j++) { -+ if (data->dev[j].dev_type == -1) { ++ if (data->dev[j].target == STM32PROG_NONE) { + /* new device found */ -+ data->dev[j].dev_type = part->dev_type; ++ data->dev[j].target = part->target; + data->dev[j].dev_id = part->dev_id; ++ data->dev[j].full_update = true; + data->dev_nb++; + break; -+ } else if ((part->dev_type == data->dev[j].dev_type) && ++ } else if ((part->target == data->dev[j].target) && + (part->dev_id == data->dev[j].dev_id)) { + break; + } @@ -1504,7 +1669,24 @@ index 0000000..d263b38 + stm32prog_err("Layout: too many device"); + return -EINVAL; + } ++ switch (part->target) { ++ case STM32PROG_NOR: ++ if (!data->fsbl_nor_detected && ++ !strncmp(part->name, "fsbl", 4)) ++ data->fsbl_nor_detected = true; ++ /* fallthrough */ ++ case STM32PROG_NAND: ++ case STM32PROG_SPI_NAND: ++ if (!data->tee_detected && ++ !strncmp(part->name, "tee", 3)) ++ data->tee_detected = true; ++ break; ++ default: ++ break; ++ } + part->dev = &data->dev[j]; ++ if (!IS_SELECT(part)) ++ part->dev->full_update = false; + list_add_tail(&part->list, &data->dev[j].part_list); + } + @@ -1513,36 +1695,52 @@ index 0000000..d263b38 + +static int create_partitions(struct stm32prog_data *data) +{ ++#ifdef CONFIG_MMC + int offset = 0; -+ char cmdbuf[32]; -+ char buf[ENV_BUF_LEN]; ++ const int buflen = SZ_8K; ++ char *buf; + char uuid[UUID_STR_LEN + 1]; + unsigned char *uuid_bin; -+ int i, mmc_id; ++ unsigned int mmc_id; ++ int i; + bool rootfs_found; + struct stm32prog_part_t *part; + ++ buf = malloc(buflen); ++ if (!buf) ++ return -ENOMEM; ++ + puts("partitions : "); + /* initialize the selected device */ + for (i = 0; i < data->dev_nb; i++) { -+ /* gpt support only for MMC */ -+ if (data->dev[i].dev_type != DFU_DEV_MMC) ++ /* create gpt partition support only for full update on MMC */ ++ if (data->dev[i].target != STM32PROG_MMC || ++ !data->dev[i].full_update) + continue; + + offset = 0; + rootfs_found = false; -+ memset(buf, 0, sizeof(buf)); ++ memset(buf, 0, buflen); + + list_for_each_entry(part, &data->dev[i].part_list, list) { + /* skip eMMC boot partitions */ + if (part->part_id < 0) + continue; -+ + /* skip Raw Image */ + if (part->part_type == RAW_IMAGE) + continue; + -+ offset += snprintf(buf + offset, ENV_BUF_LEN - offset, ++ if (offset + 100 > buflen) { ++ pr_debug("\n%s: buffer too small, %s skippped", ++ __func__, part->name); ++ continue; ++ } ++ ++ if (!offset) ++ offset += sprintf(buf, "gpt write mmc %d \"", ++ data->dev[i].dev_id); ++ ++ offset += snprintf(buf + offset, buflen - offset, + "name=%s,start=0x%llx,size=0x%llx", + part->name, + part->addr, @@ -1550,16 +1748,17 @@ index 0000000..d263b38 + + if (part->part_type == PART_BINARY) + offset += snprintf(buf + offset, -+ ENV_BUF_LEN - offset, -+ ",type=data"); ++ buflen - offset, ++ ",type=" ++ LINUX_RESERVED_UUID); + else + offset += snprintf(buf + offset, -+ ENV_BUF_LEN - offset, ++ buflen - offset, + ",type=linux"); + + if (part->part_type == PART_SYSTEM) + offset += snprintf(buf + offset, -+ ENV_BUF_LEN - offset, ++ buflen - offset, + ",bootable"); + + if (!rootfs_found && !strcmp(part->name, "rootfs")) { @@ -1571,46 +1770,49 @@ index 0000000..d263b38 + uuid_bin_to_str(uuid_bin, uuid, + UUID_STR_FORMAT_GUID); + offset += snprintf(buf + offset, -+ ENV_BUF_LEN - offset, ++ buflen - offset, + ",uuid=%s", uuid); + } + } + -+ offset += snprintf(buf + offset, -+ ENV_BUF_LEN - offset, -+ ";"); ++ offset += snprintf(buf + offset, buflen - offset, ";"); + } + + if (offset) { -+ sprintf(cmdbuf, "gpt write mmc %d \"%s\"", -+ data->dev[i].dev_id, buf); -+ pr_debug("cmd: %s\n", cmdbuf); -+ if (run_command(cmdbuf, 0)) { -+ stm32prog_err("partitionning fail : %s", -+ cmdbuf); ++ offset += snprintf(buf + offset, buflen - offset, "\""); ++ pr_debug("\ncmd: %s\n", buf); ++ if (run_command(buf, 0)) { ++ stm32prog_err("GPT partitionning fail: %s", ++ buf); ++ free(buf); ++ + return -1; + } + } + -+ if (data->dev[i].block_dev) -+ part_init(data->dev[i].block_dev); ++ if (data->dev[i].mmc) ++ part_init(mmc_get_blk_desc(data->dev[i].mmc)); + +#ifdef DEBUG -+ sprintf(cmdbuf, "gpt verify mmc %d", -+ data->dev[i].dev_id); -+ pr_debug("cmd: %s ", cmdbuf); -+ if (run_command(cmdbuf, 0)) ++ sprintf(buf, "gpt verify mmc %d", data->dev[i].dev_id); ++ pr_debug("\ncmd: %s", buf); ++ if (run_command(buf, 0)) + printf("fail !\n"); + else + printf("OK\n"); + -+ /* TEMP : for debug, display partition */ -+ sprintf(cmdbuf, "part list mmc %d", -+ data->dev[i].dev_id); -+ run_command(cmdbuf, 0); ++ sprintf(buf, "part list mmc %d", data->dev[i].dev_id); ++ run_command(buf, 0); +#endif + } + puts("done\n"); ++ ++#ifdef DEBUG ++ run_command("mtd list", 0); ++#endif ++ free(buf); ++#endif ++ + return 0; +} + @@ -1620,9 +1822,9 @@ index 0000000..d263b38 +{ + int ret = 0; + int offset = 0; -+ char devstr[4]; ++ char devstr[10]; + char dfustr[10]; -+ char buf[ENV_BUF_LEN]; ++ char buf[ALT_BUF_LEN]; + u32 size; + char multiplier, type; + @@ -1643,62 +1845,75 @@ index 0000000..d263b38 + type = 'a';/*Readable*/ + + memset(buf, 0, sizeof(buf)); -+ offset = snprintf(buf, ENV_BUF_LEN - offset, ++ offset = snprintf(buf, ALT_BUF_LEN - offset, + "@%s/0x%02x/1*%d%c%c ", + part->name, part->id, + size, multiplier, type); + -+ if (part->part_type == RAW_IMAGE) { ++ if (part->target == STM32PROG_RAM) { ++ offset += snprintf(buf + offset, ALT_BUF_LEN - offset, ++ "ram 0x%llx 0x%llx", ++ part->addr, part->size); ++ } else if (part->part_type == RAW_IMAGE) { + u64 dfu_size; + -+ if (part->dev->dev_type == DFU_DEV_MMC) -+ dfu_size = part->size / part->dev->lba_blk_size; ++ if (part->dev->target == STM32PROG_MMC) ++ dfu_size = part->size / part->dev->mmc->read_bl_len; + else + dfu_size = part->size; -+ offset += snprintf(buf + offset, ENV_BUF_LEN - offset, ++ offset += snprintf(buf + offset, ALT_BUF_LEN - offset, + "raw 0x0 0x%llx", dfu_size); + } else if (part->part_id < 0) { -+ u64 nb_blk = part->size / part->dev->lba_blk_size; ++ u64 nb_blk = part->size / part->dev->mmc->read_bl_len; + -+ /* lba_blk_size, mmc->read_bl_len */ -+ offset += snprintf(buf + offset, ENV_BUF_LEN - offset, ++ offset += snprintf(buf + offset, ALT_BUF_LEN - offset, + "raw 0x%llx 0x%llx", + part->addr, nb_blk); -+ offset += snprintf(buf + offset, ENV_BUF_LEN - offset, ++ offset += snprintf(buf + offset, ALT_BUF_LEN - offset, + " mmcpart %d;", -(part->part_id)); + } else { + if (part->part_type == PART_SYSTEM && -+ (part->dev_type == DFU_DEV_NAND || -+ part->dev_type == DFU_DEV_SF)) ++ (part->target == STM32PROG_NAND || ++ part->target == STM32PROG_NOR || ++ part->target == STM32PROG_SPI_NAND)) + offset += snprintf(buf + offset, -+ ENV_BUF_LEN - offset, ++ ALT_BUF_LEN - offset, + "partubi"); + else + offset += snprintf(buf + offset, -+ ENV_BUF_LEN - offset, ++ ALT_BUF_LEN - offset, + "part"); -+ offset += snprintf(buf + offset, ENV_BUF_LEN - offset, -+ " %d %d;", -+ part->dev_id, -+ part->part_id); ++ /* dev_id requested by DFU MMC */ ++ if (part->target == STM32PROG_MMC) ++ offset += snprintf(buf + offset, ALT_BUF_LEN - offset, ++ " %d", part->dev_id); ++ offset += snprintf(buf + offset, ALT_BUF_LEN - offset, ++ " %d;", part->part_id); + } -+ switch (part->dev_type) { -+ case DFU_DEV_MMC: ++ switch (part->target) { ++#ifdef CONFIG_MMC ++ case STM32PROG_MMC: + sprintf(dfustr, "mmc"); + sprintf(devstr, "%d", part->dev_id); + break; -+ case DFU_DEV_SF: -+ sprintf(dfustr, "sf"); -+ sprintf(devstr, "0:%d", part->dev_id); ++#endif ++#ifdef CONFIG_MTD ++ case STM32PROG_NAND: ++ case STM32PROG_NOR: ++ case STM32PROG_SPI_NAND: ++ sprintf(dfustr, "mtd"); ++ get_mtd_by_target(devstr, part->target, part->dev_id); + break; -+ case DFU_DEV_NAND: -+ sprintf(dfustr, "nand"); -+ sprintf(devstr, "%d", part->dev_id); ++#endif ++ case STM32PROG_RAM: ++ sprintf(dfustr, "ram"); ++ sprintf(devstr, "0"); + break; + default: -+ stm32prog_err("invalid dev_type: %d", part->dev_type); ++ stm32prog_err("invalid target: %d", part->target); + return -ENODEV; + } ++ pr_debug("dfu_alt_add(%s,%s,%s)\n", dfustr, devstr, buf); + ret = dfu_alt_add(dfu, dfustr, devstr, buf); + pr_debug("dfu_alt_add(%s,%s,%s) result %d\n", + dfustr, devstr, buf, ret); @@ -1711,7 +1926,7 @@ index 0000000..d263b38 +{ + int ret = 0; + char devstr[4]; -+ char buf[ENV_BUF_LEN]; ++ char buf[ALT_BUF_LEN]; + + sprintf(devstr, "%d", phase); + sprintf(buf, "@%s/0x%02x/1*%dBe", name, phase, size); @@ -1729,18 +1944,14 @@ index 0000000..d263b38 + struct dfu_entity *dfu; + int alt_nb; + -+ /* nb of alternate = nb part not virtual or 1 for FlashLayout -+ * + 3 virtual for CMD and OTP and PMIC -+ */ -+ if (data->part_nb == 0) { -+ alt_nb = 4; -+ } else { -+ alt_nb = 3; ++ alt_nb = 3; /* number of virtual = CMD, OTP, PMIC*/ ++ if (data->part_nb == 0) ++ alt_nb++; /* +1 for FlashLayout */ ++ else + for (i = 0; i < data->part_nb; i++) { -+ if (data->part_array[i].dev_type != DFU_DEV_VIRT) ++ if (data->part_array[i].target != STM32PROG_NONE) + alt_nb++; + } -+ } + + if (dfu_alt_init(alt_nb, &dfu)) + return -ENODEV; @@ -1762,7 +1973,7 @@ index 0000000..d263b38 + } + if (!part) + continue; -+ if (part->dev_type == DFU_DEV_VIRT) ++ if (part->target == STM32PROG_NONE) + continue; + part->alt_id = alt_id; + alt_id++; @@ -1770,7 +1981,7 @@ index 0000000..d263b38 + ret = stm32prog_alt_add(data, dfu, part); + } + } else { -+ char buf[ENV_BUF_LEN]; ++ char buf[ALT_BUF_LEN]; + + sprintf(buf, "@FlashLayout/0x%02x/1*256Ke ram %x 40000", + PHASE_FLASHLAYOUT, STM32_DDR_BASE); @@ -1784,16 +1995,14 @@ index 0000000..d263b38 + if (!ret) + ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, 512); + -+#ifdef CONFIG_DM_PMIC -+ if (!ret) ++ if (!ret && CONFIG_IS_ENABLED(DM_PMIC)) + ret = stm32prog_alt_add_virt(dfu, "PMIC", PHASE_PMIC, 8); -+#endif + + if (ret) + stm32prog_err("dfu init failed: %d", ret); + puts("done\n"); ++ +#ifdef DEBUG -+ /* TEMP : for debug */ + dfu_show_entities(); +#endif + return ret; @@ -1802,7 +2011,7 @@ index 0000000..d263b38 +int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, + long *size) +{ -+ pr_debug("%s : %x %lx\n", __func__, offset, *size); ++ pr_debug("%s: %x %lx\n", __func__, offset, *size); + + if (!data->otp_part) { + data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, OTP_SIZE); @@ -1817,6 +2026,7 @@ index 0000000..d263b38 + *size = OTP_SIZE - offset; + + memcpy((void *)((u32)data->otp_part + offset), buffer, *size); ++ + return 0; +} + @@ -1825,11 +2035,12 @@ index 0000000..d263b38 +{ +#ifndef CONFIG_ARM_SMCCC + stm32prog_err("OTP update not supported"); ++ + return -1; +#else + int result = 0; + -+ pr_debug("%s : %x %lx\n", __func__, offset, *size); ++ pr_debug("%s: %x %lx\n", __func__, offset, *size); + /* alway read for first packet */ + if (!offset) { + if (!data->otp_part) @@ -1861,7 +2072,8 @@ index 0000000..d263b38 + memcpy(buffer, (void *)((u32)data->otp_part + offset), *size); + +end_otp_read: -+ pr_debug("%s : result %i\n", __func__, result); ++ pr_debug("%s: result %i\n", __func__, result); ++ + return result; +#endif +} @@ -1870,6 +2082,7 @@ index 0000000..d263b38 +{ +#ifndef CONFIG_ARM_SMCCC + stm32prog_err("OTP update not supported"); ++ + return -1; +#else + int result = 0; @@ -1899,14 +2112,15 @@ index 0000000..d263b38 + break; + } + } else { -+ pr_err("%s: Failed to exec in secure mode (err = %ld)\n", -+ __func__, res.a0); ++ pr_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); + data->otp_part = NULL; -+ pr_debug("%s : result %i\n", __func__, result); ++ pr_debug("%s: result %i\n", __func__, result); ++ + return result; +#endif +} @@ -1914,7 +2128,7 @@ index 0000000..d263b38 +int stm32prog_pmic_write(struct stm32prog_data *data, u32 offset, u8 *buffer, + long *size) +{ -+ pr_debug("%s : %x %lx\n", __func__, offset, *size); ++ pr_debug("%s: %x %lx\n", __func__, offset, *size); + + if (!offset) + memset(data->pmic_part, 0, PMIC_SIZE); @@ -1930,22 +2144,42 @@ index 0000000..d263b38 +int stm32prog_pmic_read(struct stm32prog_data *data, u32 offset, u8 *buffer, + long *size) +{ -+#ifndef CONFIG_DM_PMIC -+ stm32prog_err("PMIC update not supported"); -+ return -EOPNOTSUPP; -+#else /* CONFIG_DM_PMIC */ -+ int result = 0; ++ int result = 0, ret; ++ struct udevice *dev; + -+ pr_debug("%s : %x %lx\n", __func__, offset, *size); ++ if (!CONFIG_IS_ENABLED(PMIC_STPMIC1)) { ++ stm32prog_err("PMIC update not supported"); ++ ++ return -EOPNOTSUPP; ++ } ++ ++ pr_debug("%s: %x %lx\n", __func__, offset, *size); ++ ret = uclass_get_device_by_driver(UCLASS_MISC, ++ DM_GET_DRIVER(stpmic1_nvm), ++ &dev); ++ if (ret) ++ return ret; + + /* alway request PMIC for first packet */ + if (!offset) { + /* init struct with 0 */ + memset(data->pmic_part, 0, PMIC_SIZE); + -+ result = stpmic1_nvm_read_all(data->pmic_part, PMIC_SIZE); -+ if (result < 0) ++ ret = uclass_get_device_by_driver(UCLASS_MISC, ++ DM_GET_DRIVER(stpmic1_nvm), ++ &dev); ++ if (ret) ++ return ret; ++ ++ ret = misc_read(dev, 0xF8, data->pmic_part, PMIC_SIZE); ++ if (ret < 0) { ++ result = ret; + goto end_pmic_read; ++ } ++ if (ret != PMIC_SIZE) { ++ result = -EACCES; ++ goto end_pmic_read; ++ } + } + + if (offset + *size > PMIC_SIZE) @@ -1954,99 +2188,84 @@ index 0000000..d263b38 + memcpy(buffer, &data->pmic_part[offset], *size); + +end_pmic_read: -+ pr_debug("%s : result %i\n", __func__, result); ++ pr_debug("%s: result %i\n", __func__, result); + return result; -+#endif /* CONFIG_DM_PMIC */ +} + +int stm32prog_pmic_start(struct stm32prog_data *data) +{ -+#ifndef CONFIG_DM_PMIC -+ stm32prog_err("PMIC update not supported"); -+ return -EOPNOTSUPP; -+#else /* CONFIG_DM_PMIC */ -+ return stpmic1_nvm_write_all(data->pmic_part, PMIC_SIZE); -+#endif /* CONFIG_DM_PMIC */ ++ int ret; ++ struct udevice *dev; ++ ++ if (!CONFIG_IS_ENABLED(PMIC_STPMIC1)) { ++ stm32prog_err("PMIC update not supported"); ++ ++ return -EOPNOTSUPP; ++ } ++ ++ ret = uclass_get_device_by_driver(UCLASS_MISC, ++ DM_GET_DRIVER(stpmic1_nvm), ++ &dev); ++ if (ret) ++ return ret; ++ ++ return misc_write(dev, 0xF8, data->pmic_part, PMIC_SIZE); +} + +/* copy FSBL on NAND to improve reliability on NAND */ +static int stm32prog_copy_fsbl(struct stm32prog_part_t *part) +{ -+#ifndef CONFIG_CMD_NAND -+ return -1; -+#else -+ loff_t start, lim; -+ size_t count, actual = 0; + int ret, i; + void *fsbl; -+ nand_erase_options_t opts; + struct image_header_s header; + struct raw_header_s raw_header; ++ struct dfu_entity *dfu; ++ long size, offset; + -+ if (part->dev_type != DFU_DEV_NAND) ++ if (part->target != STM32PROG_NAND && ++ part->target != STM32PROG_SPI_NAND) + return -1; + -+ start = part->addr; -+ lim = part->size; -+ count = BL_HEADER_SIZE; ++ dfu = dfu_get_entity(part->alt_id); + -+ ret = nand_read_skip_bad(part->dev->mtd, start, &count, &actual, lim, -+ (void *)&raw_header); ++ /* read header */ ++ dfu_transaction_cleanup(dfu); ++ size = BL_HEADER_SIZE; ++ ret = dfu->read_medium(dfu, 0, (void *)&raw_header, &size); + if (ret) + return ret; + if (stm32prog_header_check(&raw_header, &header)) + return -1; + -+ count = header.image_length + BL_HEADER_SIZE; -+ fsbl = calloc(1, count); ++ /* read header + payload */ ++ size = header.image_length + BL_HEADER_SIZE; ++ size = round_up(size, part->dev->mtd->erasesize); ++ fsbl = calloc(1, size); + if (!fsbl) + return -ENOMEM; -+ ret = nand_read_skip_bad(part->dev->mtd, start, &count, &actual, lim, -+ fsbl); ++ ret = dfu->read_medium(dfu, 0, fsbl, &size); ++ pr_debug("%s read size=%lx ret=%d\n", __func__, size, ret); + if (ret) + goto error; + -+ memset(&opts, 0, sizeof(opts)); -+ opts.length = count; -+ opts.spread = 1; -+#ifndef DEBUG -+ opts.quiet = 1; -+#endif -+ ++ dfu_transaction_cleanup(dfu); ++ offset = 0; + for (i = part->bin_nb - 1; i > 0; i--) { -+ size_t block_offset; -+ -+ /* copy to next block */ -+ start += actual; -+ block_offset = start & (part->dev->mtd->erasesize - 1); -+ if (block_offset != 0) -+ start += part->dev->mtd->erasesize - block_offset; -+ -+ lim = part->size - (start - part->addr); -+ -+ /* first erase */ -+ opts.offset = start; -+ opts.lim = lim; -+ ret = nand_erase_opts(part->dev->mtd, &opts); -+ if (ret) -+ goto error; -+ -+ /* then write */ -+ ret = nand_write_skip_bad(part->dev->mtd, -+ start, &count, &actual, -+ lim, fsbl, WITH_WR_VERIFY); ++ offset += size; ++ /* write to the next erase block */ ++ ret = dfu->write_medium(dfu, offset, fsbl, &size); ++ pr_debug("%s copy at ofset=%lx size=%lx ret=%d", ++ __func__, offset, size, ret); + if (ret) + goto error; + } + +error: + free(fsbl); -+ /* pr_debug("%s exit ret=%d\n", __func__, ret); */ + return ret; -+#endif +} + -+void stm32prog_end_phase(struct stm32prog_data *data) ++static void stm32prog_end_phase(struct stm32prog_data *data) +{ + if (data->phase == PHASE_FLASHLAYOUT) { + if (parse_flash_layout(data, STM32_DDR_BASE, 0)) @@ -2057,21 +2276,31 @@ index 0000000..d263b38 + if (!data->cur_part) + return; + -+ if (data->cur_part->part_id < 0) { ++ if (data->cur_part->target == STM32PROG_RAM) { ++ if (data->cur_part->part_type == PART_SYSTEM) ++ data->uimage = data->cur_part->addr; ++ if (data->cur_part->part_type == PART_FILESYSTEM) ++ data->dtb = data->cur_part->addr; ++ } ++ ++ if (CONFIG_IS_ENABLED(MMC) && ++ data->cur_part->part_id < 0) { + char cmdbuf[60]; + + sprintf(cmdbuf, "mmc bootbus %d 0 0 0; mmc partconf %d 1 %d 0", + data->cur_part->dev_id, data->cur_part->dev_id, + -(data->cur_part->part_id)); + if (run_command(cmdbuf, 0)) { -+ stm32prog_err("commands %s have failed", cmdbuf); ++ stm32prog_err("commands '%s' failed", cmdbuf); + return; + } + } + -+ if (data->cur_part->bin_nb > 1) { ++ if (CONFIG_IS_ENABLED(MTD) && ++ data->cur_part->bin_nb > 1) { + if (stm32prog_copy_fsbl(data->cur_part)) { -+ stm32prog_err("copy of fsbl failed"); ++ stm32prog_err("%s (0x%x): copy of fsbl failed", ++ data->cur_part->name, data->cur_part->id); + return; + } + } @@ -2089,8 +2318,7 @@ index 0000000..d263b38 +{ + int phase, i; + struct stm32prog_part_t *part; -+ -+ /*pr_debug("%s entry\n", __func__);*/ ++ bool found; + + phase = data->phase; + switch (phase) { @@ -2101,44 +2329,52 @@ index 0000000..d263b38 + } + + /* found next selected partition */ -+ phase++; -+ data->cur_part = NULL; + data->dfu_seq = 0; ++ data->cur_part = NULL; + data->phase = PHASE_END; -+ while ((phase <= PHASE_LAST_USER) && !data->cur_part) { ++ found = false; ++ do { ++ phase++; ++ if (phase > PHASE_LAST_USER) ++ break; + for (i = 0; i < data->part_nb; i++) { + part = &data->part_array[i]; + if (part->id == phase) { + if (IS_SELECT(part) && !IS_EMPTY(part)) { + data->cur_part = part; + data->phase = phase; ++ found = true; + } + break; + } + } -+ phase++; -+ } ++ } while (!found); ++ + if (data->phase == PHASE_END) + puts("Phase=END\n"); -+ -+ /*pr_debug("%s exit phase=0x%x\n", __func__, data->phase);*/ +} + +static int part_delete(struct stm32prog_data *data, + struct stm32prog_part_t *part) +{ + int ret = 0; ++#ifdef CONFIG_MMC + unsigned long blks, blks_offset, blks_size; -+#ifdef CONFIG_SPI_FLASH ++ struct blk_desc *block_dev = NULL; ++ #endif ++#ifdef CONFIG_MTD + char cmdbuf[40]; ++ char devstr[10]; +#endif + + printf("Erasing %s ", part->name); -+ switch (part->dev_type) { -+ case DFU_DEV_MMC: ++ switch (part->target) { ++#ifdef CONFIG_MMC ++ case STM32PROG_MMC: + printf("on mmc %d: ", part->dev->dev_id); -+ blks_offset = lldiv(part->addr, part->dev->lba_blk_size); -+ blks_size = lldiv(part->size, part->dev->lba_blk_size); ++ block_dev = mmc_get_blk_desc(part->dev->mmc); ++ blks_offset = lldiv(part->addr, part->dev->mmc->read_bl_len); ++ blks_size = lldiv(part->size, part->dev->mmc->read_bl_len); + /* -1 or -2 : delete boot partition of MMC + * need to switch to associated hwpart 1 or 2 + */ @@ -2147,45 +2383,40 @@ index 0000000..d263b38 + part->dev->dev_id, + -part->part_id)) + return -1; -+ blks = blk_derase(part->dev->block_dev, blks_offset, blks_size); ++ blks = blk_derase(block_dev, blks_offset, blks_size); + /* return to user partition */ + if (part->part_id < 0) + blk_select_hwpart_devnum(IF_TYPE_MMC, + part->dev->dev_id, 0); + if (blks != blks_size) { + ret = -1; -+ stm32prog_err("mmc erase failed"); ++ stm32prog_err("%s (0x%x): MMC erase failed", ++ part->name, part->id); + } + break; -+ -+#ifdef CONFIG_SPI_FLASH -+ case DFU_DEV_SF: -+ printf("on sf %d: ", part->dev->dev_id); -+ sprintf(cmdbuf, "sf erase 0x%llx 0x%llx", -+ part->addr, part->size); ++#endif ++#ifdef CONFIG_MTD ++ case STM32PROG_NOR: ++ case STM32PROG_NAND: ++ case STM32PROG_SPI_NAND: ++ get_mtd_by_target(devstr, part->target, part->dev->dev_id); ++ printf("on %s: ", devstr); ++ sprintf(cmdbuf, "mtd erase %s 0x%llx 0x%llx", ++ devstr, part->addr, part->size); + if (run_command(cmdbuf, 0)) { + ret = -1; -+ stm32prog_err("sf erase commands failed (%s)", cmdbuf); ++ stm32prog_err("%s (0x%x): MTD erase commands failed (%s)", ++ part->name, part->id, cmdbuf); + } + break; +#endif -+ -+#ifdef CONFIG_CMD_NAND -+ case DFU_DEV_NAND: -+ printf("on nand %d: ", part->dev->dev_id); -+ nand_erase_options_t opts; -+ memset(&opts, 0, sizeof(opts)); -+ opts.offset = part->addr; -+ opts.length = part->size; -+ opts.quiet = 1; -+ ret = nand_erase_opts(part->dev->mtd, &opts); -+ if (ret) -+ stm32prog_err("nand erase failed"); ++ case STM32PROG_RAM: ++ printf("on ram: "); ++ memset((void *)(uintptr_t)part->addr, 0, (size_t)part->size); + break; -+#endif + default: + ret = -1; -+ stm32prog_err("erase invalid"); ++ stm32prog_err("%s (0x%x): erase invalid", part->name, part->id); + break; + } + if (!ret) @@ -2194,7 +2425,7 @@ index 0000000..d263b38 + return ret; +} + -+void stm32prog_devices_init(struct stm32prog_data *data) ++static void stm32prog_devices_init(struct stm32prog_data *data) +{ + int i; + int ret; @@ -2226,11 +2457,9 @@ index 0000000..d263b38 + goto error; + } + -+ if (data->full_update) { -+ ret = create_partitions(data); -+ if (ret) -+ goto error; -+ } ++ ret = create_partitions(data); ++ if (ret) ++ goto error; + + /* delete partition GPT or MTD */ + for (i = 0; i < data->part_nb; i++) { @@ -2267,49 +2496,13 @@ index 0000000..d263b38 + return dfu_init_entities(data); +} + -+struct stm32prog_data *stm32prog_init(enum stm32prog_link_t link, -+ int link_dev, -+ ulong addr, -+ ulong size) ++int stm32prog_init(struct stm32prog_data *data, ulong addr, ulong size) +{ -+ struct stm32prog_data *data; -+ -+ /*pr_debug("%s entry\n", __func__);*/ -+ data = (struct stm32prog_data *)malloc(sizeof(*data)); -+ -+ if (!data) { -+ pr_err("alloc failed"); -+ goto err; -+ } + memset(data, 0x0, sizeof(*data)); + data->read_phase = PHASE_RESET; + data->phase = PHASE_FLASHLAYOUT; + -+ parse_flash_layout(data, addr, size); -+ -+ /* prepare DFU for device read/write */ -+ if (stm32prog_dfu_init(data)) -+ goto err; -+ -+ switch (link) { -+ case LINK_SERIAL: -+ if (stm32prog_serial_init(data, link_dev)) -+ goto err; -+ data->buffer = memalign(CONFIG_SYS_CACHELINE_SIZE, -+ USART_RAM_BUFFER_SIZE); -+ break; -+ case LINK_USB: -+ break; -+ default: -+ break; -+ } -+ /*pr_debug("%s exit ok\n", __func__);*/ -+ return data; -+ -+err: -+ free(data); -+ pr_debug("%s exit error\n", __func__); -+ return 0; ++ return parse_flash_layout(data, addr, size); +} + +void stm32prog_clean(struct stm32prog_data *data) @@ -2320,58 +2513,74 @@ index 0000000..d263b38 + free(data->otp_part); + free(data->buffer); + free(data->header_data); -+ free(data); ++} ++ ++/* DFU callback: used after serial and direct DFU USB access */ ++void dfu_flush_callback(struct dfu_entity *dfu) ++{ ++ if (!stm32prog_data) ++ return; ++ ++ if (dfu->dev_type == DFU_DEV_VIRT) { ++ if (dfu->data.virt.dev_num == PHASE_OTP) ++ stm32prog_otp_start(stm32prog_data); ++ else if (dfu->data.virt.dev_num == PHASE_PMIC) ++ stm32prog_pmic_start(stm32prog_data); ++ return; ++ } ++ ++ if (dfu->dev_type == DFU_DEV_RAM) { ++ if (dfu->alt == 0 && ++ stm32prog_data->phase == PHASE_FLASHLAYOUT) { ++ stm32prog_end_phase(stm32prog_data); ++ /* waiting DFU DETACH for reenumeration */ ++ } ++ } ++ ++ if (!stm32prog_data->cur_part) ++ return; ++ ++ if (dfu->alt == stm32prog_data->cur_part->alt_id) { ++ stm32prog_end_phase(stm32prog_data); ++ stm32prog_next_phase(stm32prog_data); ++ } ++} ++ ++void dfu_initiated_callback(struct dfu_entity *dfu) ++{ ++ if (!stm32prog_data) ++ return; ++ ++ if (!stm32prog_data->cur_part) ++ return; ++ ++ /* force the saved offset for the current partition */ ++ if (dfu->alt == stm32prog_data->cur_part->alt_id) { ++ dfu->offset = stm32prog_data->offset; ++ stm32prog_data->dfu_seq = 0; ++ pr_debug("dfu offset = 0x%llx\n", dfu->offset); ++ } +} diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h new file mode 100644 -index 0000000..51541bc +index 0000000..bae4e91 --- /dev/null +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h -@@ -0,0 +1,202 @@ +@@ -0,0 +1,185 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +#ifndef _STM32PROG_H_ +#define _STM32PROG_H_ + -+/* - 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 -----------------------------*/ -+#define GET_CMD_COMMAND 0x00 /* Get CMD command*/ -+#define GET_VER_COMMAND 0x01 /* Get Version command*/ -+#define GET_ID_COMMAND 0x02 /* Get ID command*/ -+#define GET_PHASE_COMMAND 0x03 /* Get Phase command*/ -+#define RM_COMMAND 0x11 /* Read Memory command*/ -+#define READ_PART_COMMAND 0x12 /* Read Partition command*/ -+#define START_COMMAND 0x21 /* START command (Go)*/ -+#define DOWNLOAD_COMMAND 0x31 /* Download command*/ -+/* existing command for other STM32 but not used */ -+/* ERASE 0x43 */ -+/* EXTENDED_ERASE 0x44 */ -+/* WRITE_UNPROTECTED 0x73 */ -+/* READOUT_PROTECT 0x82 */ -+/* READOUT_UNPROTECT 0x92 */ -+ -+/* - miscellaneous defines ----------------------------------------*/ -+#define INIT_BYTE 0x7F /*Init Byte ID*/ -+#define ACK_BYTE 0x79 /*Acknowlede Byte ID*/ -+#define NACK_BYTE 0x1F /*No Acknowlede Byte ID*/ -+#define ABORT_BYTE 0x5F /*ABORT*/ -+ +/* - phase defines ------------------------------------------------*/ +#define PHASE_FLASHLAYOUT 0x00 +#define PHASE_FIRST_USER 0x10 +#define PHASE_LAST_USER 0xF0 +#define PHASE_CMD 0xF1 +#define PHASE_OTP 0xF2 -+#define PHASE_SSP 0xF3 +#define PHASE_PMIC 0xF4 +#define PHASE_END 0xFE +#define PHASE_RESET 0xFF @@ -2382,6 +2591,15 @@ index 0000000..51541bc +#define OTP_SIZE 1024 +#define PMIC_SIZE 8 + ++enum stm32prog_target { ++ STM32PROG_NONE, ++ STM32PROG_MMC, ++ STM32PROG_NAND, ++ STM32PROG_NOR, ++ STM32PROG_SPI_NAND, ++ STM32PROG_RAM ++}; ++ +enum stm32prog_link_t { + LINK_SERIAL, + LINK_USB, @@ -2424,24 +2642,25 @@ index 0000000..51541bc + +/* device information */ +struct stm32prog_dev_t { -+ enum dfu_device_type dev_type; ++ enum stm32prog_target target; + char dev_id; -+ struct blk_desc *block_dev; -+ u32 lba_blk_size; /* for MMC RAW */ + u32 erase_size; ++ struct mmc *mmc; + struct mtd_info *mtd; + /* list of partition for this device / ordered in offset */ + struct list_head part_list; ++ bool full_update; +}; + -+/* partition information build form FlashLayout and device */ ++/* partition information build from FlashLayout and device */ +struct stm32prog_part_t { -+ /* FlashLayout inforamtion */ ++ /* FlashLayout information */ + int option; + int id; + enum stm32prog_part_type part_type; -+ enum dfu_device_type dev_type; ++ enum stm32prog_target target; + char dev_id; ++ + /* partition name + * (16 char in gpt, + 1 for null terminated string + */ @@ -2452,8 +2671,7 @@ index 0000000..51541bc + + /* information on associated device */ + struct stm32prog_dev_t *dev; /* pointer to device */ -+ /* partition id in gpt when >0, -1 and -2 for boot partition of MMC */ -+ s16 part_id; ++ s16 part_id; /* partition id in device */ + int alt_id; /* alt id in usb/dfu */ + + struct list_head list; @@ -2466,10 +2684,11 @@ index 0000000..51541bc + 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 */ -+ int full_update; ++ bool tee_detected; ++ bool fsbl_nor_detected; + + /* command internal information */ -+ int phase; ++ unsigned int phase; + u32 offset; + char error[255]; + struct stm32prog_part_t *cur_part; @@ -2487,8 +2706,14 @@ index 0000000..51541bc + u8 *buffer; /* size = USART_RAM_BUFFER_SIZE*/ + int dfu_seq; + u8 read_phase; ++ ++ /* bootm information */ ++ u32 uimage; ++ u32 dtb; +}; + ++extern struct stm32prog_data *stm32prog_data; ++ +/* OTP access */ +int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, + u8 *buffer, long *size); @@ -2507,12 +2732,9 @@ index 0000000..51541bc +u8 stm32prog_header_check(struct raw_header_s *raw_header, + struct image_header_s *header); +int stm32prog_dfu_init(struct stm32prog_data *data); -+void stm32prog_end_phase(struct stm32prog_data *data); +void stm32prog_next_phase(struct stm32prog_data *data); +void stm32prog_do_reset(struct stm32prog_data *data); + -+int stm32prog_serial_init(struct stm32prog_data *data, int link_dev); -+ +char *stm32prog_get_error(struct stm32prog_data *data); + +#define stm32prog_err(args...) {\ @@ -2523,8 +2745,8 @@ index 0000000..51541bc + } + +/* Main function */ -+struct stm32prog_data *stm32prog_init(enum stm32prog_link_t link, -+ int dev, ulong addr, ulong size); ++int stm32prog_init(struct stm32prog_data *data, ulong addr, ulong size); ++int stm32prog_serial_init(struct stm32prog_data *data, int link_dev); +bool stm32prog_serial_loop(struct stm32prog_data *data); +bool stm32prog_usb_loop(struct stm32prog_data *data, int dev); +void stm32prog_clean(struct stm32prog_data *data); @@ -2532,13 +2754,13 @@ index 0000000..51541bc +#endif diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c new file mode 100644 -index 0000000..36f9393 +index 0000000..5a16979 --- /dev/null +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c -@@ -0,0 +1,972 @@ +@@ -0,0 +1,993 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +#include @@ -2551,6 +2773,35 @@ index 0000000..36f9393 +#include +#include "stm32prog.h" + ++/* - 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 -----------------------------*/ ++#define GET_CMD_COMMAND 0x00 /* Get CMD command*/ ++#define GET_VER_COMMAND 0x01 /* Get Version command*/ ++#define GET_ID_COMMAND 0x02 /* Get ID command*/ ++#define GET_PHASE_COMMAND 0x03 /* Get Phase command*/ ++#define RM_COMMAND 0x11 /* Read Memory command*/ ++#define READ_PART_COMMAND 0x12 /* Read Partition command*/ ++#define START_COMMAND 0x21 /* START command (Go)*/ ++#define DOWNLOAD_COMMAND 0x31 /* Download command*/ ++/* existing command for other STM32 but not used */ ++/* ERASE 0x43 */ ++/* EXTENDED_ERASE 0x44 */ ++/* WRITE_UNPROTECTED 0x73 */ ++/* READOUT_PROTECT 0x82 */ ++/* READOUT_UNPROTECT 0x92 */ ++ ++/* - miscellaneous defines ----------------------------------------*/ ++#define INIT_BYTE 0x7F /*Init Byte ID*/ ++#define ACK_BYTE 0x79 /*Acknowlede Byte ID*/ ++#define NACK_BYTE 0x1F /*No Acknowlede Byte ID*/ ++#define ABORT_BYTE 0x5F /*ABORT*/ ++ +struct udevice *down_serial_dev; + +const u8 cmd_id[] = { @@ -2567,7 +2818,7 @@ index 0000000..36f9393 +#define NB_CMD sizeof(cmd_id) + +/* DFU support for serial *********************************************/ -+struct dfu_entity *stm32prog_get_entity(struct stm32prog_data *data) ++static struct dfu_entity *stm32prog_get_entity(struct stm32prog_data *data) +{ + int alt_id; + @@ -2614,9 +2865,10 @@ index 0000000..36f9393 + u8 *buffer, u32 buffer_size) +{ + struct dfu_entity *dfu_entity; -+ int ret; ++ struct stm32prog_part_t *part; ++ u32 size; ++ int ret, i; + -+ /* pr_debug("%s entry\n", __func__); */ + if (data->dfu_seq) { + stm32prog_err("DFU write pending for phase %d, seq %d", + data->phase, data->dfu_seq); @@ -2633,11 +2885,19 @@ index 0000000..36f9393 + if (dfu_entity) + dfu_transaction_cleanup(dfu_entity); + } -+ dfu_entity = dfu_get_entity(phase - 1); ++ ++ dfu_entity = NULL; ++ /* found partition for the expected phase */ ++ for (i = 0; i < data->part_nb; i++) { ++ part = &data->part_array[i]; ++ if (part->id == phase) ++ dfu_entity = dfu_get_entity(part->alt_id); ++ } + if (!dfu_entity) { + stm32prog_err("read failed : phase %d is unknown", phase); + return -ENODEV; + } ++ + /* clear pending read before to force offset */ + if (dfu_entity->inited && + (data->read_phase != phase || data->offset != offset)) @@ -2666,14 +2926,17 @@ index 0000000..36f9393 + ret, phase, offset); + return ret; + } -+ if (ret < buffer_size) { ++ ++ size = ret; ++ ++ if (size < buffer_size) { + data->offset = 0; + data->read_phase = PHASE_END; -+ memset(buffer + ret, 0, buffer_size - ret); ++ memset(buffer + size, 0, buffer_size - size); + } else { -+ data->offset += ret; ++ data->offset += size; + } -+ /*pr_debug("%s exit ret=%d\n", __func__, ret);*/ ++ + return ret; +} + @@ -2702,13 +2965,10 @@ index 0000000..36f9393 + down_serial_dev = dev; + } else if (node > 0 && + !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node), -+ &dev)) { ++ &dev, false)) { + if (!device_probe(dev)) + down_serial_dev = dev; + } -+ /*pr_debug("alias=%s, path=%s, node = %d, dev=%0x\n", -+ * alias, path, node, (u32)down_serial_dev); -+ */ + if (!down_serial_dev) { + pr_err("%s = %s device not found", alias, path); + return -ENODEV; @@ -2733,6 +2993,9 @@ index 0000000..36f9393 + + clrsetbits_le32(&serial_config, SERIAL_PAR_MASK, SERIAL_PAR_EVEN); + ++ data->buffer = memalign(CONFIG_SYS_CACHELINE_SIZE, ++ USART_RAM_BUFFER_SIZE); ++ + return ops->setconfig(down_serial_dev, serial_config); +} + @@ -2753,8 +3016,10 @@ index 0000000..36f9393 + + do { + err = ops->getc(down_serial_dev); -+ if (err == -EAGAIN) ++ if (err == -EAGAIN) { + ctrlc(); ++ WATCHDOG_RESET(); ++ } + } while ((err == -EAGAIN) && (!had_ctrlc())); + + return err; @@ -2781,6 +3046,7 @@ index 0000000..36f9393 + *count -= 1; + } else if (err == -EAGAIN) { + ctrlc(); ++ WATCHDOG_RESET(); + } else { + break; + } @@ -2808,8 +3074,6 @@ index 0000000..36f9393 + struct dfu_entity *dfu_entity; + u64 size = 0; + -+ /*pr_debug("%s entry\n", __func__);*/ -+ + dfu_entity = stm32prog_get_entity(data); + if (!dfu_entity) + return -ENODEV; @@ -2849,7 +3113,7 @@ index 0000000..36f9393 + + free(data->header_data); + data->header_data = NULL; -+ /*pr_debug("%s result=%d\n", __func__, ret);*/ ++ + return ret; +} + @@ -2858,8 +3122,6 @@ index 0000000..36f9393 + u8 ret = 0; + struct dfu_entity *dfu_entity; + -+ /*pr_debug("%s entry\n", __func__);*/ -+ + if (address < 0x100) { + if (address == PHASE_OTP) + return stm32prog_otp_start(data); @@ -2920,12 +3182,9 @@ index 0000000..36f9393 + printf("\n checksum OK (0x%x)\n", data->checksum); + } + -+ stm32prog_end_phase(data); + /* update DFU with received flashlayout */ + if (data->phase == PHASE_FLASHLAYOUT) + stm32prog_dfu_init(data); -+ /* found next selected partition */ -+ stm32prog_next_phase(data); + } else { + void (*entry)(void) = (void *)address; + @@ -2934,18 +3193,15 @@ index 0000000..36f9393 + printf("## Application terminated\n"); + ret = -ENOEXEC; + } -+ /*pr_debug("%s exit ret=%d, phase=0x%x, add=0x%x\n", __func__, -+ * ret, data->phase, address); -+ */ ++ + return ret; +} + -+/* -+ * Function Name : get_address -+ * Description : Get address if it is valid -+ * Input : None -+ * Output : None -+ * Return : The address area or Error_32 ++/** ++ * get_address() - Get address if it is valid ++ * ++ * @tmp_xor: Current xor value to update ++ * @return The address area + */ +static u32 get_address(u8 *tmp_xor) +{ @@ -2979,12 +3235,10 @@ index 0000000..36f9393 +} + +/* Command -----------------------------------------------*/ -+/* -+ * Function Name : get_cmd_command -+ * Description : Respond to Get command -+ * Input : None -+ * Output : None -+ * Return : None ++/** ++ * get_cmd_command() - Respond to Get command ++ * ++ * @data: Current command context + */ +static void get_cmd_command(struct stm32prog_data *data) +{ @@ -2999,12 +3253,10 @@ index 0000000..36f9393 + stm32prog_serial_result(ACK_BYTE); +} + -+/* -+ * Function Name : get_version_command -+ * Description : Respond to Get Version command -+ * Input : None -+ * Output : None -+ * Return : None ++/** ++ * get_version_command() - Respond to Get Version command ++ * ++ * @data: Current command context + */ +static void get_version_command(struct stm32prog_data *data) +{ @@ -3012,12 +3264,10 @@ index 0000000..36f9393 + stm32prog_serial_result(ACK_BYTE); +} + -+/* -+ * Function Name : get_id_command -+ * Description : Respond to Get ID command -+ * Input : None -+ * Output : None -+ * Return : None ++/** ++ * get_id_command() - Respond to Get ID command ++ * ++ * @data: Current command context + */ +static void get_id_command(struct stm32prog_data *data) +{ @@ -3028,12 +3278,10 @@ index 0000000..36f9393 + stm32prog_serial_result(ACK_BYTE); +} + -+/* -+ * Function Name : get_phase_command -+ * Description : Respond to Get phase -+ * Input : None -+ * Output : None -+ * Return : None ++/** ++ * get_phase_command() - Respond to Get phase ++ * ++ * @data: Current command context + */ +static void get_phase_command(struct stm32prog_data *data) +{ @@ -3065,12 +3313,10 @@ index 0000000..36f9393 + stm32prog_do_reset(data); +} + -+/* -+ * Function Name : read_memory_command -+ * Description : Read data from memory -+ * Input : None -+ * Output : None -+ * Return : None ++/** ++ * read_memory_command() - Read data from memory ++ * ++ * @data: Current command context + */ +static void read_memory_command(struct stm32prog_data *data) +{ @@ -3110,12 +3356,12 @@ index 0000000..36f9393 + stm32prog_serial_putc(*(u8 *)(address++)); +} + -+/* -+ * Function Name : start_command -+ * Description : Jump to user application in RAM or partition check -+ * Input : None -+ * Output : None -+ * Return : None ++/** ++ * start_command() - Respond to start command ++ * ++ * Jump to user application in RAM or partition check ++ * ++ * @data: Current command context + */ +static void start_command(struct stm32prog_data *data) +{ @@ -3142,12 +3388,12 @@ index 0000000..36f9393 + stm32prog_serial_result(ACK_BYTE); +} + -+/* -+ * Function Name : download_command -+ * Description : Write data to Flash -+ * Input : None -+ * Output : None -+ * Return : Result ++/** ++ * download_command() - Respond to download command ++ * ++ * Write data to not volatile memory, Flash ++ * ++ * @data: Current command context + */ +static void download_command(struct stm32prog_data *data) +{ @@ -3164,7 +3410,7 @@ index 0000000..36f9393 + u32 packet_number; + u32 result = ACK_BYTE; + u8 ret; -+ int i; ++ unsigned int i; + bool error; + int rcv; + @@ -3267,6 +3513,10 @@ index 0000000..36f9393 + if (rcv_xor != my_xor) { + printf("checksum error on packet %d\n", + packet_number); ++ /* wait to be sure that all data are received ++ * in the FIFO before flush ++ */ ++ mdelay(30); + data->packet_number--; + result = NACK_BYTE; + goto end; @@ -3313,17 +3563,12 @@ index 0000000..36f9393 + goto end; + } + } -+ /* -+ * pr_debug("packet_number = 0x%x\n", packet_number); -+ * pr_debug("cursor = 0x%x\n", data->cursor); -+ * pr_debug("image_length = 0x%x\n", image_header->image_length); -+ * pr_debug("codesize = 0x%x\n", codesize); -+ */ ++ + if (image_header->present) { + if (data->cursor <= BL_HEADER_SIZE) + goto end; + /* compute checksum on payload */ -+ for (i = size; i < codesize; i++) ++ for (i = (unsigned long)size; i < codesize; i++) + data->checksum += data->buffer[i]; + + if (data->cursor > @@ -3347,23 +3592,22 @@ index 0000000..36f9393 + result = ABORT_BYTE; + +end: -+ /*pr_debug("%s : result = 0x%x\n", __func__, result);*/ + stm32prog_serial_result(result); +} + -+/* -+ * Function Name : read_partition -+ * Description : read data from Flash -+ * Input : None -+ * Output : None -+ * Return : Result ++/** ++ * read_partition() - Respond to read command ++ * ++ * Read data from not volatile memory, Flash ++ * ++ * @data: Current command context + */ +static void read_partition_command(struct stm32prog_data *data) +{ -+ u32 part_id, codesize, offset = 0, rcv_data; ++ u32 i, part_id, codesize, offset = 0, rcv_data; + long size; + u8 tmp_xor; -+ int i, res; ++ int res; + u8 buffer[256]; + + part_id = stm32prog_serial_getc(); @@ -3392,28 +3636,29 @@ index 0000000..36f9393 + } + + pr_debug("%s : %x\n", __func__, part_id); ++ rcv_data = 0; + switch (part_id) { + case PHASE_OTP: -+ res = 0; + size = codesize; + if (!stm32prog_otp_read(data, offset, buffer, &size)) -+ res = size; ++ rcv_data = size; + break; + case PHASE_PMIC: -+ res = 0; + size = codesize; + if (!stm32prog_pmic_read(data, offset, buffer, &size)) -+ res = size; ++ rcv_data = size; + break; + default: + res = stm32prog_read(data, part_id, offset, + buffer, codesize); ++ if (res > 0) ++ rcv_data = res; + break; + } -+ if (res > 0) { ++ if (rcv_data > 0) { + stm32prog_serial_putc(ACK_BYTE); + /*----------- Send data to the host -----------*/ -+ for (i = 0; i < res; i++) ++ for (i = 0; i < rcv_data; i++) + stm32prog_serial_putc(buffer[i]); + /*----------- Send filler to the host -----------*/ + for (; i < codesize; i++) @@ -3427,14 +3672,13 @@ index 0000000..36f9393 + stm32prog_serial_result(NACK_BYTE); +} + -+/** SERIAL LOOP ****************************************************/ ++/* MAIN function = SERIAL LOOP ***********************************************/ + -+/* -+ * Function Name : stm32prog_serial_loop -+ * Description : USART bootloader Loop routine -+ * Input : data -+ * Output : None -+ * Return : None ++/** ++ * stm32prog_serial_loop() - USART bootloader Loop routine ++ * ++ * @data: Current command context ++ * @return true if reset is needed after loop + */ +bool stm32prog_serial_loop(struct stm32prog_data *data) +{ @@ -3489,10 +3733,9 @@ index 0000000..36f9393 + /* wait to be sure that all data are received + * in the FIFO before flush (CMD and XOR) + */ -+ mdelay(2); ++ mdelay(3); + stm32prog_serial_result(NACK_BYTE); + } else { -+ /*pr_debug("+ cmd %x\n", counter);*/ + stm32prog_serial_result(ACK_BYTE); + cmd_func[counter](data); + } @@ -3510,33 +3753,23 @@ index 0000000..36f9393 +} diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c new file mode 100644 -index 0000000..c7dd678 +index 0000000..30547f9 --- /dev/null +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c -@@ -0,0 +1,278 @@ +@@ -0,0 +1,232 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved + */ + +#include -+#include +#include +#include +#include -+#include ++#include ++#include +#include "stm32prog.h" + -+struct stm32prog_data *stm32prog_data; -+ -+static int stm32prog_get_alternate(struct stm32prog_data *data) -+{ -+ if (data->cur_part) -+ return data->cur_part->alt_id; -+ else -+ return -EINVAL; -+} -+ +static int stm32prog_set_phase(struct stm32prog_data *data, u8 phase, + u32 offset) +{ @@ -3549,7 +3782,7 @@ index 0000000..c7dd678 + return 0; + } + -+ /* found partition */ ++ /* found partition for phase */ + for (i = 0; i < data->part_nb; i++) { + part = &data->part_array[i]; + if (part->id == phase) { @@ -3649,53 +3882,8 @@ index 0000000..c7dd678 + return 0; +} + -+/* DFU access to virtual partition */ -+ -+void dfu_flush_callback(struct dfu_entity *dfu) -+{ -+ if (!stm32prog_data) -+ return; -+ -+ if (dfu->dev_type == DFU_DEV_VIRT) { -+ if (dfu->data.virt.dev_num == PHASE_OTP) -+ stm32prog_otp_start(stm32prog_data); -+ else if (dfu->data.virt.dev_num == PHASE_PMIC) -+ stm32prog_pmic_start(stm32prog_data); -+ return; -+ } -+ -+ if (dfu->dev_type == DFU_DEV_RAM) { -+ if (dfu->alt == 0 && -+ stm32prog_data->phase == PHASE_FLASHLAYOUT) { -+ stm32prog_end_phase(stm32prog_data); -+ /* waiting DFU DETACH for reenumeration */ -+ } -+ return; -+ } -+ -+ if (dfu->alt == stm32prog_get_alternate(stm32prog_data)) { -+ stm32prog_end_phase(stm32prog_data); -+ stm32prog_next_phase(stm32prog_data); -+ } -+} -+ -+void dfu_initiated_callback(struct dfu_entity *dfu) -+{ -+ int phase; -+ -+ if (!stm32prog_data) -+ return; -+ -+ phase = stm32prog_data->phase; -+ if (dfu->alt == stm32prog_get_alternate(stm32prog_data)) { -+ dfu->offset = stm32prog_data->offset; -+ stm32prog_set_phase(stm32prog_data, phase, 0); -+ pr_debug("dfu offset = 0x%llx\n", dfu->offset); -+ } -+} -+ -+int dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset, -+ void *buf, long *len) ++int stm32prog_write_medium_virt(struct dfu_entity *dfu, u64 offset, ++ void *buf, long *len) +{ + if (dfu->dev_type != DFU_DEV_VIRT) + return -EINVAL; @@ -3716,8 +3904,8 @@ index 0000000..c7dd678 + return 0; +} + -+int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset, -+ void *buf, long *len) ++int stm32prog_read_medium_virt(struct dfu_entity *dfu, u64 offset, ++ void *buf, long *len) +{ + if (dfu->dev_type != DFU_DEV_VIRT) + return -EINVAL; @@ -3738,7 +3926,7 @@ index 0000000..c7dd678 + return 0; +} + -+int dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size) ++int stm32prog_get_medium_size_virt(struct dfu_entity *dfu, u64 *size) +{ + if (dfu->dev_type != DFU_DEV_VIRT) { + *size = 0; @@ -3762,17 +3950,20 @@ index 0000000..c7dd678 + return 0; +} + -+/* USB download gadget for STM32 Programmer */ -+ -+static const char product[] = -+ "USB download gadget@Device ID /0x500, @Revision ID /0x0000"; -+ +bool stm32prog_usb_loop(struct stm32prog_data *data, int dev) +{ + int ret; ++ bool result; ++ /* USB download gadget for STM32 Programmer */ ++ char product[128]; ++ char name[SOC_NAME_SIZE]; + -+ stm32prog_data = data; ++ get_soc_name(name); ++ snprintf(product, sizeof(product), ++ "USB download gadget@Device ID /0x%03X, @Revision ID /0x%04X, @Name /%s,", ++ get_cpu_dev(), get_cpu_rev(), name); + g_dnl_set_product(product); ++ + if (stm32prog_data->phase == PHASE_FLASHLAYOUT) { + ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu"); + if (ret || stm32prog_data->phase == PHASE_DO_RESET) @@ -3783,8 +3974,14 @@ index 0000000..c7dd678 + /* found next selected partition */ + stm32prog_next_phase(data); + } -+ return (run_usb_dnl_gadget(dev, "usb_dnl_dfu") || -+ (stm32prog_data->phase == PHASE_DO_RESET)); ++ ++ ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu"); ++ ++ result = !!(ret) || (stm32prog_data->phase == PHASE_DO_RESET); ++ ++ g_dnl_set_product(NULL); ++ ++ return result; +} + +int g_dnl_get_board_bcd_device_number(int gcnum) @@ -3792,509 +3989,561 @@ index 0000000..c7dd678 + pr_debug("%s\n", __func__); + return 0x200; +} -diff --git a/arch/arm/mach-stm32mp/config.mk b/arch/arm/mach-stm32mp/config.mk -index cde5850..bd8944a 100644 ---- a/arch/arm/mach-stm32mp/config.mk -+++ b/arch/arm/mach-stm32mp/config.mk -@@ -3,7 +3,21 @@ - # Copyright (C) 2018, STMicroelectronics - All Rights Reserved - # - --ALL-$(CONFIG_SPL_BUILD) += spl/u-boot-spl.stm32 -+ifndef CONFIG_SPL -+ALL-y += u-boot.stm32 -+else -+ifdef CONFIG_SPL_BUILD -+ALL-y += spl/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) - diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c -index 0e01f8e..5d5ce4a 100644 +index ed7d9f6..305534f 100644 --- a/arch/arm/mach-stm32mp/cpu.c +++ b/arch/arm/mach-stm32mp/cpu.c -@@ -6,18 +6,23 @@ - #include - #include - #include -+#include +@@ -9,6 +9,7 @@ + #include #include #include ++#include #include #include #include -+#include - #include -+#include -+#include +@@ -35,7 +36,9 @@ + #define TAMP_CR1 (STM32_TAMP_BASE + 0x00) - /* 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_BDCR_VSWRST BIT(31) - #define RCC_BDCR_RTCSRC GENMASK(17, 16) - #define RCC_DBGCFGR_DBGCKEN BIT(8) -@@ -55,10 +60,34 @@ + #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) +@@ -59,12 +62,6 @@ + #define BOOTROM_INSTANCE_MASK GENMASK(31, 16) #define BOOTROM_INSTANCE_SHIFT 16 - /* BSEC OTP index */ -+#define BSEC_OTP_RPN 1 - #define BSEC_OTP_SERIAL 13 -+#define BSEC_OTP_PKG 16 - #define BSEC_OTP_MAC 57 - -+/* 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 PKG_AA_LBGA448 4 -+#define PKG_AB_LBGA354 3 -+#define PKG_AC_TFBGA361 2 -+#define PKG_AD_TFBGA257 1 -+ -+DECLARE_GLOBAL_DATA_PTR; -+ - #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) -+#ifndef CONFIG_STM32MP1_TRUSTED - static void security_init(void) - { - /* Disable the backup domain write protection */ -@@ -114,6 +143,7 @@ static void security_init(void) - */ - writel(0x0, TAMP_CR1); - } -+#endif /* CONFIG_STM32MP1_TRUSTED */ - - /* - * Debug init -@@ -130,10 +160,12 @@ static void dbgmcu_init(void) - static u32 get_bootmode(void) - { - u32 boot_mode; --#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) -+#if !defined(CONFIG_STM32MP1_TRUSTED) && \ -+ (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) - u32 bootrom_itf = readl(BOOTROM_PARAM_ADDR); - u32 bootrom_device, bootrom_instance; - -+ /* read bootrom context */ - bootrom_device = - (bootrom_itf & BOOTROM_MODE_MASK) >> BOOTROM_MODE_SHIFT; - bootrom_instance = -@@ -167,16 +199,18 @@ int arch_cpu_init(void) - - #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) - dbgmcu_init(); +-/* BSEC OTP index */ +-#define BSEC_OTP_RPN 1 +-#define BSEC_OTP_SERIAL 13 +-#define BSEC_OTP_PKG 16 +-#define BSEC_OTP_MAC 57 - -+#ifndef CONFIG_STM32MP1_TRUSTED + /* Device Part Number (RPN) = OTP_DATA1 lower 8 bits */ + #define RPN_SHIFT 0 + #define RPN_MASK GENMASK(7, 0) +@@ -149,8 +146,13 @@ static void dbgmcu_init(void) + { + setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN); + +- /* Freeze IWDG2 if Cortex-A7 is in debug mode */ +- setbits_le32(DBGMCU_APB4FZ1, DBGMCU_APB4FZ1_IWDG2); ++ /* ++ * 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 (!CONFIG_IS_ENABLED(STM32MP1_TRUSTED) && bsec_dbgswenable()) ++ setbits_le32(DBGMCU_APB4FZ1, DBGMCU_APB4FZ1_IWDG2); + } + #endif /* !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) */ + +@@ -206,6 +208,11 @@ int arch_cpu_init(void) 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 -+#endif - /* get bootmode from BootRom context: saved in TAMP register */ boot_mode = get_bootmode(); +@@ -230,9 +237,22 @@ void enable_caches(void) - if ((boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART) - gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; --#if defined(CONFIG_DEBUG_UART) && \ -+#if defined(CONFIG_DEBUG_UART) &&\ -+ !defined(CONFIG_STM32MP1_TRUSTED) && \ - (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) - else - debug_uart_init(); -@@ -203,25 +237,94 @@ u32 get_cpu_rev(void) - return (read_idc() & DBGMCU_IDC_REV_ID_MASK) >> DBGMCU_IDC_REV_ID_SHIFT; + static u32 read_idc(void) + { +- setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN); ++ /* DBGMCU access is controlled by BSEC_DENABLE.DBGSWENABLE */ ++ if (bsec_dbgswenable()) { ++ setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN); ++ ++ return readl(DBGMCU_IDC); ++ } + +- 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; } -+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_GET_DRIVER(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_rev(void) +@@ -265,11 +285,7 @@ static u32 get_cpu_rpn(void) + u32 get_cpu_type(void) { -- return (read_idc() & DBGMCU_IDC_DEV_ID_MASK) >> DBGMCU_IDC_DEV_ID_SHIFT; -+ u32 id; -+ -+ id = (read_idc() & DBGMCU_IDC_DEV_ID_MASK) >> DBGMCU_IDC_DEV_ID_SHIFT; -+ -+ return (id << 16) | get_cpu_rpn(); -+} -+ -+/* Get Package options from OTP */ -+static u32 get_cpu_package(void) -+{ -+ return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK); +- u32 id; +- +- id = (read_idc() & DBGMCU_IDC_DEV_ID_MASK) >> DBGMCU_IDC_DEV_ID_SHIFT; +- +- return (id << 16) | get_cpu_rpn(); ++ return (get_cpu_dev() << 16) | get_cpu_rpn(); } - #if defined(CONFIG_DISPLAY_CPUINFO) - int print_cpuinfo(void) + /* Get Package options from OTP */ +@@ -278,25 +294,42 @@ u32 get_cpu_package(void) + return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK); + } + +-#if defined(CONFIG_DISPLAY_CPUINFO) +-int print_cpuinfo(void) ++void get_soc_name(char name[SOC_NAME_SIZE]) { -- char *cpu_s, *cpu_r; -+ char *cpu_s, *cpu_r, *pkg; + char *cpu_s, *cpu_r, *pkg; -+ /* MPUs Part Numbers */ + /* MPUs Part Numbers */ switch (get_cpu_type()) { -- case CPU_STMP32MP15x: -- cpu_s = "15x"; -+ case CPU_STM32MP157Cxx: -+ cpu_s = "157C"; ++ case CPU_STM32MP157Fxx: ++ cpu_s = "157F"; + break; -+ case CPU_STM32MP157Axx: -+ cpu_s = "157A"; ++ case CPU_STM32MP157Dxx: ++ cpu_s = "157D"; + break; -+ case CPU_STM32MP153Cxx: -+ cpu_s = "153C"; -+ break; -+ case CPU_STM32MP153Axx: -+ cpu_s = "153A"; -+ break; -+ case CPU_STM32MP151Cxx: -+ cpu_s = "151C"; -+ break; -+ case CPU_STM32MP151Axx: -+ cpu_s = "151A"; -+ break; -+ default: -+ cpu_s = "????"; -+ break; -+ } -+ -+ /* Package */ -+ switch (get_cpu_package()) { -+ case PKG_AA_LBGA448: -+ pkg = "AA"; -+ break; -+ case PKG_AB_LBGA354: -+ pkg = "AB"; -+ break; -+ case PKG_AC_TFBGA361: -+ pkg = "AC"; -+ break; -+ case PKG_AD_TFBGA257: -+ pkg = "AD"; + case CPU_STM32MP157Cxx: + cpu_s = "157C"; break; + case CPU_STM32MP157Axx: + cpu_s = "157A"; + break; ++ case CPU_STM32MP153Fxx: ++ cpu_s = "153F"; ++ break; ++ case CPU_STM32MP153Dxx: ++ cpu_s = "153D"; ++ break; + case CPU_STM32MP153Cxx: + cpu_s = "153C"; + break; + case CPU_STM32MP153Axx: + cpu_s = "153A"; + break; ++ case CPU_STM32MP151Fxx: ++ cpu_s = "151F"; ++ break; ++ case CPU_STM32MP151Dxx: ++ cpu_s = "151D"; ++ break; + case CPU_STM32MP151Cxx: + cpu_s = "151C"; + break; +@@ -335,12 +368,24 @@ int print_cpuinfo(void) + case CPU_REVB: + cpu_r = "B"; + break; ++ case CPU_REVZ: ++ cpu_r = "Z"; ++ break; default: -- cpu_s = "?"; -+ pkg = "??"; + cpu_r = "?"; break; } -+ /* REVISION */ - switch (get_cpu_rev()) { - case CPU_REVA: - cpu_r = "A"; -@@ -234,7 +337,7 @@ int print_cpuinfo(void) - break; - } - -- printf("CPU: STM32MP%s.%s\n", cpu_s, cpu_r); -+ printf("CPU: STM32MP%s%s Rev.%s\n", cpu_s, pkg, cpu_r); +- printf("CPU: STM32MP%s%s Rev.%s\n", cpu_s, pkg, cpu_r); ++ snprintf(name, SOC_NAME_SIZE, "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r); ++} ++ ++#if defined(CONFIG_DISPLAY_CPUINFO) ++int print_cpuinfo(void) ++{ ++ char name[SOC_NAME_SIZE]; ++ ++ get_soc_name(name); ++ printf("CPU: %s\n", name); return 0; } -@@ -242,20 +345,48 @@ int print_cpuinfo(void) - - static void setup_boot_mode(void) - { -+ const u32 serial_addr[] = { -+ STM32_USART1_BASE, -+ STM32_USART2_BASE, -+ STM32_USART3_BASE, -+ STM32_UART4_BASE, -+ STM32_UART5_BASE, -+ STM32_USART6_BASE, -+ STM32_UART7_BASE, -+ STM32_UART8_BASE -+ }; - char cmd[60]; - u32 boot_ctx = readl(TAMP_BOOT_CONTEXT); - u32 boot_mode = - (boot_ctx & TAMP_BOOT_MODE_MASK) >> TAMP_BOOT_MODE_SHIFT; - 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\n", -- __func__, boot_ctx, boot_mode, instance); -- -+ debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d forced=%x\n", -+ __func__, boot_ctx, boot_mode, instance, forced_mode); - switch (boot_mode & TAMP_BOOT_DEVICE_MASK) { - case BOOT_SERIAL_UART: -- sprintf(cmd, "%d", instance); -- env_set("boot_device", "uart"); -+ if (instance > ARRAY_SIZE(serial_addr)) -+ 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)) -+ break; -+ sprintf(cmd, "%d", alias); -+ env_set("boot_device", "serial"); - env_set("boot_instance", cmd); -+ -+ /* restore console on uart when not used */ -+ if (gd->cur_serial_dev != dev) { -+ gd->flags &= ~(GD_FLG_SILENT | -+ GD_FLG_DISABLE_CONSOLE); -+ printf("serial boot with console enabled!\n"); -+ } - break; - case BOOT_SERIAL_USB: - env_set("boot_device", "usb"); -@@ -268,17 +399,44 @@ static void setup_boot_mode(void) - env_set("boot_instance", cmd); - break; - case BOOT_FLASH_NAND: -+ sprintf(cmd, "%d", instance); +@@ -405,6 +450,10 @@ static void setup_boot_mode(void) env_set("boot_device", "nand"); -- env_set("boot_instance", "0"); -+ env_set("boot_instance", cmd); + env_set("boot_instance", "0"); break; ++ case BOOT_FLASH_SPINAND: ++ env_set("boot_device", "spi-nand"); ++ env_set("boot_instance", "0"); ++ break; case BOOT_FLASH_NOR: env_set("boot_device", "nor"); env_set("boot_instance", "0"); - break; +@@ -449,7 +498,7 @@ static void setup_boot_mode(void) + * If there is no MAC address in the environment, then it will be initialized + * (silently) from the value in the OTP. + */ +-static int setup_mac_address(void) ++__weak int setup_mac_address(void) + { + #if defined(CONFIG_NET) + int ret; +@@ -481,8 +530,9 @@ static int setup_mac_address(void) + return -EINVAL; + } + pr_debug("OTP MAC address = %pM\n", enetaddr); +- ret = !eth_env_set_enetaddr("ethaddr", enetaddr); +- if (!ret) ++ ++ ret = eth_env_set_enetaddr("ethaddr", enetaddr); ++ if (ret) + pr_err("Failed to set mac address %pM from OTP: %d\n", + enetaddr, ret); + #endif +@@ -492,13 +542,13 @@ static int setup_mac_address(void) + + static int setup_serial_number(void) + { ++ char *serial_env; + char serial_string[25]; + u32 otp[3] = {0, 0, 0 }; + struct udevice *dev; + int ret; + +- if (env_get("serial#")) +- return 0; ++ serial_env = env_get("serial#"); + + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_GET_DRIVER(stm32mp_bsec), +@@ -512,6 +562,15 @@ static int setup_serial_number(void) + return ret; + + sprintf(serial_string, "%08X%08X%08X", otp[0], otp[1], otp[2]); ++ ++ if (serial_env) { ++ if (!strcmp(serial_string, serial_env)) ++ return 0; ++ /* For invalid enviromnent (serial# change), reset to default */ ++ env_set_default("serial number mismatch", 0); + } + -+ switch (forced_mode) { -+ case BOOT_FASTBOOT: -+ printf("Enter fastboot!\n"); -+ env_set("preboot", "env set preboot; fastboot 0"); -+ break; -+ case BOOT_STM32PROG: -+ printf("Enter STM32CubeProgrammer mode!\n"); -+ env_set("preboot", "env set preboot; stm32prog usb 0"); -+ break; -+ case BOOT_UMS_MMC0: -+ case BOOT_UMS_MMC1: -+ case BOOT_UMS_MMC2: -+ printf("Enter UMS!\n"); -+ instance = forced_mode - BOOT_UMS_MMC0; -+ sprintf(cmd, "env set preboot; ums 0 mmc %d", instance); -+ env_set("preboot", cmd); -+ break; -+ case BOOT_RECOVERY: -+ env_set("preboot", "env set preboot; run altbootcmd"); -+ break; -+ case BOOT_NORMAL: - default: - pr_debug("unexpected boot mode = %x\n", boot_mode); - break; - } -+ -+ /* clear TAMP for next reboot */ -+ clrsetbits_le32(TAMP_BOOT_CONTEXT, TAMP_BOOT_FORCED_MASK, BOOT_NORMAL); - } - - /* -@@ -304,7 +462,7 @@ static int setup_mac_address(void) - if (ret) - return ret; - -- ret = misc_read(dev, BSEC_OTP_MAC * 4 + STM32_BSEC_OTP_OFFSET, -+ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_MAC), - otp, sizeof(otp)); - if (ret) - return ret; -@@ -342,12 +500,12 @@ static int setup_serial_number(void) - if (ret) - return ret; - -- ret = misc_read(dev, BSEC_OTP_SERIAL * 4 + STM32_BSEC_OTP_OFFSET, -+ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_SERIAL), - otp, sizeof(otp)); - if (ret) - return ret; - -- sprintf(serial_string, "%08x%08x%08x", otp[0], otp[1], otp[2]); -+ sprintf(serial_string, "%08X%08X%08X", otp[0], otp[1], otp[2]); ++ /* save serial number */ env_set("serial#", serial_string); return 0; -@@ -361,3 +519,45 @@ int arch_misc_init(void) +@@ -519,9 +578,9 @@ static int setup_serial_number(void) + + int arch_misc_init(void) + { ++ setup_serial_number(); + setup_boot_mode(); + setup_mac_address(); +- setup_serial_number(); + + return 0; + } +diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c +index 7688b3e..3233415 100644 +--- a/arch/arm/mach-stm32mp/dram_init.c ++++ b/arch/arm/mach-stm32mp/dram_init.c +@@ -5,6 +5,7 @@ + + #include + #include ++#include + #include + + DECLARE_GLOBAL_DATA_PTR; +@@ -31,3 +32,20 @@ int dram_init(void) return 0; } + -+/* -+ * 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, bd_t *bd) ++ulong board_get_usable_ram_top(ulong total_size) +{ -+ int ret = 0; -+ u32 pkg; ++ phys_addr_t reg; ++ struct lmb lmb; + -+#if CONFIG_STM32_ETZPC -+ ret = stm32_fdt_fixup_etzpc(blob); -+ if (ret) -+ return ret; -+#endif ++ /* 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); + -+ switch (get_cpu_package()) { -+ case PKG_AA_LBGA448: -+ pkg = STM32MP157CAA; -+ break; -+ case PKG_AB_LBGA354: -+ pkg = STM32MP157CAB; -+ break; -+ case PKG_AC_TFBGA361: -+ pkg = STM32MP157CAC; -+ break; -+ case PKG_AD_TFBGA257: -+ pkg = STM32MP157CAD; ++ if (reg) ++ return ALIGN(reg + CONFIG_SYS_MALLOC_LEN + total_size, SZ_4K); ++ ++ return gd->ram_top; ++} +diff --git a/arch/arm/mach-stm32mp/fdt.c b/arch/arm/mach-stm32mp/fdt.c +index 82c430b..21b5f09 100644 +--- a/arch/arm/mach-stm32mp/fdt.c ++++ b/arch/arm/mach-stm32mp/fdt.c +@@ -5,6 +5,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -23,6 +24,12 @@ + + #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 ++ + static const u32 stm32mp1_ip_addr[] = { + 0x5c008000, /* 00 stgenc */ + 0x54000000, /* 01 bkpsram */ +@@ -33,7 +40,7 @@ static const u32 stm32mp1_ip_addr[] = { + ETZPC_RESERVED, /* 06 reserved */ + 0x54003000, /* 07 rng1 */ + 0x54002000, /* 08 hash1 */ +- 0x54001000, /* 09 cryp1 */ ++ STM32_CRYP1_BASE, /* 09 cryp1 */ + 0x5a003000, /* 0A ddrctrl */ + 0x5a004000, /* 0B ddrphyc */ + 0x5c009000, /* 0C i2c6 */ +@@ -86,7 +93,7 @@ static const u32 stm32mp1_ip_addr[] = { + 0x4400b000, /* 3B sai2 */ + 0x4400c000, /* 3C sai3 */ + 0x4400d000, /* 3D dfsdm */ +- 0x4400e000, /* 3E tt_fdcan */ ++ STM32_FDCAN_BASE, /* 3E tt_fdcan */ + ETZPC_RESERVED, /* 3F reserved */ + 0x50021000, /* 40 lptim2 */ + 0x50022000, /* 41 lptim3 */ +@@ -99,7 +106,7 @@ static const u32 stm32mp1_ip_addr[] = { + 0x48003000, /* 48 adc */ + 0x4c002000, /* 49 hash2 */ + 0x4c003000, /* 4A rng2 */ +- 0x4c005000, /* 4B cryp2 */ ++ STM32_CRYP2_BASE, /* 4B cryp2 */ + ETZPC_RESERVED, /* 4C reserved */ + ETZPC_RESERVED, /* 4D reserved */ + ETZPC_RESERVED, /* 4E reserved */ +@@ -126,11 +133,13 @@ static const u32 stm32mp1_ip_addr[] = { + static bool fdt_disable_subnode_by_address(void *fdt, int offset, u32 addr) + { + int node; ++ fdt_addr_t regs; + + for (node = fdt_first_subnode(fdt, offset); + node >= 0; + node = fdt_next_subnode(fdt, node)) { +- if (addr == (u32)fdt_getprop(fdt, node, "reg", 0)) { ++ regs = fdtdec_get_addr(fdt, node, "reg"); ++ if (addr == regs) { + if (fdtdec_get_is_enabled(fdt, node)) { + fdt_status_disabled(fdt, node); + +@@ -143,11 +152,11 @@ static bool fdt_disable_subnode_by_address(void *fdt, int offset, u32 addr) + return false; + } + +-static int stm32_fdt_fixup_etzpc(void *fdt) ++static int stm32_fdt_fixup_etzpc(void *fdt, int soc_node) + { + const u32 *array; + int array_size, i; +- int soc_node, offset, shift; ++ int offset, shift; + u32 addr, status, decprot[ETZPC_DECPROT_NB]; + + array = stm32mp1_ip_addr; +@@ -156,10 +165,6 @@ static int stm32_fdt_fixup_etzpc(void *fdt) + for (i = 0; i < ETZPC_DECPROT_NB; i++) + decprot[i] = readl(ETZPC_DECPROT(i)); + +- soc_node = fdt_path_offset(fdt, "/soc"); +- if (soc_node < 0) +- return soc_node; +- + for (i = 0; i < array_size; i++) { + offset = i / NB_PROT_PER_REG; + shift = (i % NB_PROT_PER_REG) * DECPROT_NB_BITS; +@@ -180,6 +185,60 @@ static int stm32_fdt_fixup_etzpc(void *fdt) + return 0; + } + ++/* deactivate all the cpu except core 0 */ ++static void stm32_fdt_fixup_cpu(void *blob, char *name) ++{ ++ int off; ++ u32 reg; ++ ++ off = fdt_path_offset(blob, "/cpus"); ++ if (off < 0) { ++ printf("%s: couldn't find /cpus node\n", __func__); ++ return; ++ } ++ ++ off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4); ++ while (off != -FDT_ERR_NOTFOUND) { ++ reg = fdtdec_get_addr(blob, off, "reg"); ++ if (reg != 0) { ++ fdt_del_node(blob, off); ++ printf("FDT: cpu %d node remove for %s\n", reg, name); ++ /* after delete we can't trust the offsets anymore */ ++ off = -1; ++ } ++ off = fdt_node_offset_by_prop_value(blob, off, ++ "device_type", "cpu", 4); ++ } ++} ++ ++static void stm32_fdt_disable(void *fdt, int offset, u32 addr, ++ const char *string, const char *name) ++{ ++ if (fdt_disable_subnode_by_address(fdt, offset, addr)) ++ printf("FDT: %s@%08x node disabled for %s\n", ++ string, addr, name); ++} ++ ++static void stm32_fdt_disable_optee(void *blob) ++{ ++ int off, node; ++ ++ off = fdt_node_offset_by_compatible(blob, -1, "linaro,optee-tz"); ++ if (off >= 0 && fdtdec_get_is_enabled(blob, off)) ++ fdt_status_disabled(blob, off); ++ ++ /* Disabled "optee@..." reserved-memory node */ ++ off = fdt_path_offset(blob, "/reserved-memory/"); ++ if (off < 0) ++ return; ++ for (node = fdt_first_subnode(blob, off); ++ node >= 0; ++ node = fdt_next_subnode(blob, node)) { ++ if (!strncmp(fdt_get_name(blob, node, NULL), "optee@", 6)) ++ fdt_status_disabled(blob, node); ++ } ++} ++ + /* + * This function is called right before the kernel is booted. "blob" is the + * device tree that will be passed to the kernel. +@@ -187,14 +246,59 @@ static int stm32_fdt_fixup_etzpc(void *fdt) + int ft_system_setup(void *blob, bd_t *bd) + { + int ret = 0; +- u32 pkg; ++ int soc; ++ u32 pkg, cpu; ++ char name[SOC_NAME_SIZE]; ++ ++ soc = fdt_path_offset(blob, "/soc"); ++ if (soc < 0) ++ return soc; + + if (CONFIG_IS_ENABLED(STM32_ETZPC)) { +- ret = stm32_fdt_fixup_etzpc(blob); ++ ret = stm32_fdt_fixup_etzpc(blob, soc); + if (ret) + return ret; + } + ++ /* MPUs Part Numbers and name*/ ++ cpu = get_cpu_type(); ++ get_soc_name(name); ++ ++ switch (cpu) { ++ case CPU_STM32MP151Fxx: ++ case CPU_STM32MP151Dxx: ++ case CPU_STM32MP151Cxx: ++ case CPU_STM32MP151Axx: ++ 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 */ ++ 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); + break; + default: -+ pkg = 0; + break; + } -+ if (pkg) { -+ do_fixup_by_compat_u32(blob, "st,stm32mp157-pinctrl", -+ "st,package", pkg, false); -+ do_fixup_by_compat_u32(blob, "st,stm32mp157-z-pinctrl", -+ "st,package", pkg, false); ++ ++ switch (cpu) { ++ case CPU_STM32MP157Dxx: ++ case CPU_STM32MP157Axx: ++ case CPU_STM32MP153Dxx: ++ 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); ++ break; ++ default: ++ break; + } + -+ return ret; -+} + switch (get_cpu_package()) { + case PKG_AA_LBGA448: + pkg = STM32MP_PKG_AA; +@@ -219,5 +323,9 @@ int ft_system_setup(void *blob, bd_t *bd) + "st,package", pkg, false); + } + ++ if (!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 +new file mode 100644 +index 0000000..252eac3 +--- /dev/null ++++ b/arch/arm/mach-stm32mp/include/mach/bsec.h +@@ -0,0 +1,7 @@ ++/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ ++/* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++/* check self hosted debug status = BSEC_DENABLE.DBGSWENABLE */ ++bool bsec_dbgswenable(void); diff --git a/arch/arm/mach-stm32mp/include/mach/ddr.h b/arch/arm/mach-stm32mp/include/mach/ddr.h -index 1857584..b8a17cf 100644 +index b8a17cf..bfc42a7 100644 --- a/arch/arm/mach-stm32mp/include/mach/ddr.h +++ b/arch/arm/mach-stm32mp/include/mach/ddr.h -@@ -6,6 +6,13 @@ - #ifndef __MACH_STM32MP_DDR_H_ - #define __MACH_STM32MP_DDR_H_ - --int board_ddr_power_init(void); -+/* DDR power initializations */ -+enum ddr_type { -+ STM32MP_DDR3, -+ STM32MP_LPDDR2, -+ STM32MP_LPDDR3, -+}; -+ -+int board_ddr_power_init(enum ddr_type ddr_type); - - #endif -diff --git a/arch/arm/mach-stm32mp/include/mach/gpio.h b/arch/arm/mach-stm32mp/include/mach/gpio.h -index 5151150..5ca76d2 100644 ---- a/arch/arm/mach-stm32mp/include/mach/gpio.h -+++ b/arch/arm/mach-stm32mp/include/mach/gpio.h -@@ -8,6 +8,8 @@ - #define _STM32_GPIO_H_ - #include - -+#define STM32_GPIOS_PER_BANK 16 -+ - enum stm32_gpio_port { - STM32_GPIO_PORT_A = 0, - STM32_GPIO_PORT_B, -@@ -110,5 +112,9 @@ struct stm32_gpio_regs { - - struct stm32_gpio_priv { - struct stm32_gpio_regs *regs; -+ unsigned int gpio_range; +@@ -9,8 +9,10 @@ + /* DDR power initializations */ + enum ddr_type { + STM32MP_DDR3, +- STM32MP_LPDDR2, +- STM32MP_LPDDR3, ++ STM32MP_LPDDR2_16, ++ STM32MP_LPDDR2_32, ++ STM32MP_LPDDR3_16, ++ STM32MP_LPDDR3_32, }; -+ -+int stm32_offset_to_index(struct udevice *dev, unsigned int offset); -+ - #endif /* _STM32_GPIO_H_ */ + + int board_ddr_power_init(enum ddr_type ddr_type); diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h -index 5d0bdca..4147873 100644 +index b3e9ccc..8820bc4 100644 --- a/arch/arm/mach-stm32mp/include/mach/stm32.h +++ b/arch/arm/mach-stm32mp/include/mach/stm32.h -@@ -13,13 +13,10 @@ - #define STM32_RCC_BASE 0x50000000 - #define STM32_PWR_BASE 0x50001000 - #define STM32_DBGMCU_BASE 0x50081000 --#define STM32_BSEC_BASE 0x5C005000 - #define STM32_TZC_BASE 0x5C006000 - #define STM32_ETZPC_BASE 0x5C007000 - #define STM32_TAMP_BASE 0x5C00A000 - --#ifdef CONFIG_DEBUG_UART_BASE --/* hardcoded value can be only used for DEBUG UART */ - #define STM32_USART1_BASE 0x5C000000 - #define STM32_USART2_BASE 0x4000E000 - #define STM32_USART3_BASE 0x4000F000 -@@ -28,20 +25,27 @@ - #define STM32_USART6_BASE 0x44003000 - #define STM32_UART7_BASE 0x40018000 - #define STM32_UART8_BASE 0x40019000 --#endif - - #define STM32_SYSRAM_BASE 0x2FFC0000 - #define STM32_SYSRAM_SIZE SZ_256K - -+#define STM32_MCU_SRAM_BASE 0x30000000 -+#define STM32_MCU_SRAM_SIZE (3 * SZ_128K) -+ - #define STM32_DDR_BASE 0xC0000000 - #define STM32_DDR_SIZE SZ_1G - - #ifndef __ASSEMBLY__ -+#include -+ +@@ -37,7 +37,6 @@ /* enumerated used to identify the SYSCON driver instance */ enum { STM32MP_SYSCON_UNKNOWN, -- STM32MP_SYSCON_STGEN, -+ STM32MP_SYSCON_ETZPC, -+ STM32MP_SYSCON_IWDG, - STM32MP_SYSCON_PWR, -+ STM32MP_SYSCON_STGEN, -+ STM32MP_SYSCON_SYSCFG, +- STM32MP_SYSCON_PWR, + STM32MP_SYSCON_SYSCFG, }; - /* -@@ -87,18 +91,41 @@ enum boot_device { +@@ -80,15 +79,29 @@ enum boot_device { + + BOOT_SERIAL_USB = 0x60, + BOOT_SERIAL_USB_OTG = 0x62, ++ ++ BOOT_FLASH_SPINAND = 0x70, ++ BOOT_FLASH_SPINAND_1 = 0x71, + }; /* TAMP registers */ #define TAMP_BACKUP_REGISTER(x) (STM32_TAMP_BASE + 0x100 + 4 * x) @@ -4302,175 +4551,222 @@ index 5d0bdca..4147873 100644 #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) -+#define TAMP_BOOTCOUNT TAMP_BACKUP_REGISTER(21) + #define TAMP_BOOTCOUNT TAMP_BACKUP_REGISTER(21) ++#define TAMP_COPRO_STATE_OFF 0 ++#define TAMP_COPRO_STATE_INIT 1 ++#define TAMP_COPRO_STATE_CRUN 2 ++#define TAMP_COPRO_STATE_CSTOP 3 ++#define TAMP_COPRO_STATE_STANDBY 4 ++#define TAMP_COPRO_STATE_CRASH 5 ++ #define TAMP_BOOT_MODE_MASK GENMASK(15, 8) #define TAMP_BOOT_MODE_SHIFT 8 #define TAMP_BOOT_DEVICE_MASK GENMASK(7, 4) - #define TAMP_BOOT_INSTANCE_MASK GENMASK(3, 0) -+#define TAMP_BOOT_FORCED_MASK GENMASK(7, 0) -+#define TAMP_BOOT_DEBUG_ON BIT(16) -+ -+enum forced_boot_mode { -+ BOOT_NORMAL = 0x00, -+ BOOT_FASTBOOT = 0x01, -+ BOOT_RECOVERY = 0x02, -+ BOOT_STM32PROG = 0x03, -+ BOOT_UMS_MMC0 = 0x10, -+ BOOT_UMS_MMC1 = 0x11, -+ BOOT_UMS_MMC2 = 0x12, -+}; - - /* offset used for BSEC driver: misc_read and misc_write */ - #define STM32_BSEC_SHADOW_OFFSET 0x0 -+#define STM32_BSEC_SHADOW(id) (STM32_BSEC_SHADOW_OFFSET + (id) * 4) +@@ -111,7 +124,14 @@ enum forced_boot_mode { + #define STM32_BSEC_SHADOW(id) (STM32_BSEC_SHADOW_OFFSET + (id) * 4) #define STM32_BSEC_OTP_OFFSET 0x80000000 -+#define STM32_BSEC_OTP(id) (STM32_BSEC_OTP_OFFSET + (id) * 4) + #define STM32_BSEC_OTP(id) (STM32_BSEC_OTP_OFFSET + (id) * 4) +- ++#define STM32_BSEC_LOCK_OFFSET 0xC0000000 ++#define STM32_BSEC_LOCK(id) (STM32_BSEC_LOCK_OFFSET + (id) * 4) + -+#define BSEC_OTP_BOARD 59 -+ -+#if CONFIG_STM32_ETZPC -+int stm32_fdt_fixup_etzpc(void *fdt); -+#endif ++/* BSEC OTP index */ ++#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 /* __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 -new file mode 100644 -index 0000000..538958f ---- /dev/null +index 8130546..dea5b4a 100644 +--- a/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h +++ b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h -@@ -0,0 +1,75 @@ -+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#ifndef __STM32MP1_SMC_H__ -+#define __STM32MP1_SMC_H__ -+ -+#include -+ -+/* -+ * 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 -+ */ -+#define STM32_SMC_VERSION 0x82000000 -+/* SMC reserved for future ST services */ -+#define STM32_SMC_RESERVED_ST 0x82000001 -+ -+/* Secure Service access from Non-secure */ +@@ -18,8 +18,16 @@ + #define STM32_SMC_VERSION 0x82000000 + + /* Secure Service access from Non-secure */ +#define STM32_SMC_RCC 0x82001000 +#define STM32_SMC_PWR 0x82001001 +#define STM32_SMC_RTC 0x82001002 -+#define STM32_SMC_BSEC 0x82001003 -+ + #define STM32_SMC_BSEC 0x82001003 + +/* Register access service use for RCC/RTC/PWR */ +#define STM32_SMC_REG_WRITE 0x1 +#define STM32_SMC_REG_SET 0x2 +#define STM32_SMC_REG_CLEAR 0x3 + -+/* Service for BSEC */ -+#define STM32_SMC_READ_SHADOW 0x01 -+#define STM32_SMC_PROG_OTP 0x02 -+#define STM32_SMC_WRITE_SHADOW 0x03 -+#define STM32_SMC_READ_OTP 0x04 -+#define STM32_SMC_READ_ALL 0x05 -+#define STM32_SMC_WRITE_ALL 0x06 + /* Service for BSEC */ + #define STM32_SMC_READ_SHADOW 0x01 + #define STM32_SMC_PROG_OTP 0x02 +@@ -27,6 +35,7 @@ + #define STM32_SMC_READ_OTP 0x04 + #define STM32_SMC_READ_ALL 0x05 + #define STM32_SMC_WRITE_ALL 0x06 ++#define STM32_SMC_WRLOCK_OTP 0x07 + + /* SMC error codes */ + #define STM32_SMC_OK 0x0 +@@ -45,8 +54,8 @@ static inline u32 stm32_smc(u32 svc, u8 op, u32 data1, u32 data2, u32 *result) + arm_smccc_smc(svc, op, data1, data2, 0, 0, 0, 0, &res); + + if (res.a0) { +- pr_err("%s: Failed to exec in secure mode (err = %ld)\n", +- __func__, res.a0); ++ pr_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n", ++ __func__, svc, op, res.a0); + return -EINVAL; + } + if (result) +diff --git a/arch/arm/mach-stm32mp/include/mach/stm32prog.h b/arch/arm/mach-stm32mp/include/mach/stm32prog.h +new file mode 100644 +index 0000000..c080b9c +--- /dev/null ++++ b/arch/arm/mach-stm32mp/include/mach/stm32prog.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ ++/* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ */ + -+/* 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 STM32PROG_VIRT_FIRST_DEV_NUM 0xF1 + -+#define stm32_smc_exec(svc, op, data1, data2) \ -+ stm32_smc(svc, op, data1, data2, NULL) ++int stm32prog_write_medium_virt(struct dfu_entity *dfu, u64 offset, ++ void *buf, long *len); ++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); + -+#ifdef CONFIG_ARM_SMCCC -+static inline u32 stm32_smc(u32 svc, u8 op, u32 data1, u32 data2, u32 *result) -+{ -+ struct arm_smccc_res res; ++bool stm32prog_get_tee_partitions(void); + -+ arm_smccc_smc(svc, op, data1, data2, 0, 0, 0, 0, &res); -+ -+ if (res.a0) { -+ pr_err("%s: Failed to exec in secure mode (err = %ld)\n", -+ __func__, res.a0); -+ return -EINVAL; -+ } -+ if (result) -+ *result = (u32)res.a1; -+ -+ return 0; -+} -+#else -+static inline u32 stm32_smc(u32 svc, u8 op, u32 data1, u32 data2, u32 *result) -+{ -+ return 0; -+} -+ -+#endif -+ -+#endif /* __STM32MP1_SMC_H__ */ ++bool stm32prog_get_fsbl_nor(void); diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h -index 41d4b40..c565748 100644 +index 99eefab..b6ad3c6 100644 --- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h +++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h -@@ -3,9 +3,15 @@ +@@ -3,19 +3,31 @@ * Copyright (C) 2015-2017, STMicroelectronics - All Rights Reserved */ --#define CPU_STMP32MP15x 0x500 -+/* ID = Device Version (bit31:16) + Device Part Number (RPN) (bit15:0)*/ -+#define CPU_STM32MP157Cxx 0x05000000 -+#define CPU_STM32MP157Axx 0x05000001 -+#define CPU_STM32MP153Cxx 0x05000024 -+#define CPU_STM32MP153Axx 0x05000025 -+#define CPU_STM32MP151Cxx 0x0500002E -+#define CPU_STM32MP151Axx 0x0500002F +-/* ID = Device Version (bit31:16) + Device Part Number (RPN) (bit15:0)*/ ++/* ID = Device Version (bit31:16) + Device Part Number (RPN) (bit7:0) */ + #define CPU_STM32MP157Cxx 0x05000000 + #define CPU_STM32MP157Axx 0x05000001 + #define CPU_STM32MP153Cxx 0x05000024 + #define CPU_STM32MP153Axx 0x05000025 + #define CPU_STM32MP151Cxx 0x0500002E + #define CPU_STM32MP151Axx 0x0500002F ++#define CPU_STM32MP157Fxx 0x05000080 ++#define CPU_STM32MP157Dxx 0x05000081 ++#define CPU_STM32MP153Fxx 0x050000A4 ++#define CPU_STM32MP153Dxx 0x050000A5 ++#define CPU_STM32MP151Fxx 0x050000AE ++#define CPU_STM32MP151Dxx 0x050000AF --/* return CPU_STMP32MPxx constants */ -+/* return CPU_STMP32MP...Xxx constants */ + /* return CPU_STMP32MP...Xxx constants */ u32 get_cpu_type(void); ++#define CPU_DEV_STM32MP15 0x500 ++ ++/* return CPU_DEV constants */ ++u32 get_cpu_dev(void); ++ #define CPU_REVA 0x1000 + #define CPU_REVB 0x2000 ++#define CPU_REVZ 0x2001 + + /* return CPU_REV constants */ + u32 get_cpu_rev(void); +@@ -28,5 +40,15 @@ u32 get_cpu_package(void); + #define PKG_AC_TFBGA361 2 + #define PKG_AD_TFBGA257 1 + ++/* Get SOC name */ ++#define SOC_NAME_SIZE 20 ++void get_soc_name(char name[SOC_NAME_SIZE]); ++ + /* return boot mode */ + u32 get_bootmode(void); ++ ++int setup_mac_address(void); ++ ++/* board power management : configure vddcore according OPP */ ++void board_vddcore_init(u32 voltage_mv); ++int board_vddcore_set(void); diff --git a/arch/arm/mach-stm32mp/psci.c b/arch/arm/mach-stm32mp/psci.c -index 6ed2482..c2dff38 100644 +index 1d91b2d..3fb038d 100644 --- a/arch/arm/mach-stm32mp/psci.c +++ b/arch/arm/mach-stm32mp/psci.c -@@ -103,7 +103,13 @@ int __secure psci_affinity_info(u32 function_id, u32 target_affinity, +@@ -30,6 +30,22 @@ u8 psci_state[STM32MP1_PSCI_NR_CPUS] __secure_data = { + PSCI_AFFINITY_LEVEL_ON, + PSCI_AFFINITY_LEVEL_OFF}; - int __secure psci_migrate_info_type(u32 function_id) ++static u32 __secure_data cntfrq; ++ ++static u32 __secure cp15_read_cntfrq(void) ++{ ++ u32 frq; ++ ++ asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (frq)); ++ ++ return frq; ++} ++ ++static void __secure cp15_write_cntfrq(u32 frq) ++{ ++ asm volatile ("mcr p15, 0, %0, c14, c0, 0" : : "r" (frq)); ++} ++ + static inline void psci_set_state(int cpu, u8 state) { -- /* Trusted OS is either not present or does not require migration */ -+ /* -+ * in Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf -+ * return 2 = Trusted OS is either not present or does not require -+ * migration, system of this type does not require the caller -+ * to use the MIGRATE function. -+ * MIGRATE function calls return NOT_SUPPORTED. -+ */ - return 2; - } + psci_state[cpu] = state; +@@ -63,6 +79,9 @@ void __secure psci_arch_cpu_entry(void) + psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON); + ++ /* write the saved cntfrq */ ++ cp15_write_cntfrq(cntfrq); ++ + /* reset magic in TAMP register */ + writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER); + } +@@ -130,6 +149,9 @@ s32 __secure psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc, + if (psci_state[cpu] == PSCI_AFFINITY_LEVEL_ON) + return ARM_PSCI_RET_ALREADY_ON; + ++ /* read and save cntfrq of current cpu to write on target cpu */ ++ cntfrq = cp15_read_cntfrq(); ++ + /* reset magic in TAMP register */ + if (readl(TAMP_BACKUP_MAGIC_NUMBER)) + writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER); diff --git a/arch/arm/mach-stm32mp/pwr_regulator.c b/arch/arm/mach-stm32mp/pwr_regulator.c -index 9484645..dbfbdcc 100644 +index 9484645..7219af5 100644 --- a/arch/arm/mach-stm32mp/pwr_regulator.c +++ b/arch/arm/mach-stm32mp/pwr_regulator.c -@@ -8,6 +8,7 @@ +@@ -6,8 +6,9 @@ + #include + #include #include - #include +-#include #include ++#include +#include #include #include -@@ -32,13 +33,20 @@ struct stm32mp_pwr_priv { +@@ -26,19 +27,28 @@ struct stm32mp_pwr_reg_info { + }; + + struct stm32mp_pwr_priv { +- struct regmap *regmap; ++ fdt_addr_t base; + }; + static int stm32mp_pwr_write(struct udevice *dev, uint reg, const uint8_t *buff, int len) { @@ -4482,319 +4778,328 @@ index 9484645..dbfbdcc 100644 if (len != 4) return -EINVAL; +- return regmap_write(priv->regmap, STM32MP_PWR_CR3, val); +#ifdef CONFIG_STM32MP1_TRUSTED + return stm32_smc_exec(STM32_SMC_PWR, STM32_SMC_REG_WRITE, + STM32MP_PWR_CR3, val); +#else /* CONFIG_STM32MP1_TRUSTED */ - return regmap_write(priv->regmap, STM32MP_PWR_CR3, val); ++ writel(val, priv->base + STM32MP_PWR_CR3); ++ ++ return 0; +#endif /* CONFIG_STM32MP1_TRUSTED */ } static int stm32mp_pwr_read(struct udevice *dev, uint reg, uint8_t *buff, +@@ -49,21 +59,18 @@ static int stm32mp_pwr_read(struct udevice *dev, uint reg, uint8_t *buff, + if (len != 4) + return -EINVAL; + +- return regmap_read(priv->regmap, STM32MP_PWR_CR3, (u32 *)buff); ++ *(u32 *)buff = readl(priv->base + STM32MP_PWR_CR3); ++ ++ return 0; + } + + static int stm32mp_pwr_ofdata_to_platdata(struct udevice *dev) + { + struct stm32mp_pwr_priv *priv = dev_get_priv(dev); +- struct regmap *regmap; + +- regmap = syscon_get_regmap_by_driver_data(STM32MP_SYSCON_PWR); +- if (IS_ERR(regmap)) { +- pr_err("%s: unable to find regmap (%ld)\n", __func__, +- PTR_ERR(regmap)); +- return PTR_ERR(regmap); +- } +- priv->regmap = regmap; ++ priv->base = dev_read_addr(dev); ++ if (priv->base == FDT_ADDR_T_NONE) ++ return -EINVAL; + + return 0; + } diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c -index 790973e..fa393cc 100644 +index a3b0d6f..f4b4c3b 100644 --- a/arch/arm/mach-stm32mp/spl.c +++ b/arch/arm/mach-stm32mp/spl.c -@@ -7,6 +7,18 @@ - #include - #include - #include -+#include -+#include -+ -+static int spl_board_load_image(struct spl_image_info *spl_image, -+ struct spl_boot_device *bootdev) -+{ -+ /* TODO : add download support in SPL without TF-A */ -+ return -1; -+} -+ -+SPL_LOAD_IMAGE_METHOD("UART", 0, BOOT_DEVICE_UART, spl_board_load_image); -+SPL_LOAD_IMAGE_METHOD("USB", 0, BOOT_DEVICE_USB, spl_board_load_image); - - u32 spl_boot_device(void) - { -@@ -22,8 +34,22 @@ u32 spl_boot_device(void) - case BOOT_FLASH_SD_2: - case BOOT_FLASH_EMMC_2: - return BOOT_DEVICE_MMC2; -+ case BOOT_SERIAL_UART_1: -+ case BOOT_SERIAL_UART_2: -+ case BOOT_SERIAL_UART_3: -+ case BOOT_SERIAL_UART_4: -+ case BOOT_SERIAL_UART_5: -+ case BOOT_SERIAL_UART_6: -+ case BOOT_SERIAL_UART_7: -+ case BOOT_SERIAL_UART_8: -+ return BOOT_DEVICE_UART; -+ case BOOT_SERIAL_USB_OTG: -+ return BOOT_DEVICE_USB; -+ case BOOT_FLASH_NAND_FMC: -+ return BOOT_DEVICE_NAND; -+ case BOOT_FLASH_NOR_QSPI: -+ return BOOT_DEVICE_SPI; +@@ -38,6 +38,8 @@ u32 spl_boot_device(void) + return BOOT_DEVICE_NAND; + case BOOT_FLASH_NOR_QSPI: + return BOOT_DEVICE_SPI; ++ case BOOT_FLASH_SPINAND_1: ++ return BOOT_DEVICE_NONE; /* SPINAND not supported in SPL */ } -- + return BOOT_DEVICE_MMC1; +@@ -75,40 +77,47 @@ void spl_display_print(void) } + #endif -@@ -44,6 +70,21 @@ int spl_boot_partition(const u32 boot_device) - } - } - -+#ifdef CONFIG_SPL_DISPLAY_PRINT -+void spl_display_print(void) ++__weak int board_vddcore_set(void) +{ -+ DECLARE_GLOBAL_DATA_PTR; -+ const char *model; -+ -+ /* same code than show_board_info() but not compiled for SPL -+ * see CONFIG_DISPLAY_BOARDINFO & common/board_info.c -+ */ -+ model = fdt_getprop(gd->fdt_blob, 0, "model", NULL); -+ if (model) -+ printf("Model: %s\n", model); ++ return 0; +} -+#endif + void board_init_f(ulong dummy) { struct udevice *dev; -@@ -80,7 +121,7 @@ void board_init_f(ulong dummy) +- int ret; ++ int ret, clk, reset, pinctrl, power; + arch_cpu_init(); + + ret = spl_early_init(); + if (ret) { +- debug("spl_early_init() failed: %d\n", ret); ++ debug("%s: spl_early_init() failed: %d\n", __func__, ret); + hang(); + } + +- ret = uclass_get_device(UCLASS_CLK, 0, &dev); +- if (ret) { +- debug("Clock init failed: %d\n", ret); +- return; +- } ++ clk = uclass_get_device(UCLASS_CLK, 0, &dev); ++ if (clk) ++ debug("%s: Clock init failed: %d\n", __func__, clk); + +- ret = uclass_get_device(UCLASS_RESET, 0, &dev); +- if (ret) { +- debug("Reset init failed: %d\n", ret); +- return; +- } ++ reset = uclass_get_device(UCLASS_RESET, 0, &dev); ++ if (reset) ++ debug("%s: Reset init failed: %d\n", __func__, reset); + +- ret = uclass_get_device(UCLASS_PINCTRL, 0, &dev); +- if (ret) { +- debug("%s: Cannot find pinctrl device\n", __func__); +- return; +- } ++ pinctrl = uclass_get_device(UCLASS_PINCTRL, 0, &dev); ++ if (pinctrl) ++ debug("%s: Cannot find pinctrl device: %d\n", ++ __func__, pinctrl); + + /* enable console uart printing */ + preloader_console_init(); + ++ /* change vddcore if needed after clock tree init */ ++ power = board_vddcore_set(); ++ ++ if (clk || reset || pinctrl || power) ++ printf("%s: probe failed clk=%d reset=%d pinctrl=%d power=%d\n", ++ __func__, clk, reset, pinctrl, power); ++ ret = uclass_get_device(UCLASS_RAM, 0, &dev); if (ret) { -- debug("DRAM init failed: %d\n", ret); -- return; -+ printf("DRAM init failed: %d\n", ret); -+ hang(); - } - } -diff --git a/arch/arm/mach-stm32mp/stm32-etzpc.c b/arch/arm/mach-stm32mp/stm32-etzpc.c -new file mode 100644 -index 0000000..ea6dcca ---- /dev/null -+++ b/arch/arm/mach-stm32mp/stm32-etzpc.c -@@ -0,0 +1,199 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define ETZPC_DECPROT(n) (0x10 + 4 * (n)) -+#define ETZPC_DECPROT_NB 6 -+ -+#define ETZPC_IP_VER 0x3F4 -+ -+#define IP_VER_STM32MP1 0x00000020 -+ -+#define DECPROT_MASK 0x03 -+#define NB_PROT_PER_REG 0x10 -+#define DECPROT_NB_BITS 2 -+ -+#define DECPROT_SECURED 0x00 -+#define DECPROT_WRITE_SECURE 0x01 -+#define DECPROT_MCU_ISOLATION 0x02 -+#define DECPROT_NON_SECURED 0x03 -+ -+#define ETZPC_RESERVED 0xffffffff -+ -+static const u32 stm32mp1_ip_addr[] = { -+ 0x5c008000, /* 00 stgenc */ -+ 0x54000000, /* 01 bkpsram */ -+ 0x5c003000, /* 02 iwdg1 */ -+ 0x5c000000, /* 03 usart1 */ -+ 0x5c001000, /* 04 spi6 */ -+ 0x5c002000, /* 05 i2c4 */ -+ ETZPC_RESERVED, /* 06 reserved */ -+ 0x54003000, /* 07 rng1 */ -+ 0x54002000, /* 08 hash1 */ -+ 0x54001000, /* 09 cryp1 */ -+ 0x5a003000, /* 0A ddrctrl */ -+ 0x5a004000, /* 0B ddrphyc */ -+ 0x5c009000, /* 0C i2c6 */ -+ ETZPC_RESERVED, /* 0D reserved */ -+ ETZPC_RESERVED, /* 0E reserved */ -+ ETZPC_RESERVED, /* 0F reserved */ -+ 0x40000000, /* 10 tim2 */ -+ 0x40001000, /* 11 tim3 */ -+ 0x40002000, /* 12 tim4 */ -+ 0x40003000, /* 13 tim5 */ -+ 0x40004000, /* 14 tim6 */ -+ 0x40005000, /* 15 tim7 */ -+ 0x40006000, /* 16 tim12 */ -+ 0x40007000, /* 17 tim13 */ -+ 0x40008000, /* 18 tim14 */ -+ 0x40009000, /* 19 lptim1 */ -+ 0x4000a000, /* 1A wwdg1 */ -+ 0x4000b000, /* 1B spi2 */ -+ 0x4000c000, /* 1C spi3 */ -+ 0x4000d000, /* 1D spdifrx */ -+ 0x4000e000, /* 1E usart2 */ -+ 0x4000f000, /* 1F usart3 */ -+ 0x40010000, /* 20 uart4 */ -+ 0x40011000, /* 21 uart5 */ -+ 0x40012000, /* 22 i2c1 */ -+ 0x40013000, /* 23 i2c2 */ -+ 0x40014000, /* 24 i2c3 */ -+ 0x40015000, /* 25 i2c5 */ -+ 0x40016000, /* 26 cec */ -+ 0x40017000, /* 27 dac */ -+ 0x40018000, /* 28 uart7 */ -+ 0x40019000, /* 29 uart8 */ -+ ETZPC_RESERVED, /* 2A reserved */ -+ ETZPC_RESERVED, /* 2B reserved */ -+ 0x4001c000, /* 2C mdios */ -+ ETZPC_RESERVED, /* 2D reserved */ -+ ETZPC_RESERVED, /* 2E reserved */ -+ ETZPC_RESERVED, /* 2F reserved */ -+ 0x44000000, /* 30 tim1 */ -+ 0x44001000, /* 31 tim8 */ -+ ETZPC_RESERVED, /* 32 reserved */ -+ 0x44003000, /* 33 usart6 */ -+ 0x44004000, /* 34 spi1 */ -+ 0x44005000, /* 35 spi4 */ -+ 0x44006000, /* 36 tim15 */ -+ 0x44007000, /* 37 tim16 */ -+ 0x44008000, /* 38 tim17 */ -+ 0x44009000, /* 39 spi5 */ -+ 0x4400a000, /* 3A sai1 */ -+ 0x4400b000, /* 3B sai2 */ -+ 0x4400c000, /* 3C sai3 */ -+ 0x4400d000, /* 3D dfsdm */ -+ 0x4400e000, /* 3E tt_fdcan */ -+ ETZPC_RESERVED, /* 3F reserved */ -+ 0x50021000, /* 40 lptim2 */ -+ 0x50022000, /* 41 lptim3 */ -+ 0x50023000, /* 42 lptim4 */ -+ 0x50024000, /* 43 lptim5 */ -+ 0x50027000, /* 44 sai4 */ -+ 0x50025000, /* 45 vrefbuf */ -+ 0x4c006000, /* 46 dcmi */ -+ 0x4c004000, /* 47 crc2 */ -+ 0x48003000, /* 48 adc */ -+ 0x4c002000, /* 49 hash2 */ -+ 0x4c003000, /* 4A rng2 */ -+ 0x4c005000, /* 4B cryp2 */ -+ ETZPC_RESERVED, /* 4C reserved */ -+ ETZPC_RESERVED, /* 4D reserved */ -+ ETZPC_RESERVED, /* 4E reserved */ -+ ETZPC_RESERVED, /* 4F reserved */ -+ ETZPC_RESERVED, /* 50 sram1 */ -+ ETZPC_RESERVED, /* 51 sram2 */ -+ ETZPC_RESERVED, /* 52 sram3 */ -+ ETZPC_RESERVED, /* 53 sram4 */ -+ ETZPC_RESERVED, /* 54 retram */ -+ 0x49000000, /* 55 otg */ -+ 0x48004000, /* 56 sdmmc3 */ -+ 0x48005000, /* 57 dlybsd3 */ -+ 0x48000000, /* 58 dma1 */ -+ 0x48001000, /* 59 dma2 */ -+ 0x48002000, /* 5A dmamux */ -+ 0x58002000, /* 5B fmc */ -+ 0x58003000, /* 5C qspi */ -+ 0x58004000, /* 5D dlybq */ -+ 0x5800a000, /* 5E eth */ -+ ETZPC_RESERVED, /* 5F reserved */ -+}; -+ -+/* fdt helper */ -+static bool fdt_disable_subnode_by_address(void *fdt, int offset, u32 addr) -+{ -+ int node; -+ -+ for (node = fdt_first_subnode(fdt, offset); -+ node >= 0; -+ node = fdt_next_subnode(fdt, node)) { -+ if (addr == (u32)fdt_getprop(fdt, node, "reg", 0)) { -+ if (fdtdec_get_is_enabled(fdt, node)) { -+ fdt_status_disabled(fdt, node); -+ -+ return true; -+ } -+ return false; -+ } -+ } -+ -+ return false; -+} -+ -+int stm32_fdt_fixup_etzpc(void *fdt) -+{ -+ void *base; -+ u32 version; -+ const u32 *array; -+ int array_size, i; -+ int soc_node, offset, shift; -+ u32 addr, status, decprot[ETZPC_DECPROT_NB]; -+ -+ base = syscon_get_first_range(STM32MP_SYSCON_ETZPC); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ version = readl(base + ETZPC_IP_VER); -+ -+ switch (version) { -+ case IP_VER_STM32MP1: -+ array = stm32mp1_ip_addr; -+ array_size = ARRAY_SIZE(stm32mp1_ip_addr); -+ break; -+ default: -+ return 0; -+ } -+ -+ for (i = 0; i < ETZPC_DECPROT_NB; i++) -+ decprot[i] = readl(base + ETZPC_DECPROT(i)); -+ -+ soc_node = fdt_path_offset(fdt, "/soc"); -+ if (soc_node < 0) -+ return soc_node; -+ -+ for (i = 0; i < array_size; i++) { -+ offset = i / NB_PROT_PER_REG; -+ shift = (i % NB_PROT_PER_REG) * DECPROT_NB_BITS; -+ status = (decprot[offset] >> shift) & DECPROT_MASK; -+ addr = array[i]; -+ -+ debug("ETZPC: 0x%08x decprot %d=%d\n", addr, i, status); -+ -+ if (addr == ETZPC_RESERVED || -+ status == DECPROT_NON_SECURED) -+ continue; -+ -+ if (fdt_disable_subnode_by_address(fdt, soc_node, addr)) -+ printf("ETZPC: 0x%08x node disabled, decprot %d=%d\n", -+ addr, i, status); -+ } -+ -+ return 0; -+} + printf("DRAM init failed: %d\n", ret); diff --git a/arch/arm/mach-stm32mp/syscon.c b/arch/arm/mach-stm32mp/syscon.c -index eb7f435..242f834 100644 +index 6070837..3e61ce4 100644 --- a/arch/arm/mach-stm32mp/syscon.c +++ b/arch/arm/mach-stm32mp/syscon.c -@@ -9,10 +9,11 @@ +@@ -9,7 +9,6 @@ #include static const struct udevice_id stm32mp_syscon_ids[] = { -- { .compatible = "st,stm32-stgen", -- .data = STM32MP_SYSCON_STGEN }, -- { .compatible = "st,stm32mp1-pwr", -- .data = STM32MP_SYSCON_PWR }, -+ { .compatible = "st,stm32mp1-etzpc", .data = STM32MP_SYSCON_ETZPC }, -+ { .compatible = "st,stm32mp1-pwr", .data = STM32MP_SYSCON_PWR }, -+ { .compatible = "st,stm32-stgen", .data = STM32MP_SYSCON_STGEN }, -+ { .compatible = "st,stm32mp157-syscfg", -+ .data = STM32MP_SYSCON_SYSCFG }, +- { .compatible = "st,stm32mp1-pwr", .data = STM32MP_SYSCON_PWR }, + { .compatible = "st,stm32mp157-syscfg", + .data = STM32MP_SYSCON_SYSCFG }, { } - }; +diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts +index fdb08f2..b69f0da 100644 +--- a/arch/sandbox/dts/test.dts ++++ b/arch/sandbox/dts/test.dts +@@ -1,5 +1,8 @@ + /dts-v1/; ++#include ++#include ++ + / { + model = "sandbox"; + compatible = "sandbox"; +@@ -13,6 +16,7 @@ + eth5 = ð_5; + gpio1 = &gpio_a; + gpio2 = &gpio_b; ++ gpio3 = &gpio_c; + i2c0 = "/i2c@0"; + mmc0 = "/mmc0"; + mmc1 = "/mmc1"; +@@ -86,11 +90,21 @@ + ping-expect = <0>; + ping-add = <0>; + u-boot,dm-pre-reloc; +- test-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 5 0 3 2 1>, ++ test-gpios = <&gpio_a 1>, <&gpio_a 4>, ++ <&gpio_b 5 GPIO_ACTIVE_HIGH 3 2 1>, + <0>, <&gpio_a 12>; +- test2-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 6 1 3 2 1>, +- <&gpio_b 7 2 3 2 1>, <&gpio_b 8 4 3 2 1>, +- <&gpio_b 9 0xc 3 2 1>; ++ test2-gpios = <&gpio_a 1>, <&gpio_a 4>, ++ <&gpio_b 6 GPIO_ACTIVE_LOW 3 2 1>, ++ <&gpio_b 7 GPIO_IN 3 2 1>, ++ <&gpio_b 8 GPIO_OUT 3 2 1>, ++ <&gpio_b 9 (GPIO_OUT|GPIO_OUT_ACTIVE) 3 2 1>; ++ test3-gpios = ++ <&gpio_c 0 (GPIO_OUT|GPIO_OPEN_DRAIN)>, ++ <&gpio_c 1 (GPIO_OUT|GPIO_OPEN_SOURCE)>, ++ <&gpio_c 2 GPIO_OUT>, ++ <&gpio_c 3 (GPIO_IN|GPIO_PULL_UP)>, ++ <&gpio_c 4 (GPIO_IN|GPIO_PULL_DOWN)>, ++ <&gpio_c 5 GPIO_IN>; + int-value = <1234>; + uint-value = <(-1234)>; + }; +@@ -274,20 +288,32 @@ + }; + }; + +- gpio_a: base-gpios { +- compatible = "sandbox,gpio"; +- gpio-controller; +- #gpio-cells = <1>; +- gpio-bank-name = "a"; +- sandbox,gpio-count = <20>; +- }; ++ pinctrl-gpio { ++ compatible = "sandbox,pinctrl-gpio"; ++ ++ gpio_a: base-gpios { ++ compatible = "sandbox,gpio"; ++ gpio-controller; ++ #gpio-cells = <1>; ++ gpio-bank-name = "a"; ++ sandbox,gpio-count = <20>; ++ }; + +- gpio_b: extra-gpios { +- compatible = "sandbox,gpio"; +- gpio-controller; +- #gpio-cells = <5>; +- gpio-bank-name = "b"; +- sandbox,gpio-count = <10>; ++ gpio_b: extra-gpios { ++ compatible = "sandbox,gpio"; ++ gpio-controller; ++ #gpio-cells = <5>; ++ gpio-bank-name = "b"; ++ sandbox,gpio-count = <10>; ++ }; ++ ++ gpio_c: pinmux-gpios { ++ compatible = "sandbox,gpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-bank-name = "c"; ++ sandbox,gpio-count = <10>; ++ }; + }; + + i2c@0 { +@@ -851,6 +877,31 @@ + + pinctrl { + compatible = "sandbox,pinctrl"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpios>; ++ ++ gpios: gpios { ++ gpio0 { ++ pins = "GPIO0"; ++ bias-pull-up; ++ input-disable; ++ }; ++ gpio1 { ++ pins = "GPIO1"; ++ output-high; ++ drive-open-drain; ++ }; ++ gpio2 { ++ pins = "GPIO2"; ++ bias-pull-down; ++ input-enable; ++ }; ++ gpio3 { ++ pins = "GPIO3"; ++ bias-disable; ++ }; ++ }; + }; + + hwspinlock@0 { +diff --git a/arch/sandbox/include/asm/gpio.h b/arch/sandbox/include/asm/gpio.h +index de8ac37..df4ba4f 100644 +--- a/arch/sandbox/include/asm/gpio.h ++++ b/arch/sandbox/include/asm/gpio.h +@@ -43,43 +43,43 @@ int sandbox_gpio_get_value(struct udevice *dev, unsigned int offset); + int sandbox_gpio_set_value(struct udevice *dev, unsigned int offset, int value); + + /** +- * Set or reset the simulated open drain mode of a GPIO (used only in sandbox +- * test code) ++ * Return the simulated direction of a GPIO (used only in sandbox test code) + * +- * @param gp GPIO number +- * @param value value to set (0 for enabled open drain mode, non-zero for +- * disabled) +- * @return -1 on error, 0 if ok ++ * @param dev device to use ++ * @param offset GPIO offset within bank ++ * @return -1 on error, 0 if GPIO is input, >0 if output + */ +-int sandbox_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value); ++int sandbox_gpio_get_direction(struct udevice *dev, unsigned int offset); + + /** +- * Return the state of the simulated open drain mode of a GPIO (used only in +- * sandbox test code) ++ * Set the simulated direction of a GPIO (used only in sandbox test code) + * +- * @param gp GPIO number +- * @return -1 on error, 0 if GPIO is input, >0 if output ++ * @param dev device to use ++ * @param offset GPIO offset within bank ++ * @param output 0 to set as input, 1 to set as output ++ * @return -1 on error, 0 if ok + */ +-int sandbox_gpio_get_open_drain(struct udevice *dev, unsigned offset); ++int sandbox_gpio_set_direction(struct udevice *dev, unsigned int offset, ++ int output); + + /** +- * Return the simulated direction of a GPIO (used only in sandbox test code) ++ * Return the simulated flags of a GPIO (used only in sandbox test code) + * + * @param dev device to use + * @param offset GPIO offset within bank +- * @return -1 on error, 0 if GPIO is input, >0 if output ++ * @return dir_flags: bitfield accesses by GPIOD_ defines + */ +-int sandbox_gpio_get_direction(struct udevice *dev, unsigned int offset); ++ulong sandbox_gpio_get_dir_flags(struct udevice *dev, unsigned int offset); + + /** +- * Set the simulated direction of a GPIO (used only in sandbox test code) ++ * Set the simulated flags of a GPIO (used only in sandbox test code) + * + * @param dev device to use + * @param offset GPIO offset within bank +- * @param output 0 to set as input, 1 to set as output ++ * @param flags dir_flags: bitfield accesses by GPIOD_ defines + * @return -1 on error, 0 if ok + */ +-int sandbox_gpio_set_direction(struct udevice *dev, unsigned int offset, +- int output); ++int sandbox_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, ++ ulong flags); + + #endif -- 2.7.4 diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0002-ARM-v2018.11-stm32mp-r1-BOARD.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0002-ARM-v2018.11-stm32mp-r1-BOARD.patch deleted file mode 100644 index 02c0c72..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0002-ARM-v2018.11-stm32mp-r1-BOARD.patch +++ /dev/null @@ -1,1960 +0,0 @@ -From bfe9ecaff00a65f8a41387f2be771ba11efa0d3c Mon Sep 17 00:00:00 2001 -From: christophe montaud -Date: Fri, 4 Jan 2019 15:04:41 +0100 -Subject: [PATCH 2/5] ARM v2018.11 stm32mp r1 BOARD - ---- - board/st/stm32mp1/Kconfig | 7 + - board/st/stm32mp1/MAINTAINERS | 7 +- - board/st/stm32mp1/Makefile | 1 + - board/st/stm32mp1/README | 118 +++- - board/st/stm32mp1/board.c | 178 ++++-- - board/st/stm32mp1/cmd_stboard.c | 145 +++++ - board/st/stm32mp1/extlinux.conf | 20 + - board/st/stm32mp1/fit_copro_kernel_dtb.its | 103 ++++ - board/st/stm32mp1/fit_kernel_dtb.its | 82 +++ - board/st/stm32mp1/spl.c | 27 +- - board/st/stm32mp1/stm32mp1.c | 909 ++++++++++++++++++++++++++--- - 11 files changed, 1434 insertions(+), 163 deletions(-) - create mode 100644 board/st/stm32mp1/cmd_stboard.c - create mode 100644 board/st/stm32mp1/extlinux.conf - create mode 100644 board/st/stm32mp1/fit_copro_kernel_dtb.its - create mode 100644 board/st/stm32mp1/fit_kernel_dtb.its - -diff --git a/board/st/stm32mp1/Kconfig b/board/st/stm32mp1/Kconfig -index 5ab9415..92d8f90 100644 ---- a/board/st/stm32mp1/Kconfig -+++ b/board/st/stm32mp1/Kconfig -@@ -9,4 +9,11 @@ config SYS_VENDOR - config SYS_CONFIG_NAME - default "stm32mp1" - -+config CMD_STBOARD -+ bool "stboard - command for OTP board information" -+ default y -+ help -+ This compile the stboard command to -+ read and write the board in the OTP. -+ - endif -diff --git a/board/st/stm32mp1/MAINTAINERS b/board/st/stm32mp1/MAINTAINERS -index 48d8fd2..6c9710a 100644 ---- a/board/st/stm32mp1/MAINTAINERS -+++ b/board/st/stm32mp1/MAINTAINERS -@@ -1,8 +1,11 @@ - STM32MP1 BOARD - M: Patrick Delaunay -+M: Christophe Kerello - L: uboot-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers) - S: Maintained -+F: arch/arm/dts/stm32mp157* - F: board/st/stm32mp1 --F: include/configs/stm32mp1.h -+F: configs/stm32mp15_trusted_defconfig -+F: configs/stm32mp15_optee_defconfig - F: configs/stm32mp15_basic_defconfig --F: arch/arm/dts/stm32mp157* -+F: include/configs/stm32mp1.h -diff --git a/board/st/stm32mp1/Makefile b/board/st/stm32mp1/Makefile -index 8188075..3c6c035 100644 ---- a/board/st/stm32mp1/Makefile -+++ b/board/st/stm32mp1/Makefile -@@ -7,6 +7,7 @@ ifdef CONFIG_SPL_BUILD - obj-y += spl.o - else - obj-y += stm32mp1.o -+obj-$(CONFIG_CMD_STBOARD) += cmd_stboard.o - endif - - obj-y += board.o -diff --git a/board/st/stm32mp1/README b/board/st/stm32mp1/README -index 174e6db..4ebcfb4 100644 ---- a/board/st/stm32mp1/README -+++ b/board/st/stm32mp1/README -@@ -25,17 +25,21 @@ It features: - Everything is supported in Linux but U-Boot is limited to: - 1. UART - 2. SDCard/MMC controller (SDMMC) -+3. NAND controller (FMC) -+4. NOR controller (QSPI) -+5. USB controller (OTG DWC2) - - And the necessary drivers - 1. I2C --2. STPMU1 --2. STPMU1 (PMIC and regulator) -+2. STPMIC1 (PMIC and regulator) - 3. Clock, Reset, Sysreset - 4. Fuse - - Currently the following boards are supported: - + stm32mp157c-ev1 - + stm32mp157c-ed1 -++ stm32mp157a-dk1 -++ stm32mp157c-dk2 - - 3. Boot Sequences - ================= -@@ -45,15 +49,22 @@ BootRom => FSBL in SYSRAM => SSBL in DDR => OS (Linux Kernel) - with FSBL = First Stage Bootloader - SSBL = Second Stage Bootloader - --One boot configuration is supported: -+2 boot configurations are supported: - -- The "Basic" boot chain (defconfig_file : stm32mp15_basic_defconfig) -+1) The "Trusted" boot chain (defconfig_file : stm32mp15_trusted_defconfig) -+ BootRom => FSBL = Trusted Firmware-A (TF-A) => SSBL = U-Boot -+ TF-A performs a full initialization of Secure peripherals and installs a -+ secure monitor. -+ U-Boot is running in normal world and uses TF-A monitor -+ to access to secure resources -+ -+2) The "Basic" boot chain (defconfig_file : stm32mp15_basic_defconfig) - BootRom => FSBL = U-Boot SPL => SSBL = U-Boot - SPL has limited security initialisation - 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 STM32MP1 board supported by U-Boot use the same generic board -+All the STM32MP1 boards supported by U-Boot use the same generic board - stm32mp1 which support all the bootable devices. - - Each board is configurated only with the associated device tree. -@@ -64,12 +75,18 @@ Each board is configurated only with the associated device tree. - You need to select the appropriate device tree for your board, - the supported device trees for stm32mp157 are: - --+ ev1: eval board with pmic stpmu1 (ev1 = mother board + daughter ed1) -++ ev1: eval board with pmic stpmic1 (ev1 = mother board + daughter ed1) - dts: stm32mp157c-ev1 - --+ ed1: daughter board with pmic stpmu1 -++ ed1: daughter board with pmic stpmic1 - dts: stm32mp157c-ed1 - -++ dk1: Discovery board -+ dts: stm32mp157a-dk1 -+ -++ dk2: Discovery board = dk1 with a BT/WiFI combo and a DSI panel -+ dts: stm32mp157c-dk2 -+ - 5. Build Procedure - ================== - -@@ -90,29 +107,30 @@ the supported device trees for stm32mp157 are: - # export KBUILD_OUTPUT=/path/to/output - - for example: use one output directory for each configuration -+ # export KBUILD_OUTPUT=stm32mp15_trusted - # export KBUILD_OUTPUT=stm32mp15_basic - --4. Configure the U-Boot: -+4. Configure U-Boot: - - # make - -+ - For trusted boot mode : "stm32mp15_trusted_defconfig" - - For basic boot mode: "stm32mp15_basic_defconfig" - - 5. Configure the device-tree and build the U-Boot image: - - # make DEVICE_TREE= all - -- - example: -- basic boot on ev1 -- # export KBUILD_OUTPUT=stm32mp15_basic -- # make stm32mp15_basic_defconfig -+ a) trusted boot on ev1 -+ # export KBUILD_OUTPUT=stm32mp15_trusted -+ # make stm32mp15_trusted_defconfig - # make DEVICE_TREE=stm32mp157c-ev1 all - -- basic boot on ed1 -+ b) basic boot on dk2 - # export KBUILD_OUTPUT=stm32mp15_basic - # make stm32mp15_basic_defconfig -- # make DEVICE_TREE=stm32mp157c-ed1 all -+ # make DEVICE_TREE=stm32mp157c-dk2 all - - 6. Output files - -@@ -122,13 +140,20 @@ the supported device trees for stm32mp157 are: - So in the output directory (selected by KBUILD_OUTPUT), - you can found the needed files: - -+ a) For Trusted boot -+ + FSBL = tf-a.stm32 (provided by TF-A compilation) -+ + SSBL = u-boot.stm32 -+ -+ b) For Basic boot - + FSBL = spl/u-boot-spl.stm32 - + SSBL = u-boot.img - - 6. Switch Setting for Boot Mode - =============================== - --You can select the boot mode, on the board ed1 with the switch SW1 -+You can select the boot mode, -+- on the daugther board ed1 with the switch SW1 : BOOT0, BOOT1, BOOT2 -+- on board DK1/DK2 with the switch SW1 (BOOT1 forced to 0) - - ----------------------------------- - Boot Mode BOOT2 BOOT1 BOOT0 -@@ -142,6 +167,16 @@ You can select the boot mode, on the board ed1 with the switch SW1 - Recovery 1 1 0 - Recovery 0 0 0 - -+- on board DK1/DK2 with the switch SW1 : BOOT0, BOOT2 -+ (BOOT1 forced to 0, NOR not supported) -+ -+ -------------------------- -+ Boot Mode BOOT2 BOOT0 -+ -------------------------- -+ Reserved 1 0 -+ SD-Card 1 1 -+ Recovery 0 0 -+ - Recovery is a boot from serial link (UART/USB) and it is used with - STM32CubeProgrammer tool to load executable in RAM and to update the flash - devices available on the board (NOR/NAND/eMMC/SDCARD). -@@ -158,14 +193,14 @@ The minimal requirements for STMP32MP1 boot up to U-Boot are: - - one ssbl partition for U-Boot - - Then the minimal GPT partition is: -- ----- ------- --------- ------------- -- | Num | Name | Size | Content | -- ----- ------- -------- -------------- -+ ----- ------- --------- --------------- -+ | 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 | -- | * | - | - | Boot/Rootfs| -- ----- ------- --------- ------------- -+ | 3 | ssbl | enought | U-Boot | -+ | * | - | - | Boot/Rootfs | -+ ----- ------- --------- --------------- - - (*) add bootable partition for extlinux.conf - following Generic Distribution -@@ -189,7 +224,7 @@ for example: with gpt table with 128 entries - - you can add other partitions for kernel - one partition rootfs for example: -- -n 3:5154: -c 4:rootfs -+ -n 3:5154: -c 4:rootfs \ - - c) copy the FSBL (2 times) and SSBL file on the correct partition. - in this example in partition 1 to 3 -@@ -199,6 +234,11 @@ for example: with gpt table with 128 entries - # dd if=u-boot-spl.stm32 of=/dev/mmcblk0p2 - # dd if=u-boot.img of=/dev/mmcblk0p3 - -+ for trusted boot mode : -+ # dd if=tf-a.stm32 of=/dev/mmcblk0p1 -+ # dd if=tf-a.stm32 of=/dev/mmcblk0p2 -+ # dd if=u-boot.stm32 of=/dev/mmcblk0p3 -+ - To boot from SDCard, select BootPinMode = 1 1 1 and reset. - - 8. Prepare eMMC -@@ -266,3 +306,37 @@ on bank 0 to access to internal OTP: - 4 check env update - STM32MP> print ethaddr - ethaddr=12:34:56:78:9a:bc -+ -+10. Coprocessor firmware -+======================== -+ -+U-Boot can boot the coprocessor before the kernel (coprocessor early boot). -+ -+A/ Manuallly by using rproc commands (update the bootcmd) -+ Configurations -+ # env set name_copro "stm32mp15_m4.elf" -+ # env set dev_copro 0 -+ # env set loadaddr_copro 0xC1000000 -+ -+ Load binary from bootfs partition (number 4) on SDCard (mmc 0) -+ # ext4load mmc 0:4 ${loadaddr_copro} ${name_copro} -+ => ${filesize} updated with the size of the loaded file -+ -+ Start M4 firmware with remote proc command -+ # rproc init -+ # rproc load ${dev_copro} ${loadaddr_copro} ${filesize} -+ # rproc load_rsc ${dev_copro} ${loadaddr_copro} ${filesize} -+ # rproc start ${dev_copro} -+ -+B/ Automatically by using FIT feature and generic DISTRO bootcmd -+ -+ see examples in this directory : -+ -+ Generate FIT including kernel + device tree + M4 firmware -+ with cfg with M4 boot -+ $> mkimage -f fit_copro_kernel_dtb.its fit_copro_kernel_dtb.itb -+ -+ Then using DISTRO configuration file: see extlinux.conf to select -+ the correct configuration -+ => stm32mp157c-ev1-m4 -+ => stm32mp157c-dk2-m4 -diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c -index 5f31ea9..b6e5288 100644 ---- a/board/st/stm32mp1/board.c -+++ b/board/st/stm32mp1/board.c -@@ -8,7 +8,7 @@ - #include - #include - #include --#include -+#include - - #ifdef CONFIG_DEBUG_UART_BOARD_INIT - void board_debug_uart_init(void) -@@ -37,64 +37,140 @@ void board_debug_uart_init(void) - } - #endif - --#ifdef CONFIG_PMIC_STPMU1 --int board_ddr_power_init(void) -+#ifdef CONFIG_PMIC_STPMIC1 -+int board_ddr_power_init(enum ddr_type ddr_type) - { - struct udevice *dev; -+ bool buck3_at_1800000v = false; - int ret; - - ret = uclass_get_device_by_driver(UCLASS_PMIC, -- DM_GET_DRIVER(pmic_stpmu1), &dev); -+ DM_GET_DRIVER(pmic_stpmic1), &dev); - if (ret) -- /* No PMIC on board */ -+ /* No PMIC on power discrete board */ - return 0; - -- /* Set LDO3 to sync mode */ -- ret = pmic_reg_read(dev, STPMU1_LDOX_CTRL_REG(STPMU1_LDO3)); -- if (ret < 0) -- return ret; -- -- ret &= ~STPMU1_LDO3_MODE; -- ret &= ~STPMU1_LDO12356_OUTPUT_MASK; -- ret |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT; -- -- ret = pmic_reg_write(dev, STPMU1_LDOX_CTRL_REG(STPMU1_LDO3), -- ret); -- if (ret < 0) -- return ret; -- -- /* Set BUCK2 to 1.35V */ -- ret = pmic_clrsetbits(dev, -- STPMU1_BUCKX_CTRL_REG(STPMU1_BUCK2), -- STPMU1_BUCK_OUTPUT_MASK, -- STPMU1_BUCK2_1350000V); -- if (ret < 0) -- return ret; -- -- /* Enable BUCK2 and VREF */ -- ret = pmic_clrsetbits(dev, -- STPMU1_BUCKX_CTRL_REG(STPMU1_BUCK2), -- STPMU1_BUCK_EN, STPMU1_BUCK_EN); -- if (ret < 0) -- return ret; -- -- mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS); -- -- ret = pmic_clrsetbits(dev, STPMU1_VREF_CTRL_REG, -- STPMU1_VREF_EN, STPMU1_VREF_EN); -- if (ret < 0) -- return ret; -- -- mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS); -- -- /* Enable LDO3 */ -- ret = pmic_clrsetbits(dev, -- STPMU1_LDOX_CTRL_REG(STPMU1_LDO3), -- STPMU1_LDO_EN, STPMU1_LDO_EN); -- if (ret < 0) -- return ret; -- -- mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS); -+ switch (ddr_type) { -+ case STM32MP_DDR3: -+ /* VTT = Set LDO3 to sync mode */ -+ ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3)); -+ if (ret < 0) -+ return ret; -+ -+ ret &= ~STPMIC1_LDO3_MODE; -+ ret &= ~STPMIC1_LDO12356_VOUT_MASK; -+ ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL); -+ -+ ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), -+ ret); -+ if (ret < 0) -+ return ret; -+ -+ /* VDD_DDR = Set BUCK2 to 1.35V */ -+ ret = pmic_clrsetbits(dev, -+ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), -+ STPMIC1_BUCK_VOUT_MASK, -+ STPMIC1_BUCK2_1350000V); -+ if (ret < 0) -+ return ret; -+ -+ /* Enable VDD_DDR = BUCK2 */ -+ ret = pmic_clrsetbits(dev, -+ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), -+ STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA); -+ if (ret < 0) -+ return ret; -+ -+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); -+ -+ /* Enable VREF */ -+ ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR, -+ STPMIC1_VREF_ENA, STPMIC1_VREF_ENA); -+ if (ret < 0) -+ return ret; -+ -+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); -+ -+ /* Enable VTT = LDO3 */ -+ ret = pmic_clrsetbits(dev, -+ STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), -+ STPMIC1_LDO_ENA, STPMIC1_LDO_ENA); -+ if (ret < 0) -+ return ret; -+ -+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); -+ -+ break; -+ -+ case STM32MP_LPDDR2: -+ case STM32MP_LPDDR3: -+ /* -+ * configure VDD_DDR1 = LDO3 -+ * Set LDO3 to 1.8V -+ * + bypass mode if BUCK3 = 1.8V -+ * + normal mode if BUCK3 != 1.8V -+ */ -+ ret = pmic_reg_read(dev, -+ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK3)); -+ if (ret < 0) -+ return ret; -+ -+ if ((ret & STPMIC1_BUCK3_1800000V) == STPMIC1_BUCK3_1800000V) -+ buck3_at_1800000v = true; -+ -+ ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3)); -+ if (ret < 0) -+ return ret; -+ -+ ret &= ~STPMIC1_LDO3_MODE; -+ ret &= ~STPMIC1_LDO12356_VOUT_MASK; -+ ret |= STPMIC1_LDO3_1800000; -+ if (buck3_at_1800000v) -+ ret |= STPMIC1_LDO3_MODE; -+ -+ ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), -+ ret); -+ if (ret < 0) -+ return ret; -+ -+ /* VDD_DDR2 : Set BUCK2 to 1.2V */ -+ ret = pmic_clrsetbits(dev, -+ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), -+ STPMIC1_BUCK_VOUT_MASK, -+ STPMIC1_BUCK2_1200000V); -+ if (ret < 0) -+ return ret; -+ -+ /* Enable VDD_DDR1 = LDO3 */ -+ ret = pmic_clrsetbits(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), -+ STPMIC1_LDO_ENA, STPMIC1_LDO_ENA); -+ if (ret < 0) -+ return ret; -+ -+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); -+ -+ /* Enable VDD_DDR22 =BUCK2 */ -+ ret = pmic_clrsetbits(dev, -+ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), -+ STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA); -+ if (ret < 0) -+ return ret; -+ -+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); -+ -+ /* Enable VREF */ -+ ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR, -+ STPMIC1_VREF_ENA, STPMIC1_VREF_ENA); -+ if (ret < 0) -+ return ret; -+ -+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); -+ -+ break; -+ -+ default: -+ break; -+ }; - - return 0; - } -diff --git a/board/st/stm32mp1/cmd_stboard.c b/board/st/stm32mp1/cmd_stboard.c -new file mode 100644 -index 0000000..38b1c1b ---- /dev/null -+++ b/board/st/stm32mp1/cmd_stboard.c -@@ -0,0 +1,145 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static bool check_stboard(u16 board) -+{ -+ int i; -+ const u16 st_board_id[] = { -+ 0x1272, -+ 0x1263, -+ 0x1264, -+ 0x1298, -+ 0x1341, -+ 0x1497, -+ }; -+ -+ for (i = 0; i < ARRAY_SIZE(st_board_id); i++) -+ if (board == st_board_id[i]) -+ return true; -+ -+ return false; -+} -+ -+static void display_stboard(u32 otp) -+{ -+ printf("Board: MB%04x Var%d Rev.%c-%02d\n", -+ otp >> 16, -+ (otp >> 12) & 0xF, -+ ((otp >> 8) & 0xF) - 1 + 'A', -+ otp & 0xF); -+} -+ -+static int do_stboard(cmd_tbl_t *cmdtp, int flag, int argc, -+ char * const argv[]) -+{ -+ int ret; -+ u32 otp; -+ u8 revision; -+ unsigned long board, variant, bom; -+ struct udevice *dev; -+ int confirmed = argc == 6 && !strcmp(argv[1], "-y"); -+ -+ argc -= 1 + confirmed; -+ argv += 1 + confirmed; -+ -+ if (argc != 0 && argc != 4) -+ return CMD_RET_USAGE; -+ -+ ret = uclass_get_device_by_driver(UCLASS_MISC, -+ DM_GET_DRIVER(stm32mp_bsec), -+ &dev); -+ -+ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), -+ &otp, sizeof(otp)); -+ -+ if (ret) { -+ puts("OTP read error"); -+ return CMD_RET_FAILURE; -+ } -+ -+ if (argc == 0) { -+ if (!otp) -+ puts("Board : OTP board FREE\n"); -+ else -+ display_stboard(otp); -+ return CMD_RET_SUCCESS; -+ } -+ -+ if (otp) { -+ display_stboard(otp); -+ printf("ERROR: OTP board not FREE\n"); -+ return CMD_RET_FAILURE; -+ } -+ -+ if (strict_strtoul(argv[0], 16, &board) < 0 || -+ board == 0 || board > 0xFFFF) { -+ printf("argument %d invalid: %s\n", 1, argv[0]); -+ return CMD_RET_USAGE; -+ } -+ -+ if (strict_strtoul(argv[1], 10, &variant) < 0 || -+ variant == 0 || variant > 15) { -+ printf("argument %d invalid: %s\n", 2, argv[1]); -+ return CMD_RET_USAGE; -+ } -+ -+ revision = argv[2][0] - 'A' + 1; -+ if (strlen(argv[2]) > 1 || revision == 0 || revision > 15) { -+ printf("argument %d invalid: %s\n", 3, argv[2]); -+ return CMD_RET_USAGE; -+ } -+ -+ if (strict_strtoul(argv[3], 10, &bom) < 0 || -+ bom == 0 || bom > 15) { -+ printf("argument %d invalid: %s\n", 4, argv[3]); -+ return CMD_RET_USAGE; -+ } -+ -+ otp = (board << 16) | (variant << 12) | (revision << 8) | bom; -+ display_stboard(otp); -+ printf("=> OTP[%d] = %08X\n", BSEC_OTP_BOARD, otp); -+ -+ if (!check_stboard((u16)board)) { -+ printf("Unknown board MB%04x\n", (u16)board); -+ return CMD_RET_FAILURE; -+ } -+ if (!confirmed) { -+ printf("Warning: Programming BOARD in OTP is irreversible!\n"); -+ printf("Really perform this OTP programming? \n"); -+ -+ if (!confirm_yesno()) { -+ puts("BOARD programming aborted\n"); -+ return CMD_RET_FAILURE; -+ } -+ } -+ -+ ret = misc_write(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD), -+ &otp, sizeof(otp)); -+ -+ if (ret) { -+ puts("BOARD programming error\n"); -+ return CMD_RET_FAILURE; -+ } -+ puts("BOARD programming done\n"); -+ -+ return CMD_RET_SUCCESS; -+} -+ -+U_BOOT_CMD(stboard, 6, 0, do_stboard, -+ "read/write board reference in OTP", -+ "\n" -+ " Print current board information\n" -+ "stboard [-y] \n" -+ " Write board information\n" -+ " - Board: xxxx, example 1264 for MB1264\n" -+ " - Variant: 1 ... 15\n" -+ " - Revision: A...O\n" -+ " - BOM: 1...15\n"); -diff --git a/board/st/stm32mp1/extlinux.conf b/board/st/stm32mp1/extlinux.conf -new file mode 100644 -index 0000000..2b46328 ---- /dev/null -+++ b/board/st/stm32mp1/extlinux.conf -@@ -0,0 +1,20 @@ -+# Generic Distro Configuration for STM32MP157 -+menu title Select the boot mode -+TIMEOUT 20 -+DEFAULT stm32mp157c-ev1 -+ -+LABEL stm32mp157c-ev1 -+ KERNEL /fit_kernel_dtb.itb#ev1 -+ APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttyS3,115200 -+ -+LABEL stm32mp157c-ev1-m4 -+ KERNEL /fit_copro_kernel_dtb.itb#ev1-m4 -+ APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttyS3,115200 -+ -+LABEL stm32mp157c-dk2 -+ KERNEL /fit_kernel_dtb.itb#dk2 -+ APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttyS3,115200 -+ -+LABEL stm32mp157c-dk2-m4 -+ KERNEL /fit_copro_kernel_dtb.itb#dk2-m4 -+ APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttyS3,115200 -diff --git a/board/st/stm32mp1/fit_copro_kernel_dtb.its b/board/st/stm32mp1/fit_copro_kernel_dtb.its -new file mode 100644 -index 0000000..7582fc3 ---- /dev/null -+++ b/board/st/stm32mp1/fit_copro_kernel_dtb.its -@@ -0,0 +1,103 @@ -+/* -+ * Compilation: -+ * mkimage -f fit_copro_kernel_dtb.its fit_copro_kernel_dtb.itb -+ */ -+ -+/dts-v1/; -+/ { -+ description = "U-Boot fitImage for stm32mp157"; -+ #address-cells = <1>; -+ -+ images { -+ -+ copro { -+ description = "M4 copro"; -+ data = /incbin/("stm32mp15_m4.elf"); -+ type = "stm32copro"; -+ arch = "arm"; -+ compression = "none"; -+ load = <0xC0800000>; -+ hash-1 { -+ algo = "sha1"; -+ }; -+ }; -+ -+ kernel { -+ description = "Linux kernel"; -+ data = /incbin/("zImage"); -+ type = "kernel"; -+ arch = "arm"; -+ os = "linux"; -+ compression = "none"; -+ load = <0xC0008000>; -+ entry = <0xC0008000>; -+ hash-1 { -+ algo = "sha1"; -+ }; -+ }; -+ -+ fdt-dk2 { -+ description = "FDT dk2"; -+ data = /incbin/("stm32mp157c-dk2.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash-1 { -+ algo = "sha1"; -+ }; -+ }; -+ -+ fdt-ev1 { -+ description = "FDT ev1"; -+ data = /incbin/("stm32mp157c-ev1.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash-1 { -+ algo = "sha1"; -+ }; -+ }; -+ }; -+ -+ configurations { -+ default = "dk2-m4"; -+ -+ dk2-m4 { -+ description = "dk2-m4"; -+ loadables = "copro"; -+ kernel = "kernel"; -+ fdt = "fdt-dk2"; -+ hash-1 { -+ algo = "sha1"; -+ }; -+ }; -+ -+ dk2 { -+ description = "dk2"; -+ kernel = "kernel"; -+ fdt = "fdt-dk2"; -+ hash-1 { -+ algo = "sha1"; -+ }; -+ }; -+ -+ ev1-m4 { -+ description = "ev1-m4"; -+ loadables = "copro"; -+ kernel = "kernel"; -+ fdt = "fdt-ev1"; -+ hash-1 { -+ algo = "sha1"; -+ }; -+ }; -+ -+ ev1 { -+ description = "ev1"; -+ kernel = "kernel"; -+ fdt = "fdt-ev1"; -+ hash-1 { -+ algo = "sha1"; -+ }; -+ }; -+ }; -+}; -diff --git a/board/st/stm32mp1/fit_kernel_dtb.its b/board/st/stm32mp1/fit_kernel_dtb.its -new file mode 100644 -index 0000000..18d03eb ---- /dev/null -+++ b/board/st/stm32mp1/fit_kernel_dtb.its -@@ -0,0 +1,82 @@ -+/* -+ * Compilation: -+ * mkimage -f fit_kernel_dtb.its fit_kernel_dtb.itb -+ * -+ * 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_kernel_dtb.itb -+ * bootm $kernel_addr_r -+ * bootm $kernel_addr_r#dk2 -+ * bootm $kernel_addr_r#ev1 -+ * -+ * or use extlinux.conf in this directory -+ */ -+ -+/dts-v1/; -+/ { -+ description = "U-Boot fitImage for stm32mp157"; -+ #address-cells = <1>; -+ -+ images { -+ kernel { -+ description = "Linux kernel"; -+ data = /incbin/("zImage"); -+ type = "kernel"; -+ arch = "arm"; -+ os = "linux"; -+ compression = "none"; -+ load = <0xC0008000>; -+ entry = <0xC0008000>; -+ hash-1 { -+ algo = "sha1"; -+ }; -+ }; -+ -+ fdt-dk2 { -+ description = "FDT dk2"; -+ data = /incbin/("stm32mp157c-dk2.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash-1 { -+ algo = "sha1"; -+ }; -+ }; -+ -+ fdt-ev1 { -+ description = "FDT ev1"; -+ data = /incbin/("stm32mp157c-ev1.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash-1 { -+ algo = "sha1"; -+ }; -+ }; -+ }; -+ -+ configurations { -+ default = "dk2"; -+ -+ dk2 { -+ description = "dk2"; -+ kernel = "kernel"; -+ fdt = "fdt-dk2"; -+ hash-1 { -+ algo = "sha1"; -+ }; -+ }; -+ -+ ev1 { -+ description = "ev1"; -+ kernel = "kernel"; -+ fdt = "fdt-ev1"; -+ hash-1 { -+ algo = "sha1"; -+ }; -+ }; -+ }; -+}; -diff --git a/board/st/stm32mp1/spl.c b/board/st/stm32mp1/spl.c -index f3db0d6..e65ff28 100644 ---- a/board/st/stm32mp1/spl.c -+++ b/board/st/stm32mp1/spl.c -@@ -9,24 +9,37 @@ - #include - #include - #include --#include - #include --#include -+#include - #include - - void spl_board_init(void) - { - /* Keep vdd on during the reset cycle */ --#if defined(CONFIG_PMIC_STPMU1) && defined(CONFIG_SPL_POWER_SUPPORT) -+#if defined(CONFIG_PMIC_STPMIC1) && defined(CONFIG_SPL_POWER_SUPPORT) - struct udevice *dev; - int ret; - - ret = uclass_get_device_by_driver(UCLASS_PMIC, -- DM_GET_DRIVER(pmic_stpmu1), &dev); -+ DM_GET_DRIVER(pmic_stpmic1), &dev); - if (!ret) - pmic_clrsetbits(dev, -- STPMU1_MASK_RESET_BUCK, -- STPMU1_MASK_RESET_BUCK3, -- STPMU1_MASK_RESET_BUCK3); -+ STPMIC1_BUCKS_MRST_CR, -+ STPMIC1_MRST_BUCK(STPMIC1_BUCK3), -+ STPMIC1_MRST_BUCK(STPMIC1_BUCK3)); -+ -+ /* Check if debug is enabled to program PMIC according to the bit */ -+ if ((readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_DEBUG_ON) && !ret) { -+ printf("Keep debug unit ON\n"); -+ -+ pmic_clrsetbits(dev, STPMIC1_BUCKS_MRST_CR, -+ STPMIC1_MRST_BUCK_DEBUG, -+ STPMIC1_MRST_BUCK_DEBUG); -+ -+ if (STPMIC1_MRST_LDO_DEBUG) -+ pmic_clrsetbits(dev, STPMIC1_LDOS_MRST_CR, -+ STPMIC1_MRST_LDO_DEBUG, -+ STPMIC1_MRST_LDO_DEBUG); -+ } - #endif - } -diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c -index 54feca0..5dc6296 100644 ---- a/board/st/stm32mp1/stm32mp1.c -+++ b/board/st/stm32mp1/stm32mp1.c -@@ -2,136 +2,351 @@ - /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved - */ -+ - #include - #include --#include --#include -+#include - #include -+#include -+#include -+#include - #include -+#include -+#include -+#include -+#include - #include -+#include - #include -+#include - #include --#include - #include -+#include -+#include -+#include -+#include - #include - #include - -+/* SYSCFG registers */ -+#define SYSCFG_BOOTR 0x00 -+#define SYSCFG_PMCSETR 0x04 -+#define SYSCFG_IOCTRLSETR 0x18 -+#define SYSCFG_ICNR 0x1C -+#define SYSCFG_CMPCR 0x20 -+#define SYSCFG_CMPENSETR 0x24 -+#define SYSCFG_PMCCLRR 0x44 -+ -+#define SYSCFG_IOCTRLSETR_HSLVEN_TRACE BIT(0) -+#define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI BIT(1) -+#define SYSCFG_IOCTRLSETR_HSLVEN_ETH BIT(2) -+#define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC BIT(3) -+#define SYSCFG_IOCTRLSETR_HSLVEN_SPI BIT(4) -+ -+#define SYSCFG_CMPCR_SW_CTRL BIT(1) -+#define SYSCFG_CMPCR_READY BIT(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 << 21) -+#define SYSCFG_PMCSETR_ETH_SEL_RGMII (1 << 21) -+#define SYSCFG_PMCSETR_ETH_SEL_RMII (4 << 21) -+ - /* - * Get a global data pointer - */ - DECLARE_GLOBAL_DATA_PTR; - --#define STM32MP_GUSBCFG 0x40002407 -+#define USB_WARNING_LOW_THRESHOLD_UV 660000 -+#define USB_START_LOW_THRESHOLD_UV 1230000 -+#define USB_START_HIGH_THRESHOLD_UV 2100000 -+ -+int checkboard(void) -+{ -+ int ret; -+ char *mode; -+ u32 otp; -+ struct udevice *dev; -+ const char *fdt_compat; -+ int fdt_compat_len; -+ -+ if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED)) -+ mode = "trusted"; -+ else -+ mode = "basic"; -+ -+ printf("Board: stm32mp1 in %s mode", mode); -+ fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible", -+ &fdt_compat_len); -+ if (fdt_compat && fdt_compat_len) -+ printf(" (%s)", fdt_compat); -+ puts("\n"); -+ -+ ret = uclass_get_device_by_driver(UCLASS_MISC, -+ DM_GET_DRIVER(stm32mp_bsec), -+ &dev); -+ -+ if (!ret) -+ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), -+ &otp, sizeof(otp)); -+ if (!ret && otp) { -+ printf("Board: MB%04x Var%d Rev.%c-%02d\n", -+ otp >> 16, -+ (otp >> 12) & 0xF, -+ ((otp >> 8) & 0xF) - 1 + 'A', -+ otp & 0xF); -+ } -+ -+ return 0; -+} -+ -+static void board_key_check(void) -+{ -+#if defined(CONFIG_FASTBOOT) || defined(CONFIG_CMD_STM32PROG) -+ ofnode node; -+ struct gpio_desc gpio; -+ enum forced_boot_mode boot_mode = BOOT_NORMAL; -+ -+ node = ofnode_path("/config"); -+ if (!ofnode_valid(node)) { -+ debug("%s: no /config node?\n", __func__); -+ return; -+ } -+#ifdef CONFIG_FASTBOOT -+ if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0, -+ &gpio, GPIOD_IS_IN)) { -+ debug("%s: could not find a /config/st,fastboot-gpios\n", -+ __func__); -+ } else { -+ if (dm_gpio_get_value(&gpio)) { -+ puts("Fastboot key pressed, "); -+ boot_mode = BOOT_FASTBOOT; -+ } -+ -+ dm_gpio_free(NULL, &gpio); -+ } -+#endif -+#ifdef CONFIG_CMD_STM32PROG -+ if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0, -+ &gpio, GPIOD_IS_IN)) { -+ debug("%s: could not find a /config/st,stm32prog-gpios\n", -+ __func__); -+ } else { -+ if (dm_gpio_get_value(&gpio)) { -+ puts("STM32Programmer key pressed, "); -+ boot_mode = BOOT_STM32PROG; -+ } -+ dm_gpio_free(NULL, &gpio); -+ } -+#endif -+ -+ if (boot_mode != BOOT_NORMAL) { -+ puts("entering download mode...\n"); -+ clrsetbits_le32(TAMP_BOOT_CONTEXT, -+ TAMP_BOOT_FORCED_MASK, -+ boot_mode); -+ } -+#endif -+} -+ -+bool board_is_dk2(void) -+{ -+ if (of_machine_is_compatible("st,stm32mp157c-dk2")) -+ return true; - --#define STM32MP_GGPIO 0x38 --#define STM32MP_GGPIO_VBUS_SENSING BIT(21) -+ return false; -+} -+ -+int board_late_init(void) -+{ -+#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG -+ const void *fdt_compat; -+ int fdt_compat_len; -+ -+ fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible", -+ &fdt_compat_len); -+ if (fdt_compat && fdt_compat_len) { -+ if (strncmp(fdt_compat, "st,", 3) != 0) -+ env_set("board_name", fdt_compat); -+ else -+ env_set("board_name", fdt_compat + 3); -+ } -+#endif -+ -+ return 0; -+} -+ -+#ifdef CONFIG_STM32_SDMMC2 -+/* this is a weak define that we are overriding */ -+int board_mmc_init(void) -+{ -+ return 0; -+} -+#endif -+ -+#ifdef CONFIG_STM32_QSPI -+void board_qspi_init(void) -+{ -+} -+#endif /* CONFIG_STM32_QSPI */ -+ -+#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) -+ -+/* -+ * DWC2 registers should be defined in drivers -+ * OTG: drivers/usb/gadget/dwc2_udc_otg_regs.h -+ * HOST: ./drivers/usb/host/dwc2.h -+ */ -+#define DWC2_GOTGCTL_OFFSET 0x00 -+#define DWC2_GGPIO_OFFSET 0x38 -+ -+#define DWC2_GGPIO_VBUS_SENSING BIT(21) -+ -+#define DWC2_GOTGCTL_AVALIDOVEN BIT(4) -+#define DWC2_GOTGCTL_AVALIDOVVAL BIT(5) -+#define DWC2_GOTGCTL_BVALIDOVEN BIT(6) -+#define DWC2_GOTGCTL_BVALIDOVVAL BIT(7) -+#define DWC2_GOTGCTL_BSVLD BIT(19) -+ -+#define STM32MP_GUSBCFG 0x40002407 - - static struct dwc2_plat_otg_data stm32mp_otg_data = { -+ .regs_otg = FDT_ADDR_T_NONE, - .usb_gusbcfg = STM32MP_GUSBCFG, -+ .priv = NULL, /* pointer to udevice for stusb1600 when present */ - }; - - static struct reset_ctl usbotg_reset; - --int board_usb_init(int index, enum usb_init_type init) -+/* STMicroelectronics STUSB1600 Type-C controller */ -+#define STUSB1600_CC_CONNECTION_STATUS 0x0E -+ -+/* STUSB1600_CC_CONNECTION_STATUS bitfields */ -+#define STUSB1600_CC_ATTACH BIT(0) -+ -+static int stusb1600_init(void) - { -+ struct udevice *dev, *bus; -+ ofnode node; -+ int ret; -+ u32 chip_addr; -+ -+ node = ofnode_by_compatible(ofnode_null(), "st,stusb1600"); -+ if (!ofnode_valid(node)) { -+ printf("stusb1600 not found\n"); -+ return -ENODEV; -+ } -+ -+ ret = ofnode_read_u32(node, "reg", &chip_addr); -+ if (ret) -+ return -EINVAL; -+ -+ ret = uclass_get_device_by_ofnode(UCLASS_I2C, ofnode_get_parent(node), -+ &bus); -+ if (ret) { -+ printf("bus for stusb1600 not found\n"); -+ return -ENODEV; -+ } -+ -+ ret = dm_i2c_probe(bus, chip_addr, 0, &dev); -+ if (!ret) -+ stm32mp_otg_data.priv = dev; -+ -+ return ret; -+} -+ -+static int stusb1600_cable_connected(void) -+{ -+ struct udevice *stusb1600_dev = stm32mp_otg_data.priv; -+ u8 status; -+ -+ if (dm_i2c_read(stusb1600_dev, -+ STUSB1600_CC_CONNECTION_STATUS, -+ &status, 1)) -+ return 0; -+ -+ return status & STUSB1600_CC_ATTACH; -+} -+ -+void board_usbotg_init(void) -+{ -+ int node; - struct fdtdec_phandle_args args; - struct udevice *dev; - const void *blob = gd->fdt_blob; - struct clk clk; -- struct phy phy; -- int node; -- int phy_provider; -- int ret; - - /* find the usb otg node */ - node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2"); - if (node < 0) { - debug("Not found usb_otg device\n"); -- return -ENODEV; -+ return; - } - - if (!fdtdec_get_is_enabled(blob, node)) { - debug("stm32 usbotg is disabled in the device tree\n"); -- return -ENODEV; -+ return; - } - - /* Enable clock */ -- ret = fdtdec_parse_phandle_with_args(blob, node, "clocks", -- "#clock-cells", 0, 0, &args); -- if (ret) { -+ if (fdtdec_parse_phandle_with_args(blob, node, "clocks", -+ "#clock-cells", 0, 0, &args)) { - debug("usbotg has no clocks defined in the device tree\n"); -- return ret; -+ return; - } - -- ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev); -- if (ret) -- return ret; -+ if (uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev)) -+ return; - -- if (args.args_count != 1) { -- debug("Can't find clock ID in the device tree\n"); -- return -ENODATA; -- } -+ if (args.args_count != 1) -+ return; - - clk.dev = dev; - clk.id = args.args[0]; - -- ret = clk_enable(&clk); -- if (ret) { -+ if (clk_enable(&clk)) { - debug("Failed to enable usbotg clock\n"); -- return ret; -+ return; - } - - /* Reset */ -- ret = fdtdec_parse_phandle_with_args(blob, node, "resets", -- "#reset-cells", 0, 0, &args); -- if (ret) { -+ if (fdtdec_parse_phandle_with_args(blob, node, "resets", -+ "#reset-cells", 0, 0, &args)) { - debug("usbotg has no resets defined in the device tree\n"); - goto clk_err; - } - -- ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev); -- if (ret || args.args_count != 1) -+ if ((uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev)) || -+ args.args_count != 1) - goto clk_err; - - usbotg_reset.dev = dev; - usbotg_reset.id = args.args[0]; - -- reset_assert(&usbotg_reset); -- udelay(2); -- reset_deassert(&usbotg_reset); -- -- /* Get USB PHY */ -- ret = fdtdec_parse_phandle_with_args(blob, node, "phys", -- "#phy-cells", 0, 0, &args); -- if (!ret) { -- phy_provider = fdt_parent_offset(blob, args.node); -- ret = uclass_get_device_by_of_offset(UCLASS_PHY, -- phy_provider, &dev); -- if (ret) -- goto clk_err; -- -- phy.dev = dev; -- phy.id = fdtdec_get_uint(blob, args.node, "reg", -1); -- -- ret = generic_phy_power_on(&phy); -- if (ret) { -- debug("unable to power on the phy\n"); -+ /* Phy */ -+ if (!(fdtdec_parse_phandle_with_args(blob, node, "phys", -+ "#phy-cells", 0, 0, &args))) { -+ stm32mp_otg_data.phy_of_node = -+ fdt_parent_offset(blob, args.node); -+ if (stm32mp_otg_data.phy_of_node <= 0) { -+ debug("Not found usbo phy device\n"); - goto clk_err; - } -- -- ret = generic_phy_init(&phy); -- if (ret) { -- debug("failed to init usb phy\n"); -- goto phy_power_err; -- } -+ stm32mp_otg_data.regs_phy = fdtdec_get_uint(blob, args.node, -+ "reg", -1); - } - - /* Parse and store data needed for gadget */ - stm32mp_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg"); - if (stm32mp_otg_data.regs_otg == FDT_ADDR_T_NONE) { - debug("usbotg: can't get base address\n"); -- ret = -ENODATA; -- goto phy_init_err; -+ goto clk_err; - } - - stm32mp_otg_data.rx_fifo_sz = fdtdec_get_int(blob, node, -@@ -140,59 +355,591 @@ int board_usb_init(int index, enum usb_init_type init) - "g-np-tx-fifo-size", 0); - stm32mp_otg_data.tx_fifo_sz = fdtdec_get_int(blob, node, - "g-tx-fifo-size", 0); -+ -+ if (fdtdec_get_bool(blob, node, "usb1600")) { -+ stusb1600_init(); -+ return; -+ } -+ - /* Enable voltage level detector */ - if (!(fdtdec_parse_phandle_with_args(blob, node, "usb33d-supply", -- NULL, 0, 0, &args))) { -+ NULL, 0, 0, &args))) - if (!uclass_get_device_by_of_offset(UCLASS_REGULATOR, -- args.node, &dev)) { -- ret = regulator_set_enable(dev, true); -- if (ret) { -+ args.node, &dev)) -+ if (regulator_set_enable(dev, true)) { - debug("Failed to enable usb33d\n"); -- goto phy_init_err; -+ goto clk_err; - } -- } -- } -- /* Enable vbus sensing */ -- setbits_le32(stm32mp_otg_data.regs_otg + STM32MP_GGPIO, -- STM32MP_GGPIO_VBUS_SENSING); -- -- return dwc2_udc_probe(&stm32mp_otg_data); - --phy_init_err: -- generic_phy_exit(&phy); -- --phy_power_err: -- generic_phy_power_off(&phy); -+ return; - - clk_err: - clk_disable(&clk); -- -- return ret; - } - --int board_usb_cleanup(int index, enum usb_init_type init) -+int board_usb_init(int index, enum usb_init_type init) - { -+ if (init == USB_INIT_HOST) -+ return 0; -+ -+ if (stm32mp_otg_data.regs_otg == FDT_ADDR_T_NONE) -+ return -EINVAL; -+ - /* Reset usbotg */ - reset_assert(&usbotg_reset); - udelay(2); - reset_deassert(&usbotg_reset); - -+ /* if the board embed an USB1600 chip */ -+ if (stm32mp_otg_data.priv) -+ /* Override A/B session valid bits */ -+ stm32mp_otg_data.usb_gotgctl = DWC2_GOTGCTL_AVALIDOVEN | -+ DWC2_GOTGCTL_AVALIDOVVAL | -+ DWC2_GOTGCTL_BVALIDOVEN | -+ DWC2_GOTGCTL_BVALIDOVVAL; -+ else -+ /* Enable vbus sensing */ -+ setbits_le32(stm32mp_otg_data.regs_otg + DWC2_GGPIO_OFFSET, -+ DWC2_GGPIO_VBUS_SENSING); -+ -+ return dwc2_udc_probe(&stm32mp_otg_data); -+} -+ -+int g_dnl_board_usb_cable_connected(void) -+{ -+ if (stm32mp_otg_data.priv) -+ return stusb1600_cable_connected(); -+ -+ return readl(stm32mp_otg_data.regs_otg + DWC2_GOTGCTL_OFFSET) & -+ DWC2_GOTGCTL_BSVLD; -+} -+ -+#define STM32MP1_G_DNL_DFU_PRODUCT_NUM 0xdf11 -+int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name) -+{ -+ if (!strcmp(name, "usb_dnl_dfu")) -+ put_unaligned(STM32MP1_G_DNL_DFU_PRODUCT_NUM, &dev->idProduct); -+ else -+ put_unaligned(CONFIG_USB_GADGET_PRODUCT_NUM, &dev->idProduct); -+ - return 0; - } -+#endif /* CONFIG_USB_GADGET */ - --int board_late_init(void) -+static void sysconf_init(void) - { -+ u8 *syscfg; -+#ifdef CONFIG_DM_REGULATOR -+ struct udevice *pwr_dev; -+ struct udevice *pwr_reg; -+ struct udevice *dev; -+ int ret; -+ u32 otp = 0; -+#endif -+ u32 bootr; -+ -+ syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); -+ debug("SYSCFG: init @0x%p\n", syscfg); -+ -+ /* interconnect update : select master using the port 1 */ -+ /* LTDC = AXI_M9 */ -+ /* GPU = AXI_M8 */ -+ /* today information is hardcoded in U-Boot */ -+ writel(BIT(9), syscfg + SYSCFG_ICNR); -+ debug("[0x%x] SYSCFG.icnr = 0x%08x (LTDC and GPU)\n", -+ (u32)syscfg + SYSCFG_ICNR, readl(syscfg + SYSCFG_ICNR)); -+ -+ /* disable Pull-Down for boot pin connected to VDD */ -+ bootr = readl(syscfg + SYSCFG_BOOTR); -+ bootr |= (bootr & 0x7 << 4); -+ writel(bootr, syscfg + SYSCFG_BOOTR); -+ debug("[0x%x] SYSCFG.bootr = 0x%08x\n", -+ (u32)syscfg + SYSCFG_BOOTR, readl(syscfg + SYSCFG_BOOTR)); -+ -+#ifdef CONFIG_DM_REGULATOR -+ /* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI -+ * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection. -+ * The customer will have to disable this for low frequencies -+ * or if AFMUX is selected but the function not used, typically for -+ * TRACE. Otherwise, impact on power consumption. -+ * -+ * WARNING: -+ * enabling High Speed mode while VDD>2.7V -+ * with the OTP product_below_2v5 (OTP 18, BIT 13) -+ * erroneously set to 1 can damage the IC! -+ * => U-Boot set the register only if VDD < 2.7V (in DT) -+ * but this value need to be consistent with board design -+ */ -+ ret = syscon_get_by_driver_data(STM32MP_SYSCON_PWR, &pwr_dev); -+ if (!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 = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4); -+ if (!ret) -+ otp = otp & BIT(13); -+ -+ /* get VDD = pwr-supply */ -+ ret = device_get_supply_regulator(pwr_dev, "pwr-supply", -+ &pwr_reg); -+ -+ /* check if VDD is Low Voltage */ -+ if (!ret) { -+ if (regulator_get_value(pwr_reg) < 2700000) { -+ writel(SYSCFG_IOCTRLSETR_HSLVEN_TRACE | -+ SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI | -+ SYSCFG_IOCTRLSETR_HSLVEN_ETH | -+ SYSCFG_IOCTRLSETR_HSLVEN_SDMMC | -+ SYSCFG_IOCTRLSETR_HSLVEN_SPI, -+ syscfg + SYSCFG_IOCTRLSETR); -+ -+ if (!otp) -+ pr_err("product_below_2v5=0: HSLVEN protected by HW\n"); -+ } else { -+ if (otp) -+ pr_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n"); -+ } -+ } else { -+ debug("VDD unknown"); -+ } -+ } -+#endif -+ debug("[0x%x] SYSCFG.IOCTRLSETR = 0x%08x\n", -+ (u32)syscfg + SYSCFG_IOCTRLSETR, -+ readl(syscfg + SYSCFG_IOCTRLSETR)); -+ -+ /* activate automatic I/O compensation -+ * warning: need to ensure CSI enabled and ready in clock driver -+ */ -+ writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR); -+ -+ while (!(readl(syscfg + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY)) -+ ; -+ clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); -+ -+ debug("[0x%x] SYSCFG.cmpcr = 0x%08x\n", -+ (u32)syscfg + SYSCFG_CMPCR, readl(syscfg + SYSCFG_CMPCR)); -+} -+ -+/* board interface eth init */ -+/* this is a weak define that we are overriding */ -+int board_interface_eth_init(int interface_type, bool eth_clk_sel_reg, -+ bool eth_ref_clk_sel_reg) -+{ -+ u8 *syscfg; -+ u32 value; -+ -+ syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); -+ -+ if (!syscfg) -+ return -ENODEV; -+ -+ switch (interface_type) { -+ case PHY_INTERFACE_MODE_MII: -+ value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | -+ SYSCFG_PMCSETR_ETH_REF_CLK_SEL; -+ debug("%s: PHY_INTERFACE_MODE_MII\n", __func__); -+ 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; -+ debug("%s: PHY_INTERFACE_MODE_GMII\n", __func__); -+ 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; -+ debug("%s: PHY_INTERFACE_MODE_RMII\n", __func__); -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ if (eth_clk_sel_reg) -+ value = SYSCFG_PMCSETR_ETH_SEL_RGMII | -+ SYSCFG_PMCSETR_ETH_CLK_SEL; -+ else -+ value = SYSCFG_PMCSETR_ETH_SEL_RGMII; -+ debug("%s: PHY_INTERFACE_MODE_RGMII\n", __func__); -+ break; -+ default: -+ debug("%s: Do not manage %d interface\n", -+ __func__, interface_type); -+ /* Do not manage others interfaces */ -+ 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); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_LED -+static int get_led(struct udevice **dev, char *led_string) -+{ -+ char *led_name; -+ int ret; -+ -+ led_name = fdtdec_get_config_string(gd->fdt_blob, led_string); -+ if (!led_name) { -+ pr_debug("%s: could not find %s config string\n", -+ __func__, led_string); -+ return -ENOENT; -+ } -+ ret = led_get_by_label(led_name, dev); -+ if (ret) { -+ debug("%s: get=%d\n", __func__, ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int setup_led(enum led_state_t cmd) -+{ -+ struct udevice *dev; -+ int ret; -+ -+ ret = get_led(&dev, "u-boot,boot-led"); -+ if (ret) -+ return ret; -+ -+ ret = led_set_state(dev, cmd); -+ return ret; -+} -+#endif /* CONFIG_LED */ -+ -+#ifdef CONFIG_ADC -+static int board_check_usb_power(void) -+{ -+ struct ofnode_phandle_args adc_args; -+ struct udevice *adc; -+ struct udevice *led; -+ ofnode node; -+ unsigned int raw; -+ int max_uV = 0; -+ int ret, uV, adc_count; -+ u8 i, nb_blink; -+ -+ 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; -+ } -+ -+ for (i = 0; i < adc_count; i++) { -+ if (ofnode_parse_phandle_with_args(node, "st,adc_usb_pd", -+ "#io-channel-cells", 0, i, -+ &adc_args)) { -+ pr_debug("%s: can't find /config/st,adc_usb_pd\n", -+ __func__); -+ return 0; -+ } -+ -+ ret = uclass_get_device_by_ofnode(UCLASS_ADC, adc_args.node, -+ &adc); -+ -+ if (ret) { -+ pr_err("%s: Can't get adc device(%d)\n", __func__, -+ ret); -+ return ret; -+ } -+ -+ ret = adc_channel_single_shot(adc->name, adc_args.args[0], -+ &raw); -+ if (ret) { -+ pr_err("%s: single shot failed for %s[%d]!\n", -+ __func__, adc->name, adc_args.args[0]); -+ return ret; -+ } -+ /* Convert to uV */ -+ if (!adc_raw_to_uV(adc, raw, &uV)) { -+ if (uV > max_uV) -+ max_uV = uV; -+ pr_debug("%s: %s[%02d] = %u, %d uV\n", __func__, -+ adc->name, adc_args.args[0], raw, uV); -+ } else { -+ pr_err("%s: Can't get uV value for %s[%d]\n", -+ __func__, adc->name, adc_args.args[0]); -+ } -+ } -+ -+ /* -+ * 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) -+ return 0; -+ -+ /* Stop boot process and make u-boot,error-led blinking */ -+ pr_err("\n*******************************************\n"); -+ -+ if (max_uV < USB_WARNING_LOW_THRESHOLD_UV) { -+ pr_err("* WARNING 500mA power supply detected *\n"); -+ nb_blink = 2; -+ } else { -+ pr_err("* WARNING 1.5A power supply detected *\n"); -+ nb_blink = 3; -+ } -+ -+ pr_err("* Current too low, use a 3A power supply! *\n"); -+ pr_err("*******************************************\n\n"); -+ -+ ret = get_led(&led, "u-boot,error-led"); -+ if (ret) -+ return ret; -+ -+ for (i = 0; i < nb_blink * 2; i++) { -+ led_set_state(led, LEDST_TOGGLE); -+ mdelay(125); -+ } -+ led_set_state(led, LEDST_ON); -+ - return 0; - } -+#endif /* CONFIG_ADC */ -+ -+#ifdef CONFIG_DM_REGULATOR -+/* Fix to make I2C1 usable on DK2 for touchscreen usage in kernel */ -+static int dk2_i2c1_fix(void) -+{ -+ ofnode node; -+ struct gpio_desc hdmi, audio; -+ int ret = 0; -+ -+ node = ofnode_path("/soc/i2c@40012000/hdmi-transmitter@39"); -+ if (!ofnode_valid(node)) { -+ pr_debug("%s: no hdmi-transmitter@39 ?\n", __func__); -+ return -ENOENT; -+ } -+ -+ if (gpio_request_by_name_nodev(node, "reset-gpios", 0, -+ &hdmi, GPIOD_IS_OUT)) { -+ pr_debug("%s: could not find reset-gpios\n", -+ __func__); -+ return -ENOENT; -+ } -+ -+ node = ofnode_path("/soc/i2c@40012000/cs42l51@4a"); -+ if (!ofnode_valid(node)) { -+ pr_debug("%s: no cs42l51@4a ?\n", __func__); -+ return -ENOENT; -+ } -+ -+ if (gpio_request_by_name_nodev(node, "reset-gpios", 0, -+ &audio, GPIOD_IS_OUT)) { -+ pr_debug("%s: could not find reset-gpios\n", -+ __func__); -+ return -ENOENT; -+ } -+ -+ /* before power up, insure that HDMI anh AUDIO IC is under reset */ -+ ret = dm_gpio_set_value(&hdmi, 1); -+ if (ret) { -+ pr_err("%s: can't set_value for hdmi_nrst gpio", __func__); -+ goto error; -+ } -+ ret = dm_gpio_set_value(&audio, 1); -+ if (ret) { -+ pr_err("%s: can't set_value for audio_nrst gpio", __func__); -+ goto error; -+ } -+ -+ /* power-up audio IC */ -+ regulator_autoset_by_name("v1v8_audio", NULL); -+ -+ /* power-up HDMI IC */ -+ regulator_autoset_by_name("v1v2_hdmi", NULL); -+ regulator_autoset_by_name("v3v3_hdmi", NULL); -+ -+error: -+ return ret; -+} -+#endif - - /* board dependent setup after realloc */ - int board_init(void) - { -+ struct udevice *dev; -+ - /* address of boot parameters */ - gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100; - -+ /* probe all PINCTRL for hog */ -+ for (uclass_first_device(UCLASS_PINCTRL, &dev); -+ dev; -+ uclass_next_device(&dev)) { -+ pr_debug("probe pincontrol = %s\n", dev->name); -+ } -+ -+ board_key_check(); -+ - if (IS_ENABLED(CONFIG_LED)) - led_default_state(); - -+#ifdef CONFIG_DM_REGULATOR -+ if (board_is_dk2()) -+ dk2_i2c1_fix(); -+ -+ regulators_enable_boot_on(_DEBUG); -+#endif -+ -+#ifdef CONFIG_ADC -+ board_check_usb_power(); -+#endif /* CONFIG_ADC */ -+ -+ sysconf_init(); -+ -+#ifdef CONFIG_STM32_SDMMC2 -+ board_mmc_init(); -+#endif /* CONFIG_STM32_SDMMC2 */ -+ -+#ifdef CONFIG_STM32_QSPI -+ board_qspi_init(); -+#endif /* CONFIG_STM32_QSPI */ -+ -+#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) -+ board_usbotg_init(); -+#endif -+ -+ return 0; -+} -+ -+void board_quiesce_devices(void) -+{ -+#ifdef CONFIG_LED -+ setup_led(LEDST_OFF); -+#endif -+} -+ -+#ifdef CONFIG_SYS_MTDPARTS_RUNTIME -+void board_mtdparts_default(const char **mtdids, const char **mtdparts) -+{ -+ struct udevice *dev; -+ char *s_nand0 = NULL, *s_nor0 = NULL; -+ static char parts[256]; -+ static char ids[22]; -+ -+ if (!uclass_get_device(UCLASS_MTD, 0, &dev)) -+ s_nand0 = env_get("mtdparts_nand0"); -+ -+ if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) -+ s_nor0 = env_get("mtdparts_nor0"); -+ -+ strcpy(ids, ""); -+ strcpy(parts, ""); -+ if (s_nand0 && s_nor0) { -+ snprintf(ids, sizeof(ids), "nor0=nor0,nand0=nand0"); -+ snprintf(parts, sizeof(parts), -+ "mtdparts=nor0:%s;nand0:%s", s_nor0, s_nand0); -+ } else if (s_nand0) { -+ snprintf(ids, sizeof(ids), "nand0=nand0"); -+ snprintf(parts, sizeof(parts), "mtdparts=nand0:%s", s_nand0); -+ } else if (s_nor0) { -+ snprintf(ids, sizeof(ids), "nor0=nor0"); -+ snprintf(parts, sizeof(parts), "mtdparts=nor0:%s", s_nor0); -+ } -+ *mtdids = ids; -+ *mtdparts = parts; -+ debug("%s:mtdids=%s & mtdparts=%s\n", __func__, ids, parts); -+} -+#endif -+ -+#if defined(CONFIG_OF_BOARD_SETUP) -+int ft_board_setup(void *blob, bd_t *bd) -+{ -+ ulong copro_rsc_addr, copro_rsc_size; -+ int off; -+ char *s_copro = NULL; -+#ifdef CONFIG_FDT_FIXUP_PARTITIONS -+ struct node_info nodes[] = { -+ { "st,stm32f469-qspi", MTD_DEV_TYPE_NOR, }, -+ { "st,stm32mp15-fmc2", MTD_DEV_TYPE_NAND, }, -+ }; -+ fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); -+#endif -+ -+ /* Update DT if coprocessor started */ -+ off = fdt_path_offset(blob, "/m4"); -+ if (off > 0) { -+ s_copro = env_get("copro_state"); -+ copro_rsc_addr = env_get_hex("copro_rsc_addr", 0); -+ copro_rsc_size = env_get_hex("copro_rsc_size", 0); -+ -+ if (s_copro) { -+ fdt_setprop_empty(blob, off, "early-booted"); -+ if (copro_rsc_addr) -+ fdt_setprop_u32(blob, off, "rsc-address", -+ copro_rsc_addr); -+ if (copro_rsc_size) -+ fdt_setprop_u32(blob, off, "rsc-size", -+ copro_rsc_size); -+ } else { -+ fdt_delprop(blob, off, "early-booted"); -+ } -+ } -+ - return 0; - } -+#endif -+ -+void board_stm32copro_image_process(ulong fw_image, size_t fw_size) -+{ -+ int ret, id = 0; /* Copro id fixed to 0 as only one coproc on mp1 */ -+ unsigned int rsc_size; -+ ulong rsc_addr; -+ -+ if (!rproc_is_initialized()) -+ if (rproc_init()) { -+ printf("Remote Processor %d initialization failed\n", -+ id); -+ return; -+ } -+ -+ ret = rproc_load_rsc_table(id, fw_image, fw_size, &rsc_addr, &rsc_size); -+ if (!ret) { -+ env_set_hex("copro_rsc_addr", rsc_addr); -+ env_set_hex("copro_rsc_size", rsc_size); -+ } -+ -+ ret = rproc_load(id, fw_image, fw_size); -+ printf("Load Remote Processor %d with data@addr=0x%08lx %u bytes:%s\n", -+ id, fw_image, fw_size, ret ? " Failed!" : " Success!"); -+ -+ if (!ret) { -+ rproc_start(id); -+ env_set("copro_state", "booted"); -+ } -+} -+ -+U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_STM32COPRO, board_stm32copro_image_process); --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0002-ARM-v2020.01-stm32mp-r1-BOARD.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0002-ARM-v2020.01-stm32mp-r1-BOARD.patch new file mode 100644 index 0000000..a3d5c11 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0002-ARM-v2020.01-stm32mp-r1-BOARD.patch @@ -0,0 +1,3450 @@ +From 44c04ad9a03583c1508393fcfd7a640b6521473a Mon Sep 17 00:00:00 2001 +From: Romuald JEANNE +Date: Fri, 5 Jun 2020 13:43:23 +0200 +Subject: [PATCH 2/5] ARM v2020.01-stm32mp-r1 BOARD + +--- + board/dhelectronics/dh_stm32mp1/Kconfig | 22 + + board/dhelectronics/dh_stm32mp1/MAINTAINERS | 7 + + board/dhelectronics/dh_stm32mp1/Makefile | 13 + + board/dhelectronics/dh_stm32mp1/board.c | 547 ++++++++++++++++++++++++ + board/st/common/Kconfig | 71 ++++ + board/st/common/MAINTAINERS | 6 + + board/st/common/Makefile | 11 + + board/st/common/cmd_stboard.c | 176 ++++++++ + board/st/common/stm32mp_dfu.c | 245 +++++++++++ + board/st/common/stm32mp_mtdparts.c | 167 ++++++++ + board/st/stm32mp1/Kconfig | 20 +- + board/st/stm32mp1/MAINTAINERS | 1 - + board/st/stm32mp1/Makefile | 1 - + board/st/stm32mp1/README | 504 +--------------------- + board/st/stm32mp1/board.c | 57 ++- + board/st/stm32mp1/cmd_stboard.c | 145 ------- + board/st/stm32mp1/stm32mp1.c | 426 +++++++------------ + board/sunxi/board.c | 2 +- + doc/board/index.rst | 1 + + doc/board/st/index.rst | 9 + + doc/board/st/stm32mp1.rst | 624 ++++++++++++++++++++++++++++ + 21 files changed, 2103 insertions(+), 952 deletions(-) + create mode 100644 board/dhelectronics/dh_stm32mp1/Kconfig + create mode 100644 board/dhelectronics/dh_stm32mp1/MAINTAINERS + create mode 100644 board/dhelectronics/dh_stm32mp1/Makefile + create mode 100644 board/dhelectronics/dh_stm32mp1/board.c + create mode 100644 board/st/common/Kconfig + create mode 100644 board/st/common/MAINTAINERS + create mode 100644 board/st/common/Makefile + create mode 100644 board/st/common/cmd_stboard.c + create mode 100644 board/st/common/stm32mp_dfu.c + create mode 100644 board/st/common/stm32mp_mtdparts.c + delete mode 100644 board/st/stm32mp1/cmd_stboard.c + create mode 100644 doc/board/st/index.rst + create mode 100644 doc/board/st/stm32mp1.rst + +diff --git a/board/dhelectronics/dh_stm32mp1/Kconfig b/board/dhelectronics/dh_stm32mp1/Kconfig +new file mode 100644 +index 0000000..69cc48f +--- /dev/null ++++ b/board/dhelectronics/dh_stm32mp1/Kconfig +@@ -0,0 +1,22 @@ ++if TARGET_DH_STM32MP1_PDK2 ++ ++config SYS_BOARD ++ default "dh_stm32mp1" ++ ++config SYS_VENDOR ++ default "dhelectronics" ++ ++config SYS_CONFIG_NAME ++ default "stm32mp1" ++ ++config ENV_SECT_SIZE ++ default 0x10000 if ENV_IS_IN_SPI_FLASH ++ ++config ENV_OFFSET ++ default 0x1E0000 if ENV_IS_IN_SPI_FLASH ++ ++config ENV_OFFSET_REDUND ++ default 0x1F0000 if ENV_IS_IN_SPI_FLASH ++ ++source "board/st/common/Kconfig" ++endif +diff --git a/board/dhelectronics/dh_stm32mp1/MAINTAINERS b/board/dhelectronics/dh_stm32mp1/MAINTAINERS +new file mode 100644 +index 0000000..1511ecb +--- /dev/null ++++ b/board/dhelectronics/dh_stm32mp1/MAINTAINERS +@@ -0,0 +1,7 @@ ++DH_STM32MP1_PDK2 BOARD ++M: Marek Vasut ++S: Maintained ++F: arch/arm/dts/stm32mp15xx-dhcom* ++F: board/dhelectronics/dh_stm32mp1/ ++F: configs/stm32mp15_dhcom_basic_defconfig ++F: include/configs/stm32mp1.h +diff --git a/board/dhelectronics/dh_stm32mp1/Makefile b/board/dhelectronics/dh_stm32mp1/Makefile +new file mode 100644 +index 0000000..e8f218d +--- /dev/null ++++ b/board/dhelectronics/dh_stm32mp1/Makefile +@@ -0,0 +1,13 @@ ++# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++# ++# Copyright (C) 2018, STMicroelectronics - All Rights Reserved ++# ++ ++ifdef CONFIG_SPL_BUILD ++obj-y += ../../st/stm32mp1/spl.o ++endif ++ ++obj-y += ../../st/stm32mp1/board.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 +new file mode 100644 +index 0000000..53325e8 +--- /dev/null ++++ b/board/dhelectronics/dh_stm32mp1/board.c +@@ -0,0 +1,547 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* SYSCFG registers */ ++#define SYSCFG_BOOTR 0x00 ++#define SYSCFG_PMCSETR 0x04 ++#define SYSCFG_IOCTRLSETR 0x18 ++#define SYSCFG_ICNR 0x1C ++#define SYSCFG_CMPCR 0x20 ++#define SYSCFG_CMPENSETR 0x24 ++#define SYSCFG_PMCCLRR 0x44 ++ ++#define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0) ++#define SYSCFG_BOOTR_BOOTPD_SHIFT 4 ++ ++#define SYSCFG_IOCTRLSETR_HSLVEN_TRACE BIT(0) ++#define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI BIT(1) ++#define SYSCFG_IOCTRLSETR_HSLVEN_ETH BIT(2) ++#define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC BIT(3) ++#define SYSCFG_IOCTRLSETR_HSLVEN_SPI BIT(4) ++ ++#define SYSCFG_CMPCR_SW_CTRL BIT(1) ++#define SYSCFG_CMPCR_READY BIT(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) ++ ++/* ++ * Get a global data pointer ++ */ ++DECLARE_GLOBAL_DATA_PTR; ++ ++int setup_mac_address(void) ++{ ++ struct udevice *dev; ++ ofnode eeprom; ++ unsigned char enetaddr[6]; ++ int ret; ++ ++ ret = eth_env_get_enetaddr("ethaddr", enetaddr); ++ if (ret) /* ethaddr is already set */ ++ return 0; ++ ++ eeprom = ofnode_path("/soc/i2c@5c002000/eeprom@50"); ++ if (!ofnode_valid(eeprom)) { ++ printf("Invalid hardware path to EEPROM!\n"); ++ return -ENODEV; ++ } ++ ++ ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, eeprom, &dev); ++ if (ret) { ++ printf("Cannot find EEPROM!\n"); ++ return ret; ++ } ++ ++ ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6); ++ if (ret) { ++ printf("Error reading configuration EEPROM!\n"); ++ return ret; ++ } ++ ++ if (is_valid_ethaddr(enetaddr)) ++ eth_env_set_enetaddr("ethaddr", enetaddr); ++ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ char *mode; ++ const char *fdt_compat; ++ int fdt_compat_len; ++ ++ if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED)) ++ mode = "trusted"; ++ else ++ mode = "basic"; ++ ++ printf("Board: stm32mp1 in %s mode", mode); ++ fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible", ++ &fdt_compat_len); ++ if (fdt_compat && fdt_compat_len) ++ printf(" (%s)", fdt_compat); ++ puts("\n"); ++ ++ return 0; ++} ++ ++static void board_key_check(void) ++{ ++#if defined(CONFIG_FASTBOOT) || defined(CONFIG_CMD_STM32PROG) ++ ofnode node; ++ struct gpio_desc gpio; ++ enum forced_boot_mode boot_mode = BOOT_NORMAL; ++ ++ node = ofnode_path("/config"); ++ if (!ofnode_valid(node)) { ++ debug("%s: no /config node?\n", __func__); ++ return; ++ } ++#ifdef CONFIG_FASTBOOT ++ if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0, ++ &gpio, GPIOD_IS_IN)) { ++ debug("%s: could not find a /config/st,fastboot-gpios\n", ++ __func__); ++ } else { ++ if (dm_gpio_get_value(&gpio)) { ++ puts("Fastboot key pressed, "); ++ boot_mode = BOOT_FASTBOOT; ++ } ++ ++ dm_gpio_free(NULL, &gpio); ++ } ++#endif ++#ifdef CONFIG_CMD_STM32PROG ++ if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0, ++ &gpio, GPIOD_IS_IN)) { ++ debug("%s: could not find a /config/st,stm32prog-gpios\n", ++ __func__); ++ } else { ++ if (dm_gpio_get_value(&gpio)) { ++ puts("STM32Programmer key pressed, "); ++ boot_mode = BOOT_STM32PROG; ++ } ++ dm_gpio_free(NULL, &gpio); ++ } ++#endif ++ ++ if (boot_mode != BOOT_NORMAL) { ++ puts("entering download mode...\n"); ++ clrsetbits_le32(TAMP_BOOT_CONTEXT, ++ TAMP_BOOT_FORCED_MASK, ++ boot_mode); ++ } ++#endif ++} ++ ++#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) ++ ++#include ++int g_dnl_board_usb_cable_connected(void) ++{ ++ struct udevice *dwc2_udc_otg; ++ int ret; ++ ++ ret = uclass_get_device_by_driver(UCLASS_USB_GADGET_GENERIC, ++ DM_GET_DRIVER(dwc2_udc_otg), ++ &dwc2_udc_otg); ++ if (!ret) ++ debug("dwc2_udc_otg init failed\n"); ++ ++ return dwc2_udc_B_session_valid(dwc2_udc_otg); ++} ++ ++#define STM32MP1_G_DNL_DFU_PRODUCT_NUM 0xdf11 ++#define STM32MP1_G_DNL_FASTBOOT_PRODUCT_NUM 0x0afb ++ ++int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name) ++{ ++ if (!strcmp(name, "usb_dnl_dfu")) ++ put_unaligned(STM32MP1_G_DNL_DFU_PRODUCT_NUM, &dev->idProduct); ++ else if (!strcmp(name, "usb_dnl_fastboot")) ++ put_unaligned(STM32MP1_G_DNL_FASTBOOT_PRODUCT_NUM, ++ &dev->idProduct); ++ else ++ put_unaligned(CONFIG_USB_GADGET_PRODUCT_NUM, &dev->idProduct); ++ ++ return 0; ++} ++ ++#endif /* CONFIG_USB_GADGET */ ++ ++#ifdef CONFIG_LED ++static int get_led(struct udevice **dev, char *led_string) ++{ ++ char *led_name; ++ int ret; ++ ++ led_name = fdtdec_get_config_string(gd->fdt_blob, led_string); ++ if (!led_name) { ++ pr_debug("%s: could not find %s config string\n", ++ __func__, led_string); ++ return -ENOENT; ++ } ++ ret = led_get_by_label(led_name, dev); ++ if (ret) { ++ debug("%s: get=%d\n", __func__, ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int setup_led(enum led_state_t cmd) ++{ ++ struct udevice *dev; ++ int ret; ++ ++ ret = get_led(&dev, "u-boot,boot-led"); ++ if (ret) ++ return ret; ++ ++ ret = led_set_state(dev, cmd); ++ return ret; ++} ++#endif ++ ++static void __maybe_unused led_error_blink(u32 nb_blink) ++{ ++#ifdef CONFIG_LED ++ int ret; ++ struct udevice *led; ++ u32 i; ++#endif ++ ++ if (!nb_blink) ++ return; ++ ++#ifdef CONFIG_LED ++ ret = get_led(&led, "u-boot,error-led"); ++ if (!ret) { ++ /* make u-boot,error-led blinking */ ++ /* if U32_MAX and 125ms interval, for 17.02 years */ ++ for (i = 0; i < 2 * nb_blink; i++) { ++ led_set_state(led, LEDST_TOGGLE); ++ mdelay(125); ++ WATCHDOG_RESET(); ++ } ++ } ++#endif ++ ++ /* infinite: the boot process must be stopped */ ++ if (nb_blink == U32_MAX) ++ hang(); ++} ++ ++static void sysconf_init(void) ++{ ++#ifndef CONFIG_STM32MP1_TRUSTED ++ u8 *syscfg; ++#ifdef CONFIG_DM_REGULATOR ++ struct udevice *pwr_dev; ++ struct udevice *pwr_reg; ++ struct udevice *dev; ++ int ret; ++ u32 otp = 0; ++#endif ++ u32 bootr; ++ ++ syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); ++ ++ /* interconnect update : select master using the port 1 */ ++ /* LTDC = AXI_M9 */ ++ /* GPU = AXI_M8 */ ++ /* today information is hardcoded in U-Boot */ ++ writel(BIT(9), syscfg + SYSCFG_ICNR); ++ ++ /* disable Pull-Down for boot pin connected to VDD */ ++ bootr = readl(syscfg + SYSCFG_BOOTR); ++ bootr &= ~(SYSCFG_BOOTR_BOOT_MASK << SYSCFG_BOOTR_BOOTPD_SHIFT); ++ bootr |= (bootr & SYSCFG_BOOTR_BOOT_MASK) << SYSCFG_BOOTR_BOOTPD_SHIFT; ++ writel(bootr, syscfg + SYSCFG_BOOTR); ++ ++#ifdef CONFIG_DM_REGULATOR ++ /* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI ++ * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection. ++ * The customer will have to disable this for low frequencies ++ * or if AFMUX is selected but the function not used, typically for ++ * TRACE. Otherwise, impact on power consumption. ++ * ++ * WARNING: ++ * enabling High Speed mode while VDD>2.7V ++ * with the OTP product_below_2v5 (OTP 18, BIT 13) ++ * erroneously set to 1 can damage the IC! ++ * => U-Boot set the register only if VDD < 2.7V (in DT) ++ * but this value need to be consistent with board design ++ */ ++ ret = uclass_get_device_by_driver(UCLASS_PMIC, ++ DM_GET_DRIVER(stm32mp_pwr_pmic), ++ &pwr_dev); ++ if (!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 = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4); ++ if (ret > 0) ++ otp = otp & BIT(13); ++ ++ /* get VDD = vdd-supply */ ++ ret = device_get_supply_regulator(pwr_dev, "vdd-supply", ++ &pwr_reg); ++ ++ /* check if VDD is Low Voltage */ ++ if (!ret) { ++ if (regulator_get_value(pwr_reg) < 2700000) { ++ writel(SYSCFG_IOCTRLSETR_HSLVEN_TRACE | ++ SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI | ++ SYSCFG_IOCTRLSETR_HSLVEN_ETH | ++ SYSCFG_IOCTRLSETR_HSLVEN_SDMMC | ++ SYSCFG_IOCTRLSETR_HSLVEN_SPI, ++ syscfg + SYSCFG_IOCTRLSETR); ++ ++ if (!otp) ++ pr_err("product_below_2v5=0: HSLVEN protected by HW\n"); ++ } else { ++ if (otp) ++ pr_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n"); ++ } ++ } else { ++ debug("VDD unknown"); ++ } ++ } ++#endif ++ ++ /* activate automatic I/O compensation ++ * warning: need to ensure CSI enabled and ready in clock driver ++ */ ++ writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR); ++ ++ while (!(readl(syscfg + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY)) ++ ; ++ clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); ++#endif ++} ++ ++/* board dependent setup after realloc */ ++int board_init(void) ++{ ++ struct udevice *dev; ++ ++ /* address of boot parameters */ ++ gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100; ++ ++ /* probe all PINCTRL for hog */ ++ for (uclass_first_device(UCLASS_PINCTRL, &dev); ++ dev; ++ uclass_next_device(&dev)) { ++ pr_debug("probe pincontrol = %s\n", dev->name); ++ } ++ ++ board_key_check(); ++ ++#ifdef CONFIG_DM_REGULATOR ++ regulators_enable_boot_on(_DEBUG); ++#endif ++ ++ sysconf_init(); ++ ++ if (CONFIG_IS_ENABLED(LED)) ++ led_default_state(); ++ ++ return 0; ++} ++ ++int board_late_init(void) ++{ ++ char *boot_device; ++#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG ++ const void *fdt_compat; ++ int fdt_compat_len; ++ ++ fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible", ++ &fdt_compat_len); ++ if (fdt_compat && fdt_compat_len) { ++ if (strncmp(fdt_compat, "st,", 3) != 0) ++ env_set("board_name", fdt_compat); ++ else ++ env_set("board_name", fdt_compat + 3); ++ } ++#endif ++ ++ /* Check the boot-source to disable bootdelay */ ++ boot_device = env_get("boot_device"); ++ if (!strcmp(boot_device, "serial") || !strcmp(boot_device, "usb")) ++ env_set("bootdelay", "0"); ++ ++ return 0; ++} ++ ++void board_quiesce_devices(void) ++{ ++#ifdef CONFIG_LED ++ setup_led(LEDST_OFF); ++#endif ++} ++ ++/* eth init function : weak called in eqos driver */ ++int board_interface_eth_init(struct udevice *dev, ++ phy_interface_t interface_type) ++{ ++ u8 *syscfg; ++ u32 value; ++ bool eth_clk_sel_reg = false; ++ bool eth_ref_clk_sel_reg = false; ++ ++ /* 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"); ++ ++ syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); ++ ++ if (!syscfg) ++ return -ENODEV; ++ ++ switch (interface_type) { ++ case PHY_INTERFACE_MODE_MII: ++ value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | ++ SYSCFG_PMCSETR_ETH_REF_CLK_SEL; ++ debug("%s: PHY_INTERFACE_MODE_MII\n", __func__); ++ 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; ++ debug("%s: PHY_INTERFACE_MODE_GMII\n", __func__); ++ 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; ++ debug("%s: PHY_INTERFACE_MODE_RMII\n", __func__); ++ 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; ++ debug("%s: PHY_INTERFACE_MODE_RGMII\n", __func__); ++ break; ++ default: ++ debug("%s: Do not manage %d interface\n", ++ __func__, interface_type); ++ /* Do not manage others interfaces */ ++ 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); ++ ++ return 0; ++} ++ ++enum env_location env_get_location(enum env_operation op, int prio) ++{ ++ if (prio) ++ return ENVL_UNKNOWN; ++ ++#ifdef CONFIG_ENV_IS_IN_SPI_FLASH ++ return ENVL_SPI_FLASH; ++#else ++ return ENVL_NOWHERE; ++#endif ++} ++ ++#if defined(CONFIG_OF_BOARD_SETUP) ++int ft_board_setup(void *blob, bd_t *bd) ++{ ++ return 0; ++} ++#endif ++ ++static void board_copro_image_process(ulong fw_image, size_t fw_size) ++{ ++ int ret, id = 0; /* Copro id fixed to 0 as only one coproc on mp1 */ ++ ++ if (!rproc_is_initialized()) ++ if (rproc_init()) { ++ printf("Remote Processor %d initialization failed\n", ++ id); ++ return; ++ } ++ ++ ret = rproc_load(id, fw_image, fw_size); ++ printf("Load Remote Processor %d with data@addr=0x%08lx %u bytes:%s\n", ++ id, fw_image, fw_size, ret ? " Failed!" : " Success!"); ++ ++ if (!ret) { ++ rproc_start(id); ++ env_set("copro_state", "booted"); ++ } ++} ++ ++U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process); +diff --git a/board/st/common/Kconfig b/board/st/common/Kconfig +new file mode 100644 +index 0000000..750dbb6 +--- /dev/null ++++ b/board/st/common/Kconfig +@@ -0,0 +1,71 @@ ++config CMD_STBOARD ++ bool "stboard - command for OTP board information" ++ depends on ARCH_STM32MP ++ default y if TARGET_ST_STM32MP15x ++ help ++ This compile the stboard command to ++ read and write the board in the OTP. ++ ++config MTDPARTS_NAND0_BOOT ++ string "mtd boot partitions for nand0" ++ default "2m(fsbl),2m(ssbl1),2m(ssbl2)" ++ 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. ++ ++config MTDPARTS_NAND0_TEE ++ string "mtd tee partitions for nand0" ++ default "512k(teeh),512k(teed),512k(teex)" ++ depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP ++ help ++ This define the tee partitions added in mtparts dynamically ++ when tee is supported with 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. ++ ++config MTDPARTS_NOR0_BOOT ++ string "mtd boot partitions for nor0" ++ default "256k(fsbl1),256k(fsbl2),2m(ssbl),512k(u-boot-env)" ++ depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP ++ help ++ This define the partitions of nand0 used to build mtparts dynamically ++ for boot from nor0. ++ Each partition need to be aligned with the device erase block size, ++ with 256KB we support all the NOR. ++ U-Boot env partition (512kB) use 2 erase block for redundancy. ++ ++config MTDPARTS_NOR0_TEE ++ string "mtd tee partitions for nor0" ++ default "256k(teeh),512k(teed),256k(teex)" ++ depends on SYS_MTDPARTS_RUNTIME && ARCH_STM32MP ++ 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)" ++ 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. ++ ++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 ++ help ++ This define the tee partitions added in mtparts dynamically ++ when tee is supported with boot from spi-nand0, ++ 512KB is the max size for the NAND supported by stm32mp1 platform. ++ ++config DFU_ALT_RAM0 ++ string "dfu for ram0" ++ default "uImage ram 0xc2000000 0x2000000;devicetree.dtb ram 0xc4000000 0x100000;uramdisk.image.gz ram 0xc4400000 0x10000000" ++ depends on ARCH_STM32MP && SET_DFU_ALT_INFO ++ help ++ This defines the partitions of ram used to build dfu dynamically. +diff --git a/board/st/common/MAINTAINERS b/board/st/common/MAINTAINERS +new file mode 100644 +index 0000000..3b02f4a +--- /dev/null ++++ b/board/st/common/MAINTAINERS +@@ -0,0 +1,6 @@ ++ST BOARDS ++M: Patrick Delaunay ++L: uboot-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers) ++T: git https://gitlab.denx.de/u-boot/custodians/u-boot-stm.git ++S: Maintained ++F: board/st/common/ +diff --git a/board/st/common/Makefile b/board/st/common/Makefile +new file mode 100644 +index 0000000..aa030bac +--- /dev/null ++++ b/board/st/common/Makefile +@@ -0,0 +1,11 @@ ++# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++# ++# Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++# ++ ++obj-$(CONFIG_CMD_STBOARD) += cmd_stboard.o ++ ++ifeq ($(CONFIG_ARCH_STM32MP),y) ++obj-$(CONFIG_SYS_MTDPARTS_RUNTIME) += stm32mp_mtdparts.o ++obj-$(CONFIG_SET_DFU_ALT_INFO) += stm32mp_dfu.o ++endif +diff --git a/board/st/common/cmd_stboard.c b/board/st/common/cmd_stboard.c +new file mode 100644 +index 0000000..3ead1ed +--- /dev/null ++++ b/board/st/common/cmd_stboard.c +@@ -0,0 +1,176 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved ++ */ ++ ++#ifndef CONFIG_SPL_BUILD ++#include ++#include ++#include ++#include ++#include ++ ++static bool check_stboard(u16 board) ++{ ++ unsigned int i; ++ const u16 st_board_id[] = { ++ 0x1272, ++ 0x1263, ++ 0x1264, ++ 0x1298, ++ 0x1341, ++ 0x1497, ++ }; ++ ++ for (i = 0; i < ARRAY_SIZE(st_board_id); i++) ++ if (board == st_board_id[i]) ++ return true; ++ ++ return false; ++} ++ ++static void display_stboard(u32 otp) ++{ ++ printf("Board: MB%04x Var%d.%d Rev.%c-%02d\n", ++ otp >> 16, ++ (otp >> 12) & 0xF, ++ (otp >> 4) & 0xF, ++ ((otp >> 8) & 0xF) - 1 + 'A', ++ otp & 0xF); ++} ++ ++static int do_stboard(cmd_tbl_t *cmdtp, int flag, int argc, ++ char * const argv[]) ++{ ++ int ret; ++ u32 otp, lock; ++ u8 revision; ++ unsigned long board, var_cpn, var_fg, bom; ++ struct udevice *dev; ++ int confirmed = argc == 7 && !strcmp(argv[1], "-y"); ++ ++ argc -= 1 + confirmed; ++ argv += 1 + confirmed; ++ ++ if (argc != 0 && argc != 5) ++ return CMD_RET_USAGE; ++ ++ ret = uclass_get_device_by_driver(UCLASS_MISC, ++ DM_GET_DRIVER(stm32mp_bsec), ++ &dev); ++ ++ ret = misc_read(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD), ++ &otp, sizeof(otp)); ++ ++ if (ret < 0) { ++ puts("OTP read error"); ++ return CMD_RET_FAILURE; ++ } ++ ++ ret = misc_read(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD), ++ &lock, sizeof(lock)); ++ if (ret < 0) { ++ puts("LOCK read error"); ++ return CMD_RET_FAILURE; ++ } ++ ++ if (argc == 0) { ++ if (!otp) ++ puts("Board : OTP board FREE\n"); ++ else ++ display_stboard(otp); ++ printf(" OTP %d %s locked !\n", BSEC_OTP_BOARD, ++ lock == 1 ? "" : "NOT"); ++ return CMD_RET_SUCCESS; ++ } ++ ++ if (otp) { ++ display_stboard(otp); ++ printf("ERROR: OTP board not FREE\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ if (strict_strtoul(argv[0], 16, &board) < 0 || ++ board == 0 || board > 0xFFFF) { ++ printf("argument %d invalid: %s\n", 1, argv[0]); ++ return CMD_RET_USAGE; ++ } ++ ++ if (strict_strtoul(argv[1], 10, &var_cpn) < 0 || ++ var_cpn == 0 || var_cpn > 15) { ++ printf("argument %d invalid: %s\n", 2, argv[1]); ++ return CMD_RET_USAGE; ++ } ++ ++ revision = argv[2][0] - 'A' + 1; ++ if (strlen(argv[2]) > 1 || revision == 0 || revision > 15) { ++ printf("argument %d invalid: %s\n", 3, argv[2]); ++ return CMD_RET_USAGE; ++ } ++ ++ if (strict_strtoul(argv[3], 10, &var_fg) < 0 || ++ var_fg > 15) { ++ printf("argument %d invalid: %s\n", 4, argv[3]); ++ return CMD_RET_USAGE; ++ } ++ ++ if (strict_strtoul(argv[4], 10, &bom) < 0 || ++ bom == 0 || bom > 15) { ++ printf("argument %d invalid: %s\n", 4, argv[3]); ++ return CMD_RET_USAGE; ++ } ++ ++ otp = (board << 16) | (var_cpn << 12) | (revision << 8) | ++ (var_fg << 4) | bom; ++ display_stboard(otp); ++ printf("=> OTP[%d] = %08X\n", BSEC_OTP_BOARD, otp); ++ ++ if (!check_stboard((u16)board)) { ++ printf("Unknown board MB%04x\n", (u16)board); ++ return CMD_RET_FAILURE; ++ } ++ if (!confirmed) { ++ printf("Warning: Programming BOARD in OTP is irreversible!\n"); ++ printf("Really perform this OTP programming? \n"); ++ ++ if (!confirm_yesno()) { ++ puts("BOARD programming aborted\n"); ++ return CMD_RET_FAILURE; ++ } ++ } ++ ++ ret = misc_write(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD), ++ &otp, sizeof(otp)); ++ ++ if (ret < 0) { ++ puts("BOARD programming error\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ /* write persistent lock */ ++ otp = 1; ++ ret = misc_write(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD), ++ &otp, sizeof(otp)); ++ if (ret < 0) { ++ puts("BOARD lock error\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ puts("BOARD programming done\n"); ++ ++ return CMD_RET_SUCCESS; ++} ++ ++U_BOOT_CMD(stboard, 7, 0, do_stboard, ++ "read/write board reference in OTP", ++ "\n" ++ " Print current board information\n" ++ "stboard [-y] \n" ++ " Write board information\n" ++ " - Board: xxxx, example 1264 for MB1264\n" ++ " - VarCPN: 1...15\n" ++ " - Revision: A...O\n" ++ " - VarFG: 0...15\n" ++ " - BOM: 1...15\n"); ++ ++#endif +diff --git a/board/st/common/stm32mp_dfu.c b/board/st/common/stm32mp_dfu.c +new file mode 100644 +index 0000000..3bd005b +--- /dev/null ++++ b/board/st/common/stm32mp_dfu.c +@@ -0,0 +1,245 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DFU_ALT_BUF_LEN SZ_1K ++ ++static void board_get_alt_info_mmc(struct udevice *dev, char *buf) ++{ ++ disk_partition_t info; ++ int p, len, devnum; ++ bool first = true; ++ const char *name; ++ struct mmc *mmc; ++ struct blk_desc *desc; ++ ++ mmc = mmc_get_mmc_dev(dev); ++ if (!mmc) ++ return; ++ ++ if (mmc_init(mmc)) ++ return; ++ ++ desc = mmc_get_blk_desc(mmc); ++ if (!desc) ++ return; ++ ++ name = blk_get_if_type_name(desc->if_type); ++ devnum = desc->devnum; ++ len = strlen(buf); ++ ++ if (buf[0] != '\0') ++ len += snprintf(buf + len, ++ DFU_ALT_BUF_LEN - len, "&"); ++ len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ++ "%s %d=", name, devnum); ++ ++ if (IS_MMC(mmc) && mmc->capacity_boot) { ++ len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ++ "%s%d_boot1 raw 0x0 0x%llx mmcpart 1;", ++ name, devnum, mmc->capacity_boot); ++ len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ++ "%s%d_boot2 raw 0x0 0x%llx mmcpart 2", ++ name, devnum, mmc->capacity_boot); ++ first = false; ++ } ++ ++ for (p = 1; p < MAX_SEARCH_PARTITIONS; p++) { ++ if (part_get_info(desc, p, &info)) ++ continue; ++ if (!first) ++ len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ";"); ++ first = false; ++ len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ++ "%s%d_%s part %d %d", ++ name, devnum, info.name, devnum, p); ++ } ++} ++ ++static void board_get_alt_info_mtd(struct mtd_info *mtd, char *buf) ++{ ++ struct mtd_info *part; ++ bool first = true; ++ const char *name; ++ int len, partnum = 0; ++ ++ name = mtd->name; ++ len = strlen(buf); ++ ++ if (buf[0] != '\0') ++ len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, "&"); ++ len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ++ "mtd %s=", name); ++ ++ len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ++ "%s raw 0x0 0x%llx ", ++ name, mtd->size); ++ ++ list_for_each_entry(part, &mtd->partitions, node) { ++ partnum++; ++ if (!first) ++ len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ";"); ++ first = false; ++ ++ len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ++ "%s_%s part %d", ++ name, part->name, partnum); ++ } ++} ++ ++void set_dfu_alt_info(char *interface, char *devstr) ++{ ++ struct udevice *dev; ++ struct mtd_info *mtd; ++ ++ ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); ++ ++ if (env_get("dfu_alt_info")) ++ return; ++ ++ memset(buf, 0, sizeof(buf)); ++ ++ snprintf(buf, DFU_ALT_BUF_LEN, ++ "ram 0=%s", CONFIG_DFU_ALT_RAM0); ++ ++ if (!uclass_get_device(UCLASS_MMC, 0, &dev)) ++ board_get_alt_info_mmc(dev, buf); ++ ++ if (!uclass_get_device(UCLASS_MMC, 1, &dev)) ++ board_get_alt_info_mmc(dev, buf); ++ ++ if (CONFIG_IS_ENABLED(MTD)) { ++ /* probe all MTD devices */ ++ mtd_probe_devices(); ++ ++ /* probe SPI flash device on a bus */ ++ if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) { ++ mtd = get_mtd_device_nm("nor0"); ++ if (!IS_ERR_OR_NULL(mtd)) ++ board_get_alt_info_mtd(mtd, buf); ++ } ++ ++ mtd = get_mtd_device_nm("nand0"); ++ if (!IS_ERR_OR_NULL(mtd)) ++ board_get_alt_info_mtd(mtd, buf); ++ ++ mtd = get_mtd_device_nm("spi-nand0"); ++ if (!IS_ERR_OR_NULL(mtd)) ++ board_get_alt_info_mtd(mtd, buf); ++ } ++ ++#ifdef CONFIG_DFU_VIRT ++ strncat(buf, "&virt 0=OTP", DFU_ALT_BUF_LEN); ++ ++ if (IS_ENABLED(CONFIG_PMIC_STPMIC1)) ++ strncat(buf, "&virt 1=PMIC", DFU_ALT_BUF_LEN); ++#endif ++ ++ env_set("dfu_alt_info", buf); ++ puts("DFU alt info setting: done\n"); ++} ++ ++#if CONFIG_IS_ENABLED(DFU_VIRT) ++#include ++#include ++ ++static int dfu_otp_read(u64 offset, u8 *buffer, long *size) ++{ ++ struct udevice *dev; ++ int ret; ++ ++ ret = uclass_get_device_by_driver(UCLASS_MISC, ++ DM_GET_DRIVER(stm32mp_bsec), ++ &dev); ++ if (ret) ++ return ret; ++ ++ ret = misc_read(dev, offset + STM32_BSEC_OTP_OFFSET, buffer, *size); ++ if (ret >= 0) { ++ *size = ret; ++ ret = 0; ++ } ++ ++ return 0; ++} ++ ++static int dfu_pmic_read(u64 offset, u8 *buffer, long *size) ++{ ++ int ret; ++#ifdef CONFIG_PMIC_STPMIC1 ++ struct udevice *dev; ++ ++ ret = uclass_get_device_by_driver(UCLASS_MISC, ++ DM_GET_DRIVER(stpmic1_nvm), ++ &dev); ++ if (ret) ++ return ret; ++ ++ ret = misc_read(dev, 0xF8 + offset, buffer, *size); ++ if (ret >= 0) { ++ *size = ret; ++ ret = 0; ++ } ++ if (ret == -EACCES) { ++ *size = 0; ++ ret = 0; ++ } ++#else ++ pr_err("PMIC update not supported"); ++ ret = -EOPNOTSUPP; ++#endif ++ ++ return ret; ++} ++ ++int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset, ++ void *buf, long *len) ++{ ++ switch (dfu->data.virt.dev_num) { ++ case 0x0: ++ return dfu_otp_read(offset, buf, len); ++ case 0x1: ++ return dfu_pmic_read(offset, buf, len); ++ } ++ ++ if (CONFIG_IS_ENABLED(CMD_STM32PROG) && ++ dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM) ++ return stm32prog_read_medium_virt(dfu, offset, buf, len); ++ ++ *len = 0; ++ return 0; ++} ++ ++int dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset, ++ void *buf, long *len) ++{ ++ if (CONFIG_IS_ENABLED(CMD_STM32PROG) && ++ dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM) ++ return stm32prog_write_medium_virt(dfu, offset, buf, len); ++ ++ return -EOPNOTSUPP; ++} ++ ++int __weak dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size) ++{ ++ if (CONFIG_IS_ENABLED(CMD_STM32PROG) && ++ dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM) ++ return stm32prog_get_medium_size_virt(dfu, size); ++ ++ *size = SZ_1K; ++ ++ return 0; ++} ++ ++#endif +diff --git a/board/st/common/stm32mp_mtdparts.c b/board/st/common/stm32mp_mtdparts.c +new file mode 100644 +index 0000000..9f5897f +--- /dev/null ++++ b/board/st/common/stm32mp_mtdparts.c +@@ -0,0 +1,167 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MTDPARTS_LEN 256 ++#define MTDIDS_LEN 128 ++ ++/* ++ * Get a global data pointer ++ */ ++DECLARE_GLOBAL_DATA_PTR; ++ ++/** ++ * update the variables "mtdids" and "mtdparts" with boot, tee and user strings ++ */ ++static void board_set_mtdparts(const char *dev, ++ char *mtdids, ++ char *mtdparts, ++ const char *boot, ++ const char *tee, ++ const char *user) ++{ ++ /* mtdids: "=, ...." */ ++ if (mtdids[0] != '\0') ++ strcat(mtdids, ","); ++ strcat(mtdids, dev); ++ strcat(mtdids, "="); ++ strcat(mtdids, dev); ++ ++ /* mtdparts: "mtdparts=:>;..." */ ++ if (mtdparts[0] != '\0') ++ strncat(mtdparts, ";", MTDPARTS_LEN); ++ else ++ strcat(mtdparts, "mtdparts="); ++ ++ strncat(mtdparts, dev, MTDPARTS_LEN); ++ strncat(mtdparts, ":", MTDPARTS_LEN); ++ ++ if (boot) { ++ strncat(mtdparts, boot, MTDPARTS_LEN); ++ strncat(mtdparts, ",", MTDPARTS_LEN); ++ } ++ ++ if (tee) { ++ strncat(mtdparts, tee, MTDPARTS_LEN); ++ strncat(mtdparts, ",", MTDPARTS_LEN); ++ } ++ ++ strncat(mtdparts, user, MTDPARTS_LEN); ++} ++ ++void board_mtdparts_default(const char **mtdids, const char **mtdparts) ++{ ++ struct mtd_info *mtd; ++ struct udevice *dev; ++ static char parts[3 * MTDPARTS_LEN + 1]; ++ static char ids[MTDIDS_LEN + 1]; ++ static bool mtd_initialized; ++ bool tee, nor, nand, spinand, serial; ++ ++ if (mtd_initialized) { ++ *mtdids = ids; ++ *mtdparts = parts; ++ return; ++ } ++ ++ tee = false; ++ nor = false; ++ nand = false; ++ spinand = false; ++ serial = false; ++ ++ switch (get_bootmode() & TAMP_BOOT_DEVICE_MASK) { ++ case BOOT_SERIAL_UART: ++ case BOOT_SERIAL_USB: ++ serial = true; ++ if (CONFIG_IS_ENABLED(CMD_STM32PROG)) { ++ tee = stm32prog_get_tee_partitions(); ++ nor = stm32prog_get_fsbl_nor(); ++ } ++ nand = true; ++ spinand = true; ++ break; ++ case BOOT_FLASH_NAND: ++ nand = true; ++ break; ++ case BOOT_FLASH_SPINAND: ++ spinand = true; ++ break; ++ case BOOT_FLASH_NOR: ++ nor = true; ++ break; ++ default: ++ break; ++ } ++ ++ if (!serial && CONFIG_IS_ENABLED(OPTEE) && ++ tee_find_device(NULL, NULL, NULL, NULL)) ++ tee = true; ++ ++ memset(parts, 0, sizeof(parts)); ++ memset(ids, 0, sizeof(ids)); ++ ++ /* probe all MTD devices */ ++ for (uclass_first_device(UCLASS_MTD, &dev); ++ dev; ++ uclass_next_device(&dev)) { ++ pr_debug("mtd device = %s\n", dev->name); ++ } ++ ++ if (nor || 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, ++ "-(UBI)"); ++ put_mtd_device(mtd); ++ } ++ } ++ ++ if (nor || 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, ++ "-(UBI)"); ++ put_mtd_device(mtd); ++ } ++ } ++ ++ 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, ++ "-(nor_user)"); ++ } ++ } ++ ++ mtd_initialized = true; ++ *mtdids = ids; ++ *mtdparts = parts; ++ debug("%s:mtdids=%s & mtdparts=%s\n", __func__, ids, parts); ++} +diff --git a/board/st/stm32mp1/Kconfig b/board/st/stm32mp1/Kconfig +index 4fa2360..c5ab755 100644 +--- a/board/st/stm32mp1/Kconfig ++++ b/board/st/stm32mp1/Kconfig +@@ -1,4 +1,4 @@ +-if TARGET_STM32MP1 ++if TARGET_ST_STM32MP15x + + config SYS_BOARD + default "stm32mp1" +@@ -9,21 +9,5 @@ config SYS_VENDOR + config SYS_CONFIG_NAME + default "stm32mp1" + +-config ENV_SECT_SIZE +- default 0x40000 if ENV_IS_IN_SPI_FLASH +- +-config ENV_OFFSET +- default 0x280000 if ENV_IS_IN_SPI_FLASH +- +-config CMD_STBOARD +- bool "stboard - command for OTP board information" +- default y +- help +- This compile the stboard command to +- read and write the board in the OTP. +- +-config TARGET_STM32MP157C_DK2 +- bool "support of STMicroelectronics STM32MP157C-DK2 Discovery Board" +- default y +- ++source "board/st/common/Kconfig" + endif +diff --git a/board/st/stm32mp1/MAINTAINERS b/board/st/stm32mp1/MAINTAINERS +index 2930947..96c4559 100644 +--- a/board/st/stm32mp1/MAINTAINERS ++++ b/board/st/stm32mp1/MAINTAINERS +@@ -6,6 +6,5 @@ S: Maintained + F: arch/arm/dts/stm32mp15* + F: board/st/stm32mp1/ + F: configs/stm32mp15_basic_defconfig +-F: configs/stm32mp15_optee_defconfig + F: configs/stm32mp15_trusted_defconfig + F: include/configs/stm32mp1.h +diff --git a/board/st/stm32mp1/Makefile b/board/st/stm32mp1/Makefile +index 3c6c035..8188075 100644 +--- a/board/st/stm32mp1/Makefile ++++ b/board/st/stm32mp1/Makefile +@@ -7,7 +7,6 @@ ifdef CONFIG_SPL_BUILD + obj-y += spl.o + else + obj-y += stm32mp1.o +-obj-$(CONFIG_CMD_STBOARD) += cmd_stboard.o + endif + + obj-y += board.o +diff --git a/board/st/stm32mp1/README b/board/st/stm32mp1/README +index f2069bc..8172d26 100644 +--- a/board/st/stm32mp1/README ++++ b/board/st/stm32mp1/README +@@ -1,503 +1 @@ +-SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +-# +-# Copyright (C) 2018 STMicroelectronics - All Rights Reserved +-# +- +-U-Boot on STMicroelectronics STM32MP1 +-====================================== +- +-1. Summary +-========== +-This is a quick instruction for setup stm32mp1 boards. +- +-2. Supported devices +-==================== +-U-Boot supports one STMP32MP1 SoCs: STM32MP157 +- +-The STM32MP157 is a Cortex-A MPU aimed at various applications. +-It features: +-- Dual core Cortex-A7 application core +-- 2D/3D image composition with GPU +-- Standard memories interface support +-- Standard connectivity, widely inherited from the STM32 MCU family +-- Comprehensive security support +- +-Everything is supported in Linux but U-Boot is limited to: +-1. UART +-2. SDCard/MMC controller (SDMMC) +-3. NAND controller (FMC) +-4. NOR controller (QSPI) +-5. USB controller (OTG DWC2) +-6. Ethernet controller +- +-And the necessary drivers +-1. I2C +-2. STPMIC1 (PMIC and regulator) +-3. Clock, Reset, Sysreset +-4. Fuse +- +-Currently the following boards are supported: +-+ stm32mp157c-ev1 +-+ stm32mp157c-ed1 +-+ stm32mp157a-dk1 +-+ stm32mp157c-dk2 +-+ stm32mp157a-avenger96 +- +-3. Boot Sequences +-================= +- +-BootRom => FSBL in SYSRAM => SSBL in DDR => OS (Linux Kernel) +- +-with FSBL = First Stage Bootloader +- SSBL = Second Stage Bootloader +- +-3 boot configurations are supported: +- +-1) The "Trusted" boot chain (defconfig_file : stm32mp15_trusted_defconfig) +- BootRom => FSBL = Trusted Firmware-A (TF-A) => SSBL = U-Boot +- TF-A performs a full initialization of Secure peripherals and installs a +- secure monitor. +- U-Boot is running in normal world and uses TF-A monitor +- to access to secure resources. +- +-2) The "Trusted" boot chain with OP-TEE +- (defconfig_file : stm32mp15_optee_defconfig) +- BootRom => FSBL = Trusted Firmware-A (TF-A) => SSBL = U-Boot +- TF-A performs a full initialization of Secure peripherals and installs OP-TEE +- from specific partitions (teeh, teed, teex). +- U-Boot is running in normal world and uses OP-TEE monitor to access +- to secure resources. +- +-3) The "Basic" boot chain (defconfig_file : stm32mp15_basic_defconfig) +- BootRom => FSBL = U-Boot SPL => SSBL = U-Boot +- SPL has limited security initialisation +- 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 STM32MP1 boards supported by U-Boot use the same generic board +-stm32mp1 which support all the bootable devices. +- +-Each board is configurated only with the associated device tree. +- +-4. Device Tree Selection +-======================== +- +-You need to select the appropriate device tree for your board, +-the supported device trees for stm32mp157 are: +- +-+ ev1: eval board with pmic stpmic1 (ev1 = mother board + daughter ed1) +- dts: stm32mp157c-ev1 +- +-+ ed1: daughter board with pmic stpmic1 +- dts: stm32mp157c-ed1 +- +-+ dk1: Discovery board +- dts: stm32mp157a-dk1 +- +-+ dk2: Discovery board = dk1 with a BT/WiFI combo and a DSI panel +- dts: stm32mp157c-dk2 +- +-+ avenger96: Avenger96 board from Arrow Electronics +- dts: stm32mp157a-avenger96 +- +-5. Build Procedure +-================== +- +-1. Install required tools for U-Boot +- +- + install package needed in U-Boot makefile +- (libssl-dev, swig, libpython-dev...) +- + install ARMv7 toolchain for 32bit Cortex-A (from Linaro, +- from SDK for STM32MP1, or any crosstoolchains from your distribution) +- +-2. Set the cross compiler: +- +- # export CROSS_COMPILE=/path/to/toolchain/arm-linux-gnueabi- +- (you can use any gcc cross compiler compatible with U-Boot) +- +-3. Select the output directory (optional) +- +- # export KBUILD_OUTPUT=/path/to/output +- +- for example: use one output directory for each configuration +- # export KBUILD_OUTPUT=stm32mp15_trusted +- # export KBUILD_OUTPUT=stm32mp15_optee +- # export KBUILD_OUTPUT=stm32mp15_basic +- +- you can build outside of code directory: +- # export KBUILD_OUTPUT=../build/stm32mp15_trusted +- +-4. Configure U-Boot: +- +- # make +- +- - For trusted boot mode : "stm32mp15_trusted_defconfig" +- - For trusted with OP-TEE boot mode : "stm32mp15_optee_defconfig" +- - For basic boot mode: "stm32mp15_basic_defconfig" +- +-5. Configure the device-tree and build the U-Boot image: +- +- # make DEVICE_TREE= all +- +- example: +- a) trusted boot on ev1 +- # export KBUILD_OUTPUT=stm32mp15_trusted +- # make stm32mp15_trusted_defconfig +- # make DEVICE_TREE=stm32mp157c-ev1 all +- +- b) trusted with OP-TEE boot on dk2 +- # export KBUILD_OUTPUT=stm32mp15_optee +- # make stm32mp15_optee_defconfig +- # make DEVICE_TREE=stm32mp157c-dk2 all +- +- c) basic boot on ev1 +- # export KBUILD_OUTPUT=stm32mp15_basic +- # make stm32mp15_basic_defconfig +- # make DEVICE_TREE=stm32mp157c-ev1 all +- +- d) basic boot on ed1 +- # export KBUILD_OUTPUT=stm32mp15_basic +- # make stm32mp15_basic_defconfig +- # make DEVICE_TREE=stm32mp157c-ed1 all +- +- e) basic boot on dk1 +- # export KBUILD_OUTPUT=stm32mp15_basic +- # make stm32mp15_basic_defconfig +- # make DEVICE_TREE=stm32mp157a-dk1 all +- +- f) basic boot on avenger96 +- # export KBUILD_OUTPUT=stm32mp15_basic +- # make stm32mp15_basic_defconfig +- # make DEVICE_TREE=stm32mp157a-avenger96 all +- +-6. Output files +- +- BootRom and TF-A expect binaries with STM32 image header +- SPL expects file with U-Boot uImage header +- +- So in the output directory (selected by KBUILD_OUTPUT), +- you can found the needed files: +- +- a) For Trusted boot (with or without OP-TEE) +- + FSBL = tf-a.stm32 (provided by TF-A compilation) +- + SSBL = u-boot.stm32 +- +- b) For Basic boot +- + FSBL = spl/u-boot-spl.stm32 +- + SSBL = u-boot.img +- +-6. Switch Setting for Boot Mode +-=============================== +- +-You can select the boot mode, on the board with one switch : +- +-- on the daugther board ed1 with the switch SW1 : BOOT0, BOOT1, BOOT2 +- +- ----------------------------------- +- Boot Mode BOOT2 BOOT1 BOOT0 +- ----------------------------------- +- Reserved 0 0 0 +- NOR 0 0 1 +- SD-Card 1 0 1 +- eMMC 0 1 0 +- NAND 0 1 1 +- Recovery 1 1 0 +- Recovery 0 0 0 +- +-- on board DK1/DK2 with the switch SW1 : BOOT0, BOOT2 +- (BOOT1 forced to 0, NOR not supported) +- +- -------------------------- +- Boot Mode BOOT2 BOOT0 +- -------------------------- +- Reserved 1 0 +- SD-Card 1 1 +- Recovery 0 0 +- +-- Boot mode of Avenger96 can be selected using switch S3 +- +- ----------------------------------- +- Boot Mode BOOT2 BOOT1 BOOT0 +- ----------------------------------- +- Recovery 0 0 0 +- NOR 0 0 1 +- SD-Card 1 0 1 +- eMMC 0 1 0 +- NAND 0 1 1 +- Reserved 1 0 0 +- Recovery 1 1 0 +- SD-Card 1 1 1 +- +-Recovery is a boot from serial link (UART/USB) and it is used with +-STM32CubeProgrammer tool to load executable in RAM and to update the flash +-devices available on the board (NOR/NAND/eMMC/SDCARD). +-The communication between HOST and board is based on +-- for UARTs : the uart protocol used with all MCU STM32 +-- for USB : based on USB DFU 1.1 (without the ST extensions used on MCU STM32) +- +-7. Prepare an SDCard +-=================== +- +-The minimal requirements for STMP32MP1 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 +- +-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 | +- | * | - | - | Boot/Rootfs | +- ----- ------- --------- -------------- +- +-(*) add bootable partition for extlinux.conf +- following Generic Distribution +- (doc/README.distro for use) +- +- according the used card reader select the block device +- (/dev/sdx or /dev/mmcblk0) +- in the next example I use /dev/mmcblk0 +- +-for example: with gpt table with 128 entries +- +- a) remove previous formatting +- # sgdisk -o /dev/ +- +- 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 \ +- -p /dev/ +- +- you can add other partitions for kernel +- one partition rootfs for example: +- -n 4:5154: -c 4:rootfs \ +- +- c) copy the FSBL (2 times) and SSBL file on the correct partition. +- in this example in partition 1 to 3 +- +- for basic boot mode : = /dev/mmcblk0 +- # dd if=u-boot-spl.stm32 of=/dev/mmcblk0p1 +- # dd if=u-boot-spl.stm32 of=/dev/mmcblk0p2 +- # dd if=u-boot.img of=/dev/mmcblk0p3 +- +- for trusted boot mode : +- # dd if=tf-a.stm32 of=/dev/mmcblk0p1 +- # dd if=tf-a.stm32 of=/dev/mmcblk0p2 +- # dd if=u-boot.stm32 of=/dev/mmcblk0p3 +- +-To boot from SDCard, select BootPinMode = 1 0 1 and reset. +- +-8. Prepare eMMC +-=============== +-You can use U-Boot to copy binary in eMMC. +- +-In the next example, you need to boot from SDCARD and the images (u-boot-spl.stm32, u-boot.img) +-are presents on SDCARD (mmc 0) in ext4 partition 4 (bootfs). +- +-To boot from SDCard, select BootPinMode = 1 0 1 and reset. +- +-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" +- # 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 u-boot-spl.stm32 +- # mmc dev 1 +- # mmc partconf 1 1 1 1 +- # mmc write ${fileaddr} 0 200 +- # mmc partconf 1 1 1 0 +- +-c) copy U-Boot in first GPT partition of eMMC +- +- # ext4load mmc 0:4 0xC0000000 u-boot.img +- # mmc dev 1 +- # part start mmc 1 1 partstart +- # part size mmc 1 1 partsize +- # mmc write ${fileaddr} ${partstart} ${partsize} +- +-To boot from eMMC, select BootPinMode = 0 1 0 and reset. +- +-9. MAC Address +-============== +- +-Please read doc/README.enetaddr for the implementation guidelines for mac id +-usage. Basically, environment has precedence over board specific storage. +- +-Mac id storage and retrieval in stm32mp otp : +-- 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 +-on bank 0 to access to internal OTP: +- +- example to set mac address "12:34:56:78:9a:bc" +- +- 1- Write OTP +- STM32MP> fuse prog -y 0 57 0x78563412 0x0000bc9a +- +- 2- Read OTP +- STM32MP> fuse sense 0 57 2 +- Sensing bank 0: +- Word 0x00000039: 78563412 0000bc9a +- +- 3- next REBOOT : +- ### Setting environment from OTP MAC address = "12:34:56:78:9a:bc" +- +- 4 check env update +- STM32MP> print ethaddr +- ethaddr=12:34:56:78:9a:bc +- +-10. Coprocessor firmware +-======================== +- +-U-Boot can boot the coprocessor before the kernel (coprocessor early boot). +- +-A/ Manuallly by using rproc commands (update the bootcmd) +- Configurations +- # env set name_copro "rproc-m4-fw.elf" +- # env set dev_copro 0 +- # env set loadaddr_copro 0xC1000000 +- +- Load binary from bootfs partition (number 4) on SDCard (mmc 0) +- # ext4load mmc 0:4 ${loadaddr_copro} ${name_copro} +- => ${filesize} updated with the size of the loaded file +- +- Start M4 firmware with remote proc command +- # rproc init +- # rproc load ${dev_copro} ${loadaddr_copro} ${filesize} +- # rproc start ${dev_copro} +- +-B/ Automatically by using FIT feature and generic DISTRO bootcmd +- +- see examples in this directory : +- +- Generate FIT including kernel + device tree + M4 firmware +- with cfg with M4 boot +- $> mkimage -f fit_copro_kernel_dtb.its fit_copro_kernel_dtb.itb +- +- Then using DISTRO configuration file: see extlinux.conf to select +- the correct configuration +- => stm32mp157c-ev1-m4 +- => stm32mp157c-dk2-m4 +- +-11. DFU support +-=============== +- +-The DFU is supported on ST board. +-The env variable dfu_alt_info is automatically build, and all +-the memory present on the ST boards are exported. +- +-The mode is started by +- +-STM32MP> dfu 0 +- +-On EV1 board: +- +-STM32MP> dfu 0 list +- +-DFU alt settings list: +-dev: RAM alt: 0 name: uImage layout: RAM_ADDR +-dev: RAM alt: 1 name: devicetree.dtb layout: RAM_ADDR +-dev: RAM alt: 2 name: uramdisk.image.gz layout: RAM_ADDR +-dev: eMMC alt: 3 name: sdcard_fsbl1 layout: RAW_ADDR +-dev: eMMC alt: 4 name: sdcard_fsbl2 layout: RAW_ADDR +-dev: eMMC alt: 5 name: sdcard_ssbl layout: RAW_ADDR +-dev: eMMC alt: 6 name: sdcard_bootfs layout: RAW_ADDR +-dev: eMMC alt: 7 name: sdcard_vendorfs layout: RAW_ADDR +-dev: eMMC alt: 8 name: sdcard_rootfs layout: RAW_ADDR +-dev: eMMC alt: 9 name: sdcard_userfs layout: RAW_ADDR +-dev: eMMC alt: 10 name: emmc_fsbl1 layout: RAW_ADDR +-dev: eMMC alt: 11 name: emmc_fsbl2 layout: RAW_ADDR +-dev: eMMC alt: 12 name: emmc_ssbl layout: RAW_ADDR +-dev: eMMC alt: 13 name: emmc_bootfs layout: RAW_ADDR +-dev: eMMC alt: 14 name: emmc_vendorfs layout: RAW_ADDR +-dev: eMMC alt: 15 name: emmc_rootfs layout: RAW_ADDR +-dev: eMMC alt: 16 name: emmc_userfs layout: RAW_ADDR +-dev: MTD alt: 17 name: nor_fsbl1 layout: RAW_ADDR +-dev: MTD alt: 18 name: nor_fsbl2 layout: RAW_ADDR +-dev: MTD alt: 19 name: nor_ssbl layout: RAW_ADDR +-dev: MTD alt: 20 name: nor_env layout: RAW_ADDR +-dev: MTD alt: 21 name: nand_fsbl layout: RAW_ADDR +-dev: MTD alt: 22 name: nand_ssbl1 layout: RAW_ADDR +-dev: MTD alt: 23 name: nand_ssbl2 layout: RAW_ADDR +-dev: MTD alt: 24 name: nand_UBI layout: RAW_ADDR +-dev: VIRT alt: 25 name: OTP layout: RAW_ADDR +-dev: VIRT alt: 26 name: PMIC layout: RAW_ADDR +- +-All the supported device are exported for dfu-util tool: +- +-$> dfu-util -l +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=26, name="PMIC", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=25, name="OTP", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=24, name="nand_UBI", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=23, name="nand_ssbl2", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=22, name="nand_ssbl1", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=21, name="nand_fsbl", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=20, name="nor_env", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=19, name="nor_ssbl", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=18, name="nor_fsbl2", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=17, name="nor_fsbl1", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=16, name="emmc_userfs", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=15, name="emmc_rootfs", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=14, name="emmc_vendorfs", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=13, name="emmc_bootfs", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=12, name="emmc_ssbl", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=11, name="emmc_fsbl2", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=10, name="emmc_fsbl1", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=9, name="sdcard_userfs", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=8, name="sdcard_rootfs", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=7, name="sdcard_vendorfs", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=6, name="sdcard_bootfs", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=5, name="sdcard_ssbl", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=4, name="sdcard_fsbl2", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=3, name="sdcard_fsbl1", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=2, name="uramdisk.image.gz", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=1, name="devicetree.dtb", serial="002700333338511934383330" +-Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=0, name="uImage", serial="002700333338511934383330" +- +-You can update the boot device: +- +-#SDCARD +-$> 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 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 +-$> dfu-util -d 0483:5720 -a 9 -D st-image-userfs-openstlinux-weston-stm32mp1.ext4 +- +-#EMMC +-$> 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 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 +-$> dfu-util -d 0483:5720 -a 16 -D st-image-userfs-openstlinux-weston-stm32mp1.ext4 +- +-#NOR +-$> dfu-util -d 0483:5720 -a 17 -D tf-a-stm32mp157c-ev1-trusted.stm32 +-$> dfu-util -d 0483:5720 -a 18 -D tf-a-stm32mp157c-ev1-trusted.stm32 +-$> dfu-util -d 0483:5720 -a 19 -D u-boot-stm32mp157c-ev1-trusted.img +- +-#NAND (UBI partition used for NAND only boot or NOR + NAND boot) +-$> dfu-util -d 0483:5720 -a 21 -D tf-a-stm32mp157c-ev1-trusted.stm32 +-$> dfu-util -d 0483:5720 -a 22 -D u-boot-stm32mp157c-ev1-trusted.img +-$> dfu-util -d 0483:5720 -a 23 -D u-boot-stm32mp157c-ev1-trusted.img +-$> dfu-util -d 0483:5720 -a 24 -D st-image-weston-openstlinux-weston-stm32mp1_nand_4_256_multivolume.ubi +- +-And you can also dump the OTP and the PMIC NVM with: +- +-$> dfu-util -d 0483:5720 -a 25 -U otp.bin +-$> dfu-util -d 0483:5720 -a 26 -U pmic.bin ++see doc/board/st/stm32mp1.rst +diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c +index c3d832f..3e38aef 100644 +--- a/board/st/stm32mp1/board.c ++++ b/board/st/stm32mp1/board.c +@@ -38,11 +38,46 @@ void board_debug_uart_init(void) + #endif + + #ifdef CONFIG_PMIC_STPMIC1 ++u32 opp_voltage_mv; ++ ++void board_vddcore_init(u32 voltage_mv) ++{ ++ opp_voltage_mv = voltage_mv; ++} ++ ++int board_vddcore_set(void) ++{ ++ struct udevice *dev; ++ int ret; ++ u32 value; ++ ++ if (!opp_voltage_mv) ++ return 0; ++ ++ ret = uclass_get_device_by_driver(UCLASS_PMIC, ++ DM_GET_DRIVER(pmic_stpmic1), &dev); ++ if (ret) ++ return ret; ++ ++ /* VDDCORE= STMPCI1 BUCK1 ramp=+25mV, 5 => 725mV, 36 => 1500mV */ ++ value = ((opp_voltage_mv - 725) / 25) + 5; ++ if (value < 5) ++ value = 5; ++ if (value > 36) ++ value = 36; ++ ++ return pmic_clrsetbits(dev, ++ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK1), ++ STPMIC1_BUCK_VOUT_MASK, ++ STPMIC1_BUCK_VOUT(value)); ++} ++ + int board_ddr_power_init(enum ddr_type ddr_type) + { + struct udevice *dev; + bool buck3_at_1800000v = false; + int ret; ++ u32 buck2; + + ret = uclass_get_device_by_driver(UCLASS_PMIC, + DM_GET_DRIVER(pmic_stpmic1), &dev); +@@ -102,8 +137,10 @@ int board_ddr_power_init(enum ddr_type ddr_type) + + break; + +- case STM32MP_LPDDR2: +- case STM32MP_LPDDR3: ++ case STM32MP_LPDDR2_16: ++ case STM32MP_LPDDR2_32: ++ case STM32MP_LPDDR3_16: ++ case STM32MP_LPDDR3_32: + /* + * configure VDD_DDR1 = LDO3 + * Set LDO3 to 1.8V +@@ -133,11 +170,23 @@ int board_ddr_power_init(enum ddr_type ddr_type) + if (ret < 0) + return ret; + +- /* VDD_DDR2 : Set BUCK2 to 1.2V */ ++ /* VDD_DDR2 : Set BUCK2 to 1.2V (16bits) or 1.25V (32 bits)*/ ++ switch (ddr_type) { ++ case STM32MP_LPDDR2_32: ++ case STM32MP_LPDDR3_32: ++ buck2 = STPMIC1_BUCK2_1250000V; ++ break; ++ default: ++ case STM32MP_LPDDR2_16: ++ case STM32MP_LPDDR3_16: ++ buck2 = STPMIC1_BUCK2_1200000V; ++ break; ++ } ++ + ret = pmic_clrsetbits(dev, + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), + STPMIC1_BUCK_VOUT_MASK, +- STPMIC1_BUCK2_1200000V); ++ buck2); + if (ret < 0) + return ret; + +diff --git a/board/st/stm32mp1/cmd_stboard.c b/board/st/stm32mp1/cmd_stboard.c +deleted file mode 100644 +index 04352ae..0000000 +--- a/board/st/stm32mp1/cmd_stboard.c ++++ /dev/null +@@ -1,145 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +-/* +- * Copyright (C) 2019, STMicroelectronics - All Rights Reserved +- */ +- +-#include +-#include +-#include +-#include +-#include +- +-static bool check_stboard(u16 board) +-{ +- unsigned int i; +- const u16 st_board_id[] = { +- 0x1272, +- 0x1263, +- 0x1264, +- 0x1298, +- 0x1341, +- 0x1497, +- }; +- +- for (i = 0; i < ARRAY_SIZE(st_board_id); i++) +- if (board == st_board_id[i]) +- return true; +- +- return false; +-} +- +-static void display_stboard(u32 otp) +-{ +- printf("Board: MB%04x Var%d Rev.%c-%02d\n", +- otp >> 16, +- (otp >> 12) & 0xF, +- ((otp >> 8) & 0xF) - 1 + 'A', +- otp & 0xF); +-} +- +-static int do_stboard(cmd_tbl_t *cmdtp, int flag, int argc, +- char * const argv[]) +-{ +- int ret; +- u32 otp; +- u8 revision; +- unsigned long board, variant, bom; +- struct udevice *dev; +- int confirmed = argc == 6 && !strcmp(argv[1], "-y"); +- +- argc -= 1 + confirmed; +- argv += 1 + confirmed; +- +- if (argc != 0 && argc != 4) +- return CMD_RET_USAGE; +- +- ret = uclass_get_device_by_driver(UCLASS_MISC, +- DM_GET_DRIVER(stm32mp_bsec), +- &dev); +- +- ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), +- &otp, sizeof(otp)); +- +- if (ret < 0) { +- puts("OTP read error"); +- return CMD_RET_FAILURE; +- } +- +- if (argc == 0) { +- if (!otp) +- puts("Board : OTP board FREE\n"); +- else +- display_stboard(otp); +- return CMD_RET_SUCCESS; +- } +- +- if (otp) { +- display_stboard(otp); +- printf("ERROR: OTP board not FREE\n"); +- return CMD_RET_FAILURE; +- } +- +- if (strict_strtoul(argv[0], 16, &board) < 0 || +- board == 0 || board > 0xFFFF) { +- printf("argument %d invalid: %s\n", 1, argv[0]); +- return CMD_RET_USAGE; +- } +- +- if (strict_strtoul(argv[1], 10, &variant) < 0 || +- variant == 0 || variant > 15) { +- printf("argument %d invalid: %s\n", 2, argv[1]); +- return CMD_RET_USAGE; +- } +- +- revision = argv[2][0] - 'A' + 1; +- if (strlen(argv[2]) > 1 || revision == 0 || revision > 15) { +- printf("argument %d invalid: %s\n", 3, argv[2]); +- return CMD_RET_USAGE; +- } +- +- if (strict_strtoul(argv[3], 10, &bom) < 0 || +- bom == 0 || bom > 15) { +- printf("argument %d invalid: %s\n", 4, argv[3]); +- return CMD_RET_USAGE; +- } +- +- otp = (board << 16) | (variant << 12) | (revision << 8) | bom; +- display_stboard(otp); +- printf("=> OTP[%d] = %08X\n", BSEC_OTP_BOARD, otp); +- +- if (!check_stboard((u16)board)) { +- printf("Unknown board MB%04x\n", (u16)board); +- return CMD_RET_FAILURE; +- } +- if (!confirmed) { +- printf("Warning: Programming BOARD in OTP is irreversible!\n"); +- printf("Really perform this OTP programming? \n"); +- +- if (!confirm_yesno()) { +- puts("BOARD programming aborted\n"); +- return CMD_RET_FAILURE; +- } +- } +- +- ret = misc_write(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD), +- &otp, sizeof(otp)); +- +- if (ret) { +- puts("BOARD programming error\n"); +- return CMD_RET_FAILURE; +- } +- puts("BOARD programming done\n"); +- +- return CMD_RET_SUCCESS; +-} +- +-U_BOOT_CMD(stboard, 6, 0, do_stboard, +- "read/write board reference in OTP", +- "\n" +- " Print current board information\n" +- "stboard [-y] \n" +- " Write board information\n" +- " - Board: xxxx, example 1264 for MB1264\n" +- " - Variant: 1 ... 15\n" +- " - Revision: A...O\n" +- " - BOM: 1...15\n"); +diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c +index cee3500..617d05d 100644 +--- a/board/st/stm32mp1/stm32mp1.c ++++ b/board/st/stm32mp1/stm32mp1.c +@@ -15,9 +15,7 @@ + #include + #include + #include +-#include + #include +-#include + #include + #include + #include +@@ -31,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -77,6 +76,39 @@ DECLARE_GLOBAL_DATA_PTR; + #define USB_START_LOW_THRESHOLD_UV 1230000 + #define USB_START_HIGH_THRESHOLD_UV 2150000 + ++static void stboard_lock(struct udevice *dev) ++{ ++ int ret; ++ u32 lock; ++ u32 mac[2]; ++ ++ ret = misc_read(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD), ++ &lock, sizeof(lock)); ++ if (ret != sizeof(lock) || lock == 1) ++ return; ++ ++ lock = 1; ++ misc_write(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD), &lock, sizeof(lock)); ++ printf("Lock the BOARD OTP (%d)\n", BSEC_OTP_BOARD); ++ ++ /* check LOCK status on MAC address */ ++ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_MAC), ++ &mac, sizeof(mac)); ++ if (ret != sizeof(mac) || (mac[0] == 0x0 && mac[1] == 0x0)) ++ return; ++ ++ ret = misc_read(dev, STM32_BSEC_LOCK(BSEC_OTP_MAC), ++ &mac, sizeof(mac)); ++ /* already locked : nothing to do */ ++ if (ret != sizeof(mac) || (mac[0] == 1 && mac[1] == 1)) ++ return; ++ ++ mac[0] = 1; ++ mac[1] = 1; ++ misc_write(dev, STM32_BSEC_LOCK(BSEC_OTP_MAC), &mac, sizeof(mac)); ++ printf("Lock the MAC OTP (%d)\n", BSEC_OTP_MAC); ++} ++ + int checkboard(void) + { + int ret; +@@ -86,9 +118,7 @@ int checkboard(void) + const char *fdt_compat; + int fdt_compat_len; + +- if (IS_ENABLED(CONFIG_STM32MP1_OPTEE)) +- mode = "trusted with OP-TEE"; +- else if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED)) ++ if (CONFIG_IS_ENABLED(STM32MP1_TRUSTED)) + mode = "trusted"; + else + mode = "basic"; +@@ -100,19 +130,27 @@ int checkboard(void) + printf(" (%s)", fdt_compat); + puts("\n"); + +- ret = uclass_get_device_by_driver(UCLASS_MISC, +- DM_GET_DRIVER(stm32mp_bsec), +- &dev); ++ if (CONFIG_IS_ENABLED(CMD_STBOARD)) { ++ ret = uclass_get_device_by_driver(UCLASS_MISC, ++ DM_GET_DRIVER(stm32mp_bsec), ++ &dev); + +- if (!ret) +- ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), +- &otp, sizeof(otp)); +- if (ret > 0 && otp) { +- printf("Board: MB%04x Var%d Rev.%c-%02d\n", +- otp >> 16, +- (otp >> 12) & 0xF, +- ((otp >> 8) & 0xF) - 1 + 'A', +- otp & 0xF); ++ if (!ret) ++ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), ++ &otp, sizeof(otp)); ++ if (ret > 0 && otp) { ++ printf("Board: MB%04x Var%d.%d Rev.%c-%02d\n", ++ otp >> 16, ++ (otp >> 12) & 0xF, ++ (otp >> 4) & 0xF, ++ ((otp >> 8) & 0xF) - 1 + 'A', ++ otp & 0xF); ++ ++ /* LOCK OTP for board ID and MAC address on ST board */ ++ if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) && ++ ((otp >> 16) == 0x1272 || (otp >> 16) == 0x1263)) ++ stboard_lock(dev); ++ } + } + + return 0; +@@ -274,9 +312,11 @@ static int get_led(struct udevice **dev, char *led_string) + + return 0; + } ++#endif + + static int setup_led(enum led_state_t cmd) + { ++#ifdef CONFIG_LED + struct udevice *dev; + int ret; + +@@ -286,8 +326,10 @@ static int setup_led(enum led_state_t cmd) + + ret = led_set_state(dev, cmd); + return ret; +-} ++#else ++ return 0; + #endif ++} + + static void __maybe_unused led_error_blink(u32 nb_blink) + { +@@ -310,6 +352,7 @@ static void __maybe_unused led_error_blink(u32 nb_blink) + mdelay(125); + WATCHDOG_RESET(); + } ++ led_set_state(led, LEDST_ON); + } + #endif + +@@ -429,7 +472,7 @@ static int board_check_usb_power(void) + if (max_uV > USB_WARNING_LOW_THRESHOLD_UV && + max_uV <= USB_START_LOW_THRESHOLD_UV && + min_uV <= USB_LOW_THRESHOLD_UV) { +- pr_err("* WARNING 1.5mA power supply detected *\n"); ++ pr_err("* WARNING 1.5A power supply detected *\n"); + nb_blink = 3; + } + +@@ -462,10 +505,10 @@ static void sysconf_init(void) + struct udevice *pwr_dev; + struct udevice *pwr_reg; + struct udevice *dev; +- int ret; + u32 otp = 0; + #endif +- u32 bootr; ++ int ret; ++ u32 bootr, val; + + syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); + +@@ -542,8 +585,15 @@ static void sysconf_init(void) + */ + writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR); + +- while (!(readl(syscfg + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY)) +- ; ++ /* poll until ready (1s timeout) */ ++ ret = readl_poll_timeout(syscfg + SYSCFG_CMPCR, val, ++ val & SYSCFG_CMPCR_READY, ++ 1000000); ++ if (ret) { ++ pr_err("SYSCFG: I/O compensation failed, timeout.\n"); ++ led_error_blink(10); ++ } ++ + clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); + #endif + } +@@ -607,31 +657,67 @@ error: + + static bool board_is_dk2(void) + { +- if (CONFIG_IS_ENABLED(TARGET_STM32MP157C_DK2) && +- of_machine_is_compatible("st,stm32mp157c-dk2")) ++ if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) && ++ (of_machine_is_compatible("st,stm32mp157c-dk2") || ++ of_machine_is_compatible("st,stm32mp157f-dk2"))) + return true; + + return false; + } + #endif + +-/* board dependent setup after realloc */ +-int board_init(void) ++static bool board_is_ev1(void) ++{ ++ if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) && ++ (of_machine_is_compatible("st,stm32mp157a-ev1") || ++ of_machine_is_compatible("st,stm32mp157c-ev1") || ++ of_machine_is_compatible("st,stm32mp157d-ev1") || ++ of_machine_is_compatible("st,stm32mp157f-ev1"))) ++ return true; ++ ++ return false; ++} ++ ++/* touchscreen driver: only used for pincontrol configuration */ ++static const struct udevice_id goodix_ids[] = { ++ { .compatible = "goodix,gt9147", }, ++ { } ++}; ++ ++U_BOOT_DRIVER(goodix) = { ++ .name = "goodix", ++ .id = UCLASS_NOP, ++ .of_match = goodix_ids, ++}; ++ ++static int board_ev1_init(void) + { + struct udevice *dev; ++ int ret; ++ ++ /* configure IRQ line on EV1 for touchscreen before LCD reset */ ++ ret = uclass_get_device_by_driver(UCLASS_NOP, DM_GET_DRIVER(goodix), ++ &dev); ++ if (ret) ++ debug("goodix init failed: %d\n", ret); + ++ return ret; ++} ++ ++/* board dependent setup after realloc */ ++int board_init(void) ++{ + /* address of boot parameters */ + gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100; + +- /* probe all PINCTRL for hog */ +- for (uclass_first_device(UCLASS_PINCTRL, &dev); +- dev; +- uclass_next_device(&dev)) { +- pr_debug("probe pincontrol = %s\n", dev->name); +- } ++ if (CONFIG_IS_ENABLED(DM_GPIO_HOG)) ++ gpio_hog_probe_all(); + + board_key_check(); + ++ if (board_is_ev1()) ++ board_ev1_init(); ++ + #ifdef CONFIG_DM_REGULATOR + if (board_is_dk2()) + dk2_i2c1_fix(); +@@ -641,8 +727,10 @@ int board_init(void) + + sysconf_init(); + +- if (CONFIG_IS_ENABLED(CONFIG_LED)) ++ if (CONFIG_IS_ENABLED(LED)) { + led_default_state(); ++ setup_led(LEDST_ON); ++ } + + return 0; + } +@@ -661,10 +749,19 @@ int board_late_init(void) + fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible", + &fdt_compat_len); + if (fdt_compat && fdt_compat_len) { +- if (strncmp(fdt_compat, "st,", 3) != 0) ++ if (strncmp(fdt_compat, "st,", 3) != 0) { + env_set("board_name", fdt_compat); +- else ++ } else { ++ char dtb_name[256]; ++ int buf_len = sizeof(dtb_name); ++ + env_set("board_name", fdt_compat + 3); ++ ++ strncpy(dtb_name, fdt_compat + 3, buf_len); ++ buf_len -= strlen(fdt_compat + 3); ++ strncat(dtb_name, ".dtb", buf_len); ++ env_set("fdtfile", dtb_name); ++ } + } + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_GET_DRIVER(stm32mp_bsec), +@@ -690,7 +787,8 @@ int board_late_init(void) + + /* Check the boot-source to disable bootdelay */ + boot_device = env_get("boot_device"); +- if (!strcmp(boot_device, "serial") || !strcmp(boot_device, "usb")) ++ if (boot_device && ++ (!strcmp(boot_device, "serial") || !strcmp(boot_device, "usb"))) + env_set("bootdelay", "0"); + + return 0; +@@ -781,6 +879,11 @@ enum env_location env_get_location(enum env_operation op, int prio) + return ENVL_UNKNOWN; + + switch (bootmode & TAMP_BOOT_DEVICE_MASK) { ++#ifdef CONFIG_ENV_IS_IN_MMC ++ case BOOT_FLASH_SD: ++ case BOOT_FLASH_EMMC: ++ return ENVL_MMC; ++#endif + #ifdef CONFIG_ENV_IS_IN_EXT4 + case BOOT_FLASH_SD: + case BOOT_FLASH_EMMC: +@@ -788,6 +891,7 @@ enum env_location env_get_location(enum env_operation op, int prio) + #endif + #ifdef CONFIG_ENV_IS_IN_UBI + case BOOT_FLASH_NAND: ++ case BOOT_FLASH_SPINAND: + return ENVL_UBI; + #endif + #ifdef CONFIG_ENV_IS_IN_SPI_FLASH +@@ -822,105 +926,12 @@ const char *env_ext4_get_dev_part(void) + } + #endif + +-#ifdef CONFIG_SYS_MTDPARTS_RUNTIME +- +-#define MTDPARTS_LEN 256 +-#define MTDIDS_LEN 128 +- +-/** +- * The mtdparts_nand0 and mtdparts_nor0 variable tends to be long. +- * If we need to access it before the env is relocated, then we need +- * to use our own stack buffer. gd->env_buf will be too small. +- * +- * @param buf temporary buffer pointer MTDPARTS_LEN long +- * @return mtdparts variable string, NULL if not found +- */ +-static const char *env_get_mtdparts(const char *str, char *buf) ++#if defined(CONFIG_ENV_IS_IN_MMC) ++int mmc_get_env_dev(void) + { +- if (gd->flags & GD_FLG_ENV_READY) +- return env_get(str); +- if (env_get_f(str, buf, MTDPARTS_LEN) != -1) +- return buf; +- +- return NULL; +-} +- +-/** +- * update the variables "mtdids" and "mtdparts" with content of mtdparts_ +- */ +-static void board_get_mtdparts(const char *dev, +- char *mtdids, +- char *mtdparts) +-{ +- char env_name[32] = "mtdparts_"; +- char tmp_mtdparts[MTDPARTS_LEN]; +- const char *tmp; +- +- /* name of env variable to read = mtdparts_ */ +- strcat(env_name, dev); +- tmp = env_get_mtdparts(env_name, tmp_mtdparts); +- if (tmp) { +- /* mtdids: "=, ...." */ +- if (mtdids[0] != '\0') +- strcat(mtdids, ","); +- strcat(mtdids, dev); +- strcat(mtdids, "="); +- strcat(mtdids, dev); +- +- /* mtdparts: "mtdparts=:>;..." */ +- if (mtdparts[0] != '\0') +- strncat(mtdparts, ";", MTDPARTS_LEN); +- else +- strcat(mtdparts, "mtdparts="); +- strncat(mtdparts, dev, MTDPARTS_LEN); +- strncat(mtdparts, ":", MTDPARTS_LEN); +- strncat(mtdparts, tmp, MTDPARTS_LEN); +- } +-} +- +-void board_mtdparts_default(const char **mtdids, const char **mtdparts) +-{ +- struct mtd_info *mtd; +- struct udevice *dev; +- static char parts[3 * MTDPARTS_LEN + 1]; +- static char ids[MTDIDS_LEN + 1]; +- static bool mtd_initialized; +- +- if (mtd_initialized) { +- *mtdids = ids; +- *mtdparts = parts; +- return; +- } +- +- memset(parts, 0, sizeof(parts)); +- memset(ids, 0, sizeof(ids)); +- +- /* probe all MTD devices */ +- for (uclass_first_device(UCLASS_MTD, &dev); +- dev; +- uclass_next_device(&dev)) { +- pr_debug("mtd device = %s\n", dev->name); +- } +- +- mtd = get_mtd_device_nm("nand0"); +- if (!IS_ERR_OR_NULL(mtd)) { +- board_get_mtdparts("nand0", ids, parts); +- put_mtd_device(mtd); +- } +- +- mtd = get_mtd_device_nm("spi-nand0"); +- if (!IS_ERR_OR_NULL(mtd)) { +- board_get_mtdparts("spi-nand0", ids, parts); +- put_mtd_device(mtd); +- } +- +- if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) +- board_get_mtdparts("nor0", ids, parts); ++ u32 bootmode = get_bootmode(); + +- mtd_initialized = true; +- *mtdids = ids; +- *mtdparts = parts; +- debug("%s:mtdids=%s & mtdparts=%s\n", __func__, ids, parts); ++ return (bootmode & TAMP_BOOT_INSTANCE_MASK) - 1; + } + #endif + +@@ -930,6 +941,7 @@ int ft_board_setup(void *blob, bd_t *bd) + #ifdef CONFIG_FDT_FIXUP_PARTITIONS + struct node_info nodes[] = { + { "st,stm32f469-qspi", MTD_DEV_TYPE_NOR, }, ++ { "st,stm32f469-qspi", MTD_DEV_TYPE_SPINAND}, + { "st,stm32mp15-fmc2", MTD_DEV_TYPE_NAND, }, + }; + fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); +@@ -939,148 +951,6 @@ int ft_board_setup(void *blob, bd_t *bd) + } + #endif + +-#ifdef CONFIG_SET_DFU_ALT_INFO +-#define DFU_ALT_BUF_LEN SZ_1K +- +-static void board_get_alt_info(const char *dev, char *buff) +-{ +- char var_name[32] = "dfu_alt_info_"; +- int ret; +- +- ALLOC_CACHE_ALIGN_BUFFER(char, tmp_alt, DFU_ALT_BUF_LEN); +- +- /* name of env variable to read = dfu_alt_info_ */ +- strcat(var_name, dev); +- ret = env_get_f(var_name, tmp_alt, DFU_ALT_BUF_LEN); +- if (ret) { +- if (buff[0] != '\0') +- strcat(buff, "&"); +- strncat(buff, tmp_alt, DFU_ALT_BUF_LEN); +- } +-} +- +-void set_dfu_alt_info(char *interface, char *devstr) +-{ +- struct udevice *dev; +- struct mtd_info *mtd; +- +- ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); +- +- if (env_get("dfu_alt_info")) +- return; +- +- memset(buf, 0, sizeof(buf)); +- +- /* probe all MTD devices */ +- mtd_probe_devices(); +- +- board_get_alt_info("ram", buf); +- +- if (!uclass_get_device(UCLASS_MMC, 0, &dev)) +- board_get_alt_info("mmc0", buf); +- +- if (!uclass_get_device(UCLASS_MMC, 1, &dev)) +- board_get_alt_info("mmc1", buf); +- +- if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) +- board_get_alt_info("nor0", buf); +- +- mtd = get_mtd_device_nm("nand0"); +- if (!IS_ERR_OR_NULL(mtd)) +- board_get_alt_info("nand0", buf); +- +- mtd = get_mtd_device_nm("spi-nand0"); +- if (!IS_ERR_OR_NULL(mtd)) +- board_get_alt_info("spi-nand0", buf); +- +-#ifdef CONFIG_DFU_VIRT +- strncat(buf, "&virt 0=OTP", DFU_ALT_BUF_LEN); +- +- if (IS_ENABLED(CONFIG_PMIC_STPMIC1)) +- strncat(buf, "&virt 1=PMIC", DFU_ALT_BUF_LEN); +-#endif +- +- env_set("dfu_alt_info", buf); +- puts("DFU alt info setting: done\n"); +-} +- +-#if CONFIG_IS_ENABLED(DFU_VIRT) +-#include +-#include +- +-int dfu_otp_read(u64 offset, u8 *buffer, long *size) +-{ +- struct udevice *dev; +- int ret; +- +- ret = uclass_get_device_by_driver(UCLASS_MISC, +- DM_GET_DRIVER(stm32mp_bsec), +- &dev); +- if (ret) +- return ret; +- +- ret = misc_read(dev, offset + STM32_BSEC_OTP_OFFSET, buffer, *size); +- if (ret >= 0) { +- *size = ret; +- ret = 0; +- } +- +- return 0; +-} +- +-int dfu_pmic_read(u64 offset, u8 *buffer, long *size) +-{ +- int ret; +-#ifdef CONFIG_PMIC_STPMIC1 +- struct udevice *dev; +- +- ret = uclass_get_device_by_driver(UCLASS_MISC, +- DM_GET_DRIVER(stpmic1_nvm), +- &dev); +- if (ret) +- return ret; +- +- ret = misc_read(dev, 0xF8 + offset, buffer, *size); +- if (ret >= 0) { +- *size = ret; +- ret = 0; +- } +- if (ret == -EACCES) { +- *size = 0; +- ret = 0; +- } +-#else +- pr_err("PMIC update not supported"); +- ret = -EOPNOTSUPP; +-#endif +- +- return ret; +-} +- +-int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset, +- void *buf, long *len) +-{ +- switch (dfu->data.virt.dev_num) { +- case 0x0: +- return dfu_otp_read(offset, buf, len); +- case 0x1: +- return dfu_pmic_read(offset, buf, len); +- } +- *len = 0; +- return 0; +-} +- +-int __weak dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size) +-{ +- *size = SZ_1K; +- +- return 0; +-} +- +-#endif +- +-#endif +- + static void board_copro_image_process(ulong fw_image, size_t fw_size) + { + int ret, id = 0; /* Copro id fixed to 0 as only one coproc on mp1 */ +@@ -1096,10 +966,8 @@ static void board_copro_image_process(ulong fw_image, size_t fw_size) + printf("Load Remote Processor %d with data@addr=0x%08lx %u bytes:%s\n", + id, fw_image, fw_size, ret ? " Failed!" : " Success!"); + +- if (!ret) { ++ if (!ret) + rproc_start(id); +- env_set("copro_state", "booted"); +- } + } + + U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process); +diff --git a/board/sunxi/board.c b/board/sunxi/board.c +index b9450a0..f02141d 100644 +--- a/board/sunxi/board.c ++++ b/board/sunxi/board.c +@@ -706,7 +706,7 @@ int g_dnl_board_usb_cable_connected(void) + + ret = generic_phy_init(&phy); + if (ret) { +- pr_err("failed to init %s USB PHY\n", dev->name); ++ pr_debug("failed to init %s USB PHY\n", dev->name); + return ret; + } + +diff --git a/doc/board/index.rst b/doc/board/index.rst +index 00e72f5..21fddd2 100644 +--- a/doc/board/index.rst ++++ b/doc/board/index.rst +@@ -15,4 +15,5 @@ Board-specific doc + intel/index + renesas/index + sifive/index ++ st/index + xilinx/index +diff --git a/doc/board/st/index.rst b/doc/board/st/index.rst +new file mode 100644 +index 0000000..91f1d51 +--- /dev/null ++++ b/doc/board/st/index.rst +@@ -0,0 +1,9 @@ ++.. SPDX-License-Identifier: GPL-2.0+ ++ ++STMicroelectronics ++================== ++ ++.. toctree:: ++ :maxdepth: 2 ++ ++ stm32mp1 +diff --git a/doc/board/st/stm32mp1.rst b/doc/board/st/stm32mp1.rst +new file mode 100644 +index 0000000..62de184 +--- /dev/null ++++ b/doc/board/st/stm32mp1.rst +@@ -0,0 +1,624 @@ ++.. SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++.. sectionauthor:: Patrick Delaunay ++ ++STM32MP15x boards ++================= ++ ++This is a quick instruction for setup STM32MP15x boards. ++ ++Supported devices ++----------------- ++ ++U-Boot supports STMP32MP15x SoCs: ++ ++ - STM32MP157 ++ - STM32MP153 ++ - STM32MP151 ++ ++The STM32MP15x is a Cortex-A 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 ++ ++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 ++ ++Everything is supported in Linux but U-Boot is limited to: ++ ++ 1. UART ++ 2. SD card/MMC controller (SDMMC) ++ 3. NAND controller (FMC) ++ 4. NOR controller (QSPI) ++ 5. USB controller (OTG DWC2) ++ 6. Ethernet controller ++ ++And the necessary drivers ++ ++ 1. I2C ++ 2. STPMIC1 (PMIC and regulator) ++ 3. Clock, Reset, Sysreset ++ 4. Fuse ++ ++Currently the following boards are supported: ++ ++ + stm32mp157a-avenger96.dts ++ + 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 ++ ++Boot Sequences ++-------------- ++ ++3 boot configurations are supported with: ++ +++----------+------------------------+-------------------------+--------------+ ++| **ROM** | **FSBL** | **SSBL** | **OS** | +++ **code** +------------------------+-------------------------+--------------+ ++| | First Stage Bootloader | Second Stage Bootloader | Linux Kernel | +++ +------------------------+-------------------------+--------------+ ++| | embedded RAM | DDR | +++----------+------------------------+-------------------------+--------------+ ++ ++The **Trusted** boot chain ++`````````````````````````` ++ ++defconfig_file : stm32mp15_trusted_defconfig ++ ++ +-------------+-------------------------+------------+-------+ ++ | ROM code | FSBL | SSBL | OS | ++ + +-------------------------+------------+-------+ ++ | |Trusted Firmware-A (TF-A)| U-Boot | Linux | ++ +-------------+-------------------------+------------+-------+ ++ | 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. ++ ++The **Basic** boot chain ++```````````````````````` ++ ++defconfig_file : stm32mp15_basic_defconfig ++ ++ +-------------+------------+------------+-------+ ++ | ROM code | FSBL | SSBL | OS | ++ + +------------+------------+-------+ ++ | |U-Boot SPL | U-Boot | Linux | ++ +-------------+------------+------------+-------+ ++ | TrustZone | | PSCI from U-Boot | ++ +-------------+------------+------------+-------+ ++ ++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. ++ ++Each board is configured only with the associated device tree. ++ ++Device Tree Selection ++--------------------- ++ ++You need to select the appropriate device tree for your board, ++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 ++ ++ + stm32mp157a-avenger96 ++ ++Build Procedure ++--------------- ++ ++1. Install the required tools for U-Boot ++ ++ * install package needed in U-Boot makefile ++ (libssl-dev, swig, libpython-dev...) ++ ++ * install ARMv7 toolchain for 32bit Cortex-A (from Linaro, ++ from SDK for STM32MP15x, or any crosstoolchains from your distribution) ++ (you can use any gcc cross compiler compatible with U-Boot) ++ ++2. Set the cross compiler:: ++ ++ # export CROSS_COMPILE=/path/to/toolchain/arm-linux-gnueabi- ++ ++3. Select the output directory (optional):: ++ ++ # export KBUILD_OUTPUT=/path/to/output ++ ++ for example: use one output directory for each configuration:: ++ ++ # export KBUILD_OUTPUT=stm32mp15_trusted ++ # export KBUILD_OUTPUT=stm32mp15_basic ++ ++ you can build outside of code directory:: ++ ++ # export KBUILD_OUTPUT=../build/stm32mp15_trusted ++ ++4. Configure U-Boot:: ++ ++ # make ++ ++ with : ++ ++ - For **trusted** boot mode : **stm32mp15_trusted_defconfig** ++ - For basic boot mode: stm32mp15_basic_defconfig ++ ++5. Configure the device-tree and build the U-Boot image:: ++ ++ # make DEVICE_TREE= all ++ ++ Examples: ++ ++ a) trusted boot on ev1:: ++ ++ # export KBUILD_OUTPUT=stm32mp15_trusted ++ # make stm32mp15_trusted_defconfig ++ # make DEVICE_TREE=stm32mp157c-ev1 all ++ ++ b) trusted with OP-TEE boot on dk2:: ++ ++ # export KBUILD_OUTPUT=stm32mp15_trusted ++ # make stm32mp15_trusted_defconfig ++ # make DEVICE_TREE=stm32mp157c-dk2 all ++ ++ c) basic boot on ev1:: ++ ++ # export KBUILD_OUTPUT=stm32mp15_basic ++ # make stm32mp15_basic_defconfig ++ # make DEVICE_TREE=stm32mp157c-ev1 all ++ ++ d) basic boot on ed1:: ++ ++ # export KBUILD_OUTPUT=stm32mp15_basic ++ # make stm32mp15_basic_defconfig ++ # make DEVICE_TREE=stm32mp157c-ed1 all ++ ++ e) basic boot on dk1:: ++ ++ # export KBUILD_OUTPUT=stm32mp15_basic ++ # make stm32mp15_basic_defconfig ++ # make DEVICE_TREE=stm32mp157a-dk1 all ++ ++ f) basic boot on avenger96:: ++ ++ # export KBUILD_OUTPUT=stm32mp15_basic ++ # make stm32mp15_basic_defconfig ++ # make DEVICE_TREE=stm32mp157a-avenger96 all ++ ++6. Output files ++ ++ BootRom and TF-A expect binaries with STM32 image header ++ 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** ++ ++ - For Basic boot ++ ++ - FSBL = spl/u-boot-spl.stm32 ++ - SSBL = u-boot.img ++ ++Switch Setting for Boot Mode ++---------------------------- ++ ++You can select the boot mode, on the board with one switch, to select ++the boot pin values = BOOT0, BOOT1, BOOT2 ++ ++ +-------------+---------+---------+---------+ ++ |*Boot Mode* | *BOOT2* | *BOOT1* | *BOOT0* | ++ +=============+=========+=========+=========+ ++ | Recovery | 0 | 0 | 0 | ++ +-------------+---------+---------+---------+ ++ | NOR | 0 | 0 | 1 | ++ +-------------+---------+---------+---------+ ++ | eMMC | 0 | 1 | 0 | ++ +-------------+---------+---------+---------+ ++ | NAND | 0 | 1 | 1 | ++ +-------------+---------+---------+---------+ ++ | Reserved | 1 | 0 | 0 | ++ +-------------+---------+---------+---------+ ++ | SD-Card | 1 | 0 | 1 | ++ +-------------+---------+---------+---------+ ++ | Recovery | 1 | 1 | 0 | ++ +-------------+---------+---------+---------+ ++ | 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 ++ with only 2 pins available (BOOT1 is forced to 0 and NOR not supported), ++ the possible value becomes: ++ ++ +-------------+---------+---------+ ++ |*Boot Mode* | *BOOT2* | *BOOT0* | ++ +=============+=========+=========+ ++ | Recovery | 0 | 0 | ++ +-------------+---------+---------+ ++ | NOR (NA)| 0 | 1 | ++ +-------------+---------+---------+ ++ | Reserved | 1 | 0 | ++ +-------------+---------+---------+ ++ | SD-Card | 1 | 1 | ++ +-------------+---------+---------+ ++ ++Recovery is a boot from serial link (UART/USB) and it is used with ++STM32CubeProgrammer tool to load executable in RAM and to update the flash ++devices available on the board (NOR/NAND/eMMC/SD card). ++ ++The communication between HOST and board is based on ++ ++ - for UARTs : the uart protocol used with all MCU STM32 ++ - for USB : based on USB DFU 1.1 (without the ST extensions used on MCU STM32) ++ ++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 ++ ++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 | ++ +-------+--------+---------+-------------+ ++ ++Add a 4th partition (Rootfs) marked bootable with a file extlinux.conf ++following the Generic Distribution feature (doc/README.distro for use). ++ ++According the used card reader select the correct block device ++(for example /dev/sdx or /dev/mmcblk0). ++ ++In the next example, it is /dev/mmcblk0 ++ ++For example: with gpt table with 128 entries ++ ++a) remove previous formatting:: ++ ++ # sgdisk -o /dev/ ++ ++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 4:5154: -c 4:rootfs \ ++ -p /dev/ ++ ++ With other partition for kernel one partition rootfs for kernel. ++ ++c) copy the FSBL (2 times) and SSBL file on the correct partition. ++ in this example in partition 1 to 3 ++ ++ for basic boot mode : = /dev/mmcblk0:: ++ ++ # dd if=u-boot-spl.stm32 of=/dev/mmcblk0p1 ++ # dd if=u-boot-spl.stm32 of=/dev/mmcblk0p2 ++ # dd if=u-boot.img of=/dev/mmcblk0p3 ++ ++ for trusted boot mode: :: ++ ++ # dd if=tf-a.stm32 of=/dev/mmcblk0p1 ++ # dd if=tf-a.stm32 of=/dev/mmcblk0p2 ++ # dd if=u-boot.stm32 of=/dev/mmcblk0p3 ++ ++To boot from SD card, select BootPinMode = 1 0 1 and reset. ++ ++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). ++ ++To boot from SD card, select BootPinMode = 1 0 1 and reset. ++ ++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" ++ # 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 u-boot-spl.stm32 ++ # mmc dev 1 ++ # mmc partconf 1 1 1 1 ++ # mmc write ${fileaddr} 0 200 ++ # mmc partconf 1 1 1 0 ++ ++c) copy U-Boot in first GPT partition of eMMC:: ++ ++ # ext4load mmc 0:4 0xC0000000 u-boo t.img ++ # mmc dev 1 ++ # part start mmc 1 1 partstart ++ # mmc write ${fileaddr} ${partstart} ${filesize} ++ ++To boot from eMMC, select BootPinMode = 0 1 0 and reset. ++ ++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 : ++ ++ - 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 ++on bank 0 to access to internal OTP and lock them: ++ ++Prerequisite: check if a MAC address isn't yet programmed in OTP ++ ++1) check OTP: their value must be equal to 0:: ++ ++ STM32MP> fuse sense 0 57 2 ++ Sensing bank 0: ++ Word 0x00000039: 00000000 00000000 ++ ++2) check environment variable:: ++ ++ STM32MP> env print ethaddr ++ ## Error: "ethaddr" not defined ++ ++3) check lock status of fuse 57 & 58 (at 0x39, 0=unlocked, 1=locked):: ++ ++ STM32MP> fuse sense 0 0x10000039 2 ++ Sensing bank 0: ++ Word 0x10000039: 00000000 00000000 ++ ++Example to set mac address "12:34:56:78:9a:bc" ++ ++1) Write OTP:: ++ ++ STM32MP> fuse prog -y 0 57 0x78563412 0x0000bc9a ++ ++2) Read OTP:: ++ ++ STM32MP> fuse sense 0 57 2 ++ Sensing bank 0: ++ Word 0x00000039: 78563412 0000bc9a ++ ++3) Lock OTP:: ++ ++ STM32MP> fuse prog 0 0x10000039 1 1 ++ ++ STM32MP> fuse sense 0 0x10000039 2 ++ Sensing bank 0: ++ Word 0x10000039: 00000001 00000001 ++ ++4) next REBOOT, in the trace:: ++ ++ ### Setting environment from OTP MAC address = "12:34:56:78:9a:bc" ++ ++5) check env update:: ++ ++ STM32MP> env print ethaddr ++ ethaddr=12:34:56:78:9a:bc ++ ++.. warning:: This command can't be executed twice on the same board as ++ OTP are protected. It is already done for the board ++ provided by STMicroelectronics. ++ ++Coprocessor firmware ++-------------------- ++ ++U-Boot can boot the coprocessor before the kernel (coprocessor early boot). ++ ++a) Manuallly by using rproc commands (update the bootcmd) ++ ++ Configurations:: ++ ++ # env set name_copro "rproc-m4-fw.elf" ++ # env set dev_copro 0 ++ # env set loadaddr_copro 0xC1000000 ++ ++ Load binary from bootfs partition (number 4) on SD card (mmc 0):: ++ ++ # ext4load mmc 0:4 ${loadaddr_copro} ${name_copro} ++ ++ => ${filesize} variable is updated with the size of the loaded file. ++ ++ Start M4 firmware with remote proc command:: ++ ++ # rproc init ++ # rproc load ${dev_copro} ${loadaddr_copro} ${filesize} ++ # rproc start ${dev_copro}"00270033 ++ ++b) Automatically by using FIT feature and generic DISTRO bootcmd ++ ++ see examples in the board stm32mp1 directory: fit_copro_kernel_dtb.its ++ ++ Generate FIT including kernel + device tree + M4 firmware with cfg with M4 boot:: ++ ++ $> mkimage -f fit_copro_kernel_dtb.its fit_copro_kernel_dtb.itb ++ ++ Then using DISTRO configuration file: see extlinux.conf to select the correct ++ configuration: ++ ++ - stm32mp157c-ev1-m4 ++ - stm32mp157c-dk2-m4 ++ ++DFU support ++----------- ++ ++The DFU is supported on ST board. ++ ++The env variable dfu_alt_info is automatically build, and all ++the memory present on the ST boards are exported. ++ ++The dfu mode is started by the command:: ++ ++ STM32MP> dfu 0 ++ ++On EV1 board, booting from SD card, without OP-TEE:: ++ ++ STM32MP> dfu 0 list ++ DFU alt settings list: ++ dev: RAM alt: 0 name: uImage layout: RAM_ADDR ++ dev: RAM alt: 1 name: devicetree.dtb layout: RAM_ADDR ++ 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: 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: 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 ++ 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 ++ ++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=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" ++ 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=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=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" ++ Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=1, name="devicetree.dtb", serial="002700333338511934383330" ++ Found DFU: [0483:df11] ver=9999, devnum=99, cfg=1, intf=0, alt=0, name="uImage", serial="002700333338511934383330" ++ ++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 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 ++ $> dfu-util -d 0483:5720 -a 9 -D st-image-userfs-openstlinux-weston-stm32mp1.ext4 ++ ++- 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 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 ++ $> dfu-util -d 0483:5720 -a 16 -D st-image-userfs-openstlinux-weston-stm32mp1.ext4 ++ ++- you can also dump the OTP and the PMIC NVM with:: ++ ++ $> dfu-util -d 0483:5720 -a 19 -U otp.bin ++ $> dfu-util -d 0483:5720 -a 20 -U pmic.bin ++ ++ ++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) :: ++ ++ $> 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 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 25 -D st-image-weston-openstlinux-weston-stm32mp1_nand_4_256_multivolume.ubi +-- +2.7.4 + diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0003-ARM-v2018.11-stm32mp-r1-DEVICETREE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0003-ARM-v2018.11-stm32mp-r1-DEVICETREE.patch deleted file mode 100644 index d7bb243..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0003-ARM-v2018.11-stm32mp-r1-DEVICETREE.patch +++ /dev/null @@ -1,8320 +0,0 @@ -From b5942158e9598d71df00e2071259d7e408bf081f Mon Sep 17 00:00:00 2001 -From: christophe montaud -Date: Fri, 4 Jan 2019 15:07:12 +0100 -Subject: [PATCH 3/5] ARM v2018.11 stm32mp r1 DEVICETREE - ---- - arch/arm/dts/Makefile | 2 + - arch/arm/dts/stm32h743i-eval.dts | 2 +- - arch/arm/dts/stm32mp15-ddr.dtsi | 2 +- - arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binF.dtsi | 120 ++ - arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi | 121 ++ - arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binF.dtsi | 120 ++ - arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi | 21 +- - arch/arm/dts/stm32mp157-pinctrl.dtsi | 1474 ++++++++++++++++++-- - arch/arm/dts/stm32mp157-u-boot.dtsi | 73 +- - arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi | 190 +++ - arch/arm/dts/stm32mp157a-dk1.dts | 700 ++++++++++ - arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi | 6 + - arch/arm/dts/stm32mp157c-dk2.dts | 144 ++ - arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi | 109 +- - arch/arm/dts/stm32mp157c-ed1.dts | 396 +++--- - arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi | 19 +- - arch/arm/dts/stm32mp157c-ev1.dts | 657 ++++++++- - arch/arm/dts/stm32mp157c.dtsi | 1125 +++++++++++++-- - arch/arm/dts/stm32mp157caa-pinctrl.dtsi | 90 ++ - arch/arm/dts/stm32mp157cab-pinctrl.dtsi | 62 + - arch/arm/dts/stm32mp157cac-pinctrl.dtsi | 78 ++ - arch/arm/dts/stm32mp157cad-pinctrl.dtsi | 62 + - arch/sandbox/dts/test.dts | 8 + - doc/device-tree-bindings/arm/stm32.txt | 17 + - doc/device-tree-bindings/clock/st,stm32-rcc.txt | 37 + - doc/device-tree-bindings/clock/st,stm32mp1-rcc.txt | 60 + - doc/device-tree-bindings/i2c/i2c-stm32.txt | 98 +- - doc/device-tree-bindings/mfd/stpmic1.txt | 138 ++ - doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt | 59 + - doc/device-tree-bindings/mtd/stm32-quadspi.txt | 43 + - .../net/snps,dwc-qos-ethernet.txt | 3 + - doc/device-tree-bindings/net/stm32-dwmac.txt | 62 + - doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt | 65 +- - .../pinctrl/st,stm32-pinctrl.txt | 101 +- - doc/device-tree-bindings/power/st,stm32mp1-pwr.txt | 52 + - doc/device-tree-bindings/ram/st,stm32mp1-ddr.txt | 4 +- - .../regulator/st,stm32mp1-pwr-reg.txt | 31 + - doc/device-tree-bindings/serial/st,stm32-usart.txt | 88 ++ - .../watchdog/st,stm32-iwdg.txt | 26 + - include/dt-bindings/clock/stm32mp1-clks.h | 3 - - include/dt-bindings/mfd/st,stpmic1.h | 46 + - include/dt-bindings/mfd/st,stpmu1.h | 60 - - include/dt-bindings/pinctrl/stm32-pinfunc.h | 6 + - include/dt-bindings/rtc/rtc-stm32.h | 13 + - include/dt-bindings/soc/stm32-hdp.h | 108 ++ - 45 files changed, 6122 insertions(+), 579 deletions(-) - create mode 100644 arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binF.dtsi - create mode 100644 arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi - create mode 100644 arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binF.dtsi - create mode 100644 arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi - create mode 100644 arch/arm/dts/stm32mp157a-dk1.dts - create mode 100644 arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi - create mode 100644 arch/arm/dts/stm32mp157c-dk2.dts - create mode 100644 arch/arm/dts/stm32mp157caa-pinctrl.dtsi - create mode 100644 arch/arm/dts/stm32mp157cab-pinctrl.dtsi - create mode 100644 arch/arm/dts/stm32mp157cac-pinctrl.dtsi - create mode 100644 arch/arm/dts/stm32mp157cad-pinctrl.dtsi - create mode 100644 doc/device-tree-bindings/arm/stm32.txt - create mode 100644 doc/device-tree-bindings/clock/st,stm32mp1-rcc.txt - create mode 100644 doc/device-tree-bindings/mfd/stpmic1.txt - create mode 100644 doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt - create mode 100644 doc/device-tree-bindings/mtd/stm32-quadspi.txt - create mode 100644 doc/device-tree-bindings/net/stm32-dwmac.txt - create mode 100644 doc/device-tree-bindings/power/st,stm32mp1-pwr.txt - create mode 100644 doc/device-tree-bindings/regulator/st,stm32mp1-pwr-reg.txt - create mode 100644 doc/device-tree-bindings/serial/st,stm32-usart.txt - create mode 100644 doc/device-tree-bindings/watchdog/st,stm32-iwdg.txt - create mode 100644 include/dt-bindings/mfd/st,stpmic1.h - delete mode 100644 include/dt-bindings/mfd/st,stpmu1.h - create mode 100644 include/dt-bindings/rtc/rtc-stm32.h - create mode 100644 include/dt-bindings/soc/stm32-hdp.h - -diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile -index d36447d..a346021 100644 ---- a/arch/arm/dts/Makefile -+++ b/arch/arm/dts/Makefile -@@ -553,6 +553,8 @@ dtb-$(CONFIG_ARCH_ASPEED) += ast2500-evb.dtb - dtb-$(CONFIG_ARCH_STI) += stih410-b2260.dtb - - dtb-$(CONFIG_TARGET_STM32MP1) += \ -+ stm32mp157a-dk1.dtb \ -+ stm32mp157c-dk2.dtb \ - stm32mp157c-ed1.dtb \ - stm32mp157c-ev1.dtb - -diff --git a/arch/arm/dts/stm32h743i-eval.dts b/arch/arm/dts/stm32h743i-eval.dts -index 28c876b..368432f 100644 ---- a/arch/arm/dts/stm32h743i-eval.dts -+++ b/arch/arm/dts/stm32h743i-eval.dts -@@ -105,5 +105,5 @@ - <&pinctrl_sdmmc1_level_shifter>; - pinctrl-names = "default"; - bus-width = <4>; -- st,dirpol; -+ st,sig-dir; - }; -diff --git a/arch/arm/dts/stm32mp15-ddr.dtsi b/arch/arm/dts/stm32mp15-ddr.dtsi -index 4172c02..0164e34 100644 ---- a/arch/arm/dts/stm32mp15-ddr.dtsi -+++ b/arch/arm/dts/stm32mp15-ddr.dtsi -@@ -5,7 +5,7 @@ - - / { - soc { -- ddr: ddr@0x5A003000{ -+ ddr: ddr@5A003000{ - u-boot,dm-pre-reloc; - - compatible = "st,stm32mp1-ddr"; -diff --git a/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binF.dtsi b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binF.dtsi -new file mode 100644 -index 0000000..da83310 ---- /dev/null -+++ b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binF.dtsi -@@ -0,0 +1,120 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+/* STM32MP157C DK1/DK2 BOARD configuration -+ * 1x DDR3L 4Gb, 16-bit, 533MHz. -+ * Reference used NT5CC256M16DP-DI from NANYA -+ * -+ * DDR type / Platform DDR3/3L -+ * freq 533MHz -+ * width 16 -+ * datasheet 1 = MT41J256M16-187 / DDR3-1066 bin F -+ * DDR density 4 -+ * timing mode optimized -+ * Scheduling/QoS options : type = 2 -+ * address mapping : RBC -+ * Tc > + 85C : N -+ */ -+#define DDR_MEM_NAME "DDR3-1066/777 bin F 1x4Gb 533MHz v1.41" -+#define DDR_MEM_SPEED 533000 -+#define DDR_MEM_SIZE 0x20000000 -+ -+#define DDR_MSTR 0x00041401 -+#define DDR_MRCTRL0 0x00000010 -+#define DDR_MRCTRL1 0x00000000 -+#define DDR_DERATEEN 0x00000000 -+#define DDR_DERATEINT 0x00800000 -+#define DDR_PWRCTL 0x00000000 -+#define DDR_PWRTMG 0x00400010 -+#define DDR_HWLPCTL 0x00000000 -+#define DDR_RFSHCTL0 0x00210000 -+#define DDR_RFSHCTL3 0x00000000 -+#define DDR_RFSHTMG 0x0081008B -+#define DDR_CRCPARCTL0 0x00000000 -+#define DDR_DRAMTMG0 0x121B2414 -+#define DDR_DRAMTMG1 0x000A041B -+#define DDR_DRAMTMG2 0x0607080F -+#define DDR_DRAMTMG3 0x0050400C -+#define DDR_DRAMTMG4 0x07040607 -+#define DDR_DRAMTMG5 0x06060403 -+#define DDR_DRAMTMG6 0x02020002 -+#define DDR_DRAMTMG7 0x00000202 -+#define DDR_DRAMTMG8 0x00001005 -+#define DDR_DRAMTMG14 0x000000A0 -+#define DDR_ZQCTL0 0xC2000040 -+#define DDR_DFITMG0 0x02050105 -+#define DDR_DFITMG1 0x00000202 -+#define DDR_DFILPCFG0 0x07000000 -+#define DDR_DFIUPD0 0xC0400003 -+#define DDR_DFIUPD1 0x00000000 -+#define DDR_DFIUPD2 0x00000000 -+#define DDR_DFIPHYMSTR 0x00000000 -+#define DDR_ADDRMAP1 0x00070707 -+#define DDR_ADDRMAP2 0x00000000 -+#define DDR_ADDRMAP3 0x1F000000 -+#define DDR_ADDRMAP4 0x00001F1F -+#define DDR_ADDRMAP5 0x06060606 -+#define DDR_ADDRMAP6 0x0F060606 -+#define DDR_ADDRMAP9 0x00000000 -+#define DDR_ADDRMAP10 0x00000000 -+#define DDR_ADDRMAP11 0x00000000 -+#define DDR_ODTCFG 0x06000600 -+#define DDR_ODTMAP 0x00000001 -+#define DDR_SCHED 0x00000C01 -+#define DDR_SCHED1 0x00000000 -+#define DDR_PERFHPR1 0x01000001 -+#define DDR_PERFLPR1 0x08000200 -+#define DDR_PERFWR1 0x08000400 -+#define DDR_DBG0 0x00000000 -+#define DDR_DBG1 0x00000000 -+#define DDR_DBGCMD 0x00000000 -+#define DDR_POISONCFG 0x00000000 -+#define DDR_PCCFG 0x00000010 -+#define DDR_PCFGR_0 0x00010000 -+#define DDR_PCFGW_0 0x00000000 -+#define DDR_PCFGQOS0_0 0x02100C03 -+#define DDR_PCFGQOS1_0 0x00800100 -+#define DDR_PCFGWQOS0_0 0x01100C03 -+#define DDR_PCFGWQOS1_0 0x01000200 -+#define DDR_PCFGR_1 0x00010000 -+#define DDR_PCFGW_1 0x00000000 -+#define DDR_PCFGQOS0_1 0x02100C03 -+#define DDR_PCFGQOS1_1 0x00800040 -+#define DDR_PCFGWQOS0_1 0x01100C03 -+#define DDR_PCFGWQOS1_1 0x01000200 -+#define DDR_PGCR 0x01442E02 -+#define DDR_PTR0 0x0022AA5B -+#define DDR_PTR1 0x04841104 -+#define DDR_PTR2 0x042DA068 -+#define DDR_ACIOCR 0x10400812 -+#define DDR_DXCCR 0x00000C40 -+#define DDR_DSGCR 0xF200001F -+#define DDR_DCR 0x0000000B -+#define DDR_DTPR0 0x36D477D0 -+#define DDR_DTPR1 0x098B00D8 -+#define DDR_DTPR2 0x10023600 -+#define DDR_MR0 0x00000830 -+#define DDR_MR1 0x00000000 -+#define DDR_MR2 0x00000208 -+#define DDR_MR3 0x00000000 -+#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-1x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi -new file mode 100644 -index 0000000..16b8cf6 ---- /dev/null -+++ b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi -@@ -0,0 +1,121 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+/* STM32MP157C DK1/DK2 BOARD configuration -+ * 1x DDR3L 4Gb, 16-bit, 533MHz. -+ * Reference used NT5CC256M16DP-DI from NANYA -+ * -+ * DDR type / Platform DDR3/3L -+ * freq 533MHz -+ * width 16 -+ * datasheet 0 = MT41J256M16-187 / DDR3-1066 bin G -+ * DDR density 4 -+ * timing mode optimized -+ * Scheduling/QoS options : type = 2 -+ * address mapping : RBC -+ * Tc > + 85C : N -+ */ -+ -+#define DDR_MEM_NAME "DDR3-1066/888 bin G 1x4Gb 533MHz v1.41" -+#define DDR_MEM_SPEED 533000 -+#define DDR_MEM_SIZE 0x20000000 -+ -+#define DDR_MSTR 0x00041401 -+#define DDR_MRCTRL0 0x00000010 -+#define DDR_MRCTRL1 0x00000000 -+#define DDR_DERATEEN 0x00000000 -+#define DDR_DERATEINT 0x00800000 -+#define DDR_PWRCTL 0x00000000 -+#define DDR_PWRTMG 0x00400010 -+#define DDR_HWLPCTL 0x00000000 -+#define DDR_RFSHCTL0 0x00210000 -+#define DDR_RFSHCTL3 0x00000000 -+#define DDR_RFSHTMG 0x0081008B -+#define DDR_CRCPARCTL0 0x00000000 -+#define DDR_DRAMTMG0 0x121B2414 -+#define DDR_DRAMTMG1 0x000A041C -+#define DDR_DRAMTMG2 0x0608090F -+#define DDR_DRAMTMG3 0x0050400C -+#define DDR_DRAMTMG4 0x08040608 -+#define DDR_DRAMTMG5 0x06060403 -+#define DDR_DRAMTMG6 0x02020002 -+#define DDR_DRAMTMG7 0x00000202 -+#define DDR_DRAMTMG8 0x00001005 -+#define DDR_DRAMTMG14 0x000000A0 -+#define DDR_ZQCTL0 0xC2000040 -+#define DDR_DFITMG0 0x02060105 -+#define DDR_DFITMG1 0x00000202 -+#define DDR_DFILPCFG0 0x07000000 -+#define DDR_DFIUPD0 0xC0400003 -+#define DDR_DFIUPD1 0x00000000 -+#define DDR_DFIUPD2 0x00000000 -+#define DDR_DFIPHYMSTR 0x00000000 -+#define DDR_ADDRMAP1 0x00070707 -+#define DDR_ADDRMAP2 0x00000000 -+#define DDR_ADDRMAP3 0x1F000000 -+#define DDR_ADDRMAP4 0x00001F1F -+#define DDR_ADDRMAP5 0x06060606 -+#define DDR_ADDRMAP6 0x0F060606 -+#define DDR_ADDRMAP9 0x00000000 -+#define DDR_ADDRMAP10 0x00000000 -+#define DDR_ADDRMAP11 0x00000000 -+#define DDR_ODTCFG 0x06000600 -+#define DDR_ODTMAP 0x00000001 -+#define DDR_SCHED 0x00000C01 -+#define DDR_SCHED1 0x00000000 -+#define DDR_PERFHPR1 0x01000001 -+#define DDR_PERFLPR1 0x08000200 -+#define DDR_PERFWR1 0x08000400 -+#define DDR_DBG0 0x00000000 -+#define DDR_DBG1 0x00000000 -+#define DDR_DBGCMD 0x00000000 -+#define DDR_POISONCFG 0x00000000 -+#define DDR_PCCFG 0x00000010 -+#define DDR_PCFGR_0 0x00010000 -+#define DDR_PCFGW_0 0x00000000 -+#define DDR_PCFGQOS0_0 0x02100C03 -+#define DDR_PCFGQOS1_0 0x00800100 -+#define DDR_PCFGWQOS0_0 0x01100C03 -+#define DDR_PCFGWQOS1_0 0x01000200 -+#define DDR_PCFGR_1 0x00010000 -+#define DDR_PCFGW_1 0x00000000 -+#define DDR_PCFGQOS0_1 0x02100C03 -+#define DDR_PCFGQOS1_1 0x00800040 -+#define DDR_PCFGWQOS0_1 0x01100C03 -+#define DDR_PCFGWQOS1_1 0x01000200 -+#define DDR_PGCR 0x01442E02 -+#define DDR_PTR0 0x0022AA5B -+#define DDR_PTR1 0x04841104 -+#define DDR_PTR2 0x042DA068 -+#define DDR_ACIOCR 0x10400812 -+#define DDR_DXCCR 0x00000C40 -+#define DDR_DSGCR 0xF200001F -+#define DDR_DCR 0x0000000B -+#define DDR_DTPR0 0x38D488D0 -+#define DDR_DTPR1 0x098B00D8 -+#define DDR_DTPR2 0x10023600 -+#define DDR_MR0 0x00000840 -+#define DDR_MR1 0x00000000 -+#define DDR_MR2 0x00000208 -+#define DDR_MR3 0x00000000 -+#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-2x4Gb-1066-binF.dtsi b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binF.dtsi -new file mode 100644 -index 0000000..82781e7 ---- /dev/null -+++ b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binF.dtsi -@@ -0,0 +1,120 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+/* STM32MP157C ED1 BOARD configuration -+ * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology. -+ * Reference used NT5CC256M16DP-DI from NANYA -+ * -+ * DDR type / Platform DDR3/3L -+ * freq 533MHz -+ * width 32 -+ * datasheet 1 = MT41J256M16-187 / DDR3-1066 bin F -+ * DDR density 8 -+ * timing mode optimized -+ * Scheduling/QoS options : type = 2 -+ * address mapping : RBC -+ * Tc > + 85C : N -+ */ -+#define DDR_MEM_NAME "DDR3-1066/777 bin F 2x4Gb 533MHz v1.41" -+#define DDR_MEM_SPEED 533000 -+#define DDR_MEM_SIZE 0x40000000 -+ -+#define DDR_MSTR 0x00040401 -+#define DDR_MRCTRL0 0x00000010 -+#define DDR_MRCTRL1 0x00000000 -+#define DDR_DERATEEN 0x00000000 -+#define DDR_DERATEINT 0x00800000 -+#define DDR_PWRCTL 0x00000000 -+#define DDR_PWRTMG 0x00400010 -+#define DDR_HWLPCTL 0x00000000 -+#define DDR_RFSHCTL0 0x00210000 -+#define DDR_RFSHCTL3 0x00000000 -+#define DDR_RFSHTMG 0x0081008B -+#define DDR_CRCPARCTL0 0x00000000 -+#define DDR_DRAMTMG0 0x121B2414 -+#define DDR_DRAMTMG1 0x000A041B -+#define DDR_DRAMTMG2 0x0607080F -+#define DDR_DRAMTMG3 0x0050400C -+#define DDR_DRAMTMG4 0x07040607 -+#define DDR_DRAMTMG5 0x06060403 -+#define DDR_DRAMTMG6 0x02020002 -+#define DDR_DRAMTMG7 0x00000202 -+#define DDR_DRAMTMG8 0x00001005 -+#define DDR_DRAMTMG14 0x000000A0 -+#define DDR_ZQCTL0 0xC2000040 -+#define DDR_DFITMG0 0x02050105 -+#define DDR_DFITMG1 0x00000202 -+#define DDR_DFILPCFG0 0x07000000 -+#define DDR_DFIUPD0 0xC0400003 -+#define DDR_DFIUPD1 0x00000000 -+#define DDR_DFIUPD2 0x00000000 -+#define DDR_DFIPHYMSTR 0x00000000 -+#define DDR_ADDRMAP1 0x00080808 -+#define DDR_ADDRMAP2 0x00000000 -+#define DDR_ADDRMAP3 0x00000000 -+#define DDR_ADDRMAP4 0x00001F1F -+#define DDR_ADDRMAP5 0x07070707 -+#define DDR_ADDRMAP6 0x0F070707 -+#define DDR_ADDRMAP9 0x00000000 -+#define DDR_ADDRMAP10 0x00000000 -+#define DDR_ADDRMAP11 0x00000000 -+#define DDR_ODTCFG 0x06000600 -+#define DDR_ODTMAP 0x00000001 -+#define DDR_SCHED 0x00000C01 -+#define DDR_SCHED1 0x00000000 -+#define DDR_PERFHPR1 0x01000001 -+#define DDR_PERFLPR1 0x08000200 -+#define DDR_PERFWR1 0x08000400 -+#define DDR_DBG0 0x00000000 -+#define DDR_DBG1 0x00000000 -+#define DDR_DBGCMD 0x00000000 -+#define DDR_POISONCFG 0x00000000 -+#define DDR_PCCFG 0x00000010 -+#define DDR_PCFGR_0 0x00010000 -+#define DDR_PCFGW_0 0x00000000 -+#define DDR_PCFGQOS0_0 0x02100C03 -+#define DDR_PCFGQOS1_0 0x00800100 -+#define DDR_PCFGWQOS0_0 0x01100C03 -+#define DDR_PCFGWQOS1_0 0x01000200 -+#define DDR_PCFGR_1 0x00010000 -+#define DDR_PCFGW_1 0x00000000 -+#define DDR_PCFGQOS0_1 0x02100C03 -+#define DDR_PCFGQOS1_1 0x00800040 -+#define DDR_PCFGWQOS0_1 0x01100C03 -+#define DDR_PCFGWQOS1_1 0x01000200 -+#define DDR_PGCR 0x01442E02 -+#define DDR_PTR0 0x0022AA5B -+#define DDR_PTR1 0x04841104 -+#define DDR_PTR2 0x042DA068 -+#define DDR_ACIOCR 0x10400812 -+#define DDR_DXCCR 0x00000C40 -+#define DDR_DSGCR 0xF200001F -+#define DDR_DCR 0x0000000B -+#define DDR_DTPR0 0x36D477D0 -+#define DDR_DTPR1 0x098B00D8 -+#define DDR_DTPR2 0x10023600 -+#define DDR_MR0 0x00000830 -+#define DDR_MR1 0x00000000 -+#define DDR_MR2 0x00000208 -+#define DDR_MR3 0x00000000 -+#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-2x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi -index 8a5a821..82e7104 100644 ---- a/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi -+++ b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi -@@ -3,7 +3,7 @@ - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved - */ - --/* STM32MP157C ED1 and ED2 BOARD configuration -+/* STM32MP157C ED1 BOARD configuration - * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology. - * Reference used NT5CC256M16DP-DI from NANYA - * -@@ -15,10 +15,11 @@ - * timing mode optimized - * Scheduling/QoS options : type = 2 - * address mapping : RBC -+ * Tc > + 85C : N - */ - --#define DDR_MEM_NAME "DDR3-1066 bin G 2x4Gb 533MHz v1.36" --#define DDR_MEM_SPEED 533 -+#define DDR_MEM_NAME "DDR3-1066/888 bin G 2x4Gb 533MHz v1.41" -+#define DDR_MEM_SPEED 533000 - #define DDR_MEM_SIZE 0x40000000 - - #define DDR_MSTR 0x00040401 -@@ -62,7 +63,7 @@ - #define DDR_ADDRMAP11 0x00000000 - #define DDR_ODTCFG 0x06000600 - #define DDR_ODTMAP 0x00000001 --#define DDR_SCHED 0x00001201 -+#define DDR_SCHED 0x00000C01 - #define DDR_SCHED1 0x00000000 - #define DDR_PERFHPR1 0x01000001 - #define DDR_PERFLPR1 0x08000200 -@@ -74,15 +75,15 @@ - #define DDR_PCCFG 0x00000010 - #define DDR_PCFGR_0 0x00010000 - #define DDR_PCFGW_0 0x00000000 --#define DDR_PCFGQOS0_0 0x02100B03 -+#define DDR_PCFGQOS0_0 0x02100C03 - #define DDR_PCFGQOS1_0 0x00800100 --#define DDR_PCFGWQOS0_0 0x01100B03 -+#define DDR_PCFGWQOS0_0 0x01100C03 - #define DDR_PCFGWQOS1_0 0x01000200 - #define DDR_PCFGR_1 0x00010000 - #define DDR_PCFGW_1 0x00000000 --#define DDR_PCFGQOS0_1 0x02100B03 --#define DDR_PCFGQOS1_1 0x00800100 --#define DDR_PCFGWQOS0_1 0x01100B03 -+#define DDR_PCFGQOS0_1 0x02100C03 -+#define DDR_PCFGQOS1_1 0x00800040 -+#define DDR_PCFGWQOS0_1 0x01100C03 - #define DDR_PCFGWQOS1_1 0x01000200 - #define DDR_PGCR 0x01442E02 - #define DDR_PTR0 0x0022AA5B -@@ -100,7 +101,7 @@ - #define DDR_MR2 0x00000208 - #define DDR_MR3 0x00000000 - #define DDR_ODTCR 0x00010000 --#define DDR_ZQ0CR1 0x0000005B -+#define DDR_ZQ0CR1 0x00000038 - #define DDR_DX0GCR 0x0000CE81 - #define DDR_DX0DLLCR 0x40000000 - #define DDR_DX0DQTR 0xFFFFFFFF -diff --git a/arch/arm/dts/stm32mp157-pinctrl.dtsi b/arch/arm/dts/stm32mp157-pinctrl.dtsi -index 85da592..183d7ba 100644 ---- a/arch/arm/dts/stm32mp157-pinctrl.dtsi -+++ b/arch/arm/dts/stm32mp157-pinctrl.dtsi -@@ -14,6 +14,7 @@ - ranges = <0 0x50002000 0xa400>; - interrupt-parent = <&exti>; - st,syscfg = <&exti 0x60 0xff>; -+ hwlocks = <&hsem 0>; - pins-are-numbered; - - gpioa: gpio@50002000 { -@@ -24,8 +25,7 @@ - reg = <0x0 0x400>; - clocks = <&rcc GPIOA>; - st,bank-name = "GPIOA"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 0 16>; -+ status = "disabled"; - }; - - gpiob: gpio@50003000 { -@@ -36,8 +36,7 @@ - reg = <0x1000 0x400>; - clocks = <&rcc GPIOB>; - st,bank-name = "GPIOB"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 16 16>; -+ status = "disabled"; - }; - - gpioc: gpio@50004000 { -@@ -48,8 +47,7 @@ - reg = <0x2000 0x400>; - clocks = <&rcc GPIOC>; - st,bank-name = "GPIOC"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 32 16>; -+ status = "disabled"; - }; - - gpiod: gpio@50005000 { -@@ -60,8 +58,7 @@ - reg = <0x3000 0x400>; - clocks = <&rcc GPIOD>; - st,bank-name = "GPIOD"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 48 16>; -+ status = "disabled"; - }; - - gpioe: gpio@50006000 { -@@ -72,8 +69,7 @@ - reg = <0x4000 0x400>; - clocks = <&rcc GPIOE>; - st,bank-name = "GPIOE"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 64 16>; -+ status = "disabled"; - }; - - gpiof: gpio@50007000 { -@@ -84,8 +80,7 @@ - reg = <0x5000 0x400>; - clocks = <&rcc GPIOF>; - st,bank-name = "GPIOF"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 80 16>; -+ status = "disabled"; - }; - - gpiog: gpio@50008000 { -@@ -96,8 +91,7 @@ - reg = <0x6000 0x400>; - clocks = <&rcc GPIOG>; - st,bank-name = "GPIOG"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 96 16>; -+ status = "disabled"; - }; - - gpioh: gpio@50009000 { -@@ -108,8 +102,7 @@ - reg = <0x7000 0x400>; - clocks = <&rcc GPIOH>; - st,bank-name = "GPIOH"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 112 16>; -+ status = "disabled"; - }; - - gpioi: gpio@5000a000 { -@@ -120,8 +113,7 @@ - reg = <0x8000 0x400>; - clocks = <&rcc GPIOI>; - st,bank-name = "GPIOI"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 128 16>; -+ status = "disabled"; - }; - - gpioj: gpio@5000b000 { -@@ -132,8 +124,7 @@ - reg = <0x9000 0x400>; - clocks = <&rcc GPIOJ>; - st,bank-name = "GPIOJ"; -- ngpios = <16>; -- gpio-ranges = <&pinctrl 0 144 16>; -+ status = "disabled"; - }; - - gpiok: gpio@5000c000 { -@@ -144,8 +135,29 @@ - reg = <0xa000 0x400>; - clocks = <&rcc GPIOK>; - st,bank-name = "GPIOK"; -- ngpios = <8>; -- gpio-ranges = <&pinctrl 0 160 8>; -+ status = "disabled"; -+ }; -+ -+ adc1_in6_pins_a: adc1-in6 { -+ pins { -+ pinmux = ; -+ }; -+ }; -+ -+ adc12_ain_pins_a: adc12-ain-0 { -+ pins { -+ pinmux = , /* ADC1 in13 */ -+ , /* ADC1 in6 */ -+ , /* ADC2 in2 */ -+ ; /* ADC2 in6 */ -+ }; -+ }; -+ -+ adc12_usb_pwr_pins_a: adc12-usb-pwr-pins-0 { -+ pins { -+ pinmux = , /* ADC12 in18 */ -+ ; /* ADC12 in19 */ -+ }; - }; - - cec_pins_a: cec-0 { -@@ -153,180 +165,1374 @@ - pinmux = ; - bias-disable; - drive-open-drain; -- slew-rate = <0>; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ cec_pins_sleep_a: cec-sleep-0 { -+ pins { -+ pinmux = ; /* HDMI_CEC */ -+ }; -+ }; -+ -+ cec_pins_b: cec-1 { -+ pins { -+ pinmux = ; -+ bias-disable; -+ drive-open-drain; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ cec_pins_sleep_b: cec-sleep-1 { -+ pins { -+ pinmux = ; /* HDMI_CEC */ -+ }; -+ }; -+ -+ dac_ch1_pins_a: dac-ch1 { -+ pins { -+ pinmux = ; -+ }; -+ }; -+ -+ dac_ch2_pins_a: dac-ch2 { -+ pins { -+ pinmux = ; -+ }; -+ }; -+ -+ dcmi_pins_a: dcmi-0 { -+ pins { -+ pinmux = ,/* DCMI_HSYNC */ -+ ,/* DCMI_VSYNC */ -+ ,/* DCMI_PIXCLK */ -+ ,/* DCMI_D0 */ -+ ,/* DCMI_D1 */ -+ ,/* DCMI_D2 */ -+ ,/* DCMI_D3 */ -+ ,/* DCMI_D4 */ -+ ,/* DCMI_D5 */ -+ ,/* DCMI_D6 */ -+ ,/* DCMI_D7 */ -+ ,/* DCMI_D8 */ -+ ,/* DCMI_D9 */ -+ ,/* DCMI_D10 */ -+ ;/* DCMI_D11 */ -+ bias-disable; -+ }; -+ }; -+ -+ dcmi_sleep_pins_a: dcmi-sleep-0 { -+ pins { -+ pinmux = ,/* DCMI_HSYNC */ -+ ,/* DCMI_VSYNC */ -+ ,/* DCMI_PIXCLK */ -+ ,/* DCMI_D0 */ -+ ,/* DCMI_D1 */ -+ ,/* DCMI_D2 */ -+ ,/* DCMI_D3 */ -+ ,/* DCMI_D4 */ -+ ,/* DCMI_D5 */ -+ ,/* DCMI_D6 */ -+ ,/* DCMI_D7 */ -+ ,/* DCMI_D8 */ -+ ,/* DCMI_D9 */ -+ ,/* DCMI_D10 */ -+ ;/* DCMI_D11 */ -+ }; -+ }; -+ -+ dfsdm_clkout_pins_a: dfsdm-clkout-pins-0 { -+ pins { -+ pinmux = ; /* DFSDM_CKOUT */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ }; -+ -+ dfsdm_clkout_sleep_pins_a: dfsdm-clkout-sleep-pins-0 { -+ pins { -+ pinmux = ; /* DFSDM_CKOUT */ -+ }; -+ }; -+ -+ dfsdm_data1_pins_a: dfsdm-data1-pins-0 { -+ pins { -+ pinmux = ; /* DFSDM_DATA1 */ -+ }; -+ }; -+ -+ dfsdm_data1_sleep_pins_a: dfsdm-data1-sleep-pins-0 { -+ pins { -+ pinmux = ; /* DFSDM_DATA1 */ -+ }; -+ }; -+ -+ dfsdm_data3_pins_a: dfsdm-data3-pins-0 { -+ pins { -+ pinmux = ; /* DFSDM_DATA3 */ -+ }; -+ }; -+ -+ dfsdm_data3_sleep_pins_a: dfsdm-data3-sleep-pins-0 { -+ pins { -+ pinmux = ; /* DFSDM_DATA3 */ -+ }; -+ }; -+ -+ ethernet0_rgmii_pins_a: rgmii-0 { -+ pins1 { -+ pinmux = , /* ETH_RGMII_CLK125 */ -+ , /* ETH_RGMII_GTX_CLK */ -+ , /* ETH_RGMII_TXD0 */ -+ , /* ETH_RGMII_TXD1 */ -+ , /* ETH_RGMII_TXD2 */ -+ , /* ETH_RGMII_TXD3 */ -+ , /* ETH_RGMII_TX_CTL */ -+ , /* ETH_MDIO */ -+ ; /* ETH_MDC */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ pins2 { -+ pinmux = , /* ETH_RGMII_RXD0 */ -+ , /* ETH_RGMII_RXD1 */ -+ , /* ETH_RGMII_RXD2 */ -+ , /* ETH_RGMII_RXD3 */ -+ , /* ETH_RGMII_RX_CLK */ -+ ; /* ETH_RGMII_RX_CTL */ -+ bias-disable; -+ }; -+ }; -+ -+ ethernet0_rgmii_pins_sleep_a: rgmii-sleep-0 { -+ pins1 { -+ pinmux = , /* ETH_RGMII_CLK125 */ -+ , /* ETH_RGMII_GTX_CLK */ -+ , /* ETH_RGMII_TXD0 */ -+ , /* ETH_RGMII_TXD1 */ -+ , /* ETH_RGMII_TXD2 */ -+ , /* ETH_RGMII_TXD3 */ -+ , /* ETH_RGMII_TX_CTL */ -+ , /* ETH_MDIO */ -+ , /* ETH_MDC */ -+ , /* ETH_RGMII_RXD0 */ -+ , /* ETH_RGMII_RXD1 */ -+ , /* ETH_RGMII_RXD2 */ -+ , /* ETH_RGMII_RXD3 */ -+ , /* ETH_RGMII_RX_CLK */ -+ ; /* ETH_RGMII_RX_CTL */ -+ }; -+ }; -+ -+ fmc_pins_a: fmc-0 { -+ pins1 { -+ pinmux = , /* FMC_NOE */ -+ , /* FMC_NWE */ -+ , /* FMC_A16_FMC_CLE */ -+ , /* FMC_A17_FMC_ALE */ -+ , /* FMC_D0 */ -+ , /* FMC_D1 */ -+ , /* FMC_D2 */ -+ , /* FMC_D3 */ -+ , /* FMC_D4 */ -+ , /* FMC_D5 */ -+ , /* FMC_D6 */ -+ , /* FMC_D7 */ -+ ; /* FMC_NE2_FMC_NCE */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ pins2 { -+ pinmux = ; /* FMC_NWAIT */ -+ bias-pull-up; -+ }; -+ }; -+ -+ fmc_sleep_pins_a: fmc-sleep-0 { -+ pins { -+ pinmux = , /* FMC_NOE */ -+ , /* FMC_NWE */ -+ , /* FMC_A16_FMC_CLE */ -+ , /* FMC_A17_FMC_ALE */ -+ , /* FMC_D0 */ -+ , /* FMC_D1 */ -+ , /* FMC_D2 */ -+ , /* FMC_D3 */ -+ , /* FMC_D4 */ -+ , /* FMC_D5 */ -+ , /* FMC_D6 */ -+ , /* FMC_D7 */ -+ , /* FMC_NWAIT */ -+ ; /* FMC_NE2_FMC_NCE */ -+ }; -+ }; -+ -+ hdp0_pins_a: hdp0-0 { -+ pins { -+ pinmux = ; /* HDP0 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp0_pins_sleep_a: hdp0-sleep-0 { -+ pins { -+ pinmux = ; /* HDP0 */ -+ }; -+ }; -+ -+ hdp0_pins_b: hdp0-1 { -+ pins { -+ pinmux = ; /* HDP0 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp0_pins_sleep_b: hdp0-sleep-1 { -+ pins { -+ pinmux = ; /* HDP0 */ -+ }; -+ }; -+ -+ hdp1_pins_a: hdp1-0 { -+ pins { -+ pinmux = ; /* HDP1 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp1_pins_sleep_a: hdp1-sleep-0 { -+ pins { -+ pinmux = ; /* HDP1 */ -+ }; -+ }; -+ -+ hdp1_pins_b: hdp1-1 { -+ pins { -+ pinmux = ; /* HDP1 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp1_pins_sleep_b: hdp1-sleep-1 { -+ pins { -+ pinmux = ; /* HDP1 */ -+ }; -+ }; -+ -+ hdp2_pins_a: hdp2-0 { -+ pins { -+ pinmux = ; /* HDP2 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp2_pins_sleep_a: hdp2-sleep-0 { -+ pins { -+ pinmux = ; /* HDP2 */ -+ }; -+ }; -+ -+ hdp2_pins_b: hdp2-1 { -+ pins { -+ pinmux = ; /* HDP2 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp2_pins_sleep_b: hdp2-sleep-1 { -+ pins { -+ pinmux = ; /* HDP2 */ -+ }; -+ }; -+ -+ hdp3_pins_a: hdp3-0 { -+ pins { -+ pinmux = ; /* HDP3 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp3_pins_sleep_a: hdp3-sleep-0 { -+ pins { -+ pinmux = ; /* HDP3 */ -+ }; -+ }; -+ -+ hdp3_pins_b: hdp3-1 { -+ pins { -+ pinmux = ; /* HDP3 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp3_pins_sleep_b: hdp3-sleep-1 { -+ pins { -+ pinmux = ; /* HDP3 */ -+ }; -+ }; -+ -+ hdp4_pins_a: hdp4-0 { -+ pins { -+ pinmux = ; /* HDP4 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp4_pins_sleep_a: hdp4-sleep-0 { -+ pins { -+ pinmux = ; /* HDP4 */ -+ }; -+ }; -+ -+ hdp4_pins_b: hdp4-1 { -+ pins { -+ pinmux = ; /* HDP4 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp4_pins_sleep_b: hdp4-sleep-1 { -+ pins { -+ pinmux = ; /* HDP4 */ -+ }; -+ }; -+ -+ hdp5_pins_a: hdp5-0 { -+ pins { -+ pinmux = ; /* HDP5 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp5_pins_sleep_a: hdp5-sleep-0 { -+ pins { -+ pinmux = ; /* HDP5 */ -+ }; -+ }; -+ -+ hdp5_pins_b: hdp5-1 { -+ pins { -+ pinmux = ; /* HDP5 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp5_pins_sleep_b: hdp5-sleep-1 { -+ pins { -+ pinmux = ; /* HDP5 */ -+ }; -+ }; -+ -+ hdp6_pins_a: hdp6-0 { -+ pins { -+ pinmux = ; /* HDP6 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp6_pins_sleep_a: hdp6-sleep-0 { -+ pins { -+ pinmux = ; /* HDP6 */ -+ }; -+ }; -+ -+ hdp6_pins_b: hdp6-1 { -+ pins { -+ pinmux = ; /* HDP6 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp6_pins_sleep_b: hdp6-sleep-1 { -+ pins { -+ pinmux = ; /* HDP6 */ -+ }; -+ }; -+ -+ hdp7_pins_a: hdp7-0 { -+ pins { -+ pinmux = ; /* HDP7 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp7_pins_sleep_a: hdp7-sleep-0 { -+ pins { -+ pinmux = ; /* HDP7 */ -+ }; -+ }; -+ -+ hdp7_pins_b: hdp7-1 { -+ pins { -+ pinmux = ; /* HDP7 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <2>; -+ }; -+ }; -+ -+ hdp7_pins_sleep_b: hdp7-sleep-1 { -+ pins { -+ pinmux = ; /* HDP7 */ -+ }; -+ }; -+ -+ i2c1_pins_a: i2c1-0 { -+ pins { -+ pinmux = , /* I2C1_SCL */ -+ ; /* I2C1_SDA */ -+ bias-disable; -+ drive-open-drain; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ i2c1_pins_sleep_a: i2c1-1 { -+ pins { -+ pinmux = , /* I2C1_SCL */ -+ ; /* I2C1_SDA */ -+ }; -+ }; -+ -+ i2c2_pins_a: i2c2-0 { -+ pins { -+ pinmux = , /* I2C2_SCL */ -+ ; /* I2C2_SDA */ -+ bias-disable; -+ drive-open-drain; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ i2c2_pins_sleep_a: i2c2-1 { -+ pins { -+ pinmux = , /* I2C2_SCL */ -+ ; /* I2C2_SDA */ -+ }; -+ }; -+ -+ i2c5_pins_a: i2c5-0 { -+ pins { -+ pinmux = , /* I2C5_SCL */ -+ ; /* I2C5_SDA */ -+ bias-disable; -+ drive-open-drain; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ i2c5_pins_sleep_a: i2c5-1 { -+ pins { -+ pinmux = , /* I2C5_SCL */ -+ ; /* I2C5_SDA */ -+ -+ }; -+ }; -+ -+ i2s2_pins_a: i2s2-0 { -+ pins { -+ pinmux = , /* I2S2_SDO */ -+ , /* I2S2_WS */ -+ ; /* I2S2_CK */ -+ slew-rate = <1>; -+ drive-push-pull; -+ bias-disable; -+ }; -+ }; -+ -+ i2s2_pins_sleep_a: i2s2-1 { -+ pins { -+ pinmux = , /* I2S2_SDO */ -+ , /* I2S2_WS */ -+ ; /* I2S2_CK */ -+ }; -+ }; -+ -+ ltdc_pins_a: ltdc-a-0 { -+ pins { -+ pinmux = , /* LCD_CLK */ -+ , /* LCD_HSYNC */ -+ , /* LCD_VSYNC */ -+ , /* LCD_DE */ -+ , /* LCD_R0 */ -+ , /* LCD_R1 */ -+ , /* LCD_R2 */ -+ , /* LCD_R3 */ -+ , /* LCD_R4 */ -+ , /* LCD_R5 */ -+ , /* LCD_R6 */ -+ , /* LCD_R7 */ -+ , /* LCD_G0 */ -+ , /* LCD_G1 */ -+ , /* LCD_G2 */ -+ , /* LCD_G3 */ -+ , /* LCD_G4 */ -+ , /* LCD_G5 */ -+ , /* LCD_G6 */ -+ , /* LCD_G7 */ -+ , /* LCD_B0 */ -+ , /* LCD_B1 */ -+ , /* LCD_B2 */ -+ , /* LCD_B3 */ -+ , /* LCD_B4 */ -+ , /* LCD_B5 */ -+ , /* LCD_B6 */ -+ ; /* LCD_B7 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ }; -+ -+ ltdc_pins_sleep_a: ltdc-a-1 { -+ pins { -+ pinmux = , /* LCD_CLK */ -+ , /* LCD_HSYNC */ -+ , /* LCD_VSYNC */ -+ , /* LCD_DE */ -+ , /* LCD_R0 */ -+ , /* LCD_R1 */ -+ , /* LCD_R2 */ -+ , /* LCD_R3 */ -+ , /* LCD_R4 */ -+ , /* LCD_R5 */ -+ , /* LCD_R6 */ -+ , /* LCD_R7 */ -+ , /* LCD_G0 */ -+ , /* LCD_G1 */ -+ , /* LCD_G2 */ -+ , /* LCD_G3 */ -+ , /* LCD_G4 */ -+ , /* LCD_G5 */ -+ , /* LCD_G6 */ -+ , /* LCD_G7 */ -+ , /* LCD_B0 */ -+ , /* LCD_B1 */ -+ , /* LCD_B2 */ -+ , /* LCD_B3 */ -+ , /* LCD_B4 */ -+ , /* LCD_B5 */ -+ , /* LCD_B6 */ -+ ; /* LCD_B7 */ -+ }; -+ }; -+ -+ ltdc_pins_b: ltdc-b-0 { -+ pins { -+ pinmux = , /* LCD_CLK */ -+ , /* LCD_HSYNC */ -+ , /* LCD_VSYNC */ -+ , /* LCD_DE */ -+ , /* LCD_R0 */ -+ , /* LCD_R1 */ -+ , /* LCD_R2 */ -+ , /* LCD_R3 */ -+ , /* LCD_R4 */ -+ , /* LCD_R5 */ -+ , /* LCD_R6 */ -+ , /* LCD_R7 */ -+ , /* LCD_G0 */ -+ , /* LCD_G1 */ -+ , /* LCD_G2 */ -+ , /* LCD_G3 */ -+ , /* LCD_G4 */ -+ , /* LCD_G5 */ -+ , /* LCD_G6 */ -+ , /* LCD_G7 */ -+ , /* LCD_B0 */ -+ , /* LCD_B1 */ -+ , /* LCD_B2 */ -+ , /* LCD_B3 */ -+ , /* LCD_B4 */ -+ , /* LCD_B5 */ -+ , /* LCD_B6 */ -+ ; /* LCD_B7 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ }; -+ -+ ltdc_pins_sleep_b: ltdc-b-1 { -+ pins { -+ pinmux = , /* LCD_CLK */ -+ , /* LCD_HSYNC */ -+ , /* LCD_VSYNC */ -+ , /* LCD_DE */ -+ , /* LCD_R0 */ -+ , /* LCD_R1 */ -+ , /* LCD_R2 */ -+ , /* LCD_R3 */ -+ , /* LCD_R4 */ -+ , /* LCD_R5 */ -+ , /* LCD_R6 */ -+ , /* LCD_R7 */ -+ , /* LCD_G0 */ -+ , /* LCD_G1 */ -+ , /* LCD_G2 */ -+ , /* LCD_G3 */ -+ , /* LCD_G4 */ -+ , /* LCD_G5 */ -+ , /* LCD_G6 */ -+ , /* LCD_G7 */ -+ , /* LCD_B0 */ -+ , /* LCD_B1 */ -+ , /* LCD_B2 */ -+ , /* LCD_B3 */ -+ , /* LCD_B4 */ -+ , /* LCD_B5 */ -+ , /* LCD_B6 */ -+ ; /* LCD_B7 */ -+ }; -+ }; -+ -+ m_can1_pins_a: m-can1-0 { -+ pins1 { -+ pinmux = ; /* CAN1_TX */ -+ slew-rate = <0>; -+ drive-push-pull; -+ bias-disable; -+ }; -+ pins2 { -+ pinmux = ; /* CAN1_RX */ -+ bias-disable; -+ }; -+ }; -+ -+ m_can1_sleep_pins_a: m_can1-sleep@0 { -+ pins { -+ pinmux = , /* CAN1_TX */ -+ ; /* CAN1_RX */ -+ }; -+ }; -+ -+ pwm1_pins_a: pwm1-0 { -+ pins { -+ pinmux = , /* TIM1_CH1 */ -+ , /* TIM1_CH2 */ -+ ; /* TIM1_CH4 */ -+ bias-pull-down; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ pwm1_sleep_pins_a: pwm1-sleep-0 { -+ pins { -+ pinmux = , /* TIM1_CH1 */ -+ , /* TIM1_CH2 */ -+ ; /* TIM1_CH4 */ -+ }; -+ }; -+ -+ pwm2_pins_a: pwm2-0 { -+ pins { -+ pinmux = ; /* TIM2_CH4 */ -+ bias-pull-down; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ pwm2_sleep_pins_a: pwm2-sleep-0 { -+ pins { -+ pinmux = ; /* TIM2_CH4 */ -+ }; -+ }; -+ -+ pwm3_pins_a: pwm3-0 { -+ pins { -+ pinmux = ; /* TIM3_CH2 */ -+ bias-pull-down; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ pwm3_sleep_pins_a: pwm3-sleep-0 { -+ pins { -+ pinmux = ; /* TIM3_CH2 */ -+ }; -+ }; -+ -+ pwm4_pins_a: pwm4-0 { -+ pins { -+ pinmux = , /* TIM4_CH3 */ -+ ; /* TIM4_CH4 */ -+ bias-pull-down; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ pwm4_sleep_pins_a: pwm4-sleep-0 { -+ pins { -+ pinmux = , /* TIM4_CH3 */ -+ ; /* TIM4_CH4 */ -+ }; -+ }; -+ -+ pwm4_pins_b: pwm4-1 { -+ pins { -+ pinmux = ; /* TIM4_CH2 */ -+ bias-pull-down; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ pwm4_sleep_pins_b: pwm4-sleep-1 { -+ pins { -+ pinmux = ; /* TIM4_CH2 */ -+ }; -+ }; -+ -+ pwm5_pins_a: pwm5-0 { -+ pins { -+ pinmux = ; /* TIM5_CH2 */ -+ bias-pull-down; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ pwm5_sleep_pins_a: pwm5-sleep-0 { -+ pins { -+ pinmux = ; /* TIM5_CH2 */ -+ }; -+ }; -+ -+ pwm8_pins_a: pwm8-0 { -+ pins { -+ pinmux = ; /* TIM8_CH4 */ -+ bias-pull-down; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ pwm8_sleep_pins_a: pwm8-sleep-0 { -+ pins { -+ pinmux = ; /* TIM8_CH4 */ -+ }; -+ }; -+ -+ pwm12_pins_a: pwm12-0 { -+ pins { -+ pinmux = ; /* TIM12_CH1 */ -+ bias-pull-down; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ pwm12_sleep_pins_a: pwm12-sleep-0 { -+ pins { -+ pinmux = ; /* TIM12_CH1 */ -+ }; -+ }; -+ -+ qspi_bk1_pins_a: qspi-bk1-0 { -+ pins1 { -+ pinmux = , /* QSPI_BK1_IO0 */ -+ , /* QSPI_BK1_IO1 */ -+ , /* QSPI_BK1_IO2 */ -+ ; /* QSPI_BK1_IO3 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ pins2 { -+ pinmux = ; /* QSPI_BK1_NCS */ -+ bias-pull-up; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ }; -+ -+ qspi_bk1_sleep_pins_a: qspi-bk1-sleep-0 { -+ pins { -+ pinmux = , /* QSPI_BK1_IO0 */ -+ , /* QSPI_BK1_IO1 */ -+ , /* QSPI_BK1_IO2 */ -+ , /* QSPI_BK1_IO3 */ -+ ; /* QSPI_BK1_NCS */ -+ }; -+ }; -+ -+ qspi_bk2_pins_a: qspi-bk2-0 { -+ pins1 { -+ pinmux = , /* QSPI_BK2_IO0 */ -+ , /* QSPI_BK2_IO1 */ -+ , /* QSPI_BK2_IO2 */ -+ ; /* QSPI_BK2_IO3 */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ pins2 { -+ pinmux = ; /* QSPI_BK2_NCS */ -+ bias-pull-up; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ }; -+ -+ qspi_bk2_sleep_pins_a: qspi-bk2-sleep-0 { -+ pins { -+ pinmux = , /* QSPI_BK2_IO0 */ -+ , /* QSPI_BK2_IO1 */ -+ , /* QSPI_BK2_IO2 */ -+ , /* QSPI_BK2_IO3 */ -+ ; /* QSPI_BK2_NCS */ -+ }; -+ }; -+ -+ qspi_clk_pins_a: qspi-clk-0 { -+ pins { -+ pinmux = ; /* QSPI_CLK */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <3>; -+ }; -+ }; -+ -+ qspi_clk_sleep_pins_a: qspi-clk-sleep-0 { -+ pins { -+ pinmux = ; /* QSPI_CLK */ -+ }; -+ }; -+ -+ rtc_out2_rmp_pins_a: rtc-out2-rmp-pins@0 { -+ pins { -+ pinmux = ; /* RTC_OUT2_RMP */ -+ }; -+ }; -+ -+ sai2a_pins_a: sai2a-0 { -+ pins { -+ pinmux = , /* SAI2_SCK_A */ -+ , /* SAI2_SD_A */ -+ , /* SAI2_FS_A */ -+ ; /* SAI2_MCLK_A */ -+ slew-rate = <0>; -+ drive-push-pull; -+ bias-disable; -+ }; -+ }; -+ -+ sai2a_sleep_pins_a: sai2a-1 { -+ pins { -+ pinmux = , /* SAI2_SCK_A */ -+ , /* SAI2_SD_A */ -+ , /* SAI2_FS_A */ -+ ; /* SAI2_MCLK_A */ -+ }; -+ }; -+ -+ sai2b_pins_a: sai2b-0 { -+ pins1 { -+ pinmux = , /* SAI2_SCK_B */ -+ , /* SAI2_FS_B */ -+ ; /* SAI2_MCLK_B */ -+ slew-rate = <0>; -+ drive-push-pull; -+ bias-disable; -+ }; -+ pins2 { -+ pinmux = ; /* SAI2_SD_B */ -+ bias-disable; -+ }; -+ }; -+ -+ sai2b_sleep_pins_a: sai2b-1 { -+ pins { -+ pinmux = , /* SAI2_SD_B */ -+ , /* SAI2_SCK_B */ -+ , /* SAI2_FS_B */ -+ ; /* SAI2_MCLK_B */ -+ }; -+ }; -+ -+ sai2b_pins_b: sai2b-2 { -+ pins { -+ pinmux = ; /* SAI2_SD_B */ -+ bias-disable; -+ }; -+ }; -+ -+ sai2b_sleep_pins_b: sai2b-3 { -+ pins { -+ pinmux = ; /* SAI2_SD_B */ -+ }; -+ }; -+ -+ sai4a_pins_a: sai4a-0 { -+ pins { -+ pinmux = ; /* SAI4_SD_A */ -+ slew-rate = <0>; -+ drive-push-pull; -+ bias-disable; -+ }; -+ }; -+ -+ sai4a_sleep_pins_a: sai4a-1 { -+ pins { -+ pinmux = ; /* SAI4_SD_A */ -+ }; -+ }; -+ -+ sdmmc1_b4_pins_a: sdmmc1-b4-0 { -+ pins1 { -+ pinmux = , /* SDMMC1_D0 */ -+ , /* SDMMC1_D1 */ -+ , /* SDMMC1_D2 */ -+ , /* SDMMC1_D3 */ -+ ; /* SDMMC1_CMD */ -+ slew-rate = <1>; -+ drive-push-pull; -+ bias-disable; -+ }; -+ pins2 { -+ pinmux = ; /* SDMMC1_CK */ -+ slew-rate = <2>; -+ 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_CK */ -+ slew-rate = <2>; -+ drive-push-pull; -+ bias-disable; -+ }; -+ pins3 { -+ pinmux = ; /* SDMMC1_CMD */ -+ slew-rate = <1>; -+ drive-open-drain; -+ bias-disable; - }; - }; - -- i2c1_pins_a: i2c1-0 { -+ sdmmc1_b4_sleep_pins_a: sdmmc1-b4-sleep-0 { - pins { -- pinmux = , /* I2C1_SCL */ -- ; /* I2C1_SDA */ -- bias-disable; -- drive-open-drain; -- slew-rate = <0>; -+ pinmux = , /* SDMMC1_D0 */ -+ , /* SDMMC1_D1 */ -+ , /* SDMMC1_D2 */ -+ , /* SDMMC1_D3 */ -+ , /* SDMMC1_CK */ -+ ; /* SDMMC1_CMD */ - }; - }; - -- i2c2_pins_a: i2c2-0 { -+ sdmmc1_dir_pins_a: sdmmc1-dir-0 { -+ pins1 { -+ pinmux = , /* SDMMC1_D0DIR */ -+ , /* SDMMC1_D123DIR */ -+ ; /* SDMMC1_CDIR */ -+ slew-rate = <1>; -+ drive-push-pull; -+ bias-pull-up; -+ }; -+ pins2{ -+ pinmux = ; /* SDMMC1_CKIN */ -+ bias-pull-up; -+ }; -+ }; -+ -+ sdmmc1_dir_sleep_pins_a: sdmmc1-dir-sleep-0 { - pins { -- pinmux = , /* I2C2_SCL */ -- ; /* I2C2_SDA */ -- bias-disable; -+ pinmux = , /* SDMMC1_D0DIR */ -+ , /* SDMMC1_D123DIR */ -+ , /* SDMMC1_CDIR */ -+ ; /* SDMMC1_CKIN */ -+ }; -+ }; -+ -+ sdmmc2_b4_pins_a: sdmmc2-b4-0 { -+ pins1 { -+ pinmux = , /* SDMMC2_D0 */ -+ , /* SDMMC2_D1 */ -+ , /* SDMMC2_D2 */ -+ , /* SDMMC2_D3 */ -+ ; /* SDMMC2_CMD */ -+ slew-rate = <1>; -+ drive-push-pull; -+ bias-pull-up; -+ }; -+ pins2 { -+ pinmux = ; /* SDMMC2_CK */ -+ slew-rate = <2>; -+ 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_CK */ -+ slew-rate = <2>; -+ drive-push-pull; -+ bias-pull-up; -+ }; -+ pins3 { -+ pinmux = ; /* SDMMC2_CMD */ -+ slew-rate = <1>; - drive-open-drain; -- slew-rate = <0>; -+ bias-pull-up; - }; - }; - -- i2c5_pins_a: i2c5-0 { -+ sdmmc2_b4_sleep_pins_a: sdmmc2-b4-sleep-0 { - pins { -- pinmux = , /* I2C5_SCL */ -- ; /* I2C5_SDA */ -- bias-disable; -- drive-open-drain; -- slew-rate = <0>; -+ pinmux = , /* SDMMC2_D0 */ -+ , /* SDMMC2_D1 */ -+ , /* SDMMC2_D2 */ -+ , /* SDMMC2_D3 */ -+ , /* SDMMC2_CK */ -+ ; /* SDMMC2_CMD */ - }; - }; - -- pwm2_pins_a: pwm2-0 { -+ sdmmc2_d47_pins_a: sdmmc2-d47-0 { - pins { -- pinmux = ; /* TIM2_CH4 */ -- bias-pull-down; -+ pinmux = , /* SDMMC2_D4 */ -+ , /* SDMMC2_D5 */ -+ , /* SDMMC2_D6 */ -+ ; /* SDMMC2_D7 */ -+ slew-rate = <1>; - drive-push-pull; -- slew-rate = <0>; -+ bias-pull-up; - }; - }; - -- pwm8_pins_a: pwm8-0 { -+ sdmmc2_d47_sleep_pins_a: sdmmc2-d47-sleep-0 { - pins { -- pinmux = ; /* TIM8_CH4 */ -- bias-pull-down; -+ pinmux = , /* SDMMC2_D4 */ -+ , /* SDMMC2_D5 */ -+ , /* SDMMC2_D6 */ -+ ; /* SDMMC2_D7 */ -+ }; -+ }; -+ -+ sdmmc3_b4_pins_a: sdmmc3-b4-0 { -+ pins1 { -+ pinmux = , /* SDMMC3_D0 */ -+ , /* SDMMC3_D1 */ -+ , /* SDMMC3_D2 */ -+ , /* SDMMC3_D3 */ -+ ; /* SDMMC3_CMD */ -+ slew-rate = <1>; - drive-push-pull; -- slew-rate = <0>; -+ bias-pull-up; -+ }; -+ pins2 { -+ pinmux = ; /* SDMMC3_CK */ -+ slew-rate = <2>; -+ drive-push-pull; -+ bias-pull-up; - }; - }; - -- pwm12_pins_a: pwm12-0 { -- pins { -- pinmux = ; /* TIM12_CH1 */ -- bias-pull-down; -+ sdmmc3_b4_od_pins_a: sdmmc3-b4-od-0 { -+ pins1 { -+ pinmux = , /* SDMMC3_D0 */ -+ , /* SDMMC3_D1 */ -+ , /* SDMMC3_D2 */ -+ ; /* SDMMC3_D3 */ -+ slew-rate = <1>; - drive-push-pull; -- slew-rate = <0>; -+ bias-pull-up; -+ }; -+ pins2 { -+ pinmux = ; /* SDMMC3_CK */ -+ slew-rate = <2>; -+ drive-push-pull; -+ bias-pull-up; -+ }; -+ pins3 { -+ pinmux = ; /* SDMMC2_CMD */ -+ slew-rate = <1>; -+ drive-open-drain; -+ bias-pull-up; - }; - }; - -- qspi_clk_pins_a: qspi-clk-0 { -+ sdmmc3_b4_sleep_pins_a: sdmmc3-b4-sleep-0 { - pins { -- pinmux = ; /* QSPI_CLK */ -+ pinmux = , /* SDMMC3_D0 */ -+ , /* SDMMC3_D1 */ -+ , /* SDMMC3_D2 */ -+ , /* SDMMC3_D3 */ -+ , /* SDMMC3_CK */ -+ ; /* SDMMC3_CMD */ -+ }; -+ }; -+ -+ spdifrx_pins_a: spdifrx-0 { -+ pins { -+ pinmux = ; /* SPDIF_IN1 */ - bias-disable; -- drive-push-pull; -- slew-rate = <3>; - }; - }; - -- qspi_bk1_pins_a: qspi-bk1-0 { -+ spdifrx_sleep_pins_a: spdifrx-1 { -+ pins { -+ pinmux = ; /* SPDIF_IN1 */ -+ }; -+ }; -+ -+ spi4_pins_a: spi4-0 { - pins1 { -- pinmux = , /* QSPI_BK1_IO0 */ -- , /* QSPI_BK1_IO1 */ -- , /* QSPI_BK1_IO2 */ -- ; /* QSPI_BK1_IO3 */ -+ pinmux = , /* SPI4_SCK */ -+ ; /* SPI4_MOSI */ - bias-disable; - drive-push-pull; -- slew-rate = <3>; -+ slew-rate = <1>; - }; -+ - pins2 { -- pinmux = ; /* QSPI_BK1_NCS */ -- bias-pull-up; -- drive-push-pull; -- slew-rate = <3>; -+ pinmux = ; /* SPI4_MISO */ -+ bias-disable; - }; - }; - -- qspi_bk2_pins_a: qspi-bk2-0 { -+ spi4_sleep_pins_a: spi4-sleep-0 { -+ pins { -+ pinmux = , /* SPI4_SCK */ -+ , /* SPI4_MISO */ -+ ; /* SPI4_MOSI */ -+ }; -+ }; -+ -+ spi5_pins_a: spi5-0 { - pins1 { -- pinmux = , /* QSPI_BK2_IO0 */ -- , /* QSPI_BK2_IO1 */ -- , /* QSPI_BK2_IO2 */ -- ; /* QSPI_BK2_IO3 */ -+ pinmux = , /* SPI5_SCK */ -+ ; /* SPI5_MOSI */ - bias-disable; - drive-push-pull; -- slew-rate = <3>; -+ slew-rate = <1>; - }; -+ - pins2 { -- pinmux = ; /* QSPI_BK2_NCS */ -- bias-pull-up; -- drive-push-pull; -- slew-rate = <3>; -+ pinmux = ; /* SPI5_MISO */ -+ bias-disable; - }; - }; -- sdmmc1_b4_pins_a: sdmmc1-b4@0 { -+ -+ spi5_sleep_pins_a: spi5-sleep-0 { - pins { -- pinmux = , /* SDMMC1_D0 */ -- , /* SDMMC1_D1 */ -- , /* SDMMC1_D2 */ -- , /* SDMMC1_D3 */ -- , /* SDMMC1_CK */ -- ; /* SDMMC1_CMD */ -- slew-rate = <3>; -+ pinmux = , /* SPI5_SCK */ -+ , /* SPI5_MISO */ -+ ; /* SPI5_MOSI */ -+ }; -+ }; -+ -+ 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; - }; - }; - -- sdmmc1_dir_pins_a: sdmmc1-dir@0 { -+ uart4_sleep_pins_a: uart4-sleep-0 { - pins { -- pinmux = , /* SDMMC1_D0DIR */ -- , /* SDMMC1_D123DIR */ -- , /* SDMMC1_CDIR */ -- ; /* SDMMC1_CKIN */ -- slew-rate = <3>; -+ pinmux = , /* UART4_TX */ -+ ; /* UART4_RX */ -+ }; -+ }; -+ -+ usart2_pins_a: usart2-0 { -+ pins1 { -+ pinmux = , /* USART2_TX */ -+ ; /* USART2_RTS */ -+ bias-disable; - drive-push-pull; -- bias-pull-up; -+ slew-rate = <0>; -+ }; -+ pins2 { -+ pinmux = , /* USART2_RX */ -+ ; /* USART2_CTS_NSS */ -+ bias-disable; -+ }; -+ }; -+ -+ usart2_idle_pins_a: usart2-idle-0 { -+ pins1 { -+ pinmux = , /* USART2_TX */ -+ , /* USART2_RTS */ -+ ; /* USART2_CTS_NSS */ -+ }; -+ pins2 { -+ pinmux = ; /* USART2_RX */ -+ bias-disable; - }; - }; -- sdmmc2_b4_pins_a: sdmmc2-b4@0 { -+ -+ usart2_sleep_pins_a: usart2-sleep-0 { - pins { -- pinmux = , /* SDMMC2_D0 */ -- , /* SDMMC2_D1 */ -- , /* SDMMC2_D2 */ -- , /* SDMMC2_D3 */ -- , /* SDMMC2_CK */ -- ; /* SDMMC2_CMD */ -- slew-rate = <3>; -+ pinmux = , /* USART2_TX */ -+ , /* USART2_RTS */ -+ , /* USART2_RX */ -+ ; /* USART2_CTS_NSS */ -+ }; -+ }; -+ -+ usart3_pins_a: usart3-0 { -+ pins1 { -+ pinmux = , /* USART3_TX */ -+ ; /* USART3_RTS */ -+ bias-disable; - drive-push-pull; -- bias-pull-up; -+ slew-rate = <0>; -+ }; -+ pins2 { -+ pinmux = , /* USART3_RX */ -+ ; /* USART3_CTS_NSS */ -+ bias-disable; -+ }; -+ }; -+ -+ usart3_idle_pins_a: usart3-idle-0 { -+ pins1 { -+ pinmux = , /* USART3_TX */ -+ , /* USART3_RTS */ -+ ; /* USART3_CTS_NSS */ -+ }; -+ pins2 { -+ pinmux = ; /* USART3_RX */ -+ bias-disable; - }; - }; - -- sdmmc2_d47_pins_a: sdmmc2-d47@0 { -+ usart3_sleep_pins_a: usart3-sleep-0 { - pins { -- pinmux = , /* SDMMC2_D4 */ -- , /* SDMMC2_D5 */ -- , /* SDMMC2_D6 */ -- ; /* SDMMC2_D7 */ -- slew-rate = <3>; -- drive-push-pull; -- bias-pull-up; -+ pinmux = , /* USART3_TX */ -+ , /* USART3_RTS */ -+ , /* USART3_CTS_NSS */ -+ ; /* USART3_RX */ - }; - }; - -- uart4_pins_a: uart4-0 { -+ 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; - }; - }; - -+ usart3_idle_pins_b: usart3-idle-1 { -+ pins1 { -+ pinmux = , /* USART3_TX */ -+ , /* USART3_RTS */ -+ ; /* USART3_CTS_NSS */ -+ }; -+ pins2 { -+ pinmux = ; /* USART3_RX */ -+ bias-disable; -+ }; -+ }; -+ -+ usart3_sleep_pins_b: usart3-sleep-1 { -+ pins { -+ pinmux = , /* USART3_TX */ -+ , /* USART3_RTS */ -+ , /* USART3_CTS_NSS */ -+ ; /* USART3_RX */ -+ }; -+ }; -+ - usbotg_hs_pins_a: usbotg_hs-0 { - pins { - pinmux = ; /* OTG_ID */ - }; - }; -+ -+ usbotg_fs_dp_dm_pins_a: usbotg-fs-dp-dm-0 { -+ pins { -+ pinmux = , /* OTG_FS_DM */ -+ ; /* OTG_FS_DP */ -+ }; -+ }; - }; - - pinctrl_z: pin-controller-z@54004000 { -@@ -337,6 +1543,7 @@ - pins-are-numbered; - interrupt-parent = <&exti>; - st,syscfg = <&exti 0x60 0xff>; -+ hwlocks = <&hsem 0>; - - gpioz: gpio@54004000 { - gpio-controller; -@@ -347,8 +1554,17 @@ - clocks = <&rcc GPIOZ>; - st,bank-name = "GPIOZ"; - st,bank-ioport = <11>; -- ngpios = <8>; -- gpio-ranges = <&pinctrl_z 0 400 8>; -+ status = "disabled"; -+ }; -+ -+ btreg: bt_reg_on-0 { -+ pins { -+ pinmux = ; -+ drive-push-pull; -+ bias-pull-up; -+ output-high; -+ slew-rate = <0>; -+ }; - }; - - i2c4_pins_a: i2c4-0 { -@@ -360,6 +1576,36 @@ - slew-rate = <0>; - }; - }; -+ -+ i2c4_pins_sleep_a: i2c4-1 { -+ pins { -+ pinmux = , /* I2C4_SCL */ -+ ; /* I2C4_SDA */ -+ }; -+ }; -+ -+ spi1_pins_a: spi1-0 { -+ pins1 { -+ pinmux = , /* SPI1_SCK */ -+ ; /* SPI1_MOSI */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <1>; -+ }; -+ -+ pins2 { -+ pinmux = ; /* SPI1_MISO */ -+ bias-disable; -+ }; -+ }; -+ -+ spi1_sleep_pins_a: spi1-sleep-0 { -+ pins { -+ pinmux = , /* SPI1_SCK */ -+ , /* SPI1_MISO */ -+ ; /* SPI1_MOSI */ -+ }; -+ }; - }; - }; - }; -diff --git a/arch/arm/dts/stm32mp157-u-boot.dtsi b/arch/arm/dts/stm32mp157-u-boot.dtsi -index 90d13f3..035b1c6 100644 ---- a/arch/arm/dts/stm32mp157-u-boot.dtsi -+++ b/arch/arm/dts/stm32mp157-u-boot.dtsi -@@ -17,19 +17,31 @@ - gpio9 = &gpioj; - gpio10 = &gpiok; - gpio25 = &gpioz; -+ pinctrl0 = &pinctrl; -+ pinctrl1 = &pinctrl_z; -+ }; -+ -+ clocks { -+ u-boot,dm-pre-reloc; - }; - - config { - u-boot,dm-pre-reloc; - }; - -- clocks { -+ reboot { - u-boot,dm-pre-reloc; - }; - - soc { - u-boot,dm-pre-reloc; - -+ etzpc: etzpc@5C007000 { -+ compatible = "st,stm32mp1-etzpc"; -+ reg = <0x5C007000 0x400>; -+ status = "okay"; -+ }; -+ - stgen: stgen@5C008000 { - compatible = "st,stm32-stgen"; - reg = <0x5C008000 0x1000>; -@@ -39,19 +51,7 @@ - }; - }; - --&clk_hsi { -- u-boot,dm-pre-reloc; --}; -- --&clk_hse { -- u-boot,dm-pre-reloc; --}; -- --&clk_lse { -- u-boot,dm-pre-reloc; --}; -- --&clk_lsi { -+&bsec { - u-boot,dm-pre-reloc; - }; - -@@ -59,19 +59,19 @@ - u-boot,dm-pre-reloc; - }; - --&rcc { -+&clk_hsi { - u-boot,dm-pre-reloc; - }; - --&rcc_reboot { -+&clk_hse { - u-boot,dm-pre-reloc; - }; - --&pinctrl { -+&clk_lsi { - u-boot,dm-pre-reloc; - }; - --&pinctrl_z { -+&clk_lse { - u-boot,dm-pre-reloc; - }; - -@@ -134,3 +134,40 @@ - compatible = "st,stm32-gpio"; - 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-reloc; -+}; -+ -+&pinctrl { -+ u-boot,dm-pre-reloc; -+}; -+ -+&pinctrl_z { -+ u-boot,dm-pre-reloc; -+}; -+ -+&pwr { -+ u-boot,dm-pre-reloc; -+}; -+ -+&rcc { -+ u-boot,dm-pre-reloc; -+}; -+ -+&sdmmc1 { -+ compatible = "st,stm32-sdmmc2"; -+}; -+ -+&sdmmc2 { -+ compatible = "st,stm32-sdmmc2"; -+}; -+ -+&sdmmc3 { -+ compatible = "st,stm32-sdmmc2"; -+}; -diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi -new file mode 100644 -index 0000000..0f9ed9f ---- /dev/null -+++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi -@@ -0,0 +1,190 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright : STMicroelectronics 2018 -+ */ -+ -+#include -+#include "stm32mp157-u-boot.dtsi" -+#include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi" -+ -+/ { -+ aliases { -+ i2c3 = &i2c4; -+ mmc0 = &sdmmc1; -+ }; -+ config { -+ u-boot,boot-led = "heartbeat"; -+ u-boot,error-led = "error"; -+ st,adc_usb_pd = <&adc1 18>, <&adc1 19>; -+ st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; -+ st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; -+ }; -+ led { -+ red { -+ label = "error"; -+ gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; -+ default-state = "off"; -+ status = "okay"; -+ }; -+ -+ blue { -+ default-state = "on"; -+ }; -+ }; -+}; -+ -+&clk_hse { -+ st,digbypass; -+}; -+ -+&i2c4 { -+ u-boot,dm-pre-reloc; -+ -+ stusb1600: typec@28 { -+ #extcon-cells = <0>; -+ compatible = "st,stusb1600"; -+ reg = <0x28>; -+ status = "okay"; -+ }; -+}; -+ -+&i2c4_pins_a { -+ u-boot,dm-pre-reloc; -+ pins { -+ u-boot,dm-pre-reloc; -+ }; -+}; -+ -+&pmic { -+ u-boot,dm-pre-reloc; -+}; -+ -+&rcc { -+ st,clksrc = < -+ CLK_MPU_PLL1P -+ CLK_AXI_PLL2P -+ CLK_MCU_PLL3P -+ CLK_PLL12_HSE -+ CLK_PLL3_HSE -+ CLK_PLL4_HSE -+ CLK_RTC_LSE -+ CLK_MCO1_DISABLED -+ CLK_MCO2_DISABLED -+ >; -+ -+ st,clkdiv = < -+ 1 /*MPU*/ -+ 0 /*AXI*/ -+ 0 /*MCU*/ -+ 1 /*APB1*/ -+ 1 /*APB2*/ -+ 1 /*APB3*/ -+ 1 /*APB4*/ -+ 2 /*APB5*/ -+ 23 /*RTC*/ -+ 0 /*MCO1*/ -+ 0 /*MCO2*/ -+ >; -+ -+ st,pkcs = < -+ CLK_CKPER_HSE -+ CLK_FMC_ACLK -+ CLK_QSPI_ACLK -+ CLK_ETH_DISABLED -+ CLK_SDMMC12_PLL4P -+ CLK_DSI_DSIPLL -+ CLK_STGEN_HSE -+ CLK_USBPHY_HSE -+ CLK_SPI2S1_PLL3Q -+ CLK_SPI2S23_PLL3Q -+ CLK_SPI45_HSI -+ CLK_SPI6_HSI -+ CLK_I2C46_HSI -+ CLK_SDMMC3_PLL4P -+ CLK_USBO_USBPHY -+ CLK_ADC_CKPER -+ CLK_CEC_LSE -+ CLK_I2C12_HSI -+ CLK_I2C35_HSI -+ CLK_UART1_HSI -+ CLK_UART24_HSI -+ CLK_UART35_HSI -+ CLK_UART6_HSI -+ CLK_UART78_HSI -+ CLK_SPDIF_PLL4P -+ CLK_FDCAN_PLL4Q -+ CLK_SAI1_PLL3Q -+ CLK_SAI2_PLL3Q -+ CLK_SAI3_PLL3Q -+ CLK_SAI4_PLL3Q -+ CLK_RNG1_LSI -+ CLK_RNG2_LSI -+ CLK_LPTIM1_PCLK1 -+ CLK_LPTIM23_PCLK3 -+ CLK_LPTIM45_LSE -+ >; -+ -+ /* VCO = 1300.0 MHz => P = 650 (CPU) */ -+ pll1: st,pll@0 { -+ cfg = < 2 80 0 0 0 PQR(1,0,0) >; -+ frac = < 0x800 >; -+ u-boot,dm-pre-reloc; -+ }; -+ -+ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ -+ pll2: st,pll@1 { -+ cfg = < 2 65 1 0 0 PQR(1,1,1) >; -+ frac = < 0x1400 >; -+ u-boot,dm-pre-reloc; -+ }; -+ -+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ -+ pll3: st,pll@2 { -+ cfg = < 1 33 1 16 36 PQR(1,1,1) >; -+ frac = < 0x1a04 >; -+ u-boot,dm-pre-reloc; -+ }; -+ -+ /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ -+ pll4: st,pll@3 { -+ cfg = < 3 98 5 7 7 PQR(1,1,1) >; -+ u-boot,dm-pre-reloc; -+ }; -+}; -+ -+&sdmmc1 { -+ u-boot,dm-spl; -+}; -+ -+&sdmmc1_b4_pins_a { -+ u-boot,dm-spl; -+ pins1 { -+ u-boot,dm-spl; -+ }; -+ pins2 { -+ u-boot,dm-spl; -+ }; -+}; -+ -+&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; -+ }; -+}; -+ -+&usbotg_hs { -+ usb1600; -+ hnp-srp-disable; -+}; -+ -+&v3v3 { -+ regulator-always-on; -+}; -diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts -new file mode 100644 -index 0000000..e3d305a ---- /dev/null -+++ b/arch/arm/dts/stm32mp157a-dk1.dts -@@ -0,0 +1,700 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved -+ * Author: Alexandre Torgue . -+ */ -+ -+/dts-v1/; -+ -+#include "stm32mp157c.dtsi" -+#include "stm32mp157cac-pinctrl.dtsi" -+#include -+#include -+#include -+ -+/ { -+ model = "STMicroelectronics STM32MP157A-DK1 Discovery Board"; -+ compatible = "st,stm32mp157a-dk1", "st,stm32mp157"; -+ -+ aliases { -+ ethernet0 = ðernet0; -+ serial0 = &uart4; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ -+ memory@c0000000 { -+ reg = <0xc0000000 0x20000000>; -+ }; -+ -+ reserved-memory { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ retram: retram@0x38000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x38000000 0x10000>; -+ no-map; -+ }; -+ -+ mcuram: mcuram@0x30000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x30000000 0x40000>; -+ no-map; -+ }; -+ -+ mcuram2: mcuram2@0x10000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x10000000 0x40000>; -+ no-map; -+ }; -+ -+ vdev0vring0: vdev0vring0@10040000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x10040000 0x2000>; -+ no-map; -+ }; -+ -+ vdev0vring1: vdev0vring1@10042000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x10042000 0x2000>; -+ no-map; -+ }; -+ -+ vdev0buffer: vdev0buffer@10044000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x10044000 0x4000>; -+ no-map; -+ }; -+ -+ gpu_reserved: gpu@dc000000 { -+ reg = <0xdc000000 0x4000000>; -+ no-map; -+ }; -+ }; -+ -+ sram: sram@10050000 { -+ compatible = "mmio-sram"; -+ reg = <0x10050000 0x10000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0x10050000 0x10000>; -+ -+ dma_pool: dma_pool@0 { -+ reg = <0x0 0x10000>; -+ pool; -+ }; -+ }; -+ -+ led { -+ compatible = "gpio-leds"; -+ blue { -+ label = "heartbeat"; -+ gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ default-state = "off"; -+ }; -+ }; -+ -+ sound { -+ compatible = "audio-graph-card"; -+ label = "STM32MP1-DK"; -+ routing = -+ "Playback" , "MCLK", -+ "Capture" , "MCLK", -+ "MICL" , "Mic Bias"; -+ 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; -+ }; -+}; -+ -+&adc { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&adc12_usb_pwr_pins_a>; -+ vdd-supply = <&vdd>; -+ vdda-supply = <&vdd>; -+ vref-supply = <&vrefbuf>; -+ status = "okay"; -+ adc1: adc@0 { -+ /* -+ * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in18 & in19. -+ * Use at least 5 * RC time, e.g. 5 * (Rp + Rd) * C: -+ * 5 * (56 + 47kOhms) * 5pF => 2.5us. -+ * Use arbitrary margin here (e.g. 5µs). -+ */ -+ st,min-sample-time-nsecs = <5000>; -+ /* ANA0, ANA1, USB Type-C CC1 & CC2 */ -+ st,adc-channels = <0 1 18 19>; -+ status = "okay"; -+ }; -+ adc2: adc@100 { -+ /* ANA0, ANA1, temp sensor, USB Type-C CC1 & CC2 */ -+ st,adc-channels = <0 1 12 18 19>; -+ /* temperature sensor min sample time */ -+ st,min-sample-time-nsecs = <10000>; -+ status = "okay"; -+ }; -+ adc_temp: temp { -+ status = "okay"; -+ }; -+}; -+ -+&cec { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&cec_pins_b>; -+ pinctrl-1 = <&cec_pins_sleep_b>; -+ status = "okay"; -+}; -+ -+&dma1 { -+ sram = <&dma_pool>; -+}; -+ -+&dma2 { -+ sram = <&dma_pool>; -+}; -+ -+&dts { -+ status = "okay"; -+}; -+ -+ðernet0 { -+ status = "okay"; -+ pinctrl-0 = <ðernet0_rgmii_pins_a>; -+ pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; -+ pinctrl-names = "default", "sleep"; -+ phy-mode = "rgmii"; -+ max-speed = <1000>; -+ phy-handle = <&phy0>; -+ -+ mdio0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "snps,dwmac-mdio"; -+ phy0: ethernet-phy@0 { -+ reg = <0>; -+ }; -+ }; -+}; -+ -+&gpu { -+ contiguous-area = <&gpu_reserved>; -+ status = "okay"; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&i2c1_pins_a>; -+ pinctrl-1 = <&i2c1_pins_sleep_a>; -+ i2c-scl-rising-time-ns = <100>; -+ i2c-scl-falling-time-ns = <7>; -+ status = "okay"; -+ /delete-property/dmas; -+ /delete-property/dma-names; -+ -+ cs42l51: cs42l51@4a { -+ compatible = "cirrus,cs42l51"; -+ reg = <0x4a>; -+ #sound-dai-cells = <0>; -+ status = "okay"; -+ -+ VL-supply = <&v3v3>; -+ VD-supply = <&v1v8_audio>; -+ VA-supply = <&v1v8_audio>; -+ VAHP-supply = <&v1v8_audio>; -+ -+ reset-gpios = <&gpiog 9 GPIO_ACTIVE_LOW>; -+ -+ clocks = <&sai2a>; -+ clock-names = "MCLK"; -+ -+ cs42l51_port: port { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cs42l51_tx_endpoint: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&sai2a_endpoint>; -+ frame-master; -+ bitclock-master; -+ }; -+ -+ cs42l51_rx_endpoint: endpoint@1 { -+ reg = <1>; -+ remote-endpoint = <&sai2b_endpoint>; -+ frame-master; -+ bitclock-master; -+ }; -+ }; -+ }; -+ -+ hdmi-transmitter@39 { -+ compatible = "sil,sii9022"; -+ reg = <0x39>; -+ iovcc-supply = <&v3v3_hdmi>; -+ cvcc12-supply = <&v1v2_hdmi>; -+ reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>; -+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>; -+ interrupt-parent = <&gpiog>; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <<dc_pins_a>; -+ pinctrl-1 = <<dc_pins_sleep_a>; -+ status = "okay"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ sii9022_in: endpoint { -+ remote-endpoint = <<dc_ep0_out>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ sii9022_tx_endpoint: endpoint { -+ remote-endpoint = <&i2s2_endpoint>; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&i2c4 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&i2c4_pins_a>; -+ pinctrl-1 = <&i2c4_pins_sleep_a>; -+ i2c-scl-rising-time-ns = <185>; -+ i2c-scl-falling-time-ns = <20>; -+ status = "okay"; -+ /delete-property/dmas; -+ /delete-property/dma-names; -+ -+ pmic: stpmic@33 { -+ compatible = "st,stpmic1"; -+ reg = <0x33>; -+ interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ status = "okay"; -+ -+ st,main-control-register = <0x04>; -+ st,vin-control-register = <0xc0>; -+ st,usb-control-register = <0x30>; -+ -+ regulators { -+ compatible = "st,stpmic1-regulators"; -+ -+ ldo1-supply = <&v3v3>; -+ ldo3-supply = <&vdd_ddr>; -+ ldo6-supply = <&v3v3>; -+ pwr_sw1-supply = <&bst_out>; -+ pwr_sw2-supply = <&bst_out>; -+ -+ vddcore: buck1 { -+ regulator-name = "vddcore"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-always-on; -+ regulator-initial-mode = <0>; -+ regulator-over-current-protection; -+ }; -+ -+ vdd_ddr: buck2 { -+ regulator-name = "vdd_ddr"; -+ regulator-min-microvolt = <1350000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-always-on; -+ regulator-initial-mode = <0>; -+ regulator-over-current-protection; -+ }; -+ -+ vdd: buck3 { -+ regulator-name = "vdd"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ st,mask-reset; -+ regulator-initial-mode = <0>; -+ regulator-over-current-protection; -+ }; -+ -+ v3v3: buck4 { -+ regulator-name = "v3v3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ regulator-over-current-protection; -+ regulator-initial-mode = <0>; -+ }; -+ -+ v1v8_audio: ldo1 { -+ regulator-name = "v1v8_audio"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ interrupts = ; -+ -+ }; -+ -+ v3v3_hdmi: ldo2 { -+ regulator-name = "v3v3_hdmi"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ interrupts = ; -+ -+ }; -+ -+ vtt_ddr: ldo3 { -+ regulator-name = "vtt_ddr"; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <750000>; -+ regulator-always-on; -+ regulator-over-current-protection; -+ }; -+ -+ vdd_usb: ldo4 { -+ regulator-name = "vdd_usb"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ interrupts = ; -+ }; -+ -+ vdda: ldo5 { -+ regulator-name = "vdda"; -+ regulator-min-microvolt = <2900000>; -+ regulator-max-microvolt = <2900000>; -+ interrupts = ; -+ regulator-boot-on; -+ }; -+ -+ v1v2_hdmi: ldo6 { -+ regulator-name = "v1v2_hdmi"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ regulator-always-on; -+ interrupts = ; -+ -+ }; -+ -+ vref_ddr: vref_ddr { -+ regulator-name = "vref_ddr"; -+ regulator-always-on; -+ regulator-over-current-protection; -+ }; -+ -+ bst_out: boost { -+ regulator-name = "bst_out"; -+ interrupts = ; -+ }; -+ -+ vbus_otg: pwr_sw1 { -+ regulator-name = "vbus_otg"; -+ interrupts = ; -+ regulator-active-discharge; -+ }; -+ -+ vbus_sw: pwr_sw2 { -+ regulator-name = "vbus_sw"; -+ interrupts = ; -+ regulator-active-discharge; -+ }; -+ }; -+ -+ onkey { -+ compatible = "st,stpmic1-onkey"; -+ interrupts = , ; -+ interrupt-names = "onkey-falling", "onkey-rising"; -+ status = "okay"; -+ }; -+ -+ watchdog { -+ compatible = "st,stpmic1-wdt"; -+ status = "disabled"; -+ }; -+ }; -+}; -+ -+&i2s2 { -+ clocks = <&rcc SPI2>, <&rcc SPI2_K>, <&rcc PLL3_Q>, <&rcc PLL3_R>; -+ clock-names = "pclk", "i2sclk", "x8k", "x11k"; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&i2s2_pins_a>; -+ pinctrl-1 = <&i2s2_pins_sleep_a>; -+ status = "okay"; -+ -+ i2s2_port: port { -+ i2s2_endpoint: endpoint { -+ remote-endpoint = <&sii9022_tx_endpoint>; -+ format = "i2s"; -+ mclk-fs = <256>; -+ }; -+ }; -+}; -+ -+&ipcc { -+ status = "okay"; -+}; -+ -+&iwdg2 { -+ timeout-sec = <32>; -+ status = "okay"; -+}; -+ -+<dc { -+ status = "okay"; -+ -+ port { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ltdc_ep0_out: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&sii9022_in>; -+ }; -+ }; -+}; -+ -+&m4_rproc { -+ memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, -+ <&vdev0vring1>, <&vdev0buffer>; -+ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; -+ mbox-names = "vq0", "vq1", "shutdown"; -+ interrupt-parent = <&exti>; -+ interrupts = <68 1>; -+ interrupt-names = "wdg"; -+ recovery; -+ status = "okay"; -+}; -+ -+&pwr { -+ pwr-supply = <&vdd>; -+}; -+ -+&rng1 { -+ status = "okay"; -+}; -+ -+&rtc { -+ status = "okay"; -+}; -+ -+&sai2 { -+ clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>; -+ clock-names = "pclk", "x8k", "x11k"; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>; -+ pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>; -+ status = "okay"; -+ -+ sai2a: audio-controller@4400b004 { -+ #clock-cells = <0>; -+ dma-names = "tx"; -+ clocks = <&rcc SAI2_K>; -+ clock-names = "sai_ck"; -+ status = "okay"; -+ -+ sai2a_port: port { -+ sai2a_endpoint: endpoint { -+ remote-endpoint = <&cs42l51_tx_endpoint>; -+ format = "i2s"; -+ mclk-fs = <256>; -+ dai-tdm-slot-num = <2>; -+ dai-tdm-slot-width = <32>; -+ }; -+ }; -+ }; -+ -+ sai2b: audio-controller@4400b024 { -+ dma-names = "rx"; -+ st,sync = <&sai2a 2>; -+ status = "okay"; -+ clocks = <&rcc SAI2_K>, <&sai2a>; -+ clock-names = "sai_ck", "MCLK"; -+ -+ sai2b_port: port { -+ sai2b_endpoint: endpoint { -+ remote-endpoint = <&cs42l51_rx_endpoint>; -+ format = "i2s"; -+ mclk-fs = <256>; -+ dai-tdm-slot-num = <2>; -+ dai-tdm-slot-width = <32>; -+ }; -+ }; -+ }; -+}; -+ -+&sdmmc1 { -+ pinctrl-names = "default", "opendrain", "sleep"; -+ pinctrl-0 = <&sdmmc1_b4_pins_a>; -+ pinctrl-1 = <&sdmmc1_b4_od_pins_a>; -+ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; -+ broken-cd; -+ st,neg-edge; -+ bus-width = <4>; -+ vmmc-supply = <&v3v3>; -+ status = "okay"; -+}; -+ -+&spi4 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&spi4_pins_a>; -+ pinctrl-1 = <&spi4_sleep_pins_a>; -+ status = "disabled"; -+}; -+ -+&spi5 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&spi5_pins_a>; -+ pinctrl-1 = <&spi5_sleep_pins_a>; -+ status = "disabled"; -+}; -+ -+&timers1 { -+ /* spare dmas for other usage */ -+ /delete-property/dmas; -+ /delete-property/dma-names; -+ pwm { -+ pinctrl-0 = <&pwm1_pins_a>; -+ pinctrl-1 = <&pwm1_sleep_pins_a>; -+ pinctrl-names = "default", "sleep"; -+ status = "okay"; -+ }; -+ timer@0 { -+ status = "okay"; -+ }; -+}; -+ -+&timers3 { -+ /delete-property/dmas; -+ /delete-property/dma-names; -+ 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; -+ pwm { -+ pinctrl-0 = <&pwm4_pins_a &pwm4_pins_b>; -+ pinctrl-1 = <&pwm4_sleep_pins_a &pwm4_sleep_pins_b>; -+ pinctrl-names = "default", "sleep"; -+ status = "okay"; -+ }; -+ timer@3 { -+ status = "okay"; -+ }; -+}; -+ -+&timers5 { -+ /delete-property/dmas; -+ /delete-property/dma-names; -+ pwm { -+ pinctrl-0 = <&pwm5_pins_a>; -+ pinctrl-1 = <&pwm5_sleep_pins_a>; -+ pinctrl-names = "default", "sleep"; -+ status = "okay"; -+ }; -+ timer@4 { -+ status = "okay"; -+ }; -+}; -+ -+&timers6 { -+ status = "okay"; -+ /* spare dmas for other usage */ -+ /delete-property/dmas; -+ /delete-property/dma-names; -+ timer@5 { -+ status = "okay"; -+ }; -+}; -+ -+&timers12 { -+ /delete-property/dmas; -+ /delete-property/dma-names; -+ pwm { -+ pinctrl-0 = <&pwm12_pins_a>; -+ pinctrl-1 = <&pwm12_sleep_pins_a>; -+ pinctrl-names = "default", "sleep"; -+ status = "okay"; -+ }; -+ timer@11 { -+ status = "okay"; -+ }; -+}; -+ -+&uart4 { -+ pinctrl-names = "default", "sleep", "idle", "no_console_suspend"; -+ pinctrl-0 = <&uart4_pins_a>; -+ pinctrl-1 = <&uart4_sleep_pins_a>; -+ pinctrl-2 = <&uart4_idle_pins_a>; -+ pinctrl-3 = <&uart4_pins_a>; -+ status = "okay"; -+}; -+ -+&usart3 { -+ pinctrl-names = "default", "sleep", "idle"; -+ pinctrl-0 = <&usart3_pins_b>; -+ pinctrl-1 = <&usart3_sleep_pins_b>; -+ pinctrl-2 = <&usart3_idle_pins_b>; -+ status = "disabled"; -+}; -+ -+&usbh_ehci { -+ phys = <&usbphyc_port0>; -+ phy-names = "usb"; -+ status = "okay"; -+}; -+ -+&usbotg_hs { -+ dr_mode = "peripheral"; -+ force-b-session-valid; -+ phys = <&usbphyc_port1 0>; -+ phy-names = "usb2-phy"; -+ status = "okay"; -+}; -+ -+&usbphyc { -+ vdd3v3-supply = <&vdd_usb>; -+ status = "okay"; -+}; -+ -+&usbphyc_port0 { -+ st,phy-tuning = <&usb_phy_tuning>; -+}; -+ -+&usbphyc_port1 { -+ st,phy-tuning = <&usb_phy_tuning>; -+}; -+ -+&vrefbuf { -+ regulator-min-microvolt = <2500000>; -+ regulator-max-microvolt = <2500000>; -+ vdda-supply = <&vdd>; -+ status = "okay"; -+}; -diff --git a/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi -new file mode 100644 -index 0000000..06ef3a4 ---- /dev/null -+++ b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi -@@ -0,0 +1,6 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright : STMicroelectronics 2018 -+ */ -+ -+#include "stm32mp157a-dk1-u-boot.dtsi" -diff --git a/arch/arm/dts/stm32mp157c-dk2.dts b/arch/arm/dts/stm32mp157c-dk2.dts -new file mode 100644 -index 0000000..c276c59 ---- /dev/null -+++ b/arch/arm/dts/stm32mp157c-dk2.dts -@@ -0,0 +1,144 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved -+ * Author: Alexandre Torgue . -+ */ -+ -+/dts-v1/; -+ -+#include "stm32mp157a-dk1.dts" -+#include -+ -+/ { -+ model = "STMicroelectronics STM32MP157C-DK2 Discovery Board"; -+ compatible = "st,stm32mp157c-dk2", "st,stm32mp157"; -+ -+ aliases { -+ serial1 = &usart2; -+ }; -+ -+ wifi_pwrseq: wifi-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ reset-gpios = <&gpioh 4 GPIO_ACTIVE_LOW>; -+ }; -+}; -+ -+&dsi { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ dsi_in: endpoint { -+ remote-endpoint = <<dc_ep1_out>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ dsi_out: endpoint { -+ remote-endpoint = <&panel_in>; -+ }; -+ }; -+ }; -+ -+ panel@0 { -+ compatible = "orisetech,otm8009a"; -+ reg = <0>; -+ reset-gpios = <&gpioe 4 GPIO_ACTIVE_LOW>; -+ status = "okay"; -+ -+ port { -+ panel_in: endpoint { -+ remote-endpoint = <&dsi_out>; -+ }; -+ }; -+ }; -+}; -+ -+&i2c1 { -+ touchscreen@2a { -+ compatible = "focaltech,ft6236"; -+ reg = <0x2a>; -+ interrupts = <2 2>; -+ interrupt-parent = <&gpiof>; -+ interrupt-controller; -+ touchscreen-size-x = <480>; -+ touchscreen-size-y = <800>; -+ status = "okay"; -+ }; -+ touchscreen@38 { -+ compatible = "focaltech,ft6336"; -+ reg = <0x38>; -+ interrupts = <2 2>; -+ interrupt-parent = <&gpiof>; -+ interrupt-controller; -+ touchscreen-size-x = <480>; -+ touchscreen-size-y = <800>; -+ status = "okay"; -+ }; -+}; -+ -+<dc { -+ status = "okay"; -+ -+ port { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ltdc_ep1_out: endpoint@1 { -+ reg = <1>; -+ remote-endpoint = <&dsi_in>; -+ }; -+ }; -+}; -+ -+&rtc { -+ st,lsco = ; -+ pinctrl-0 = <&rtc_out2_rmp_pins_a>; -+ pinctrl-names = "default"; -+}; -+ -+/* Wifi */ -+&sdmmc2 { -+ pinctrl-names = "default", "opendrain", "sleep"; -+ pinctrl-0 = <&sdmmc2_b4_pins_a>; -+ pinctrl-1 = <&sdmmc2_b4_od_pins_a>; -+ pinctrl-2 = <&sdmmc2_b4_sleep_pins_a>; -+ non-removable; -+ st,neg-edge; -+ bus-width = <4>; -+ vmmc-supply = <&v3v3>; -+ mmc-pwrseq = <&wifi_pwrseq>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ keep-power-in-suspend; -+ status = "okay"; -+ -+ brcmf: bcrmf@1 { -+ reg = <1>; -+ compatible = "brcm,bcm4329-fmac"; -+ }; -+}; -+ -+/* Bluetooth */ -+&usart2 { -+ pinctrl-names = "default", "sleep", "idle"; -+ pinctrl-0 = <&usart2_pins_a>; -+ pinctrl-1 = <&usart2_sleep_pins_a>; -+ pinctrl-2 = <&usart2_idle_pins_a>; -+ st,hw-flow-ctrl; -+ status = "okay"; -+ -+ bluetooth { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&btreg>; -+ compatible = "brcm,bcm43438-bt"; -+ max-speed = <3000000>; -+ }; -+}; -diff --git a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi -index 4898483..b6bf6f1 100644 ---- a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi -+++ b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi -@@ -9,44 +9,30 @@ - - / { - aliases { -+ i2c3 = &i2c4; - mmc0 = &sdmmc1; - mmc1 = &sdmmc2; -- i2c3 = &i2c4; - }; - -- led { -- compatible = "gpio-leds"; -+ config { -+ u-boot,boot-led = "heartbeat"; -+ st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; -+ st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; -+ }; - -- red { -- label = "stm32mp:red:status"; -- gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; -- default-state = "off"; -- }; -- green { -- label = "stm32mp:green:user"; -- gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; -- default-state = "on"; -- }; -- orange { -- label = "stm32mp:orange:status"; -- gpios = <&gpioh 7 GPIO_ACTIVE_HIGH>; -- default-state = "off"; -- }; -+ led { - blue { -- label = "stm32mp:blue:user"; -- gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>; -+ default-state = "on"; - }; - }; - }; - --&uart4_pins_a { -+&clk_hse { -+ st,digbypass; -+}; -+ -+&i2c4 { - u-boot,dm-pre-reloc; -- pins1 { -- u-boot,dm-pre-reloc; -- }; -- pins2 { -- u-boot,dm-pre-reloc; -- }; - }; - - &i2c4_pins_a { -@@ -56,19 +42,10 @@ - }; - }; - --&uart4 { -- u-boot,dm-pre-reloc; --}; -- --&i2c4 { -- u-boot,dm-pre-reloc; --}; -- - &pmic { - u-boot,dm-pre-reloc; - }; - --/* CLOCK init */ - &rcc { - st,clksrc = < - CLK_MPU_PLL1P -@@ -101,7 +78,7 @@ - CLK_FMC_ACLK - CLK_QSPI_ACLK - CLK_ETH_DISABLED -- CLK_SDMMC12_PLL3R -+ CLK_SDMMC12_PLL4P - CLK_DSI_DSIPLL - CLK_STGEN_HSE - CLK_USBPHY_HSE -@@ -110,7 +87,7 @@ - CLK_SPI45_HSI - CLK_SPI6_HSI - CLK_I2C46_HSI -- CLK_SDMMC3_PLL3R -+ CLK_SDMMC3_PLL4P - CLK_USBO_USBPHY - CLK_ADC_CKPER - CLK_CEC_LSE -@@ -121,17 +98,17 @@ - CLK_UART35_HSI - CLK_UART6_HSI - CLK_UART78_HSI -- CLK_SPDIF_PLL3Q -+ CLK_SPDIF_PLL4P - CLK_FDCAN_PLL4Q - CLK_SAI1_PLL3Q - CLK_SAI2_PLL3Q - CLK_SAI3_PLL3Q - CLK_SAI4_PLL3Q -- CLK_RNG1_CSI -- CLK_RNG2_CSI -+ CLK_RNG1_LSI -+ CLK_RNG2_LSI - CLK_LPTIM1_PCLK1 - CLK_LPTIM23_PCLK3 -- CLK_LPTIM45_PCLK3 -+ CLK_LPTIM45_LSE - >; - - /* VCO = 1300.0 MHz => P = 650 (CPU) */ -@@ -148,44 +125,54 @@ - u-boot,dm-pre-reloc; - }; - -- /* VCO = 786.4 MHz => P = 197, Q = 49, R = 98 */ -+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ - pll3: st,pll@2 { -- cfg = < 2 97 3 15 7 PQR(1,1,1) >; -- frac = < 0x9ba >; -+ cfg = < 1 33 1 16 36 PQR(1,1,1) >; -+ frac = < 0x1a04 >; - u-boot,dm-pre-reloc; - }; - -- /* VCO = 508.0 MHz => P = 56, Q = 56, R = 56 */ -+ /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ - pll4: st,pll@3 { -- cfg = < 5 126 8 8 8 PQR(1,1,1) >; -+ cfg = < 3 98 5 7 7 PQR(1,1,1) >; - u-boot,dm-pre-reloc; - }; - }; - --/* SPL part **************************************/ --/* MMC1 boot */ -+&sdmmc1 { -+ u-boot,dm-spl; -+}; -+ - &sdmmc1_b4_pins_a { - u-boot,dm-spl; -- pins { -+ pins1 { -+ u-boot,dm-spl; -+ }; -+ pins2 { - u-boot,dm-spl; - }; - }; - - &sdmmc1_dir_pins_a { - u-boot,dm-spl; -- pins { -+ pins1 { -+ u-boot,dm-spl; -+ }; -+ pins2 { - u-boot,dm-spl; - }; - }; - --&sdmmc1 { -+&sdmmc2 { - u-boot,dm-spl; - }; - --/* MMC2 boot */ - &sdmmc2_b4_pins_a { - u-boot,dm-spl; -- pins { -+ pins1 { -+ u-boot,dm-spl; -+ }; -+ pins2 { - u-boot,dm-spl; - }; - }; -@@ -197,6 +184,16 @@ - }; - }; - --&sdmmc2 { -- u-boot,dm-spl; -+&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/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts -index f8b7701..37edf87 100644 ---- a/arch/arm/dts/stm32mp157c-ed1.dts -+++ b/arch/arm/dts/stm32mp157c-ed1.dts -@@ -6,22 +6,96 @@ - /dts-v1/; - - #include "stm32mp157c.dtsi" --#include "stm32mp157-pinctrl.dtsi" -+#include "stm32mp157caa-pinctrl.dtsi" - #include --#include -+#include - - / { - model = "STMicroelectronics STM32MP157C eval daughter"; - compatible = "st,stm32mp157c-ed1", "st,stm32mp157"; - - chosen { -- stdout-path = "serial3:115200n8"; -+ stdout-path = "serial0:115200n8"; - }; - - memory@c0000000 { - reg = <0xC0000000 0x40000000>; - }; - -+ reserved-memory { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ retram: retram@0x38000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x38000000 0x10000>; -+ no-map; -+ }; -+ -+ mcuram: mcuram@0x30000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x30000000 0x40000>; -+ no-map; -+ }; -+ -+ mcuram2: mcuram2@0x10000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x10000000 0x40000>; -+ no-map; -+ }; -+ -+ vdev0vring0: vdev0vring0@10040000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x10040000 0x2000>; -+ no-map; -+ }; -+ -+ vdev0vring1: vdev0vring1@10042000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x10042000 0x2000>; -+ no-map; -+ }; -+ -+ vdev0buffer: vdev0buffer@10044000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x10044000 0x4000>; -+ no-map; -+ }; -+ -+ gpu_reserved: gpu@f8000000 { -+ reg = <0xf8000000 0x8000000>; -+ no-map; -+ }; -+ }; -+ -+ aliases { -+ serial0 = &uart4; -+ }; -+ -+ sram: sram@10050000 { -+ compatible = "mmio-sram"; -+ reg = <0x10050000 0x10000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0x10050000 0x10000>; -+ -+ dma_pool: dma_pool@0 { -+ reg = <0x0 0x10000>; -+ pool; -+ }; -+ }; -+ -+ led { -+ compatible = "gpio-leds"; -+ blue { -+ label = "heartbeat"; -+ gpios = <&gpiod 9 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ default-state = "off"; -+ }; -+ }; -+ - sd_switch: regulator-sd_switch { - compatible = "regulator-gpio"; - regulator-name = "sd_switch"; -@@ -36,39 +110,87 @@ - }; - }; - --&rng1 { -+&adc { -+ /* ANA0, ANA1 are dedicated pins and don't need pinctrl: only in6. */ -+ vdd-supply = <&vdd>; -+ vdda-supply = <&vdda>; -+ vref-supply = <&vdda>; - status = "okay"; -+ adc1: adc@0 { -+ st,adc-channels = <0 1>; -+ /* 16.5 ck_cycles sampling time */ -+ st,min-sample-time-nsecs = <400>; -+ status = "okay"; -+ }; -+ jadc1: jadc@0 { -+ st,adc-channels = <0 1>; -+ /* 16.5 ck_cycles sampling time */ -+ st,min-sample-time-nsecs = <400>; -+ status = "okay"; -+ }; -+ /* temperature sensor on adc2 */ -+ adc2: adc@100 { -+ status = "okay"; -+ }; -+ adc_temp: temp { -+ status = "okay"; -+ }; - }; - --&timers6 { -+&dac { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&dac_ch1_pins_a &dac_ch2_pins_a>; -+ vref-supply = <&vdda>; - status = "okay"; -- timer@5 { -+ dac1: dac@1 { - status = "okay"; - }; -+ dac2: dac@2 { -+ status = "okay"; -+ }; -+}; -+ -+&dma1 { -+ sram = <&dma_pool>; -+}; -+ -+&dma2 { -+ sram = <&dma_pool>; -+}; -+ -+&dts { -+ status = "okay"; -+}; -+ -+&gpu { -+ contiguous-area = <&gpu_reserved>; -+ status = "okay"; - }; - - &i2c4 { -- pinctrl-names = "default"; -+ pinctrl-names = "default", "sleep"; - pinctrl-0 = <&i2c4_pins_a>; -+ pinctrl-1 = <&i2c4_pins_sleep_a>; - i2c-scl-rising-time-ns = <185>; - i2c-scl-falling-time-ns = <20>; - status = "okay"; -+ /delete-property/dmas; -+ /delete-property/dma-names; - -- pmic: stpmu1@33 { -- compatible = "st,stpmu1"; -+ pmic: stpmic@33 { -+ compatible = "st,stpmic1"; - reg = <0x33>; -- interrupts = <0 2>; -- interrupt-parent = <&gpioa>; -+ interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>; - interrupt-controller; - #interrupt-cells = <2>; - status = "okay"; - -- st,main_control_register = <0x04>; -- st,vin_control_register = <0xc0>; -- st,usb_control_register = <0x30>; -+ st,main-control-register = <0x04>; -+ st,vin-control-register = <0xc0>; -+ st,usb-control-register = <0x30>; - - regulators { -- compatible = "st,stpmu1-regulators"; -+ compatible = "st,stpmic1-regulators"; - - ldo1-supply = <&v3v3>; - ldo2-supply = <&v3v3>; -@@ -83,20 +205,8 @@ - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <1350000>; - regulator-always-on; -- regulator-initial-mode = <2>; -+ regulator-initial-mode = <0>; - regulator-over-current-protection; -- -- regulator-state-standby { -- regulator-on-in-suspend; -- regulator-suspend-microvolt = <1200000>; -- regulator-mode = <8>; -- }; -- regulator-state-mem { -- regulator-off-in-suspend; -- }; -- regulator-state-disk { -- regulator-off-in-suspend; -- }; - }; - - vdd_ddr: buck2 { -@@ -104,22 +214,8 @@ - regulator-min-microvolt = <1350000>; - regulator-max-microvolt = <1350000>; - regulator-always-on; -- regulator-initial-mode = <2>; -+ regulator-initial-mode = <0>; - regulator-over-current-protection; -- -- regulator-state-standby { -- regulator-suspend-microvolt = <1350000>; -- regulator-on-in-suspend; -- regulator-mode = <8>; -- }; -- regulator-state-mem { -- regulator-suspend-microvolt = <1350000>; -- regulator-on-in-suspend; -- regulator-mode = <8>; -- }; -- regulator-state-disk { -- regulator-off-in-suspend; -- }; - }; - - vdd: buck3 { -@@ -127,46 +223,18 @@ - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; -- st,mask_reset; -- regulator-initial-mode = <8>; -+ st,mask-reset; -+ regulator-initial-mode = <0>; - regulator-over-current-protection; -- -- regulator-state-standby { -- regulator-suspend-microvolt = <3300000>; -- regulator-on-in-suspend; -- regulator-mode = <8>; -- }; -- regulator-state-mem { -- regulator-suspend-microvolt = <3300000>; -- regulator-on-in-suspend; -- regulator-mode = <8>; -- }; -- regulator-state-disk { -- regulator-suspend-microvolt = <3300000>; -- regulator-on-in-suspend; -- regulator-mode = <8>; -- }; - }; - - v3v3: buck4 { - regulator-name = "v3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; -- regulator-boot-on; -+ regulator-always-on; - regulator-over-current-protection; -- regulator-initial-mode = <8>; -- -- regulator-state-standby { -- regulator-suspend-microvolt = <3300000>; -- regulator-unchanged-in-suspend; -- regulator-mode = <8>; -- }; -- regulator-state-mem { -- regulator-off-in-suspend; -- }; -- regulator-state-disk { -- regulator-off-in-suspend; -- }; -+ regulator-initial-mode = <0>; - }; - - vdda: ldo1 { -@@ -174,18 +242,6 @@ - regulator-min-microvolt = <2900000>; - regulator-max-microvolt = <2900000>; - interrupts = ; -- interrupt-parent = <&pmic>; -- -- regulator-state-standby { -- regulator-suspend-microvolt = <2900000>; -- regulator-unchanged-in-suspend; -- }; -- regulator-state-mem { -- regulator-off-in-suspend; -- }; -- regulator-state-disk { -- regulator-off-in-suspend; -- }; - }; - - v2v8: ldo2 { -@@ -193,36 +249,14 @@ - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - interrupts = ; -- interrupt-parent = <&pmic>; -- -- regulator-state-standby { -- regulator-suspend-microvolt = <2800000>; -- regulator-unchanged-in-suspend; -- }; -- regulator-state-mem { -- regulator-off-in-suspend; -- }; -- regulator-state-disk { -- regulator-off-in-suspend; -- }; - }; - - vtt_ddr: ldo3 { - regulator-name = "vtt_ddr"; -- regulator-min-microvolt = <0000000>; -- regulator-max-microvolt = <1000000>; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <750000>; - regulator-always-on; - regulator-over-current-protection; -- -- regulator-state-standby { -- regulator-off-in-suspend; -- }; -- regulator-state-mem { -- regulator-off-in-suspend; -- }; -- regulator-state-disk { -- regulator-off-in-suspend; -- }; - }; - - vdd_usb: ldo4 { -@@ -230,17 +264,6 @@ - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - interrupts = ; -- interrupt-parent = <&pmic>; -- -- regulator-state-standby { -- regulator-unchanged-in-suspend; -- }; -- regulator-state-mem { -- regulator-off-in-suspend; -- }; -- regulator-state-disk { -- regulator-off-in-suspend; -- }; - }; - - vdd_sd: ldo5 { -@@ -248,19 +271,7 @@ - regulator-min-microvolt = <2900000>; - regulator-max-microvolt = <2900000>; - interrupts = ; -- interrupt-parent = <&pmic>; - regulator-boot-on; -- -- regulator-state-standby { -- regulator-suspend-microvolt = <2900000>; -- regulator-unchanged-in-suspend; -- }; -- regulator-state-mem { -- regulator-off-in-suspend; -- }; -- regulator-state-disk { -- regulator-off-in-suspend; -- }; - }; - - v1v8: ldo6 { -@@ -268,69 +279,88 @@ - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - interrupts = ; -- interrupt-parent = <&pmic>; -- -- regulator-state-standby { -- regulator-suspend-microvolt = <1800000>; -- regulator-unchanged-in-suspend; -- }; -- regulator-state-mem { -- regulator-off-in-suspend; -- }; -- regulator-state-disk { -- regulator-off-in-suspend; -- }; - }; - - vref_ddr: vref_ddr { - regulator-name = "vref_ddr"; - regulator-always-on; - regulator-over-current-protection; -- -- regulator-state-standby { -- regulator-on-in-suspend; -- }; -- regulator-state-mem { -- regulator-on-in-suspend; -- }; -- regulator-state-disk { -- regulator-off-in-suspend; -- }; - }; - -- bst_out: boost { -+ bst_out: boost { - regulator-name = "bst_out"; - interrupts = ; -- interrupt-parent = <&pmic>; -- }; -+ }; - - vbus_otg: pwr_sw1 { - regulator-name = "vbus_otg"; - interrupts = ; -- interrupt-parent = <&pmic>; - regulator-active-discharge; - }; - - vbus_sw: pwr_sw2 { - regulator-name = "vbus_sw"; - interrupts = ; -- interrupt-parent = <&pmic>; - regulator-active-discharge; - }; - }; -+ -+ onkey { -+ compatible = "st,stpmic1-onkey"; -+ interrupts = , ; -+ interrupt-names = "onkey-falling", "onkey-rising"; -+ status = "okay"; -+ }; -+ -+ watchdog { -+ compatible = "st,stpmic1-wdt"; -+ status = "disabled"; -+ }; - }; - }; - -+&ipcc { -+ status = "okay"; -+}; -+ -+&iwdg2 { -+ timeout-sec = <32>; -+ status = "okay"; -+}; -+ -+&m4_rproc { -+ memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, -+ <&vdev0vring1>, <&vdev0buffer>; -+ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; -+ mbox-names = "vq0", "vq1", "shutdown"; -+ interrupt-parent = <&exti>; -+ interrupts = <68 1>; -+ interrupt-names = "wdg"; -+ recovery; -+ status = "okay"; -+}; -+ - &pwr { - pwr-supply = <&vdd>; - }; - -+&rng1 { -+ status = "okay"; -+}; -+ -+&rtc { -+ status = "okay"; -+}; -+ - &sdmmc1 { -+ pinctrl-names = "default", "opendrain", "sleep"; - pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; -+ pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_dir_pins_a>; -+ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a &sdmmc1_dir_sleep_pins_a>; - broken-cd; -- st,dirpol; -- st,negedge; -- st,pin-ckin; -+ st,sig-dir; -+ st,neg-edge; -+ st,use-ckin; - bus-width = <4>; - vmmc-supply = <&vdd_sd>; - vqmmc-supply = <&sd_switch>; -@@ -343,36 +373,44 @@ - }; - - &sdmmc2 { -+ pinctrl-names = "default", "opendrain", "sleep"; - pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>; -+ pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>; -+ pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>; - non-removable; - no-sd; - no-sdio; -- st,dirpol; -- st,negedge; -+ st,neg-edge; - bus-width = <8>; - vmmc-supply = <&v3v3>; -- vqmmc-supply = <&vdd>; -+ vqmmc-supply = <&v3v3>; -+ mmc-ddr-3_3v; - status = "okay"; - }; - -+&timers6 { -+ status = "okay"; -+ /* spare dmas for other usage */ -+ /delete-property/dmas; -+ /delete-property/dma-names; -+ timer@5 { -+ status = "okay"; -+ }; -+}; -+ - &uart4 { -- pinctrl-names = "default"; -+ pinctrl-names = "default", "sleep", "idle", "no_console_suspend"; - pinctrl-0 = <&uart4_pins_a>; -+ pinctrl-1 = <&uart4_sleep_pins_a>; -+ pinctrl-2 = <&uart4_idle_pins_a>; -+ pinctrl-3 = <&uart4_pins_a>; - status = "okay"; - }; - - &usbotg_hs { -- usb33d-supply = <&usb33>; --}; -- --&usbphyc_port0 { -- phy-supply = <&vdd_usb>; -- vdda1v1-supply = <®11>; -- vdda1v8-supply = <®18>; -+ vbus-supply = <&vbus_otg>; - }; - --&usbphyc_port1 { -- phy-supply = <&vdd_usb>; -- vdda1v1-supply = <®11>; -- vdda1v8-supply = <®18>; -+&usbphyc { -+ vdd3v3-supply = <&vdd_usb>; - }; -diff --git a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi -index 30b1734..ec08813 100644 ---- a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi -+++ b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi -@@ -7,29 +7,23 @@ - - / { - aliases { -- spi0 = &qspi; -+ gpio26 = &stmfx_pinctrl; - i2c1 = &i2c2; - i2c4 = &i2c5; -+ pinctrl2 = &stmfx_pinctrl; -+ spi0 = &qspi; - }; - }; - - &flash0 { - compatible = "spi-flash"; -+ u-boot,dm-spl; - }; - - &flash1 { - compatible = "spi-flash"; - }; - --&v3v3 { -- regulator-always-on; --}; -- --&usbotg_hs { -- g-tx-fifo-size = <576>; --}; -- --/* SPL part **************************************/ - &qspi { - u-boot,dm-spl; - }; -@@ -61,7 +55,6 @@ - }; - }; - --&flash0 { -- u-boot,dm-spl; -+&usbotg_hs { -+ g-tx-fifo-size = <576>; - }; -- -diff --git a/arch/arm/dts/stm32mp157c-ev1.dts b/arch/arm/dts/stm32mp157c-ev1.dts -index 902a42b..18742e8 100644 ---- a/arch/arm/dts/stm32mp157c-ev1.dts -+++ b/arch/arm/dts/stm32mp157c-ev1.dts -@@ -6,44 +6,565 @@ - /dts-v1/; - - #include "stm32mp157c-ed1.dts" -+#include -+#include -+#include - - / { - model = "STMicroelectronics STM32MP157C eval daughter on eval mother"; - compatible = "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", "st,stm32mp157"; - -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ -+ aliases { -+ serial1 = &usart3; -+ ethernet0 = ðernet0; -+ }; -+ -+ clocks { -+ clk_ext_camera: clk-ext-camera { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <24000000>; -+ }; -+ }; -+ -+ joystick { -+ compatible = "gpio-keys"; -+ #size-cells = <0>; -+ pinctrl-0 = <&joystick_pins>; -+ pinctrl-names = "default"; -+ button-0 { -+ label = "JoySel"; -+ linux,code = ; -+ interrupt-parent = <&stmfx_pinctrl>; -+ interrupts = <0 IRQ_TYPE_EDGE_RISING>; -+ }; -+ button-1 { -+ label = "JoyDown"; -+ linux,code = ; -+ interrupt-parent = <&stmfx_pinctrl>; -+ interrupts = <1 IRQ_TYPE_EDGE_RISING>; -+ }; -+ button-2 { -+ label = "JoyLeft"; -+ linux,code = ; -+ interrupt-parent = <&stmfx_pinctrl>; -+ interrupts = <2 IRQ_TYPE_EDGE_RISING>; -+ }; -+ button-3 { -+ label = "JoyRight"; -+ linux,code = ; -+ interrupt-parent = <&stmfx_pinctrl>; -+ interrupts = <3 IRQ_TYPE_EDGE_RISING>; -+ }; -+ button-4 { -+ label = "JoyUp"; -+ 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"; -+ }; -+ -+ spdif_out: spdif-out { -+ #sound-dai-cells = <0>; -+ compatible = "linux,spdif-dit"; -+ status = "okay"; -+ -+ spdif_out_port: port { -+ spdif_out_endpoint: endpoint { -+ remote-endpoint = <&sai4a_endpoint>; -+ }; -+ }; -+ }; -+ -+ spdif_in: spdif-in { -+ #sound-dai-cells = <0>; -+ compatible = "linux,spdif-dir"; -+ status = "okay"; -+ -+ spdif_in_port: port { -+ spdif_in_endpoint: endpoint { -+ remote-endpoint = <&spdifrx_endpoint>; -+ }; -+ }; -+ }; -+ -+ sound { -+ compatible = "audio-graph-card"; -+ label = "STM32MP1-EV"; -+ routing = -+ "AIF1CLK" , "MCLK1", -+ "AIF2CLK" , "MCLK1", -+ "IN1LN" , "MICBIAS2", -+ "DMIC2DAT" , "MICBIAS1", -+ "DMIC1DAT" , "MICBIAS1"; -+ dais = <&sai2a_port &sai2b_port &sai4a_port &spdifrx_port -+ &dfsdm0_port &dfsdm1_port &dfsdm2_port &dfsdm3_port>; -+ status = "okay"; -+ }; -+ -+ dmic0: dmic-0 { -+ compatible = "dmic-codec"; -+ #sound-dai-cells = <1>; -+ status = "okay"; -+ -+ port { -+ dmic0_endpoint: endpoint { -+ remote-endpoint = <&dfsdm_endpoint0>; -+ }; -+ }; -+ }; -+ -+ dmic1: dmic-1 { -+ compatible = "dmic-codec"; -+ #sound-dai-cells = <1>; -+ status = "okay"; -+ -+ port { -+ dmic1_endpoint: endpoint { -+ remote-endpoint = <&dfsdm_endpoint1>; -+ }; -+ }; -+ }; -+ -+ dmic2: dmic-2 { -+ compatible = "dmic-codec"; -+ #sound-dai-cells = <1>; -+ status = "okay"; -+ -+ port { -+ dmic2_endpoint: endpoint { -+ remote-endpoint = <&dfsdm_endpoint2>; -+ }; -+ }; -+ }; -+ -+ dmic3: dmic-3 { -+ compatible = "dmic-codec"; -+ #sound-dai-cells = <1>; -+ status = "okay"; -+ -+ port { -+ dmic3_endpoint: endpoint { -+ remote-endpoint = <&dfsdm_endpoint3>; -+ }; -+ }; -+ }; -+ -+ 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 { -- pinctrl-names = "default"; -+ pinctrl-names = "default", "sleep"; - pinctrl-0 = <&cec_pins_a>; -+ pinctrl-1 = <&cec_pins_sleep_a>; -+}; -+ -+&dcmi { -+ status = "okay"; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&dcmi_pins_a>; -+ pinctrl-1 = <&dcmi_sleep_pins_a>; -+ -+ port { -+ dcmi_0: endpoint { -+ remote-endpoint = <&ov5640_0>; -+ bus-width = <8>; -+ hsync-active = <0>; -+ vsync-active = <0>; -+ pclk-sample = <1>; -+ pclk-max-frequency = <77000000>; -+ }; -+ }; -+}; -+ -+&dfsdm { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&dfsdm_clkout_pins_a -+ &dfsdm_data1_pins_a &dfsdm_data3_pins_a>; -+ pinctrl-1 = <&dfsdm_clkout_sleep_pins_a -+ &dfsdm_data1_sleep_pins_a &dfsdm_data3_sleep_pins_a>; -+ spi-max-frequency = <2048000>; -+ -+ clocks = <&rcc DFSDM_K>, <&rcc ADFSDM_K>; -+ clock-names = "dfsdm", "audio"; -+ status = "okay"; -+ -+ dfsdm0: filter@0 { -+ compatible = "st,stm32-dfsdm-dmic"; -+ st,adc-channels = <3>; -+ st,adc-channel-names = "dmic_u1"; -+ st,adc-channel-types = "SPI_R"; -+ st,adc-channel-clk-src = "CLKOUT"; -+ st,filter-order = <3>; -+ status = "okay"; -+ -+ asoc_pdm0: dfsdm-dai { -+ compatible = "st,stm32h7-dfsdm-dai"; -+ #sound-dai-cells = <0>; -+ io-channels = <&dfsdm0 0>; -+ status = "okay"; -+ -+ dfsdm0_port: port { -+ dfsdm_endpoint0: endpoint { -+ remote-endpoint = <&dmic0_endpoint>; -+ }; -+ }; -+ }; -+ }; -+ -+ dfsdm1: filter@1 { -+ compatible = "st,stm32-dfsdm-dmic"; -+ st,adc-channels = <1>; -+ st,adc-channel-names = "dmic_u2"; -+ st,adc-channel-types = "SPI_F"; -+ st,adc-channel-clk-src = "CLKOUT"; -+ st,filter-order = <3>; -+ status = "okay"; -+ -+ asoc_pdm1: dfsdm-dai { -+ compatible = "st,stm32h7-dfsdm-dai"; -+ #sound-dai-cells = <0>; -+ io-channels = <&dfsdm1 0>; -+ status = "okay"; -+ -+ dfsdm1_port: port { -+ dfsdm_endpoint1: endpoint { -+ remote-endpoint = <&dmic1_endpoint>; -+ }; -+ }; -+ }; -+ }; -+ -+ dfsdm2: filter@2 { -+ compatible = "st,stm32-dfsdm-dmic"; -+ st,adc-channels = <3>; -+ st,adc-channel-names = "dmic_u3"; -+ st,adc-channel-types = "SPI_F"; -+ st,adc-channel-clk-src = "CLKOUT"; -+ st,filter-order = <3>; -+ status = "okay"; -+ -+ asoc_pdm2: dfsdm-dai { -+ compatible = "st,stm32h7-dfsdm-dai"; -+ #sound-dai-cells = <0>; -+ io-channels = <&dfsdm2 0>; -+ status = "okay"; -+ -+ dfsdm2_port: port { -+ dfsdm_endpoint2: endpoint { -+ remote-endpoint = <&dmic2_endpoint>; -+ }; -+ }; -+ }; -+ }; -+ -+ dfsdm3: filter@3 { -+ compatible = "st,stm32-dfsdm-dmic"; -+ st,adc-channels = <1>; -+ st,adc-channel-names = "dmic_u4"; -+ st,adc-channel-types = "SPI_R"; -+ st,adc-channel-clk-src = "CLKOUT"; -+ st,filter-order = <3>; -+ status = "okay"; -+ -+ asoc_pdm3: dfsdm-dai { -+ compatible = "st,stm32h7-dfsdm-dai"; -+ #sound-dai-cells = <0>; -+ io-channels = <&dfsdm3 0>; -+ status = "okay"; -+ -+ dfsdm3_port: port { -+ dfsdm_endpoint3: endpoint { -+ remote-endpoint = <&dmic3_endpoint>; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&dsi { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ dsi_in: endpoint { -+ remote-endpoint = <<dc_ep0_out>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ dsi_out: endpoint { -+ remote-endpoint = <&dsi_panel_in>; -+ }; -+ }; -+ }; -+ -+ panel-dsi@0 { -+ compatible = "raydium,rm68200"; -+ reg = <0>; -+ reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>; -+ power-supply = <&v1v8>; -+ backlight = <&panel_backlight>; -+ status = "okay"; -+ -+ port { -+ dsi_panel_in: endpoint { -+ remote-endpoint = <&dsi_out>; -+ }; -+ }; -+ }; -+}; -+ -+ðernet0 { -+ status = "okay"; -+ pinctrl-0 = <ðernet0_rgmii_pins_a>; -+ pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; -+ pinctrl-names = "default", "sleep"; -+ phy-mode = "rgmii"; -+ max-speed = <1000>; -+ phy-handle = <&phy0>; -+ -+ mdio0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "snps,dwmac-mdio"; -+ phy0: ethernet-phy@0 { -+ reg = <0>; -+ }; -+ }; -+}; -+ -+&fmc { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&fmc_pins_a>; -+ pinctrl-1 = <&fmc_sleep_pins_a>; - status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ nand: nand@0 { -+ reg = <0>; -+ nand-on-flash-bbt; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ }; -+}; -+ -+&hdp { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&hdp0_pins_a &hdp6_pins_a &hdp7_pins_a>; -+ pinctrl-1 = <&hdp0_pins_sleep_a &hdp6_pins_sleep_a &hdp7_pins_sleep_a>; -+ status = "disabled"; -+ -+ muxing-hdp = <(STM32_HDP(0, HDP0_GPOVAL_0) | -+ STM32_HDP(6, HDP6_GPOVAL_6) | -+ STM32_HDP(7, HDP7_GPOVAL_7))>; - }; - - &i2c2 { -- pinctrl-names = "default"; -+ pinctrl-names = "default", "sleep"; - pinctrl-0 = <&i2c2_pins_a>; -+ pinctrl-1 = <&i2c2_pins_sleep_a>; - i2c-scl-rising-time-ns = <185>; - i2c-scl-falling-time-ns = <20>; - status = "okay"; -+ /delete-property/dmas; -+ /delete-property/dma-names; -+ -+ wm8994: wm8994@1b { -+ compatible = "wlf,wm8994"; -+ #sound-dai-cells = <0>; -+ reg = <0x1b>; -+ status = "okay"; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ DBVDD-supply = <&vdd>; -+ SPKVDD1-supply = <&vdd>; -+ SPKVDD2-supply = <&vdd>; -+ AVDD2-supply = <&v1v8>; -+ CPVDD-supply = <&v1v8>; -+ -+ wlf,ldoena-always-driven; -+ -+ clocks = <&sai2a>; -+ clock-names = "MCLK1"; -+ -+ wlf,gpio-cfg = <0x8101 0xa100 0xa100 0xa100 0xa101 0xa101 0xa100 0xa101 0xa101 0xa101 0xa101>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ wm8994_tx_port: port@0 { -+ reg = <0>; -+ wm8994_tx_endpoint: endpoint { -+ remote-endpoint = <&sai2a_endpoint>; -+ }; -+ }; -+ -+ wm8994_rx_port: port@1 { -+ reg = <1>; -+ wm8994_rx_endpoint: endpoint { -+ remote-endpoint = <&sai2b_endpoint>; -+ }; -+ }; -+ }; -+ }; -+ -+ ov5640: camera@3c { -+ compatible = "ovti,ov5640"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ov5640_pins>; -+ reg = <0x3c>; -+ clocks = <&clk_ext_camera>; -+ clock-names = "xclk"; -+ DOVDD-supply = <&v2v8>; -+ powerdown-gpios = <&stmfx_pinctrl 18 GPIO_ACTIVE_HIGH>; -+ reset-gpios = <&stmfx_pinctrl 19 GPIO_ACTIVE_LOW>; -+ rotation = <180>; -+ status = "okay"; -+ -+ port { -+ ov5640_0: endpoint { -+ remote-endpoint = <&dcmi_0>; -+ bus-width = <8>; -+ data-shift = <2>; /* lines 9:2 are used */ -+ hsync-active = <0>; -+ vsync-active = <0>; -+ pclk-sample = <1>; -+ pclk-max-frequency = <77000000>; -+ }; -+ }; -+ }; -+ -+ stmfx: stmfx@42 { -+ compatible = "st,stmfx-0300"; -+ reg = <0x42>; -+ interrupts = <8 IRQ_TYPE_EDGE_RISING>; -+ interrupt-parent = <&gpioi>; -+ vdd-supply = <&v3v3>; -+ -+ stmfx_pinctrl: stmfx-pin-controller { -+ compatible = "st,stmfx-0300-pinctrl"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ gpio-ranges = <&stmfx_pinctrl 0 0 24>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hog_pins>; -+ -+ hog_pins: hog { -+ pins = "gpio14"; -+ drive-push-pull; -+ bias-pull-down; -+ }; -+ -+ joystick_pins: joystick { -+ pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4"; -+ drive-push-pull; -+ bias-pull-down; -+ }; -+ -+ ov5640_pins: camera { -+ pins = "agpio2", "agpio3"; /* stmfx pins 18 & 19 */ -+ drive-push-pull; -+ output-low; -+ }; -+ }; -+ }; -+ -+ gt9147: goodix_ts@5d { -+ compatible = "goodix,gt9147"; -+ reg = <0x5d>; -+ status = "okay"; -+ -+ irq-gpios = <&stmfx_pinctrl 14 GPIO_ACTIVE_HIGH>; -+ irq-flags = ; -+ }; -+}; -+ -+&i2c4 { -+ pmic: stpmic@33 { -+ regulators { -+ v1v8: ldo6 { -+ regulator-enable-ramp-delay = <300000>; -+ }; -+ }; -+ }; - }; - - &i2c5 { -- pinctrl-names = "default"; -+ pinctrl-names = "default", "sleep"; - pinctrl-0 = <&i2c5_pins_a>; -+ pinctrl-1 = <&i2c5_pins_sleep_a>; - i2c-scl-rising-time-ns = <185>; - i2c-scl-falling-time-ns = <20>; -+ /delete-property/dmas; -+ /delete-property/dma-names; -+}; -+ -+<dc { -+ status = "okay"; -+ -+ port { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ltdc_ep0_out: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&dsi_in>; -+ }; -+ }; -+}; -+ -+&m_can1 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&m_can1_pins_a>; -+ pinctrl-1 = <&m_can1_sleep_pins_a>; - status = "okay"; - }; - - &qspi { -- pinctrl-names = "default"; -+ pinctrl-names = "default", "sleep"; - pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>; -+ pinctrl-1 = <&qspi_clk_sleep_pins_a &qspi_bk1_sleep_pins_a &qspi_bk2_sleep_pins_a>; - reg = <0x58003000 0x1000>, <0x70000000 0x4000000>; - #address-cells = <1>; - #size-cells = <0>; - status = "okay"; - - flash0: mx66l51235l@0 { -+ compatible = "jedec,spi-nor"; - reg = <0>; - spi-rx-bus-width = <4>; - spi-max-frequency = <108000000>; -@@ -52,6 +573,7 @@ - }; - - flash1: mx66l51235l@1 { -+ compatible = "jedec,spi-nor"; - reg = <1>; - spi-rx-bus-width = <4>; - spi-max-frequency = <108000000>; -@@ -60,11 +582,110 @@ - }; - }; - -+&sai2 { -+ clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_a>; -+ pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_a>; -+ clock-names = "pclk", "x8k", "x11k"; -+ status = "okay"; -+ -+ sai2a: audio-controller@4400b004 { -+ #clock-cells = <0>; -+ dma-names = "tx"; -+ clocks = <&rcc SAI2_K>; -+ clock-names = "sai_ck"; -+ status = "okay"; -+ -+ sai2a_port: port { -+ sai2a_endpoint: endpoint { -+ remote-endpoint = <&wm8994_tx_endpoint>; -+ format = "i2s"; -+ mclk-fs = <256>; -+ }; -+ }; -+ }; -+ -+ sai2b: audio-controller@4400b024 { -+ dma-names = "rx"; -+ clocks = <&rcc SAI2_K>, <&sai2a>; -+ clock-names = "sai_ck", "MCLK"; -+ status = "okay"; -+ -+ sai2b_port: port { -+ sai2b_endpoint: endpoint { -+ remote-endpoint = <&wm8994_rx_endpoint>; -+ format = "i2s"; -+ mclk-fs = <256>; -+ }; -+ }; -+ }; -+}; -+ -+&sai4 { -+ clocks = <&rcc SAI4>, <&rcc PLL3_Q>, <&rcc PLL3_R>; -+ clock-names = "pclk", "x8k", "x11k"; -+ status = "okay"; -+ -+ sai4a: audio-controller@50027004 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&sai4a_pins_a>; -+ pinctrl-1 = <&sai4a_sleep_pins_a>; -+ dma-names = "tx"; -+ clocks = <&rcc SAI4_K>; -+ clock-names = "sai_ck"; -+ st,iec60958; -+ status = "okay"; -+ -+ sai4a_port: port { -+ sai4a_endpoint: endpoint { -+ remote-endpoint = <&spdif_out_endpoint>; -+ }; -+ }; -+ }; -+}; -+ -+&sdmmc3 { -+ pinctrl-names = "default", "opendrain", "sleep"; -+ pinctrl-0 = <&sdmmc3_b4_pins_a>; -+ pinctrl-1 = <&sdmmc3_b4_od_pins_a>; -+ pinctrl-2 = <&sdmmc3_b4_sleep_pins_a>; -+ vmmc-supply = <&v3v3>; -+ broken-cd; -+ st,neg-edge; -+ bus-width = <4>; -+ status = "disabled"; -+}; -+ -+&spdifrx { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&spdifrx_pins_a>; -+ pinctrl-1 = <&spdifrx_sleep_pins_a>; -+ status = "okay"; -+ -+ spdifrx_port: port { -+ spdifrx_endpoint: endpoint { -+ remote-endpoint = <&spdif_in_endpoint>; -+ }; -+ }; -+}; -+ -+&spi1 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&spi1_pins_a>; -+ pinctrl-1 = <&spi1_sleep_pins_a>; -+ status = "disabled"; -+}; -+ - &timers2 { - status = "disabled"; -+ /* spare dmas for other usage (un-delete to enable pwm capture) */ -+ /delete-property/dmas; -+ /delete-property/dma-names; - pwm { - pinctrl-0 = <&pwm2_pins_a>; -- pinctrl-names = "default"; -+ pinctrl-1 = <&pwm2_sleep_pins_a>; -+ pinctrl-names = "default", "sleep"; - status = "okay"; - }; - timer@1 { -@@ -74,9 +695,12 @@ - - &timers8 { - status = "disabled"; -+ /delete-property/dmas; -+ /delete-property/dma-names; - pwm { - pinctrl-0 = <&pwm8_pins_a>; -- pinctrl-names = "default"; -+ pinctrl-1 = <&pwm8_sleep_pins_a>; -+ pinctrl-names = "default", "sleep"; - status = "okay"; - }; - timer@7 { -@@ -86,9 +710,12 @@ - - &timers12 { - status = "disabled"; -+ /delete-property/dmas; -+ /delete-property/dma-names; - pwm { - pinctrl-0 = <&pwm12_pins_a>; -- pinctrl-names = "default"; -+ pinctrl-1 = <&pwm12_sleep_pins_a>; -+ pinctrl-names = "default", "sleep"; - status = "okay"; - }; - timer@11 { -@@ -96,6 +723,14 @@ - }; - }; - -+&usart3 { -+ pinctrl-names = "default", "sleep", "idle"; -+ pinctrl-0 = <&usart3_pins_a>; -+ pinctrl-1 = <&usart3_sleep_pins_a>; -+ pinctrl-2 = <&usart3_idle_pins_a>; -+ status = "disabled"; -+}; -+ - &usbh_ehci { - phys = <&usbphyc_port0>; - phy-names = "usb"; -@@ -114,3 +749,11 @@ - &usbphyc { - status = "okay"; - }; -+ -+&usbphyc_port0 { -+ st,phy-tuning = <&usb_phy_tuning>; -+}; -+ -+&usbphyc_port1 { -+ st,phy-tuning = <&usb_phy_tuning>; -+}; -diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp157c.dtsi -index 33c5981..4de499e 100644 ---- a/arch/arm/dts/stm32mp157c.dtsi -+++ b/arch/arm/dts/stm32mp157c.dtsi -@@ -19,42 +19,28 @@ - compatible = "arm,cortex-a7"; - device_type = "cpu"; - reg = <0>; -+ clock-frequency = <650000000>; - }; - - cpu1: cpu@1 { - compatible = "arm,cortex-a7"; - device_type = "cpu"; - reg = <1>; -+ clock-frequency = <650000000>; - }; - }; - -- psci { -- compatible = "arm,psci"; -- method = "smc"; -- cpu_off = <0x84000002>; -- cpu_on = <0x84000003>; -+ arm-pmu { -+ compatible = "arm,cortex-a7-pmu"; -+ interrupts = , -+ ; -+ interrupt-affinity = <&cpu0>, <&cpu1>; -+ interrupt-parent = <&intc>; - }; - -- aliases { -- gpio0 = &gpioa; -- gpio1 = &gpiob; -- gpio2 = &gpioc; -- gpio3 = &gpiod; -- gpio4 = &gpioe; -- gpio5 = &gpiof; -- gpio6 = &gpiog; -- gpio7 = &gpioh; -- gpio8 = &gpioi; -- gpio9 = &gpioj; -- gpio10 = &gpiok; -- serial0 = &usart1; -- serial1 = &usart2; -- serial2 = &usart3; -- serial3 = &uart4; -- serial4 = &uart5; -- serial5 = &usart6; -- serial6 = &uart7; -- serial7 = &uart8; -+ psci { -+ compatible = "arm,psci-1.0"; -+ method = "smc"; - }; - - intc: interrupt-controller@a0021000 { -@@ -104,6 +90,18 @@ - compatible = "fixed-clock"; - clock-frequency = <4000000>; - }; -+ -+ clk_i2s_ckin: i2s_ckin { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+ }; -+ -+ clk_dsi_phy: ck_dsi_phy { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+ }; - }; - - pm_domain { -@@ -126,6 +124,61 @@ - }; - }; - -+ thermal-zones { -+ cpu_thermal: cpu-thermal { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&dts>; -+ -+ trips { -+ cpu_alert1: cpu-alert1 { -+ temperature = <85000>; -+ hysteresis = <0>; -+ type = "passive"; -+ }; -+ -+ cpu-crit { -+ temperature = <120000>; -+ hysteresis = <0>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ }; -+ }; -+ }; -+ -+ reboot { -+ compatible = "syscon-reboot"; -+ regmap = <&rcc>; -+ offset = <0x404>; -+ mask = <0x1>; -+ }; -+ -+ replicator { -+ /* -+ * non-configurable replicators don't show up on the -+ * AMBA bus. As such no need to add "arm,primecell" -+ */ -+ compatible = "arm,coresight-replicator"; -+ clocks = <&rcc CK_TRACE>; -+ clock-names = "apb_pclk"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* replicator output ports */ -+ port@0 { -+ reg = <0>; -+ replicator_out_port0: endpoint { -+ remote-endpoint = <&funnel_in_port4>; -+ }; -+ }; -+ }; -+ }; -+ - soc { - compatible = "simple-bus"; - #address-cells = <1>; -@@ -140,6 +193,12 @@ - reg = <0x40000000 0x400>; - clocks = <&rcc TIM2_K>; - clock-names = "int"; -+ dmas = <&dmamux1 18 0x400 0x5>, -+ <&dmamux1 19 0x400 0x5>, -+ <&dmamux1 20 0x400 0x5>, -+ <&dmamux1 21 0x400 0x5>, -+ <&dmamux1 22 0x400 0x5>; -+ dma-names = "ch1", "ch2", "ch3", "ch4", "up"; - status = "disabled"; - - pwm { -@@ -161,6 +220,13 @@ - reg = <0x40001000 0x400>; - clocks = <&rcc TIM3_K>; - clock-names = "int"; -+ dmas = <&dmamux1 23 0x400 0x5>, -+ <&dmamux1 24 0x400 0x5>, -+ <&dmamux1 25 0x400 0x5>, -+ <&dmamux1 26 0x400 0x5>, -+ <&dmamux1 27 0x400 0x5>, -+ <&dmamux1 28 0x400 0x5>; -+ dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig"; - status = "disabled"; - - pwm { -@@ -182,6 +248,11 @@ - reg = <0x40002000 0x400>; - clocks = <&rcc TIM4_K>; - clock-names = "int"; -+ dmas = <&dmamux1 29 0x400 0x5>, -+ <&dmamux1 30 0x400 0x5>, -+ <&dmamux1 31 0x400 0x5>, -+ <&dmamux1 32 0x400 0x5>; -+ dma-names = "ch1", "ch2", "ch3", "ch4"; - status = "disabled"; - - pwm { -@@ -203,6 +274,13 @@ - reg = <0x40003000 0x400>; - clocks = <&rcc TIM5_K>; - clock-names = "int"; -+ dmas = <&dmamux1 55 0x400 0x5>, -+ <&dmamux1 56 0x400 0x5>, -+ <&dmamux1 57 0x400 0x5>, -+ <&dmamux1 58 0x400 0x5>, -+ <&dmamux1 59 0x400 0x5>, -+ <&dmamux1 60 0x400 0x5>; -+ dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig"; - status = "disabled"; - - pwm { -@@ -224,6 +302,8 @@ - reg = <0x40004000 0x400>; - clocks = <&rcc TIM6_K>; - clock-names = "int"; -+ dmas = <&dmamux1 69 0x400 0x5>; -+ dma-names = "up"; - status = "disabled"; - - timer@5 { -@@ -240,6 +320,8 @@ - reg = <0x40005000 0x400>; - clocks = <&rcc TIM7_K>; - clock-names = "int"; -+ dmas = <&dmamux1 70 0x400 0x5>; -+ dma-names = "up"; - status = "disabled"; - - timer@6 { -@@ -319,6 +401,7 @@ - reg = <0x40009000 0x400>; - clocks = <&rcc LPTIM1_K>; - clock-names = "mux"; -+ power-domains = <&pd_core>; - status = "disabled"; - - pwm { -@@ -339,87 +422,196 @@ - }; - }; - -+ 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 0x05>, -+ <&dmamux1 40 0x400 0x05>; -+ dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; -+ 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"; -+ }; -+ -+ 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 0x05>, -+ <&dmamux1 62 0x400 0x05>; -+ dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; -+ 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"; -+ }; -+ -+ 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"; -+ }; -+ - usart2: serial@4000e000 { - compatible = "st,stm32h7-uart"; - reg = <0x4000e000 0x400>; -- interrupts = ; -+ interrupt-names = "event", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 27 1>; - clocks = <&rcc USART2_K>; -+ resets = <&rcc USART2_R>; -+ wakeup-source; -+ power-domains = <&pd_core>; - status = "disabled"; - }; - - usart3: serial@4000f000 { - compatible = "st,stm32h7-uart"; - reg = <0x4000f000 0x400>; -- interrupts = ; -+ interrupt-names = "event", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 28 1>; - clocks = <&rcc USART3_K>; -+ resets = <&rcc USART3_R>; -+ wakeup-source; -+ power-domains = <&pd_core>; - status = "disabled"; - }; - - uart4: serial@40010000 { - compatible = "st,stm32h7-uart"; - reg = <0x40010000 0x400>; -- interrupts = ; -+ interrupt-names = "event", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 30 1>; - clocks = <&rcc UART4_K>; -+ resets = <&rcc UART4_R>; -+ wakeup-source; -+ power-domains = <&pd_core>; - status = "disabled"; - }; - - uart5: serial@40011000 { - compatible = "st,stm32h7-uart"; - reg = <0x40011000 0x400>; -- interrupts = ; -+ interrupt-names = "event", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 31 1>; - clocks = <&rcc UART5_K>; -+ resets = <&rcc UART5_R>; -+ wakeup-source; -+ power-domains = <&pd_core>; - status = "disabled"; - }; - - i2c1: i2c@40012000 { - compatible = "st,stm32f7-i2c"; - reg = <0x40012000 0x400>; -- interrupt-names = "event", "error"; -- interrupts = , -- ; -+ interrupt-names = "event", "error", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>, -+ <&intc GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 21 1>; - clocks = <&rcc I2C1_K>; - resets = <&rcc I2C1_R>; - #address-cells = <1>; - #size-cells = <0>; -+ dmas = <&dmamux1 33 0x400 0x05>, -+ <&dmamux1 34 0x400 0x05>; -+ dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; -+ st,syscfg-fmp = <&syscfg 0x4 0x1>; - status = "disabled"; - }; - - i2c2: i2c@40013000 { - compatible = "st,stm32f7-i2c"; - reg = <0x40013000 0x400>; -- interrupt-names = "event", "error"; -- interrupts = , -- ; -+ interrupt-names = "event", "error", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>, -+ <&intc GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 22 1>; - clocks = <&rcc I2C2_K>; - resets = <&rcc I2C2_R>; - #address-cells = <1>; - #size-cells = <0>; -+ dmas = <&dmamux1 35 0x400 0x05>, -+ <&dmamux1 36 0x400 0x05>; -+ dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; -+ st,syscfg-fmp = <&syscfg 0x4 0x2>; - status = "disabled"; - }; - - i2c3: i2c@40014000 { - compatible = "st,stm32f7-i2c"; - reg = <0x40014000 0x400>; -- interrupt-names = "event", "error"; -- interrupts = , -- ; -+ interrupt-names = "event", "error", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, -+ <&intc GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 23 1>; - clocks = <&rcc I2C3_K>; - resets = <&rcc I2C3_R>; - #address-cells = <1>; - #size-cells = <0>; -+ dmas = <&dmamux1 73 0x400 0x05>, -+ <&dmamux1 74 0x400 0x05>; -+ dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; -+ st,syscfg-fmp = <&syscfg 0x4 0x4>; - status = "disabled"; - }; - - i2c5: i2c@40015000 { - compatible = "st,stm32f7-i2c"; - reg = <0x40015000 0x400>; -- interrupt-names = "event", "error"; -- interrupts = , -- ; -+ interrupt-names = "event", "error", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>, -+ <&intc GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 25 1>; - clocks = <&rcc I2C5_K>; - resets = <&rcc I2C5_R>; - #address-cells = <1>; - #size-cells = <0>; -+ dmas = <&dmamux1 115 0x400 0x05>, -+ <&dmamux1 116 0x400 0x05>; -+ dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; -+ st,syscfg-fmp = <&syscfg 0x4 0x10>; - status = "disabled"; - }; - -@@ -429,6 +621,7 @@ - interrupts = ; - clocks = <&rcc CEC_K>, <&clk_lse>; - clock-names = "cec", "hdmi-cec"; -+ power-domains = <&pd_core>; - status = "disabled"; - }; - -@@ -459,16 +652,26 @@ - uart7: serial@40018000 { - compatible = "st,stm32h7-uart"; - reg = <0x40018000 0x400>; -- interrupts = ; -+ interrupt-names = "event", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 32 1>; - clocks = <&rcc UART7_K>; -+ resets = <&rcc UART7_R>; -+ wakeup-source; -+ power-domains = <&pd_core>; - status = "disabled"; - }; - - uart8: serial@40019000 { - compatible = "st,stm32h7-uart"; - reg = <0x40019000 0x400>; -- interrupts = ; -+ interrupt-names = "event", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 33 1>; - clocks = <&rcc UART8_K>; -+ resets = <&rcc UART8_R>; -+ wakeup-source; -+ power-domains = <&pd_core>; - status = "disabled"; - }; - -@@ -479,6 +682,15 @@ - reg = <0x44000000 0x400>; - clocks = <&rcc TIM1_K>; - clock-names = "int"; -+ dmas = <&dmamux1 11 0x400 0x5>, -+ <&dmamux1 12 0x400 0x5>, -+ <&dmamux1 13 0x400 0x5>, -+ <&dmamux1 14 0x400 0x5>, -+ <&dmamux1 15 0x400 0x5>, -+ <&dmamux1 16 0x400 0x5>, -+ <&dmamux1 17 0x400 0x5>; -+ dma-names = "ch1", "ch2", "ch3", "ch4", -+ "up", "trig", "com"; - status = "disabled"; - - pwm { -@@ -500,6 +712,15 @@ - reg = <0x44001000 0x400>; - clocks = <&rcc TIM8_K>; - clock-names = "int"; -+ dmas = <&dmamux1 47 0x400 0x5>, -+ <&dmamux1 48 0x400 0x5>, -+ <&dmamux1 49 0x400 0x5>, -+ <&dmamux1 50 0x400 0x5>, -+ <&dmamux1 51 0x400 0x5>, -+ <&dmamux1 52 0x400 0x5>, -+ <&dmamux1 53 0x400 0x5>; -+ dma-names = "ch1", "ch2", "ch3", "ch4", -+ "up", "trig", "com"; - status = "disabled"; - - pwm { -@@ -517,8 +738,54 @@ - usart6: serial@44003000 { - compatible = "st,stm32h7-uart"; - reg = <0x44003000 0x400>; -- interrupts = ; -+ interrupt-names = "event", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 29 1>; - clocks = <&rcc USART6_K>; -+ resets = <&rcc USART6_R>; -+ wakeup-source; -+ power-domains = <&pd_core>; -+ 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 0x05>, -+ <&dmamux1 38 0x400 0x05>; -+ dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; -+ 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"; -+ }; -+ -+ spi4: spi@44005000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "st,stm32h7-spi"; -+ reg = <0x44005000 0x400>; -+ interrupts = ; -+ clocks = <&rcc SPI4_K>; -+ resets = <&rcc SPI4_R>; -+ dmas = <&dmamux1 83 0x400 0x05>, -+ <&dmamux1 84 0x400 0x05>; -+ dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; - status = "disabled"; - }; - -@@ -529,6 +796,11 @@ - reg = <0x44006000 0x400>; - clocks = <&rcc TIM15_K>; - clock-names = "int"; -+ dmas = <&dmamux1 105 0x400 0x5>, -+ <&dmamux1 106 0x400 0x5>, -+ <&dmamux1 107 0x400 0x5>, -+ <&dmamux1 108 0x400 0x5>; -+ dma-names = "ch1", "up", "trig", "com"; - status = "disabled"; - - pwm { -@@ -550,6 +822,9 @@ - reg = <0x44007000 0x400>; - clocks = <&rcc TIM16_K>; - clock-names = "int"; -+ dmas = <&dmamux1 109 0x400 0x5>, -+ <&dmamux1 110 0x400 0x5>; -+ dma-names = "ch1", "up"; - status = "disabled"; - - pwm { -@@ -570,6 +845,9 @@ - reg = <0x44008000 0x400>; - clocks = <&rcc TIM17_K>; - clock-names = "int"; -+ dmas = <&dmamux1 111 0x400 0x5>, -+ <&dmamux1 112 0x400 0x5>; -+ dma-names = "ch1", "up"; - status = "disabled"; - - pwm { -@@ -584,6 +862,199 @@ - }; - }; - -+ spi5: spi@44009000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "st,stm32h7-spi"; -+ reg = <0x44009000 0x400>; -+ interrupts = ; -+ clocks = <&rcc SPI5_K>; -+ resets = <&rcc SPI5_R>; -+ dmas = <&dmamux1 85 0x400 0x05>, -+ <&dmamux1 86 0x400 0x05>; -+ dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; -+ status = "disabled"; -+ }; -+ -+ sai1: sai@4400a000 { -+ compatible = "st,stm32h7-sai"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0x4400a000 0x400>; -+ reg = <0x4400a000 0x4>; -+ interrupts = ; -+ resets = <&rcc SAI1_R>; -+ status = "disabled"; -+ -+ sai1a: audio-controller@4400a004 { -+ #sound-dai-cells = <0>; -+ -+ compatible = "st,stm32-sai-sub-a"; -+ reg = <0x4 0x1c>; -+ dmas = <&dmamux1 87 0x400 0x01>; -+ status = "disabled"; -+ }; -+ -+ sai1b: audio-controller@4400a024 { -+ #sound-dai-cells = <0>; -+ compatible = "st,stm32-sai-sub-b"; -+ reg = <0x24 0x1c>; -+ 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>; -+ interrupts = ; -+ resets = <&rcc SAI2_R>; -+ status = "disabled"; -+ -+ sai2a: audio-controller@4400b004 { -+ #sound-dai-cells = <0>; -+ compatible = "st,stm32-sai-sub-a"; -+ reg = <0x4 0x1c>; -+ dmas = <&dmamux1 89 0x400 0x01>; -+ status = "disabled"; -+ }; -+ -+ sai2b: audio-controller@4400b024 { -+ #sound-dai-cells = <0>; -+ compatible = "st,stm32-sai-sub-b"; -+ reg = <0x24 0x1c>; -+ dmas = <&dmamux1 90 0x400 0x01>; -+ status = "disabled"; -+ }; -+ }; -+ -+ sai3: sai@4400c000 { -+ compatible = "st,stm32h7-sai"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0x4400c000 0x400>; -+ reg = <0x4400c000 0x4>; -+ interrupts = ; -+ resets = <&rcc SAI3_R>; -+ status = "disabled"; -+ -+ sai3a: audio-controller@4400c004 { -+ #sound-dai-cells = <0>; -+ compatible = "st,stm32-sai-sub-a"; -+ reg = <0x04 0x1c>; -+ dmas = <&dmamux1 113 0x400 0x01>; -+ status = "disabled"; -+ }; -+ -+ sai3b: audio-controller@4400c024 { -+ #sound-dai-cells = <0>; -+ compatible = "st,stm32-sai-sub-b"; -+ reg = <0x24 0x1c>; -+ dmas = <&dmamux1 114 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"; -+ }; -+ -+ dfsdm2: filter@2 { -+ compatible = "st,stm32-dfsdm-adc"; -+ #io-channel-cells = <1>; -+ reg = <2>; -+ interrupts = ; -+ dmas = <&dmamux1 103 0x400 0x01>; -+ dma-names = "rx"; -+ status = "disabled"; -+ }; -+ -+ dfsdm3: filter@3 { -+ compatible = "st,stm32-dfsdm-adc"; -+ #io-channel-cells = <1>; -+ reg = <3>; -+ interrupts = ; -+ dmas = <&dmamux1 104 0x400 0x01>; -+ dma-names = "rx"; -+ status = "disabled"; -+ }; -+ -+ dfsdm4: filter@4 { -+ compatible = "st,stm32-dfsdm-adc"; -+ #io-channel-cells = <1>; -+ reg = <4>; -+ interrupts = ; -+ dmas = <&dmamux1 91 0x400 0x01>; -+ dma-names = "rx"; -+ status = "disabled"; -+ }; -+ -+ dfsdm5: filter@5 { -+ compatible = "st,stm32-dfsdm-adc"; -+ #io-channel-cells = <1>; -+ reg = <5>; -+ interrupts = ; -+ dmas = <&dmamux1 92 0x400 0x01>; -+ dma-names = "rx"; -+ 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 = <&rcc CK_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 = <&rcc CK_HSE>, <&rcc FDCAN_K>; -+ clock-names = "hclk", "cclk"; -+ bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>; -+ status = "disabled"; -+ }; -+ - dma1: dma@48000000 { - compatible = "st,stm32-dma"; - reg = <0x48000000 0x400>; -@@ -599,6 +1070,15 @@ - #dma-cells = <4>; - st,mem2mem; - dma-requests = <8>; -+ dmas = <&mdma1 0 0x11 0x1200000a 0x48000008 0x00000020 1>, -+ <&mdma1 1 0x11 0x1200000a 0x48000008 0x00000800 1>, -+ <&mdma1 2 0x11 0x1200000a 0x48000008 0x00200000 1>, -+ <&mdma1 3 0x11 0x1200000a 0x48000008 0x08000000 1>, -+ <&mdma1 4 0x11 0x1200000a 0x4800000C 0x00000020 1>, -+ <&mdma1 5 0x11 0x1200000a 0x4800000C 0x00000800 1>, -+ <&mdma1 6 0x11 0x1200000a 0x4800000C 0x00200000 1>, -+ <&mdma1 7 0x11 0x1200000a 0x4800000C 0x08000000 1>; -+ dma-names = "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7"; - }; - - dma2: dma@48001000 { -@@ -616,6 +1096,15 @@ - #dma-cells = <4>; - st,mem2mem; - dma-requests = <8>; -+ dmas = <&mdma1 8 0x11 0x1200000a 0x48001008 0x00000020 1>, -+ <&mdma1 9 0x11 0x1200000a 0x48001008 0x00000800 1>, -+ <&mdma1 10 0x11 0x1200000a 0x48001008 0x00200000 1>, -+ <&mdma1 11 0x11 0x1200000a 0x48001008 0x08000000 1>, -+ <&mdma1 12 0x11 0x1200000a 0x4800100C 0x00000020 1>, -+ <&mdma1 13 0x11 0x1200000a 0x4800100C 0x00000800 1>, -+ <&mdma1 14 0x11 0x1200000a 0x4800100C 0x00200000 1>, -+ <&mdma1 15 0x11 0x1200000a 0x4800100C 0x08000000 1>; -+ dma-names = "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7"; - }; - - dmamux1: dma-router@48002000 { -@@ -636,6 +1125,10 @@ - clocks = <&rcc ADC12>, <&rcc ADC12_K>; - clock-names = "bus", "adc"; - interrupt-controller; -+ st,syscfg-vbooster = <&syscfg 0x4 0x100>; -+ st,syscfg-vbooster-clr = <&syscfg 0x44 0x100>; -+ st,syscfg-anaswvdd = <&syscfg 0x4 0x200>; -+ st,syscfg-anaswvdd-clr = <&syscfg 0x44 0x200>; - #interrupt-cells = <1>; - #address-cells = <1>; - #size-cells = <0>; -@@ -647,6 +1140,8 @@ - reg = <0x0>; - interrupt-parent = <&adc>; - interrupts = <0>; -+ dmas = <&dmamux1 9 0x400 0x05>; -+ dma-names = "rx"; - status = "disabled"; - }; - -@@ -656,18 +1151,57 @@ - reg = <0x100>; - interrupt-parent = <&adc>; - interrupts = <1>; -+ dmas = <&dmamux1 10 0x400 0x05>; -+ dma-names = "rx"; -+ /* temperature sensor */ -+ st,adc-channels = <12>; -+ st,min-sample-time-nsecs = <10000>; -+ status = "disabled"; -+ }; -+ -+ jadc1: jadc@0 { -+ compatible = "st,stm32mp1-adc"; -+ st,injected; -+ #io-channel-cells = <1>; -+ reg = <0x0>; -+ interrupt-parent = <&adc>; -+ interrupts = <3>; -+ status = "disabled"; -+ }; -+ -+ jadc2: jadc@100 { -+ compatible = "st,stm32mp1-adc"; -+ st,injected; -+ #io-channel-cells = <1>; -+ reg = <0x100>; -+ interrupt-parent = <&adc>; -+ interrupts = <4>; -+ /* temperature sensor */ -+ st,adc-channels = <12>; -+ st,min-sample-time-nsecs = <10000>; -+ status = "disabled"; -+ }; -+ -+ adc_temp: temp { -+ compatible = "st,stm32mp1-adc-temp"; -+ io-channels = <&adc2 12>; -+ nvmem-cells = <&ts_cal1>, <&ts_cal2>; -+ nvmem-cell-names = "ts_cal1", "ts_cal2"; -+ #io-channel-cells = <0>; -+ #thermal-sensor-cells = <0>; - status = "disabled"; - }; - }; - - sdmmc3: sdmmc@48004000 { -- compatible = "st,stm32-sdmmc2"; -+ compatible = "arm,pl18x", "arm,primecell"; -+ arm,primecell-periphid = <0x00253180>; - reg = <0x48004000 0x400>, <0x48005000 0x400>; -- reg-names = "sdmmc", "delay"; -- interrupts = ; -+ interrupts = ; -+ interrupt-names = "cmd_irq"; - clocks = <&rcc SDMMC3_K>; -+ clock-names = "apb_pclk"; - resets = <&rcc SDMMC3_R>; -- st,idma = <1>; - cap-sd-highspeed; - cap-mmc-highspeed; - max-frequency = <120000000>; -@@ -686,34 +1220,66 @@ - g-np-tx-fifo-size = <32>; - g-tx-fifo-size = <128 128 64 64 64 64 32 32>; - dr_mode = "otg"; -+ usb33d-supply = <&usb33>; - power-domains = <&pd_core>; - status = "disabled"; - }; - -+ hsem: hwspinlock@4c000000 { -+ compatible = "st,stm32-hwspinlock"; -+ #hwlock-cells = <1>; -+ reg = <0x4c000000 0x400>; -+ clocks = <&rcc HSEM>; -+ clock-names = "hsem"; -+ status = "okay"; -+ }; -+ -+ ipcc: mailbox@4c001000 { -+ compatible = "st,stm32mp1-ipcc"; -+ #mbox-cells = <1>; -+ reg = <0x4c001000 0x400>; -+ st,proc-id = <0>; -+ interrupts-extended = -+ <&intc GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, -+ <&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 61 1>; -+ interrupt-names = "rx", "tx", "wakeup"; -+ clocks = <&rcc IPCC>; -+ wakeup-source; -+ power-domains = <&pd_core>; -+ status = "disabled"; -+ }; -+ -+ dcmi: dcmi@4c006000 { -+ compatible = "st,stm32-dcmi"; -+ reg = <0x4c006000 0x400>; -+ interrupts = ; -+ resets = <&rcc CAMITF_R>; -+ clocks = <&rcc DCMI>; -+ clock-names = "mclk"; -+ dmas = <&dmamux1 75 0x400 0xd>; -+ dma-names = "tx"; -+ status = "disabled"; -+ }; -+ - rcc: rcc@50000000 { - compatible = "st,stm32mp1-rcc", "syscon"; - reg = <0x50000000 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; -- }; -- -- rcc_reboot: rcc-reboot@50000000 { -- compatible = "syscon-reboot"; -- regmap = <&rcc>; -- offset = <0x404>; -- mask = <0x1>; -+ interrupts = ; - }; - - pwr: pwr@50001000 { -- compatible = "st,stm32mp1-pwr", "st,stm32-pwr", "syscon", "simple-mfd"; -+ compatible = "st,stm32mp1-pwr", "syscon", "simple-mfd"; - reg = <0x50001000 0x400>; -- system-power-controller; -+ - interrupts = ; -- st,sysrcc = <&rcc>; -- clocks = <&rcc PLL2_R>; -- clock-names = "phyclk"; - -- pwr-regulators@c { -+ interrupt-controller; -+ #interrupt-cells = <3>; -+ -+ pwr-regulators { - compatible = "st,stm32mp1,pwr-reg"; - st,tzcr = <&rcc 0x0 0x1>; - -@@ -742,11 +1308,24 @@ - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x5000d000 0x400>; -+ hwlocks = <&hsem 1>; -+ -+ /* exti_pwr is an extra interrupt controller used for -+ * EXTI 55 to 60. It's mapped on pwr interrupt -+ * controller. -+ */ -+ exti_pwr: exti-pwr { -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ interrupt-parent = <&pwr>; -+ st,irq-number = <6>; -+ }; - }; - -- syscfg: system-config@50020000 { -- compatible = "st,stm32-syscfg", "syscon"; -+ syscfg: syscon@50020000 { -+ compatible = "st,stm32mp157-syscfg", "syscon"; - reg = <0x50020000 0x400>; -+ clocks = <&rcc SYSCFG>; - }; - - lptimer2: timer@50021000 { -@@ -756,6 +1335,7 @@ - reg = <0x50021000 0x400>; - clocks = <&rcc LPTIM2_K>; - clock-names = "mux"; -+ power-domains = <&pd_core>; - status = "disabled"; - - pwm { -@@ -783,6 +1363,7 @@ - reg = <0x50022000 0x400>; - clocks = <&rcc LPTIM3_K>; - clock-names = "mux"; -+ power-domains = <&pd_core>; - status = "disabled"; - - pwm { -@@ -803,6 +1384,7 @@ - reg = <0x50023000 0x400>; - clocks = <&rcc LPTIM4_K>; - clock-names = "mux"; -+ power-domains = <&pd_core>; - status = "disabled"; - - pwm { -@@ -817,6 +1399,7 @@ - reg = <0x50024000 0x400>; - clocks = <&rcc LPTIM5_K>; - clock-names = "mux"; -+ power-domains = <&pd_core>; - status = "disabled"; - - pwm { -@@ -835,6 +1418,196 @@ - status = "disabled"; - }; - -+ sai4: sai@50027000 { -+ compatible = "st,stm32h7-sai"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0x50027000 0x400>; -+ reg = <0x50027000 0x4>; -+ interrupts = ; -+ resets = <&rcc SAI4_R>; -+ status = "disabled"; -+ -+ sai4a: audio-controller@50027004 { -+ #sound-dai-cells = <0>; -+ compatible = "st,stm32-sai-sub-a"; -+ reg = <0x04 0x1c>; -+ clocks = <&rcc SAI4_K>; -+ clock-names = "sai_ck"; -+ dmas = <&dmamux1 99 0x400 0x01>; -+ status = "disabled"; -+ }; -+ -+ sai4b: audio-controller@50027024 { -+ #sound-dai-cells = <0>; -+ compatible = "st,stm32-sai-sub-b"; -+ reg = <0x24 0x1c>; -+ dmas = <&dmamux1 100 0x400 0x01>; -+ status = "disabled"; -+ }; -+ }; -+ -+ dts: thermal@50028000 { -+ compatible = "st,stm32-thermal"; -+ reg = <0x50028000 0x100>; -+ interrupts = ; -+ clocks = <&rcc TMPSENS>; -+ clock-names = "pclk"; -+ #thermal-sensor-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ hdp: hdp@5002a000 { -+ compatible = "st,stm32mp1-hdp"; -+ reg = <0x5002a000 0x400>; -+ clocks = <&rcc HDP>; -+ clock-names = "hdp"; -+ status = "disabled"; -+ }; -+ -+ funnel: funnel@50091000 { -+ compatible = "arm,coresight-funnel", "arm,primecell"; -+ reg = <0x50091000 0x1000>; -+ clocks = <&rcc CK_TRACE>; -+ clock-names = "apb_pclk"; -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* funnel input ports */ -+ port@0 { -+ reg = <0>; -+ funnel_in_port0: endpoint { -+ slave-mode; -+ remote-endpoint = <&stm_out_port>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ funnel_in_port1: endpoint { -+ slave-mode; /* A7-1 input */ -+ remote-endpoint = <&etm1_out_port>; -+ }; -+ }; -+ -+ port@2 { -+ reg = <2>; -+ funnel_in_port2: endpoint { -+ slave-mode; /* A7-2 input */ -+ remote-endpoint = <&etm2_out_port>; -+ }; -+ }; -+ -+ port@4 { -+ reg = <4>; -+ funnel_in_port4: endpoint { -+ slave-mode; /* REPLICATOR input */ -+ remote-endpoint = <&replicator_out_port0>; -+ }; -+ }; -+ -+ port@5 { -+ reg = <0>; -+ funnel_out_port0: endpoint { -+ remote-endpoint = <&etf_in_port>; -+ }; -+ }; -+ }; -+ }; -+ -+ etf: etf@50092000 { -+ compatible = "arm,coresight-tmc", "arm,primecell"; -+ reg = <0x50092000 0x1000>; -+ clocks = <&rcc CK_TRACE>; -+ clock-names = "apb_pclk"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ etf_in_port: endpoint { -+ slave-mode; -+ remote-endpoint = <&funnel_out_port0>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <0>; -+ etf_out_port: endpoint { -+ remote-endpoint = <&tpiu_in_port>; -+ }; -+ }; -+ }; -+ }; -+ -+ tpiu: tpiu@50093000 { -+ compatible = "arm,coresight-tpiu", "arm,primecell"; -+ reg = <0x50093000 0x1000>; -+ clocks = <&rcc CK_TRACE>; -+ clock-names = "apb_pclk"; -+ -+ port { -+ tpiu_in_port: endpoint { -+ slave-mode; -+ remote-endpoint = <&etf_out_port>; -+ }; -+ }; -+ }; -+ -+ stm: stm@500a0000 { -+ compatible = "arm,coresight-stm", "arm,primecell"; -+ reg = <0x500a0000 0x1000>, <0x90000000 0x1000000>, -+ <0x50094000 0x1000>; -+ reg-names = "stm-base", "stm-stimulus-base", "cti-base"; -+ -+ clocks = <&rcc CK_TRACE>; -+ clock-names = "apb_pclk"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ stm_out_port: endpoint { -+ remote-endpoint = <&funnel_in_port0>; -+ }; -+ }; -+ }; -+ }; -+ -+ /* Cortex A7-1 */ -+ etm1: etm@500dc000 { -+ compatible = "arm,coresight-etm3x", "arm,primecell"; -+ reg = <0x500dc000 0x1000>; -+ cpu = <&cpu0>; -+ clocks = <&rcc CK_TRACE>; -+ clock-names = "apb_pclk"; -+ port { -+ etm1_out_port: endpoint { -+ remote-endpoint = <&funnel_in_port1>; -+ }; -+ }; -+ }; -+ -+ /* Cortex A7-2 */ -+ etm2: etm@500dd000 { -+ compatible = "arm,coresight-etm3x", "arm,primecell"; -+ reg = <0x500dd000 0x1000>; -+ cpu = <&cpu1>; -+ clocks = <&rcc CK_TRACE>; -+ clock-names = "apb_pclk"; -+ -+ port { -+ etm2_out_port: endpoint { -+ remote-endpoint = <&funnel_in_port2>; -+ }; -+ }; -+ }; -+ - cryp1: cryp@54001000 { - compatible = "st,stm32mp1-cryp"; - reg = <0x54001000 0x400>; -@@ -844,6 +1617,18 @@ - status = "disabled"; - }; - -+ hash1: hash@54002000 { -+ compatible = "st,stm32f756-hash"; -+ reg = <0x54002000 0x400>; -+ interrupts = ; -+ clocks = <&rcc HASH1>; -+ resets = <&rcc HASH1_R>; -+ dmas = <&mdma1 31 0x10 0x1000A02 0x0 0x0 0x0 0x0>; -+ dma-names = "in"; -+ dma-maxburst = <2>; -+ status = "disabled"; -+ }; -+ - rng1: rng@54003000 { - compatible = "st,stm32-rng"; - reg = <0x54003000 0x400>; -@@ -857,28 +1642,52 @@ - reg = <0x58000000 0x1000>; - interrupts = ; - clocks = <&rcc MDMA>; -- #dma-cells = <5>; -+ #dma-cells = <6>; - dma-channels = <32>; - dma-requests = <48>; - }; - -+ fmc: nand-controller@58002000 { -+ compatible = "st,stm32mp15-fmc2"; -+ reg = <0x58002000 0x1000>, -+ <0x80000000 0x1000>, -+ <0x88010000 0x1000>, -+ <0x88020000 0x1000>, -+ <0x81000000 0x1000>, -+ <0x89010000 0x1000>, -+ <0x89020000 0x1000>; -+ interrupts = ; -+ dmas = <&mdma1 20 0x10 0x12000A02 0x0 0x0 0>, -+ <&mdma1 20 0x10 0x12000A08 0x0 0x0 0>, -+ <&mdma1 21 0x10 0x12000A0A 0x0 0x0 0>; -+ dma-names = "tx", "rx", "ecc"; -+ clocks = <&rcc FMC_K>; -+ resets = <&rcc FMC_R>; -+ status = "disabled"; -+ }; -+ - qspi: qspi@58003000 { - compatible = "st,stm32f469-qspi"; - reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; - reg-names = "qspi", "qspi_mm"; - interrupts = ; -+ dmas = <&mdma1 22 0x10 0x100002 0x0 0x0 0x0>, -+ <&mdma1 22 0x10 0x100008 0x0 0x0 0x0>; -+ dma-names = "tx", "rx"; - clocks = <&rcc QSPI_K>; - resets = <&rcc QSPI_R>; - status = "disabled"; - }; - - sdmmc1: sdmmc@58005000 { -- compatible = "st,stm32-sdmmc2"; -+ compatible = "arm,pl18x", "arm,primecell"; -+ arm,primecell-periphid = <0x00253180>; - reg = <0x58005000 0x1000>, <0x58006000 0x1000>; -- reg-names = "sdmmc", "delay"; -+ interrupts = ; -+ interrupt-names = "cmd_irq"; - clocks = <&rcc SDMMC1_K>; -+ clock-names = "apb_pclk"; - resets = <&rcc SDMMC1_R>; -- st,idma = <1>; - cap-sd-highspeed; - cap-mmc-highspeed; - max-frequency = <120000000>; -@@ -886,13 +1695,14 @@ - }; - - sdmmc2: sdmmc@58007000 { -- compatible = "st,stm32-sdmmc2"; -+ compatible = "arm,pl18x", "arm,primecell"; -+ arm,primecell-periphid = <0x00253180>; - reg = <0x58007000 0x1000>, <0x58008000 0x1000>; -- reg-names = "sdmmc", "delay"; -- interrupts = ; -+ interrupts = ; -+ interrupt-names = "cmd_irq"; - clocks = <&rcc SDMMC2_K>; -+ clock-names = "apb_pclk"; - resets = <&rcc SDMMC2_R>; -- st,idma = <1>; - cap-sd-highspeed; - cap-mmc-highspeed; - max-frequency = <120000000>; -@@ -906,12 +1716,47 @@ - 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>; -+ reg-names = "stmmaceth"; -+ interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, -+ <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 70 1>; -+ interrupt-names = "macirq", -+ "eth_wake_irq", -+ "stm32_pwr_wakeup"; -+ clock-names = "stmmaceth", -+ "mac-clk-tx", -+ "mac-clk-rx", -+ "ethstp"; -+ clocks = <&rcc ETHMAC>, -+ <&rcc ETHTX>, -+ <&rcc ETHRX>, -+ <&rcc ETHSTP>; -+ st,syscon = <&syscfg 0x4>; -+ snps,mixed-burst; -+ snps,pbl = <2>; -+ snps,en-tx-lpi-clockgating; -+ snps,axi-config = <&stmmac_axi_config_0>; -+ snps,tso; -+ power-domains = <&pd_core>; -+ status = "disabled"; -+ }; -+ - usbh_ohci: usbh-ohci@5800c000 { - compatible = "generic-ohci"; - reg = <0x5800c000 0x1000>; - clocks = <&rcc USBH>; - resets = <&rcc USBH_R>; - interrupts = ; -+ power-domains = <&pd_core>; - status = "disabled"; - }; - -@@ -922,6 +1767,17 @@ - resets = <&rcc USBH_R>; - interrupts = ; - companion = <&usbh_ohci>; -+ power-domains = <&pd_core>; -+ status = "disabled"; -+ }; -+ -+ gpu: gpu@59000000 { -+ compatible = "vivante,gc"; -+ reg = <0x59000000 0x800>; -+ interrupts = ; -+ clocks = <&rcc GPU>, <&rcc GPU_K>; -+ clock-names = "bus" ,"core"; -+ resets = <&rcc GPU_R>; - status = "disabled"; - }; - -@@ -932,6 +1788,7 @@ - clock-names = "pclk", "ref", "px_clk"; - resets = <&rcc DSI_R>; - reset-names = "apb"; -+ phy-dsi-supply = <®18>; - status = "disabled"; - }; - -@@ -946,13 +1803,24 @@ - status = "disabled"; - }; - -+ iwdg2: watchdog@5a002000 { -+ compatible = "st,stm32mp1-iwdg"; -+ reg = <0x5a002000 0x400>; -+ clocks = <&rcc IWDG2>, <&rcc CK_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 = <®11>; -+ vdda1v8-supply = <®18>; - status = "disabled"; - - usbphyc_port0: usb-phy@0 { -@@ -969,35 +1837,136 @@ - usart1: serial@5c000000 { - compatible = "st,stm32h7-uart"; - reg = <0x5c000000 0x400>; -- interrupts = ; -+ interrupt-names = "event", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 26 1>; - clocks = <&rcc USART1_K>; -+ resets = <&rcc USART1_R>; -+ wakeup-source; -+ power-domains = <&pd_core>; -+ status = "disabled"; -+ }; -+ -+ spi6: spi@5c001000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "st,stm32h7-spi"; -+ reg = <0x5c001000 0x400>; -+ interrupts = ; -+ clocks = <&rcc SPI6_K>; -+ resets = <&rcc SPI6_R>; -+ 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"; - }; - - i2c4: i2c@5c002000 { - compatible = "st,stm32f7-i2c"; - reg = <0x5c002000 0x400>; -- interrupt-names = "event", "error"; -- interrupts = , -- ; -+ interrupt-names = "event", "error", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, -+ <&intc GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 24 1>; - clocks = <&rcc I2C4_K>; - resets = <&rcc I2C4_R>; - #address-cells = <1>; - #size-cells = <0>; -+ dmas = <&mdma1 36 0x0 0x40008 0x0 0x0 0>, -+ <&mdma1 37 0x0 0x40002 0x0 0x0 0>; -+ dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; -+ st,syscfg-fmp = <&syscfg 0x4 0x8>; - status = "disabled"; - }; - -+ rtc: rtc@5c004000 { -+ compatible = "st,stm32mp1-rtc"; -+ reg = <0x5c004000 0x400>; -+ clocks = <&rcc RTCAPB>, <&rcc RTC>; -+ clock-names = "pclk", "rtc_ck"; -+ interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 19 1>; -+ status = "disabled"; -+ }; -+ -+ bsec: nvmem@5c005000 { -+ compatible = "st,stm32mp15-bsec"; -+ reg = <0x5c005000 0x400>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ts_cal1: calib@5c { -+ reg = <0x5c 0x2>; -+ }; -+ ts_cal2: calib@5e { -+ reg = <0x5e 0x2>; -+ }; -+ }; -+ - i2c6: i2c@5c009000 { - compatible = "st,stm32f7-i2c"; - reg = <0x5c009000 0x400>; -- interrupt-names = "event", "error"; -- interrupts = , -- ; -+ interrupt-names = "event", "error", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, -+ <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 54 1>; - clocks = <&rcc I2C6_K>; - resets = <&rcc I2C6_R>; - #address-cells = <1>; - #size-cells = <0>; -+ dmas = <&mdma1 38 0x0 0x40008 0x0 0x0 0>, -+ <&mdma1 39 0x0 0x40002 0x0 0x0 0>; -+ dma-names = "rx", "tx"; -+ power-domains = <&pd_core>; -+ st,syscfg-fmp = <&syscfg 0x4 0x20>; -+ status = "disabled"; -+ }; -+ -+ tamp: tamp@5c00a000 { -+ compatible = "simple-bus", "syscon", "simple-mfd"; -+ reg = <0x5c00a000 0x400>; -+ -+ reboot-mode { -+ compatible = "syscon-reboot-mode"; -+ offset = <0x150>; /* reg20 */ -+ mask = <0xff>; -+ mode-normal = <0>; -+ mode-fastboot = <0x1>; -+ mode-recovery = <0x2>; -+ mode-stm32cubeprogrammer = <0x3>; -+ mode-ums_mmc0 = <0x10>; -+ mode-ums_mmc1 = <0x11>; -+ mode-ums_mmc2 = <0x12>; -+ }; -+ }; -+ }; -+ -+ m4_rproc: m4@0 { -+ compatible = "st,stm32mp1-rproc"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ ranges = <0x00000000 0x38000000 0x10000>, -+ <0x30000000 0x30000000 0x60000>, -+ <0x10000000 0x10000000 0x60000>; -+ resets = <&rcc MCU_R>; -+ reset-names = "mcu_rst"; -+ st,syscfg-pdds = <&pwr 0x014 0x1>; -+ st,syscfg-holdboot = <&rcc 0x10C 0x1>; -+ st,syscfg-tz = <&rcc 0x000 0x1>; -+ status = "disabled"; -+ -+ m4_system_resources { -+ compatible = "rproc-srm-core"; - status = "disabled"; - }; - }; -+ -+ firmware { -+ optee { -+ compatible = "linaro,optee-tz"; -+ method = "smc"; -+ }; -+ }; - }; -diff --git a/arch/arm/dts/stm32mp157caa-pinctrl.dtsi b/arch/arm/dts/stm32mp157caa-pinctrl.dtsi -new file mode 100644 -index 0000000..9b9cd08 ---- /dev/null -+++ b/arch/arm/dts/stm32mp157caa-pinctrl.dtsi -@@ -0,0 +1,90 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved -+ * Author: Alexandre Torgue -+ */ -+ -+#include "stm32mp157-pinctrl.dtsi" -+/ { -+ soc { -+ pinctrl: pin-controller@50002000 { -+ st,package = ; -+ -+ gpioa: gpio@50002000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 0 16>; -+ }; -+ -+ gpiob: gpio@50003000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 16 16>; -+ }; -+ -+ gpioc: gpio@50004000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 32 16>; -+ }; -+ -+ gpiod: gpio@50005000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 48 16>; -+ }; -+ -+ gpioe: gpio@50006000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 64 16>; -+ }; -+ -+ gpiof: gpio@50007000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 80 16>; -+ }; -+ -+ gpiog: gpio@50008000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 96 16>; -+ }; -+ -+ gpioh: gpio@50009000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 112 16>; -+ }; -+ -+ gpioi: gpio@5000a000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 128 16>; -+ }; -+ -+ gpioj: gpio@5000b000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 144 16>; -+ }; -+ -+ gpiok: gpio@5000c000 { -+ status = "okay"; -+ ngpios = <8>; -+ gpio-ranges = <&pinctrl 0 160 8>; -+ }; -+ }; -+ -+ pinctrl_z: pin-controller-z@54004000 { -+ st,package = ; -+ -+ gpioz: gpio@54004000 { -+ status = "okay"; -+ ngpios = <8>; -+ gpio-ranges = <&pinctrl_z 0 400 8>; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/dts/stm32mp157cab-pinctrl.dtsi b/arch/arm/dts/stm32mp157cab-pinctrl.dtsi -new file mode 100644 -index 0000000..c570cf9 ---- /dev/null -+++ b/arch/arm/dts/stm32mp157cab-pinctrl.dtsi -@@ -0,0 +1,62 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved -+ * Author: Alexandre Torgue -+ */ -+ -+#include "stm32mp157-pinctrl.dtsi" -+/ { -+ soc { -+ pinctrl: pin-controller@50002000 { -+ st,package = ; -+ -+ gpioa: gpio@50002000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 0 16>; -+ }; -+ -+ gpiob: gpio@50003000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 16 16>; -+ }; -+ -+ gpioc: gpio@50004000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 32 16>; -+ }; -+ -+ gpiod: gpio@50005000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 48 16>; -+ }; -+ -+ gpioe: gpio@50006000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 64 16>; -+ }; -+ -+ gpiof: gpio@50007000 { -+ status = "okay"; -+ ngpios = <6>; -+ gpio-ranges = <&pinctrl 6 86 6>; -+ }; -+ -+ gpiog: gpio@50008000 { -+ status = "okay"; -+ ngpios = <10>; -+ gpio-ranges = <&pinctrl 6 102 10>; -+ }; -+ -+ gpioh: gpio@50009000 { -+ status = "okay"; -+ ngpios = <2>; -+ gpio-ranges = <&pinctrl 0 112 2>; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/dts/stm32mp157cac-pinctrl.dtsi b/arch/arm/dts/stm32mp157cac-pinctrl.dtsi -new file mode 100644 -index 0000000..777f991 ---- /dev/null -+++ b/arch/arm/dts/stm32mp157cac-pinctrl.dtsi -@@ -0,0 +1,78 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved -+ * Author: Alexandre Torgue -+ */ -+ -+#include "stm32mp157-pinctrl.dtsi" -+/ { -+ soc { -+ pinctrl: pin-controller@50002000 { -+ st,package = ; -+ -+ gpioa: gpio@50002000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 0 16>; -+ }; -+ -+ gpiob: gpio@50003000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 16 16>; -+ }; -+ -+ gpioc: gpio@50004000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 32 16>; -+ }; -+ -+ gpiod: gpio@50005000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 48 16>; -+ }; -+ -+ gpioe: gpio@50006000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 64 16>; -+ }; -+ -+ gpiof: gpio@50007000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 80 16>; -+ }; -+ -+ gpiog: gpio@50008000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 96 16>; -+ }; -+ -+ gpioh: gpio@50009000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 112 16>; -+ }; -+ -+ gpioi: gpio@5000a000 { -+ status = "okay"; -+ ngpios = <12>; -+ gpio-ranges = <&pinctrl 0 128 12>; -+ }; -+ }; -+ -+ pinctrl_z: pin-controller-z@54004000 { -+ st,package = ; -+ -+ gpioz: gpio@54004000 { -+ status = "okay"; -+ ngpios = <8>; -+ gpio-ranges = <&pinctrl_z 0 400 8>; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/dts/stm32mp157cad-pinctrl.dtsi b/arch/arm/dts/stm32mp157cad-pinctrl.dtsi -new file mode 100644 -index 0000000..c4c303a ---- /dev/null -+++ b/arch/arm/dts/stm32mp157cad-pinctrl.dtsi -@@ -0,0 +1,62 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved -+ * Author: Alexandre Torgue -+ */ -+ -+#include "stm32mp157-pinctrl.dtsi" -+/ { -+ soc { -+ pinctrl: pin-controller@50002000 { -+ st,package = ; -+ -+ gpioa: gpio@50002000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 0 16>; -+ }; -+ -+ gpiob: gpio@50003000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 16 16>; -+ }; -+ -+ gpioc: gpio@50004000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 32 16>; -+ }; -+ -+ gpiod: gpio@50005000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 48 16>; -+ }; -+ -+ gpioe: gpio@50006000 { -+ status = "okay"; -+ ngpios = <16>; -+ gpio-ranges = <&pinctrl 0 64 16>; -+ }; -+ -+ gpiof: gpio@50007000 { -+ status = "okay"; -+ ngpios = <6>; -+ gpio-ranges = <&pinctrl 6 86 6>; -+ }; -+ -+ gpiog: gpio@50008000 { -+ status = "okay"; -+ ngpios = <10>; -+ gpio-ranges = <&pinctrl 6 102 10>; -+ }; -+ -+ gpioh: gpio@50009000 { -+ status = "okay"; -+ ngpios = <2>; -+ gpio-ranges = <&pinctrl 0 112 2>; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts -index 57e0dd7..2505d53 100644 ---- a/arch/sandbox/dts/test.dts -+++ b/arch/sandbox/dts/test.dts -@@ -712,6 +712,14 @@ - sandbox_tee { - compatible = "sandbox,tee"; - }; -+ -+ pinctrl { -+ compatible = "sandbox,pinctrl"; -+ }; -+ -+ hwspinlock@0 { -+ compatible = "sandbox,hwspinlock"; -+ }; - }; - - #include "sandbox_pmic.dtsi" -diff --git a/doc/device-tree-bindings/arm/stm32.txt b/doc/device-tree-bindings/arm/stm32.txt -new file mode 100644 -index 0000000..a871a78 ---- /dev/null -+++ b/doc/device-tree-bindings/arm/stm32.txt -@@ -0,0 +1,17 @@ -+STMicroelectronics STM32 Platforms Device Tree Bindings -+ -+Each device tree must specify which STM32 SoC it uses, -+using one of the following compatible strings: -+ -+ st,stm32f429 -+ st,stm32f469 -+ st,stm32f746 -+ st,stm32h743 -+ st,stm32mp157 -+ -+Required nodes: -+ -+- syscon: some subnode of the STM32 SoC node must be a -+ system controller node pointing to the control registers, -+ with the compatible string set to one of these tuples: -+ "st,stm32-syscfg", "syscon" -diff --git a/doc/device-tree-bindings/clock/st,stm32-rcc.txt b/doc/device-tree-bindings/clock/st,stm32-rcc.txt -index 0532d81..b240121 100644 ---- a/doc/device-tree-bindings/clock/st,stm32-rcc.txt -+++ b/doc/device-tree-bindings/clock/st,stm32-rcc.txt -@@ -10,6 +10,7 @@ Required properties: - - compatible: Should be: - "st,stm32f42xx-rcc" - "st,stm32f469-rcc" -+ "st,stm32f746-rcc" - - reg: should be register base and length as documented in the - datasheet - - #reset-cells: 1, see below -@@ -17,6 +18,9 @@ Required properties: - property, containing a phandle to the clock device node, an index selecting - between gated clocks and other clocks and an index specifying the clock to - use. -+- clocks: External oscillator clock phandle -+ - high speed external clock signal (HSE) -+ - external I2S clock (I2S_CKIN) - - Example: - -@@ -25,6 +29,7 @@ Example: - #clock-cells = <2> - compatible = "st,stm32f42xx-rcc", "st,stm32-rcc"; - reg = <0x40023800 0x400>; -+ clocks = <&clk_hse>, <&clk_i2s_ckin>; - }; - - Specifying gated clocks -@@ -66,6 +71,38 @@ The secondary index is bound with the following magic numbers: - - 0 SYSTICK - 1 FCLK -+ 2 CLK_LSI (low-power clock source) -+ 3 CLK_LSE (generated from a 32.768 kHz low-speed external -+ crystal or ceramic resonator) -+ 4 CLK_HSE_RTC (HSE division factor for RTC clock) -+ 5 CLK_RTC (real-time clock) -+ 6 PLL_VCO_I2S (vco frequency of I2S pll) -+ 7 PLL_VCO_SAI (vco frequency of SAI pll) -+ 8 CLK_LCD (LCD-TFT) -+ 9 CLK_I2S (I2S clocks) -+ 10 CLK_SAI1 (audio clocks) -+ 11 CLK_SAI2 -+ 12 CLK_I2SQ_PDIV (post divisor of pll i2s q divisor) -+ 13 CLK_SAIQ_PDIV (post divisor of pll sai q divisor) -+ -+ 14 CLK_HSI (Internal ocscillator clock) -+ 15 CLK_SYSCLK (System Clock) -+ 16 CLK_HDMI_CEC (HDMI-CEC clock) -+ 17 CLK_SPDIF (SPDIF-Rx clock) -+ 18 CLK_USART1 (U(s)arts clocks) -+ 19 CLK_USART2 -+ 20 CLK_USART3 -+ 21 CLK_UART4 -+ 22 CLK_UART5 -+ 23 CLK_USART6 -+ 24 CLK_UART7 -+ 25 CLK_UART8 -+ 26 CLK_I2C1 (I2S clocks) -+ 27 CLK_I2C2 -+ 28 CLK_I2C3 -+ 29 CLK_I2C4 -+ 30 CLK_LPTIMER (LPTimer1 clock) -+) - - Example: - -diff --git a/doc/device-tree-bindings/clock/st,stm32mp1-rcc.txt b/doc/device-tree-bindings/clock/st,stm32mp1-rcc.txt -new file mode 100644 -index 0000000..fb9495e ---- /dev/null -+++ b/doc/device-tree-bindings/clock/st,stm32mp1-rcc.txt -@@ -0,0 +1,60 @@ -+STMicroelectronics STM32 Peripheral Reset Clock Controller -+========================================================== -+ -+The RCC IP is both a reset and a clock controller. -+ -+RCC makes also power management (resume/supend and wakeup interrupt). -+ -+Please also refer to reset.txt for common reset controller binding usage. -+ -+Please also refer to clock-bindings.txt for common clock controller -+binding usage. -+ -+ -+Required properties: -+- compatible: "st,stm32mp1-rcc", "syscon" -+- reg: should be register base and length as documented in the datasheet -+- #clock-cells: 1, device nodes should specify the clock in their -+ "clocks" property, containing a phandle to the clock device node, -+ an index specifying the clock to use. -+- #reset-cells: Shall be 1 -+- interrupts: Should contain a general interrupt line and a interrupt line -+ to the wake-up of processor (CSTOP). -+ -+Example: -+ rcc: rcc@50000000 { -+ compatible = "st,stm32mp1-rcc", "syscon"; -+ reg = <0x50000000 0x1000>; -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ interrupts = , -+ ; -+ }; -+ -+Specifying clocks -+================= -+ -+All available clocks are defined as preprocessor macros in -+dt-bindings/clock/stm32mp1-clks.h header and can be used in device -+tree sources. -+ -+Specifying softreset control of devices -+======================================= -+ -+Device nodes should specify the reset channel required in their "resets" -+property, containing a phandle to the reset device node and an index specifying -+which channel to use. -+The index is the bit number within the RCC registers bank, starting from RCC -+base address. -+It is calculated as: index = register_offset / 4 * 32 + bit_offset. -+Where bit_offset is the bit offset within the register. -+ -+For example on STM32MP1, for LTDC reset: -+ ltdc = APB4_RSTSETR_offset / 4 * 32 + LTDC_bit_offset -+ = 0x180 / 4 * 32 + 0 = 3072 -+ -+The list of valid indices for STM32MP1 is available in: -+include/dt-bindings/reset-controller/stm32mp1-resets.h -+ -+This file implements defines like: -+#define LTDC_R 3072 -diff --git a/doc/device-tree-bindings/i2c/i2c-stm32.txt b/doc/device-tree-bindings/i2c/i2c-stm32.txt -index df03743..352dba5 100644 ---- a/doc/device-tree-bindings/i2c/i2c-stm32.txt -+++ b/doc/device-tree-bindings/i2c/i2c-stm32.txt -@@ -1,30 +1,102 @@ --* I2C controller embedded in STMicroelectronis STM32 platforms -+* I2C controller embedded in STMicroelectronics STM32 I2C platform - - Required properties : --- compatible : Must be "st,stm32f7-i2c" -+- compatible : Must be one of the following -+ - "st,stm32f4-i2c" -+ - "st,stm32f7-i2c" - - reg : Offset and length of the register set for the device --- resets: Must contain the phandle to the reset controller --- clocks: Must contain the input clock of the I2C instance -+- interrupts : Must contain the interrupt id for I2C event and then the -+ interrupt id for I2C error. -+- resets: Must contain the phandle to the reset controller. -+- clocks: Must contain the input clock of the I2C instance. - - A pinctrl state named "default" must be defined to set pins in mode of -- operation for I2C transfer -+ operation for I2C transfer. An optional pinctrl state named "sleep" has to -+ be defined as well as to put I2C in low power mode in suspend mode. - - #address-cells = <1>; - - #size-cells = <0>; - - Optional properties : - - clock-frequency : Desired I2C bus clock frequency in Hz. If not specified, -- the default 100 kHz frequency will be used. As only Normal, Fast and Fast+ -- modes are implemented, possible values are 100000, 400000 and 1000000. -+ the default 100 kHz frequency will be used. -+ For STM32F4 SoC Standard-mode and Fast-mode are supported, possible values are -+ 100000 and 400000. -+ For STM32F7 SoC, Standard-mode, Fast-mode and Fast-mode Plus are supported, -+ possible values are 100000, 400000 and 1000000. -+- i2c-scl-rising-time-ns : Only for STM32F7, I2C SCL Rising time for the board -+ (default: 25) -+- i2c-scl-falling-time-ns : Only for STM32F7, I2C SCL Falling time for the board -+ (default: 10) -+ I2C Timings are derived from these 2 values -+- st,syscfg-fmp: Only for STM32F7, use to set Fast Mode Plus bit within SYSCFG -+ whether Fast Mode Plus speed is selected by slave. -+ 1st cell : phandle to syscfg -+ 2nd cell : register offset within SYSCFG -+ 3rd cell : register bitmask for FMP bit - - Example : - -- i2c1: i2c@40005400 { -- compatible = "st,stm32f7-i2c"; -+ i2c@40005400 { -+ compatible = "st,stm32f4-i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; - reg = <0x40005400 0x400>; -- resets = <&rcc 181>; -- clocks = <&clk_pclk1>; -+ interrupts = <31>, -+ <32>; -+ resets = <&rcc 277>; -+ clocks = <&rcc 0 149>; -+ pinctrl-0 = <&i2c1_sda_pin>, <&i2c1_scl_pin>; - pinctrl-names = "default"; -- pinctrl-0 = <&pinctrl_i2c1>; -- clock-frequency = <400000>; -+ }; -+ -+ i2c@40005400 { -+ compatible = "st,stm32f7-i2c"; - #address-cells = <1>; - #size-cells = <0>; -+ reg = <0x40005400 0x400>; -+ interrupts = <31>, -+ <32>; -+ resets = <&rcc STM32F7_APB1_RESET(I2C1)>; -+ clocks = <&rcc 1 CLK_I2C1>; -+ pinctrl-0 = <&i2c1_sda_pin>, <&i2c1_scl_pin>; -+ pinctrl-1 = <&i2c1_sda_pin_sleep>, <&i2c1_scl_pin_sleep>; -+ pinctrl-names = "default", "sleep"; -+ st,syscfg-fmp = <&syscfg 0x4 0x1>; -+ }; -+ -+* I2C Devices -+ -+An I2C device connected onto STM32 I2C controller must use a format described by -+i2c.txt file. -+ -+Required properties : -+- compatible -+ Device driver compatible name -+- reg -+ I2C slave addresses (see i2c.txt for more details) -+ -+Optional properties : -+- wakeup-source -+ device can be used as a wakeup source. Valid only if device is a -+ master. -+- interrupt-names -+ should be set as "wakeup" if a dedicated wakeup source is used. -+ Imply "wakeup-source" property -+- interrupts -+ defined dedicated IRQ wakeup source from controller. -+ -+ i2c@40005400 { -+ camera@3c { -+ compatible = "ovti,ov5640"; -+ reg = <0x3c>; -+ }; -+ }; -+ -+ i2c@40005400 { -+ eeprom@64 { -+ compatible = "linux,slave-24c02"; -+ reg = <0x40000064>; -+ wakeup-source; -+ interrupt-names = "wakeup"; -+ interrupts-extended = <&exti 25 1>; -+ }; - }; -diff --git a/doc/device-tree-bindings/mfd/stpmic1.txt b/doc/device-tree-bindings/mfd/stpmic1.txt -new file mode 100644 -index 0000000..eb4d692 ---- /dev/null -+++ b/doc/device-tree-bindings/mfd/stpmic1.txt -@@ -0,0 +1,138 @@ -+* STMicroelectronics STPMIC1 Power Management IC -+ -+Required parent device properties: -+- compatible: "st,stpmic1" -+- reg: the I2C slave address for the stpmic1 chip -+- interrupts-extended: interrupt lines to use: second irq is for wakeup. -+- #interrupt-cells: should be 2. -+- interrupt-controller: describes the STPMIC1 as an interrupt -+ controller (has its own domain). interrupt number are the following: -+ /* Interrupt Register 1 (0x50 for latch) */ -+ IT_SWOUT_R=0 -+ IT_SWOUT_F=1 -+ IT_VBUS_OTG_R=2 -+ IT_VBUS_OTG_F=3 -+ IT_WAKEUP_R=4 -+ IT_WAKEUP_F=5 -+ IT_PONKEY_R=6 -+ IT_PONKEY_F=7 -+ /* Interrupt Register 2 (0x51 for latch) */ -+ IT_OVP_BOOST=8 -+ IT_OCP_BOOST=9 -+ IT_OCP_SWOUT=10 -+ IT_OCP_OTG=11 -+ IT_CURLIM_BUCK4=12 -+ IT_CURLIM_BUCK3=13 -+ IT_CURLIM_BUCK2=14 -+ IT_CURLIM_BUCK1=15 -+ /* Interrupt Register 3 (0x52 for latch) */ -+ IT_SHORT_SWOUT=16 -+ IT_SHORT_SWOTG=17 -+ IT_CURLIM_LDO6=18 -+ IT_CURLIM_LDO5=19 -+ IT_CURLIM_LDO4=20 -+ IT_CURLIM_LDO3=21 -+ IT_CURLIM_LDO2=22 -+ IT_CURLIM_LDO1=23 -+ /* Interrupt Register 3 (0x52 for latch) */ -+ IT_SWIN_R=24 -+ IT_SWIN_F=25 -+ IT_RESERVED_1=26 -+ IT_RESERVED_2=27 -+ IT_VINLOW_R=28 -+ IT_VINLOW_F=29 -+ IT_TWARN_R=30 -+ IT_TWARN_F=31 -+ -+Optional parent device properties: -+- st,main_control_register: -+ -bit 1: Power cycling will be performed on turn OFF condition -+ -bit 2: PWRCTRL is functional -+ -bit 3: PWRCTRL active high -+- st,pads_pull_register: -+ -bit 1: WAKEUP pull down is not active -+ -bit 2: PWRCTRL pull up is active -+ -bit 3: PWRCTRL pull down is active -+ -bit 4: WAKEUP detector is disabled -+- st,vin_control_register: -+ -bit 0: VINLOW monitoring is enabled -+ -bit [1...3]: VINLOW rising threshold -+ 000 VINOK_f + 50mV -+ 001 VINOK_f + 100mV -+ 010 VINOK_f + 150mV -+ 011 VINOK_f + 200mV -+ 100 VINOK_f + 250mV -+ 101 VINOK_f + 300mV -+ 110 VINOK_f + 350mV -+ 111 VINOK_f + 400mV -+ -bit [4...5]: VINLOW hyst -+ 00 100mV -+ 01 200mV -+ 10 300mV -+ 11 400mV -+ -bit 6: SW_OUT detector is disabled -+ -bit 7: SW_IN detector is enabled. -+- st,usb_control_register: -+ -bit 3: SW_OUT current limit -+ 0: 600mA -+ 1: 1.1A -+ -bit 4: VBUS_OTG discharge is enabled -+ -bit 5: SW_OUT discharge is enabled -+ -bit 6: VBUS_OTG detection is enabled -+ -bit 7: BOOST_OVP is disabled -+ -+ -+stpmic1 consists is a varied group of sub-devices: -+ -+Device Description -+------ ------------ -+stpmic1-onkey : On key -+stpmic1-regulators : Regulators -+stpmic1-wdt : Watchdog -+ -+each sub-device bindings is be described in associated driver -+documentation section. -+ -+Example: -+ -+pmic: stpmic1@33 { -+ compatible = "st,stpmic1"; -+ reg = <0x33>; -+ interrupts = <0 2>; -+ interrupts-extended = <&intc GIC_SPI 149 IRQ_TYPE_NONE>, -+ <&exti 55 1>; -+ st,version_status = <0x10>; -+ st,main_control_register=<0x0c>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ onkey { -+ compatible = "st,stpmic1-onkey"; -+ interrupt-parent = <&pmic>; -+ interrupts = <7 0>,<6 1>; -+ st,onkey-pwroff-enabled; -+ st,onkey-press-seconds = <10>; -+ }; -+ -+ watchdog { -+ compatible = "st,stpmic1-wdt"; -+ }; -+ -+ regulators { -+ compatible = "st,stpmic1-regulators"; -+ -+ vdd_core: regulator@0 { -+ regulator-compatible = "buck1"; -+ regulator-name = "vdd_core"; -+ regulator-boot-on; -+ regulator-min-microvolt = <700000>; -+ regulator-max-microvolt = <1200000>; -+ }; -+ vdd: regulator@1 { -+ regulator-compatible = "buck3"; -+ regulator-name = "vdd"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-pull-down; -+ }; -+ }; -diff --git a/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt b/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt -new file mode 100644 -index 0000000..68eebb6 ---- /dev/null -+++ b/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt -@@ -0,0 +1,59 @@ -+STMicroelectronics Flexible Memory Controller 2 (FMC2) -+NAND Interface -+ -+Required properties: -+- compatible: Should be one of: -+ * st,stm32mp15-fmc2 -+- reg: NAND flash controller memory areas. -+ First region contains the register location. -+ Regions 2 to 4 respectively contain the data, command, -+ and address space for CS0. -+ Regions 5 to 7 contain the same areas for CS1. -+- interrupts: The interrupt number -+- pinctrl-0: Standard Pinctrl phandle (see: pinctrl/pinctrl-bindings.txt) -+- clocks: The clock needed by the NAND flash controller -+ -+Optional properties: -+- resets: Reference to a reset controller asserting the FMC controller -+ -+* NAND device bindings: -+ -+Required properties: -+- reg: describes the CS lines assigned to the NAND device. -+ -+Optional properties: -+- nand-on-flash-bbt: see nand.txt -+- nand-ecc-strength: see nand.txt -+- nand-ecc-step-size: see nand.txt -+ -+The following ECC strength and step size are currently supported: -+ - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Hamming) -+ - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4) -+ - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8) (default) -+ -+Example: -+ -+ fmc: nand-controller@58002000 { -+ compatible = "st,stm32mp15-fmc2"; -+ reg = <0x58002000 0x1000>, -+ <0x80000000 0x1000>, -+ <0x88010000 0x1000>, -+ <0x88020000 0x1000>, -+ <0x81000000 0x1000>, -+ <0x89010000 0x1000>, -+ <0x89020000 0x1000>; -+ interrupts = ; -+ clocks = <&rcc FMC_K>; -+ resets = <&rcc FMC_R>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&fmc_pins_a>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ nand@0 { -+ reg = <0>; -+ nand-on-flash-bbt; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ }; -+ }; -diff --git a/doc/device-tree-bindings/mtd/stm32-quadspi.txt b/doc/device-tree-bindings/mtd/stm32-quadspi.txt -new file mode 100644 -index 0000000..ddd18c1 ---- /dev/null -+++ b/doc/device-tree-bindings/mtd/stm32-quadspi.txt -@@ -0,0 +1,43 @@ -+* STMicroelectronics Quad Serial Peripheral Interface(QuadSPI) -+ -+Required properties: -+- compatible: should be "st,stm32f469-qspi" -+- reg: the first contains the register location and length. -+ the second contains the memory mapping address and length -+- reg-names: should contain the reg names "qspi" "qspi_mm" -+- interrupts: should contain the interrupt for the device -+- clocks: the phandle of the clock needed by the QSPI controller -+- A pinctrl must be defined to set pins in mode of operation for QSPI transfer -+ -+Optional properties: -+- resets: must contain the phandle to the reset controller. -+ -+A spi flash must be a child of the nor_flash node and could have some -+properties. Also see jedec,spi-nor.txt. -+ -+Required properties: -+- reg: chip-Select number (QSPI controller may connect 2 nor flashes) -+- spi-max-frequency: max frequency of spi bus -+ -+Optional property: -+- spi-rx-bus-width: see ../spi/spi-bus.txt for the description -+ -+Example: -+ -+qspi: spi@a0001000 { -+ compatible = "st,stm32f469-qspi"; -+ reg = <0xa0001000 0x1000>, <0x90000000 0x10000000>; -+ reg-names = "qspi", "qspi_mm"; -+ interrupts = <91>; -+ resets = <&rcc STM32F4_AHB3_RESET(QSPI)>; -+ clocks = <&rcc 0 STM32F4_AHB3_CLOCK(QSPI)>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_qspi0>; -+ -+ flash@0 { -+ reg = <0>; -+ spi-rx-bus-width = <4>; -+ spi-max-frequency = <108000000>; -+ ... -+ }; -+}; -diff --git a/doc/device-tree-bindings/net/snps,dwc-qos-ethernet.txt b/doc/device-tree-bindings/net/snps,dwc-qos-ethernet.txt -index d93f71c..21d27aa 100644 ---- a/doc/device-tree-bindings/net/snps,dwc-qos-ethernet.txt -+++ b/doc/device-tree-bindings/net/snps,dwc-qos-ethernet.txt -@@ -1,5 +1,8 @@ - * Synopsys DWC Ethernet QoS IP version 4.10 driver (GMAC) - -+This binding is deprecated, but it continues to be supported, but new -+features should be preferably added to the stmmac binding document. -+ - This binding supports the Synopsys Designware Ethernet QoS (Quality Of Service) - IP block. The IP supports multiple options for bus type, clocking and reset - structure, and feature list. Consequently, a number of properties and list -diff --git a/doc/device-tree-bindings/net/stm32-dwmac.txt b/doc/device-tree-bindings/net/stm32-dwmac.txt -new file mode 100644 -index 0000000..73773ec ---- /dev/null -+++ b/doc/device-tree-bindings/net/stm32-dwmac.txt -@@ -0,0 +1,62 @@ -+STMicroelectronics STM32 / MCU DWMAC glue layer controller -+ -+This file documents platform glue layer for stmmac. -+Please see stmmac.txt for the other unchanged properties. -+ -+The device node has following properties. -+ -+Required properties: -+- compatible: For MCU family should be "st,stm32-dwmac" to select glue, and -+ "snps,dwmac-3.50a" to select IP version. -+ For MPU family should be "st,stm32mp1-dwmac" to select -+ glue, and "snps,dwmac-4.20a" to select IP version. -+- clocks: Must contain a phandle for each entry in clock-names. -+- clock-names: Should be "stmmaceth" for the host clock. -+ Should be "mac-clk-tx" for the MAC TX clock. -+ Should be "mac-clk-rx" for the MAC RX clock. -+ For MPU family need to add also "ethstp" for power mode clock and, -+ "syscfg-clk" for SYSCFG clock. -+- interrupt-names: Should contain a list of interrupt names corresponding to -+ the interrupts in the interrupts property, if available. -+ Should be "macirq" for the main MAC IRQ -+ Should be "eth_wake_irq" for the IT which wake up system -+- st,syscon : Should be phandle/offset pair. The phandle to the syscon node which -+ encompases the glue register, and the offset of the control register. -+ -+Optional properties: -+- clock-names: For MPU family "mac-clk-ck" for PHY without quartz -+- st,eth_clk_sel (boolean) : set this property in RGMII PHY when you do not want use 125Mhz -+- st,eth_ref_clk_sel (boolean) : set this property in RMII mode when you have PHY without crystal 50MHz -+ -+ --------------------------------------------------------------------------------------- -+ | PHY_MODE | Normal | PHY wo crystal| PHY wo crystal |No 125Mhz from PHY| -+ | | | 25MHz | 50MHz | | -+ --------------------------------------------------------------------------------------- -+ | MII | - | eth-ck | n/a | n/a | -+ | | | | | | -+ --------------------------------------------------------------------------------------- -+ | GMII | - | eth-ck | n/a | n/a | -+ | | | | | | -+ --------------------------------------------------------------------------------------- -+ | RGMII | - | eth-ck | n/a | eth-ck (no pin) | -+ | | | | | st,eth_clk_sel | -+ --------------------------------------------------------------------------------------- -+ | RMII | - | eth-ck | eth-ck | n/a | -+ | | | | st,eth_ref_clk_sel | | -+ --------------------------------------------------------------------------------------- -+ -+Example: -+ -+ ethernet@40028000 { -+ compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; -+ reg = <0x40028000 0x8000>; -+ reg-names = "stmmaceth"; -+ interrupts = <0 61 0>, <0 62 0>; -+ interrupt-names = "macirq", "eth_wake_irq"; -+ clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx"; -+ clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; -+ st,syscon = <&syscfg 0x4>; -+ snps,pbl = <8>; -+ snps,mixed-burst; -+ dma-ranges; -+ }; -diff --git a/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt b/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt -index 725ae71..cc44bf4 100644 ---- a/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt -+++ b/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt -@@ -23,8 +23,12 @@ Required properties: - - compatible: must be "st,stm32mp1-usbphyc" - - reg: address and length of the usb phy control register set - - clocks: phandle + clock specifier for the PLL phy clock -+- vdda1v1-supply: phandle to the regulator providing 1V1 power to the PHY -+- vdda1v8-supply: phandle to the regulator providing 1V8 power to the PHY -+- vdd3v3-supply: phandle to the regulator providing 3V3 power to the PHY - - #address-cells: number of address cells for phys sub-nodes, must be <1> - - #size-cells: number of size cells for phys sub-nodes, must be <0> -+- #clock-cells: number of clock cells for ck_usbo_48m consumer, must be <0> - - Optional properties: - - assigned-clocks: phandle + clock specifier for the PLL phy clock -@@ -34,40 +38,79 @@ Optional properties: - Required nodes: one sub-node per port the controller provides. - - Phy sub-nodes --============== -+============= - - Required properties: - - reg: phy port index --- phy-supply: phandle to the regulator providing 3V3 power to the PHY, -- see phy-bindings.txt in the same directory. --- vdda1v1-supply: phandle to the regulator providing 1V1 power to the PHY --- vdda1v8-supply: phandle to the regulator providing 1V8 power to the PHY - - #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: -+- st,phy-tuning : phandle to the usb phy tuning node, see Phy tuning node below -+ -+Phy tuning node -+=============== -+ -+It may be necessary to adjust the phy settings to compensate parasitics, which -+can be due to USB connector/receptacle, routing, ESD protection component, ... -+ -+Here is the list of all optional parameters to tune the interface of the phy -+(HS for High-Speed, FS for Full-Speed, LS for Low-Speed) -+ -+Optional properties: -+- st,current-boost: <1> current boosting of 1mA -+ <2> current boosting of 2mA -+- st,no-lsfs-fb-cap: disables the LS/FS feedback capacitor -+- st,hs-slew-ctrl: slows the HS driver slew rate by 10% -+- st,hs-dc-level: <0> decreases the HS driver DC level by 5 to 7mV -+ <1> increases the HS driver DC level by 5 to 7mV -+ <2> increases the HS driver DC level by 10 to 14mV -+- st,fs-rftime-tuning: enables the FS rise/fall tuning option -+- st,hs-rftime-reduction: enables the HS rise/fall reduction feature -+- st,hs-current-trim: controls HS driver current trimming for choke -+- st,hs-impedance-trim: controls HS driver impedance tuning for choke -+- st,squelch-level: adjusts the squelch DC threshold value -+- st,hs-rx-gain-eq: enables the HS Rx gain equalizer -+- st,hs-rx-offset: adjusts the HS Rx offset -+- st,no-hs-ftime-ctrl: disables the HS fall time control of single -+ ended signals during pre-emphasis -+- st,no-lsfs-sc: disables the short circuit protection in LS/FS driver -+- st,hs-tx-staggering: enables the basic staggering in HS Tx mode -+ - - Example: -+ usb_phy_tuning: usb-phy-tuning { -+ st,current-boost = <2>; -+ st,no-lfs-fb-cap; -+ st,hs-dc-level = <2>; -+ st,hs-rftime-reduction; -+ st,hs-current-trim = <5>; -+ st,hs-impedance-trim = <0>; -+ st,squelch-level = <1>; -+ st,no-hs-ftime-ctrl; -+ st,hs-tx-staggering; -+ }; -+ - usbphyc: usb-phy@5a006000 { - compatible = "st,stm32mp1-usbphyc"; - reg = <0x5a006000 0x1000>; - clocks = <&rcc_clk USBPHY_K>; - resets = <&rcc_rst USBPHY_R>; -+ vdda1v1-supply = <®11>; -+ vdda1v8-supply = <®18>; -+ vdd3v3-supply = <&vdd_usb>; - #address-cells = <1>; - #size-cells = <0>; -+ #clock-cells = <0>; - - usbphyc_port0: usb-phy@0 { - reg = <0>; -- phy-supply = <&vdd_usb>; -- vdda1v1-supply = <®11>; -- vdda1v8-supply = <®18> - #phy-cells = <0>; - }; - - usbphyc_port1: usb-phy@1 { - reg = <1>; -- phy-supply = <&vdd_usb>; -- vdda1v1-supply = <®11>; -- vdda1v8-supply = <®18> - #phy-cells = <1>; -+ st,phy-tuning = <&usb_phy_tuning>; - }; - }; -diff --git a/doc/device-tree-bindings/pinctrl/st,stm32-pinctrl.txt b/doc/device-tree-bindings/pinctrl/st,stm32-pinctrl.txt -index c41ae91..1a5d1e2 100644 ---- a/doc/device-tree-bindings/pinctrl/st,stm32-pinctrl.txt -+++ b/doc/device-tree-bindings/pinctrl/st,stm32-pinctrl.txt -@@ -8,8 +8,13 @@ controllers onto these pads. - Pin controller node: - Required properies: - - compatible: value should be one of the following: -- (a) "st,stm32f429-pinctrl" -- (b) "st,stm32f746-pinctrl" -+ "st,stm32f429-pinctrl" -+ "st,stm32f469-pinctrl" -+ "st,stm32f746-pinctrl" -+ "st,stm32f769-pinctrl" -+ "st,stm32h743-pinctrl" -+ "st,stm32mp157-pinctrl" -+ "st,stm32mp157-z-pinctrl" - - #address-cells: The value of this property must be 1 - - #size-cells : The value of this property must be 1 - - ranges : defines mapping between pin controller node (parent) to -@@ -32,13 +37,30 @@ Required properties: - - Optional properties: - - reset: : Reference to the reset controller -- - interrupt-parent: phandle of the interrupt parent to which the external -- GPIO interrupts are forwarded to. -- - st,syscfg: Should be phandle/offset pair. The phandle to the syscon node -- which includes IRQ mux selection register, and the offset of the IRQ mux -- selection register. -+ - st,syscfg: Should be phandle/offset/mask. -+ -The phandle to the syscon node which includes IRQ mux selection register. -+ -The offset of the IRQ mux selection register -+ -The field mask of IRQ mux, needed if different of 0xf. -+ - gpio-ranges: Define a dedicated mapping between a pin-controller and -+ a gpio controller. Format is <&phandle a b c> with: -+ -(phandle): phandle of pin-controller. -+ -(a): gpio base offset in range. -+ -(b): pin base offset in range. -+ -(c): gpio count in range -+ This entry has to be used either if there are holes inside a bank: -+ GPIOB0/B1/B2/B14/B15 (see example 2) -+ or if banks are not contiguous: -+ GPIOA/B/C/E... -+ NOTE: If "gpio-ranges" is used for a gpio controller, all gpio-controller -+ have to use a "gpio-ranges" entry. -+ More details in Documentation/devicetree/bindings/gpio/gpio.txt. -+ - st,bank-ioport: should correspond to the EXTI IOport selection (EXTI line -+ used to select GPIOs as interrupts). -+ - st,package: Indicates the SOC package used. -+ More details in include/dt-bindings/pinctrl/stm32-pinfunc.h -+ - hwlocks: reference to a phandle of a hardware spinlock provider node. - --Example: -+Example 1: - #include - ... - -@@ -60,6 +82,43 @@ Example: - pin-functions nodes follow... - }; - -+Example 2: -+#include -+... -+ -+ pinctrl: pin-controller { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "st,stm32f429-pinctrl"; -+ ranges = <0 0x40020000 0x3000>; -+ pins-are-numbered; -+ -+ gpioa: gpio@40020000 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ reg = <0x0 0x400>; -+ resets = <&reset_ahb1 0>; -+ st,bank-name = "GPIOA"; -+ gpio-ranges = <&pinctrl 0 0 16>; -+ }; -+ -+ gpiob: gpio@40020400 { -+ gpio-controller; -+ #gpio-cells = <2>; -+ reg = <0x0 0x400>; -+ resets = <&reset_ahb1 0>; -+ st,bank-name = "GPIOB"; -+ ngpios = 4; -+ gpio-ranges = <&pinctrl 0 16 3>, -+ <&pinctrl 14 30 2>; -+ }; -+ -+ -+ ... -+ pin-functions nodes follow... -+ }; -+ -+ - Contents of function subnode node: - ---------------------------------- - Subnode format -@@ -83,14 +142,31 @@ Required properties: - - port: The gpio port index (PA = 0, PB = 1, ..., PK = 11) - - line: The line offset within the port (PA0 = 0, PA1 = 1, ..., PA15 = 15) - - function: The function number, can be: -- * 0 : GPIO IN -+ * 0 : GPIO - * 1 : Alternate Function 0 - * 2 : Alternate Function 1 - * 3 : Alternate Function 2 - * ... - * 16 : Alternate Function 15 - * 17 : Analog -- * 18 : GPIO OUT -+ -+ To simplify the usage, macro is available to generate "pinmux" field. -+ This macro is available here: -+ - include/dt-bindings/pinctrl/stm32-pinfunc.h -+ -+ Some examples of using macro: -+ /* GPIO A9 set as alernate function 2 */ -+ ... { -+ pinmux = ; -+ }; -+ /* GPIO A9 set as GPIO */ -+ ... { -+ pinmux = ; -+ }; -+ /* GPIO A9 set as analog */ -+ ... { -+ pinmux = ; -+ }; - - Optional properties: - - GENERIC_PINCONFIG: is the generic pinconfig options to use. -@@ -114,13 +190,13 @@ pin-controller { - ... - usart1_pins_a: usart1@0 { - pins1 { -- pinmux = ; -+ pinmux = ; - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { -- pinmux = ; -+ pinmux = ; - bias-disable; - }; - }; -@@ -129,5 +205,4 @@ pin-controller { - &usart1 { - pinctrl-0 = <&usart1_pins_a>; - pinctrl-names = "default"; -- status = "okay"; - }; -diff --git a/doc/device-tree-bindings/power/st,stm32mp1-pwr.txt b/doc/device-tree-bindings/power/st,stm32mp1-pwr.txt -new file mode 100644 -index 0000000..ccdaffc ---- /dev/null -+++ b/doc/device-tree-bindings/power/st,stm32mp1-pwr.txt -@@ -0,0 +1,52 @@ -+STMicroelectronics STM32MP1 Power Management Controller -+======================================================= -+ -+The PWR IP is responsible for handling the power related resources such as -+clocks, power supplies and resets. It provides 6 wake-up pins that are handled -+by an interrupt-controller. Wake-up pin can be used to wake-up from STANDBY SoC state. -+ -+Required properties: -+- compatible should be: "st,stm32mp1-pwr" -+- reg: should be register base and length as documented in the -+ datasheet -+- interrupts: contains the reference to the gic wake-up pin interrupt -+- interrupt-controller; Enable interrupt controller for wake-up pins. -+- #interrupt-cells = <3> -+ -+Optional Properties: -+- pwr-supply: main soc power supply -+ -+Interrupt consumers have to specify 3 cells: -+ - cell 1: wake-up pin id from 0 to 5 -+ - cell 2: IRQ_TYPE_EDGE_FALLING or IRQ_TYPE_EDGE_RISING -+ - cell 3: Pull config: 0 = No Pull, 1=Pull Up, 2=Pull Down -+ -+ -+Example: -+ -+ pwr: pwr@50001000 { -+ compatible = "st,stm32mp1-pwr", "simple-mfd"; -+ reg = <0x50001000 0x400>; -+ interrupts = ; -+ interrupt-controller; -+ #interrupt-cells = <3>; -+ -+ pwr-supply = <&vdd>; -+ }; -+ -+ -+Example of interrupt user: -+gpio_keys { -+ compatible = "gpio-keys"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ button@4 { -+ label = "WakeUp4"; -+ linux,code = ; -+ interrupt-parent = <&pwr>; -+ interrupts = <3 IRQ_TYPE_EDGE_FALLING 1>; -+ status = "okay"; -+ wakeup-source; -+ }; -+}; -diff --git a/doc/device-tree-bindings/ram/st,stm32mp1-ddr.txt b/doc/device-tree-bindings/ram/st,stm32mp1-ddr.txt -index 3028636..e5b1bb5 100644 ---- a/doc/device-tree-bindings/ram/st,stm32mp1-ddr.txt -+++ b/doc/device-tree-bindings/ram/st,stm32mp1-ddr.txt -@@ -16,7 +16,7 @@ included in STM32 Cube tool - info attributes: - ---------------- - - st,mem-name : name for DDR configuration, simple string for information --- st,mem-speed : DDR expected speed for the setting in MHz -+- st,mem-speed : DDR expected speed for the setting in kHz - - st,mem-size : DDR mem size in byte - - -@@ -173,7 +173,7 @@ Example: - "ddrphycapb"; - - st,mem-name = "DDR3 2x4Gb 533MHz"; -- st,mem-speed = <533>; -+ st,mem-speed = <533000>; - st,mem-size = <0x40000000>; - - st,ctl-reg = < -diff --git a/doc/device-tree-bindings/regulator/st,stm32mp1-pwr-reg.txt b/doc/device-tree-bindings/regulator/st,stm32mp1-pwr-reg.txt -new file mode 100644 -index 0000000..cee27d5 ---- /dev/null -+++ b/doc/device-tree-bindings/regulator/st,stm32mp1-pwr-reg.txt -@@ -0,0 +1,31 @@ -+STM32MP1 POWER Regulators -+------------------------- -+ -+Required properties: -+- compatible: Must be "st,stm32mp1,pwr-reg" -+- list of child nodes that specify the regulator -+ initialization data for defined regulators. The definition for each of -+ these nodes is defined using the standard binding for regulators found at -+ Documentation/devicetree/bindings/regulator/regulator.txt. -+- st,tzcr: syscon of Trust Zone Configuration Register. Usefull to know if we -+ are in secure mode. -+ st,tzcr = & ; -+ -+Example: -+ -+ pwr-regulators@c { -+ compatible = "st,stm32mp1,pwr-reg"; -+ st,tzcr = <&rcc 0x0 0x1>; -+ -+ reg11: reg11 { -+ regulator-name = "reg11"; -+ regulator-min-microvolt = <1100000>; -+ regulator-max-microvolt = <1100000>; -+ }; -+ -+ reg18: reg18 { -+ regulator-name = "reg18"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ }; -+ }; -diff --git a/doc/device-tree-bindings/serial/st,stm32-usart.txt b/doc/device-tree-bindings/serial/st,stm32-usart.txt -new file mode 100644 -index 0000000..08b4990 ---- /dev/null -+++ b/doc/device-tree-bindings/serial/st,stm32-usart.txt -@@ -0,0 +1,88 @@ -+* STMicroelectronics STM32 USART -+ -+Required properties: -+- compatible: can be either: -+ - "st,stm32-uart", -+ - "st,stm32f7-uart", -+ - "st,stm32h7-uart". -+ depending is compatible with stm32(f4), stm32f7 or stm32h7. -+- reg: The address and length of the peripheral registers space -+- interrupts: -+ - The interrupt line for the USART instance, -+ - An optional wake-up interrupt. -+- interrupt-names: Contains "event" for the USART interrupt line. -+- clocks: The input clock of the USART instance -+ -+Optional properties: -+- resets: Must contain the phandle to the reset controller. -+- pinctrl-names: Set to "default". An additional "sleep" state can be defined -+ to set pins in sleep state when in low power. In case the device is used as -+ a wakeup source, "idle" state is defined in order to keep RX pin active. -+ For a console device, an optional state "no_console_suspend" can be defined -+ to enable console messages during suspend. Typically, "no_console_suspend" and -+ "default" states can refer to the same pin configuration. -+- pinctrl-n: Phandle(s) pointing to pin configuration nodes. -+ For Pinctrl properties see ../pinctrl/pinctrl-bindings.txt -+- st,hw-flow-ctrl: bool flag to enable hardware flow control. -+- rs485-rts-delay, rs485-rx-during-tx, rs485-rts-active-low, -+ linux,rs485-enabled-at-boot-time: see rs485.txt. -+- dmas: phandle(s) to DMA controller node(s). Refer to stm32-dma.txt -+- dma-names: "rx" and/or "tx" -+- wakeup-source: bool flag to indicate this device has wakeup capabilities -+- interrupt-names : Should contain "wakeup" if optional wake-up interrupt is -+ used. -+ -+Note for dma using: -+- "tx" dma can be used without any constraint since it uses single -+dma transfers. -+- "rx" dma using requires some attention: -+ 1) if you cannot anticipate the length of your received packets -+ and if your usart device embeds an internal fifo, then DON'T use -+ dma mode. -+ 2) if you enable dma mode WITHOUT mdma intermediate copy (cf. -+ stm32-dma.txt), then the availability of the received data will -+ depend on the dma driver policy and it may be delayed until dma -+ internal fifo is full. The usart driver will see this checking -+ the dma residue when rx interrupt (RXNE or RTO) occurs. -+ 3) if you enable dma mode WITH mdma intermediate copy (cf. -+ stm32-dma.txt) then the usart driver will never see the dma -+ residue becoming smaller than RX_BUF_P but it will get its -+ rx dma complete callback called when the cyclic transfer period -+ (RX_BUF_P) is reached. -+The three possibilities above are ordered from the most cpu time -+consuming one to the least one. The counterpart of this optimisation -+is the reception granularity achievable by the usart driver, from -+one byte up to RX_BUF_P. -+ -+Examples: -+usart4: serial@40004c00 { -+ compatible = "st,stm32-uart"; -+ reg = <0x40004c00 0x400>; -+ interrupts = <52>; -+ clocks = <&clk_pclk1>; -+ pinctrl-names = "default", "sleep", "idle", "no_console_suspend"; -+ pinctrl-0 = <&pinctrl_usart4>; -+ pinctrl-1 = <&pinctrl_usart4_sleep>; -+ pinctrl-2 = <&pinctrl_usart4_idle>; -+ pinctrl-3 = <&pinctrl_usart4>; -+}; -+ -+usart2: serial@40004400 { -+ compatible = "st,stm32-uart"; -+ reg = <0x40004400 0x400>; -+ interrupts = <38>; -+ clocks = <&clk_pclk1>; -+ st,hw-flow-ctrl; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rtscts>; -+}; -+ -+usart1: serial@40011000 { -+ compatible = "st,stm32-uart"; -+ reg = <0x40011000 0x400>; -+ interrupts = <37>; -+ clocks = <&rcc 0 164>; -+ dmas = <&dma2 2 4 0x414 0x0>, -+ <&dma2 7 4 0x414 0x0>; -+ dma-names = "rx", "tx"; -+}; -diff --git a/doc/device-tree-bindings/watchdog/st,stm32-iwdg.txt b/doc/device-tree-bindings/watchdog/st,stm32-iwdg.txt -new file mode 100644 -index 0000000..d8f4430 ---- /dev/null -+++ b/doc/device-tree-bindings/watchdog/st,stm32-iwdg.txt -@@ -0,0 +1,26 @@ -+STM32 Independent WatchDoG (IWDG) -+--------------------------------- -+ -+Required properties: -+- compatible: Should be either: -+ - "st,stm32-iwdg" -+ - "st,stm32mp1-iwdg" -+- reg: Physical base address and length of the registers set for the device -+- clocks: Reference to the clock entry lsi. Additional pclk clock entry -+ is required only for st,stm32mp1-iwdg. -+- clock-names: Name of the clocks used. -+ "lsi" for st,stm32-iwdg -+ "lsi", "pclk" for st,stm32mp1-iwdg -+ -+Optional Properties: -+- timeout-sec: Watchdog timeout value in seconds. -+ -+Example: -+ -+iwdg: watchdog@40003000 { -+ compatible = "st,stm32-iwdg"; -+ reg = <0x40003000 0x400>; -+ clocks = <&clk_lsi>; -+ clock-names = "lsi"; -+ timeout-sec = <32>; -+}; -diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h -index 90ec780..4cdaf13 100644 ---- a/include/dt-bindings/clock/stm32mp1-clks.h -+++ b/include/dt-bindings/clock/stm32mp1-clks.h -@@ -248,7 +248,4 @@ - - #define STM32MP1_LAST_CLK 232 - --#define LTDC_K LTDC_PX --#define ETHMAC_K ETHCK_K -- - #endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */ -diff --git a/include/dt-bindings/mfd/st,stpmic1.h b/include/dt-bindings/mfd/st,stpmic1.h -new file mode 100644 -index 0000000..b2d6c83 ---- /dev/null -+++ b/include/dt-bindings/mfd/st,stpmic1.h -@@ -0,0 +1,46 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved -+ * Author: Philippe Peurichard , -+ * Pascal Paillet for STMicroelectronics. -+ */ -+ -+#ifndef __DT_BINDINGS_STPMIC1_H__ -+#define __DT_BINDINGS_STPMIC1_H__ -+ -+/* IRQ definitions */ -+#define IT_PONKEY_F 0 -+#define IT_PONKEY_R 1 -+#define IT_WAKEUP_F 2 -+#define IT_WAKEUP_R 3 -+#define IT_VBUS_OTG_F 4 -+#define IT_VBUS_OTG_R 5 -+#define IT_SWOUT_F 6 -+#define IT_SWOUT_R 7 -+ -+#define IT_CURLIM_BUCK1 8 -+#define IT_CURLIM_BUCK2 9 -+#define IT_CURLIM_BUCK3 10 -+#define IT_CURLIM_BUCK4 11 -+#define IT_OCP_OTG 12 -+#define IT_OCP_SWOUT 13 -+#define IT_OCP_BOOST 14 -+#define IT_OVP_BOOST 15 -+ -+#define IT_CURLIM_LDO1 16 -+#define IT_CURLIM_LDO2 17 -+#define IT_CURLIM_LDO3 18 -+#define IT_CURLIM_LDO4 19 -+#define IT_CURLIM_LDO5 20 -+#define IT_CURLIM_LDO6 21 -+#define IT_SHORT_SWOTG 22 -+#define IT_SHORT_SWOUT 23 -+ -+#define IT_TWARN_F 24 -+#define IT_TWARN_R 25 -+#define IT_VINLOW_F 26 -+#define IT_VINLOW_R 27 -+#define IT_SWIN_F 30 -+#define IT_SWIN_R 31 -+ -+#endif /* __DT_BINDINGS_STPMIC1_H__ */ -diff --git a/include/dt-bindings/mfd/st,stpmu1.h b/include/dt-bindings/mfd/st,stpmu1.h -deleted file mode 100644 -index 81982eb..0000000 ---- a/include/dt-bindings/mfd/st,stpmu1.h -+++ /dev/null -@@ -1,60 +0,0 @@ --/* -- * This file is part of stpmu1 pmic driver -- * -- * Copyright (C) 2017, STMicroelectronics - All Rights Reserved -- * Author: Pascal Paillet for STMicroelectronics. -- * -- * License type: GPLv2 -- * -- * This program is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License version 2 as published by -- * the Free Software Foundation. -- * -- * This program is distributed in the hope that it will be useful, but -- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- * or FITNESS FOR A PARTICULAR PURPOSE. -- * See the GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License along with -- * this program. If not, see . -- */ -- --#ifndef __DT_BINDINGS_STPMU1_H__ --#define __DT_BINDINGS_STPMU1_H__ -- --/* IRQ definitions */ --#define IT_PONKEY_F 0 --#define IT_PONKEY_R 1 --#define IT_WAKEUP_F 2 --#define IT_WAKEUP_R 3 --#define IT_VBUS_OTG_F 4 --#define IT_VBUS_OTG_R 5 --#define IT_SWOUT_F 6 --#define IT_SWOUT_R 7 -- --#define IT_CURLIM_BUCK1 8 --#define IT_CURLIM_BUCK2 9 --#define IT_CURLIM_BUCK3 10 --#define IT_CURLIM_BUCK4 11 --#define IT_OCP_OTG 12 --#define IT_OCP_SWOUT 13 --#define IT_OCP_BOOST 14 --#define IT_OVP_BOOST 15 -- --#define IT_CURLIM_LDO1 16 --#define IT_CURLIM_LDO2 17 --#define IT_CURLIM_LDO3 18 --#define IT_CURLIM_LDO4 19 --#define IT_CURLIM_LDO5 20 --#define IT_CURLIM_LDO6 21 --#define IT_SHORT_SWOTG 22 --#define IT_SHORT_SWOUT 23 -- --#define IT_TWARN_F 24 --#define IT_TWARN_R 25 --#define IT_VINLOW_F 26 --#define IT_VINLOW_R 27 --#define IT_SWIN_F 30 --#define IT_SWIN_R 31 -- --#endif /* __DT_BINDINGS_STPMU1_H__ */ -diff --git a/include/dt-bindings/pinctrl/stm32-pinfunc.h b/include/dt-bindings/pinctrl/stm32-pinfunc.h -index b5a2174..e928aea 100644 ---- a/include/dt-bindings/pinctrl/stm32-pinfunc.h -+++ b/include/dt-bindings/pinctrl/stm32-pinfunc.h -@@ -32,5 +32,11 @@ - - #define STM32_PINMUX(port, line, mode) (((PIN_NO(port, line)) << 8) | (mode)) - -+/* package information */ -+#define STM32MP157CAA 0x1 -+#define STM32MP157CAB 0x2 -+#define STM32MP157CAC 0x4 -+#define STM32MP157CAD 0x8 -+ - #endif /* _DT_BINDINGS_STM32_PINFUNC_H */ - -diff --git a/include/dt-bindings/rtc/rtc-stm32.h b/include/dt-bindings/rtc/rtc-stm32.h -new file mode 100644 -index 0000000..4373c4d ---- /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 0000000..d986653 ---- /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 */ --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0003-ARM-v2020.01-stm32mp-r1-MISC-DRIVERS.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0003-ARM-v2020.01-stm32mp-r1-MISC-DRIVERS.patch new file mode 100644 index 0000000..d13fb6b --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0003-ARM-v2020.01-stm32mp-r1-MISC-DRIVERS.patch @@ -0,0 +1,9969 @@ +From b3ad756bcf4959e8ec4c2cfdcd8d0eeeca12a845 Mon Sep 17 00:00:00 2001 +From: Romuald JEANNE +Date: Fri, 5 Jun 2020 13:45:13 +0200 +Subject: [PATCH 3/5] ARM v2020.01-stm32mp-r1 MISC-DRIVERS + +--- + cmd/Kconfig | 1 + + cmd/dtimg.c | 50 ++- + cmd/mtd.c | 24 +- + cmd/nvedit.c | 39 ++- + common/board_f.c | 27 +- + common/cli_readline.c | 6 + + common/image-android-dt.c | 42 +++ + configs/igep00x0_defconfig | 1 + + configs/mt8518_ap1_emmc_defconfig | 2 + + configs/odroid-xu3_defconfig | 1 + + configs/odroid_defconfig | 1 + + configs/sandbox64_defconfig | 1 + + configs/sandbox_defconfig | 1 + + configs/sandbox_flattree_defconfig | 1 + + configs/sandbox_spl_defconfig | 1 + + doc/README.gpio | 42 +++ + doc/android/fastboot.txt | 3 + + doc/device-tree-bindings/clock/st,stm32-rcc.txt | 37 ++ + doc/device-tree-bindings/clock/st,stm32mp1.txt | 36 +- + doc/device-tree-bindings/gpio/gpio.txt | 304 ++++++++++------- + doc/device-tree-bindings/i2c/i2c-stm32.txt | 105 +++++- + .../memory-controllers/st,stm32mp1-ddr.txt | 2 + + doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt | 6 +- + doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt | 55 ++- + drivers/ata/dwc_ahci.c | 4 +- + drivers/clk/Kconfig | 8 + + drivers/clk/Makefile | 1 + + drivers/clk/clk_scmi.c | 152 +++++++++ + drivers/clk/clk_stm32mp1.c | 378 +++++++++++++++++---- + drivers/core/of_access.c | 32 ++ + drivers/core/ofnode.c | 48 +++ + drivers/core/read.c | 16 + + drivers/core/root.c | 52 +-- + drivers/dfu/Kconfig | 5 + + drivers/fastboot/Kconfig | 68 ++++ + drivers/fastboot/fb_command.c | 72 ++++ + drivers/fastboot/fb_mmc.c | 118 +++++++ + drivers/gpio/gpio-uclass.c | 203 ++++++++--- + drivers/gpio/mpc8xxx_gpio.c | 22 -- + drivers/gpio/sandbox.c | 321 ++++++++++++++--- + drivers/gpio/stm32_gpio.c | 152 ++++++++- + drivers/i2c/stm32f7_i2c.c | 128 +++---- + drivers/mailbox/Kconfig | 7 + + drivers/mailbox/Makefile | 1 + + drivers/mailbox/arm-smc-mbox.c | 118 +++++++ + drivers/misc/Kconfig | 12 + + drivers/misc/Makefile | 1 + + drivers/misc/scmi_agent.c | 337 ++++++++++++++++++ + drivers/mmc/stm32_sdmmc2.c | 2 +- + drivers/mtd/Kconfig | 7 + + drivers/net/dwc_eth_qos.c | 73 +++- + drivers/phy/phy-stm32-usbphyc.c | 2 +- + drivers/phy/phy-uclass.c | 40 ++- + drivers/pinctrl/pinctrl-generic.c | 30 +- + drivers/pinctrl/pinctrl-sandbox.c | 44 ++- + drivers/pinctrl/pinctrl-single.c | 27 +- + drivers/pinctrl/pinctrl-stmfx.c | 232 +++++++++---- + drivers/pinctrl/pinctrl_stm32.c | 27 +- + drivers/power/regulator/stm32-vrefbuf.c | 16 +- + drivers/ram/stm32mp1/stm32mp1_ddr.c | 54 ++- + drivers/ram/stm32mp1/stm32mp1_ddr.h | 1 + + drivers/ram/stm32mp1/stm32mp1_ddr_regs.h | 1 + + drivers/ram/stm32mp1/stm32mp1_interactive.c | 17 +- + drivers/ram/stm32mp1/stm32mp1_ram.c | 34 +- + drivers/ram/stm32mp1/stm32mp1_tests.c | 31 +- + drivers/ram/stm32mp1/stm32mp1_tuning.c | 223 ++++++++++-- + drivers/remoteproc/rproc-elf-loader.c | 269 +++++++++++++++ + drivers/remoteproc/stm32_copro.c | 61 +++- + drivers/reset/Kconfig | 8 + + drivers/reset/Makefile | 1 + + drivers/reset/reset-scmi.c | 86 +++++ + drivers/tee/optee/core.c | 13 +- + drivers/usb/dwc3/core.c | 12 +- + drivers/usb/gadget/dwc2_udc_otg.c | 6 +- + drivers/usb/gadget/g_dnl.c | 8 + + drivers/usb/host/dwc2.c | 118 ++++++- + drivers/usb/host/ehci-hcd.c | 8 +- + drivers/usb/host/ohci-generic.c | 8 +- + drivers/usb/musb-new/sunxi.c | 8 +- + drivers/video/orisetech_otm8009a.c | 20 +- + drivers/video/raydium-rm68200.c | 20 +- + drivers/video/stm32/stm32_dsi.c | 15 +- + env/mmc.c | 26 +- + include/asm-generic/gpio.h | 102 +++--- + include/clk.h | 104 +++++- + include/configs/odroid.h | 1 - + include/configs/odroid_xu3.h | 1 - + include/configs/omap3_igep00x0.h | 2 - + include/configs/stm32f429-evaluation.h | 15 +- + include/configs/stm32f469-discovery.h | 15 +- + include/configs/stm32f746-disco.h | 15 +- + include/configs/stm32h743-disco.h | 14 +- + include/configs/stm32h743-eval.h | 14 +- + include/configs/stm32mp1.h | 208 +++++++----- + include/dfu.h | 3 + + include/dm/of_access.h | 40 +++ + include/dm/ofnode.h | 63 +++- + include/dm/read.h | 67 ++++ + include/dt-bindings/clock/stm32mp1-clks.h | 33 ++ + include/dt-bindings/gpio/gpio.h | 6 + + include/dt-bindings/gpio/sandbox-gpio.h | 24 ++ + include/dt-bindings/mfd/stm32h7-rcc.h | 1 - + include/dt-bindings/pinctrl/stm32-pinfunc.h | 1 + + include/dt-bindings/reset/stm32mp1-resets.h | 13 + + include/dt-bindings/rtc/rtc-stm32.h | 13 + + include/dt-bindings/soc/stm32-hdp.h | 108 ++++++ + include/env_internal.h | 31 ++ + include/fastboot.h | 6 + + include/g_dnl.h | 1 + + include/i2c.h | 26 ++ + include/image-android-dt.h | 2 + + include/mipi_dsi.h | 6 + + include/mtd.h | 2 + + include/power/stpmic1.h | 1 + + include/remoteproc.h | 70 ++++ + include/scmi_agent.h | 82 +++++ + lib/libfdt/fdt_ro.c | 20 +- + lib/optee/optee.c | 2 +- + scripts/config_whitelist.txt | 2 - + scripts/dtc/libfdt/fdt_ro.c | 20 +- + scripts/dtc/libfdt/libfdt.h | 33 +- + test/dm/Makefile | 1 + + test/dm/gpio.c | 69 +++- + test/dm/ofread.c | 50 +++ + test/dm/remoteproc.c | 91 ++++- + test/dm/test-fdt.c | 4 +- + test/py/tests/test_env.py | 44 +++ + test/py/tests/test_pinmux.py | 38 ++- + tools/fdtgrep.c | 6 +- + tools/stm32image.c | 5 +- + 130 files changed, 5029 insertions(+), 1038 deletions(-) + create mode 100644 doc/README.gpio + create mode 100644 drivers/clk/clk_scmi.c + create mode 100644 drivers/mailbox/arm-smc-mbox.c + create mode 100644 drivers/misc/scmi_agent.c + create mode 100644 drivers/reset/reset-scmi.c + create mode 100644 include/dt-bindings/gpio/sandbox-gpio.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/scmi_agent.h + create mode 100644 test/dm/ofread.c + +diff --git a/cmd/Kconfig b/cmd/Kconfig +index 1e4cf14..8a44461 100644 +--- a/cmd/Kconfig ++++ b/cmd/Kconfig +@@ -551,6 +551,7 @@ config CMD_NVEDIT_INFO + This command can be optionally used for evaluation in scripts: + [-d] : evaluate whether default environment is used + [-p] : evaluate whether environment can be persisted ++ [-q] : quiet output + The result of multiple evaluations will be combined with AND. + + endmenu +diff --git a/cmd/dtimg.c b/cmd/dtimg.c +index 6c5d53c..cd221b2 100644 +--- a/cmd/dtimg.c ++++ b/cmd/dtimg.c +@@ -99,10 +99,52 @@ static int do_dtimg_size(cmd_tbl_t *cmdtp, int flag, int argc, + return dtimg_get_fdt(argc, argv, CMD_DTIMG_SIZE); + } + ++static int do_dtimg_getindex(cmd_tbl_t *cmdtp, int flag, int argc, ++ char * const argv[]) ++{ ++ char *endp; ++ ulong hdr_addr; ++ int index; ++ char buf[512] = { 0 }; ++ ++ if (argc < 4) ++ return CMD_RET_USAGE; ++ ++ hdr_addr = simple_strtoul(argv[1], &endp, 16); ++ if (*endp != '\0') { ++ printf("Error: Wrong image address\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ if (!android_dt_check_header(hdr_addr)) { ++ printf("Error: DT image header is incorrect\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ index = android_dt_get_index(hdr_addr, strtoul(argv[2], NULL, 0), ++ strtoul(argv[3], NULL, 0)); ++ ++ if (index < 0) { ++ printf("Error: board id %04lx not found in DT table\n", ++ strtoul(argv[2], NULL, 0)); ++ return CMD_RET_FAILURE; ++ } ++ ++ snprintf(buf, sizeof(buf), "%i", index); ++ ++ if (argc == 5) ++ env_set(argv[4], buf); ++ else ++ printf("%s\n", buf); ++ ++ return CMD_RET_SUCCESS; ++} ++ + static cmd_tbl_t cmd_dtimg_sub[] = { + U_BOOT_CMD_MKENT(dump, 2, 0, do_dtimg_dump, "", ""), + U_BOOT_CMD_MKENT(start, 4, 0, do_dtimg_start, "", ""), + U_BOOT_CMD_MKENT(size, 4, 0, do_dtimg_size, "", ""), ++ U_BOOT_CMD_MKENT(getindex, 5, 0, do_dtimg_getindex, "", ""), + }; + + static int do_dtimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +@@ -138,5 +180,11 @@ U_BOOT_CMD( + " - get size (hex, bytes) of FDT in the image, by index\n" + " : image address in RAM, in hex\n" + " : index of desired FDT in the image\n" +- " : name of variable where to store size of FDT" ++ " : name of variable where to store size of FDT\n" ++ "dtimg getindex [varname]\n" ++ " - get index of FDT in the image, by board identifier and revision\n" ++ " : image address in RAM, in hex\n" ++ " : board identifier\n" ++ " : board revision (0 if not used)\n" ++ " [varname]: name of variable where to store index of FDT" + ); +diff --git a/cmd/mtd.c b/cmd/mtd.c +index 1b6b8dd..a559b5a 100644 +--- a/cmd/mtd.c ++++ b/cmd/mtd.c +@@ -387,7 +387,7 @@ static int do_mtd_erase(cmd_tbl_t *cmdtp, int flag, int argc, + struct mtd_info *mtd; + u64 off, len; + bool scrub; +- int ret; ++ int ret = 0; + + if (argc < 2) + return CMD_RET_USAGE; +@@ -423,22 +423,22 @@ static int do_mtd_erase(cmd_tbl_t *cmdtp, int flag, int argc, + + erase_op.mtd = mtd; + erase_op.addr = off; +- erase_op.len = len; ++ erase_op.len = mtd->erasesize; + erase_op.scrub = scrub; + +- while (erase_op.len) { ++ while (len) { + ret = mtd_erase(mtd, &erase_op); + +- /* Abort if its not a bad block error */ +- if (ret != -EIO) +- break; +- +- printf("Skipping bad block at 0x%08llx\n", erase_op.fail_addr); ++ if (ret) { ++ /* Abort if its not a bad block error */ ++ if (ret != -EIO) ++ break; ++ printf("Skipping bad block at 0x%08llx\n", ++ erase_op.addr); ++ } + +- /* Skip bad block and continue behind it */ +- erase_op.len -= erase_op.fail_addr - erase_op.addr; +- erase_op.len -= mtd->erasesize; +- erase_op.addr = erase_op.fail_addr + mtd->erasesize; ++ len -= mtd->erasesize; ++ erase_op.addr += mtd->erasesize; + } + + if (ret && ret != -EIO) +diff --git a/cmd/nvedit.c b/cmd/nvedit.c +index 81d94cd..218fdfb 100644 +--- a/cmd/nvedit.c ++++ b/cmd/nvedit.c +@@ -1219,12 +1219,18 @@ static int print_env_info(void) + * env info - display environment information + * env info [-d] - evaluate whether default environment is used + * env info [-p] - evaluate whether environment can be persisted ++ * Add [-q] - quiet mode, use only for command result, for test by example: ++ * test env info -p -d -q + */ + static int do_env_info(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) + { + int eval_flags = 0; + int eval_results = 0; ++ bool quiet = false; ++#if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE) ++ enum env_location loc; ++#endif + + /* display environment information */ + if (argc <= 1) +@@ -1242,6 +1248,9 @@ static int do_env_info(cmd_tbl_t *cmdtp, int flag, + case 'p': + eval_flags |= ENV_INFO_IS_PERSISTED; + break; ++ case 'q': ++ quiet = true; ++ break; + default: + return CMD_RET_USAGE; + } +@@ -1251,20 +1260,30 @@ static int do_env_info(cmd_tbl_t *cmdtp, int flag, + /* evaluate whether default environment is used */ + if (eval_flags & ENV_INFO_IS_DEFAULT) { + if (gd->flags & GD_FLG_ENV_DEFAULT) { +- printf("Default environment is used\n"); ++ if (!quiet) ++ printf("Default environment is used\n"); + eval_results |= ENV_INFO_IS_DEFAULT; + } else { +- printf("Environment was loaded from persistent storage\n"); ++ if (!quiet) ++ printf("Environment was loaded from persistent storage\n"); + } + } + + /* evaluate whether environment can be persisted */ + if (eval_flags & ENV_INFO_IS_PERSISTED) { +-#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) +- printf("Environment can be persisted\n"); +- eval_results |= ENV_INFO_IS_PERSISTED; ++#if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE) ++ loc = env_get_location(ENVOP_SAVE, gd->env_load_prio); ++ if (ENVL_NOWHERE != loc && ENVL_UNKNOWN != loc) { ++ if (!quiet) ++ printf("Environment can be persisted\n"); ++ eval_results |= ENV_INFO_IS_PERSISTED; ++ } else { ++ if (!quiet) ++ printf("Environment cannot be persisted\n"); ++ } + #else +- printf("Environment cannot be persisted\n"); ++ if (!quiet) ++ printf("Environment cannot be persisted\n"); + #endif + } + +@@ -1321,7 +1340,7 @@ static cmd_tbl_t cmd_env_sub[] = { + U_BOOT_CMD_MKENT(import, 5, 0, do_env_import, "", ""), + #endif + #if defined(CONFIG_CMD_NVEDIT_INFO) +- U_BOOT_CMD_MKENT(info, 2, 0, do_env_info, "", ""), ++ U_BOOT_CMD_MKENT(info, 3, 0, do_env_info, "", ""), + #endif + U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", ""), + #if defined(CONFIG_CMD_RUN) +@@ -1400,8 +1419,10 @@ static char env_help_text[] = + #endif + #if defined(CONFIG_CMD_NVEDIT_INFO) + "env info - display environment information\n" +- "env info [-d] - whether default environment is used\n" +- "env info [-p] - whether environment can be persisted\n" ++ "env info [-d] [-p] [-q] - evaluate environment information\n" ++ " \"-d\": default environment is used\n" ++ " \"-p\": environment can be persisted\n" ++ " \"-q\": quiet output\n" + #endif + "env print [-a | name ...] - print environment\n" + #if defined(CONFIG_CMD_NVEDIT_EFI) +diff --git a/common/board_f.c b/common/board_f.c +index d66afb3..ef59630 100644 +--- a/common/board_f.c ++++ b/common/board_f.c +@@ -470,6 +470,17 @@ static int reserve_uboot(void) + return 0; + } + ++/* ++ * reserve after start_addr_sp the requested size and make the stack pointer ++ * 16-byte aligned, this alignment is needed for cast on the reserved memory ++ * ref = x86_64 ABI: https://reviews.llvm.org/D30049: 16 bytes ++ * = ARMv8 Instruction Set Overview: quad word, 16 bytes ++ */ ++static unsigned long reserve_stack_aligned(size_t size) ++{ ++ return ALIGN_DOWN(gd->start_addr_sp - size, 16); ++} ++ + #ifdef CONFIG_SYS_NONCACHED_MEMORY + static int reserve_noncached(void) + { +@@ -495,7 +506,7 @@ static int reserve_noncached(void) + /* reserve memory for malloc() area */ + static int reserve_malloc(void) + { +- gd->start_addr_sp = gd->start_addr_sp - TOTAL_MALLOC_LEN; ++ gd->start_addr_sp = reserve_stack_aligned(TOTAL_MALLOC_LEN); + debug("Reserving %dk for malloc() at: %08lx\n", + TOTAL_MALLOC_LEN >> 10, gd->start_addr_sp); + #ifdef CONFIG_SYS_NONCACHED_MEMORY +@@ -509,7 +520,7 @@ static int reserve_malloc(void) + static int reserve_board(void) + { + if (!gd->bd) { +- gd->start_addr_sp -= sizeof(bd_t); ++ gd->start_addr_sp = reserve_stack_aligned(sizeof(bd_t)); + gd->bd = (bd_t *)map_sysmem(gd->start_addr_sp, sizeof(bd_t)); + memset(gd->bd, '\0', sizeof(bd_t)); + debug("Reserving %zu Bytes for Board Info at: %08lx\n", +@@ -528,7 +539,7 @@ static int setup_machine(void) + + static int reserve_global_data(void) + { +- gd->start_addr_sp -= sizeof(gd_t); ++ gd->start_addr_sp = reserve_stack_aligned(sizeof(gd_t)); + gd->new_gd = (gd_t *)map_sysmem(gd->start_addr_sp, sizeof(gd_t)); + debug("Reserving %zu Bytes for Global Data at: %08lx\n", + sizeof(gd_t), gd->start_addr_sp); +@@ -546,7 +557,7 @@ static int reserve_fdt(void) + if (gd->fdt_blob) { + gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32); + +- gd->start_addr_sp -= gd->fdt_size; ++ gd->start_addr_sp = reserve_stack_aligned(gd->fdt_size); + gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size); + debug("Reserving %lu Bytes for FDT at: %08lx\n", + gd->fdt_size, gd->start_addr_sp); +@@ -561,7 +572,7 @@ static int reserve_bootstage(void) + #ifdef CONFIG_BOOTSTAGE + int size = bootstage_get_size(); + +- gd->start_addr_sp -= size; ++ gd->start_addr_sp = reserve_stack_aligned(size); + gd->new_bootstage = map_sysmem(gd->start_addr_sp, size); + debug("Reserving %#x Bytes for bootstage at: %08lx\n", size, + gd->start_addr_sp); +@@ -578,8 +589,7 @@ __weak int arch_reserve_stacks(void) + static int reserve_stacks(void) + { + /* make stack pointer 16-byte aligned */ +- gd->start_addr_sp -= 16; +- gd->start_addr_sp &= ~0xf; ++ gd->start_addr_sp = reserve_stack_aligned(16); + + /* + * let the architecture-specific code tailor gd->start_addr_sp and +@@ -591,8 +601,7 @@ static int reserve_stacks(void) + static int reserve_bloblist(void) + { + #ifdef CONFIG_BLOBLIST +- gd->start_addr_sp &= ~0xf; +- gd->start_addr_sp -= CONFIG_BLOBLIST_SIZE; ++ gd->start_addr_sp = reserve_stack_aligned(CONFIG_BLOBLIST_SIZE); + gd->new_bloblist = map_sysmem(gd->start_addr_sp, CONFIG_BLOBLIST_SIZE); + #endif + +diff --git a/common/cli_readline.c b/common/cli_readline.c +index 6ef7a3e..a0ae778 100644 +--- a/common/cli_readline.c ++++ b/common/cli_readline.c +@@ -14,6 +14,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-android-dt.c b/common/image-android-dt.c +index a2d52df..a325e67 100644 +--- a/common/image-android-dt.c ++++ b/common/image-android-dt.c +@@ -154,4 +154,46 @@ void android_dt_print_contents(ulong hdr_addr) + unmap_sysmem(fdt); + } + } ++ + #endif ++ ++/** ++ * Get dtb index based on board identifier and revision. ++ * ++ * @param hdr_addr Start address of DT image ++ * @param board_id board identifier ++ * @param board_rev board revision (0 if not used) ++ * ++ * @return index in dt table ++ */ ++int android_dt_get_index(ulong hdr_addr, u32 board_id, u32 board_rev) ++{ ++ const struct dt_table_header *hdr; ++ u32 entry_count, entries_offset, entry_size; ++ u32 i; ++ int ret = -1; ++ ++ hdr = map_sysmem(hdr_addr, sizeof(*hdr)); ++ entry_count = fdt32_to_cpu(hdr->dt_entry_count); ++ entries_offset = fdt32_to_cpu(hdr->dt_entries_offset); ++ entry_size = fdt32_to_cpu(hdr->dt_entry_size); ++ unmap_sysmem(hdr); ++ ++ for (i = 0; i < entry_count; ++i) { ++ const ulong e_addr = hdr_addr + entries_offset + i * entry_size; ++ const struct dt_table_entry *e; ++ ++ e = map_sysmem(e_addr, sizeof(*e)); ++ ++ if ((fdt32_to_cpu(e->id) == board_id) && ++ (board_rev == 0 || fdt32_to_cpu(e->rev) == board_rev)) { ++ ret = i; ++ unmap_sysmem(e); ++ break; ++ } ++ ++ unmap_sysmem(e); ++ } ++ ++ return ret; ++} +diff --git a/configs/igep00x0_defconfig b/configs/igep00x0_defconfig +index cb72a01..483f37c 100644 +--- a/configs/igep00x0_defconfig ++++ b/configs/igep00x0_defconfig +@@ -52,6 +52,7 @@ CONFIG_NET_RANDOM_ETHADDR=y + CONFIG_DM_MMC=y + CONFIG_MMC_OMAP_HS=y + CONFIG_MTD=y ++CONFIG_SYS_MTDPARTS_RUNTIME=y + CONFIG_MTD_RAW_NAND=y + CONFIG_SYS_NAND_BUSWIDTH_16BIT=y + CONFIG_SPL_NAND_SIMPLE=y +diff --git a/configs/mt8518_ap1_emmc_defconfig b/configs/mt8518_ap1_emmc_defconfig +index 6d824cc..be5ab64 100644 +--- a/configs/mt8518_ap1_emmc_defconfig ++++ b/configs/mt8518_ap1_emmc_defconfig +@@ -16,6 +16,8 @@ CONFIG_DEFAULT_DEVICE_TREE="mt8518-ap1-emmc" + CONFIG_REGMAP=y + CONFIG_SYSCON=y + CONFIG_CLK=y ++CONFIG_FASTBOOT_MMC_BOOT_SUPPORT=y ++CONFIG_FASTBOOT_MMC_USER_SUPPORT=y + CONFIG_DM_MMC=y + CONFIG_MMC_HS200_SUPPORT=y + CONFIG_MMC_MTK=y +diff --git a/configs/odroid-xu3_defconfig b/configs/odroid-xu3_defconfig +index 20038d4..ff0bdc3 100644 +--- a/configs/odroid-xu3_defconfig ++++ b/configs/odroid-xu3_defconfig +@@ -38,6 +38,7 @@ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y + CONFIG_ADC=y + CONFIG_ADC_EXYNOS=y + CONFIG_DFU_MMC=y ++CONFIG_SET_DFU_ALT_INFO=y + CONFIG_SUPPORT_EMMC_BOOT=y + CONFIG_MMC_DW=y + CONFIG_MTD=y +diff --git a/configs/odroid_defconfig b/configs/odroid_defconfig +index be914e4..c77541c 100644 +--- a/configs/odroid_defconfig ++++ b/configs/odroid_defconfig +@@ -39,6 +39,7 @@ CONFIG_DEFAULT_DEVICE_TREE="exynos4412-odroid" + CONFIG_SYS_RELOC_GD_ENV_ADDR=y + CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y + CONFIG_DFU_MMC=y ++CONFIG_SET_DFU_ALT_INFO=y + CONFIG_SYS_I2C_S3C24X0=y + CONFIG_MMC_DW=y + CONFIG_MMC_SDHCI=y +diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig +index cc536ff..f3565a9 100644 +--- a/configs/sandbox64_defconfig ++++ b/configs/sandbox64_defconfig +@@ -27,6 +27,7 @@ CONFIG_CMD_ASKENV=y + CONFIG_CMD_GREPENV=y + CONFIG_CMD_ENV_CALLBACK=y + CONFIG_CMD_ENV_FLAGS=y ++CONFIG_CMD_NVEDIT_INFO=y + CONFIG_LOOPW=y + CONFIG_CMD_MD5SUM=y + CONFIG_CMD_MEMINFO=y +diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig +index 64245f7..8a2d397 100644 +--- a/configs/sandbox_defconfig ++++ b/configs/sandbox_defconfig +@@ -30,6 +30,7 @@ CONFIG_CMD_ASKENV=y + CONFIG_CMD_GREPENV=y + CONFIG_CMD_ENV_CALLBACK=y + CONFIG_CMD_ENV_FLAGS=y ++CONFIG_CMD_NVEDIT_INFO=y + CONFIG_LOOPW=y + CONFIG_CMD_MD5SUM=y + CONFIG_CMD_MEMINFO=y +diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig +index bb31b00..ffd0dfa 100644 +--- a/configs/sandbox_flattree_defconfig ++++ b/configs/sandbox_flattree_defconfig +@@ -22,6 +22,7 @@ CONFIG_CMD_BOOTZ=y + # CONFIG_CMD_ELF is not set + CONFIG_CMD_ASKENV=y + CONFIG_CMD_GREPENV=y ++CONFIG_CMD_NVEDIT_INFO=y + CONFIG_LOOPW=y + CONFIG_CMD_MD5SUM=y + CONFIG_CMD_MEMINFO=y +diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig +index 61a8ffd..ab2c29a 100644 +--- a/configs/sandbox_spl_defconfig ++++ b/configs/sandbox_spl_defconfig +@@ -33,6 +33,7 @@ CONFIG_CMD_ASKENV=y + CONFIG_CMD_GREPENV=y + CONFIG_CMD_ENV_CALLBACK=y + CONFIG_CMD_ENV_FLAGS=y ++CONFIG_CMD_NVEDIT_INFO=y + CONFIG_LOOPW=y + CONFIG_CMD_MD5SUM=y + CONFIG_CMD_MEMINFO=y +diff --git a/doc/README.gpio b/doc/README.gpio +new file mode 100644 +index 0000000..548ff37 +--- /dev/null ++++ b/doc/README.gpio +@@ -0,0 +1,42 @@ ++ ++GPIO hog (CONFIG_GPIO_HOG) ++-------- ++ ++All the GPIO hog are initialized in gpio_hog_probe_all() function called in ++board_r.c just before board_late_init() but you can also acces directly to ++the gpio with gpio_hog_lookup_name(). ++ ++ ++Example, for the device tree: ++ ++ tca6416@20 { ++ compatible = "ti,tca6416"; ++ reg = <0x20>; ++ #gpio-cells = <2>; ++ gpio-controller; ++ ++ env_reset { ++ gpio-hog; ++ input; ++ gpios = <6 GPIO_ACTIVE_LOW>; ++ }; ++ boot_rescue { ++ gpio-hog; ++ input; ++ line-name = "foo-bar-gpio"; ++ gpios = <7 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++You can than access the gpio in your board code with: ++ ++ struct gpio_desc *desc; ++ int ret; ++ ++ ret = gpio_hog_lookup_name("boot_rescue", &desc); ++ if (ret) ++ return; ++ if (dm_gpio_get_value(desc) == 1) ++ printf("\nBooting into Rescue System\n"); ++ else if (dm_gpio_get_value(desc) == 0) ++ printf("\nBoot normal\n"); +diff --git a/doc/android/fastboot.txt b/doc/android/fastboot.txt +index 9de1322..e01eec6 100644 +--- a/doc/android/fastboot.txt ++++ b/doc/android/fastboot.txt +@@ -23,6 +23,9 @@ The current implementation supports the following standard commands: + The following OEM commands are supported (if enabled): + + - oem format - this executes ``gpt write mmc %x $partitions`` ++- oem partconf - this executes - ``mmc partconf %x 0`` to configure eMMC ++ with = boot_ack boot_partition ++- oem bootbus - this executes - ``mmc bootbus %x %s`` to configure eMMC + + Support for both eMMC and NAND devices is included. + +diff --git a/doc/device-tree-bindings/clock/st,stm32-rcc.txt b/doc/device-tree-bindings/clock/st,stm32-rcc.txt +index 0532d81..b240121 100644 +--- a/doc/device-tree-bindings/clock/st,stm32-rcc.txt ++++ b/doc/device-tree-bindings/clock/st,stm32-rcc.txt +@@ -10,6 +10,7 @@ Required properties: + - compatible: Should be: + "st,stm32f42xx-rcc" + "st,stm32f469-rcc" ++ "st,stm32f746-rcc" + - reg: should be register base and length as documented in the + datasheet + - #reset-cells: 1, see below +@@ -17,6 +18,9 @@ Required properties: + property, containing a phandle to the clock device node, an index selecting + between gated clocks and other clocks and an index specifying the clock to + use. ++- clocks: External oscillator clock phandle ++ - high speed external clock signal (HSE) ++ - external I2S clock (I2S_CKIN) + + Example: + +@@ -25,6 +29,7 @@ Example: + #clock-cells = <2> + compatible = "st,stm32f42xx-rcc", "st,stm32-rcc"; + reg = <0x40023800 0x400>; ++ clocks = <&clk_hse>, <&clk_i2s_ckin>; + }; + + Specifying gated clocks +@@ -66,6 +71,38 @@ The secondary index is bound with the following magic numbers: + + 0 SYSTICK + 1 FCLK ++ 2 CLK_LSI (low-power clock source) ++ 3 CLK_LSE (generated from a 32.768 kHz low-speed external ++ crystal or ceramic resonator) ++ 4 CLK_HSE_RTC (HSE division factor for RTC clock) ++ 5 CLK_RTC (real-time clock) ++ 6 PLL_VCO_I2S (vco frequency of I2S pll) ++ 7 PLL_VCO_SAI (vco frequency of SAI pll) ++ 8 CLK_LCD (LCD-TFT) ++ 9 CLK_I2S (I2S clocks) ++ 10 CLK_SAI1 (audio clocks) ++ 11 CLK_SAI2 ++ 12 CLK_I2SQ_PDIV (post divisor of pll i2s q divisor) ++ 13 CLK_SAIQ_PDIV (post divisor of pll sai q divisor) ++ ++ 14 CLK_HSI (Internal ocscillator clock) ++ 15 CLK_SYSCLK (System Clock) ++ 16 CLK_HDMI_CEC (HDMI-CEC clock) ++ 17 CLK_SPDIF (SPDIF-Rx clock) ++ 18 CLK_USART1 (U(s)arts clocks) ++ 19 CLK_USART2 ++ 20 CLK_USART3 ++ 21 CLK_UART4 ++ 22 CLK_UART5 ++ 23 CLK_USART6 ++ 24 CLK_UART7 ++ 25 CLK_UART8 ++ 26 CLK_I2C1 (I2S clocks) ++ 27 CLK_I2C2 ++ 28 CLK_I2C3 ++ 29 CLK_I2C4 ++ 30 CLK_LPTIMER (LPTimer1 clock) ++) + + Example: + +diff --git a/doc/device-tree-bindings/clock/st,stm32mp1.txt b/doc/device-tree-bindings/clock/st,stm32mp1.txt +index ec1d703..4d4136d 100644 +--- a/doc/device-tree-bindings/clock/st,stm32mp1.txt ++++ b/doc/device-tree-bindings/clock/st,stm32mp1.txt +@@ -12,6 +12,9 @@ describes the fields added for clock tree initialization which are not present + in Linux binding for compatible "st,stm32mp1-rcc" defined in st,stm32mp1-rcc.txt + file. + ++This parent node may optionally have additional children nodes which define ++specific init values for RCC elements. ++ + The added properties for clock tree initialization are: + + Required properties: +@@ -78,13 +81,20 @@ Required properties: + >; + + Optional Properties: +-- st,pll : A specific PLL configuration, including frequency. ++- children for a PLL configuration with "st,stm32mp1-pll" compatible ++ ++ each PLL children nodes for PLL1 to PLL4 (see ref manual for details) ++ are listed with associated reg 0 to 3. ++ PLLx is off when the associated node is absent or deactivated. + +- PLL children nodes for PLL1 to PLL4 (see ref manual for details) +- are listed with associated index 0 to 3 (st,pll@0 to st,pll@3). +- PLLx is off when the associated node is absent. ++ For PLL1, when the node is absent, the frequency of the OPP node is used ++ to compute the PLL setting (see compatible "operating-points-v2" in ++ opp/opp.txt for details). + + Here are the available properties for each PLL node: ++ - compatible: should be "st,stm32mp1-pll" ++ ++ - reg: index of the pll instance + + - cfg: The parameters for PLL configuration in the following order: + DIVM DIVN DIVP DIVQ DIVR Output. +@@ -118,18 +128,26 @@ Optional Properties: + + Example: + st,pll@0 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <0>; + cfg = < 1 53 0 0 0 1 >; + frac = < 0x810 >; + }; + st,pll@1 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <1>; + cfg = < 1 43 1 0 0 PQR(0,1,1) >; + csg = < 10 20 1 >; + }; + st,pll@2 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <2>; + cfg = < 2 85 3 13 3 0 >; + csg = < 10 20 SSCG_MODE_CENTER_SPREAD >; + }; + st,pll@3 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <3>; + cfg = < 2 78 4 7 9 3 >; + }; + +@@ -277,6 +295,8 @@ Example of clock tree initialization + u-boot,dm-pre-reloc; + compatible = "st,stm32mp1-rcc", "syscon"; + reg = <0x50000000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; + #clock-cells = <1>; + #reset-cells = <1>; + interrupts = ; +@@ -347,6 +367,8 @@ Example of clock tree initialization + + /* VCO = 1300.0 MHz => P = 650 (CPU) */ + pll1: st,pll@0 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <0>; + cfg = < 2 80 0 0 0 PQR(1,0,0) >; + frac = < 0x800 >; + u-boot,dm-pre-reloc; +@@ -355,6 +377,8 @@ Example of clock tree initialization + /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), + R = 533 (DDR) */ + pll2: st,pll@1 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <1>; + cfg = < 2 65 1 0 0 PQR(1,1,1) >; + frac = < 0x1400 >; + u-boot,dm-pre-reloc; +@@ -362,6 +386,8 @@ Example of clock tree initialization + + /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ + pll3: st,pll@2 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <2>; + cfg = < 1 33 1 16 36 PQR(1,1,1) >; + frac = < 0x1a04 >; + u-boot,dm-pre-reloc; +@@ -369,6 +395,8 @@ Example of clock tree initialization + + /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ + pll4: st,pll@3 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <3>; + cfg = < 3 98 5 7 7 PQR(1,1,1) >; + u-boot,dm-pre-reloc; + }; +diff --git a/doc/device-tree-bindings/gpio/gpio.txt b/doc/device-tree-bindings/gpio/gpio.txt +index e146917..1481ed6 100644 +--- a/doc/device-tree-bindings/gpio/gpio.txt ++++ b/doc/device-tree-bindings/gpio/gpio.txt +@@ -4,19 +4,12 @@ Specifying GPIO information for devices + 1) gpios property + ----------------- + +-Nodes that makes use of GPIOs should specify them using one or more +-properties, each containing a 'gpio-list': +- +- gpio-list ::= [gpio-list] +- single-gpio ::= +- gpio-phandle : phandle to gpio controller node +- gpio-specifier : Array of #gpio-cells specifying specific gpio +- (controller specific) +- + GPIO properties should be named "[-]gpios", with being the purpose + of this GPIO for the device. While a non-existent is considered valid + for compatibility reasons (resolving to the "gpios" property), it is not allowed +-for new bindings. ++for new bindings. Also, GPIO properties named "[-]gpio" are valid and old ++bindings use it, but are only supported for compatibility reasons and should not ++be used for newer bindings since it has been deprecated. + + GPIO properties can contain one or more GPIO phandles, but only in exceptional + cases should they contain more than one. If your device uses several GPIOs with +@@ -31,30 +24,28 @@ The following example could be used to describe GPIO pins used as device enable + and bit-banged data signals: + + gpio1: gpio1 { +- gpio-controller +- #gpio-cells = <2>; +- }; +- gpio2: gpio2 { +- gpio-controller +- #gpio-cells = <1>; ++ gpio-controller; ++ #gpio-cells = <2>; + }; + [...] + +- enable-gpios = <&gpio2 2>; + data-gpios = <&gpio1 12 0>, + <&gpio1 13 0>, + <&gpio1 14 0>, + <&gpio1 15 0>; + +-Note that gpio-specifier length is controller dependent. In the +-above example, &gpio1 uses 2 cells to specify a gpio, while &gpio2 +-only uses one. ++In the above example, &gpio1 uses 2 cells to specify a gpio. The first cell is ++a local offset to the GPIO line and the second cell represent consumer flags, ++such as if the consumer desire the line to be active low (inverted) or open ++drain. This is the recommended practice. + +-gpio-specifier may encode: bank, pin position inside the bank, +-whether pin is open-drain and whether pin is logically inverted. +-Exact meaning of each specifier cell is controller specific, and must +-be documented in the device tree binding for the device. Use the macros +-defined in include/dt-bindings/gpio/gpio.h whenever possible: ++The exact meaning of each specifier cell is controller specific, and must be ++documented in the device tree binding for the device, but it is strongly ++recommended to use the two-cell approach. ++ ++Most controllers are specifying a generic flag bitfield in the last cell, so ++for these, use the macros defined in ++include/dt-bindings/gpio/gpio.h whenever possible: + + Example of a node using GPIOs: + +@@ -65,6 +56,30 @@ Example of a node using GPIOs: + GPIO_ACTIVE_HIGH is 0, so in this example gpio-specifier is "18 0" and encodes + GPIO pin number, and GPIO flags as accepted by the "qe_pio_e" gpio-controller. + ++Optional standard bitfield specifiers for the last cell: ++ ++- Bit 0: 0 means active high, 1 means active low ++- Bit 1: 0 mean push-pull wiring, see: ++ https://en.wikipedia.org/wiki/Push-pull_output ++ 1 means single-ended wiring, see: ++ https://en.wikipedia.org/wiki/Single-ended_triode ++- Bit 2: 0 means open-source, 1 means open drain, see: ++ https://en.wikipedia.org/wiki/Open_collector ++- Bit 3: 0 means the output should be maintained during sleep/low-power mode ++ 1 means the output state can be lost during sleep/low-power mode ++- Bit 4: 0 means no pull-up resistor should be enabled ++ 1 means a pull-up resistor should be enabled ++ This setting only applies to hardware with a simple on/off ++ control for pull-up configuration. If the hardware has more ++ elaborate pull-up configuration, it should be represented ++ using a pin control binding. ++- Bit 5: 0 means no pull-down resistor should be enabled ++ 1 means a pull-down resistor should be enabled ++ This setting only applies to hardware with a simple on/off ++ control for pull-down configuration. If the hardware has more ++ elaborate pull-down configuration, it should be represented ++ using a pin control binding. ++ + 1.1) GPIO specifier best practices + ---------------------------------- + +@@ -116,6 +131,80 @@ Every GPIO controller node must contain both an empty "gpio-controller" + property, and a #gpio-cells integer property, which indicates the number of + cells in a gpio-specifier. + ++Some system-on-chips (SoCs) use the concept of GPIO banks. A GPIO bank is an ++instance of a hardware IP core on a silicon die, usually exposed to the ++programmer as a coherent range of I/O addresses. Usually each such bank is ++exposed in the device tree as an individual gpio-controller node, reflecting ++the fact that the hardware was synthesized by reusing the same IP block a ++few times over. ++ ++Optionally, a GPIO controller may have a "ngpios" property. This property ++indicates the number of in-use slots of available slots for GPIOs. The ++typical example is something like this: the hardware register is 32 bits ++wide, but only 18 of the bits have a physical counterpart. The driver is ++generally written so that all 32 bits can be used, but the IP block is reused ++in a lot of designs, some using all 32 bits, some using 18 and some using ++12. In this case, setting "ngpios = <18>;" informs the driver that only the ++first 18 GPIOs, at local offset 0 .. 17, are in use. ++ ++If these GPIOs do not happen to be the first N GPIOs at offset 0...N-1, an ++additional set of tuples is needed to specify which GPIOs are unusable, with ++the gpio-reserved-ranges binding. This property indicates the start and size ++of the GPIOs that can't be used. ++ ++Optionally, a GPIO controller may have a "gpio-line-names" property. This is ++an array of strings defining the names of the GPIO lines going out of the ++GPIO controller. This name should be the most meaningful producer name ++for the system, such as a rail name indicating the usage. Package names ++such as pin name are discouraged: such lines have opaque names (since they ++are by definition generic purpose) and such names are usually not very ++helpful. For example "MMC-CD", "Red LED Vdd" and "ethernet reset" are ++reasonable line names as they describe what the line is used for. "GPIO0" ++is not a good name to give to a GPIO line. Placeholders are discouraged: ++rather use the "" (blank string) if the use of the GPIO line is undefined ++in your design. The names are assigned starting from line offset 0 from ++left to right from the passed array. An incomplete array (where the number ++of passed named are less than ngpios) will still be used up until the last ++provided valid line index. ++ ++Example: ++ ++gpio-controller@00000000 { ++ compatible = "foo"; ++ reg = <0x00000000 0x1000>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ngpios = <18>; ++ gpio-reserved-ranges = <0 4>, <12 2>; ++ gpio-line-names = "MMC-CD", "MMC-WP", "VDD eth", "RST eth", "LED R", ++ "LED G", "LED B", "Col A", "Col B", "Col C", "Col D", ++ "Row A", "Row B", "Row C", "Row D", "NMI button", ++ "poweroff", "reset"; ++} ++ ++The GPIO chip may contain GPIO hog definitions. GPIO hogging is a mechanism ++providing automatic GPIO request and configuration as part of the ++gpio-controller's driver probe function. ++ ++Each GPIO hog definition is represented as a child node of the GPIO controller. ++Required properties: ++- gpio-hog: A property specifying that this child node represents a GPIO hog. ++- gpios: Store the GPIO information (id, flags, ...) for each GPIO to ++ affect. Shall contain an integer multiple of the number of cells ++ specified in its parent node (GPIO controller node). ++Only one of the following properties scanned in the order shown below. ++This means that when multiple properties are present they will be searched ++in the order presented below and the first match is taken as the intended ++configuration. ++- input: A property specifying to set the GPIO direction as input. ++- output-low A property specifying to set the GPIO direction as output with ++ the value low. ++- output-high A property specifying to set the GPIO direction as output with ++ the value high. ++ ++Optional properties: ++- line-name: The GPIO label name. If not present the node name is used. ++ + Example of two SOC GPIO banks defined as gpio-controller nodes: + + qe_pio_a: gpio-controller@1400 { +@@ -137,46 +226,40 @@ Example of two SOC GPIO banks defined as gpio-controller nodes: + + Some or all of the GPIOs provided by a GPIO controller may be routed to pins + on the package via a pin controller. This allows muxing those pins between +-GPIO and other functions. ++GPIO and other functions. It is a fairly common practice among silicon ++engineers. ++ ++2.2) Ordinary (numerical) GPIO ranges ++------------------------------------- + + It is useful to represent which GPIOs correspond to which pins on which pin +-controllers. The gpio-ranges property described below represents this, and +-contains information structures as follows: +- +- gpio-range-list ::= [gpio-range-list] +- single-gpio-range ::= | +- numeric-gpio-range ::= +- +- named-gpio-range ::= '<0 0>' +- pinctrl-phandle : phandle to pin controller node +- gpio-base : Base GPIO ID in the GPIO controller +- pinctrl-base : Base pinctrl pin ID in the pin controller +- count : The number of GPIOs/pins in this range +- +-The "pin controller node" mentioned above must conform to the bindings +-described in ../pinctrl/pinctrl-bindings.txt. +- +-In case named gpio ranges are used (ranges with both and +- set to 0), the property gpio-ranges-group-names contains one string +-for every single-gpio-range in gpio-ranges: +- gpiorange-names-list ::= [gpiorange-names-list] +- gpiorange-name : Name of the pingroup associated to the GPIO range in +- the respective pin controller. +- +-Elements of gpiorange-names-list corresponding to numeric ranges contain +-the empty string. Elements of gpiorange-names-list corresponding to named +-ranges contain the name of a pin group defined in the respective pin +-controller. The number of pins/GPIOs in the range is the number of pins in +-that pin group. ++controllers. The gpio-ranges property described below represents this with ++a discrete set of ranges mapping pins from the pin controller local number space ++to pins in the GPIO controller local number space. + +-Previous versions of this binding required all pin controller nodes that +-were referenced by any gpio-ranges property to contain a property named +-#gpio-range-cells with value <3>. This requirement is now deprecated. +-However, that property may still exist in older device trees for +-compatibility reasons, and would still be required even in new device +-trees that need to be compatible with older software. ++The format is: <[pin controller phandle], [GPIO controller offset], ++ [pin controller offset], [number of pins]>; ++ ++The GPIO controller offset pertains to the GPIO controller node containing the ++range definition. ++ ++The pin controller node referenced by the phandle must conform to the bindings ++described in pinctrl/pinctrl-bindings.txt. ++ ++Each offset runs from 0 to N. It is perfectly fine to pile any number of ++ranges with just one pin-to-GPIO line mapping if the ranges are concocted, but ++in practice these ranges are often lumped in discrete sets. ++ ++Example: ++ ++ gpio-ranges = <&foo 0 20 10>, <&bar 10 50 20>; ++ ++This means: ++- pins 20..29 on pin controller "foo" is mapped to GPIO line 0..9 and ++- pins 50..69 on pin controller "bar" is mapped to GPIO line 10..29 + +-Example 1: ++ ++Verbose example: + + qe_pio_e: gpio-controller@1460 { + #gpio-cells = <2>; +@@ -187,12 +270,33 @@ Example 1: + }; + + Here, a single GPIO controller has GPIOs 0..9 routed to pin controller +-pinctrl1's pins 20..29, and GPIOs 10..19 routed to pin controller pinctrl2's +-pins 50..59. ++pinctrl1's pins 20..29, and GPIOs 10..29 routed to pin controller pinctrl2's ++pins 50..69. ++ ++ ++2.3) GPIO ranges from named pin groups ++-------------------------------------- ++ ++It is also possible to use pin groups for gpio ranges when pin groups are the ++easiest and most convenient mapping. ++ ++Both both and must set to 0 when using named pin groups ++names. ++ ++The property gpio-ranges-group-names must contain exactly one string for each ++range. ++ ++Elements of gpio-ranges-group-names must contain the name of a pin group ++defined in the respective pin controller. The number of pins/GPIO lines in the ++range is the number of pins in that pin group. The number of pins of that ++group is defined int the implementation and not in the device tree. + +-Example 2: ++If numerical and named pin groups are mixed, the string corresponding to a ++numerical pin range in gpio-ranges-group-names must be empty. + +- gpio_pio_i: gpio-controller@14B0 { ++Example: ++ ++ gpio_pio_i: gpio-controller@14b0 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; + reg = <0x1480 0x18>; +@@ -207,66 +311,14 @@ Example 2: + "bar"; + }; + +-Here, three GPIO ranges are defined wrt. two pin controllers. pinctrl1 GPIO +-ranges are defined using pin numbers whereas the GPIO ranges wrt. pinctrl2 +-are named "foo" and "bar". +- +-3) GPIO hog definitions +------------------------ +- +-The GPIO chip may contain GPIO hog definitions. GPIO hogging is a mechanism +-providing automatic GPIO request and configuration as part of the +-gpio-controller's driver probe function. ++Here, three GPIO ranges are defined referring to two pin controllers. + +-Each GPIO hog definition is represented as a child node of the GPIO controller. +-Required properties: +-- gpio-hog: A property specifying that this child node represents a GPIO hog. +-- gpios: Store the GPIO information (id, flags) for the GPIO to +- affect. ++pinctrl1 GPIO ranges are defined using pin numbers whereas the GPIO ranges ++in pinctrl2 are defined using the pin groups named "foo" and "bar". + +- ! Not yet support more than one gpio ! +- +-Only one of the following properties scanned in the order shown below. +-- input: A property specifying to set the GPIO direction as input. +-- output-low A property specifying to set the GPIO direction as output with +- the value low. +-- output-high A property specifying to set the GPIO direction as output with +- the value high. +- +-Optional properties: +-- line-name: The GPIO label name. If not present the node name is used. +- +-Example: +- +- tca6416@20 { +- compatible = "ti,tca6416"; +- reg = <0x20>; +- #gpio-cells = <2>; +- gpio-controller; +- +- env_reset { +- gpio-hog; +- input; +- gpios = <6 GPIO_ACTIVE_LOW>; +- }; +- boot_rescue { +- gpio-hog; +- input; +- line-name = "foo-bar-gpio"; +- gpios = <7 GPIO_ACTIVE_LOW>; +- }; +- }; +- +-For the above Example you can than access the gpio in your boardcode +-with: +- +- struct gpio_desc *desc; +- int ret; +- +- ret = gpio_hog_lookup_name("boot_rescue", &desc); +- if (ret) +- return; +- if (dm_gpio_get_value(desc) == 1) +- printf("\nBooting into Rescue System\n"); +- else if (dm_gpio_get_value(desc) == 0) +- printf("\nBoot normal\n"); ++Previous versions of this binding required all pin controller nodes that ++were referenced by any gpio-ranges property to contain a property named ++#gpio-range-cells with value <3>. This requirement is now deprecated. ++However, that property may still exist in older device trees for ++compatibility reasons, and would still be required even in new device ++trees that need to be compatible with older software. +diff --git a/doc/device-tree-bindings/i2c/i2c-stm32.txt b/doc/device-tree-bindings/i2c/i2c-stm32.txt +index df03743..7f7686e 100644 +--- a/doc/device-tree-bindings/i2c/i2c-stm32.txt ++++ b/doc/device-tree-bindings/i2c/i2c-stm32.txt +@@ -1,30 +1,109 @@ +-* I2C controller embedded in STMicroelectronis STM32 platforms ++* I2C controller embedded in STMicroelectronics STM32 I2C platform + + Required properties : +-- compatible : Must be "st,stm32f7-i2c" ++- compatible : Must be one of the following ++ - "st,stm32f4-i2c" ++ - "st,stm32f7-i2c" + - reg : Offset and length of the register set for the device +-- resets: Must contain the phandle to the reset controller +-- clocks: Must contain the input clock of the I2C instance ++- interrupts : Must contain the interrupt id for I2C event and then the ++ interrupt id for I2C error. ++ Optionnaly a wakeup interrupt may be specified. ++- resets: Must contain the phandle to the reset controller. ++- clocks: Must contain the input clock of the I2C instance. + - A pinctrl state named "default" must be defined to set pins in mode of +- operation for I2C transfer ++ operation for I2C transfer. An optional pinctrl state named "sleep" has to ++ be defined as well as to put I2C in low power mode in suspend mode. + - #address-cells = <1>; + - #size-cells = <0>; + + Optional properties : + - clock-frequency : Desired I2C bus clock frequency in Hz. If not specified, +- the default 100 kHz frequency will be used. As only Normal, Fast and Fast+ +- modes are implemented, possible values are 100000, 400000 and 1000000. ++ the default 100 kHz frequency will be used. ++ For STM32F4 SoC Standard-mode and Fast-mode are supported, possible values are ++ 100000 and 400000. ++ For STM32F7, STM32H7 and STM32MP1 SoCs, Standard-mode, Fast-mode and Fast-mode ++ Plus are supported, possible values are 100000, 400000 and 1000000. ++- i2c-scl-rising-time-ns: I2C SCL Rising time for the board (default: 25) ++ For STM32F7, STM32H7 and STM32MP1 only. ++- i2c-scl-falling-time-ns: I2C SCL Falling time for the board (default: 10) ++ For STM32F7, STM32H7 and STM32MP1 only. ++ I2C Timings are derived from these 2 values ++- st,syscfg-fmp: Use to set Fast Mode Plus bit within SYSCFG when Fast Mode ++ Plus speed is selected by slave. ++ 1st cell : phandle to syscfg ++ 2nd cell : register offset within SYSCFG ++ 3rd cell : register bitmask for FMP bit ++ For STM32F7, STM32H7 and STM32MP1 only. ++- st,syscfg-fmp-clr: Use to clear Fast Mode Plus bit within SYSCFG when Fast ++ Mode Plus speed is selected by slave. ++ 1st cell: phandle to syscfg ++ 2nd cell: clear register offset within SYSCFG ++ 3rd cell: register bitmask for FMP clear bit ++ For STM32MP1 family only. + + Example : + +- i2c1: i2c@40005400 { +- compatible = "st,stm32f7-i2c"; ++ i2c@40005400 { ++ compatible = "st,stm32f4-i2c"; ++ #address-cells = <1>; ++ #size-cells = <0>; + reg = <0x40005400 0x400>; +- resets = <&rcc 181>; +- clocks = <&clk_pclk1>; ++ interrupts = <31>, ++ <32>; ++ resets = <&rcc 277>; ++ clocks = <&rcc 0 149>; ++ pinctrl-0 = <&i2c1_sda_pin>, <&i2c1_scl_pin>; + pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_i2c1>; +- clock-frequency = <400000>; ++ }; ++ ++ i2c@40005400 { ++ compatible = "st,stm32f7-i2c"; + #address-cells = <1>; + #size-cells = <0>; ++ reg = <0x40005400 0x400>; ++ interrupts = <31>, ++ <32>; ++ resets = <&rcc STM32F7_APB1_RESET(I2C1)>; ++ clocks = <&rcc 1 CLK_I2C1>; ++ pinctrl-0 = <&i2c1_sda_pin>, <&i2c1_scl_pin>; ++ pinctrl-1 = <&i2c1_sda_pin_sleep>, <&i2c1_scl_pin_sleep>; ++ pinctrl-names = "default", "sleep"; ++ st,syscfg-fmp = <&syscfg 0x4 0x1>; ++ st,syscfg-fmp-clr = <&syscfg 0x44 0x1>; ++ }; ++ ++ i2c@40013000 { ++ compatible = "st,stm32f7-i2c"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x40013000 0x400>; ++ interrupt-names = "event", "error", "wakeup"; ++ interrupts-extended = <&intc GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>, ++ <&intc GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>, ++ <&exti 22 1>; ++ clocks = <&rcc I2C2_K>; ++ resets = <&rcc I2C2_R>; ++ st,syscfg-fmp = <&syscfg 0x4 0x2>; ++ st,syscfg-fmp-clr = <&syscfg 0x44 0x2>; ++ }; ++ ++ ++* I2C Devices ++ ++An I2C device connected onto STM32 I2C controller must use a format described by ++i2c.txt file. ++ ++Required properties : ++- compatible ++ Device driver compatible name ++- reg ++ I2C slave addresses (see i2c.txt for more details) ++ ++Optional properties : ++ ++ i2c@40013000 { ++ camera@3c { ++ compatible = "ovti,ov5640"; ++ reg = <0x3c>; ++ }; + }; +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 ee708ce..ac6a7df 100644 +--- a/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt ++++ b/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt +@@ -129,6 +129,8 @@ phyc attributes: + 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 + DX0DLLCR + DX0DQTR +diff --git a/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt b/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt +index 70e76be..ad2bef8 100644 +--- a/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt ++++ b/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt +@@ -18,8 +18,10 @@ Optional properties: + - dmas: DMA specifiers (see: dma/stm32-mdma.txt) + - dma-names: Must be "tx", "rx" and "ecc" + +-Optional children nodes: +-Children nodes represent the available NAND chips. ++* NAND device bindings: ++ ++Required properties: ++- reg: describes the CS lines assigned to the NAND device. + + Optional properties: + - nand-on-flash-bbt: see nand.txt +diff --git a/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt b/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt +index da98407..156229b 100644 +--- a/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt ++++ b/doc/device-tree-bindings/phy/phy-stm32-usbphyc.txt +@@ -27,6 +27,7 @@ Required properties: + - vdda1v8-supply: phandle to the regulator providing 1V8 power to the PHY + - #address-cells: number of address cells for phys sub-nodes, must be <1> + - #size-cells: number of size cells for phys sub-nodes, must be <0> ++- #clock-cells: number of clock cells for ck_usbo_48m consumer, must be <0> + + Optional properties: + - assigned-clocks: phandle + clock specifier for the PLL phy clock +@@ -36,7 +37,7 @@ Optional properties: + Required nodes: one sub-node per port the controller provides. + + Phy sub-nodes +-============== ++============= + + Required properties: + - reg: phy port index +@@ -45,29 +46,73 @@ 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: ++- st,phy-tuning : phandle to the usb phy tuning node, see Phy tuning node below ++ ++Phy tuning node ++=============== ++ ++It may be necessary to adjust the phy settings to compensate parasitics, which ++can be due to USB connector/receptacle, routing, ESD protection component, ... ++ ++Here is the list of all optional parameters to tune the interface of the phy ++(HS for High-Speed, FS for Full-Speed, LS for Low-Speed) ++ ++Optional properties: ++- st,current-boost: <1> current boosting of 1mA ++ <2> current boosting of 2mA ++- st,no-lsfs-fb-cap: disables the LS/FS feedback capacitor ++- st,hs-slew-ctrl: slows the HS driver slew rate by 10% ++- st,hs-dc-level: <0> decreases the HS driver DC level by 5 to 7mV ++ <1> increases the HS driver DC level by 5 to 7mV ++ <2> increases the HS driver DC level by 10 to 14mV ++- st,fs-rftime-tuning: enables the FS rise/fall tuning option ++- st,hs-rftime-reduction: enables the HS rise/fall reduction feature ++- st,hs-current-trim: controls HS driver current trimming for choke ++- st,hs-impedance-trim: controls HS driver impedance tuning for choke ++- st,squelch-level: adjusts the squelch DC threshold value ++- st,hs-rx-gain-eq: enables the HS Rx gain equalizer ++- st,hs-rx-offset: adjusts the HS Rx offset ++- st,no-hs-ftime-ctrl: disables the HS fall time control of single ++ ended signals during pre-emphasis ++- st,no-lsfs-sc: disables the short circuit protection in LS/FS driver ++- st,hs-tx-staggering: enables the basic staggering in HS Tx mode ++ + + Example: ++ usb_phy_tuning: usb-phy-tuning { ++ st,current-boost = <2>; ++ st,no-lfs-fb-cap; ++ st,hs-dc-level = <2>; ++ st,hs-rftime-reduction; ++ st,hs-current-trim = <5>; ++ st,hs-impedance-trim = <0>; ++ st,squelch-level = <1>; ++ st,no-hs-ftime-ctrl; ++ st,hs-tx-staggering; ++ }; ++ + usbphyc: usb-phy@5a006000 { + compatible = "st,stm32mp1-usbphyc"; + reg = <0x5a006000 0x1000>; + clocks = <&rcc_clk USBPHY_K>; + resets = <&rcc_rst USBPHY_R>; ++ vdda1v1-supply = <®11>; ++ vdda1v8-supply = <®18>; + #address-cells = <1>; + #size-cells = <0>; ++ #clock-cells = <0>; + + usbphyc_port0: usb-phy@0 { + reg = <0>; + phy-supply = <&vdd_usb>; +- vdda1v1-supply = <®11>; +- vdda1v8-supply = <®18> + #phy-cells = <0>; + }; + + usbphyc_port1: usb-phy@1 { + reg = <1>; + phy-supply = <&vdd_usb>; +- vdda1v1-supply = <®11>; +- vdda1v8-supply = <®18> + #phy-cells = <1>; ++ st,phy-tuning = <&usb_phy_tuning>; + }; + }; +diff --git a/drivers/ata/dwc_ahci.c b/drivers/ata/dwc_ahci.c +index 017650a..3c2a3ac 100644 +--- a/drivers/ata/dwc_ahci.c ++++ b/drivers/ata/dwc_ahci.c +@@ -62,13 +62,13 @@ static int dwc_ahci_probe(struct udevice *dev) + + ret = generic_phy_init(&phy); + if (ret) { +- pr_err("unable to initialize the sata phy\n"); ++ pr_debug("unable to initialize the sata phy\n"); + return ret; + } + + ret = generic_phy_power_on(&phy); + if (ret) { +- pr_err("unable to power on the sata phy\n"); ++ pr_debug("unable to power on the sata phy\n"); + return ret; + } + +diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig +index 16d4237..322f02a 100644 +--- a/drivers/clk/Kconfig ++++ b/drivers/clk/Kconfig +@@ -141,6 +141,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" ++ select SCMI_AGENT ++ 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 06131ed..b732852 100644 +--- a/drivers/clk/Makefile ++++ b/drivers/clk/Makefile +@@ -29,6 +29,7 @@ obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o + obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.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 0000000..f24b8b0 +--- /dev/null ++++ b/drivers/clk/clk_scmi.c +@@ -0,0 +1,152 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2019 Linaro Limited ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++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 { ++ u32 clock_id; ++ u32 attributes; ++}; ++ ++struct scmi_clk_state_out { ++ s32 status; ++}; ++ ++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 scmi_msg = { ++ .protocol_id = SCMI_PROTOCOL_ID_CLOCK, ++ .message_id = SCMI_CLOCK_CONFIG_SET, ++ .in_msg = (u8 *)&in, ++ .in_msg_sz = sizeof(in), ++ .out_msg = (u8 *)&out, ++ .out_msg_sz = sizeof(out), ++ }; ++ int rc; ++ ++ rc = scmi_agent_process_msg(clk->dev->parent, &scmi_msg); ++ if (rc) ++ return rc; ++ ++ 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); ++} ++ ++struct scmi_clk_rate_get_in { ++ u32 clock_id; ++}; ++ ++struct scmi_clk_rate_get_out { ++ s32 status; ++ u32 rate_lsb; ++ u32 rate_msb; ++}; ++ ++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 scmi_msg = { ++ .protocol_id = SCMI_PROTOCOL_ID_CLOCK, ++ .message_id = SCMI_CLOCK_RATE_GET, ++ .in_msg = (u8 *)&in, ++ .in_msg_sz = sizeof(in), ++ .out_msg = (u8 *)&out, ++ .out_msg_sz = sizeof(out), ++ }; ++ int rc; ++ ++ rc = scmi_agent_process_msg(clk->dev->parent, &scmi_msg); ++ if (rc) ++ return 0; ++ ++ rc = scmi_to_linux_errno(out.status); ++ if (rc) ++ return 0; ++ ++ return (ulong)(((u64)out.rate_msb << 32) | out.rate_lsb); ++} ++ ++struct scmi_clk_rate_set_in { ++ u32 clock_id; ++ u32 flags; ++ u32 rate_lsb; ++ u32 rate_msb; ++}; ++ ++struct scmi_clk_rate_set_out { ++ s32 status; ++}; ++ ++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_ASYNC_NORESP | ++ 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 scmi_msg = { ++ .protocol_id = SCMI_PROTOCOL_ID_CLOCK, ++ .message_id = SCMI_CLOCK_RATE_SET, ++ .in_msg = (u8 *)&in, ++ .in_msg_sz = sizeof(in), ++ .out_msg = (u8 *)&out, ++ .out_msg_sz = sizeof(out), ++ }; ++ int rc; ++ ++ rc = scmi_agent_process_msg(clk->dev->parent, &scmi_msg); ++ if (rc) ++ return 0; ++ ++ return scmi_to_linux_errno(out.status); ++} ++ ++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 3718970..76fddcc 100644 +--- a/drivers/clk/clk_stm32mp1.c ++++ b/drivers/clk/clk_stm32mp1.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -95,6 +96,7 @@ DECLARE_GLOBAL_DATA_PTR; + #define RCC_I2C12CKSELR 0x8C0 + #define RCC_I2C35CKSELR 0x8C4 + #define RCC_SPI2S1CKSELR 0x8D8 ++#define RCC_SPI45CKSELR 0x8E0 + #define RCC_UART6CKSELR 0x8E4 + #define RCC_UART24CKSELR 0x8E8 + #define RCC_UART35CKSELR 0x8EC +@@ -241,7 +243,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, +@@ -304,6 +306,7 @@ enum stm32mp1_parent_sel { + _DSI_SEL, + _ADC12_SEL, + _SPI1_SEL, ++ _SPI45_SEL, + _RTC_SEL, + _PARENT_SEL_NB, + _UNKNOWN_SEL = 0xff, +@@ -420,8 +423,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) \ +@@ -527,6 +529,7 @@ 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, 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), +@@ -602,6 +605,8 @@ static const u8 dsi_parents[] = {_DSI_PHY, _PLL4_P}; + static const u8 adc_parents[] = {_PLL4_R, _CK_PER, _PLL3_Q}; + 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 rtc_parents[] = {_UNKNOWN_ID, _LSE, _LSI, _HSE}; + + static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { +@@ -620,22 +625,33 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { + STM32MP1_CLK_PARENT(_SDMMC3_SEL, RCC_SDMMC3CKSELR, 0, 0x7, + sdmmc3_parents), + STM32MP1_CLK_PARENT(_ETH_SEL, RCC_ETHCKSELR, 0, 0x3, eth_parents), +- STM32MP1_CLK_PARENT(_QSPI_SEL, RCC_QSPICKSELR, 0, 0xf, qspi_parents), +- STM32MP1_CLK_PARENT(_FMC_SEL, RCC_FMCCKSELR, 0, 0xf, fmc_parents), ++ STM32MP1_CLK_PARENT(_QSPI_SEL, RCC_QSPICKSELR, 0, 0x3, qspi_parents), ++ STM32MP1_CLK_PARENT(_FMC_SEL, RCC_FMCCKSELR, 0, 0x3, fmc_parents), + STM32MP1_CLK_PARENT(_USBPHY_SEL, RCC_USBCKSELR, 0, 0x3, usbphy_parents), + STM32MP1_CLK_PARENT(_USBO_SEL, RCC_USBCKSELR, 4, 0x1, usbo_parents), + STM32MP1_CLK_PARENT(_STGEN_SEL, RCC_STGENCKSELR, 0, 0x3, stgen_parents), + STM32MP1_CLK_PARENT(_DSI_SEL, RCC_DSICKSELR, 0, 0x1, dsi_parents), +- STM32MP1_CLK_PARENT(_ADC12_SEL, RCC_ADCCKSELR, 0, 0x1, adc_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(_SPI45_SEL, RCC_SPI45CKSELR, 0, 0x7, spi45_parents), + STM32MP1_CLK_PARENT(_RTC_SEL, RCC_BDCR, RCC_BDCR_RTCSRC_SHIFT, + (RCC_BDCR_RTCSRC_MASK >> RCC_BDCR_RTCSRC_SHIFT), + rtc_parents), + }; + + #ifdef STM32MP1_CLOCK_TREE_INIT ++ + /* define characteristic of PLL according type */ ++#define DIVM_MIN 0 ++#define DIVM_MAX 63 + #define DIVN_MIN 24 ++#define DIVP_MIN 0 ++#define DIVP_MAX 127 ++#define FRAC_MAX 8192 ++ ++#define PLL1600_VCO_MIN 800000000 ++#define PLL1600_VCO_MAX 1600000000 ++ + static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = { + [PLL_800] = { + .refclk_min = 4, +@@ -746,6 +762,7 @@ char * const stm32mp1_clk_parent_sel_name[_PARENT_SEL_NB] = { + [_DSI_SEL] = "DSI", + [_ADC12_SEL] = "ADC12", + [_SPI1_SEL] = "SPI1", ++ [_SPI45_SEL] = "SPI45", + [_RTC_SEL] = "RTC", + }; + +@@ -763,7 +780,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) +@@ -946,10 +963,11 @@ static ulong stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p) + case RCC_MPCKSELR_PLL: + case RCC_MPCKSELR_PLL_MPUDIV: + clock = stm32mp1_read_pll_freq(priv, _PLL1, _DIV_P); +- if (p == RCC_MPCKSELR_PLL_MPUDIV) { ++ if ((reg & RCC_SELR_SRC_MASK) == ++ RCC_MPCKSELR_PLL_MPUDIV) { + reg = readl(priv->base + RCC_MPCKDIVR); +- clock /= stm32mp1_mpu_div[reg & +- RCC_MPUDIV_MASK]; ++ clock >>= stm32mp1_mpu_div[reg & ++ RCC_MPUDIV_MASK]; + } + break; + } +@@ -1178,6 +1196,213 @@ static ulong stm32mp1_clk_get_rate(struct clk *clk) + } + + #ifdef STM32MP1_CLOCK_TREE_INIT ++ ++bool stm32mp1_supports_opp(u32 opp_id, u32 cpu_type) ++{ ++ unsigned int id; ++ ++ switch (opp_id) { ++ case 1: ++ case 2: ++ id = opp_id; ++ break; ++ default: ++ id = 1; /* default value */ ++ break; ++ } ++ ++ switch (cpu_type) { ++ case CPU_STM32MP157Fxx: ++ case CPU_STM32MP157Dxx: ++ case CPU_STM32MP153Fxx: ++ case CPU_STM32MP153Dxx: ++ case CPU_STM32MP151Fxx: ++ case CPU_STM32MP151Dxx: ++ return true; ++ default: ++ return id == 1; ++ } ++} ++ ++__weak void board_vddcore_init(u32 voltage_mv) ++{ ++} ++ ++/* ++ * gets OPP parameters (frequency in KHz and voltage in mV) from ++ * an OPP table subnode. Platform HW support capabilities are also checked. ++ * Returns 0 on success and a negative FDT error code on failure. ++ */ ++static int stm32mp1_get_opp(u32 cpu_type, ofnode subnode, ++ u32 *freq_khz, u32 *voltage_mv) ++{ ++ u32 opp_hw; ++ u64 read_freq_64; ++ u32 read_voltage_32; ++ ++ *freq_khz = 0; ++ *voltage_mv = 0; ++ ++ opp_hw = ofnode_read_u32_default(subnode, "opp-supported-hw", 0); ++ if (opp_hw) ++ if (!stm32mp1_supports_opp(opp_hw, cpu_type)) ++ return -FDT_ERR_BADVALUE; ++ ++ read_freq_64 = ofnode_read_u64_default(subnode, "opp-hz", 0) / ++ 1000ULL; ++ read_voltage_32 = ofnode_read_u32_default(subnode, "opp-microvolt", 0) / ++ 1000U; ++ ++ if (!read_voltage_32 || !read_freq_64) ++ return -FDT_ERR_NOTFOUND; ++ ++ /* Frequency value expressed in KHz must fit on 32 bits */ ++ if (read_freq_64 > U32_MAX) ++ return -FDT_ERR_BADVALUE; ++ ++ /* Millivolt value must fit on 16 bits */ ++ if (read_voltage_32 > U16_MAX) ++ return -FDT_ERR_BADVALUE; ++ ++ *freq_khz = (u32)read_freq_64; ++ *voltage_mv = read_voltage_32; ++ ++ return 0; ++} ++ ++/* ++ * parses OPP table in DT and finds the parameters for the ++ * highest frequency supported by the HW platform. ++ * Returns 0 on success and a negative FDT error code on failure. ++ */ ++int stm32mp1_get_max_opp_freq(struct stm32mp1_clk_priv *priv, u64 *freq_hz) ++{ ++ ofnode node, subnode; ++ int ret; ++ u32 freq = 0U, voltage = 0U; ++ u32 cpu_type = get_cpu_type(); ++ ++ node = ofnode_by_compatible(ofnode_null(), "operating-points-v2"); ++ if (!ofnode_valid(node)) ++ return -FDT_ERR_NOTFOUND; ++ ++ ofnode_for_each_subnode(subnode, node) { ++ unsigned int read_freq; ++ unsigned int read_voltage; ++ ++ ret = stm32mp1_get_opp(cpu_type, subnode, ++ &read_freq, &read_voltage); ++ if (ret) ++ continue; ++ ++ if (read_freq > freq) { ++ freq = read_freq; ++ voltage = read_voltage; ++ } ++ } ++ ++ if (!freq || !voltage) ++ return -FDT_ERR_NOTFOUND; ++ ++ *freq_hz = (u64)1000U * freq; ++ board_vddcore_init(voltage); ++ ++ return 0; ++} ++ ++static int stm32mp1_pll1_opp(struct stm32mp1_clk_priv *priv, int clksrc, ++ u32 *pllcfg, u32 *fracv) ++{ ++ u32 post_divm; ++ u32 input_freq; ++ u64 output_freq; ++ u64 freq; ++ u64 vco; ++ u32 divm, divn, divp, frac; ++ int i, ret; ++ u32 diff; ++ u32 best_diff = U32_MAX; ++ ++ /* PLL1 is 1600 */ ++ const u32 DIVN_MAX = stm32mp1_pll[PLL_1600].divn_max; ++ const u32 POST_DIVM_MIN = stm32mp1_pll[PLL_1600].refclk_min * 1000000U; ++ const u32 POST_DIVM_MAX = stm32mp1_pll[PLL_1600].refclk_max * 1000000U; ++ ++ ret = stm32mp1_get_max_opp_freq(priv, &output_freq); ++ if (ret) { ++ debug("PLL1 OPP configuraton not found (%d).\n", ret); ++ return ret; ++ } ++ ++ switch (clksrc) { ++ case CLK_PLL12_HSI: ++ input_freq = stm32mp1_clk_get_fixed(priv, _HSI); ++ break; ++ case CLK_PLL12_HSE: ++ input_freq = stm32mp1_clk_get_fixed(priv, _HSE); ++ break; ++ default: ++ return -EINTR; ++ } ++ ++ /* Following parameters have always the same value */ ++ pllcfg[PLLCFG_Q] = 0; ++ pllcfg[PLLCFG_R] = 0; ++ pllcfg[PLLCFG_O] = PQR(1, 0, 0); ++ ++ for (divm = DIVM_MAX; divm >= DIVM_MIN; divm--) { ++ post_divm = (u32)(input_freq / (divm + 1)); ++ if (post_divm < POST_DIVM_MIN || post_divm > POST_DIVM_MAX) ++ continue; ++ ++ for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) { ++ freq = output_freq * (divm + 1) * (divp + 1); ++ divn = (u32)((freq / input_freq) - 1); ++ if (divn < DIVN_MIN || divn > DIVN_MAX) ++ continue; ++ ++ frac = (u32)(((freq * FRAC_MAX) / input_freq) - ++ ((divn + 1) * FRAC_MAX)); ++ /* 2 loops to refine the fractional part */ ++ for (i = 2; i != 0; i--) { ++ if (frac > FRAC_MAX) ++ break; ++ ++ vco = (post_divm * (divn + 1)) + ++ ((post_divm * (u64)frac) / ++ FRAC_MAX); ++ if (vco < (PLL1600_VCO_MIN / 2) || ++ vco > (PLL1600_VCO_MAX / 2)) { ++ frac++; ++ continue; ++ } ++ freq = vco / (divp + 1); ++ if (output_freq < freq) ++ diff = (u32)(freq - output_freq); ++ else ++ diff = (u32)(output_freq - freq); ++ if (diff < best_diff) { ++ pllcfg[PLLCFG_M] = divm; ++ pllcfg[PLLCFG_N] = divn; ++ pllcfg[PLLCFG_P] = divp; ++ *fracv = frac; ++ ++ if (diff == 0) ++ return 0; ++ ++ best_diff = diff; ++ } ++ frac++; ++ } ++ } ++ } ++ ++ if (best_diff == U32_MAX) ++ return -1; ++ ++ return 0; ++} ++ + static void stm32mp1_ls_osc_set(int enable, fdt_addr_t rcc, u32 offset, + u32 mask_on) + { +@@ -1217,7 +1442,7 @@ static int stm32mp1_osc_wait(int enable, fdt_addr_t rcc, u32 offset, + } + + static void stm32mp1_lse_enable(fdt_addr_t rcc, int bypass, int digbyp, +- int lsedrv) ++ u32 lsedrv) + { + u32 value; + +@@ -1316,7 +1541,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; + } + +@@ -1649,7 +1874,10 @@ static int stm32mp1_clktree(struct udevice *dev) + unsigned int clksrc[CLKSRC_NB]; + unsigned int clkdiv[CLKDIV_NB]; + unsigned int pllcfg[_PLL_NB][PLLCFG_NB]; +- ofnode plloff[_PLL_NB]; ++ unsigned int pllfracv[_PLL_NB]; ++ unsigned int pllcsg[_PLL_NB][PLLCSG_NB]; ++ bool pllcfg_valid[_PLL_NB]; ++ bool pllcsg_set[_PLL_NB]; + int ret; + int i, len; + int lse_css = 0; +@@ -1671,16 +1899,43 @@ static int stm32mp1_clktree(struct udevice *dev) + /* check mandatory field in each pll */ + for (i = 0; i < _PLL_NB; i++) { + char name[12]; ++ ofnode node; + + sprintf(name, "st,pll@%d", i); +- plloff[i] = dev_read_subnode(dev, name); +- if (!ofnode_valid(plloff[i])) +- continue; +- ret = ofnode_read_u32_array(plloff[i], "cfg", +- pllcfg[i], PLLCFG_NB); +- if (ret < 0) { +- debug("field cfg invalid: error %d\n", ret); +- return -FDT_ERR_NOTFOUND; ++ node = dev_read_subnode(dev, name); ++ pllcfg_valid[i] = ofnode_valid(node); ++ pllcsg_set[i] = false; ++ if (pllcfg_valid[i]) { ++ debug("DT for PLL %d @ %s\n", i, name); ++ ret = ofnode_read_u32_array(node, "cfg", ++ pllcfg[i], PLLCFG_NB); ++ if (ret < 0) { ++ debug("field cfg invalid: error %d\n", ret); ++ return -FDT_ERR_NOTFOUND; ++ } ++ pllfracv[i] = ofnode_read_u32_default(node, "frac", 0); ++ ++ ret = ofnode_read_u32_array(node, "csg", pllcsg[i], ++ PLLCSG_NB); ++ if (!ret) { ++ pllcsg_set[i] = true; ++ } else if (ret != -FDT_ERR_NOTFOUND) { ++ debug("invalid csg node for pll@%d res=%d\n", ++ i, ret); ++ return ret; ++ } ++ } else if (i == _PLL1) { ++ /* use OPP for PLL1 for A7 CPU */ ++ debug("DT for PLL %d with OPP\n", i); ++ ret = stm32mp1_pll1_opp(priv, ++ clksrc[CLKSRC_PLL12], ++ pllcfg[i], ++ &pllfracv[i]); ++ if (ret) { ++ debug("PLL %d with OPP error = %d\n", i, ret); ++ return ret; ++ } ++ pllcfg_valid[i] = true; + } + } + +@@ -1693,12 +1948,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]) { +- int bypass, digbyp, lsedrv; +- struct udevice *dev = priv->osc_dev[_LSE]; ++ if (clk_valid(&priv->osc_clk[_LSE])) { ++ int bypass, digbyp; ++ u32 lsedrv; ++ struct udevice *dev = priv->osc_clk[_LSE].dev; + + bypass = dev_read_bool(dev, "st,bypass"); + digbyp = dev_read_bool(dev, "st,digbypass"); +@@ -1709,9 +1965,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"); +@@ -1736,8 +1992,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); + } + +@@ -1765,36 +2021,25 @@ static int stm32mp1_clktree(struct udevice *dev) + /* configure and start PLLs */ + debug("configure PLLs\n"); + for (i = 0; i < _PLL_NB; i++) { +- u32 fracv; +- u32 csg[PLLCSG_NB]; +- +- debug("configure PLL %d @ %d\n", i, +- ofnode_to_offset(plloff[i])); +- if (!ofnode_valid(plloff[i])) ++ if (!pllcfg_valid[i]) + continue; +- +- fracv = ofnode_read_u32_default(plloff[i], "frac", 0); +- pll_config(priv, i, pllcfg[i], fracv); +- ret = ofnode_read_u32_array(plloff[i], "csg", csg, PLLCSG_NB); +- if (!ret) { +- pll_csg(priv, i, csg); +- } else if (ret != -FDT_ERR_NOTFOUND) { +- debug("invalid csg node for pll@%d res=%d\n", i, ret); +- return ret; +- } ++ debug("configure PLL %d\n", i); ++ pll_config(priv, i, pllcfg[i], pllfracv[i]); ++ if (pllcsg_set[i]) ++ pll_csg(priv, i, pllcsg[i]); + pll_start(priv, i); + } + + /* wait and start PLLs ouptut when ready */ + for (i = 0; i < _PLL_NB; i++) { +- if (!ofnode_valid(plloff[i])) ++ if (!pllcfg_valid[i]) + continue; + debug("output PLL %d\n", i); + pll_output(priv, i, pllcfg[i][PLLCFG_O]); + } + + /* 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 */ +@@ -1833,7 +2078,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 */ +@@ -1931,40 +2176,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])); + } + } + +@@ -2037,6 +2267,8 @@ static int stm32mp1_clk_probe(struct udevice *dev) + /* clock tree init is done only one time, before relocation */ + if (!(gd->flags & GD_FLG_RELOC)) + result = stm32mp1_clktree(dev); ++ if (result) ++ printf("clock tree initialization failed (%d)\n", result); + #endif + + #ifndef CONFIG_SPL_BUILD +diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c +index 945b814..86fe42a 100644 +--- a/drivers/core/of_access.c ++++ b/drivers/core/of_access.c +@@ -170,6 +170,38 @@ const void *of_get_property(const struct device_node *np, const char *name, + return pp ? pp->value : NULL; + } + ++const struct property *of_get_first_property(const struct device_node *np) ++{ ++ if (!np) ++ return NULL; ++ ++ return np->properties; ++} ++ ++const struct property *of_get_next_property(const struct device_node *np, ++ const struct property *property) ++{ ++ if (!np) ++ return NULL; ++ ++ return property->next; ++} ++ ++const void *of_get_property_by_prop(const struct device_node *np, ++ const struct property *property, ++ const char **name, ++ int *lenp) ++{ ++ if (!np || !property) ++ return NULL; ++ if (name) ++ *name = property->name; ++ if (lenp) ++ *lenp = property->length; ++ ++ return property->value; ++} ++ + static const char *of_prop_next_string(struct property *prop, const char *cur) + { + const void *curv = cur; +diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c +index 8f0eab2..cb27562 100644 +--- a/drivers/core/ofnode.c ++++ b/drivers/core/ofnode.c +@@ -536,6 +536,54 @@ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp) + propname, lenp); + } + ++int ofnode_get_first_property(ofnode node, struct ofprop *prop) ++{ ++ prop->node = node; ++ ++ if (ofnode_is_np(node)) { ++ prop->prop = of_get_first_property(ofnode_to_np(prop->node)); ++ if (!prop->prop) ++ return -FDT_ERR_NOTFOUND; ++ } else { ++ prop->offset = ++ fdt_first_property_offset(gd->fdt_blob, ++ ofnode_to_offset(prop->node)); ++ if (prop->offset < 0) ++ return prop->offset; ++ } ++ ++ return 0; ++} ++ ++int ofnode_get_next_property(struct ofprop *prop) ++{ ++ if (ofnode_is_np(prop->node)) { ++ prop->prop = of_get_next_property(ofnode_to_np(prop->node), ++ prop->prop); ++ if (!prop->prop) ++ return -FDT_ERR_NOTFOUND; ++ } else { ++ prop->offset = fdt_next_property_offset(gd->fdt_blob, ++ prop->offset); ++ if (prop->offset < 0) ++ return prop->offset; ++ } ++ ++ return 0; ++} ++ ++const void *ofnode_get_property_by_prop(const struct ofprop *prop, ++ const char **propname, int *lenp) ++{ ++ if (ofnode_is_np(prop->node)) ++ return of_get_property_by_prop(ofnode_to_np(prop->node), ++ prop->prop, propname, lenp); ++ else ++ return fdt_getprop_by_offset(gd->fdt_blob, ++ prop->offset, ++ propname, lenp); ++} ++ + bool ofnode_is_available(ofnode node) + { + if (ofnode_is_np(node)) +diff --git a/drivers/core/read.c b/drivers/core/read.c +index 9602e52..a9f5d14 100644 +--- a/drivers/core/read.c ++++ b/drivers/core/read.c +@@ -238,6 +238,22 @@ const void *dev_read_prop(struct udevice *dev, const char *propname, int *lenp) + return ofnode_get_property(dev_ofnode(dev), propname, lenp); + } + ++int dev_read_first_prop(struct udevice *dev, struct ofprop *prop) ++{ ++ return ofnode_get_first_property(dev_ofnode(dev), prop); ++} ++ ++int dev_read_next_prop(struct ofprop *prop) ++{ ++ return ofnode_get_next_property(prop); ++} ++ ++const void *dev_read_prop_by_prop(struct ofprop *prop, ++ const char **propname, int *lenp) ++{ ++ return ofnode_get_property_by_prop(prop, propname, lenp); ++} ++ + int dev_read_alias_seq(struct udevice *dev, int *devnump) + { + ofnode node = dev_ofnode(dev); +diff --git a/drivers/core/root.c b/drivers/core/root.c +index e856438..14df16c 100644 +--- a/drivers/core/root.c ++++ b/drivers/core/root.c +@@ -203,15 +203,6 @@ static int dm_scan_fdt_live(struct udevice *parent, + int ret = 0, err; + + for (np = node_parent->child; np; np = np->sibling) { +- /* "chosen" node isn't a device itself but may contain some: */ +- if (!strcmp(np->name, "chosen")) { +- pr_debug("parsing subnodes of \"chosen\"\n"); +- +- err = dm_scan_fdt_live(parent, np, pre_reloc_only); +- if (err && !ret) +- ret = err; +- continue; +- } + + if (!of_device_is_available(np)) { + pr_debug(" - ignoring disabled device\n"); +@@ -256,21 +247,6 @@ static int dm_scan_fdt_node(struct udevice *parent, const void *blob, + offset = fdt_next_subnode(blob, offset)) { + const char *node_name = fdt_get_name(blob, offset, NULL); + +- /* +- * The "chosen" and "firmware" nodes aren't devices +- * themselves but may contain some: +- */ +- if (!strcmp(node_name, "chosen") || +- !strcmp(node_name, "firmware")) { +- pr_debug("parsing subnodes of \"%s\"\n", node_name); +- +- err = dm_scan_fdt_node(parent, blob, offset, +- pre_reloc_only); +- if (err && !ret) +- ret = err; +- continue; +- } +- + if (!fdtdec_get_is_enabled(blob, offset)) { + pr_debug(" - ignoring disabled device\n"); + continue; +@@ -315,7 +291,8 @@ int dm_scan_fdt(const void *blob, bool pre_reloc_only) + return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only); + } + +-static int dm_scan_fdt_ofnode_path(const char *path, bool pre_reloc_only) ++static int dm_scan_fdt_ofnode_path(const void *blob, const char *path, ++ bool pre_reloc_only) + { + ofnode node; + +@@ -327,13 +304,18 @@ static int dm_scan_fdt_ofnode_path(const char *path, bool pre_reloc_only) + if (of_live_active()) + return dm_scan_fdt_live(gd->dm_root, node.np, pre_reloc_only); + #endif +- return dm_scan_fdt_node(gd->dm_root, gd->fdt_blob, node.of_offset, ++ return dm_scan_fdt_node(gd->dm_root, blob, node.of_offset, + pre_reloc_only); + } + + int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only) + { +- int ret; ++ int ret, i; ++ const char * const nodes[] = { ++ "/chosen", ++ "/clocks", ++ "/firmware" ++ }; + + ret = dm_scan_fdt(blob, pre_reloc_only); + if (ret) { +@@ -341,16 +323,16 @@ int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only) + return ret; + } + +- ret = dm_scan_fdt_ofnode_path("/clocks", pre_reloc_only); +- if (ret) { +- debug("scan for /clocks failed: %d\n", ret); +- return ret; ++ /* Some nodes aren't devices themselves but may contain some */ ++ for (i = 0; i < ARRAY_SIZE(nodes); i++) { ++ ret = dm_scan_fdt_ofnode_path(blob, nodes[i], pre_reloc_only); ++ if (ret) { ++ debug("dm_scan_fdt() scan for %s failed: %d\n", ++ nodes[i], ret); ++ return ret; ++ } + } + +- ret = dm_scan_fdt_ofnode_path("/firmware", pre_reloc_only); +- if (ret) +- debug("scan for /firmware failed: %d\n", ret); +- + return ret; + } + #endif +diff --git a/drivers/dfu/Kconfig b/drivers/dfu/Kconfig +index 75fe0a1..1783656 100644 +--- a/drivers/dfu/Kconfig ++++ b/drivers/dfu/Kconfig +@@ -68,5 +68,10 @@ config DFU_VIRT + used at board level to manage specific behavior + (OTP update for example). + ++config SET_DFU_ALT_INFO ++ bool "Dynamic set of DFU alternate information" ++ help ++ This option allows to call the function set_dfu_alt_info to ++ dynamically build dfu_alt_info in board. + endif + endmenu +diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig +index 9f85054..a17e488 100644 +--- a/drivers/fastboot/Kconfig ++++ b/drivers/fastboot/Kconfig +@@ -104,6 +104,60 @@ config FASTBOOT_FLASH_NAND_TRIMFFS + When flashing NAND enable the DROP_FFS flag to drop trailing all-0xff + pages. + ++config FASTBOOT_MMC_BOOT_SUPPORT ++ bool "Enable EMMC_BOOT flash/erase" ++ depends on FASTBOOT_FLASH_MMC ++ help ++ The fastboot "flash" and "erase" commands normally does operations ++ on eMMC userdata. Define this to enable the special commands to ++ flash/erase eMMC boot partition. ++ The default target name for updating eMMC boot partition 1/2 is ++ CONFIG_FASTBOOT_MMC_BOOT1_NAME/CONFIG_FASTBOOT_MMC_BOOT2_NAME. ++ ++config FASTBOOT_MMC_BOOT1_NAME ++ string "Target name for updating EMMC_BOOT1" ++ depends on FASTBOOT_MMC_BOOT_SUPPORT ++ default "mmc0boot0" ++ help ++ The fastboot "flash" and "erase" commands support operations on ++ EMMC_BOOT1. This occurs when the specified "EMMC_BOOT1 name" on ++ the "fastboot flash" and "fastboot erase" commands match the value ++ defined here. ++ The default target name for updating EMMC_BOOT1 is "mmc0boot0". ++ ++config FASTBOOT_MMC_BOOT2_NAME ++ string "Target name for updating EMMC_BOOT2" ++ depends on FASTBOOT_MMC_BOOT_SUPPORT ++ default "mmc0boot1" ++ help ++ The fastboot "flash" and "erase" commands support operations on ++ EMMC_BOOT2. This occurs when the specified "EMMC_BOOT2 name" on ++ the "fastboot flash" and "fastboot erase" commands match the value ++ defined here. ++ The default target name for updating EMMC_BOOT2 is "mmc0boot1". ++ ++config FASTBOOT_MMC_USER_SUPPORT ++ bool "Enable eMMC userdata partition flash/erase" ++ depends on FASTBOOT_FLASH_MMC ++ help ++ Define this to enable the support "flash" and "erase" command on ++ eMMC userdata. The "flash" command only update the MBR and GPT ++ header when CONFIG_EFI_PARTITION is supported. ++ The "erase" command erase all the userdata. ++ This occurs when the specified "partition name" on the ++ fastboot command line matches the value CONFIG_FASTBOOT_MMC_USER_NAME. ++ ++config FASTBOOT_MMC_USER_NAME ++ string "Target name for updating EMMC_USER" ++ depends on FASTBOOT_MMC_USER_SUPPORT ++ default "mmc0" ++ help ++ The fastboot "flash" and "erase" command supports EMMC_USER. ++ This occurs when the specified "EMMC_USER name" on the ++ "fastboot flash" and the "fastboot erase" commands match the value ++ defined here. ++ The default target name for erasing EMMC_USER is "mmc0". ++ + config FASTBOOT_GPT_NAME + string "Target name for updating GPT" + depends on FASTBOOT_FLASH_MMC && EFI_PARTITION +@@ -135,6 +189,20 @@ config FASTBOOT_CMD_OEM_FORMAT + relies on the env variable partitions to contain the list of + partitions as required by the gpt command. + ++config FASTBOOT_CMD_OEM_PARTCONF ++ bool "Enable the 'oem partconf' command" ++ depends on FASTBOOT_FLASH_MMC && SUPPORT_EMMC_BOOT ++ help ++ Add support for the "oem partconf" command from a client. This set ++ the mmc boot-partition for the selecting eMMC device. ++ ++config FASTBOOT_CMD_OEM_BOOTBUS ++ bool "Enable the 'oem bootbus' command" ++ depends on FASTBOOT_FLASH_MMC && SUPPORT_EMMC_BOOT ++ help ++ Add support for the "oem bootbus" command from a client. This set ++ the mmc boot configuration for the selecting eMMC device. ++ + endif # FASTBOOT + + endmenu +diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c +index 3c4acfe..842aa5e 100644 +--- a/drivers/fastboot/fb_command.c ++++ b/drivers/fastboot/fb_command.c +@@ -39,6 +39,12 @@ static void reboot_bootloader(char *, char *); + #if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT) + static void oem_format(char *, char *); + #endif ++#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF) ++static void oem_partconf(char *, char *); ++#endif ++#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS) ++static void oem_bootbus(char *, char *); ++#endif + + static const struct { + const char *command; +@@ -88,6 +94,18 @@ static const struct { + .dispatch = oem_format, + }, + #endif ++#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF) ++ [FASTBOOT_COMMAND_OEM_PARTCONF] = { ++ .command = "oem partconf", ++ .dispatch = oem_partconf, ++ }, ++#endif ++#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS) ++ [FASTBOOT_COMMAND_OEM_BOOTBUS] = { ++ .command = "oem bootbus", ++ .dispatch = oem_bootbus, ++ }, ++#endif + }; + + /** +@@ -335,3 +353,57 @@ static void oem_format(char *cmd_parameter, char *response) + } + } + #endif ++ ++#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF) ++/** ++ * oem_partconf() - Execute the OEM partconf command ++ * ++ * @cmd_parameter: Pointer to command parameter ++ * @response: Pointer to fastboot response buffer ++ */ ++static void oem_partconf(char *cmd_parameter, char *response) ++{ ++ char cmdbuf[32]; ++ ++ if (!cmd_parameter) { ++ fastboot_fail("Expected command parameter", response); ++ return; ++ } ++ ++ /* execute 'mmc partconfg' command with cmd_parameter arguments*/ ++ snprintf(cmdbuf, sizeof(cmdbuf), "mmc partconf %x %s 0", ++ CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter); ++ printf("Execute: %s\n", cmdbuf); ++ if (run_command(cmdbuf, 0)) ++ fastboot_fail("Cannot set oem partconf", response); ++ else ++ fastboot_okay(NULL, response); ++} ++#endif ++ ++#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS) ++/** ++ * oem_bootbus() - Execute the OEM bootbus command ++ * ++ * @cmd_parameter: Pointer to command parameter ++ * @response: Pointer to fastboot response buffer ++ */ ++static void oem_bootbus(char *cmd_parameter, char *response) ++{ ++ char cmdbuf[32]; ++ ++ if (!cmd_parameter) { ++ fastboot_fail("Expected command parameter", response); ++ return; ++ } ++ ++ /* execute 'mmc bootbus' command with cmd_parameter arguments*/ ++ snprintf(cmdbuf, sizeof(cmdbuf), "mmc bootbus %x %s", ++ CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter); ++ printf("Execute: %s\n", cmdbuf); ++ if (run_command(cmdbuf, 0)) ++ fastboot_fail("Cannot set oem bootbus", response); ++ else ++ fastboot_okay(NULL, response); ++} ++#endif +diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c +index b0b19c5..09ba2f2 100644 +--- a/drivers/fastboot/fb_mmc.c ++++ b/drivers/fastboot/fb_mmc.c +@@ -129,6 +129,82 @@ static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info, + fastboot_okay(NULL, response); + } + ++#if defined(CONFIG_FASTBOOT_MMC_BOOT_SUPPORT) || \ ++ defined(CONFIG_FASTBOOT_MMC_USER_SUPPORT) ++static int fb_mmc_erase_mmc_hwpart(struct blk_desc *dev_desc) ++{ ++ lbaint_t blks; ++ ++ debug("Start Erasing mmc hwpart[%u]...\n", dev_desc->hwpart); ++ ++ blks = fb_mmc_blk_write(dev_desc, 0, dev_desc->lba, NULL); ++ ++ if (blks != dev_desc->lba) { ++ pr_err("Failed to erase mmc hwpart[%u]\n", dev_desc->hwpart); ++ return 1; ++ } ++ ++ printf("........ erased %lu bytes from mmc hwpart[%u]\n", ++ dev_desc->lba * dev_desc->blksz, dev_desc->hwpart); ++ ++ return 0; ++} ++#endif ++ ++#ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT ++static void fb_mmc_boot_ops(struct blk_desc *dev_desc, void *buffer, ++ int hwpart, u32 buff_sz, char *response) ++{ ++ lbaint_t blkcnt; ++ lbaint_t blks; ++ unsigned long blksz; ++ ++ // To operate on EMMC_BOOT1/2 (mmc0boot0/1) we first change the hwpart ++ if (blk_dselect_hwpart(dev_desc, hwpart)) { ++ pr_err("Failed to select hwpart\n"); ++ fastboot_fail("Failed to select hwpart", response); ++ return; ++ } ++ ++ if (buffer) { /* flash */ ++ ++ /* determine number of blocks to write */ ++ blksz = dev_desc->blksz; ++ blkcnt = ((buff_sz + (blksz - 1)) & ~(blksz - 1)); ++ blkcnt = lldiv(blkcnt, blksz); ++ ++ if (blkcnt > dev_desc->lba) { ++ pr_err("Image size too large\n"); ++ fastboot_fail("Image size too large", response); ++ return; ++ } ++ ++ debug("Start Flashing Image to EMMC_BOOT%d...\n", hwpart); ++ ++ blks = fb_mmc_blk_write(dev_desc, 0, blkcnt, buffer); ++ ++ if (blks != blkcnt) { ++ pr_err("Failed to write EMMC_BOOT%d\n", hwpart); ++ fastboot_fail("Failed to write EMMC_BOOT part", ++ response); ++ return; ++ } ++ ++ printf("........ wrote %lu bytes to EMMC_BOOT%d\n", ++ blkcnt * blksz, hwpart); ++ } else { /* erase */ ++ if (fb_mmc_erase_mmc_hwpart(dev_desc)) { ++ pr_err("Failed to erase EMMC_BOOT%d\n", hwpart); ++ fastboot_fail("Failed to erase EMMC_BOOT part", ++ response); ++ return; ++ } ++ } ++ ++ fastboot_okay(NULL, response); ++} ++#endif ++ + #ifdef CONFIG_ANDROID_BOOT_IMAGE + /** + * Read Android boot image header from boot partition. +@@ -345,8 +421,26 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer, + return; + } + ++#ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT ++ if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) { ++ fb_mmc_boot_ops(dev_desc, download_buffer, 1, ++ download_bytes, response); ++ return; ++ } ++ if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT2_NAME) == 0) { ++ fb_mmc_boot_ops(dev_desc, download_buffer, 2, ++ download_bytes, response); ++ return; ++ } ++#endif ++ + #if CONFIG_IS_ENABLED(EFI_PARTITION) ++#ifndef CONFIG_FASTBOOT_MMC_USER_SUPPORT + if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) { ++#else ++ if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0 || ++ strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) { ++#endif + printf("%s: updating MBR, Primary and Backup GPT(s)\n", + __func__); + if (is_valid_gpt_buf(dev_desc, download_buffer)) { +@@ -457,6 +551,30 @@ void fastboot_mmc_erase(const char *cmd, char *response) + return; + } + ++#ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT ++ if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) { ++ /* erase EMMC boot1 */ ++ fb_mmc_boot_ops(dev_desc, NULL, 1, 0, response); ++ return; ++ } ++ if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT2_NAME) == 0) { ++ /* erase EMMC boot2 */ ++ fb_mmc_boot_ops(dev_desc, NULL, 2, 0, response); ++ return; ++ } ++#endif ++ ++#ifdef CONFIG_FASTBOOT_MMC_USER_SUPPORT ++ if (strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) { ++ /* erase EMMC userdata */ ++ if (fb_mmc_erase_mmc_hwpart(dev_desc)) ++ fastboot_fail("Failed to erase EMMC_USER", response); ++ else ++ fastboot_okay(NULL, response); ++ return; ++ } ++#endif ++ + ret = part_get_info_by_name_or_alias(dev_desc, cmd, &info); + if (ret < 0) { + pr_err("cannot find partition: '%s'\n", cmd); +diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c +index 90fbed4..5da28e6 100644 +--- a/drivers/gpio/gpio-uclass.c ++++ b/drivers/gpio/gpio-uclass.c +@@ -19,6 +19,22 @@ + DECLARE_GLOBAL_DATA_PTR; + + /** ++ * gpio_desc_init() - Initialize the GPIO descriptor ++ * ++ * @desc: GPIO descriptor to initialize ++ * @dev: GPIO device ++ * @offset: Offset of device GPIO ++ */ ++static void gpio_desc_init(struct gpio_desc *desc, ++ struct udevice *dev, ++ uint offset) ++{ ++ desc->dev = dev; ++ desc->offset = offset; ++ desc->flags = 0; ++} ++ ++/** + * gpio_to_device() - Convert global GPIO number to device, number + * + * Convert the GPIO number to an entry in the list of GPIOs +@@ -41,9 +57,7 @@ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc) + uc_priv = dev_get_uclass_priv(dev); + if (gpio >= uc_priv->gpio_base && + gpio < uc_priv->gpio_base + uc_priv->gpio_count) { +- desc->dev = dev; +- desc->offset = gpio - uc_priv->gpio_base; +- desc->flags = 0; ++ gpio_desc_init(desc, dev, gpio - uc_priv->gpio_base); + return 0; + } + } +@@ -85,8 +99,7 @@ int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc) + if (!dev) + return ret ? ret : -EINVAL; + +- desc->dev = dev; +- desc->offset = offset; ++ gpio_desc_init(desc, dev, offset); + + return 0; + } +@@ -127,8 +140,27 @@ int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc, + if (args->args_count < 2) + return 0; + ++ desc->flags = 0; + if (args->args[1] & GPIO_ACTIVE_LOW) +- desc->flags = GPIOD_ACTIVE_LOW; ++ desc->flags |= GPIOD_ACTIVE_LOW; ++ ++ /* ++ * need to test 2 bits for gpio output binding: ++ * OPEN_DRAIN (0x6) = SINGLE_ENDED (0x2) | LINE_OPEN_DRAIN (0x4) ++ * OPEN_SOURCE (0x2) = SINGLE_ENDED (0x2) | LINE_OPEN_SOURCE (0x0) ++ */ ++ if (args->args[1] & GPIO_SINGLE_ENDED) { ++ if (args->args[1] & GPIO_LINE_OPEN_DRAIN) ++ desc->flags |= GPIOD_OPEN_DRAIN; ++ else ++ desc->flags |= GPIOD_OPEN_SOURCE; ++ } ++ ++ if (args->args[1] & GPIO_PULL_UP) ++ desc->flags |= GPIOD_PULL_UP; ++ ++ if (args->args[1] & GPIO_PULL_DOWN) ++ desc->flags |= GPIOD_PULL_DOWN; + + return 0; + } +@@ -463,18 +495,24 @@ int gpio_direction_output(unsigned gpio, int value) + desc.offset, value); + } + +-int dm_gpio_get_value(const struct gpio_desc *desc) ++static int _gpio_get_value(const struct gpio_desc *desc) + { + int value; ++ ++ value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset); ++ ++ return desc->flags & GPIOD_ACTIVE_LOW ? !value : value; ++} ++ ++int dm_gpio_get_value(const struct gpio_desc *desc) ++{ + int ret; + + ret = check_reserved(desc, "get_value"); + if (ret) + return ret; + +- value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset); +- +- return desc->flags & GPIOD_ACTIVE_LOW ? !value : value; ++ return _gpio_get_value(desc); + } + + int dm_gpio_set_value(const struct gpio_desc *desc, int value) +@@ -491,71 +529,128 @@ int dm_gpio_set_value(const struct gpio_desc *desc, int value) + return 0; + } + +-int dm_gpio_get_open_drain(struct gpio_desc *desc) ++/* check dir flags invalid configuration */ ++static int check_dir_flags(ulong flags) + { +- struct dm_gpio_ops *ops = gpio_get_ops(desc->dev); +- int ret; ++ if ((flags & GPIOD_IS_OUT) && (flags & GPIOD_IS_IN)) { ++ log_debug("%s: flags 0x%lx has GPIOD_IS_OUT and GPIOD_IS_IN\n", ++ __func__, flags); ++ return -EINVAL; ++ } ++ ++ if ((flags & GPIOD_PULL_UP) && (flags & GPIOD_PULL_DOWN)) { ++ log_debug("%s: flags 0x%lx has GPIOD_PULL_UP and GPIOD_PULL_DOWN\n", ++ __func__, flags); ++ return -EINVAL; ++ } ++ ++ if ((flags & GPIOD_OPEN_DRAIN) && (flags & GPIOD_OPEN_SOURCE)) { ++ log_debug("%s: flags 0x%lx has GPIOD_OPEN_DRAIN and GPIOD_OPEN_SOURCE\n", ++ __func__, flags); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int _dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags) ++{ ++ struct udevice *dev = desc->dev; ++ struct dm_gpio_ops *ops = gpio_get_ops(dev); ++ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); ++ int ret = 0; ++ ++ ret = check_dir_flags(flags); ++ if (ret) { ++ dev_dbg(dev, ++ "%s error: set_dir_flags for gpio %s%d has invalid dir flags 0x%lx\n", ++ desc->dev->name, ++ uc_priv->bank_name ? uc_priv->bank_name : "", ++ desc->offset, flags); + +- ret = check_reserved(desc, "get_open_drain"); +- if (ret) + return ret; ++ } + +- if (ops->set_open_drain) +- return ops->get_open_drain(desc->dev, desc->offset); +- else +- return -ENOSYS; ++ /* GPIOD_ are directly managed by driver in set_dir_flags*/ ++ if (ops->set_dir_flags) { ++ ret = ops->set_dir_flags(dev, desc->offset, flags); ++ } else { ++ if (flags & GPIOD_IS_OUT) { ++ ret = ops->direction_output(dev, desc->offset, ++ GPIOD_FLAGS_OUTPUT(flags)); ++ } else if (flags & GPIOD_IS_IN) { ++ ret = ops->direction_input(dev, desc->offset); ++ } ++ } ++ ++ return ret; + } + +-int dm_gpio_set_open_drain(struct gpio_desc *desc, int value) ++int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags) + { +- struct dm_gpio_ops *ops = gpio_get_ops(desc->dev); + int ret; + +- ret = check_reserved(desc, "set_open_drain"); ++ ret = check_reserved(desc, "set_dir_flags"); + if (ret) + return ret; + +- if (ops->set_open_drain) +- ret = ops->set_open_drain(desc->dev, desc->offset, value); +- else +- return 0; /* feature not supported -> ignore setting */ ++ /* combine the requested flags (for IN/OUT) and the descriptor flags */ ++ flags |= desc->flags; ++ ret = _dm_gpio_set_dir_flags(desc, flags); ++ ++ /* update the descriptor flags */ ++ if (ret) ++ desc->flags = flags; + + return ret; + } + +-int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags) ++int dm_gpio_set_dir(struct gpio_desc *desc) + { +- struct udevice *dev = desc->dev; +- struct dm_gpio_ops *ops = gpio_get_ops(dev); + int ret; + + ret = check_reserved(desc, "set_dir"); + if (ret) + return ret; + +- if (flags & GPIOD_IS_OUT) { +- int value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0; ++ return _dm_gpio_set_dir_flags(desc, desc->flags); ++} + +- if (flags & GPIOD_ACTIVE_LOW) +- value = !value; +- ret = ops->direction_output(dev, desc->offset, value); +- } else if (flags & GPIOD_IS_IN) { +- ret = ops->direction_input(dev, desc->offset); +- } ++int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags) ++{ ++ struct udevice *dev = desc->dev; ++ int ret, value; ++ struct dm_gpio_ops *ops = gpio_get_ops(dev); ++ ulong dir_flags; ++ ++ ret = check_reserved(desc, "get_dir_flags"); + if (ret) + return ret; +- /* +- * Update desc->flags here, so that GPIO_ACTIVE_LOW is honoured in +- * futures +- */ +- desc->flags = flags; + +- return 0; +-} ++ /* GPIOD_ are directly provided by driver except GPIOD_ACTIVE_LOW */ ++ if (ops->get_dir_flags) { ++ ret = ops->get_dir_flags(dev, desc->offset, &dir_flags); ++ if (ret) ++ return ret; + +-int dm_gpio_set_dir(struct gpio_desc *desc) +-{ +- return dm_gpio_set_dir_flags(desc, desc->flags); ++ /* GPIOD_ACTIVE_LOW is saved in desc->flags */ ++ value = dir_flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0; ++ if (desc->flags & GPIOD_ACTIVE_LOW) ++ value = !value; ++ dir_flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE); ++ dir_flags |= (desc->flags & GPIOD_ACTIVE_LOW); ++ if (value) ++ dir_flags |= GPIOD_IS_OUT_ACTIVE; ++ } else { ++ dir_flags = desc->flags; ++ /* only GPIOD_IS_OUT_ACTIVE is provided by uclass */ ++ dir_flags &= ~GPIOD_IS_OUT_ACTIVE; ++ if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc)) ++ dir_flags |= GPIOD_IS_OUT_ACTIVE; ++ } ++ *flags = dir_flags; ++ ++ return 0; + } + + /** +@@ -804,9 +899,7 @@ static int gpio_request_tail(int ret, const char *nodename, + struct gpio_desc *desc, int flags, + bool add_index, struct udevice *gpio_dev) + { +- desc->dev = gpio_dev; +- desc->offset = 0; +- desc->flags = 0; ++ gpio_desc_init(desc, gpio_dev, 0); + if (ret) + goto err; + +@@ -830,7 +923,7 @@ static int gpio_request_tail(int ret, const char *nodename, + debug("%s: dm_gpio_requestf failed\n", __func__); + goto err; + } +- ret = dm_gpio_set_dir_flags(desc, flags | desc->flags); ++ ret = dm_gpio_set_dir_flags(desc, flags); + if (ret) { + debug("%s: dm_gpio_set_dir failed\n", __func__); + goto err; +@@ -1053,14 +1146,14 @@ static int gpio_post_bind(struct udevice *dev) + ops->get_value += gd->reloc_off; + if (ops->set_value) + ops->set_value += gd->reloc_off; +- if (ops->get_open_drain) +- ops->get_open_drain += gd->reloc_off; +- if (ops->set_open_drain) +- ops->set_open_drain += gd->reloc_off; + if (ops->get_function) + ops->get_function += gd->reloc_off; + if (ops->xlate) + ops->xlate += gd->reloc_off; ++ if (ops->set_dir_flags) ++ ops->set_dir_flags += gd->reloc_off; ++ if (ops->get_dir_flags) ++ ops->get_dir_flags += gd->reloc_off; + + reloc_done++; + } +diff --git a/drivers/gpio/mpc8xxx_gpio.c b/drivers/gpio/mpc8xxx_gpio.c +index c273c2c..c23f5b5 100644 +--- a/drivers/gpio/mpc8xxx_gpio.c ++++ b/drivers/gpio/mpc8xxx_gpio.c +@@ -144,26 +144,6 @@ static int mpc8xxx_gpio_get_value(struct udevice *dev, uint gpio) + return !!mpc8xxx_gpio_get_val(data->base, gpio_mask(gpio)); + } + +-static int mpc8xxx_gpio_get_open_drain(struct udevice *dev, uint gpio) +-{ +- struct mpc8xxx_gpio_data *data = dev_get_priv(dev); +- +- return !!mpc8xxx_gpio_open_drain_val(data->base, gpio_mask(gpio)); +-} +- +-static int mpc8xxx_gpio_set_open_drain(struct udevice *dev, uint gpio, +- int value) +-{ +- struct mpc8xxx_gpio_data *data = dev_get_priv(dev); +- +- if (value) +- mpc8xxx_gpio_open_drain_on(data->base, gpio_mask(gpio)); +- else +- mpc8xxx_gpio_open_drain_off(data->base, gpio_mask(gpio)); +- +- return 0; +-} +- + static int mpc8xxx_gpio_get_function(struct udevice *dev, uint gpio) + { + struct mpc8xxx_gpio_data *data = dev_get_priv(dev); +@@ -240,8 +220,6 @@ static const struct dm_gpio_ops gpio_mpc8xxx_ops = { + .direction_output = mpc8xxx_gpio_direction_output, + .get_value = mpc8xxx_gpio_get_value, + .set_value = mpc8xxx_gpio_set_value, +- .get_open_drain = mpc8xxx_gpio_get_open_drain, +- .set_open_drain = mpc8xxx_gpio_set_open_drain, + .get_function = mpc8xxx_gpio_get_function, + }; + +diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c +index 2ef5c67..bf6287f 100644 +--- a/drivers/gpio/sandbox.c ++++ b/drivers/gpio/sandbox.c +@@ -8,43 +8,43 @@ + #include + #include + #include ++#include + #include ++#include + #include ++#include + +-/* Flags for each GPIO */ +-#define GPIOF_OUTPUT (1 << 0) /* Currently set as an output */ +-#define GPIOF_HIGH (1 << 1) /* Currently set high */ +-#define GPIOF_ODR (1 << 2) /* Currently set to open drain mode */ + + struct gpio_state { + const char *label; /* label given by requester */ +- u8 flags; /* flags (GPIOF_...) */ ++ ulong dir_flags; /* dir_flags (GPIOD_...) */ + }; + +-/* Access routines for GPIO state */ +-static u8 *get_gpio_flags(struct udevice *dev, unsigned offset) ++/* Access routines for GPIO dir flags */ ++static ulong *get_gpio_dir_flags(struct udevice *dev, unsigned int offset) + { + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct gpio_state *state = dev_get_priv(dev); + + if (offset >= uc_priv->gpio_count) { +- static u8 invalid_flags; ++ static ulong invalid_dir_flags; + printf("sandbox_gpio: error: invalid gpio %u\n", offset); +- return &invalid_flags; ++ return &invalid_dir_flags; + } + +- return &state[offset].flags; ++ return &state[offset].dir_flags; ++ + } + +-static int get_gpio_flag(struct udevice *dev, unsigned offset, int flag) ++static int get_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag) + { +- return (*get_gpio_flags(dev, offset) & flag) != 0; ++ return (*get_gpio_dir_flags(dev, offset) & flag) != 0; + } + +-static int set_gpio_flag(struct udevice *dev, unsigned offset, int flag, ++static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag, + int value) + { +- u8 *gpio = get_gpio_flags(dev, offset); ++ ulong *gpio = get_gpio_dir_flags(dev, offset); + + if (value) + *gpio |= flag; +@@ -60,34 +60,40 @@ static int set_gpio_flag(struct udevice *dev, unsigned offset, int flag, + + int sandbox_gpio_get_value(struct udevice *dev, unsigned offset) + { +- if (get_gpio_flag(dev, offset, GPIOF_OUTPUT)) ++ if (get_gpio_flag(dev, offset, GPIOD_IS_OUT)) + debug("sandbox_gpio: get_value on output gpio %u\n", offset); +- return get_gpio_flag(dev, offset, GPIOF_HIGH); ++ return get_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE); + } + + int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value) + { +- return set_gpio_flag(dev, offset, GPIOF_HIGH, value); ++ return set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE, value); + } + +-int sandbox_gpio_get_open_drain(struct udevice *dev, unsigned offset) ++int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset) + { +- return get_gpio_flag(dev, offset, GPIOF_ODR); ++ return get_gpio_flag(dev, offset, GPIOD_IS_OUT); + } + +-int sandbox_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value) ++int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output) + { +- return set_gpio_flag(dev, offset, GPIOF_ODR, value); ++ set_gpio_flag(dev, offset, GPIOD_IS_OUT, output); ++ set_gpio_flag(dev, offset, GPIOD_IS_IN, !(output)); ++ ++ return 0; + } + +-int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset) ++ulong sandbox_gpio_get_dir_flags(struct udevice *dev, unsigned int offset) + { +- return get_gpio_flag(dev, offset, GPIOF_OUTPUT); ++ return *get_gpio_dir_flags(dev, offset); + } + +-int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output) ++int sandbox_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, ++ ulong flags) + { +- return set_gpio_flag(dev, offset, GPIOF_OUTPUT, output); ++ *get_gpio_dir_flags(dev, offset) = flags; ++ ++ return 0; + } + + /* +@@ -134,33 +140,14 @@ static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value) + return sandbox_gpio_set_value(dev, offset, value); + } + +-/* read GPIO ODR value of port 'offset' */ +-static int sb_gpio_get_open_drain(struct udevice *dev, unsigned offset) +-{ +- debug("%s: offset:%u\n", __func__, offset); +- +- return sandbox_gpio_get_open_drain(dev, offset); +-} +- +-/* write GPIO ODR value to port 'offset' */ +-static int sb_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value) +-{ +- debug("%s: offset:%u, value = %d\n", __func__, offset, value); +- +- if (!sandbox_gpio_get_direction(dev, offset)) { +- printf("sandbox_gpio: error: set_open_drain on input gpio %u\n", +- offset); +- return -1; +- } +- +- return sandbox_gpio_set_open_drain(dev, offset, value); +-} +- + static int sb_gpio_get_function(struct udevice *dev, unsigned offset) + { +- if (get_gpio_flag(dev, offset, GPIOF_OUTPUT)) ++ if (get_gpio_flag(dev, offset, GPIOD_IS_OUT)) + return GPIOF_OUTPUT; +- return GPIOF_INPUT; ++ if (get_gpio_flag(dev, offset, GPIOD_IS_IN)) ++ return GPIOF_INPUT; ++ ++ return GPIOF_INPUT; /*GPIO is not configurated */ + } + + static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, +@@ -169,27 +156,54 @@ static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, + desc->offset = args->args[0]; + if (args->args_count < 2) + return 0; +- if (args->args[1] & GPIO_ACTIVE_LOW) +- desc->flags |= GPIOD_ACTIVE_LOW; +- if (args->args[1] & 2) ++ /* treat generic binding with gpio uclass */ ++ gpio_xlate_offs_flags(dev, desc, args); ++ ++ /* sandbox test specific, not defined in gpio.h */ ++ if (args->args[1] & GPIO_IN) + desc->flags |= GPIOD_IS_IN; +- if (args->args[1] & 4) ++ ++ if (args->args[1] & GPIO_OUT) + desc->flags |= GPIOD_IS_OUT; +- if (args->args[1] & 8) ++ ++ if (args->args[1] & GPIO_OUT_ACTIVE) + desc->flags |= GPIOD_IS_OUT_ACTIVE; + + return 0; + } + ++static int sb_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, ++ ulong flags) ++{ ++ ulong *dir_flags; ++ ++ debug("%s: offset:%u, dir_flags = %lx\n", __func__, offset, flags); ++ ++ dir_flags = get_gpio_dir_flags(dev, offset); ++ ++ *dir_flags = flags; ++ ++ return 0; ++} ++ ++static int sb_gpio_get_dir_flags(struct udevice *dev, unsigned int offset, ++ ulong *flags) ++{ ++ debug("%s: offset:%u\n", __func__, offset); ++ *flags = *get_gpio_dir_flags(dev, offset); ++ ++ return 0; ++} ++ + static const struct dm_gpio_ops gpio_sandbox_ops = { + .direction_input = sb_gpio_direction_input, + .direction_output = sb_gpio_direction_output, + .get_value = sb_gpio_get_value, + .set_value = sb_gpio_set_value, +- .get_open_drain = sb_gpio_get_open_drain, +- .set_open_drain = sb_gpio_set_open_drain, + .get_function = sb_gpio_get_function, + .xlate = sb_gpio_xlate, ++ .set_dir_flags = sb_gpio_set_dir_flags, ++ .get_dir_flags = sb_gpio_get_dir_flags, + }; + + static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev) +@@ -237,3 +251,198 @@ U_BOOT_DRIVER(gpio_sandbox) = { + .remove = gpio_sandbox_remove, + .ops = &gpio_sandbox_ops, + }; ++ ++/* pincontrol: used only to check GPIO pin configuration (pinmux command) */ ++ ++struct sb_pinctrl_priv { ++ int pinctrl_ngpios; ++ struct list_head gpio_dev; ++}; ++ ++struct sb_gpio_bank { ++ struct udevice *gpio_dev; ++ struct list_head list; ++}; ++ ++static int sb_populate_gpio_dev_list(struct udevice *dev) ++{ ++ struct sb_pinctrl_priv *priv = dev_get_priv(dev); ++ struct udevice *gpio_dev; ++ struct udevice *child; ++ struct sb_gpio_bank *gpio_bank; ++ int ret; ++ ++ /* ++ * parse pin-controller sub-nodes (ie gpio bank nodes) and fill ++ * a list with all gpio device reference which belongs to the ++ * current pin-controller. This list is used to find pin_name and ++ * pin muxing ++ */ ++ list_for_each_entry(child, &dev->child_head, sibling_node) { ++ ret = uclass_get_device_by_name(UCLASS_GPIO, child->name, ++ &gpio_dev); ++ if (ret < 0) ++ continue; ++ ++ gpio_bank = malloc(sizeof(*gpio_bank)); ++ if (!gpio_bank) { ++ dev_err(dev, "Not enough memory\n"); ++ return -ENOMEM; ++ } ++ ++ gpio_bank->gpio_dev = gpio_dev; ++ list_add_tail(&gpio_bank->list, &priv->gpio_dev); ++ } ++ ++ return 0; ++} ++ ++static int sb_pinctrl_get_pins_count(struct udevice *dev) ++{ ++ struct sb_pinctrl_priv *priv = dev_get_priv(dev); ++ struct gpio_dev_priv *uc_priv; ++ struct sb_gpio_bank *gpio_bank; ++ ++ /* ++ * if get_pins_count has already been executed once on this ++ * pin-controller, no need to run it again ++ */ ++ if (priv->pinctrl_ngpios) ++ return priv->pinctrl_ngpios; ++ ++ if (list_empty(&priv->gpio_dev)) ++ sb_populate_gpio_dev_list(dev); ++ /* ++ * walk through all banks to retrieve the pin-controller ++ * pins number ++ */ ++ list_for_each_entry(gpio_bank, &priv->gpio_dev, list) { ++ uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev); ++ ++ priv->pinctrl_ngpios += uc_priv->gpio_count; ++ } ++ ++ return priv->pinctrl_ngpios; ++} ++ ++static struct udevice *sb_pinctrl_get_gpio_dev(struct udevice *dev, ++ unsigned int selector, ++ unsigned int *idx) ++{ ++ struct sb_pinctrl_priv *priv = dev_get_priv(dev); ++ struct sb_gpio_bank *gpio_bank; ++ struct gpio_dev_priv *uc_priv; ++ int pin_count = 0; ++ ++ if (list_empty(&priv->gpio_dev)) ++ sb_populate_gpio_dev_list(dev); ++ ++ /* look up for the bank which owns the requested pin */ ++ list_for_each_entry(gpio_bank, &priv->gpio_dev, list) { ++ uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev); ++ ++ if (selector < (pin_count + uc_priv->gpio_count)) { ++ /* ++ * we found the bank, convert pin selector to ++ * gpio bank index ++ */ ++ *idx = selector - pin_count; ++ ++ return gpio_bank->gpio_dev; ++ } ++ pin_count += uc_priv->gpio_count; ++ } ++ ++ return NULL; ++} ++ ++static const char *sb_pinctrl_get_pin_name(struct udevice *dev, ++ unsigned int selector) ++{ ++ struct gpio_dev_priv *uc_priv; ++ struct udevice *gpio_dev; ++ unsigned int gpio_idx; ++ static char pin_name[PINNAME_SIZE]; ++ ++ /* look up for the bank which owns the requested pin */ ++ gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx); ++ if (!gpio_dev) { ++ snprintf(pin_name, PINNAME_SIZE, "Error"); ++ } else { ++ uc_priv = dev_get_uclass_priv(gpio_dev); ++ ++ snprintf(pin_name, PINNAME_SIZE, "%s%d", ++ uc_priv->bank_name, ++ gpio_idx); ++ } ++ ++ return pin_name; ++} ++ ++static char *get_dir_flags_string(ulong flags) ++{ ++ if (flags & GPIOD_OPEN_DRAIN) ++ return "drive-open-drain"; ++ if (flags & GPIOD_OPEN_SOURCE) ++ return "drive-open-source"; ++ if (flags & GPIOD_PULL_UP) ++ return "bias-pull-up"; ++ if (flags & GPIOD_PULL_DOWN) ++ return "bias-pull-down"; ++ return "."; ++} ++ ++static int sb_pinctrl_get_pin_muxing(struct udevice *dev, ++ unsigned int selector, ++ char *buf, int size) ++{ ++ struct udevice *gpio_dev; ++ unsigned int gpio_idx; ++ ulong dir_flags; ++ int function; ++ ++ /* look up for the bank which owns the requested pin */ ++ gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx); ++ if (!gpio_dev) { ++ snprintf(buf, size, "Error"); ++ } else { ++ function = sb_gpio_get_function(gpio_dev, gpio_idx); ++ dir_flags = *get_gpio_dir_flags(gpio_dev, gpio_idx); ++ ++ snprintf(buf, size, "gpio %s %s", ++ function == GPIOF_OUTPUT ? "output" : "input", ++ get_dir_flags_string(dir_flags)); ++ } ++ ++ return 0; ++} ++ ++static int sandbox_pinctrl_probe(struct udevice *dev) ++{ ++ struct sb_pinctrl_priv *priv = dev_get_priv(dev); ++ ++ INIT_LIST_HEAD(&priv->gpio_dev); ++ ++ return 0; ++} ++ ++static struct pinctrl_ops sandbox_pinctrl_gpio_ops = { ++ .get_pin_name = sb_pinctrl_get_pin_name, ++ .get_pins_count = sb_pinctrl_get_pins_count, ++ .get_pin_muxing = sb_pinctrl_get_pin_muxing, ++}; ++ ++static const struct udevice_id sandbox_pinctrl_gpio_match[] = { ++ { .compatible = "sandbox,pinctrl-gpio" }, ++ { /* sentinel */ } ++}; ++ ++U_BOOT_DRIVER(sandbox_pinctrl_gpio) = { ++ .name = "sandbox_pinctrl_gpio", ++ .id = UCLASS_PINCTRL, ++ .of_match = sandbox_pinctrl_gpio_match, ++ .ops = &sandbox_pinctrl_gpio_ops, ++ .bind = dm_scan_fdt_dev, ++ .probe = sandbox_pinctrl_probe, ++ .priv_auto_alloc_size = sizeof(struct sb_pinctrl_priv), ++}; +diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c +index 302a434..a7c89a4 100644 +--- a/drivers/gpio/stm32_gpio.c ++++ b/drivers/gpio/stm32_gpio.c +@@ -19,7 +19,62 @@ + #define MODE_BITS_MASK 3 + #define BSRR_BIT(gpio_pin, value) BIT(gpio_pin + (value ? 0 : 16)) + +-#ifndef CONFIG_SPL_BUILD ++#define PUPD_BITS(gpio_pin) (gpio_pin * 2) ++#define PUPD_MASK 3 ++ ++#define OTYPE_BITS(gpio_pin) (gpio_pin) ++#define OTYPE_MSK 1 ++ ++static void stm32_gpio_set_moder(struct stm32_gpio_regs *regs, ++ int idx, ++ int mode) ++{ ++ int bits_index; ++ int mask; ++ ++ bits_index = MODE_BITS(idx); ++ mask = MODE_BITS_MASK << bits_index; ++ ++ clrsetbits_le32(®s->moder, mask, mode << bits_index); ++} ++ ++static int stm32_gpio_get_moder(struct stm32_gpio_regs *regs, int idx) ++{ ++ return (readl(®s->moder) >> MODE_BITS(idx)) & MODE_BITS_MASK; ++} ++ ++static void stm32_gpio_set_otype(struct stm32_gpio_regs *regs, ++ int idx, ++ enum stm32_gpio_otype otype) ++{ ++ int bits; ++ ++ bits = OTYPE_BITS(idx); ++ clrsetbits_le32(®s->otyper, OTYPE_MSK << bits, otype << bits); ++} ++ ++static enum stm32_gpio_otype stm32_gpio_get_otype(struct stm32_gpio_regs *regs, ++ int idx) ++{ ++ return (readl(®s->otyper) >> OTYPE_BITS(idx)) & OTYPE_MSK; ++} ++ ++static void stm32_gpio_set_pupd(struct stm32_gpio_regs *regs, ++ int idx, ++ enum stm32_gpio_pupd pupd) ++{ ++ int bits; ++ ++ bits = PUPD_BITS(idx); ++ clrsetbits_le32(®s->pupdr, PUPD_MASK << bits, pupd << bits); ++} ++ ++static enum stm32_gpio_pupd stm32_gpio_get_pupd(struct stm32_gpio_regs *regs, ++ int idx) ++{ ++ return (readl(®s->pupdr) >> PUPD_BITS(idx)) & PUPD_MASK; ++} ++ + /* + * convert gpio offset to gpio index taking into account gpio holes + * into gpio bank +@@ -45,18 +100,13 @@ 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 bits_index; +- int mask; + int idx; + + idx = stm32_offset_to_index(dev, offset); + if (idx < 0) + return idx; + +- bits_index = MODE_BITS(idx); +- mask = MODE_BITS_MASK << bits_index; +- +- clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_IN << bits_index); ++ stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN); + + return 0; + } +@@ -66,18 +116,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 bits_index; +- int mask; + int idx; + + idx = stm32_offset_to_index(dev, offset); + if (idx < 0) + return idx; + +- bits_index = MODE_BITS(idx); +- mask = MODE_BITS_MASK << bits_index; +- +- clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_OUT << bits_index); ++ stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT); + + writel(BSRR_BIT(idx, value), ®s->bsrr); + +@@ -139,14 +184,88 @@ static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset) + return GPIOF_FUNC; + } + ++static int stm32_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, ++ ulong flags) ++{ ++ 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 (flags & GPIOD_IS_OUT) { ++ int value = GPIOD_FLAGS_OUTPUT(flags); ++ ++ if (flags & GPIOD_OPEN_DRAIN) ++ stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD); ++ else ++ stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP); ++ stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT); ++ writel(BSRR_BIT(idx, value), ®s->bsrr); ++ ++ } 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); ++ } ++ ++ return 0; ++} ++ ++static int stm32_gpio_get_dir_flags(struct udevice *dev, unsigned int offset, ++ ulong *flags) ++{ ++ 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; ++ ++ switch (stm32_gpio_get_moder(regs, idx)) { ++ case STM32_GPIO_MODE_OUT: ++ dir_flags |= GPIOD_IS_OUT; ++ if (stm32_gpio_get_otype(regs, idx) == STM32_GPIO_OTYPE_OD) ++ dir_flags |= GPIOD_OPEN_DRAIN; ++ if (readl(®s->idr) & BIT(idx)) ++ dir_flags |= GPIOD_IS_OUT_ACTIVE; ++ 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; ++ } ++ *flags = dir_flags; ++ ++ return 0; ++} ++ + static const struct dm_gpio_ops gpio_stm32_ops = { + .direction_input = stm32_gpio_direction_input, + .direction_output = stm32_gpio_direction_output, + .get_value = stm32_gpio_get_value, + .set_value = stm32_gpio_set_value, + .get_function = stm32_gpio_get_function, ++ .set_dir_flags = stm32_gpio_set_dir_flags, ++ .get_dir_flags = stm32_gpio_get_dir_flags, + }; +-#endif + + static int gpio_stm32_probe(struct udevice *dev) + { +@@ -161,7 +280,6 @@ static int gpio_stm32_probe(struct udevice *dev) + + priv->regs = (struct stm32_gpio_regs *)addr; + +-#ifndef CONFIG_SPL_BUILD + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct ofnode_phandle_args args; + const char *name; +@@ -194,7 +312,7 @@ static int gpio_stm32_probe(struct udevice *dev) + dev_dbg(dev, "addr = 0x%p bank_name = %s gpio_count = %d gpio_range = 0x%x\n", + (u32 *)priv->regs, uc_priv->bank_name, uc_priv->gpio_count, + priv->gpio_range); +-#endif ++ + ret = clk_get_by_index(dev, 0, &clk); + if (ret < 0) + return ret; +@@ -214,9 +332,7 @@ U_BOOT_DRIVER(gpio_stm32) = { + .name = "gpio_stm32", + .id = UCLASS_GPIO, + .probe = gpio_stm32_probe, +-#ifndef CONFIG_SPL_BUILD + .ops = &gpio_stm32_ops, +-#endif + .flags = DM_UC_FLAG_SEQ_ALIAS, + .priv_auto_alloc_size = sizeof(struct stm32_gpio_priv), + }; +diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c +index 2b18735..7321f80 100644 +--- a/drivers/i2c/stm32f7_i2c.c ++++ b/drivers/i2c/stm32f7_i2c.c +@@ -10,6 +10,7 @@ + #include + + #include ++#include + #include + + /* STM32 I2C registers */ +@@ -115,17 +116,6 @@ struct stm32_i2c_regs { + + #define STM32_NSEC_PER_SEC 1000000000L + +-#define STANDARD_RATE 100000 +-#define FAST_RATE 400000 +-#define FAST_PLUS_RATE 1000000 +- +-enum stm32_i2c_speed { +- STM32_I2C_SPEED_STANDARD, /* 100 kHz */ +- STM32_I2C_SPEED_FAST, /* 400 kHz */ +- STM32_I2C_SPEED_FAST_PLUS, /* 1 MHz */ +- STM32_I2C_SPEED_END, +-}; +- + /** + * struct stm32_i2c_spec - private i2c specification timing + * @rate: I2C bus speed (Hz) +@@ -155,7 +145,6 @@ struct stm32_i2c_spec { + + /** + * struct stm32_i2c_setup - private I2C timing setup parameters +- * @speed: I2C speed mode (standard, Fast Plus) + * @speed_freq: I2C speed frequency (Hz) + * @clock_src: I2C clock source frequency (Hz) + * @rise_time: Rise time (ns) +@@ -164,7 +153,6 @@ struct stm32_i2c_spec { + * @analog_filter: Analog filter delay (On/Off) + */ + struct stm32_i2c_setup { +- enum stm32_i2c_speed speed; + u32 speed_freq; + u32 clock_src; + u32 rise_time; +@@ -194,12 +182,13 @@ struct stm32_i2c_priv { + struct stm32_i2c_regs *regs; + struct clk clk; + struct stm32_i2c_setup *setup; +- int speed; ++ u32 speed; + }; + + static const struct stm32_i2c_spec i2c_specs[] = { +- [STM32_I2C_SPEED_STANDARD] = { +- .rate = STANDARD_RATE, ++ /* Standard speed - 100 KHz */ ++ [IC_SPEED_MODE_STANDARD] = { ++ .rate = I2C_SPEED_STANDARD_RATE, + .rate_min = 8000, + .rate_max = 120000, + .fall_max = 300, +@@ -210,8 +199,9 @@ static const struct stm32_i2c_spec i2c_specs[] = { + .l_min = 4700, + .h_min = 4000, + }, +- [STM32_I2C_SPEED_FAST] = { +- .rate = FAST_RATE, ++ /* Fast speed - 400 KHz */ ++ [IC_SPEED_MODE_FAST] = { ++ .rate = I2C_SPEED_FAST_RATE, + .rate_min = 320000, + .rate_max = 480000, + .fall_max = 300, +@@ -222,8 +212,9 @@ static const struct stm32_i2c_spec i2c_specs[] = { + .l_min = 1300, + .h_min = 600, + }, +- [STM32_I2C_SPEED_FAST_PLUS] = { +- .rate = FAST_PLUS_RATE, ++ /* Fast Plus Speed - 1 MHz */ ++ [IC_SPEED_MODE_FAST_PLUS] = { ++ .rate = I2C_SPEED_FAST_PLUS_RATE, + .rate_min = 800000, + .rate_max = 1200000, + .fall_max = 100, +@@ -484,6 +475,7 @@ static int stm32_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, + } + + static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, ++ const struct stm32_i2c_spec *specs, + struct list_head *solutions) + { + struct stm32_i2c_timings *v; +@@ -500,13 +492,13 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, + af_delay_max = setup->analog_filter ? + STM32_I2C_ANALOG_FILTER_DELAY_MAX : 0; + +- sdadel_min = i2c_specs[setup->speed].hddat_min + setup->fall_time - ++ sdadel_min = specs->hddat_min + setup->fall_time - + af_delay_min - (setup->dnf + 3) * i2cclk; + +- sdadel_max = i2c_specs[setup->speed].vddat_max - setup->rise_time - ++ sdadel_max = specs->vddat_max - setup->rise_time - + af_delay_max - (setup->dnf + 4) * i2cclk; + +- scldel_min = setup->rise_time + i2c_specs[setup->speed].sudat_min; ++ scldel_min = setup->rise_time + specs->sudat_min; + + if (sdadel_min < 0) + sdadel_min = 0; +@@ -558,6 +550,7 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, + } + + static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, ++ const struct stm32_i2c_spec *specs, + struct list_head *solutions, + struct stm32_i2c_timings *s) + { +@@ -580,8 +573,8 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, + dnf_delay = setup->dnf * i2cclk; + + tsync = af_delay_min + dnf_delay + (2 * i2cclk); +- clk_max = STM32_NSEC_PER_SEC / i2c_specs[setup->speed].rate_min; +- clk_min = STM32_NSEC_PER_SEC / i2c_specs[setup->speed].rate_max; ++ clk_max = STM32_NSEC_PER_SEC / specs->rate_min; ++ clk_min = STM32_NSEC_PER_SEC / specs->rate_max; + + /* + * Among Prescaler possibilities discovered above figures out SCL Low +@@ -599,7 +592,7 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, + for (l = 0; l < STM32_SCLL_MAX; l++) { + u32 tscl_l = (l + 1) * prescaler + tsync; + +- if ((tscl_l < i2c_specs[setup->speed].l_min) || ++ if (tscl_l < specs->l_min || + (i2cclk >= + ((tscl_l - af_delay_min - dnf_delay) / 4))) { + continue; +@@ -611,7 +604,7 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, + setup->rise_time + setup->fall_time; + + if ((tscl >= clk_min) && (tscl <= clk_max) && +- (tscl_h >= i2c_specs[setup->speed].h_min) && ++ (tscl_h >= specs->h_min) && + (i2cclk < tscl_h)) { + u32 clk_error; + +@@ -640,26 +633,40 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, + return ret; + } + ++static const struct stm32_i2c_spec *get_specs(u32 rate) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(i2c_specs); i++) ++ if (rate <= i2c_specs[i].rate) ++ return &i2c_specs[i]; ++ ++ /* NOT REACHED */ ++ return ERR_PTR(-EINVAL); ++} ++ + static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, + struct stm32_i2c_setup *setup, + struct stm32_i2c_timings *output) + { ++ const struct stm32_i2c_spec *specs; + struct stm32_i2c_timings *v, *_v; + struct list_head solutions; + int ret; + +- if (setup->speed >= STM32_I2C_SPEED_END) { +- pr_err("%s: speed out of bound {%d/%d}\n", __func__, +- setup->speed, STM32_I2C_SPEED_END - 1); ++ specs = get_specs(setup->speed_freq); ++ if (specs == ERR_PTR(-EINVAL)) { ++ pr_err("%s: speed out of bound {%d}\n", __func__, ++ setup->speed_freq); + return -EINVAL; + } + +- if ((setup->rise_time > i2c_specs[setup->speed].rise_max) || +- (setup->fall_time > i2c_specs[setup->speed].fall_max)) { ++ if (setup->rise_time > specs->rise_max || ++ setup->fall_time > specs->fall_max) { + pr_err("%s :timings out of bound Rise{%d>%d}/Fall{%d>%d}\n", + __func__, +- setup->rise_time, i2c_specs[setup->speed].rise_max, +- setup->fall_time, i2c_specs[setup->speed].fall_max); ++ setup->rise_time, specs->rise_max, ++ setup->fall_time, specs->fall_max); + return -EINVAL; + } + +@@ -669,18 +676,12 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, + return -EINVAL; + } + +- if (setup->speed_freq > i2c_specs[setup->speed].rate) { +- pr_err("%s: Freq {%d/%d}\n", __func__, +- setup->speed_freq, i2c_specs[setup->speed].rate); +- return -EINVAL; +- } +- + INIT_LIST_HEAD(&solutions); +- ret = stm32_i2c_compute_solutions(setup, &solutions); ++ ret = stm32_i2c_compute_solutions(setup, specs, &solutions); + if (ret) + goto exit; + +- ret = stm32_i2c_choose_solution(setup, &solutions, output); ++ ret = stm32_i2c_choose_solution(setup, specs, &solutions, output); + if (ret) + goto exit; + +@@ -699,14 +700,24 @@ exit: + return ret; + } + ++static u32 get_lower_rate(u32 rate) ++{ ++ int i; ++ ++ for (i = ARRAY_SIZE(i2c_specs) - 1; i >= 0; i--) ++ if (rate > i2c_specs[i].rate) ++ return i2c_specs[i].rate; ++ ++ return i2c_specs[0].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; + int ret = 0; + +- setup->speed = i2c_priv->speed; +- setup->speed_freq = i2c_specs[setup->speed].rate; ++ setup->speed_freq = i2c_priv->speed; + setup->clock_src = clk_get_rate(&i2c_priv->clk); + + if (!setup->clock_src) { +@@ -719,13 +730,11 @@ static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv, + if (ret) { + debug("%s: failed to compute I2C timings.\n", + __func__); +- if (i2c_priv->speed > STM32_I2C_SPEED_STANDARD) { +- i2c_priv->speed--; +- setup->speed = i2c_priv->speed; ++ if (setup->speed_freq > I2C_SPEED_STANDARD_RATE) { + setup->speed_freq = +- i2c_specs[setup->speed].rate; ++ get_lower_rate(setup->speed_freq); + debug("%s: downgrade I2C Speed Freq to (%i)\n", +- __func__, i2c_specs[setup->speed].rate); ++ __func__, setup->speed_freq); + } else { + break; + } +@@ -737,13 +746,15 @@ static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv, + return ret; + } + +- debug("%s: I2C Speed(%i), Freq(%i), Clk Source(%i)\n", __func__, +- setup->speed, setup->speed_freq, setup->clock_src); ++ debug("%s: I2C Freq(%i), Clk Source(%i)\n", __func__, ++ setup->speed_freq, setup->clock_src); + debug("%s: I2C Rise(%i) and Fall(%i) Time\n", __func__, + setup->rise_time, setup->fall_time); + debug("%s: I2C Analog Filter(%s), DNF(%i)\n", __func__, + setup->analog_filter ? "On" : "Off", setup->dnf); + ++ i2c_priv->speed = setup->speed_freq; ++ + return 0; + } + +@@ -783,21 +794,13 @@ static int stm32_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) + { + struct stm32_i2c_priv *i2c_priv = dev_get_priv(bus); + +- switch (speed) { +- case STANDARD_RATE: +- i2c_priv->speed = STM32_I2C_SPEED_STANDARD; +- break; +- case FAST_RATE: +- i2c_priv->speed = STM32_I2C_SPEED_FAST; +- break; +- case FAST_PLUS_RATE: +- i2c_priv->speed = STM32_I2C_SPEED_FAST_PLUS; +- break; +- default: ++ if (speed > I2C_SPEED_FAST_PLUS_RATE) { + debug("%s: Speed %d not supported\n", __func__, speed); + return -EINVAL; + } + ++ i2c_priv->speed = speed; ++ + return stm32_i2c_hw_config(i2c_priv); + } + +@@ -867,6 +870,7 @@ 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)&stm32f7_setup }, + {} + }; + +diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig +index 85c2a82..dbb3d81 100644 +--- a/drivers/mailbox/Kconfig ++++ b/drivers/mailbox/Kconfig +@@ -47,4 +47,11 @@ config ZYNQMP_IPI + help + This enables support for the Xilinx ZynqMP Inter Processor Interrupt + communication controller. ++ ++config ARM_SMC_MAILBOX ++ bool "Enable Arm SMC mailbox support" ++ depends on DM_MAILBOX && ARM_SMCCC ++ help ++ Mailbox notification through an Arm SMC or HVC calls. ++ + endmenu +diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile +index d2ace8c..7a56a45 100644 +--- a/drivers/mailbox/Makefile ++++ b/drivers/mailbox/Makefile +@@ -3,6 +3,7 @@ + # Copyright (c) 2016, NVIDIA CORPORATION. + # + ++obj-$(CONFIG_ARM_SMC_MAILBOX) += arm-smc-mbox.o + obj-$(CONFIG_$(SPL_)DM_MAILBOX) += mailbox-uclass.o + obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox.o + obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox-test.o +diff --git a/drivers/mailbox/arm-smc-mbox.c b/drivers/mailbox/arm-smc-mbox.c +new file mode 100644 +index 0000000..37f595a +--- /dev/null ++++ b/drivers/mailbox/arm-smc-mbox.c +@@ -0,0 +1,118 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2019, Linaro Limited ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#define ARM_SMC_METHOD 0 ++#define ARM_HVC_METHOD 1 ++ ++typedef void (invoke_fn_t)(unsigned long); ++ ++struct smc_pdata { ++ unsigned long func_id; ++ invoke_fn_t *invoke_fn; ++}; ++ ++/* Simple wrapper functions to be able to use a function pointer */ ++static void smccc_smc(unsigned long a0) ++{ ++ struct arm_smccc_res res; ++ ++ arm_smccc_smc(a0, 0, 0, 0, 0, 0, 0, 0, &res); ++} ++ ++static void smccc_hvc(unsigned long a0) ++{ ++ struct arm_smccc_res res; ++ ++ arm_smccc_hvc(a0, 0, 0, 0, 0, 0, 0, 0, &res); ++} ++ ++static int smc_mbox_send(struct mbox_chan *chan, const void *data) ++{ ++ struct smc_pdata *pdata = dev_get_platdata(chan->dev); ++ ++ /* ++ * This mailbox invokes secure world for a channel event. ++ * Message is already in the channel's shared memory. ++ */ ++ pdata->invoke_fn(pdata->func_id); ++ ++ return 0; ++} ++ ++static int smc_mbox_recv(struct mbox_chan *chan, void *data) ++{ ++ /* Mbox owner already got the return message from shared memory */ ++ return 0; ++} ++ ++static int smc_mbox_request(struct mbox_chan *chan) ++{ ++ return 0; ++} ++ ++static int smc_mbox_free(struct mbox_chan *chan) ++{ ++ return 0; ++} ++ ++static int smc_mbox_of_xlate(struct mbox_chan *chan, ++ struct ofnode_phandle_args *args) ++{ ++ if (args->args_count) ++ dev_warn(chan->dev, "Expect no argument to smc-mbox cells\n"); ++ ++ chan->id = 0; ++ ++ return 0; ++} ++ ++static int smc_mbox_ofdata_to_platdata(struct udevice *dev) ++{ ++ ulong compat_data = dev_get_driver_data(dev); ++ struct smc_pdata *pdata = dev_get_platdata(dev); ++ u32 func_id; ++ ++ if (dev_read_u32(dev, "arm,func-id", &func_id)) { ++ dev_err(dev, "Missing property arm,func-id\n"); ++ return -EINVAL; ++ } ++ ++ pdata->func_id = func_id; ++ ++ if (compat_data == ARM_SMC_METHOD) ++ pdata->invoke_fn = smccc_smc; ++ else ++ pdata->invoke_fn = smccc_hvc; ++ ++ return 0; ++} ++ ++static const struct udevice_id smc_mbox_ids[] = { ++ { .compatible = "arm,smc-mbox", .data = ARM_SMC_METHOD, }, ++ { .compatible = "arm,hvc-mbox", .data = ARM_HVC_METHOD, }, ++ { } ++}; ++ ++struct mbox_ops smc_mbox_ops = { ++ .of_xlate = smc_mbox_of_xlate, ++ .request = smc_mbox_request, ++ .free = smc_mbox_free, ++ .send = smc_mbox_send, ++ .recv = smc_mbox_recv, ++}; ++ ++U_BOOT_DRIVER(smc_mbox) = { ++ .name = "arm_smc_mbox", ++ .id = UCLASS_MAILBOX, ++ .of_match = smc_mbox_ids, ++ .ofdata_to_platdata = smc_mbox_ofdata_to_platdata, ++ .platdata_auto_alloc_size = sizeof(struct smc_pdata), ++ .ops = &smc_mbox_ops, ++}; +diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig +index 82bb093..547e144 100644 +--- a/drivers/misc/Kconfig ++++ b/drivers/misc/Kconfig +@@ -439,4 +439,16 @@ config K3_AVS0 + optimized voltage from the efuse, so that it can be programmed + to the PMIC on board. + ++config SCMI_AGENT ++ bool "Enable SCMI support" ++ select OF_TRANSLATE ++ help ++ An SCMI agent communicates with a related SCMI server 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, for example through a mailbox device ++ and some piece of identified shared memory. ++ + endmenu +diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile +index 55976d6..df7b3ed 100644 +--- a/drivers/misc/Makefile ++++ b/drivers/misc/Makefile +@@ -68,3 +68,4 @@ obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o + obj-$(CONFIG_JZ4780_EFUSE) += jz4780_efuse.o + obj-$(CONFIG_MICROCHIP_FLEXCOM) += microchip_flexcom.o + obj-$(CONFIG_K3_AVS0) += k3_avs.o ++obj-$(CONFIG_SCMI_AGENT) += scmi_agent.o +diff --git a/drivers/misc/scmi_agent.c b/drivers/misc/scmi_agent.c +new file mode 100644 +index 0000000..d36e460 +--- /dev/null ++++ b/drivers/misc/scmi_agent.c +@@ -0,0 +1,337 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. ++ * Copyright (C) 2019 Linaro Limited. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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(int32_t scmi_code) ++{ ++ int n; ++ ++ if (scmi_code == 0) ++ 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; ++} ++ ++struct method_ops { ++ int (*process_msg)(struct udevice *dev, struct scmi_msg *msg); ++ int (*remove_agent)(struct udevice *dev); ++}; ++ ++struct scmi_agent { ++ struct method_ops *method_ops; ++ void *method_priv; ++}; ++ ++/* ++ * Shared Memory based Transport (SMT) message buffer management ++ * ++ * 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_shm_buf { ++ u8 *buf; ++ size_t size; ++}; ++ ++static int get_shm_buffer(struct udevice *dev, struct scmi_shm_buf *shm) ++{ ++ int rc; ++ struct ofnode_phandle_args args; ++ struct resource resource; ++ fdt32_t faddr; ++ phys_addr_t paddr; ++ ++ rc = dev_read_phandle_with_args(dev, "shmem", NULL, 0, 0, &args); ++ if (rc) ++ return rc; ++ ++ rc = ofnode_read_resource(args.node, 0, &resource); ++ if (rc) ++ return rc; ++ ++ faddr = cpu_to_fdt32(resource.start); ++ paddr = ofnode_translate_address(args.node, &faddr); ++ ++ shm->size = resource_size(&resource); ++ if (shm->size < sizeof(struct scmi_smt_header)) { ++ dev_err(dev, "Shared memory buffer too small\n"); ++ return -EINVAL; ++ } ++ ++ shm->buf = devm_ioremap(dev, paddr, shm->size); ++ if (!shm->buf) ++ return -ENOMEM; ++ ++ if (dcache_status()) ++ mmu_set_region_dcache_behaviour((uintptr_t)shm->buf, ++ shm->size, DCACHE_OFF); ++ ++ return 0; ++} ++ ++/* ++ * Mailbox support ++ */ ++struct scmi_mbox_channel { ++ struct scmi_shm_buf shm_buf; ++ struct mbox_chan mbox; ++ ulong timeout_us; ++}; ++ ++static int mbox_process_msg(struct udevice *dev, struct scmi_msg *msg) ++{ ++ struct scmi_agent *agent = dev_get_priv(dev); ++ struct scmi_mbox_channel *chan = agent->method_priv; ++ struct scmi_smt_header *hdr = (void *)chan->shm_buf.buf; ++ int rc; ++ ++ /* Basic check-up */ ++ if (!(hdr->channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE)) { ++ dev_dbg(dev, "Channel busy\n"); ++ return -EBUSY; ++ } ++ ++ if ((!msg->in_msg && msg->in_msg_sz) || ++ (!msg->out_msg && msg->out_msg_sz)) ++ return -EINVAL; ++ ++ if (chan->shm_buf.size < (sizeof(*hdr) + msg->in_msg_sz) || ++ chan->shm_buf.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(hdr->msg_payload, msg->in_msg, msg->in_msg_sz); ++ ++ /* Give shm addr to mbox in case it is meaningful */ ++ rc = mbox_send(&chan->mbox, hdr); ++ if (rc) { ++ dev_err(dev, "Message send failed: %d\n", rc); ++ goto out; ++ } ++ ++ /* Receive the response */ ++ rc = mbox_recv(&chan->mbox, hdr, chan->timeout_us); ++ if (rc) { ++ dev_err(dev, "Response failed: %d, abort\n", rc); ++ goto out; ++ } ++ ++ /* Check the statuses */ ++ if (!(hdr->channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE)) { ++ dev_err(dev, "Channel unexpectedly busy, reset channel\n"); ++ rc = -ECOMM; ++ goto out; ++ } ++ ++ if (hdr->channel_status & SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR) { ++ dev_err(dev, "Channel error reported, reset channel\n"); ++ rc = -ECOMM; ++ goto out; ++ } ++ ++ if (hdr->length > msg->out_msg_sz + sizeof(hdr->msg_header)) { ++ dev_err(dev, "Buffer to small\n"); ++ rc = -ETOOSMALL; ++ goto out; ++ } ++ ++ /* Get the data */ ++ msg->out_msg_sz = hdr->length - sizeof(hdr->msg_header); ++ memcpy(msg->out_msg, hdr->msg_payload, msg->out_msg_sz); ++ ++out: ++ /* Free channel for further communication */ ++ hdr->channel_status |= SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE; ++ hdr->channel_status &= ~SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR; ++ ++ return rc; ++} ++ ++struct method_ops mbox_channel_ops = { ++ .process_msg = mbox_process_msg, ++}; ++ ++static int probe_smc_mailbox_channel(struct udevice *dev) ++{ ++ struct scmi_agent *agent = dev_get_priv(dev); ++ struct scmi_mbox_channel *chan; ++ int rc; ++ ++ chan = devm_kzalloc(dev, sizeof(*chan), GFP_KERNEL); ++ if (!chan) ++ return -ENOMEM; ++ ++ chan->timeout_us = 10000; ++ ++ rc = mbox_get_by_index(dev, 0, &chan->mbox); ++ if (rc) { ++ dev_err(dev, "Failed to find mailbox: %d\n", rc); ++ goto out; ++ } ++ ++ rc = get_shm_buffer(dev, &chan->shm_buf); ++ if (rc) ++ dev_err(dev, "Failed to get shm resources: %d\n", rc); ++ ++out: ++ if (rc) { ++ devm_kfree(dev, chan); ++ } else { ++ agent->method_ops = &mbox_channel_ops; ++ agent->method_priv = (void *)chan; ++ } ++ ++ return rc; ++} ++ ++/* ++ * Exported functions by the SCMI agent ++ */ ++ ++int scmi_agent_process_msg(struct udevice *dev, struct scmi_msg *msg) ++{ ++ struct scmi_agent *agent = dev_get_priv(dev); ++ ++ return agent->method_ops->process_msg(dev, msg); ++} ++ ++static int scmi_agent_remove(struct udevice *dev) ++{ ++ struct scmi_agent *agent = dev_get_priv(dev); ++ ++ if (agent->method_ops->remove_agent) ++ return agent->method_ops->remove_agent(dev); ++ ++ return 0; ++} ++ ++static int scmi_agent_probe(struct udevice *dev) ++{ ++ /* Only mailbox method supported for now */ ++ return probe_smc_mailbox_channel(dev); ++} ++ ++static int scmi_agent_bind(struct udevice *dev) ++{ ++ int rc = 0; ++ ofnode node; ++ struct driver *drv; ++ ++ dev_for_each_subnode(node, dev) { ++ 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: ++ drv = DM_GET_DRIVER(scmi_clock); ++ break; ++ case SCMI_PROTOCOL_ID_RESET_DOMAIN: ++ drv = DM_GET_DRIVER(scmi_reset_domain); ++ break; ++ default: ++ dev_info(dev, "Ignore unsupported SCMI protocol %u\n", ++ protocol_id); ++ continue; ++ } ++ ++ rc = device_bind_ofnode(dev, drv, ofnode_get_name(node), ++ NULL, node, NULL); ++ if (rc) ++ break; ++ } ++ ++ if (rc) ++ device_unbind(dev); ++ ++ return rc; ++} ++ ++static const struct udevice_id scmi_agent_ids[] = { ++ { .compatible = "arm,scmi", }, ++ { } ++}; ++ ++U_BOOT_DRIVER(scmi_agent) = { ++ .name = "scmi-agent", ++ .id = UCLASS_NOP, ++ .of_match = scmi_agent_ids, ++ .priv_auto_alloc_size = sizeof(struct scmi_agent), ++ .bind = scmi_agent_bind, ++ .probe = scmi_agent_probe, ++ .remove = scmi_agent_remove, ++ .flags = DM_FLAG_OS_PREPARE, ++}; +diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c +index 0a7a2fe..9ad0504 100644 +--- a/drivers/mmc/stm32_sdmmc2.c ++++ b/drivers/mmc/stm32_sdmmc2.c +@@ -673,7 +673,7 @@ static int stm32_sdmmc2_probe(struct udevice *dev) + cfg->f_max = dev_read_u32_default(dev, "max-frequency", 52000000); + 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 SDMMC2"; ++ cfg->name = "STM32 SD/MMC"; + + cfg->host_caps = 0; + if (cfg->f_max > 25000000) +diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig +index 5e7571c..348b43e 100644 +--- a/drivers/mtd/Kconfig ++++ b/drivers/mtd/Kconfig +@@ -22,6 +22,13 @@ config MTD_NOR_FLASH + help + Enable support for parallel NOR flash. + ++config SYS_MTDPARTS_RUNTIME ++ bool "Allow MTDPARTS to be configured at runtime" ++ depends on MTD ++ help ++ This option allows to call the function board_mtdparts_default to ++ dynamically build the variables mtdids and mtdparts at runtime. ++ + config FLASH_CFI_DRIVER + bool "Enable CFI Flash driver" + help +diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c +index 4632111..fad7810 100644 +--- a/drivers/net/dwc_eth_qos.c ++++ b/drivers/net/dwc_eth_qos.c +@@ -305,6 +305,8 @@ 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; + struct eqos_desc *rx_descs; +@@ -693,6 +695,29 @@ static int eqos_start_resets_tegra186(struct udevice *dev) + + 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; + } + +@@ -708,6 +733,18 @@ static int eqos_stop_resets_tegra186(struct udevice *dev) + + 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; + } + +@@ -1045,12 +1082,21 @@ static int eqos_start(struct udevice *dev) + * don't need to reconnect/reconfigure again + */ + if (!eqos->phy) { +- eqos->phy = phy_connect(eqos->mii, -1, dev, ++ eqos->phy = phy_connect(eqos->mii, eqos->phyaddr, dev, + eqos->config->interface(dev)); + if (!eqos->phy) { + pr_err("phy_connect() failed"); + goto err_stop_resets; + } ++ ++ if (eqos->max_speed) { ++ ret = phy_set_supported(eqos->phy, eqos->max_speed); ++ if (ret) { ++ pr_err("phy_set_supported() failed: %d", ret); ++ goto err_shutdown_phy; ++ } ++ } ++ + ret = phy_config(eqos->phy); + if (ret < 0) { + pr_err("phy_config() failed: %d", ret); +@@ -1603,6 +1649,9 @@ 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; ++ /* Hardcode for now */ ++ eqos->phyaddr = -1; + + debug("%s(dev=%p):\n", __func__, dev); + +@@ -1617,6 +1666,8 @@ static int eqos_probe_resources_stm32(struct udevice *dev) + if (ret) + return -EINVAL; + ++ eqos->max_speed = dev_read_u32_default(dev, "max-speed", 0); ++ + ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus); + if (ret) { + pr_err("clk_get_by_name(master_bus) failed: %d", ret); +@@ -1640,6 +1691,23 @@ static int eqos_probe_resources_stm32(struct udevice *dev) + if (ret) + pr_warn("No phy clock provided %d", ret); + ++ 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; + +@@ -1703,6 +1771,9 @@ static int eqos_remove_resources_stm32(struct udevice *dev) + if (clk_valid(&eqos->clk_ck)) + clk_free(&eqos->clk_ck); + ++ if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) ++ dm_gpio_free(dev, &eqos->phy_reset_gpio); ++ + debug("%s: OK\n", __func__); + return 0; + } +diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c +index 6f11190..c122608 100644 +--- a/drivers/phy/phy-stm32-usbphyc.c ++++ b/drivers/phy/phy-stm32-usbphyc.c +@@ -260,7 +260,7 @@ static int stm32_usbphyc_phy_power_off(struct phy *phy) + return 0; + + if (usbphyc_phy->vdd) { +- ret = regulator_set_enable(usbphyc_phy->vdd, false); ++ ret = regulator_set_enable_if_allowed(usbphyc_phy->vdd, false); + if (ret) + return ret; + } +diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c +index e201a90..363985b 100644 +--- a/drivers/phy/phy-uclass.c ++++ b/drivers/phy/phy-uclass.c +@@ -109,56 +109,86 @@ int generic_phy_get_by_name(struct udevice *dev, const char *phy_name, + int generic_phy_init(struct phy *phy) + { + struct phy_ops const *ops; ++ int ret; + + if (!phy) + return 0; + ops = phy_dev_ops(phy->dev); + +- return ops->init ? ops->init(phy) : 0; ++ ret = ops->init ? ops->init(phy) : 0; ++ if (ret) ++ dev_err(phy->dev, "PHY: Failed to init %s: %d.\n", ++ phy->dev->name, ret); ++ ++ return ret; + } + + int generic_phy_reset(struct phy *phy) + { + struct phy_ops const *ops; ++ int ret; + + if (!phy) + return 0; + ops = phy_dev_ops(phy->dev); + +- return ops->reset ? ops->reset(phy) : 0; ++ ret = ops->reset ? ops->reset(phy) : 0; ++ if (ret) ++ dev_err(phy->dev, "PHY: Failed to reset %s: %d.\n", ++ phy->dev->name, ret); ++ ++ return ret; + } + + int generic_phy_exit(struct phy *phy) + { + struct phy_ops const *ops; ++ int ret; + + if (!phy) + return 0; + ops = phy_dev_ops(phy->dev); + +- return ops->exit ? ops->exit(phy) : 0; ++ ret = ops->exit ? ops->exit(phy) : 0; ++ if (ret) ++ dev_err(phy->dev, "PHY: Failed to exit %s: %d.\n", ++ phy->dev->name, ret); ++ ++ return ret; + } + + int generic_phy_power_on(struct phy *phy) + { + struct phy_ops const *ops; ++ int ret; + + if (!phy) + return 0; + ops = phy_dev_ops(phy->dev); + +- return ops->power_on ? ops->power_on(phy) : 0; ++ ret = ops->power_on ? ops->power_on(phy) : 0; ++ if (ret) ++ dev_err(phy->dev, "PHY: Failed to power on %s: %d.\n", ++ phy->dev->name, ret); ++ ++ return ret; + } + + int generic_phy_power_off(struct phy *phy) + { + struct phy_ops const *ops; ++ int ret; + + if (!phy) + return 0; + ops = phy_dev_ops(phy->dev); + +- return ops->power_off ? ops->power_off(phy) : 0; ++ ret = ops->power_off ? ops->power_off(phy) : 0; ++ if (ret) ++ dev_err(phy->dev, "PHY: Failed to power off %s: %d.\n", ++ phy->dev->name, ret); ++ ++ return ret; + } + + UCLASS_DRIVER(phy) = { +diff --git a/drivers/pinctrl/pinctrl-generic.c b/drivers/pinctrl/pinctrl-generic.c +index eecf0f5..9c4f73b 100644 +--- a/drivers/pinctrl/pinctrl-generic.c ++++ b/drivers/pinctrl/pinctrl-generic.c +@@ -8,8 +8,6 @@ + #include + #include + +-DECLARE_GLOBAL_DATA_PTR; +- + /** + * pinctrl_pin_name_to_selector() - return the pin selector for a pin + * +@@ -243,18 +241,14 @@ static int pinctrl_generic_set_state_one(struct udevice *dev, + struct udevice *config, + bool is_group, unsigned selector) + { +- const void *fdt = gd->fdt_blob; +- int node_offset = dev_of_offset(config); + const char *propname; + const void *value; +- int prop_offset, len, func_selector, param, ret; ++ struct ofprop property; ++ int len, func_selector, param, ret; + u32 arg, default_val; + +- for (prop_offset = fdt_first_property_offset(fdt, node_offset); +- prop_offset > 0; +- prop_offset = fdt_next_property_offset(fdt, prop_offset)) { +- value = fdt_getprop_by_offset(fdt, prop_offset, +- &propname, &len); ++ dev_for_each_property(property, config) { ++ value = dev_read_prop_by_prop(&property, &propname, &len); + if (!value) + return -EINVAL; + +@@ -298,19 +292,17 @@ static int pinctrl_generic_set_state_one(struct udevice *dev, + static int pinctrl_generic_set_state_subnode(struct udevice *dev, + struct udevice *config) + { +- const void *fdt = gd->fdt_blob; +- int node = dev_of_offset(config); + const char *subnode_target_type = "pins"; + bool is_group = false; + const char *name; + int strings_count, selector, i, ret; + +- strings_count = fdt_stringlist_count(fdt, node, subnode_target_type); ++ strings_count = dev_read_string_count(config, subnode_target_type); + if (strings_count < 0) { + subnode_target_type = "groups"; + is_group = true; +- strings_count = fdt_stringlist_count(fdt, node, +- subnode_target_type); ++ strings_count = dev_read_string_count(config, ++ subnode_target_type); + if (strings_count < 0) { + /* skip this node; may contain config child nodes */ + return 0; +@@ -318,10 +310,10 @@ static int pinctrl_generic_set_state_subnode(struct udevice *dev, + } + + for (i = 0; i < strings_count; i++) { +- name = fdt_stringlist_get(fdt, node, subnode_target_type, i, +- NULL); +- if (!name) +- return -EINVAL; ++ ret = dev_read_string_index(config, subnode_target_type, i, ++ &name); ++ if (ret) ++ return ret; + + if (is_group) + selector = pinctrl_group_name_to_selector(dev, name); +diff --git a/drivers/pinctrl/pinctrl-sandbox.c b/drivers/pinctrl/pinctrl-sandbox.c +index 0786afe..3ee75fb 100644 +--- a/drivers/pinctrl/pinctrl-sandbox.c ++++ b/drivers/pinctrl/pinctrl-sandbox.c +@@ -14,7 +14,11 @@ static const char * const sandbox_pins[] = { + "SDA", + "TX", + "RX", +- "W1" ++ "W1", ++ "GPIO0", ++ "GPIO1", ++ "GPIO2", ++ "GPIO3", + }; + + static const char * const sandbox_pins_muxing[] = { +@@ -23,6 +27,10 @@ static const char * const sandbox_pins_muxing[] = { + "Uart TX", + "Uart RX", + "1-wire gpio", ++ "gpio", ++ "gpio", ++ "gpio", ++ "gpio", + }; + + static const char * const sandbox_groups[] = { +@@ -38,6 +46,10 @@ static const char * const sandbox_functions[] = { + "serial", + "spi", + "w1", ++ "gpio", ++ "gpio", ++ "gpio", ++ "gpio", + }; + + static const struct pinconf_param sandbox_conf_params[] = { +@@ -54,6 +66,10 @@ static const struct pinconf_param sandbox_conf_params[] = { + { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 }, + }; + ++/* bitfield used to save param and value of each pin/selector */ ++static unsigned int sandbox_pins_param[ARRAY_SIZE(sandbox_pins)]; ++static unsigned int sandbox_pins_value[ARRAY_SIZE(sandbox_pins)]; ++ + static int sandbox_get_pins_count(struct udevice *dev) + { + return ARRAY_SIZE(sandbox_pins); +@@ -68,8 +84,25 @@ static int sandbox_get_pin_muxing(struct udevice *dev, + unsigned int selector, + char *buf, int size) + { ++ const struct pinconf_param *p; ++ int i; ++ + snprintf(buf, size, "%s", sandbox_pins_muxing[selector]); + ++ if (sandbox_pins_param[selector]) { ++ for (i = 0, p = sandbox_conf_params; ++ i < ARRAY_SIZE(sandbox_conf_params); ++ i++, p++) { ++ if ((sandbox_pins_param[selector] & BIT(p->param)) && ++ (!!(sandbox_pins_value[selector] & BIT(p->param)) == ++ p->default_value)) { ++ strncat(buf, " ", size); ++ strncat(buf, p->property, size); ++ } ++ } ++ } ++ strncat(buf, ".", size); ++ + return 0; + } + +@@ -102,6 +135,9 @@ static int sandbox_pinmux_set(struct udevice *dev, unsigned pin_selector, + pin_selector, sandbox_get_pin_name(dev, pin_selector), + func_selector, sandbox_get_function_name(dev, func_selector)); + ++ sandbox_pins_param[pin_selector] = 0; ++ sandbox_pins_value[pin_selector] = 0; ++ + return 0; + } + +@@ -123,6 +159,12 @@ static int sandbox_pinconf_set(struct udevice *dev, unsigned pin_selector, + pin_selector, sandbox_get_pin_name(dev, pin_selector), + param, argument); + ++ sandbox_pins_param[pin_selector] |= BIT(param); ++ if (argument) ++ sandbox_pins_value[pin_selector] |= BIT(param); ++ else ++ sandbox_pins_value[pin_selector] &= ~BIT(param); ++ + return 0; + } + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index 1dfc97d..6d8f989 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -9,8 +9,6 @@ + #include + #include + +-DECLARE_GLOBAL_DATA_PTR; +- + struct single_pdata { + fdt_addr_t base; /* first configuration register */ + int offset; /* index of last configuration register */ +@@ -117,13 +115,11 @@ static int single_configure_bits(struct udevice *dev, + static int single_set_state(struct udevice *dev, + struct udevice *config) + { +- const void *fdt = gd->fdt_blob; + const struct single_fdt_pin_cfg *prop; + const struct single_fdt_bits_cfg *prop_bits; + int len; + +- prop = fdt_getprop(fdt, dev_of_offset(config), "pinctrl-single,pins", +- &len); ++ prop = dev_read_prop(dev, "pinctrl-single,pins", &len); + + if (prop) { + dev_dbg(dev, "configuring pins for %s\n", config->name); +@@ -136,9 +132,7 @@ static int single_set_state(struct udevice *dev, + } + + /* pinctrl-single,pins not found so check for pinctrl-single,bits */ +- prop_bits = fdt_getprop(fdt, dev_of_offset(config), +- "pinctrl-single,bits", +- &len); ++ prop_bits = dev_read_prop(dev, "pinctrl-single,bits", &len); + if (prop_bits) { + dev_dbg(dev, "configuring pins for %s\n", config->name); + if (len % sizeof(struct single_fdt_bits_cfg)) { +@@ -160,27 +154,24 @@ static int single_ofdata_to_platdata(struct udevice *dev) + int res; + struct single_pdata *pdata = dev->platdata; + +- pdata->width = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), +- "pinctrl-single,register-width", 0); ++ pdata->width = ++ dev_read_u32_default(dev, "pinctrl-single,register-width", 0); + +- res = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), +- "reg", of_reg, 2); ++ res = dev_read_u32_array(dev, "reg", of_reg, 2); + if (res) + return res; + pdata->offset = of_reg[1] - pdata->width / 8; + +- addr = devfdt_get_addr(dev); ++ addr = dev_read_addr(dev); + if (addr == FDT_ADDR_T_NONE) { + dev_dbg(dev, "no valid base register address\n"); + return -EINVAL; + } + pdata->base = addr; + +- pdata->mask = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), +- "pinctrl-single,function-mask", +- 0xffffffff); +- pdata->bits_per_mux = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev), +- "pinctrl-single,bit-per-mux"); ++ pdata->mask = dev_read_u32_default(dev, "pinctrl-single,function-mask", ++ 0xffffffff); ++ pdata->bits_per_mux = dev_read_bool(dev, "pinctrl-single,bit-per-mux"); + + return 0; + } +diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c +index 0b5a043..b7987d5 100644 +--- a/drivers/pinctrl/pinctrl-stmfx.c ++++ b/drivers/pinctrl/pinctrl-stmfx.c +@@ -71,17 +71,61 @@ static int stmfx_write(struct udevice *dev, uint offset, unsigned int val) + return dm_i2c_reg_write(dev_get_parent(dev), offset, val); + } + +-static int stmfx_gpio_get(struct udevice *dev, unsigned int offset) ++static int stmfx_read_reg(struct udevice *dev, u8 reg_base, uint offset) + { +- u32 reg = STMFX_REG_GPIO_STATE + get_reg(offset); ++ u8 reg = reg_base + get_reg(offset); + u32 mask = get_mask(offset); + int ret; + + ret = stmfx_read(dev, reg); ++ if (ret < 0) ++ return ret; + + return ret < 0 ? ret : !!(ret & mask); + } + ++static int stmfx_write_reg(struct udevice *dev, u8 reg_base, uint offset, ++ uint val) ++{ ++ u8 reg = reg_base + get_reg(offset); ++ u32 mask = get_mask(offset); ++ int ret; ++ ++ ret = stmfx_read(dev, reg); ++ if (ret < 0) ++ return ret; ++ ret = (ret & ~mask) | (val ? mask : 0); ++ ++ return stmfx_write(dev, reg, ret); ++} ++ ++static int stmfx_conf_set_pupd(struct udevice *dev, ++ unsigned int offset, uint pupd) ++{ ++ return stmfx_write_reg(dev, STMFX_REG_GPIO_PUPD, offset, pupd); ++} ++ ++static int stmfx_conf_get_pupd(struct udevice *dev, unsigned int offset) ++{ ++ return stmfx_read_reg(dev, STMFX_REG_GPIO_PUPD, offset); ++} ++ ++static int stmfx_conf_set_type(struct udevice *dev, ++ unsigned int offset, uint type) ++{ ++ return stmfx_write_reg(dev, STMFX_REG_GPIO_TYPE, offset, type); ++} ++ ++static int stmfx_conf_get_type(struct udevice *dev, unsigned int offset) ++{ ++ return stmfx_read_reg(dev, STMFX_REG_GPIO_TYPE, offset); ++} ++ ++static int stmfx_gpio_get(struct udevice *dev, unsigned int offset) ++{ ++ return stmfx_read_reg(dev, STMFX_REG_GPIO_STATE, offset); ++} ++ + static int stmfx_gpio_set(struct udevice *dev, unsigned int offset, int value) + { + u32 reg = value ? STMFX_REG_GPO_SET : STMFX_REG_GPO_CLR; +@@ -92,50 +136,103 @@ static int stmfx_gpio_set(struct udevice *dev, unsigned int offset, int value) + + static int stmfx_gpio_get_function(struct udevice *dev, unsigned int offset) + { +- u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset); +- u32 mask = get_mask(offset); +- int ret; +- +- ret = stmfx_read(dev, reg); ++ int ret = stmfx_read_reg(dev, STMFX_REG_GPIO_DIR, offset); + + if (ret < 0) + return ret; + /* On stmfx, gpio pins direction is (0)input, (1)output. */ + +- return ret & mask ? GPIOF_OUTPUT : GPIOF_INPUT; ++ return ret ? GPIOF_OUTPUT : GPIOF_INPUT; + } + + static int stmfx_gpio_direction_input(struct udevice *dev, unsigned int offset) + { +- u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset); +- u32 mask = get_mask(offset); +- int ret; ++ return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 0); ++} + +- ret = stmfx_read(dev, reg); ++static int stmfx_gpio_direction_output(struct udevice *dev, ++ unsigned int offset, int value) ++{ ++ int ret = stmfx_gpio_set(dev, offset, value); + if (ret < 0) + return ret; + +- ret &= ~mask; ++ return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 1); ++} + +- return stmfx_write(dev, reg, ret & ~mask); ++static int stmfx_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, ++ ulong flags) ++{ ++ int ret = -ENOTSUPP; ++ ++ if (flags & GPIOD_IS_OUT) { ++ if (flags & GPIOD_OPEN_SOURCE) ++ return -ENOTSUPP; ++ if (flags & GPIOD_OPEN_DRAIN) ++ ret = stmfx_conf_set_type(dev, offset, 0); ++ else /* PUSH-PULL */ ++ ret = stmfx_conf_set_type(dev, offset, 1); ++ if (ret) ++ return ret; ++ ret = stmfx_gpio_direction_output(dev, offset, ++ GPIOD_FLAGS_OUTPUT(flags)); ++ } else if (flags & GPIOD_IS_IN) { ++ ret = stmfx_gpio_direction_input(dev, offset); ++ if (ret) ++ return ret; ++ if (flags & GPIOD_PULL_UP) { ++ ret = stmfx_conf_set_type(dev, offset, 1); ++ if (ret) ++ return ret; ++ ret = stmfx_conf_set_pupd(dev, offset, 1); ++ } else if (flags & GPIOD_PULL_DOWN) { ++ ret = stmfx_conf_set_type(dev, offset, 1); ++ if (ret) ++ return ret; ++ ret = stmfx_conf_set_pupd(dev, offset, 0); ++ } ++ } ++ ++ return ret; + } + +-static int stmfx_gpio_direction_output(struct udevice *dev, +- unsigned int offset, int value) ++static int stmfx_gpio_get_dir_flags(struct udevice *dev, unsigned int offset, ++ ulong *flags) + { +- u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset); +- u32 mask = get_mask(offset); ++ ulong dir_flags = 0; + int ret; + +- ret = stmfx_gpio_set(dev, offset, value); +- if (ret < 0) +- return ret; +- +- ret = stmfx_read(dev, reg); +- if (ret < 0) +- return ret; ++ if (stmfx_gpio_get_function(dev, offset) == GPIOF_OUTPUT) { ++ dir_flags |= GPIOD_IS_OUT; ++ ret = stmfx_conf_get_type(dev, offset); ++ if (ret < 0) ++ return ret; ++ if (ret == 0) ++ dir_flags |= GPIOD_OPEN_DRAIN; ++ /* 1 = push-pull (default), open source not supported */ ++ ret = stmfx_gpio_get(dev, offset); ++ if (ret < 0) ++ return ret; ++ if (ret) ++ dir_flags |= GPIOD_IS_OUT_ACTIVE; ++ } else { ++ dir_flags |= GPIOD_IS_IN; ++ ret = stmfx_conf_get_type(dev, offset); ++ if (ret < 0) ++ return ret; ++ if (ret == 1) { ++ ret = stmfx_conf_get_pupd(dev, offset); ++ if (ret < 0) ++ return ret; ++ if (ret == 1) ++ dir_flags |= GPIOD_PULL_UP; ++ else ++ dir_flags |= GPIOD_PULL_DOWN; ++ } ++ } ++ *flags = dir_flags; + +- return stmfx_write(dev, reg, ret | mask); ++ return 0; + } + + static int stmfx_gpio_probe(struct udevice *dev) +@@ -166,6 +263,8 @@ static const struct dm_gpio_ops stmfx_gpio_ops = { + .get_function = stmfx_gpio_get_function, + .direction_input = stmfx_gpio_direction_input, + .direction_output = stmfx_gpio_direction_output, ++ .set_dir_flags = stmfx_gpio_set_dir_flags, ++ .get_dir_flags = stmfx_gpio_get_dir_flags, + }; + + U_BOOT_DRIVER(stmfx_gpio) = { +@@ -187,36 +286,6 @@ static const struct pinconf_param stmfx_pinctrl_conf_params[] = { + { "output-low", PIN_CONFIG_OUTPUT, 0 }, + }; + +-static int stmfx_pinctrl_set_pupd(struct udevice *dev, +- unsigned int pin, u32 pupd) +-{ +- u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin); +- u32 mask = get_mask(pin); +- int ret; +- +- ret = stmfx_read(dev, reg); +- if (ret < 0) +- return ret; +- ret = (ret & ~mask) | (pupd ? mask : 0); +- +- return stmfx_write(dev, reg, ret); +-} +- +-static int stmfx_pinctrl_set_type(struct udevice *dev, +- unsigned int pin, u32 type) +-{ +- u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin); +- u32 mask = get_mask(pin); +- int ret; +- +- ret = stmfx_read(dev, reg); +- if (ret < 0) +- return ret; +- ret = (ret & ~mask) | (type ? mask : 0); +- +- return stmfx_write(dev, reg, ret); +-} +- + static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin, + unsigned int param, unsigned int arg) + { +@@ -232,22 +301,22 @@ static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin, + case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_DRIVE_PUSH_PULL: +- ret = stmfx_pinctrl_set_type(dev, pin, 0); ++ ret = stmfx_conf_set_type(dev, pin, 0); + break; + case PIN_CONFIG_BIAS_PULL_DOWN: +- ret = stmfx_pinctrl_set_type(dev, pin, 1); ++ ret = stmfx_conf_set_type(dev, pin, 1); + if (ret) + return ret; +- ret = stmfx_pinctrl_set_pupd(dev, pin, 0); ++ ret = stmfx_conf_set_pupd(dev, pin, 0); + break; + case PIN_CONFIG_BIAS_PULL_UP: +- ret = stmfx_pinctrl_set_type(dev, pin, 1); ++ ret = stmfx_conf_set_type(dev, pin, 1); + if (ret) + return ret; +- ret = stmfx_pinctrl_set_pupd(dev, pin, 1); ++ ret = stmfx_conf_set_pupd(dev, pin, 1); + break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: +- ret = stmfx_pinctrl_set_type(dev, pin, 1); ++ ret = stmfx_conf_set_type(dev, pin, 1); + break; + case PIN_CONFIG_OUTPUT: + ret = stmfx_gpio_direction_output(plat->gpio, pin, arg); +@@ -286,6 +355,34 @@ static const char *stmfx_pinctrl_get_pin_name(struct udevice *dev, + return pin_name; + } + ++static const char *stmfx_pinctrl_get_pin_conf(struct udevice *dev, ++ unsigned int pin, int func) ++{ ++ int pupd, type; ++ ++ type = stmfx_conf_get_type(dev, pin); ++ if (type < 0) ++ return ""; ++ ++ if (func == GPIOF_OUTPUT) { ++ if (type) ++ return "drive-open-drain"; ++ else ++ return ""; /* default: push-pull*/ ++ } ++ if (!type) ++ return ""; /* default: bias-disable*/ ++ ++ pupd = stmfx_conf_get_pupd(dev, pin); ++ if (pupd < 0) ++ return ""; ++ ++ if (pupd) ++ return "bias-pull-up"; ++ else ++ return "bias-pull-down"; ++} ++ + static int stmfx_pinctrl_get_pin_muxing(struct udevice *dev, + unsigned int selector, + char *buf, int size) +@@ -297,7 +394,9 @@ static int stmfx_pinctrl_get_pin_muxing(struct udevice *dev, + if (func < 0) + return func; + +- snprintf(buf, size, "%s", func == GPIOF_INPUT ? "input" : "output"); ++ snprintf(buf, size, "%s ", func == GPIOF_INPUT ? "input" : "output"); ++ ++ strncat(buf, stmfx_pinctrl_get_pin_conf(dev, selector, func), size); + + return 0; + } +@@ -351,11 +450,12 @@ static int stmfx_chip_init(struct udevice *dev) + int ret; + struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); + +- id = dm_i2c_reg_read(dev, STMFX_REG_CHIP_ID); +- if (id < 0) { +- dev_err(dev, "error reading chip id: %d\n", id); ++ ret = dm_i2c_reg_read(dev, STMFX_REG_CHIP_ID); ++ if (ret < 0) { ++ dev_err(dev, "error reading chip id: %d\n", ret); + return ret; + } ++ id = (u8)ret; + /* + * Check that ID is the complement of the I2C address: + * STMFX I2C address follows the 7-bit format (MSB), that's why +diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c +index 3a235ae..4511cd7 100644 +--- a/drivers/pinctrl/pinctrl_stm32.c ++++ b/drivers/pinctrl/pinctrl_stm32.c +@@ -39,6 +39,17 @@ 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_input[] = { ++ [STM32_GPIO_OTYPE_PP] = "drive-push-pull", ++ [STM32_GPIO_OTYPE_OD] = "drive-open-drain", ++}; ++ + static int stm32_pinctrl_get_af(struct udevice *dev, unsigned int offset) + { + struct stm32_gpio_priv *priv = dev_get_priv(dev); +@@ -176,10 +187,12 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, + int size) + { + struct udevice *gpio_dev; ++ struct stm32_gpio_priv *priv; + const char *label; + int mode; + int af_num; + unsigned int gpio_idx; ++ u32 pupd, otype; + + /* look up for the bank which owns the requested pin */ + gpio_dev = stm32_pinctrl_get_gpio_dev(dev, selector, &gpio_idx); +@@ -188,9 +201,9 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, + return -ENODEV; + + 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); ++ priv = dev_get_priv(gpio_dev); + + + switch (mode) { +@@ -205,9 +218,17 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, + snprintf(buf, size, "%s %d", pinmux_mode[mode], af_num); + 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 : ""); ++ break; + case GPIOF_INPUT: +- snprintf(buf, size, "%s %s", +- pinmux_mode[mode], label ? label : ""); ++ otype = (readl(&priv->regs->otyper) >> gpio_idx) & OTYPE_MSK; ++ snprintf(buf, size, "%s %s %s", ++ pinmux_mode[mode], pinmux_input[otype], ++ label ? label : ""); + break; + } + +diff --git a/drivers/power/regulator/stm32-vrefbuf.c b/drivers/power/regulator/stm32-vrefbuf.c +index 645528e..c8ff6a1 100644 +--- a/drivers/power/regulator/stm32-vrefbuf.c ++++ b/drivers/power/regulator/stm32-vrefbuf.c +@@ -41,8 +41,20 @@ static int stm32_vrefbuf_set_enable(struct udevice *dev, bool enable) + u32 val; + int ret; + +- clrsetbits_le32(priv->base + STM32_VREFBUF_CSR, STM32_HIZ | STM32_ENVR, +- enable ? STM32_ENVR : STM32_HIZ); ++ if (enable && !(readl(priv->base + STM32_VREFBUF_CSR) & STM32_ENVR)) { ++ /* ++ * There maybe an overshoot: ++ * - when disabling, then re-enabling vrefbuf too quickly ++ * - or upon platform reset as external capacitor maybe slow ++ * discharging (VREFBUF is HiZ at reset by default). ++ * So force active discharge (HiZ=0) for 1ms before enabling. ++ */ ++ clrbits_le32(priv->base + STM32_VREFBUF_CSR, STM32_HIZ); ++ udelay(1000); ++ } ++ ++ clrsetbits_le32(priv->base + STM32_VREFBUF_CSR, STM32_ENVR, ++ enable ? STM32_ENVR : 0); + if (!enable) + return 0; + +diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c +index d765a46..11b14ae 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_ddr.c ++++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c +@@ -639,7 +639,8 @@ void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl) + start_sw_done(ctl); + /* quasi-dynamic register update*/ + setbits_le32(&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH); +- clrbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN); ++ clrbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN | ++ DDRCTRL_PWRCTL_SELFREF_EN); + clrbits_le32(&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); + wait_sw_done_ack(ctl); + } +@@ -652,6 +653,8 @@ void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl, + clrbits_le32(&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH); + if (pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN) + setbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN); ++ if ((pwrctl & DDRCTRL_PWRCTL_SELFREF_EN)) ++ setbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_EN); + setbits_le32(&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); + wait_sw_done_ack(ctl); + } +@@ -668,14 +671,34 @@ void stm32mp1_ddr_init(struct ddr_info *priv, + { + u32 pir; + int ret = -EINVAL; ++ char bus_width; ++ ++ switch (config->c_reg.mstr & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) { ++ case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER: ++ bus_width = 8; ++ break; ++ case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF: ++ bus_width = 16; ++ break; ++ default: ++ bus_width = 32; ++ break; ++ } ++ + + if (config->c_reg.mstr & DDRCTRL_MSTR_DDR3) + ret = board_ddr_power_init(STM32MP_DDR3); +- else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2) +- ret = board_ddr_power_init(STM32MP_LPDDR2); +- else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3) +- ret = board_ddr_power_init(STM32MP_LPDDR3); +- ++ else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2) { ++ if (bus_width == 32) ++ ret = board_ddr_power_init(STM32MP_LPDDR2_32); ++ else ++ ret = board_ddr_power_init(STM32MP_LPDDR2_16); ++ } else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3) { ++ if (bus_width == 32) ++ ret = board_ddr_power_init(STM32MP_LPDDR3_32); ++ else ++ ret = board_ddr_power_init(STM32MP_LPDDR3_16); ++ } + if (ret) + panic("ddr power init failed\n"); + +@@ -746,7 +769,8 @@ start: + */ + set_reg(priv, REGPHY_REG, &config->p_reg); + set_reg(priv, REGPHY_TIMING, &config->p_timing); +- set_reg(priv, REGPHY_CAL, &config->p_cal); ++ if (config->p_cal_present) ++ set_reg(priv, REGPHY_CAL, &config->p_cal); + + if (INTERACTIVE(STEP_PHY_INIT)) + goto start; +@@ -781,13 +805,16 @@ start: + + wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL); + +- debug("DDR DQS training : "); ++ if (config->p_cal_present) { ++ debug("DDR DQS training skipped.\n"); ++ } else { ++ 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 +@@ -795,14 +822,15 @@ 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); ++ stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_QSTRN); + + /* 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); ++ stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3, ++ config->c_reg.pwrctl); ++ } /* if (config->p_cal_present) */ + + /* 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 52b748f..4998f04 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_ddr.h ++++ b/drivers/ram/stm32mp1/stm32mp1_ddr.h +@@ -170,6 +170,7 @@ struct stm32mp1_ddr_config { + 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); +diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h +index 9d33186..afd93c5 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h ++++ b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h +@@ -260,6 +260,7 @@ struct stm32mp1_ddrphy { + + #define DDRCTRL_MRSTAT_MR_WR_BUSY BIT(0) + ++#define DDRCTRL_PWRCTL_SELFREF_EN BIT(0) + #define DDRCTRL_PWRCTL_POWERDOWN_EN BIT(1) + #define DDRCTRL_PWRCTL_SELFREF_SW BIT(5) + +diff --git a/drivers/ram/stm32mp1/stm32mp1_interactive.c b/drivers/ram/stm32mp1/stm32mp1_interactive.c +index cc9b2e7..805c9dd 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_interactive.c ++++ b/drivers/ram/stm32mp1/stm32mp1_interactive.c +@@ -106,7 +106,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 or speed\n" ++ " with = step, name, size, speed or cal\n" + "freq displays the DDR PHY frequency in kHz\n" + "freq changes the DDR PHY frequency\n" + "param [type|reg] prints input parameters\n" +@@ -160,6 +160,7 @@ 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; + } + +@@ -208,6 +209,16 @@ 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]); + } + +@@ -367,7 +378,6 @@ bool stm32mp1_ddr_interactive(void *priv, + enum stm32mp1_ddr_interact_step step, + const struct stm32mp1_ddr_config *config) + { +- const char *prompt = "DDR>"; + char buffer[CONFIG_SYS_CBSIZE]; + char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ + int argc; +@@ -403,13 +413,12 @@ bool stm32mp1_ddr_interactive(void *priv, + } + + printf("%d:%s\n", step, step_str[step]); +- printf("%s\n", prompt); + + if (next_step > step) + return false; + + while (next_step == step) { +- cli_readline_into_buffer(prompt, buffer, 0); ++ cli_readline_into_buffer("DDR>", buffer, 0); + argc = cli_simple_parse_line(buffer, argv); + if (!argc) + continue; +diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c b/drivers/ram/stm32mp1/stm32mp1_ram.c +index a362cf9..c54f314 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_ram.c ++++ b/drivers/ram/stm32mp1/stm32mp1_ram.c +@@ -64,18 +64,22 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) + struct clk axidcg; + struct stm32mp1_ddr_config config; + +-#define PARAM(x, y) \ +- { x,\ +- offsetof(struct stm32mp1_ddr_config, y),\ +- sizeof(config.y) / sizeof(u32)} ++#define PARAM(x, y, z) \ ++ { .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) +-#define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x) ++#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), +@@ -83,7 +87,7 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) + CTL_PARAM(perf), + PHY_PARAM(reg), + PHY_PARAM(timing), +- PHY_PARAM(cal) ++ PHY_PARAM_OPT(cal) + }; + + config.info.speed = dev_read_u32_default(dev, "st,mem-speed", 0); +@@ -102,11 +106,25 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) + param[idx].size); + debug("%s: %s[0x%x] = %d\n", __func__, + param[idx].name, param[idx].size, ret); +- if (ret) { ++ if (ret && ++ (ret != -FDT_ERR_NOTFOUND || !param[idx].present)) { + pr_err("%s: Cannot read %s, error=%d\n", + __func__, 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); +diff --git a/drivers/ram/stm32mp1/stm32mp1_tests.c b/drivers/ram/stm32mp1/stm32mp1_tests.c +index 581ee48..cc7b429 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_tests.c ++++ b/drivers/ram/stm32mp1/stm32mp1_tests.c +@@ -14,7 +14,7 @@ + DECLARE_GLOBAL_DATA_PTR; + + static int get_bufsize(char *string, int argc, char *argv[], int arg_nb, +- size_t *bufsize, size_t default_size) ++ size_t *bufsize, size_t default_size, size_t min_size) + { + unsigned long value; + +@@ -24,8 +24,9 @@ static int get_bufsize(char *string, int argc, char *argv[], int arg_nb, + arg_nb, argv[arg_nb]); + return -1; + } +- if (value > STM32_DDR_SIZE || value == 0) { +- sprintf(string, "invalid size %s", argv[arg_nb]); ++ if (value > STM32_DDR_SIZE || value < min_size) { ++ sprintf(string, "invalid size %s (min=%d)", ++ argv[arg_nb], min_size); + return -1; + } + if (value & 0x3) { +@@ -438,7 +439,7 @@ static enum test_result test_addressbus(struct stm32mp1_ddrctl *ctl, + u32 bufsize; + u32 error; + +- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) ++ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4)) + return TEST_ERROR; + if (!is_power_of_2(bufsize)) { + sprintf(string, "size 0x%x is not a power of 2", +@@ -467,7 +468,7 @@ static enum test_result test_memdevice(struct stm32mp1_ddrctl *ctl, + size_t bufsize; + u32 error; + +- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) ++ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4)) + return TEST_ERROR; + if (get_addr(string, argc, argv, 1, &addr)) + return TEST_ERROR; +@@ -509,7 +510,7 @@ static enum test_result test_sso(struct stm32mp1_ddrctl *ctl, + u32 error = 0; + u32 data; + +- if (get_bufsize(string, argc, argv, 0, &bufsize, 4)) ++ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4)) + return TEST_ERROR; + if (get_addr(string, argc, argv, 1, &addr)) + return TEST_ERROR; +@@ -581,7 +582,7 @@ static enum test_result test_random(struct stm32mp1_ddrctl *ctl, + u32 error = 0; + unsigned int seed; + +- if (get_bufsize(string, argc, argv, 0, &bufsize, 8 * 1024)) ++ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 8)) + return TEST_ERROR; + if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) + return TEST_ERROR; +@@ -741,7 +742,7 @@ static enum test_result test_noise_burst(struct stm32mp1_ddrctl *ctl, + int i; + enum test_result res = TEST_PASSED; + +- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) ++ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 128)) + return TEST_ERROR; + if (get_pattern(string, argc, argv, 1, &pattern, 0xFFFFFFFF)) + return TEST_ERROR; +@@ -917,7 +918,7 @@ static enum test_result test_freq_pattern(struct stm32mp1_ddrctl *ctl, + const u32 **patterns; + u32 bufsize; + +- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) ++ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 128)) + return TEST_ERROR; + + switch (readl(&ctl->mstr) & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) { +@@ -1004,7 +1005,7 @@ static enum test_result test_checkboard(struct stm32mp1_ddrctl *ctl, + + u32 checkboard[2] = {0x55555555, 0xAAAAAAAA}; + +- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) ++ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 8)) + return TEST_ERROR; + if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) + return TEST_ERROR; +@@ -1039,7 +1040,7 @@ static enum test_result test_blockseq(struct stm32mp1_ddrctl *ctl, + u32 bufsize, nb_loop, loop = 0, addr, value; + int i; + +- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) ++ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4)) + return TEST_ERROR; + if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) + return TEST_ERROR; +@@ -1073,7 +1074,7 @@ static enum test_result test_walkbit0(struct stm32mp1_ddrctl *ctl, + u32 bufsize, nb_loop, loop = 0, addr, value; + int i; + +- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) ++ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4)) + return TEST_ERROR; + if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) + return TEST_ERROR; +@@ -1111,7 +1112,7 @@ static enum test_result test_walkbit1(struct stm32mp1_ddrctl *ctl, + u32 bufsize, nb_loop, loop = 0, addr, value; + int i; + +- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) ++ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4)) + return TEST_ERROR; + if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) + return TEST_ERROR; +@@ -1153,7 +1154,7 @@ static enum test_result test_bitspread(struct stm32mp1_ddrctl *ctl, + u32 bufsize, nb_loop, loop = 0, addr, bitspread[4]; + int i, j; + +- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) ++ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 32)) + return TEST_ERROR; + if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) + return TEST_ERROR; +@@ -1200,7 +1201,7 @@ static enum test_result test_bitflip(struct stm32mp1_ddrctl *ctl, + + u32 bitflip[4]; + +- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) ++ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 32)) + return TEST_ERROR; + if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) + return TEST_ERROR; +diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c +index 4e1c1fa..3013b7b 100644 +--- a/drivers/ram/stm32mp1/stm32mp1_tuning.c ++++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c +@@ -8,6 +8,8 @@ + #include + #include + #include ++#include ++#include + + #include "stm32mp1_ddr_regs.h" + #include "stm32mp1_ddr.h" +@@ -75,6 +77,133 @@ static u8 get_nb_bytes(struct stm32mp1_ddrctl *ctl) + 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); +@@ -169,8 +298,13 @@ static void set_r0dgps_delay(struct stm32mp1_ddrphy *phy, + } + + /* Basic BIST configuration for data lane tests. */ +-static void config_BIST(struct stm32mp1_ddrphy *phy) ++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. */ +@@ -190,18 +324,20 @@ static void config_BIST(struct stm32mp1_ddrphy *phy) + * 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; ++ 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 = 0x7FFF; /* To check */ ++ 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 = 0x3FF; /* To check */ ++ 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 */ +@@ -223,8 +359,6 @@ static void config_BIST(struct stm32mp1_ddrphy *phy) + + writel(bcol | (brow << 12) | (bbank << 28), &phy->bistar0); + writel(brank | (bmrank << 2) | (bainc << 4), &phy->bistar1); +- +- /* To check this line : */ + writel(bmcol | (bmrow << 12) | (bmbank << 28), &phy->bistar2); + } + +@@ -246,6 +380,8 @@ static void BIST_test(struct stm32mp1_ddrphy *phy, u8 byte, + bool result = true; /* BIST_SUCCESS */ + u32 cnt = 0; + u32 error = 0; ++ u32 val; ++ int ret; + + bist->test_result = true; + +@@ -266,7 +402,7 @@ run: + writel(rand(), &phy->bistlsr); + + /* some delay to reset BIST */ +- mdelay(1); ++ udelay(10); + + /*Perform BIST Run*/ + clrsetbits_le32(&phy->bistrr, +@@ -274,27 +410,29 @@ run: + 0x00000001); + /* Write BISTRR.BINST = 3?b001; */ + +- /* Wait for a number of CTL clocks before reading BIST register*/ +- /* Wait 300 ctl_clk cycles; ... IS it really needed?? */ +- /* Perform BIST Instruction Stop*/ +- /* Write BISTRR.BINST = 3?b010;*/ +- +- /* poll on BISTGSR.BDONE. If 0, wait. ++TODO Add timeout */ +- while (!(readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDDONE)) +- ; +- +- /*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 { ++ /* 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 */ +@@ -394,7 +532,7 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, + clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN); + + /* Config the BIST block */ +- config_BIST(phy); ++ config_BIST(ctl, phy); + pr_debug("BIST Config done.\n"); + + /* Train each byte */ +@@ -807,7 +945,7 @@ static enum test_result eye_training(struct stm32mp1_ddrctl *ctl, + clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN); + + /* Config the BIST block */ +- config_BIST(phy); ++ config_BIST(ctl, phy); + + for (byte = 0; byte < nb_bytes; byte++) { + if (ctrlc()) { +@@ -1182,15 +1320,17 @@ static u8 set_midpoint_read_dqs_gating(struct stm32mp1_ddrphy *phy, u8 byte, + dqs_gate_values[byte][0], + dqs_gate_values[byte][1]); + pr_debug("*******the nominal values were system latency: 0 phase: 2*******\n"); +- set_r0dgsl_delay(phy, byte, dqs_gate_values[byte][0]); +- set_r0dgps_delay(phy, byte, dqs_gate_values[byte][1]); + } + } else { + /* if intermitant, restore defaut values */ + pr_debug("dqs gating:no regular fail/pass/fail found. defaults values restored.\n"); +- set_r0dgsl_delay(phy, byte, 0); +- set_r0dgps_delay(phy, byte, 2); ++ 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 +@@ -1227,7 +1367,7 @@ static enum test_result read_dqs_gating(struct stm32mp1_ddrctl *ctl, + clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN); + + /* config the bist block */ +- config_BIST(phy); ++ config_BIST(ctl, phy); + + for (byte = 0; byte < nb_bytes; byte++) { + if (ctrlc()) { +@@ -1281,11 +1421,16 @@ static enum test_result do_read_dqs_gating(struct stm32mp1_ddrctl *ctl, + { + 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; + } +@@ -1296,11 +1441,16 @@ static enum test_result do_bit_deskew(struct stm32mp1_ddrctl *ctl, + { + 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; + } +@@ -1311,11 +1461,16 @@ static enum test_result do_eye_training(struct stm32mp1_ddrctl *ctl, + { + 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; + } +diff --git a/drivers/remoteproc/rproc-elf-loader.c b/drivers/remoteproc/rproc-elf-loader.c +index e8026cd..5384812 100644 +--- a/drivers/remoteproc/rproc-elf-loader.c ++++ b/drivers/remoteproc/rproc-elf-loader.c +@@ -8,6 +8,39 @@ + #include + #include + ++/** ++ * struct resource_table - firmware resource table header ++ * @ver: version number ++ * @num: number of resource entries ++ * @reserved: reserved (must be zero) ++ * @offset: array of offsets pointing at the various resource entries ++ * ++ * A resource table is essentially a list of system resources required ++ * by the remote processor. It may also include configuration entries. ++ * If needed, the remote processor firmware should contain this table ++ * as a dedicated ".resource_table" ELF section. ++ * ++ * Some resources entries are mere announcements, where the host is informed ++ * of specific remoteproc configuration. Other entries require the host to ++ * do something (e.g. allocate a system resource). Sometimes a negotiation ++ * is expected, where the firmware requests a resource, and once allocated, ++ * the host should provide back its details (e.g. address of an allocated ++ * memory region). ++ * ++ * The header of the resource table, as expressed by this structure, ++ * contains a version number (should we need to change this format in the ++ * future), the number of available resource entries, and their offsets ++ * in the table. ++ * ++ * Immediately following this header are the resource entries themselves. ++ */ ++struct resource_table { ++ u32 ver; ++ u32 num; ++ u32 reserved[2]; ++ u32 offset[0]; ++} __packed; ++ + /* Basic function to verify ELF32 image format */ + int rproc_elf32_sanity_check(ulong addr, ulong size) + { +@@ -276,3 +309,239 @@ ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr) + else + return rproc_elf32_get_boot_addr(addr); + } ++ ++/* ++ * Search for the resource table in an ELF32 image. ++ * Returns the address of the resource table section if found, NULL if there is ++ * no resource table section, or error pointer. ++ */ ++static Elf32_Shdr *rproc_elf32_find_rsc_table(struct udevice *dev, ++ ulong fw_addr, ulong fw_size) ++{ ++ int ret; ++ unsigned int i; ++ const char *name_table; ++ struct resource_table *table; ++ const u8 *elf_data = (void *)fw_addr; ++ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)fw_addr; ++ Elf32_Shdr *shdr; ++ ++ ret = rproc_elf32_sanity_check(fw_addr, fw_size); ++ if (ret) { ++ pr_debug("Invalid ELF32 Image %d\n", ret); ++ return ERR_PTR(ret); ++ } ++ ++ /* look for the resource table and handle it */ ++ shdr = (Elf32_Shdr *)(elf_data + ehdr->e_shoff); ++ name_table = (const char *)(elf_data + ++ shdr[ehdr->e_shstrndx].sh_offset); ++ ++ for (i = 0; i < ehdr->e_shnum; i++, shdr++) { ++ u32 size = shdr->sh_size; ++ u32 offset = shdr->sh_offset; ++ ++ if (strcmp(name_table + shdr->sh_name, ".resource_table")) ++ continue; ++ ++ table = (struct resource_table *)(elf_data + offset); ++ ++ /* make sure we have the entire table */ ++ if (offset + size > fw_size) { ++ pr_debug("resource table truncated\n"); ++ return ERR_PTR(-ENOSPC); ++ } ++ ++ /* make sure table has at least the header */ ++ if (sizeof(*table) > size) { ++ pr_debug("header-less resource table\n"); ++ return ERR_PTR(-ENOSPC); ++ } ++ ++ /* we don't support any version beyond the first */ ++ if (table->ver != 1) { ++ pr_debug("unsupported fw ver: %d\n", table->ver); ++ return ERR_PTR(-EPROTONOSUPPORT); ++ } ++ ++ /* make sure reserved bytes are zeroes */ ++ if (table->reserved[0] || table->reserved[1]) { ++ pr_debug("non zero reserved bytes\n"); ++ return ERR_PTR(-EBADF); ++ } ++ ++ /* make sure the offsets array isn't truncated */ ++ if (table->num * sizeof(table->offset[0]) + ++ sizeof(*table) > size) { ++ pr_debug("resource table incomplete\n"); ++ return ERR_PTR(-ENOSPC); ++ } ++ ++ return shdr; ++ } ++ ++ return NULL; ++} ++ ++/* Load the resource table from an ELF32 image */ ++int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr, ++ ulong fw_size, ulong *rsc_addr, ulong *rsc_size) ++{ ++ const struct dm_rproc_ops *ops; ++ Elf32_Shdr *shdr; ++ void *src, *dst; ++ ++ shdr = rproc_elf32_find_rsc_table(dev, fw_addr, fw_size); ++ if (!shdr) ++ return -ENODATA; ++ if (IS_ERR(shdr)) ++ return PTR_ERR(shdr); ++ ++ ops = rproc_get_ops(dev); ++ *rsc_addr = (ulong)shdr->sh_addr; ++ *rsc_size = (ulong)shdr->sh_size; ++ ++ src = (void *)fw_addr + shdr->sh_offset; ++ if (ops->device_to_virt) ++ dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size); ++ else ++ dst = (void *)rsc_addr; ++ ++ dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n", ++ (ulong)dst, *rsc_size); ++ ++ memcpy(dst, src, *rsc_size); ++ flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN), ++ roundup((unsigned long)dst + *rsc_size, ++ ARCH_DMA_MINALIGN) - ++ rounddown((unsigned long)dst, ARCH_DMA_MINALIGN)); ++ ++ return 0; ++} ++ ++/* ++ * Search for the resource table in an ELF64 image. ++ * Returns the address of the resource table section if found, NULL if there is ++ * no resource table section, or error pointer. ++ */ ++static Elf64_Shdr *rproc_elf64_find_rsc_table(struct udevice *dev, ++ ulong fw_addr, ulong fw_size) ++{ ++ int ret; ++ unsigned int i; ++ const char *name_table; ++ struct resource_table *table; ++ const u8 *elf_data = (void *)fw_addr; ++ Elf64_Ehdr *ehdr = (Elf64_Ehdr *)fw_addr; ++ Elf64_Shdr *shdr; ++ ++ ret = rproc_elf64_sanity_check(fw_addr, fw_size); ++ if (ret) { ++ pr_debug("Invalid ELF64 Image %d\n", ret); ++ return ERR_PTR(ret); ++ } ++ ++ /* look for the resource table and handle it */ ++ shdr = (Elf64_Shdr *)(elf_data + ehdr->e_shoff); ++ name_table = (const char *)(elf_data + ++ shdr[ehdr->e_shstrndx].sh_offset); ++ ++ for (i = 0; i < ehdr->e_shnum; i++, shdr++) { ++ u64 size = shdr->sh_size; ++ u64 offset = shdr->sh_offset; ++ ++ if (strcmp(name_table + shdr->sh_name, ".resource_table")) ++ continue; ++ ++ table = (struct resource_table *)(elf_data + offset); ++ ++ /* make sure we have the entire table */ ++ if (offset + size > fw_size) { ++ pr_debug("resource table truncated\n"); ++ return ERR_PTR(-ENOSPC); ++ } ++ ++ /* make sure table has at least the header */ ++ if (sizeof(*table) > size) { ++ pr_debug("header-less resource table\n"); ++ return ERR_PTR(-ENOSPC); ++ } ++ ++ /* we don't support any version beyond the first */ ++ if (table->ver != 1) { ++ pr_debug("unsupported fw ver: %d\n", table->ver); ++ return ERR_PTR(-EPROTONOSUPPORT); ++ } ++ ++ /* make sure reserved bytes are zeroes */ ++ if (table->reserved[0] || table->reserved[1]) { ++ pr_debug("non zero reserved bytes\n"); ++ return ERR_PTR(-EBADF); ++ } ++ ++ /* make sure the offsets array isn't truncated */ ++ if (table->num * sizeof(table->offset[0]) + ++ sizeof(*table) > size) { ++ pr_debug("resource table incomplete\n"); ++ return ERR_PTR(-ENOSPC); ++ } ++ ++ return shdr; ++ } ++ ++ return NULL; ++} ++ ++/* Load the resource table from an ELF64 image */ ++int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr, ++ ulong fw_size, ulong *rsc_addr, ulong *rsc_size) ++{ ++ const struct dm_rproc_ops *ops; ++ Elf64_Shdr *shdr; ++ void *src, *dst; ++ ++ shdr = rproc_elf64_find_rsc_table(dev, fw_addr, fw_size); ++ if (!shdr) ++ return -ENODATA; ++ if (IS_ERR(shdr)) ++ return PTR_ERR(shdr); ++ ++ ops = rproc_get_ops(dev); ++ *rsc_addr = (ulong)shdr->sh_addr; ++ *rsc_size = (ulong)shdr->sh_size; ++ ++ src = (void *)fw_addr + shdr->sh_offset; ++ if (ops->device_to_virt) ++ dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size); ++ else ++ dst = (void *)rsc_addr; ++ ++ dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n", ++ (ulong)dst, *rsc_size); ++ ++ memcpy(dst, src, *rsc_size); ++ flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN), ++ roundup((unsigned long)dst + *rsc_size, ++ ARCH_DMA_MINALIGN) - ++ rounddown((unsigned long)dst, ARCH_DMA_MINALIGN)); ++ ++ return 0; ++} ++ ++/* Load the resource table from an ELF32 or ELF64 image */ ++int rproc_elf_load_rsc_table(struct udevice *dev, ulong fw_addr, ++ ulong fw_size, ulong *rsc_addr, ulong *rsc_size) ++ ++{ ++ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)fw_addr; ++ ++ if (!fw_addr) ++ return -EFAULT; ++ ++ if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) ++ return rproc_elf64_load_rsc_table(dev, fw_addr, fw_size, ++ rsc_addr, rsc_size); ++ else ++ return rproc_elf32_load_rsc_table(dev, fw_addr, fw_size, ++ rsc_addr, rsc_size); ++} +diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c +index 40bba37..b8e62e5 100644 +--- a/drivers/remoteproc/stm32_copro.c ++++ b/drivers/remoteproc/stm32_copro.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + #define RCC_GCR_HOLD_BOOT 0 + #define RCC_GCR_RELEASE_BOOT 1 +@@ -22,14 +23,16 @@ + * @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 +- * @is_running: is the remote processor running ++ * @secured_soc: TZEN flag (register protection) ++ * @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; +- bool is_running; ++ bool secured_soc; ++ ulong rsc_table_addr; + }; + + /** +@@ -42,6 +45,7 @@ static int stm32_copro_probe(struct udevice *dev) + struct stm32_copro_privdata *priv; + struct regmap *regmap; + const fdt32_t *cell; ++ uint tz_offset, tz_mask, tzen; + int len, ret; + + priv = dev_get_priv(dev); +@@ -69,6 +73,31 @@ static int stm32_copro_probe(struct udevice *dev) + return ret; + } + ++ regmap = syscon_regmap_lookup_by_phandle(dev, "st,syscfg-tz"); ++ if (IS_ERR(regmap)) { ++ dev_dbg(dev, "unable to find tz regmap (%ld)\n", ++ PTR_ERR(regmap)); ++ return -EINVAL; ++ } ++ ++ cell = dev_read_prop(dev, "st,syscfg-tz", &len); ++ if (3 * sizeof(fdt32_t) - len > 0) { ++ dev_dbg(dev, "tz offset and mask not available\n"); ++ return -EINVAL; ++ } ++ ++ tz_offset = fdtdec_get_number(cell + 1, 1); ++ ++ tz_mask = fdtdec_get_number(cell + 2, 1); ++ ++ ret = regmap_read(regmap, tz_offset, &tzen); ++ if (ret) { ++ dev_dbg(dev, "failed to read soc secure state\n"); ++ return ret; ++ } ++ ++ priv->secured_soc = !!(tzen & tz_mask); ++ + dev_dbg(dev, "probed\n"); + + return 0; +@@ -90,6 +119,11 @@ static int stm32_copro_set_hold_boot(struct udevice *dev, bool hold) + + val = hold ? RCC_GCR_HOLD_BOOT : RCC_GCR_RELEASE_BOOT; + ++ if (priv->secured_soc) { ++ return stm32_smc_exec(STM32_SMC_RCC, STM32_SMC_REG_WRITE, ++ priv->hold_boot_offset, val); ++ } ++ + /* + * 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 +@@ -141,6 +175,7 @@ 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; ++ ulong rsc_table_size; + int ret; + + priv = dev_get_priv(dev); +@@ -155,6 +190,12 @@ static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size) + return ret; + } + ++ if (rproc_elf32_load_rsc_table(dev, addr, size, &priv->rsc_table_addr, ++ &rsc_table_size)) { ++ priv->rsc_table_addr = 0; ++ dev_warn(dev, "No valid resource table for this firmware\n"); ++ } ++ + return rproc_elf32_load_image(dev, addr, size); + } + +@@ -180,7 +221,12 @@ static int stm32_copro_start(struct udevice *dev) + * rebooting autonomously + */ + ret = stm32_copro_set_hold_boot(dev, true); +- priv->is_running = !ret; ++ 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; + } + +@@ -206,7 +252,7 @@ static int stm32_copro_reset(struct udevice *dev) + return ret; + } + +- priv->is_running = false; ++ writel(TAMP_COPRO_STATE_OFF, TAMP_COPRO_STATE); + + return 0; + } +@@ -224,14 +270,11 @@ static int stm32_copro_stop(struct udevice *dev) + /** + * stm32_copro_is_running() - Is the STM32 remote processor running + * @dev: corresponding STM32 remote processor device +- * @return 1 if the remote processor is running, 0 otherwise ++ * @return 0 if the remote processor is running, 1 otherwise + */ + static int stm32_copro_is_running(struct udevice *dev) + { +- struct stm32_copro_privdata *priv; +- +- priv = dev_get_priv(dev); +- return priv->is_running; ++ return (readl(TAMP_COPRO_STATE) == TAMP_COPRO_STATE_OFF); + } + + static const struct dm_rproc_ops stm32_copro_ops = { +diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig +index 75ccd65..4c92c49 100644 +--- a/drivers/reset/Kconfig ++++ b/drivers/reset/Kconfig +@@ -148,4 +148,12 @@ config RESET_IMX7 + help + Support for reset controller on i.MX7/8 SoCs. + ++config RESET_SCMI ++ bool "Enable SCMI reset domain driver" ++ select SCMI_AGENT ++ 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 0a044d5..1ce9760 100644 +--- a/drivers/reset/Makefile ++++ b/drivers/reset/Makefile +@@ -23,3 +23,4 @@ obj-$(CONFIG_RESET_MTMIPS) += reset-mtmips.o + obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o + obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o + obj-$(CONFIG_RESET_IMX7) += reset-imx7.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 0000000..8f4c895 +--- /dev/null ++++ b/drivers/reset/reset-scmi.c +@@ -0,0 +1,86 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2019 Linaro Limited ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++enum scmi_reset_domain_message_id { ++ SCMI_RESET_DOMAIN_RESET = 0x4, ++}; ++ ++#define SCMI_RD_RESET_FLAG_ASSERT BIT(1) ++#define SCMI_RD_RESET_FLAG_DEASSERT 0 ++ ++struct scmi_rd_reset_in { ++ u32 domain_id; ++ u32 flags; ++ u32 reset_state; ++}; ++ ++struct scmi_rd_reset_out { ++ s32 status; ++}; ++ ++static int scmi_reset_set_state(struct reset_ctl *rst, int assert_not_deassert) ++{ ++ struct scmi_rd_reset_in in = { ++ .domain_id = rst->id, ++ .flags = assert_not_deassert ? SCMI_RD_RESET_FLAG_ASSERT : ++ SCMI_RD_RESET_FLAG_DEASSERT, ++ .reset_state = 0, ++ }; ++ struct scmi_rd_reset_out out; ++ struct scmi_msg scmi_msg = { ++ .protocol_id = SCMI_PROTOCOL_ID_RESET_DOMAIN, ++ .message_id = SCMI_RESET_DOMAIN_RESET, ++ .in_msg = (u8 *)&in, ++ .in_msg_sz = sizeof(in), ++ .out_msg = (u8 *)&out, ++ .out_msg_sz = sizeof(out), ++ }; ++ int rc; ++ ++ rc = scmi_agent_process_msg(rst->dev->parent, &scmi_msg); ++ if (rc) ++ return rc; ++ ++ return scmi_to_linux_errno(out.status); ++} ++ ++static int scmi_reset_assert(struct reset_ctl *rst) ++{ ++ return scmi_reset_set_state(rst, SCMI_RD_RESET_FLAG_ASSERT); ++} ++ ++static int scmi_reset_deassert(struct reset_ctl *rst) ++{ ++ return scmi_reset_set_state(rst, SCMI_RD_RESET_FLAG_DEASSERT); ++} ++ ++static int scmi_reset_request(struct reset_ctl *reset_ctl) ++{ ++ return 0; ++} ++ ++static int scmi_reset_free(struct reset_ctl *reset_ctl) ++{ ++ return 0; ++} ++ ++static const struct reset_ops scmi_reset_domain_ops = { ++ .request = scmi_reset_request, ++ .free = scmi_reset_free, ++ .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/tee/optee/core.c b/drivers/tee/optee/core.c +index 7f870f2..8a0009b 100644 +--- a/drivers/tee/optee/core.c ++++ b/drivers/tee/optee/core.c +@@ -510,7 +510,7 @@ static bool is_optee_api(optee_invoke_fn *invoke_fn) + res.a2 == OPTEE_MSG_UID_2 && res.a3 == OPTEE_MSG_UID_3; + } + +-static void print_os_revision(optee_invoke_fn *invoke_fn) ++static void print_os_revision(struct udevice *dev, optee_invoke_fn *invoke_fn) + { + union { + struct arm_smccc_res smccc; +@@ -525,11 +525,12 @@ static void print_os_revision(optee_invoke_fn *invoke_fn) + &res.smccc); + + if (res.result.build_id) +- debug("OP-TEE revision %lu.%lu (%08lx)\n", res.result.major, +- res.result.minor, res.result.build_id); ++ dev_info(dev, "OP-TEE: revision %lu.%lu (%08lx)\n", ++ res.result.major, res.result.minor, ++ res.result.build_id); + else +- debug("OP-TEE revision %lu.%lu\n", res.result.major, +- res.result.minor); ++ dev_info(dev, "OP-TEE: revision %lu.%lu\n", ++ res.result.major, res.result.minor); + } + + static bool api_revision_is_compatible(optee_invoke_fn *invoke_fn) +@@ -624,7 +625,7 @@ static int optee_probe(struct udevice *dev) + return -ENOENT; + } + +- print_os_revision(pdata->invoke_fn); ++ print_os_revision(dev, pdata->invoke_fn); + + if (!api_revision_is_compatible(pdata->invoke_fn)) { + debug("%s: OP-TEE api revision mismatch\n", __func__); +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 77c555e..988cf02 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -864,8 +864,8 @@ int dwc3_setup_phy(struct udevice *dev, struct phy **array, int *num_phys) + for (i = 0; i < count; i++) { + ret = generic_phy_init(&usb_phys[i]); + if (ret) { +- pr_err("Can't init USB PHY%d for %s\n", +- i, dev->name); ++ pr_debug("Can't init USB PHY%d for %s\n", ++ i, dev->name); + goto phys_init_err; + } + } +@@ -873,8 +873,8 @@ int dwc3_setup_phy(struct udevice *dev, struct phy **array, int *num_phys) + for (i = 0; i < count; i++) { + ret = generic_phy_power_on(&usb_phys[i]); + if (ret) { +- pr_err("Can't power USB PHY%d for %s\n", +- i, dev->name); ++ pr_debug("Can't power USB PHY%d for %s\n", ++ i, dev->name); + goto phys_poweron_err; + } + } +@@ -910,8 +910,8 @@ int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys) + ret = generic_phy_power_off(&usb_phys[i]); + ret |= generic_phy_exit(&usb_phys[i]); + if (ret) { +- pr_err("Can't shutdown USB PHY%d for %s\n", +- i, dev->name); ++ pr_debug("Can't shutdown USB PHY%d for %s\n", ++ i, dev->name); + } + } + +diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c +index 35f4147..35495e4 100644 +--- a/drivers/usb/gadget/dwc2_udc_otg.c ++++ b/drivers/usb/gadget/dwc2_udc_otg.c +@@ -980,7 +980,7 @@ int dwc2_phy_setup(struct udevice *dev, struct phy **array, int *num_phys) + for (i = 0; i < count; i++) { + ret = generic_phy_init(&usb_phys[i]); + if (ret) { +- dev_err(dev, "Can't init USB PHY%d for %s\n", ++ dev_dbg(dev, "Can't init USB PHY%d for %s\n", + i, dev->name); + goto phys_init_err; + } +@@ -989,7 +989,7 @@ int dwc2_phy_setup(struct udevice *dev, struct phy **array, int *num_phys) + for (i = 0; i < count; i++) { + ret = generic_phy_power_on(&usb_phys[i]); + if (ret) { +- dev_err(dev, "Can't power USB PHY%d for %s\n", ++ dev_dbg(dev, "Can't power USB PHY%d for %s\n", + i, dev->name); + goto phys_poweron_err; + } +@@ -1027,7 +1027,7 @@ void dwc2_phy_shutdown(struct udevice *dev, struct phy *usb_phys, int num_phys) + ret = generic_phy_power_off(&usb_phys[i]); + ret |= generic_phy_exit(&usb_phys[i]); + if (ret) { +- dev_err(dev, "Can't shutdown USB PHY%d for %s\n", ++ dev_dbg(dev, "Can't shutdown USB PHY%d for %s\n", + i, dev->name); + } + } +diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c +index e9e1600..7a51b53 100644 +--- a/drivers/usb/gadget/g_dnl.c ++++ b/drivers/usb/gadget/g_dnl.c +@@ -89,6 +89,14 @@ static struct usb_gadget_strings *g_dnl_composite_strings[] = { + NULL, + }; + ++void g_dnl_set_product(const char *s) ++{ ++ if (s) ++ g_dnl_string_defs[1].s = s; ++ else ++ g_dnl_string_defs[1].s = product; ++} ++ + static int g_dnl_unbind(struct usb_composite_dev *cdev) + { + struct usb_gadget *gadget = cdev->gadget; +diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c +index b9c56f7..2fbb8b8 100644 +--- a/drivers/usb/host/dwc2.c ++++ b/drivers/usb/host/dwc2.c +@@ -5,13 +5,15 @@ + */ + + #include ++#include + #include + #include + #include +-#include ++#include + #include + #include + #include ++#include + #include + #include + #include +@@ -36,6 +38,8 @@ struct dwc2_priv { + #ifdef CONFIG_DM_REGULATOR + struct udevice *vbus_supply; + #endif ++ struct phy phy; ++ struct clk_bulk clks; + #else + uint8_t *aligned_buffer; + uint8_t *status_buffer; +@@ -1146,6 +1150,8 @@ static int dwc2_reset(struct udevice *dev) + return ret; + } + ++ /* force reset to clear all IP register */ ++ reset_assert_bulk(&priv->resets); + ret = reset_deassert_bulk(&priv->resets); + if (ret) { + reset_release_bulk(&priv->resets); +@@ -1212,6 +1218,8 @@ static int dwc2_init_common(struct udevice *dev, struct dwc2_priv *priv) + if (readl(®s->gintsts) & DWC2_GINTSTS_CURMODE_HOST) + mdelay(1000); + ++ printf("USB DWC2\n"); ++ + return 0; + } + +@@ -1321,13 +1329,113 @@ static int dwc2_usb_ofdata_to_platdata(struct udevice *dev) + return 0; + } + ++static int dwc2_setup_phy(struct udevice *dev) ++{ ++ struct dwc2_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ ret = generic_phy_get_by_index(dev, 0, &priv->phy); ++ if (ret) { ++ if (ret == -ENOENT) ++ return 0; /* no PHY, nothing to do */ ++ dev_err(dev, "Failed to get USB PHY: %d.\n", ret); ++ return ret; ++ } ++ ++ ret = generic_phy_init(&priv->phy); ++ if (ret) { ++ dev_dbg(dev, "Failed to init USB PHY: %d.\n", ret); ++ return ret; ++ } ++ ++ ret = generic_phy_power_on(&priv->phy); ++ if (ret) { ++ dev_dbg(dev, "Failed to power on USB PHY: %d.\n", ret); ++ generic_phy_exit(&priv->phy); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int dwc2_shutdown_phy(struct udevice *dev) ++{ ++ struct dwc2_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ /* PHY is not valid when generic_phy_get_by_index() = -ENOENT */ ++ if (!generic_phy_valid(&priv->phy)) ++ return 0; /* no PHY, nothing to do */ ++ ++ ret = generic_phy_power_off(&priv->phy); ++ if (ret) { ++ dev_dbg(dev, "Failed to power off USB PHY: %d.\n", ret); ++ return ret; ++ } ++ ++ ret = generic_phy_exit(&priv->phy); ++ if (ret) { ++ dev_dbg(dev, "Failed to power off USB PHY: %d.\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int dwc2_clk_init(struct udevice *dev) ++{ ++ struct dwc2_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ ret = clk_get_bulk(dev, &priv->clks); ++ if (ret == -ENOSYS || ret == -ENOENT) ++ return 0; ++ if (ret) ++ return ret; ++ ++ ret = clk_enable_bulk(&priv->clks); ++ if (ret) { ++ clk_release_bulk(&priv->clks); ++ return ret; ++ } ++ ++ return 0; ++} ++ + static int dwc2_usb_probe(struct udevice *dev) + { + struct dwc2_priv *priv = dev_get_priv(dev); + struct usb_bus_priv *bus_priv = dev_get_uclass_priv(dev); ++ int ret; + + bus_priv->desc_before_addr = true; + ++ ret = dwc2_clk_init(dev); ++ if (ret) ++ return ret; ++ ++ ret = dwc2_setup_phy(dev); ++ if (ret) ++ return ret; ++ ++ if (CONFIG_IS_ENABLED(ARCH_STM32MP) && ++ device_is_compatible(dev, "st,stm32mp1-hsotg")) { ++ struct udevice *usb33d_supply; ++ ++ ret = device_get_supply_regulator(dev, "usb33d-supply", ++ &usb33d_supply); ++ if (ret) { ++ dev_err(dev, ++ "can't get voltage level detector supply\n"); ++ } else { ++ ret = regulator_set_enable(usb33d_supply, true); ++ if (ret) { ++ dev_err(dev, ++ "can't enable voltage level detector supply\n"); ++ } ++ } ++ } ++ + return dwc2_init_common(dev, priv); + } + +@@ -1340,9 +1448,17 @@ static int dwc2_usb_remove(struct udevice *dev) + if (ret) + return ret; + ++ ret = dwc2_shutdown_phy(dev); ++ if (ret) { ++ dev_dbg(dev, "Failed to shutdown USB PHY: %d.\n", ret); ++ return ret; ++ } ++ + dwc2_uninit_common(priv->regs); + + reset_release_bulk(&priv->resets); ++ clk_disable_bulk(&priv->clks); ++ clk_release_bulk(&priv->clks); + + return 0; + } +diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c +index ef20c3c..0c31775 100644 +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -1698,13 +1698,13 @@ int ehci_setup_phy(struct udevice *dev, struct phy *phy, int index) + } else { + ret = generic_phy_init(phy); + if (ret) { +- dev_err(dev, "failed to init usb phy\n"); ++ dev_dbg(dev, "failed to init usb phy\n"); + return ret; + } + + ret = generic_phy_power_on(phy); + if (ret) { +- dev_err(dev, "failed to power on usb phy\n"); ++ dev_dbg(dev, "failed to power on usb phy\n"); + return generic_phy_exit(phy); + } + } +@@ -1722,13 +1722,13 @@ int ehci_shutdown_phy(struct udevice *dev, struct phy *phy) + if (generic_phy_valid(phy)) { + ret = generic_phy_power_off(phy); + if (ret) { +- dev_err(dev, "failed to power off usb phy\n"); ++ dev_dbg(dev, "failed to power off usb phy\n"); + return ret; + } + + ret = generic_phy_exit(phy); + if (ret) { +- dev_err(dev, "failed to power off usb phy\n"); ++ dev_dbg(dev, "failed to power off usb phy\n"); + return ret; + } + } +diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c +index 916ea0b..e8cf26a 100644 +--- a/drivers/usb/host/ohci-generic.c ++++ b/drivers/usb/host/ohci-generic.c +@@ -38,13 +38,13 @@ static int ohci_setup_phy(struct udevice *dev, int index) + } else { + ret = generic_phy_init(&priv->phy); + if (ret) { +- dev_err(dev, "failed to init usb phy\n"); ++ dev_dbg(dev, "failed to init usb phy\n"); + return ret; + } + + ret = generic_phy_power_on(&priv->phy); + if (ret) { +- dev_err(dev, "failed to power on usb phy\n"); ++ dev_dbg(dev, "failed to power on usb phy\n"); + return generic_phy_exit(&priv->phy); + } + } +@@ -60,13 +60,13 @@ static int ohci_shutdown_phy(struct udevice *dev) + if (generic_phy_valid(&priv->phy)) { + ret = generic_phy_power_off(&priv->phy); + if (ret) { +- dev_err(dev, "failed to power off usb phy\n"); ++ dev_dbg(dev, "failed to power off usb phy\n"); + return ret; + } + + ret = generic_phy_exit(&priv->phy); + if (ret) { +- dev_err(dev, "failed to power off usb phy\n"); ++ dev_dbg(dev, "failed to power off usb phy\n"); + return ret; + } + } +diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c +index 45eecfe..3b36ab3 100644 +--- a/drivers/usb/musb-new/sunxi.c ++++ b/drivers/usb/musb-new/sunxi.c +@@ -252,7 +252,7 @@ static int sunxi_musb_enable(struct musb *musb) + + ret = generic_phy_power_on(&glue->phy); + if (ret) { +- pr_err("failed to power on USB PHY\n"); ++ pr_debug("failed to power on USB PHY\n"); + return ret; + } + } +@@ -276,7 +276,7 @@ static void sunxi_musb_disable(struct musb *musb) + if (is_host_enabled(musb)) { + ret = generic_phy_power_off(&glue->phy); + if (ret) { +- pr_err("failed to power off USB PHY\n"); ++ pr_debug("failed to power off USB PHY\n"); + return; + } + } +@@ -310,7 +310,7 @@ static int sunxi_musb_init(struct musb *musb) + + ret = generic_phy_init(&glue->phy); + if (ret) { +- dev_err(dev, "failed to init USB PHY\n"); ++ dev_dbg(dev, "failed to init USB PHY\n"); + goto err_rst; + } + +@@ -347,7 +347,7 @@ static int sunxi_musb_exit(struct musb *musb) + if (generic_phy_valid(&glue->phy)) { + ret = generic_phy_exit(&glue->phy); + if (ret) { +- dev_err(dev, "failed to power off usb phy\n"); ++ dev_dbg(dev, "failed to power off usb phy\n"); + return ret; + } + } +diff --git a/drivers/video/orisetech_otm8009a.c b/drivers/video/orisetech_otm8009a.c +index 89d9cfd..629bf76 100644 +--- a/drivers/video/orisetech_otm8009a.c ++++ b/drivers/video/orisetech_otm8009a.c +@@ -60,9 +60,6 @@ + struct otm8009a_panel_priv { + struct udevice *reg; + struct gpio_desc reset; +- unsigned int lanes; +- enum mipi_dsi_pixel_format format; +- unsigned long mode_flags; + }; + + static const struct display_timing default_timing = { +@@ -291,17 +288,8 @@ static int otm8009a_panel_enable_backlight(struct udevice *dev) + static int otm8009a_panel_get_display_timing(struct udevice *dev, + struct display_timing *timings) + { +- struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); +- struct mipi_dsi_device *device = plat->device; +- struct otm8009a_panel_priv *priv = dev_get_priv(dev); +- + memcpy(timings, &default_timing, sizeof(*timings)); + +- /* fill characteristics of DSI data link */ +- device->lanes = priv->lanes; +- device->format = priv->format; +- device->mode_flags = priv->mode_flags; +- + return 0; + } + +@@ -333,6 +321,7 @@ static int otm8009a_panel_ofdata_to_platdata(struct udevice *dev) + static int otm8009a_panel_probe(struct udevice *dev) + { + struct otm8009a_panel_priv *priv = dev_get_priv(dev); ++ struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); + int ret; + + if (IS_ENABLED(CONFIG_DM_REGULATOR) && priv->reg) { +@@ -348,9 +337,10 @@ static int otm8009a_panel_probe(struct udevice *dev) + dm_gpio_set_value(&priv->reset, false); + mdelay(10); /* >5ms */ + +- priv->lanes = 2; +- priv->format = MIPI_DSI_FMT_RGB888; +- priv->mode_flags = MIPI_DSI_MODE_VIDEO | ++ /* 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; + +diff --git a/drivers/video/raydium-rm68200.c b/drivers/video/raydium-rm68200.c +index 91555e2..76b0ed2 100644 +--- a/drivers/video/raydium-rm68200.c ++++ b/drivers/video/raydium-rm68200.c +@@ -73,9 +73,6 @@ struct rm68200_panel_priv { + struct udevice *reg; + struct udevice *backlight; + struct gpio_desc reset; +- unsigned int lanes; +- enum mipi_dsi_pixel_format format; +- unsigned long mode_flags; + }; + + static const struct display_timing default_timing = { +@@ -257,17 +254,8 @@ static int rm68200_panel_enable_backlight(struct udevice *dev) + static int rm68200_panel_get_display_timing(struct udevice *dev, + struct display_timing *timings) + { +- struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); +- struct mipi_dsi_device *device = plat->device; +- struct rm68200_panel_priv *priv = dev_get_priv(dev); +- + memcpy(timings, &default_timing, sizeof(*timings)); + +- /* fill characteristics of DSI data link */ +- device->lanes = priv->lanes; +- device->format = priv->format; +- device->mode_flags = priv->mode_flags; +- + return 0; + } + +@@ -306,6 +294,7 @@ static int rm68200_panel_ofdata_to_platdata(struct udevice *dev) + static int rm68200_panel_probe(struct udevice *dev) + { + struct rm68200_panel_priv *priv = dev_get_priv(dev); ++ struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); + int ret; + + if (IS_ENABLED(CONFIG_DM_REGULATOR) && priv->reg) { +@@ -320,9 +309,10 @@ static int rm68200_panel_probe(struct udevice *dev) + dm_gpio_set_value(&priv->reset, false); + mdelay(10); + +- priv->lanes = 2; +- priv->format = MIPI_DSI_FMT_RGB888; +- priv->mode_flags = MIPI_DSI_MODE_VIDEO | ++ /* 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; + +diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c +index 12895a8..022ae96 100644 +--- a/drivers/video/stm32/stm32_dsi.c ++++ b/drivers/video/stm32/stm32_dsi.c +@@ -268,7 +268,6 @@ static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings, + u32 val; + + /* Update lane capabilities according to hw version */ +- dsi->hw_version = dsi_read(dsi, DSI_VERSION) & VERSION; + dsi->lane_min_kbps = LANE_MIN_KBPS; + dsi->lane_max_kbps = LANE_MAX_KBPS; + if (dsi->hw_version == HWVER_131) { +@@ -351,6 +350,9 @@ static int stm32_dsi_attach(struct udevice *dev) + + mplat = dev_get_platdata(priv->panel); + mplat->device = &priv->device; ++ device->lanes = mplat->lanes; ++ device->format = mplat->format; ++ device->mode_flags = mplat->mode_flags; + + ret = panel_get_display_timing(priv->panel, &timings); + if (ret) { +@@ -472,6 +474,17 @@ static int stm32_dsi_probe(struct udevice *dev) + /* Reset */ + reset_deassert(&rst); + ++ /* check hardware version */ ++ priv->hw_version = dsi_read(priv, DSI_VERSION) & VERSION; ++ if (priv->hw_version != HWVER_130 && ++ priv->hw_version != HWVER_131) { ++ dev_err(dev, "bad dsi hardware version\n"); ++ clk_disable(&clk); ++ if (IS_ENABLED(CONFIG_DM_REGULATOR)) ++ regulator_set_enable(priv->vdd_reg, false); ++ return -ENODEV; ++ } ++ + return 0; + err_clk: + clk_disable(&clk); +diff --git a/env/mmc.c b/env/mmc.c +index b24c35c..f64c993 100644 +--- a/env/mmc.c ++++ b/env/mmc.c +@@ -24,14 +24,25 @@ + + DECLARE_GLOBAL_DATA_PTR; + ++#if !defined(CONFIG_SYS_MMC_ENV_DEV) ++#define CONFIG_SYS_MMC_ENV_DEV 0 ++#endif ++ ++__weak int mmc_get_env_dev(void) ++{ ++ return CONFIG_SYS_MMC_ENV_DEV; ++} ++ + #if CONFIG_IS_ENABLED(OF_CONTROL) +-static inline int mmc_offset_try_partition(const char *str, s64 *val) ++static inline int mmc_offset_try_partition(const char *str, int copy, s64 *val) + { + disk_partition_t info; + struct blk_desc *desc; + int len, i, ret; ++ char dev_str[4]; + +- ret = blk_get_device_by_str("mmc", STR(CONFIG_SYS_MMC_ENV_DEV), &desc); ++ snprintf(dev_str, sizeof(dev_str), "%d", mmc_get_env_dev()); ++ ret = blk_get_device_by_str("mmc", dev_str, &desc); + if (ret < 0) + return (ret); + +@@ -45,10 +56,10 @@ static inline int mmc_offset_try_partition(const char *str, s64 *val) + } + + /* round up to info.blksz */ +- len = (CONFIG_ENV_SIZE + info.blksz - 1) & ~(info.blksz - 1); ++ len = DIV_ROUND_UP(CONFIG_ENV_SIZE, info.blksz); + + /* use the top of the partion for the environment */ +- *val = (info.start + info.size - 1) - len / info.blksz; ++ *val = (info.start + info.size - (1 + copy) * len) * info.blksz; + + return 0; + } +@@ -73,7 +84,7 @@ static inline s64 mmc_offset(int copy) + str = fdtdec_get_config_string(gd->fdt_blob, dt_prop.partition); + if (str) { + /* try to place the environment at end of the partition */ +- err = mmc_offset_try_partition(str, &val); ++ err = mmc_offset_try_partition(str, copy, &val); + if (!err) + return val; + } +@@ -114,11 +125,6 @@ __weak int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr) + return 0; + } + +-__weak int mmc_get_env_dev(void) +-{ +- return CONFIG_SYS_MMC_ENV_DEV; +-} +- + #ifdef CONFIG_SYS_MMC_ENV_PART + __weak uint mmc_get_env_part(struct mmc *mmc) + { +diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h +index d6cf187..ec48770 100644 +--- a/include/asm-generic/gpio.h ++++ b/include/asm-generic/gpio.h +@@ -117,11 +117,14 @@ struct udevice; + struct gpio_desc { + struct udevice *dev; /* Device, NULL for invalid GPIO */ + unsigned long flags; +-#define GPIOD_REQUESTED (1 << 0) /* Requested/claimed */ +-#define GPIOD_IS_OUT (1 << 1) /* GPIO is an output */ +-#define GPIOD_IS_IN (1 << 2) /* GPIO is an input */ +-#define GPIOD_ACTIVE_LOW (1 << 3) /* value has active low */ +-#define GPIOD_IS_OUT_ACTIVE (1 << 4) /* set output active */ ++#define GPIOD_IS_OUT BIT(1) /* GPIO is an output */ ++#define GPIOD_IS_IN BIT(2) /* GPIO is an input */ ++#define GPIOD_ACTIVE_LOW BIT(3) /* GPIO is active when value is low */ ++#define GPIOD_IS_OUT_ACTIVE BIT(4) /* set output active */ ++#define GPIOD_OPEN_DRAIN BIT(5) /* GPIO is open drain type */ ++#define GPIOD_OPEN_SOURCE BIT(6) /* GPIO is open source type */ ++#define GPIOD_PULL_UP BIT(7) /* GPIO has pull-up enabled */ ++#define GPIOD_PULL_DOWN BIT(8) /* GPIO has pull-down enabled */ + + uint offset; /* GPIO offset within the device */ + /* +@@ -130,6 +133,12 @@ struct gpio_desc { + */ + }; + ++/* helper to compute the value of the gpio output */ ++#define GPIOD_FLAGS_OUTPUT_MASK (GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE) ++#define GPIOD_FLAGS_OUTPUT(flags) \ ++ (((((flags) & GPIOD_FLAGS_OUTPUT_MASK) == GPIOD_IS_OUT_ACTIVE) || \ ++ (((flags) & GPIOD_FLAGS_OUTPUT_MASK) == GPIOD_ACTIVE_LOW))) ++ + /** + * dm_gpio_is_valid() - Check if a GPIO is valid + * +@@ -254,8 +263,6 @@ struct dm_gpio_ops { + int value); + int (*get_value)(struct udevice *dev, unsigned offset); + int (*set_value)(struct udevice *dev, unsigned offset, int value); +- int (*get_open_drain)(struct udevice *dev, unsigned offset); +- int (*set_open_drain)(struct udevice *dev, unsigned offset, int value); + /** + * get_function() Get the GPIO function + * +@@ -290,6 +297,37 @@ struct dm_gpio_ops { + */ + int (*xlate)(struct udevice *dev, struct gpio_desc *desc, + struct ofnode_phandle_args *args); ++ ++ /** ++ * set_dir_flags() - Set GPIO dir flags ++ * ++ * This function should set up the GPIO configuration according to the ++ * information provide by the direction flags bitfield. ++ * ++ * This method is optional. ++ * ++ * @dev: GPIO device ++ * @offset: GPIO offset within that device ++ * @flags: GPIO configuration to use ++ * @return 0 if OK, -ve on error ++ */ ++ int (*set_dir_flags)(struct udevice *dev, unsigned int offset, ++ ulong flags); ++ ++ /** ++ * get_dir_flags() - Get GPIO dir flags ++ * ++ * This function return the GPIO direction flags used. ++ * ++ * This method is optional. ++ * ++ * @dev: GPIO device ++ * @offset: GPIO offset within that device ++ * @flags: place to put the used direction flags by GPIO ++ * @return 0 if OK, -ve on error ++ */ ++ int (*get_dir_flags)(struct udevice *dev, unsigned int offset, ++ ulong *flags); + }; + + /** +@@ -587,63 +625,41 @@ int dm_gpio_get_value(const struct gpio_desc *desc); + int dm_gpio_set_value(const struct gpio_desc *desc, int value); + + /** +- * dm_gpio_get_open_drain() - Check if open-drain-mode of a GPIO is active +- * +- * This checks if open-drain-mode for a GPIO is enabled or not. This method is +- * optional. +- * +- * @desc: GPIO description containing device, offset and flags, +- * previously returned by gpio_request_by_name() +- * @return Value of open drain mode for GPIO (0 for inactive, 1 for active) or +- * -ve on error +- */ +-int dm_gpio_get_open_drain(struct gpio_desc *desc); +- +-/** +- * dm_gpio_set_open_drain() - Switch open-drain-mode of a GPIO on or off +- * +- * This enables or disables open-drain mode for a GPIO. This method is +- * optional; if the driver does not support it, nothing happens when the method +- * is called. ++ * dm_gpio_set_dir() - Set the direction for a GPIO + * +- * In open-drain mode, instead of actively driving the output (Push-pull +- * output), the GPIO's pin is connected to the collector (for a NPN transistor) +- * or the drain (for a MOSFET) of a transistor, respectively. The pin then +- * either forms an open circuit or a connection to ground, depending on the +- * state of the transistor. ++ * This sets up the direction according to the GPIO flags: desc->flags. + * + * @desc: GPIO description containing device, offset and flags, + * previously returned by gpio_request_by_name() + * @return 0 if OK, -ve on error + */ +-int dm_gpio_set_open_drain(struct gpio_desc *desc, int value); ++int dm_gpio_set_dir(struct gpio_desc *desc); + + /** +- * dm_gpio_set_dir() - Set the direction for a GPIO ++ * dm_gpio_set_dir_flags() - Set direction using description and added flags + * +- * This sets up the direction according tot the provided flags. It will do +- * nothing unless the direction is actually specified. ++ * This sets up the direction according to the provided flags and the GPIO ++ * description (desc->flags) which include direction information. ++ * Note that desc->flags is updated by this function. + * + * @desc: GPIO description containing device, offset and flags, + * previously returned by gpio_request_by_name() +- * @return 0 if OK, -ve on error ++ * @flags: New flags to use ++ * @return 0 if OK, -ve on error, in which case desc->flags is not updated + */ +-int dm_gpio_set_dir(struct gpio_desc *desc); ++int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags); + + /** +- * dm_gpio_set_dir_flags() - Set direction using specific flags ++ * dm_gpio_get_dir_flags() - Get direction flags + * +- * This is like dm_gpio_set_dir() except that the flags value is provided +- * instead of being used from desc->flags. This is needed because in many +- * cases the GPIO description does not include direction information. +- * Note that desc->flags is updated by this function. ++ * read the current direction flags + * + * @desc: GPIO description containing device, offset and flags, + * previously returned by gpio_request_by_name() +- * @flags: New flags to use ++ * @flags: place to put the used flags + * @return 0 if OK, -ve on error, in which case desc->flags is not updated + */ +-int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags); ++int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags); + + /** + * gpio_get_number() - Get the global GPIO number of a GPIO +diff --git a/include/clk.h b/include/clk.h +index a5ee53d..950b5da 100644 +--- a/include/clk.h ++++ b/include/clk.h +@@ -9,6 +9,7 @@ + #define _CLK_H_ + + #include ++#include + #include + #include + +@@ -221,6 +222,8 @@ static inline int clk_get_by_index(struct udevice *dev, int index, + + static inline int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk) + { ++ if (bulk) ++ bulk->count = 0; + return -ENOSYS; + } + +@@ -272,6 +275,7 @@ static inline int clk_release_bulk(struct clk_bulk *bulk) + return clk_release_all(bulk->clks, bulk->count); + } + ++#if CONFIG_IS_ENABLED(CLK) + /** + * clk_request - Request a clock by provider-specific ID. + * +@@ -393,19 +397,6 @@ int clk_disable_bulk(struct clk_bulk *bulk); + */ + bool clk_is_match(const struct clk *p, const struct clk *q); + +-int soc_clk_dump(void); +- +-/** +- * clk_valid() - check if clk is valid +- * +- * @clk: the clock to check +- * @return true if valid, or false +- */ +-static inline bool clk_valid(struct clk *clk) +-{ +- return clk && !!clk->dev; +-} +- + /** + * clk_get_by_id() - Get the clock by its ID + * +@@ -425,6 +416,93 @@ int clk_get_by_id(ulong id, struct clk **clkp); + * @return true on binded, or false on no + */ + bool clk_dev_binded(struct clk *clk); ++ ++#else /* CONFIG_IS_ENABLED(CLK) */ ++ ++static inline int clk_request(struct udevice *dev, struct clk *clk) ++{ ++ return -ENOSYS; ++} ++ ++static inline int clk_free(struct clk *clk) ++{ ++ return -ENOSYS; ++} ++ ++static inline ulong clk_get_rate(struct clk *clk) ++{ ++ return -ENOSYS; ++} ++ ++static inline struct clk *clk_get_parent(struct clk *clk) ++{ ++ return ERR_PTR(-ENOSYS); ++} ++ ++static inline long long clk_get_parent_rate(struct clk *clk) ++{ ++ return -ENOSYS; ++} ++ ++static inline ulong clk_set_rate(struct clk *clk, ulong rate) ++{ ++ return -ENOSYS; ++} ++ ++static inline int clk_set_parent(struct clk *clk, struct clk *parent) ++{ ++ return -ENOSYS; ++} ++ ++static inline int clk_enable(struct clk *clk) ++{ ++ return -ENOSYS; ++} ++ ++static inline int clk_enable_bulk(struct clk_bulk *bulk) ++{ ++ return bulk && bulk->count == 0 ? 0 : -ENOSYS; ++} ++ ++static inline int clk_disable(struct clk *clk) ++{ ++ return -ENOSYS; ++} ++ ++static inline int clk_disable_bulk(struct clk_bulk *bulk) ++{ ++ return bulk && bulk->count == 0 ? 0 : -ENOSYS; ++} ++ ++static inline bool clk_is_match(const struct clk *p, const struct clk *q) ++{ ++ return false; ++} ++ ++static inline int clk_get_by_id(ulong id, struct clk **clkp) ++{ ++ return -ENOSYS; ++} ++ ++static inline bool clk_dev_binded(struct clk *clk) ++{ ++ return false; ++} ++#endif /* CONFIG_IS_ENABLED(CLK) */ ++ ++/** ++ * clk_valid() - check if clk is valid ++ * ++ * @clk: the clock to check ++ * @return true if valid, or false ++ */ ++static inline bool clk_valid(struct clk *clk) ++{ ++ return clk && !!clk->dev; ++} ++ ++int soc_clk_dump(void); ++ + #endif + + #define clk_prepare_enable(clk) clk_enable(clk) +diff --git a/include/configs/odroid.h b/include/configs/odroid.h +index 77fca32..5d78825 100644 +--- a/include/configs/odroid.h ++++ b/include/configs/odroid.h +@@ -64,7 +64,6 @@ + ""PARTS_BOOT" part 0 1;" \ + ""PARTS_ROOT" part 0 2\0" \ + +-#define CONFIG_SET_DFU_ALT_INFO + #define CONFIG_SET_DFU_ALT_BUF_LEN (SZ_1K) + + #define CONFIG_DFU_ALT_BOOT_EMMC \ +diff --git a/include/configs/odroid_xu3.h b/include/configs/odroid_xu3.h +index 47c3054..564319c 100644 +--- a/include/configs/odroid_xu3.h ++++ b/include/configs/odroid_xu3.h +@@ -76,7 +76,6 @@ + + /* Enable: board/samsung/common/misc.c to use set_dfu_alt_info() */ + #define CONFIG_MISC_COMMON +-#define CONFIG_SET_DFU_ALT_INFO + #define CONFIG_SET_DFU_ALT_BUF_LEN (SZ_1K) + + /* Set soc_rev, soc_id, board_rev, board_name, fdtfile */ +diff --git a/include/configs/omap3_igep00x0.h b/include/configs/omap3_igep00x0.h +index 4ad7dc1..8dc30be 100644 +--- a/include/configs/omap3_igep00x0.h ++++ b/include/configs/omap3_igep00x0.h +@@ -71,8 +71,6 @@ + + #endif + +-#define CONFIG_SYS_MTDPARTS_RUNTIME +- + /* OneNAND config */ + #define CONFIG_USE_ONENAND_BOARD_INIT + #define CONFIG_SYS_ONENAND_BASE ONENAND_MAP +diff --git a/include/configs/stm32f429-evaluation.h b/include/configs/stm32f429-evaluation.h +index 7a17222..a715031 100644 +--- a/include/configs/stm32f429-evaluation.h ++++ b/include/configs/stm32f429-evaluation.h +@@ -7,6 +7,11 @@ + #ifndef __CONFIG_H + #define __CONFIG_H + ++#include ++ ++/* For booting Linux, use the first 16MB of memory */ ++#define CONFIG_SYS_BOOTMAPSZ SZ_16M ++ + #define CONFIG_SYS_FLASH_BASE 0x08000000 + + #define CONFIG_SYS_INIT_SP_ADDR 0x10010000 +@@ -40,12 +45,10 @@ + #define CONFIG_EXTRA_ENV_SETTINGS \ + "kernel_addr_r=0x00008000\0" \ + "fdtfile=stm32429i-eval.dtb\0" \ +- "fdt_addr_r=0x00700000\0" \ +- "scriptaddr=0x00800000\0" \ +- "pxefile_addr_r=0x00800000\0" \ +- "fdt_high=0xffffffffffffffff\0" \ +- "initrd_high=0xffffffffffffffff\0" \ +- "ramdisk_addr_r=0x00900000\0" \ ++ "fdt_addr_r=0x00408000\0" \ ++ "scriptaddr=0x00418000\0" \ ++ "pxefile_addr_r=0x00428000\0" \ ++ "ramdisk_addr_r=0x00438000\0" \ + BOOTENV + + /* +diff --git a/include/configs/stm32f469-discovery.h b/include/configs/stm32f469-discovery.h +index 463f1c4..8212fb6 100644 +--- a/include/configs/stm32f469-discovery.h ++++ b/include/configs/stm32f469-discovery.h +@@ -7,6 +7,11 @@ + #ifndef __CONFIG_H + #define __CONFIG_H + ++#include ++ ++/* For booting Linux, use the first 12MB of memory */ ++#define CONFIG_SYS_BOOTMAPSZ SZ_8M + SZ_4M ++ + #define CONFIG_SYS_FLASH_BASE 0x08000000 + + #define CONFIG_SYS_INIT_SP_ADDR 0x10010000 +@@ -40,12 +45,10 @@ + #define CONFIG_EXTRA_ENV_SETTINGS \ + "kernel_addr_r=0x00008000\0" \ + "fdtfile=stm32f469-disco.dtb\0" \ +- "fdt_addr_r=0x00700000\0" \ +- "scriptaddr=0x00800000\0" \ +- "pxefile_addr_r=0x00800000\0" \ +- "fdt_high=0xffffffffffffffff\0" \ +- "initrd_high=0xffffffffffffffff\0" \ +- "ramdisk_addr_r=0x00900000\0" \ ++ "fdt_addr_r=0x00408000\0" \ ++ "scriptaddr=0x00418000\0" \ ++ "pxefile_addr_r=0x00428000\0" \ ++ "ramdisk_addr_r=0x00438000\0" \ + BOOTENV + + /* +diff --git a/include/configs/stm32f746-disco.h b/include/configs/stm32f746-disco.h +index 337b999..45343d2 100644 +--- a/include/configs/stm32f746-disco.h ++++ b/include/configs/stm32f746-disco.h +@@ -7,6 +7,11 @@ + #ifndef __CONFIG_H + #define __CONFIG_H + ++#include ++ ++/* For booting Linux, use the first 6MB of memory */ ++#define CONFIG_SYS_BOOTMAPSZ SZ_4M + SZ_2M ++ + #define CONFIG_SYS_FLASH_BASE 0x08000000 + #define CONFIG_SYS_INIT_SP_ADDR 0x20050000 + +@@ -48,12 +53,10 @@ + #define CONFIG_EXTRA_ENV_SETTINGS \ + "kernel_addr_r=0xC0008000\0" \ + "fdtfile=stm32f746-disco.dtb\0" \ +- "fdt_addr_r=0xC0500000\0" \ +- "scriptaddr=0xC0008000\0" \ +- "pxefile_addr_r=0xC0008000\0" \ +- "fdt_high=0xffffffffffffffff\0" \ +- "initrd_high=0xffffffffffffffff\0" \ +- "ramdisk_addr_r=0xC0600000\0" \ ++ "fdt_addr_r=0xC0408000\0" \ ++ "scriptaddr=0xC0418000\0" \ ++ "pxefile_addr_r=0xC0428000\0" \ ++ "ramdisk_addr_r=0xC0438000\0" \ + BOOTENV + + /* +diff --git a/include/configs/stm32h743-disco.h b/include/configs/stm32h743-disco.h +index 74c69eb..39c93ee 100644 +--- a/include/configs/stm32h743-disco.h ++++ b/include/configs/stm32h743-disco.h +@@ -8,6 +8,10 @@ + #define __CONFIG_H + + #include ++#include ++ ++/* For booting Linux, use the first 16MB of memory */ ++#define CONFIG_SYS_BOOTMAPSZ SZ_16M + + #define CONFIG_SYS_FLASH_BASE 0x08000000 + #define CONFIG_SYS_INIT_SP_ADDR 0x24040000 +@@ -35,12 +39,10 @@ + #define CONFIG_EXTRA_ENV_SETTINGS \ + "kernel_addr_r=0xD0008000\0" \ + "fdtfile=stm32h743i-disco.dtb\0" \ +- "fdt_addr_r=0xD0700000\0" \ +- "scriptaddr=0xD0800000\0" \ +- "pxefile_addr_r=0xD0800000\0" \ +- "fdt_high=0xffffffffffffffff\0" \ +- "initrd_high=0xffffffffffffffff\0" \ +- "ramdisk_addr_r=0xD0900000\0" \ ++ "fdt_addr_r=0xD0408000\0" \ ++ "scriptaddr=0xD0418000\0" \ ++ "pxefile_addr_r=0xD0428000\0" \ ++ "ramdisk_addr_r=0xD0438000\0" \ + BOOTENV + + /* +diff --git a/include/configs/stm32h743-eval.h b/include/configs/stm32h743-eval.h +index b7c8492..8eb94c1 100644 +--- a/include/configs/stm32h743-eval.h ++++ b/include/configs/stm32h743-eval.h +@@ -8,6 +8,10 @@ + #define __CONFIG_H + + #include ++#include ++ ++/* For booting Linux, use the first 16MB of memory */ ++#define CONFIG_SYS_BOOTMAPSZ SZ_16M + + #define CONFIG_SYS_FLASH_BASE 0x08000000 + #define CONFIG_SYS_INIT_SP_ADDR 0x24040000 +@@ -35,12 +39,10 @@ + #define CONFIG_EXTRA_ENV_SETTINGS \ + "kernel_addr_r=0xD0008000\0" \ + "fdtfile=stm32h743i-eval.dtb\0" \ +- "fdt_addr_r=0xD0700000\0" \ +- "scriptaddr=0xD0800000\0" \ +- "pxefile_addr_r=0xD0800000\0" \ +- "fdt_high=0xffffffffffffffff\0" \ +- "initrd_high=0xffffffffffffffff\0" \ +- "ramdisk_addr_r=0xD0900000\0" \ ++ "fdt_addr_r=0xD0408000\0" \ ++ "scriptaddr=0xD0418000\0" \ ++ "pxefile_addr_r=0xD0428000\0" \ ++ "ramdisk_addr_r=0xD0438000\0" \ + BOOTENV + + /* +diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h +index d42a786..7b4fe48 100644 +--- a/include/configs/stm32mp1.h ++++ b/include/configs/stm32mp1.h +@@ -23,27 +23,30 @@ + #define CONFIG_SYS_SDRAM_BASE STM32_DDR_BASE + #define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_TEXT_BASE + +-#ifdef CONFIG_STM32MP1_OPTEE +-#define CONFIG_SYS_MEM_TOP_HIDE SZ_32M +-#endif /* CONFIG_STM32MP1_OPTEE */ +- + /* + * Console I/O buffer size + */ + #define CONFIG_SYS_CBSIZE SZ_1K + + /* +- * Needed by "loadb" ++ * default load address used for command tftp, bootm , loadb, ... + */ +-#define CONFIG_SYS_LOAD_ADDR STM32_DDR_BASE ++#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. ++ */ ++#define CONFIG_SYS_BOOTMAPSZ SZ_256M ++ + /* Extend size of kernel image for uncompression */ +-#define CONFIG_SYS_BOOTM_LEN SZ_32M ++#define CONFIG_SYS_BOOTM_LEN SZ_32M + + /* SPL support */ + #ifdef CONFIG_SPL +@@ -70,6 +73,11 @@ + #define CONFIG_SYS_NAND_ONFI_DETECTION + #define CONFIG_SYS_MAX_NAND_DEVICE 1 + ++/* SPI FLASH support */ ++#if defined(CONFIG_SPL_BUILD) ++#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x80000 ++#endif ++ + /* Ethernet need */ + #ifdef CONFIG_DWC_ETH_QOS + #define CONFIG_SYS_NONCACHED_MEMORY (1 * SZ_1M) /* 1M */ +@@ -78,13 +86,6 @@ + #define CONFIG_SYS_AUTOLOAD "no" + #endif + +-/* Dynamic MTD partition support */ +-#if defined(CONFIG_STM32_QSPI) || defined(CONFIG_NAND_STM32_FMC2) +-#define CONFIG_SYS_MTDPARTS_RUNTIME +-#endif +- +-#define CONFIG_SET_DFU_ALT_INFO +- + #ifdef CONFIG_DM_VIDEO + #define CONFIG_VIDEO_BMP_RLE8 + #define CONFIG_BMP_16BPP +@@ -98,20 +99,44 @@ + + #if !defined(CONFIG_SPL_BUILD) + +-#define BOOT_TARGET_DEVICES(func) \ +- func(MMC, mmc, 1) \ +- func(UBIFS, ubifs, 0) \ +- func(MMC, mmc, 0) \ +- func(MMC, mmc, 2) \ +- func(PXE, pxe, na) ++#ifdef CONFIG_CMD_MMC ++#define BOOT_TARGET_MMC0(func) func(MMC, mmc, 0) ++#define BOOT_TARGET_MMC1(func) func(MMC, mmc, 1) ++#define BOOT_TARGET_MMC2(func) func(MMC, mmc, 2) ++#else ++#define BOOT_TARGET_MMC0(func) ++#define BOOT_TARGET_MMC1(func) ++#define BOOT_TARGET_MMC2(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 ++ ++#define BOOT_TARGET_DEVICES(func) \ ++ BOOT_TARGET_MMC1(func) \ ++ BOOT_TARGET_UBIFS(func) \ ++ BOOT_TARGET_MMC0(func) \ ++ BOOT_TARGET_MMC2(func) \ ++ BOOT_TARGET_PXE(func) + + /* + * bootcmd for stm32mp1: ++ * CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" + * for serial/usb: execute the stm32prog command + * for mmc boot (eMMC, SD card), boot only on the same device +- * for nand boot, boot with on ubifs partition on nand +- * for nor boot, use the default order ++ * for nand or spi-nand boot, boot with on ubifs partition on UBI partition ++ * for nor boot, use SD card = mmc0 + */ ++ + #define STM32MP_BOOTCMD "bootcmd_stm32mp=" \ + "echo \"Boot over ${boot_device}${boot_instance}!\";" \ + "if test ${boot_device} = serial || test ${boot_device} = usb;" \ +@@ -120,65 +145,86 @@ + "run env_check;" \ + "if test ${boot_device} = mmc;" \ + "then env set boot_targets \"mmc${boot_instance}\"; fi;" \ +- "if test ${boot_device} = nand;" \ ++ "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" + +-#include ++/* DTIMG command added only for Android distribution */ ++#ifdef CONFIG_CMD_DTIMG ++/* ++ * bootcmd for android on MMC: ++ * CONFIG_BOOTCOMMAND="run bootcmd_android" ++ * overidde DISTRO script "mmc_boot" to boot android on mmc ++ * using system_${suffix} partition (with "_a") by default ++ * - display splash screen ++ * - load device tree form dtimg ++ * - load kernel and set bootargs ++ * - start kernel ++ */ + +-#ifdef CONFIG_STM32MP1_OPTEE +-/* with OPTEE: define specific MTD partitions = teeh, teed, teex */ +-#define STM32MP_MTDPARTS \ +- "mtdparts_nor0=256k(fsbl1),256k(fsbl2),2m(ssbl),256k(u-boot-env),256k(teeh),256k(teed),256k(teex),-(nor_user)\0" \ +- "mtdparts_nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),512k(teeh),512k(teed),512k(teex),-(UBI)\0" \ +- "mtdparts_spi-nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),"\ +- "512k(teeh),512k(teed),512k(teex),-(UBI)\0" +- +-#else /* CONFIG_STM32MP1_OPTEE */ +-#define STM32MP_MTDPARTS \ +- "mtdparts_nor0=256k(fsbl1),256k(fsbl2),2m(ssbl),256k(u-boot-env),-(nor_user)\0" \ +- "mtdparts_nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),-(UBI)\0" \ +- "mtdparts_spi-nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),-(UBI)\0" +- +-#endif /* CONFIG_STM32MP1_OPTEE */ +- +-#ifndef CONFIG_SYS_MTDPARTS_RUNTIME +-#undef STM32MP_MTDPARTS +-#define STM32MP_MTDPARTS +-#endif ++#define STM32MP_ANDROID \ ++ "suffix=a\0" \ ++ "dtimg_addr=0xc4500000\0" \ ++ "android_mmc_splash="\ ++ "if part start mmc ${devnum} splash splash_start && " \ ++ "part size mmc ${devnum} splash splash_size;"\ ++ "then " \ ++ "mmc read ${splashimage} ${splash_start} ${splash_size};" \ ++ "cls; bmp display ${splashimage} m m;" \ ++ "fi\0" \ ++ "android_mmc_fdt="\ ++ "if part start mmc ${devnum} dt_${suffix} dt_start &&" \ ++ "part size mmc ${devnum} dt_${suffix} dt_size;"\ ++ "then " \ ++ "mmc read ${dtimg_addr} ${dt_start} ${dt_size};" \ ++ "dtimg getindex ${dtimg_addr} ${board_id} ${board_rev}" \ ++ " dt_index;" \ ++ "dtimg start ${dtimg_addr} ${dt_index} fdt_addr_r;"\ ++ "fi\0" \ ++ "android_mmc_kernel="\ ++ "if part start mmc ${devnum} boot_${suffix} boot_start &&" \ ++ "part size mmc ${devnum} boot_${suffix} boot_size;"\ ++ "then " \ ++ "mmc read ${kernel_addr_r} ${boot_start} ${boot_size};" \ ++ "part nb mmc ${devnum} system_${suffix} rootpart_nb;" \ ++ "env set bootargs" \ ++ "root=/dev/mmcblk${devnum}p${rootpart_nb} " \ ++ "androidboot.serialno=${serial#} " \ ++ "androidboot.slot_suffix=_${suffix};"\ ++ "fi\0" \ ++ "android_mmc_boot="\ ++ "mmc dev ${devnum};"\ ++ "run android_mmc_splash;" \ ++ "run android_mmc_fdt;" \ ++ "run android_mmc_kernel;" \ ++ "bootm ${kernel_addr_r} - ${fdt_addr_r};\0" \ ++ "bootcmd_android=" \ ++ "env set mmc_boot run android_mmc_boot;" \ ++ "run bootcmd_stm32mp\0" ++ ++#else ++#define STM32MP_ANDROID ++#endif/* CONFIG_CMD_DTIMG */ + +-#define STM32MP_DFU_ALT_RAM \ +- "dfu_alt_info_ram=ram 0=" \ +- "uImage ram ${kernel_addr_r} 0x2000000;" \ +- "devicetree.dtb ram ${fdt_addr_r} 0x100000;" \ +- "uramdisk.image.gz ram ${ramdisk_addr_r} 0x10000000\0" +- +-#ifdef CONFIG_SET_DFU_ALT_INFO +-#define STM32MP_DFU_ALT_INFO \ +- "dfu_alt_info_nor0=mtd nor0=" \ +- "nor_fsbl1 part 1;nor_fsbl2 part 2;" \ +- "nor_ssbl part 3;nor_env part 4\0" \ +- "dfu_alt_info_nand0=mtd nand0="\ +- "nand_fsbl part 1;nand_ssbl1 part 2;" \ +- "nand_ssbl2 part 3;nand_UBI partubi 4\0" \ +- "dfu_alt_info_spi-nand0=mtd spi-nand0="\ +- "spi-nand_fsbl part 1;spi-nand_ssbl1 part 2;" \ +- "spi-nand_ssbl2 part 3;spi-nand_UBI partubi 4\0" \ +- "dfu_alt_info_mmc0=mmc 0=" \ +- "sdcard_fsbl1 part 0 1;sdcard_fsbl2 part 0 2;" \ +- "sdcard_ssbl part 0 3;sdcard_bootfs part 0 4;" \ +- "sdcard_vendorfs part 0 5;sdcard_rootfs part 0 6;" \ +- "sdcard_userfs part 0 7\0" \ +- "dfu_alt_info_mmc1=mmc 1=" \ +- "emmc_fsbl1 raw 0x0 0x200 mmcpart 1;" \ +- "emmc_fsbl2 raw 0x0 0x200 mmcpart 2;emmc_ssbl part 1 1;" \ +- "emmc_bootfs part 1 2;emmc_vendorfs part 1 3;" \ +- "emmc_rootfs part 1 4;emmc_userfs part 1 5\0" ++#ifdef CONFIG_FASTBOOT_CMD_OEM_FORMAT ++/* eMMC default partitions for fastboot command: oem format */ ++#define PARTS_DEFAULT \ ++ "partitions=" \ ++ "name=ssbl,size=2M;" \ ++ "name=bootfs,size=64MB,bootable;" \ ++ "name=vendorfs,size=16M;" \ ++ "name=rootfs,size=746M;" \ ++ "name=userfs,size=-\0" + #else +-#define STM32MP_DFU_ALT_INFO ++#define PARTS_DEFAULT + #endif + ++#include ++ + /* + * memory layout for 32M uncompressed/compressed kernel, + * 1M fdt, 1M script, 1M pxe and 1M for splashimage +@@ -192,16 +238,18 @@ + "pxefile_addr_r=0xc4200000\0" \ + "splashimage=0xc4300000\0" \ + "ramdisk_addr_r=0xc4400000\0" \ +- "fdt_high=0xffffffff\0" \ +- "initrd_high=0xffffffff\0" \ + "altbootcmd=run bootcmd\0" \ +- "env_default=1\0" \ +- "env_check=if test $env_default -eq 1;"\ +- " then env set env_default 0;env save;fi\0" \ ++ "env_check=" \ ++ "env exists env_ver || env set env_ver ${ver};" \ ++ "if env info -p -d -q; then env save; fi;" \ ++ "if test \"$env_ver\" != \"$ver\"; then" \ ++ " echo \"*** Warning: old environment ${env_ver}\";" \ ++ " echo '* set default: env default -a; env save; reset';" \ ++ " echo '* update current: env set env_ver ${ver}; env save';" \ ++ "fi;\0" \ + STM32MP_BOOTCMD \ +- STM32MP_MTDPARTS \ +- STM32MP_DFU_ALT_RAM \ +- STM32MP_DFU_ALT_INFO \ ++ STM32MP_ANDROID \ ++ PARTS_DEFAULT \ + BOOTENV \ + "boot_net_usb_start=true\0" + +diff --git a/include/dfu.h b/include/dfu.h +index 5649663..bb512a8 100644 +--- a/include/dfu.h ++++ b/include/dfu.h +@@ -205,6 +205,9 @@ void dfu_initiated_callback(struct dfu_entity *dfu); + */ + void dfu_flush_callback(struct dfu_entity *dfu); + ++int dfu_transaction_initiate(struct dfu_entity *dfu, bool read); ++void dfu_transaction_cleanup(struct dfu_entity *dfu); ++ + /* + * dfu_defer_flush - pointer to store dfu_entity for deferred flashing. + * It should be NULL when not used. +diff --git a/include/dm/of_access.h b/include/dm/of_access.h +index 13fedb7..1eb1ce1 100644 +--- a/include/dm/of_access.h ++++ b/include/dm/of_access.h +@@ -104,6 +104,46 @@ const void *of_get_property(const struct device_node *np, const char *name, + int *lenp); + + /** ++ * of_get_first_property()- get to the pointer of the first property ++ * ++ * Get pointer to the first property of the node, it is used to iterate ++ * and read all the property with of_get_next_property_by_prop(). ++ * ++ * @np: Pointer to device node ++ * @return pointer to property or NULL if not found ++ */ ++const struct property *of_get_first_property(const struct device_node *np); ++ ++/** ++ * of_get_next_property() - get to the pointer of the next property ++ * ++ * Get pointer to the next property of the node, it is used to iterate ++ * and read all the property with of_get_property_by_prop(). ++ * ++ * @np: Pointer to device node ++ * @property: pointer of the current property ++ * @return pointer to next property or NULL if not found ++ */ ++const struct property *of_get_next_property(const struct device_node *np, ++ const struct property *property); ++ ++/** ++ * of_get_property_by_prop() - get a property value of a node property ++ * ++ * Get value for the property identified by node and property pointer. ++ * ++ * @node: node to read ++ * @property: pointer of the property to read ++ * @propname: place to property name on success ++ * @lenp: place to put length on success ++ * @return pointer to property value or NULL if error ++ */ ++const void *of_get_property_by_prop(const struct device_node *np, ++ const struct property *property, ++ const char **name, ++ int *lenp); ++ ++/** + * of_device_is_compatible() - Check if the node matches given constraints + * @device: pointer to node + * @compat: required compatible string, NULL or "" for any match +diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h +index 5c4cbf0..9ee5556 100644 +--- a/include/dm/ofnode.h ++++ b/include/dm/ofnode.h +@@ -59,6 +59,31 @@ struct ofnode_phandle_args { + }; + + /** ++ * ofprop - reference to a property of a device tree node ++ * ++ * This struct hold the reference on one property of one node, ++ * using struct ofnode and an offset within the flat device tree or either ++ * a pointer to a struct property in the live device tree. ++ * ++ * Thus we can reference arguments in both the live tree and the flat tree. ++ * ++ * The property reference can also hold a null reference. This corresponds to ++ * a struct property NULL pointer or an offset of -1. ++ * ++ * @node: Pointer to device node ++ * @offset: Pointer into flat device tree, used for flat tree. ++ * @prop: Pointer to property, used for live treee. ++ */ ++ ++struct ofprop { ++ ofnode node; ++ union { ++ int offset; ++ const struct property *prop; ++ }; ++}; ++ ++/** + * _ofnode_to_np() - convert an ofnode to a live DT node pointer + * + * This cannot be called if the reference contains an offset. +@@ -543,7 +568,7 @@ int ofnode_decode_display_timing(ofnode node, int index, + struct display_timing *config); + + /** +- * ofnode_get_property()- - get a pointer to the value of a node property ++ * ofnode_get_property() - get a pointer to the value of a node property + * + * @node: node to read + * @propname: property to read +@@ -553,6 +578,42 @@ int ofnode_decode_display_timing(ofnode node, int index, + const void *ofnode_get_property(ofnode node, const char *propname, int *lenp); + + /** ++ * ofnode_get_first_property()- get the reference of the first property ++ * ++ * Get reference to the first property of the node, it is used to iterate ++ * and read all the property with ofnode_get_property_by_prop(). ++ * ++ * @node: node to read ++ * @prop: place to put argument reference ++ * @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found ++ */ ++int ofnode_get_first_property(ofnode node, struct ofprop *prop); ++ ++/** ++ * ofnode_get_next_property() - get the reference of the next property ++ * ++ * Get reference to the next property of the node, it is used to iterate ++ * and read all the property with ofnode_get_property_by_prop(). ++ * ++ * @prop: reference of current argument and place to put reference of next one ++ * @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found ++ */ ++int ofnode_get_next_property(struct ofprop *prop); ++ ++/** ++ * ofnode_get_property_by_prop() - get a pointer to the value of a property ++ * ++ * Get value for the property identified by the provided reference. ++ * ++ * @prop: reference on property ++ * @propname: If non-NULL, place to property name on success, ++ * @lenp: If non-NULL, place to put length on success ++ * @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found ++ */ ++const void *ofnode_get_property_by_prop(const struct ofprop *prop, ++ const char **propname, int *lenp); ++ ++/** + * ofnode_is_available() - check if a node is marked available + * + * @node: node to check +diff --git a/include/dm/read.h b/include/dm/read.h +index d37fcb5..3c6bed7 100644 +--- a/include/dm/read.h ++++ b/include/dm/read.h +@@ -466,6 +466,42 @@ int dev_read_phandle(struct udevice *dev); + const void *dev_read_prop(struct udevice *dev, const char *propname, int *lenp); + + /** ++ * dev_read_first_prop()- get the reference of the first property ++ * ++ * Get reference to the first property of the node, it is used to iterate ++ * and read all the property with dev_read_prop_by_prop(). ++ * ++ * @dev: device to check ++ * @prop: place to put argument reference ++ * @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found ++ */ ++int dev_read_first_prop(struct udevice *dev, struct ofprop *prop); ++ ++/** ++ * ofnode_get_next_property() - get the reference of the next property ++ * ++ * Get reference to the next property of the node, it is used to iterate ++ * and read all the property with dev_read_prop_by_prop(). ++ * ++ * @prop: reference of current argument and place to put reference of next one ++ * @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found ++ */ ++int dev_read_next_prop(struct ofprop *prop); ++ ++/** ++ * dev_read_prop_by_prop() - get a pointer to the value of a property ++ * ++ * Get value for the property identified by the provided reference. ++ * ++ * @prop: reference on property ++ * @propname: If non-NULL, place to property name on success, ++ * @lenp: If non-NULL, place to put length on success ++ * @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found ++ */ ++const void *dev_read_prop_by_prop(struct ofprop *prop, ++ const char **propname, int *lenp); ++ ++/** + * dev_read_alias_seq() - Get the alias sequence number of a node + * + * This works out whether a node is pointed to by an alias, and if so, the +@@ -812,6 +848,23 @@ static inline const void *dev_read_prop(struct udevice *dev, + return ofnode_get_property(dev_ofnode(dev), propname, lenp); + } + ++static inline int dev_read_first_prop(struct udevice *dev, struct ofprop *prop) ++{ ++ return ofnode_get_first_property(dev_ofnode(dev), prop); ++} ++ ++static inline int dev_read_next_prop(struct ofprop *prop) ++{ ++ return ofnode_get_next_property(prop); ++} ++ ++static inline const void *dev_read_prop_by_prop(struct ofprop *prop, ++ const char **propname, ++ int *lenp) ++{ ++ return ofnode_get_property_by_prop(prop, propname, lenp); ++} ++ + static inline int dev_read_alias_seq(struct udevice *dev, int *devnump) + { + return fdtdec_get_alias_seq(gd->fdt_blob, dev->uclass->uc_drv->name, +@@ -889,4 +942,18 @@ static inline int dev_read_alias_highest_id(const char *stem) + ofnode_valid(subnode); \ + subnode = ofnode_next_subnode(subnode)) + ++/** ++ * dev_for_each_property() - Helper function to iterate through property ++ * ++ * This creates a for() loop which works through the property in a device's ++ * device-tree node. ++ * ++ * @prop: struct ofprop holding the current property ++ * @dev: device to use for interation (struct udevice *) ++ */ ++#define dev_for_each_property(prop, dev) \ ++ for (int ret_prop = dev_read_first_prop(dev, &prop); \ ++ !ret_prop; \ ++ ret_prop = dev_read_next_prop(&prop)) ++ + #endif +diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h +index 4cdaf13..ec7b1a9 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/gpio/gpio.h b/include/dt-bindings/gpio/gpio.h +index 2cc10ae..c029467 100644 +--- a/include/dt-bindings/gpio/gpio.h ++++ b/include/dt-bindings/gpio/gpio.h +@@ -33,4 +33,10 @@ + #define GPIO_PERSISTENT 0 + #define GPIO_TRANSITORY 8 + ++/* Bit 4 express pull up */ ++#define GPIO_PULL_UP 16 ++ ++/* Bit 5 express pull down */ ++#define GPIO_PULL_DOWN 32 ++ + #endif +diff --git a/include/dt-bindings/gpio/sandbox-gpio.h b/include/dt-bindings/gpio/sandbox-gpio.h +new file mode 100644 +index 0000000..e4bfdb3 +--- /dev/null ++++ b/include/dt-bindings/gpio/sandbox-gpio.h +@@ -0,0 +1,24 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * This header provides constants for binding sandbox,gpio ++ * ++ */ ++#ifndef _DT_BINDINGS_GPIO_SANDBOX_GPIO_H ++#define _DT_BINDINGS_GPIO_SANDBOX_GPIO_H ++ ++/* ++ * Add a specific binding for sandbox gpio. ++ * The value need to be after the generic defines of ++ * dt-bindings/gpio/gpio.h ++ */ ++ ++/* Bit 16 express GPIO input mode */ ++#define GPIO_IN 0x10000 ++ ++/* Bit 17 express GPIO output mode */ ++#define GPIO_OUT 0x20000 ++ ++/* Bit 18 express GPIO output is active */ ++#define GPIO_OUT_ACTIVE 0x40000 ++ ++#endif +diff --git a/include/dt-bindings/mfd/stm32h7-rcc.h b/include/dt-bindings/mfd/stm32h7-rcc.h +index 06e8476..a1efc30 100644 +--- a/include/dt-bindings/mfd/stm32h7-rcc.h ++++ b/include/dt-bindings/mfd/stm32h7-rcc.h +@@ -13,7 +13,6 @@ + #define STM32H7_RCC_AHB3_QUADSPI 14 + #define STM32H7_RCC_AHB3_SDMMC1 16 + #define STM32H7_RCC_AHB3_CPU 31 +-#define STM32H7_RCC_AHB3_CPU1 31 + + #define STM32H7_AHB3_RESET(bit) (STM32H7_RCC_AHB3_##bit + (0x7C * 8)) + +diff --git a/include/dt-bindings/pinctrl/stm32-pinfunc.h b/include/dt-bindings/pinctrl/stm32-pinfunc.h +index e6fb8ad..370a25a 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 f0c3aae..bc71924 100644 +--- a/include/dt-bindings/reset/stm32mp1-resets.h ++++ b/include/dt-bindings/reset/stm32mp1-resets.h +@@ -105,4 +105,17 @@ + #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 ++ + #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 0000000..4373c4d +--- /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 0000000..d986653 +--- /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 90a4df8..3f13a90 100644 +--- a/include/env_internal.h ++++ b/include/env_internal.h +@@ -209,6 +209,37 @@ struct env_driver { + + extern struct hsearch_data env_htab; + ++/** ++ * env_ext4_get_intf() - Provide the interface for env in EXT4 ++ * ++ * It is a weak function allowing board to overidde the default interface for ++ * U-Boot env in EXT4: CONFIG_ENV_EXT4_INTERFACE ++ * ++ * @return string of interface, empty if not supported ++ */ ++const char *env_ext4_get_intf(void); ++ ++/** ++ * env_ext4_get_dev_part() - Provide the device and partition for env in EXT4 ++ * ++ * It is a weak function allowing board to overidde the default device and ++ * partition used for U-Boot env in EXT4: CONFIG_ENV_EXT4_DEVICE_AND_PART ++ * ++ * @return string of device and partition ++ */ ++const char *env_ext4_get_dev_part(void); ++ ++/** ++ * env_get_location()- Provide the best location for the U-Boot environment ++ * ++ * It is a weak function allowing board to overidde the environment location ++ * ++ * @op: operations performed on the environment ++ * @prio: priority between the multiple environments, 0 being the ++ * highest priority ++ * @return an enum env_location value on success, or -ve error code. ++ */ ++enum env_location env_get_location(enum env_operation op, int prio); + #endif /* DO_DEPS_ONLY */ + + #endif /* _ENV_INTERNAL_H_ */ +diff --git a/include/fastboot.h b/include/fastboot.h +index 1933b1d..966ffc6 100644 +--- a/include/fastboot.h ++++ b/include/fastboot.h +@@ -36,6 +36,12 @@ enum { + #if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT) + FASTBOOT_COMMAND_OEM_FORMAT, + #endif ++#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF) ++ FASTBOOT_COMMAND_OEM_PARTCONF, ++#endif ++#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS) ++ FASTBOOT_COMMAND_OEM_BOOTBUS, ++#endif + + FASTBOOT_COMMAND_COUNT + }; +diff --git a/include/g_dnl.h b/include/g_dnl.h +index 6d461c7..836ee60 100644 +--- a/include/g_dnl.h ++++ b/include/g_dnl.h +@@ -38,6 +38,7 @@ int g_dnl_board_usb_cable_connected(void); + int g_dnl_register(const char *s); + void g_dnl_unregister(void); + void g_dnl_set_serialnumber(char *); ++void g_dnl_set_product(const char *s); + + bool g_dnl_detach(void); + void g_dnl_trigger_detach(void); +diff --git a/include/i2c.h b/include/i2c.h +index 33570f5..6642480 100644 +--- a/include/i2c.h ++++ b/include/i2c.h +@@ -30,6 +30,32 @@ enum dm_i2c_chip_flags { + DM_I2C_CHIP_WR_ADDRESS = 1 << 2, /* Send address for each write byte */ + }; + ++/** enum i2c_speed_mode - standard I2C speed modes */ ++enum i2c_speed_mode { ++ IC_SPEED_MODE_STANDARD, ++ IC_SPEED_MODE_FAST, ++ IC_SPEED_MODE_FAST_PLUS, ++ IC_SPEED_MODE_HIGH, ++ IC_SPEED_MODE_FAST_ULTRA, ++ ++ IC_SPEED_MODE_COUNT, ++}; ++ ++/** enum i2c_speed_rate - standard I2C speeds in Hz */ ++enum i2c_speed_rate { ++ I2C_SPEED_STANDARD_RATE = 100000, ++ I2C_SPEED_FAST_RATE = 400000, ++ I2C_SPEED_FAST_PLUS_RATE = 1000000, ++ I2C_SPEED_HIGH_RATE = 3400000, ++ I2C_SPEED_FAST_ULTRA_RATE = 5000000, ++}; ++ ++/** enum i2c_address_mode - available address modes */ ++enum i2c_address_mode { ++ I2C_MODE_7_BIT, ++ I2C_MODE_10_BIT ++}; ++ + struct udevice; + /** + * struct dm_i2c_chip - information about an i2c chip +diff --git a/include/image-android-dt.h b/include/image-android-dt.h +index 9a3aa8f..f9abe85 100644 +--- a/include/image-android-dt.h ++++ b/include/image-android-dt.h +@@ -17,4 +17,6 @@ bool android_dt_get_fdt_by_index(ulong hdr_addr, u32 index, ulong *addr, + void android_dt_print_contents(ulong hdr_addr); + #endif + ++int android_dt_get_index(ulong hdr_addr, u32 board_id, u32 board_rev); ++ + #endif /* IMAGE_ANDROID_DT_H */ +diff --git a/include/mipi_dsi.h b/include/mipi_dsi.h +index f4a63b4..52a7a87 100644 +--- a/include/mipi_dsi.h ++++ b/include/mipi_dsi.h +@@ -220,9 +220,15 @@ static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt) + /** + * struct mipi_dsi_panel_plat - DSI panel platform data + * @device: DSI peripheral device ++ * @lanes: number of active data lanes ++ * @format: pixel format for video mode ++ * @mode_flags: DSI operation mode related flags + */ + struct mipi_dsi_panel_plat { + struct mipi_dsi_device *device; ++ unsigned int lanes; ++ enum mipi_dsi_pixel_format format; ++ unsigned long mode_flags; + }; + + /** +diff --git a/include/mtd.h b/include/mtd.h +index 65fcd3c..b0f8693 100644 +--- a/include/mtd.h ++++ b/include/mtd.h +@@ -11,4 +11,6 @@ + int mtd_probe(struct udevice *dev); + int mtd_probe_devices(void); + ++void board_mtdparts_default(const char **mtdids, const char **mtdparts); ++ + #endif /* _MTD_H_ */ +diff --git a/include/power/stpmic1.h b/include/power/stpmic1.h +index dc8b5a7..1493a67 100644 +--- a/include/power/stpmic1.h ++++ b/include/power/stpmic1.h +@@ -37,6 +37,7 @@ + #define STPMIC1_BUCK_VOUT(sel) (sel << STPMIC1_BUCK_VOUT_SHIFT) + + #define STPMIC1_BUCK2_1200000V STPMIC1_BUCK_VOUT(24) ++#define STPMIC1_BUCK2_1250000V STPMIC1_BUCK_VOUT(26) + #define STPMIC1_BUCK2_1350000V STPMIC1_BUCK_VOUT(30) + + #define STPMIC1_BUCK3_1800000V STPMIC1_BUCK_VOUT(39) +diff --git a/include/remoteproc.h b/include/remoteproc.h +index 046cd9e..a903acb 100644 +--- a/include/remoteproc.h ++++ b/include/remoteproc.h +@@ -277,6 +277,64 @@ int rproc_elf_load_image(struct udevice *dev, unsigned long addr, ulong size); + * image. + */ + ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr); ++ ++/** ++ * rproc_elf32_load_rsc_table() - load the resource table from an ELF32 image ++ * ++ * Search for the resource table in an ELF32 image, and if found, copy it to ++ * device memory. ++ * ++ * @dev: device loading the resource table ++ * @fw_addr: ELF image address ++ * @fw_size: size of the ELF image ++ * @rsc_addr: pointer to the found resource table address. Updated on ++ * operation success ++ * @rsc_size: pointer to the found resource table size. Updated on operation ++ * success ++ * ++ * @return 0 if a valid resource table is successfully loaded, -ENODATA if there ++ * is no resource table (which is optional), or another appropriate error value. ++ */ ++int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr, ++ ulong fw_size, ulong *rsc_addr, ulong *rsc_size); ++/** ++ * rproc_elf64_load_rsc_table() - load the resource table from an ELF64 image ++ * ++ * Search for the resource table in an ELF64 image, and if found, copy it to ++ * device memory. ++ * ++ * @dev: device loading the resource table ++ * @fw_addr: ELF image address ++ * @fw_size: size of the ELF image ++ * @rsc_addr: pointer to the found resource table address. Updated on ++ * operation success ++ * @rsc_size: pointer to the found resource table size. Updated on operation ++ * success ++ * ++ * @return 0 if a valid resource table is successfully loaded, -ENODATA if there ++ * is no resource table (which is optional), or another appropriate error value. ++ */ ++int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr, ++ ulong fw_size, ulong *rsc_addr, ulong *rsc_size); ++/** ++ * rproc_elf_load_rsc_table() - load the resource table from an ELF image ++ * ++ * Auto detects if the image is ELF32 or ELF64 image and search accordingly for ++ * the resource table, and if found, copy it to device memory. ++ * ++ * @dev: device loading the resource table ++ * @fw_addr: ELF image address ++ * @fw_size: size of the ELF image ++ * @rsc_addr: pointer to the found resource table address. Updated on ++ * operation success ++ * @rsc_size: pointer to the found resource table size. Updated on operation ++ * success ++ * ++ * @return 0 if a valid resource table is successfully loaded, -ENODATA if there ++ * is no resource table (which is optional), or another appropriate error value. ++ */ ++int rproc_elf_load_rsc_table(struct udevice *dev, ulong fw_addr, ++ ulong fw_size, ulong *rsc_addr, ulong *rsc_size); + #else + static inline int rproc_init(void) { return -ENOSYS; } + static inline int rproc_dev_init(int id) { return -ENOSYS; } +@@ -304,6 +362,18 @@ static inline int rproc_elf_load_image(struct udevice *dev, ulong addr, + { return -ENOSYS; } + static inline ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr) + { return 0; } ++static inline int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr, ++ ulong fw_size, ulong *rsc_addr, ++ ulong *rsc_size) ++{ return -ENOSYS; } ++static inline int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr, ++ ulong fw_size, ulong *rsc_addr, ++ ulong *rsc_size) ++{ return -ENOSYS; } ++static inline int rproc_elf_load_rsc_table(struct udevice *dev, ulong fw_addr, ++ ulong fw_size, ulong *rsc_addr, ++ ulong *rsc_size) ++{ return -ENOSYS; } + #endif + + #endif /* _RPROC_H_ */ +diff --git a/include/scmi_agent.h b/include/scmi_agent.h +new file mode 100644 +index 0000000..78fcc3b +--- /dev/null ++++ b/include/scmi_agent.h +@@ -0,0 +1,82 @@ ++/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ ++/* ++ * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. ++ * Copyright (C) 2019, Linaro Limited ++ */ ++#ifndef SCMI_AGENT_H ++#define SCMI_AGENT_H ++ ++#include ++ ++/** ++ * An SCMI agent represent on communication path from a device driver to ++ * the remote SCMI server which driver sends messages to and receives ++ * response messages from. ++ */ ++struct scmi_agent; ++ ++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, ++}; ++ ++/* ++ * 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_size: Byte size of the response buffer or 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; ++}; ++ ++/** ++ * 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, a negative errno otherwise ++ */ ++int scmi_agent_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(int32_t scmi_errno); ++ ++#endif /* SCMI_AGENT_H */ +diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c +index 560041b..be03aea 100644 +--- a/lib/libfdt/fdt_ro.c ++++ b/lib/libfdt/fdt_ro.c +@@ -183,8 +183,8 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) + if (fdt_chk_extra() && !re) + return -FDT_ERR_BADOFFSET; + +- *address = fdt64_ld(&re->address); +- *size = fdt64_ld(&re->size); ++ *address = fdt64_to_cpu(re->address); ++ *size = fdt64_to_cpu(re->size); + return 0; + } + +@@ -194,7 +194,7 @@ int fdt_num_mem_rsv(const void *fdt) + const struct fdt_reserve_entry *re; + + for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) { +- if (fdt64_ld(&re->size) == 0) ++ if (fdt64_to_cpu(re->size) == 0) + return i; + } + return -FDT_ERR_TRUNCATED; +@@ -372,7 +372,7 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt, + prop = fdt_offset_ptr_(fdt, offset); + + if (lenp) +- *lenp = fdt32_ld(&prop->len); ++ *lenp = fdt32_to_cpu(prop->len); + + return prop; + } +@@ -410,7 +410,7 @@ static const struct fdt_property *fdt_get_property_namelen_(const void *fdt, + offset = -FDT_ERR_INTERNAL; + break; + } +- if (fdt_string_eq_(fdt, fdt32_ld(&prop->nameoff), ++ if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff), + name, namelen)) { + if (poffset) + *poffset = offset; +@@ -463,7 +463,7 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, + + /* Handle realignment */ + if (fdt_chk_version() && fdt_version(fdt) < 0x10 && +- (poffset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8) ++ (poffset + sizeof(*prop)) % 8 && fdt32_to_cpu(prop->len) >= 8) + return prop->data + 4; + return prop->data; + } +@@ -481,7 +481,7 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, + int namelen; + + if (fdt_chk_extra()) { +- name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff), ++ name = fdt_get_string(fdt, fdt32_to_cpu(prop->nameoff), + &namelen); + if (!name) { + if (lenp) +@@ -490,13 +490,13 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, + } + *namep = name; + } else { +- *namep = fdt_string(fdt, fdt32_ld(&prop->nameoff)); ++ *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + } + } + + /* Handle realignment */ + if (fdt_chk_version() && fdt_version(fdt) < 0x10 && +- (offset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8) ++ (offset + sizeof(*prop)) % 8 && fdt32_to_cpu(prop->len) >= 8) + return prop->data + 4; + return prop->data; + } +@@ -521,7 +521,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) + return 0; + } + +- return fdt32_ld(php); ++ return fdt32_to_cpu(*php); + } + + const char *fdt_get_alias_namelen(const void *fdt, +diff --git a/lib/optee/optee.c b/lib/optee/optee.c +index c883c49..79b058a 100644 +--- a/lib/optee/optee.c ++++ b/lib/optee/optee.c +@@ -91,7 +91,7 @@ static int optee_copy_firmware_node(const void *old_blob, void *fdt_blob) + + offs = fdt_add_subnode(fdt_blob, offs, "optee"); + if (offs < 0) +- return ret; ++ return offs; + + /* copy the compatible property */ + prop = fdt_getprop(old_blob, old_offs, "compatible", &len); +diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt +index cf1808e..db089be 100644 +--- a/scripts/config_whitelist.txt ++++ b/scripts/config_whitelist.txt +@@ -1547,7 +1547,6 @@ CONFIG_SETUP_MEMORY_TAGS + CONFIG_SET_BIST + CONFIG_SET_BOOTARGS + CONFIG_SET_DFU_ALT_BUF_LEN +-CONFIG_SET_DFU_ALT_INFO + CONFIG_SFIO + CONFIG_SF_DATAFLASH + CONFIG_SGI_IP28 +@@ -3228,7 +3227,6 @@ CONFIG_SYS_MRAM_SIZE + CONFIG_SYS_MSC0_VAL + CONFIG_SYS_MSC1_VAL + CONFIG_SYS_MSC2_VAL +-CONFIG_SYS_MTDPARTS_RUNTIME + CONFIG_SYS_MX5_CLK32 + CONFIG_SYS_MX5_HCLK + CONFIG_SYS_MX6_CLK32 +diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c +index e398815..d9d52e0 100644 +--- a/scripts/dtc/libfdt/fdt_ro.c ++++ b/scripts/dtc/libfdt/fdt_ro.c +@@ -179,8 +179,8 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) + if (fdt_chk_extra() && !re) + return -FDT_ERR_BADOFFSET; + +- *address = fdt64_ld(&re->address); +- *size = fdt64_ld(&re->size); ++ *address = fdt64_to_cpu(re->address); ++ *size = fdt64_to_cpu(re->size); + return 0; + } + +@@ -190,7 +190,7 @@ int fdt_num_mem_rsv(const void *fdt) + const struct fdt_reserve_entry *re; + + for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) { +- if (fdt64_ld(&re->size) == 0) ++ if (fdt64_to_cpu(re->size) == 0) + return i; + } + return -FDT_ERR_TRUNCATED; +@@ -368,7 +368,7 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt, + prop = fdt_offset_ptr_(fdt, offset); + + if (lenp) +- *lenp = fdt32_ld(&prop->len); ++ *lenp = fdt32_to_cpu(prop->len); + + return prop; + } +@@ -406,7 +406,7 @@ static const struct fdt_property *fdt_get_property_namelen_(const void *fdt, + offset = -FDT_ERR_INTERNAL; + break; + } +- if (fdt_string_eq_(fdt, fdt32_ld(&prop->nameoff), ++ if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff), + name, namelen)) { + if (poffset) + *poffset = offset; +@@ -459,7 +459,7 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, + + /* Handle realignment */ + if (fdt_chk_version() && fdt_version(fdt) < 0x10 && +- (poffset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8) ++ (poffset + sizeof(*prop)) % 8 && fdt32_to_cpu(prop->len) >= 8) + return prop->data + 4; + return prop->data; + } +@@ -477,7 +477,7 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, + int namelen; + + if (fdt_chk_extra()) { +- name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff), ++ name = fdt_get_string(fdt, fdt32_to_cpu(prop->nameoff), + &namelen); + if (!name) { + if (lenp) +@@ -486,13 +486,13 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, + } + *namep = name; + } else { +- *namep = fdt_string(fdt, fdt32_ld(&prop->nameoff)); ++ *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + } + } + + /* Handle realignment */ + if (fdt_chk_version() && fdt_version(fdt) < 0x10 && +- (offset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8) ++ (offset + sizeof(*prop)) % 8 && fdt32_to_cpu(prop->len) >= 8) + return prop->data + 4; + return prop->data; + } +@@ -517,7 +517,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) + return 0; + } + +- return fdt32_ld(php); ++ return fdt32_to_cpu(*php); + } + + const char *fdt_get_alias_namelen(const void *fdt, +diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h +index 36fadcd..fa63fff 100644 +--- a/scripts/dtc/libfdt/libfdt.h ++++ b/scripts/dtc/libfdt/libfdt.h +@@ -117,23 +117,6 @@ static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) + + uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); + +-/* +- * Alignment helpers: +- * These helpers access words from a device tree blob. They're +- * built to work even with unaligned pointers on platforms (ike +- * ARM) that don't like unaligned loads and stores +- */ +- +-static inline uint32_t fdt32_ld(const fdt32_t *p) +-{ +- const uint8_t *bp = (const uint8_t *)p; +- +- return ((uint32_t)bp[0] << 24) +- | ((uint32_t)bp[1] << 16) +- | ((uint32_t)bp[2] << 8) +- | bp[3]; +-} +- + static inline void fdt32_st(void *property, uint32_t value) + { + uint8_t *bp = (uint8_t *)property; +@@ -144,20 +127,6 @@ static inline void fdt32_st(void *property, uint32_t value) + bp[3] = value & 0xff; + } + +-static inline uint64_t fdt64_ld(const fdt64_t *p) +-{ +- const uint8_t *bp = (const uint8_t *)p; +- +- return ((uint64_t)bp[0] << 56) +- | ((uint64_t)bp[1] << 48) +- | ((uint64_t)bp[2] << 40) +- | ((uint64_t)bp[3] << 32) +- | ((uint64_t)bp[4] << 24) +- | ((uint64_t)bp[5] << 16) +- | ((uint64_t)bp[6] << 8) +- | bp[7]; +-} +- + static inline void fdt64_st(void *property, uint64_t value) + { + uint8_t *bp = (uint8_t *)property; +@@ -232,7 +201,7 @@ int fdt_next_subnode(const void *fdt, int offset); + /* General functions */ + /**********************************************************************/ + #define fdt_get_header(fdt, field) \ +- (fdt32_ld(&((const struct fdt_header *)(fdt))->field)) ++ (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) + #define fdt_magic(fdt) (fdt_get_header(fdt, magic)) + #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) + #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) +diff --git a/test/dm/Makefile b/test/dm/Makefile +index 0c2fd5c..6a1af15 100644 +--- a/test/dm/Makefile ++++ b/test/dm/Makefile +@@ -29,6 +29,7 @@ obj-$(CONFIG_LED) += led.o + obj-$(CONFIG_DM_MAILBOX) += mailbox.o + obj-$(CONFIG_DM_MMC) += mmc.o + obj-y += ofnode.o ++obj-y += ofread.o + obj-$(CONFIG_OSD) += osd.o + obj-$(CONFIG_DM_VIDEO) += panel.o + obj-$(CONFIG_DM_PCI) += pci.o +diff --git a/test/dm/gpio.c b/test/dm/gpio.c +index bb4b20c..5992d93 100644 +--- a/test/dm/gpio.c ++++ b/test/dm/gpio.c +@@ -23,9 +23,9 @@ static int dm_test_gpio(struct unit_test_state *uts) + char buf[80]; + + /* +- * We expect to get 3 banks. One is anonymous (just numbered) and +- * comes from platdata. The other two are named a (20 gpios) +- * and b (10 gpios) and come from the device tree. See ++ * We expect to get 4 banks. One is anonymous (just numbered) and ++ * comes from platdata. The other are named a (20 gpios), ++ * b (10 gpios) and c (10 gpios) and come from the device tree. See + * test/dm/test.dts. + */ + ut_assertok(gpio_lookup_name("b4", &dev, &offset, &gpio)); +@@ -73,11 +73,16 @@ static int dm_test_gpio(struct unit_test_state *uts) + ut_asserteq(1, ops->get_value(dev, offset)); + + /* Make it an open drain output, and reset it */ +- ut_asserteq(0, sandbox_gpio_get_open_drain(dev, offset)); +- ut_assertok(ops->set_open_drain(dev, offset, 1)); +- ut_asserteq(1, sandbox_gpio_get_open_drain(dev, offset)); +- ut_assertok(ops->set_open_drain(dev, offset, 0)); +- ut_asserteq(0, sandbox_gpio_get_open_drain(dev, offset)); ++ ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE, ++ sandbox_gpio_get_dir_flags(dev, offset)); ++ ut_assertok(ops->set_dir_flags(dev, offset, ++ GPIOD_IS_OUT | GPIOD_OPEN_DRAIN)); ++ ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN, ++ sandbox_gpio_get_dir_flags(dev, offset)); ++ ut_assertok(ops->set_dir_flags(dev, offset, ++ GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE)); ++ ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE, ++ sandbox_gpio_get_dir_flags(dev, offset)); + + /* Make it an input */ + ut_assertok(ops->direction_input(dev, offset)); +@@ -214,11 +219,14 @@ static int dm_test_gpio_phandles(struct unit_test_state *uts) + desc_list2, + ARRAY_SIZE(desc_list2), + 0)); ++ ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 4, NULL)); + ut_assertok(gpio_free_list(dev, desc_list, 3)); ++ ut_asserteq(GPIOF_UNUSED, gpio_get_function(gpio_a, 4, NULL)); + ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc_list, + ARRAY_SIZE(desc_list), + GPIOD_IS_OUT | + GPIOD_IS_OUT_ACTIVE)); ++ ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_a, 4, NULL)); + ut_asserteq_ptr(gpio_a, desc_list[0].dev); + ut_asserteq(1, desc_list[0].offset); + ut_asserteq_ptr(gpio_a, desc_list[1].dev); +@@ -228,10 +236,14 @@ static int dm_test_gpio_phandles(struct unit_test_state *uts) + ut_asserteq(1, dm_gpio_get_value(desc_list)); + ut_assertok(gpio_free_list(dev, desc_list, 3)); + ++ ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE, ++ sandbox_gpio_get_dir_flags(gpio_a, 1)); + ut_asserteq(6, gpio_request_list_by_name(dev, "test2-gpios", desc_list, + ARRAY_SIZE(desc_list), 0)); +- /* This was set to output previously, so still will be */ +- ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_a, 1, NULL)); ++ ++ /* This was set to output previously but flags resetted to 0 = INPUT */ ++ ut_asserteq(0, sandbox_gpio_get_dir_flags(gpio_a, 1)); ++ ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 1, NULL)); + + /* Active low should invert the input value */ + ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 6, NULL)); +@@ -243,7 +255,42 @@ static int dm_test_gpio_phandles(struct unit_test_state *uts) + ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 9, NULL)); + ut_asserteq(1, dm_gpio_get_value(&desc_list[5])); + +- + return 0; + } + DM_TEST(dm_test_gpio_phandles, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); ++ ++/* Check the gpio pin configuration get from device tree information */ ++static int dm_test_gpio_get_dir_flags(struct unit_test_state *uts) ++{ ++ struct gpio_desc desc_list[6]; ++ struct udevice *dev; ++ ulong flags; ++ ++ ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); ++ ++ ut_asserteq(6, gpio_request_list_by_name(dev, "test3-gpios", desc_list, ++ ARRAY_SIZE(desc_list), 0)); ++ ++ ut_assertok(dm_gpio_get_dir_flags(&desc_list[0], &flags)); ++ ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN, flags); ++ ++ ut_assertok(dm_gpio_get_dir_flags(&desc_list[1], &flags)); ++ ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_SOURCE, flags); ++ ++ ut_assertok(dm_gpio_get_dir_flags(&desc_list[2], &flags)); ++ ut_asserteq(GPIOD_IS_OUT, flags); ++ ++ ut_assertok(dm_gpio_get_dir_flags(&desc_list[3], &flags)); ++ ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_UP, flags); ++ ++ ut_assertok(dm_gpio_get_dir_flags(&desc_list[4], &flags)); ++ ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_DOWN, flags); ++ ++ ut_assertok(dm_gpio_get_dir_flags(&desc_list[5], &flags)); ++ ut_asserteq(GPIOD_IS_IN, flags); ++ ++ ut_assertok(gpio_free_list(dev, desc_list, 6)); ++ ++ return 0; ++} ++DM_TEST(dm_test_gpio_get_dir_flags, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); +diff --git a/test/dm/ofread.c b/test/dm/ofread.c +new file mode 100644 +index 0000000..f2a1382 +--- /dev/null ++++ b/test/dm/ofread.c +@@ -0,0 +1,50 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++ ++#include ++#include ++#include ++#include ++ ++static int dm_test_ofnode_get_property_by_prop(struct unit_test_state *uts) ++{ ++ ofnode node; ++ struct ofprop prop; ++ const void *value; ++ const char *propname; ++ int res, len, count = 0; ++ ++ node = ofnode_path("/cros-ec/flash"); ++ for (res = ofnode_get_first_property(node, &prop); ++ !res; ++ res = ofnode_get_next_property(&prop)) { ++ value = ofnode_get_property_by_prop(&prop, &propname, &len); ++ ut_assertnonnull(value); ++ switch (count) { ++ case 0: ++ ut_asserteq_str("image-pos", propname); ++ ut_asserteq(4, len); ++ break; ++ case 1: ++ ut_asserteq_str("size", propname); ++ ut_asserteq(4, len); ++ break; ++ case 2: ++ ut_asserteq_str("erase-value", propname); ++ ut_asserteq(4, len); ++ break; ++ case 3: ++ /* only for platdata */ ++ ut_asserteq_str("name", propname); ++ ut_asserteq(6, len); ++ ut_asserteq_str("flash", value); ++ break; ++ default: ++ break; ++ } ++ count++; ++ } ++ ++ return 0; ++} ++DM_TEST(dm_test_ofnode_get_property_by_prop, ++ DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); +diff --git a/test/dm/remoteproc.c b/test/dm/remoteproc.c +index 1d9a9b3..4067596 100644 +--- a/test/dm/remoteproc.c ++++ b/test/dm/remoteproc.c +@@ -103,8 +103,8 @@ static int dm_test_remoteproc_elf(struct unit_test_state *uts) + 0x00, 0x00, 0x00, 0x08, + /* phoff (program header offset @ 0x40)*/ + 0x40, 0x00, 0x00, 0x00, +- /* shoff (section header offset : none) */ +- 0x00, 0x00, 0x00, 0x00, ++ /* shoff (section header offset @ 0x90) */ ++ 0x90, 0x00, 0x00, 0x00, + /* flags */ + 0x00, 0x00, 0x00, 0x00, + /* ehsize (elf header size = 0x34) */ +@@ -113,16 +113,17 @@ static int dm_test_remoteproc_elf(struct unit_test_state *uts) + 0x20, 0x00, + /* phnum (program header number : 1) */ + 0x01, 0x00, +- /* shentsize (section heade size : none) */ +- 0x00, 0x00, +- /* shnum (section header number: none) */ +- 0x00, 0x00, +- /* shstrndx (section header name section index: none) */ +- 0x00, 0x00, ++ /* shentsize (section header size : 40 bytes) */ ++ 0x28, 0x00, ++ /* shnum (section header number: 3) */ ++ 0x02, 0x00, ++ /* shstrndx (section header name section index: 1) */ ++ 0x01, 0x00, + /* padding */ + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, ++ + /* @0x40 - PROGRAM HEADER TABLE - */ + /* type : PT_LOAD */ + 0x01, 0x00, 0x00, 0x00, +@@ -140,14 +141,63 @@ static int dm_test_remoteproc_elf(struct unit_test_state *uts) + 0x05, 0x00, 0x00, 0x00, + /* padding */ + 0x00, 0x00, 0x00, 0x00, ++ ++ /* @0x60 - RESOURCE TABLE SECTION - */ ++ /* version */ ++ 0x01, 0x00, 0x00, 0x00, ++ /* num (0, no entries) */ ++ 0x00, 0x00, 0x00, 0x00, ++ /* Reserved */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ ++ /* @0x70 - SECTION'S NAMES SECTION - */ ++ /* section 0 name (".shrtrtab") */ ++ 0x2e, 0x73, 0x68, 0x73, 0x74, 0x72, 0x74, 0x61, 0x62, 0x00, ++ /* section 1 name (".resource_table") */ ++ 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, ++ 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, ++ /* padding */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ ++ /* @0x90 - SECTION HEADER TABLE - */ ++ /* Section 0 : resource table header */ ++ /* sh_name - index into section header string table section */ ++ 0x0a, 0x00, 0x00, 0x00, ++ /* sh_type and sh_flags */ ++ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, ++ /* sh_addr = where the resource table has to be copied to */ ++ 0x00, 0x00, 0x00, 0x00, ++ /* sh_offset = 0x60 */ ++ 0x60, 0x00, 0x00, 0x00, ++ /* sh_size = 16 bytes */ ++ 0x10, 0x00, 0x00, 0x00, ++ /* sh_link, sh_info, sh_addralign, sh_entsize */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* Section 1 : section's names section header */ ++ /* sh_name - index into section header string table section */ ++ 0x00, 0x00, 0x00, 0x00, ++ /* sh_type and sh_flags */ ++ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* sh_addr */ ++ 0x00, 0x00, 0x00, 0x00, ++ /* sh_offset = 0x70 */ ++ 0x70, 0x00, 0x00, 0x00, ++ /* sh_size = 27 bytes */ ++ 0x1b, 0x00, 0x00, 0x00, ++ /* sh_link, sh_info, sh_addralign, sh_entsize */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + unsigned int size = ARRAY_SIZE(valid_elf32); + struct udevice *dev; +- phys_addr_t loaded_firmware_paddr; +- void *loaded_firmware; +- u32 loaded_firmware_size; ++ phys_addr_t loaded_firmware_paddr, loaded_rsc_table_paddr; ++ void *loaded_firmware, *loaded_rsc_table; ++ u32 loaded_firmware_size, rsc_table_size; ++ ulong rsc_addr, rsc_size; + Elf32_Ehdr *ehdr = (Elf32_Ehdr *)valid_elf32; + Elf32_Phdr *phdr = (Elf32_Phdr *)(valid_elf32 + ehdr->e_phoff); ++ Elf32_Shdr *shdr = (Elf32_Shdr *)(valid_elf32 + ehdr->e_shoff); + + ut_assertok(uclass_get_device(UCLASS_REMOTEPROC, 0, &dev)); + +@@ -178,6 +228,25 @@ static int dm_test_remoteproc_elf(struct unit_test_state *uts) + 0x08000000); + unmap_physmem(loaded_firmware, MAP_NOCACHE); + ++ /* Resource table */ ++ shdr->sh_addr = CONFIG_SYS_SDRAM_BASE; ++ rsc_table_size = shdr->sh_size; ++ ++ loaded_rsc_table_paddr = shdr->sh_addr + DEVICE_TO_PHYSICAL_OFFSET; ++ loaded_rsc_table = map_physmem(loaded_rsc_table_paddr, ++ rsc_table_size, MAP_NOCACHE); ++ ut_assertnonnull(loaded_rsc_table); ++ memset(loaded_rsc_table, 0, rsc_table_size); ++ ++ /* Load and verify */ ++ ut_assertok(rproc_elf32_load_rsc_table(dev, (ulong)valid_elf32, size, ++ &rsc_addr, &rsc_size)); ++ ut_asserteq(rsc_addr, CONFIG_SYS_SDRAM_BASE); ++ ut_asserteq(rsc_size, rsc_table_size); ++ ut_assertok(memcmp(loaded_firmware, valid_elf32 + shdr->sh_offset, ++ shdr->sh_size)); ++ unmap_physmem(loaded_firmware, MAP_NOCACHE); ++ + /* Invalid ELF Magic */ + valid_elf32[0] = 0; + ut_asserteq(-EPROTONOSUPPORT, +diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c +index 1fb8b5c..0997d2b 100644 +--- a/test/dm/test-fdt.c ++++ b/test/dm/test-fdt.c +@@ -196,7 +196,7 @@ static int dm_test_fdt(struct unit_test_state *uts) + int ret; + int i; + +- ret = dm_scan_fdt(gd->fdt_blob, false); ++ ret = dm_extended_scan_fdt(gd->fdt_blob, false); + ut_assert(!ret); + + ret = uclass_get(UCLASS_TEST_FDT, &uc); +@@ -227,7 +227,7 @@ static int dm_test_alias_highest_id(struct unit_test_state *uts) + ut_asserteq(5, ret); + + ret = dev_read_alias_highest_id("gpio"); +- ut_asserteq(2, ret); ++ ut_asserteq(3, ret); + + ret = dev_read_alias_highest_id("pci"); + ut_asserteq(2, ret); +diff --git a/test/py/tests/test_env.py b/test/py/tests/test_env.py +index 6ff38f1..cbdb410 100644 +--- a/test/py/tests/test_env.py ++++ b/test/py/tests/test_env.py +@@ -336,3 +336,47 @@ def test_env_import_whitelist_delete(state_test_env): + unset_var(state_test_env, 'foo2') + unset_var(state_test_env, 'foo3') + unset_var(state_test_env, 'foo4') ++ ++@pytest.mark.boardspec('sandbox') ++@pytest.mark.buildconfigspec('cmd_nvedit_info') ++def test_env_info(state_test_env): ++ ++ """Test 'env info' command with several options. ++ """ ++ c = state_test_env.u_boot_console ++ ++ response = c.run_command('env info') ++ assert 'env_valid = invalid' in response ++ assert 'env_ready = true' in response ++ assert 'env_use_default = true' in response ++ ++ response = c.run_command('env info -p -d') ++ assert 'Default environment is used' in response ++ assert 'Environment cannot be persisted' in response ++ ++ response = c.run_command('env info -p -d -q') ++ assert response == "" ++ ++@pytest.mark.boardspec('sandbox') ++@pytest.mark.buildconfigspec('cmd_nvedit_info') ++@pytest.mark.buildconfigspec('cmd_echo') ++def test_env_info_quiet(state_test_env): ++ ++ """Test 'env info' quiet command result with several options for test. ++ """ ++ c = state_test_env.u_boot_console ++ ++ response = c.run_command('env info -d -q') ++ assert response == "" ++ response = c.run_command('echo $?') ++ assert response == "0" ++ ++ response = c.run_command('env info -p -q') ++ assert response == "" ++ response = c.run_command('echo $?') ++ assert response == "1" ++ ++ response = c.run_command('env info -d -p -q') ++ assert response == "" ++ response = c.run_command('echo $?') ++ assert response == "1" +diff --git a/test/py/tests/test_pinmux.py b/test/py/tests/test_pinmux.py +index 25394f1..4e6df99 100644 +--- a/test/py/tests/test_pinmux.py ++++ b/test/py/tests/test_pinmux.py +@@ -22,11 +22,21 @@ def test_pinmux_usage_2(u_boot_console): + def test_pinmux_status_all(u_boot_console): + """Test that 'pinmux status -a' displays pin's muxing.""" + output = u_boot_console.run_command('pinmux status -a') +- assert ('SCL : I2C SCL' in output) +- assert ('SDA : I2C SDA' in output) +- assert ('TX : Uart TX' in output) +- assert ('RX : Uart RX' in output) +- assert ('W1 : 1-wire gpio' in output) ++ ++ assert ('pinctrl-gpio:' in output) ++ assert ('a5 : gpio output .' in output) ++ assert ('a6 : gpio output .' in output) ++ ++ assert ('pinctrl:' in output) ++ assert ('SCL : I2C SCL.' in output) ++ assert ('SDA : I2C SDA.' in output) ++ assert ('TX : Uart TX.' in output) ++ assert ('RX : Uart RX.' in output) ++ assert ('W1 : 1-wire gpio.' in output) ++ assert ('GPIO0 : gpio bias-pull-up input-disable.' in output) ++ assert ('GPIO1 : gpio drive-open-drain.' in output) ++ assert ('GPIO2 : gpio bias-pull-down input-enable.' in output) ++ assert ('GPIO3 : gpio bias-disable.' in output) + + @pytest.mark.buildconfigspec('cmd_pinmux') + @pytest.mark.boardspec('sandbox') +@@ -59,8 +69,16 @@ def test_pinmux_status(u_boot_console): + """Test that 'pinmux status' displays selected pincontroller's pin + muxing descriptions.""" + output = u_boot_console.run_command('pinmux status') +- assert ('SCL : I2C SCL' in output) +- assert ('SDA : I2C SDA' in output) +- assert ('TX : Uart TX' in output) +- assert ('RX : Uart RX' in output) +- assert ('W1 : 1-wire gpio' in output) ++ ++ assert (not 'pinctrl-gpio:' in output) ++ assert (not 'pinctrl:' in output) ++ ++ assert ('SCL : I2C SCL.' in output) ++ assert ('SDA : I2C SDA.' in output) ++ assert ('TX : Uart TX.' in output) ++ assert ('RX : Uart RX.' in output) ++ assert ('W1 : 1-wire gpio.' in output) ++ assert ('GPIO0 : gpio bias-pull-up input-disable.' in output) ++ assert ('GPIO1 : gpio drive-open-drain.' in output) ++ assert ('GPIO2 : gpio bias-pull-down input-enable.' in output) ++ assert ('GPIO3 : gpio bias-disable.' in output) +diff --git a/tools/fdtgrep.c b/tools/fdtgrep.c +index 8f44f59..2a8058f 100644 +--- a/tools/fdtgrep.c ++++ b/tools/fdtgrep.c +@@ -805,7 +805,7 @@ static int do_fdtgrep(struct display_info *disp, const char *filename) + * we do another pass to actually record them. + */ + for (i = 0; i < 2; i++) { +- region = malloc(count * sizeof(struct fdt_region)); ++ region = realloc(region, count * sizeof(struct fdt_region)); + if (!region) { + fprintf(stderr, "Out of memory for %d regions\n", + count); +@@ -823,8 +823,10 @@ static int do_fdtgrep(struct display_info *disp, const char *filename) + } + if (count <= max_regions) + break; ++ } ++ if (count > max_regions) { + free(region); +- fprintf(stderr, "Internal error with fdtgrep_find_region)(\n"); ++ fprintf(stderr, "Internal error with fdtgrep_find_region()\n"); + return -1; + } + +diff --git a/tools/stm32image.c b/tools/stm32image.c +index ff3ec5f..18357c0 100644 +--- a/tools/stm32image.c ++++ b/tools/stm32image.c +@@ -45,7 +45,7 @@ static void stm32image_default_header(struct stm32_header *ptr) + ptr->magic_number = HEADER_MAGIC; + ptr->header_version[VER_MAJOR_IDX] = HEADER_VERSION_V1; + ptr->option_flags = HEADER_DEFAULT_OPTION; +- ptr->ecdsa_algorithm = 1; ++ ptr->ecdsa_algorithm = cpu_to_le32(1); + ptr->binary_type = HEADER_TYPE_UBOOT; + } + +@@ -131,7 +131,8 @@ static void stm32image_set_header(void *ptr, struct stat *sbuf, int ifd, + stm32hdr->image_entry_point = cpu_to_le32(params->ep); + stm32hdr->image_length = cpu_to_le32((uint32_t)sbuf->st_size - + sizeof(struct stm32_header)); +- stm32hdr->image_checksum = stm32image_checksum(ptr, sbuf->st_size); ++ stm32hdr->image_checksum = ++ cpu_to_le32(stm32image_checksum(ptr, sbuf->st_size)); + } + + /* +-- +2.7.4 + diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0004-ARM-v2018.11-stm32mp-r1-CONFIG.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0004-ARM-v2018.11-stm32mp-r1-CONFIG.patch deleted file mode 100644 index 1670dc5..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0004-ARM-v2018.11-stm32mp-r1-CONFIG.patch +++ /dev/null @@ -1,378 +0,0 @@ -From b8317d14837ab109d5063c84a8cde6c6de474970 Mon Sep 17 00:00:00 2001 -From: christophe montaud -Date: Fri, 4 Jan 2019 15:08:43 +0100 -Subject: [PATCH 4/5] ARM v2018.11 stm32mp r1 CONFIG - ---- - configs/sandbox_defconfig | 2 + - configs/stm32mp15_basic_defconfig | 71 ++++++++++++++++++++---- - configs/stm32mp15_optee_defconfig | 105 ++++++++++++++++++++++++++++++++++++ - configs/stm32mp15_trusted_defconfig | 104 +++++++++++++++++++++++++++++++++++ - 4 files changed, 273 insertions(+), 9 deletions(-) - create mode 100644 configs/stm32mp15_optee_defconfig - create mode 100644 configs/stm32mp15_trusted_defconfig - -diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig -index 5a744f4..587e2aa 100644 ---- a/configs/sandbox_defconfig -+++ b/configs/sandbox_defconfig -@@ -215,3 +215,5 @@ CONFIG_UT_TIME=y - CONFIG_UT_DM=y - CONFIG_UT_ENV=y - CONFIG_UT_OVERLAY=y -+CONFIG_DM_HWSPINLOCK=y -+CONFIG_HWSPINLOCK_SANDBOX=y -diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig -index 3bf7538..ad3424e 100644 ---- a/configs/stm32mp15_basic_defconfig -+++ b/configs/stm32mp15_basic_defconfig -@@ -1,14 +1,18 @@ - CONFIG_ARM=y - CONFIG_ARCH_STM32MP=y --CONFIG_SYS_MALLOC_F_LEN=0x2000 -+CONFIG_SYS_MALLOC_F_LEN=0x3000 - CONFIG_SPL_MMC_SUPPORT=y - CONFIG_SPL=y - CONFIG_TARGET_STM32MP1=y -+CONFIG_SPL_SPI_FLASH_SUPPORT=y -+CONFIG_SPL_SPI_SUPPORT=y -+# CONFIG_ARMV7_VIRT is not set - CONFIG_DISTRO_DEFAULTS=y --CONFIG_NR_DRAM_BANKS=1 -+CONFIG_FIT=y - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=3 - CONFIG_SPL_I2C_SUPPORT=y -+CONFIG_SPL_MTD_SUPPORT=y - CONFIG_SPL_POWER_SUPPORT=y - CONFIG_SYS_PROMPT="STM32MP> " - # CONFIG_CMD_BOOTD is not set -@@ -18,48 +22,97 @@ CONFIG_SYS_PROMPT="STM32MP> " - # CONFIG_CMD_EXPORTENV is not set - # CONFIG_CMD_IMPORTENV is not set - CONFIG_CMD_MEMINFO=y -+CONFIG_CMD_MEMTEST=y - CONFIG_CMD_ADC=y -+CONFIG_CMD_CLK=y -+CONFIG_CMD_DFU=y - CONFIG_CMD_FUSE=y - CONFIG_CMD_GPIO=y --CONFIG_CMD_GPT=y - CONFIG_CMD_I2C=y - CONFIG_CMD_MMC=y -+CONFIG_CMD_REMOTEPROC=y -+CONFIG_CMD_SF=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 - CONFIG_CMD_PMIC=y - CONFIG_CMD_REGULATOR=y - CONFIG_CMD_EXT4_WRITE=y -+CONFIG_CMD_MTDPARTS=y -+CONFIG_CMD_UBI=y - # CONFIG_SPL_DOS_PARTITION is not set - CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" - CONFIG_STM32_ADC=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_DM_HWSPINLOCK=y -+CONFIG_HWSPINLOCK_STM32=y - 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_DM_MMC=y - CONFIG_STM32_SDMMC2=y -+CONFIG_MTD=y -+CONFIG_NAND=y -+CONFIG_NAND_STM32_FMC2=y -+CONFIG_DM_SPI_FLASH=y -+CONFIG_SPI_FLASH=y -+CONFIG_SPI_FLASH_BAR=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_FIXED=y -+CONFIG_DM_ETH=y -+CONFIG_DWC_ETH_QOS=y - CONFIG_PHY=y - CONFIG_PHY_STM32_USBPHYC=y --# CONFIG_PINCTRL_FULL is not set -+CONFIG_PINCONF=y - # CONFIG_SPL_PINCTRL_FULL is not set -+CONFIG_PINCTRL_STMFX=y - CONFIG_DM_PMIC=y - # CONFIG_SPL_PMIC_CHILDREN is not set --CONFIG_PMIC_STPMU1=y -+CONFIG_PMIC_STPMIC1=y - CONFIG_DM_REGULATOR_FIXED=y - CONFIG_DM_REGULATOR_GPIO=y - CONFIG_DM_REGULATOR_STM32_VREFBUF=y --CONFIG_DM_REGULATOR_STPMU1=y -+CONFIG_DM_REGULATOR_STPMIC1=y -+CONFIG_STM32MP1_DDR_INTERACTIVE=y -+CONFIG_REMOTEPROC_STM32_COPRO=y - CONFIG_SERIAL_RX_BUFFER=y --CONFIG_STM32_SERIAL=y -+CONFIG_SPI=y -+CONFIG_DM_SPI=y -+CONFIG_STM32_QSPI=y - CONFIG_USB=y - CONFIG_DM_USB=y - CONFIG_USB_EHCI_HCD=y - CONFIG_USB_EHCI_GENERIC=y --CONFIG_USB_DWC2=y - CONFIG_USB_STORAGE=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_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_STM32MP_WATCHDOG=y -+CONFIG_FDT_FIXUP_PARTITIONS=y -+# CONFIG_EFI_LOADER is not set -diff --git a/configs/stm32mp15_optee_defconfig b/configs/stm32mp15_optee_defconfig -new file mode 100644 -index 0000000..a24727c ---- /dev/null -+++ b/configs/stm32mp15_optee_defconfig -@@ -0,0 +1,105 @@ -+CONFIG_ARM=y -+CONFIG_ARCH_STM32MP=y -+CONFIG_SYS_MALLOC_F_LEN=0x3000 -+CONFIG_TARGET_STM32MP1=y -+CONFIG_STM32MP1_OPTEE=y -+CONFIG_DISTRO_DEFAULTS=y -+CONFIG_FIT=y -+CONFIG_SYS_PROMPT="STM32MP> " -+# CONFIG_CMD_BOOTD is not set -+# CONFIG_CMD_ELF is not set -+# CONFIG_CMD_IMI is not set -+# CONFIG_CMD_XIMG is not set -+# CONFIG_CMD_EXPORTENV is not set -+# CONFIG_CMD_IMPORTENV is not set -+CONFIG_CMD_MEMINFO=y -+CONFIG_CMD_MEMTEST=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_REMOTEPROC=y -+CONFIG_CMD_SF=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 -+CONFIG_CMD_PMIC=y -+CONFIG_CMD_REGULATOR=y -+CONFIG_CMD_EXT4_WRITE=y -+CONFIG_CMD_MTDPARTS=y -+CONFIG_CMD_UBI=y -+CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" -+CONFIG_STM32_ADC=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_DM_HWSPINLOCK=y -+CONFIG_HWSPINLOCK_STM32=y -+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_DM_MMC=y -+CONFIG_STM32_SDMMC2=y -+CONFIG_MTD=y -+CONFIG_NAND=y -+CONFIG_NAND_STM32_FMC2=y -+CONFIG_DM_SPI_FLASH=y -+CONFIG_SPI_FLASH=y -+CONFIG_SPI_FLASH_BAR=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_FIXED=y -+CONFIG_DM_ETH=y -+CONFIG_DWC_ETH_QOS=y -+CONFIG_PHY=y -+CONFIG_PHY_STM32_USBPHYC=y -+CONFIG_PINCONF=y -+CONFIG_PINCTRL_STMFX=y -+CONFIG_DM_PMIC=y -+CONFIG_PMIC_STPMIC1=y -+CONFIG_DM_REGULATOR_FIXED=y -+CONFIG_DM_REGULATOR_GPIO=y -+CONFIG_DM_REGULATOR_STM32_VREFBUF=y -+CONFIG_DM_REGULATOR_STPMIC1=y -+CONFIG_REMOTEPROC_STM32_COPRO=y -+CONFIG_SERIAL_RX_BUFFER=y -+CONFIG_SPI=y -+CONFIG_DM_SPI=y -+CONFIG_STM32_QSPI=y -+CONFIG_USB=y -+CONFIG_DM_USB=y -+CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_EHCI_GENERIC=y -+CONFIG_USB_STORAGE=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_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_STM32MP_WATCHDOG=y -+CONFIG_FDT_FIXUP_PARTITIONS=y -+# CONFIG_EFI_LOADER is not set -diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig -new file mode 100644 -index 0000000..e41506b ---- /dev/null -+++ b/configs/stm32mp15_trusted_defconfig -@@ -0,0 +1,104 @@ -+CONFIG_ARM=y -+CONFIG_ARCH_STM32MP=y -+CONFIG_SYS_MALLOC_F_LEN=0x3000 -+CONFIG_TARGET_STM32MP1=y -+CONFIG_DISTRO_DEFAULTS=y -+CONFIG_FIT=y -+CONFIG_SYS_PROMPT="STM32MP> " -+# CONFIG_CMD_BOOTD is not set -+# CONFIG_CMD_ELF is not set -+# CONFIG_CMD_IMI is not set -+# CONFIG_CMD_XIMG is not set -+# CONFIG_CMD_EXPORTENV is not set -+# CONFIG_CMD_IMPORTENV is not set -+CONFIG_CMD_MEMINFO=y -+CONFIG_CMD_MEMTEST=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_REMOTEPROC=y -+CONFIG_CMD_SF=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 -+CONFIG_CMD_PMIC=y -+CONFIG_CMD_REGULATOR=y -+CONFIG_CMD_EXT4_WRITE=y -+CONFIG_CMD_MTDPARTS=y -+CONFIG_CMD_UBI=y -+CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" -+CONFIG_STM32_ADC=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_DM_HWSPINLOCK=y -+CONFIG_HWSPINLOCK_STM32=y -+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_DM_MMC=y -+CONFIG_STM32_SDMMC2=y -+CONFIG_MTD=y -+CONFIG_NAND=y -+CONFIG_NAND_STM32_FMC2=y -+CONFIG_DM_SPI_FLASH=y -+CONFIG_SPI_FLASH=y -+CONFIG_SPI_FLASH_BAR=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_FIXED=y -+CONFIG_DM_ETH=y -+CONFIG_DWC_ETH_QOS=y -+CONFIG_PHY=y -+CONFIG_PHY_STM32_USBPHYC=y -+CONFIG_PINCONF=y -+CONFIG_PINCTRL_STMFX=y -+CONFIG_DM_PMIC=y -+CONFIG_PMIC_STPMIC1=y -+CONFIG_DM_REGULATOR_FIXED=y -+CONFIG_DM_REGULATOR_GPIO=y -+CONFIG_DM_REGULATOR_STM32_VREFBUF=y -+CONFIG_DM_REGULATOR_STPMIC1=y -+CONFIG_REMOTEPROC_STM32_COPRO=y -+CONFIG_SERIAL_RX_BUFFER=y -+CONFIG_SPI=y -+CONFIG_DM_SPI=y -+CONFIG_STM32_QSPI=y -+CONFIG_USB=y -+CONFIG_DM_USB=y -+CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_EHCI_GENERIC=y -+CONFIG_USB_STORAGE=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_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_STM32MP_WATCHDOG=y -+CONFIG_FDT_FIXUP_PARTITIONS=y -+# CONFIG_EFI_LOADER is not set --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0004-ARM-v2020.01-stm32mp-r1-DEVICETREE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0004-ARM-v2020.01-stm32mp-r1-DEVICETREE.patch new file mode 100644 index 0000000..07a0a5f --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0004-ARM-v2020.01-stm32mp-r1-DEVICETREE.patch @@ -0,0 +1,14427 @@ +From 362734e9999cbf5ffe6a8b2f81d29a51c011feff Mon Sep 17 00:00:00 2001 +From: Romuald JEANNE +Date: Fri, 5 Jun 2020 13:45:44 +0200 +Subject: [PATCH 4/5] ARM v2020.01-stm32mp-r1 DEVICETREE + +--- + arch/arm/dts/Makefile | 15 +- + arch/arm/dts/stm32mp15-ddr.dtsi | 7 +- + arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi | 49 +- + arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi | 49 +- + arch/arm/dts/stm32mp15-no-scmi.dtsi | 157 ++ + arch/arm/dts/stm32mp15-pinctrl.dtsi | 1426 +++++++++++++++ + arch/arm/dts/stm32mp15-u-boot.dtsi | 231 +++ + arch/arm/dts/stm32mp151.dtsi | 1997 ++++++++++++++++++++++ + arch/arm/dts/stm32mp153.dtsi | 54 + + arch/arm/dts/stm32mp157-m4-srm-pinctrl.dtsi | 524 ++++++ + arch/arm/dts/stm32mp157-m4-srm.dtsi | 442 +++++ + arch/arm/dts/stm32mp157-pinctrl.dtsi | 1036 ----------- + arch/arm/dts/stm32mp157-u-boot.dtsi | 153 -- + arch/arm/dts/stm32mp157.dtsi | 32 + + arch/arm/dts/stm32mp157a-avenger96-u-boot.dtsi | 32 +- + arch/arm/dts/stm32mp157a-avenger96.dts | 20 +- + arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi | 56 +- + arch/arm/dts/stm32mp157a-dk1.dts | 488 +----- + arch/arm/dts/stm32mp157a-ed1-u-boot.dtsi | 207 +++ + arch/arm/dts/stm32mp157a-ed1.dts | 52 + + arch/arm/dts/stm32mp157a-ev1-u-boot.dtsi | 69 + + arch/arm/dts/stm32mp157a-ev1.dts | 86 + + arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi | 6 - + arch/arm/dts/stm32mp157c-dk2.dts | 122 +- + arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi | 202 +-- + arch/arm/dts/stm32mp157c-ed1.dts | 324 +--- + arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi | 49 +- + arch/arm/dts/stm32mp157c-ev1.dts | 300 +--- + arch/arm/dts/stm32mp157c.dtsi | 1592 ----------------- + arch/arm/dts/stm32mp157d-dk1-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp157d-dk1.dts | 44 + + arch/arm/dts/stm32mp157d-ed1-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp157d-ed1.dts | 52 + + arch/arm/dts/stm32mp157d-ev1-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp157d-ev1.dts | 86 + + arch/arm/dts/stm32mp157f-dk2-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp157f-dk2.dts | 185 ++ + arch/arm/dts/stm32mp157f-ed1-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp157f-ed1.dts | 56 + + arch/arm/dts/stm32mp157f-ev1-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp157f-ev1.dts | 86 + + arch/arm/dts/stm32mp157xaa-pinctrl.dtsi | 90 - + arch/arm/dts/stm32mp157xab-pinctrl.dtsi | 62 - + arch/arm/dts/stm32mp157xac-pinctrl.dtsi | 78 - + arch/arm/dts/stm32mp157xad-pinctrl.dtsi | 62 - + arch/arm/dts/stm32mp15xa.dtsi | 13 + + arch/arm/dts/stm32mp15xc.dtsi | 20 + + arch/arm/dts/stm32mp15xd.dtsi | 42 + + arch/arm/dts/stm32mp15xf.dtsi | 20 + + arch/arm/dts/stm32mp15xx-dhcom-pdk2-u-boot.dtsi | 6 + + arch/arm/dts/stm32mp15xx-dhcom-pdk2.dts | 88 + + arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi | 249 +++ + arch/arm/dts/stm32mp15xx-dhcom.dtsi | 379 ++++ + arch/arm/dts/stm32mp15xx-dkx.dtsi | 768 +++++++++ + arch/arm/dts/stm32mp15xx-edx.dtsi | 408 +++++ + arch/arm/dts/stm32mp15xx-evx.dtsi | 680 ++++++++ + arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi | 85 + + arch/arm/dts/stm32mp15xxab-pinctrl.dtsi | 57 + + arch/arm/dts/stm32mp15xxac-pinctrl.dtsi | 73 + + arch/arm/dts/stm32mp15xxad-pinctrl.dtsi | 57 + + 60 files changed, 9051 insertions(+), 4508 deletions(-) + create mode 100644 arch/arm/dts/stm32mp15-no-scmi.dtsi + create mode 100644 arch/arm/dts/stm32mp15-pinctrl.dtsi + create mode 100644 arch/arm/dts/stm32mp15-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp151.dtsi + create mode 100644 arch/arm/dts/stm32mp153.dtsi + create mode 100644 arch/arm/dts/stm32mp157-m4-srm-pinctrl.dtsi + create mode 100644 arch/arm/dts/stm32mp157-m4-srm.dtsi + delete mode 100644 arch/arm/dts/stm32mp157-pinctrl.dtsi + delete mode 100644 arch/arm/dts/stm32mp157-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp157.dtsi + create mode 100644 arch/arm/dts/stm32mp157a-ed1-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp157a-ed1.dts + create mode 100644 arch/arm/dts/stm32mp157a-ev1-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp157a-ev1.dts + delete mode 100644 arch/arm/dts/stm32mp157c.dtsi + create mode 100644 arch/arm/dts/stm32mp157d-dk1-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp157d-dk1.dts + create mode 100644 arch/arm/dts/stm32mp157d-ed1-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp157d-ed1.dts + create mode 100644 arch/arm/dts/stm32mp157d-ev1-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp157d-ev1.dts + create mode 100644 arch/arm/dts/stm32mp157f-dk2-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp157f-dk2.dts + create mode 100644 arch/arm/dts/stm32mp157f-ed1-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp157f-ed1.dts + create mode 100644 arch/arm/dts/stm32mp157f-ev1-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp157f-ev1.dts + delete mode 100644 arch/arm/dts/stm32mp157xaa-pinctrl.dtsi + delete mode 100644 arch/arm/dts/stm32mp157xab-pinctrl.dtsi + delete mode 100644 arch/arm/dts/stm32mp157xac-pinctrl.dtsi + delete mode 100644 arch/arm/dts/stm32mp157xad-pinctrl.dtsi + create mode 100644 arch/arm/dts/stm32mp15xa.dtsi + create mode 100644 arch/arm/dts/stm32mp15xc.dtsi + create mode 100644 arch/arm/dts/stm32mp15xd.dtsi + create mode 100644 arch/arm/dts/stm32mp15xf.dtsi + create mode 100644 arch/arm/dts/stm32mp15xx-dhcom-pdk2-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp15xx-dhcom-pdk2.dts + create mode 100644 arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi + create mode 100644 arch/arm/dts/stm32mp15xx-dhcom.dtsi + create mode 100644 arch/arm/dts/stm32mp15xx-dkx.dtsi + create mode 100644 arch/arm/dts/stm32mp15xx-edx.dtsi + create mode 100644 arch/arm/dts/stm32mp15xx-evx.dtsi + create mode 100644 arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi + create mode 100644 arch/arm/dts/stm32mp15xxab-pinctrl.dtsi + create mode 100644 arch/arm/dts/stm32mp15xxac-pinctrl.dtsi + create mode 100644 arch/arm/dts/stm32mp15xxad-pinctrl.dtsi + +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index 0127a91..c3fd89b 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -823,12 +823,21 @@ dtb-$(CONFIG_ARCH_ASPEED) += ast2500-evb.dtb + + dtb-$(CONFIG_ARCH_STI) += stih410-b2260.dtb + +-dtb-$(CONFIG_TARGET_STM32MP1) += \ +- stm32mp157a-dk1.dtb \ ++dtb-$(CONFIG_STM32MP15x) += \ + stm32mp157a-avenger96.dtb \ ++ stm32mp157a-dk1.dtb \ ++ stm32mp157a-ed1.dtb \ ++ stm32mp157a-ev1.dtb \ + stm32mp157c-dk2.dtb \ + stm32mp157c-ed1.dtb \ +- stm32mp157c-ev1.dtb ++ stm32mp157c-ev1.dtb \ ++ stm32mp157d-dk1.dtb \ ++ stm32mp157d-ed1.dtb \ ++ stm32mp157d-ev1.dtb \ ++ stm32mp157f-dk2.dtb \ ++ stm32mp157f-ed1.dtb \ ++ stm32mp157f-ev1.dtb \ ++ stm32mp15xx-dhcom-pdk2.dtb + + dtb-$(CONFIG_SOC_K3_AM6) += k3-am654-base-board.dtb k3-am654-r5-base-board.dtb + dtb-$(CONFIG_SOC_K3_J721E) += k3-j721e-common-proc-board.dtb \ +diff --git a/arch/arm/dts/stm32mp15-ddr.dtsi b/arch/arm/dts/stm32mp15-ddr.dtsi +index 479b700..cc604c0 100644 +--- a/arch/arm/dts/stm32mp15-ddr.dtsi ++++ b/arch/arm/dts/stm32mp15-ddr.dtsi +@@ -5,7 +5,7 @@ + + / { + soc { +- ddr: ddr@5A003000 { ++ ddr: ddr@5a003000 { + u-boot,dm-pre-reloc; + + compatible = "st,stm32mp1-ddr"; +@@ -31,6 +31,7 @@ + st,mem-speed = ; + st,mem-size = ; + ++#ifndef CONFIG_STM32MP1_TRUSTED + st,ctl-reg = < + DDR_MSTR + DDR_MRCTRL0 +@@ -133,6 +134,7 @@ + DDR_MR3 + >; + ++#ifdef DDR_PHY_CAL_SKIP + st,phy-cal = < + DDR_DX0DLLCR + DDR_DX0DQTR +@@ -147,6 +149,9 @@ + DDR_DX3DQTR + DDR_DX3DQSTR + >; ++#endif ++ ++#endif + + status = "okay"; + }; +diff --git a/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi +index 11e8f2b..c0fc1f7 100644 +--- a/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi ++++ b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi +@@ -1,24 +1,23 @@ + // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause + /* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved ++ */ ++ ++/* ++ * File generated by STMicroelectronics STM32CubeMX DDR Tool for MPUs ++ * DDR type: DDR3 / DDR3L ++ * DDR width: 16bits ++ * DDR density: 4Gb ++ * System frequency: 533000Khz ++ * Relaxed Timing Mode: false ++ * Address mapping type: RBC + * +- * STM32MP157C DK1/DK2 BOARD configuration +- * 1x DDR3L 4Gb, 16-bit, 533MHz. +- * Reference used NT5CC256M16DP-DI from NANYA +- * +- * DDR type / Platform DDR3/3L +- * freq 533MHz +- * width 16 +- * datasheet 0 = MT41J256M16-187 / DDR3-1066 bin G +- * DDR density 4 +- * timing mode optimized +- * Scheduling/QoS options : type = 2 +- * address mapping : RBC +- * Tc > + 85C : N ++ * Save Date: 2020.02.20, save Time: 18:45:20 + */ +-#define DDR_MEM_NAME "DDR3-1066/888 bin G 1x4Gb 533MHz v1.45" +-#define DDR_MEM_SPEED 533000 +-#define DDR_MEM_SIZE 0x20000000 ++ ++#define DDR_MEM_NAME "DDR3-DDR3L 16bits 533000Khz" ++#define DDR_MEM_SPEED 533000 ++#define DDR_MEM_SIZE 0x20000000 + + #define DDR_MSTR 0x00041401 + #define DDR_MRCTRL0 0x00000010 +@@ -50,15 +49,6 @@ + #define DDR_DFIUPD1 0x00000000 + #define DDR_DFIUPD2 0x00000000 + #define DDR_DFIPHYMSTR 0x00000000 +-#define DDR_ADDRMAP1 0x00070707 +-#define DDR_ADDRMAP2 0x00000000 +-#define DDR_ADDRMAP3 0x1F000000 +-#define DDR_ADDRMAP4 0x00001F1F +-#define DDR_ADDRMAP5 0x06060606 +-#define DDR_ADDRMAP6 0x0F060606 +-#define DDR_ADDRMAP9 0x00000000 +-#define DDR_ADDRMAP10 0x00000000 +-#define DDR_ADDRMAP11 0x00000000 + #define DDR_ODTCFG 0x06000600 + #define DDR_ODTMAP 0x00000001 + #define DDR_SCHED 0x00000C01 +@@ -83,6 +73,15 @@ + #define DDR_PCFGQOS1_1 0x00800040 + #define DDR_PCFGWQOS0_1 0x01100C03 + #define DDR_PCFGWQOS1_1 0x01000200 ++#define DDR_ADDRMAP1 0x00070707 ++#define DDR_ADDRMAP2 0x00000000 ++#define DDR_ADDRMAP3 0x1F000000 ++#define DDR_ADDRMAP4 0x00001F1F ++#define DDR_ADDRMAP5 0x06060606 ++#define DDR_ADDRMAP6 0x0F060606 ++#define DDR_ADDRMAP9 0x00000000 ++#define DDR_ADDRMAP10 0x00000000 ++#define DDR_ADDRMAP11 0x00000000 + #define DDR_PGCR 0x01442E02 + #define DDR_PTR0 0x0022AA5B + #define DDR_PTR1 0x04841104 +diff --git a/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi +index 4b70b60..fc226d2 100644 +--- a/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi ++++ b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi +@@ -1,24 +1,23 @@ + // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause + /* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved ++ */ ++ ++/* ++ * File generated by STMicroelectronics STM32CubeMX DDR Tool for MPUs ++ * DDR type: DDR3 / DDR3L ++ * DDR width: 32bits ++ * DDR density: 8Gb ++ * System frequency: 533000Khz ++ * Relaxed Timing Mode: false ++ * Address mapping type: RBC + * +- * STM32MP157C ED1 BOARD configuration +- * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology. +- * Reference used NT5CC256M16DP-DI from NANYA +- * +- * DDR type / Platform DDR3/3L +- * freq 533MHz +- * width 32 +- * datasheet 0 = MT41J256M16-187 / DDR3-1066 bin G +- * DDR density 8 +- * timing mode optimized +- * Scheduling/QoS options : type = 2 +- * address mapping : RBC +- * Tc > + 85C : N ++ * Save Date: 2020.02.20, save Time: 18:49:33 + */ +-#define DDR_MEM_NAME "DDR3-1066/888 bin G 2x4Gb 533MHz v1.45" +-#define DDR_MEM_SPEED 533000 +-#define DDR_MEM_SIZE 0x40000000 ++ ++#define DDR_MEM_NAME "DDR3-DDR3L 32bits 533000Khz" ++#define DDR_MEM_SPEED 533000 ++#define DDR_MEM_SIZE 0x40000000 + + #define DDR_MSTR 0x00040401 + #define DDR_MRCTRL0 0x00000010 +@@ -50,15 +49,6 @@ + #define DDR_DFIUPD1 0x00000000 + #define DDR_DFIUPD2 0x00000000 + #define DDR_DFIPHYMSTR 0x00000000 +-#define DDR_ADDRMAP1 0x00080808 +-#define DDR_ADDRMAP2 0x00000000 +-#define DDR_ADDRMAP3 0x00000000 +-#define DDR_ADDRMAP4 0x00001F1F +-#define DDR_ADDRMAP5 0x07070707 +-#define DDR_ADDRMAP6 0x0F070707 +-#define DDR_ADDRMAP9 0x00000000 +-#define DDR_ADDRMAP10 0x00000000 +-#define DDR_ADDRMAP11 0x00000000 + #define DDR_ODTCFG 0x06000600 + #define DDR_ODTMAP 0x00000001 + #define DDR_SCHED 0x00000C01 +@@ -83,6 +73,15 @@ + #define DDR_PCFGQOS1_1 0x00800040 + #define DDR_PCFGWQOS0_1 0x01100C03 + #define DDR_PCFGWQOS1_1 0x01000200 ++#define DDR_ADDRMAP1 0x00080808 ++#define DDR_ADDRMAP2 0x00000000 ++#define DDR_ADDRMAP3 0x00000000 ++#define DDR_ADDRMAP4 0x00001F1F ++#define DDR_ADDRMAP5 0x07070707 ++#define DDR_ADDRMAP6 0x0F070707 ++#define DDR_ADDRMAP9 0x00000000 ++#define DDR_ADDRMAP10 0x00000000 ++#define DDR_ADDRMAP11 0x00000000 + #define DDR_PGCR 0x01442E02 + #define DDR_PTR0 0x0022AA5B + #define DDR_PTR1 0x04841104 +diff --git a/arch/arm/dts/stm32mp15-no-scmi.dtsi b/arch/arm/dts/stm32mp15-no-scmi.dtsi +new file mode 100644 +index 0000000..3bb96ab +--- /dev/null ++++ b/arch/arm/dts/stm32mp15-no-scmi.dtsi +@@ -0,0 +1,157 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2020 - All Rights Reserved ++ * Author: Gabriel Fernandez for STMicroelectronics. ++ */ ++ ++/ { ++ ++ clocks { ++ clk_hse: clk-hse { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <24000000>; ++ }; ++ ++ clk_hsi: clk-hsi { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <64000000>; ++ }; ++ ++ clk_lse: clk-lse { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ }; ++ ++ clk_lsi: clk-lsi { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <32000>; ++ }; ++ ++ clk_csi: clk-csi { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <4000000>; ++ }; ++ }; ++ ++ cpus { ++ cpu0: cpu@0 { ++ clocks = <&rcc CK_MPU>; ++ }; ++ ++ cpu1: cpu@1 { ++ clocks = <&rcc CK_MPU>; ++ }; ++ }; ++ ++ soc { ++ m_can1: can@4400e000 { ++ clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; ++ }; ++ ++ m_can2: can@4400f000 { ++ clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; ++ }; ++ ++ cryp1: cryp@54001000 { ++ clocks = <&rcc CRYP1>; ++ resets = <&rcc CRYP1_R>; ++ }; ++ }; ++ ++ mlahb { ++ m4_rproc: m4@10000000 { ++ resets = <&rcc MCU_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>; ++ }; ++ ++ m4_m_can2: can@4400f000 { ++ clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; ++ }; ++ }; ++ }; ++ }; ++ ++ firmware { ++ /delete-node/ scmi-0; ++ /delete-node/ scmi-1; ++ }; ++ /delete-node/ sram@2ffff000; ++ /delete-node/ mailbox-0; ++ /delete-node/ mailbox-1; ++}; ++ ++&cec { ++ clocks = <&rcc CEC_K>, <&clk_lse>; ++}; ++ ++&ddrperfm { ++ clocks = <&rcc DDRPERFM>, <&rcc PLL2_R>; ++}; ++ ++&dsi { ++ clocks = <&rcc DSI_K>, <&clk_hse>, <&rcc DSI_PX>; ++}; ++ ++&gpioz { ++ clocks = <&rcc GPIOZ>; ++}; ++ ++&hash1 { ++ clocks = <&rcc HASH1>; ++ resets = <&rcc HASH1_R>; ++}; ++ ++&i2c4 { ++ clocks = <&rcc I2C4_K>; ++ resets = <&rcc I2C4_R>; ++}; ++ ++&i2c6 { ++ clocks = <&rcc I2C6_K>; ++ resets = <&rcc I2C6_R>; ++}; ++ ++&iwdg2 { ++ clocks = <&rcc IWDG2>, <&rcc CK_LSI>; ++}; ++ ++&mdma1 { ++ clocks = <&rcc MDMA>; ++ resets = <&rcc MDMA_R>; ++}; ++ ++&rcc { ++ compatible = "st,stm32mp1-rcc", "syscon"; ++ clocks = <&clk_hse>, <&clk_hsi>, <&clk_csi>, <&clk_lse>, <&clk_lsi>; ++}; ++ ++&rng1 { ++ clocks = <&rcc RNG1_K>; ++ resets = <&rcc RNG1_R>; ++}; ++ ++&rtc { ++ clocks = <&rcc RTCAPB>, <&rcc RTC>; ++}; ++ ++&spi6 { ++ clocks = <&rcc SPI6_K>; ++ resets = <&rcc SPI6_R>; ++}; ++ ++&usart1 { ++ clocks = <&rcc USART1_K>; ++ resets = <&rcc USART1_R>; ++}; +diff --git a/arch/arm/dts/stm32mp15-pinctrl.dtsi b/arch/arm/dts/stm32mp15-pinctrl.dtsi +new file mode 100644 +index 0000000..b8e82ad +--- /dev/null ++++ b/arch/arm/dts/stm32mp15-pinctrl.dtsi +@@ -0,0 +1,1426 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved ++ * Author: Ludovic Barre for STMicroelectronics. ++ */ ++#include ++ ++&pinctrl { ++ adc1_in6_pins_a: adc1-in6 { ++ pins { ++ pinmux = ; ++ }; ++ }; ++ ++ adc12_ain_pins_a: adc12-ain-0 { ++ pins { ++ pinmux = , /* ADC1 in13 */ ++ , /* ADC1 in6 */ ++ , /* ADC2 in2 */ ++ ; /* ADC2 in6 */ ++ }; ++ }; ++ ++ adc12_usb_cc_pins_a: adc12-usb-cc-pins-0 { ++ pins { ++ pinmux = , /* ADC12 in18 */ ++ ; /* ADC12 in19 */ ++ }; ++ }; ++ ++ cec_pins_a: cec-0 { ++ pins { ++ pinmux = ; ++ bias-disable; ++ drive-open-drain; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ cec_pins_sleep_a: cec-sleep-0 { ++ pins { ++ pinmux = ; /* HDMI_CEC */ ++ }; ++ }; ++ ++ cec_pins_b: cec-1 { ++ pins { ++ pinmux = ; ++ bias-disable; ++ drive-open-drain; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ cec_pins_sleep_b: cec-sleep-1 { ++ pins { ++ pinmux = ; /* HDMI_CEC */ ++ }; ++ }; ++ ++ dac_ch1_pins_a: dac-ch1 { ++ pins { ++ pinmux = ; ++ }; ++ }; ++ ++ dac_ch2_pins_a: dac-ch2 { ++ pins { ++ pinmux = ; ++ }; ++ }; ++ ++ dcmi_pins_a: dcmi-0 { ++ pins { ++ pinmux = ,/* DCMI_HSYNC */ ++ ,/* DCMI_VSYNC */ ++ ,/* DCMI_PIXCLK */ ++ ,/* DCMI_D0 */ ++ ,/* DCMI_D1 */ ++ ,/* DCMI_D2 */ ++ ,/* DCMI_D3 */ ++ ,/* DCMI_D4 */ ++ ,/* DCMI_D5 */ ++ ,/* DCMI_D6 */ ++ ,/* DCMI_D7 */ ++ ,/* DCMI_D8 */ ++ ,/* DCMI_D9 */ ++ ,/* DCMI_D10 */ ++ ;/* DCMI_D11 */ ++ bias-disable; ++ }; ++ }; ++ ++ dcmi_sleep_pins_a: dcmi-sleep-0 { ++ pins { ++ pinmux = ,/* DCMI_HSYNC */ ++ ,/* DCMI_VSYNC */ ++ ,/* DCMI_PIXCLK */ ++ ,/* DCMI_D0 */ ++ ,/* DCMI_D1 */ ++ ,/* DCMI_D2 */ ++ ,/* DCMI_D3 */ ++ ,/* DCMI_D4 */ ++ ,/* DCMI_D5 */ ++ ,/* DCMI_D6 */ ++ ,/* DCMI_D7 */ ++ ,/* DCMI_D8 */ ++ ,/* DCMI_D9 */ ++ ,/* DCMI_D10 */ ++ ;/* DCMI_D11 */ ++ }; ++ }; ++ ++ 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_data1_pins_a: dfsdm-data1-pins-0 { ++ pins { ++ pinmux = ; /* DFSDM_DATA1 */ ++ }; ++ }; ++ ++ dfsdm_data1_sleep_pins_a: dfsdm-data1-sleep-pins-0 { ++ pins { ++ pinmux = ; /* DFSDM_DATA1 */ ++ }; ++ }; ++ ++ dfsdm_data3_pins_a: dfsdm-data3-pins-0 { ++ pins { ++ pinmux = ; /* DFSDM_DATA3 */ ++ }; ++ }; ++ ++ dfsdm_data3_sleep_pins_a: dfsdm-data3-sleep-pins-0 { ++ pins { ++ pinmux = ; /* DFSDM_DATA3 */ ++ }; ++ }; ++ ++ ethernet0_rgmii_pins_a: rgmii-0 { ++ pins1 { ++ pinmux = , /* ETH_RGMII_CLK125 */ ++ , /* ETH_RGMII_GTX_CLK */ ++ , /* ETH_RGMII_TXD0 */ ++ , /* ETH_RGMII_TXD1 */ ++ , /* ETH_RGMII_TXD2 */ ++ , /* ETH_RGMII_TXD3 */ ++ , /* ETH_RGMII_TX_CTL */ ++ ; /* ETH_MDC */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <2>; ++ }; ++ pins2 { ++ pinmux = ; /* ETH_MDIO */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ pins3 { ++ pinmux = , /* ETH_RGMII_RXD0 */ ++ , /* ETH_RGMII_RXD1 */ ++ , /* ETH_RGMII_RXD2 */ ++ , /* ETH_RGMII_RXD3 */ ++ , /* ETH_RGMII_RX_CLK */ ++ ; /* ETH_RGMII_RX_CTL */ ++ bias-disable; ++ }; ++ }; ++ ++ ethernet0_rgmii_pins_sleep_a: rgmii-sleep-0 { ++ pins1 { ++ pinmux = , /* ETH_RGMII_CLK125 */ ++ , /* ETH_RGMII_GTX_CLK */ ++ , /* ETH_RGMII_TXD0 */ ++ , /* ETH_RGMII_TXD1 */ ++ , /* ETH_RGMII_TXD2 */ ++ , /* ETH_RGMII_TXD3 */ ++ , /* ETH_RGMII_TX_CTL */ ++ , /* ETH_MDIO */ ++ , /* ETH_MDC */ ++ , /* ETH_RGMII_RXD0 */ ++ , /* ETH_RGMII_RXD1 */ ++ , /* ETH_RGMII_RXD2 */ ++ , /* ETH_RGMII_RXD3 */ ++ , /* ETH_RGMII_RX_CLK */ ++ ; /* ETH_RGMII_RX_CTL */ ++ }; ++ }; ++ ++ fmc_pins_a: fmc-0 { ++ pins1 { ++ pinmux = , /* FMC_NOE */ ++ , /* FMC_NWE */ ++ , /* FMC_A16_FMC_CLE */ ++ , /* FMC_A17_FMC_ALE */ ++ , /* FMC_D0 */ ++ , /* FMC_D1 */ ++ , /* FMC_D2 */ ++ , /* FMC_D3 */ ++ , /* FMC_D4 */ ++ , /* FMC_D5 */ ++ , /* FMC_D6 */ ++ , /* FMC_D7 */ ++ ; /* FMC_NE2_FMC_NCE */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <1>; ++ }; ++ pins2 { ++ pinmux = ; /* FMC_NWAIT */ ++ bias-pull-up; ++ }; ++ }; ++ ++ fmc_sleep_pins_a: fmc-sleep-0 { ++ pins { ++ pinmux = , /* FMC_NOE */ ++ , /* FMC_NWE */ ++ , /* FMC_A16_FMC_CLE */ ++ , /* FMC_A17_FMC_ALE */ ++ , /* FMC_D0 */ ++ , /* FMC_D1 */ ++ , /* FMC_D2 */ ++ , /* FMC_D3 */ ++ , /* FMC_D4 */ ++ , /* FMC_D5 */ ++ , /* FMC_D6 */ ++ , /* FMC_D7 */ ++ , /* FMC_NWAIT */ ++ ; /* FMC_NE2_FMC_NCE */ ++ }; ++ }; ++ ++ hdp0_pins_a: hdp0-0 { ++ pins { ++ pinmux = ; /* HDP0 */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <2>; ++ }; ++ }; ++ ++ hdp0_pins_sleep_a: hdp0-sleep-0 { ++ pins { ++ pinmux = ; /* HDP0 */ ++ }; ++ }; ++ ++ hdp6_pins_a: hdp6-0 { ++ pins { ++ pinmux = ; /* HDP6 */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <2>; ++ }; ++ }; ++ ++ hdp6_pins_sleep_a: hdp6-sleep-0 { ++ pins { ++ pinmux = ; /* HDP6 */ ++ }; ++ }; ++ ++ hdp7_pins_a: hdp7-0 { ++ pins { ++ pinmux = ; /* HDP7 */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <2>; ++ }; ++ }; ++ ++ hdp7_pins_sleep_a: hdp7-sleep-0 { ++ pins { ++ pinmux = ; /* HDP7 */ ++ }; ++ }; ++ ++ i2c1_pins_a: i2c1-0 { ++ pins { ++ pinmux = , /* I2C1_SCL */ ++ ; /* I2C1_SDA */ ++ bias-disable; ++ drive-open-drain; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ i2c1_pins_sleep_a: i2c1-1 { ++ pins { ++ pinmux = , /* I2C1_SCL */ ++ ; /* I2C1_SDA */ ++ }; ++ }; ++ ++ i2c1_pins_b: i2c1-2 { ++ pins { ++ pinmux = , /* I2C1_SCL */ ++ ; /* I2C1_SDA */ ++ bias-disable; ++ drive-open-drain; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ i2c1_pins_sleep_b: i2c1-3 { ++ pins { ++ pinmux = , /* I2C1_SCL */ ++ ; /* I2C1_SDA */ ++ }; ++ }; ++ ++ i2c2_pins_a: i2c2-0 { ++ pins { ++ pinmux = , /* I2C2_SCL */ ++ ; /* I2C2_SDA */ ++ bias-disable; ++ drive-open-drain; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ i2c2_pins_sleep_a: i2c2-1 { ++ pins { ++ pinmux = , /* I2C2_SCL */ ++ ; /* I2C2_SDA */ ++ }; ++ }; ++ ++ i2c2_pins_b1: i2c2-2 { ++ pins { ++ pinmux = ; /* I2C2_SDA */ ++ bias-disable; ++ drive-open-drain; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ i2c2_pins_sleep_b1: i2c2-3 { ++ pins { ++ pinmux = ; /* I2C2_SDA */ ++ }; ++ }; ++ ++ i2c5_pins_a: i2c5-0 { ++ pins { ++ pinmux = , /* I2C5_SCL */ ++ ; /* I2C5_SDA */ ++ bias-disable; ++ drive-open-drain; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ i2c5_pins_sleep_a: i2c5-1 { ++ pins { ++ pinmux = , /* I2C5_SCL */ ++ ; /* I2C5_SDA */ ++ ++ }; ++ }; ++ ++ i2s2_pins_a: i2s2-0 { ++ pins { ++ pinmux = , /* I2S2_SDO */ ++ , /* I2S2_WS */ ++ ; /* I2S2_CK */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ }; ++ ++ i2s2_pins_sleep_a: i2s2-1 { ++ pins { ++ pinmux = , /* I2S2_SDO */ ++ , /* I2S2_WS */ ++ ; /* I2S2_CK */ ++ }; ++ }; ++ ++ ltdc_pins_a: ltdc-a-0 { ++ pins { ++ pinmux = , /* LCD_CLK */ ++ , /* LCD_HSYNC */ ++ , /* LCD_VSYNC */ ++ , /* LCD_DE */ ++ , /* LCD_R0 */ ++ , /* LCD_R1 */ ++ , /* LCD_R2 */ ++ , /* LCD_R3 */ ++ , /* LCD_R4 */ ++ , /* LCD_R5 */ ++ , /* LCD_R6 */ ++ , /* LCD_R7 */ ++ , /* LCD_G0 */ ++ , /* LCD_G1 */ ++ , /* LCD_G2 */ ++ , /* LCD_G3 */ ++ , /* LCD_G4 */ ++ , /* LCD_G5 */ ++ , /* LCD_G6 */ ++ , /* LCD_G7 */ ++ , /* LCD_B0 */ ++ , /* LCD_B1 */ ++ , /* LCD_B2 */ ++ , /* LCD_B3 */ ++ , /* LCD_B4 */ ++ , /* LCD_B5 */ ++ , /* LCD_B6 */ ++ ; /* LCD_B7 */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <1>; ++ }; ++ }; ++ ++ ltdc_pins_sleep_a: ltdc-a-1 { ++ pins { ++ pinmux = , /* LCD_CLK */ ++ , /* LCD_HSYNC */ ++ , /* LCD_VSYNC */ ++ , /* LCD_DE */ ++ , /* LCD_R0 */ ++ , /* LCD_R1 */ ++ , /* LCD_R2 */ ++ , /* LCD_R3 */ ++ , /* LCD_R4 */ ++ , /* LCD_R5 */ ++ , /* LCD_R6 */ ++ , /* LCD_R7 */ ++ , /* LCD_G0 */ ++ , /* LCD_G1 */ ++ , /* LCD_G2 */ ++ , /* LCD_G3 */ ++ , /* LCD_G4 */ ++ , /* LCD_G5 */ ++ , /* LCD_G6 */ ++ , /* LCD_G7 */ ++ , /* LCD_B0 */ ++ , /* LCD_B1 */ ++ , /* LCD_B2 */ ++ , /* LCD_B3 */ ++ , /* LCD_B4 */ ++ , /* LCD_B5 */ ++ , /* LCD_B6 */ ++ ; /* LCD_B7 */ ++ }; ++ }; ++ ++ ltdc_pins_b: ltdc-b-0 { ++ pins { ++ pinmux = , /* LCD_CLK */ ++ , /* LCD_HSYNC */ ++ , /* LCD_VSYNC */ ++ , /* LCD_DE */ ++ , /* LCD_R0 */ ++ , /* LCD_R1 */ ++ , /* LCD_R2 */ ++ , /* LCD_R3 */ ++ , /* LCD_R4 */ ++ , /* LCD_R5 */ ++ , /* LCD_R6 */ ++ , /* LCD_R7 */ ++ , /* LCD_G0 */ ++ , /* LCD_G1 */ ++ , /* LCD_G2 */ ++ , /* LCD_G3 */ ++ , /* LCD_G4 */ ++ , /* LCD_G5 */ ++ , /* LCD_G6 */ ++ , /* LCD_G7 */ ++ , /* LCD_B0 */ ++ , /* LCD_B1 */ ++ , /* LCD_B2 */ ++ , /* LCD_B3 */ ++ , /* LCD_B4 */ ++ , /* LCD_B5 */ ++ , /* LCD_B6 */ ++ ; /* LCD_B7 */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <1>; ++ }; ++ }; ++ ++ ltdc_pins_sleep_b: ltdc-b-1 { ++ pins { ++ pinmux = , /* LCD_CLK */ ++ , /* LCD_HSYNC */ ++ , /* LCD_VSYNC */ ++ , /* LCD_DE */ ++ , /* LCD_R0 */ ++ , /* LCD_R1 */ ++ , /* LCD_R2 */ ++ , /* LCD_R3 */ ++ , /* LCD_R4 */ ++ , /* LCD_R5 */ ++ , /* LCD_R6 */ ++ , /* LCD_R7 */ ++ , /* LCD_G0 */ ++ , /* LCD_G1 */ ++ , /* LCD_G2 */ ++ , /* LCD_G3 */ ++ , /* LCD_G4 */ ++ , /* LCD_G5 */ ++ , /* LCD_G6 */ ++ , /* LCD_G7 */ ++ , /* LCD_B0 */ ++ , /* LCD_B1 */ ++ , /* LCD_B2 */ ++ , /* LCD_B3 */ ++ , /* LCD_B4 */ ++ , /* LCD_B5 */ ++ , /* LCD_B6 */ ++ ; /* LCD_B7 */ ++ }; ++ }; ++ ++ m_can1_pins_a: m-can1-0 { ++ pins1 { ++ pinmux = ; /* CAN1_TX */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ pins2 { ++ pinmux = ; /* CAN1_RX */ ++ bias-disable; ++ }; ++ }; ++ ++ m_can1_sleep_pins_a: m_can1-sleep-0 { ++ pins { ++ pinmux = , /* CAN1_TX */ ++ ; /* CAN1_RX */ ++ }; ++ }; ++ ++ pwm1_pins_a: pwm1-0 { ++ pins { ++ pinmux = , /* TIM1_CH1 */ ++ , /* TIM1_CH2 */ ++ ; /* TIM1_CH4 */ ++ bias-pull-down; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ pwm1_sleep_pins_a: pwm1-sleep-0 { ++ pins { ++ pinmux = , /* TIM1_CH1 */ ++ , /* TIM1_CH2 */ ++ ; /* TIM1_CH4 */ ++ }; ++ }; ++ ++ pwm2_pins_a: pwm2-0 { ++ pins { ++ pinmux = ; /* TIM2_CH4 */ ++ bias-pull-down; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ pwm2_sleep_pins_a: pwm2-sleep-0 { ++ pins { ++ pinmux = ; /* TIM2_CH4 */ ++ }; ++ }; ++ ++ pwm3_pins_a: pwm3-0 { ++ pins { ++ pinmux = ; /* TIM3_CH2 */ ++ bias-pull-down; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ pwm3_sleep_pins_a: pwm3-sleep-0 { ++ pins { ++ pinmux = ; /* TIM3_CH2 */ ++ }; ++ }; ++ ++ pwm4_pins_a: pwm4-0 { ++ pins { ++ pinmux = , /* TIM4_CH3 */ ++ ; /* TIM4_CH4 */ ++ bias-pull-down; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ pwm4_sleep_pins_a: pwm4-sleep-0 { ++ pins { ++ pinmux = , /* TIM4_CH3 */ ++ ; /* TIM4_CH4 */ ++ }; ++ }; ++ ++ pwm4_pins_b: pwm4-1 { ++ pins { ++ pinmux = ; /* TIM4_CH2 */ ++ bias-pull-down; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ pwm4_sleep_pins_b: pwm4-sleep-1 { ++ pins { ++ pinmux = ; /* TIM4_CH2 */ ++ }; ++ }; ++ ++ pwm5_pins_a: pwm5-0 { ++ pins { ++ pinmux = ; /* TIM5_CH2 */ ++ bias-pull-down; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ pwm5_sleep_pins_a: pwm5-sleep-0 { ++ pins { ++ pinmux = ; /* TIM5_CH2 */ ++ }; ++ }; ++ ++ pwm8_pins_a: pwm8-0 { ++ pins { ++ pinmux = ; /* TIM8_CH4 */ ++ bias-pull-down; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ pwm8_sleep_pins_a: pwm8-sleep-0 { ++ pins { ++ pinmux = ; /* TIM8_CH4 */ ++ }; ++ }; ++ ++ pwm12_pins_a: pwm12-0 { ++ pins { ++ pinmux = ; /* TIM12_CH1 */ ++ bias-pull-down; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ pwm12_sleep_pins_a: pwm12-sleep-0 { ++ pins { ++ pinmux = ; /* TIM12_CH1 */ ++ }; ++ }; ++ ++ qspi_clk_pins_a: qspi-clk-0 { ++ pins { ++ pinmux = ; /* QSPI_CLK */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <3>; ++ }; ++ }; ++ ++ qspi_clk_sleep_pins_a: qspi-clk-sleep-0 { ++ pins { ++ pinmux = ; /* QSPI_CLK */ ++ }; ++ }; ++ ++ qspi_bk1_pins_a: qspi-bk1-0 { ++ pins1 { ++ pinmux = , /* QSPI_BK1_IO0 */ ++ , /* QSPI_BK1_IO1 */ ++ , /* QSPI_BK1_IO2 */ ++ ; /* QSPI_BK1_IO3 */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <1>; ++ }; ++ pins2 { ++ pinmux = ; /* QSPI_BK1_NCS */ ++ bias-pull-up; ++ drive-push-pull; ++ slew-rate = <1>; ++ }; ++ }; ++ ++ qspi_bk1_sleep_pins_a: qspi-bk1-sleep-0 { ++ pins { ++ pinmux = , /* QSPI_BK1_IO0 */ ++ , /* QSPI_BK1_IO1 */ ++ , /* QSPI_BK1_IO2 */ ++ , /* QSPI_BK1_IO3 */ ++ ; /* QSPI_BK1_NCS */ ++ }; ++ }; ++ ++ qspi_bk2_pins_a: qspi-bk2-0 { ++ pins1 { ++ pinmux = , /* QSPI_BK2_IO0 */ ++ , /* QSPI_BK2_IO1 */ ++ , /* QSPI_BK2_IO2 */ ++ ; /* QSPI_BK2_IO3 */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <1>; ++ }; ++ pins2 { ++ pinmux = ; /* QSPI_BK2_NCS */ ++ bias-pull-up; ++ drive-push-pull; ++ slew-rate = <1>; ++ }; ++ }; ++ ++ qspi_bk2_sleep_pins_a: qspi-bk2-sleep-0 { ++ pins { ++ pinmux = , /* QSPI_BK2_IO0 */ ++ , /* QSPI_BK2_IO1 */ ++ , /* QSPI_BK2_IO2 */ ++ , /* QSPI_BK2_IO3 */ ++ ; /* QSPI_BK2_NCS */ ++ }; ++ }; ++ ++ rtc_out2_rmp_pins_a: rtc-out2-rmp-pins-0 { ++ pins { ++ pinmux = ; /* RTC_OUT2_RMP */ ++ }; ++ }; ++ ++ sai2a_pins_a: sai2a-0 { ++ pins { ++ pinmux = , /* SAI2_SCK_A */ ++ , /* SAI2_SD_A */ ++ , /* SAI2_FS_A */ ++ ; /* SAI2_MCLK_A */ ++ slew-rate = <0>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ }; ++ ++ sai2a_sleep_pins_a: sai2a-1 { ++ pins { ++ pinmux = , /* SAI2_SCK_A */ ++ , /* SAI2_SD_A */ ++ , /* SAI2_FS_A */ ++ ; /* SAI2_MCLK_A */ ++ }; ++ }; ++ ++ sai2b_pins_a: sai2b-0 { ++ pins1 { ++ pinmux = , /* SAI2_SCK_B */ ++ , /* SAI2_FS_B */ ++ ; /* SAI2_MCLK_B */ ++ slew-rate = <0>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ pins2 { ++ pinmux = ; /* SAI2_SD_B */ ++ bias-disable; ++ }; ++ }; ++ ++ sai2b_sleep_pins_a: sai2b-1 { ++ pins { ++ pinmux = , /* SAI2_SD_B */ ++ , /* SAI2_SCK_B */ ++ , /* SAI2_FS_B */ ++ ; /* SAI2_MCLK_B */ ++ }; ++ }; ++ ++ sai2b_pins_b: sai2b-2 { ++ pins { ++ pinmux = ; /* SAI2_SD_B */ ++ bias-disable; ++ }; ++ }; ++ ++ sai2b_sleep_pins_b: sai2b-3 { ++ pins { ++ pinmux = ; /* SAI2_SD_B */ ++ }; ++ }; ++ ++ sai4a_pins_a: sai4a-0 { ++ pins { ++ pinmux = ; /* SAI4_SD_A */ ++ slew-rate = <0>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ }; ++ ++ sai4a_sleep_pins_a: sai4a-1 { ++ pins { ++ pinmux = ; /* SAI4_SD_A */ ++ }; ++ }; ++ ++ sdmmc1_b4_pins_a: sdmmc1-b4-0 { ++ pins1 { ++ pinmux = , /* SDMMC1_D0 */ ++ , /* SDMMC1_D1 */ ++ , /* SDMMC1_D2 */ ++ , /* SDMMC1_D3 */ ++ ; /* SDMMC1_CMD */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ pins2 { ++ pinmux = ; /* SDMMC1_CK */ ++ slew-rate = <2>; ++ 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_CK */ ++ slew-rate = <2>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ pins3 { ++ 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_dir_pins_a: sdmmc1-dir-0 { ++ pins1 { ++ pinmux = , /* SDMMC1_D0DIR */ ++ , /* SDMMC1_D123DIR */ ++ ; /* SDMMC1_CDIR */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-pull-up; ++ }; ++ pins2{ ++ pinmux = ; /* SDMMC1_CKIN */ ++ bias-pull-up; ++ }; ++ }; ++ ++ sdmmc1_dir_sleep_pins_a: sdmmc1-dir-sleep-0 { ++ pins { ++ pinmux = , /* SDMMC1_D0DIR */ ++ , /* SDMMC1_D123DIR */ ++ , /* SDMMC1_CDIR */ ++ ; /* SDMMC1_CKIN */ ++ }; ++ }; ++ ++ sdmmc2_b4_pins_a: sdmmc2-b4-0 { ++ pins1 { ++ pinmux = , /* SDMMC2_D0 */ ++ , /* SDMMC2_D1 */ ++ , /* SDMMC2_D2 */ ++ , /* SDMMC2_D3 */ ++ ; /* SDMMC2_CMD */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-pull-up; ++ }; ++ pins2 { ++ pinmux = ; /* SDMMC2_CK */ ++ slew-rate = <2>; ++ 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_CK */ ++ slew-rate = <2>; ++ drive-push-pull; ++ bias-pull-up; ++ }; ++ pins3 { ++ 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_b4_pins_b: sdmmc2-b4-1 { ++ pins1 { ++ pinmux = , /* SDMMC2_D0 */ ++ , /* SDMMC2_D1 */ ++ , /* SDMMC2_D2 */ ++ , /* SDMMC2_D3 */ ++ ; /* SDMMC2_CMD */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ pins2 { ++ pinmux = ; /* SDMMC2_CK */ ++ slew-rate = <2>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ }; ++ ++ sdmmc2_b4_od_pins_b: sdmmc2-b4-od-1 { ++ pins1 { ++ pinmux = , /* SDMMC2_D0 */ ++ , /* SDMMC2_D1 */ ++ , /* SDMMC2_D2 */ ++ ; /* SDMMC2_D3 */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ pins2 { ++ pinmux = ; /* SDMMC2_CK */ ++ slew-rate = <2>; ++ drive-push-pull; ++ bias-disable; ++ }; ++ pins3 { ++ pinmux = ; /* SDMMC2_CMD */ ++ slew-rate = <1>; ++ drive-open-drain; ++ bias-disable; ++ }; ++ }; ++ ++ sdmmc2_d47_pins_a: sdmmc2-d47-0 { ++ pins { ++ pinmux = , /* SDMMC2_D4 */ ++ , /* SDMMC2_D5 */ ++ , /* SDMMC2_D6 */ ++ ; /* SDMMC2_D7 */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-pull-up; ++ }; ++ }; ++ ++ sdmmc2_d47_sleep_pins_a: sdmmc2-d47-sleep-0 { ++ pins { ++ pinmux = , /* SDMMC2_D4 */ ++ , /* SDMMC2_D5 */ ++ , /* SDMMC2_D6 */ ++ ; /* SDMMC2_D7 */ ++ }; ++ }; ++ ++ sdmmc3_b4_pins_a: sdmmc3-b4-0 { ++ pins1 { ++ pinmux = , /* SDMMC3_D0 */ ++ , /* SDMMC3_D1 */ ++ , /* SDMMC3_D2 */ ++ , /* SDMMC3_D3 */ ++ ; /* SDMMC3_CMD */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-pull-up; ++ }; ++ pins2 { ++ pinmux = ; /* SDMMC3_CK */ ++ slew-rate = <2>; ++ drive-push-pull; ++ bias-pull-up; ++ }; ++ }; ++ ++ sdmmc3_b4_od_pins_a: sdmmc3-b4-od-0 { ++ pins1 { ++ pinmux = , /* SDMMC3_D0 */ ++ , /* SDMMC3_D1 */ ++ , /* SDMMC3_D2 */ ++ ; /* SDMMC3_D3 */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-pull-up; ++ }; ++ pins2 { ++ pinmux = ; /* SDMMC3_CK */ ++ slew-rate = <2>; ++ drive-push-pull; ++ bias-pull-up; ++ }; ++ pins3 { ++ pinmux = ; /* SDMMC2_CMD */ ++ slew-rate = <1>; ++ drive-open-drain; ++ bias-pull-up; ++ }; ++ }; ++ ++ sdmmc3_b4_sleep_pins_a: sdmmc3-b4-sleep-0 { ++ pins { ++ pinmux = , /* SDMMC3_D0 */ ++ , /* SDMMC3_D1 */ ++ , /* SDMMC3_D2 */ ++ , /* SDMMC3_D3 */ ++ , /* SDMMC3_CK */ ++ ; /* SDMMC3_CMD */ ++ }; ++ }; ++ ++ spdifrx_pins_a: spdifrx-0 { ++ pins { ++ pinmux = ; /* SPDIF_IN1 */ ++ bias-disable; ++ }; ++ }; ++ ++ spdifrx_sleep_pins_a: spdifrx-1 { ++ pins { ++ pinmux = ; /* SPDIF_IN1 */ ++ }; ++ }; ++ ++ spi2_pins_a: spi2-0 { ++ pins1 { ++ pinmux = , /* SPI2_SCK */ ++ , /* SPI2_NSS */ ++ ; /* SPI2_MOSI */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <3>; ++ }; ++ pins2 { ++ pinmux = ; /* SPI2_MISO */ ++ bias-disable; ++ }; ++ }; ++ ++ spi4_pins_a: spi4-0 { ++ pins1 { ++ pinmux = , /* SPI4_SCK */ ++ ; /* SPI4_MOSI */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <1>; ++ }; ++ ++ pins2 { ++ pinmux = ; /* SPI4_MISO */ ++ bias-disable; ++ }; ++ }; ++ ++ spi4_sleep_pins_a: spi4-sleep-0 { ++ pins { ++ pinmux = , /* SPI4_SCK */ ++ , /* SPI4_MISO */ ++ ; /* SPI4_MOSI */ ++ }; ++ }; ++ ++ 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 */ ++ }; ++ }; ++ ++ stusb1600_pins_a: stusb1600-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 */ ++ }; ++ }; ++ ++ uart4_pins_b: uart4-1 { ++ 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 = ; /* UART4_TX */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ pins2 { ++ pinmux = , /* UART4_RX */ ++ , /* UART4_CTS */ ++ ; /* UART4_RTS */ ++ bias-disable; ++ }; ++ }; ++ ++ uart7_pins_b: uart7-1 { ++ pins1 { ++ pinmux = ; /* USART7_TX */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ pins2 { ++ pinmux = ; /* USART7_RX */ ++ bias-disable; ++ }; ++ }; ++ ++ uart7_idle_pins_b: uart7-idle-1 { ++ pins1 { ++ pinmux = ; /* USART7_TX */ ++ }; ++ pins2 { ++ pinmux = ; /* USART7_RX */ ++ bias-disable; ++ }; ++ }; ++ ++ uart7_sleep_pins_b: uart7-sleep-1 { ++ pins { ++ pinmux = , /* USART7_TX */ ++ ; /* USART7_RX */ ++ }; ++ }; ++ ++ usart2_pins_a: usart2-0 { ++ pins1 { ++ pinmux = , /* USART2_TX */ ++ ; /* USART2_RTS */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <3>; ++ }; ++ pins2 { ++ pinmux = , /* USART2_RX */ ++ ; /* USART2_CTS_NSS */ ++ bias-disable; ++ }; ++ }; ++ ++ usart2_idle_pins_a: usart2-idle-0 { ++ pins1 { ++ pinmux = , /* USART2_TX */ ++ , /* USART2_RTS */ ++ ; /* USART2_CTS_NSS */ ++ }; ++ pins2 { ++ pinmux = ; /* USART2_RX */ ++ bias-disable; ++ }; ++ }; ++ ++ usart2_sleep_pins_a: usart2-sleep-0 { ++ pins { ++ pinmux = , /* USART2_TX */ ++ , /* USART2_RTS */ ++ , /* USART2_RX */ ++ ; /* USART2_CTS_NSS */ ++ }; ++ }; ++ ++ usart3_pins_a: usart3-0 { ++ pins1 { ++ pinmux = , /* USART3_TX */ ++ ; /* USART3_RTS */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ pins2 { ++ pinmux = , /* USART3_RX */ ++ ; /* USART3_CTS_NSS */ ++ bias-disable; ++ }; ++ }; ++ ++ usart3_idle_pins_a: usart3-idle-0 { ++ pins1 { ++ pinmux = , /* USART3_TX */ ++ , /* USART3_RTS */ ++ ; /* USART3_CTS_NSS */ ++ }; ++ pins2 { ++ pinmux = ; /* USART3_RX */ ++ bias-disable; ++ }; ++ }; ++ ++ usart3_sleep_pins_a: usart3-sleep-0 { ++ pins { ++ pinmux = , /* USART3_TX */ ++ , /* USART3_RTS */ ++ , /* USART3_CTS_NSS */ ++ ; /* USART3_RX */ ++ }; ++ }; ++ ++ usart3_pins_b: usart3-1 { ++ pins1 { ++ pinmux = , /* USART3_TX */ ++ ; /* USART3_RTS */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ pins2 { ++ pinmux = , /* USART3_RX */ ++ ; /* USART3_CTS_NSS */ ++ bias-disable; ++ }; ++ }; ++ ++ usart3_idle_pins_b: usart3-idle-1 { ++ pins1 { ++ pinmux = , /* USART3_TX */ ++ , /* USART3_RTS */ ++ ; /* USART3_CTS_NSS */ ++ }; ++ pins2 { ++ pinmux = ; /* USART3_RX */ ++ bias-disable; ++ }; ++ }; ++ ++ usart3_sleep_pins_b: usart3-sleep-1 { ++ pins { ++ pinmux = , /* USART3_TX */ ++ , /* USART3_RTS */ ++ , /* USART3_CTS_NSS */ ++ ; /* USART3_RX */ ++ }; ++ }; ++ ++ usbotg_hs_pins_a: usbotg_hs-0 { ++ pins { ++ pinmux = ; /* OTG_ID */ ++ }; ++ }; ++ ++ usbotg_fs_dp_dm_pins_a: usbotg-fs-dp-dm-0 { ++ pins { ++ pinmux = , /* OTG_FS_DM */ ++ ; /* OTG_FS_DP */ ++ }; ++ }; ++}; ++ ++&pinctrl_z { ++ i2c2_pins_b2: i2c2-0 { ++ pins { ++ pinmux = ; /* I2C2_SCL */ ++ bias-disable; ++ drive-open-drain; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ i2c2_pins_sleep_b2: i2c2-1 { ++ pins { ++ pinmux = ; /* I2C2_SCL */ ++ }; ++ }; ++ ++ i2c4_pins_a: i2c4-0 { ++ pins { ++ pinmux = , /* I2C4_SCL */ ++ ; /* I2C4_SDA */ ++ bias-disable; ++ drive-open-drain; ++ slew-rate = <0>; ++ }; ++ }; ++ ++ i2c4_pins_sleep_a: i2c4-1 { ++ pins { ++ pinmux = , /* I2C4_SCL */ ++ ; /* I2C4_SDA */ ++ }; ++ }; ++ ++ spi1_pins_a: spi1-0 { ++ pins1 { ++ pinmux = , /* SPI1_SCK */ ++ ; /* SPI1_MOSI */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <1>; ++ }; ++ ++ pins2 { ++ pinmux = ; /* SPI1_MISO */ ++ bias-disable; ++ }; ++ }; ++ ++ spi1_sleep_pins_a: spi1-sleep-0 { ++ 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 +new file mode 100644 +index 0000000..823e281 +--- /dev/null ++++ b/arch/arm/dts/stm32mp15-u-boot.dtsi +@@ -0,0 +1,231 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright : STMicroelectronics 2018 ++ */ ++ ++/ { ++ aliases { ++ gpio0 = &gpioa; ++ gpio1 = &gpiob; ++ gpio2 = &gpioc; ++ gpio3 = &gpiod; ++ gpio4 = &gpioe; ++ gpio5 = &gpiof; ++ gpio6 = &gpiog; ++ gpio7 = &gpioh; ++ gpio8 = &gpioi; ++ gpio9 = &gpioj; ++ gpio10 = &gpiok; ++ gpio25 = &gpioz; ++ pinctrl0 = &pinctrl; ++ pinctrl1 = &pinctrl_z; ++ }; ++ ++ /* need PSCI for sysreset during board_f */ ++ psci { ++ u-boot,dm-pre-proper; ++ }; ++ ++ soc { ++ u-boot,dm-pre-reloc; ++ }; ++}; ++ ++&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; ++}; ++ ++&gpioj { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpiok { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpioz { ++ 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; ++}; ++ ++&pinctrl_z { ++ u-boot,dm-pre-reloc; ++}; ++ ++&pwr_regulators { ++ u-boot,dm-pre-reloc; ++}; ++ ++&rcc { ++ u-boot,dm-pre-reloc; ++ #address-cells = <1>; ++ #size-cells = <0>; ++}; ++ ++#ifdef CONFIG_STM32MP1_TRUSTED ++&scmi0 { ++ u-boot,dm-pre-reloc; ++}; ++ ++&scmi0_clk { ++ u-boot,dm-pre-reloc; ++}; ++ ++&scmi0_mbox { ++ u-boot,dm-pre-reloc; ++}; ++ ++&scmi0_reset { ++ u-boot,dm-pre-reloc; ++}; ++ ++&scmi0_shm { ++ u-boot,dm-pre-reloc; ++}; ++ ++&scmi1 { ++ u-boot,dm-pre-reloc; ++}; ++ ++&scmi1_clk { ++ u-boot,dm-pre-reloc; ++}; ++ ++&scmi1_mbox { ++ 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"; ++}; ++ ++&sdmmc2 { ++ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; ++}; ++ ++&sdmmc3 { ++ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; ++}; ++ ++/* NO MORE USE SCMI SUPPORT for BASIC boot chain */ ++#ifndef CONFIG_STM32MP1_TRUSTED ++ ++#include "stm32mp15-no-scmi.dtsi" ++ ++/ { ++ clocks { ++ u-boot,dm-pre-reloc; ++ ++ clk_hse: clk-hse { ++ u-boot,dm-pre-reloc; ++ }; ++ ++ clk_hsi: clk-hsi { ++ u-boot,dm-pre-reloc; ++ }; ++ ++ clk_lse: clk-lse { ++ u-boot,dm-pre-reloc; ++ }; ++ ++ clk_lsi: clk-lsi { ++ u-boot,dm-pre-reloc; ++ }; ++ ++ clk_csi: clk-csi { ++ u-boot,dm-pre-reloc; ++ }; ++ }; ++ ++ reboot { ++ u-boot,dm-pre-reloc; ++ }; ++}; ++ ++&clk_hse { ++ u-boot,dm-pre-reloc; ++}; ++ ++&clk_hsi { ++ u-boot,dm-pre-reloc; ++}; ++ ++&clk_lse { ++ u-boot,dm-pre-reloc; ++}; ++ ++&clk_lsi { ++ u-boot,dm-pre-reloc; ++}; ++ ++&clk_csi { ++ u-boot,dm-pre-reloc; ++}; ++ ++&cpu0_opp_table { ++ u-boot,dm-spl; ++ opp-650000000 { ++ u-boot,dm-spl; ++ }; ++ opp-800000000 { ++ u-boot,dm-spl; ++ }; ++}; ++#endif /* CONFIG_STM32MP1_TRUSTED */ +diff --git a/arch/arm/dts/stm32mp151.dtsi b/arch/arm/dts/stm32mp151.dtsi +new file mode 100644 +index 0000000..c516e2e +--- /dev/null ++++ b/arch/arm/dts/stm32mp151.dtsi +@@ -0,0 +1,1997 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved ++ * Author: Ludovic Barre for STMicroelectronics. ++ */ ++#include ++#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 = <&scmi0_clk CK_SCMI0_MPU>; ++ clock-names = "cpu"; ++ operating-points-v2 = <&cpu0_opp_table>; ++ nvmem-cells = <&part_number_otp>; ++ nvmem-cell-names = "part_number"; ++ #cooling-cells = <2>; ++ }; ++ }; ++ ++ cpu0_opp_table: cpu0-opp-table { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ }; ++ ++ 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>; ++ ++ scmi0_shm: scmi_shm@0 { ++ reg = <0 0x80>; ++ }; ++ ++ scmi1_shm: scmi_shm@200 { ++ reg = <0x200 0x80>; ++ }; ++ }; ++ ++ scmi0_mbox: mailbox-0 { ++ #mbox-cells = <0>; ++ compatible = "arm,smc-mbox"; ++ arm,func-id = <0x82002000>; ++ }; ++ ++ scmi1_mbox: mailbox-1 { ++ #mbox-cells = <0>; ++ compatible = "arm,smc-mbox"; ++ arm,func-id = <0x82002001>; ++ }; ++ ++ firmware { ++ scmi0: scmi-0 { ++ compatible = "arm,scmi"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ mboxes = <&scmi0_mbox 0>; ++ mbox-names = "txrx"; ++ shmem = <&scmi0_shm>; ++ ++ scmi0_clk: protocol@14 { ++ reg = <0x14>; ++ #clock-cells = <1>; ++ }; ++ scmi0_reset: protocol@16 { ++ reg = <0x16>; ++ #reset-cells = <1>; ++ }; ++ }; ++ ++ scmi1: scmi-1 { ++ compatible = "arm,scmi"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ status = "disabled"; ++ mboxes = <&scmi1_mbox 0>; ++ mbox-names = "txrx"; ++ shmem = <&scmi1_shm>; ++ ++ scmi1_clk: protocol@14 { ++ reg = <0x14>; ++ #clock-cells = <1>; ++ }; ++ }; ++ ++ optee: optee { ++ compatible = "linaro,optee-tz"; ++ method = "smc"; ++ status = "disabled"; ++ }; ++ }; ++ ++ psci { ++ compatible = "arm,psci-1.0"; ++ method = "smc"; ++ }; ++ ++ intc: interrupt-controller@a0021000 { ++ compatible = "arm,cortex-a7-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0xa0021000 0x1000>, ++ <0xa0022000 0x2000>; ++ }; ++ ++ timer { ++ compatible = "arm,armv7-timer"; ++ interrupts = , ++ , ++ , ++ ; ++ interrupt-parent = <&intc>; ++ always-on; ++ }; ++ ++ 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 { ++ }; ++ }; ++ }; ++ ++ booster: regulator-booster { ++ compatible = "st,stm32mp1-booster"; ++ st,syscfg = <&syscfg>; ++ status = "disabled"; ++ }; ++ ++ 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"; ++ }; ++ }; ++ }; ++ ++ reboot { ++ compatible = "syscon-reboot"; ++ regmap = <&rcc>; ++ offset = <0x404>; ++ mask = <0x1>; ++ }; ++ ++ soc { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ interrupt-parent = <&intc>; ++ ranges; ++ ++ sram: sram@10000000 { ++ compatible = "mmio-sram"; ++ reg = <0x10000000 0x60000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0x10000000 0x60000>; ++ }; ++ ++ 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", "ch4"; ++ 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"; ++ }; ++ }; ++ ++ timers12: timer@40006000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x40006000 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@40007000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x40007000 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@40008000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x40008000 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"; ++ }; ++ }; ++ ++ lptimer1: timer@40009000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-lptimer"; ++ reg = <0x40009000 0x400>; ++ clocks = <&rcc LPTIM1_K>; ++ clock-names = "mux"; ++ 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"; ++ }; ++ }; ++ ++ 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"; ++ power-domains = <&pd_core>; ++ 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"; ++ }; ++ ++ 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"; ++ power-domains = <&pd_core>; ++ 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"; ++ }; ++ ++ 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"; ++ }; ++ ++ usart2: serial@4000e000 { ++ compatible = "st,stm32h7-uart"; ++ reg = <0x4000e000 0x400>; ++ interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&rcc USART2_K>; ++ resets = <&rcc USART2_R>; ++ wakeup-source; ++ power-domains = <&pd_core>; ++ dmas = <&dmamux1 43 0x400 0x5>, ++ <&dmamux1 44 0x400 0x1>; ++ dma-names = "rx", "tx"; ++ 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>; ++ 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>; ++ 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>; ++ dmas = <&dmamux1 65 0x400 0x5>, ++ <&dmamux1 66 0x400 0x1>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@40012000 { ++ compatible = "st,stm32mp15-i2c"; ++ reg = <0x40012000 0x400>; ++ interrupt-names = "event", "error"; ++ interrupts-extended = <&exti 21 IRQ_TYPE_LEVEL_HIGH>, ++ <&intc GIC_SPI 32 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"; ++ power-domains = <&pd_core>; ++ st,syscfg-fmp = <&syscfg 0x4 0x1>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ i2c2: i2c@40013000 { ++ compatible = "st,stm32mp15-i2c"; ++ reg = <0x40013000 0x400>; ++ interrupt-names = "event", "error"; ++ interrupts-extended = <&exti 22 IRQ_TYPE_LEVEL_HIGH>, ++ <&intc GIC_SPI 34 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"; ++ power-domains = <&pd_core>; ++ st,syscfg-fmp = <&syscfg 0x4 0x2>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ i2c3: i2c@40014000 { ++ compatible = "st,stm32mp15-i2c"; ++ reg = <0x40014000 0x400>; ++ interrupt-names = "event", "error"; ++ interrupts-extended = <&exti 23 IRQ_TYPE_LEVEL_HIGH>, ++ <&intc GIC_SPI 73 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"; ++ power-domains = <&pd_core>; ++ st,syscfg-fmp = <&syscfg 0x4 0x4>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ i2c5: i2c@40015000 { ++ compatible = "st,stm32mp15-i2c"; ++ reg = <0x40015000 0x400>; ++ interrupt-names = "event", "error"; ++ interrupts-extended = <&exti 25 IRQ_TYPE_LEVEL_HIGH>, ++ <&intc GIC_SPI 108 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"; ++ power-domains = <&pd_core>; ++ st,syscfg-fmp = <&syscfg 0x4 0x10>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ cec: cec@40016000 { ++ compatible = "st,stm32-cec"; ++ reg = <0x40016000 0x400>; ++ interrupts = ; ++ clocks = <&rcc CEC_K>, <&scmi0_clk CK_SCMI0_LSE>; ++ clock-names = "cec", "hdmi-cec"; ++ status = "disabled"; ++ }; ++ ++ dac: dac@40017000 { ++ compatible = "st,stm32h7-dac-core"; ++ reg = <0x40017000 0x400>; ++ clocks = <&rcc DAC12>; ++ clock-names = "pclk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ dac1: dac@1 { ++ compatible = "st,stm32-dac"; ++ #io-channel-cells = <1>; ++ reg = <1>; ++ status = "disabled"; ++ }; ++ ++ dac2: dac@2 { ++ compatible = "st,stm32-dac"; ++ #io-channel-cells = <1>; ++ reg = <2>; ++ 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>; ++ 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>; ++ 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>; ++ dmas = <&dmamux1 71 0x400 0x5>, ++ <&dmamux1 72 0x400 0x1>; ++ 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"; ++ power-domains = <&pd_core>; ++ 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"; ++ }; ++ ++ spi4: spi@44005000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32h7-spi"; ++ reg = <0x44005000 0x400>; ++ interrupts = ; ++ clocks = <&rcc SPI4_K>; ++ resets = <&rcc SPI4_R>; ++ dmas = <&dmamux1 83 0x400 0x01>, ++ <&dmamux1 84 0x400 0x01>; ++ dma-names = "rx", "tx"; ++ power-domains = <&pd_core>; ++ status = "disabled"; ++ }; ++ ++ timers15: timer@44006000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x44006000 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@44007000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x44007000 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@44008000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-timers"; ++ reg = <0x44008000 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"; ++ }; ++ }; ++ ++ spi5: spi@44009000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32h7-spi"; ++ reg = <0x44009000 0x400>; ++ interrupts = ; ++ clocks = <&rcc SPI5_K>; ++ resets = <&rcc SPI5_R>; ++ dmas = <&dmamux1 85 0x400 0x01>, ++ <&dmamux1 86 0x400 0x01>; ++ dma-names = "rx", "tx"; ++ power-domains = <&pd_core>; ++ 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 0x1c>; ++ 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 0x1c>; ++ 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 0x1c>; ++ 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 0x1c>; ++ clocks = <&rcc SAI2_K>; ++ clock-names = "sai_ck"; ++ dmas = <&dmamux1 90 0x400 0x01>; ++ status = "disabled"; ++ }; ++ }; ++ ++ sai3: sai@4400c000 { ++ compatible = "st,stm32h7-sai"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0x4400c000 0x400>; ++ reg = <0x4400c000 0x4>, <0x4400c3f0 0x10>; ++ interrupts = ; ++ resets = <&rcc SAI3_R>; ++ status = "disabled"; ++ ++ sai3a: audio-controller@4400c004 { ++ #sound-dai-cells = <0>; ++ compatible = "st,stm32-sai-sub-a"; ++ reg = <0x04 0x1c>; ++ clocks = <&rcc SAI3_K>; ++ clock-names = "sai_ck"; ++ dmas = <&dmamux1 113 0x400 0x01>; ++ status = "disabled"; ++ }; ++ ++ sai3b: audio-controller@4400c024 { ++ #sound-dai-cells = <0>; ++ compatible = "st,stm32-sai-sub-b"; ++ reg = <0x24 0x1c>; ++ clocks = <&rcc SAI3_K>; ++ clock-names = "sai_ck"; ++ dmas = <&dmamux1 114 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"; ++ }; ++ ++ dfsdm2: filter@2 { ++ compatible = "st,stm32-dfsdm-adc"; ++ #io-channel-cells = <1>; ++ reg = <2>; ++ interrupts = ; ++ dmas = <&dmamux1 103 0x400 0x01>; ++ dma-names = "rx"; ++ status = "disabled"; ++ }; ++ ++ dfsdm3: filter@3 { ++ compatible = "st,stm32-dfsdm-adc"; ++ #io-channel-cells = <1>; ++ reg = <3>; ++ interrupts = ; ++ dmas = <&dmamux1 104 0x400 0x01>; ++ dma-names = "rx"; ++ status = "disabled"; ++ }; ++ ++ dfsdm4: filter@4 { ++ compatible = "st,stm32-dfsdm-adc"; ++ #io-channel-cells = <1>; ++ reg = <4>; ++ interrupts = ; ++ dmas = <&dmamux1 91 0x400 0x01>; ++ dma-names = "rx"; ++ status = "disabled"; ++ }; ++ ++ dfsdm5: filter@5 { ++ compatible = "st,stm32-dfsdm-adc"; ++ #io-channel-cells = <1>; ++ reg = <5>; ++ interrupts = ; ++ dmas = <&dmamux1 92 0x400 0x01>; ++ dma-names = "rx"; ++ status = "disabled"; ++ }; ++ }; ++ ++ dma1: dma@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 = <&mdma1 0 0x3 0x1200000a 0x48000008 0x00000020 1>, ++ <&mdma1 1 0x3 0x1200000a 0x48000008 0x00000800 1>, ++ <&mdma1 2 0x3 0x1200000a 0x48000008 0x00200000 1>, ++ <&mdma1 3 0x3 0x1200000a 0x48000008 0x08000000 1>, ++ <&mdma1 4 0x3 0x1200000a 0x4800000C 0x00000020 1>, ++ <&mdma1 5 0x3 0x1200000a 0x4800000C 0x00000800 1>, ++ <&mdma1 6 0x3 0x1200000a 0x4800000C 0x00200000 1>, ++ <&mdma1 7 0x3 0x1200000a 0x4800000C 0x08000000 1>; ++ dma-names = "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7"; ++ }; ++ ++ dma2: dma@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 = <&mdma1 8 0x3 0x1200000a 0x48001008 0x00000020 1>, ++ <&mdma1 9 0x3 0x1200000a 0x48001008 0x00000800 1>, ++ <&mdma1 10 0x3 0x1200000a 0x48001008 0x00200000 1>, ++ <&mdma1 11 0x3 0x1200000a 0x48001008 0x08000000 1>, ++ <&mdma1 12 0x3 0x1200000a 0x4800100C 0x00000020 1>, ++ <&mdma1 13 0x3 0x1200000a 0x4800100C 0x00000800 1>, ++ <&mdma1 14 0x3 0x1200000a 0x4800100C 0x00200000 1>, ++ <&mdma1 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>; ++ #dma-cells = <3>; ++ dma-requests = <128>; ++ dma-masters = <&dma1 &dma2>; ++ dma-channels = <16>; ++ clocks = <&rcc DMAMUX>; ++ resets = <&rcc DMAMUX_R>; ++ }; ++ ++ adc: adc@48003000 { ++ compatible = "st,stm32mp1-adc-core"; ++ reg = <0x48003000 0x400>; ++ interrupts = , ++ ; ++ clocks = <&rcc ADC12>, <&rcc ADC12_K>; ++ clock-names = "bus", "adc"; ++ interrupt-controller; ++ st,syscfg = <&syscfg>; ++ #interrupt-cells = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ adc1: adc@0 { ++ compatible = "st,stm32mp1-adc"; ++ #io-channel-cells = <1>; ++ reg = <0x0>; ++ interrupt-parent = <&adc>; ++ interrupts = <0>; ++ dmas = <&dmamux1 9 0x400 0x80000001>; ++ dma-names = "rx"; ++ status = "disabled"; ++ }; ++ ++ adc2: adc@100 { ++ compatible = "st,stm32mp1-adc"; ++ #io-channel-cells = <1>; ++ reg = <0x100>; ++ interrupt-parent = <&adc>; ++ interrupts = <1>; ++ dmas = <&dmamux1 10 0x400 0x80000001>; ++ dma-names = "rx"; ++ status = "disabled"; ++ }; ++ }; ++ ++ sdmmc3: sdmmc@48004000 { ++ compatible = "arm,pl18x", "arm,primecell"; ++ arm,primecell-periphid = <0x00253180>; ++ reg = <0x48004000 0x400>, <0x48005000 0x400>; ++ interrupts = ; ++ interrupt-names = "cmd_irq"; ++ clocks = <&rcc SDMMC3_K>; ++ clock-names = "apb_pclk"; ++ resets = <&rcc SDMMC3_R>; ++ cap-sd-highspeed; ++ cap-mmc-highspeed; ++ max-frequency = <120000000>; ++ status = "disabled"; ++ }; ++ ++ usbotg_hs: usb-otg@49000000 { ++ compatible = "st,stm32mp1-hsotg", "snps,dwc2"; ++ reg = <0x49000000 0x10000>; ++ 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"; ++ usb33d-supply = <&usb33>; ++ power-domains = <&pd_core>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ hsem: hwspinlock@4c000000 { ++ compatible = "st,stm32-hwspinlock"; ++ #hwlock-cells = <2>; ++ reg = <0x4c000000 0x400>; ++ clocks = <&rcc HSEM>; ++ clock-names = "hsem"; ++ }; ++ ++ ipcc: mailbox@4c001000 { ++ compatible = "st,stm32mp1-ipcc"; ++ #mbox-cells = <1>; ++ reg = <0x4c001000 0x400>; ++ st,proc-id = <0>; ++ interrupts-extended = ++ <&exti 61 1>, ++ <&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "rx", "tx"; ++ clocks = <&rcc IPCC>; ++ wakeup-source; ++ power-domains = <&pd_core>; ++ status = "disabled"; ++ }; ++ ++ dcmi: dcmi@4c006000 { ++ compatible = "st,stm32-dcmi"; ++ reg = <0x4c006000 0x400>; ++ interrupts = ; ++ resets = <&rcc CAMITF_R>; ++ clocks = <&rcc DCMI>; ++ clock-names = "mclk"; ++ dmas = <&dmamux1 75 0x400 0xe0000001>; ++ dma-names = "tx"; ++ status = "disabled"; ++ }; ++ ++ rcc: rcc@50000000 { ++ compatible = "st,stm32mp1-rcc-secure", "st,stm32mp1-rcc", "syscon"; ++ 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>; ++ }; ++ ++ pwr_regulators: pwr@50001000 { ++ compatible = "st,stm32mp1,pwr-reg"; ++ reg = <0x50001000 0x10>; ++ st,tzcr = <&rcc 0x0 0x1>; ++ ++ reg11: reg11 { ++ regulator-name = "reg11"; ++ regulator-min-microvolt = <1100000>; ++ regulator-max-microvolt = <1100000>; ++ }; ++ ++ reg18: reg18 { ++ regulator-name = "reg18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ }; ++ ++ usb33: usb33 { ++ regulator-name = "usb33"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ }; ++ ++ pwr_mcu: pwr_mcu@50001014 { ++ compatible = "syscon"; ++ reg = <0x50001014 0x4>; ++ }; ++ ++ pwr_irq: pwr@50001020 { ++ compatible = "st,stm32mp1-pwr"; ++ reg = <0x50001020 0x100>; ++ interrupts = ; ++ 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>; ++ }; ++ ++ exti: interrupt-controller@5000d000 { ++ compatible = "st,stm32mp1-exti", "syscon"; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x5000d000 0x400>; ++ hwlocks = <&hsem 1 1>; ++ ++ /* exti_pwr is an extra interrupt controller used for ++ * EXTI 55 to 60. It's mapped on pwr interrupt ++ * controller. ++ */ ++ exti_pwr: exti-pwr { ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupt-parent = <&pwr_irq>; ++ st,irq-number = <6>; ++ }; ++ }; ++ ++ 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>; ++ clocks = <&rcc LPTIM2_K>; ++ clock-names = "mux"; ++ 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"; ++ }; ++ }; ++ ++ lptimer3: timer@50022000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32-lptimer"; ++ reg = <0x50022000 0x400>; ++ clocks = <&rcc LPTIM3_K>; ++ clock-names = "mux"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm-lp"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ trigger@2 { ++ compatible = "st,stm32-lptimer-trigger"; ++ reg = <2>; ++ status = "disabled"; ++ }; ++ }; ++ ++ lptimer4: timer@50023000 { ++ compatible = "st,stm32-lptimer"; ++ reg = <0x50023000 0x400>; ++ clocks = <&rcc LPTIM4_K>; ++ clock-names = "mux"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm-lp"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ }; ++ ++ lptimer5: timer@50024000 { ++ compatible = "st,stm32-lptimer"; ++ reg = <0x50024000 0x400>; ++ clocks = <&rcc LPTIM5_K>; ++ clock-names = "mux"; ++ status = "disabled"; ++ ++ pwm { ++ compatible = "st,stm32-pwm-lp"; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ }; ++ ++ vrefbuf: vrefbuf@50025000 { ++ compatible = "st,stm32-vrefbuf"; ++ reg = <0x50025000 0x8>; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <2500000>; ++ clocks = <&rcc VREF>; ++ status = "disabled"; ++ }; ++ ++ sai4: sai@50027000 { ++ compatible = "st,stm32h7-sai"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0x50027000 0x400>; ++ reg = <0x50027000 0x4>, <0x500273f0 0x10>; ++ interrupts = ; ++ resets = <&rcc SAI4_R>; ++ status = "disabled"; ++ ++ sai4a: audio-controller@50027004 { ++ #sound-dai-cells = <0>; ++ compatible = "st,stm32-sai-sub-a"; ++ reg = <0x04 0x1c>; ++ clocks = <&rcc SAI4_K>; ++ clock-names = "sai_ck"; ++ dmas = <&dmamux1 99 0x400 0x01>; ++ status = "disabled"; ++ }; ++ ++ sai4b: audio-controller@50027024 { ++ #sound-dai-cells = <0>; ++ compatible = "st,stm32-sai-sub-b"; ++ reg = <0x24 0x1c>; ++ clocks = <&rcc SAI4_K>; ++ clock-names = "sai_ck"; ++ dmas = <&dmamux1 100 0x400 0x01>; ++ status = "disabled"; ++ }; ++ }; ++ ++ dts: thermal@50028000 { ++ compatible = "st,stm32-thermal"; ++ reg = <0x50028000 0x100>; ++ interrupts = ; ++ clocks = <&rcc TMPSENS>; ++ clock-names = "pclk"; ++ #thermal-sensor-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ hdp: hdp@5002a000 { ++ compatible = "st,stm32mp1-hdp"; ++ reg = <0x5002a000 0x400>; ++ clocks = <&rcc HDP>; ++ clock-names = "hdp"; ++ status = "disabled"; ++ }; ++ ++ hash1: hash@54002000 { ++ compatible = "st,stm32f756-hash"; ++ reg = <0x54002000 0x400>; ++ interrupts = ; ++ clocks = <&scmi0_clk CK_SCMI0_HASH1>; ++ resets = <&scmi0_reset RST_SCMI0_HASH1>; ++ dmas = <&mdma1 31 0x2 0x1000A02 0x0 0x0 0x0>; ++ dma-names = "in"; ++ dma-maxburst = <2>; ++ status = "disabled"; ++ }; ++ ++ rng1: rng@54003000 { ++ compatible = "st,stm32-rng"; ++ reg = <0x54003000 0x400>; ++ clocks = <&scmi0_clk CK_SCMI0_RNG1>; ++ resets = <&scmi0_reset RST_SCMI0_RNG1>; ++ status = "disabled"; ++ }; ++ ++ mdma1: dma@58000000 { ++ compatible = "st,stm32h7-mdma"; ++ reg = <0x58000000 0x1000>; ++ interrupts = ; ++ clocks = <&rcc MDMA>; ++ resets = <&scmi0_reset RST_SCMI0_MDMA>; ++ #dma-cells = <6>; ++ dma-channels = <32>; ++ dma-requests = <48>; ++ }; ++ ++ fmc: nand-controller@58002000 { ++ compatible = "st,stm32mp15-fmc2"; ++ reg = <0x58002000 0x1000>, ++ <0x80000000 0x1000>, ++ <0x88010000 0x1000>, ++ <0x88020000 0x1000>, ++ <0x81000000 0x1000>, ++ <0x89010000 0x1000>, ++ <0x89020000 0x1000>; ++ interrupts = ; ++ dmas = <&mdma1 20 0x2 0x12000a02 0x0 0x0 0x0>, ++ <&mdma1 20 0x2 0x12000a08 0x0 0x0 0x0>, ++ <&mdma1 21 0x2 0x12000a0a 0x0 0x0 0x0>; ++ dma-names = "tx", "rx", "ecc"; ++ clocks = <&rcc FMC_K>; ++ resets = <&rcc FMC_R>; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@58003000 { ++ compatible = "st,stm32f469-qspi"; ++ 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>; ++ dma-names = "tx", "rx"; ++ clocks = <&rcc QSPI_K>; ++ resets = <&rcc QSPI_R>; ++ status = "disabled"; ++ }; ++ ++ sdmmc1: sdmmc@58005000 { ++ compatible = "arm,pl18x", "arm,primecell"; ++ arm,primecell-periphid = <0x00253180>; ++ 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 = <120000000>; ++ status = "disabled"; ++ }; ++ ++ sdmmc2: sdmmc@58007000 { ++ compatible = "arm,pl18x", "arm,primecell"; ++ arm,primecell-periphid = <0x00253180>; ++ 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 = <120000000>; ++ 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>; ++ }; ++ ++ ethernet0: ethernet@5800a000 { ++ compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; ++ reg = <0x5800a000 0x2000>; ++ reg-names = "stmmaceth"; ++ interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, ++ <&exti 70 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "macirq", ++ "eth_wake_irq"; ++ clock-names = "stmmaceth", ++ "mac-clk-tx", ++ "mac-clk-rx", ++ "ethstp"; ++ clocks = <&rcc ETHMAC>, ++ <&rcc ETHTX>, ++ <&rcc ETHRX>, ++ <&rcc ETHSTP>; ++ st,syscon = <&syscfg 0x4>; ++ snps,mixed-burst; ++ snps,pbl = <2>; ++ snps,en-tx-lpi-clockgating; ++ snps,axi-config = <&stmmac_axi_config_0>; ++ snps,tso; ++ power-domains = <&pd_core>; ++ status = "disabled"; ++ }; ++ ++ usbh_ohci: usbh-ohci@5800c000 { ++ compatible = "generic-ohci"; ++ reg = <0x5800c000 0x1000>; ++ clocks = <&rcc USBH>; ++ resets = <&rcc USBH_R>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbh_ehci: usbh-ehci@5800d000 { ++ compatible = "generic-ehci"; ++ reg = <0x5800d000 0x1000>; ++ clocks = <&rcc USBH>; ++ resets = <&rcc USBH_R>; ++ interrupts-extended = <&exti 43 IRQ_TYPE_LEVEL_HIGH>; ++ companion = <&usbh_ohci>; ++ power-domains = <&pd_core>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ ltdc: display-controller@5a001000 { ++ compatible = "st,stm32-ltdc"; ++ reg = <0x5a001000 0x400>; ++ interrupts = , ++ ; ++ clocks = <&rcc LTDC_PX>; ++ clock-names = "lcd"; ++ resets = <&rcc LTDC_R>; ++ status = "disabled"; ++ }; ++ ++ iwdg2: watchdog@5a002000 { ++ compatible = "st,stm32mp1-iwdg"; ++ reg = <0x5a002000 0x400>; ++ clocks = <&rcc IWDG2>, <&scmi0_clk CK_SCMI0_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 = <®11>; ++ vdda1v8-supply = <®18>; ++ status = "disabled"; ++ ++ usbphyc_port0: usb-phy@0 { ++ #phy-cells = <0>; ++ reg = <0>; ++ }; ++ ++ usbphyc_port1: usb-phy@1 { ++ #phy-cells = <1>; ++ reg = <1>; ++ }; ++ }; ++ ++ ddrperfm: perf@5a007000 { ++ compatible = "st,stm32-ddr-pmu"; ++ reg = <0x5a007000 0x400>; ++ clocks = <&rcc DDRPERFM>, <&scmi0_clk CK_SCMI0_PLL2_R>; ++ clock-names = "bus", "ddr"; ++ resets = <&rcc DDRPERFM_R>; ++ }; ++ ++ usart1: serial@5c000000 { ++ compatible = "st,stm32h7-uart"; ++ reg = <0x5c000000 0x400>; ++ interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&scmi0_clk CK_SCMI0_USART1>; ++ resets = <&scmi0_reset RST_SCMI0_USART1>; ++ wakeup-source; ++ power-domains = <&pd_core>; ++ status = "disabled"; ++ }; ++ ++ spi6: spi@5c001000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stm32h7-spi"; ++ reg = <0x5c001000 0x400>; ++ interrupts = ; ++ clocks = <&scmi0_clk CK_SCMI0_SPI6>; ++ resets = <&scmi0_reset RST_SCMI0_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"; ++ }; ++ ++ i2c4: i2c@5c002000 { ++ compatible = "st,stm32mp15-i2c"; ++ reg = <0x5c002000 0x400>; ++ interrupt-names = "event", "error"; ++ 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>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ dmas = <&mdma1 36 0x0 0x40008 0x0 0x0 0>, ++ <&mdma1 37 0x0 0x40002 0x0 0x0 0>; ++ dma-names = "rx", "tx"; ++ power-domains = <&pd_core>; ++ st,syscfg-fmp = <&syscfg 0x4 0x8>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ rtc: rtc@5c004000 { ++ compatible = "st,stm32mp1-rtc"; ++ reg = <0x5c004000 0x400>; ++ clocks = <&scmi0_clk CK_SCMI0_RTCAPB>, ++ <&scmi0_clk CK_SCMI0_RTC>; ++ clock-names = "pclk", "rtc_ck"; ++ interrupts-extended = <&exti 19 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ bsec: nvmem@5c005000 { ++ compatible = "st,stm32mp15-bsec"; ++ reg = <0x5c005000 0x400>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ part_number_otp: part_number_otp@4 { ++ reg = <0x4 0x1>; ++ }; ++ ts_cal1: calib@5c { ++ reg = <0x5c 0x2>; ++ }; ++ ts_cal2: calib@5e { ++ reg = <0x5e 0x2>; ++ }; ++ }; ++ ++ i2c6: i2c@5c009000 { ++ compatible = "st,stm32mp15-i2c"; ++ reg = <0x5c009000 0x400>; ++ interrupt-names = "event", "error"; ++ 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>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ dmas = <&mdma1 38 0x0 0x40008 0x0 0x0 0>, ++ <&mdma1 39 0x0 0x40002 0x0 0x0 0>; ++ dma-names = "rx", "tx"; ++ power-domains = <&pd_core>; ++ st,syscfg-fmp = <&syscfg 0x4 0x20>; ++ wakeup-source; ++ status = "disabled"; ++ }; ++ ++ tamp: tamp@5c00a000 { ++ compatible = "simple-bus", "syscon", "simple-mfd"; ++ reg = <0x5c00a000 0x400>; ++ ++ reboot-mode { ++ compatible = "syscon-reboot-mode"; ++ offset = <0x150>; /* reg20 */ ++ mask = <0xff>; ++ mode-normal = <0>; ++ mode-fastboot = <0x1>; ++ mode-recovery = <0x2>; ++ mode-stm32cubeprogrammer = <0x3>; ++ mode-ums_mmc0 = <0x10>; ++ mode-ums_mmc1 = <0x11>; ++ mode-ums_mmc2 = <0x12>; ++ }; ++ }; ++ ++ /* ++ * Break node order to solve dependency probe issue between ++ * pinctrl and exti. ++ */ ++ pinctrl: pin-controller@50002000 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "st,stm32mp157-pinctrl"; ++ ranges = <0 0x50002000 0xa400>; ++ interrupt-parent = <&exti>; ++ st,syscfg = <&exti 0x60 0xff>; ++ hwlocks = <&hsem 0 1>; ++ 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"; ++ status = "disabled"; ++ }; ++ ++ gpiob: gpio@50003000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x1000 0x400>; ++ clocks = <&rcc GPIOB>; ++ st,bank-name = "GPIOB"; ++ status = "disabled"; ++ }; ++ ++ gpioc: gpio@50004000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x2000 0x400>; ++ clocks = <&rcc GPIOC>; ++ st,bank-name = "GPIOC"; ++ status = "disabled"; ++ }; ++ ++ gpiod: gpio@50005000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x3000 0x400>; ++ clocks = <&rcc GPIOD>; ++ st,bank-name = "GPIOD"; ++ status = "disabled"; ++ }; ++ ++ gpioe: gpio@50006000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x4000 0x400>; ++ clocks = <&rcc GPIOE>; ++ st,bank-name = "GPIOE"; ++ status = "disabled"; ++ }; ++ ++ gpiof: gpio@50007000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x5000 0x400>; ++ clocks = <&rcc GPIOF>; ++ st,bank-name = "GPIOF"; ++ status = "disabled"; ++ }; ++ ++ gpiog: gpio@50008000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x6000 0x400>; ++ clocks = <&rcc GPIOG>; ++ st,bank-name = "GPIOG"; ++ status = "disabled"; ++ }; ++ ++ gpioh: gpio@50009000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x7000 0x400>; ++ clocks = <&rcc GPIOH>; ++ st,bank-name = "GPIOH"; ++ status = "disabled"; ++ }; ++ ++ gpioi: gpio@5000a000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x8000 0x400>; ++ clocks = <&rcc GPIOI>; ++ st,bank-name = "GPIOI"; ++ status = "disabled"; ++ }; ++ ++ gpioj: gpio@5000b000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0x9000 0x400>; ++ clocks = <&rcc GPIOJ>; ++ st,bank-name = "GPIOJ"; ++ status = "disabled"; ++ }; ++ ++ gpiok: gpio@5000c000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0xa000 0x400>; ++ clocks = <&rcc GPIOK>; ++ st,bank-name = "GPIOK"; ++ status = "disabled"; ++ }; ++ }; ++ ++ pinctrl_z: pin-controller-z@54004000 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "st,stm32mp157-z-pinctrl"; ++ ranges = <0 0x54004000 0x400>; ++ pins-are-numbered; ++ interrupt-parent = <&exti>; ++ st,syscfg = <&exti 0x60 0xff>; ++ hwlocks = <&hsem 0 1>; ++ ++ gpioz: gpio@54004000 { ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ reg = <0 0x400>; ++ clocks = <&scmi0_clk CK_SCMI0_GPIOZ>; ++ st,bank-name = "GPIOZ"; ++ st,bank-ioport = <11>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ mlahb { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ dma-ranges = <0x00000000 0x38000000 0x10000>, ++ <0x10000000 0x10000000 0x60000>, ++ <0x30000000 0x30000000 0x60000>; ++ ++ m4_rproc: m4@10000000 { ++ compatible = "st,stm32mp1-m4"; ++ reg = <0x10000000 0x40000>, ++ <0x30000000 0x40000>, ++ <0x38000000 0x10000>; ++ resets = <&scmi0_reset RST_SCMI0_MCU>; ++ st,syscfg-holdboot = <&rcc 0x10C 0x1>; ++ st,syscfg-tz = <&rcc 0x000 0x1>; ++ st,syscfg-rsc-tbl = <&tamp 0x144 0xFFFFFFFF>; ++ st,syscfg-copro-state = <&tamp 0x148 0xFFFFFFFF>; ++ st,syscfg-pdds = <&pwr_mcu 0x0 0x1>; ++ status = "disabled"; ++ ++ m4_system_resources { ++ compatible = "rproc-srm-core"; ++ status = "disabled"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp153.dtsi b/arch/arm/dts/stm32mp153.dtsi +new file mode 100644 +index 0000000..cf16b84 +--- /dev/null ++++ b/arch/arm/dts/stm32mp153.dtsi +@@ -0,0 +1,54 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++#include "stm32mp151.dtsi" ++ ++/ { ++ cpus { ++ cpu1: cpu@1 { ++ compatible = "arm,cortex-a7"; ++ device_type = "cpu"; ++ reg = <1>; ++ clocks = <&scmi0_clk CK_SCMI0_MPU>; ++ clock-names = "cpu"; ++ operating-points-v2 = <&cpu0_opp_table>; ++ }; ++ }; ++ ++ arm-pmu { ++ interrupts = , ++ ; ++ interrupt-affinity = <&cpu0>, <&cpu1>; ++ }; ++ ++ soc { ++ 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 = <&scmi0_clk CK_SCMI0_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 = <&scmi0_clk CK_SCMI0_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-m4-srm-pinctrl.dtsi b/arch/arm/dts/stm32mp157-m4-srm-pinctrl.dtsi +new file mode 100644 +index 0000000..b4030e5 +--- /dev/null ++++ b/arch/arm/dts/stm32mp157-m4-srm-pinctrl.dtsi +@@ -0,0 +1,524 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Fabien Dessenne for STMicroelectronics. ++ */ ++ ++&pinctrl { ++ m4_adc1_in6_pins_a: m4-adc1-in6 { ++ pins { ++ pinmux = ; ++ }; ++ }; ++ ++ m4_adc12_ain_pins_a: m4-adc12-ain-0 { ++ pins { ++ pinmux = , /* ADC1 in13 */ ++ , /* ADC1 in6 */ ++ , /* ADC2 in2 */ ++ ; /* ADC2 in6 */ ++ }; ++ }; ++ ++ m4_adc12_usb_pwr_pins_a: m4-adc12-usb-pwr-pins-0 { ++ pins { ++ pinmux = , /* ADC12 in18 */ ++ ; /* ADC12 in19 */ ++ }; ++ }; ++ ++ m4_cec_pins_a: m4-cec-0 { ++ pins { ++ pinmux = ; ++ }; ++ }; ++ ++ m4_cec_pins_b: m4-cec-1 { ++ pins { ++ pinmux = ; ++ }; ++ }; ++ ++ m4_dac_ch1_pins_a: m4-dac-ch1 { ++ pins { ++ pinmux = ; ++ }; ++ }; ++ ++ m4_dac_ch2_pins_a: m4-dac-ch2 { ++ pins { ++ pinmux = ; ++ }; ++ }; ++ ++ m4_dcmi_pins_a: m4-dcmi-0 { ++ pins { ++ pinmux = ,/* DCMI_HSYNC */ ++ ,/* DCMI_VSYNC */ ++ ,/* DCMI_PIXCLK */ ++ ,/* DCMI_D0 */ ++ ,/* DCMI_D1 */ ++ ,/* DCMI_D2 */ ++ ,/* DCMI_D3 */ ++ ,/* DCMI_D4 */ ++ ,/* DCMI_D5 */ ++ ,/* DCMI_D6 */ ++ ,/* DCMI_D7 */ ++ ,/* DCMI_D8 */ ++ ,/* DCMI_D9 */ ++ ,/* DCMI_D10 */ ++ ;/* DCMI_D11 */ ++ }; ++ }; ++ ++ m4_dfsdm_clkout_pins_a: m4-dfsdm-clkout-pins-0 { ++ pins { ++ pinmux = ; /* DFSDM_CKOUT */ ++ }; ++ }; ++ ++ m4_dfsdm_data1_pins_a: m4-dfsdm-data1-pins-0 { ++ pins { ++ pinmux = ; /* DFSDM_DATA1 */ ++ }; ++ }; ++ ++ m4_dfsdm_data3_pins_a: m4-dfsdm-data3-pins-0 { ++ pins { ++ pinmux = ; /* DFSDM_DATA3 */ ++ }; ++ }; ++ ++ m4_ethernet0_rgmii_pins_a: m4-rgmii-0 { ++ pins { ++ pinmux = , /* ETH_RGMII_CLK125 */ ++ , /* ETH_RGMII_GTX_CLK */ ++ , /* ETH_RGMII_TXD0 */ ++ , /* ETH_RGMII_TXD1 */ ++ , /* ETH_RGMII_TXD2 */ ++ , /* ETH_RGMII_TXD3 */ ++ , /* ETH_RGMII_TX_CTL */ ++ , /* ETH_MDC */ ++ , /* ETH_MDIO */ ++ , /* ETH_RGMII_RXD0 */ ++ , /* ETH_RGMII_RXD1 */ ++ , /* ETH_RGMII_RXD2 */ ++ , /* ETH_RGMII_RXD3 */ ++ , /* ETH_RGMII_RX_CLK */ ++ ; /* ETH_RGMII_RX_CTL */ ++ }; ++ }; ++ ++ m4_fmc_pins_a: m4-fmc-0 { ++ pins { ++ pinmux = , /* FMC_NOE */ ++ , /* FMC_NWE */ ++ , /* FMC_A16_FMC_CLE */ ++ , /* FMC_A17_FMC_ALE */ ++ , /* FMC_D0 */ ++ , /* FMC_D1 */ ++ , /* FMC_D2 */ ++ , /* FMC_D3 */ ++ , /* FMC_D4 */ ++ , /* FMC_D5 */ ++ , /* FMC_D6 */ ++ , /* FMC_D7 */ ++ , /* FMC_NE2_FMC_NCE */ ++ ; /* FMC_NWAIT */ ++ }; ++ }; ++ ++ m4_hdp0_pins_a: m4-hdp0-0 { ++ pins { ++ pinmux = ; /* HDP0 */ ++ }; ++ }; ++ ++ m4_hdp6_pins_a: m4-hdp6-0 { ++ pins { ++ pinmux = ; /* HDP6 */ ++ }; ++ }; ++ ++ m4_hdp7_pins_a: m4-hdp7-0 { ++ pins { ++ pinmux = ; /* HDP7 */ ++ }; ++ }; ++ ++ m4_i2c1_pins_a: m4-i2c1-0 { ++ pins { ++ pinmux = , /* I2C1_SCL */ ++ ; /* I2C1_SDA */ ++ }; ++ }; ++ ++ m4_i2c2_pins_a: m4-i2c2-0 { ++ pins { ++ pinmux = , /* I2C2_SCL */ ++ ; /* I2C2_SDA */ ++ }; ++ }; ++ ++ m4_i2c5_pins_a: m4-i2c5-0 { ++ pins { ++ pinmux = , /* I2C5_SCL */ ++ ; /* I2C5_SDA */ ++ }; ++ }; ++ ++ m4_i2s2_pins_a: m4-i2s2-0 { ++ pins { ++ pinmux = , /* I2S2_SDO */ ++ , /* I2S2_WS */ ++ ; /* I2S2_CK */ ++ }; ++ }; ++ ++ m4_ltdc_pins_a: m4-ltdc-a-0 { ++ pins { ++ pinmux = , /* LCD_CLK */ ++ , /* LCD_HSYNC */ ++ , /* LCD_VSYNC */ ++ , /* LCD_DE */ ++ , /* LCD_R0 */ ++ , /* LCD_R1 */ ++ , /* LCD_R2 */ ++ , /* LCD_R3 */ ++ , /* LCD_R4 */ ++ , /* LCD_R5 */ ++ , /* LCD_R6 */ ++ , /* LCD_R7 */ ++ , /* LCD_G0 */ ++ , /* LCD_G1 */ ++ , /* LCD_G2 */ ++ , /* LCD_G3 */ ++ , /* LCD_G4 */ ++ , /* LCD_G5 */ ++ , /* LCD_G6 */ ++ , /* LCD_G7 */ ++ , /* LCD_B0 */ ++ , /* LCD_B1 */ ++ , /* LCD_B2 */ ++ , /* LCD_B3 */ ++ , /* LCD_B4 */ ++ , /* LCD_B5 */ ++ , /* LCD_B6 */ ++ ; /* LCD_B7 */ ++ }; ++ }; ++ ++ m4_ltdc_pins_b: m4-ltdc-b-0 { ++ pins { ++ pinmux = , /* LCD_CLK */ ++ , /* LCD_HSYNC */ ++ , /* LCD_VSYNC */ ++ , /* LCD_DE */ ++ , /* LCD_R0 */ ++ , /* LCD_R1 */ ++ , /* LCD_R2 */ ++ , /* LCD_R3 */ ++ , /* LCD_R4 */ ++ , /* LCD_R5 */ ++ , /* LCD_R6 */ ++ , /* LCD_R7 */ ++ , /* LCD_G0 */ ++ , /* LCD_G1 */ ++ , /* LCD_G2 */ ++ , /* LCD_G3 */ ++ , /* LCD_G4 */ ++ , /* LCD_G5 */ ++ , /* LCD_G6 */ ++ , /* LCD_G7 */ ++ , /* LCD_B0 */ ++ , /* LCD_B1 */ ++ , /* LCD_B2 */ ++ , /* LCD_B3 */ ++ , /* LCD_B4 */ ++ , /* LCD_B5 */ ++ , /* LCD_B6 */ ++ ; /* LCD_B7 */ ++ }; ++ }; ++ ++ m4_m_can1_pins_a: m4-m-can1-0 { ++ pins { ++ pinmux = , /* CAN1_TX */ ++ ; /* CAN1_RX */ ++ }; ++ }; ++ ++ m4_pwm1_pins_a: m4-pwm1-0 { ++ pins { ++ pinmux = , /* TIM1_CH1 */ ++ , /* TIM1_CH2 */ ++ ; /* TIM1_CH4 */ ++ }; ++ }; ++ ++ m4_pwm2_pins_a: m4-pwm2-0 { ++ pins { ++ pinmux = ; /* TIM2_CH4 */ ++ }; ++ }; ++ ++ m4_pwm3_pins_a: m4-pwm3-0 { ++ pins { ++ pinmux = ; /* TIM3_CH2 */ ++ }; ++ }; ++ ++ m4_pwm4_pins_a: m4-pwm4-0 { ++ pins { ++ pinmux = , /* TIM4_CH3 */ ++ ; /* TIM4_CH4 */ ++ }; ++ }; ++ ++ m4_pwm4_pins_b: m4-pwm4-1 { ++ pins { ++ pinmux = ; /* TIM4_CH2 */ ++ }; ++ }; ++ ++ m4_pwm5_pins_a: m4-pwm5-0 { ++ pins { ++ pinmux = ; /* TIM5_CH2 */ ++ }; ++ }; ++ ++ m4_pwm8_pins_a: m4-pwm8-0 { ++ pins { ++ pinmux = ; /* TIM8_CH4 */ ++ }; ++ }; ++ ++ m4_pwm12_pins_a: m4-pwm12-0 { ++ pins { ++ pinmux = ; /* TIM12_CH1 */ ++ }; ++ }; ++ ++ m4_qspi_bk1_pins_a: m4-qspi-bk1-0 { ++ pins { ++ pinmux = , /* QSPI_BK1_IO0 */ ++ , /* QSPI_BK1_IO1 */ ++ , /* QSPI_BK1_IO2 */ ++ , /* QSPI_BK1_IO3 */ ++ ; /* QSPI_BK1_NCS */ ++ }; ++ }; ++ ++ m4_qspi_bk2_pins_a: m4-qspi-bk2-0 { ++ pins { ++ pinmux = , /* QSPI_BK2_IO0 */ ++ , /* QSPI_BK2_IO1 */ ++ , /* QSPI_BK2_IO2 */ ++ , /* QSPI_BK2_IO3 */ ++ ; /* QSPI_BK2_NCS */ ++ }; ++ }; ++ ++ m4_qspi_clk_pins_a: m4-qspi-clk-0 { ++ pins { ++ pinmux = ; /* QSPI_CLK */ ++ }; ++ }; ++ ++ m4_rtc_out2_rmp_pins_a: m4-rtc-out2-rmp-pins-0 { ++ pins { ++ pinmux = ; /* RTC_OUT2_RMP */ ++ }; ++ }; ++ ++ m4_sai2a_pins_a: m4-sai2a-0 { ++ pins { ++ pinmux = , /* SAI2_SCK_A */ ++ , /* SAI2_SD_A */ ++ , /* SAI2_FS_A */ ++ ; /* SAI2_MCLK_A */ ++ }; ++ }; ++ ++ m4_sai2b_pins_a: m4-sai2b-0 { ++ pins { ++ pinmux = , /* SAI2_SCK_B */ ++ , /* SAI2_FS_B */ ++ , /* SAI2_MCLK_B */ ++ ; /* SAI2_SD_B */ ++ }; ++ }; ++ ++ m4_sai2b_pins_b: m4-sai2b-2 { ++ pins { ++ pinmux = ; /* SAI2_SD_B */ ++ }; ++ }; ++ ++ m4_sai4a_pins_a: m4-sai4a-0 { ++ pins { ++ pinmux = ; /* SAI4_SD_A */ ++ }; ++ }; ++ ++ m4_sdmmc1_b4_pins_a: m4-sdmmc1-b4-0 { ++ pins { ++ pinmux = , /* SDMMC1_D0 */ ++ , /* SDMMC1_D1 */ ++ , /* SDMMC1_D2 */ ++ , /* SDMMC1_D3 */ ++ , /* SDMMC1_CMD */ ++ ; /* SDMMC1_CK */ ++ }; ++ }; ++ ++ m4_sdmmc1_dir_pins_a: m4-sdmmc1-dir-0 { ++ pins { ++ pinmux = , /* SDMMC1_D0DIR */ ++ , /* SDMMC1_D123DIR */ ++ , /* SDMMC1_CDIR */ ++ ; /* SDMMC1_CKIN */ ++ }; ++ }; ++ ++ m4_sdmmc2_b4_pins_a: m4-sdmmc2-b4-0 { ++ pins { ++ pinmux = , /* SDMMC2_D0 */ ++ , /* SDMMC2_D1 */ ++ , /* SDMMC2_D2 */ ++ , /* SDMMC2_D3 */ ++ , /* SDMMC2_CMD */ ++ ; /* SDMMC2_CK */ ++ }; ++ }; ++ ++ m4_sdmmc2_b4_pins_b: m4-sdmmc2-b4-1 { ++ pins { ++ pinmux = , /* SDMMC2_D0 */ ++ , /* SDMMC2_D1 */ ++ , /* SDMMC2_D2 */ ++ , /* SDMMC2_D3 */ ++ , /* SDMMC2_CMD */ ++ ; /* SDMMC2_CK */ ++ }; ++ }; ++ ++ m4_sdmmc2_d47_pins_a: m4-sdmmc2-d47-0 { ++ pins { ++ pinmux = , /* SDMMC2_D4 */ ++ , /* SDMMC2_D5 */ ++ , /* SDMMC2_D6 */ ++ ; /* SDMMC2_D7 */ ++ }; ++ }; ++ ++ m4_sdmmc3_b4_pins_a: m4-sdmmc3-b4-0 { ++ pins { ++ pinmux = , /* SDMMC3_D0 */ ++ , /* SDMMC3_D1 */ ++ , /* SDMMC3_D2 */ ++ , /* SDMMC3_D3 */ ++ , /* SDMMC3_CMD */ ++ ; /* SDMMC3_CK */ ++ }; ++ }; ++ ++ m4_spdifrx_pins_a: m4-spdifrx-0 { ++ pins { ++ pinmux = ; /* SPDIF_IN1 */ ++ }; ++ }; ++ ++ m4_spi4_pins_a: m4-spi4-0 { ++ pins { ++ pinmux = , /* SPI4_SCK */ ++ , /* SPI4_MOSI */ ++ ; /* SPI4_MISO */ ++ }; ++ }; ++ ++ m4_spi5_pins_a: m4-spi5-0 { ++ pins { ++ pinmux = , /* SPI5_SCK */ ++ , /* SPI5_MOSI */ ++ ; /* SPI5_MISO */ ++ }; ++ }; ++ ++ m4_stusb1600_pins_a: m4-stusb1600-0 { ++ pins { ++ pinmux = ; ++ }; ++ }; ++ ++ m4_uart4_pins_a: m4-uart4-0 { ++ pins { ++ pinmux = , /* UART4_TX */ ++ ; /* UART4_RX */ ++ }; ++ }; ++ ++ m4_uart7_pins_a: m4-uart7-0 { ++ pins { ++ pinmux = , /* USART7_TX */ ++ ; /* USART7_RX */ ++ }; ++ }; ++ ++ m4_usart2_pins_a: m4-usart2-0 { ++ pins { ++ pinmux = , /* USART2_TX */ ++ , /* USART2_RTS */ ++ , /* USART2_RX */ ++ ; /* USART2_CTS_NSS */ ++ }; ++ }; ++ ++ m4_usart3_pins_a: m4-usart3-0 { ++ pins { ++ pinmux = , /* USART3_TX */ ++ , /* USART3_RTS */ ++ , /* USART3_RX */ ++ ; /* USART3_CTS_NSS */ ++ }; ++ }; ++ ++ m4_usart3_pins_b: m4-usart3-1 { ++ pins { ++ pinmux = , /* USART3_TX */ ++ , /* USART3_RTS */ ++ , /* USART3_RX */ ++ ; /* USART3_CTS_NSS */ ++ }; ++ }; ++ ++ m4_usbotg_hs_pins_a: m4-usbotg_hs-0 { ++ pins { ++ pinmux = ; /* OTG_ID */ ++ }; ++ }; ++ ++ m4_usbotg_fs_dp_dm_pins_a: m4-usbotg-fs-dp-dm-0 { ++ pins { ++ pinmux = , /* OTG_FS_DM */ ++ ; /* OTG_FS_DP */ ++ }; ++ }; ++}; ++ ++&pinctrl_z { ++ m4_i2c4_pins_a: m4-i2c4-0 { ++ pins { ++ pinmux = , /* I2C4_SCL */ ++ ; /* I2C4_SDA */ ++ }; ++ }; ++ ++ m4_spi1_pins_a: m4-spi1-0 { ++ pins { ++ pinmux = , /* SPI1_SCK */ ++ , /* SPI1_MOSI */ ++ ; /* SPI1_MISO */ ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp157-m4-srm.dtsi b/arch/arm/dts/stm32mp157-m4-srm.dtsi +new file mode 100644 +index 0000000..60454ae +--- /dev/null ++++ b/arch/arm/dts/stm32mp157-m4-srm.dtsi +@@ -0,0 +1,442 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Fabien Dessenne for STMicroelectronics. ++ */ ++ ++&m4_rproc { ++ m4_system_resources { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ m4_timers2: timer@40000000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40000000 0x400>; ++ clocks = <&rcc TIM2_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_timers3: timer@40001000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40001000 0x400>; ++ clocks = <&rcc TIM3_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_timers4: timer@40002000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40002000 0x400>; ++ clocks = <&rcc TIM4_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_timers5: timer@40003000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40003000 0x400>; ++ clocks = <&rcc TIM5_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_timers6: timer@40004000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40004000 0x400>; ++ clocks = <&rcc TIM6_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_timers7: timer@40005000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40005000 0x400>; ++ clocks = <&rcc TIM7_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_timers12: timer@40006000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40006000 0x400>; ++ clocks = <&rcc TIM12_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_timers13: timer@40007000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40007000 0x400>; ++ clocks = <&rcc TIM13_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_timers14: timer@40008000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40008000 0x400>; ++ clocks = <&rcc TIM14_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_lptimer1: timer@40009000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40009000 0x400>; ++ clocks = <&rcc LPTIM1_K>; ++ clock-names = "mux"; ++ status = "disabled"; ++ }; ++ m4_spi2: spi@4000b000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4000b000 0x400>; ++ clocks = <&rcc SPI2_K>; ++ status = "disabled"; ++ }; ++ m4_i2s2: audio-controller@4000b000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4000b000 0x400>; ++ status = "disabled"; ++ }; ++ m4_spi3: spi@4000c000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4000c000 0x400>; ++ clocks = <&rcc SPI3_K>; ++ status = "disabled"; ++ }; ++ m4_i2s3: audio-controller@4000c000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4000c000 0x400>; ++ status = "disabled"; ++ }; ++ m4_spdifrx: audio-controller@4000d000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4000d000 0x400>; ++ clocks = <&rcc SPDIF_K>; ++ clock-names = "kclk"; ++ status = "disabled"; ++ }; ++ m4_usart2: serial@4000e000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4000e000 0x400>; ++ interrupt-parent = <&exti>; ++ interrupts = <27 1>; ++ clocks = <&rcc USART2_K>; ++ status = "disabled"; ++ }; ++ m4_usart3: serial@4000f000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4000f000 0x400>; ++ interrupt-parent = <&exti>; ++ interrupts = <28 1>; ++ clocks = <&rcc USART3_K>; ++ status = "disabled"; ++ }; ++ m4_uart4: serial@40010000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40010000 0x400>; ++ interrupt-parent = <&exti>; ++ interrupts = <30 1>; ++ clocks = <&rcc UART4_K>; ++ status = "disabled"; ++ }; ++ m4_uart5: serial@40011000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40011000 0x400>; ++ interrupt-parent = <&exti>; ++ interrupts = <31 1>; ++ clocks = <&rcc UART5_K>; ++ status = "disabled"; ++ }; ++ m4_i2c1: i2c@40012000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40012000 0x400>; ++ interrupt-parent = <&exti>; ++ interrupts = <21 1>; ++ clocks = <&rcc I2C1_K>; ++ status = "disabled"; ++ }; ++ m4_i2c2: i2c@40013000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40013000 0x400>; ++ interrupt-parent = <&exti>; ++ interrupts = <22 1>; ++ clocks = <&rcc I2C2_K>; ++ status = "disabled"; ++ }; ++ m4_i2c3: i2c@40014000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40014000 0x400>; ++ interrupt-parent = <&exti>; ++ interrupts = <23 1>; ++ clocks = <&rcc I2C3_K>; ++ status = "disabled"; ++ }; ++ m4_i2c5: i2c@40015000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40015000 0x400>; ++ interrupt-parent = <&exti>; ++ interrupts = <25 1>; ++ clocks = <&rcc I2C5_K>; ++ status = "disabled"; ++ }; ++ m4_cec: cec@40016000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40016000 0x400>; ++ interrupt-parent = <&exti>; ++ interrupts = <69 1>; ++ clocks = <&rcc CEC_K>, <&scmi0_clk CK_SCMI0_LSE>; ++ clock-names = "cec", "hdmi-cec"; ++ status = "disabled"; ++ }; ++ m4_dac: dac@40017000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40017000 0x400>; ++ clocks = <&rcc DAC12>; ++ clock-names = "pclk"; ++ status = "disabled"; ++ }; ++ m4_uart7: serial@40018000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40018000 0x400>; ++ interrupt-parent = <&exti>; ++ interrupts = <32 1>; ++ clocks = <&rcc UART7_K>; ++ status = "disabled"; ++ }; ++ m4_uart8: serial@40019000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x40019000 0x400>; ++ interrupt-parent = <&exti>; ++ interrupts = <33 1>; ++ clocks = <&rcc UART8_K>; ++ status = "disabled"; ++ }; ++ m4_timers1: timer@44000000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x44000000 0x400>; ++ clocks = <&rcc TIM1_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_timers8: timer@44001000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x44001000 0x400>; ++ clocks = <&rcc TIM8_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_usart6: serial@44003000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x44003000 0x400>; ++ interrupt-parent = <&exti>; ++ interrupts = <29 1>; ++ clocks = <&rcc USART6_K>; ++ status = "disabled"; ++ }; ++ m4_spi1: spi@44004000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x44004000 0x400>; ++ clocks = <&rcc SPI1_K>; ++ status = "disabled"; ++ }; ++ m4_i2s1: audio-controller@44004000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x44004000 0x400>; ++ status = "disabled"; ++ }; ++ m4_spi4: spi@44005000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x44005000 0x400>; ++ clocks = <&rcc SPI4_K>; ++ status = "disabled"; ++ }; ++ m4_timers15: timer@44006000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x44006000 0x400>; ++ clocks = <&rcc TIM15_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_timers16: timer@44007000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x44007000 0x400>; ++ clocks = <&rcc TIM16_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_timers17: timer@44008000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x44008000 0x400>; ++ clocks = <&rcc TIM17_K>; ++ clock-names = "int"; ++ status = "disabled"; ++ }; ++ m4_spi5: spi@44009000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x44009000 0x400>; ++ clocks = <&rcc SPI5_K>; ++ status = "disabled"; ++ }; ++ m4_sai1: sai@4400a000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4400a000 0x4>; ++ clocks = <&rcc SAI1_K>; ++ clock-names = "sai_ck"; ++ status = "disabled"; ++ }; ++ m4_sai2: sai@4400b000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4400b000 0x4>; ++ clocks = <&rcc SAI2_K>; ++ clock-names = "sai_ck"; ++ status = "disabled"; ++ }; ++ m4_sai3: sai@4400c000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4400c000 0x4>; ++ clocks = <&rcc SAI3_K>; ++ clock-names = "sai_ck"; ++ status = "disabled"; ++ }; ++ m4_dfsdm: dfsdm@4400d000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4400d000 0x800>; ++ clocks = <&rcc DFSDM_K>, <&rcc ADFSDM_K>; ++ clock-names = "dfsdm", "audio"; ++ status = "disabled"; ++ }; ++ m4_m_can1: can@4400e000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4400e000 0x400>, <0x44011000 0x2800>; ++ clocks = <&scmi0_clk CK_SCMI0_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>; ++ clock-names = "hclk", "cclk"; ++ status = "disabled"; ++ }; ++ m4_dma1: dma@48000000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x48000000 0x400>; ++ clocks = <&rcc DMA1>; ++ status = "disabled"; ++ }; ++ m4_dma2: dma@48001000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x48001000 0x400>; ++ clocks = <&rcc DMA2>; ++ status = "disabled"; ++ }; ++ m4_dmamux1: dma-router@48002000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x48002000 0x1c>; ++ clocks = <&rcc DMAMUX>; ++ status = "disabled"; ++ }; ++ m4_adc: adc@48003000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x48003000 0x400>; ++ clocks = <&rcc ADC12>, <&rcc ADC12_K>; ++ clock-names = "bus", "adc"; ++ status = "disabled"; ++ }; ++ m4_sdmmc3: sdmmc@48004000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x48004000 0x400>, <0x48005000 0x400>; ++ clocks = <&rcc SDMMC3_K>; ++ status = "disabled"; ++ }; ++ m4_usbotg_hs: usb-otg@49000000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x49000000 0x10000>; ++ clocks = <&rcc USBO_K>; ++ clock-names = "otg"; ++ status = "disabled"; ++ }; ++ m4_hash2: hash@4c002000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4c002000 0x400>; ++ clocks = <&rcc HASH2>; ++ status = "disabled"; ++ }; ++ m4_rng2: rng@4c003000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4c003000 0x400>; ++ clocks = <&rcc RNG2_K>; ++ status = "disabled"; ++ }; ++ m4_crc2: crc@4c004000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4c004000 0x400>; ++ clocks = <&rcc CRC2>; ++ status = "disabled"; ++ }; ++ m4_cryp2: cryp@4c005000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4c005000 0x400>; ++ clocks = <&rcc CRYP2>; ++ status = "disabled"; ++ }; ++ m4_dcmi: dcmi@4c006000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x4c006000 0x400>; ++ clocks = <&rcc DCMI>; ++ clock-names = "mclk"; ++ status = "disabled"; ++ }; ++ m4_lptimer2: timer@50021000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x50021000 0x400>; ++ clocks = <&rcc LPTIM2_K>; ++ clock-names = "mux"; ++ status = "disabled"; ++ }; ++ m4_lptimer3: timer@50022000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x50022000 0x400>; ++ clocks = <&rcc LPTIM3_K>; ++ clock-names = "mux"; ++ status = "disabled"; ++ }; ++ m4_lptimer4: timer@50023000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x50023000 0x400>; ++ clocks = <&rcc LPTIM4_K>; ++ clock-names = "mux"; ++ status = "disabled"; ++ }; ++ m4_lptimer5: timer@50024000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x50024000 0x400>; ++ clocks = <&rcc LPTIM5_K>; ++ clock-names = "mux"; ++ status = "disabled"; ++ }; ++ m4_sai4: sai@50027000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x50027000 0x4>; ++ clocks = <&rcc SAI4_K>; ++ clock-names = "sai_ck"; ++ status = "disabled"; ++ }; ++ m4_qspi: qspi@58003000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; ++ clocks = <&rcc QSPI_K>; ++ status = "disabled"; ++ }; ++ m4_ethernet0: ethernet@5800a000 { ++ compatible = "rproc-srm-dev"; ++ reg = <0x5800a000 0x2000>; ++ clock-names = "stmmaceth", ++ "mac-clk-tx", ++ "mac-clk-rx", ++ "ethstp", ++ "syscfg-clk"; ++ clocks = <&rcc ETHMAC>, ++ <&rcc ETHTX>, ++ <&rcc ETHRX>, ++ <&rcc ETHSTP>, ++ <&rcc SYSCFG>; ++ status = "disabled"; ++ }; ++ }; ++}; ++ +diff --git a/arch/arm/dts/stm32mp157-pinctrl.dtsi b/arch/arm/dts/stm32mp157-pinctrl.dtsi +deleted file mode 100644 +index 0d53396..0000000 +--- a/arch/arm/dts/stm32mp157-pinctrl.dtsi ++++ /dev/null +@@ -1,1036 +0,0 @@ +-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +-/* +- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved +- * Author: Ludovic Barre for STMicroelectronics. +- */ +-#include +- +-/ { +- soc { +- pinctrl: pin-controller@50002000 { +- #address-cells = <1>; +- #size-cells = <1>; +- compatible = "st,stm32mp157-pinctrl"; +- ranges = <0 0x50002000 0xa400>; +- interrupt-parent = <&exti>; +- st,syscfg = <&exti 0x60 0xff>; +- hwlocks = <&hwspinlock 0>; +- 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"; +- status = "disabled"; +- }; +- +- gpiob: gpio@50003000 { +- gpio-controller; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- reg = <0x1000 0x400>; +- clocks = <&rcc GPIOB>; +- st,bank-name = "GPIOB"; +- status = "disabled"; +- }; +- +- gpioc: gpio@50004000 { +- gpio-controller; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- reg = <0x2000 0x400>; +- clocks = <&rcc GPIOC>; +- st,bank-name = "GPIOC"; +- status = "disabled"; +- }; +- +- gpiod: gpio@50005000 { +- gpio-controller; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- reg = <0x3000 0x400>; +- clocks = <&rcc GPIOD>; +- st,bank-name = "GPIOD"; +- status = "disabled"; +- }; +- +- gpioe: gpio@50006000 { +- gpio-controller; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- reg = <0x4000 0x400>; +- clocks = <&rcc GPIOE>; +- st,bank-name = "GPIOE"; +- status = "disabled"; +- }; +- +- gpiof: gpio@50007000 { +- gpio-controller; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- reg = <0x5000 0x400>; +- clocks = <&rcc GPIOF>; +- st,bank-name = "GPIOF"; +- status = "disabled"; +- }; +- +- gpiog: gpio@50008000 { +- gpio-controller; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- reg = <0x6000 0x400>; +- clocks = <&rcc GPIOG>; +- st,bank-name = "GPIOG"; +- status = "disabled"; +- }; +- +- gpioh: gpio@50009000 { +- gpio-controller; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- reg = <0x7000 0x400>; +- clocks = <&rcc GPIOH>; +- st,bank-name = "GPIOH"; +- status = "disabled"; +- }; +- +- gpioi: gpio@5000a000 { +- gpio-controller; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- reg = <0x8000 0x400>; +- clocks = <&rcc GPIOI>; +- st,bank-name = "GPIOI"; +- status = "disabled"; +- }; +- +- gpioj: gpio@5000b000 { +- gpio-controller; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- reg = <0x9000 0x400>; +- clocks = <&rcc GPIOJ>; +- st,bank-name = "GPIOJ"; +- status = "disabled"; +- }; +- +- gpiok: gpio@5000c000 { +- gpio-controller; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- reg = <0xa000 0x400>; +- clocks = <&rcc GPIOK>; +- st,bank-name = "GPIOK"; +- status = "disabled"; +- }; +- +- adc12_usb_pwr_pins_a: adc12-usb-pwr-pins-0 { +- pins { +- pinmux = , /* ADC12 in18 */ +- ; /* ADC12 in19 */ +- }; +- }; +- +- cec_pins_a: cec-0 { +- pins { +- pinmux = ; +- bias-disable; +- drive-open-drain; +- slew-rate = <0>; +- }; +- }; +- +- cec_pins_sleep_a: cec-sleep-0 { +- pins { +- pinmux = ; /* HDMI_CEC */ +- }; +- }; +- +- cec_pins_b: cec-1 { +- pins { +- pinmux = ; +- bias-disable; +- drive-open-drain; +- slew-rate = <0>; +- }; +- }; +- +- cec_pins_sleep_b: cec-sleep-1 { +- pins { +- pinmux = ; /* HDMI_CEC */ +- }; +- }; +- +- dcmi_pins_a: dcmi-0 { +- pins { +- pinmux = ,/* DCMI_HSYNC */ +- ,/* DCMI_VSYNC */ +- ,/* DCMI_PIXCLK */ +- ,/* DCMI_D0 */ +- ,/* DCMI_D1 */ +- ,/* DCMI_D2 */ +- ,/* DCMI_D3 */ +- ,/* DCMI_D4 */ +- ,/* DCMI_D5 */ +- ,/* DCMI_D6 */ +- ,/* DCMI_D7 */ +- ,/* DCMI_D8 */ +- ,/* DCMI_D9 */ +- ,/* DCMI_D10 */ +- ;/* DCMI_D11 */ +- bias-disable; +- }; +- }; +- +- dcmi_sleep_pins_a: dcmi-sleep-0 { +- pins { +- pinmux = ,/* DCMI_HSYNC */ +- ,/* DCMI_VSYNC */ +- ,/* DCMI_PIXCLK */ +- ,/* DCMI_D0 */ +- ,/* DCMI_D1 */ +- ,/* DCMI_D2 */ +- ,/* DCMI_D3 */ +- ,/* DCMI_D4 */ +- ,/* DCMI_D5 */ +- ,/* DCMI_D6 */ +- ,/* DCMI_D7 */ +- ,/* DCMI_D8 */ +- ,/* DCMI_D9 */ +- ,/* DCMI_D10 */ +- ;/* DCMI_D11 */ +- }; +- }; +- +- ethernet0_rgmii_pins_a: rgmii-0 { +- pins1 { +- pinmux = , /* ETH_RGMII_CLK125 */ +- , /* ETH_RGMII_GTX_CLK */ +- , /* ETH_RGMII_TXD0 */ +- , /* ETH_RGMII_TXD1 */ +- , /* ETH_RGMII_TXD2 */ +- , /* ETH_RGMII_TXD3 */ +- , /* ETH_RGMII_TX_CTL */ +- ; /* ETH_MDC */ +- bias-disable; +- drive-push-pull; +- slew-rate = <2>; +- }; +- pins2 { +- pinmux = ; /* ETH_MDIO */ +- bias-disable; +- drive-push-pull; +- slew-rate = <0>; +- }; +- pins3 { +- pinmux = , /* ETH_RGMII_RXD0 */ +- , /* ETH_RGMII_RXD1 */ +- , /* ETH_RGMII_RXD2 */ +- , /* ETH_RGMII_RXD3 */ +- , /* ETH_RGMII_RX_CLK */ +- ; /* ETH_RGMII_RX_CTL */ +- bias-disable; +- }; +- }; +- +- ethernet0_rgmii_pins_sleep_a: rgmii-sleep-0 { +- pins1 { +- pinmux = , /* ETH_RGMII_CLK125 */ +- , /* ETH_RGMII_GTX_CLK */ +- , /* ETH_RGMII_TXD0 */ +- , /* ETH_RGMII_TXD1 */ +- , /* ETH_RGMII_TXD2 */ +- , /* ETH_RGMII_TXD3 */ +- , /* ETH_RGMII_TX_CTL */ +- , /* ETH_MDIO */ +- , /* ETH_MDC */ +- , /* ETH_RGMII_RXD0 */ +- , /* ETH_RGMII_RXD1 */ +- , /* ETH_RGMII_RXD2 */ +- , /* ETH_RGMII_RXD3 */ +- , /* ETH_RGMII_RX_CLK */ +- ; /* ETH_RGMII_RX_CTL */ +- }; +- }; +- +- fmc_pins_a: fmc-0 { +- pins1 { +- pinmux = , /* FMC_NOE */ +- , /* FMC_NWE */ +- , /* FMC_A16_FMC_CLE */ +- , /* FMC_A17_FMC_ALE */ +- , /* FMC_D0 */ +- , /* FMC_D1 */ +- , /* FMC_D2 */ +- , /* FMC_D3 */ +- , /* FMC_D4 */ +- , /* FMC_D5 */ +- , /* FMC_D6 */ +- , /* FMC_D7 */ +- ; /* FMC_NE2_FMC_NCE */ +- bias-disable; +- drive-push-pull; +- slew-rate = <1>; +- }; +- pins2 { +- pinmux = ; /* FMC_NWAIT */ +- bias-pull-up; +- }; +- }; +- +- fmc_sleep_pins_a: fmc-sleep-0 { +- pins { +- pinmux = , /* FMC_NOE */ +- , /* FMC_NWE */ +- , /* FMC_A16_FMC_CLE */ +- , /* FMC_A17_FMC_ALE */ +- , /* FMC_D0 */ +- , /* FMC_D1 */ +- , /* FMC_D2 */ +- , /* FMC_D3 */ +- , /* FMC_D4 */ +- , /* FMC_D5 */ +- , /* FMC_D6 */ +- , /* FMC_D7 */ +- , /* FMC_NWAIT */ +- ; /* FMC_NE2_FMC_NCE */ +- }; +- }; +- +- i2c1_pins_a: i2c1-0 { +- pins { +- pinmux = , /* I2C1_SCL */ +- ; /* I2C1_SDA */ +- bias-disable; +- drive-open-drain; +- slew-rate = <0>; +- }; +- }; +- +- i2c1_pins_sleep_a: i2c1-1 { +- pins { +- pinmux = , /* I2C1_SCL */ +- ; /* I2C1_SDA */ +- }; +- }; +- +- i2c1_pins_b: i2c1-2 { +- pins { +- pinmux = , /* I2C1_SCL */ +- ; /* I2C1_SDA */ +- bias-disable; +- drive-open-drain; +- slew-rate = <0>; +- }; +- }; +- +- i2c1_pins_sleep_b: i2c1-3 { +- pins { +- pinmux = , /* I2C1_SCL */ +- ; /* I2C1_SDA */ +- }; +- }; +- +- i2c2_pins_a: i2c2-0 { +- pins { +- pinmux = , /* I2C2_SCL */ +- ; /* I2C2_SDA */ +- bias-disable; +- drive-open-drain; +- slew-rate = <0>; +- }; +- }; +- +- i2c2_pins_sleep_a: i2c2-1 { +- pins { +- pinmux = , /* I2C2_SCL */ +- ; /* I2C2_SDA */ +- }; +- }; +- +- i2c2_pins_b1: i2c2-2 { +- pins { +- pinmux = ; /* I2C2_SDA */ +- bias-disable; +- drive-open-drain; +- slew-rate = <0>; +- }; +- }; +- +- i2c2_pins_sleep_b1: i2c2-3 { +- pins { +- pinmux = ; /* I2C2_SDA */ +- }; +- }; +- +- i2c5_pins_a: i2c5-0 { +- pins { +- pinmux = , /* I2C5_SCL */ +- ; /* I2C5_SDA */ +- bias-disable; +- drive-open-drain; +- slew-rate = <0>; +- }; +- }; +- +- i2c5_pins_sleep_a: i2c5-1 { +- pins { +- pinmux = , /* I2C5_SCL */ +- ; /* I2C5_SDA */ +- +- }; +- }; +- +- i2s2_pins_a: i2s2-0 { +- pins { +- pinmux = , /* I2S2_SDO */ +- , /* I2S2_WS */ +- ; /* I2S2_CK */ +- slew-rate = <1>; +- drive-push-pull; +- bias-disable; +- }; +- }; +- +- i2s2_pins_sleep_a: i2s2-1 { +- pins { +- pinmux = , /* I2S2_SDO */ +- , /* I2S2_WS */ +- ; /* I2S2_CK */ +- }; +- }; +- +- ltdc_pins_a: ltdc-a-0 { +- pins { +- pinmux = , /* LCD_CLK */ +- , /* LCD_HSYNC */ +- , /* LCD_VSYNC */ +- , /* LCD_DE */ +- , /* LCD_R0 */ +- , /* LCD_R1 */ +- , /* LCD_R2 */ +- , /* LCD_R3 */ +- , /* LCD_R4 */ +- , /* LCD_R5 */ +- , /* LCD_R6 */ +- , /* LCD_R7 */ +- , /* LCD_G0 */ +- , /* LCD_G1 */ +- , /* LCD_G2 */ +- , /* LCD_G3 */ +- , /* LCD_G4 */ +- , /* LCD_G5 */ +- , /* LCD_G6 */ +- , /* LCD_G7 */ +- , /* LCD_B0 */ +- , /* LCD_B1 */ +- , /* LCD_B2 */ +- , /* LCD_B3 */ +- , /* LCD_B4 */ +- , /* LCD_B5 */ +- , /* LCD_B6 */ +- ; /* LCD_B7 */ +- bias-disable; +- drive-push-pull; +- slew-rate = <1>; +- }; +- }; +- +- ltdc_pins_sleep_a: ltdc-a-1 { +- pins { +- pinmux = , /* LCD_CLK */ +- , /* LCD_HSYNC */ +- , /* LCD_VSYNC */ +- , /* LCD_DE */ +- , /* LCD_R0 */ +- , /* LCD_R1 */ +- , /* LCD_R2 */ +- , /* LCD_R3 */ +- , /* LCD_R4 */ +- , /* LCD_R5 */ +- , /* LCD_R6 */ +- , /* LCD_R7 */ +- , /* LCD_G0 */ +- , /* LCD_G1 */ +- , /* LCD_G2 */ +- , /* LCD_G3 */ +- , /* LCD_G4 */ +- , /* LCD_G5 */ +- , /* LCD_G6 */ +- , /* LCD_G7 */ +- , /* LCD_B0 */ +- , /* LCD_B1 */ +- , /* LCD_B2 */ +- , /* LCD_B3 */ +- , /* LCD_B4 */ +- , /* LCD_B5 */ +- , /* LCD_B6 */ +- ; /* LCD_B7 */ +- }; +- }; +- +- ltdc_pins_b: ltdc-b-0 { +- pins { +- pinmux = , /* LCD_CLK */ +- , /* LCD_HSYNC */ +- , /* LCD_VSYNC */ +- , /* LCD_DE */ +- , /* LCD_R0 */ +- , /* LCD_R1 */ +- , /* LCD_R2 */ +- , /* LCD_R3 */ +- , /* LCD_R4 */ +- , /* LCD_R5 */ +- , /* LCD_R6 */ +- , /* LCD_R7 */ +- , /* LCD_G0 */ +- , /* LCD_G1 */ +- , /* LCD_G2 */ +- , /* LCD_G3 */ +- , /* LCD_G4 */ +- , /* LCD_G5 */ +- , /* LCD_G6 */ +- , /* LCD_G7 */ +- , /* LCD_B0 */ +- , /* LCD_B1 */ +- , /* LCD_B2 */ +- , /* LCD_B3 */ +- , /* LCD_B4 */ +- , /* LCD_B5 */ +- , /* LCD_B6 */ +- ; /* LCD_B7 */ +- bias-disable; +- drive-push-pull; +- slew-rate = <1>; +- }; +- }; +- +- ltdc_pins_sleep_b: ltdc-b-1 { +- pins { +- pinmux = , /* LCD_CLK */ +- , /* LCD_HSYNC */ +- , /* LCD_VSYNC */ +- , /* LCD_DE */ +- , /* LCD_R0 */ +- , /* LCD_R1 */ +- , /* LCD_R2 */ +- , /* LCD_R3 */ +- , /* LCD_R4 */ +- , /* LCD_R5 */ +- , /* LCD_R6 */ +- , /* LCD_R7 */ +- , /* LCD_G0 */ +- , /* LCD_G1 */ +- , /* LCD_G2 */ +- , /* LCD_G3 */ +- , /* LCD_G4 */ +- , /* LCD_G5 */ +- , /* LCD_G6 */ +- , /* LCD_G7 */ +- , /* LCD_B0 */ +- , /* LCD_B1 */ +- , /* LCD_B2 */ +- , /* LCD_B3 */ +- , /* LCD_B4 */ +- , /* LCD_B5 */ +- , /* LCD_B6 */ +- ; /* LCD_B7 */ +- }; +- }; +- +- m_can1_pins_a: m-can1-0 { +- pins1 { +- pinmux = ; /* CAN1_TX */ +- slew-rate = <1>; +- drive-push-pull; +- bias-disable; +- }; +- pins2 { +- pinmux = ; /* CAN1_RX */ +- bias-disable; +- }; +- }; +- +- m_can1_sleep_pins_a: m_can1-sleep-0 { +- pins { +- pinmux = , /* CAN1_TX */ +- ; /* CAN1_RX */ +- }; +- }; +- +- pwm2_pins_a: pwm2-0 { +- pins { +- pinmux = ; /* TIM2_CH4 */ +- bias-pull-down; +- drive-push-pull; +- slew-rate = <0>; +- }; +- }; +- +- pwm8_pins_a: pwm8-0 { +- pins { +- pinmux = ; /* TIM8_CH4 */ +- bias-pull-down; +- drive-push-pull; +- slew-rate = <0>; +- }; +- }; +- +- pwm12_pins_a: pwm12-0 { +- pins { +- pinmux = ; /* TIM12_CH1 */ +- bias-pull-down; +- drive-push-pull; +- slew-rate = <0>; +- }; +- }; +- +- qspi_clk_pins_a: qspi-clk-0 { +- pins { +- pinmux = ; /* QSPI_CLK */ +- bias-disable; +- drive-push-pull; +- slew-rate = <3>; +- }; +- }; +- +- qspi_clk_sleep_pins_a: qspi-clk-sleep-0 { +- pins { +- pinmux = ; /* QSPI_CLK */ +- }; +- }; +- +- qspi_bk1_pins_a: qspi-bk1-0 { +- pins1 { +- pinmux = , /* QSPI_BK1_IO0 */ +- , /* QSPI_BK1_IO1 */ +- , /* QSPI_BK1_IO2 */ +- ; /* QSPI_BK1_IO3 */ +- bias-disable; +- drive-push-pull; +- slew-rate = <3>; +- }; +- pins2 { +- pinmux = ; /* QSPI_BK1_NCS */ +- bias-pull-up; +- drive-push-pull; +- slew-rate = <3>; +- }; +- }; +- +- qspi_bk1_sleep_pins_a: qspi-bk1-sleep-0 { +- pins { +- pinmux = , /* QSPI_BK1_IO0 */ +- , /* QSPI_BK1_IO1 */ +- , /* QSPI_BK1_IO2 */ +- , /* QSPI_BK1_IO3 */ +- ; /* QSPI_BK1_NCS */ +- }; +- }; +- +- qspi_bk2_pins_a: qspi-bk2-0 { +- pins1 { +- pinmux = , /* QSPI_BK2_IO0 */ +- , /* QSPI_BK2_IO1 */ +- , /* QSPI_BK2_IO2 */ +- ; /* QSPI_BK2_IO3 */ +- bias-disable; +- drive-push-pull; +- slew-rate = <3>; +- }; +- pins2 { +- pinmux = ; /* QSPI_BK2_NCS */ +- bias-pull-up; +- drive-push-pull; +- slew-rate = <3>; +- }; +- }; +- +- qspi_bk2_sleep_pins_a: qspi-bk2-sleep-0 { +- pins { +- pinmux = , /* QSPI_BK2_IO0 */ +- , /* QSPI_BK2_IO1 */ +- , /* QSPI_BK2_IO2 */ +- , /* QSPI_BK2_IO3 */ +- ; /* QSPI_BK2_NCS */ +- }; +- }; +- +- sai2a_pins_a: sai2a-0 { +- pins { +- pinmux = , /* SAI2_SCK_A */ +- , /* SAI2_SD_A */ +- , /* SAI2_FS_A */ +- ; /* SAI2_MCLK_A */ +- slew-rate = <0>; +- drive-push-pull; +- bias-disable; +- }; +- }; +- +- sai2a_sleep_pins_a: sai2a-1 { +- pins { +- pinmux = , /* SAI2_SCK_A */ +- , /* SAI2_SD_A */ +- , /* SAI2_FS_A */ +- ; /* SAI2_MCLK_A */ +- }; +- }; +- +- sai2b_pins_a: sai2b-0 { +- pins1 { +- pinmux = , /* SAI2_SCK_B */ +- , /* SAI2_FS_B */ +- ; /* SAI2_MCLK_B */ +- slew-rate = <0>; +- drive-push-pull; +- bias-disable; +- }; +- pins2 { +- pinmux = ; /* SAI2_SD_B */ +- bias-disable; +- }; +- }; +- +- sai2b_sleep_pins_a: sai2b-1 { +- pins { +- pinmux = , /* SAI2_SD_B */ +- , /* SAI2_SCK_B */ +- , /* SAI2_FS_B */ +- ; /* SAI2_MCLK_B */ +- }; +- }; +- +- sai2b_pins_b: sai2b-2 { +- pins { +- pinmux = ; /* SAI2_SD_B */ +- bias-disable; +- }; +- }; +- +- sai2b_sleep_pins_b: sai2b-3 { +- pins { +- pinmux = ; /* SAI2_SD_B */ +- }; +- }; +- +- sai4a_pins_a: sai4a-0 { +- pins { +- pinmux = ; /* SAI4_SD_A */ +- slew-rate = <0>; +- drive-push-pull; +- bias-disable; +- }; +- }; +- +- sai4a_sleep_pins_a: sai4a-1 { +- pins { +- pinmux = ; /* SAI4_SD_A */ +- }; +- }; +- +- sdmmc1_b4_pins_a: sdmmc1-b4-0 { +- pins { +- pinmux = , /* SDMMC1_D0 */ +- , /* SDMMC1_D1 */ +- , /* SDMMC1_D2 */ +- , /* SDMMC1_D3 */ +- , /* SDMMC1_CK */ +- ; /* SDMMC1_CMD */ +- slew-rate = <3>; +- drive-push-pull; +- bias-disable; +- }; +- }; +- +- sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 { +- pins1 { +- pinmux = , /* SDMMC1_D0 */ +- , /* SDMMC1_D1 */ +- , /* SDMMC1_D2 */ +- , /* SDMMC1_D3 */ +- ; /* SDMMC1_CK */ +- slew-rate = <3>; +- drive-push-pull; +- bias-disable; +- }; +- pins2{ +- pinmux = ; /* SDMMC1_CMD */ +- slew-rate = <3>; +- 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_dir_pins_a: sdmmc1-dir-0 { +- pins1 { +- pinmux = , /* SDMMC1_D0DIR */ +- , /* SDMMC1_D123DIR */ +- ; /* SDMMC1_CDIR */ +- slew-rate = <3>; +- drive-push-pull; +- bias-pull-up; +- }; +- pins2{ +- pinmux = ; /* SDMMC1_CKIN */ +- bias-pull-up; +- }; +- }; +- +- sdmmc1_dir_sleep_pins_a: sdmmc1-dir-sleep-0 { +- pins { +- pinmux = , /* SDMMC1_D0DIR */ +- , /* SDMMC1_D123DIR */ +- , /* SDMMC1_CDIR */ +- ; /* SDMMC1_CKIN */ +- }; +- }; +- +- sdmmc2_b4_pins_a: sdmmc2-b4-0 { +- pins1 { +- pinmux = , /* SDMMC2_D0 */ +- , /* SDMMC2_D1 */ +- , /* SDMMC2_D2 */ +- , /* SDMMC2_D3 */ +- ; /* SDMMC2_CMD */ +- slew-rate = <1>; +- drive-push-pull; +- bias-pull-up; +- }; +- pins2 { +- pinmux = ; /* SDMMC2_CK */ +- slew-rate = <2>; +- 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_CK */ +- slew-rate = <2>; +- drive-push-pull; +- bias-pull-up; +- }; +- pins3 { +- 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_d47_pins_a: sdmmc2-d47-0 { +- pins { +- pinmux = , /* SDMMC2_D4 */ +- , /* SDMMC2_D5 */ +- , /* SDMMC2_D6 */ +- ; /* SDMMC2_D7 */ +- slew-rate = <1>; +- drive-push-pull; +- bias-pull-up; +- }; +- }; +- +- sdmmc2_d47_sleep_pins_a: sdmmc2-d47-sleep-0 { +- pins { +- pinmux = , /* SDMMC2_D4 */ +- , /* SDMMC2_D5 */ +- , /* SDMMC2_D6 */ +- ; /* SDMMC2_D7 */ +- }; +- }; +- +- spdifrx_pins_a: spdifrx-0 { +- pins { +- pinmux = ; /* SPDIF_IN1 */ +- bias-disable; +- }; +- }; +- +- spdifrx_sleep_pins_a: spdifrx-1 { +- pins { +- pinmux = ; /* SPDIF_IN1 */ +- }; +- }; +- +- spi2_pins_a: spi2-0 { +- pins1 { +- pinmux = , /* SPI2_SCK */ +- , /* SPI2_NSS */ +- ; /* SPI2_MOSI */ +- bias-disable; +- drive-push-pull; +- slew-rate = <3>; +- }; +- pins2 { +- pinmux = ; /* SPI2_MISO */ +- bias-disable; +- }; +- }; +- +- stusb1600_pins_a: stusb1600-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_pins_b: uart4-1 { +- 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 = ; /* UART4_TX */ +- bias-disable; +- drive-push-pull; +- slew-rate = <0>; +- }; +- pins2 { +- pinmux = , /* UART4_RX */ +- , /* UART4_CTS */ +- ; /* UART4_RTS */ +- bias-disable; +- }; +- }; +- }; +- +- pinctrl_z: pin-controller-z@54004000 { +- #address-cells = <1>; +- #size-cells = <1>; +- compatible = "st,stm32mp157-z-pinctrl"; +- ranges = <0 0x54004000 0x400>; +- pins-are-numbered; +- interrupt-parent = <&exti>; +- st,syscfg = <&exti 0x60 0xff>; +- hwlocks = <&hwspinlock 0>; +- +- gpioz: gpio@54004000 { +- gpio-controller; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- reg = <0 0x400>; +- clocks = <&rcc GPIOZ>; +- st,bank-name = "GPIOZ"; +- st,bank-ioport = <11>; +- status = "disabled"; +- }; +- +- i2c2_pins_b2: i2c2-0 { +- pins { +- pinmux = ; /* I2C2_SCL */ +- bias-disable; +- drive-open-drain; +- slew-rate = <0>; +- }; +- }; +- +- i2c2_pins_sleep_b2: i2c2-1 { +- pins { +- pinmux = ; /* I2C2_SCL */ +- }; +- }; +- +- i2c4_pins_a: i2c4-0 { +- pins { +- pinmux = , /* I2C4_SCL */ +- ; /* I2C4_SDA */ +- bias-disable; +- drive-open-drain; +- slew-rate = <0>; +- }; +- }; +- +- i2c4_pins_sleep_a: i2c4-1 { +- pins { +- pinmux = , /* I2C4_SCL */ +- ; /* I2C4_SDA */ +- }; +- }; +- +- spi1_pins_a: spi1-0 { +- pins1 { +- pinmux = , /* SPI1_SCK */ +- ; /* SPI1_MOSI */ +- bias-disable; +- drive-push-pull; +- slew-rate = <1>; +- }; +- +- pins2 { +- pinmux = ; /* SPI1_MISO */ +- bias-disable; +- }; +- }; +- }; +- }; +-}; +diff --git a/arch/arm/dts/stm32mp157-u-boot.dtsi b/arch/arm/dts/stm32mp157-u-boot.dtsi +deleted file mode 100644 +index 0d1d387..0000000 +--- a/arch/arm/dts/stm32mp157-u-boot.dtsi ++++ /dev/null +@@ -1,153 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +-/* +- * Copyright : STMicroelectronics 2018 +- */ +- +-/ { +- aliases { +- gpio0 = &gpioa; +- gpio1 = &gpiob; +- gpio2 = &gpioc; +- gpio3 = &gpiod; +- gpio4 = &gpioe; +- gpio5 = &gpiof; +- gpio6 = &gpiog; +- gpio7 = &gpioh; +- gpio8 = &gpioi; +- gpio9 = &gpioj; +- gpio10 = &gpiok; +- gpio25 = &gpioz; +- pinctrl0 = &pinctrl; +- pinctrl1 = &pinctrl_z; +- }; +- +- clocks { +- u-boot,dm-pre-reloc; +- }; +- +- /* need PSCI for sysreset during board_f */ +- psci { +- u-boot,dm-pre-proper; +- }; +- +- reboot { +- u-boot,dm-pre-reloc; +- }; +- +- soc { +- u-boot,dm-pre-reloc; +- }; +-}; +- +-&bsec { +- u-boot,dm-pre-proper; +-}; +- +-&clk_csi { +- u-boot,dm-pre-reloc; +-}; +- +-&clk_hsi { +- u-boot,dm-pre-reloc; +-}; +- +-&clk_hse { +- u-boot,dm-pre-reloc; +-}; +- +-&clk_lsi { +- u-boot,dm-pre-reloc; +-}; +- +-&clk_lse { +- 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; +-}; +- +-&gpioj { +- u-boot,dm-pre-reloc; +-}; +- +-&gpiok { +- u-boot,dm-pre-reloc; +-}; +- +-&gpioz { +- 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; +-}; +- +-&pinctrl_z { +- u-boot,dm-pre-reloc; +-}; +- +-&pwr { +- u-boot,dm-pre-reloc; +-}; +- +-&rcc { +- u-boot,dm-pre-reloc; +-}; +- +-&sdmmc1 { +- compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; +-}; +- +-&sdmmc2 { +- compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; +-}; +- +-&sdmmc3 { +- compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; +-}; +- +-&usbotg_hs { +- compatible = "st,stm32mp1-hsotg", "snps,dwc2"; +-}; +diff --git a/arch/arm/dts/stm32mp157.dtsi b/arch/arm/dts/stm32mp157.dtsi +new file mode 100644 +index 0000000..ce1d83a +--- /dev/null ++++ b/arch/arm/dts/stm32mp157.dtsi +@@ -0,0 +1,32 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++#include "stm32mp153.dtsi" ++ ++/ { ++ soc { ++ gpu: gpu@59000000 { ++ compatible = "vivante,gc"; ++ reg = <0x59000000 0x800>; ++ interrupts = ; ++ clocks = <&rcc GPU>, <&rcc GPU_K>; ++ clock-names = "bus" ,"core"; ++ resets = <&rcc GPU_R>; ++ status = "disabled"; ++ }; ++ ++ dsi: dsi@5a000000 { ++ compatible = "st,stm32-dsi"; ++ reg = <0x5a000000 0x800>; ++ phy-dsi-supply = <®18>; ++ clocks = <&rcc DSI_K>, <&scmi0_clk CK_SCMI0_HSE>, <&rcc DSI_PX>; ++ clock-names = "pclk", "ref", "px_clk"; ++ resets = <&rcc DSI_R>; ++ reset-names = "apb"; ++ status = "disabled"; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp157a-avenger96-u-boot.dtsi b/arch/arm/dts/stm32mp157a-avenger96-u-boot.dtsi +index 1104a70..e885b6d 100644 +--- a/arch/arm/dts/stm32mp157a-avenger96-u-boot.dtsi ++++ b/arch/arm/dts/stm32mp157a-avenger96-u-boot.dtsi +@@ -7,7 +7,7 @@ + */ + + #include +-#include "stm32mp157-u-boot.dtsi" ++#include "stm32mp15-u-boot.dtsi" + #include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" + + / { +@@ -20,6 +20,7 @@ + config { + u-boot,boot-led = "led1"; + u-boot,error-led = "led4"; ++ u-boot,mmc-env-partition = "ssbl"; + }; + }; + +@@ -91,7 +92,7 @@ + CLK_UART6_HSI + CLK_UART78_HSI + CLK_SPDIF_PLL4P +- CLK_FDCAN_PLL4Q ++ CLK_FDCAN_PLL4R + CLK_SAI1_PLL3Q + CLK_SAI2_PLL3Q + CLK_SAI3_PLL3Q +@@ -103,15 +104,10 @@ + CLK_LPTIM45_LSE + >; + +- /* VCO = 1300.0 MHz => P = 650 (CPU) */ +- pll1: st,pll@0 { +- cfg = < 2 80 0 0 0 PQR(1,0,0) >; +- frac = < 0x800 >; +- u-boot,dm-pre-reloc; +- }; +- + /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ + pll2: st,pll@1 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <1>; + cfg = < 2 65 1 0 0 PQR(1,1,1) >; + frac = < 0x1400 >; + u-boot,dm-pre-reloc; +@@ -119,6 +115,8 @@ + + /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ + pll3: st,pll@2 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <2>; + cfg = < 1 33 1 16 36 PQR(1,1,1) >; + frac = < 0x1a04 >; + u-boot,dm-pre-reloc; +@@ -126,6 +124,8 @@ + + /* VCO = 480.0 MHz => P = 120, Q = 40, R = 96 */ + pll4: st,pll@3 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <3>; + cfg = < 1 39 3 11 4 PQR(1,1,1) >; + u-boot,dm-pre-reloc; + }; +@@ -137,14 +137,20 @@ + + &sdmmc1_b4_pins_a { + u-boot,dm-spl; +- pins { ++ pins1 { ++ u-boot,dm-spl; ++ }; ++ pins2 { + u-boot,dm-spl; + }; + }; + + &sdmmc1_dir_pins_a { + u-boot,dm-spl; +- pins { ++ pins1 { ++ u-boot,dm-spl; ++ }; ++ pins2 { + u-boot,dm-spl; + }; + }; +@@ -188,7 +194,3 @@ + u-boot,force-b-session-valid; + hnp-srp-disable; + }; +- +-&v3v3 { +- regulator-always-on; +-}; +diff --git a/arch/arm/dts/stm32mp157a-avenger96.dts b/arch/arm/dts/stm32mp157a-avenger96.dts +index 5b15a4a..941963c 100644 +--- a/arch/arm/dts/stm32mp157a-avenger96.dts ++++ b/arch/arm/dts/stm32mp157a-avenger96.dts +@@ -6,9 +6,10 @@ + + /dts-v1/; + +-#include "stm32mp157c.dtsi" +-#include "stm32mp157xac-pinctrl.dtsi" +-#include ++#include "stm32mp157.dtsi" ++#include "stm32mp15xa.dtsi" ++#include "stm32mp15-pinctrl.dtsi" ++#include "stm32mp15xxac-pinctrl.dtsi" + #include + + / { +@@ -252,14 +253,13 @@ + regulator-name = "vbus_otg"; + interrupts = ; + interrupt-parent = <&pmic>; +- regulator-active-discharge; + }; + + vbus_sw: pwr_sw2 { + regulator-name = "vbus_sw"; + interrupts = ; + interrupt-parent = <&pmic>; +- regulator-active-discharge; ++ regulator-active-discharge = <1>; + }; + }; + +@@ -282,11 +282,9 @@ + status = "okay"; + }; + +-&pwr { +- pwr-regulators { +- vdd-supply = <&vdd>; +- vdd_3v3_usbfs-supply = <&vdd_usb>; +- }; ++&pwr_regulators { ++ vdd-supply = <&vdd>; ++ vdd_3v3_usbfs-supply = <&vdd_usb>; + }; + + &rng1 { +@@ -302,7 +300,7 @@ + pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; + pinctrl-1 = <&sdmmc1_b4_od_pins_a>; + pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; +- broken-cd; ++ cd-gpios = <&gpioi 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + st,sig-dir; + st,neg-edge; + st,use-ckin; +diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi +index dcaab3e..62d7062 100644 +--- a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi ++++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi +@@ -4,7 +4,7 @@ + */ + + #include +-#include "stm32mp157-u-boot.dtsi" ++#include "stm32mp15-u-boot.dtsi" + #include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi" + + / { +@@ -16,6 +16,7 @@ + config { + u-boot,boot-led = "heartbeat"; + u-boot,error-led = "error"; ++ u-boot,mmc-env-partition = "ssbl"; + st,adc_usb_pd = <&adc1 18>, <&adc1 19>; + st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; + st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; +@@ -27,34 +28,14 @@ + default-state = "off"; + status = "okay"; + }; +- +- blue { +- default-state = "on"; +- }; + }; + }; + + &adc { +- pinctrl-names = "default"; +- pinctrl-0 = <&adc12_usb_pwr_pins_a>; +- vdd-supply = <&vdd>; +- vdda-supply = <&vdd>; +- vref-supply = <&vrefbuf>; + status = "okay"; +- adc1: adc@0 { +- /* +- * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in18 & in19. +- * Use at least 5 * RC time, e.g. 5 * (Rp + Rd) * C: +- * 5 * (56 + 47kOhms) * 5pF => 2.5us. +- * Use arbitrary margin here (e.g. 5µs). +- */ +- st,min-sample-time-nsecs = <5000>; +- /* ANA0, ANA1, USB Type-C CC1 & CC2 */ +- st,adc-channels = <0 1 18 19>; +- status = "okay"; +- }; + }; + ++#ifndef CONFIG_STM32MP1_TRUSTED + &clk_hse { + st,digbypass; + }; +@@ -70,6 +51,10 @@ + }; + }; + ++&i2s2 { ++ clocks = <&rcc SPI2>, <&rcc SPI2_K>, <&rcc PLL3_Q>, <&rcc PLL3_R>; ++}; ++ + &pmic { + u-boot,dm-pre-reloc; + }; +@@ -127,7 +112,7 @@ + CLK_UART6_HSI + CLK_UART78_HSI + CLK_SPDIF_PLL4P +- CLK_FDCAN_PLL4Q ++ CLK_FDCAN_PLL4R + CLK_SAI1_PLL3Q + CLK_SAI2_PLL3Q + CLK_SAI3_PLL3Q +@@ -139,15 +124,10 @@ + CLK_LPTIM45_LSE + >; + +- /* VCO = 1300.0 MHz => P = 650 (CPU) */ +- pll1: st,pll@0 { +- cfg = < 2 80 0 0 0 PQR(1,0,0) >; +- frac = < 0x800 >; +- u-boot,dm-pre-reloc; +- }; +- + /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ + pll2: st,pll@1 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <1>; + cfg = < 2 65 1 0 0 PQR(1,1,1) >; + frac = < 0x1400 >; + u-boot,dm-pre-reloc; +@@ -155,6 +135,8 @@ + + /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ + pll3: st,pll@2 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <2>; + cfg = < 1 33 1 16 36 PQR(1,1,1) >; + frac = < 0x1a04 >; + u-boot,dm-pre-reloc; +@@ -162,21 +144,31 @@ + + /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ + pll4: st,pll@3 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <3>; + cfg = < 3 98 5 7 7 PQR(1,1,1) >; + u-boot,dm-pre-reloc; + }; + }; + ++&sai2 { ++ clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>; ++}; ++ + &sdmmc1 { + u-boot,dm-spl; + }; + + &sdmmc1_b4_pins_a { + u-boot,dm-spl; +- pins { ++ pins1 { ++ u-boot,dm-spl; ++ }; ++ pins2 { + u-boot,dm-spl; + }; + }; ++#endif + + &uart4 { + u-boot,dm-pre-reloc; +@@ -197,4 +189,6 @@ + &usbotg_hs { + u-boot,force-b-session-valid; + hnp-srp-disable; ++ /* TEMP: force peripheral for USB OTG */ ++ dr_mode = "peripheral"; + }; +diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts +index 4652253..baff3f6 100644 +--- a/arch/arm/dts/stm32mp157a-dk1.dts ++++ b/arch/arm/dts/stm32mp157a-dk1.dts +@@ -6,11 +6,11 @@ + + /dts-v1/; + +-#include "stm32mp157c.dtsi" +-#include "stm32mp157xac-pinctrl.dtsi" +-#include +-#include +- ++#include "stm32mp157.dtsi" ++#include "stm32mp15xa.dtsi" ++#include "stm32mp15-pinctrl.dtsi" ++#include "stm32mp15xxac-pinctrl.dtsi" ++#include "stm32mp15xx-dkx.dtsi" + / { + model = "STMicroelectronics STM32MP157A-DK1 Discovery Board"; + compatible = "st,stm32mp157a-dk1", "st,stm32mp157"; +@@ -18,491 +18,27 @@ + aliases { + ethernet0 = ðernet0; + serial0 = &uart4; ++ serial1 = &usart3; ++ serial2 = &uart7; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + +- memory@c0000000 { +- reg = <0xc0000000 0x20000000>; +- }; +- + reserved-memory { +- #address-cells = <1>; +- #size-cells = <1>; +- ranges; +- +- mcuram2: mcuram2@10000000 { +- compatible = "shared-dma-pool"; +- reg = <0x10000000 0x40000>; +- no-map; +- }; +- +- vdev0vring0: vdev0vring0@10040000 { +- compatible = "shared-dma-pool"; +- reg = <0x10040000 0x1000>; +- no-map; +- }; +- +- vdev0vring1: vdev0vring1@10041000 { +- compatible = "shared-dma-pool"; +- reg = <0x10041000 0x1000>; +- no-map; +- }; +- +- vdev0buffer: vdev0buffer@10042000 { +- compatible = "shared-dma-pool"; +- reg = <0x10042000 0x4000>; +- no-map; +- }; +- +- mcuram: mcuram@30000000 { +- compatible = "shared-dma-pool"; +- reg = <0x30000000 0x40000>; +- no-map; +- }; +- +- retram: retram@38000000 { +- compatible = "shared-dma-pool"; +- reg = <0x38000000 0x10000>; ++ gpu_reserved: gpu@da000000 { ++ reg = <0xda000000 0x4000000>; + no-map; + }; + +- gpu_reserved: gpu@d4000000 { +- reg = <0xd4000000 0x4000000>; ++ optee_memory: optee@0xde000000 { ++ reg = <0xde000000 0x02000000>; + no-map; + }; + }; +- +- led { +- compatible = "gpio-leds"; +- blue { +- label = "heartbeat"; +- gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>; +- linux,default-trigger = "heartbeat"; +- default-state = "off"; +- }; +- }; +- +- sound { +- compatible = "audio-graph-card"; +- label = "STM32MP1-DK"; +- routing = +- "Playback" , "MCLK", +- "Capture" , "MCLK", +- "MICL" , "Mic Bias"; +- dais = <&sai2a_port &sai2b_port>; +- status = "okay"; +- }; +-}; +- +-&cec { +- pinctrl-names = "default", "sleep"; +- pinctrl-0 = <&cec_pins_b>; +- pinctrl-1 = <&cec_pins_sleep_b>; +- status = "okay"; +-}; +- +-ðernet0 { +- status = "okay"; +- pinctrl-0 = <ðernet0_rgmii_pins_a>; +- pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; +- pinctrl-names = "default", "sleep"; +- phy-mode = "rgmii-id"; +- max-speed = <1000>; +- phy-handle = <&phy0>; +- +- mdio0 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "snps,dwmac-mdio"; +- phy0: ethernet-phy@0 { +- reg = <0>; +- }; +- }; +-}; +- +-&gpu { +- contiguous-area = <&gpu_reserved>; +- status = "okay"; +-}; +- +-&i2c1 { +- pinctrl-names = "default", "sleep"; +- pinctrl-0 = <&i2c1_pins_a>; +- pinctrl-1 = <&i2c1_pins_sleep_a>; +- i2c-scl-rising-time-ns = <100>; +- i2c-scl-falling-time-ns = <7>; +- status = "okay"; +- /delete-property/dmas; +- /delete-property/dma-names; +- +- hdmi-transmitter@39 { +- compatible = "sil,sii9022"; +- reg = <0x39>; +- iovcc-supply = <&v3v3_hdmi>; +- cvcc12-supply = <&v1v2_hdmi>; +- reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>; +- interrupts = <1 IRQ_TYPE_EDGE_FALLING>; +- interrupt-parent = <&gpiog>; +- pinctrl-names = "default", "sleep"; +- pinctrl-0 = <<dc_pins_a>; +- pinctrl-1 = <<dc_pins_sleep_a>; +- status = "okay"; +- +- ports { +- #address-cells = <1>; +- #size-cells = <0>; +- +- port@0 { +- reg = <0>; +- sii9022_in: endpoint { +- remote-endpoint = <<dc_ep0_out>; +- }; +- }; +- }; +- }; +- +- cs42l51: cs42l51@4a { +- compatible = "cirrus,cs42l51"; +- reg = <0x4a>; +- #sound-dai-cells = <0>; +- VL-supply = <&v3v3>; +- VD-supply = <&v1v8_audio>; +- VA-supply = <&v1v8_audio>; +- VAHP-supply = <&v1v8_audio>; +- reset-gpios = <&gpiog 9 GPIO_ACTIVE_LOW>; +- clocks = <&sai2a>; +- clock-names = "MCLK"; +- status = "okay"; +- +- cs42l51_port: port { +- #address-cells = <1>; +- #size-cells = <0>; +- +- cs42l51_tx_endpoint: endpoint@0 { +- reg = <0>; +- remote-endpoint = <&sai2a_endpoint>; +- frame-master; +- bitclock-master; +- }; +- +- cs42l51_rx_endpoint: endpoint@1 { +- reg = <1>; +- remote-endpoint = <&sai2b_endpoint>; +- frame-master; +- bitclock-master; +- }; +- }; +- }; +-}; +- +-&i2c4 { +- pinctrl-names = "default"; +- pinctrl-0 = <&i2c4_pins_a>; +- i2c-scl-rising-time-ns = <185>; +- i2c-scl-falling-time-ns = <20>; +- status = "okay"; +- /* spare dmas for other usage */ +- /delete-property/dmas; +- /delete-property/dma-names; +- +- typec: stusb1600@28 { +- compatible = "st,stusb1600"; +- reg = <0x28>; +- interrupts = <11 IRQ_TYPE_EDGE_FALLING>; +- interrupt-parent = <&gpioi>; +- pinctrl-names = "default"; +- pinctrl-0 = <&stusb1600_pins_a>; +- +- status = "okay"; +- +- typec_con: connector { +- compatible = "usb-c-connector"; +- label = "USB-C"; +- power-role = "sink"; +- power-opmode = "default"; +- }; +- }; +- +- pmic: stpmic@33 { +- compatible = "st,stpmic1"; +- reg = <0x33>; +- interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>; +- interrupt-controller; +- #interrupt-cells = <2>; +- status = "okay"; +- +- regulators { +- compatible = "st,stpmic1-regulators"; +- ldo1-supply = <&v3v3>; +- ldo3-supply = <&vdd_ddr>; +- ldo6-supply = <&v3v3>; +- pwr_sw1-supply = <&bst_out>; +- pwr_sw2-supply = <&bst_out>; +- +- vddcore: buck1 { +- regulator-name = "vddcore"; +- regulator-min-microvolt = <800000>; +- regulator-max-microvolt = <1350000>; +- regulator-always-on; +- regulator-initial-mode = <0>; +- regulator-over-current-protection; +- }; +- +- vdd_ddr: buck2 { +- regulator-name = "vdd_ddr"; +- regulator-min-microvolt = <1350000>; +- regulator-max-microvolt = <1350000>; +- regulator-always-on; +- regulator-initial-mode = <0>; +- regulator-over-current-protection; +- }; +- +- vdd: buck3 { +- regulator-name = "vdd"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- regulator-always-on; +- st,mask-reset; +- regulator-initial-mode = <0>; +- regulator-over-current-protection; +- }; +- +- v3v3: buck4 { +- regulator-name = "v3v3"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- regulator-always-on; +- regulator-over-current-protection; +- regulator-initial-mode = <0>; +- }; +- +- v1v8_audio: ldo1 { +- regulator-name = "v1v8_audio"; +- regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <1800000>; +- regulator-always-on; +- interrupts = ; +- }; +- +- v3v3_hdmi: ldo2 { +- regulator-name = "v3v3_hdmi"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- regulator-always-on; +- interrupts = ; +- }; +- +- vtt_ddr: ldo3 { +- regulator-name = "vtt_ddr"; +- regulator-min-microvolt = <500000>; +- regulator-max-microvolt = <750000>; +- regulator-always-on; +- regulator-over-current-protection; +- }; +- +- vdd_usb: ldo4 { +- regulator-name = "vdd_usb"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- interrupts = ; +- }; +- +- vdda: ldo5 { +- regulator-name = "vdda"; +- regulator-min-microvolt = <2900000>; +- regulator-max-microvolt = <2900000>; +- interrupts = ; +- regulator-boot-on; +- }; +- +- v1v2_hdmi: ldo6 { +- regulator-name = "v1v2_hdmi"; +- regulator-min-microvolt = <1200000>; +- regulator-max-microvolt = <1200000>; +- regulator-always-on; +- interrupts = ; +- }; +- +- vref_ddr: vref_ddr { +- regulator-name = "vref_ddr"; +- regulator-always-on; +- regulator-over-current-protection; +- }; +- +- bst_out: boost { +- regulator-name = "bst_out"; +- interrupts = ; +- }; +- +- vbus_otg: pwr_sw1 { +- regulator-name = "vbus_otg"; +- interrupts = ; +- }; +- +- vbus_sw: pwr_sw2 { +- regulator-name = "vbus_sw"; +- interrupts = ; +- regulator-active-discharge; +- }; +- }; +- +- onkey { +- compatible = "st,stpmic1-onkey"; +- interrupts = , ; +- interrupt-names = "onkey-falling", "onkey-rising"; +- power-off-time-sec = <10>; +- status = "okay"; +- }; +- +- watchdog { +- compatible = "st,stpmic1-wdt"; +- status = "disabled"; +- }; +- }; +-}; +- +-&ipcc { +- status = "okay"; +-}; +- +-&iwdg2 { +- timeout-sec = <32>; +- status = "okay"; +-}; +- +-<dc { +- status = "okay"; +- +- port { +- #address-cells = <1>; +- #size-cells = <0>; +- +- ltdc_ep0_out: endpoint@0 { +- reg = <0>; +- remote-endpoint = <&sii9022_in>; +- }; +- }; +-}; +- +-&m4_rproc { +- memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, +- <&vdev0vring1>, <&vdev0buffer>; +- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; +- mbox-names = "vq0", "vq1", "shutdown"; +- interrupt-parent = <&exti>; +- interrupts = <68 1>; +- status = "okay"; +-}; +- +-&pwr { +- pwr-regulators { +- vdd-supply = <&vdd>; +- vdd_3v3_usbfs-supply = <&vdd_usb>; +- }; +-}; +- +-&rng1 { +- status = "okay"; +-}; +- +-&rtc { +- status = "okay"; +-}; +- +-&sai2 { +- clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>; +- clock-names = "pclk", "x8k", "x11k"; +- pinctrl-names = "default", "sleep"; +- pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>; +- pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>; +- status = "okay"; +- +- sai2a: audio-controller@4400b004 { +- #clock-cells = <0>; +- dma-names = "tx"; +- clocks = <&rcc SAI2_K>; +- clock-names = "sai_ck"; +- status = "okay"; +- +- sai2a_port: port { +- sai2a_endpoint: endpoint { +- remote-endpoint = <&cs42l51_tx_endpoint>; +- format = "i2s"; +- mclk-fs = <256>; +- dai-tdm-slot-num = <2>; +- dai-tdm-slot-width = <32>; +- }; +- }; +- }; +- +- sai2b: audio-controller@4400b024 { +- dma-names = "rx"; +- st,sync = <&sai2a 2>; +- clocks = <&rcc SAI2_K>, <&sai2a>; +- clock-names = "sai_ck", "MCLK"; +- status = "okay"; +- +- sai2b_port: port { +- sai2b_endpoint: endpoint { +- remote-endpoint = <&cs42l51_rx_endpoint>; +- format = "i2s"; +- mclk-fs = <256>; +- dai-tdm-slot-num = <2>; +- dai-tdm-slot-width = <32>; +- }; +- }; +- }; +-}; +- +-&sdmmc1 { +- pinctrl-names = "default", "opendrain", "sleep"; +- pinctrl-0 = <&sdmmc1_b4_pins_a>; +- pinctrl-1 = <&sdmmc1_b4_od_pins_a>; +- pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; +- broken-cd; +- st,neg-edge; +- bus-width = <4>; +- vmmc-supply = <&v3v3>; +- status = "okay"; +-}; +- +-&uart4 { +- pinctrl-names = "default"; +- pinctrl-0 = <&uart4_pins_a>; +- status = "okay"; +-}; +- +-&usbh_ehci { +- phys = <&usbphyc_port0>; +- phy-names = "usb"; +- status = "okay"; +-}; +- +-&usbotg_hs { +- dr_mode = "peripheral"; +- phys = <&usbphyc_port1 0>; +- phy-names = "usb2-phy"; +- status = "okay"; +-}; +- +-&usbphyc { +- status = "okay"; +-}; +- +-&usbphyc_port0 { +- phy-supply = <&vdd_usb>; +-}; +- +-&usbphyc_port1 { +- phy-supply = <&vdd_usb>; + }; + +-&vrefbuf { +- regulator-min-microvolt = <2500000>; +- regulator-max-microvolt = <2500000>; +- vdda-supply = <&vdd>; ++&optee { + status = "okay"; + }; +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 0000000..0f163bc +--- /dev/null ++++ b/arch/arm/dts/stm32mp157a-ed1-u-boot.dtsi +@@ -0,0 +1,207 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright : STMicroelectronics 2018 ++ */ ++ ++#include ++#include "stm32mp15-u-boot.dtsi" ++#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" ++ ++/ { ++ 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>; ++ }; ++ ++ led { ++ red { ++ label = "error"; ++ gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ status = "okay"; ++ }; ++ }; ++}; ++ ++#ifndef CONFIG_STM32MP1_TRUSTED ++&clk_hse { ++ st,digbypass; ++}; ++ ++&i2c4 { ++ u-boot,dm-pre-reloc; ++}; ++ ++&i2c4_pins_a { ++ u-boot,dm-pre-reloc; ++ pins { ++ u-boot,dm-pre-reloc; ++ }; ++}; ++ ++&pmic { ++ u-boot,dm-pre-reloc; ++}; ++ ++&rcc { ++ st,clksrc = < ++ CLK_MPU_PLL1P ++ CLK_AXI_PLL2P ++ CLK_MCU_PLL3P ++ CLK_PLL12_HSE ++ CLK_PLL3_HSE ++ CLK_PLL4_HSE ++ CLK_RTC_LSE ++ CLK_MCO1_DISABLED ++ CLK_MCO2_DISABLED ++ >; ++ ++ st,clkdiv = < ++ 1 /*MPU*/ ++ 0 /*AXI*/ ++ 0 /*MCU*/ ++ 1 /*APB1*/ ++ 1 /*APB2*/ ++ 1 /*APB3*/ ++ 1 /*APB4*/ ++ 2 /*APB5*/ ++ 23 /*RTC*/ ++ 0 /*MCO1*/ ++ 0 /*MCO2*/ ++ >; ++ ++ st,pkcs = < ++ CLK_CKPER_HSE ++ CLK_FMC_ACLK ++ CLK_QSPI_ACLK ++ CLK_ETH_DISABLED ++ CLK_SDMMC12_PLL4P ++ CLK_DSI_DSIPLL ++ CLK_STGEN_HSE ++ CLK_USBPHY_HSE ++ CLK_SPI2S1_PLL3Q ++ CLK_SPI2S23_PLL3Q ++ CLK_SPI45_HSI ++ CLK_SPI6_HSI ++ CLK_I2C46_HSI ++ CLK_SDMMC3_PLL4P ++ CLK_USBO_USBPHY ++ CLK_ADC_CKPER ++ CLK_CEC_LSE ++ CLK_I2C12_HSI ++ CLK_I2C35_HSI ++ CLK_UART1_HSI ++ CLK_UART24_HSI ++ CLK_UART35_HSI ++ CLK_UART6_HSI ++ CLK_UART78_HSI ++ CLK_SPDIF_PLL4P ++ CLK_FDCAN_PLL4R ++ CLK_SAI1_PLL3Q ++ CLK_SAI2_PLL3Q ++ CLK_SAI3_PLL3Q ++ CLK_SAI4_PLL3Q ++ CLK_RNG1_LSI ++ CLK_RNG2_LSI ++ CLK_LPTIM1_PCLK1 ++ CLK_LPTIM23_PCLK3 ++ CLK_LPTIM45_LSE ++ >; ++ ++ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ ++ pll2: st,pll@1 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <1>; ++ cfg = < 2 65 1 0 0 PQR(1,1,1) >; ++ frac = < 0x1400 >; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ ++ pll3: st,pll@2 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <2>; ++ cfg = < 1 33 1 16 36 PQR(1,1,1) >; ++ frac = < 0x1a04 >; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ ++ pll4: st,pll@3 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <3>; ++ cfg = < 3 98 5 7 7 PQR(1,1,1) >; ++ u-boot,dm-pre-reloc; ++ }; ++}; ++ ++&sdmmc1 { ++ u-boot,dm-spl; ++}; ++ ++&sdmmc1_b4_pins_a { ++ u-boot,dm-spl; ++ pins1 { ++ u-boot,dm-spl; ++ }; ++ pins2 { ++ u-boot,dm-spl; ++ }; ++}; ++ ++&sdmmc1_dir_pins_a { ++ u-boot,dm-spl; ++ pins1 { ++ u-boot,dm-spl; ++ }; ++ pins2 { ++ u-boot,dm-spl; ++ }; ++}; ++ ++&sdmmc2 { ++ u-boot,dm-spl; ++}; ++ ++&sdmmc2_b4_pins_a { ++ u-boot,dm-spl; ++ pins1 { ++ u-boot,dm-spl; ++ }; ++ pins2 { ++ u-boot,dm-spl; ++ }; ++}; ++ ++&sdmmc2_d47_pins_a { ++ u-boot,dm-spl; ++ pins { ++ u-boot,dm-spl; ++ }; ++}; ++#endif ++ ++&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; ++ /* pull-up on rx to avoid floating level */ ++ bias-pull-up; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp157a-ed1.dts b/arch/arm/dts/stm32mp157a-ed1.dts +new file mode 100644 +index 0000000..5dca956 +--- /dev/null ++++ b/arch/arm/dts/stm32mp157a-ed1.dts +@@ -0,0 +1,52 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++/dts-v1/; ++ ++#include "stm32mp157.dtsi" ++#include "stm32mp15xa.dtsi" ++#include "stm32mp15-pinctrl.dtsi" ++#include "stm32mp15xxaa-pinctrl.dtsi" ++#include "stm32mp157-m4-srm.dtsi" ++#include "stm32mp157-m4-srm-pinctrl.dtsi" ++#include "stm32mp15xx-edx.dtsi" ++ ++/ { ++ model = "STMicroelectronics STM32MP157A eval daughter"; ++ compatible = "st,stm32mp157a-ed1", "st,stm32mp157"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ serial0 = &uart4; ++ }; ++ ++ reserved-memory { ++ gpu_reserved: gpu@f6000000 { ++ reg = <0xf6000000 0x8000000>; ++ no-map; ++ }; ++ ++ optee_memory: optee@fe000000 { ++ reg = <0xfe000000 0x02000000>; ++ no-map; ++ }; ++ }; ++}; ++ ++&cpu1{ ++ cpu-supply = <&vddcore>; ++}; ++ ++&gpu { ++ contiguous-area = <&gpu_reserved>; ++ status = "okay"; ++}; ++ ++&optee { ++ status = "okay"; ++}; +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 0000000..f634c4c +--- /dev/null ++++ b/arch/arm/dts/stm32mp157a-ev1-u-boot.dtsi +@@ -0,0 +1,69 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright : STMicroelectronics 2018 ++ */ ++ ++#include "stm32mp157c-ed1-u-boot.dtsi" ++ ++/ { ++ aliases { ++ gpio26 = &stmfx_pinctrl; ++ i2c1 = &i2c2; ++ i2c4 = &i2c5; ++ pinctrl2 = &stmfx_pinctrl; ++ spi0 = &qspi; ++ usb0 = &usbotg_hs; ++ }; ++}; ++ ++#ifndef CONFIG_STM32MP1_TRUSTED ++&flash0 { ++ u-boot,dm-spl; ++}; ++ ++&qspi { ++ u-boot,dm-spl; ++}; ++ ++&qspi_clk_pins_a { ++ u-boot,dm-spl; ++ pins { ++ u-boot,dm-spl; ++ }; ++}; ++ ++&qspi_bk1_pins_a { ++ u-boot,dm-spl; ++ pins1 { ++ u-boot,dm-spl; ++ }; ++ pins2 { ++ u-boot,dm-spl; ++ }; ++}; ++ ++&qspi_bk2_pins_a { ++ u-boot,dm-spl; ++ pins1 { ++ u-boot,dm-spl; ++ }; ++ pins2 { ++ u-boot,dm-spl; ++ }; ++}; ++ ++&sai2 { ++ clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>; ++}; ++ ++&sai4 { ++ clocks = <&rcc SAI4>, <&rcc PLL3_Q>, <&rcc PLL3_R>; ++}; ++ ++#endif ++ ++/* TEMP: force peripheral for USB OTG */ ++&usbotg_hs { ++ dr_mode = "peripheral"; ++}; ++ +diff --git a/arch/arm/dts/stm32mp157a-ev1.dts b/arch/arm/dts/stm32mp157a-ev1.dts +new file mode 100644 +index 0000000..29ecd15 +--- /dev/null ++++ b/arch/arm/dts/stm32mp157a-ev1.dts +@@ -0,0 +1,86 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++/dts-v1/; ++ ++#include "stm32mp157a-ed1.dts" ++#include "stm32mp15xx-evx.dtsi" ++#include ++#include ++ ++/ { ++ model = "STMicroelectronics STM32MP157A eval daughter on eval mother"; ++ compatible = "st,stm32mp157a-ev1", "st,stm32mp157a-ed1", "st,stm32mp157"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ serial1 = &usart3; ++ ethernet0 = ðernet0; ++ }; ++}; ++ ++&dsi { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ dsi_in: endpoint { ++ remote-endpoint = <<dc_ep0_out>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ dsi_out: endpoint { ++ remote-endpoint = <&dsi_panel_in>; ++ }; ++ }; ++ }; ++ ++ panel_dsi: panel-dsi@0 { ++ compatible = "raydium,rm68200"; ++ reg = <0>; ++ reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>; ++ backlight = <&panel_backlight>; ++ power-supply = <&v3v3>; ++ status = "okay"; ++ ++ port { ++ dsi_panel_in: endpoint { ++ remote-endpoint = <&dsi_out>; ++ }; ++ }; ++ }; ++}; ++ ++&i2c2 { ++ gt9147: goodix_ts@5d { ++ compatible = "goodix,gt9147"; ++ reg = <0x5d>; ++ panel = <&panel_dsi>; ++ pinctrl-0 = <&goodix_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ interrupts = <14 IRQ_TYPE_EDGE_RISING>; ++ interrupt-parent = <&stmfx_pinctrl>; ++ }; ++}; ++ ++&m_can1 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&m_can1_pins_a>; ++ pinctrl-1 = <&m_can1_sleep_pins_a>; ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi +index 18ac1e3..06ef3a4 100644 +--- a/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi ++++ b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi +@@ -4,9 +4,3 @@ + */ + + #include "stm32mp157a-dk1-u-boot.dtsi" +- +-&i2c1 { +- hdmi-transmitter@39 { +- reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>; +- }; +-}; +diff --git a/arch/arm/dts/stm32mp157c-dk2.dts b/arch/arm/dts/stm32mp157c-dk2.dts +index 020ea0f..a7d5e86 100644 +--- a/arch/arm/dts/stm32mp157c-dk2.dts ++++ b/arch/arm/dts/stm32mp157c-dk2.dts +@@ -6,18 +6,55 @@ + + /dts-v1/; + +-#include "stm32mp157a-dk1.dts" ++#include "stm32mp157.dtsi" ++#include "stm32mp15xc.dtsi" ++#include "stm32mp15-pinctrl.dtsi" ++#include "stm32mp15xxac-pinctrl.dtsi" ++#include "stm32mp15xx-dkx.dtsi" ++#include + + / { + model = "STMicroelectronics STM32MP157C-DK2 Discovery Board"; + compatible = "st,stm32mp157c-dk2", "st,stm32mp157"; ++ ++ aliases { ++ ethernet0 = ðernet0; ++ serial0 = &uart4; ++ serial1 = &usart3; ++ serial2 = &uart7; ++ serial3 = &usart2; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ reserved-memory { ++ gpu_reserved: gpu@da000000 { ++ reg = <0xda000000 0x4000000>; ++ no-map; ++ }; ++ ++ optee_memory: optee@0xde000000 { ++ reg = <0xde000000 0x02000000>; ++ no-map; ++ }; ++ }; ++ ++ wifi_pwrseq: wifi-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ reset-gpios = <&gpioh 4 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&cryp1 { ++ status="okay"; + }; + + &dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; +- phy-dsi-supply = <®18>; + + ports { + #address-cells = <1>; +@@ -38,7 +75,7 @@ + }; + }; + +- panel@0 { ++ panel_otm8009a: panel-otm8009a@0 { + compatible = "orisetech,otm8009a"; + reg = <0>; + reset-gpios = <&gpioe 4 GPIO_ACTIVE_LOW>; +@@ -53,6 +90,31 @@ + }; + }; + ++&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>; ++ status = "okay"; ++ }; ++ touchscreen@38 { ++ compatible = "focaltech,ft6236"; ++ reg = <0x38>; ++ interrupts = <2 2>; ++ interrupt-parent = <&gpiof>; ++ interrupt-controller; ++ touchscreen-size-x = <480>; ++ touchscreen-size-y = <800>; ++ panel = <&panel_otm8009a>; ++ status = "okay"; ++ }; ++}; ++ + <dc { + status = "okay"; + +@@ -66,3 +128,57 @@ + }; + }; + }; ++ ++&rtc { ++ st,lsco = ; ++ pinctrl-0 = <&rtc_out2_rmp_pins_a>; ++ pinctrl-names = "default"; ++}; ++ ++/* Wifi */ ++&sdmmc2 { ++ arm,primecell-periphid = <0x10153180>; ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc2_b4_pins_a>; ++ pinctrl-1 = <&sdmmc2_b4_od_pins_a>; ++ pinctrl-2 = <&sdmmc2_b4_sleep_pins_a>; ++ non-removable; ++ st,neg-edge; ++ bus-width = <4>; ++ vmmc-supply = <&v3v3>; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ brcmf: bcrmf@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ }; ++}; ++ ++/* 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 = <&gpioz 6 GPIO_ACTIVE_HIGH>; ++ compatible = "brcm,bcm43438-bt"; ++ max-speed = <3000000>; ++ vbat-supply = <&v3v3>; ++ vddio-supply = <&v3v3>; ++ }; ++}; ++ ++&optee_memory { ++ status = "okay"; ++}; ++ ++&optee { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi +index b2ac494..44a689b 100644 +--- a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi ++++ b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi +@@ -3,204 +3,4 @@ + * Copyright : STMicroelectronics 2018 + */ + +-#include +-#include "stm32mp157-u-boot.dtsi" +-#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" +- +-/ { +- aliases { +- i2c3 = &i2c4; +- mmc0 = &sdmmc1; +- mmc1 = &sdmmc2; +- }; +- +- config { +- u-boot,boot-led = "heartbeat"; +- u-boot,error-led = "error"; +- st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; +- st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; +- }; +- +- led { +- red { +- label = "error"; +- gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; +- default-state = "off"; +- status = "okay"; +- }; +- +- blue { +- default-state = "on"; +- }; +- }; +-}; +- +-&clk_hse { +- st,digbypass; +-}; +- +-&i2c4 { +- u-boot,dm-pre-reloc; +-}; +- +-&i2c4_pins_a { +- u-boot,dm-pre-reloc; +- pins { +- u-boot,dm-pre-reloc; +- }; +-}; +- +-&pmic { +- u-boot,dm-pre-reloc; +-}; +- +-&rcc { +- st,clksrc = < +- CLK_MPU_PLL1P +- CLK_AXI_PLL2P +- CLK_MCU_PLL3P +- CLK_PLL12_HSE +- CLK_PLL3_HSE +- CLK_PLL4_HSE +- CLK_RTC_LSE +- CLK_MCO1_DISABLED +- CLK_MCO2_DISABLED +- >; +- +- st,clkdiv = < +- 1 /*MPU*/ +- 0 /*AXI*/ +- 0 /*MCU*/ +- 1 /*APB1*/ +- 1 /*APB2*/ +- 1 /*APB3*/ +- 1 /*APB4*/ +- 2 /*APB5*/ +- 23 /*RTC*/ +- 0 /*MCO1*/ +- 0 /*MCO2*/ +- >; +- +- st,pkcs = < +- CLK_CKPER_HSE +- CLK_FMC_ACLK +- CLK_QSPI_ACLK +- CLK_ETH_DISABLED +- CLK_SDMMC12_PLL4P +- CLK_DSI_DSIPLL +- CLK_STGEN_HSE +- CLK_USBPHY_HSE +- CLK_SPI2S1_PLL3Q +- CLK_SPI2S23_PLL3Q +- CLK_SPI45_HSI +- CLK_SPI6_HSI +- CLK_I2C46_HSI +- CLK_SDMMC3_PLL4P +- CLK_USBO_USBPHY +- CLK_ADC_CKPER +- CLK_CEC_LSE +- CLK_I2C12_HSI +- CLK_I2C35_HSI +- CLK_UART1_HSI +- CLK_UART24_HSI +- CLK_UART35_HSI +- CLK_UART6_HSI +- CLK_UART78_HSI +- CLK_SPDIF_PLL4P +- CLK_FDCAN_PLL4Q +- CLK_SAI1_PLL3Q +- CLK_SAI2_PLL3Q +- CLK_SAI3_PLL3Q +- CLK_SAI4_PLL3Q +- CLK_RNG1_LSI +- CLK_RNG2_LSI +- CLK_LPTIM1_PCLK1 +- CLK_LPTIM23_PCLK3 +- CLK_LPTIM45_LSE +- >; +- +- /* VCO = 1300.0 MHz => P = 650 (CPU) */ +- pll1: st,pll@0 { +- cfg = < 2 80 0 0 0 PQR(1,0,0) >; +- frac = < 0x800 >; +- u-boot,dm-pre-reloc; +- }; +- +- /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ +- pll2: st,pll@1 { +- cfg = < 2 65 1 0 0 PQR(1,1,1) >; +- frac = < 0x1400 >; +- u-boot,dm-pre-reloc; +- }; +- +- /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ +- pll3: st,pll@2 { +- cfg = < 1 33 1 16 36 PQR(1,1,1) >; +- frac = < 0x1a04 >; +- u-boot,dm-pre-reloc; +- }; +- +- /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ +- pll4: st,pll@3 { +- cfg = < 3 98 5 7 7 PQR(1,1,1) >; +- u-boot,dm-pre-reloc; +- }; +-}; +- +-&sdmmc1 { +- u-boot,dm-spl; +-}; +- +-&sdmmc1_b4_pins_a { +- u-boot,dm-spl; +- pins { +- u-boot,dm-spl; +- }; +-}; +- +-&sdmmc1_dir_pins_a { +- u-boot,dm-spl; +- pins1 { +- u-boot,dm-spl; +- }; +- pins2 { +- u-boot,dm-spl; +- }; +-}; +- +-&sdmmc2 { +- u-boot,dm-spl; +-}; +- +-&sdmmc2_b4_pins_a { +- u-boot,dm-spl; +- pins1 { +- u-boot,dm-spl; +- }; +- pins2 { +- u-boot,dm-spl; +- }; +-}; +- +-&sdmmc2_d47_pins_a { +- u-boot,dm-spl; +- pins { +- u-boot,dm-spl; +- }; +-}; +- +-&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; +- /* pull-up on rx to avoid floating level */ +- bias-pull-up; +- }; +-}; ++#include "stm32mp157a-ed1-u-boot.dtsi" +diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts +index bc4d7e1..bf2d7e7 100644 +--- a/arch/arm/dts/stm32mp157c-ed1.dts ++++ b/arch/arm/dts/stm32mp157c-ed1.dts +@@ -1,14 +1,17 @@ + // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + /* +- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved +- * Author: Ludovic Barre for STMicroelectronics. ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. + */ + /dts-v1/; + +-#include "stm32mp157c.dtsi" +-#include "stm32mp157xaa-pinctrl.dtsi" +-#include +-#include ++#include "stm32mp157.dtsi" ++#include "stm32mp15xc.dtsi" ++#include "stm32mp15-pinctrl.dtsi" ++#include "stm32mp15xxaa-pinctrl.dtsi" ++#include "stm32mp157-m4-srm.dtsi" ++#include "stm32mp157-m4-srm-pinctrl.dtsi" ++#include "stm32mp15xx-edx.dtsi" + + / { + model = "STMicroelectronics STM32MP157C eval daughter"; +@@ -18,78 +21,29 @@ + stdout-path = "serial0:115200n8"; + }; + +- memory@c0000000 { +- device_type = "memory"; +- reg = <0xC0000000 0x40000000>; ++ aliases { ++ serial0 = &uart4; + }; + + reserved-memory { +- #address-cells = <1>; +- #size-cells = <1>; +- ranges; +- +- mcuram2: mcuram2@10000000 { +- compatible = "shared-dma-pool"; +- reg = <0x10000000 0x40000>; +- no-map; +- }; +- +- vdev0vring0: vdev0vring0@10040000 { +- compatible = "shared-dma-pool"; +- reg = <0x10040000 0x1000>; +- no-map; +- }; +- +- vdev0vring1: vdev0vring1@10041000 { +- compatible = "shared-dma-pool"; +- reg = <0x10041000 0x1000>; +- no-map; +- }; +- +- vdev0buffer: vdev0buffer@10042000 { +- compatible = "shared-dma-pool"; +- reg = <0x10042000 0x4000>; +- no-map; +- }; +- +- mcuram: mcuram@30000000 { +- compatible = "shared-dma-pool"; +- reg = <0x30000000 0x40000>; ++ gpu_reserved: gpu@f6000000 { ++ reg = <0xf6000000 0x8000000>; + no-map; + }; + +- retram: retram@38000000 { +- compatible = "shared-dma-pool"; +- reg = <0x38000000 0x10000>; ++ optee_memory: optee@fe000000 { ++ reg = <0xfe000000 0x02000000>; + no-map; + }; +- +- gpu_reserved: gpu@e8000000 { +- reg = <0xe8000000 0x8000000>; +- no-map; +- }; +- }; +- +- aliases { +- serial0 = &uart4; + }; ++}; + +- sd_switch: regulator-sd_switch { +- compatible = "regulator-gpio"; +- regulator-name = "sd_switch"; +- regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <2900000>; +- regulator-type = "voltage"; +- regulator-always-on; +- +- gpios = <&gpiof 14 GPIO_ACTIVE_HIGH>; +- gpios-states = <0>; +- states = <1800000 0x1 2900000 0x0>; +- }; ++&cpu1{ ++ cpu-supply = <&vddcore>; + }; + +-&dts { +- status = "okay"; ++&cryp1 { ++ status="okay"; + }; + + &gpu { +@@ -97,242 +51,6 @@ + status = "okay"; + }; + +-&i2c4 { +- pinctrl-names = "default"; +- pinctrl-0 = <&i2c4_pins_a>; +- i2c-scl-rising-time-ns = <185>; +- i2c-scl-falling-time-ns = <20>; ++&optee { + status = "okay"; +- /* spare dmas for other usage */ +- /delete-property/dmas; +- /delete-property/dma-names; +- +- pmic: stpmic@33 { +- compatible = "st,stpmic1"; +- reg = <0x33>; +- interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>; +- interrupt-controller; +- #interrupt-cells = <2>; +- status = "okay"; +- +- regulators { +- compatible = "st,stpmic1-regulators"; +- ldo1-supply = <&v3v3>; +- ldo2-supply = <&v3v3>; +- ldo3-supply = <&vdd_ddr>; +- ldo5-supply = <&v3v3>; +- ldo6-supply = <&v3v3>; +- pwr_sw1-supply = <&bst_out>; +- pwr_sw2-supply = <&bst_out>; +- +- vddcore: buck1 { +- regulator-name = "vddcore"; +- regulator-min-microvolt = <800000>; +- regulator-max-microvolt = <1350000>; +- regulator-always-on; +- regulator-initial-mode = <0>; +- regulator-over-current-protection; +- }; +- +- vdd_ddr: buck2 { +- regulator-name = "vdd_ddr"; +- regulator-min-microvolt = <1350000>; +- regulator-max-microvolt = <1350000>; +- regulator-always-on; +- regulator-initial-mode = <0>; +- regulator-over-current-protection; +- }; +- +- vdd: buck3 { +- regulator-name = "vdd"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- regulator-always-on; +- st,mask-reset; +- regulator-initial-mode = <0>; +- regulator-over-current-protection; +- }; +- +- v3v3: buck4 { +- regulator-name = "v3v3"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- regulator-always-on; +- regulator-over-current-protection; +- regulator-initial-mode = <0>; +- }; +- +- vdda: ldo1 { +- regulator-name = "vdda"; +- regulator-min-microvolt = <2900000>; +- regulator-max-microvolt = <2900000>; +- interrupts = ; +- }; +- +- v2v8: ldo2 { +- regulator-name = "v2v8"; +- regulator-min-microvolt = <2800000>; +- regulator-max-microvolt = <2800000>; +- interrupts = ; +- }; +- +- vtt_ddr: ldo3 { +- regulator-name = "vtt_ddr"; +- regulator-min-microvolt = <500000>; +- regulator-max-microvolt = <750000>; +- regulator-always-on; +- regulator-over-current-protection; +- }; +- +- vdd_usb: ldo4 { +- regulator-name = "vdd_usb"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- interrupts = ; +- }; +- +- vdd_sd: ldo5 { +- regulator-name = "vdd_sd"; +- regulator-min-microvolt = <2900000>; +- regulator-max-microvolt = <2900000>; +- interrupts = ; +- regulator-boot-on; +- }; +- +- v1v8: ldo6 { +- regulator-name = "v1v8"; +- regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <1800000>; +- interrupts = ; +- }; +- +- vref_ddr: vref_ddr { +- regulator-name = "vref_ddr"; +- regulator-always-on; +- regulator-over-current-protection; +- }; +- +- bst_out: boost { +- regulator-name = "bst_out"; +- interrupts = ; +- }; +- +- vbus_otg: pwr_sw1 { +- regulator-name = "vbus_otg"; +- interrupts = ; +- }; +- +- vbus_sw: pwr_sw2 { +- regulator-name = "vbus_sw"; +- interrupts = ; +- regulator-active-discharge; +- }; +- }; +- +- onkey { +- compatible = "st,stpmic1-onkey"; +- interrupts = , ; +- interrupt-names = "onkey-falling", "onkey-rising"; +- power-off-time-sec = <10>; +- status = "okay"; +- }; +- +- watchdog { +- compatible = "st,stpmic1-wdt"; +- status = "disabled"; +- }; +- }; +-}; +- +-&ipcc { +- status = "okay"; +-}; +- +-&iwdg2 { +- timeout-sec = <32>; +- status = "okay"; +-}; +- +-&m4_rproc { +- memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, +- <&vdev0vring1>, <&vdev0buffer>; +- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; +- mbox-names = "vq0", "vq1", "shutdown"; +- interrupt-parent = <&exti>; +- interrupts = <68 1>; +- status = "okay"; +-}; +- +-&pwr { +- pwr-regulators { +- vdd-supply = <&vdd>; +- vdd_3v3_usbfs-supply = <&vdd_usb>; +- }; +-}; +- +-&rng1 { +- status = "okay"; +-}; +- +-&rtc { +- status = "okay"; +-}; +- +-&sdmmc1 { +- pinctrl-names = "default", "opendrain", "sleep"; +- pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; +- pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_dir_pins_a>; +- pinctrl-2 = <&sdmmc1_b4_sleep_pins_a &sdmmc1_dir_sleep_pins_a>; +- broken-cd; +- st,sig-dir; +- st,neg-edge; +- st,use-ckin; +- bus-width = <4>; +- vmmc-supply = <&vdd_sd>; +- vqmmc-supply = <&sd_switch>; +- status = "okay"; +-}; +- +-&sdmmc2 { +- pinctrl-names = "default", "opendrain", "sleep"; +- pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>; +- pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>; +- pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>; +- non-removable; +- no-sd; +- no-sdio; +- st,neg-edge; +- bus-width = <8>; +- vmmc-supply = <&v3v3>; +- vqmmc-supply = <&v3v3>; +- mmc-ddr-3_3v; +- status = "okay"; +-}; +- +-&timers6 { +- status = "okay"; +- /* spare dmas for other usage */ +- /delete-property/dmas; +- /delete-property/dma-names; +- timer@5 { +- status = "okay"; +- }; +-}; +- +-&uart4 { +- pinctrl-names = "default"; +- pinctrl-0 = <&uart4_pins_a>; +- status = "okay"; +-}; +- +-&usbotg_hs { +- vbus-supply = <&vbus_otg>; +-}; +- +-&usbphyc_port0 { +- phy-supply = <&vdd_usb>; +-}; +- +-&usbphyc_port1 { +- phy-supply = <&vdd_usb>; + }; +diff --git a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi +index ec60486..cc02806 100644 +--- a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi ++++ b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi +@@ -3,51 +3,4 @@ + * Copyright : STMicroelectronics 2018 + */ + +-#include "stm32mp157c-ed1-u-boot.dtsi" +- +-/ { +- aliases { +- gpio26 = &stmfx_pinctrl; +- i2c1 = &i2c2; +- i2c4 = &i2c5; +- pinctrl2 = &stmfx_pinctrl; +- spi0 = &qspi; +- usb0 = &usbotg_hs; +- }; +-}; +- +-&flash0 { +- u-boot,dm-spl; +-}; +- +-&qspi { +- u-boot,dm-spl; +-}; +- +-&qspi_clk_pins_a { +- u-boot,dm-spl; +- pins { +- u-boot,dm-spl; +- }; +-}; +- +-&qspi_bk1_pins_a { +- u-boot,dm-spl; +- pins1 { +- u-boot,dm-spl; +- }; +- pins2 { +- u-boot,dm-spl; +- }; +-}; +- +-&qspi_bk2_pins_a { +- u-boot,dm-spl; +- pins1 { +- u-boot,dm-spl; +- }; +- pins2 { +- u-boot,dm-spl; +- }; +-}; +- ++#include "stm32mp157a-ev1-u-boot.dtsi" +diff --git a/arch/arm/dts/stm32mp157c-ev1.dts b/arch/arm/dts/stm32mp157c-ev1.dts +index 89d29b5..c60727d 100644 +--- a/arch/arm/dts/stm32mp157c-ev1.dts ++++ b/arch/arm/dts/stm32mp157c-ev1.dts +@@ -1,13 +1,14 @@ + // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + /* +- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved +- * Author: Ludovic Barre for STMicroelectronics. ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. + */ + /dts-v1/; + + #include "stm32mp157c-ed1.dts" +-#include ++#include "stm32mp15xx-evx.dtsi" + #include ++#include + + / { + model = "STMicroelectronics STM32MP157C eval daughter on eval mother"; +@@ -18,90 +19,14 @@ + }; + + aliases { +- serial0 = &uart4; ++ serial1 = &usart3; + ethernet0 = ðernet0; + }; +- +- clocks { +- clk_ext_camera: clk-ext-camera { +- #clock-cells = <0>; +- compatible = "fixed-clock"; +- clock-frequency = <24000000>; +- }; +- }; +- +- joystick { +- compatible = "gpio-keys"; +- #size-cells = <0>; +- pinctrl-0 = <&joystick_pins>; +- pinctrl-names = "default"; +- button-0 { +- label = "JoySel"; +- linux,code = ; +- interrupt-parent = <&stmfx_pinctrl>; +- interrupts = <0 IRQ_TYPE_EDGE_RISING>; +- }; +- button-1 { +- label = "JoyDown"; +- linux,code = ; +- interrupt-parent = <&stmfx_pinctrl>; +- interrupts = <1 IRQ_TYPE_EDGE_RISING>; +- }; +- button-2 { +- label = "JoyLeft"; +- linux,code = ; +- interrupt-parent = <&stmfx_pinctrl>; +- interrupts = <2 IRQ_TYPE_EDGE_RISING>; +- }; +- button-3 { +- label = "JoyRight"; +- linux,code = ; +- interrupt-parent = <&stmfx_pinctrl>; +- interrupts = <3 IRQ_TYPE_EDGE_RISING>; +- }; +- button-4 { +- label = "JoyUp"; +- 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"; +- }; +-}; +- +-&cec { +- pinctrl-names = "default"; +- pinctrl-0 = <&cec_pins_a>; +- status = "okay"; +-}; +- +-&dcmi { +- status = "okay"; +- pinctrl-names = "default", "sleep"; +- pinctrl-0 = <&dcmi_pins_a>; +- pinctrl-1 = <&dcmi_sleep_pins_a>; +- +- port { +- dcmi_0: endpoint { +- remote-endpoint = <&ov5640_0>; +- bus-width = <8>; +- hsync-active = <0>; +- vsync-active = <0>; +- pclk-sample = <1>; +- }; +- }; + }; + + &dsi { + #address-cells = <1>; + #size-cells = <0>; +- phy-dsi-supply = <®18>; + status = "okay"; + + ports { +@@ -123,7 +48,7 @@ + }; + }; + +- panel-dsi@0 { ++ panel_dsi: panel-dsi@0 { + compatible = "raydium,rm68200"; + reg = <0>; + reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>; +@@ -139,122 +64,17 @@ + }; + }; + +-ðernet0 { +- status = "okay"; +- pinctrl-0 = <ðernet0_rgmii_pins_a>; +- pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; +- pinctrl-names = "default", "sleep"; +- phy-mode = "rgmii-id"; +- max-speed = <1000>; +- phy-handle = <&phy0>; +- +- mdio0 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "snps,dwmac-mdio"; +- phy0: ethernet-phy@0 { +- reg = <0>; +- }; +- }; +-}; +- +-&fmc { +- pinctrl-names = "default", "sleep"; +- pinctrl-0 = <&fmc_pins_a>; +- pinctrl-1 = <&fmc_sleep_pins_a>; +- status = "okay"; +- #address-cells = <1>; +- #size-cells = <0>; +- +- nand@0 { +- reg = <0>; +- nand-on-flash-bbt; +- #address-cells = <1>; +- #size-cells = <1>; +- }; +-}; +- + &i2c2 { +- pinctrl-names = "default"; +- pinctrl-0 = <&i2c2_pins_a>; +- i2c-scl-rising-time-ns = <185>; +- i2c-scl-falling-time-ns = <20>; +- status = "okay"; +- +- ov5640: camera@3c { +- compatible = "ovti,ov5640"; ++ gt9147: goodix_ts@5d { ++ compatible = "goodix,gt9147"; ++ reg = <0x5d>; ++ panel = <&panel_dsi>; ++ pinctrl-0 = <&goodix_pins>; + pinctrl-names = "default"; +- pinctrl-0 = <&ov5640_pins>; +- reg = <0x3c>; +- clocks = <&clk_ext_camera>; +- clock-names = "xclk"; +- DOVDD-supply = <&v2v8>; +- powerdown-gpios = <&stmfx_pinctrl 18 GPIO_ACTIVE_HIGH>; +- reset-gpios = <&stmfx_pinctrl 19 GPIO_ACTIVE_LOW>; +- rotation = <180>; + status = "okay"; + +- port { +- ov5640_0: endpoint { +- remote-endpoint = <&dcmi_0>; +- bus-width = <8>; +- data-shift = <2>; /* lines 9:2 are used */ +- hsync-active = <0>; +- vsync-active = <0>; +- pclk-sample = <1>; +- }; +- }; +- }; +- +- stmfx: stmfx@42 { +- compatible = "st,stmfx-0300"; +- reg = <0x42>; +- interrupts = <8 IRQ_TYPE_EDGE_RISING>; +- interrupt-parent = <&gpioi>; +- vdd-supply = <&v3v3>; +- +- stmfx_pinctrl: stmfx-pin-controller { +- compatible = "st,stmfx-0300-pinctrl"; +- gpio-controller; +- #gpio-cells = <2>; +- interrupt-controller; +- #interrupt-cells = <2>; +- gpio-ranges = <&stmfx_pinctrl 0 0 24>; +- +- joystick_pins: joystick { +- pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4"; +- drive-push-pull; +- bias-pull-down; +- }; +- +- ov5640_pins: camera { +- pins = "agpio2", "agpio3"; /* stmfx pins 18 & 19 */ +- drive-push-pull; +- output-low; +- }; +- }; +- }; +-}; +- +-&i2c5 { +- pinctrl-names = "default"; +- pinctrl-0 = <&i2c5_pins_a>; +- i2c-scl-rising-time-ns = <185>; +- i2c-scl-falling-time-ns = <20>; +- status = "okay"; +-}; +- +-<dc { +- status = "okay"; +- +- port { +- #address-cells = <1>; +- #size-cells = <0>; +- +- ltdc_ep0_out: endpoint@0 { +- reg = <0>; +- remote-endpoint = <&dsi_in>; +- }; ++ interrupts = <14 IRQ_TYPE_EDGE_RISING>; ++ interrupt-parent = <&stmfx_pinctrl>; + }; + }; + +@@ -264,97 +84,3 @@ + pinctrl-1 = <&m_can1_sleep_pins_a>; + status = "okay"; + }; +- +-&qspi { +- pinctrl-names = "default", "sleep"; +- pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>; +- pinctrl-1 = <&qspi_clk_sleep_pins_a &qspi_bk1_sleep_pins_a &qspi_bk2_sleep_pins_a>; +- reg = <0x58003000 0x1000>, <0x70000000 0x4000000>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "okay"; +- +- flash0: mx66l51235l@0 { +- compatible = "jedec,spi-nor"; +- reg = <0>; +- spi-rx-bus-width = <4>; +- spi-max-frequency = <108000000>; +- #address-cells = <1>; +- #size-cells = <1>; +- }; +- +- flash1: mx66l51235l@1 { +- compatible = "jedec,spi-nor"; +- reg = <1>; +- spi-rx-bus-width = <4>; +- spi-max-frequency = <108000000>; +- #address-cells = <1>; +- #size-cells = <1>; +- }; +-}; +- +-&spi1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&spi1_pins_a>; +- status = "disabled"; +-}; +- +-&timers2 { +- /* spare dmas for other usage (un-delete to enable pwm capture) */ +- /delete-property/dmas; +- /delete-property/dma-names; +- status = "disabled"; +- pwm { +- pinctrl-0 = <&pwm2_pins_a>; +- pinctrl-names = "default"; +- status = "okay"; +- }; +- timer@1 { +- status = "okay"; +- }; +-}; +- +-&timers8 { +- /delete-property/dmas; +- /delete-property/dma-names; +- status = "disabled"; +- pwm { +- pinctrl-0 = <&pwm8_pins_a>; +- pinctrl-names = "default"; +- status = "okay"; +- }; +- timer@7 { +- status = "okay"; +- }; +-}; +- +-&timers12 { +- /delete-property/dmas; +- /delete-property/dma-names; +- status = "disabled"; +- pwm { +- pinctrl-0 = <&pwm12_pins_a>; +- pinctrl-names = "default"; +- status = "okay"; +- }; +- timer@11 { +- status = "okay"; +- }; +-}; +- +-&usbh_ehci { +- phys = <&usbphyc_port0>; +- phy-names = "usb"; +- status = "okay"; +-}; +- +-&usbotg_hs { +- dr_mode = "peripheral"; +- phys = <&usbphyc_port1 0>; +- phy-names = "usb2-phy"; +- status = "okay"; +-}; +- +-&usbphyc { +- status = "okay"; +-}; +diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp157c.dtsi +deleted file mode 100644 +index 6c670cf..0000000 +--- a/arch/arm/dts/stm32mp157c.dtsi ++++ /dev/null +@@ -1,1592 +0,0 @@ +-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +-/* +- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved +- * Author: Ludovic Barre for STMicroelectronics. +- */ +-#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>; +- }; +- +- cpu1: cpu@1 { +- compatible = "arm,cortex-a7"; +- device_type = "cpu"; +- reg = <1>; +- }; +- }; +- +- psci { +- compatible = "arm,psci-1.0"; +- method = "smc"; +- cpu_off = <0x84000002>; +- cpu_on = <0x84000003>; +- }; +- +- intc: interrupt-controller@a0021000 { +- compatible = "arm,cortex-a7-gic"; +- #interrupt-cells = <3>; +- interrupt-controller; +- reg = <0xa0021000 0x1000>, +- <0xa0022000 0x2000>; +- }; +- +- timer { +- compatible = "arm,armv7-timer"; +- interrupts = , +- , +- , +- ; +- interrupt-parent = <&intc>; +- }; +- +- clocks { +- clk_hse: clk-hse { +- #clock-cells = <0>; +- compatible = "fixed-clock"; +- clock-frequency = <24000000>; +- }; +- +- clk_hsi: clk-hsi { +- #clock-cells = <0>; +- compatible = "fixed-clock"; +- clock-frequency = <64000000>; +- }; +- +- clk_lse: clk-lse { +- #clock-cells = <0>; +- compatible = "fixed-clock"; +- clock-frequency = <32768>; +- }; +- +- clk_lsi: clk-lsi { +- #clock-cells = <0>; +- compatible = "fixed-clock"; +- clock-frequency = <32000>; +- }; +- +- clk_csi: clk-csi { +- #clock-cells = <0>; +- compatible = "fixed-clock"; +- clock-frequency = <4000000>; +- }; +- }; +- +- thermal-zones { +- cpu_thermal: cpu-thermal { +- polling-delay-passive = <0>; +- polling-delay = <0>; +- thermal-sensors = <&dts>; +- +- trips { +- cpu_alert1: cpu-alert1 { +- temperature = <85000>; +- hysteresis = <0>; +- type = "passive"; +- }; +- +- cpu-crit { +- temperature = <120000>; +- hysteresis = <0>; +- type = "critical"; +- }; +- }; +- +- cooling-maps { +- }; +- }; +- }; +- +- booster: regulator-booster { +- compatible = "st,stm32mp1-booster"; +- st,syscfg = <&syscfg>; +- status = "disabled"; +- }; +- +- reboot { +- compatible = "syscon-reboot"; +- regmap = <&rcc>; +- offset = <0x404>; +- mask = <0x1>; +- }; +- +- soc { +- compatible = "simple-bus"; +- #address-cells = <1>; +- #size-cells = <1>; +- interrupt-parent = <&intc>; +- ranges; +- +- 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 0x1>, +- <&dmamux1 19 0x400 0x1>, +- <&dmamux1 20 0x400 0x1>, +- <&dmamux1 21 0x400 0x1>, +- <&dmamux1 22 0x400 0x1>; +- 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"; +- }; +- }; +- +- 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 0x1>, +- <&dmamux1 24 0x400 0x1>, +- <&dmamux1 25 0x400 0x1>, +- <&dmamux1 26 0x400 0x1>, +- <&dmamux1 27 0x400 0x1>, +- <&dmamux1 28 0x400 0x1>; +- 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"; +- }; +- }; +- +- 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 0x1>, +- <&dmamux1 30 0x400 0x1>, +- <&dmamux1 31 0x400 0x1>, +- <&dmamux1 32 0x400 0x1>; +- dma-names = "ch1", "ch2", "ch3", "ch4"; +- status = "disabled"; +- +- pwm { +- compatible = "st,stm32-pwm"; +- #pwm-cells = <3>; +- status = "disabled"; +- }; +- +- timer@3 { +- compatible = "st,stm32h7-timer-trigger"; +- reg = <3>; +- 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 0x1>, +- <&dmamux1 56 0x400 0x1>, +- <&dmamux1 57 0x400 0x1>, +- <&dmamux1 58 0x400 0x1>, +- <&dmamux1 59 0x400 0x1>, +- <&dmamux1 60 0x400 0x1>; +- 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"; +- }; +- }; +- +- 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 0x1>; +- 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 0x1>; +- dma-names = "up"; +- status = "disabled"; +- +- timer@6 { +- compatible = "st,stm32h7-timer-trigger"; +- reg = <6>; +- status = "disabled"; +- }; +- }; +- +- timers12: timer@40006000 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "st,stm32-timers"; +- reg = <0x40006000 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@40007000 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "st,stm32-timers"; +- reg = <0x40007000 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@40008000 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "st,stm32-timers"; +- reg = <0x40008000 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"; +- }; +- }; +- +- lptimer1: timer@40009000 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "st,stm32-lptimer"; +- reg = <0x40009000 0x400>; +- clocks = <&rcc LPTIM1_K>; +- clock-names = "mux"; +- 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"; +- }; +- }; +- +- 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 0x05>, +- <&dmamux1 40 0x400 0x05>; +- dma-names = "rx", "tx"; +- 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"; +- }; +- +- 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 0x05>, +- <&dmamux1 62 0x400 0x05>; +- 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"; +- }; +- +- 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"; +- }; +- +- usart2: serial@4000e000 { +- compatible = "st,stm32h7-uart"; +- reg = <0x4000e000 0x400>; +- interrupts = ; +- clocks = <&rcc USART2_K>; +- status = "disabled"; +- }; +- +- usart3: serial@4000f000 { +- compatible = "st,stm32h7-uart"; +- reg = <0x4000f000 0x400>; +- interrupts = ; +- clocks = <&rcc USART3_K>; +- status = "disabled"; +- }; +- +- uart4: serial@40010000 { +- compatible = "st,stm32h7-uart"; +- reg = <0x40010000 0x400>; +- interrupts = ; +- clocks = <&rcc UART4_K>; +- status = "disabled"; +- }; +- +- uart5: serial@40011000 { +- compatible = "st,stm32h7-uart"; +- reg = <0x40011000 0x400>; +- interrupts = ; +- clocks = <&rcc UART5_K>; +- status = "disabled"; +- }; +- +- i2c1: i2c@40012000 { +- compatible = "st,stm32f7-i2c"; +- reg = <0x40012000 0x400>; +- interrupt-names = "event", "error"; +- interrupts = , +- ; +- clocks = <&rcc I2C1_K>; +- resets = <&rcc I2C1_R>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- i2c2: i2c@40013000 { +- compatible = "st,stm32f7-i2c"; +- reg = <0x40013000 0x400>; +- interrupt-names = "event", "error"; +- interrupts = , +- ; +- clocks = <&rcc I2C2_K>; +- resets = <&rcc I2C2_R>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- i2c3: i2c@40014000 { +- compatible = "st,stm32f7-i2c"; +- reg = <0x40014000 0x400>; +- interrupt-names = "event", "error"; +- interrupts = , +- ; +- clocks = <&rcc I2C3_K>; +- resets = <&rcc I2C3_R>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- i2c5: i2c@40015000 { +- compatible = "st,stm32f7-i2c"; +- reg = <0x40015000 0x400>; +- interrupt-names = "event", "error"; +- interrupts = , +- ; +- clocks = <&rcc I2C5_K>; +- resets = <&rcc I2C5_R>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- cec: cec@40016000 { +- compatible = "st,stm32-cec"; +- reg = <0x40016000 0x400>; +- interrupts = ; +- clocks = <&rcc CEC_K>, <&clk_lse>; +- clock-names = "cec", "hdmi-cec"; +- status = "disabled"; +- }; +- +- dac: dac@40017000 { +- compatible = "st,stm32h7-dac-core"; +- reg = <0x40017000 0x400>; +- clocks = <&rcc DAC12>; +- clock-names = "pclk"; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- +- dac1: dac@1 { +- compatible = "st,stm32-dac"; +- #io-channels-cells = <1>; +- reg = <1>; +- status = "disabled"; +- }; +- +- dac2: dac@2 { +- compatible = "st,stm32-dac"; +- #io-channels-cells = <1>; +- reg = <2>; +- status = "disabled"; +- }; +- }; +- +- uart7: serial@40018000 { +- compatible = "st,stm32h7-uart"; +- reg = <0x40018000 0x400>; +- interrupts = ; +- clocks = <&rcc UART7_K>; +- status = "disabled"; +- }; +- +- uart8: serial@40019000 { +- compatible = "st,stm32h7-uart"; +- reg = <0x40019000 0x400>; +- interrupts = ; +- clocks = <&rcc UART8_K>; +- 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 0x1>, +- <&dmamux1 12 0x400 0x1>, +- <&dmamux1 13 0x400 0x1>, +- <&dmamux1 14 0x400 0x1>, +- <&dmamux1 15 0x400 0x1>, +- <&dmamux1 16 0x400 0x1>, +- <&dmamux1 17 0x400 0x1>; +- 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"; +- }; +- }; +- +- 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 0x1>, +- <&dmamux1 48 0x400 0x1>, +- <&dmamux1 49 0x400 0x1>, +- <&dmamux1 50 0x400 0x1>, +- <&dmamux1 51 0x400 0x1>, +- <&dmamux1 52 0x400 0x1>, +- <&dmamux1 53 0x400 0x1>; +- 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"; +- }; +- }; +- +- usart6: serial@44003000 { +- compatible = "st,stm32h7-uart"; +- reg = <0x44003000 0x400>; +- interrupts = ; +- clocks = <&rcc USART6_K>; +- 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 0x05>, +- <&dmamux1 38 0x400 0x05>; +- 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"; +- }; +- +- spi4: spi@44005000 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "st,stm32h7-spi"; +- reg = <0x44005000 0x400>; +- interrupts = ; +- clocks = <&rcc SPI4_K>; +- resets = <&rcc SPI4_R>; +- dmas = <&dmamux1 83 0x400 0x05>, +- <&dmamux1 84 0x400 0x05>; +- dma-names = "rx", "tx"; +- status = "disabled"; +- }; +- +- timers15: timer@44006000 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "st,stm32-timers"; +- reg = <0x44006000 0x400>; +- clocks = <&rcc TIM15_K>; +- clock-names = "int"; +- dmas = <&dmamux1 105 0x400 0x1>, +- <&dmamux1 106 0x400 0x1>, +- <&dmamux1 107 0x400 0x1>, +- <&dmamux1 108 0x400 0x1>; +- 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@44007000 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "st,stm32-timers"; +- reg = <0x44007000 0x400>; +- clocks = <&rcc TIM16_K>; +- clock-names = "int"; +- dmas = <&dmamux1 109 0x400 0x1>, +- <&dmamux1 110 0x400 0x1>; +- 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@44008000 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "st,stm32-timers"; +- reg = <0x44008000 0x400>; +- clocks = <&rcc TIM17_K>; +- clock-names = "int"; +- dmas = <&dmamux1 111 0x400 0x1>, +- <&dmamux1 112 0x400 0x1>; +- 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"; +- }; +- }; +- +- spi5: spi@44009000 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "st,stm32h7-spi"; +- reg = <0x44009000 0x400>; +- interrupts = ; +- clocks = <&rcc SPI5_K>; +- resets = <&rcc SPI5_R>; +- dmas = <&dmamux1 85 0x400 0x05>, +- <&dmamux1 86 0x400 0x05>; +- 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 0x1c>; +- 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 0x1c>; +- 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 0x1c>; +- 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 0x1c>; +- clocks = <&rcc SAI2_K>; +- clock-names = "sai_ck"; +- dmas = <&dmamux1 90 0x400 0x01>; +- status = "disabled"; +- }; +- }; +- +- sai3: sai@4400c000 { +- compatible = "st,stm32h7-sai"; +- #address-cells = <1>; +- #size-cells = <1>; +- ranges = <0 0x4400c000 0x400>; +- reg = <0x4400c000 0x4>, <0x4400c3f0 0x10>; +- interrupts = ; +- resets = <&rcc SAI3_R>; +- status = "disabled"; +- +- sai3a: audio-controller@4400c004 { +- #sound-dai-cells = <0>; +- compatible = "st,stm32-sai-sub-a"; +- reg = <0x04 0x1c>; +- clocks = <&rcc SAI3_K>; +- clock-names = "sai_ck"; +- dmas = <&dmamux1 113 0x400 0x01>; +- status = "disabled"; +- }; +- +- sai3b: audio-controller@4400c024 { +- #sound-dai-cells = <0>; +- compatible = "st,stm32-sai-sub-b"; +- reg = <0x24 0x1c>; +- clocks = <&rcc SAI3_K>; +- clock-names = "sai_ck"; +- dmas = <&dmamux1 114 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"; +- }; +- +- dfsdm2: filter@2 { +- compatible = "st,stm32-dfsdm-adc"; +- #io-channel-cells = <1>; +- reg = <2>; +- interrupts = ; +- dmas = <&dmamux1 103 0x400 0x01>; +- dma-names = "rx"; +- status = "disabled"; +- }; +- +- dfsdm3: filter@3 { +- compatible = "st,stm32-dfsdm-adc"; +- #io-channel-cells = <1>; +- reg = <3>; +- interrupts = ; +- dmas = <&dmamux1 104 0x400 0x01>; +- dma-names = "rx"; +- status = "disabled"; +- }; +- +- dfsdm4: filter@4 { +- compatible = "st,stm32-dfsdm-adc"; +- #io-channel-cells = <1>; +- reg = <4>; +- interrupts = ; +- dmas = <&dmamux1 91 0x400 0x01>; +- dma-names = "rx"; +- status = "disabled"; +- }; +- +- dfsdm5: filter@5 { +- compatible = "st,stm32-dfsdm-adc"; +- #io-channel-cells = <1>; +- reg = <5>; +- interrupts = ; +- dmas = <&dmamux1 92 0x400 0x01>; +- dma-names = "rx"; +- 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 = <&rcc CK_HSE>, <&rcc FDCAN_K>; +- clock-names = "hclk", "cclk"; +- bosch,mram-cfg = <0x1400 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 = <&rcc CK_HSE>, <&rcc FDCAN_K>; +- clock-names = "hclk", "cclk"; +- bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>; +- status = "disabled"; +- }; +- +- dma1: dma@48000000 { +- compatible = "st,stm32-dma"; +- reg = <0x48000000 0x400>; +- interrupts = , +- , +- , +- , +- , +- , +- , +- ; +- clocks = <&rcc DMA1>; +- #dma-cells = <4>; +- st,mem2mem; +- dma-requests = <8>; +- }; +- +- dma2: dma@48001000 { +- compatible = "st,stm32-dma"; +- reg = <0x48001000 0x400>; +- interrupts = , +- , +- , +- , +- , +- , +- , +- ; +- clocks = <&rcc DMA2>; +- #dma-cells = <4>; +- st,mem2mem; +- dma-requests = <8>; +- }; +- +- dmamux1: dma-router@48002000 { +- compatible = "st,stm32h7-dmamux"; +- reg = <0x48002000 0x1c>; +- #dma-cells = <3>; +- dma-requests = <128>; +- dma-masters = <&dma1 &dma2>; +- dma-channels = <16>; +- clocks = <&rcc DMAMUX>; +- }; +- +- adc: adc@48003000 { +- compatible = "st,stm32mp1-adc-core"; +- reg = <0x48003000 0x400>; +- interrupts = , +- ; +- clocks = <&rcc ADC12>, <&rcc ADC12_K>; +- clock-names = "bus", "adc"; +- interrupt-controller; +- st,syscfg = <&syscfg>; +- #interrupt-cells = <1>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- +- adc1: adc@0 { +- compatible = "st,stm32mp1-adc"; +- #io-channel-cells = <1>; +- reg = <0x0>; +- interrupt-parent = <&adc>; +- interrupts = <0>; +- dmas = <&dmamux1 9 0x400 0x01>; +- dma-names = "rx"; +- status = "disabled"; +- }; +- +- adc2: adc@100 { +- compatible = "st,stm32mp1-adc"; +- #io-channel-cells = <1>; +- reg = <0x100>; +- interrupt-parent = <&adc>; +- interrupts = <1>; +- dmas = <&dmamux1 10 0x400 0x01>; +- dma-names = "rx"; +- status = "disabled"; +- }; +- }; +- +- sdmmc3: sdmmc@48004000 { +- compatible = "arm,pl18x", "arm,primecell"; +- arm,primecell-periphid = <0x10153180>; +- reg = <0x48004000 0x400>; +- reg-names = "sdmmc"; +- interrupts = ; +- clocks = <&rcc SDMMC3_K>; +- clock-names = "apb_pclk"; +- resets = <&rcc SDMMC3_R>; +- cap-sd-highspeed; +- cap-mmc-highspeed; +- max-frequency = <120000000>; +- status = "disabled"; +- }; +- +- usbotg_hs: usb-otg@49000000 { +- compatible = "snps,dwc2"; +- reg = <0x49000000 0x10000>; +- clocks = <&rcc USBO_K>; +- clock-names = "otg"; +- resets = <&rcc USBO_R>; +- reset-names = "dwc2"; +- interrupts = ; +- g-rx-fifo-size = <256>; +- g-np-tx-fifo-size = <32>; +- g-tx-fifo-size = <128 128 64 64 64 64 32 32>; +- dr_mode = "otg"; +- usb33d-supply = <&usb33>; +- status = "disabled"; +- }; +- +- hwspinlock: hwspinlock@4c000000 { +- compatible = "st,stm32-hwspinlock"; +- #hwlock-cells = <1>; +- reg = <0x4c000000 0x400>; +- clocks = <&rcc HSEM>; +- clock-names = "hwspinlock"; +- }; +- +- ipcc: mailbox@4c001000 { +- compatible = "st,stm32mp1-ipcc"; +- #mbox-cells = <1>; +- reg = <0x4c001000 0x400>; +- st,proc-id = <0>; +- interrupts-extended = +- <&intc GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, +- <&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, +- <&exti 61 1>; +- interrupt-names = "rx", "tx", "wakeup"; +- clocks = <&rcc IPCC>; +- wakeup-source; +- status = "disabled"; +- }; +- +- dcmi: dcmi@4c006000 { +- compatible = "st,stm32-dcmi"; +- reg = <0x4c006000 0x400>; +- interrupts = ; +- resets = <&rcc CAMITF_R>; +- clocks = <&rcc DCMI>; +- clock-names = "mclk"; +- dmas = <&dmamux1 75 0x400 0x0d>; +- dma-names = "tx"; +- status = "disabled"; +- }; +- +- rcc: rcc@50000000 { +- compatible = "st,stm32mp1-rcc", "syscon"; +- reg = <0x50000000 0x1000>; +- #clock-cells = <1>; +- #reset-cells = <1>; +- }; +- +- pwr: pwr@50001000 { +- compatible = "st,stm32mp1-pwr", "st,stm32-pwr", "syscon", "simple-mfd"; +- reg = <0x50001000 0x400>; +- system-power-controller; +- interrupts = ; +- st,sysrcc = <&rcc>; +- clocks = <&rcc PLL2_R>; +- clock-names = "phyclk"; +- +- pwr-regulators { +- compatible = "st,stm32mp1,pwr-reg"; +- st,tzcr = <&rcc 0x0 0x1>; +- +- reg11: reg11 { +- regulator-name = "reg11"; +- regulator-min-microvolt = <1100000>; +- regulator-max-microvolt = <1100000>; +- }; +- +- reg18: reg18 { +- regulator-name = "reg18"; +- regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <1800000>; +- }; +- +- usb33: usb33 { +- regulator-name = "usb33"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- }; +- }; +- }; +- +- exti: interrupt-controller@5000d000 { +- compatible = "st,stm32mp1-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>; +- clocks = <&rcc LPTIM2_K>; +- clock-names = "mux"; +- 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"; +- }; +- }; +- +- lptimer3: timer@50022000 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "st,stm32-lptimer"; +- reg = <0x50022000 0x400>; +- clocks = <&rcc LPTIM3_K>; +- clock-names = "mux"; +- status = "disabled"; +- +- pwm { +- compatible = "st,stm32-pwm-lp"; +- #pwm-cells = <3>; +- status = "disabled"; +- }; +- +- trigger@2 { +- compatible = "st,stm32-lptimer-trigger"; +- reg = <2>; +- status = "disabled"; +- }; +- }; +- +- lptimer4: timer@50023000 { +- compatible = "st,stm32-lptimer"; +- reg = <0x50023000 0x400>; +- clocks = <&rcc LPTIM4_K>; +- clock-names = "mux"; +- status = "disabled"; +- +- pwm { +- compatible = "st,stm32-pwm-lp"; +- #pwm-cells = <3>; +- status = "disabled"; +- }; +- }; +- +- lptimer5: timer@50024000 { +- compatible = "st,stm32-lptimer"; +- reg = <0x50024000 0x400>; +- clocks = <&rcc LPTIM5_K>; +- clock-names = "mux"; +- status = "disabled"; +- +- pwm { +- compatible = "st,stm32-pwm-lp"; +- #pwm-cells = <3>; +- status = "disabled"; +- }; +- }; +- +- vrefbuf: vrefbuf@50025000 { +- compatible = "st,stm32-vrefbuf"; +- reg = <0x50025000 0x8>; +- regulator-min-microvolt = <1500000>; +- regulator-max-microvolt = <2500000>; +- clocks = <&rcc VREF>; +- status = "disabled"; +- }; +- +- sai4: sai@50027000 { +- compatible = "st,stm32h7-sai"; +- #address-cells = <1>; +- #size-cells = <1>; +- ranges = <0 0x50027000 0x400>; +- reg = <0x50027000 0x4>, <0x500273f0 0x10>; +- interrupts = ; +- resets = <&rcc SAI4_R>; +- status = "disabled"; +- +- sai4a: audio-controller@50027004 { +- #sound-dai-cells = <0>; +- compatible = "st,stm32-sai-sub-a"; +- reg = <0x04 0x1c>; +- clocks = <&rcc SAI4_K>; +- clock-names = "sai_ck"; +- dmas = <&dmamux1 99 0x400 0x01>; +- status = "disabled"; +- }; +- +- sai4b: audio-controller@50027024 { +- #sound-dai-cells = <0>; +- compatible = "st,stm32-sai-sub-b"; +- reg = <0x24 0x1c>; +- clocks = <&rcc SAI4_K>; +- clock-names = "sai_ck"; +- dmas = <&dmamux1 100 0x400 0x01>; +- status = "disabled"; +- }; +- }; +- +- dts: thermal@50028000 { +- compatible = "st,stm32-thermal"; +- reg = <0x50028000 0x100>; +- interrupts = ; +- clocks = <&rcc TMPSENS>; +- clock-names = "pclk"; +- #thermal-sensor-cells = <0>; +- status = "disabled"; +- }; +- +- cryp1: cryp@54001000 { +- compatible = "st,stm32mp1-cryp"; +- reg = <0x54001000 0x400>; +- interrupts = ; +- clocks = <&rcc CRYP1>; +- resets = <&rcc CRYP1_R>; +- status = "disabled"; +- }; +- +- hash1: hash@54002000 { +- compatible = "st,stm32f756-hash"; +- reg = <0x54002000 0x400>; +- interrupts = ; +- clocks = <&rcc HASH1>; +- resets = <&rcc HASH1_R>; +- dmas = <&mdma1 31 0x10 0x1000A02 0x0 0x0>; +- dma-names = "in"; +- dma-maxburst = <2>; +- status = "disabled"; +- }; +- +- rng1: rng@54003000 { +- compatible = "st,stm32-rng"; +- reg = <0x54003000 0x400>; +- clocks = <&rcc RNG1_K>; +- resets = <&rcc RNG1_R>; +- status = "disabled"; +- }; +- +- mdma1: dma@58000000 { +- compatible = "st,stm32h7-mdma"; +- reg = <0x58000000 0x1000>; +- interrupts = ; +- clocks = <&rcc MDMA>; +- #dma-cells = <5>; +- dma-channels = <32>; +- dma-requests = <48>; +- }; +- +- fmc: nand-controller@58002000 { +- compatible = "st,stm32mp15-fmc2"; +- reg = <0x58002000 0x1000>, +- <0x80000000 0x1000>, +- <0x88010000 0x1000>, +- <0x88020000 0x1000>, +- <0x81000000 0x1000>, +- <0x89010000 0x1000>, +- <0x89020000 0x1000>; +- interrupts = ; +- dmas = <&mdma1 20 0x10 0x12000a02 0x0 0x0>, +- <&mdma1 20 0x10 0x12000a08 0x0 0x0>, +- <&mdma1 21 0x10 0x12000a0a 0x0 0x0>; +- dma-names = "tx", "rx", "ecc"; +- clocks = <&rcc FMC_K>; +- resets = <&rcc FMC_R>; +- status = "disabled"; +- }; +- +- qspi: spi@58003000 { +- compatible = "st,stm32f469-qspi"; +- reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; +- reg-names = "qspi", "qspi_mm"; +- interrupts = ; +- dmas = <&mdma1 22 0x10 0x100002 0x0 0x0>, +- <&mdma1 22 0x10 0x100008 0x0 0x0>; +- dma-names = "tx", "rx"; +- clocks = <&rcc QSPI_K>; +- resets = <&rcc QSPI_R>; +- status = "disabled"; +- }; +- +- sdmmc1: sdmmc@58005000 { +- compatible = "arm,pl18x", "arm,primecell"; +- arm,primecell-periphid = <0x10153180>; +- reg = <0x58005000 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 = <120000000>; +- }; +- +- sdmmc2: sdmmc@58007000 { +- compatible = "arm,pl18x", "arm,primecell"; +- arm,primecell-periphid = <0x10153180>; +- reg = <0x58007000 0x1000>; +- interrupts = ; +- clocks = <&rcc SDMMC2_K>; +- clock-names = "apb_pclk"; +- resets = <&rcc SDMMC2_R>; +- cap-sd-highspeed; +- cap-mmc-highspeed; +- max-frequency = <120000000>; +- 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>; +- }; +- +- ethernet0: ethernet@5800a000 { +- compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; +- reg = <0x5800a000 0x2000>; +- reg-names = "stmmaceth"; +- interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; +- interrupt-names = "macirq"; +- clock-names = "stmmaceth", +- "mac-clk-tx", +- "mac-clk-rx", +- "ethstp", +- "syscfg-clk"; +- clocks = <&rcc ETHMAC>, +- <&rcc ETHTX>, +- <&rcc ETHRX>, +- <&rcc ETHSTP>, +- <&rcc SYSCFG>; +- st,syscon = <&syscfg 0x4>; +- snps,mixed-burst; +- snps,pbl = <2>; +- snps,axi-config = <&stmmac_axi_config_0>; +- snps,tso; +- status = "disabled"; +- }; +- +- usbh_ohci: usbh-ohci@5800c000 { +- compatible = "generic-ohci"; +- reg = <0x5800c000 0x1000>; +- clocks = <&rcc USBH>; +- resets = <&rcc USBH_R>; +- interrupts = ; +- status = "disabled"; +- }; +- +- usbh_ehci: usbh-ehci@5800d000 { +- compatible = "generic-ehci"; +- reg = <0x5800d000 0x1000>; +- clocks = <&rcc USBH>; +- resets = <&rcc USBH_R>; +- interrupts = ; +- companion = <&usbh_ohci>; +- status = "disabled"; +- }; +- +- gpu: gpu@59000000 { +- compatible = "vivante,gc"; +- reg = <0x59000000 0x800>; +- interrupts = ; +- clocks = <&rcc GPU>, <&rcc GPU_K>; +- clock-names = "bus" ,"core"; +- resets = <&rcc GPU_R>; +- status = "disabled"; +- }; +- +- dsi: dsi@5a000000 { +- compatible = "st,stm32-dsi"; +- reg = <0x5a000000 0x800>; +- clocks = <&rcc DSI_K>, <&clk_hse>, <&rcc DSI_PX>; +- clock-names = "pclk", "ref", "px_clk"; +- resets = <&rcc DSI_R>; +- reset-names = "apb"; +- status = "disabled"; +- }; +- +- ltdc: display-controller@5a001000 { +- compatible = "st,stm32-ltdc"; +- reg = <0x5a001000 0x400>; +- interrupts = , +- ; +- clocks = <&rcc LTDC_PX>; +- clock-names = "lcd"; +- resets = <&rcc LTDC_R>; +- status = "disabled"; +- }; +- +- iwdg2: watchdog@5a002000 { +- compatible = "st,stm32mp1-iwdg"; +- reg = <0x5a002000 0x400>; +- clocks = <&rcc IWDG2>, <&rcc CK_LSI>; +- clock-names = "pclk", "lsi"; +- status = "disabled"; +- }; +- +- usbphyc: usbphyc@5a006000 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "st,stm32mp1-usbphyc"; +- reg = <0x5a006000 0x1000>; +- clocks = <&rcc USBPHY_K>; +- resets = <&rcc USBPHY_R>; +- vdda1v1-supply = <®11>; +- vdda1v8-supply = <®18>; +- status = "disabled"; +- +- usbphyc_port0: usb-phy@0 { +- #phy-cells = <0>; +- reg = <0>; +- }; +- +- usbphyc_port1: usb-phy@1 { +- #phy-cells = <1>; +- reg = <1>; +- }; +- }; +- +- usart1: serial@5c000000 { +- compatible = "st,stm32h7-uart"; +- reg = <0x5c000000 0x400>; +- interrupts = ; +- clocks = <&rcc USART1_K>; +- status = "disabled"; +- }; +- +- spi6: spi@5c001000 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "st,stm32h7-spi"; +- reg = <0x5c001000 0x400>; +- interrupts = ; +- clocks = <&rcc SPI6_K>; +- resets = <&rcc SPI6_R>; +- dmas = <&mdma1 34 0x0 0x40008 0x0 0x0>, +- <&mdma1 35 0x0 0x40002 0x0 0x0>; +- dma-names = "rx", "tx"; +- status = "disabled"; +- }; +- +- i2c4: i2c@5c002000 { +- compatible = "st,stm32f7-i2c"; +- reg = <0x5c002000 0x400>; +- interrupt-names = "event", "error"; +- interrupts = , +- ; +- clocks = <&rcc I2C4_K>; +- resets = <&rcc I2C4_R>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- +- rtc: rtc@5c004000 { +- compatible = "st,stm32mp1-rtc"; +- reg = <0x5c004000 0x400>; +- clocks = <&rcc RTCAPB>, <&rcc RTC>; +- clock-names = "pclk", "rtc_ck"; +- interrupts = ; +- status = "disabled"; +- }; +- +- bsec: nvmem@5c005000 { +- compatible = "st,stm32mp15-bsec"; +- reg = <0x5c005000 0x400>; +- #address-cells = <1>; +- #size-cells = <1>; +- ts_cal1: calib@5c { +- reg = <0x5c 0x2>; +- }; +- ts_cal2: calib@5e { +- reg = <0x5e 0x2>; +- }; +- }; +- +- i2c6: i2c@5c009000 { +- compatible = "st,stm32f7-i2c"; +- reg = <0x5c009000 0x400>; +- interrupt-names = "event", "error"; +- interrupts = , +- ; +- clocks = <&rcc I2C6_K>; +- resets = <&rcc I2C6_R>; +- #address-cells = <1>; +- #size-cells = <0>; +- status = "disabled"; +- }; +- }; +- +- mlahb { +- compatible = "simple-bus"; +- #address-cells = <1>; +- #size-cells = <1>; +- dma-ranges = <0x00000000 0x38000000 0x10000>, +- <0x10000000 0x10000000 0x60000>, +- <0x30000000 0x30000000 0x60000>; +- +- m4_rproc: m4@10000000 { +- compatible = "st,stm32mp1-m4"; +- reg = <0x10000000 0x40000>, +- <0x30000000 0x40000>, +- <0x38000000 0x10000>; +- resets = <&rcc MCU_R>; +- st,syscfg-holdboot = <&rcc 0x10C 0x1>; +- st,syscfg-tz = <&rcc 0x000 0x1>; +- status = "disabled"; +- }; +- }; +-}; +diff --git a/arch/arm/dts/stm32mp157d-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157d-dk1-u-boot.dtsi +new file mode 100644 +index 0000000..4f9b7a9 +--- /dev/null ++++ b/arch/arm/dts/stm32mp157d-dk1-u-boot.dtsi +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright : STMicroelectronics 2019 ++ */ ++ ++#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 0000000..c7d65a6 +--- /dev/null ++++ b/arch/arm/dts/stm32mp157d-dk1.dts +@@ -0,0 +1,44 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++/dts-v1/; ++ ++#include "stm32mp157.dtsi" ++#include "stm32mp15xd.dtsi" ++#include "stm32mp15-pinctrl.dtsi" ++#include "stm32mp15xxac-pinctrl.dtsi" ++#include "stm32mp15xx-dkx.dtsi" ++/ { ++ model = "STMicroelectronics STM32MP157D-DK1 Discovery Board"; ++ compatible = "st,stm32mp157d-dk1", "st,stm32mp157"; ++ ++ aliases { ++ ethernet0 = ðernet0; ++ serial0 = &uart4; ++ serial1 = &usart3; ++ serial2 = &uart7; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ reserved-memory { ++ gpu_reserved: gpu@da000000 { ++ reg = <0xda000000 0x4000000>; ++ no-map; ++ }; ++ ++ optee_memory: optee@0xde000000 { ++ reg = <0xde000000 0x02000000>; ++ no-map; ++ }; ++ }; ++}; ++ ++&optee { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/stm32mp157d-ed1-u-boot.dtsi b/arch/arm/dts/stm32mp157d-ed1-u-boot.dtsi +new file mode 100644 +index 0000000..70d9afc +--- /dev/null ++++ b/arch/arm/dts/stm32mp157d-ed1-u-boot.dtsi +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright : STMicroelectronics 2019 ++ */ ++ ++#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 0000000..ee55ac8 +--- /dev/null ++++ b/arch/arm/dts/stm32mp157d-ed1.dts +@@ -0,0 +1,52 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++/dts-v1/; ++ ++#include "stm32mp157.dtsi" ++#include "stm32mp15xd.dtsi" ++#include "stm32mp15-pinctrl.dtsi" ++#include "stm32mp15xxaa-pinctrl.dtsi" ++#include "stm32mp157-m4-srm.dtsi" ++#include "stm32mp157-m4-srm-pinctrl.dtsi" ++#include "stm32mp15xx-edx.dtsi" ++ ++/ { ++ model = "STMicroelectronics STM32MP157D eval daughter"; ++ compatible = "st,stm32mp157d-ed1", "st,stm32mp157"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ serial0 = &uart4; ++ }; ++ ++ reserved-memory { ++ gpu_reserved: gpu@f6000000 { ++ reg = <0xf6000000 0x8000000>; ++ no-map; ++ }; ++ ++ optee_memory: optee@fe000000 { ++ reg = <0xfe000000 0x02000000>; ++ no-map; ++ }; ++ }; ++}; ++ ++&cpu1{ ++ cpu-supply = <&vddcore>; ++}; ++ ++&gpu { ++ contiguous-area = <&gpu_reserved>; ++ status = "okay"; ++}; ++ ++&optee { ++ 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 +index 0000000..77168a4 +--- /dev/null ++++ b/arch/arm/dts/stm32mp157d-ev1-u-boot.dtsi +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright : STMicroelectronics 2019 ++ */ ++ ++#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 0000000..a4752c1 +--- /dev/null ++++ b/arch/arm/dts/stm32mp157d-ev1.dts +@@ -0,0 +1,86 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++/dts-v1/; ++ ++#include "stm32mp157d-ed1.dts" ++#include "stm32mp15xx-evx.dtsi" ++#include ++#include ++ ++/ { ++ model = "STMicroelectronics STM32MP157D eval daughter on eval mother"; ++ compatible = "st,stm32mp157d-ev1", "st,stm32mp157d-ed1", "st,stm32mp157"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ serial1 = &usart3; ++ ethernet0 = ðernet0; ++ }; ++}; ++ ++&dsi { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ dsi_in: endpoint { ++ remote-endpoint = <<dc_ep0_out>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ dsi_out: endpoint { ++ remote-endpoint = <&dsi_panel_in>; ++ }; ++ }; ++ }; ++ ++ panel_dsi: panel-dsi@0 { ++ compatible = "raydium,rm68200"; ++ reg = <0>; ++ reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>; ++ backlight = <&panel_backlight>; ++ power-supply = <&v3v3>; ++ status = "okay"; ++ ++ port { ++ dsi_panel_in: endpoint { ++ remote-endpoint = <&dsi_out>; ++ }; ++ }; ++ }; ++}; ++ ++&i2c2 { ++ gt9147: goodix_ts@5d { ++ compatible = "goodix,gt9147"; ++ reg = <0x5d>; ++ panel = <&panel_dsi>; ++ pinctrl-0 = <&goodix_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ interrupts = <14 IRQ_TYPE_EDGE_RISING>; ++ interrupt-parent = <&stmfx_pinctrl>; ++ }; ++}; ++ ++&m_can1 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&m_can1_pins_a>; ++ pinctrl-1 = <&m_can1_sleep_pins_a>; ++ status = "okay"; ++}; +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 0000000..1bed79c +--- /dev/null ++++ b/arch/arm/dts/stm32mp157f-dk2-u-boot.dtsi +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright : STMicroelectronics 2019 ++ */ ++ ++#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 0000000..b57db30 +--- /dev/null ++++ b/arch/arm/dts/stm32mp157f-dk2.dts +@@ -0,0 +1,185 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++/dts-v1/; ++ ++#include "stm32mp157.dtsi" ++#include "stm32mp15xf.dtsi" ++#include "stm32mp15-pinctrl.dtsi" ++#include "stm32mp15xxac-pinctrl.dtsi" ++#include "stm32mp15xx-dkx.dtsi" ++#include ++ ++/ { ++ model = "STMicroelectronics STM32MP157F-DK2 Discovery Board"; ++ compatible = "st,stm32mp157f-dk2", "st,stm32mp157"; ++ ++ aliases { ++ ethernet0 = ðernet0; ++ serial0 = &uart4; ++ serial1 = &usart3; ++ serial2 = &uart7; ++ serial3 = &usart2; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ reserved-memory { ++ gpu_reserved: gpu@da000000 { ++ reg = <0xda000000 0x4000000>; ++ no-map; ++ }; ++ ++ optee_memory: optee@0xde000000 { ++ reg = <0xde000000 0x02000000>; ++ no-map; ++ status = "disabled"; ++ }; ++ }; ++ ++ wifi_pwrseq: wifi-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ reset-gpios = <&gpioh 4 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&cryp1 { ++ status="okay"; ++}; ++ ++&dsi { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ dsi_in: endpoint { ++ remote-endpoint = <<dc_ep1_out>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ dsi_out: endpoint { ++ remote-endpoint = <&panel_in>; ++ }; ++ }; ++ }; ++ ++ panel_otm8009a: panel-otm8009a@0 { ++ compatible = "orisetech,otm8009a"; ++ reg = <0>; ++ reset-gpios = <&gpioe 4 GPIO_ACTIVE_LOW>; ++ power-supply = <&v3v3>; ++ status = "okay"; ++ ++ port { ++ panel_in: endpoint { ++ remote-endpoint = <&dsi_out>; ++ }; ++ }; ++ }; ++}; ++ ++&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>; ++ status = "okay"; ++ }; ++ touchscreen@38 { ++ compatible = "focaltech,ft6236"; ++ reg = <0x38>; ++ interrupts = <2 2>; ++ interrupt-parent = <&gpiof>; ++ interrupt-controller; ++ touchscreen-size-x = <480>; ++ touchscreen-size-y = <800>; ++ panel = <&panel_otm8009a>; ++ status = "okay"; ++ }; ++}; ++ ++<dc { ++ status = "okay"; ++ ++ port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ltdc_ep1_out: endpoint@1 { ++ reg = <1>; ++ remote-endpoint = <&dsi_in>; ++ }; ++ }; ++}; ++ ++&rtc { ++ st,lsco = ; ++ pinctrl-0 = <&rtc_out2_rmp_pins_a>; ++ pinctrl-names = "default"; ++}; ++ ++/* Wifi */ ++&sdmmc2 { ++ arm,primecell-periphid = <0x10153180>; ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc2_b4_pins_a>; ++ pinctrl-1 = <&sdmmc2_b4_od_pins_a>; ++ pinctrl-2 = <&sdmmc2_b4_sleep_pins_a>; ++ non-removable; ++ st,neg-edge; ++ bus-width = <4>; ++ vmmc-supply = <&v3v3>; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ brcmf: bcrmf@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ }; ++}; ++ ++/* 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 = <&gpioz 6 GPIO_ACTIVE_HIGH>; ++ compatible = "brcm,bcm43438-bt"; ++ max-speed = <3000000>; ++ vbat-supply = <&v3v3>; ++ vddio-supply = <&v3v3>; ++ }; ++}; ++ ++&optee_memory { ++ status = "okay"; ++}; ++ ++&optee { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/stm32mp157f-ed1-u-boot.dtsi b/arch/arm/dts/stm32mp157f-ed1-u-boot.dtsi +new file mode 100644 +index 0000000..2b8d2af +--- /dev/null ++++ b/arch/arm/dts/stm32mp157f-ed1-u-boot.dtsi +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright : STMicroelectronics 2019 ++ */ ++ ++#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 0000000..6538069 +--- /dev/null ++++ b/arch/arm/dts/stm32mp157f-ed1.dts +@@ -0,0 +1,56 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++/dts-v1/; ++ ++#include "stm32mp157.dtsi" ++#include "stm32mp15xf.dtsi" ++#include "stm32mp15-pinctrl.dtsi" ++#include "stm32mp15xxaa-pinctrl.dtsi" ++#include "stm32mp157-m4-srm.dtsi" ++#include "stm32mp157-m4-srm-pinctrl.dtsi" ++#include "stm32mp15xx-edx.dtsi" ++ ++/ { ++ model = "STMicroelectronics STM32MP157F eval daughter"; ++ compatible = "st,stm32mp157f-ed1", "st,stm32mp157"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ serial0 = &uart4; ++ }; ++ ++ reserved-memory { ++ gpu_reserved: gpu@f6000000 { ++ reg = <0xf6000000 0x8000000>; ++ no-map; ++ }; ++ ++ optee_memory: optee@0xfe000000 { ++ reg = <0xfe000000 0x02000000>; ++ no-map; ++ }; ++ }; ++}; ++ ++&cpu1{ ++ cpu-supply = <&vddcore>; ++}; ++ ++&cryp1 { ++ status="okay"; ++}; ++ ++&gpu { ++ contiguous-area = <&gpu_reserved>; ++ status = "okay"; ++}; ++ ++&optee { ++ 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 +index 0000000..0e415a1 +--- /dev/null ++++ b/arch/arm/dts/stm32mp157f-ev1-u-boot.dtsi +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright : STMicroelectronics 2019 ++ */ ++ ++#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 0000000..0c18333 +--- /dev/null ++++ b/arch/arm/dts/stm32mp157f-ev1.dts +@@ -0,0 +1,86 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++/dts-v1/; ++ ++#include "stm32mp157f-ed1.dts" ++#include "stm32mp15xx-evx.dtsi" ++#include ++#include ++ ++/ { ++ model = "STMicroelectronics STM32MP157F eval daughter on eval mother"; ++ compatible = "st,stm32mp157f-ev1", "st,stm32mp157f-ed1", "st,stm32mp157"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ serial1 = &usart3; ++ ethernet0 = ðernet0; ++ }; ++}; ++ ++&dsi { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ dsi_in: endpoint { ++ remote-endpoint = <<dc_ep0_out>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ dsi_out: endpoint { ++ remote-endpoint = <&dsi_panel_in>; ++ }; ++ }; ++ }; ++ ++ panel_dsi: panel-dsi@0 { ++ compatible = "raydium,rm68200"; ++ reg = <0>; ++ reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>; ++ backlight = <&panel_backlight>; ++ power-supply = <&v3v3>; ++ status = "okay"; ++ ++ port { ++ dsi_panel_in: endpoint { ++ remote-endpoint = <&dsi_out>; ++ }; ++ }; ++ }; ++}; ++ ++&i2c2 { ++ gt9147: goodix_ts@5d { ++ compatible = "goodix,gt9147"; ++ reg = <0x5d>; ++ panel = <&panel_dsi>; ++ pinctrl-0 = <&goodix_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ interrupts = <14 IRQ_TYPE_EDGE_RISING>; ++ interrupt-parent = <&stmfx_pinctrl>; ++ }; ++}; ++ ++&m_can1 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&m_can1_pins_a>; ++ pinctrl-1 = <&m_can1_sleep_pins_a>; ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/stm32mp157xaa-pinctrl.dtsi b/arch/arm/dts/stm32mp157xaa-pinctrl.dtsi +deleted file mode 100644 +index 875adf5..0000000 +--- a/arch/arm/dts/stm32mp157xaa-pinctrl.dtsi ++++ /dev/null +@@ -1,90 +0,0 @@ +-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +-/* +- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved +- * Author: Alexandre Torgue +- */ +- +-#include "stm32mp157-pinctrl.dtsi" +-/ { +- soc { +- pinctrl: pin-controller@50002000 { +- st,package = ; +- +- gpioa: gpio@50002000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 0 16>; +- }; +- +- gpiob: gpio@50003000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 16 16>; +- }; +- +- gpioc: gpio@50004000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 32 16>; +- }; +- +- gpiod: gpio@50005000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 48 16>; +- }; +- +- gpioe: gpio@50006000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 64 16>; +- }; +- +- gpiof: gpio@50007000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 80 16>; +- }; +- +- gpiog: gpio@50008000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 96 16>; +- }; +- +- gpioh: gpio@50009000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 112 16>; +- }; +- +- gpioi: gpio@5000a000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 128 16>; +- }; +- +- gpioj: gpio@5000b000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 144 16>; +- }; +- +- gpiok: gpio@5000c000 { +- status = "okay"; +- ngpios = <8>; +- gpio-ranges = <&pinctrl 0 160 8>; +- }; +- }; +- +- pinctrl_z: pin-controller-z@54004000 { +- st,package = ; +- +- gpioz: gpio@54004000 { +- status = "okay"; +- ngpios = <8>; +- gpio-ranges = <&pinctrl_z 0 400 8>; +- }; +- }; +- }; +-}; +diff --git a/arch/arm/dts/stm32mp157xab-pinctrl.dtsi b/arch/arm/dts/stm32mp157xab-pinctrl.dtsi +deleted file mode 100644 +index 961fa12..0000000 +--- a/arch/arm/dts/stm32mp157xab-pinctrl.dtsi ++++ /dev/null +@@ -1,62 +0,0 @@ +-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +-/* +- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved +- * Author: Alexandre Torgue +- */ +- +-#include "stm32mp157-pinctrl.dtsi" +-/ { +- soc { +- pinctrl: pin-controller@50002000 { +- st,package = ; +- +- gpioa: gpio@50002000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 0 16>; +- }; +- +- gpiob: gpio@50003000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 16 16>; +- }; +- +- gpioc: gpio@50004000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 32 16>; +- }; +- +- gpiod: gpio@50005000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 48 16>; +- }; +- +- gpioe: gpio@50006000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 64 16>; +- }; +- +- gpiof: gpio@50007000 { +- status = "okay"; +- ngpios = <6>; +- gpio-ranges = <&pinctrl 6 86 6>; +- }; +- +- gpiog: gpio@50008000 { +- status = "okay"; +- ngpios = <10>; +- gpio-ranges = <&pinctrl 6 102 10>; +- }; +- +- gpioh: gpio@50009000 { +- status = "okay"; +- ngpios = <2>; +- gpio-ranges = <&pinctrl 0 112 2>; +- }; +- }; +- }; +-}; +diff --git a/arch/arm/dts/stm32mp157xac-pinctrl.dtsi b/arch/arm/dts/stm32mp157xac-pinctrl.dtsi +deleted file mode 100644 +index 26600f1..0000000 +--- a/arch/arm/dts/stm32mp157xac-pinctrl.dtsi ++++ /dev/null +@@ -1,78 +0,0 @@ +-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +-/* +- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved +- * Author: Alexandre Torgue +- */ +- +-#include "stm32mp157-pinctrl.dtsi" +-/ { +- soc { +- pinctrl: pin-controller@50002000 { +- st,package = ; +- +- gpioa: gpio@50002000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 0 16>; +- }; +- +- gpiob: gpio@50003000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 16 16>; +- }; +- +- gpioc: gpio@50004000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 32 16>; +- }; +- +- gpiod: gpio@50005000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 48 16>; +- }; +- +- gpioe: gpio@50006000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 64 16>; +- }; +- +- gpiof: gpio@50007000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 80 16>; +- }; +- +- gpiog: gpio@50008000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 96 16>; +- }; +- +- gpioh: gpio@50009000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 112 16>; +- }; +- +- gpioi: gpio@5000a000 { +- status = "okay"; +- ngpios = <12>; +- gpio-ranges = <&pinctrl 0 128 12>; +- }; +- }; +- +- pinctrl_z: pin-controller-z@54004000 { +- st,package = ; +- +- gpioz: gpio@54004000 { +- status = "okay"; +- ngpios = <8>; +- gpio-ranges = <&pinctrl_z 0 400 8>; +- }; +- }; +- }; +-}; +diff --git a/arch/arm/dts/stm32mp157xad-pinctrl.dtsi b/arch/arm/dts/stm32mp157xad-pinctrl.dtsi +deleted file mode 100644 +index 910113f..0000000 +--- a/arch/arm/dts/stm32mp157xad-pinctrl.dtsi ++++ /dev/null +@@ -1,62 +0,0 @@ +-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +-/* +- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved +- * Author: Alexandre Torgue +- */ +- +-#include "stm32mp157-pinctrl.dtsi" +-/ { +- soc { +- pinctrl: pin-controller@50002000 { +- st,package = ; +- +- gpioa: gpio@50002000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 0 16>; +- }; +- +- gpiob: gpio@50003000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 16 16>; +- }; +- +- gpioc: gpio@50004000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 32 16>; +- }; +- +- gpiod: gpio@50005000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 48 16>; +- }; +- +- gpioe: gpio@50006000 { +- status = "okay"; +- ngpios = <16>; +- gpio-ranges = <&pinctrl 0 64 16>; +- }; +- +- gpiof: gpio@50007000 { +- status = "okay"; +- ngpios = <6>; +- gpio-ranges = <&pinctrl 6 86 6>; +- }; +- +- gpiog: gpio@50008000 { +- status = "okay"; +- ngpios = <10>; +- gpio-ranges = <&pinctrl 6 102 10>; +- }; +- +- gpioh: gpio@50009000 { +- status = "okay"; +- ngpios = <2>; +- gpio-ranges = <&pinctrl 0 112 2>; +- }; +- }; +- }; +-}; +diff --git a/arch/arm/dts/stm32mp15xa.dtsi b/arch/arm/dts/stm32mp15xa.dtsi +new file mode 100644 +index 0000000..5ed7e59 +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xa.dtsi +@@ -0,0 +1,13 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++&cpu0_opp_table { ++ opp-650000000 { ++ opp-hz = /bits/ 64 <650000000>; ++ opp-microvolt = <1200000>; ++ opp-supported-hw = <0x1>; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp15xc.dtsi b/arch/arm/dts/stm32mp15xc.dtsi +new file mode 100644 +index 0000000..adc1568 +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xc.dtsi +@@ -0,0 +1,20 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++#include "stm32mp15xa.dtsi" ++ ++/ { ++ soc { ++ cryp1: cryp@54001000 { ++ compatible = "st,stm32mp1-cryp"; ++ reg = <0x54001000 0x400>; ++ interrupts = ; ++ clocks = <&scmi0_clk CK_SCMI0_CRYP1>; ++ resets = <&scmi0_reset RST_SCMI0_CRYP1>; ++ status = "disabled"; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp15xd.dtsi b/arch/arm/dts/stm32mp15xd.dtsi +new file mode 100644 +index 0000000..faa039e +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xd.dtsi +@@ -0,0 +1,42 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++&cpu0_opp_table { ++ opp-800000000 { ++ opp-hz = /bits/ 64 <800000000>; ++ opp-microvolt = <1350000>; ++ opp-supported-hw = <0x2>; ++ }; ++ opp-400000000 { ++ opp-hz = /bits/ 64 <400000000>; ++ opp-microvolt = <1200000>; ++ opp-supported-hw = <0x2>; ++ opp-suspend; ++ }; ++}; ++ ++&cpu_thermal { ++ trips { ++ cpu-crit { ++ temperature = <105000>; ++ hysteresis = <0>; ++ type = "critical"; ++ }; ++ ++ cpu_alert: cpu-alert { ++ temperature = <950000>; ++ hysteresis = <10000>; ++ type = "passive"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&cpu_alert>; ++ cooling-device = <&cpu0 1 1>; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp15xf.dtsi b/arch/arm/dts/stm32mp15xf.dtsi +new file mode 100644 +index 0000000..77f50b9 +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xf.dtsi +@@ -0,0 +1,20 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++#include "stm32mp15xd.dtsi" ++ ++/ { ++ soc { ++ cryp1: cryp@54001000 { ++ compatible = "st,stm32mp1-cryp"; ++ reg = <0x54001000 0x400>; ++ interrupts = ; ++ clocks = <&scmi0_clk CK_SCMI0_CRYP1>; ++ resets = <&scmi0_reset RST_SCMI0_CRYP1>; ++ status = "disabled"; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp15xx-dhcom-pdk2-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcom-pdk2-u-boot.dtsi +new file mode 100644 +index 0000000..12f89b3 +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xx-dhcom-pdk2-u-boot.dtsi +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright (C) 2019 Marek Vasut ++ */ ++ ++#include "stm32mp15xx-dhcom-u-boot.dtsi" +diff --git a/arch/arm/dts/stm32mp15xx-dhcom-pdk2.dts b/arch/arm/dts/stm32mp15xx-dhcom-pdk2.dts +new file mode 100644 +index 0000000..dd98c7a +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xx-dhcom-pdk2.dts +@@ -0,0 +1,88 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright (C) 2019 Marek Vasut ++ */ ++ ++#include "stm32mp15xx-dhcom.dtsi" ++ ++/ { ++ model = "STMicroelectronics STM32MP15xx DHCOM Premium Developer Kit (2)"; ++ compatible = "dh,stm32mp15xx-dhcom-pdk2", "st,stm32mp15x"; ++ ++ aliases { ++ serial0 = &uart4; ++ ethernet0 = ðernet0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ ethernet_vio: vioregulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vio"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ gpio = <&gpiog 3 GPIO_ACTIVE_LOW>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++}; ++ ++ðernet0 { ++ status = "okay"; ++ pinctrl-0 = <ðernet0_rmii_pins_a>; ++ pinctrl-1 = <ðernet0_rmii_pins_sleep_a>; ++ pinctrl-names = "default", "sleep"; ++ phy-mode = "rmii"; ++ max-speed = <100>; ++ phy-handle = <&phy0>; ++ st,eth_ref_clk_sel; ++ phy-reset-gpios = <&gpioh 15 GPIO_ACTIVE_LOW>; ++ ++ mdio0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "snps,dwmac-mdio"; ++ ++ phy0: ethernet-phy@1 { ++ reg = <1>; ++ }; ++ }; ++}; ++ ++&pinctrl { ++ ethernet0_rmii_pins_a: rmii-0 { ++ pins1 { ++ pinmux = , /* ETH1_RMII_TXD0 */ ++ , /* ETH1_RMII_TXD1 */ ++ , /* ETH1_RMII_TX_EN */ ++ , /* ETH1_RMII_REF_CLK */ ++ , /* ETH1_MDIO */ ++ ; /* ETH1_MDC */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <2>; ++ }; ++ pins2 { ++ pinmux = , /* ETH1_RMII_RXD0 */ ++ , /* ETH1_RMII_RXD1 */ ++ ; /* ETH1_RMII_CRS_DV */ ++ bias-disable; ++ }; ++ }; ++ ++ ethernet0_rmii_pins_sleep_a: rmii-sleep-0 { ++ pins1 { ++ pinmux = , /* ETH1_RMII_TXD0 */ ++ , /* ETH1_RMII_TXD1 */ ++ , /* ETH1_RMII_TX_EN */ ++ , /* ETH1_MDIO */ ++ , /* ETH1_MDC */ ++ , /* ETH1_RMII_RXD0 */ ++ , /* ETH1_RMII_RXD1 */ ++ , /* ETH1_RMII_REF_CLK */ ++ ; /* ETH1_RMII_CRS_DV */ ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi +new file mode 100644 +index 0000000..62c45de +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi +@@ -0,0 +1,249 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * Copyright (C) 2019 Marek Vasut ++ */ ++ ++#include ++#include "stm32mp15-u-boot.dtsi" ++#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" ++ ++/ { ++ aliases { ++ i2c1 = &i2c2; ++ i2c3 = &i2c4; ++ i2c4 = &i2c5; ++ mmc0 = &sdmmc1; ++ mmc1 = &sdmmc2; ++ spi0 = &qspi; ++ usb0 = &usbotg_hs; ++ }; ++ ++ config { ++ u-boot,boot-led = "heartbeat"; ++ u-boot,error-led = "error"; ++ st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; ++ st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led { ++ red { ++ label = "error"; ++ gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ status = "okay"; ++ }; ++ ++ blue { ++ default-state = "on"; ++ }; ++ }; ++}; ++ ++&i2c4 { ++ u-boot,dm-pre-reloc; ++}; ++ ++&i2c4_pins_a { ++ u-boot,dm-pre-reloc; ++ pins { ++ u-boot,dm-pre-reloc; ++ }; ++}; ++ ++&pmic { ++ u-boot,dm-pre-reloc; ++}; ++ ++&flash0 { ++ u-boot,dm-spl; ++}; ++ ++&qspi { ++ u-boot,dm-spl; ++}; ++ ++&qspi_clk_pins_a { ++ u-boot,dm-spl; ++ pins { ++ u-boot,dm-spl; ++ }; ++}; ++ ++&qspi_bk1_pins_a { ++ u-boot,dm-spl; ++ pins1 { ++ u-boot,dm-spl; ++ }; ++ pins2 { ++ u-boot,dm-spl; ++ }; ++}; ++ ++&qspi_bk2_pins_a { ++ u-boot,dm-spl; ++ pins1 { ++ u-boot,dm-spl; ++ }; ++ pins2 { ++ u-boot,dm-spl; ++ }; ++}; ++ ++&rcc { ++ st,clksrc = < ++ CLK_MPU_PLL1P ++ CLK_AXI_PLL2P ++ CLK_MCU_PLL3P ++ CLK_PLL12_HSE ++ CLK_PLL3_HSE ++ CLK_PLL4_HSE ++ CLK_RTC_LSE ++ CLK_MCO1_DISABLED ++ CLK_MCO2_DISABLED ++ >; ++ ++ st,clkdiv = < ++ 1 /*MPU*/ ++ 0 /*AXI*/ ++ 0 /*MCU*/ ++ 1 /*APB1*/ ++ 1 /*APB2*/ ++ 1 /*APB3*/ ++ 1 /*APB4*/ ++ 2 /*APB5*/ ++ 23 /*RTC*/ ++ 0 /*MCO1*/ ++ 0 /*MCO2*/ ++ >; ++ ++ st,pkcs = < ++ CLK_CKPER_HSE ++ CLK_FMC_ACLK ++ CLK_QSPI_ACLK ++ CLK_ETH_PLL4P ++ CLK_SDMMC12_PLL4P ++ CLK_DSI_DSIPLL ++ CLK_STGEN_HSE ++ CLK_USBPHY_HSE ++ CLK_SPI2S1_PLL3Q ++ CLK_SPI2S23_PLL3Q ++ CLK_SPI45_HSI ++ CLK_SPI6_HSI ++ CLK_I2C46_HSI ++ CLK_SDMMC3_PLL4P ++ CLK_USBO_USBPHY ++ CLK_ADC_CKPER ++ CLK_CEC_LSE ++ CLK_I2C12_HSI ++ CLK_I2C35_HSI ++ CLK_UART1_HSI ++ CLK_UART24_HSI ++ CLK_UART35_HSI ++ CLK_UART6_HSI ++ CLK_UART78_HSI ++ CLK_SPDIF_PLL4P ++ CLK_FDCAN_PLL4R ++ CLK_SAI1_PLL3Q ++ CLK_SAI2_PLL3Q ++ CLK_SAI3_PLL3Q ++ CLK_SAI4_PLL3Q ++ CLK_RNG1_LSI ++ CLK_RNG2_LSI ++ CLK_LPTIM1_PCLK1 ++ CLK_LPTIM23_PCLK3 ++ CLK_LPTIM45_LSE ++ >; ++ ++ /* VCO = 1300.0 MHz => P = 650 (CPU) */ ++ pll1: st,pll@0 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <0>; ++ cfg = < 2 80 0 0 0 PQR(1,0,0) >; ++ frac = < 0x800 >; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ ++ pll2: st,pll@1 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <1>; ++ cfg = < 2 65 1 0 0 PQR(1,1,1) >; ++ frac = < 0x1400 >; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ ++ pll3: st,pll@2 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <2>; ++ cfg = < 1 33 1 16 36 PQR(1,1,1) >; ++ frac = < 0x1a04 >; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ /* VCO = 600.0 MHz => P = 50, Q = 50, R = 50 */ ++ pll4: st,pll@3 { ++ compatible = "st,stm32mp1-pll"; ++ reg = <3>; ++ cfg = < 1 49 11 11 11 PQR(1,1,1) >; ++ u-boot,dm-pre-reloc; ++ }; ++}; ++ ++&sdmmc1 { ++ u-boot,dm-spl; ++}; ++ ++&sdmmc1_b4_pins_a { ++ u-boot,dm-spl; ++ pins1 { ++ u-boot,dm-spl; ++ }; ++ pins2 { ++ u-boot,dm-spl; ++ }; ++}; ++ ++&sdmmc1_dir_pins_a { ++ u-boot,dm-spl; ++ pins1 { ++ u-boot,dm-spl; ++ }; ++ pins2 { ++ u-boot,dm-spl; ++ }; ++}; ++ ++&sdmmc2 { ++ u-boot,dm-spl; ++}; ++ ++&sdmmc2_b4_pins_a { ++ u-boot,dm-spl; ++ pins { ++ u-boot,dm-spl; ++ }; ++}; ++ ++&sdmmc2_d47_pins_a { ++ u-boot,dm-spl; ++ pins { ++ u-boot,dm-spl; ++ }; ++}; ++ ++&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; ++ /* pull-up on rx to avoid floating level */ ++ bias-pull-up; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp15xx-dhcom.dtsi b/arch/arm/dts/stm32mp15xx-dhcom.dtsi +new file mode 100644 +index 0000000..31da41b +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xx-dhcom.dtsi +@@ -0,0 +1,379 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) 2019 Marek Vasut ++ */ ++/dts-v1/; ++ ++#include "stm32mp157.dtsi" ++#include "stm32mp15xc.dtsi" ++#include "stm32mp15-pinctrl.dtsi" ++#include "stm32mp15xxaa-pinctrl.dtsi" ++#include ++#include ++ ++/ { ++ memory@c0000000 { ++ device_type = "memory"; ++ reg = <0xC0000000 0x40000000>; ++ }; ++}; ++ ++&cec { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cec_pins_a>; ++ status = "okay"; ++}; ++ ++&dcmi { ++ status = "okay"; ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&dcmi_pins_a>; ++ pinctrl-1 = <&dcmi_sleep_pins_a>; ++}; ++ ++&dts { ++ status = "okay"; ++}; ++ ++&i2c2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins_a>; ++ i2c-scl-rising-time-ns = <185>; ++ i2c-scl-falling-time-ns = <20>; ++ status = "okay"; ++}; ++ ++&i2c4 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c4_pins_a>; ++ i2c-scl-rising-time-ns = <185>; ++ i2c-scl-falling-time-ns = <20>; ++ status = "okay"; ++ /* spare dmas for other usage */ ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ ++ pmic: stpmic@33 { ++ compatible = "st,stpmic1"; ++ reg = <0x33>; ++ interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ status = "okay"; ++ ++ regulators { ++ compatible = "st,stpmic1-regulators"; ++ ldo1-supply = <&v3v3>; ++ ldo2-supply = <&v3v3>; ++ ldo3-supply = <&vdd_ddr>; ++ ldo5-supply = <&v3v3>; ++ ldo6-supply = <&v3v3>; ++ pwr_sw1-supply = <&bst_out>; ++ pwr_sw2-supply = <&bst_out>; ++ ++ vddcore: buck1 { ++ regulator-name = "vddcore"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-always-on; ++ regulator-initial-mode = <0>; ++ regulator-over-current-protection; ++ }; ++ ++ vdd_ddr: buck2 { ++ regulator-name = "vdd_ddr"; ++ regulator-min-microvolt = <1350000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-always-on; ++ regulator-initial-mode = <0>; ++ regulator-over-current-protection; ++ }; ++ ++ vdd: buck3 { ++ regulator-name = "vdd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ st,mask-reset; ++ regulator-initial-mode = <0>; ++ regulator-over-current-protection; ++ }; ++ ++ v3v3: buck4 { ++ regulator-name = "v3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-over-current-protection; ++ regulator-initial-mode = <0>; ++ }; ++ ++ vdda: ldo1 { ++ regulator-name = "vdda"; ++ regulator-min-microvolt = <2900000>; ++ regulator-max-microvolt = <2900000>; ++ interrupts = ; ++ }; ++ ++ v2v8: ldo2 { ++ regulator-name = "v2v8"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ interrupts = ; ++ }; ++ ++ vtt_ddr: ldo3 { ++ regulator-name = "vtt_ddr"; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <750000>; ++ regulator-always-on; ++ regulator-over-current-protection; ++ }; ++ ++ vdd_usb: ldo4 { ++ regulator-name = "vdd_usb"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ interrupts = ; ++ }; ++ ++ vdd_sd: ldo5 { ++ regulator-name = "vdd_sd"; ++ regulator-min-microvolt = <2900000>; ++ regulator-max-microvolt = <2900000>; ++ interrupts = ; ++ regulator-boot-on; ++ }; ++ ++ v1v8: ldo6 { ++ regulator-name = "v1v8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ interrupts = ; ++ }; ++ ++ vref_ddr: vref_ddr { ++ regulator-name = "vref_ddr"; ++ regulator-always-on; ++ regulator-over-current-protection; ++ }; ++ ++ bst_out: boost { ++ regulator-name = "bst_out"; ++ interrupts = ; ++ }; ++ ++ vbus_otg: pwr_sw1 { ++ regulator-name = "vbus_otg"; ++ interrupts = ; ++ }; ++ ++ vbus_sw: pwr_sw2 { ++ regulator-name = "vbus_sw"; ++ interrupts = ; ++ regulator-active-discharge; ++ }; ++ }; ++ ++ onkey { ++ compatible = "st,stpmic1-onkey"; ++ interrupts = , ; ++ interrupt-names = "onkey-falling", "onkey-rising"; ++ power-off-time-sec = <10>; ++ status = "okay"; ++ }; ++ ++ watchdog { ++ compatible = "st,stpmic1-wdt"; ++ status = "disabled"; ++ }; ++ }; ++ ++ eeprom@50 { ++ compatible = "atmel,24c02"; ++ reg = <0x50>; ++ pagesize = <16>; ++ }; ++}; ++ ++&i2c5 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c5_pins_a>; ++ i2c-scl-rising-time-ns = <185>; ++ i2c-scl-falling-time-ns = <20>; ++ status = "okay"; ++}; ++ ++&ipcc { ++ status = "okay"; ++}; ++ ++&iwdg2 { ++ timeout-sec = <32>; ++ status = "okay"; ++}; ++ ++&m4_rproc { ++ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; ++ mbox-names = "vq0", "vq1", "shutdown"; ++ status = "okay"; ++}; ++ ++&pwr_regulators { ++ vdd-supply = <&vdd>; ++ vdd_3v3_usbfs-supply = <&vdd_usb>; ++}; ++ ++&qspi { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>; ++ pinctrl-1 = <&qspi_clk_sleep_pins_a &qspi_bk1_sleep_pins_a &qspi_bk2_sleep_pins_a>; ++ reg = <0x58003000 0x1000>, <0x70000000 0x4000000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ flash0: mx66l51235l@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-rx-bus-width = <4>; ++ spi-max-frequency = <108000000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ }; ++ ++ flash1: mx66l51235l@1 { ++ compatible = "jedec,spi-nor"; ++ reg = <1>; ++ spi-rx-bus-width = <4>; ++ spi-max-frequency = <108000000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ }; ++}; ++ ++&rng1 { ++ status = "okay"; ++}; ++ ++&rtc { ++ status = "okay"; ++}; ++ ++&sdmmc1 { ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; ++ pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_dir_pins_a>; ++ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a &sdmmc1_dir_sleep_pins_a>; ++ broken-cd; ++ st,sig-dir; ++ st,neg-edge; ++ st,use-ckin; ++ bus-width = <4>; ++ vmmc-supply = <&vdd_sd>; ++ status = "okay"; ++}; ++ ++&sdmmc2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>; ++ non-removable; ++ no-sd; ++ no-sdio; ++ st,sig-dir; ++ st,neg-edge; ++ bus-width = <8>; ++ vmmc-supply = <&v3v3>; ++ status = "okay"; ++}; ++ ++&spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pins_a>; ++ status = "disabled"; ++}; ++ ++&timers2 { ++ /* spare dmas for other usage (un-delete to enable pwm capture) */ ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm2_pins_a>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ }; ++ timer@1 { ++ status = "okay"; ++ }; ++}; ++ ++&timers6 { ++ status = "okay"; ++ /* spare dmas for other usage */ ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ timer@5 { ++ status = "okay"; ++ }; ++}; ++ ++&timers8 { ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm8_pins_a>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ }; ++ timer@7 { ++ status = "okay"; ++ }; ++}; ++ ++&timers12 { ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm12_pins_a>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ }; ++ timer@11 { ++ status = "okay"; ++ }; ++}; ++ ++&uart4 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_pins_a>; ++ status = "okay"; ++}; ++ ++&usbh_ehci { ++ phys = <&usbphyc_port0>; ++ phy-names = "usb"; ++ status = "okay"; ++}; ++ ++&usbotg_hs { ++ dr_mode = "peripheral"; ++ phys = <&usbphyc_port1 0>; ++ phy-names = "usb2-phy"; ++ vbus-supply = <&vbus_otg>; ++ status = "okay"; ++}; ++ ++&usbphyc { ++ status = "okay"; ++}; ++ ++&usbphyc_port0 { ++ phy-supply = <&vdd_usb>; ++}; ++ ++&usbphyc_port1 { ++ phy-supply = <&vdd_usb>; ++}; +diff --git a/arch/arm/dts/stm32mp15xx-dkx.dtsi b/arch/arm/dts/stm32mp15xx-dkx.dtsi +new file mode 100644 +index 0000000..3516938 +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xx-dkx.dtsi +@@ -0,0 +1,768 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue for STMicroelectronics. ++ */ ++ ++#include "stm32mp157-m4-srm.dtsi" ++#include "stm32mp157-m4-srm-pinctrl.dtsi" ++#include ++ ++/ { ++ memory@c0000000 { ++ device_type = "memory"; ++ reg = <0xc0000000 0x20000000>; ++ }; ++ ++ reserved-memory { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ mcuram2: mcuram2@10000000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10000000 0x40000>; ++ no-map; ++ }; ++ ++ vdev0vring0: vdev0vring0@10040000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10040000 0x1000>; ++ no-map; ++ }; ++ ++ vdev0vring1: vdev0vring1@10041000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10041000 0x1000>; ++ no-map; ++ }; ++ ++ vdev0buffer: vdev0buffer@10042000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10042000 0x4000>; ++ no-map; ++ }; ++ ++ mcuram: mcuram@30000000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x30000000 0x40000>; ++ no-map; ++ }; ++ ++ retram: retram@38000000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x38000000 0x10000>; ++ no-map; ++ }; ++ }; ++ ++ led { ++ compatible = "gpio-leds"; ++ blue { ++ label = "heartbeat"; ++ gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ default-state = "off"; ++ }; ++ }; ++ ++ sound { ++ compatible = "audio-graph-card"; ++ label = "STM32MP1-DK"; ++ routing = ++ "Playback" , "MCLK", ++ "Capture" , "MCLK", ++ "MICL" , "Mic Bias"; ++ 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; ++ }; ++}; ++ ++&adc { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&adc12_ain_pins_a>, <&adc12_usb_cc_pins_a>; ++ vdd-supply = <&vdd>; ++ vdda-supply = <&vdd>; ++ vref-supply = <&vrefbuf>; ++ status = "disabled"; ++ adc1: adc@0 { ++ /* ++ * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in18 & in19. ++ * Use at least 5 * RC time, e.g. 5 * (Rp + Rd) * C: ++ * 5 * (56 + 47kOhms) * 5pF => 2.5us. ++ * 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>; ++ status = "okay"; ++ }; ++ adc2: adc@100 { ++ /* AIN connector, USB Type-C CC1 & CC2 */ ++ st,adc-channels = <0 1 2 6 18 19>; ++ st,min-sample-time-nsecs = <5000>; ++ status = "okay"; ++ }; ++}; ++ ++&cec { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&cec_pins_b>; ++ pinctrl-1 = <&cec_pins_sleep_b>; ++ status = "okay"; ++}; ++ ++&cpu0{ ++ cpu-supply = <&vddcore>; ++}; ++ ++&cpu1{ ++ cpu-supply = <&vddcore>; ++}; ++ ++&crc1 { ++ status = "okay"; ++}; ++ ++&dma1 { ++ sram = <&dma_pool>; ++}; ++ ++&dma2 { ++ sram = <&dma_pool>; ++}; ++ ++&dts { ++ status = "okay"; ++}; ++ ++ðernet0 { ++ status = "okay"; ++ pinctrl-0 = <ðernet0_rgmii_pins_a>; ++ pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; ++ pinctrl-names = "default", "sleep"; ++ phy-mode = "rgmii-id"; ++ max-speed = <1000>; ++ phy-handle = <&phy0>; ++ ++ mdio0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "snps,dwmac-mdio"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++ }; ++}; ++ ++&gpu { ++ contiguous-area = <&gpu_reserved>; ++ status = "okay"; ++}; ++ ++&hash1 { ++ status = "okay"; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&i2c1_pins_a>; ++ pinctrl-1 = <&i2c1_pins_sleep_a>; ++ i2c-scl-rising-time-ns = <100>; ++ i2c-scl-falling-time-ns = <7>; ++ status = "okay"; ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ ++ hdmi-transmitter@39 { ++ compatible = "sil,sii9022"; ++ reg = <0x39>; ++ iovcc-supply = <&v3v3_hdmi>; ++ cvcc12-supply = <&v1v2_hdmi>; ++ reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>; ++ interrupts = <1 IRQ_TYPE_EDGE_FALLING>; ++ interrupt-parent = <&gpiog>; ++ #sound-dai-cells = <0>; ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ sii9022_in: endpoint { ++ remote-endpoint = <<dc_ep0_out>; ++ }; ++ }; ++ ++ port@3 { ++ reg = <3>; ++ sii9022_tx_endpoint: endpoint { ++ remote-endpoint = <&i2s2_endpoint>; ++ }; ++ }; ++ }; ++ }; ++ ++ cs42l51: cs42l51@4a { ++ compatible = "cirrus,cs42l51"; ++ reg = <0x4a>; ++ #sound-dai-cells = <0>; ++ VL-supply = <&v3v3>; ++ VD-supply = <&v1v8_audio>; ++ VA-supply = <&v1v8_audio>; ++ VAHP-supply = <&v1v8_audio>; ++ reset-gpios = <&gpiog 9 GPIO_ACTIVE_LOW>; ++ clocks = <&sai2a>; ++ clock-names = "MCLK"; ++ status = "okay"; ++ ++ cs42l51_port: port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cs42l51_tx_endpoint: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&sai2a_endpoint>; ++ frame-master; ++ bitclock-master; ++ }; ++ ++ cs42l51_rx_endpoint: endpoint@1 { ++ reg = <1>; ++ remote-endpoint = <&sai2b_endpoint>; ++ frame-master; ++ bitclock-master; ++ }; ++ }; ++ }; ++}; ++ ++&i2c4 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&i2c4_pins_a>; ++ pinctrl-1 = <&i2c4_pins_sleep_a>; ++ i2c-scl-rising-time-ns = <185>; ++ i2c-scl-falling-time-ns = <20>; ++ clock-frequency = <400000>; ++ status = "okay"; ++ /* spare dmas for other usage */ ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ ++ stusb1600@28 { ++ compatible = "st,stusb1600"; ++ reg = <0x28>; ++ interrupts = <11 IRQ_TYPE_EDGE_FALLING>; ++ interrupt-parent = <&gpioi>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&stusb1600_pins_a>; ++ status = "okay"; ++ vdd-supply = <&vin>; ++ ++ connector { ++ compatible = "usb-c-connector"; ++ label = "USB-C"; ++ power-role = "dual"; ++ power-opmode = "default"; ++ ++ port { ++ con_usbotg_hs_ep: endpoint { ++ remote-endpoint = <&usbotg_hs_ep>; ++ }; ++ }; ++ }; ++ }; ++ ++ pmic: stpmic@33 { ++ compatible = "st,stpmic1"; ++ reg = <0x33>; ++ interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>; ++ 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>; ++ ++ vddcore: buck1 { ++ regulator-name = "vddcore"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-always-on; ++ regulator-initial-mode = <0>; ++ regulator-over-current-protection; ++ }; ++ ++ vdd_ddr: buck2 { ++ regulator-name = "vdd_ddr"; ++ regulator-min-microvolt = <1350000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-always-on; ++ regulator-initial-mode = <0>; ++ regulator-over-current-protection; ++ }; ++ ++ vdd: buck3 { ++ regulator-name = "vdd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ st,mask-reset; ++ regulator-initial-mode = <0>; ++ regulator-over-current-protection; ++ }; ++ ++ v3v3: buck4 { ++ regulator-name = "v3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-over-current-protection; ++ regulator-initial-mode = <0>; ++ }; ++ ++ v1v8_audio: ldo1 { ++ regulator-name = "v1v8_audio"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ interrupts = ; ++ }; ++ ++ v3v3_hdmi: ldo2 { ++ regulator-name = "v3v3_hdmi"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ interrupts = ; ++ }; ++ ++ vtt_ddr: ldo3 { ++ regulator-name = "vtt_ddr"; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <750000>; ++ regulator-always-on; ++ regulator-over-current-protection; ++ }; ++ ++ vdd_usb: ldo4 { ++ regulator-name = "vdd_usb"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ interrupts = ; ++ regulator-always-on; ++ }; ++ ++ vdda: ldo5 { ++ regulator-name = "vdda"; ++ regulator-min-microvolt = <2900000>; ++ regulator-max-microvolt = <2900000>; ++ interrupts = ; ++ regulator-boot-on; ++ }; ++ ++ v1v2_hdmi: ldo6 { ++ regulator-name = "v1v2_hdmi"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-always-on; ++ interrupts = ; ++ }; ++ ++ vref_ddr: vref_ddr { ++ regulator-name = "vref_ddr"; ++ regulator-always-on; ++ regulator-over-current-protection; ++ }; ++ ++ bst_out: boost { ++ regulator-name = "bst_out"; ++ interrupts = ; ++ }; ++ ++ vbus_otg: pwr_sw1 { ++ regulator-name = "vbus_otg"; ++ interrupts = ; ++ }; ++ ++ vbus_sw: pwr_sw2 { ++ regulator-name = "vbus_sw"; ++ interrupts = ; ++ regulator-active-discharge = <1>; ++ }; ++ }; ++ ++ onkey { ++ compatible = "st,stpmic1-onkey"; ++ interrupts = , ; ++ interrupt-names = "onkey-falling", "onkey-rising"; ++ power-off-time-sec = <10>; ++ status = "okay"; ++ }; ++ ++ watchdog { ++ compatible = "st,stpmic1-wdt"; ++ status = "disabled"; ++ }; ++ }; ++}; ++ ++&i2c5 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&i2c5_pins_a>; ++ pinctrl-1 = <&i2c5_pins_sleep_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"; ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&i2s2_pins_a>; ++ pinctrl-1 = <&i2s2_pins_sleep_a>; ++ status = "okay"; ++ ++ i2s2_port: port { ++ i2s2_endpoint: endpoint { ++ remote-endpoint = <&sii9022_tx_endpoint>; ++ format = "i2s"; ++ mclk-fs = <256>; ++ }; ++ }; ++}; ++ ++&ipcc { ++ status = "okay"; ++}; ++ ++&iwdg2 { ++ timeout-sec = <32>; ++ status = "okay"; ++}; ++ ++<dc { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <<dc_pins_a>; ++ pinctrl-1 = <<dc_pins_sleep_a>; ++ status = "okay"; ++ ++ port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ltdc_ep0_out: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&sii9022_in>; ++ }; ++ }; ++}; ++ ++&m4_rproc { ++ memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, ++ <&vdev0vring1>, <&vdev0buffer>; ++ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; ++ mbox-names = "vq0", "vq1", "shutdown"; ++ interrupt-parent = <&exti>; ++ interrupts = <68 1>; ++ wakeup-source; ++ status = "okay"; ++}; ++ ++&pwr_regulators { ++ vdd-supply = <&vdd>; ++ vdd_3v3_usbfs-supply = <&vdd_usb>; ++}; ++ ++&rng1 { ++ status = "okay"; ++}; ++ ++&rtc { ++ status = "okay"; ++}; ++ ++&sai2 { ++ clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>; ++ clock-names = "pclk", "x8k", "x11k"; ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>; ++ pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>; ++ status = "okay"; ++ ++ sai2a: audio-controller@4400b004 { ++ #clock-cells = <0>; ++ dma-names = "tx"; ++ clocks = <&rcc SAI2_K>; ++ clock-names = "sai_ck"; ++ status = "okay"; ++ ++ sai2a_port: port { ++ sai2a_endpoint: endpoint { ++ remote-endpoint = <&cs42l51_tx_endpoint>; ++ format = "i2s"; ++ mclk-fs = <256>; ++ dai-tdm-slot-num = <2>; ++ dai-tdm-slot-width = <32>; ++ }; ++ }; ++ }; ++ ++ sai2b: audio-controller@4400b024 { ++ dma-names = "rx"; ++ st,sync = <&sai2a 2>; ++ clocks = <&rcc SAI2_K>, <&sai2a>; ++ clock-names = "sai_ck", "MCLK"; ++ status = "okay"; ++ ++ sai2b_port: port { ++ sai2b_endpoint: endpoint { ++ remote-endpoint = <&cs42l51_rx_endpoint>; ++ format = "i2s"; ++ mclk-fs = <256>; ++ dai-tdm-slot-num = <2>; ++ dai-tdm-slot-width = <32>; ++ }; ++ }; ++ }; ++}; ++ ++&sdmmc1 { ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc1_b4_pins_a>; ++ pinctrl-1 = <&sdmmc1_b4_od_pins_a>; ++ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; ++ cd-gpios = <&gpiob 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ disable-wp; ++ st,neg-edge; ++ bus-width = <4>; ++ vmmc-supply = <&v3v3>; ++ status = "okay"; ++}; ++ ++&sdmmc3 { ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc3_b4_pins_a>; ++ pinctrl-1 = <&sdmmc3_b4_od_pins_a>; ++ pinctrl-2 = <&sdmmc3_b4_sleep_pins_a>; ++ broken-cd; ++ st,neg-edge; ++ bus-width = <4>; ++ vmmc-supply = <&v3v3>; ++ status = "disabled"; ++}; ++ ++&spi4 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&spi4_pins_a>; ++ pinctrl-1 = <&spi4_sleep_pins_a>; ++ status = "disabled"; ++}; ++ ++&spi5 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&spi5_pins_a>; ++ pinctrl-1 = <&spi5_sleep_pins_a>; ++ status = "disabled"; ++}; ++ ++&sram { ++ dma_pool: dma_pool@0 { ++ reg = <0x50000 0x10000>; ++ pool; ++ }; ++}; ++ ++&timers1 { ++ /* spare dmas for other usage */ ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm1_pins_a>; ++ pinctrl-1 = <&pwm1_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@0 { ++ status = "okay"; ++ }; ++}; ++ ++&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 &pwm4_pins_b>; ++ pinctrl-1 = <&pwm4_sleep_pins_a &pwm4_sleep_pins_b>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@3 { ++ status = "okay"; ++ }; ++}; ++ ++&timers5 { ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm5_pins_a>; ++ pinctrl-1 = <&pwm5_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@4 { ++ status = "okay"; ++ }; ++}; ++ ++&timers6 { ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ timer@5 { ++ status = "okay"; ++ }; ++}; ++ ++&timers12 { ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm12_pins_a>; ++ pinctrl-1 = <&pwm12_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@11 { ++ 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>; ++ pinctrl-3 = <&uart4_pins_a>; ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "okay"; ++}; ++ ++&uart7 { ++ pinctrl-names = "default", "sleep", "idle"; ++ pinctrl-0 = <&uart7_pins_b>; ++ pinctrl-1 = <&uart7_sleep_pins_b>; ++ pinctrl-2 = <&uart7_idle_pins_b>; ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++}; ++ ++&usart3 { ++ pinctrl-names = "default", "sleep", "idle"; ++ pinctrl-0 = <&usart3_pins_b>; ++ pinctrl-1 = <&usart3_sleep_pins_b>; ++ pinctrl-2 = <&usart3_idle_pins_b>; ++ uart-has-rtscts; ++ status = "disabled"; ++}; ++ ++&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_usbotg_hs_ep>; ++ }; ++ }; ++}; ++ ++&usbphyc { ++ status = "okay"; ++}; ++ ++&usbphyc_port0 { ++ phy-supply = <&vdd_usb>; ++ st,phy-tuning = <&usb_phy_tuning>; ++}; ++ ++&usbphyc_port1 { ++ phy-supply = <&vdd_usb>; ++ st,phy-tuning = <&usb_phy_tuning>; ++}; ++ ++&vrefbuf { ++ regulator-min-microvolt = <2500000>; ++ regulator-max-microvolt = <2500000>; ++ vdda-supply = <&vdd>; ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/stm32mp15xx-edx.dtsi b/arch/arm/dts/stm32mp15xx-edx.dtsi +new file mode 100644 +index 0000000..7ed6b14 +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xx-edx.dtsi +@@ -0,0 +1,408 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved ++ * Author: Ludovic Barre for STMicroelectronics. ++ */ ++ ++#include ++#include ++ ++/ { ++ memory@c0000000 { ++ device_type = "memory"; ++ reg = <0xC0000000 0x40000000>; ++ }; ++ ++ reserved-memory { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ mcuram2: mcuram2@10000000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10000000 0x40000>; ++ no-map; ++ }; ++ ++ vdev0vring0: vdev0vring0@10040000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10040000 0x1000>; ++ no-map; ++ }; ++ ++ vdev0vring1: vdev0vring1@10041000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10041000 0x1000>; ++ no-map; ++ }; ++ ++ vdev0buffer: vdev0buffer@10042000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10042000 0x4000>; ++ no-map; ++ }; ++ ++ mcuram: mcuram@30000000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x30000000 0x40000>; ++ no-map; ++ }; ++ ++ retram: retram@38000000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x38000000 0x10000>; ++ no-map; ++ }; ++ }; ++ ++ led { ++ compatible = "gpio-leds"; ++ blue { ++ label = "heartbeat"; ++ gpios = <&gpiod 9 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ default-state = "off"; ++ }; ++ }; ++ ++ sd_switch: regulator-sd_switch { ++ compatible = "regulator-gpio"; ++ regulator-name = "sd_switch"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <2900000>; ++ regulator-type = "voltage"; ++ regulator-always-on; ++ ++ gpios = <&gpiof 14 GPIO_ACTIVE_HIGH>; ++ gpios-states = <0>; ++ 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 { ++ /* ANA0, ANA1 are dedicated pins and don't need pinctrl: only in6. */ ++ pinctrl-0 = <&adc1_in6_pins_a>; ++ pinctrl-names = "default"; ++ vdd-supply = <&vdd>; ++ vdda-supply = <&vdda>; ++ vref-supply = <&vdda>; ++ status = "disabled"; ++ adc1: adc@0 { ++ st,adc-channels = <0 1 6>; ++ /* 16.5 ck_cycles sampling time */ ++ st,min-sample-time-nsecs = <400>; ++ status = "okay"; ++ }; ++}; ++ ++&cpu0{ ++ cpu-supply = <&vddcore>; ++}; ++ ++&crc1 { ++ status = "okay"; ++}; ++ ++&dac { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&dac_ch1_pins_a &dac_ch2_pins_a>; ++ vref-supply = <&vdda>; ++ status = "disabled"; ++ dac1: dac@1 { ++ status = "okay"; ++ }; ++ dac2: dac@2 { ++ status = "okay"; ++ }; ++}; ++ ++&dma1 { ++ sram = <&dma_pool>; ++}; ++ ++&dma2 { ++ sram = <&dma_pool>; ++}; ++ ++&dts { ++ status = "okay"; ++}; ++ ++&hash1 { ++ status = "okay"; ++}; ++ ++&i2c4 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&i2c4_pins_a>; ++ pinctrl-1 = <&i2c4_pins_sleep_a>; ++ i2c-scl-rising-time-ns = <185>; ++ i2c-scl-falling-time-ns = <20>; ++ clock-frequency = <400000>; ++ status = "okay"; ++ /* spare dmas for other usage */ ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ ++ pmic: stpmic@33 { ++ compatible = "st,stpmic1"; ++ reg = <0x33>; ++ interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>; ++ 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 = <&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>; ++ ++ vddcore: buck1 { ++ regulator-name = "vddcore"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-always-on; ++ regulator-initial-mode = <0>; ++ regulator-over-current-protection; ++ }; ++ ++ vdd_ddr: buck2 { ++ regulator-name = "vdd_ddr"; ++ regulator-min-microvolt = <1350000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-always-on; ++ regulator-initial-mode = <0>; ++ regulator-over-current-protection; ++ }; ++ ++ vdd: buck3 { ++ regulator-name = "vdd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ st,mask-reset; ++ regulator-initial-mode = <0>; ++ regulator-over-current-protection; ++ }; ++ ++ v3v3: buck4 { ++ regulator-name = "v3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-over-current-protection; ++ regulator-initial-mode = <0>; ++ }; ++ ++ vdda: ldo1 { ++ regulator-name = "vdda"; ++ regulator-min-microvolt = <2900000>; ++ regulator-max-microvolt = <2900000>; ++ interrupts = ; ++ }; ++ ++ v2v8: ldo2 { ++ regulator-name = "v2v8"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ interrupts = ; ++ }; ++ ++ vtt_ddr: ldo3 { ++ regulator-name = "vtt_ddr"; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <750000>; ++ regulator-always-on; ++ regulator-over-current-protection; ++ }; ++ ++ vdd_usb: ldo4 { ++ regulator-name = "vdd_usb"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ interrupts = ; ++ regulator-always-on; ++ }; ++ ++ vdd_sd: ldo5 { ++ regulator-name = "vdd_sd"; ++ regulator-min-microvolt = <2900000>; ++ regulator-max-microvolt = <2900000>; ++ interrupts = ; ++ regulator-boot-on; ++ }; ++ ++ v1v8: ldo6 { ++ regulator-name = "v1v8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ interrupts = ; ++ }; ++ ++ vref_ddr: vref_ddr { ++ regulator-name = "vref_ddr"; ++ regulator-always-on; ++ regulator-over-current-protection; ++ }; ++ ++ bst_out: boost { ++ regulator-name = "bst_out"; ++ interrupts = ; ++ }; ++ ++ vbus_otg: pwr_sw1 { ++ regulator-name = "vbus_otg"; ++ interrupts = ; ++ }; ++ ++ vbus_sw: pwr_sw2 { ++ regulator-name = "vbus_sw"; ++ interrupts = ; ++ regulator-active-discharge = <1>; ++ }; ++ }; ++ ++ onkey { ++ compatible = "st,stpmic1-onkey"; ++ interrupts = , ; ++ interrupt-names = "onkey-falling", "onkey-rising"; ++ power-off-time-sec = <10>; ++ status = "okay"; ++ }; ++ ++ watchdog { ++ compatible = "st,stpmic1-wdt"; ++ status = "disabled"; ++ }; ++ }; ++}; ++ ++&ipcc { ++ status = "okay"; ++}; ++ ++&iwdg2 { ++ timeout-sec = <32>; ++ status = "okay"; ++}; ++ ++&m4_rproc { ++ memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, ++ <&vdev0vring1>, <&vdev0buffer>; ++ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; ++ mbox-names = "vq0", "vq1", "shutdown"; ++ interrupt-parent = <&exti>; ++ interrupts = <68 1>; ++ wakeup-source; ++ status = "okay"; ++}; ++ ++&pwr_regulators { ++ vdd-supply = <&vdd>; ++ vdd_3v3_usbfs-supply = <&vdd_usb>; ++}; ++ ++&rng1 { ++ status = "okay"; ++}; ++ ++&rtc { ++ status = "okay"; ++}; ++ ++&sdmmc1 { ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; ++ pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_dir_pins_a>; ++ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a &sdmmc1_dir_sleep_pins_a>; ++ cd-gpios = <&gpiog 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ disable-wp; ++ st,sig-dir; ++ st,neg-edge; ++ st,use-ckin; ++ bus-width = <4>; ++ vmmc-supply = <&vdd_sd>; ++ vqmmc-supply = <&sd_switch>; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-ddr50; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; ++ ++&sdmmc2 { ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>; ++ pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>; ++ pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>; ++ non-removable; ++ no-sd; ++ no-sdio; ++ st,neg-edge; ++ bus-width = <8>; ++ vmmc-supply = <&v3v3>; ++ vqmmc-supply = <&vdd>; ++ mmc-ddr-3_3v; ++ status = "okay"; ++}; ++ ++&sram { ++ dma_pool: dma_pool@0 { ++ reg = <0x50000 0x10000>; ++ pool; ++ }; ++}; ++ ++&timers6 { ++ status = "okay"; ++ /* spare dmas for other usage */ ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ timer@5 { ++ 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>; ++ pinctrl-3 = <&uart4_pins_a>; ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "okay"; ++}; ++ ++&usbotg_hs { ++ vbus-supply = <&vbus_otg>; ++}; ++ ++&usbphyc_port0 { ++ phy-supply = <&vdd_usb>; ++}; ++ ++&usbphyc_port1 { ++ phy-supply = <&vdd_usb>; ++}; +diff --git a/arch/arm/dts/stm32mp15xx-evx.dtsi b/arch/arm/dts/stm32mp15xx-evx.dtsi +new file mode 100644 +index 0000000..07cb93d +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xx-evx.dtsi +@@ -0,0 +1,680 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved ++ * Author: Ludovic Barre for STMicroelectronics. ++ */ ++ ++#include ++#include ++ ++/ { ++ clocks { ++ clk_ext_camera: clk-ext-camera { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <24000000>; ++ }; ++ }; ++ ++ joystick { ++ compatible = "gpio-keys"; ++ #size-cells = <0>; ++ pinctrl-0 = <&joystick_pins>; ++ pinctrl-names = "default"; ++ button-0 { ++ label = "JoySel"; ++ linux,code = ; ++ interrupt-parent = <&stmfx_pinctrl>; ++ interrupts = <0 IRQ_TYPE_EDGE_RISING>; ++ }; ++ button-1 { ++ label = "JoyDown"; ++ linux,code = ; ++ interrupt-parent = <&stmfx_pinctrl>; ++ interrupts = <1 IRQ_TYPE_EDGE_RISING>; ++ }; ++ button-2 { ++ label = "JoyLeft"; ++ linux,code = ; ++ interrupt-parent = <&stmfx_pinctrl>; ++ interrupts = <2 IRQ_TYPE_EDGE_RISING>; ++ }; ++ button-3 { ++ label = "JoyRight"; ++ linux,code = ; ++ interrupt-parent = <&stmfx_pinctrl>; ++ interrupts = <3 IRQ_TYPE_EDGE_RISING>; ++ }; ++ button-4 { ++ label = "JoyUp"; ++ 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"; ++ }; ++ ++ spdif_out: spdif-out { ++ #sound-dai-cells = <0>; ++ compatible = "linux,spdif-dit"; ++ status = "okay"; ++ ++ spdif_out_port: port { ++ spdif_out_endpoint: endpoint { ++ remote-endpoint = <&sai4a_endpoint>; ++ }; ++ }; ++ }; ++ ++ spdif_in: spdif-in { ++ #sound-dai-cells = <0>; ++ compatible = "linux,spdif-dir"; ++ status = "okay"; ++ ++ spdif_in_port: port { ++ spdif_in_endpoint: endpoint { ++ remote-endpoint = <&spdifrx_endpoint>; ++ }; ++ }; ++ }; ++ ++ sound { ++ compatible = "audio-graph-card"; ++ label = "STM32MP1-EV"; ++ routing = ++ "AIF1CLK" , "MCLK1", ++ "AIF2CLK" , "MCLK1", ++ "IN1LN" , "MICBIAS2", ++ "DMIC2DAT" , "MICBIAS1", ++ "DMIC1DAT" , "MICBIAS1"; ++ dais = <&sai2a_port &sai2b_port &sai4a_port &spdifrx_port ++ &dfsdm0_port &dfsdm1_port &dfsdm2_port &dfsdm3_port>; ++ status = "okay"; ++ }; ++ ++ dmic0: dmic-0 { ++ compatible = "dmic-codec"; ++ #sound-dai-cells = <1>; ++ sound-name-prefix = "dmic0"; ++ status = "okay"; ++ ++ port { ++ dmic0_endpoint: endpoint { ++ remote-endpoint = <&dfsdm_endpoint0>; ++ }; ++ }; ++ }; ++ ++ dmic1: dmic-1 { ++ compatible = "dmic-codec"; ++ #sound-dai-cells = <1>; ++ sound-name-prefix = "dmic1"; ++ status = "okay"; ++ ++ port { ++ dmic1_endpoint: endpoint { ++ remote-endpoint = <&dfsdm_endpoint1>; ++ }; ++ }; ++ }; ++ ++ dmic2: dmic-2 { ++ compatible = "dmic-codec"; ++ #sound-dai-cells = <1>; ++ sound-name-prefix = "dmic2"; ++ status = "okay"; ++ ++ port { ++ dmic2_endpoint: endpoint { ++ remote-endpoint = <&dfsdm_endpoint2>; ++ }; ++ }; ++ }; ++ ++ dmic3: dmic-3 { ++ compatible = "dmic-codec"; ++ #sound-dai-cells = <1>; ++ sound-name-prefix = "dmic3"; ++ status = "okay"; ++ ++ port { ++ dmic3_endpoint: endpoint { ++ remote-endpoint = <&dfsdm_endpoint3>; ++ }; ++ }; ++ }; ++ ++ 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 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cec_pins_a>; ++ status = "okay"; ++}; ++ ++&dcmi { ++ status = "okay"; ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&dcmi_pins_a>; ++ pinctrl-1 = <&dcmi_sleep_pins_a>; ++ ++ port { ++ dcmi_0: endpoint { ++ remote-endpoint = <&ov5640_0>; ++ bus-width = <8>; ++ hsync-active = <0>; ++ vsync-active = <0>; ++ pclk-sample = <1>; ++ pclk-max-frequency = <77000000>; ++ }; ++ }; ++}; ++ ++&dfsdm { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&dfsdm_clkout_pins_a ++ &dfsdm_data1_pins_a &dfsdm_data3_pins_a>; ++ pinctrl-1 = <&dfsdm_clkout_sleep_pins_a ++ &dfsdm_data1_sleep_pins_a &dfsdm_data3_sleep_pins_a>; ++ spi-max-frequency = <2048000>; ++ ++ clocks = <&rcc DFSDM_K>, <&rcc ADFSDM_K>; ++ clock-names = "dfsdm", "audio"; ++ status = "okay"; ++ ++ dfsdm0: filter@0 { ++ compatible = "st,stm32-dfsdm-dmic"; ++ st,adc-channels = <3>; ++ st,adc-channel-names = "dmic_u1"; ++ st,adc-channel-types = "SPI_R"; ++ st,adc-channel-clk-src = "CLKOUT"; ++ st,filter-order = <3>; ++ status = "okay"; ++ ++ asoc_pdm0: dfsdm-dai { ++ compatible = "st,stm32h7-dfsdm-dai"; ++ #sound-dai-cells = <0>; ++ io-channels = <&dfsdm0 0>; ++ status = "okay"; ++ ++ dfsdm0_port: port { ++ dfsdm_endpoint0: endpoint { ++ remote-endpoint = <&dmic0_endpoint>; ++ }; ++ }; ++ }; ++ }; ++ ++ dfsdm1: filter@1 { ++ compatible = "st,stm32-dfsdm-dmic"; ++ st,adc-channels = <1>; ++ st,adc-channel-names = "dmic_u2"; ++ st,adc-channel-types = "SPI_F"; ++ st,adc-channel-clk-src = "CLKOUT"; ++ st,filter-order = <3>; ++ status = "okay"; ++ ++ asoc_pdm1: dfsdm-dai { ++ compatible = "st,stm32h7-dfsdm-dai"; ++ #sound-dai-cells = <0>; ++ io-channels = <&dfsdm1 0>; ++ status = "okay"; ++ ++ dfsdm1_port: port { ++ dfsdm_endpoint1: endpoint { ++ remote-endpoint = <&dmic1_endpoint>; ++ }; ++ }; ++ }; ++ }; ++ ++ dfsdm2: filter@2 { ++ compatible = "st,stm32-dfsdm-dmic"; ++ st,adc-channels = <3>; ++ st,adc-channel-names = "dmic_u3"; ++ st,adc-channel-types = "SPI_F"; ++ st,adc-channel-clk-src = "CLKOUT"; ++ st,filter-order = <3>; ++ status = "okay"; ++ ++ asoc_pdm2: dfsdm-dai { ++ compatible = "st,stm32h7-dfsdm-dai"; ++ #sound-dai-cells = <0>; ++ io-channels = <&dfsdm2 0>; ++ status = "okay"; ++ ++ dfsdm2_port: port { ++ dfsdm_endpoint2: endpoint { ++ remote-endpoint = <&dmic2_endpoint>; ++ }; ++ }; ++ }; ++ }; ++ ++ dfsdm3: filter@3 { ++ compatible = "st,stm32-dfsdm-dmic"; ++ st,adc-channels = <1>; ++ st,adc-channel-names = "dmic_u4"; ++ st,adc-channel-types = "SPI_R"; ++ st,adc-channel-clk-src = "CLKOUT"; ++ st,filter-order = <3>; ++ status = "okay"; ++ ++ asoc_pdm3: dfsdm-dai { ++ compatible = "st,stm32h7-dfsdm-dai"; ++ #sound-dai-cells = <0>; ++ io-channels = <&dfsdm3 0>; ++ status = "okay"; ++ ++ dfsdm3_port: port { ++ dfsdm_endpoint3: endpoint { ++ remote-endpoint = <&dmic3_endpoint>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++ðernet0 { ++ status = "okay"; ++ pinctrl-0 = <ðernet0_rgmii_pins_a>; ++ pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; ++ pinctrl-names = "default", "sleep"; ++ phy-mode = "rgmii-id"; ++ max-speed = <1000>; ++ phy-handle = <&phy0>; ++ ++ mdio0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "snps,dwmac-mdio"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++ }; ++}; ++ ++&fmc { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&fmc_pins_a>; ++ pinctrl-1 = <&fmc_sleep_pins_a>; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ nand@0 { ++ reg = <0>; ++ nand-on-flash-bbt; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ }; ++}; ++ ++&hdp { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&hdp0_pins_a &hdp6_pins_a &hdp7_pins_a>; ++ pinctrl-1 = <&hdp0_pins_sleep_a &hdp6_pins_sleep_a &hdp7_pins_sleep_a>; ++ status = "disabled"; ++ ++ muxing-hdp = <(STM32_HDP(0, HDP0_GPOVAL_0) | ++ STM32_HDP(6, HDP6_GPOVAL_6) | ++ STM32_HDP(7, HDP7_GPOVAL_7))>; ++}; ++ ++&i2c2 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&i2c2_pins_a>; ++ pinctrl-1 = <&i2c2_pins_sleep_a>; ++ i2c-scl-rising-time-ns = <185>; ++ i2c-scl-falling-time-ns = <20>; ++ status = "okay"; ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ ++ wm8994: wm8994@1b { ++ compatible = "wlf,wm8994"; ++ #sound-dai-cells = <0>; ++ reg = <0x1b>; ++ status = "okay"; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ DBVDD-supply = <&vdd>; ++ SPKVDD1-supply = <&vdd>; ++ SPKVDD2-supply = <&vdd>; ++ AVDD2-supply = <&v1v8>; ++ CPVDD-supply = <&v1v8>; ++ ++ wlf,ldoena-always-driven; ++ ++ clocks = <&sai2a>; ++ clock-names = "MCLK1"; ++ ++ wlf,gpio-cfg = <0x8101 0xa100 0xa100 0xa100 0xa101 0xa101 0xa100 0xa101 0xa101 0xa101 0xa101>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ wm8994_tx_port: port@0 { ++ reg = <0>; ++ wm8994_tx_endpoint: endpoint { ++ remote-endpoint = <&sai2a_endpoint>; ++ }; ++ }; ++ ++ wm8994_rx_port: port@1 { ++ reg = <1>; ++ wm8994_rx_endpoint: endpoint { ++ remote-endpoint = <&sai2b_endpoint>; ++ }; ++ }; ++ }; ++ }; ++ ++ ov5640: camera@3c { ++ compatible = "ovti,ov5640"; ++ reg = <0x3c>; ++ clocks = <&clk_ext_camera>; ++ clock-names = "xclk"; ++ DOVDD-supply = <&v2v8>; ++ 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"; ++ ++ port { ++ ov5640_0: endpoint { ++ remote-endpoint = <&dcmi_0>; ++ bus-width = <8>; ++ data-shift = <2>; /* lines 9:2 are used */ ++ hsync-active = <0>; ++ vsync-active = <0>; ++ pclk-sample = <1>; ++ pclk-max-frequency = <77000000>; ++ }; ++ }; ++ }; ++ ++ stmfx: stmfx@42 { ++ compatible = "st,stmfx-0300"; ++ reg = <0x42>; ++ interrupts = <8 IRQ_TYPE_EDGE_RISING>; ++ interrupt-parent = <&gpioi>; ++ vdd-supply = <&v3v3>; ++ ++ stmfx_pinctrl: stmfx-pin-controller { ++ compatible = "st,stmfx-0300-pinctrl"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ gpio-ranges = <&stmfx_pinctrl 0 0 24>; ++ ++ goodix_pins: goodix { ++ pins = "gpio14"; ++ bias-pull-down; ++ }; ++ ++ joystick_pins: joystick { ++ pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4"; ++ bias-pull-down; ++ }; ++ }; ++ }; ++}; ++ ++&i2c4 { ++ pmic: stpmic@33 { ++ regulators { ++ v1v8: ldo6 { ++ regulator-enable-ramp-delay = <300000>; ++ }; ++ }; ++ }; ++}; ++ ++&i2c5 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&i2c5_pins_a>; ++ pinctrl-1 = <&i2c5_pins_sleep_a>; ++ i2c-scl-rising-time-ns = <185>; ++ i2c-scl-falling-time-ns = <20>; ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "okay"; ++}; ++ ++<dc { ++ status = "okay"; ++ ++ port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ltdc_ep0_out: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&dsi_in>; ++ }; ++ }; ++}; ++ ++&qspi { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>; ++ pinctrl-1 = <&qspi_clk_sleep_pins_a &qspi_bk1_sleep_pins_a &qspi_bk2_sleep_pins_a>; ++ reg = <0x58003000 0x1000>, <0x70000000 0x4000000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ flash0: mx66l51235l@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-rx-bus-width = <4>; ++ spi-max-frequency = <108000000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ }; ++ ++ flash1: mx66l51235l@1 { ++ compatible = "jedec,spi-nor"; ++ reg = <1>; ++ spi-rx-bus-width = <4>; ++ spi-max-frequency = <108000000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ }; ++}; ++ ++&sai2 { ++ clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>; ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_a>; ++ pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_a>; ++ clock-names = "pclk", "x8k", "x11k"; ++ status = "okay"; ++ ++ sai2a: audio-controller@4400b004 { ++ #clock-cells = <0>; ++ dma-names = "tx"; ++ clocks = <&rcc SAI2_K>; ++ clock-names = "sai_ck"; ++ status = "okay"; ++ ++ sai2a_port: port { ++ sai2a_endpoint: endpoint { ++ remote-endpoint = <&wm8994_tx_endpoint>; ++ format = "i2s"; ++ mclk-fs = <256>; ++ }; ++ }; ++ }; ++ ++ sai2b: audio-controller@4400b024 { ++ dma-names = "rx"; ++ clocks = <&rcc SAI2_K>, <&sai2a>; ++ clock-names = "sai_ck", "MCLK"; ++ status = "okay"; ++ ++ sai2b_port: port { ++ sai2b_endpoint: endpoint { ++ remote-endpoint = <&wm8994_rx_endpoint>; ++ format = "i2s"; ++ mclk-fs = <256>; ++ }; ++ }; ++ }; ++}; ++ ++&sai4 { ++ clocks = <&rcc SAI4>, <&rcc PLL3_Q>, <&rcc PLL3_R>; ++ clock-names = "pclk", "x8k", "x11k"; ++ status = "okay"; ++ ++ sai4a: audio-controller@50027004 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&sai4a_pins_a>; ++ pinctrl-1 = <&sai4a_sleep_pins_a>; ++ dma-names = "tx"; ++ clocks = <&rcc SAI4_K>; ++ clock-names = "sai_ck"; ++ st,iec60958; ++ status = "okay"; ++ ++ sai4a_port: port { ++ sai4a_endpoint: endpoint { ++ remote-endpoint = <&spdif_out_endpoint>; ++ }; ++ }; ++ }; ++}; ++ ++&sdmmc3 { ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc3_b4_pins_a>; ++ pinctrl-1 = <&sdmmc3_b4_od_pins_a>; ++ pinctrl-2 = <&sdmmc3_b4_sleep_pins_a>; ++ vmmc-supply = <&v3v3>; ++ broken-cd; ++ st,neg-edge; ++ bus-width = <4>; ++ status = "disabled"; ++}; ++ ++&spdifrx { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&spdifrx_pins_a>; ++ pinctrl-1 = <&spdifrx_sleep_pins_a>; ++ status = "okay"; ++ ++ spdifrx_port: port { ++ spdifrx_endpoint: endpoint { ++ remote-endpoint = <&spdif_in_endpoint>; ++ }; ++ }; ++}; ++ ++&spi1 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&spi1_pins_a>; ++ pinctrl-1 = <&spi1_sleep_pins_a>; ++ status = "disabled"; ++}; ++ ++&timers2 { ++ /* spare dmas for other usage (un-delete to enable pwm capture) */ ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm2_pins_a>; ++ pinctrl-1 = <&pwm2_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@1 { ++ 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"; ++ }; ++}; ++ ++&timers12 { ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ status = "disabled"; ++ pwm { ++ pinctrl-0 = <&pwm12_pins_a>; ++ pinctrl-1 = <&pwm12_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ status = "okay"; ++ }; ++ timer@11 { ++ status = "okay"; ++ }; ++}; ++ ++&usart3 { ++ pinctrl-names = "default", "sleep", "idle"; ++ pinctrl-0 = <&usart3_pins_a>; ++ pinctrl-1 = <&usart3_sleep_pins_a>; ++ pinctrl-2 = <&usart3_idle_pins_a>; ++ uart-has-rtscts; ++ status = "disabled"; ++}; ++ ++&usbh_ehci { ++ phys = <&usbphyc_port0>; ++ status = "okay"; ++}; ++ ++&usbotg_hs { ++ pinctrl-0 = <&usbotg_hs_pins_a>; ++ pinctrl-names = "default"; ++ phys = <&usbphyc_port1 0>; ++ phy-names = "usb2-phy"; ++ status = "okay"; ++}; ++ ++&usbphyc { ++ status = "okay"; ++}; ++ ++&usbphyc_port0 { ++ st,phy-tuning = <&usb_phy_tuning>; ++}; ++ ++&usbphyc_port1 { ++ st,phy-tuning = <&usb_phy_tuning>; ++}; +diff --git a/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi b/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi +new file mode 100644 +index 0000000..64e566b +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi +@@ -0,0 +1,85 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue ++ */ ++ ++&pinctrl { ++ st,package = ; ++ ++ gpioa: gpio@50002000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 0 16>; ++ }; ++ ++ gpiob: gpio@50003000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 16 16>; ++ }; ++ ++ gpioc: gpio@50004000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 32 16>; ++ }; ++ ++ gpiod: gpio@50005000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 48 16>; ++ }; ++ ++ gpioe: gpio@50006000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 64 16>; ++ }; ++ ++ gpiof: gpio@50007000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 80 16>; ++ }; ++ ++ gpiog: gpio@50008000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 96 16>; ++ }; ++ ++ gpioh: gpio@50009000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 112 16>; ++ }; ++ ++ gpioi: gpio@5000a000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 128 16>; ++ }; ++ ++ gpioj: gpio@5000b000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 144 16>; ++ }; ++ ++ gpiok: gpio@5000c000 { ++ status = "okay"; ++ ngpios = <8>; ++ gpio-ranges = <&pinctrl 0 160 8>; ++ }; ++}; ++ ++&pinctrl_z { ++ st,package = ; ++ ++ gpioz: gpio@54004000 { ++ status = "okay"; ++ ngpios = <8>; ++ gpio-ranges = <&pinctrl_z 0 400 8>; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi b/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi +new file mode 100644 +index 0000000..d29af89 +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi +@@ -0,0 +1,57 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue ++ */ ++ ++&pinctrl { ++ st,package = ; ++ ++ gpioa: gpio@50002000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 0 16>; ++ }; ++ ++ gpiob: gpio@50003000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 16 16>; ++ }; ++ ++ gpioc: gpio@50004000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 32 16>; ++ }; ++ ++ gpiod: gpio@50005000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 48 16>; ++ }; ++ ++ gpioe: gpio@50006000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 64 16>; ++ }; ++ ++ gpiof: gpio@50007000 { ++ status = "okay"; ++ ngpios = <6>; ++ gpio-ranges = <&pinctrl 6 86 6>; ++ }; ++ ++ gpiog: gpio@50008000 { ++ status = "okay"; ++ ngpios = <10>; ++ gpio-ranges = <&pinctrl 6 102 10>; ++ }; ++ ++ gpioh: gpio@50009000 { ++ status = "okay"; ++ ngpios = <2>; ++ gpio-ranges = <&pinctrl 0 112 2>; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi b/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi +new file mode 100644 +index 0000000..5d8199f +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi +@@ -0,0 +1,73 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue ++ */ ++ ++&pinctrl { ++ st,package = ; ++ ++ gpioa: gpio@50002000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 0 16>; ++ }; ++ ++ gpiob: gpio@50003000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 16 16>; ++ }; ++ ++ gpioc: gpio@50004000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 32 16>; ++ }; ++ ++ gpiod: gpio@50005000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 48 16>; ++ }; ++ ++ gpioe: gpio@50006000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 64 16>; ++ }; ++ ++ gpiof: gpio@50007000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 80 16>; ++ }; ++ ++ gpiog: gpio@50008000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 96 16>; ++ }; ++ ++ gpioh: gpio@50009000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 112 16>; ++ }; ++ ++ gpioi: gpio@5000a000 { ++ status = "okay"; ++ ngpios = <12>; ++ gpio-ranges = <&pinctrl 0 128 12>; ++ }; ++}; ++ ++&pinctrl_z { ++ st,package = ; ++ ++ gpioz: gpio@54004000 { ++ status = "okay"; ++ ngpios = <8>; ++ gpio-ranges = <&pinctrl_z 0 400 8>; ++ }; ++}; +diff --git a/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi b/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi +new file mode 100644 +index 0000000..023f540 +--- /dev/null ++++ b/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi +@@ -0,0 +1,57 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved ++ * Author: Alexandre Torgue ++ */ ++ ++&pinctrl { ++ st,package = ; ++ ++ gpioa: gpio@50002000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 0 16>; ++ }; ++ ++ gpiob: gpio@50003000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 16 16>; ++ }; ++ ++ gpioc: gpio@50004000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 32 16>; ++ }; ++ ++ gpiod: gpio@50005000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 48 16>; ++ }; ++ ++ gpioe: gpio@50006000 { ++ status = "okay"; ++ ngpios = <16>; ++ gpio-ranges = <&pinctrl 0 64 16>; ++ }; ++ ++ gpiof: gpio@50007000 { ++ status = "okay"; ++ ngpios = <6>; ++ gpio-ranges = <&pinctrl 6 86 6>; ++ }; ++ ++ gpiog: gpio@50008000 { ++ status = "okay"; ++ ngpios = <10>; ++ gpio-ranges = <&pinctrl 6 102 10>; ++ }; ++ ++ gpioh: gpio@50009000 { ++ status = "okay"; ++ ngpios = <2>; ++ gpio-ranges = <&pinctrl 0 112 2>; ++ }; ++}; +-- +2.7.4 + diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0005-ARM-v2018.11-stm32mp-r1-MISC.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0005-ARM-v2018.11-stm32mp-r1-MISC.patch deleted file mode 100644 index 637a319..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0005-ARM-v2018.11-stm32mp-r1-MISC.patch +++ /dev/null @@ -1,18320 +0,0 @@ -From f8fe203c145990d107dac84bf2bf441237bc5b17 Mon Sep 17 00:00:00 2001 -From: christophe montaud -Date: Fri, 4 Jan 2019 15:09:10 +0100 -Subject: [PATCH 5/5] ARM v2018.11 stm32mp r1 MISC - ---- - .gitignore | 3 + - MAINTAINERS | 2 + - Makefile | 2 +- - arch/sandbox/include/asm/state.h | 1 + - cmd/Kconfig | 8 + - cmd/Makefile | 1 + - cmd/adc.c | 70 +- - cmd/bmp.c | 18 +- - cmd/pinmux.c | 146 +++ - cmd/pxe.c | 24 + - cmd/remoteproc.c | 62 +- - cmd/usb_mass_storage.c | 3 + - common/Makefile | 1 + - common/board_f.c | 3 +- - common/image.c | 1 + - common/spl/spl_spi.c | 9 +- - common/usb.c | 2 + - drivers/Kconfig | 2 + - drivers/Makefile | 1 + - drivers/adc/adc-uclass.c | 54 +- - drivers/clk/clk_stm32mp1.c | 271 ++++- - drivers/core/syscon-uclass.c | 61 +- - drivers/core/uclass.c | 13 + - drivers/dfu/Kconfig | 5 + - drivers/dfu/Makefile | 1 + - drivers/dfu/dfu.c | 84 +- - drivers/dfu/dfu_sf.c | 54 +- - drivers/dfu/dfu_virt.c | 47 + - drivers/gpio/stm32f7_gpio.c | 120 ++- - drivers/hwspinlock/Kconfig | 24 + - drivers/hwspinlock/Makefile | 7 + - drivers/hwspinlock/hwspinlock-uclass.c | 144 +++ - drivers/hwspinlock/sandbox_hwspinlock.c | 56 + - drivers/hwspinlock/stm32_hwspinlock.c | 90 ++ - drivers/i2c/stm32f7_i2c.c | 41 +- - drivers/mailbox/Kconfig | 7 + - drivers/mailbox/Makefile | 1 + - drivers/mailbox/stm32-ipcc.c | 187 ++++ - drivers/misc/stm32mp_fuse.c | 28 + - drivers/mmc/mmc_write.c | 2 +- - drivers/mmc/stm32_sdmmc2.c | 67 +- - drivers/mtd/nand/raw/Kconfig | 11 + - drivers/mtd/nand/raw/Makefile | 1 + - drivers/mtd/nand/raw/nand_ids.c | 4 + - drivers/mtd/nand/raw/stm32_fmc2_nand.c | 1092 +++++++++++++++++++ - drivers/mtd/spi/spi_flash.c | 9 + - drivers/net/dwc_eth_qos.c | 451 ++++++-- - drivers/phy/phy-stm32-usbphyc.c | 201 ++-- - drivers/pinctrl/Kconfig | 19 + - drivers/pinctrl/Makefile | 1 + - drivers/pinctrl/pinctrl-sandbox.c | 18 + - drivers/pinctrl/pinctrl-stmfx.c | 414 ++++++++ - drivers/pinctrl/pinctrl-uclass.c | 39 +- - drivers/pinctrl/pinctrl_stm32.c | 252 ++++- - drivers/power/pmic/Kconfig | 6 +- - drivers/power/pmic/Makefile | 2 +- - drivers/power/pmic/stpmic1.c | 258 +++++ - drivers/power/pmic/stpmu1.c | 95 -- - drivers/power/regulator/Kconfig | 14 +- - drivers/power/regulator/Makefile | 2 +- - drivers/power/regulator/fixed.c | 4 +- - drivers/power/regulator/regulator-uclass.c | 5 + - drivers/power/regulator/stpmic1.c | 672 ++++++++++++ - drivers/power/regulator/stpmu1.c | 671 ------------ - drivers/ram/stm32mp1/Kconfig | 29 + - drivers/ram/stm32mp1/Makefile | 7 + - drivers/ram/stm32mp1/stm32mp1_ddr.c | 522 +++++++++- - drivers/ram/stm32mp1/stm32mp1_ddr.h | 10 +- - drivers/ram/stm32mp1/stm32mp1_ddr_regs.h | 3 + - drivers/ram/stm32mp1/stm32mp1_interactive.c | 467 +++++++++ - drivers/ram/stm32mp1/stm32mp1_ram.c | 30 +- - drivers/ram/stm32mp1/stm32mp1_tests.c | 1360 ++++++++++++++++++++++++ - drivers/ram/stm32mp1/stm32mp1_tests.h | 34 + - drivers/ram/stm32mp1/stm32mp1_tuning.c | 1504 +++++++++++++++++++++++++++ - drivers/ram/stm32mp1/stm32mp1_tuning.h | 54 + - drivers/remoteproc/Kconfig | 9 + - drivers/remoteproc/Makefile | 1 + - drivers/remoteproc/rproc-uclass.c | 333 +++++- - drivers/remoteproc/stm32_copro.c | 272 +++++ - drivers/reset/stm32-reset.c | 33 +- - drivers/serial/serial_stm32.c | 18 +- - drivers/spi/Kconfig | 2 +- - drivers/spi/soft_spi.c | 4 +- - drivers/sysreset/sysreset_syscon.c | 18 +- - drivers/usb/gadget/Kconfig | 9 + - drivers/usb/gadget/Makefile | 1 + - drivers/usb/gadget/dwc2_udc_otg.c | 3 + - drivers/usb/gadget/g_dnl.c | 5 + - drivers/usb/gadget/gen_udc_otg_phy.c | 66 ++ - drivers/usb/host/dwc2.c | 118 ++- - drivers/video/Kconfig | 33 + - drivers/video/Makefile | 4 + - drivers/video/dw_mipi_dsi.c | 826 +++++++++++++++ - drivers/video/mipi_display.c | 817 +++++++++++++++ - drivers/video/orisetech_otm8009a.c | 339 ++++++ - drivers/video/raydium-rm68200.c | 338 ++++++ - drivers/video/stm32/Kconfig | 9 + - drivers/video/stm32/Makefile | 1 + - drivers/video/stm32/stm32_dsi.c | 446 ++++++++ - drivers/video/stm32/stm32_ltdc.c | 155 +-- - drivers/video/video-uclass.c | 14 + - drivers/watchdog/Kconfig | 15 + - drivers/watchdog/Makefile | 1 + - drivers/watchdog/stm32mp_wdt.c | 119 +++ - include/adc.h | 21 + - include/configs/stm32mp1.h | 117 ++- - include/dfu.h | 29 + - include/dm/pinctrl.h | 59 ++ - include/dm/uclass-id.h | 1 + - include/dm/uclass.h | 28 + - include/dw_mipi_dsi.h | 32 + - include/g_dnl.h | 1 + - include/hwspinlock.h | 140 +++ - include/image.h | 1 + - include/mipi_display.h | 257 ++++- - include/power/stpmic1.h | 118 +++ - include/power/stpmu1.h | 85 -- - include/remoteproc.h | 20 +- - include/syscon.h | 9 + - include/usb/dwc2_udc.h | 1 + - test/dm/Makefile | 1 + - test/dm/hwspinlock.c | 40 + - test/py/tests/test_pinmux.py | 62 ++ - tools/stm32image.c | 8 +- - 124 files changed, 13670 insertions(+), 1353 deletions(-) - create mode 100644 cmd/pinmux.c - create mode 100644 drivers/dfu/dfu_virt.c - create mode 100644 drivers/hwspinlock/Kconfig - create mode 100644 drivers/hwspinlock/Makefile - create mode 100644 drivers/hwspinlock/hwspinlock-uclass.c - create mode 100644 drivers/hwspinlock/sandbox_hwspinlock.c - create mode 100644 drivers/hwspinlock/stm32_hwspinlock.c - create mode 100644 drivers/mailbox/stm32-ipcc.c - create mode 100644 drivers/mtd/nand/raw/stm32_fmc2_nand.c - create mode 100644 drivers/pinctrl/pinctrl-stmfx.c - create mode 100644 drivers/power/pmic/stpmic1.c - delete mode 100644 drivers/power/pmic/stpmu1.c - create mode 100644 drivers/power/regulator/stpmic1.c - delete mode 100644 drivers/power/regulator/stpmu1.c - create mode 100644 drivers/ram/stm32mp1/stm32mp1_interactive.c - create mode 100644 drivers/ram/stm32mp1/stm32mp1_tests.c - create mode 100644 drivers/ram/stm32mp1/stm32mp1_tests.h - create mode 100644 drivers/ram/stm32mp1/stm32mp1_tuning.c - create mode 100644 drivers/ram/stm32mp1/stm32mp1_tuning.h - create mode 100644 drivers/remoteproc/stm32_copro.c - create mode 100644 drivers/usb/gadget/gen_udc_otg_phy.c - create mode 100644 drivers/video/dw_mipi_dsi.c - create mode 100644 drivers/video/mipi_display.c - create mode 100644 drivers/video/orisetech_otm8009a.c - create mode 100644 drivers/video/raydium-rm68200.c - create mode 100644 drivers/video/stm32/stm32_dsi.c - create mode 100644 drivers/watchdog/stm32mp_wdt.c - create mode 100644 include/dw_mipi_dsi.h - create mode 100644 include/hwspinlock.h - create mode 100644 include/power/stpmic1.h - delete mode 100644 include/power/stpmu1.h - create mode 100644 test/dm/hwspinlock.c - create mode 100644 test/py/tests/test_pinmux.py - -diff --git a/.gitignore b/.gitignore -index 8d18d6f..b22e7d0 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -88,3 +88,6 @@ GTAGS - *.orig - *~ - \#*# -+ -+/oe-* -+bitbake-cookerdaemon.log -diff --git a/MAINTAINERS b/MAINTAINERS -index abdb6dc..17f9cd3 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -242,7 +242,9 @@ F: drivers/misc/stm32mp_fuse.c - F: drivers/mmc/stm32_sdmmc2.c - F: drivers/phy/phy-stm32-usbphyc.c - F: drivers/pinctrl/pinctrl_stm32.c -+F: drivers/power/pmic/stpmic1.c - F: drivers/power/regulator/stm32-vrefbuf.c -+F: drivers/power/regulator/stpmic1.c - F: drivers/ram/stm32mp1/ - F: drivers/misc/stm32_rcc.c - F: drivers/reset/stm32-reset.c -diff --git a/Makefile b/Makefile -index 552687d..84cb372 100644 ---- a/Makefile -+++ b/Makefile -@@ -3,7 +3,7 @@ - VERSION = 2018 - PATCHLEVEL = 11 - SUBLEVEL = --EXTRAVERSION = -+EXTRAVERSION = -stm32mp-r1 - NAME = - - # *DOCUMENTATION* -diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h -index dcb6d5f..79e0e1e 100644 ---- a/arch/sandbox/include/asm/state.h -+++ b/arch/sandbox/include/asm/state.h -@@ -97,6 +97,7 @@ struct sandbox_state { - /* Information about Watchdog */ - struct sandbox_wdt_info wdt; - -+ bool hwspinlock; /* Hardware Spinlock status */ - ulong next_tag; /* Next address tag to allocate */ - struct list_head mapmem_head; /* struct sandbox_mapmem_entry */ - }; -diff --git a/cmd/Kconfig b/cmd/Kconfig -index ad14c9c..3aa10d5 100644 ---- a/cmd/Kconfig -+++ b/cmd/Kconfig -@@ -953,6 +953,14 @@ config CMD_PCMCIA - about 1990. These devices are typically removable memory or network - cards using a standard 68-pin connector. - -+config CMD_PINMUX -+ bool "pinmux - show pins muxing" -+ default y if PINCTRL -+ help -+ Parse all available pin-controllers and show pins muxing. This -+ is useful for debug purpoer to check the pin muxing and to know if -+ a pin is configured as a GPIO or as an alternate function. -+ - config CMD_POWEROFF - bool "poweroff" - help -diff --git a/cmd/Makefile b/cmd/Makefile -index ac4830a..e9ab126 100644 ---- a/cmd/Makefile -+++ b/cmd/Makefile -@@ -103,6 +103,7 @@ ifdef CONFIG_PCI - obj-$(CONFIG_CMD_PCI) += pci.o - endif - obj-y += pcmcia.o -+obj-$(CONFIG_CMD_PINMUX) += pinmux.o - obj-$(CONFIG_CMD_PXE) += pxe.o - obj-$(CONFIG_CMD_WOL) += wol.o - obj-$(CONFIG_CMD_QFW) += qfw.o -diff --git a/cmd/adc.c b/cmd/adc.c -index c8857ed..2d635ac 100644 ---- a/cmd/adc.c -+++ b/cmd/adc.c -@@ -35,7 +35,7 @@ static int do_adc_info(cmd_tbl_t *cmdtp, int flag, int argc, - char *const argv[]) - { - struct udevice *dev; -- unsigned int data_mask; -+ unsigned int data_mask, ch_mask; - int ret, vss, vdd; - - if (argc < 2) -@@ -49,6 +49,10 @@ static int do_adc_info(cmd_tbl_t *cmdtp, int flag, int argc, - - printf("ADC Device '%s' :\n", argv[1]); - -+ ret = adc_channel_mask(dev, &ch_mask); -+ if (!ret) -+ printf("channel mask: %x\n", ch_mask); -+ - ret = adc_data_mask(dev, &data_mask); - if (!ret) - printf("data mask: %x\n", data_mask); -@@ -67,8 +71,9 @@ static int do_adc_info(cmd_tbl_t *cmdtp, int flag, int argc, - static int do_adc_single(cmd_tbl_t *cmdtp, int flag, int argc, - char *const argv[]) - { -+ struct udevice *dev; - unsigned int data; -- int ret; -+ int ret, uV; - - if (argc < 3) - return CMD_RET_USAGE; -@@ -81,7 +86,62 @@ static int do_adc_single(cmd_tbl_t *cmdtp, int flag, int argc, - return CMD_RET_FAILURE; - } - -- printf("%u\n", data); -+ ret = uclass_get_device_by_name(UCLASS_ADC, argv[1], &dev); -+ if (!ret && !adc_raw_to_uV(dev, data, &uV)) -+ printf("%u, %d uV\n", data, uV); -+ else -+ printf("%u\n", data); -+ -+ return CMD_RET_SUCCESS; -+} -+ -+static int do_adc_scan(cmd_tbl_t *cmdtp, int flag, int argc, -+ char *const argv[]) -+{ -+ struct adc_channel ch[ADC_MAX_CHANNEL]; -+ struct udevice *dev; -+ unsigned int ch_mask; -+ int i, chan, ret, uV; -+ -+ if (argc < 2) -+ return CMD_RET_USAGE; -+ -+ ret = uclass_get_device_by_name(UCLASS_ADC, argv[1], &dev); -+ if (ret) { -+ pr_err("Can't get the ADC %s: %d\n", argv[1], ret); -+ return CMD_RET_FAILURE; -+ } -+ -+ switch (argc) { -+ case 3: -+ ch_mask = simple_strtoul(argv[2], NULL, 0); -+ if (ch_mask) -+ break; -+ case 2: -+ ret = adc_channel_mask(dev, &ch_mask); -+ if (ret) { -+ pr_err("Can't get mask for %s: %d\n", dev->name, ret); -+ return CMD_RET_FAILURE; -+ } -+ break; -+ } -+ -+ ret = adc_channels_single_shot(dev->name, ch_mask, ch); -+ if (ret) { -+ pr_err("Can't get single shot for %s (chans mask: 0x%x): %d\n", -+ dev->name, ch_mask, ret); -+ return CMD_RET_FAILURE; -+ } -+ -+ for (chan = 0, i = 0; chan < ADC_MAX_CHANNEL; chan++) { -+ if (!(ch_mask & ADC_CHANNEL(chan))) -+ continue; -+ if (!adc_raw_to_uV(dev, ch[i].data, &uV)) -+ printf("[%02d]: %u, %d uV\n", ch[i].id, ch[i].data, uV); -+ else -+ printf("[%02d]: %u\n", ch[i].id, ch[i].data); -+ i++; -+ } - - return CMD_RET_SUCCESS; - } -@@ -90,6 +150,7 @@ static cmd_tbl_t cmd_adc_sub[] = { - U_BOOT_CMD_MKENT(list, 1, 1, do_adc_list, "", ""), - U_BOOT_CMD_MKENT(info, 2, 1, do_adc_info, "", ""), - U_BOOT_CMD_MKENT(single, 3, 1, do_adc_single, "", ""), -+ U_BOOT_CMD_MKENT(scan, 3, 1, do_adc_scan, "", ""), - }; - - static int do_adc(cmd_tbl_t *cmdtp, int flag, int argc, -@@ -115,6 +176,7 @@ static int do_adc(cmd_tbl_t *cmdtp, int flag, int argc, - static char adc_help_text[] = - "list - list ADC devices\n" - "adc info - Get ADC device info\n" -- "adc single - Get Single data of ADC device channel"; -+ "adc single - Get Single data of ADC device channel\n" -+ "adc scan [channel mask] - Scan all [or masked] ADC channels"; - - U_BOOT_CMD(adc, 4, 1, do_adc, "ADC sub-system", adc_help_text); -diff --git a/cmd/bmp.c b/cmd/bmp.c -index 02bdf48..b8af784 100644 ---- a/cmd/bmp.c -+++ b/cmd/bmp.c -@@ -124,8 +124,14 @@ static int do_bmp_display(cmd_tbl_t * cmdtp, int flag, int argc, char * const ar - break; - case 4: - addr = simple_strtoul(argv[1], NULL, 16); -- x = simple_strtoul(argv[2], NULL, 10); -- y = simple_strtoul(argv[3], NULL, 10); -+ if (!strcmp(argv[2], "m")) -+ x = BMP_ALIGN_CENTER; -+ else -+ x = simple_strtoul(argv[2], NULL, 10); -+ if (!strcmp(argv[3], "m")) -+ y = BMP_ALIGN_CENTER; -+ else -+ y = simple_strtoul(argv[3], NULL, 10); - break; - default: - return CMD_RET_USAGE; -@@ -249,9 +255,11 @@ int bmp_display(ulong addr, int x, int y) - if (!ret) { - bool align = false; - --# ifdef CONFIG_SPLASH_SCREEN_ALIGN -- align = true; --# endif /* CONFIG_SPLASH_SCREEN_ALIGN */ -+ if (CONFIG_IS_ENABLED(SPLASH_SCREEN_ALIGN) || -+ x == BMP_ALIGN_CENTER || -+ y == BMP_ALIGN_CENTER) -+ align = true; -+ - ret = video_bmp_display(dev, addr, x, y, align); - } - #elif defined(CONFIG_LCD) -diff --git a/cmd/pinmux.c b/cmd/pinmux.c -new file mode 100644 -index 0000000..6c8ec51 ---- /dev/null -+++ b/cmd/pinmux.c -@@ -0,0 +1,146 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define LIMIT_DEVNAME 30 -+ -+static struct udevice *currdev; -+ -+static int do_dev(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -+{ -+ const char *name; -+ int ret; -+ -+ switch (argc) { -+ case 2: -+ name = argv[1]; -+ ret = uclass_get_device_by_name(UCLASS_PINCTRL, name, &currdev); -+ if (ret) { -+ printf("Can't get the pin-controller: %s!\n", name); -+ return CMD_RET_FAILURE; -+ } -+ case 1: -+ if (!currdev) { -+ printf("Pin-controller device is not set!\n"); -+ return CMD_RET_USAGE; -+ } -+ -+ printf("dev: %s\n", currdev->name); -+ } -+ -+ return CMD_RET_SUCCESS; -+} -+ -+static int show_pinmux(struct udevice *dev) -+{ -+ char pin_name[PINNAME_SIZE]; -+ char pin_mux[PINMUX_SIZE]; -+ int pins_count; -+ int i; -+ int ret; -+ -+ pins_count = pinctrl_get_pins_count(dev); -+ -+ if (pins_count == -ENOSYS) { -+ printf("Ops get_pins_count not supported\n"); -+ return pins_count; -+ } -+ -+ for (i = 0; i < pins_count; i++) { -+ ret = pinctrl_get_pin_name(dev, i, pin_name, PINNAME_SIZE); -+ if (ret == -ENOSYS) { -+ printf("Ops get_pin_name not supported\n"); -+ return ret; -+ } -+ -+ ret = pinctrl_get_pin_muxing(dev, i, pin_mux, PINMUX_SIZE); -+ if (ret) { -+ printf("Ops get_pin_muxing error (%d)\n", ret); -+ return ret; -+ } -+ -+ printf("%-*s: %-*s\n", PINNAME_SIZE, pin_name, -+ PINMUX_SIZE, pin_mux); -+ } -+ -+ return 0; -+} -+ -+static int do_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -+{ -+ struct udevice *dev; -+ int ret = CMD_RET_USAGE; -+ -+ if (currdev && (argc < 2 || strcmp(argv[1], "-a"))) -+ return show_pinmux(currdev); -+ -+ if (argc < 2 || strcmp(argv[1], "-a")) -+ return ret; -+ -+ uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) { -+ /* insert a separator between each pin-controller display */ -+ printf("--------------------------\n"); -+ printf("%s:\n", dev->name); -+ ret = show_pinmux(dev); -+ if (ret < 0) -+ printf("Can't display pin muxing for %s\n", -+ dev->name); -+ } -+ -+ return ret; -+} -+ -+static int do_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -+{ -+ struct udevice *dev; -+ -+ printf("| %-*.*s| %-*.*s| %s\n", -+ LIMIT_DEVNAME, LIMIT_DEVNAME, "Device", -+ LIMIT_DEVNAME, LIMIT_DEVNAME, "Driver", -+ "Parent"); -+ -+ uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) { -+ printf("| %-*.*s| %-*.*s| %s\n", -+ LIMIT_DEVNAME, LIMIT_DEVNAME, dev->name, -+ LIMIT_DEVNAME, LIMIT_DEVNAME, dev->driver->name, -+ dev->parent->name); -+ } -+ -+ return CMD_RET_SUCCESS; -+} -+ -+static cmd_tbl_t pinmux_subcmd[] = { -+ U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""), -+ U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""), -+ U_BOOT_CMD_MKENT(status, 2, 1, do_status, "", ""), -+}; -+ -+static int do_pinmux(cmd_tbl_t *cmdtp, int flag, int argc, -+ char * const argv[]) -+{ -+ cmd_tbl_t *cmd; -+ -+ argc--; -+ argv++; -+ -+ cmd = find_cmd_tbl(argv[0], pinmux_subcmd, ARRAY_SIZE(pinmux_subcmd)); -+ if (!cmd || argc > cmd->maxargs) -+ return CMD_RET_USAGE; -+ -+ return cmd->cmd(cmdtp, flag, argc, argv); -+} -+ -+U_BOOT_CMD(pinmux, CONFIG_SYS_MAXARGS, 1, do_pinmux, -+ "show pin-controller muxing", -+ "list - list UCLASS_PINCTRL devices\n" -+ "pinmux dev [pincontroller-name] - select pin-controller device\n" -+ "pinmux status [-a] - print pin-controller muxing [for all]\n" -+) -diff --git a/cmd/pxe.c b/cmd/pxe.c -index 2745553..e777702 100644 ---- a/cmd/pxe.c -+++ b/cmd/pxe.c -@@ -8,11 +8,13 @@ - #include - #include - #include -+#include - #include - #include - #include - #include - #include -+#include - #include - - #include "menu.h" -@@ -488,6 +490,7 @@ struct pxe_label { - * - * title - the name of the menu as given by a 'menu title' line. - * default_label - the name of the default label, if any. -+ * bmp - the bmp file name which is displayed in background - * timeout - time in tenths of a second to wait for a user key-press before - * booting the default label. - * prompt - if 0, don't prompt for a choice unless the timeout period is -@@ -498,6 +501,7 @@ struct pxe_label { - struct pxe_menu { - char *title; - char *default_label; -+ char *bmp; - int timeout; - int prompt; - struct list_head labels; -@@ -850,6 +854,7 @@ enum token_type { - T_FDTDIR, - T_ONTIMEOUT, - T_IPAPPEND, -+ T_BACKGROUND, - T_INVALID - }; - -@@ -883,6 +888,7 @@ static const struct token keywords[] = { - {"fdtdir", T_FDTDIR}, - {"ontimeout", T_ONTIMEOUT,}, - {"ipappend", T_IPAPPEND,}, -+ {"background", T_BACKGROUND,}, - {NULL, T_INVALID} - }; - -@@ -1160,6 +1166,10 @@ static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, - nest_level + 1); - break; - -+ case T_BACKGROUND: -+ err = parse_sliteral(c, &cfg->bmp); -+ break; -+ - default: - printf("Ignoring malformed menu command: %.*s\n", - (int)(*c - s), s); -@@ -1574,6 +1584,20 @@ static void handle_pxe_menu(cmd_tbl_t *cmdtp, struct pxe_menu *cfg) - struct menu *m; - int err; - -+#ifdef CONFIG_CMD_BMP -+ /* display BMP if available */ -+ if (cfg->bmp) { -+ if (get_relfile(cmdtp, cfg->bmp, load_addr)) { -+ run_command("cls", 0); -+ bmp_display(load_addr, -+ BMP_ALIGN_CENTER, BMP_ALIGN_CENTER); -+ } else { -+ printf("Skipping background bmp %s for failure\n", -+ cfg->bmp); -+ } -+ } -+#endif -+ - m = pxe_menu_to_menu(cfg); - if (!m) - return; -diff --git a/cmd/remoteproc.c b/cmd/remoteproc.c -index 81463f3..755e933 100644 ---- a/cmd/remoteproc.c -+++ b/cmd/remoteproc.c -@@ -103,7 +103,7 @@ static int do_remoteproc_list(cmd_tbl_t *cmdtp, int flag, int argc, - } - - /** -- * do_remoteproc_load() - Load a remote processor with binary image -+ * do_remoteproc_load() - Load a remote processor with binary or elf image - * @cmdtp: unused - * @flag: unused - * @argc: argument count for the load function -@@ -143,6 +143,53 @@ static int do_remoteproc_load(cmd_tbl_t *cmdtp, int flag, int argc, - } - - /** -+ * do_remoteproc_load_rsc_table() - Get resource table from an elf image -+ * @cmdtp: unused -+ * @flag: unused -+ * @argc: argument count for the load function -+ * @argv: arguments for the load function -+ * -+ * Return: 0 if no error, else returns appropriate error value. -+ */ -+static int do_remoteproc_load_rsc_table(cmd_tbl_t *cmdtp, int flag, int argc, -+ char *const argv[]) -+{ -+ ulong addr, size, rsc_addr; -+ unsigned int rsc_size; -+ int id, ret; -+ -+ if (argc != 4) -+ return CMD_RET_USAGE; -+ -+ id = (int)simple_strtoul(argv[1], NULL, 3); -+ addr = simple_strtoul(argv[2], NULL, 16); -+ -+ size = simple_strtoul(argv[3], NULL, 16); -+ -+ if (!size) { -+ printf("\t Expect some size??\n"); -+ return CMD_RET_USAGE; -+ } -+ -+ if (!rproc_is_initialized()) { -+ printf("\tRemote Processors are not initialized\n"); -+ return CMD_RET_USAGE; -+ } -+ -+ ret = rproc_load_rsc_table(id, addr, size, &rsc_addr, &rsc_size); -+ if (!ret) { -+ env_set_hex("copro_rsc_addr", rsc_addr); -+ env_set_hex("copro_rsc_size", rsc_size); -+ } -+ -+ printf("Remote Processor %d resource table %s : 0x%08lx-0x%x\n", -+ id, ret ? "Not found" : "Found", ret ? 0 : rsc_addr, -+ ret ? 0 : rsc_size); -+ -+ return ret ? CMD_RET_FAILURE : 0; -+} -+ -+/** - * do_remoteproc_wrapper() - wrapper for various rproc commands - * @cmdtp: unused - * @flag: unused -@@ -172,6 +219,9 @@ static int do_remoteproc_wrapper(cmd_tbl_t *cmdtp, int flag, int argc, - - if (!strcmp(argv[0], "start")) { - ret = rproc_start(id); -+ if (!ret) -+ env_set("copro_state", "booted"); -+ - } else if (!strcmp(argv[0], "stop")) { - ret = rproc_stop(id); - } else if (!strcmp(argv[0], "reset")) { -@@ -213,6 +263,12 @@ static cmd_tbl_t cmd_remoteproc_sub[] = { - "- id: ID of the remote processor(see 'list' cmd)\n" - "- addr: Address in memory of the image to loadup\n" - "- size: Size of the image to loadup\n"), -+ U_BOOT_CMD_MKENT(load_rsc, 5, 1, do_remoteproc_load_rsc_table, -+ "Load resource table address from remote processor provided image", -+ " [addr] [size]\n" -+ "- id: ID of the remote processor(see 'list' cmd)\n" -+ "- addr: Address in memory of the image\n" -+ "- size: Size of the image\n"), - U_BOOT_CMD_MKENT(start, 1, 1, do_remoteproc_wrapper, - "Start remote processor", - "id - ID of the remote processor (see 'list' cmd)\n"), -@@ -272,8 +328,10 @@ U_BOOT_CMD(rproc, 5, 1, do_remoteproc, - "\n\tSubcommands:\n" - "\tinit - Enumerate and initalize the remote processors\n" - "\tlist - list available remote processors\n" -- "\tload [addr] [size]- Load the remote processor with binary\n" -+ "\tload [addr] [size]- Load the remote processor with\n" - "\t image stored at address [addr] in memory\n" -+ "\tload_rsc [addr] [size]- Load resource table from remote\n" -+ "\t processor provided image at address [addr]\n" - "\tstart - Start the remote processor(must be loaded)\n" - "\tstop - Stop the remote processor\n" - "\treset - Reset the remote processor\n" -diff --git a/cmd/usb_mass_storage.c b/cmd/usb_mass_storage.c -index 0d55114..26b41b4c4 100644 ---- a/cmd/usb_mass_storage.c -+++ b/cmd/usb_mass_storage.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - - static int ums_read_sector(struct ums *ums_dev, - ulong start, lbaint_t blkcnt, void *buf) -@@ -226,6 +227,8 @@ static int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, - rc = CMD_RET_SUCCESS; - goto cleanup_register; - } -+ -+ WATCHDOG_RESET(); - } - - cleanup_register: -diff --git a/common/Makefile b/common/Makefile -index a238836..336bed7 100644 ---- a/common/Makefile -+++ b/common/Makefile -@@ -116,6 +116,7 @@ endif - - obj-y += cli.o - obj-$(CONFIG_FSL_DDR_INTERACTIVE) += cli_simple.o cli_readline.o -+obj-$(CONFIG_STM32MP1_DDR_INTERACTIVE) += cli_simple.o cli_readline.o - obj-$(CONFIG_DFU_OVER_USB) += dfu.o - obj-y += command.o - obj-$(CONFIG_$(SPL_)LOG) += log.o -diff --git a/common/board_f.c b/common/board_f.c -index afafec5..59745d5 100644 ---- a/common/board_f.c -+++ b/common/board_f.c -@@ -92,7 +92,7 @@ static int init_func_watchdog_init(void) - (defined(CONFIG_M68K) || defined(CONFIG_MICROBLAZE) || \ - defined(CONFIG_SH) || defined(CONFIG_AT91SAM9_WATCHDOG) || \ - defined(CONFIG_DESIGNWARE_WATCHDOG) || \ -- defined(CONFIG_IMX_WATCHDOG)) -+ defined(CONFIG_IMX_WATCHDOG) || defined(CONFIG_STM32MP_WATCHDOG)) - hw_watchdog_init(); - puts(" Watchdog enabled\n"); - # endif -@@ -434,7 +434,6 @@ static int reserve_uboot(void) - debug("Reserving %ldk for U-Boot at: %08lx\n", - gd->mon_len >> 10, gd->relocaddr); - } -- - gd->start_addr_sp = gd->relocaddr; - - return 0; -diff --git a/common/image.c b/common/image.c -index 1c3a772..6ace71f 100644 ---- a/common/image.c -+++ b/common/image.c -@@ -166,6 +166,7 @@ static const table_entry_t uimage_type[] = { - { IH_TYPE_FIRMWARE_IVT, "firmware_ivt", "Firmware with HABv4 IVT" }, - { IH_TYPE_PMMC, "pmmc", "TI Power Management Micro-Controller Firmware",}, - { IH_TYPE_STM32IMAGE, "stm32image", "STMicroelectronics STM32 Image" }, -+ { IH_TYPE_STM32COPRO, "stm32copro", "STMicroelectronics STM32 Coprocessor Image"}, - { -1, "", "", }, - }; - -diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c -index 8cd4830..3cefc9a 100644 ---- a/common/spl/spl_spi.c -+++ b/common/spl/spl_spi.c -@@ -78,11 +78,18 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, - /* - * Load U-Boot image from SPI flash into RAM - */ -- -+#ifdef CONFIG_DM_SPI_FLASH -+ /* In DM mode defaults will be taken from DT */ -+ flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, -+ CONFIG_SF_DEFAULT_CS, -+ 0, -+ 0); -+#else - flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, - CONFIG_SF_DEFAULT_CS, - CONFIG_SF_DEFAULT_SPEED, - CONFIG_SF_DEFAULT_MODE); -+#endif - if (!flash) { - puts("SPI probe failed.\n"); - return -ENODEV; -diff --git a/common/usb.c b/common/usb.c -index 78178c5..239b104 100644 ---- a/common/usb.c -+++ b/common/usb.c -@@ -233,6 +233,8 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, - request, requesttype, value, index, size); - dev->status = USB_ST_NOT_PROC; /*not yet processed */ - -+ mdelay(5); -+ - err = submit_control_msg(dev, pipe, data, size, setup_packet); - if (err < 0) - return err; -diff --git a/drivers/Kconfig b/drivers/Kconfig -index 927a2b8..7e6ca7c 100644 ---- a/drivers/Kconfig -+++ b/drivers/Kconfig -@@ -40,6 +40,8 @@ source "drivers/fpga/Kconfig" - - source "drivers/gpio/Kconfig" - -+source "drivers/hwspinlock/Kconfig" -+ - source "drivers/i2c/Kconfig" - - source "drivers/input/Kconfig" -diff --git a/drivers/Makefile b/drivers/Makefile -index fb38b67..0ef56fb 100644 ---- a/drivers/Makefile -+++ b/drivers/Makefile -@@ -111,4 +111,5 @@ obj-$(CONFIG_W1) += w1/ - obj-$(CONFIG_W1_EEPROM) += w1-eeprom/ - - obj-$(CONFIG_MACH_PIC32) += ddr/microchip/ -+obj-$(CONFIG_DM_HWSPINLOCK) += hwspinlock/ - endif -diff --git a/drivers/adc/adc-uclass.c b/drivers/adc/adc-uclass.c -index 738c1ea..27b2654 100644 ---- a/drivers/adc/adc-uclass.c -+++ b/drivers/adc/adc-uclass.c -@@ -6,6 +6,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -77,6 +78,18 @@ int adc_data_mask(struct udevice *dev, unsigned int *data_mask) - return 0; - } - -+int adc_channel_mask(struct udevice *dev, unsigned int *channel_mask) -+{ -+ struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); -+ -+ if (!uc_pdata) -+ return -ENOSYS; -+ -+ *channel_mask = uc_pdata->channel_mask; -+ -+ return 0; -+} -+ - int adc_stop(struct udevice *dev) - { - const struct adc_ops *ops = dev_get_driver_ops(dev); -@@ -264,8 +277,13 @@ static int adc_vdd_platdata_update(struct udevice *dev) - * will bind before its supply regulator device, then the below 'get' - * will return an error. - */ -- if (!uc_pdata->vdd_supply) -- return 0; -+ if (!uc_pdata->vdd_supply) { -+ /* Only get vdd_supply once */ -+ ret = device_get_supply_regulator(dev, "vdd-supply", -+ &uc_pdata->vdd_supply); -+ if (ret) -+ return ret; -+ } - - ret = regulator_get_value(uc_pdata->vdd_supply); - if (ret < 0) -@@ -281,8 +299,12 @@ static int adc_vss_platdata_update(struct udevice *dev) - struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); - int ret; - -- if (!uc_pdata->vss_supply) -- return 0; -+ if (!uc_pdata->vss_supply) { -+ ret = device_get_supply_regulator(dev, "vss-supply", -+ &uc_pdata->vss_supply); -+ if (ret) -+ return ret; -+ } - - ret = regulator_get_value(uc_pdata->vss_supply); - if (ret < 0) -@@ -329,6 +351,30 @@ int adc_vss_value(struct udevice *dev, int *uV) - return 0; - } - -+int adc_raw_to_uV(struct udevice *dev, unsigned int raw, int *uV) -+{ -+ unsigned int data_mask; -+ int ret, val, vref; -+ u64 raw64 = raw; -+ -+ ret = adc_vdd_value(dev, &vref); -+ if (ret) -+ return ret; -+ -+ if (!adc_vss_value(dev, &val)) -+ vref -= val; -+ -+ ret = adc_data_mask(dev, &data_mask); -+ if (ret) -+ return ret; -+ -+ raw64 *= vref; -+ do_div(raw64, data_mask); -+ *uV = raw64; -+ -+ return 0; -+} -+ - static int adc_vdd_platdata_set(struct udevice *dev) - { - struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); -diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c -index 6a8c7b7..79f834b 100644 ---- a/drivers/clk/clk_stm32mp1.c -+++ b/drivers/clk/clk_stm32mp1.c -@@ -12,13 +12,19 @@ - #include - #include - #include -+#include -+#include - #include - #include - -+DECLARE_GLOBAL_DATA_PTR; -+ -+#ifndef CONFIG_STM32MP1_TRUSTED - #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) - /* activate clock tree initialization in the driver */ - #define STM32MP1_CLOCK_TREE_INIT - #endif -+#endif - - #define MAX_HSI_HZ 64000000 - -@@ -104,6 +110,7 @@ - #define RCC_MP_APB2ENSETR 0XA08 - #define RCC_MP_APB3ENSETR 0xA10 - #define RCC_MP_AHB2ENSETR 0xA18 -+#define RCC_MP_AHB3ENSETR 0xA20 - #define RCC_MP_AHB4ENSETR 0xA28 - - /* used for most of SELR register */ -@@ -240,7 +247,6 @@ enum stm32mp1_parent_id { - _LSI, - _LSE, - _I2S_CKIN, -- _USB_PHY_48, - NB_OSC, - - /* other parent source */ -@@ -272,6 +278,7 @@ enum stm32mp1_parent_id { - _CK_MPU, - _CK_MCU, - _DSI_PHY, -+ _USB_PHY_48, - _PARENT_NB, - _UNKNOWN_ID = 0xff, - }; -@@ -377,6 +384,7 @@ struct stm32mp1_clk_gate { - u8 set_clr; - u8 sel; - u8 fixed; -+ bool secure; - }; - - struct stm32mp1_clk_sel { -@@ -421,6 +429,7 @@ struct stm32mp1_clk_priv { - .set_clr = 0, \ - .sel = (s), \ - .fixed = _UNKNOWN_ID, \ -+ .secure = 0, \ - } - - #define STM32MP1_CLK_F(off, b, idx, f) \ -@@ -431,6 +440,7 @@ struct stm32mp1_clk_priv { - .set_clr = 0, \ - .sel = _UNKNOWN_SEL, \ - .fixed = (f), \ -+ .secure = 0, \ - } - - #define STM32MP1_CLK_SET_CLR(off, b, idx, s) \ -@@ -441,6 +451,7 @@ struct stm32mp1_clk_priv { - .set_clr = 1, \ - .sel = (s), \ - .fixed = _UNKNOWN_ID, \ -+ .secure = 0, \ - } - - #define STM32MP1_CLK_SET_CLR_F(off, b, idx, f) \ -@@ -451,6 +462,18 @@ struct stm32mp1_clk_priv { - .set_clr = 1, \ - .sel = _UNKNOWN_SEL, \ - .fixed = (f), \ -+ .secure = 0, \ -+ } -+ -+#define STM32MP1_CLK_SEC_SET_CLR(off, b, idx, s) \ -+ { \ -+ .offset = (off), \ -+ .bit = (b), \ -+ .index = (idx), \ -+ .set_clr = 1, \ -+ .sel = (s), \ -+ .fixed = _UNKNOWN_ID, \ -+ .secure = 1, \ - } - - #define STM32MP1_CLK_PARENT(idx, off, s, m, p) \ -@@ -526,14 +549,17 @@ 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, 2, I2C4_K, _I2C46_SEL), -- STM32MP1_CLK_SET_CLR(RCC_MP_APB5ENSETR, 20, STGEN_K, _STGEN_SEL), -+ STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 2, I2C4_K, _I2C46_SEL), -+ STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 20, STGEN_K, _STGEN_SEL), - - STM32MP1_CLK_SET_CLR_F(RCC_MP_AHB2ENSETR, 5, ADC12, _HCLK2), - STM32MP1_CLK_SET_CLR(RCC_MP_AHB2ENSETR, 5, ADC12_K, _ADC12_SEL), - STM32MP1_CLK_SET_CLR(RCC_MP_AHB2ENSETR, 8, USBO_K, _USBO_SEL), - STM32MP1_CLK_SET_CLR(RCC_MP_AHB2ENSETR, 16, SDMMC3_K, _SDMMC3_SEL), - -+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB3ENSETR, 11, HSEM, _UNKNOWN_SEL), -+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB3ENSETR, 12, IPCC, _UNKNOWN_SEL), -+ - STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 0, GPIOA, _UNKNOWN_SEL), - STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 1, GPIOB, _UNKNOWN_SEL), - STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 2, GPIOC, _UNKNOWN_SEL), -@@ -546,7 +572,7 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { - STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 9, GPIOJ, _UNKNOWN_SEL), - STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 10, GPIOK, _UNKNOWN_SEL), - -- STM32MP1_CLK_SET_CLR(RCC_MP_AHB5ENSETR, 0, GPIOZ, _UNKNOWN_SEL), -+ STM32MP1_CLK_SEC_SET_CLR(RCC_MP_AHB5ENSETR, 0, GPIOZ, _UNKNOWN_SEL), - - STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 7, ETHCK, _ETH_SEL), - STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 8, ETHTX, _UNKNOWN_SEL), -@@ -662,8 +688,8 @@ static const u8 stm32mp1_axi_div[8] = { - 1, 2, 3, 4, 4, 4, 4, 4 - }; - --#ifdef DEBUG --static const char * const stm32mp1_clk_parent_name[_PARENT_NB] = { -+static const __maybe_unused -+char * const stm32mp1_clk_parent_name[_PARENT_NB] = { - [_HSI] = "HSI", - [_HSE] = "HSE", - [_CSI] = "CSI", -@@ -701,7 +727,8 @@ static const char * const stm32mp1_clk_parent_name[_PARENT_NB] = { - [_DSI_PHY] = "DSI_PHY_PLL", - }; - --static const char * const stm32mp1_clk_parent_sel_name[_PARENT_SEL_NB] = { -+static const __maybe_unused -+char * const stm32mp1_clk_parent_sel_name[_PARENT_SEL_NB] = { - [_I2C12_SEL] = "I2C12", - [_I2C35_SEL] = "I2C35", - [_I2C46_SEL] = "I2C46", -@@ -720,7 +747,6 @@ static const char * const stm32mp1_clk_parent_sel_name[_PARENT_SEL_NB] = { - [_DSI_SEL] = "DSI", - [_ADC12_SEL] = "ADC12", - }; --#endif - - static const struct stm32mp1_clk_data stm32mp1_data = { - .gate = stm32mp1_clk_gate, -@@ -736,9 +762,6 @@ static ulong stm32mp1_clk_get_fixed(struct stm32mp1_clk_priv *priv, int idx) - return 0; - } - -- debug("%s: clk id %d = %x : %ld kHz\n", __func__, idx, -- (u32)priv->osc[idx], priv->osc[idx] / 1000); -- - return priv->osc[idx]; - } - -@@ -839,8 +862,6 @@ static ulong pll_get_fref_ck(struct stm32mp1_clk_priv *priv, - src = selr & RCC_SELR_SRC_MASK; - - refclk = stm32mp1_clk_get_fixed(priv, pll[pll_id].refclk[src]); -- debug("PLL%d : selr=%x refclk = %d kHz\n", -- pll_id, selr, (u32)(refclk / 1000)); - - return refclk; - } -@@ -865,9 +886,6 @@ static ulong pll_get_fvco(struct stm32mp1_clk_priv *priv, - divm = (cfgr1 & (RCC_PLLNCFGR1_DIVM_MASK)) >> RCC_PLLNCFGR1_DIVM_SHIFT; - divn = cfgr1 & RCC_PLLNCFGR1_DIVN_MASK; - -- debug("PLL%d : cfgr1=%x fracr=%x DIVN=%d DIVM=%d\n", -- pll_id, cfgr1, fracr, divn, divm); -- - refclk = pll_get_fref_ck(priv, pll_id); - - /* with FRACV : -@@ -884,7 +902,6 @@ static ulong pll_get_fvco(struct stm32mp1_clk_priv *priv, - } else { - fvco = (ulong)(refclk * (divn + 1) / (divm + 1)); - } -- debug("PLL%d : %s = %ld\n", pll_id, __func__, fvco); - - return fvco; - } -@@ -897,17 +914,12 @@ static ulong stm32mp1_read_pll_freq(struct stm32mp1_clk_priv *priv, - ulong dfout; - u32 cfgr2; - -- debug("%s(%d, %d)\n", __func__, pll_id, div_id); - if (div_id >= _DIV_NB) - return 0; - - cfgr2 = readl(priv->base + pll[pll_id].pllxcfgr2); - divy = (cfgr2 >> RCC_PLLNCFGR2_SHIFT(div_id)) & RCC_PLLNCFGR2_DIVX_MASK; -- -- debug("PLL%d : cfgr2=%x DIVY=%d\n", pll_id, cfgr2, divy); -- - dfout = pll_get_fvco(priv, pll_id) / (divy + 1); -- debug(" => dfout = %d kHz\n", (u32)(dfout / 1000)); - - return dfout; - } -@@ -918,8 +930,8 @@ static ulong stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p) - ulong clock = 0; - - switch (p) { -- case _CK_MPU: - /* MPU sub system */ -+ case _CK_MPU: - reg = readl(priv->base + RCC_MPCKSELR); - switch (reg & RCC_SELR_SRC_MASK) { - case RCC_MPCKSELR_HSI: -@@ -1076,7 +1088,7 @@ static ulong stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p) - break; - /* other */ - case _USB_PHY_48: -- clock = stm32mp1_clk_get_fixed(priv, _USB_PHY_48); -+ clock = 48000000; - break; - case _DSI_PHY: - { -@@ -1114,7 +1126,13 @@ static int stm32mp1_clk_enable(struct clk *clk) - return i; - - if (gate[i].set_clr) -- writel(BIT(gate[i].bit), priv->base + gate[i].offset); -+#ifdef CONFIG_STM32MP1_TRUSTED -+ if (gate[i].secure) -+ stm32_smc_exec(STM32_SMC_RCC, STM32_SMC_REG_WRITE, -+ gate[i].offset, BIT(gate[i].bit)); -+ else -+#endif /* CONFIG_STM32MP1_TRUSTED */ -+ writel(BIT(gate[i].bit), priv->base + gate[i].offset); - else - setbits_le32(priv->base + gate[i].offset, BIT(gate[i].bit)); - -@@ -1133,9 +1151,16 @@ static int stm32mp1_clk_disable(struct clk *clk) - return i; - - if (gate[i].set_clr) -- writel(BIT(gate[i].bit), -- priv->base + gate[i].offset -- + RCC_MP_ENCLRR_OFFSET); -+#ifdef CONFIG_STM32MP1_TRUSTED -+ if (gate[i].secure) -+ stm32_smc_exec(STM32_SMC_RCC, STM32_SMC_REG_WRITE, -+ gate[i].offset + RCC_MP_ENCLRR_OFFSET, -+ BIT(gate[i].bit)); -+ else -+#endif /* CONFIG_STM32MP1_TRUSTED */ -+ writel(BIT(gate[i].bit), -+ priv->base + gate[i].offset -+ + RCC_MP_ENCLRR_OFFSET); - else - clrbits_le32(priv->base + gate[i].offset, BIT(gate[i].bit)); - -@@ -1176,10 +1201,7 @@ static void stm32mp1_ls_osc_set(int enable, fdt_addr_t rcc, u32 offset, - - static void stm32mp1_hs_ocs_set(int enable, fdt_addr_t rcc, u32 mask_on) - { -- if (enable) -- setbits_le32(rcc + RCC_OCENSETR, mask_on); -- else -- setbits_le32(rcc + RCC_OCENCLRR, mask_on); -+ writel(mask_on, rcc + (enable ? RCC_OCENSETR : RCC_OCENCLRR)); - } - - static int stm32mp1_osc_wait(int enable, fdt_addr_t rcc, u32 offset, -@@ -1250,20 +1272,20 @@ static void stm32mp1_lsi_set(fdt_addr_t rcc, int enable) - static void stm32mp1_hse_enable(fdt_addr_t rcc, int bypass, int digbyp, int css) - { - if (digbyp) -- setbits_le32(rcc + RCC_OCENSETR, RCC_OCENR_DIGBYP); -+ writel(RCC_OCENR_DIGBYP, rcc + RCC_OCENSETR); - if (bypass || digbyp) -- setbits_le32(rcc + RCC_OCENSETR, RCC_OCENR_HSEBYP); -+ writel(RCC_OCENR_HSEBYP, rcc + RCC_OCENSETR); - - stm32mp1_hs_ocs_set(1, rcc, RCC_OCENR_HSEON); - stm32mp1_osc_wait(1, rcc, RCC_OCRDYR, RCC_OCRDYR_HSERDY); - - if (css) -- setbits_le32(rcc + RCC_OCENSETR, RCC_OCENR_HSECSSON); -+ writel(RCC_OCENR_HSECSSON, rcc + RCC_OCENSETR); - } - - static void stm32mp1_csi_set(fdt_addr_t rcc, int enable) - { -- stm32mp1_ls_osc_set(enable, rcc, RCC_OCENSETR, RCC_OCENR_CSION); -+ stm32mp1_hs_ocs_set(enable, rcc, RCC_OCENR_CSION); - stm32mp1_osc_wait(enable, rcc, RCC_OCRDYR, RCC_OCRDYR_CSIRDY); - } - -@@ -1439,6 +1461,71 @@ static void pll_csg(struct stm32mp1_clk_priv *priv, int pll_id, u32 *csg) - writel(pllxcsg, priv->base + pll[pll_id].pllxcsgr); - } - -+static __maybe_unused int pll_set_rate(struct udevice *dev, -+ int pll_id, -+ int div_id, -+ unsigned long clk_rate) -+{ -+ struct stm32mp1_clk_priv *priv = dev_get_priv(dev); -+ unsigned int pllcfg[PLLCFG_NB]; -+ ofnode plloff; -+ char name[12]; -+ const struct stm32mp1_clk_pll *pll = priv->data->pll; -+ enum stm32mp1_plltype type = pll[pll_id].plltype; -+ int divm, divn, divy; -+ int ret; -+ ulong fck_ref; -+ u32 fracv; -+ u64 value; -+ -+ if (div_id > _DIV_NB) -+ return -EINVAL; -+ -+ sprintf(name, "st,pll@%d", pll_id); -+ plloff = dev_read_subnode(dev, name); -+ if (!ofnode_valid(plloff)) -+ return -FDT_ERR_NOTFOUND; -+ -+ ret = ofnode_read_u32_array(plloff, "cfg", -+ pllcfg, PLLCFG_NB); -+ if (ret < 0) -+ return -FDT_ERR_NOTFOUND; -+ -+ fck_ref = pll_get_fref_ck(priv, pll_id); -+ -+ divm = pllcfg[PLLCFG_M]; -+ /* select output divider = 0: for _DIV_P, 1:_DIV_Q 2:_DIV_R */ -+ divy = pllcfg[PLLCFG_P + div_id]; -+ -+ /* For: PLL1 & PLL2 => VCO is * 2 but ck_pll_y is also / 2 -+ * So same final result than PLL2 et 4 -+ * with FRACV -+ * Fck_pll_y = Fck_ref * ((DIVN + 1) + FRACV / 2^13) -+ * / (DIVy + 1) * (DIVM + 1) -+ * value = (DIVN + 1) * 2^13 + FRACV / 2^13 -+ * = Fck_pll_y (DIVy + 1) * (DIVM + 1) * 2^13 / Fck_ref -+ */ -+ value = ((u64)clk_rate * (divy + 1) * (divm + 1)) << 13; -+ value = lldiv(value, fck_ref); -+ -+ divn = (value >> 13) - 1; -+ if (divn < DIVN_MIN || -+ divn > stm32mp1_pll[type].divn_max) { -+ pr_err("divn invalid = %d", divn); -+ return -EINVAL; -+ } -+ fracv = value - ((divn + 1) << 13); -+ pllcfg[PLLCFG_N] = divn; -+ -+ /* reconfigure PLL */ -+ pll_stop(priv, pll_id); -+ pll_config(priv, pll_id, pllcfg, fracv); -+ pll_start(priv, pll_id); -+ pll_output(priv, pll_id, pllcfg[PLLCFG_O]); -+ -+ return 0; -+} -+ - static int set_clksrc(struct stm32mp1_clk_priv *priv, unsigned int clksrc) - { - u32 address = priv->base + (clksrc >> 4); -@@ -1468,10 +1555,15 @@ static void stgen_config(struct stm32mp1_clk_priv *priv) - rate = stm32mp1_clk_get(priv, p); - - if (cntfid0 != rate) { -+ u64 counter; -+ - pr_debug("System Generic Counter (STGEN) update\n"); - clrbits_le32(stgenc + STGENC_CNTCR, STGENC_CNTCR_EN); -- writel(0x0, stgenc + STGENC_CNTCVL); -- writel(0x0, stgenc + STGENC_CNTCVU); -+ counter = (u64)readl(stgenc + STGENC_CNTCVL); -+ counter |= ((u64)(readl(stgenc + STGENC_CNTCVU))) << 32; -+ counter = lldiv(counter * (u64)rate, cntfid0); -+ writel((u32)counter, stgenc + STGENC_CNTCVL); -+ writel((u32)(counter >> 32), stgenc + STGENC_CNTCVU); - writel(rate, stgenc + STGENC_CNTFID0); - setbits_le32(stgenc + STGENC_CNTCR, STGENC_CNTCR_EN); - -@@ -1479,9 +1571,6 @@ static void stgen_config(struct stm32mp1_clk_priv *priv) - - /* need to update gd->arch.timer_rate_hz with new frequency */ - timer_init(); -- pr_debug("gd->arch.timer_rate_hz = %x\n", -- (u32)gd->arch.timer_rate_hz); -- pr_debug("Tick = %x\n", (u32)(get_ticks())); - } - } - -@@ -1787,7 +1876,6 @@ static int pll_set_output_rate(struct udevice *dev, - if (div > 128) - div = 128; - -- debug("fvco = %ld, clk_rate = %ld, div=%d\n", fvco, clk_rate, div); - /* stop the requested output */ - clrbits_le32(pllxcr, 0x1 << div_id << RCC_PLLNCR_DIVEN_SHIFT); - /* change divider */ -@@ -1806,6 +1894,11 @@ static ulong stm32mp1_clk_set_rate(struct clk *clk, unsigned long clk_rate) - int p; - - switch (clk->id) { -+#if defined(STM32MP1_CLOCK_TREE_INIT) && \ -+ defined(CONFIG_STM32MP1_DDR_INTERACTIVE) -+ case DDRPHYC: -+ break; -+#endif - case LTDC_PX: - case DSI_PX: - break; -@@ -1815,10 +1908,27 @@ static ulong stm32mp1_clk_set_rate(struct clk *clk, unsigned long clk_rate) - } - - p = stm32mp1_clk_get_parent(priv, clk->id); -+#ifdef DEBUG -+ debug("%s: parent = %d:%s\n", __func__, p, stm32mp1_clk_parent_name[p]); -+#endif - if (p < 0) - return -EINVAL; - - switch (p) { -+#if defined(STM32MP1_CLOCK_TREE_INIT) && \ -+ defined(CONFIG_STM32MP1_DDR_INTERACTIVE) -+ case _PLL2_R: /* DDRPHYC */ -+ { -+ /* only for change DDR clock in interactive mode */ -+ ulong result; -+ -+ set_clksrc(priv, CLK_AXI_HSI); -+ result = pll_set_rate(clk->dev, _PLL2, _DIV_R, clk_rate); -+ set_clksrc(priv, CLK_AXI_PLL2P); -+ return result; -+ } -+#endif -+ - case _PLL4_Q: - /* for LTDC_PX and DSI_PX case */ - return pll_set_output_rate(clk->dev, _PLL4, _DIV_Q, clk_rate); -@@ -1856,7 +1966,7 @@ static void stm32mp1_osc_init(struct udevice *dev) - [_HSE] = "clk-hse", - [_CSI] = "clk-csi", - [_I2S_CKIN] = "i2s_ckin", -- [_USB_PHY_48] = "ck_usbo_48m"}; -+ }; - - for (i = 0; i < NB_OSC; i++) { - stm32mp1_osc_clk_init(name[i], priv, i); -@@ -1864,6 +1974,54 @@ static void stm32mp1_osc_init(struct udevice *dev) - } - } - -+static void __maybe_unused stm32mp1_clk_dump(struct stm32mp1_clk_priv *priv) -+{ -+ char buf[32]; -+ int i, s, p; -+ -+ printf("Clocks:\n"); -+ for (i = 0; i < _PARENT_NB; i++) { -+ printf("- %s : %s MHz\n", -+ stm32mp1_clk_parent_name[i], -+ strmhz(buf, stm32mp1_clk_get(priv, i))); -+ } -+ printf("Source Clocks:\n"); -+ for (i = 0; i < _PARENT_SEL_NB; i++) { -+ p = (readl(priv->base + priv->data->sel[i].offset) >> -+ priv->data->sel[i].src) & priv->data->sel[i].msk; -+ if (p < priv->data->sel[i].nb_parent) { -+ s = priv->data->sel[i].parent[p]; -+ printf("- %s(%d) => parent %s(%d)\n", -+ stm32mp1_clk_parent_sel_name[i], i, -+ stm32mp1_clk_parent_name[s], s); -+ } else { -+ printf("- %s(%d) => parent index %d is invalid\n", -+ stm32mp1_clk_parent_sel_name[i], i, p); -+ } -+ } -+} -+ -+#ifdef CONFIG_CMD_CLK -+int soc_clk_dump(void) -+{ -+ struct udevice *dev; -+ struct stm32mp1_clk_priv *priv; -+ int ret; -+ -+ ret = uclass_get_device_by_driver(UCLASS_CLK, -+ DM_GET_DRIVER(stm32mp1_clock), -+ &dev); -+ if (ret) -+ return ret; -+ -+ priv = dev_get_priv(dev); -+ -+ stm32mp1_clk_dump(priv); -+ -+ return 0; -+} -+#endif -+ - static int stm32mp1_clk_probe(struct udevice *dev) - { - int result = 0; -@@ -1887,6 +2045,33 @@ static int stm32mp1_clk_probe(struct udevice *dev) - result = stm32mp1_clktree(dev); - #endif - -+#ifndef CONFIG_SPL_BUILD -+#if defined(DEBUG) -+ /* display debug information for probe after relocation */ -+ if (gd->flags & GD_FLG_RELOC) -+ stm32mp1_clk_dump(priv); -+#endif -+ -+#if defined(CONFIG_DISPLAY_CPUINFO) -+ if (gd->flags & GD_FLG_RELOC) { -+ char buf[32]; -+ -+ printf("Clocks:\n"); -+ printf("- MPU : %s MHz\n", -+ strmhz(buf, stm32mp1_clk_get(priv, _CK_MPU))); -+ printf("- MCU : %s MHz\n", -+ strmhz(buf, stm32mp1_clk_get(priv, _CK_MCU))); -+ printf("- AXI : %s MHz\n", -+ strmhz(buf, stm32mp1_clk_get(priv, _ACLK))); -+ printf("- PER : %s MHz\n", -+ strmhz(buf, stm32mp1_clk_get(priv, _CK_PER))); -+ /* DDRPHYC father */ -+ printf("- DDR : %s MHz\n", -+ strmhz(buf, stm32mp1_clk_get(priv, _PLL2_R))); -+ } -+#endif /* CONFIG_DISPLAY_CPUINFO */ -+#endif -+ - return result; - } - -diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c -index 303e166..85d82749 100644 ---- a/drivers/core/syscon-uclass.c -+++ b/drivers/core/syscon-uclass.c -@@ -123,52 +123,49 @@ U_BOOT_DRIVER(generic_syscon) = { - * The syscon node can be bound to another driver, but still works - * as a syscon provider. - */ --static LIST_HEAD(syscon_list); -- --struct syscon { -- ofnode node; -- struct regmap *regmap; -- struct list_head list; --}; -- --static struct syscon *of_syscon_register(ofnode node) -+struct regmap *syscon_node_to_regmap(ofnode node) - { -- struct syscon *syscon; -+ struct udevice *dev, *parent; -+ ofnode ofnode = node; - int ret; - -+ if (!uclass_get_device_by_ofnode(UCLASS_SYSCON, node, &dev)) -+ return syscon_get_regmap(dev); -+ - if (!ofnode_device_is_compatible(node, "syscon")) - return ERR_PTR(-EINVAL); - -- syscon = malloc(sizeof(*syscon)); -- if (!syscon) -- return ERR_PTR(-ENOMEM); -+ if (device_find_global_by_ofnode(ofnode, &parent)) -+ parent = dm_root(); - -- ret = regmap_init_mem(node, &syscon->regmap); -- if (ret) { -- free(syscon); -+ /* force bound to syscon class */ -+ ret = device_bind_driver_to_node(parent, "syscon", -+ ofnode_get_name(node), -+ node, &dev); -+ if (ret) - return ERR_PTR(ret); -- } - -- list_add_tail(&syscon->list, &syscon_list); -+ ret = device_probe(dev); -+ if (ret) -+ return ERR_PTR(ret); - -- return syscon; -+ return syscon_get_regmap(dev); - } - --struct regmap *syscon_node_to_regmap(ofnode node) -+struct regmap *syscon_phandle_to_regmap(struct udevice *parent, -+ const char *name) - { -- struct syscon *entry, *syscon = NULL; -- -- list_for_each_entry(entry, &syscon_list, list) -- if (ofnode_equal(entry->node, node)) { -- syscon = entry; -- break; -- } -+ u32 phandle; -+ ofnode node; -+ int err; - -- if (!syscon) -- syscon = of_syscon_register(node); -+ err = ofnode_read_u32(dev_ofnode(parent), name, &phandle); -+ if (err) -+ return ERR_PTR(err); - -- if (IS_ERR(syscon)) -- return ERR_CAST(syscon); -+ node = ofnode_get_by_phandle(phandle); -+ if (!ofnode_valid(node)) -+ return ERR_PTR(-EINVAL); - -- return syscon->regmap; -+ return syscon_node_to_regmap(node); - } -diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c -index 3113d6a..a4452bd 100644 ---- a/drivers/core/uclass.c -+++ b/drivers/core/uclass.c -@@ -562,6 +562,19 @@ int uclass_next_device(struct udevice **devp) - return uclass_get_device_tail(dev, ret, devp); - } - -+int uclass_next_device_err(struct udevice **devp) -+{ -+ int ret; -+ -+ ret = uclass_next_device(devp); -+ if (ret) -+ return ret; -+ else if (!*devp) -+ return -ENODEV; -+ -+ return 0; -+} -+ - int uclass_first_device_check(enum uclass_id id, struct udevice **devp) - { - int ret; -diff --git a/drivers/dfu/Kconfig b/drivers/dfu/Kconfig -index 4692736..edbe817 100644 ---- a/drivers/dfu/Kconfig -+++ b/drivers/dfu/Kconfig -@@ -46,5 +46,10 @@ config DFU_SF - This option enables using DFU to read and write to SPI flash based - storage. - -+config DFU_VIRT -+ bool "Virtual back end for DFU" -+ help -+ This option enables using DFU to read and write to virtual partition. -+ - endif - endmenu -diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile -index 56f9b0c..830eab3 100644 ---- a/drivers/dfu/Makefile -+++ b/drivers/dfu/Makefile -@@ -9,3 +9,4 @@ obj-$(CONFIG_DFU_NAND) += dfu_nand.o - obj-$(CONFIG_DFU_RAM) += dfu_ram.o - obj-$(CONFIG_DFU_SF) += dfu_sf.o - obj-$(CONFIG_DFU_TFTP) += dfu_tftp.o -+obj-$(CONFIG_DFU_VIRT) += dfu_virt.o -diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c -index 3189495..f7919b4 100644 ---- a/drivers/dfu/dfu.c -+++ b/drivers/dfu/dfu.c -@@ -22,6 +22,22 @@ static int alt_num_cnt; - static struct hash_algo *dfu_hash_algo; - - /* -+ * The purpose of the dfu_flush_callback() function is to -+ * provide callback for dfu user -+ */ -+__weak void dfu_flush_callback(struct dfu_entity *dfu) -+{ -+} -+ -+/* -+ * The purpose of the dfu_flush_callback() function is to -+ * provide callback for dfu user -+ */ -+__weak void dfu_initiated_callback(struct dfu_entity *dfu) -+{ -+} -+ -+/* - * The purpose of the dfu_usb_get_reset() function is to - * provide information if after USB_DETACH request - * being sent the dfu-util performed reset of USB -@@ -82,6 +98,7 @@ done: - - static unsigned char *dfu_buf; - static unsigned long dfu_buf_size; -+static enum dfu_device_type dfu_buf_device_type; - - unsigned char *dfu_free_buf(void) - { -@@ -99,6 +116,10 @@ unsigned char *dfu_get_buf(struct dfu_entity *dfu) - { - char *s; - -+ /* manage several entity with several contraint */ -+ if (dfu_buf && dfu->dev_type != dfu_buf_device_type) -+ dfu_free_buf(); -+ - if (dfu_buf != NULL) - return dfu_buf; - -@@ -117,6 +138,7 @@ unsigned char *dfu_get_buf(struct dfu_entity *dfu) - printf("%s: Could not memalign 0x%lx bytes\n", - __func__, dfu_buf_size); - -+ dfu_buf_device_type = dfu->dev_type; - return dfu_buf; - } - -@@ -204,6 +226,7 @@ int dfu_transaction_initiate(struct dfu_entity *dfu, bool read) - } - - dfu->inited = 1; -+ dfu_initiated_callback(dfu); - - return 0; - } -@@ -223,6 +246,8 @@ int dfu_flush(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) - printf("\nDFU complete %s: 0x%08x\n", dfu_hash_algo->name, - dfu->crc); - -+ dfu_flush_callback(dfu); -+ - dfu_transaction_cleanup(dfu); - - return ret; -@@ -337,6 +362,8 @@ static int dfu_read_buffer_fill(struct dfu_entity *dfu, void *buf, int size) - debug("%s: Read error!\n", __func__); - return ret; - } -+ if (dfu->b_left == 0) -+ break; - dfu->offset += dfu->b_left; - dfu->r_left -= dfu->b_left; - -@@ -389,7 +416,8 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt, - { - char *st; - -- debug("%s: %s interface: %s dev: %s\n", __func__, s, interface, devstr); -+ debug("%s: %s interface: %s dev: %s\n", -+ __func__, s, interface, devstr); - st = strsep(&s, " "); - strcpy(dfu->name, st); - -@@ -410,11 +438,15 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt, - } else if (strcmp(interface, "sf") == 0) { - if (dfu_fill_entity_sf(dfu, devstr, s)) - return -1; -+ } else if (strcmp(interface, "virt") == 0) { -+ if (dfu_fill_entity_virt(dfu, devstr, s)) -+ return -1; - } else { - printf("%s: Device %s not (yet) supported!\n", - __func__, interface); - return -1; - } -+ - dfu_get_buf(dfu); - - return 0; -@@ -438,13 +470,12 @@ void dfu_free_entities(void) - alt_num_cnt = 0; - } - --int dfu_config_entities(char *env, char *interface, char *devstr) -+int dfu_alt_init(int num, struct dfu_entity **dfu) - { -- struct dfu_entity *dfu; -- int i, ret; - char *s; -+ int ret; - -- dfu_alt_num = dfu_find_alt_num(env); -+ dfu_alt_num = num; - debug("%s: dfu_alt_num=%d\n", __func__, dfu_alt_num); - - dfu_hash_algo = NULL; -@@ -455,21 +486,47 @@ int dfu_config_entities(char *env, char *interface, char *devstr) - pr_err("Hash algorithm %s not supported\n", s); - } - -- dfu = calloc(sizeof(*dfu), dfu_alt_num); -+ *dfu = calloc(sizeof(struct dfu_entity), dfu_alt_num); - if (!dfu) - return -1; -- for (i = 0; i < dfu_alt_num; i++) { -+ return 0; -+} - -+int dfu_alt_add(struct dfu_entity *dfu, char *interface, char *devstr, char *s) -+{ -+ struct dfu_entity *p_dfu; -+ int ret; -+ -+ if (alt_num_cnt >= dfu_alt_num) -+ return -1; -+ -+ p_dfu = &dfu[alt_num_cnt]; -+ ret = dfu_fill_entity(p_dfu, s, alt_num_cnt, interface, devstr); -+ if (ret) -+ return -1; -+ -+ list_add_tail(&p_dfu->list, &dfu_list); -+ alt_num_cnt++; -+ return 0; -+} -+ -+int dfu_config_entities(char *env, char *interface, char *devstr) -+{ -+ struct dfu_entity *dfu; -+ int i, ret; -+ char *s; -+ -+ ret = dfu_alt_init(dfu_find_alt_num(env), &dfu); -+ if (ret) -+ return -1; -+ -+ for (i = 0; i < dfu_alt_num; i++) { - s = strsep(&env, ";"); -- ret = dfu_fill_entity(&dfu[i], s, alt_num_cnt, interface, -- devstr); -+ ret = dfu_alt_add(dfu, interface, devstr, s); - if (ret) { - /* We will free "dfu" in dfu_free_entities() */ - return -1; - } -- -- list_add_tail(&dfu[i].list, &dfu_list); -- alt_num_cnt++; - } - - return 0; -@@ -477,7 +534,8 @@ int dfu_config_entities(char *env, char *interface, char *devstr) - - const char *dfu_get_dev_type(enum dfu_device_type t) - { -- const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND", "RAM", "SF" }; -+ const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND", "RAM", "SF", -+ "VIRT"}; - return dev_t[t]; - } - -diff --git a/drivers/dfu/dfu_sf.c b/drivers/dfu/dfu_sf.c -index 066e767..65edba3 100644 ---- a/drivers/dfu/dfu_sf.c -+++ b/drivers/dfu/dfu_sf.c -@@ -10,6 +10,8 @@ - #include - #include - #include -+#include -+#include - - static int dfu_get_medium_size_sf(struct dfu_entity *dfu, u64 *size) - { -@@ -19,7 +21,7 @@ static int dfu_get_medium_size_sf(struct dfu_entity *dfu, u64 *size) - } - - static int dfu_read_medium_sf(struct dfu_entity *dfu, u64 offset, void *buf, -- long *len) -+ long *len) - { - return spi_flash_read(dfu->data.sf.dev, dfu->data.sf.start + offset, - *len, buf); -@@ -32,7 +34,7 @@ static u64 find_sector(struct dfu_entity *dfu, u64 start, u64 offset) - } - - static int dfu_write_medium_sf(struct dfu_entity *dfu, -- u64 offset, void *buf, long *len) -+ u64 offset, void *buf, long *len) - { - int ret; - -@@ -52,11 +54,32 @@ static int dfu_write_medium_sf(struct dfu_entity *dfu, - - static int dfu_flush_medium_sf(struct dfu_entity *dfu) - { -+ u64 off, length; -+ -+ if (!dfu->data.sf.ubi) -+ return 0; -+ -+ /* in case of ubi partition, erase rest of the partition */ -+ off = find_sector(dfu, dfu->data.sf.start, dfu->offset); -+ /* last write ended with unaligned length jump to next */ -+ if (off != dfu->data.sf.start + dfu->offset) -+ off += dfu->data.sf.dev->sector_size; -+ length = dfu->data.sf.start + dfu->data.sf.size - off; -+ if (length) -+ return spi_flash_erase(dfu->data.sf.dev, off, length); -+ - return 0; - } - - static unsigned int dfu_polltimeout_sf(struct dfu_entity *dfu) - { -+ /* -+ * Currently, Poll Timeout != 0 is only needed on nor -+ * ubi partition, as the not used sectors need an erase -+ */ -+ if (dfu->data.sf.ubi) -+ return DFU_MANIFEST_POLL_TIMEOUT; -+ - return DFU_DEFAULT_POLL_TIMEOUT; - } - -@@ -133,6 +156,33 @@ int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, char *s) - dfu->data.sf.start = simple_strtoul(s, &s, 16); - s++; - dfu->data.sf.size = simple_strtoul(s, &s, 16); -+ } else if ((!strcmp(st, "part")) || (!strcmp(st, "partubi"))) { -+ char mtd_id[32]; -+ struct mtd_device *mtd_dev; -+ u8 part_num; -+ struct part_info *pi; -+ int ret, dev, part; -+ -+ dfu->layout = DFU_RAW_ADDR; -+ -+ dev = simple_strtoul(s, &s, 10); -+ s++; -+ part = simple_strtoul(s, &s, 10); -+ -+ sprintf(mtd_id, "%s%d,%d", "nor", dev, part - 1); -+ printf("using id '%s'\n", mtd_id); -+ -+ mtdparts_init(); -+ -+ ret = find_dev_and_part(mtd_id, &mtd_dev, &part_num, &pi); -+ if (ret != 0) { -+ printf("Could not locate '%s'\n", mtd_id); -+ return -1; -+ } -+ dfu->data.sf.start = pi->offset; -+ dfu->data.sf.size = pi->size; -+ if (!strcmp(st, "partubi")) -+ dfu->data.sf.ubi = 1; - } else { - printf("%s: Memory layout (%s) not supported!\n", __func__, st); - spi_flash_free(dfu->data.sf.dev); -diff --git a/drivers/dfu/dfu_virt.c b/drivers/dfu/dfu_virt.c -new file mode 100644 -index 0000000..035d71f ---- /dev/null -+++ b/drivers/dfu/dfu_virt.c -@@ -0,0 +1,47 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+ -+/* TODO : weak or function to implement ? */ -+int __weak dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset, -+ void *buf, long *len) -+{ -+ debug("%s: off=0x%llx, len=0x%x\n", __func__, offset, (u32)*len); -+ return 0; -+} -+ -+int __weak dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size) -+{ -+ *size = 0; -+ -+ return 0; -+} -+ -+int __weak dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset, -+ void *buf, long *len) -+{ -+ debug("%s: off=0x%llx, len=0x%x\n", __func__, offset, (u32)*len); -+ *len = 0; -+ return 0; -+} -+ -+int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr, char *s) -+{ -+ debug("%s: devstr = %s\n", __func__, devstr); -+ dfu->dev_type = DFU_DEV_VIRT; -+ dfu->layout = DFU_RAW_ADDR; -+ dfu->data.virt.dev_num = simple_strtoul(devstr, NULL, 10); -+ dfu->write_medium = dfu_write_medium_virt; -+ dfu->get_medium_size = dfu_get_medium_size_virt; -+ dfu->read_medium = dfu_read_medium_virt; -+ -+ dfu->inited = 0; -+ -+ return 0; -+} -diff --git a/drivers/gpio/stm32f7_gpio.c b/drivers/gpio/stm32f7_gpio.c -index 4c0786f..7fff64e 100644 ---- a/drivers/gpio/stm32f7_gpio.c -+++ b/drivers/gpio/stm32f7_gpio.c -@@ -15,17 +15,45 @@ - #include - #include - --#define STM32_GPIOS_PER_BANK 16 - #define MODE_BITS(gpio_pin) (gpio_pin * 2) - #define MODE_BITS_MASK 3 - #define BSRR_BIT(gpio_pin, value) BIT(gpio_pin + (value ? 0 : 16)) - -+/* -+ * convert gpio offset to gpio index due to potential gpio -+ * holes into gpio bank -+ */ -+int stm32_offset_to_index(struct udevice *dev, unsigned int offset) -+{ -+ struct stm32_gpio_priv *priv = dev_get_priv(dev); -+ 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++; -+ } -+ } -+ /* shouldn't happen */ -+ return -EINVAL; -+} -+ - 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 bits_index = MODE_BITS(offset); -- int mask = MODE_BITS_MASK << bits_index; -+ int bits_index; -+ int mask; -+ int idx; -+ -+ idx = stm32_offset_to_index(dev, offset); -+ if (idx < 0) -+ return idx; -+ -+ bits_index = MODE_BITS(idx); -+ mask = MODE_BITS_MASK << bits_index; - - clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_IN << bits_index); - -@@ -37,12 +65,20 @@ 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 bits_index = MODE_BITS(offset); -- int mask = MODE_BITS_MASK << bits_index; -+ int bits_index; -+ int mask; -+ int idx; -+ -+ idx = stm32_offset_to_index(dev, offset); -+ if (idx < 0) -+ return idx; -+ -+ bits_index = MODE_BITS(idx); -+ mask = MODE_BITS_MASK << bits_index; - - clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_OUT << bits_index); - -- writel(BSRR_BIT(offset, value), ®s->bsrr); -+ writel(BSRR_BIT(idx, value), ®s->bsrr); - - return 0; - } -@@ -51,33 +87,75 @@ 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; - -- return readl(®s->idr) & BIT(offset) ? 1 : 0; -+ idx = stm32_offset_to_index(dev, offset); -+ if (idx < 0) -+ return idx; -+ -+ return readl(®s->idr) & BIT(idx) ? 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; - -- writel(BSRR_BIT(offset, value), ®s->bsrr); -+ writel(BSRR_BIT(idx, value), ®s->bsrr); - - return 0; - } - -+static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset) -+{ -+ struct stm32_gpio_priv *priv = dev_get_priv(dev); -+ 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; -+ -+ bits_index = MODE_BITS(idx); -+ mask = MODE_BITS_MASK << bits_index; -+ -+ mode = (readl(®s->moder) & mask) >> bits_index; -+ if (mode == STM32_GPIO_MODE_OUT) -+ return GPIOF_OUTPUT; -+ if (mode == STM32_GPIO_MODE_IN) -+ return GPIOF_INPUT; -+ if (mode == STM32_GPIO_MODE_AN) -+ return GPIOF_UNUSED; -+ -+ return GPIOF_FUNC; -+} -+ - static const struct dm_gpio_ops gpio_stm32_ops = { - .direction_input = stm32_gpio_direction_input, - .direction_output = stm32_gpio_direction_output, - .get_value = stm32_gpio_get_value, - .set_value = stm32_gpio_set_value, -+ .get_function = stm32_gpio_get_function, - }; - - static int gpio_stm32_probe(struct udevice *dev) - { - struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); - struct stm32_gpio_priv *priv = dev_get_priv(dev); -+ struct ofnode_phandle_args args; -+ struct clk clk; - fdt_addr_t addr; - const char *name; -+ int ret; -+ int i; - - addr = dev_read_addr(dev); - if (addr == FDT_ADDR_T_NONE) -@@ -88,14 +166,25 @@ static int gpio_stm32_probe(struct udevice *dev) - if (!name) - return -EINVAL; - uc_priv->bank_name = name; -- uc_priv->gpio_count = dev_read_u32_default(dev, "ngpios", -- STM32_GPIOS_PER_BANK); -- debug("%s, addr = 0x%p, bank_name = %s\n", __func__, (u32 *)priv->regs, -- uc_priv->bank_name); - --#ifdef CONFIG_CLK -- struct clk clk; -- int ret; -+ i = 0; -+ ret = dev_read_phandle_with_args(dev, "gpio-ranges", -+ NULL, 3, i, &args); -+ -+ 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); -+ } -+ -+ dev_dbg(dev, "addr = 0x%p bank_name = %s gpio_count = %d gpio_range = 0x%x\n", -+ (u32 *)priv->regs, uc_priv->bank_name, uc_priv->gpio_count, -+ priv->gpio_range); -+ - ret = clk_get_by_index(dev, 0, &clk); - if (ret < 0) - return ret; -@@ -107,7 +196,6 @@ static int gpio_stm32_probe(struct udevice *dev) - return ret; - } - debug("clock enabled for device %s\n", dev->name); --#endif - - return 0; - } -diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig -new file mode 100644 -index 0000000..96d4f5d ---- /dev/null -+++ b/drivers/hwspinlock/Kconfig -@@ -0,0 +1,24 @@ -+menu "Hardware Spinlock Support" -+ -+config DM_HWSPINLOCK -+ bool "Enable U-Boot hardware spinlock support" -+ help -+ This option enables U-Boot hardware spinlock support -+ -+config HWSPINLOCK_SANDBOX -+ bool "Enable Hardware Spinlock support for Sandbox" -+ depends on SANDBOX && DM_HWSPINLOCK -+ help -+ Enable hardware spinlock support in Sandbox. This is a dummy device that -+ can be probed and support all the methods of HWSPINLOCK, but does not -+ really do anything. -+ -+config HWSPINLOCK_STM32 -+ bool "Enable Hardware Spinlock support for STM32" -+ depends on ARCH_STM32MP && DM_HWSPINLOCK -+ help -+ Enable hardware spinlock support in STM32MP. Hardware spinlocks are -+ hardware mutex which provide a synchronisation mechanism for the -+ various processors on the SoC. -+ -+endmenu -diff --git a/drivers/hwspinlock/Makefile b/drivers/hwspinlock/Makefile -new file mode 100644 -index 0000000..289b12a ---- /dev/null -+++ b/drivers/hwspinlock/Makefile -@@ -0,0 +1,7 @@ -+# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+# -+# Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ -+obj-$(CONFIG_DM_HWSPINLOCK) += hwspinlock-uclass.o -+obj-$(CONFIG_HWSPINLOCK_SANDBOX) += sandbox_hwspinlock.o -+obj-$(CONFIG_HWSPINLOCK_STM32) += stm32_hwspinlock.o -diff --git a/drivers/hwspinlock/hwspinlock-uclass.c b/drivers/hwspinlock/hwspinlock-uclass.c -new file mode 100644 -index 0000000..195f079 ---- /dev/null -+++ b/drivers/hwspinlock/hwspinlock-uclass.c -@@ -0,0 +1,144 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static inline const struct hwspinlock_ops * -+hwspinlock_dev_ops(struct udevice *dev) -+{ -+ return (const struct hwspinlock_ops *)dev->driver->ops; -+} -+ -+static int hwspinlock_of_xlate_default(struct hwspinlock *hws, -+ struct ofnode_phandle_args *args) -+{ -+ if (args->args_count > 1) { -+ debug("Invaild args_count: %d\n", args->args_count); -+ return -EINVAL; -+ } -+ -+ if (args->args_count) -+ hws->id = args->args[0]; -+ else -+ hws->id = 0; -+ -+ return 0; -+} -+ -+int hwspinlock_get_by_index(struct udevice *dev, int index, -+ struct hwspinlock *hws) -+{ -+ int ret; -+ struct ofnode_phandle_args args; -+ struct udevice *dev_hws; -+ const struct hwspinlock_ops *ops; -+ -+ assert(hws); -+ hws->dev = NULL; -+ -+ ret = dev_read_phandle_with_args(dev, "hwlocks", "#hwlock-cells", 1, -+ index, &args); -+ if (ret) { -+ dev_dbg(dev, "%s: dev_read_phandle_with_args: err=%d\n", -+ __func__, ret); -+ return ret; -+ } -+ -+ ret = uclass_get_device_by_ofnode(UCLASS_HWSPINLOCK, -+ args.node, &dev_hws); -+ if (ret) { -+ dev_dbg(dev, -+ "%s: uclass_get_device_by_of_offset failed: err=%d\n", -+ __func__, ret); -+ return ret; -+ } -+ -+ hws->dev = dev_hws; -+ -+ ops = hwspinlock_dev_ops(dev_hws); -+ -+ if (ops->of_xlate) -+ ret = ops->of_xlate(hws, &args); -+ else -+ ret = hwspinlock_of_xlate_default(hws, &args); -+ if (ret) -+ dev_dbg(dev, "of_xlate() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+int hwspinlock_lock_timeout(struct hwspinlock *hws, unsigned int timeout) -+{ -+ const struct hwspinlock_ops *ops; -+ ulong start; -+ int ret; -+ -+ assert(hws); -+ -+ if (!hws->dev) -+ return -EINVAL; -+ -+ ops = hwspinlock_dev_ops(hws->dev); -+ if (!ops->lock) -+ return -ENOSYS; -+ -+ start = get_timer(0); -+ do { -+ ret = ops->lock(hws->dev, hws->id); -+ if (!ret) -+ return ret; -+ -+ if (ops->relax) -+ ops->relax(hws->dev); -+ } while (get_timer(start) < timeout); -+ -+ return -ETIMEDOUT; -+} -+ -+int hwspinlock_unlock(struct hwspinlock *hws) -+{ -+ const struct hwspinlock_ops *ops; -+ -+ assert(hws); -+ -+ if (!hws->dev) -+ return -EINVAL; -+ -+ ops = hwspinlock_dev_ops(hws->dev); -+ if (!ops->unlock) -+ return -ENOSYS; -+ -+ return ops->unlock(hws->dev, hws->id); -+} -+ -+static int hwspinlock_post_bind(struct udevice *dev) -+{ -+#if defined(CONFIG_NEEDS_MANUAL_RELOC) -+ struct hwspinlock_ops *ops = device_get_ops(dev); -+ static int reloc_done; -+ -+ if (!reloc_done) { -+ if (ops->lock) -+ ops->lock += gd->reloc_off; -+ if (ops->unlock) -+ ops->unlock += gd->reloc_off; -+ if (ops->relax) -+ ops->relax += gd->reloc_off; -+ -+ reloc_done++; -+ } -+#endif -+ return 0; -+} -+ -+UCLASS_DRIVER(hwspinlock) = { -+ .id = UCLASS_HWSPINLOCK, -+ .name = "hwspinlock", -+ .post_bind = hwspinlock_post_bind, -+}; -diff --git a/drivers/hwspinlock/sandbox_hwspinlock.c b/drivers/hwspinlock/sandbox_hwspinlock.c -new file mode 100644 -index 0000000..be920f5 ---- /dev/null -+++ b/drivers/hwspinlock/sandbox_hwspinlock.c -@@ -0,0 +1,56 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+ -+static int sandbox_lock(struct udevice *dev, int index) -+{ -+ struct sandbox_state *state = state_get_current(); -+ -+ if (index != 0) -+ return -1; -+ -+ if (state->hwspinlock) -+ return -1; -+ -+ state->hwspinlock = true; -+ -+ return 0; -+} -+ -+static int sandbox_unlock(struct udevice *dev, int index) -+{ -+ struct sandbox_state *state = state_get_current(); -+ -+ if (index != 0) -+ return -1; -+ -+ if (!state->hwspinlock) -+ return -1; -+ -+ state->hwspinlock = false; -+ -+ return 0; -+} -+ -+static const struct hwspinlock_ops sandbox_hwspinlock_ops = { -+ .lock = sandbox_lock, -+ .unlock = sandbox_unlock, -+}; -+ -+static const struct udevice_id sandbox_hwspinlock_ids[] = { -+ { .compatible = "sandbox,hwspinlock" }, -+ {} -+}; -+ -+U_BOOT_DRIVER(hwspinlock_sandbox) = { -+ .name = "hwspinlock_sandbox", -+ .id = UCLASS_HWSPINLOCK, -+ .of_match = sandbox_hwspinlock_ids, -+ .ops = &sandbox_hwspinlock_ops, -+}; -diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c -new file mode 100644 -index 0000000..b8f3b16 ---- /dev/null -+++ b/drivers/hwspinlock/stm32_hwspinlock.c -@@ -0,0 +1,90 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define STM32_MUTEX_COREID BIT(8) -+#define STM32_MUTEX_LOCK_BIT BIT(31) -+#define STM32_MUTEX_NUM_LOCKS 32 -+ -+static int stm32mp1_lock(struct udevice *dev, int index) -+{ -+ fdt_addr_t *base = dev_get_priv(dev); -+ u32 status; -+ -+ if (index >= STM32_MUTEX_NUM_LOCKS) -+ return -EINVAL; -+ -+ status = readl(*base + index * sizeof(u32)); -+ if (status == (STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID)) -+ return -EBUSY; -+ -+ writel(STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID, -+ *base + index * sizeof(u32)); -+ -+ status = readl(*base + index * sizeof(u32)); -+ if (status != (STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int stm32mp1_unlock(struct udevice *dev, int index) -+{ -+ fdt_addr_t *base = dev_get_priv(dev); -+ -+ if (index >= STM32_MUTEX_NUM_LOCKS) -+ return -EINVAL; -+ -+ writel(STM32_MUTEX_COREID, *base + index * sizeof(u32)); -+ -+ return 0; -+} -+ -+static int stm32mp1_hwspinlock_probe(struct udevice *dev) -+{ -+ fdt_addr_t *base = dev_get_priv(dev); -+ struct clk clk; -+ int ret; -+ -+ *base = dev_read_addr(dev); -+ if (*base == FDT_ADDR_T_NONE) -+ return -EINVAL; -+ -+ ret = clk_get_by_index(dev, 0, &clk); -+ if (ret) -+ return ret; -+ -+ ret = clk_enable(&clk); -+ if (ret) -+ clk_free(&clk); -+ -+ return ret; -+} -+ -+static const struct hwspinlock_ops stm32mp1_hwspinlock_ops = { -+ .lock = stm32mp1_lock, -+ .unlock = stm32mp1_unlock, -+}; -+ -+static const struct udevice_id stm32mp1_hwspinlock_ids[] = { -+ { .compatible = "st,stm32-hwspinlock" }, -+ {} -+}; -+ -+U_BOOT_DRIVER(hwspinlock_stm32mp1) = { -+ .name = "hwspinlock_stm32mp1", -+ .id = UCLASS_HWSPINLOCK, -+ .of_match = stm32mp1_hwspinlock_ids, -+ .ops = &stm32mp1_hwspinlock_ops, -+ .probe = stm32mp1_hwspinlock_probe, -+ .priv_auto_alloc_size = sizeof(fdt_addr_t), -+}; -diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c -index 36ec610..50c4fd0 100644 ---- a/drivers/i2c/stm32f7_i2c.c -+++ b/drivers/i2c/stm32f7_i2c.c -@@ -58,7 +58,7 @@ struct stm32_i2c_regs { - #define STM32_I2C_CR2_ADD10 BIT(11) - #define STM32_I2C_CR2_RD_WRN BIT(10) - #define STM32_I2C_CR2_SADD10_MASK GENMASK(9, 0) --#define STM32_I2C_CR2_SADD10(n) ((n & STM32_I2C_CR2_SADD10_MASK)) -+#define STM32_I2C_CR2_SADD10(n) (n & STM32_I2C_CR2_SADD10_MASK) - #define STM32_I2C_CR2_SADD7_MASK GENMASK(7, 1) - #define STM32_I2C_CR2_SADD7(n) ((n & 0x7f) << 1) - #define STM32_I2C_CR2_RESET_MASK (STM32_I2C_CR2_HEAD10R \ -@@ -197,7 +197,7 @@ struct stm32_i2c_priv { - int speed; - }; - --static struct stm32_i2c_spec i2c_specs[] = { -+static const struct stm32_i2c_spec i2c_specs[] = { - [STM32_I2C_SPEED_STANDARD] = { - .rate = STANDARD_RATE, - .rate_min = 8000, -@@ -236,7 +236,7 @@ static struct stm32_i2c_spec i2c_specs[] = { - }, - }; - --static struct stm32_i2c_setup stm32f7_setup = { -+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, -@@ -255,7 +255,7 @@ static int stm32_i2c_check_device_busy(struct stm32_i2c_priv *i2c_priv) - } - - static void stm32_i2c_message_start(struct stm32_i2c_priv *i2c_priv, -- struct i2c_msg *msg, bool stop) -+ struct i2c_msg *msg, bool stop) - { - struct stm32_i2c_regs *regs = i2c_priv->regs; - u32 cr2 = readl(®s->cr2); -@@ -299,7 +299,7 @@ static void stm32_i2c_message_start(struct stm32_i2c_priv *i2c_priv, - */ - - static void stm32_i2c_handle_reload(struct stm32_i2c_priv *i2c_priv, -- struct i2c_msg *msg, bool stop) -+ struct i2c_msg *msg, bool stop) - { - struct stm32_i2c_regs *regs = i2c_priv->regs; - u32 cr2 = readl(®s->cr2); -@@ -317,7 +317,7 @@ static void stm32_i2c_handle_reload(struct stm32_i2c_priv *i2c_priv, - } - - static int stm32_i2c_wait_flags(struct stm32_i2c_priv *i2c_priv, -- u32 flags, u32 *status) -+ u32 flags, u32 *status) - { - struct stm32_i2c_regs *regs = i2c_priv->regs; - u32 time_start = get_timer(0); -@@ -392,7 +392,7 @@ static int stm32_i2c_check_end_of_message(struct stm32_i2c_priv *i2c_priv) - } - - static int stm32_i2c_message_xfer(struct stm32_i2c_priv *i2c_priv, -- struct i2c_msg *msg, bool stop) -+ struct i2c_msg *msg, bool stop) - { - struct stm32_i2c_regs *regs = i2c_priv->regs; - u32 status; -@@ -465,7 +465,7 @@ static int stm32_i2c_message_xfer(struct stm32_i2c_priv *i2c_priv, - } - - static int stm32_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, -- int nmsgs) -+ int nmsgs) - { - struct stm32_i2c_priv *i2c_priv = dev_get_priv(bus); - int ret; -@@ -500,7 +500,7 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, - af_delay_max = setup->analog_filter ? - STM32_I2C_ANALOG_FILTER_DELAY_MAX : 0; - -- sdadel_min = setup->fall_time - i2c_specs[setup->speed].hddat_min - -+ sdadel_min = i2c_specs[setup->speed].hddat_min + setup->fall_time - - af_delay_min - (setup->dnf + 3) * i2cclk; - - sdadel_max = i2c_specs[setup->speed].vddat_max - setup->rise_time - -@@ -540,8 +540,12 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, - p_prev = p; - - list_add_tail(&v->node, solutions); -+ break; - } - } -+ -+ if (p_prev == p) -+ break; - } - } - -@@ -594,6 +598,7 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, - - for (l = 0; l < STM32_SCLL_MAX; l++) { - u32 tscl_l = (l + 1) * prescaler + tsync; -+ - if ((tscl_l < i2c_specs[setup->speed].l_min) || - (i2cclk >= - ((tscl_l - af_delay_min - dnf_delay) / 4))) { -@@ -634,8 +639,8 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, - } - - 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, -+ struct stm32_i2c_timings *output) - { - struct stm32_i2c_timings *v, *_v; - struct list_head solutions; -@@ -643,28 +648,28 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, - - if (setup->speed >= STM32_I2C_SPEED_END) { - pr_err("%s: speed out of bound {%d/%d}\n", __func__, -- setup->speed, STM32_I2C_SPEED_END - 1); -+ setup->speed, STM32_I2C_SPEED_END - 1); - return -EINVAL; - } - - if ((setup->rise_time > i2c_specs[setup->speed].rise_max) || - (setup->fall_time > i2c_specs[setup->speed].fall_max)) { - pr_err("%s :timings out of bound Rise{%d>%d}/Fall{%d>%d}\n", -- __func__, -- setup->rise_time, i2c_specs[setup->speed].rise_max, -- setup->fall_time, i2c_specs[setup->speed].fall_max); -+ __func__, -+ setup->rise_time, i2c_specs[setup->speed].rise_max, -+ setup->fall_time, i2c_specs[setup->speed].fall_max); - return -EINVAL; - } - - if (setup->dnf > STM32_I2C_DNF_MAX) { - pr_err("%s: DNF out of bound %d/%d\n", __func__, -- setup->dnf, STM32_I2C_DNF_MAX); -+ setup->dnf, STM32_I2C_DNF_MAX); - return -EINVAL; - } - - if (setup->speed_freq > i2c_specs[setup->speed].rate) { - pr_err("%s: Freq {%d/%d}\n", __func__, -- setup->speed_freq, i2c_specs[setup->speed].rate); -+ setup->speed_freq, i2c_specs[setup->speed].rate); - return -EINVAL; - } - -@@ -693,7 +698,7 @@ exit: - } - - static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv, -- struct stm32_i2c_timings *timing) -+ struct stm32_i2c_timings *timing) - { - struct stm32_i2c_setup *setup = i2c_priv->setup; - int ret = 0; -diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index 2836ee4..82a8a87 100644 ---- a/drivers/mailbox/Kconfig -+++ b/drivers/mailbox/Kconfig -@@ -24,6 +24,13 @@ config TEGRA_HSP - This enables support for the NVIDIA Tegra HSP Hw module, which - implements doorbells, mailboxes, semaphores, and shared interrupts. - -+config STM32_IPCC -+ bool "Enable STM32 IPCC controller support" -+ depends on DM_MAILBOX && ARCH_STM32MP -+ help -+ This enables support for the STM32MP IPCC Hw module, which -+ implements doorbells and shared interrupts between 2 processors. -+ - config K3_SEC_PROXY - bool "Texas Instruments K3 Secure Proxy Driver" - depends on DM_MAILBOX && ARCH_K3 -diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile -index cd23769..a753cc4 100644 ---- a/drivers/mailbox/Makefile -+++ b/drivers/mailbox/Makefile -@@ -6,5 +6,6 @@ - obj-$(CONFIG_$(SPL_)DM_MAILBOX) += mailbox-uclass.o - obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox.o - obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox-test.o -+obj-$(CONFIG_STM32_IPCC) += stm32-ipcc.o - obj-$(CONFIG_TEGRA_HSP) += tegra-hsp.o - obj-$(CONFIG_K3_SEC_PROXY) += k3-sec-proxy.o -diff --git a/drivers/mailbox/stm32-ipcc.c b/drivers/mailbox/stm32-ipcc.c -new file mode 100644 -index 0000000..dfcea91 ---- /dev/null -+++ b/drivers/mailbox/stm32-ipcc.c -@@ -0,0 +1,187 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * IPCC has one set of registers per CPU -+ * IPCC_PROC_OFFST allows to define cpu registers set base address -+ * according to assigned cpu_id. -+ * In register name, X (Y) means either C1 (C2) or C2 (C1) depending -+ * of cpu offset. -+ */ -+ -+#define IPCC_PROC_OFFST 0x010 -+ -+#define IPCC_XCR 0x000 -+#define XCR_RXOIE BIT(0) -+#define XCR_TXOIE BIT(16) -+ -+#define IPCC_XMR 0x004 -+#define IPCC_XSCR 0x008 -+#define IPCC_XTOYSR 0x00c -+ -+#define IPCC_HWCFGR 0x3f0 -+#define IPCFGR_CHAN_MASK GENMASK(7, 0) -+ -+#define IPCC_VER 0x3f4 -+#define VER_MINREV_MASK GENMASK(3, 0) -+#define VER_MAJREV_MASK GENMASK(7, 4) -+ -+#define RX_BIT_MASK GENMASK(15, 0) -+#define RX_BIT_CHAN(chan) BIT(chan) -+#define TX_BIT_SHIFT 16 -+#define TX_BIT_MASK GENMASK(31, 16) -+#define TX_BIT_CHAN(chan) BIT(TX_BIT_SHIFT + (chan)) -+ -+#define STM32_MAX_PROCS 2 -+ -+enum { -+ IPCC_IRQ_RX, -+ IPCC_IRQ_TX, -+ IPCC_IRQ_NUM, -+}; -+ -+struct stm32_ipcc { -+ void __iomem *reg_base; -+ void __iomem *reg_proc; -+ struct clk clk; -+ u32 proc_id; -+ u32 n_chans; -+}; -+ -+static int stm32_ipcc_request(struct mbox_chan *chan) -+{ -+ struct stm32_ipcc *ipcc = dev_get_priv(chan->dev); -+ -+ debug("%s(chan=%p)\n", __func__, chan); -+ -+ if (chan->id >= ipcc->n_chans) { -+ debug("%s failed to request channel: %ld\n", -+ __func__, chan->id); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int stm32_ipcc_free(struct mbox_chan *chan) -+{ -+ debug("%s(chan=%p)\n", __func__, chan); -+ -+ return 0; -+} -+ -+static int stm32_ipcc_send(struct mbox_chan *chan, const void *data) -+{ -+ struct stm32_ipcc *ipcc = dev_get_priv(chan->dev); -+ -+ debug("%s(chan=%p, data=%p)\n", __func__, chan, data); -+ -+ /* set channel n occupied */ -+ setbits_le32(ipcc->reg_proc + IPCC_XSCR, TX_BIT_CHAN(chan->id)); -+ -+ return 0; -+} -+ -+static int stm32_ipcc_recv(struct mbox_chan *chan, void *data) -+{ -+ struct stm32_ipcc *ipcc = dev_get_priv(chan->dev); -+ u32 val; -+ int proc_offset; -+ -+ debug("%s(chan=%p, data=%p)\n", __func__, chan, data); -+ -+ /* read 'channel occupied' status from other proc */ -+ proc_offset = ipcc->proc_id ? -IPCC_PROC_OFFST : IPCC_PROC_OFFST; -+ val = readl(ipcc->reg_proc + proc_offset + IPCC_XTOYSR); -+ -+ if (!(val & BIT(chan->id))) -+ return -ENODATA; -+ -+ setbits_le32(ipcc->reg_proc + IPCC_XSCR, RX_BIT_CHAN(chan->id)); -+ -+ return 0; -+} -+ -+static int stm32_ipcc_probe(struct udevice *dev) -+{ -+ struct stm32_ipcc *ipcc = dev_get_priv(dev); -+ fdt_addr_t addr; -+ const fdt32_t *cell; -+ int len, ret; -+ -+ debug("%s(dev=%p)\n", __func__, dev); -+ -+ addr = dev_read_addr(dev); -+ if (addr == FDT_ADDR_T_NONE) -+ return -EINVAL; -+ -+ ipcc->reg_base = (void __iomem *)addr; -+ -+ /* proc_id */ -+ cell = dev_read_prop(dev, "st,proc_id", &len); -+ if (len < sizeof(fdt32_t)) { -+ dev_dbg(dev, "Missing st,proc_id\n"); -+ return -EINVAL; -+ } -+ -+ ipcc->proc_id = fdtdec_get_number(cell, 1); -+ -+ if (ipcc->proc_id >= STM32_MAX_PROCS) { -+ dev_err(dev, "Invalid proc_id (%d)\n", ipcc->proc_id); -+ return -EINVAL; -+ } -+ -+ ipcc->reg_proc = ipcc->reg_base + ipcc->proc_id * IPCC_PROC_OFFST; -+ -+ ret = clk_get_by_index(dev, 0, &ipcc->clk); -+ if (ret) -+ return ret; -+ -+ ret = clk_enable(&ipcc->clk); -+ if (ret) -+ goto clk_free; -+ -+ /* get channe number */ -+ ipcc->n_chans = readl(ipcc->reg_base + IPCC_HWCFGR); -+ ipcc->n_chans &= IPCFGR_CHAN_MASK; -+ -+ /* mask and enable rx/tx irq */ -+ setbits_le32(ipcc->reg_proc + IPCC_XMR, RX_BIT_MASK | TX_BIT_MASK); -+ setbits_le32(ipcc->reg_proc + IPCC_XCR, XCR_RXOIE | XCR_TXOIE); -+ -+ return 0; -+ -+clk_free: -+ clk_free(&ipcc->clk); -+ -+ return ret; -+} -+ -+static const struct udevice_id stm32_ipcc_ids[] = { -+ { .compatible = "st,stm32mp1-ipcc" }, -+ { } -+}; -+ -+struct mbox_ops stm32_ipcc_mbox_ops = { -+ .request = stm32_ipcc_request, -+ .free = stm32_ipcc_free, -+ .send = stm32_ipcc_send, -+ .recv = stm32_ipcc_recv, -+}; -+ -+U_BOOT_DRIVER(stm32_ipcc) = { -+ .name = "stm32_ipcc", -+ .id = UCLASS_MAILBOX, -+ .of_match = stm32_ipcc_ids, -+ .probe = stm32_ipcc_probe, -+ .priv_auto_alloc_size = sizeof(struct stm32_ipcc), -+ .ops = &stm32_ipcc_mbox_ops, -+}; -diff --git a/drivers/misc/stm32mp_fuse.c b/drivers/misc/stm32mp_fuse.c -index 2d66135..842871f 100644 ---- a/drivers/misc/stm32mp_fuse.c -+++ b/drivers/misc/stm32mp_fuse.c -@@ -9,8 +9,10 @@ - #include - #include - #include -+#include - - #define STM32MP_OTP_BANK 0 -+#define STM32MP_NVM_BANK 1 - - /* - * The 'fuse' command API -@@ -31,6 +33,13 @@ int fuse_read(u32 bank, u32 word, u32 *val) - val, 4); - break; - -+#ifdef CONFIG_PMIC_STPMIC1 -+ case STM32MP_NVM_BANK: -+ *val = 0; -+ ret = stpmic1_shadow_read_byte(word, (u8 *)val); -+ break; -+#endif /* CONFIG_PMIC_STPMIC1 */ -+ - default: - printf("stm32mp %s: wrong value for bank %i\n", __func__, bank); - ret = -EINVAL; -@@ -56,6 +65,12 @@ int fuse_prog(u32 bank, u32 word, u32 val) - &val, 4); - break; - -+#ifdef CONFIG_PMIC_STPMIC1 -+ case STM32MP_NVM_BANK: -+ ret = stpmic1_nvm_write_byte(word, (u8 *)&val); -+ break; -+#endif /* CONFIG_PMIC_STPMIC1 */ -+ - default: - printf("stm32mp %s: wrong value for bank %i\n", __func__, bank); - ret = -EINVAL; -@@ -80,6 +95,13 @@ int fuse_sense(u32 bank, u32 word, u32 *val) - ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4); - break; - -+#ifdef CONFIG_PMIC_STPMIC1 -+ case STM32MP_NVM_BANK: -+ *val = 0; -+ ret = stpmic1_nvm_read_byte(word, (u8 *)val); -+ break; -+#endif /* CONFIG_PMIC_STPMIC1 */ -+ - default: - printf("stm32mp %s: wrong value for bank %i\n", __func__, bank); - ret = -EINVAL; -@@ -105,6 +127,12 @@ int fuse_override(u32 bank, u32 word, u32 val) - &val, 4); - break; - -+#ifdef CONFIG_PMIC_STPMIC1 -+ case STM32MP_NVM_BANK: -+ ret = stpmic1_shadow_write_byte(word, (u8 *)&val); -+ break; -+#endif /* CONFIG_PMIC_STPMIC1 */ -+ - default: - printf("stm32mp %s: wrong value for bank %i\n", - __func__, bank); -diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c -index b8acc33..1a3f561 100644 ---- a/drivers/mmc/mmc_write.c -+++ b/drivers/mmc/mmc_write.c -@@ -79,7 +79,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) - u32 start_rem, blkcnt_rem; - struct mmc *mmc = find_mmc_device(dev_num); - lbaint_t blk = 0, blk_r = 0; -- int timeout = 1000; -+ int timeout = 2000; - - if (!mmc) - return -1; -diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c -index a36612d..ed31ca1 100644 ---- a/drivers/mmc/stm32_sdmmc2.c -+++ b/drivers/mmc/stm32_sdmmc2.c -@@ -190,6 +190,7 @@ struct stm32_sdmmc2_ctx { - #define SDMMC_IDMACTRL_IDMAEN BIT(0) - - #define SDMMC_CMD_TIMEOUT 0xFFFFFFFF -+#define SDMMC_BUSYD0END_TIMEOUT_US 1000000 - - static void stm32_sdmmc2_start_data(struct stm32_sdmmc2_priv *priv, - struct mmc_data *data, -@@ -209,9 +210,6 @@ static void stm32_sdmmc2_start_data(struct stm32_sdmmc2_priv *priv, - idmabase0 = (u32)data->src; - } - -- /* Set the SDMMC Data TimeOut value */ -- writel(SDMMC_CMD_TIMEOUT, priv->base + SDMMC_DTIMER); -- - /* Set the SDMMC DataLength value */ - writel(ctx->data_length, priv->base + SDMMC_DLEN); - -@@ -236,8 +234,11 @@ static void stm32_sdmmc2_start_data(struct stm32_sdmmc2_priv *priv, - } - - static void stm32_sdmmc2_start_cmd(struct stm32_sdmmc2_priv *priv, -- struct mmc_cmd *cmd, u32 cmd_param) -+ struct mmc_cmd *cmd, u32 cmd_param, -+ struct stm32_sdmmc2_ctx *ctx) - { -+ u32 timeout = 0; -+ - if (readl(priv->base + SDMMC_CMD) & SDMMC_CMD_CPSMEN) - writel(0, priv->base + SDMMC_CMD); - -@@ -251,6 +252,26 @@ static void stm32_sdmmc2_start_cmd(struct stm32_sdmmc2_priv *priv, - cmd_param |= SDMMC_CMD_WAITRESP_1; - } - -+ /* -+ * SDMMC_DTIME must be set in two case: -+ * - on data transfert. -+ * - on busy request. -+ * If not done or too short, the dtimeout flag occurs and DPSM stays -+ * enabled/busy and waits for abort (stop transmission cmd). -+ * Next data command is not possible whereas DPSM is activated. -+ */ -+ if (ctx->data_length) { -+ timeout = SDMMC_CMD_TIMEOUT; -+ } else { -+ writel(0, priv->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); -+ - /* Clear flags */ - writel(SDMMC_ICR_STATIC_FLAGS, priv->base + SDMMC_ICR); - -@@ -309,6 +330,31 @@ static int stm32_sdmmc2_end_cmd(struct stm32_sdmmc2_priv *priv, - cmd->response[2] = readl(priv->base + SDMMC_RESP3); - cmd->response[3] = readl(priv->base + SDMMC_RESP4); - } -+ -+ /* Wait for BUSYD0END flag if busy status is detected */ -+ if (cmd->resp_type & MMC_RSP_BUSY && -+ status & SDMMC_STA_BUSYD0) { -+ mask = SDMMC_STA_DTIMEOUT | SDMMC_STA_BUSYD0END; -+ -+ /* Polling status register */ -+ ret = readl_poll_timeout(priv->base + SDMMC_STA, -+ status, status & mask, -+ SDMMC_BUSYD0END_TIMEOUT_US); -+ -+ if (ret < 0) { -+ debug("%s: timeout reading SDMMC_STA\n", -+ __func__); -+ ctx->dpsm_abort = true; -+ return ret; -+ } -+ -+ if (status & SDMMC_STA_DTIMEOUT) { -+ debug("%s: error SDMMC_STA_DTIMEOUT (0x%x)\n", -+ __func__, status); -+ ctx->dpsm_abort = true; -+ return -ETIMEDOUT; -+ } -+ } - } - - return 0; -@@ -395,7 +441,7 @@ retry_cmd: - stm32_sdmmc2_start_data(priv, data, &ctx); - } - -- stm32_sdmmc2_start_cmd(priv, cmd, cmdat); -+ stm32_sdmmc2_start_cmd(priv, cmd, cmdat, &ctx); - - debug("%s: send cmd %d data: 0x%x @ 0x%x\n", - __func__, cmd->cmdidx, -@@ -425,7 +471,10 @@ retry_cmd: - debug("%s: send STOP command to abort dpsm treatments\n", - __func__); - -- stm32_sdmmc2_start_cmd(priv, &stop_cmd, SDMMC_CMD_CMDSTOP); -+ ctx.data_length = 0; -+ -+ stm32_sdmmc2_start_cmd(priv, &stop_cmd, -+ SDMMC_CMD_CMDSTOP, &ctx); - stm32_sdmmc2_end_cmd(priv, &stop_cmd, &ctx); - - writel(SDMMC_ICR_STATIC_FLAGS, priv->base + SDMMC_ICR); -@@ -585,11 +634,11 @@ static int stm32_sdmmc2_probe(struct udevice *dev) - if (priv->base == FDT_ADDR_T_NONE) - return -EINVAL; - -- if (dev_read_bool(dev, "st,negedge")) -+ if (dev_read_bool(dev, "st,neg-edge")) - priv->clk_reg_msk |= SDMMC_CLKCR_NEGEDGE; -- if (dev_read_bool(dev, "st,dirpol")) -+ if (dev_read_bool(dev, "st,sig-dir")) - priv->pwr_reg_msk |= SDMMC_POWER_DIRPOL; -- if (dev_read_bool(dev, "st,pin-ckin")) -+ if (dev_read_bool(dev, "st,use-ckin")) - priv->clk_reg_msk |= SDMMC_CLKCR_SELCLKRX_CKIN; - - ret = clk_get_by_index(dev, 0, &priv->clk); -diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig -index 008f7b4..0419574 100644 ---- a/drivers/mtd/nand/raw/Kconfig -+++ b/drivers/mtd/nand/raw/Kconfig -@@ -243,6 +243,17 @@ config SYS_NAND_BUSWIDTH_16BIT - not available while configuring controller. So a static CONFIG_NAND_xx - is needed to know the device's bus-width in advance. - -+config NAND_STM32_FMC2 -+ bool "STM32 FMC2 NAND driver" -+ depends on ARCH_STM32MP && OF_CONTROL && MTD -+ select SYS_NAND_SELF_INIT -+ imply CMD_NAND -+ help -+ Enables support for NAND Flash chips on SoCs containing the FMC2 -+ NAND controller. This controller is found on STM32MP SoCs. -+ The controller supports a maximum 8k page size and supports -+ a maximum 8-bit correction error per sector of 512 bytes. -+ - if SPL - - config SYS_NAND_U_BOOT_LOCATIONS -diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile -index c61e3f3..b10e718 100644 ---- a/drivers/mtd/nand/raw/Makefile -+++ b/drivers/mtd/nand/raw/Makefile -@@ -65,6 +65,7 @@ obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o - obj-$(CONFIG_NAND_PLAT) += nand_plat.o - obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o - obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o -+obj-$(CONFIG_NAND_STM32_FMC2) += stm32_fmc2_nand.o - - else # minimal SPL drivers - -diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c -index 4009d64..d457c54 100644 ---- a/drivers/mtd/nand/raw/nand_ids.c -+++ b/drivers/mtd/nand/raw/nand_ids.c -@@ -52,6 +52,10 @@ struct nand_flash_dev nand_flash_ids[] = { - {"TC58NVG3S0F 8G 3.3V 8-bit", - { .id = {0x98, 0xd3, 0x90, 0x26, 0x76, 0x15, 0x02, 0x08} }, - SZ_4K, SZ_1K, SZ_256K, 0, 8, 232, NAND_ECC_INFO(4, SZ_512) }, -+ {"S34ML16G2 8G 3.3V 8-bit", -+ { .id = {0x01, 0xd3, 0xd1, 0x95, 0x5a} }, -+ SZ_2K, SZ_1K, SZ_128K, 0, 5, 128, NAND_ECC_INFO(4, SZ_512), -+ 4 }, - {"TC58NVG5D2 32G 3.3V 8-bit", - { .id = {0x98, 0xd7, 0x94, 0x32, 0x76, 0x56, 0x09, 0x00} }, - SZ_8K, SZ_4K, SZ_1M, 0, 8, 640, NAND_ECC_INFO(40, SZ_1K) }, -diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c -new file mode 100644 -index 0000000..6f6f5e6 ---- /dev/null -+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c -@@ -0,0 +1,1092 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ * Author: Christophe Kerello -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Bad block marker length */ -+#define FMC2_BBM_LEN 2 -+ -+/* ECC step size */ -+#define FMC2_ECC_STEP_SIZE 512 -+ -+/* Command delay */ -+#define FMC2_RB_DELAY_US 30 -+ -+/* Max chip enable */ -+#define FMC2_MAX_CE 2 -+ -+/* Timings */ -+#define FMC2_THIZ 1 -+#define FMC2_TIO 8000 -+#define FMC2_TSYNC 3000 -+#define FMC2_PCR_TIMING_MASK 0xf -+#define FMC2_PMEM_PATT_TIMING_MASK 0xff -+ -+/* FMC2 Controller Registers */ -+#define FMC2_BCR1 0x0 -+#define FMC2_PCR 0x80 -+#define FMC2_SR 0x84 -+#define FMC2_PMEM 0x88 -+#define FMC2_PATT 0x8c -+#define FMC2_HECCR 0x94 -+#define FMC2_BCHISR 0x254 -+#define FMC2_BCHICR 0x258 -+#define FMC2_BCHPBR1 0x260 -+#define FMC2_BCHPBR2 0x264 -+#define FMC2_BCHPBR3 0x268 -+#define FMC2_BCHPBR4 0x26c -+#define FMC2_BCHDSR0 0x27c -+#define FMC2_BCHDSR1 0x280 -+#define FMC2_BCHDSR2 0x284 -+#define FMC2_BCHDSR3 0x288 -+#define FMC2_BCHDSR4 0x28c -+ -+/* Register: FMC2_BCR1 */ -+#define FMC2_BCR1_FMC2EN BIT(31) -+ -+/* Register: FMC2_PCR */ -+#define FMC2_PCR_PWAITEN BIT(1) -+#define FMC2_PCR_PBKEN BIT(2) -+#define FMC2_PCR_PWID_MASK GENMASK(5, 4) -+#define FMC2_PCR_PWID(x) (((x) & 0x3) << 4) -+#define FMC2_PCR_PWID_BUSWIDTH_8 0 -+#define FMC2_PCR_PWID_BUSWIDTH_16 1 -+#define FMC2_PCR_ECCEN BIT(6) -+#define FMC2_PCR_ECCALG BIT(8) -+#define FMC2_PCR_TCLR_MASK GENMASK(12, 9) -+#define FMC2_PCR_TCLR(x) (((x) & 0xf) << 9) -+#define FMC2_PCR_TCLR_DEFAULT 0xf -+#define FMC2_PCR_TAR_MASK GENMASK(16, 13) -+#define FMC2_PCR_TAR(x) (((x) & 0xf) << 13) -+#define FMC2_PCR_TAR_DEFAULT 0xf -+#define FMC2_PCR_ECCSS_MASK GENMASK(19, 17) -+#define FMC2_PCR_ECCSS(x) (((x) & 0x7) << 17) -+#define FMC2_PCR_ECCSS_512 1 -+#define FMC2_PCR_ECCSS_2048 3 -+#define FMC2_PCR_BCHECC BIT(24) -+#define FMC2_PCR_WEN BIT(25) -+ -+/* Register: FMC2_SR */ -+#define FMC2_SR_NWRF BIT(6) -+ -+/* Register: FMC2_PMEM */ -+#define FMC2_PMEM_MEMSET(x) (((x) & 0xff) << 0) -+#define FMC2_PMEM_MEMWAIT(x) (((x) & 0xff) << 8) -+#define FMC2_PMEM_MEMHOLD(x) (((x) & 0xff) << 16) -+#define FMC2_PMEM_MEMHIZ(x) (((x) & 0xff) << 24) -+#define FMC2_PMEM_DEFAULT 0x0a0a0a0a -+ -+/* Register: FMC2_PATT */ -+#define FMC2_PATT_ATTSET(x) (((x) & 0xff) << 0) -+#define FMC2_PATT_ATTWAIT(x) (((x) & 0xff) << 8) -+#define FMC2_PATT_ATTHOLD(x) (((x) & 0xff) << 16) -+#define FMC2_PATT_ATTHIZ(x) (((x) & 0xff) << 24) -+#define FMC2_PATT_DEFAULT 0x0a0a0a0a -+ -+/* Register: FMC2_BCHISR */ -+#define FMC2_BCHISR_DERF BIT(1) -+#define FMC2_BCHISR_EPBRF BIT(4) -+ -+/* Register: FMC2_BCHICR */ -+#define FMC2_BCHICR_CLEAR_IRQ GENMASK(4, 0) -+ -+/* Register: FMC2_BCHDSR0 */ -+#define FMC2_BCHDSR0_DUE BIT(0) -+#define FMC2_BCHDSR0_DEF BIT(1) -+#define FMC2_BCHDSR0_DEN_MASK 0xf0 -+#define FMC2_BCHDSR0_DEN_SHIFT 4 -+ -+/* Register: FMC2_BCHDSR1 */ -+#define FMC2_BCHDSR1_EBP1_MASK GENMASK(12, 0) -+#define FMC2_BCHDSR1_EBP2_MASK GENMASK(28, 16) -+#define FMC2_BCHDSR1_EBP2_SHIFT 16 -+ -+/* Register: FMC2_BCHDSR2 */ -+#define FMC2_BCHDSR2_EBP3_MASK GENMASK(12, 0) -+#define FMC2_BCHDSR2_EBP4_MASK GENMASK(28, 16) -+#define FMC2_BCHDSR2_EBP4_SHIFT 16 -+ -+/* Register: FMC2_BCHDSR3 */ -+#define FMC2_BCHDSR3_EBP5_MASK GENMASK(12, 0) -+#define FMC2_BCHDSR3_EBP6_MASK GENMASK(28, 16) -+#define FMC2_BCHDSR3_EBP6_SHIFT 16 -+ -+/* Register: FMC2_BCHDSR4 */ -+#define FMC2_BCHDSR4_EBP7_MASK GENMASK(12, 0) -+#define FMC2_BCHDSR4_EBP8_MASK GENMASK(28, 16) -+#define FMC2_BCHDSR4_EBP8_SHIFT 16 -+ -+#define FMC2_NSEC_PER_SEC 1000000000L -+ -+enum stm32_fmc2_ecc { -+ FMC2_ECC_HAM = 1, -+ FMC2_ECC_BCH4 = 4, -+ FMC2_ECC_BCH8 = 8 -+}; -+ -+struct stm32_fmc2_timings { -+ u8 tclr; -+ u8 tar; -+ u8 thiz; -+ u8 twait; -+ u8 thold_mem; -+ u8 tset_mem; -+ u8 thold_att; -+ u8 tset_att; -+}; -+ -+struct stm32_fmc2_nand { -+ struct nand_chip chip; -+ struct stm32_fmc2_timings timings; -+ int ncs; -+ int cs_used[FMC2_MAX_CE]; -+}; -+ -+static inline struct stm32_fmc2_nand *to_fmc2_nand(struct nand_chip *chip) -+{ -+ return container_of(chip, struct stm32_fmc2_nand, chip); -+} -+ -+struct stm32_fmc2_nfc { -+ struct nand_hw_control base; -+ struct stm32_fmc2_nand nand; -+ struct nand_ecclayout ecclayout; -+ void __iomem *io_base; -+ void __iomem *data_base[FMC2_MAX_CE]; -+ void __iomem *cmd_base[FMC2_MAX_CE]; -+ void __iomem *addr_base[FMC2_MAX_CE]; -+ struct clk clk; -+ -+ u8 cs_assigned; -+ int cs_sel; -+}; -+ -+static inline struct stm32_fmc2_nfc *to_stm32_nfc(struct nand_hw_control *base) -+{ -+ return container_of(base, struct stm32_fmc2_nfc, base); -+} -+ -+/* Clear interrupt sources in case of bch is used */ -+static inline void stm32_fmc2_clear_bch_irq(struct stm32_fmc2_nfc *fmc2) -+{ -+ writel(FMC2_BCHICR_CLEAR_IRQ, fmc2->io_base + FMC2_BCHICR); -+} -+ -+/* Set bus width to 16-bit or 8-bit */ -+static void stm32_fmc2_set_buswidth_16(struct stm32_fmc2_nfc *fmc2, bool set) -+{ -+ u32 pcr = readl(fmc2->io_base + FMC2_PCR); -+ -+ pcr &= ~FMC2_PCR_PWID_MASK; -+ if (set) -+ pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16); -+ writel(pcr, fmc2->io_base + FMC2_PCR); -+} -+ -+/* Enable/disable ecc */ -+static void stm32_fmc2_set_ecc(struct stm32_fmc2_nfc *fmc2, bool enable) -+{ -+ u32 pcr = readl(fmc2->io_base + FMC2_PCR); -+ -+ pcr &= ~FMC2_PCR_ECCEN; -+ if (enable) -+ pcr |= FMC2_PCR_ECCEN; -+ writel(pcr, fmc2->io_base + FMC2_PCR); -+} -+ -+/* Send command and address cycles */ -+static void stm32_fmc2_cmd_ctrl(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); -+ -+ if (cmd == NAND_CMD_NONE) -+ return; -+ -+ if (ctrl & NAND_CLE) { -+ writeb(cmd, fmc2->cmd_base[fmc2->cs_sel]); -+ return; -+ } -+ -+ writeb(cmd, fmc2->addr_base[fmc2->cs_sel]); -+} -+ -+/* -+ * Enable ecc logic and reset syndrome/parity bits previously calculated -+ * Syndrome/parity bits is cleared by setting the ECCEN bit to 0 -+ */ -+static void stm32_fmc2_hwctl(struct mtd_info *mtd, int mode) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); -+ -+ stm32_fmc2_set_ecc(fmc2, false); -+ -+ if (chip->ecc.strength != FMC2_ECC_HAM) { -+ u32 pcr = readl(fmc2->io_base + FMC2_PCR); -+ -+ if (mode == NAND_ECC_WRITE) -+ pcr |= FMC2_PCR_WEN; -+ else -+ pcr &= ~FMC2_PCR_WEN; -+ writel(pcr, fmc2->io_base + FMC2_PCR); -+ -+ stm32_fmc2_clear_bch_irq(fmc2); -+ } -+ -+ stm32_fmc2_set_ecc(fmc2, true); -+} -+ -+/* -+ * Ecc Hamming calculation -+ * Ecc is 3 bytes for 512 bytes of data (supports error correction up to -+ * max of 1-bit) -+ */ -+static int stm32_fmc2_ham_calculate(struct mtd_info *mtd, const u8 *data, -+ u8 *ecc) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); -+ u32 heccr, sr; -+ int ret; -+ -+ ret = readl_poll_timeout(fmc2->io_base + FMC2_SR, sr, -+ sr & FMC2_SR_NWRF, 10000); -+ if (ret < 0) { -+ pr_err("Ham timeout\n"); -+ return -ETIMEDOUT; -+ } -+ -+ heccr = readl(fmc2->io_base + FMC2_HECCR); -+ -+ ecc[0] = heccr; -+ ecc[1] = heccr >> 8; -+ ecc[2] = heccr >> 16; -+ -+ /* Disable ecc */ -+ stm32_fmc2_set_ecc(fmc2, false); -+ -+ return 0; -+} -+ -+static int stm32_fmc2_ham_correct(struct mtd_info *mtd, u8 *dat, -+ u8 *read_ecc, u8 *calc_ecc) -+{ -+ u8 bit_position = 0, b0, b1, b2; -+ u32 byte_addr = 0, b; -+ u32 i, shifting = 1; -+ -+ /* Indicate which bit and byte is faulty (if any) */ -+ b0 = read_ecc[0] ^ calc_ecc[0]; -+ b1 = read_ecc[1] ^ calc_ecc[1]; -+ b2 = read_ecc[2] ^ calc_ecc[2]; -+ b = b0 | (b1 << 8) | (b2 << 16); -+ -+ /* No errors */ -+ if (likely(!b)) -+ return 0; -+ -+ /* Calculate bit position */ -+ for (i = 0; i < 3; i++) { -+ switch (b % 4) { -+ case 2: -+ bit_position += shifting; -+ case 1: -+ break; -+ default: -+ return -EBADMSG; -+ } -+ shifting <<= 1; -+ b >>= 2; -+ } -+ -+ /* Calculate byte position */ -+ shifting = 1; -+ for (i = 0; i < 9; i++) { -+ switch (b % 4) { -+ case 2: -+ byte_addr += shifting; -+ case 1: -+ break; -+ default: -+ return -EBADMSG; -+ } -+ shifting <<= 1; -+ b >>= 2; -+ } -+ -+ /* Flip the bit */ -+ dat[byte_addr] ^= (1 << bit_position); -+ -+ return 1; -+} -+ -+/* -+ * Ecc BCH calculation and correction -+ * Ecc is 7/13 bytes for 512 bytes of data (supports error correction up to -+ * max of 4-bit/8-bit) -+ */ -+ -+static int stm32_fmc2_bch_calculate(struct mtd_info *mtd, const u8 *data, -+ u8 *ecc) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); -+ u32 bchpbr, bchisr; -+ int ret; -+ -+ /* Wait that the BCH encoder parity is available */ -+ ret = readl_poll_timeout(fmc2->io_base + FMC2_BCHISR, bchisr, -+ bchisr & FMC2_BCHISR_EPBRF, 10000); -+ if (ret < 0) { -+ pr_err("Bch timeout\n"); -+ return -ETIMEDOUT; -+ } -+ -+ /* Read parity bits (write) or syndrome (read) */ -+ bchpbr = readl(fmc2->io_base + FMC2_BCHPBR1); -+ ecc[0] = bchpbr; -+ ecc[1] = bchpbr >> 8; -+ ecc[2] = bchpbr >> 16; -+ ecc[3] = bchpbr >> 24; -+ -+ bchpbr = readl(fmc2->io_base + FMC2_BCHPBR2); -+ ecc[4] = bchpbr; -+ ecc[5] = bchpbr >> 8; -+ ecc[6] = bchpbr >> 16; -+ -+ if (chip->ecc.strength == FMC2_ECC_BCH8) { -+ ecc[7] = bchpbr >> 24; -+ -+ bchpbr = readl(fmc2->io_base + FMC2_BCHPBR3); -+ ecc[8] = bchpbr; -+ ecc[9] = bchpbr >> 8; -+ ecc[10] = bchpbr >> 16; -+ ecc[11] = bchpbr >> 24; -+ -+ bchpbr = readl(fmc2->io_base + FMC2_BCHPBR4); -+ ecc[12] = bchpbr; -+ } -+ -+ /* Disable ecc */ -+ stm32_fmc2_set_ecc(fmc2, false); -+ -+ return 0; -+} -+ -+/* BCH algorithm correction */ -+static int stm32_fmc2_bch_correct(struct mtd_info *mtd, u8 *dat, -+ u8 *read_ecc, u8 *calc_ecc) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); -+ u32 bchdsr0, bchdsr1, bchdsr2, bchdsr3, bchdsr4, bchisr; -+ u16 pos[8]; -+ int i, ret, den, eccsize = chip->ecc.size; -+ unsigned int nb_errs = 0; -+ -+ /* Wait that the BCH encoder syndrome is available */ -+ ret = readl_poll_timeout(fmc2->io_base + FMC2_BCHISR, bchisr, -+ bchisr & FMC2_BCHISR_DERF, 10000); -+ if (ret < 0) { -+ pr_err("Bch timeout\n"); -+ return -ETIMEDOUT; -+ } -+ -+ bchdsr0 = readl(fmc2->io_base + FMC2_BCHDSR0); -+ bchdsr1 = readl(fmc2->io_base + FMC2_BCHDSR1); -+ bchdsr2 = readl(fmc2->io_base + FMC2_BCHDSR2); -+ bchdsr3 = readl(fmc2->io_base + FMC2_BCHDSR3); -+ bchdsr4 = readl(fmc2->io_base + FMC2_BCHDSR4); -+ -+ /* Disable ecc */ -+ stm32_fmc2_set_ecc(fmc2, false); -+ -+ /* No errors found */ -+ if (likely(!(bchdsr0 & FMC2_BCHDSR0_DEF))) -+ return 0; -+ -+ /* Too many errors detected */ -+ if (unlikely(bchdsr0 & FMC2_BCHDSR0_DUE)) -+ return -EBADMSG; -+ -+ pos[0] = bchdsr1 & FMC2_BCHDSR1_EBP1_MASK; -+ pos[1] = (bchdsr1 & FMC2_BCHDSR1_EBP2_MASK) >> FMC2_BCHDSR1_EBP2_SHIFT; -+ pos[2] = bchdsr2 & FMC2_BCHDSR2_EBP3_MASK; -+ pos[3] = (bchdsr2 & FMC2_BCHDSR2_EBP4_MASK) >> FMC2_BCHDSR2_EBP4_SHIFT; -+ pos[4] = bchdsr3 & FMC2_BCHDSR3_EBP5_MASK; -+ pos[5] = (bchdsr3 & FMC2_BCHDSR3_EBP6_MASK) >> FMC2_BCHDSR3_EBP6_SHIFT; -+ pos[6] = bchdsr4 & FMC2_BCHDSR4_EBP7_MASK; -+ pos[7] = (bchdsr4 & FMC2_BCHDSR4_EBP8_MASK) >> FMC2_BCHDSR4_EBP8_SHIFT; -+ -+ den = (bchdsr0 & FMC2_BCHDSR0_DEN_MASK) >> FMC2_BCHDSR0_DEN_SHIFT; -+ for (i = 0; i < den; i++) { -+ if (pos[i] < eccsize * 8) { -+ __change_bit(pos[i], (unsigned long *)dat); -+ nb_errs++; -+ } -+ } -+ -+ return nb_errs; -+} -+ -+static int stm32_fmc2_read_page(struct mtd_info *mtd, -+ struct nand_chip *chip, u8 *buf, -+ int oob_required, int page) -+{ -+ int i, s, stat, eccsize = chip->ecc.size; -+ int eccbytes = chip->ecc.bytes; -+ int eccsteps = chip->ecc.steps; -+ int eccstrength = chip->ecc.strength; -+ u8 *p = buf; -+ u8 *ecc_calc = chip->buffers->ecccalc; -+ u8 *ecc_code = chip->buffers->ecccode; -+ unsigned int max_bitflips = 0; -+ -+ for (i = mtd->writesize + FMC2_BBM_LEN, s = 0; s < eccsteps; -+ s++, i += eccbytes, p += eccsize) { -+ chip->ecc.hwctl(mtd, NAND_ECC_READ); -+ -+ /* Read the nand page sector (512 bytes) */ -+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, s * eccsize, -1); -+ chip->read_buf(mtd, p, eccsize); -+ -+ /* Read the corresponding ecc bytes */ -+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, i, -1); -+ chip->read_buf(mtd, ecc_code, eccbytes); -+ -+ /* Correct the data */ -+ stat = chip->ecc.correct(mtd, p, ecc_code, ecc_calc); -+ if (stat == -EBADMSG) -+ /* Check for empty pages with bitflips */ -+ stat = nand_check_erased_ecc_chunk(p, eccsize, -+ ecc_code, eccbytes, -+ NULL, 0, -+ eccstrength); -+ -+ if (stat < 0) { -+ mtd->ecc_stats.failed++; -+ } else { -+ mtd->ecc_stats.corrected += stat; -+ max_bitflips = max_t(unsigned int, max_bitflips, stat); -+ } -+ } -+ -+ /* Read oob */ -+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1); -+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); -+ -+ return max_bitflips; -+} -+ -+/* Timings configuration */ -+static void stm32_fmc2_timings_init(struct nand_chip *chip) -+{ -+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); -+ struct stm32_fmc2_nand *nand = to_fmc2_nand(chip); -+ struct stm32_fmc2_timings *timings = &nand->timings; -+ u32 pcr = readl(fmc2->io_base + FMC2_PCR); -+ u32 pmem, patt; -+ -+ /* Set tclr/tar timings */ -+ pcr &= ~FMC2_PCR_TCLR_MASK; -+ pcr |= FMC2_PCR_TCLR(timings->tclr); -+ pcr &= ~FMC2_PCR_TAR_MASK; -+ pcr |= FMC2_PCR_TAR(timings->tar); -+ -+ /* Set tset/twait/thold/thiz timings in common bank */ -+ pmem = FMC2_PMEM_MEMSET(timings->tset_mem); -+ pmem |= FMC2_PMEM_MEMWAIT(timings->twait); -+ pmem |= FMC2_PMEM_MEMHOLD(timings->thold_mem); -+ pmem |= FMC2_PMEM_MEMHIZ(timings->thiz); -+ -+ /* Set tset/twait/thold/thiz timings in attribut bank */ -+ patt = FMC2_PATT_ATTSET(timings->tset_att); -+ patt |= FMC2_PATT_ATTWAIT(timings->twait); -+ patt |= FMC2_PATT_ATTHOLD(timings->thold_att); -+ patt |= FMC2_PATT_ATTHIZ(timings->thiz); -+ -+ writel(pcr, fmc2->io_base + FMC2_PCR); -+ writel(pmem, fmc2->io_base + FMC2_PMEM); -+ writel(patt, fmc2->io_base + FMC2_PATT); -+} -+ -+/* Controller initialization */ -+static void stm32_fmc2_init(struct stm32_fmc2_nfc *fmc2) -+{ -+ u32 pcr = readl(fmc2->io_base + FMC2_PCR); -+ u32 bcr1 = readl(fmc2->io_base + FMC2_BCR1); -+ -+ /* Set CS used to undefined */ -+ fmc2->cs_sel = -1; -+ -+ /* Enable wait feature and nand flash memory bank */ -+ pcr |= FMC2_PCR_PWAITEN; -+ pcr |= FMC2_PCR_PBKEN; -+ -+ /* Set buswidth to 8 bits mode for identification */ -+ pcr &= ~FMC2_PCR_PWID_MASK; -+ -+ /* Ecc logic is disabled */ -+ pcr &= ~FMC2_PCR_ECCEN; -+ -+ /* Default mode */ -+ pcr &= ~FMC2_PCR_ECCALG; -+ pcr &= ~FMC2_PCR_BCHECC; -+ pcr &= ~FMC2_PCR_WEN; -+ -+ /* Set default ecc sector size */ -+ pcr &= ~FMC2_PCR_ECCSS_MASK; -+ pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_2048); -+ -+ /* Set default tclr/tar timings */ -+ pcr &= ~FMC2_PCR_TCLR_MASK; -+ pcr |= FMC2_PCR_TCLR(FMC2_PCR_TCLR_DEFAULT); -+ pcr &= ~FMC2_PCR_TAR_MASK; -+ pcr |= FMC2_PCR_TAR(FMC2_PCR_TAR_DEFAULT); -+ -+ /* Enable FMC2 controller */ -+ bcr1 |= FMC2_BCR1_FMC2EN; -+ -+ writel(bcr1, fmc2->io_base + FMC2_BCR1); -+ writel(pcr, fmc2->io_base + FMC2_PCR); -+ writel(FMC2_PMEM_DEFAULT, fmc2->io_base + FMC2_PMEM); -+ writel(FMC2_PATT_DEFAULT, fmc2->io_base + FMC2_PATT); -+} -+ -+/* Controller configuration */ -+static void stm32_fmc2_setup(struct nand_chip *chip) -+{ -+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); -+ u32 pcr = readl(fmc2->io_base + FMC2_PCR); -+ -+ /* Configure in Hamming by default */ -+ if (chip->ecc.strength == FMC2_ECC_BCH8) { -+ pcr |= FMC2_PCR_ECCALG; -+ pcr |= FMC2_PCR_BCHECC; -+ } else if (chip->ecc.strength == FMC2_ECC_BCH4) { -+ pcr |= FMC2_PCR_ECCALG; -+ } -+ -+ /* Set buswidth */ -+ if (chip->options & NAND_BUSWIDTH_16) -+ pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16); -+ -+ /* Set ecc sector size */ -+ pcr &= ~FMC2_PCR_ECCSS_MASK; -+ pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512); -+ -+ writel(pcr, fmc2->io_base + FMC2_PCR); -+} -+ -+/* Select function */ -+static void stm32_fmc2_select_chip(struct mtd_info *mtd, int chipnr) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); -+ struct stm32_fmc2_nand *nand = to_fmc2_nand(chip); -+ -+ if (chipnr < 0 || chipnr >= nand->ncs) -+ return; -+ -+ if (nand->cs_used[chipnr] == fmc2->cs_sel) -+ return; -+ -+ fmc2->cs_sel = nand->cs_used[chipnr]; -+ chip->IO_ADDR_R = fmc2->data_base[fmc2->cs_sel]; -+ chip->IO_ADDR_W = fmc2->data_base[fmc2->cs_sel]; -+ -+ /* FMC2 setup routine */ -+ stm32_fmc2_setup(chip); -+ -+ /* Apply timings */ -+ stm32_fmc2_timings_init(chip); -+} -+ -+/* Controller timings */ -+static void stm32_fmc2_calc_timings(struct nand_chip *chip, -+ const struct nand_sdr_timings *sdrt) -+{ -+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); -+ struct stm32_fmc2_nand *nand = to_fmc2_nand(chip); -+ struct stm32_fmc2_timings *tims = &nand->timings; -+ unsigned long hclk = clk_get_rate(&fmc2->clk); -+ unsigned long hclkp = FMC2_NSEC_PER_SEC / (hclk / 1000); -+ int tar, tclr, thiz, twait, tset_mem, tset_att, thold_mem, thold_att; -+ -+ tar = hclkp; -+ if (tar < sdrt->tAR_min) -+ tar = sdrt->tAR_min; -+ tims->tar = DIV_ROUND_UP(tar, hclkp) - 1; -+ if (tims->tar > FMC2_PCR_TIMING_MASK) -+ tims->tar = FMC2_PCR_TIMING_MASK; -+ -+ tclr = hclkp; -+ if (tclr < sdrt->tCLR_min) -+ tclr = sdrt->tCLR_min; -+ tims->tclr = DIV_ROUND_UP(tclr, hclkp) - 1; -+ if (tims->tclr > FMC2_PCR_TIMING_MASK) -+ tims->tclr = FMC2_PCR_TIMING_MASK; -+ -+ tims->thiz = FMC2_THIZ; -+ thiz = (tims->thiz + 1) * hclkp; -+ -+ /* -+ * tWAIT > tRP -+ * tWAIT > tWP -+ * tWAIT > tREA + tIO -+ */ -+ twait = hclkp; -+ if (twait < sdrt->tRP_min) -+ twait = sdrt->tRP_min; -+ if (twait < sdrt->tWP_min) -+ twait = sdrt->tWP_min; -+ if (twait < sdrt->tREA_max + FMC2_TIO) -+ twait = sdrt->tREA_max + FMC2_TIO; -+ tims->twait = DIV_ROUND_UP(twait, hclkp); -+ if (tims->twait == 0) -+ tims->twait = 1; -+ else if (tims->twait > FMC2_PMEM_PATT_TIMING_MASK) -+ tims->twait = FMC2_PMEM_PATT_TIMING_MASK; -+ -+ /* -+ * tSETUP_MEM > tCS - tWAIT -+ * tSETUP_MEM > tALS - tWAIT -+ * tSETUP_MEM > tDS - (tWAIT - tHIZ) -+ */ -+ tset_mem = hclkp; -+ if (sdrt->tCS_min > twait && (tset_mem < sdrt->tCS_min - twait)) -+ tset_mem = sdrt->tCS_min - twait; -+ if (sdrt->tALS_min > twait && (tset_mem < sdrt->tALS_min - twait)) -+ tset_mem = sdrt->tALS_min - twait; -+ if (twait > thiz && (sdrt->tDS_min > twait - thiz) && -+ (tset_mem < sdrt->tDS_min - (twait - thiz))) -+ tset_mem = sdrt->tDS_min - (twait - thiz); -+ tims->tset_mem = DIV_ROUND_UP(tset_mem, hclkp); -+ if (tims->tset_mem == 0) -+ tims->tset_mem = 1; -+ else if (tims->tset_mem > FMC2_PMEM_PATT_TIMING_MASK) -+ tims->tset_mem = FMC2_PMEM_PATT_TIMING_MASK; -+ -+ /* -+ * tHOLD_MEM > tCH -+ * tHOLD_MEM > tREH - tSETUP_MEM -+ * tHOLD_MEM > max(tRC, tWC) - (tSETUP_MEM + tWAIT) -+ */ -+ thold_mem = hclkp; -+ if (thold_mem < sdrt->tCH_min) -+ thold_mem = sdrt->tCH_min; -+ if (sdrt->tREH_min > tset_mem && -+ (thold_mem < sdrt->tREH_min - tset_mem)) -+ thold_mem = sdrt->tREH_min - tset_mem; -+ if ((sdrt->tRC_min > tset_mem + twait) && -+ (thold_mem < sdrt->tRC_min - (tset_mem + twait))) -+ thold_mem = sdrt->tRC_min - (tset_mem + twait); -+ if ((sdrt->tWC_min > tset_mem + twait) && -+ (thold_mem < sdrt->tWC_min - (tset_mem + twait))) -+ thold_mem = sdrt->tWC_min - (tset_mem + twait); -+ tims->thold_mem = DIV_ROUND_UP(thold_mem, hclkp); -+ if (tims->thold_mem == 0) -+ tims->thold_mem = 1; -+ else if (tims->thold_mem > FMC2_PMEM_PATT_TIMING_MASK) -+ tims->thold_mem = FMC2_PMEM_PATT_TIMING_MASK; -+ -+ /* -+ * tSETUP_ATT > tCS - tWAIT -+ * tSETUP_ATT > tCLS - tWAIT -+ * tSETUP_ATT > tALS - tWAIT -+ * tSETUP_ATT > tRHW - tHOLD_MEM -+ * tSETUP_ATT > tDS - (tWAIT - tHIZ) -+ */ -+ tset_att = hclkp; -+ if (sdrt->tCS_min > twait && (tset_att < sdrt->tCS_min - twait)) -+ tset_att = sdrt->tCS_min - twait; -+ if (sdrt->tCLS_min > twait && (tset_att < sdrt->tCLS_min - twait)) -+ tset_att = sdrt->tCLS_min - twait; -+ if (sdrt->tALS_min > twait && (tset_att < sdrt->tALS_min - twait)) -+ tset_att = sdrt->tALS_min - twait; -+ if (sdrt->tRHW_min > thold_mem && -+ (tset_att < sdrt->tRHW_min - thold_mem)) -+ tset_att = sdrt->tRHW_min - thold_mem; -+ if (twait > thiz && (sdrt->tDS_min > twait - thiz) && -+ (tset_att < sdrt->tDS_min - (twait - thiz))) -+ tset_att = sdrt->tDS_min - (twait - thiz); -+ tims->tset_att = DIV_ROUND_UP(tset_att, hclkp); -+ if (tims->tset_att == 0) -+ tims->tset_att = 1; -+ else if (tims->tset_att > FMC2_PMEM_PATT_TIMING_MASK) -+ tims->tset_att = FMC2_PMEM_PATT_TIMING_MASK; -+ -+ /* -+ * tHOLD_ATT > tALH -+ * tHOLD_ATT > tCH -+ * tHOLD_ATT > tCLH -+ * tHOLD_ATT > tCOH -+ * tHOLD_ATT > tDH -+ * tHOLD_ATT > tWB + tIO + tSYNC - tSETUP_MEM -+ * tHOLD_ATT > tADL - tSETUP_MEM -+ * tHOLD_ATT > tWH - tSETUP_MEM -+ * tHOLD_ATT > tWHR - tSETUP_MEM -+ * tHOLD_ATT > tRC - (tSETUP_ATT + tWAIT) -+ * tHOLD_ATT > tWC - (tSETUP_ATT + tWAIT) -+ */ -+ thold_att = hclkp; -+ if (thold_att < sdrt->tALH_min) -+ thold_att = sdrt->tALH_min; -+ if (thold_att < sdrt->tCH_min) -+ thold_att = sdrt->tCH_min; -+ if (thold_att < sdrt->tCLH_min) -+ thold_att = sdrt->tCLH_min; -+ if (thold_att < sdrt->tCOH_min) -+ thold_att = sdrt->tCOH_min; -+ if (thold_att < sdrt->tDH_min) -+ thold_att = sdrt->tDH_min; -+ if ((sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC > tset_mem) && -+ (thold_att < sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC - tset_mem)) -+ thold_att = sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC - tset_mem; -+ if (sdrt->tADL_min > tset_mem && -+ (thold_att < sdrt->tADL_min - tset_mem)) -+ thold_att = sdrt->tADL_min - tset_mem; -+ if (sdrt->tWH_min > tset_mem && -+ (thold_att < sdrt->tWH_min - tset_mem)) -+ thold_att = sdrt->tWH_min - tset_mem; -+ if (sdrt->tWHR_min > tset_mem && -+ (thold_att < sdrt->tWHR_min - tset_mem)) -+ thold_att = sdrt->tWHR_min - tset_mem; -+ if ((sdrt->tRC_min > tset_att + twait) && -+ (thold_att < sdrt->tRC_min - (tset_att + twait))) -+ thold_att = sdrt->tRC_min - (tset_att + twait); -+ if ((sdrt->tWC_min > tset_att + twait) && -+ (thold_att < sdrt->tWC_min - (tset_att + twait))) -+ thold_att = sdrt->tWC_min - (tset_att + twait); -+ tims->thold_att = DIV_ROUND_UP(thold_att, hclkp); -+ if (tims->thold_att == 0) -+ tims->thold_att = 1; -+ else if (tims->thold_att > FMC2_PMEM_PATT_TIMING_MASK) -+ tims->thold_att = FMC2_PMEM_PATT_TIMING_MASK; -+} -+ -+static int stm32_fmc2_setup_interface(struct mtd_info *mtd, int chipnr, -+ const struct nand_data_interface *conf) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ const struct nand_sdr_timings *sdrt; -+ -+ sdrt = nand_get_sdr_timings(conf); -+ if (IS_ERR(sdrt)) -+ return PTR_ERR(sdrt); -+ -+ if (chipnr == NAND_DATA_IFACE_CHECK_ONLY) -+ return 0; -+ -+ stm32_fmc2_calc_timings(chip, sdrt); -+ -+ /* Apply timings */ -+ stm32_fmc2_timings_init(chip); -+ -+ return 0; -+} -+ -+/* NAND callbacks setup */ -+static void stm32_fmc2_nand_callbacks_setup(struct nand_chip *chip) -+{ -+ chip->ecc.hwctl = stm32_fmc2_hwctl; -+ -+ /* -+ * Specific callbacks to read/write a page depending on -+ * the algo used (Hamming, BCH). -+ */ -+ if (chip->ecc.strength == FMC2_ECC_HAM) { -+ /* Hamming is used */ -+ chip->ecc.calculate = stm32_fmc2_ham_calculate; -+ chip->ecc.correct = stm32_fmc2_ham_correct; -+ chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 4 : 3; -+ chip->ecc.options |= NAND_ECC_GENERIC_ERASED_CHECK; -+ return; -+ } -+ -+ /* BCH is used */ -+ chip->ecc.read_page = stm32_fmc2_read_page; -+ chip->ecc.calculate = stm32_fmc2_bch_calculate; -+ chip->ecc.correct = stm32_fmc2_bch_correct; -+ -+ if (chip->ecc.strength == FMC2_ECC_BCH8) -+ chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 14 : 13; -+ else -+ chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 8 : 7; -+} -+ -+/* FMC2 caps */ -+static int stm32_fmc2_calc_ecc_bytes(int step_size, int strength) -+{ -+ /* Hamming */ -+ if (strength == FMC2_ECC_HAM) -+ return 4; -+ -+ /* BCH8 */ -+ if (strength == FMC2_ECC_BCH8) -+ return 14; -+ -+ /* BCH4 */ -+ return 8; -+} -+ -+NAND_ECC_CAPS_SINGLE(stm32_fmc2_ecc_caps, stm32_fmc2_calc_ecc_bytes, -+ FMC2_ECC_STEP_SIZE, -+ FMC2_ECC_HAM, FMC2_ECC_BCH4, FMC2_ECC_BCH8); -+ -+/* FMC2 probe */ -+static int stm32_fmc2_parse_child(struct stm32_fmc2_nfc *fmc2, -+ ofnode node) -+{ -+ struct stm32_fmc2_nand *nand = &fmc2->nand; -+ u32 cs[FMC2_MAX_CE]; -+ int ret, chip_cs; -+ -+ if (!ofnode_get_property(node, "reg", &nand->ncs)) -+ return -EINVAL; -+ -+ nand->ncs /= sizeof(u32); -+ if (!nand->ncs) { -+ pr_err("Invalid reg property size\n"); -+ return -EINVAL; -+ } -+ -+ ret = ofnode_read_u32_array(node, "reg", cs, nand->ncs); -+ if (ret < 0) { -+ pr_err("Could not retrieve reg property\n"); -+ return -EINVAL; -+ } -+ -+ for (chip_cs = 0; chip_cs < nand->ncs; chip_cs++) { -+ if (cs[chip_cs] > FMC2_MAX_CE) { -+ pr_err("Invalid reg value: %d\n", -+ nand->cs_used[chip_cs]); -+ return -EINVAL; -+ } -+ -+ if (fmc2->cs_assigned & BIT(cs[chip_cs])) { -+ pr_err("Cs already assigned: %d\n", -+ nand->cs_used[chip_cs]); -+ return -EINVAL; -+ } -+ -+ fmc2->cs_assigned |= BIT(cs[chip_cs]); -+ nand->cs_used[chip_cs] = cs[chip_cs]; -+ } -+ -+ nand->chip.flash_node = ofnode_to_offset(node); -+ -+ return 0; -+} -+ -+static int stm32_fmc2_parse_children(struct udevice *dev, -+ struct stm32_fmc2_nfc *fmc2) -+{ -+ ofnode child; -+ int ret, nchips = 0; -+ -+ dev_for_each_subnode(child, dev) -+ nchips++; -+ -+ if (!nchips) { -+ pr_err("NAND chip not defined\n"); -+ return -EINVAL; -+ } -+ -+ if (nchips > 1) { -+ pr_err("Too many NAND chips defined\n"); -+ return -EINVAL; -+ } -+ -+ dev_for_each_subnode(child, dev) { -+ ret = stm32_fmc2_parse_child(fmc2, child); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int stm32_fmc2_probe(struct udevice *dev) -+{ -+ struct stm32_fmc2_nfc *fmc2 = dev_get_priv(dev); -+ struct stm32_fmc2_nand *nand = &fmc2->nand; -+ struct nand_chip *chip = &nand->chip; -+ struct mtd_info *mtd = &chip->mtd; -+ struct nand_ecclayout *ecclayout; -+ struct resource resource; -+ struct reset_ctl reset; -+ int oob_index, chip_cs, mem_region, ret, i; -+ -+ spin_lock_init(&fmc2->controller.lock); -+ init_waitqueue_head(&fmc2->controller.wq); -+ -+ ret = stm32_fmc2_parse_children(dev, fmc2); -+ if (ret) -+ return ret; -+ -+ /* Get resources */ -+ ret = dev_read_resource(dev, 0, &resource); -+ if (ret) { -+ pr_err("Resource io_base not found"); -+ return ret; -+ } -+ fmc2->io_base = (void __iomem *)resource.start; -+ -+ for (chip_cs = 0, mem_region = 1; chip_cs < FMC2_MAX_CE; -+ chip_cs++, mem_region += 3) { -+ if (!(fmc2->cs_assigned & BIT(chip_cs))) -+ continue; -+ -+ ret = dev_read_resource(dev, mem_region, &resource); -+ if (ret) { -+ pr_err("Resource data_base not found for cs%d", -+ chip_cs); -+ return ret; -+ } -+ fmc2->data_base[chip_cs] = (void __iomem *)resource.start; -+ -+ ret = dev_read_resource(dev, mem_region + 1, &resource); -+ if (ret) { -+ pr_err("Resource cmd_base not found for cs%d", -+ chip_cs); -+ return ret; -+ } -+ fmc2->cmd_base[chip_cs] = (void __iomem *)resource.start; -+ -+ ret = dev_read_resource(dev, mem_region + 2, &resource); -+ if (ret) { -+ pr_err("Resource addr_base not found for cs%d", -+ chip_cs); -+ return ret; -+ } -+ fmc2->addr_base[chip_cs] = (void __iomem *)resource.start; -+ } -+ -+ /* Enable clock */ -+ ret = clk_get_by_index(dev, 0, &fmc2->clk); -+ if (ret) -+ return ret; -+ -+ ret = clk_enable(&fmc2->clk); -+ if (ret) -+ return ret; -+ -+ /* Reset */ -+ ret = reset_get_by_index(dev, 0, &reset); -+ if (!ret) { -+ reset_assert(&reset); -+ udelay(2); -+ reset_deassert(&reset); -+ } -+ -+ /* FMC2 init routine */ -+ stm32_fmc2_init(fmc2); -+ -+ chip->controller = &fmc2->base; -+ chip->select_chip = stm32_fmc2_select_chip; -+ chip->setup_data_interface = stm32_fmc2_setup_interface; -+ chip->cmd_ctrl = stm32_fmc2_cmd_ctrl; -+ chip->chip_delay = FMC2_RB_DELAY_US; -+ chip->options |= NAND_BUSWIDTH_AUTO | NAND_NO_SUBPAGE_WRITE | -+ NAND_USE_BOUNCE_BUFFER; -+ -+ /* Default settings */ -+ chip->ecc.mode = NAND_ECC_HW; -+ chip->ecc.size = FMC2_ECC_STEP_SIZE; -+ chip->ecc.strength = FMC2_ECC_BCH8; -+ -+ /* Scan to find existence of the device */ -+ ret = nand_scan_ident(mtd, nand->ncs, NULL); -+ if (ret) -+ return ret; -+ -+ /* -+ * Only NAND_ECC_HW mode is actually supported -+ * Hamming => ecc.strength = 1 -+ * BCH4 => ecc.strength = 4 -+ * BCH8 => ecc.strength = 8 -+ * ecc sector size = 512 -+ */ -+ if (chip->ecc.mode != NAND_ECC_HW) { -+ pr_err("Nand_ecc_mode is not well defined in the DT\n"); -+ return -EINVAL; -+ } -+ -+ ret = nand_check_ecc_caps(chip, &stm32_fmc2_ecc_caps, -+ mtd->oobsize - FMC2_BBM_LEN); -+ if (ret) { -+ pr_err("No valid ecc settings set\n"); -+ return ret; -+ } -+ -+ if (chip->bbt_options & NAND_BBT_USE_FLASH) -+ chip->bbt_options |= NAND_BBT_NO_OOB; -+ -+ /* NAND callbacks setup */ -+ stm32_fmc2_nand_callbacks_setup(chip); -+ -+ /* Define ecc layout */ -+ ecclayout = &fmc2->ecclayout; -+ ecclayout->eccbytes = chip->ecc.bytes * -+ (mtd->writesize / chip->ecc.size); -+ oob_index = FMC2_BBM_LEN; -+ for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) -+ ecclayout->eccpos[i] = oob_index; -+ ecclayout->oobfree->offset = oob_index + 1; -+ ecclayout->oobfree->length = mtd->oobsize - ecclayout->oobfree->offset; -+ chip->ecc.layout = ecclayout; -+ -+ /* Configure bus width to 16-bit */ -+ if (chip->options & NAND_BUSWIDTH_16) -+ stm32_fmc2_set_buswidth_16(fmc2, true); -+ -+ /* Scan the device to fill MTD data-structures */ -+ ret = nand_scan_tail(mtd); -+ if (ret) -+ return ret; -+ -+ return nand_register(0, mtd); -+} -+ -+static const struct udevice_id stm32_fmc2_match[] = { -+ { .compatible = "st,stm32mp15-fmc2" }, -+ { /* Sentinel */ } -+}; -+ -+U_BOOT_DRIVER(stm32_fmc2_nand) = { -+ .name = "stm32_fmc2_nand", -+ .id = UCLASS_MTD, -+ .of_match = stm32_fmc2_match, -+ .probe = stm32_fmc2_probe, -+ .priv_auto_alloc_size = sizeof(struct stm32_fmc2_nfc), -+}; -+ -+void board_nand_init(void) -+{ -+ struct udevice *dev; -+ int ret; -+ -+ ret = uclass_get_device_by_driver(UCLASS_MTD, -+ DM_GET_DRIVER(stm32_fmc2_nand), -+ &dev); -+ if (ret && ret != -ENODEV) -+ pr_err("Failed to initialize STM32 FMC2 NAND controller. (error %d)\n", -+ ret); -+} -diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c -index a87bacd..3bd6869 100644 ---- a/drivers/mtd/spi/spi_flash.c -+++ b/drivers/mtd/spi/spi_flash.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -357,6 +358,8 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) - - offset += erase_size; - len -= erase_size; -+ -+ WATCHDOG_RESET(); - } - - #ifdef CONFIG_SPI_FLASH_BAR -@@ -419,6 +422,8 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, - } - - offset += chunk_len; -+ -+ WATCHDOG_RESET(); - } - - #ifdef CONFIG_SPI_FLASH_BAR -@@ -525,6 +530,8 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, - offset += read_len; - len -= read_len; - data += read_len; -+ -+ WATCHDOG_RESET(); - } - - #ifdef CONFIG_SPI_FLASH_BAR -@@ -769,6 +776,8 @@ int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, - - cmd_len = 1; - offset += 2; -+ -+ WATCHDOG_RESET(); - } - - if (!ret) -diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c -index 9f1c5af..072b8c8 100644 ---- a/drivers/net/dwc_eth_qos.c -+++ b/drivers/net/dwc_eth_qos.c -@@ -26,7 +26,6 @@ - * supports a single RGMII PHY. This configuration also has SW control over - * all clock and reset signals to the HW block. - */ -- - #include - #include - #include -@@ -95,6 +94,7 @@ struct eqos_mac_regs { - #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK 3 - #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED 0 - #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 -+#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1 - - #define EQOS_MAC_RXQ_CTRL2_PSRQ0_SHIFT 0 - #define EQOS_MAC_RXQ_CTRL2_PSRQ0_MASK 0xff -@@ -108,6 +108,7 @@ struct eqos_mac_regs { - #define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT 16 - #define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT 8 - #define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2 -+#define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5 - #define EQOS_MAC_MDIO_ADDRESS_SKAP BIT(4) - #define EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT 2 - #define EQOS_MAC_MDIO_ADDRESS_GOC_READ 3 -@@ -260,6 +261,28 @@ struct eqos_desc { - - struct eqos_config { - bool reg_access_always_ok; -+ int mdio_wait; -+ int config_mac; -+ int config_mac_mdio; -+ int (*interface)(struct udevice *); -+ struct eqos_ops *ops; -+}; -+ -+struct eqos_ops { -+ void (*eqos_inval_desc)(void *desc); -+ void (*eqos_flush_desc)(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 *); -+ int (*eqos_remove_resources)(struct udevice *); -+ int (*eqos_stop_resets)(struct udevice *); -+ int (*eqos_start_resets)(struct udevice *); -+ void (*eqos_stop_clks)(struct udevice *); -+ int (*eqos_start_clks)(struct udevice *); -+ int (*eqos_calibrate_pads)(struct udevice *); -+ int (*eqos_disable_calibration)(struct udevice *); -+ int (*eqos_set_tx_clk_speed)(struct udevice *); -+ ulong (*eqos_get_tick_clk_rate)(struct udevice *); - }; - - struct eqos_priv { -@@ -276,6 +299,7 @@ struct eqos_priv { - struct clk clk_rx; - struct clk clk_ptp_ref; - struct clk clk_tx; -+ struct clk clk_ck; - struct clk clk_slave_bus; - struct mii_dev *mii; - struct phy_device *phy; -@@ -327,7 +351,7 @@ static void eqos_free_descs(void *descs) - #endif - } - --static void eqos_inval_desc(void *desc) -+static void eqos_inval_desc_tegra186(void *desc) - { - #ifndef CONFIG_SYS_NONCACHED_MEMORY - unsigned long start = (unsigned long)desc & ~(ARCH_DMA_MINALIGN - 1); -@@ -338,14 +362,36 @@ static void eqos_inval_desc(void *desc) - #endif - } - --static void eqos_flush_desc(void *desc) -+static void eqos_inval_desc_stm32(void *desc) -+{ -+#ifndef CONFIG_SYS_NONCACHED_MEMORY -+ unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN); -+ unsigned long end = roundup((unsigned long)desc + EQOS_DESCRIPTOR_SIZE, -+ ARCH_DMA_MINALIGN); -+ -+ invalidate_dcache_range(start, end); -+#endif -+} -+ -+static void eqos_flush_desc_tegra186(void *desc) - { - #ifndef CONFIG_SYS_NONCACHED_MEMORY - flush_cache((unsigned long)desc, EQOS_DESCRIPTOR_SIZE); - #endif - } - --static void eqos_inval_buffer(void *buf, size_t size) -+static void eqos_flush_desc_stm32(void *desc) -+{ -+#ifndef CONFIG_SYS_NONCACHED_MEMORY -+ unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN); -+ unsigned long end = roundup((unsigned long)desc + EQOS_DESCRIPTOR_SIZE, -+ ARCH_DMA_MINALIGN); -+ -+ flush_dcache_range(start, end); -+#endif -+} -+ -+static void eqos_inval_buffer_tegra186(void *buf, size_t size) - { - unsigned long start = (unsigned long)buf & ~(ARCH_DMA_MINALIGN - 1); - unsigned long end = ALIGN(start + size, ARCH_DMA_MINALIGN); -@@ -353,11 +399,29 @@ static void eqos_inval_buffer(void *buf, size_t size) - invalidate_dcache_range(start, end); - } - --static void eqos_flush_buffer(void *buf, size_t size) -+static void eqos_inval_buffer_stm32(void *buf, size_t size) -+{ -+ unsigned long start = rounddown((unsigned long)buf, ARCH_DMA_MINALIGN); -+ unsigned long end = roundup((unsigned long)buf + size, -+ ARCH_DMA_MINALIGN); -+ -+ invalidate_dcache_range(start, end); -+} -+ -+static void eqos_flush_buffer_tegra186(void *buf, size_t size) - { - flush_cache((unsigned long)buf, size); - } - -+static void eqos_flush_buffer_stm32(void *buf, size_t size) -+{ -+ unsigned long start = rounddown((unsigned long)buf, ARCH_DMA_MINALIGN); -+ unsigned long end = roundup((unsigned long)buf + size, -+ ARCH_DMA_MINALIGN); -+ -+ flush_dcache_range(start, end); -+} -+ - static int eqos_mdio_wait_idle(struct eqos_priv *eqos) - { - return wait_for_bit_le32(&eqos->mac_regs->mdio_address, -@@ -386,14 +450,14 @@ static int eqos_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad, - EQOS_MAC_MDIO_ADDRESS_C45E; - val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) | - (mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) | -- (EQOS_MAC_MDIO_ADDRESS_CR_20_35 << -+ (eqos->config->config_mac_mdio << - EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) | - (EQOS_MAC_MDIO_ADDRESS_GOC_READ << - EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) | - EQOS_MAC_MDIO_ADDRESS_GB; - writel(val, &eqos->mac_regs->mdio_address); - -- udelay(10); -+ udelay(eqos->config->mdio_wait); - - ret = eqos_mdio_wait_idle(eqos); - if (ret) { -@@ -432,14 +496,14 @@ static int eqos_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad, - EQOS_MAC_MDIO_ADDRESS_C45E; - val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) | - (mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) | -- (EQOS_MAC_MDIO_ADDRESS_CR_20_35 << -+ (eqos->config->config_mac_mdio << - EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) | - (EQOS_MAC_MDIO_ADDRESS_GOC_WRITE << - EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) | - EQOS_MAC_MDIO_ADDRESS_GB; - writel(val, &eqos->mac_regs->mdio_address); - -- udelay(10); -+ udelay(eqos->config->mdio_wait); - - ret = eqos_mdio_wait_idle(eqos); - if (ret) { -@@ -509,6 +573,53 @@ err: - return ret; - } - -+static int eqos_start_clks_stm32(struct udevice *dev) -+{ -+ struct eqos_priv *eqos = dev_get_priv(dev); -+ int ret; -+ -+ debug("%s(dev=%p):\n", __func__, dev); -+ -+ ret = clk_enable(&eqos->clk_master_bus); -+ if (ret < 0) { -+ pr_err("clk_enable(clk_master_bus) failed: %d", ret); -+ goto err; -+ } -+ -+ ret = clk_enable(&eqos->clk_rx); -+ if (ret < 0) { -+ pr_err("clk_enable(clk_rx) failed: %d", ret); -+ goto err_disable_clk_master_bus; -+ } -+ -+ ret = clk_enable(&eqos->clk_tx); -+ if (ret < 0) { -+ pr_err("clk_enable(clk_tx) failed: %d", ret); -+ goto err_disable_clk_rx; -+ } -+ -+ if (clk_valid(&eqos->clk_ck)) { -+ ret = clk_enable(&eqos->clk_ck); -+ if (ret < 0) { -+ pr_err("clk_enable(clk_ck) failed: %d", ret); -+ goto err_disable_clk_tx; -+ } -+ } -+ -+ debug("%s: OK\n", __func__); -+ return 0; -+ -+err_disable_clk_tx: -+ clk_disable(&eqos->clk_tx); -+err_disable_clk_rx: -+ clk_disable(&eqos->clk_rx); -+err_disable_clk_master_bus: -+ clk_disable(&eqos->clk_master_bus); -+err: -+ debug("%s: FAILED: %d\n", __func__, ret); -+ return ret; -+} -+ - void eqos_stop_clks_tegra186(struct udevice *dev) - { - struct eqos_priv *eqos = dev_get_priv(dev); -@@ -524,6 +635,21 @@ void eqos_stop_clks_tegra186(struct udevice *dev) - debug("%s: OK\n", __func__); - } - -+void eqos_stop_clks_stm32(struct udevice *dev) -+{ -+ struct eqos_priv *eqos = dev_get_priv(dev); -+ -+ debug("%s(dev=%p):\n", __func__, dev); -+ -+ clk_disable(&eqos->clk_tx); -+ clk_disable(&eqos->clk_rx); -+ clk_disable(&eqos->clk_master_bus); -+ if (clk_valid(&eqos->clk_ck)) -+ clk_disable(&eqos->clk_ck); -+ -+ debug("%s: OK\n", __func__); -+} -+ - static int eqos_start_resets_tegra186(struct udevice *dev) - { - struct eqos_priv *eqos = dev_get_priv(dev); -@@ -563,6 +689,11 @@ static int eqos_start_resets_tegra186(struct udevice *dev) - return 0; - } - -+static int eqos_start_resets_stm32(struct udevice *dev) -+{ -+ return 0; -+} -+ - static int eqos_stop_resets_tegra186(struct udevice *dev) - { - struct eqos_priv *eqos = dev_get_priv(dev); -@@ -573,6 +704,11 @@ static int eqos_stop_resets_tegra186(struct udevice *dev) - return 0; - } - -+static int eqos_stop_resets_stm32(struct udevice *dev) -+{ -+ return 0; -+} -+ - static int eqos_calibrate_pads_tegra186(struct udevice *dev) - { - struct eqos_priv *eqos = dev_get_priv(dev); -@@ -632,6 +768,23 @@ static ulong eqos_get_tick_clk_rate_tegra186(struct udevice *dev) - return clk_get_rate(&eqos->clk_slave_bus); - } - -+static ulong eqos_get_tick_clk_rate_stm32(struct udevice *dev) -+{ -+ struct eqos_priv *eqos = dev_get_priv(dev); -+ -+ return clk_get_rate(&eqos->clk_master_bus); -+} -+ -+static int eqos_calibrate_pads_stm32(struct udevice *dev) -+{ -+ return 0; -+} -+ -+static int eqos_disable_calibration_stm32(struct udevice *dev) -+{ -+ return 0; -+} -+ - static int eqos_set_full_duplex(struct udevice *dev) - { - struct eqos_priv *eqos = dev_get_priv(dev); -@@ -726,6 +879,11 @@ 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_adjust_link(struct udevice *dev) - { - struct eqos_priv *eqos = dev_get_priv(dev); -@@ -766,23 +924,23 @@ static int eqos_adjust_link(struct udevice *dev) - } - - if (en_calibration) { -- ret = eqos_calibrate_pads_tegra186(dev); -+ ret = eqos->config->ops->eqos_calibrate_pads(dev); - if (ret < 0) { -- pr_err("eqos_calibrate_pads_tegra186() failed: %d", ret); -+ pr_err("eqos_calibrate_pads() failed: %d", -+ ret); - return ret; - } - } else { -- ret = eqos_disable_calibration_tegra186(dev); -+ ret = eqos->config->ops->eqos_disable_calibration(dev); - if (ret < 0) { -- pr_err("eqos_disable_calibration_tegra186() failed: %d", -- ret); -+ pr_err("eqos_disable_calibration() failed: %d", -+ ret); - return ret; - } - } -- -- ret = eqos_set_tx_clk_speed_tegra186(dev); -+ ret = eqos->config->ops->eqos_set_tx_clk_speed(dev); - if (ret < 0) { -- pr_err("eqos_set_tx_clk_speed_tegra186() failed: %d", ret); -+ pr_err("eqos_set_tx_clk_speed() failed: %d", ret); - return ret; - } - -@@ -846,18 +1004,12 @@ static int eqos_start(struct udevice *dev) - eqos->tx_desc_idx = 0; - eqos->rx_desc_idx = 0; - -- ret = eqos_start_clks_tegra186(dev); -+ ret = eqos->config->ops->eqos_start_resets(dev); - if (ret < 0) { -- pr_err("eqos_start_clks_tegra186() failed: %d", ret); -+ pr_err("eqos_start_resets() failed: %d", ret); - goto err; - } - -- ret = eqos_start_resets_tegra186(dev); -- if (ret < 0) { -- pr_err("eqos_start_resets_tegra186() failed: %d", ret); -- goto err_stop_clks; -- } -- - udelay(10); - - eqos->reg_access_ok = true; -@@ -869,26 +1021,16 @@ static int eqos_start(struct udevice *dev) - goto err_stop_resets; - } - -- ret = eqos_calibrate_pads_tegra186(dev); -+ ret = eqos->config->ops->eqos_calibrate_pads(dev); - if (ret < 0) { -- pr_err("eqos_calibrate_pads_tegra186() failed: %d", ret); -+ pr_err("eqos_calibrate_pads() failed: %d", ret); - goto err_stop_resets; - } -+ rate = eqos->config->ops->eqos_get_tick_clk_rate(dev); - -- rate = eqos_get_tick_clk_rate_tegra186(dev); - val = (rate / 1000000) - 1; - writel(val, &eqos->mac_regs->us_tic_counter); - -- eqos->phy = phy_connect(eqos->mii, 0, dev, 0); -- if (!eqos->phy) { -- pr_err("phy_connect() failed"); -- goto err_stop_resets; -- } -- ret = phy_config(eqos->phy); -- if (ret < 0) { -- pr_err("phy_config() failed: %d", ret); -- goto err_shutdown_phy; -- } - ret = phy_startup(eqos->phy); - if (ret < 0) { - pr_err("phy_startup() failed: %d", ret); -@@ -993,7 +1135,7 @@ static int eqos_start(struct udevice *dev) - clrsetbits_le32(&eqos->mac_regs->rxq_ctrl0, - EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK << - EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT, -- EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB << -+ eqos->config->config_mac << - EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT); - - /* Set TX flow control parameters */ -@@ -1074,7 +1216,7 @@ static int eqos_start(struct udevice *dev) - (i * EQOS_MAX_PACKET_SIZE)); - rx_desc->des3 |= EQOS_DESC3_OWN | EQOS_DESC3_BUF1V; - } -- flush_cache((unsigned long)eqos->descs, EQOS_DESCRIPTORS_SIZE); -+ eqos->config->ops->eqos_flush_desc(eqos->descs); - - writel(0, &eqos->dma_regs->ch0_txdesc_list_haddress); - writel((ulong)eqos->tx_descs, &eqos->dma_regs->ch0_txdesc_list_address); -@@ -1115,9 +1257,7 @@ err_shutdown_phy: - phy_shutdown(eqos->phy); - eqos->phy = NULL; - err_stop_resets: -- eqos_stop_resets_tegra186(dev); --err_stop_clks: -- eqos_stop_clks_tegra186(dev); -+ eqos->config->ops->eqos_stop_resets(dev); - err: - pr_err("FAILED: %d", ret); - return ret; -@@ -1168,12 +1308,7 @@ void eqos_stop(struct udevice *dev) - clrbits_le32(&eqos->dma_regs->ch0_rx_control, - EQOS_DMA_CH0_RX_CONTROL_SR); - -- if (eqos->phy) { -- phy_shutdown(eqos->phy); -- eqos->phy = NULL; -- } -- eqos_stop_resets_tegra186(dev); -- eqos_stop_clks_tegra186(dev); -+ eqos->config->ops->eqos_stop_resets(dev); - - debug("%s: OK\n", __func__); - } -@@ -1188,7 +1323,7 @@ int eqos_send(struct udevice *dev, void *packet, int length) - length); - - memcpy(eqos->tx_dma_buf, packet, length); -- eqos_flush_buffer(eqos->tx_dma_buf, length); -+ eqos->config->ops->eqos_flush_buffer(eqos->tx_dma_buf, length); - - tx_desc = &(eqos->tx_descs[eqos->tx_desc_idx]); - eqos->tx_desc_idx++; -@@ -1203,12 +1338,12 @@ 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_flush_desc(tx_desc); -+ eqos->config->ops->eqos_flush_desc(tx_desc); - - writel((ulong)(tx_desc + 1), &eqos->dma_regs->ch0_txdesc_tail_pointer); - - for (i = 0; i < 1000000; i++) { -- eqos_inval_desc(tx_desc); -+ eqos->config->ops->eqos_inval_desc(tx_desc); - if (!(readl(&tx_desc->des3) & EQOS_DESC3_OWN)) - return 0; - udelay(1); -@@ -1238,7 +1373,7 @@ int eqos_recv(struct udevice *dev, int flags, uchar **packetp) - length = rx_desc->des3 & 0x7fff; - debug("%s: *packetp=%p, length=%d\n", __func__, *packetp, length); - -- eqos_inval_buffer(*packetp, length); -+ eqos->config->ops->eqos_inval_buffer(*packetp, length); - - return length; - } -@@ -1269,7 +1404,7 @@ int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) - */ - mb(); - rx_desc->des3 |= EQOS_DESC3_OWN | EQOS_DESC3_BUF1V; -- eqos_flush_desc(rx_desc); -+ eqos->config->ops->eqos_flush_desc(rx_desc); - - writel((ulong)rx_desc, &eqos->dma_regs->ch0_rxdesc_tail_pointer); - -@@ -1304,7 +1439,7 @@ static int eqos_probe_resources_core(struct udevice *dev) - ret = -ENOMEM; - goto err_free_descs; - } -- debug("%s: rx_dma_buf=%p\n", __func__, eqos->rx_dma_buf); -+ debug("%s: tx_dma_buf=%p\n", __func__, eqos->tx_dma_buf); - - eqos->rx_dma_buf = memalign(EQOS_BUFFER_ALIGN, EQOS_RX_BUFFER_SIZE); - if (!eqos->rx_dma_buf) { -@@ -1312,7 +1447,7 @@ static int eqos_probe_resources_core(struct udevice *dev) - ret = -ENOMEM; - goto err_free_tx_dma_buf; - } -- debug("%s: tx_dma_buf=%p\n", __func__, eqos->tx_dma_buf); -+ debug("%s: rx_dma_buf=%p\n", __func__, eqos->rx_dma_buf); - - eqos->rx_pkt = malloc(EQOS_MAX_PACKET_SIZE); - if (!eqos->rx_pkt) { -@@ -1424,6 +1559,99 @@ err_free_reset_eqos: - return ret; - } - -+/* board-specific Ethernet Interface initializations. */ -+__weak int board_interface_eth_init(int interface_type, bool eth_clk_sel_reg, -+ bool eth_ref_clk_sel_reg) -+{ -+ return 0; -+} -+ -+static int eqos_probe_resources_stm32(struct udevice *dev) -+{ -+ struct eqos_priv *eqos = dev_get_priv(dev); -+ int ret; -+ int interface; -+ bool eth_clk_sel_reg = false; -+ bool eth_ref_clk_sel_reg = false; -+ -+ -+ debug("%s(dev=%p):\n", __func__, dev); -+ -+ interface = eqos->config->interface(dev); -+ -+ if (interface == -1) { -+ pr_err("Invalid PHY interface\n"); -+ return -EINVAL; -+ } -+ -+ /* 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"); -+ -+ ret = board_interface_eth_init(interface, eth_clk_sel_reg, -+ eth_ref_clk_sel_reg); -+ if (ret) -+ return -EINVAL; -+ -+ ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus); -+ if (ret) { -+ pr_err("clk_get_by_name(master_bus) failed: %d", ret); -+ goto err_probe; -+ } -+ -+ ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx); -+ if (ret) { -+ pr_err("clk_get_by_name(rx) failed: %d", ret); -+ goto err_free_clk_master_bus; -+ } -+ -+ ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx); -+ if (ret) { -+ pr_err("clk_get_by_name(tx) failed: %d", ret); -+ 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); -+ -+ debug("%s: OK\n", __func__); -+ return 0; -+ -+err_free_clk_rx: -+ clk_free(&eqos->clk_rx); -+err_free_clk_master_bus: -+ clk_free(&eqos->clk_master_bus); -+err_probe: -+ -+ debug("%s: returns %d\n", __func__, ret); -+ return ret; -+} -+ -+static int eqos_get_interface_stm32(struct udevice *dev) -+{ -+ const char *phy_mode; -+ int interface = -1; -+ -+ debug("%s(dev=%p):\n", __func__, dev); -+ -+ phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode", -+ NULL); -+ if (phy_mode) -+ interface = phy_get_interface_by_name(phy_mode); -+ -+ return interface; -+} -+ -+static int eqos_get_interface_tegra186(struct udevice *dev) -+{ -+ return 0; -+} -+ - static int eqos_remove_resources_tegra186(struct udevice *dev) - { - struct eqos_priv *eqos = dev_get_priv(dev); -@@ -1442,6 +1670,22 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) - return 0; - } - -+static int eqos_remove_resources_stm32(struct udevice *dev) -+{ -+ struct eqos_priv *eqos = dev_get_priv(dev); -+ -+ debug("%s(dev=%p):\n", __func__, dev); -+ -+ clk_free(&eqos->clk_tx); -+ clk_free(&eqos->clk_rx); -+ clk_free(&eqos->clk_master_bus); -+ if (clk_valid(&eqos->clk_ck)) -+ clk_free(&eqos->clk_ck); -+ -+ debug("%s: OK\n", __func__); -+ return 0; -+} -+ - static int eqos_probe(struct udevice *dev) - { - struct eqos_priv *eqos = dev_get_priv(dev); -@@ -1468,9 +1712,9 @@ static int eqos_probe(struct udevice *dev) - return ret; - } - -- ret = eqos_probe_resources_tegra186(dev); -+ ret = eqos->config->ops->eqos_probe_resources(dev); - if (ret < 0) { -- pr_err("eqos_probe_resources_tegra186() failed: %d", ret); -+ pr_err("eqos_probe_resources() failed: %d", ret); - goto err_remove_resources_core; - } - -@@ -1490,13 +1734,38 @@ static int eqos_probe(struct udevice *dev) - goto err_free_mdio; - } - -+ // Bring up PHY -+ ret = eqos->config->ops->eqos_start_clks(dev); -+ if (ret < 0) { -+ pr_err("eqos_start_clks() failed: %d", ret); -+ goto err_free_mdio; -+ } -+ -+ eqos->phy = phy_connect(eqos->mii, 0, dev, -+ eqos->config->interface(dev)); -+ if (!eqos->phy) { -+ pr_err("phy_connect() failed"); -+ goto err_stop_resets; -+ } -+ ret = phy_config(eqos->phy); -+ if (ret < 0) { -+ pr_err("phy_config() failed: %d", ret); -+ goto err_shutdown_phy; -+ } -+ - debug("%s: OK\n", __func__); - return 0; - -+err_shutdown_phy: -+ phy_shutdown(eqos->phy); -+ eqos->phy = NULL; -+err_stop_resets: -+ eqos->config->ops->eqos_stop_resets(dev); -+ eqos->config->ops->eqos_stop_clks(dev); - err_free_mdio: - mdio_free(eqos->mii); - err_remove_resources_tegra: -- eqos_remove_resources_tegra186(dev); -+ eqos->config->ops->eqos_remove_resources(dev); - err_remove_resources_core: - eqos_remove_resources_core(dev); - -@@ -1512,7 +1781,16 @@ static int eqos_remove(struct udevice *dev) - - mdio_unregister(eqos->mii); - mdio_free(eqos->mii); -- eqos_remove_resources_tegra186(dev); -+ -+ if (eqos->phy) { -+ phy_shutdown(eqos->phy); -+ eqos->phy = NULL; -+ } -+ -+ eqos->config->ops->eqos_stop_resets(dev); -+ eqos->config->ops->eqos_stop_clks(dev); -+ eqos->config->ops->eqos_remove_resources(dev); -+ - eqos_probe_resources_core(dev); - - debug("%s: OK\n", __func__); -@@ -1528,8 +1806,56 @@ static const struct eth_ops eqos_ops = { - .write_hwaddr = eqos_write_hwaddr, - }; - -+static struct eqos_ops eqos_tegra186_ops = { -+ .eqos_inval_desc = eqos_inval_desc_tegra186, -+ .eqos_flush_desc = eqos_flush_desc_tegra186, -+ .eqos_inval_buffer = eqos_inval_buffer_tegra186, -+ .eqos_flush_buffer = eqos_flush_buffer_tegra186, -+ .eqos_probe_resources = eqos_probe_resources_tegra186, -+ .eqos_remove_resources = eqos_remove_resources_tegra186, -+ .eqos_stop_resets = eqos_stop_resets_tegra186, -+ .eqos_start_resets = eqos_start_resets_tegra186, -+ .eqos_stop_clks = eqos_stop_clks_tegra186, -+ .eqos_start_clks = eqos_start_clks_tegra186, -+ .eqos_calibrate_pads = eqos_calibrate_pads_tegra186, -+ .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 -+}; -+ - static const struct eqos_config eqos_tegra186_config = { - .reg_access_always_ok = false, -+ .mdio_wait = 10, -+ .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, -+ .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_20_35, -+ .interface = eqos_get_interface_tegra186, -+ .ops = &eqos_tegra186_ops -+}; -+ -+static struct eqos_ops eqos_stm32_ops = { -+ .eqos_inval_desc = eqos_inval_desc_stm32, -+ .eqos_flush_desc = eqos_flush_desc_stm32, -+ .eqos_inval_buffer = eqos_inval_buffer_stm32, -+ .eqos_flush_buffer = eqos_flush_buffer_stm32, -+ .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_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_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32 -+}; -+ -+static const struct eqos_config eqos_stm32_config = { -+ .reg_access_always_ok = false, -+ .mdio_wait = 10000, -+ .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV, -+ .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, -+ .interface = eqos_get_interface_stm32, -+ .ops = &eqos_stm32_ops - }; - - static const struct udevice_id eqos_ids[] = { -@@ -1537,6 +1863,11 @@ static const struct udevice_id eqos_ids[] = { - .compatible = "nvidia,tegra186-eqos", - .data = (ulong)&eqos_tegra186_config - }, -+ { -+ .compatible = "snps,dwmac-4.20a", -+ .data = (ulong)&eqos_stm32_config -+ }, -+ - { } - }; - -diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c -index 8e98b4b..22937d8 100644 ---- a/drivers/phy/phy-stm32-usbphyc.c -+++ b/drivers/phy/phy-stm32-usbphyc.c -@@ -37,7 +37,8 @@ - - #define MAX_PHYS 2 - --#define PLL_LOCK_TIME_US 100 -+/* max 100 us for PLL lock and 100 us for PHY init */ -+#define PLL_INIT_TIME_US 200 - #define PLL_PWR_DOWN_TIME_US 5 - #define PLL_FVCO 2880 /* in MHz */ - #define PLL_INFF_MIN_RATE 19200000 /* in Hz */ -@@ -51,13 +52,11 @@ struct pll_params { - struct stm32_usbphyc { - fdt_addr_t base; - struct clk clk; -+ struct udevice *vdda1v1; -+ struct udevice *vdda1v8; -+ struct udevice *vdd3v3; - struct stm32_usbphyc_phy { -- struct udevice *vdd; -- struct udevice *vdda1v1; -- struct udevice *vdda1v8; -- int index; - bool init; -- bool powered; - } phys[MAX_PHYS]; - }; - -@@ -129,18 +128,6 @@ static bool stm32_usbphyc_is_init(struct stm32_usbphyc *usbphyc) - return false; - } - --static bool stm32_usbphyc_is_powered(struct stm32_usbphyc *usbphyc) --{ -- int i; -- -- for (i = 0; i < MAX_PHYS; i++) { -- if (usbphyc->phys[i].powered) -- return true; -- } -- -- return false; --} -- - static int stm32_usbphyc_phy_init(struct phy *phy) - { - struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev); -@@ -154,6 +141,24 @@ static int stm32_usbphyc_phy_init(struct phy *phy) - if (pllen && stm32_usbphyc_is_init(usbphyc)) - goto initialized; - -+ if (usbphyc->vdda1v1) { -+ ret = regulator_set_enable(usbphyc->vdda1v1, true); -+ if (ret) -+ return ret; -+ } -+ -+ if (usbphyc->vdda1v8) { -+ ret = regulator_set_enable(usbphyc->vdda1v8, true); -+ if (ret) -+ return ret; -+ } -+ -+ if (usbphyc->vdd3v3) { -+ ret = regulator_set_enable(usbphyc->vdd3v3, true); -+ if (ret) -+ return ret; -+ } -+ - if (pllen) { - clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN); - udelay(PLL_PWR_DOWN_TIME_US); -@@ -165,11 +170,8 @@ static int stm32_usbphyc_phy_init(struct phy *phy) - - setbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN); - -- /* -- * We must wait PLL_LOCK_TIME_US before checking that PLLEN -- * bit is still set -- */ -- udelay(PLL_LOCK_TIME_US); -+ /* We must wait PLL_INIT_TIME_US before using PHY */ -+ udelay(PLL_INIT_TIME_US); - - if (!(readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN)) - return -EIO; -@@ -184,6 +186,7 @@ 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; - - pr_debug("%s phy ID = %lu\n", __func__, phy->id); - usbphyc_phy->init = false; -@@ -202,65 +205,20 @@ static int stm32_usbphyc_phy_exit(struct phy *phy) - - if (readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN) - return -EIO; -- -- return 0; --} -- --static int stm32_usbphyc_phy_power_on(struct phy *phy) --{ -- struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev); -- struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id; -- int ret; -- -- pr_debug("%s phy ID = %lu\n", __func__, phy->id); -- if (usbphyc_phy->vdda1v1) { -- ret = regulator_set_enable(usbphyc_phy->vdda1v1, true); -- if (ret) -- return ret; -- } -- -- if (usbphyc_phy->vdda1v8) { -- ret = regulator_set_enable(usbphyc_phy->vdda1v8, true); -- if (ret) -- return ret; -- } -- if (usbphyc_phy->vdd) { -- ret = regulator_set_enable(usbphyc_phy->vdd, true); -- if (ret) -- return ret; -- } -- -- usbphyc_phy->powered = true; -- -- return 0; --} -- --static int stm32_usbphyc_phy_power_off(struct phy *phy) --{ -- struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev); -- struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id; -- int ret; -- -- pr_debug("%s phy ID = %lu\n", __func__, phy->id); -- usbphyc_phy->powered = false; -- -- if (stm32_usbphyc_is_powered(usbphyc)) -- return 0; -- -- if (usbphyc_phy->vdda1v1) { -- ret = regulator_set_enable(usbphyc_phy->vdda1v1, false); -+ if (usbphyc->vdda1v1) { -+ ret = regulator_set_enable(usbphyc->vdda1v1, false); - if (ret) - return ret; - } - -- if (usbphyc_phy->vdda1v8) { -- ret = regulator_set_enable(usbphyc_phy->vdda1v8, false); -+ if (usbphyc->vdda1v8) { -+ ret = regulator_set_enable(usbphyc->vdda1v8, false); - if (ret) - return ret; - } - -- if (usbphyc_phy->vdd) { -- ret = regulator_set_enable(usbphyc_phy->vdd, false); -+ if (usbphyc->vdd3v3) { -+ ret = regulator_set_enable(usbphyc->vdd3v3, false); - if (ret) - return ret; - } -@@ -268,49 +226,23 @@ static int stm32_usbphyc_phy_power_off(struct phy *phy) - return 0; - } - --static int stm32_usbphyc_get_regulator(struct udevice *dev, ofnode node, -- char *supply_name, -- struct udevice **regulator) --{ -- struct ofnode_phandle_args regulator_phandle; -- int ret; -- -- 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); -- 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); -- return ret; -- } -- -- return 0; --} -- - static int stm32_usbphyc_of_xlate(struct phy *phy, - struct ofnode_phandle_args *args) - { -- if (args->args_count > 1) { -- pr_debug("%s: invalid args_count: %d\n", __func__, -- args->args_count); -- return -EINVAL; -- } -+ if (args->args_count < 1) -+ return -ENODEV; - - if (args->args[0] >= MAX_PHYS) - return -ENODEV; - -- if (args->args_count) -- phy->id = args->args[0]; -- else -- phy->id = 0; -+ phy->id = args->args[0]; -+ -+ if ((phy->id == 0 && args->args_count != 1) || -+ (phy->id == 1 && args->args_count != 2)) { -+ dev_err(dev, "invalid number of cells for phy port%ld\n", -+ phy->id); -+ return -EINVAL; -+ } - - return 0; - } -@@ -318,8 +250,6 @@ static int stm32_usbphyc_of_xlate(struct phy *phy, - static const struct phy_ops stm32_usbphyc_phy_ops = { - .init = stm32_usbphyc_phy_init, - .exit = stm32_usbphyc_phy_exit, -- .power_on = stm32_usbphyc_phy_power_on, -- .power_off = stm32_usbphyc_phy_power_off, - .of_xlate = stm32_usbphyc_of_xlate, - }; - -@@ -327,7 +257,6 @@ 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; - - usbphyc->base = dev_read_addr(dev); -@@ -351,35 +280,31 @@ static int stm32_usbphyc_probe(struct udevice *dev) - reset_deassert(&reset); - } - -- /* -- * 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; -- -- usbphyc_phy->index = i; -- usbphyc_phy->init = false; -- usbphyc_phy->powered = false; -- ret = stm32_usbphyc_get_regulator(dev, node, "phy-supply", -- &usbphyc_phy->vdd); -- if (ret) -- return ret; -- -- ret = stm32_usbphyc_get_regulator(dev, node, "vdda1v1-supply", -- &usbphyc_phy->vdda1v1); -- if (ret) -- return ret; -+ /* get usbphyc regulator */ -+ ret = device_get_supply_regulator(dev, "vdda1v1-supply", -+ &usbphyc->vdda1v1); -+ if (ret) { -+ dev_err(dev, "Can't get vdda1v1-supply regulator\n"); -+ return ret; -+ } - -- ret = stm32_usbphyc_get_regulator(dev, node, "vdda1v8-supply", -- &usbphyc_phy->vdda1v8); -- if (ret) -- return ret; -+ ret = device_get_supply_regulator(dev, "vdda1v8-supply", -+ &usbphyc->vdda1v8); -+ if (ret) { -+ dev_err(dev, "Can't get vdda1v8-supply regulator\n"); -+ return ret; -+ } - -- node = dev_read_next_subnode(node); -+ ret = device_get_supply_regulator(dev, "vdd3v3-supply", -+ &usbphyc->vdd3v3); -+ if (ret) { -+ dev_err(dev, "Can't get vdd3v3-supply regulator\n"); -+ return ret; - } - -+ for (i = 0; i < MAX_PHYS; i++) -+ usbphyc->phys[i].init = false; -+ - /* Check if second port has to be used for host controller */ - if (dev_read_bool(dev, "st,port2-switch-to-host")) - setbits_le32(usbphyc->base + STM32_USBPHYC_MISC, SWITHOST); -diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig -index ad0b8da..546613d 100644 ---- a/drivers/pinctrl/Kconfig -+++ b/drivers/pinctrl/Kconfig -@@ -289,6 +289,25 @@ config PINCTRL_STM32 - the GPIO definitions and pin control functions for each available - multiplex function. - -+config PINCTRL_STMFX -+ bool "STMicroelectronics STMFX I2C GPIO expander pinctrl driver" -+ depends on DM && PINCTRL_FULL -+ help -+ I2C driver for STMicroelectronics Multi-Function eXpander (STMFX) -+ GPIO expander. -+ Supports pin multiplexing control on stm32 SoCs. -+ -+ 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 SPL_PINCTRL_STMFX -+ bool "STMicroelectronics STMFX I2C GPIO expander pinctrl driver in SPL" -+ depends on SPL_PINCTRL_FULL -+ help -+ This option is an SPL-variant of the SPL_PINCTRL_STMFX option. -+ See the help of PINCTRL_STMFX for details. -+ - config ASPEED_AST2500_PINCTRL - bool "Aspeed AST2500 pin control driver" - depends on DM && PINCTRL_GENERIC && ASPEED_AST2500 -diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile -index a3a6c6d..d2725f6 100644 ---- a/drivers/pinctrl/Makefile -+++ b/drivers/pinctrl/Makefile -@@ -20,4 +20,5 @@ obj-$(CONFIG_ARCH_MVEBU) += mvebu/ - obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o - obj-$(CONFIG_PINCTRL_STI) += pinctrl-sti.o - obj-$(CONFIG_PINCTRL_STM32) += pinctrl_stm32.o -+obj-$(CONFIG_$(SPL_)PINCTRL_STMFX) += pinctrl-stmfx.o - obj-y += broadcom/ -diff --git a/drivers/pinctrl/pinctrl-sandbox.c b/drivers/pinctrl/pinctrl-sandbox.c -index 755ac08..0786afe 100644 ---- a/drivers/pinctrl/pinctrl-sandbox.c -+++ b/drivers/pinctrl/pinctrl-sandbox.c -@@ -17,6 +17,14 @@ static const char * const sandbox_pins[] = { - "W1" - }; - -+static const char * const sandbox_pins_muxing[] = { -+ "I2C SCL", -+ "I2C SDA", -+ "Uart TX", -+ "Uart RX", -+ "1-wire gpio", -+}; -+ - static const char * const sandbox_groups[] = { - "i2c", - "serial_a", -@@ -56,6 +64,15 @@ static const char *sandbox_get_pin_name(struct udevice *dev, unsigned selector) - return sandbox_pins[selector]; - } - -+static int sandbox_get_pin_muxing(struct udevice *dev, -+ unsigned int selector, -+ char *buf, int size) -+{ -+ snprintf(buf, size, "%s", sandbox_pins_muxing[selector]); -+ -+ return 0; -+} -+ - static int sandbox_get_groups_count(struct udevice *dev) - { - return ARRAY_SIZE(sandbox_groups); -@@ -123,6 +140,7 @@ static int sandbox_pinconf_group_set(struct udevice *dev, - const struct pinctrl_ops sandbox_pinctrl_ops = { - .get_pins_count = sandbox_get_pins_count, - .get_pin_name = sandbox_get_pin_name, -+ .get_pin_muxing = sandbox_get_pin_muxing, - .get_groups_count = sandbox_get_groups_count, - .get_group_name = sandbox_get_group_name, - .get_functions_count = sandbox_get_functions_count, -diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c -new file mode 100644 -index 0000000..9b5009a ---- /dev/null -+++ b/drivers/pinctrl/pinctrl-stmfx.c -@@ -0,0 +1,414 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ * -+ * Driver for STMicroelectronics Multi-Function eXpander (STMFX) GPIO expander -+ * based on Linux driver : pinctrl/pinctrl-stmfx.c -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* STMFX pins = GPIO[15:0] + aGPIO[7:0] */ -+#define STMFX_MAX_GPIO 16 -+#define STMFX_MAX_AGPIO 8 -+ -+/* General */ -+#define STMFX_REG_CHIP_ID 0x00 /* R */ -+#define STMFX_REG_FW_VERSION_MSB 0x01 /* R */ -+#define STMFX_REG_FW_VERSION_LSB 0x02 /* R */ -+#define STMFX_REG_SYS_CTRL 0x40 /* RW */ -+ -+/* MFX boot time is around 10ms, so after reset, we have to wait this delay */ -+#define STMFX_BOOT_TIME_MS 10 -+ -+/* GPIOs expander */ -+/* GPIO_STATE1 0x10, GPIO_STATE2 0x11, GPIO_STATE3 0x12 */ -+#define STMFX_REG_GPIO_STATE 0x10 /* R */ -+/* GPIO_DIR1 0x60, GPIO_DIR2 0x61, GPIO_DIR3 0x63 */ -+#define STMFX_REG_GPIO_DIR 0x60 /* RW */ -+/* GPIO_TYPE1 0x64, GPIO_TYPE2 0x65, GPIO_TYPE3 0x66 */ -+#define STMFX_REG_GPIO_TYPE 0x64 /* RW */ -+/* GPIO_PUPD1 0x68, GPIO_PUPD2 0x69, GPIO_PUPD3 0x6A */ -+#define STMFX_REG_GPIO_PUPD 0x68 /* RW */ -+/* GPO_SET1 0x6C, GPO_SET2 0x6D, GPO_SET3 0x6E */ -+#define STMFX_REG_GPO_SET 0x6C /* RW */ -+/* GPO_CLR1 0x70, GPO_CLR2 0x71, GPO_CLR3 0x72 */ -+#define STMFX_REG_GPO_CLR 0x70 /* RW */ -+ -+/* STMFX_REG_CHIP_ID bitfields */ -+#define STMFX_REG_CHIP_ID_MASK GENMASK(7, 0) -+ -+/* STMFX_REG_SYS_CTRL bitfields */ -+#define STMFX_REG_SYS_CTRL_GPIO_EN BIT(0) -+#define STMFX_REG_SYS_CTRL_ALTGPIO_EN BIT(3) -+#define STMFX_REG_SYS_CTRL_SWRST BIT(7) -+ -+#define NR_GPIO_REGS 3 -+#define NR_GPIOS_PER_REG 8 -+#define get_reg(offset) ((offset) / NR_GPIOS_PER_REG) -+#define get_shift(offset) ((offset) % NR_GPIOS_PER_REG) -+#define get_mask(offset) (BIT(get_shift(offset))) -+ -+struct stmfx_pinctrl { -+ struct udevice *gpio; -+}; -+ -+static int stmfx_read(struct udevice *dev, uint offset) -+{ -+ return dm_i2c_reg_read(dev_get_parent(dev), offset); -+} -+ -+static int stmfx_write(struct udevice *dev, uint offset, unsigned int val) -+{ -+ return dm_i2c_reg_write(dev_get_parent(dev), offset, val); -+} -+ -+static int stmfx_gpio_get(struct udevice *dev, unsigned int offset) -+{ -+ u32 reg = STMFX_REG_GPIO_STATE + get_reg(offset); -+ u32 mask = get_mask(offset); -+ int ret; -+ -+ ret = stmfx_read(dev, reg); -+ -+ return ret < 0 ? ret : !!(ret & mask); -+} -+ -+static int stmfx_gpio_set(struct udevice *dev, unsigned int offset, int value) -+{ -+ u32 reg = value ? STMFX_REG_GPO_SET : STMFX_REG_GPO_CLR; -+ u32 mask = get_mask(offset); -+ -+ return stmfx_write(dev, reg + get_reg(offset), mask); -+} -+ -+static int stmfx_gpio_get_function(struct udevice *dev, unsigned int offset) -+{ -+ u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset); -+ u32 mask = get_mask(offset); -+ int ret; -+ -+ ret = stmfx_read(dev, reg); -+ -+ if (ret < 0) -+ return ret; -+ /* On stmfx, gpio pins direction is (0)input, (1)output. */ -+ -+ return ret & mask ? GPIOF_OUTPUT : GPIOF_INPUT; -+} -+ -+static int stmfx_gpio_direction_input(struct udevice *dev, unsigned int offset) -+{ -+ u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset); -+ u32 mask = get_mask(offset); -+ int ret; -+ -+ ret = stmfx_read(dev, reg); -+ if (ret < 0) -+ return ret; -+ -+ ret &= ~mask; -+ -+ return stmfx_write(dev, reg, ret & ~mask); -+} -+ -+static int stmfx_gpio_direction_output(struct udevice *dev, -+ unsigned int offset, int value) -+{ -+ u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset); -+ u32 mask = get_mask(offset); -+ int ret; -+ -+ ret = stmfx_gpio_set(dev, offset, value); -+ if (ret < 0) -+ return ret; -+ -+ ret = stmfx_read(dev, reg); -+ if (ret < 0) -+ return ret; -+ -+ return stmfx_write(dev, reg, ret | mask); -+} -+ -+static int stmfx_gpio_probe(struct udevice *dev) -+{ -+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); -+ struct ofnode_phandle_args args; -+ u8 sys_ctrl; -+ -+ uc_priv->bank_name = "stmfx"; -+ uc_priv->gpio_count = STMFX_MAX_GPIO + STMFX_MAX_AGPIO; -+ if (!dev_read_phandle_with_args(dev, "gpio-ranges", -+ NULL, 3, 0, &args)) { -+ uc_priv->gpio_count = args.args[2]; -+ } -+ -+ /* enable GPIO function */ -+ sys_ctrl = STMFX_REG_SYS_CTRL_GPIO_EN; -+ if (uc_priv->gpio_count > STMFX_MAX_GPIO) -+ sys_ctrl |= STMFX_REG_SYS_CTRL_ALTGPIO_EN; -+ stmfx_write(dev, STMFX_REG_SYS_CTRL, sys_ctrl); -+ -+ return 0; -+} -+ -+static const struct dm_gpio_ops stmfx_gpio_ops = { -+ .set_value = stmfx_gpio_set, -+ .get_value = stmfx_gpio_get, -+ .get_function = stmfx_gpio_get_function, -+ .direction_input = stmfx_gpio_direction_input, -+ .direction_output = stmfx_gpio_direction_output, -+}; -+ -+U_BOOT_DRIVER(stmfx_gpio) = { -+ .name = "stmfx-gpio", -+ .id = UCLASS_GPIO, -+ .probe = stmfx_gpio_probe, -+ .ops = &stmfx_gpio_ops, -+}; -+ -+#if CONFIG_IS_ENABLED(PINCONF) -+static const struct pinconf_param stmfx_pinctrl_conf_params[] = { -+ { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, -+ { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 0 }, -+ { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 0 }, -+ { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 0 }, -+ { "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 }, -+ { "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 }, -+ { "output-high", PIN_CONFIG_OUTPUT, 1 }, -+ { "output-low", PIN_CONFIG_OUTPUT, 0 }, -+}; -+ -+static int stmfx_pinctrl_set_pupd(struct udevice *dev, -+ unsigned int pin, u32 pupd) -+{ -+ u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin); -+ u32 mask = get_mask(pin); -+ int ret; -+ -+ ret = stmfx_read(dev, reg); -+ if (ret < 0) -+ return ret; -+ ret = (ret & ~mask) | (pupd ? mask : 0); -+ -+ return stmfx_write(dev, reg, ret); -+} -+ -+static int stmfx_pinctrl_set_type(struct udevice *dev, -+ unsigned int pin, u32 type) -+{ -+ u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin); -+ u32 mask = get_mask(pin); -+ int ret; -+ -+ ret = stmfx_read(dev, reg); -+ if (ret < 0) -+ return ret; -+ ret = (ret & ~mask) | (type ? mask : 0); -+ -+ return stmfx_write(dev, reg, ret); -+} -+ -+static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin, -+ unsigned int param, unsigned int arg) -+{ -+ int ret, dir; -+ struct stmfx_pinctrl *plat = dev_get_platdata(dev); -+ -+ dir = stmfx_gpio_get_function(plat->gpio, pin); -+ -+ if (dir < 0) -+ return dir; -+ -+ switch (param) { -+ case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: -+ case PIN_CONFIG_BIAS_DISABLE: -+ case PIN_CONFIG_BIAS_PULL_DOWN: -+ ret = stmfx_pinctrl_set_pupd(dev, pin, 0); -+ break; -+ case PIN_CONFIG_BIAS_PULL_UP: -+ ret = stmfx_pinctrl_set_pupd(dev, pin, 1); -+ break; -+ case PIN_CONFIG_DRIVE_OPEN_DRAIN: -+ if (dir == GPIOF_OUTPUT) -+ ret = stmfx_pinctrl_set_type(dev, pin, 1); -+ else -+ ret = stmfx_pinctrl_set_type(dev, pin, 0); -+ break; -+ case PIN_CONFIG_DRIVE_PUSH_PULL: -+ if (dir == GPIOF_OUTPUT) -+ ret = stmfx_pinctrl_set_type(dev, pin, 0); -+ else -+ ret = stmfx_pinctrl_set_type(dev, pin, 1); -+ break; -+ case PIN_CONFIG_OUTPUT: -+ ret = stmfx_gpio_direction_output(plat->gpio, pin, arg); -+ break; -+ default: -+ return -ENOTSUPP; -+ } -+ -+ return ret; -+} -+#endif -+ -+static int stmfx_pinctrl_get_pins_count(struct udevice *dev) -+{ -+ struct stmfx_pinctrl *plat = dev_get_platdata(dev); -+ struct gpio_dev_priv *uc_priv; -+ -+ uc_priv = dev_get_uclass_priv(plat->gpio); -+ -+ return uc_priv->gpio_count; -+} -+ -+/* -+ * 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 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); -+ else -+ snprintf(pin_name, MAX_PIN_NAME_LEN, "agpio%u", selector - 16); -+ return pin_name; -+} -+ -+static int stmfx_pinctrl_bind(struct udevice *dev) -+{ -+ struct stmfx_pinctrl *plat = dev_get_platdata(dev); -+ -+ return device_bind_driver_to_node(dev->parent, -+ "stmfx-gpio", "stmfx-gpio", -+ dev_ofnode(dev), &plat->gpio); -+}; -+ -+static int stmfx_pinctrl_probe(struct udevice *dev) -+{ -+ struct stmfx_pinctrl *plat = dev_get_platdata(dev); -+ -+ return device_probe(plat->gpio); -+}; -+ -+const struct pinctrl_ops stmfx_pinctrl_ops = { -+ .get_pins_count = stmfx_pinctrl_get_pins_count, -+ .get_pin_name = stmfx_pinctrl_get_pin_name, -+ .set_state = pinctrl_generic_set_state, -+#if CONFIG_IS_ENABLED(PINCONF) -+ .pinconf_set = stmfx_pinctrl_conf_set, -+ .pinconf_num_params = ARRAY_SIZE(stmfx_pinctrl_conf_params), -+ .pinconf_params = stmfx_pinctrl_conf_params, -+#endif -+}; -+ -+static const struct udevice_id stmfx_pinctrl_match[] = { -+ { .compatible = "st,stmfx-0300-pinctrl", }, -+}; -+ -+U_BOOT_DRIVER(stmfx_pinctrl) = { -+ .name = "stmfx-pinctrl", -+ .id = UCLASS_PINCTRL, -+ .of_match = of_match_ptr(stmfx_pinctrl_match), -+ .bind = stmfx_pinctrl_bind, -+ .probe = stmfx_pinctrl_probe, -+ .ops = &stmfx_pinctrl_ops, -+ .platdata_auto_alloc_size = sizeof(struct stmfx_pinctrl), -+}; -+ -+static int stmfx_chip_init(struct udevice *dev) -+{ -+ u8 id; -+ u8 version[2]; -+ int ret; -+ struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); -+ -+ id = dm_i2c_reg_read(dev, STMFX_REG_CHIP_ID); -+ if (id < 0) { -+ dev_err(dev, "error reading chip id: %d\n", id); -+ return ret; -+ } -+ /* -+ * Check that ID is the complement of the I2C address: -+ * STMFX I2C address follows the 7-bit format (MSB), that's why -+ * client->addr is shifted. -+ * -+ * STMFX_I2C_ADDR| STMFX | Linux -+ * input pin | I2C device address | I2C device address -+ *--------------------------------------------------------- -+ * 0 | b: 1000 010x h:0x84 | 0x42 -+ * 1 | b: 1000 011x h:0x86 | 0x43 -+ */ -+ if (FIELD_GET(STMFX_REG_CHIP_ID_MASK, ~id) != (chip->chip_addr << 1)) { -+ dev_err(dev, "unknown chip id: %#x\n", id); -+ return -EINVAL; -+ } -+ -+ ret = dm_i2c_read(dev, STMFX_REG_FW_VERSION_MSB, -+ version, sizeof(version)); -+ if (ret) { -+ dev_err(dev, "error reading fw version: %d\n", ret); -+ return ret; -+ } -+ -+ dev_info(dev, "STMFX id: %#x, fw version: %x.%02x\n", -+ id, version[0], version[1]); -+ -+ ret = dm_i2c_reg_read(dev, STMFX_REG_SYS_CTRL); -+ -+ if (ret < 0) -+ return ret; -+ -+ ret = dm_i2c_reg_write(dev, STMFX_REG_SYS_CTRL, -+ ret | STMFX_REG_SYS_CTRL_SWRST); -+ if (ret) -+ return ret; -+ -+ mdelay(STMFX_BOOT_TIME_MS); -+ -+ return ret; -+} -+ -+static int stmfx_probe(struct udevice *dev) -+{ -+ struct udevice *vdd; -+ int ret; -+ -+ 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; -+ } -+ } -+ -+ return stmfx_chip_init(dev); -+} -+ -+static const struct udevice_id stmfx_match[] = { -+ { .compatible = "st,stmfx-0300", }, -+}; -+ -+U_BOOT_DRIVER(stmfx) = { -+ .name = "stmfx", -+ .id = UCLASS_I2C_GENERIC, -+ .of_match = of_match_ptr(stmfx_match), -+ .probe = stmfx_probe, -+ .bind = dm_scan_fdt_dev, -+}; -diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c -index c38bb21..3608f10 100644 ---- a/drivers/pinctrl/pinctrl-uclass.c -+++ b/drivers/pinctrl/pinctrl-uclass.c -@@ -127,6 +127,9 @@ static int pinconfig_post_bind(struct udevice *dev) - ofnode_get_property(node, "compatible", &ret); - if (ret >= 0) - continue; -+ /* If this node has "gpio-controller" property, skip */ -+ if (ofnode_read_bool(node, "gpio-controller")) -+ continue; - - if (ret != -FDT_ERR_NOTFOUND) - return ret; -@@ -183,7 +186,7 @@ static int pinctrl_select_state_simple(struct udevice *dev) - * is the correct one. This is most likely OK as there is - * usually only one pinctrl device on the system. - */ -- ret = uclass_get_device(UCLASS_PINCTRL, 0, &pctldev); -+ ret = uclass_get_device_by_seq(UCLASS_PINCTRL, 0, &pctldev); - if (ret) - return ret; - -@@ -249,6 +252,40 @@ int pinctrl_get_gpio_mux(struct udevice *dev, int banknum, int index) - return ops->get_gpio_mux(dev, banknum, index); - } - -+int pinctrl_get_pins_count(struct udevice *dev) -+{ -+ struct pinctrl_ops *ops = pinctrl_get_ops(dev); -+ -+ if (!ops->get_pins_count) -+ return -ENOSYS; -+ -+ return ops->get_pins_count(dev); -+} -+ -+int pinctrl_get_pin_name(struct udevice *dev, int selector, char *buf, -+ int size) -+{ -+ struct pinctrl_ops *ops = pinctrl_get_ops(dev); -+ -+ if (!ops->get_pin_name) -+ return -ENOSYS; -+ -+ snprintf(buf, size, ops->get_pin_name(dev, selector)); -+ -+ return 0; -+} -+ -+int pinctrl_get_pin_muxing(struct udevice *dev, int selector, char *buf, -+ int size) -+{ -+ struct pinctrl_ops *ops = pinctrl_get_ops(dev); -+ -+ if (!ops->get_pin_muxing) -+ return -ENOSYS; -+ -+ return ops->get_pin_muxing(dev, selector, buf, size); -+} -+ - /** - * pinconfig_post_bind() - post binding for PINCTRL uclass - * Recursively bind child nodes as pinconfig devices in case of full pinctrl. -diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c -index 31285cd..eb7799d 100644 ---- a/drivers/pinctrl/pinctrl_stm32.c -+++ b/drivers/pinctrl/pinctrl_stm32.c -@@ -1,9 +1,10 @@ - #include - #include --#include -+#include - #include - #include - #include -+#include - - DECLARE_GLOBAL_DATA_PTR; - -@@ -14,17 +15,241 @@ DECLARE_GLOBAL_DATA_PTR; - #define OTYPE_MSK 1 - #define AFR_MASK 0xF - -+struct stm32_pinctrl_priv { -+ struct hwspinlock hws; -+ int pinctrl_ngpios; -+ struct list_head gpio_dev; -+}; -+ -+#ifndef CONFIG_SPL_BUILD -+struct stm32_gpio_bank { -+ struct udevice *gpio_dev; -+ struct list_head list; -+}; -+ -+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 int stm32_pinctrl_get_af(struct udevice *dev, unsigned int offset) -+{ -+ struct stm32_gpio_priv *priv = dev_get_priv(dev); -+ struct stm32_gpio_regs *regs = priv->regs; -+ u32 af; -+ u32 alt_shift = (offset % 8) * 4; -+ u32 alt_index = offset / 8; -+ -+ af = (readl(®s->afr[alt_index]) & -+ GENMASK(alt_shift + 3, alt_shift)) >> alt_shift; -+ -+ return af; -+} -+ -+static int stm32_populate_gpio_dev_list(struct udevice *dev) -+{ -+ struct stm32_pinctrl_priv *priv = dev_get_priv(dev); -+ struct udevice *gpio_dev; -+ struct udevice *child; -+ struct stm32_gpio_bank *gpio_bank; -+ int ret; -+ -+ /* -+ * parse pin-controller sub-nodes (ie gpio bank nodes) and fill -+ * a list with all gpio device reference which belongs to the -+ * current pin-controller. This list is used to find pin_name and -+ * pin muxing -+ */ -+ list_for_each_entry(child, &dev->child_head, sibling_node) { -+ ret = uclass_get_device_by_name(UCLASS_GPIO, child->name, -+ &gpio_dev); -+ if (ret < 0) -+ continue; -+ -+ gpio_bank = malloc(sizeof(*gpio_bank)); -+ if (!gpio_bank) { -+ dev_err(dev, "Not enough memory\n"); -+ return -ENOMEM; -+ } -+ -+ gpio_bank->gpio_dev = gpio_dev; -+ list_add_tail(&gpio_bank->list, &priv->gpio_dev); -+ } -+ -+ return 0; -+} -+ -+static int stm32_pinctrl_get_pins_count(struct udevice *dev) -+{ -+ struct stm32_pinctrl_priv *priv = dev_get_priv(dev); -+ struct gpio_dev_priv *uc_priv; -+ struct stm32_gpio_bank *gpio_bank; -+ -+ /* -+ * if get_pins_count has already been executed once on this -+ * pin-controller, no need to run it again -+ */ -+ if (priv->pinctrl_ngpios) -+ return priv->pinctrl_ngpios; -+ -+ if (list_empty(&priv->gpio_dev)) -+ stm32_populate_gpio_dev_list(dev); -+ /* -+ * walk through all banks to retrieve the pin-controller -+ * pins number -+ */ -+ list_for_each_entry(gpio_bank, &priv->gpio_dev, list) { -+ uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev); -+ -+ priv->pinctrl_ngpios += uc_priv->gpio_count; -+ } -+ -+ return priv->pinctrl_ngpios; -+} -+ -+static struct udevice *stm32_pinctrl_get_gpio_dev(struct udevice *dev, -+ unsigned int selector, -+ unsigned int *idx) -+{ -+ struct stm32_pinctrl_priv *priv = dev_get_priv(dev); -+ struct stm32_gpio_bank *gpio_bank; -+ struct gpio_dev_priv *uc_priv; -+ int pin_count = 0; -+ -+ if (list_empty(&priv->gpio_dev)) -+ stm32_populate_gpio_dev_list(dev); -+ -+ /* look up for the bank which owns the requested pin */ -+ list_for_each_entry(gpio_bank, &priv->gpio_dev, list) { -+ uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev); -+ -+ if (selector < (pin_count + uc_priv->gpio_count)) { -+ /* -+ * we found the bank, convert pin selector to -+ * gpio bank index -+ */ -+ *idx = stm32_offset_to_index(gpio_bank->gpio_dev, -+ selector - pin_count); -+ if (*idx < 0) -+ return NULL; -+ -+ return gpio_bank->gpio_dev; -+ } -+ pin_count += uc_priv->gpio_count; -+ } -+ -+ return NULL; -+} -+ -+static const char *stm32_pinctrl_get_pin_name(struct udevice *dev, -+ unsigned int selector) -+{ -+ struct gpio_dev_priv *uc_priv; -+ struct udevice *gpio_dev; -+ unsigned int gpio_idx; -+ -+ /* look up for the bank which owns the requested pin */ -+ gpio_dev = stm32_pinctrl_get_gpio_dev(dev, selector, &gpio_idx); -+ if (!gpio_dev) { -+ snprintf(pin_name, PINNAME_SIZE, "Error"); -+ } else { -+ uc_priv = dev_get_uclass_priv(gpio_dev); -+ -+ snprintf(pin_name, PINNAME_SIZE, "%s%d", -+ uc_priv->bank_name, -+ gpio_idx); -+ } -+ -+ return pin_name; -+} -+ -+static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, -+ unsigned int selector, -+ char *buf, -+ int size) -+{ -+ struct udevice *gpio_dev; -+ const char *label; -+ int mode; -+ int af_num; -+ unsigned int gpio_idx; -+ -+ /* look up for the bank which owns the requested pin */ -+ gpio_dev = stm32_pinctrl_get_gpio_dev(dev, selector, &gpio_idx); -+ -+ if (!gpio_dev) -+ return -ENODEV; -+ -+ 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); -+ -+ -+ switch (mode) { -+ case GPIOF_UNKNOWN: -+ /* should never happen */ -+ return -EINVAL; -+ case GPIOF_UNUSED: -+ snprintf(buf, size, "%s", pinmux_mode[mode]); -+ break; -+ case GPIOF_FUNC: -+ af_num = stm32_pinctrl_get_af(gpio_dev, gpio_idx); -+ snprintf(buf, size, "%s %d", pinmux_mode[mode], af_num); -+ break; -+ case GPIOF_OUTPUT: -+ case GPIOF_INPUT: -+ snprintf(buf, size, "%s %s", -+ pinmux_mode[mode], label ? label : ""); -+ break; -+ } -+ -+ return 0; -+} -+#endif -+ -+int stm32_pinctrl_probe(struct udevice *dev) -+{ -+ struct stm32_pinctrl_priv *priv = dev_get_priv(dev); -+ int err; -+ -+ /* hwspinlock property is optional, just log the error */ -+ err = hwspinlock_get_by_index(dev, 0, &priv->hws); -+ if (err) -+ debug("%s: hwspinlock_get_by_index may have failed (%d)\n", -+ __func__, err); -+ -+ INIT_LIST_HEAD(&priv->gpio_dev); -+ -+ return 0; -+} -+ - 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 stm32_gpio_regs *regs = priv->regs; -+ struct stm32_pinctrl_priv *pinctrl_priv; -+ int ret; - u32 index; - - if (!ctl || ctl->af > 15 || ctl->mode > 3 || ctl->otype > 1 || - ctl->pupd > 2 || ctl->speed > 3) - return -EINVAL; - -+ pinctrl_priv = dev_get_priv(dev_get_parent(desc->dev)); -+ -+ ret = hwspinlock_lock_timeout(&pinctrl_priv->hws, 10); -+ if (ret == -ETIME) { -+ dev_err(desc->dev, "HWSpinlock timeout\n"); -+ return ret; -+ } -+ - index = (desc->offset & 0x07) * 4; - clrsetbits_le32(®s->afr[desc->offset >> 3], AFR_MASK << index, - ctl->af << index); -@@ -39,6 +264,8 @@ static int stm32_gpio_config(struct gpio_desc *desc, - index = desc->offset; - clrsetbits_le32(®s->otyper, OTYPE_MSK << index, ctl->otype << index); - -+ hwspinlock_unlock(&pinctrl_priv->hws); -+ - return 0; - } - -@@ -100,9 +327,9 @@ static int stm32_pinctrl_config(int offset) - int rv, len; - - /* -- * check for "pinmux" property in each subnode (e.g. pins1 and pins2 for -- * usart1) of pin controller phandle "pinctrl-0" -- * */ -+ * check for "pinmux" property in each subnode of pin controller -+ * phandle "pinctrl-0" (e.g. pins1 and pins2 for usart1) -+ */ - fdt_for_each_subnode(offset, gd->fdt_blob, offset) { - struct stm32_gpio_dsc gpio_dsc; - struct stm32_gpio_ctl gpio_ctl; -@@ -182,6 +409,11 @@ static struct pinctrl_ops stm32_pinctrl_ops = { - #else /* PINCTRL_FULL */ - .set_state_simple = stm32_pinctrl_set_state_simple, - #endif /* PINCTRL_FULL */ -+#ifndef CONFIG_SPL_BUILD -+ .get_pin_name = stm32_pinctrl_get_pin_name, -+ .get_pins_count = stm32_pinctrl_get_pins_count, -+ .get_pin_muxing = stm32_pinctrl_get_pin_muxing, -+#endif - }; - - static const struct udevice_id stm32_pinctrl_ids[] = { -@@ -195,9 +427,11 @@ static const struct udevice_id stm32_pinctrl_ids[] = { - }; - - U_BOOT_DRIVER(pinctrl_stm32) = { -- .name = "pinctrl_stm32", -- .id = UCLASS_PINCTRL, -- .of_match = stm32_pinctrl_ids, -- .ops = &stm32_pinctrl_ops, -- .bind = dm_scan_fdt_dev, -+ .name = "pinctrl_stm32", -+ .id = UCLASS_PINCTRL, -+ .of_match = stm32_pinctrl_ids, -+ .ops = &stm32_pinctrl_ops, -+ .bind = dm_scan_fdt_dev, -+ .probe = stm32_pinctrl_probe, -+ .priv_auto_alloc_size = sizeof(struct stm32_pinctrl_priv), - }; -diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig -index cba48e1..6b8f5b4 100644 ---- a/drivers/power/pmic/Kconfig -+++ b/drivers/power/pmic/Kconfig -@@ -217,10 +217,10 @@ config DM_PMIC_TPS65910 - DC-DC converter, 8 LDOs and a RTC. This driver binds the SMPS and LDO - pmic children. - --config PMIC_STPMU1 -- bool "Enable support for STMicroelectronics STPMU1 PMIC" -+config PMIC_STPMIC1 -+ bool "Enable support for STMicroelectronics STPMIC1 PMIC" - depends on DM_PMIC && DM_I2C - ---help--- -- The STPMU1 PMIC provides 4 BUCKs, 6 LDOs, 1 VREF and 2 power switches. -+ The STPMIC1 PMIC provides 4 BUCKs, 6 LDOs, 1 VREF and 2 power switches. - It is accessed via an I2C interface. The device is used with STM32MP1 - SoCs. This driver implements register read/write operations. -diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile -index 29ca442..4ba6bf6 100644 ---- a/drivers/power/pmic/Makefile -+++ b/drivers/power/pmic/Makefile -@@ -22,7 +22,7 @@ obj-$(CONFIG_DM_PMIC_TPS65910) += pmic_tps65910_dm.o - obj-$(CONFIG_$(SPL_)PMIC_PALMAS) += palmas.o - obj-$(CONFIG_$(SPL_)PMIC_LP873X) += lp873x.o - obj-$(CONFIG_$(SPL_)PMIC_LP87565) += lp87565.o --obj-$(CONFIG_PMIC_STPMU1) += stpmu1.o -+obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o - - obj-$(CONFIG_POWER_LTC3676) += pmic_ltc3676.o - obj-$(CONFIG_POWER_MAX77696) += pmic_max77696.o -diff --git a/drivers/power/pmic/stpmic1.c b/drivers/power/pmic/stpmic1.c -new file mode 100644 -index 0000000..18f46fc ---- /dev/null -+++ b/drivers/power/pmic/stpmic1.c -@@ -0,0 +1,258 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define STPMIC1_NUM_OF_REGS 0x100 -+ -+#if CONFIG_IS_ENABLED(DM_REGULATOR) -+#define STPMIC1_NVM_SIZE 8 -+#define STPMIC1_NVM_POLL_TIMEOUT 100000 -+#define STPMIC1_NVM_START_ADDRESS 0xf8 -+ -+enum pmic_nvm_op { -+ SHADOW_READ, -+ SHADOW_WRITE, -+ NVM_READ, -+ NVM_WRITE, -+}; -+ -+static const struct pmic_child_info stpmic1_children_info[] = { -+ { .prefix = "ldo", .driver = "stpmic1_ldo" }, -+ { .prefix = "buck", .driver = "stpmic1_buck" }, -+ { .prefix = "vref_ddr", .driver = "stpmic1_vref_ddr" }, -+ { .prefix = "pwr_sw", .driver = "stpmic1_pwr_sw" }, -+ { .prefix = "boost", .driver = "stpmic1_boost" }, -+ { }, -+}; -+#endif /* DM_REGULATOR */ -+ -+DECLARE_GLOBAL_DATA_PTR; -+ -+static int stpmic1_reg_count(struct udevice *dev) -+{ -+ return STPMIC1_NUM_OF_REGS; -+} -+ -+static int stpmic1_write(struct udevice *dev, uint reg, const uint8_t *buff, -+ int len) -+{ -+ int ret; -+ -+ ret = dm_i2c_write(dev, reg, buff, len); -+ if (ret) -+ dev_err(dev, "%s: failed to write register %#x :%d", -+ __func__, reg, ret); -+ -+ return ret; -+} -+ -+static int stpmic1_read(struct udevice *dev, uint reg, uint8_t *buff, int len) -+{ -+ int ret; -+ -+ ret = dm_i2c_read(dev, reg, buff, len); -+ if (ret) -+ dev_err(dev, "%s: failed to read register %#x : %d", -+ __func__, reg, ret); -+ -+ return ret; -+} -+ -+static int stpmic1_bind(struct udevice *dev) -+{ -+#if CONFIG_IS_ENABLED(DM_REGULATOR) -+ ofnode regulators_node; -+ int children; -+ -+ regulators_node = dev_read_subnode(dev, "regulators"); -+ if (!ofnode_valid(regulators_node)) { -+ dev_dbg(dev, "regulators subnode not found!"); -+ return -ENXIO; -+ } -+ dev_dbg(dev, "found regulators subnode\n"); -+ -+ children = pmic_bind_children(dev, regulators_node, -+ stpmic1_children_info); -+ if (!children) -+ dev_dbg(dev, "no child found\n"); -+#endif /* DM_REGULATOR */ -+ -+ if (CONFIG_IS_ENABLED(SYSRESET)) -+ return device_bind_driver(dev, "stpmic1-sysreset", -+ "stpmic1-sysreset", NULL); -+ -+ return 0; -+} -+ -+static struct dm_pmic_ops stpmic1_ops = { -+ .reg_count = stpmic1_reg_count, -+ .read = stpmic1_read, -+ .write = stpmic1_write, -+}; -+ -+static const struct udevice_id stpmic1_ids[] = { -+ { .compatible = "st,stpmic1" }, -+ { } -+}; -+ -+U_BOOT_DRIVER(pmic_stpmic1) = { -+ .name = "stpmic1_pmic", -+ .id = UCLASS_PMIC, -+ .of_match = stpmic1_ids, -+ .bind = stpmic1_bind, -+ .ops = &stpmic1_ops, -+}; -+ -+#ifndef CONFIG_SPL_BUILD -+static int stpmic1_nvm_rw(u8 addr, u8 *buf, int buf_len, enum pmic_nvm_op op) -+{ -+ struct udevice *dev; -+ unsigned long timeout; -+ u8 cmd = STPMIC1_NVM_CMD_READ; -+ int ret; -+ -+ ret = uclass_get_device_by_driver(UCLASS_PMIC, -+ DM_GET_DRIVER(pmic_stpmic1), &dev); -+ if (ret) -+ /* No PMIC on power discrete board */ -+ return -EOPNOTSUPP; -+ -+ if (addr < STPMIC1_NVM_START_ADDRESS) -+ return -EACCES; -+ -+ if (op == SHADOW_READ) -+ return pmic_read(dev, addr, buf, buf_len); -+ -+ if (op == SHADOW_WRITE) -+ return pmic_write(dev, addr, buf, buf_len); -+ -+ if (op == NVM_WRITE) { -+ cmd = STPMIC1_NVM_CMD_PROGRAM; -+ -+ ret = pmic_write(dev, addr, buf, buf_len); -+ if (ret < 0) -+ return ret; -+ } -+ -+ ret = pmic_reg_read(dev, STPMIC1_NVM_CR); -+ if (ret < 0) -+ return ret; -+ -+ ret = pmic_reg_write(dev, STPMIC1_NVM_CR, ret | cmd); -+ if (ret < 0) -+ return ret; -+ -+ timeout = timer_get_us() + STPMIC1_NVM_POLL_TIMEOUT; -+ for (;;) { -+ ret = pmic_reg_read(dev, STPMIC1_NVM_SR); -+ if (ret < 0) -+ return ret; -+ -+ if (!(ret & STPMIC1_NVM_BUSY)) -+ break; -+ -+ if (time_after(timer_get_us(), timeout)) -+ break; -+ } -+ -+ if (ret & STPMIC1_NVM_BUSY) -+ return -ETIMEDOUT; -+ -+ if (op == NVM_READ) { -+ ret = pmic_read(dev, addr, buf, buf_len); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+int stpmic1_shadow_read_byte(u8 addr, u8 *buf) -+{ -+ return stpmic1_nvm_rw(addr, buf, 1, SHADOW_READ); -+} -+ -+int stpmic1_shadow_write_byte(u8 addr, u8 *buf) -+{ -+ return stpmic1_nvm_rw(addr, buf, 1, SHADOW_WRITE); -+} -+ -+int stpmic1_nvm_read_byte(u8 addr, u8 *buf) -+{ -+ return stpmic1_nvm_rw(addr, buf, 1, NVM_READ); -+} -+ -+int stpmic1_nvm_write_byte(u8 addr, u8 *buf) -+{ -+ return stpmic1_nvm_rw(addr, buf, 1, NVM_WRITE); -+} -+ -+int stpmic1_nvm_read_all(u8 *buf, int buf_len) -+{ -+ if (buf_len != STPMIC1_NVM_SIZE) -+ return -EINVAL; -+ -+ return stpmic1_nvm_rw(STPMIC1_NVM_START_ADDRESS, -+ buf, buf_len, NVM_READ); -+} -+ -+int stpmic1_nvm_write_all(u8 *buf, int buf_len) -+{ -+ if (buf_len != STPMIC1_NVM_SIZE) -+ return -EINVAL; -+ -+ return stpmic1_nvm_rw(STPMIC1_NVM_START_ADDRESS, -+ buf, buf_len, NVM_WRITE); -+} -+#endif /* CONFIG_SPL_BUILD */ -+ -+#ifdef CONFIG_SYSRESET -+static int stpmic1_sysreset_request(struct udevice *dev, enum sysreset_t type) -+{ -+ struct udevice *pmic_dev; -+ int ret; -+ -+ if (type != SYSRESET_POWER) -+ return -EPROTONOSUPPORT; -+ -+ ret = uclass_get_device_by_driver(UCLASS_PMIC, -+ DM_GET_DRIVER(pmic_stpmic1), -+ &pmic_dev); -+ -+ if (ret) -+ return -EOPNOTSUPP; -+ -+ ret = pmic_reg_read(pmic_dev, STPMIC1_MAIN_CR); -+ if (ret < 0) -+ return ret; -+ -+ ret = pmic_reg_write(pmic_dev, STPMIC1_MAIN_CR, -+ ret | STPMIC1_SWOFF | STPMIC1_RREQ_EN); -+ if (ret < 0) -+ return ret; -+ -+ return -EINPROGRESS; -+} -+ -+static struct sysreset_ops stpmic1_sysreset_ops = { -+ .request = stpmic1_sysreset_request, -+}; -+ -+U_BOOT_DRIVER(stpmic1_sysreset) = { -+ .name = "stpmic1-sysreset", -+ .id = UCLASS_SYSRESET, -+ .ops = &stpmic1_sysreset_ops, -+}; -+#endif -diff --git a/drivers/power/pmic/stpmu1.c b/drivers/power/pmic/stpmu1.c -deleted file mode 100644 -index 82351b6..0000000 ---- a/drivers/power/pmic/stpmu1.c -+++ /dev/null -@@ -1,95 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause --/* -- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -- */ -- --#include --#include --#include --#include --#include --#include -- --#define STMPU1_NUM_OF_REGS 0x100 -- --#ifndef CONFIG_SPL_BUILD --static const struct pmic_child_info stpmu1_children_info[] = { -- { .prefix = "ldo", .driver = "stpmu1_ldo" }, -- { .prefix = "buck", .driver = "stpmu1_buck" }, -- { .prefix = "vref_ddr", .driver = "stpmu1_vref_ddr" }, -- { .prefix = "pwr_sw", .driver = "stpmu1_pwr_sw" }, -- { .prefix = "boost", .driver = "stpmu1_boost" }, -- { }, --}; --#endif /* CONFIG_SPL_BUILD */ -- --static int stpmu1_reg_count(struct udevice *dev) --{ -- return STMPU1_NUM_OF_REGS; --} -- --static int stpmu1_write(struct udevice *dev, uint reg, const uint8_t *buff, -- int len) --{ -- int ret; -- -- ret = dm_i2c_write(dev, reg, buff, len); -- if (ret) -- dev_err(dev, "%s: failed to write register %#x :%d", -- __func__, reg, ret); -- -- return ret; --} -- --static int stpmu1_read(struct udevice *dev, uint reg, uint8_t *buff, int len) --{ -- int ret; -- -- ret = dm_i2c_read(dev, reg, buff, len); -- if (ret) -- dev_err(dev, "%s: failed to read register %#x : %d", -- __func__, reg, ret); -- -- return ret; --} -- --static int stpmu1_bind(struct udevice *dev) --{ --#ifndef CONFIG_SPL_BUILD -- ofnode regulators_node; -- int children; -- -- regulators_node = dev_read_subnode(dev, "regulators"); -- if (!ofnode_valid(regulators_node)) { -- dev_dbg(dev, "regulators subnode not found!"); -- return -ENXIO; -- } -- dev_dbg(dev, "found regulators subnode\n"); -- -- children = pmic_bind_children(dev, regulators_node, -- stpmu1_children_info); -- if (!children) -- dev_dbg(dev, "no child found\n"); --#endif /* CONFIG_SPL_BUILD */ -- -- return 0; --} -- --static struct dm_pmic_ops stpmu1_ops = { -- .reg_count = stpmu1_reg_count, -- .read = stpmu1_read, -- .write = stpmu1_write, --}; -- --static const struct udevice_id stpmu1_ids[] = { -- { .compatible = "st,stpmu1" }, -- { } --}; -- --U_BOOT_DRIVER(pmic_stpmu1) = { -- .name = "stpmu1_pmic", -- .id = UCLASS_PMIC, -- .of_match = stpmu1_ids, -- .bind = stpmu1_bind, -- .ops = &stpmu1_ops, --}; -diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig -index 2561a8a..268f7ca 100644 ---- a/drivers/power/regulator/Kconfig -+++ b/drivers/power/regulator/Kconfig -@@ -221,11 +221,17 @@ config DM_REGULATOR_TPS65910 - regulator types of the TPS65910 (BUCK, BOOST and LDO). It implements - the get/set api for value and enable. - --config DM_REGULATOR_STPMU1 -- bool "Enable driver for STPMU1 regulators" -- depends on DM_REGULATOR && PMIC_STPMU1 -+config DM_REGULATOR_STPMIC1 -+ bool "Enable driver for STPMIC1 regulators" -+ depends on DM_REGULATOR && PMIC_STPMIC1 - ---help--- -- Enable support for the regulator functions of the STPMU1 PMIC. The -+ Enable support for the regulator functions of the STPMIC1 PMIC. The - driver implements get/set api for the various BUCKS and LDOs supported - by the PMIC device. This driver is controlled by a device tree node - which includes voltage limits. -+ -+config SPL_DM_REGULATOR_STPMIC1 -+ bool "Enable driver for STPMIC1 regulators in SPL" -+ depends on SPL_DM_REGULATOR && PMIC_STPMIC1 -+ ---help--- -+ Enable support for the regulator functions of the STPMIC1 PMIC in SPL. -diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile -index a5f5683..7a8888a 100644 ---- a/drivers/power/regulator/Makefile -+++ b/drivers/power/regulator/Makefile -@@ -23,4 +23,4 @@ obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o - obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP87565) += lp87565_regulator.o - obj-$(CONFIG_$(SPL_)DM_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o - obj-$(CONFIG_DM_REGULATOR_TPS65910) += tps65910_regulator.o --obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMU1) += stpmu1.o -+obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMIC1) += stpmic1.o -diff --git a/drivers/power/regulator/fixed.c b/drivers/power/regulator/fixed.c -index a99aa78..872e394 100644 ---- a/drivers/power/regulator/fixed.c -+++ b/drivers/power/regulator/fixed.c -@@ -35,7 +35,9 @@ static int fixed_regulator_ofdata_to_platdata(struct udevice *dev) - /* Set type to fixed */ - uc_pdata->type = REGULATOR_TYPE_FIXED; - -- if (dev_read_bool(dev, "enable-active-high")) -+ if (!dev_read_bool(dev, "enable-active-high")) -+ flags |= GPIOD_ACTIVE_LOW; -+ if (uc_pdata->boot_on) - flags |= GPIOD_IS_OUT_ACTIVE; - - /* Get fixed regulator optional enable GPIO desc */ -diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c -index 4da8e43..4511625 100644 ---- a/drivers/power/regulator/regulator-uclass.c -+++ b/drivers/power/regulator/regulator-uclass.c -@@ -106,10 +106,15 @@ int regulator_get_enable(struct udevice *dev) - int regulator_set_enable(struct udevice *dev, bool enable) - { - const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); -+ struct dm_regulator_uclass_platdata *uc_pdata; - - if (!ops || !ops->set_enable) - return -ENOSYS; - -+ uc_pdata = dev_get_uclass_platdata(dev); -+ if (!enable && uc_pdata->always_on) -+ return -EACCES; -+ - return ops->set_enable(dev, enable); - } - -diff --git a/drivers/power/regulator/stpmic1.c b/drivers/power/regulator/stpmic1.c -new file mode 100644 -index 0000000..50ef2a2 ---- /dev/null -+++ b/drivers/power/regulator/stpmic1.c -@@ -0,0 +1,672 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ * Author: Christophe Kerello -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct stpmic1_range { -+ int min_uv; -+ int min_sel; -+ int max_sel; -+ int step; -+}; -+ -+struct stpmic1_output { -+ const struct stpmic1_range *ranges; -+ int nbranges; -+}; -+ -+#define STPMIC1_MODE(_id, _val, _name) { \ -+ .id = _id, \ -+ .register_value = _val, \ -+ .name = _name, \ -+} -+ -+#define STPMIC1_RANGE(_min_uv, _min_sel, _max_sel, _step) { \ -+ .min_uv = _min_uv, \ -+ .min_sel = _min_sel, \ -+ .max_sel = _max_sel, \ -+ .step = _step, \ -+} -+ -+#define STPMIC1_OUTPUT(_ranges, _nbranges) { \ -+ .ranges = _ranges, \ -+ .nbranges = _nbranges, \ -+} -+ -+static int stpmic1_output_find_uv(int sel, -+ const struct stpmic1_output *output) -+{ -+ const struct stpmic1_range *range; -+ int i; -+ -+ for (i = 0, range = output->ranges; -+ i < output->nbranges; i++, range++) { -+ if (sel >= range->min_sel && sel <= range->max_sel) -+ return range->min_uv + -+ (sel - range->min_sel) * range->step; -+ } -+ -+ return -EINVAL; -+} -+ -+static int stpmic1_output_find_sel(int uv, -+ const struct stpmic1_output *output) -+{ -+ const struct stpmic1_range *range; -+ int i; -+ -+ for (i = 0, range = output->ranges; -+ i < output->nbranges; i++, range++) { -+ if (uv == range->min_uv && !range->step) -+ return range->min_sel; -+ -+ if (uv >= range->min_uv && -+ uv <= range->min_uv + -+ (range->max_sel - range->min_sel) * range->step) -+ return range->min_sel + -+ (uv - range->min_uv) / range->step; -+ } -+ -+ return -EINVAL; -+} -+ -+/* -+ * BUCK regulators -+ */ -+ -+static const struct stpmic1_range buck1_ranges[] = { -+ STPMIC1_RANGE(725000, 0, 4, 0), -+ STPMIC1_RANGE(725000, 5, 36, 25000), -+ STPMIC1_RANGE(1500000, 37, 63, 0), -+}; -+ -+static const struct stpmic1_range buck2_ranges[] = { -+ STPMIC1_RANGE(1000000, 0, 17, 0), -+ STPMIC1_RANGE(1050000, 18, 19, 0), -+ STPMIC1_RANGE(1100000, 20, 21, 0), -+ STPMIC1_RANGE(1150000, 22, 23, 0), -+ STPMIC1_RANGE(1200000, 24, 25, 0), -+ STPMIC1_RANGE(1250000, 26, 27, 0), -+ STPMIC1_RANGE(1300000, 28, 29, 0), -+ STPMIC1_RANGE(1350000, 30, 31, 0), -+ STPMIC1_RANGE(1400000, 32, 33, 0), -+ STPMIC1_RANGE(1450000, 34, 35, 0), -+ STPMIC1_RANGE(1500000, 36, 63, 0), -+}; -+ -+static const struct stpmic1_range buck3_ranges[] = { -+ STPMIC1_RANGE(1000000, 0, 19, 0), -+ STPMIC1_RANGE(1100000, 20, 23, 0), -+ STPMIC1_RANGE(1200000, 24, 27, 0), -+ STPMIC1_RANGE(1300000, 28, 31, 0), -+ STPMIC1_RANGE(1400000, 32, 35, 0), -+ STPMIC1_RANGE(1500000, 36, 55, 100000), -+ STPMIC1_RANGE(3400000, 56, 63, 0), -+}; -+ -+static const struct stpmic1_range buck4_ranges[] = { -+ STPMIC1_RANGE(600000, 0, 27, 25000), -+ STPMIC1_RANGE(1300000, 28, 29, 0), -+ STPMIC1_RANGE(1350000, 30, 31, 0), -+ STPMIC1_RANGE(1400000, 32, 33, 0), -+ STPMIC1_RANGE(1450000, 34, 35, 0), -+ STPMIC1_RANGE(1500000, 36, 60, 100000), -+ STPMIC1_RANGE(3900000, 61, 63, 0), -+}; -+ -+/* BUCK: 1,2,3,4 - voltage ranges */ -+static const struct stpmic1_output buck_voltage_range[] = { -+ STPMIC1_OUTPUT(buck1_ranges, ARRAY_SIZE(buck1_ranges)), -+ STPMIC1_OUTPUT(buck2_ranges, ARRAY_SIZE(buck2_ranges)), -+ STPMIC1_OUTPUT(buck3_ranges, ARRAY_SIZE(buck3_ranges)), -+ STPMIC1_OUTPUT(buck4_ranges, ARRAY_SIZE(buck4_ranges)), -+}; -+ -+/* BUCK modes */ -+static const struct dm_regulator_mode buck_modes[] = { -+ STPMIC1_MODE(STPMIC1_PREG_MODE_HP, STPMIC1_PREG_MODE_HP, "HP"), -+ STPMIC1_MODE(STPMIC1_PREG_MODE_LP, STPMIC1_PREG_MODE_LP, "LP"), -+}; -+ -+static int stpmic1_buck_get_uv(struct udevice *dev, int buck) -+{ -+ int sel; -+ -+ sel = pmic_reg_read(dev, STPMIC1_BUCKX_MAIN_CR(buck)); -+ if (sel < 0) -+ return sel; -+ -+ sel &= STPMIC1_BUCK_VOUT_MASK; -+ sel >>= STPMIC1_BUCK_VOUT_SHIFT; -+ -+ return stpmic1_output_find_uv(sel, &buck_voltage_range[buck]); -+} -+ -+static int stpmic1_buck_get_value(struct udevice *dev) -+{ -+ return stpmic1_buck_get_uv(dev->parent, dev->driver_data - 1); -+} -+ -+static int stpmic1_buck_set_value(struct udevice *dev, int uv) -+{ -+ int sel, buck = dev->driver_data - 1; -+ -+ sel = stpmic1_output_find_sel(uv, &buck_voltage_range[buck]); -+ if (sel < 0) -+ return sel; -+ -+ return pmic_clrsetbits(dev->parent, -+ STPMIC1_BUCKX_MAIN_CR(buck), -+ STPMIC1_BUCK_VOUT_MASK, -+ sel << STPMIC1_BUCK_VOUT_SHIFT); -+} -+ -+static int stpmic1_buck_get_enable(struct udevice *dev) -+{ -+ int ret; -+ -+ ret = pmic_reg_read(dev->parent, -+ STPMIC1_BUCKX_MAIN_CR(dev->driver_data - 1)); -+ if (ret < 0) -+ return false; -+ -+ return ret & STPMIC1_BUCK_ENA ? true : false; -+} -+ -+static int stpmic1_buck_set_enable(struct udevice *dev, bool enable) -+{ -+ struct dm_regulator_uclass_platdata *uc_pdata; -+ int delay = enable ? STPMIC1_DEFAULT_START_UP_DELAY_MS : -+ STPMIC1_DEFAULT_STOP_DELAY_MS; -+ int ret, uv; -+ -+ /* if regulator is already in the wanted state, nothing to do */ -+ if (stpmic1_buck_get_enable(dev) == enable) -+ return 0; -+ -+ if (enable) { -+ uc_pdata = dev_get_uclass_platdata(dev); -+ uv = stpmic1_buck_get_value(dev); -+ if (uv < uc_pdata->min_uV || uv > uc_pdata->max_uV) -+ stpmic1_buck_set_value(dev, uc_pdata->min_uV); -+ } -+ -+ ret = pmic_clrsetbits(dev->parent, -+ STPMIC1_BUCKX_MAIN_CR(dev->driver_data - 1), -+ STPMIC1_BUCK_ENA, enable ? STPMIC1_BUCK_ENA : 0); -+ mdelay(delay); -+ -+ return ret; -+} -+ -+static int stpmic1_buck_get_mode(struct udevice *dev) -+{ -+ int ret; -+ -+ ret = pmic_reg_read(dev->parent, -+ STPMIC1_BUCKX_MAIN_CR(dev->driver_data - 1)); -+ if (ret < 0) -+ return ret; -+ -+ return ret & STPMIC1_BUCK_PREG_MODE ? STPMIC1_PREG_MODE_LP : -+ STPMIC1_PREG_MODE_HP; -+} -+ -+static int stpmic1_buck_set_mode(struct udevice *dev, int mode) -+{ -+ return pmic_clrsetbits(dev->parent, -+ STPMIC1_BUCKX_MAIN_CR(dev->driver_data - 1), -+ STPMIC1_BUCK_PREG_MODE, -+ mode ? STPMIC1_BUCK_PREG_MODE : 0); -+} -+ -+static int stpmic1_buck_probe(struct udevice *dev) -+{ -+ struct dm_regulator_uclass_platdata *uc_pdata; -+ -+ if (!dev->driver_data || dev->driver_data > STPMIC1_MAX_BUCK) -+ return -EINVAL; -+ -+ uc_pdata = dev_get_uclass_platdata(dev); -+ -+ uc_pdata->type = REGULATOR_TYPE_BUCK; -+ uc_pdata->mode = (struct dm_regulator_mode *)buck_modes; -+ uc_pdata->mode_count = ARRAY_SIZE(buck_modes); -+ -+ return 0; -+} -+ -+static const struct dm_regulator_ops stpmic1_buck_ops = { -+ .get_value = stpmic1_buck_get_value, -+ .set_value = stpmic1_buck_set_value, -+ .get_enable = stpmic1_buck_get_enable, -+ .set_enable = stpmic1_buck_set_enable, -+ .get_mode = stpmic1_buck_get_mode, -+ .set_mode = stpmic1_buck_set_mode, -+}; -+ -+U_BOOT_DRIVER(stpmic1_buck) = { -+ .name = "stpmic1_buck", -+ .id = UCLASS_REGULATOR, -+ .ops = &stpmic1_buck_ops, -+ .probe = stpmic1_buck_probe, -+}; -+ -+/* -+ * LDO regulators -+ */ -+ -+static const struct stpmic1_range ldo12_ranges[] = { -+ STPMIC1_RANGE(1700000, 0, 7, 0), -+ STPMIC1_RANGE(1700000, 8, 24, 100000), -+ STPMIC1_RANGE(3300000, 25, 31, 0), -+}; -+ -+static const struct stpmic1_range ldo3_ranges[] = { -+ STPMIC1_RANGE(1700000, 0, 7, 0), -+ STPMIC1_RANGE(1700000, 8, 24, 100000), -+ STPMIC1_RANGE(3300000, 25, 30, 0), -+ /* Sel 31 is special case when LDO3 is in mode sync_source (BUCK2/2) */ -+}; -+ -+static const struct stpmic1_range ldo5_ranges[] = { -+ STPMIC1_RANGE(1700000, 0, 7, 0), -+ STPMIC1_RANGE(1700000, 8, 30, 100000), -+ STPMIC1_RANGE(3900000, 31, 31, 0), -+}; -+ -+static const struct stpmic1_range ldo6_ranges[] = { -+ STPMIC1_RANGE(900000, 0, 24, 100000), -+ STPMIC1_RANGE(3300000, 25, 31, 0), -+}; -+ -+/* LDO: 1,2,3,4,5,6 - voltage ranges */ -+static const struct stpmic1_output ldo_voltage_range[] = { -+ STPMIC1_OUTPUT(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)), -+ STPMIC1_OUTPUT(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)), -+ STPMIC1_OUTPUT(ldo3_ranges, ARRAY_SIZE(ldo3_ranges)), -+ STPMIC1_OUTPUT(NULL, 0), -+ STPMIC1_OUTPUT(ldo5_ranges, ARRAY_SIZE(ldo5_ranges)), -+ STPMIC1_OUTPUT(ldo6_ranges, ARRAY_SIZE(ldo6_ranges)), -+}; -+ -+/* LDO modes */ -+static const struct dm_regulator_mode ldo_modes[] = { -+ STPMIC1_MODE(STPMIC1_LDO_MODE_NORMAL, -+ STPMIC1_LDO_MODE_NORMAL, "NORMAL"), -+ STPMIC1_MODE(STPMIC1_LDO_MODE_BYPASS, -+ STPMIC1_LDO_MODE_BYPASS, "BYPASS"), -+ STPMIC1_MODE(STPMIC1_LDO_MODE_SINK_SOURCE, -+ STPMIC1_LDO_MODE_SINK_SOURCE, "SINK SOURCE"), -+}; -+ -+static int stpmic1_ldo_get_value(struct udevice *dev) -+{ -+ int sel, ldo = dev->driver_data - 1; -+ -+ sel = pmic_reg_read(dev->parent, STPMIC1_LDOX_MAIN_CR(ldo)); -+ if (sel < 0) -+ return sel; -+ -+ /* ldo4 => 3,3V */ -+ if (ldo == STPMIC1_LDO4) -+ return STPMIC1_LDO4_UV; -+ -+ sel &= STPMIC1_LDO12356_VOUT_MASK; -+ sel >>= STPMIC1_LDO12356_VOUT_SHIFT; -+ -+ /* ldo3, sel = 31 => BUCK2/2 */ -+ if (ldo == STPMIC1_LDO3 && sel == STPMIC1_LDO3_DDR_SEL) -+ return stpmic1_buck_get_uv(dev->parent, STPMIC1_BUCK2) / 2; -+ -+ return stpmic1_output_find_uv(sel, &ldo_voltage_range[ldo]); -+} -+ -+static int stpmic1_ldo_set_value(struct udevice *dev, int uv) -+{ -+ int sel, ldo = dev->driver_data - 1; -+ -+ /* ldo4 => not possible */ -+ if (ldo == STPMIC1_LDO4) -+ return -EINVAL; -+ -+ sel = stpmic1_output_find_sel(uv, &ldo_voltage_range[ldo]); -+ if (sel < 0) -+ return sel; -+ -+ return pmic_clrsetbits(dev->parent, -+ STPMIC1_LDOX_MAIN_CR(ldo), -+ STPMIC1_LDO12356_VOUT_MASK, -+ sel << STPMIC1_LDO12356_VOUT_SHIFT); -+} -+ -+static int stpmic1_ldo_get_enable(struct udevice *dev) -+{ -+ int ret; -+ -+ ret = pmic_reg_read(dev->parent, -+ STPMIC1_LDOX_MAIN_CR(dev->driver_data - 1)); -+ if (ret < 0) -+ return false; -+ -+ return ret & STPMIC1_LDO_ENA ? true : false; -+} -+ -+static int stpmic1_ldo_set_enable(struct udevice *dev, bool enable) -+{ -+ struct dm_regulator_uclass_platdata *uc_pdata; -+ int delay = enable ? STPMIC1_DEFAULT_START_UP_DELAY_MS : -+ STPMIC1_DEFAULT_STOP_DELAY_MS; -+ int ret, uv; -+ -+ /* if regulator is already in the wanted state, nothing to do */ -+ if (stpmic1_ldo_get_enable(dev) == enable) -+ return 0; -+ -+ if (enable) { -+ uc_pdata = dev_get_uclass_platdata(dev); -+ uv = stpmic1_ldo_get_value(dev); -+ if (uv < uc_pdata->min_uV || uv > uc_pdata->max_uV) -+ stpmic1_ldo_set_value(dev, uc_pdata->min_uV); -+ } -+ -+ ret = pmic_clrsetbits(dev->parent, -+ STPMIC1_LDOX_MAIN_CR(dev->driver_data - 1), -+ STPMIC1_LDO_ENA, enable ? STPMIC1_LDO_ENA : 0); -+ mdelay(delay); -+ -+ return ret; -+} -+ -+static int stpmic1_ldo_get_mode(struct udevice *dev) -+{ -+ int ret, ldo = dev->driver_data - 1; -+ -+ if (ldo != STPMIC1_LDO3) -+ return -EINVAL; -+ -+ ret = pmic_reg_read(dev->parent, STPMIC1_LDOX_MAIN_CR(ldo)); -+ if (ret < 0) -+ return ret; -+ -+ if (ret & STPMIC1_LDO3_MODE) -+ return STPMIC1_LDO_MODE_BYPASS; -+ -+ ret &= STPMIC1_LDO12356_VOUT_MASK; -+ ret >>= STPMIC1_LDO12356_VOUT_SHIFT; -+ -+ return ret == STPMIC1_LDO3_DDR_SEL ? STPMIC1_LDO_MODE_SINK_SOURCE : -+ STPMIC1_LDO_MODE_NORMAL; -+} -+ -+static int stpmic1_ldo_set_mode(struct udevice *dev, int mode) -+{ -+ int ret, ldo = dev->driver_data - 1; -+ -+ if (ldo != STPMIC1_LDO3) -+ return -EINVAL; -+ -+ ret = pmic_reg_read(dev->parent, STPMIC1_LDOX_MAIN_CR(ldo)); -+ if (ret < 0) -+ return ret; -+ -+ switch (mode) { -+ case STPMIC1_LDO_MODE_SINK_SOURCE: -+ ret &= ~STPMIC1_LDO12356_VOUT_MASK; -+ ret |= STPMIC1_LDO3_DDR_SEL << STPMIC1_LDO12356_VOUT_SHIFT; -+ case STPMIC1_LDO_MODE_NORMAL: -+ ret &= ~STPMIC1_LDO3_MODE; -+ break; -+ case STPMIC1_LDO_MODE_BYPASS: -+ ret |= STPMIC1_LDO3_MODE; -+ break; -+ } -+ -+ return pmic_reg_write(dev->parent, STPMIC1_LDOX_MAIN_CR(ldo), ret); -+} -+ -+static int stpmic1_ldo_probe(struct udevice *dev) -+{ -+ struct dm_regulator_uclass_platdata *uc_pdata; -+ -+ if (!dev->driver_data || dev->driver_data > STPMIC1_MAX_LDO) -+ return -EINVAL; -+ -+ uc_pdata = dev_get_uclass_platdata(dev); -+ -+ uc_pdata->type = REGULATOR_TYPE_LDO; -+ if (dev->driver_data - 1 == STPMIC1_LDO3) { -+ uc_pdata->mode = (struct dm_regulator_mode *)ldo_modes; -+ uc_pdata->mode_count = ARRAY_SIZE(ldo_modes); -+ } else { -+ uc_pdata->mode_count = 0; -+ } -+ -+ return 0; -+} -+ -+static const struct dm_regulator_ops stpmic1_ldo_ops = { -+ .get_value = stpmic1_ldo_get_value, -+ .set_value = stpmic1_ldo_set_value, -+ .get_enable = stpmic1_ldo_get_enable, -+ .set_enable = stpmic1_ldo_set_enable, -+ .get_mode = stpmic1_ldo_get_mode, -+ .set_mode = stpmic1_ldo_set_mode, -+}; -+ -+U_BOOT_DRIVER(stpmic1_ldo) = { -+ .name = "stpmic1_ldo", -+ .id = UCLASS_REGULATOR, -+ .ops = &stpmic1_ldo_ops, -+ .probe = stpmic1_ldo_probe, -+}; -+ -+/* -+ * VREF DDR regulator -+ */ -+ -+static int stpmic1_vref_ddr_get_value(struct udevice *dev) -+{ -+ /* BUCK2/2 */ -+ return stpmic1_buck_get_uv(dev->parent, STPMIC1_BUCK2) / 2; -+} -+ -+static int stpmic1_vref_ddr_get_enable(struct udevice *dev) -+{ -+ int ret; -+ -+ ret = pmic_reg_read(dev->parent, STPMIC1_REFDDR_MAIN_CR); -+ if (ret < 0) -+ return false; -+ -+ return ret & STPMIC1_VREF_ENA ? true : false; -+} -+ -+static int stpmic1_vref_ddr_set_enable(struct udevice *dev, bool enable) -+{ -+ int delay = enable ? STPMIC1_DEFAULT_START_UP_DELAY_MS : -+ STPMIC1_DEFAULT_STOP_DELAY_MS; -+ int ret; -+ -+ /* if regulator is already in the wanted state, nothing to do */ -+ if (stpmic1_vref_ddr_get_enable(dev) == enable) -+ return 0; -+ -+ ret = pmic_clrsetbits(dev->parent, STPMIC1_REFDDR_MAIN_CR, -+ STPMIC1_VREF_ENA, enable ? STPMIC1_VREF_ENA : 0); -+ mdelay(delay); -+ -+ return ret; -+} -+ -+static int stpmic1_vref_ddr_probe(struct udevice *dev) -+{ -+ struct dm_regulator_uclass_platdata *uc_pdata; -+ -+ uc_pdata = dev_get_uclass_platdata(dev); -+ -+ uc_pdata->type = REGULATOR_TYPE_FIXED; -+ uc_pdata->mode_count = 0; -+ -+ return 0; -+} -+ -+static const struct dm_regulator_ops stpmic1_vref_ddr_ops = { -+ .get_value = stpmic1_vref_ddr_get_value, -+ .get_enable = stpmic1_vref_ddr_get_enable, -+ .set_enable = stpmic1_vref_ddr_set_enable, -+}; -+ -+U_BOOT_DRIVER(stpmic1_vref_ddr) = { -+ .name = "stpmic1_vref_ddr", -+ .id = UCLASS_REGULATOR, -+ .ops = &stpmic1_vref_ddr_ops, -+ .probe = stpmic1_vref_ddr_probe, -+}; -+ -+/* -+ * BOOST regulator -+ */ -+ -+static int stpmic1_boost_get_enable(struct udevice *dev) -+{ -+ int ret; -+ -+ ret = pmic_reg_read(dev->parent, STPMIC1_BST_SW_CR); -+ if (ret < 0) -+ return false; -+ -+ return ret & STPMIC1_BST_ON ? true : false; -+} -+ -+static int stpmic1_boost_set_enable(struct udevice *dev, bool enable) -+{ -+ int ret; -+ -+ ret = pmic_reg_read(dev->parent, STPMIC1_BST_SW_CR); -+ if (ret < 0) -+ return ret; -+ -+ if (!enable && ret & STPMIC1_PWR_SW_ON) -+ return -EINVAL; -+ -+ /* if regulator is already in the wanted state, nothing to do */ -+ if (!!(ret & STPMIC1_BST_ON) == enable) -+ return 0; -+ -+ ret = pmic_clrsetbits(dev->parent, STPMIC1_BST_SW_CR, -+ STPMIC1_BST_ON, -+ enable ? STPMIC1_BST_ON : 0); -+ if (enable) -+ mdelay(STPMIC1_USB_BOOST_START_UP_DELAY_MS); -+ -+ return ret; -+} -+ -+static int stpmic1_boost_probe(struct udevice *dev) -+{ -+ struct dm_regulator_uclass_platdata *uc_pdata; -+ -+ uc_pdata = dev_get_uclass_platdata(dev); -+ -+ uc_pdata->type = REGULATOR_TYPE_FIXED; -+ uc_pdata->mode_count = 0; -+ -+ return 0; -+} -+ -+static const struct dm_regulator_ops stpmic1_boost_ops = { -+ .get_enable = stpmic1_boost_get_enable, -+ .set_enable = stpmic1_boost_set_enable, -+}; -+ -+U_BOOT_DRIVER(stpmic1_boost) = { -+ .name = "stpmic1_boost", -+ .id = UCLASS_REGULATOR, -+ .ops = &stpmic1_boost_ops, -+ .probe = stpmic1_boost_probe, -+}; -+ -+/* -+ * USB power switch -+ */ -+ -+static int stpmic1_pwr_sw_get_enable(struct udevice *dev) -+{ -+ uint mask = 1 << dev->driver_data; -+ int ret; -+ -+ ret = pmic_reg_read(dev->parent, STPMIC1_BST_SW_CR); -+ if (ret < 0) -+ return false; -+ -+ return ret & mask ? true : false; -+} -+ -+static int stpmic1_pwr_sw_set_enable(struct udevice *dev, bool enable) -+{ -+ uint mask = 1 << dev->driver_data; -+ int delay = enable ? STPMIC1_DEFAULT_START_UP_DELAY_MS : -+ STPMIC1_DEFAULT_STOP_DELAY_MS; -+ int ret; -+ -+ ret = pmic_reg_read(dev->parent, STPMIC1_BST_SW_CR); -+ if (ret < 0) -+ return ret; -+ -+ /* if regulator is already in the wanted state, nothing to do */ -+ if (!!(ret & mask) == enable) -+ return 0; -+ -+ /* Boost management */ -+ if (enable && !(ret & STPMIC1_BST_ON)) { -+ pmic_clrsetbits(dev->parent, STPMIC1_BST_SW_CR, -+ STPMIC1_BST_ON, STPMIC1_BST_ON); -+ mdelay(STPMIC1_USB_BOOST_START_UP_DELAY_MS); -+ } else if (!enable && ret & STPMIC1_BST_ON && -+ (ret & STPMIC1_PWR_SW_ON) != STPMIC1_PWR_SW_ON) { -+ pmic_clrsetbits(dev->parent, STPMIC1_BST_SW_CR, -+ STPMIC1_BST_ON, 0); -+ } -+ -+ ret = pmic_clrsetbits(dev->parent, STPMIC1_BST_SW_CR, -+ mask, enable ? mask : 0); -+ mdelay(delay); -+ -+ return ret; -+} -+ -+static int stpmic1_pwr_sw_probe(struct udevice *dev) -+{ -+ struct dm_regulator_uclass_platdata *uc_pdata; -+ -+ if (!dev->driver_data || dev->driver_data > STPMIC1_MAX_PWR_SW) -+ return -EINVAL; -+ -+ uc_pdata = dev_get_uclass_platdata(dev); -+ -+ uc_pdata->type = REGULATOR_TYPE_FIXED; -+ uc_pdata->mode_count = 0; -+ -+ return 0; -+} -+ -+static const struct dm_regulator_ops stpmic1_pwr_sw_ops = { -+ .get_enable = stpmic1_pwr_sw_get_enable, -+ .set_enable = stpmic1_pwr_sw_set_enable, -+}; -+ -+U_BOOT_DRIVER(stpmic1_pwr_sw) = { -+ .name = "stpmic1_pwr_sw", -+ .id = UCLASS_REGULATOR, -+ .ops = &stpmic1_pwr_sw_ops, -+ .probe = stpmic1_pwr_sw_probe, -+}; -diff --git a/drivers/power/regulator/stpmu1.c b/drivers/power/regulator/stpmu1.c -deleted file mode 100644 -index 6eb2420..0000000 ---- a/drivers/power/regulator/stpmu1.c -+++ /dev/null -@@ -1,671 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause --/* -- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -- * Author: Christophe Kerello -- */ -- --#include --#include --#include --#include --#include --#include -- --struct stpmu1_range { -- int min_uv; -- int min_sel; -- int max_sel; -- int step; --}; -- --struct stpmu1_output_range { -- const struct stpmu1_range *ranges; -- int nbranges; --}; -- --#define STPMU1_MODE(_id, _val, _name) { \ -- .id = _id, \ -- .register_value = _val, \ -- .name = _name, \ --} -- --#define STPMU1_RANGE(_min_uv, _min_sel, _max_sel, _step) { \ -- .min_uv = _min_uv, \ -- .min_sel = _min_sel, \ -- .max_sel = _max_sel, \ -- .step = _step, \ --} -- --#define STPMU1_OUTPUT_RANGE(_ranges, _nbranges) { \ -- .ranges = _ranges, \ -- .nbranges = _nbranges, \ --} -- --static int stpmu1_output_find_uv(int sel, -- const struct stpmu1_output_range *output_range) --{ -- const struct stpmu1_range *range; -- int i; -- -- for (i = 0, range = output_range->ranges; -- i < output_range->nbranges; i++, range++) { -- if (sel >= range->min_sel && sel <= range->max_sel) -- return range->min_uv + -- (sel - range->min_sel) * range->step; -- } -- -- return -EINVAL; --} -- --static int stpmu1_output_find_sel(int uv, -- const struct stpmu1_output_range *output_range) --{ -- const struct stpmu1_range *range; -- int i; -- -- for (i = 0, range = output_range->ranges; -- i < output_range->nbranges; i++, range++) { -- if (uv == range->min_uv && !range->step) -- return range->min_sel; -- -- if (uv >= range->min_uv && -- uv <= range->min_uv + -- (range->max_sel - range->min_sel) * range->step) -- return range->min_sel + -- (uv - range->min_uv) / range->step; -- } -- -- return -EINVAL; --} -- --/* -- * BUCK regulators -- */ -- --static const struct stpmu1_range buck1_ranges[] = { -- STPMU1_RANGE(600000, 0, 30, 25000), -- STPMU1_RANGE(1350000, 31, 63, 0), --}; -- --static const struct stpmu1_range buck2_ranges[] = { -- STPMU1_RANGE(1000000, 0, 17, 0), -- STPMU1_RANGE(1050000, 18, 19, 0), -- STPMU1_RANGE(1100000, 20, 21, 0), -- STPMU1_RANGE(1150000, 22, 23, 0), -- STPMU1_RANGE(1200000, 24, 25, 0), -- STPMU1_RANGE(1250000, 26, 27, 0), -- STPMU1_RANGE(1300000, 28, 29, 0), -- STPMU1_RANGE(1350000, 30, 31, 0), -- STPMU1_RANGE(1400000, 32, 33, 0), -- STPMU1_RANGE(1450000, 34, 35, 0), -- STPMU1_RANGE(1500000, 36, 63, 0), --}; -- --static const struct stpmu1_range buck3_ranges[] = { -- STPMU1_RANGE(1000000, 0, 19, 0), -- STPMU1_RANGE(1100000, 20, 23, 0), -- STPMU1_RANGE(1200000, 24, 27, 0), -- STPMU1_RANGE(1300000, 28, 31, 0), -- STPMU1_RANGE(1400000, 32, 35, 0), -- STPMU1_RANGE(1500000, 36, 55, 100000), -- STPMU1_RANGE(3400000, 56, 63, 0), --}; -- --static const struct stpmu1_range buck4_ranges[] = { -- STPMU1_RANGE(600000, 0, 27, 25000), -- STPMU1_RANGE(1300000, 28, 29, 0), -- STPMU1_RANGE(1350000, 30, 31, 0), -- STPMU1_RANGE(1400000, 32, 33, 0), -- STPMU1_RANGE(1450000, 34, 35, 0), -- STPMU1_RANGE(1500000, 36, 60, 100000), -- STPMU1_RANGE(3900000, 61, 63, 0), --}; -- --/* BUCK: 1,2,3,4 - voltage ranges */ --static const struct stpmu1_output_range buck_voltage_range[] = { -- STPMU1_OUTPUT_RANGE(buck1_ranges, ARRAY_SIZE(buck1_ranges)), -- STPMU1_OUTPUT_RANGE(buck2_ranges, ARRAY_SIZE(buck2_ranges)), -- STPMU1_OUTPUT_RANGE(buck3_ranges, ARRAY_SIZE(buck3_ranges)), -- STPMU1_OUTPUT_RANGE(buck4_ranges, ARRAY_SIZE(buck4_ranges)), --}; -- --/* BUCK modes */ --static const struct dm_regulator_mode buck_modes[] = { -- STPMU1_MODE(STPMU1_BUCK_MODE_HP, STPMU1_BUCK_MODE_HP, "HP"), -- STPMU1_MODE(STPMU1_BUCK_MODE_LP, STPMU1_BUCK_MODE_LP, "LP"), --}; -- --static int stpmu1_buck_get_uv(struct udevice *dev, int buck) --{ -- int sel; -- -- sel = pmic_reg_read(dev, STPMU1_BUCKX_CTRL_REG(buck)); -- if (sel < 0) -- return sel; -- -- sel &= STPMU1_BUCK_OUTPUT_MASK; -- sel >>= STPMU1_BUCK_OUTPUT_SHIFT; -- -- return stpmu1_output_find_uv(sel, &buck_voltage_range[buck]); --} -- --static int stpmu1_buck_get_value(struct udevice *dev) --{ -- return stpmu1_buck_get_uv(dev->parent, dev->driver_data - 1); --} -- --static int stpmu1_buck_set_value(struct udevice *dev, int uv) --{ -- int sel, buck = dev->driver_data - 1; -- -- sel = stpmu1_output_find_sel(uv, &buck_voltage_range[buck]); -- if (sel < 0) -- return sel; -- -- return pmic_clrsetbits(dev->parent, -- STPMU1_BUCKX_CTRL_REG(buck), -- STPMU1_BUCK_OUTPUT_MASK, -- sel << STPMU1_BUCK_OUTPUT_SHIFT); --} -- --static int stpmu1_buck_get_enable(struct udevice *dev) --{ -- int ret; -- -- ret = pmic_reg_read(dev->parent, -- STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1)); -- if (ret < 0) -- return false; -- -- return ret & STPMU1_BUCK_EN ? true : false; --} -- --static int stpmu1_buck_set_enable(struct udevice *dev, bool enable) --{ -- struct dm_regulator_uclass_platdata *uc_pdata; -- int delay = enable ? STPMU1_DEFAULT_START_UP_DELAY_MS : -- STPMU1_DEFAULT_STOP_DELAY_MS; -- int ret, uv; -- -- /* if regulator is already in the wanted state, nothing to do */ -- if (stpmu1_buck_get_enable(dev) == enable) -- return 0; -- -- if (enable) { -- uc_pdata = dev_get_uclass_platdata(dev); -- uv = stpmu1_buck_get_value(dev); -- if ((uv < uc_pdata->min_uV) || (uv > uc_pdata->max_uV)) -- stpmu1_buck_set_value(dev, uc_pdata->min_uV); -- } -- -- ret = pmic_clrsetbits(dev->parent, -- STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1), -- STPMU1_BUCK_EN, enable ? STPMU1_BUCK_EN : 0); -- mdelay(delay); -- -- return ret; --} -- --static int stpmu1_buck_get_mode(struct udevice *dev) --{ -- int ret; -- -- ret = pmic_reg_read(dev->parent, -- STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1)); -- if (ret < 0) -- return ret; -- -- return ret & STPMU1_BUCK_MODE ? STPMU1_BUCK_MODE_LP : -- STPMU1_BUCK_MODE_HP; --} -- --static int stpmu1_buck_set_mode(struct udevice *dev, int mode) --{ -- return pmic_clrsetbits(dev->parent, -- STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1), -- STPMU1_BUCK_MODE, -- mode ? STPMU1_BUCK_MODE : 0); --} -- --static int stpmu1_buck_probe(struct udevice *dev) --{ -- struct dm_regulator_uclass_platdata *uc_pdata; -- -- if (!dev->driver_data || dev->driver_data > STPMU1_MAX_BUCK) -- return -EINVAL; -- -- uc_pdata = dev_get_uclass_platdata(dev); -- -- uc_pdata->type = REGULATOR_TYPE_BUCK; -- uc_pdata->mode = (struct dm_regulator_mode *)buck_modes; -- uc_pdata->mode_count = ARRAY_SIZE(buck_modes); -- -- return 0; --} -- --static const struct dm_regulator_ops stpmu1_buck_ops = { -- .get_value = stpmu1_buck_get_value, -- .set_value = stpmu1_buck_set_value, -- .get_enable = stpmu1_buck_get_enable, -- .set_enable = stpmu1_buck_set_enable, -- .get_mode = stpmu1_buck_get_mode, -- .set_mode = stpmu1_buck_set_mode, --}; -- --U_BOOT_DRIVER(stpmu1_buck) = { -- .name = "stpmu1_buck", -- .id = UCLASS_REGULATOR, -- .ops = &stpmu1_buck_ops, -- .probe = stpmu1_buck_probe, --}; -- --/* -- * LDO regulators -- */ -- --static const struct stpmu1_range ldo12_ranges[] = { -- STPMU1_RANGE(1700000, 0, 7, 0), -- STPMU1_RANGE(1700000, 8, 24, 100000), -- STPMU1_RANGE(3300000, 25, 31, 0), --}; -- --static const struct stpmu1_range ldo3_ranges[] = { -- STPMU1_RANGE(1700000, 0, 7, 0), -- STPMU1_RANGE(1700000, 8, 24, 100000), -- STPMU1_RANGE(3300000, 25, 30, 0), -- /* Sel 31 is special case when LDO3 is in mode sync_source (BUCK2/2) */ --}; -- --static const struct stpmu1_range ldo5_ranges[] = { -- STPMU1_RANGE(1700000, 0, 7, 0), -- STPMU1_RANGE(1700000, 8, 30, 100000), -- STPMU1_RANGE(3900000, 31, 31, 0), --}; -- --static const struct stpmu1_range ldo6_ranges[] = { -- STPMU1_RANGE(900000, 0, 24, 100000), -- STPMU1_RANGE(3300000, 25, 31, 0), --}; -- --/* LDO: 1,2,3,4,5,6 - voltage ranges */ --static const struct stpmu1_output_range ldo_voltage_range[] = { -- STPMU1_OUTPUT_RANGE(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)), -- STPMU1_OUTPUT_RANGE(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)), -- STPMU1_OUTPUT_RANGE(ldo3_ranges, ARRAY_SIZE(ldo3_ranges)), -- STPMU1_OUTPUT_RANGE(NULL, 0), -- STPMU1_OUTPUT_RANGE(ldo5_ranges, ARRAY_SIZE(ldo5_ranges)), -- STPMU1_OUTPUT_RANGE(ldo6_ranges, ARRAY_SIZE(ldo6_ranges)), --}; -- --/* LDO modes */ --static const struct dm_regulator_mode ldo_modes[] = { -- STPMU1_MODE(STPMU1_LDO_MODE_NORMAL, -- STPMU1_LDO_MODE_NORMAL, "NORMAL"), -- STPMU1_MODE(STPMU1_LDO_MODE_BYPASS, -- STPMU1_LDO_MODE_BYPASS, "BYPASS"), -- STPMU1_MODE(STPMU1_LDO_MODE_SINK_SOURCE, -- STPMU1_LDO_MODE_SINK_SOURCE, "SINK SOURCE"), --}; -- --static int stpmu1_ldo_get_value(struct udevice *dev) --{ -- int sel, ldo = dev->driver_data - 1; -- -- sel = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo)); -- if (sel < 0) -- return sel; -- -- /* ldo4 => 3,3V */ -- if (ldo == STPMU1_LDO4) -- return STPMU1_LDO4_UV; -- -- sel &= STPMU1_LDO12356_OUTPUT_MASK; -- sel >>= STPMU1_LDO12356_OUTPUT_SHIFT; -- -- /* ldo3, sel = 31 => BUCK2/2 */ -- if (ldo == STPMU1_LDO3 && sel == STPMU1_LDO3_DDR_SEL) -- return stpmu1_buck_get_uv(dev->parent, STPMU1_BUCK2) / 2; -- -- return stpmu1_output_find_uv(sel, &ldo_voltage_range[ldo]); --} -- --static int stpmu1_ldo_set_value(struct udevice *dev, int uv) --{ -- int sel, ldo = dev->driver_data - 1; -- -- /* ldo4 => not possible */ -- if (ldo == STPMU1_LDO4) -- return -EINVAL; -- -- sel = stpmu1_output_find_sel(uv, &ldo_voltage_range[ldo]); -- if (sel < 0) -- return sel; -- -- return pmic_clrsetbits(dev->parent, -- STPMU1_LDOX_CTRL_REG(ldo), -- STPMU1_LDO12356_OUTPUT_MASK, -- sel << STPMU1_LDO12356_OUTPUT_SHIFT); --} -- --static int stpmu1_ldo_get_enable(struct udevice *dev) --{ -- int ret; -- -- ret = pmic_reg_read(dev->parent, -- STPMU1_LDOX_CTRL_REG(dev->driver_data - 1)); -- if (ret < 0) -- return false; -- -- return ret & STPMU1_LDO_EN ? true : false; --} -- --static int stpmu1_ldo_set_enable(struct udevice *dev, bool enable) --{ -- struct dm_regulator_uclass_platdata *uc_pdata; -- int delay = enable ? STPMU1_DEFAULT_START_UP_DELAY_MS : -- STPMU1_DEFAULT_STOP_DELAY_MS; -- int ret, uv; -- -- /* if regulator is already in the wanted state, nothing to do */ -- if (stpmu1_ldo_get_enable(dev) == enable) -- return 0; -- -- if (enable) { -- uc_pdata = dev_get_uclass_platdata(dev); -- uv = stpmu1_ldo_get_value(dev); -- if ((uv < uc_pdata->min_uV) || (uv > uc_pdata->max_uV)) -- stpmu1_ldo_set_value(dev, uc_pdata->min_uV); -- } -- -- ret = pmic_clrsetbits(dev->parent, -- STPMU1_LDOX_CTRL_REG(dev->driver_data - 1), -- STPMU1_LDO_EN, enable ? STPMU1_LDO_EN : 0); -- mdelay(delay); -- -- return ret; --} -- --static int stpmu1_ldo_get_mode(struct udevice *dev) --{ -- int ret, ldo = dev->driver_data - 1; -- -- if (ldo != STPMU1_LDO3) -- return -EINVAL; -- -- ret = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo)); -- if (ret < 0) -- return ret; -- -- if (ret & STPMU1_LDO3_MODE) -- return STPMU1_LDO_MODE_BYPASS; -- -- ret &= STPMU1_LDO12356_OUTPUT_MASK; -- ret >>= STPMU1_LDO12356_OUTPUT_SHIFT; -- -- return ret == STPMU1_LDO3_DDR_SEL ? STPMU1_LDO_MODE_SINK_SOURCE : -- STPMU1_LDO_MODE_NORMAL; --} -- --static int stpmu1_ldo_set_mode(struct udevice *dev, int mode) --{ -- int ret, ldo = dev->driver_data - 1; -- -- if (ldo != STPMU1_LDO3) -- return -EINVAL; -- -- ret = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo)); -- if (ret < 0) -- return ret; -- -- switch (mode) { -- case STPMU1_LDO_MODE_SINK_SOURCE: -- ret &= ~STPMU1_LDO12356_OUTPUT_MASK; -- ret |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT; -- case STPMU1_LDO_MODE_NORMAL: -- ret &= ~STPMU1_LDO3_MODE; -- break; -- case STPMU1_LDO_MODE_BYPASS: -- ret |= STPMU1_LDO3_MODE; -- break; -- } -- -- return pmic_reg_write(dev->parent, STPMU1_LDOX_CTRL_REG(ldo), ret); --} -- --static int stpmu1_ldo_probe(struct udevice *dev) --{ -- struct dm_regulator_uclass_platdata *uc_pdata; -- -- if (!dev->driver_data || dev->driver_data > STPMU1_MAX_LDO) -- return -EINVAL; -- -- uc_pdata = dev_get_uclass_platdata(dev); -- -- uc_pdata->type = REGULATOR_TYPE_LDO; -- if (dev->driver_data - 1 == STPMU1_LDO3) { -- uc_pdata->mode = (struct dm_regulator_mode *)ldo_modes; -- uc_pdata->mode_count = ARRAY_SIZE(ldo_modes); -- } else { -- uc_pdata->mode_count = 0; -- } -- -- return 0; --} -- --static const struct dm_regulator_ops stpmu1_ldo_ops = { -- .get_value = stpmu1_ldo_get_value, -- .set_value = stpmu1_ldo_set_value, -- .get_enable = stpmu1_ldo_get_enable, -- .set_enable = stpmu1_ldo_set_enable, -- .get_mode = stpmu1_ldo_get_mode, -- .set_mode = stpmu1_ldo_set_mode, --}; -- --U_BOOT_DRIVER(stpmu1_ldo) = { -- .name = "stpmu1_ldo", -- .id = UCLASS_REGULATOR, -- .ops = &stpmu1_ldo_ops, -- .probe = stpmu1_ldo_probe, --}; -- --/* -- * VREF DDR regulator -- */ -- --static int stpmu1_vref_ddr_get_value(struct udevice *dev) --{ -- /* BUCK2/2 */ -- return stpmu1_buck_get_uv(dev->parent, STPMU1_BUCK2) / 2; --} -- --static int stpmu1_vref_ddr_get_enable(struct udevice *dev) --{ -- int ret; -- -- ret = pmic_reg_read(dev->parent, STPMU1_VREF_CTRL_REG); -- if (ret < 0) -- return false; -- -- return ret & STPMU1_VREF_EN ? true : false; --} -- --static int stpmu1_vref_ddr_set_enable(struct udevice *dev, bool enable) --{ -- int delay = enable ? STPMU1_DEFAULT_START_UP_DELAY_MS : -- STPMU1_DEFAULT_STOP_DELAY_MS; -- int ret; -- -- /* if regulator is already in the wanted state, nothing to do */ -- if (stpmu1_vref_ddr_get_enable(dev) == enable) -- return 0; -- -- ret = pmic_clrsetbits(dev->parent, STPMU1_VREF_CTRL_REG, -- STPMU1_VREF_EN, enable ? STPMU1_VREF_EN : 0); -- mdelay(delay); -- -- return ret; --} -- --static int stpmu1_vref_ddr_probe(struct udevice *dev) --{ -- struct dm_regulator_uclass_platdata *uc_pdata; -- -- uc_pdata = dev_get_uclass_platdata(dev); -- -- uc_pdata->type = REGULATOR_TYPE_FIXED; -- uc_pdata->mode_count = 0; -- -- return 0; --} -- --static const struct dm_regulator_ops stpmu1_vref_ddr_ops = { -- .get_value = stpmu1_vref_ddr_get_value, -- .get_enable = stpmu1_vref_ddr_get_enable, -- .set_enable = stpmu1_vref_ddr_set_enable, --}; -- --U_BOOT_DRIVER(stpmu1_vref_ddr) = { -- .name = "stpmu1_vref_ddr", -- .id = UCLASS_REGULATOR, -- .ops = &stpmu1_vref_ddr_ops, -- .probe = stpmu1_vref_ddr_probe, --}; -- --/* -- * BOOST regulator -- */ -- --static int stpmu1_boost_get_enable(struct udevice *dev) --{ -- int ret; -- -- ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG); -- if (ret < 0) -- return false; -- -- return ret & STPMU1_USB_BOOST_EN ? true : false; --} -- --static int stpmu1_boost_set_enable(struct udevice *dev, bool enable) --{ -- int ret; -- -- ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG); -- if (ret < 0) -- return ret; -- -- if (!enable && ret & STPMU1_USB_PWR_SW_EN) -- return -EINVAL; -- -- /* if regulator is already in the wanted state, nothing to do */ -- if (!!(ret & STPMU1_USB_BOOST_EN) == enable) -- return 0; -- -- ret = pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG, -- STPMU1_USB_BOOST_EN, -- enable ? STPMU1_USB_BOOST_EN : 0); -- if (enable) -- mdelay(STPMU1_USB_BOOST_START_UP_DELAY_MS); -- -- return ret; --} -- --static int stpmu1_boost_probe(struct udevice *dev) --{ -- struct dm_regulator_uclass_platdata *uc_pdata; -- -- uc_pdata = dev_get_uclass_platdata(dev); -- -- uc_pdata->type = REGULATOR_TYPE_FIXED; -- uc_pdata->mode_count = 0; -- -- return 0; --} -- --static const struct dm_regulator_ops stpmu1_boost_ops = { -- .get_enable = stpmu1_boost_get_enable, -- .set_enable = stpmu1_boost_set_enable, --}; -- --U_BOOT_DRIVER(stpmu1_boost) = { -- .name = "stpmu1_boost", -- .id = UCLASS_REGULATOR, -- .ops = &stpmu1_boost_ops, -- .probe = stpmu1_boost_probe, --}; -- --/* -- * USB power switch -- */ -- --static int stpmu1_pwr_sw_get_enable(struct udevice *dev) --{ -- uint mask = 1 << dev->driver_data; -- int ret; -- -- ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG); -- if (ret < 0) -- return false; -- -- return ret & mask ? true : false; --} -- --static int stpmu1_pwr_sw_set_enable(struct udevice *dev, bool enable) --{ -- uint mask = 1 << dev->driver_data; -- int delay = enable ? STPMU1_DEFAULT_START_UP_DELAY_MS : -- STPMU1_DEFAULT_STOP_DELAY_MS; -- int ret; -- -- ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG); -- if (ret < 0) -- return ret; -- -- /* if regulator is already in the wanted state, nothing to do */ -- if (!!(ret & mask) == enable) -- return 0; -- -- /* Boost management */ -- if (enable && !(ret & STPMU1_USB_BOOST_EN)) { -- pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG, -- STPMU1_USB_BOOST_EN, STPMU1_USB_BOOST_EN); -- mdelay(STPMU1_USB_BOOST_START_UP_DELAY_MS); -- } else if (!enable && ret & STPMU1_USB_BOOST_EN && -- (ret & STPMU1_USB_PWR_SW_EN) != STPMU1_USB_PWR_SW_EN) { -- pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG, -- STPMU1_USB_BOOST_EN, 0); -- } -- -- ret = pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG, -- mask, enable ? mask : 0); -- mdelay(delay); -- -- return ret; --} -- --static int stpmu1_pwr_sw_probe(struct udevice *dev) --{ -- struct dm_regulator_uclass_platdata *uc_pdata; -- -- if (!dev->driver_data || dev->driver_data > STPMU1_MAX_PWR_SW) -- return -EINVAL; -- -- uc_pdata = dev_get_uclass_platdata(dev); -- -- uc_pdata->type = REGULATOR_TYPE_FIXED; -- uc_pdata->mode_count = 0; -- -- return 0; --} -- --static const struct dm_regulator_ops stpmu1_pwr_sw_ops = { -- .get_enable = stpmu1_pwr_sw_get_enable, -- .set_enable = stpmu1_pwr_sw_set_enable, --}; -- --U_BOOT_DRIVER(stpmu1_pwr_sw) = { -- .name = "stpmu1_pwr_sw", -- .id = UCLASS_REGULATOR, -- .ops = &stpmu1_pwr_sw_ops, -- .probe = stpmu1_pwr_sw_probe, --}; -diff --git a/drivers/ram/stm32mp1/Kconfig b/drivers/ram/stm32mp1/Kconfig -index b9c8166..761de09 100644 ---- a/drivers/ram/stm32mp1/Kconfig -+++ b/drivers/ram/stm32mp1/Kconfig -@@ -10,3 +10,32 @@ config STM32MP1_DDR - family: support for LPDDR2, LPDDR3 and DDR3 - the SDRAM parameters for controleur and phy need to be provided - in device tree (computed by DDR tuning tools) -+ -+config STM32MP1_DDR_INTERACTIVE -+ bool "STM32MP1 DDR driver : interactive support" -+ depends on STM32MP1_DDR -+ help -+ activate interactive support in STM32MP1 DDR controller driver -+ used for DDR tuning tools -+ to enter in intercative mode type 'd' during SPL DDR driver -+ initialisation -+ -+config STM32MP1_DDR_INTERACTIVE_FORCE -+ bool "STM32MP1 DDR driver : force interactive mode" -+ depends on STM32MP1_DDR_INTERACTIVE -+ default n -+ help -+ force interactive mode in STM32MP1 DDR controller driver -+ skip the polling of character 'd' in console -+ useful when SPL is loaded in sysram -+ directly by programmer -+ -+config STM32MP1_DDR_TUNING -+ bool "STM32MP1 DDR driver : support of tuning" -+ depends on SPL && STM32MP1_DDR_INTERACTIVE -+ default y -+ help -+ activate tuning command in STM32MP1 DDR interactive mode -+ used for DDR tuning tools -+ - DQ Deskew algorithm -+ - DQS Trimming -diff --git a/drivers/ram/stm32mp1/Makefile b/drivers/ram/stm32mp1/Makefile -index 79eb028..bc292d1 100644 ---- a/drivers/ram/stm32mp1/Makefile -+++ b/drivers/ram/stm32mp1/Makefile -@@ -5,3 +5,10 @@ - - obj-y += stm32mp1_ram.o - obj-y += stm32mp1_ddr.o -+ -+obj-$(CONFIG_STM32MP1_DDR_INTERACTIVE) += stm32mp1_interactive.o stm32mp1_tests.o -+obj-$(CONFIG_STM32MP1_DDR_TUNING) += stm32mp1_tuning.o -+ -+ifneq ($(DDR_INTERACTIVE),) -+CFLAGS_stm32mp1_interactive.o += -DCONFIG_STM32MP1_DDR_INTERACTIVE_FORCE=y -+endif -diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c -index c7c3ba7..a83ea39 100644 ---- a/drivers/ram/stm32mp1/stm32mp1_ddr.c -+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c -@@ -165,6 +165,32 @@ static const struct reg_desc ddrphy_cal[] = { - DDRPHY_REG_CAL(dx3dqstr), - }; - -+#define DDR_REG_DYN(x) \ -+ {#x,\ -+ offsetof(struct stm32mp1_ddrctl, x),\ -+ INVALID_OFFSET} -+ -+static const struct reg_desc ddr_dyn[] = { -+ DDR_REG_DYN(stat), -+ DDR_REG_DYN(init0), -+ DDR_REG_DYN(dfimisc), -+ DDR_REG_DYN(dfistat), -+ DDR_REG_DYN(swctl), -+ DDR_REG_DYN(swstat), -+ DDR_REG_DYN(pctrl_0), -+ DDR_REG_DYN(pctrl_1), -+}; -+ -+#define DDRPHY_REG_DYN(x) \ -+ {#x,\ -+ offsetof(struct stm32mp1_ddrphy, x),\ -+ INVALID_OFFSET} -+ -+static const struct reg_desc ddrphy_dyn[] = { -+ DDRPHY_REG_DYN(pir), -+ DDRPHY_REG_DYN(pgsr), -+}; -+ - enum reg_type { - REG_REG, - REG_TIMING, -@@ -173,6 +199,11 @@ enum reg_type { - REGPHY_REG, - REGPHY_TIMING, - REGPHY_CAL, -+/* dynamic registers => managed in driver or not changed, -+ * can be dumped in interactive mode -+ */ -+ REG_DYN, -+ REGPHY_DYN, - REG_TYPE_NB - }; - -@@ -206,6 +237,10 @@ const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = { - "timing", ddrphy_timing, ARRAY_SIZE(ddrphy_timing), DDRPHY_BASE}, - [REGPHY_CAL] = { - "cal", ddrphy_cal, ARRAY_SIZE(ddrphy_cal), DDRPHY_BASE}, -+[REG_DYN] = { -+ "dyn", ddr_dyn, ARRAY_SIZE(ddr_dyn), DDR_BASE}, -+[REGPHY_DYN] = { -+ "dyn", ddrphy_dyn, ARRAY_SIZE(ddrphy_dyn), DDRPHY_BASE}, - }; - - const char *base_name[] = { -@@ -277,10 +312,247 @@ void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, u32 pir) - ddrphy_idone_wait(phy); - } - -+#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE -+static void stm32mp1_dump_reg_desc(u32 base_addr, const struct reg_desc *desc) -+{ -+ unsigned int *ptr; -+ -+ ptr = (unsigned int *)(base_addr + desc->offset); -+#ifdef DEBUG -+ printf("[0x%08x] %s= 0x%08x\n", -+ (u32)ptr, desc->name, readl(ptr)); -+#else -+ printf("%s= 0x%08x\n", desc->name, readl(ptr)); -+#endif -+} -+ -+static void stm32mp1_dump_param_desc(u32 par_addr, const struct reg_desc *desc) -+{ -+ unsigned int *ptr; -+ -+ ptr = (unsigned int *)(par_addr + desc->par_offset); -+ printf("%s= 0x%08x\n", desc->name, readl(ptr)); -+} -+ -+static const struct reg_desc *found_reg(const char *name, enum reg_type *type) -+{ -+ unsigned int i, j; -+ const struct reg_desc *desc; -+ -+ for (i = 0; i < ARRAY_SIZE(ddr_registers); i++) { -+ desc = ddr_registers[i].desc; -+ for (j = 0; j < ddr_registers[i].size; j++) { -+ if (strcmp(name, desc[j].name) == 0) { -+ *type = i; -+ return &desc[j]; -+ } -+ } -+ } -+ *type = REG_TYPE_NB; -+ return NULL; -+} -+ -+int stm32mp1_dump_reg(const struct ddr_info *priv, -+ const char *name) -+{ -+ unsigned int i, j; -+ const struct reg_desc *desc; -+ u32 base_addr; -+ enum base_type p_base; -+ enum reg_type type; -+ const char *p_name; -+ enum base_type filter = NONE_BASE; -+ int result = -1; -+ -+ if (name) { -+ if (strcmp(name, base_name[DDR_BASE]) == 0) -+ filter = DDR_BASE; -+ else if (strcmp(name, base_name[DDRPHY_BASE]) == 0) -+ filter = DDRPHY_BASE; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(ddr_registers); i++) { -+ p_base = ddr_registers[i].base; -+ p_name = ddr_registers[i].name; -+ if (!name || (filter == p_base || !strcmp(name, p_name))) { -+ result = 0; -+ desc = ddr_registers[i].desc; -+ base_addr = get_base_addr(priv, p_base); -+ printf("==%s.%s==\n", base_name[p_base], p_name); -+ for (j = 0; j < ddr_registers[i].size; j++) -+ stm32mp1_dump_reg_desc(base_addr, &desc[j]); -+ } -+ } -+ if (result) { -+ desc = found_reg(name, &type); -+ if (desc) { -+ p_base = ddr_registers[type].base; -+ base_addr = get_base_addr(priv, p_base); -+ stm32mp1_dump_reg_desc(base_addr, desc); -+ result = 0; -+ } -+ } -+ return result; -+} -+ -+void stm32mp1_edit_reg(const struct ddr_info *priv, -+ char *name, char *string) -+{ -+ unsigned long *ptr, value; -+ enum reg_type type; -+ enum base_type base; -+ const struct reg_desc *desc; -+ u32 base_addr; -+ -+ desc = found_reg(name, &type); -+ -+ if (!desc) { -+ printf("%s not found\n", name); -+ return; -+ } -+ if (strict_strtoul(string, 16, &value) < 0) { -+ printf("invalid value %s\n", string); -+ return; -+ } -+ base = ddr_registers[type].base; -+ base_addr = get_base_addr(priv, base); -+ ptr = (unsigned long *)(base_addr + desc->offset); -+ writel(value, ptr); -+#ifdef DEBUG -+ printf("[0x%08x] %s= 0x%08lx (0x%08x)\n", -+ (u32)ptr, desc->name, value, readl(ptr)); -+#else -+ printf("%s= 0x%08x\n", desc->name, readl(ptr)); -+#endif -+} -+ -+static u32 get_par_addr(const struct stm32mp1_ddr_config *config, -+ enum reg_type type) -+{ -+ u32 par_addr = 0x0; -+ -+ switch (type) { -+ case REG_REG: -+ par_addr = (u32)&config->c_reg; -+ break; -+ case REG_TIMING: -+ par_addr = (u32)&config->c_timing; -+ break; -+ case REG_PERF: -+ par_addr = (u32)&config->c_perf; -+ break; -+ case REG_MAP: -+ par_addr = (u32)&config->c_map; -+ break; -+ case REGPHY_REG: -+ par_addr = (u32)&config->p_reg; -+ break; -+ 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: -+ par_addr = (u32)NULL; -+ break; -+ } -+ -+ return par_addr; -+} -+ -+int stm32mp1_dump_param(const struct stm32mp1_ddr_config *config, -+ const char *name) -+{ -+ unsigned int i, j; -+ const struct reg_desc *desc; -+ u32 par_addr; -+ enum base_type p_base; -+ enum reg_type type; -+ const char *p_name; -+ enum base_type filter = NONE_BASE; -+ int result = -EINVAL; -+ -+ if (name) { -+ if (strcmp(name, base_name[DDR_BASE]) == 0) -+ filter = DDR_BASE; -+ else if (strcmp(name, base_name[DDRPHY_BASE]) == 0) -+ filter = DDRPHY_BASE; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(ddr_registers); i++) { -+ par_addr = get_par_addr(config, i); -+ if (!par_addr) -+ continue; -+ p_base = ddr_registers[i].base; -+ p_name = ddr_registers[i].name; -+ if (!name || (filter == p_base || !strcmp(name, p_name))) { -+ result = 0; -+ desc = ddr_registers[i].desc; -+ printf("==%s.%s==\n", base_name[p_base], p_name); -+ for (j = 0; j < ddr_registers[i].size; j++) -+ stm32mp1_dump_param_desc(par_addr, &desc[j]); -+ } -+ } -+ if (result) { -+ desc = found_reg(name, &type); -+ if (desc) { -+ par_addr = get_par_addr(config, type); -+ if (par_addr) { -+ stm32mp1_dump_param_desc(par_addr, desc); -+ result = 0; -+ } -+ } -+ } -+ return result; -+} -+ -+void stm32mp1_edit_param(const struct stm32mp1_ddr_config *config, -+ char *name, char *string) -+{ -+ unsigned long *ptr, value; -+ enum reg_type type; -+ const struct reg_desc *desc; -+ u32 par_addr; -+ -+ desc = found_reg(name, &type); -+ if (!desc) { -+ printf("%s not found\n", name); -+ return; -+ } -+ if (strict_strtoul(string, 16, &value) < 0) { -+ printf("invalid value %s\n", string); -+ return; -+ } -+ par_addr = get_par_addr(config, type); -+ if (!par_addr) { -+ printf("no parameter %s\n", name); -+ return; -+ } -+ ptr = (unsigned long *)(par_addr + desc->par_offset); -+ writel(value, ptr); -+ printf("%s= 0x%08x\n", desc->name, readl(ptr)); -+} -+#endif -+ -+__weak bool stm32mp1_ddr_interactive(void *priv, -+ enum stm32mp1_ddr_interact_step step, -+ const struct stm32mp1_ddr_config *config) -+{ -+ return false; -+} -+ -+#define INTERACTIVE(step)\ -+ stm32mp1_ddr_interactive(priv, step, config) -+ - /* start quasi dynamic register update */ - static void start_sw_done(struct stm32mp1_ddrctl *ctl) - { - clrbits_le32(&ctl->swctl, DDRCTRL_SWCTL_SW_DONE); -+ debug("[0x%08x] swctl = 0x%08x\n", -+ (u32)&ctl->swctl, readl(&ctl->swctl)); - } - - /* wait quasi dynamic register update */ -@@ -312,7 +584,7 @@ static void wait_operating_mode(struct ddr_info *priv, int mode) - /* self-refresh due to software => check also STAT.selfref_type */ - if (mode == DDRCTRL_STAT_OPERATING_MODE_SR) { - mask |= DDRCTRL_STAT_SELFREF_TYPE_MASK; -- stat |= DDRCTRL_STAT_SELFREF_TYPE_SR; -+ val |= DDRCTRL_STAT_SELFREF_TYPE_SR; - } else if (mode == DDRCTRL_STAT_OPERATING_MODE_NORMAL) { - /* normal mode: handle also automatic self refresh */ - mask2 = DDRCTRL_STAT_OPERATING_MODE_MASK | -@@ -332,6 +604,182 @@ static void wait_operating_mode(struct ddr_info *priv, int mode) - debug("[0x%08x] stat = 0x%08x\n", (u32)&priv->ctl->stat, stat); - } - -+/* Mode Register Writes (MRW or MRS) */ -+void mode_register_write(struct ddr_info *priv, u8 addr, u16 data) -+{ -+ u32 mrctrl0; -+ -+ debug("MRS: %d = %x\n", addr, data); -+ -+ /* 1. Poll MRSTAT.mr_wr_busy until it is '0'. -+ * This checks that there is no outstanding MR transaction. -+ * No writes should be performed to MRCTRL0 and MRCTRL1 -+ * if MRSTAT.mr_wr_busy = 1. -+ */ -+ while (readl(&priv->ctl->mrstat) & DDRCTRL_MRSTAT_MR_WR_BUSY) -+ ; -+ -+ /* 2. Write the MRCTRL0.mr_type, MRCTRL0.mr_addr, MRCTRL0.mr_rank -+ * and (for MRWs) MRCTRL1.mr_data to define the MR transaction. -+ */ -+ mrctrl0 = DDRCTRL_MRCTRL0_MR_TYPE_WRITE | -+ DDRCTRL_MRCTRL0_MR_RANK_ALL | -+ ((addr << DDRCTRL_MRCTRL0_MR_ADDR_SHIFT) -+ & DDRCTRL_MRCTRL0_MR_ADDR_MASK); -+ writel(mrctrl0, &priv->ctl->mrctrl0); -+ debug("[0x%08x] mrctrl0 = 0x%08x (0x%08x)\n", -+ (u32)&priv->ctl->mrctrl0, -+ readl(&priv->ctl->mrctrl0), mrctrl0); -+ writel(data, &priv->ctl->mrctrl1); -+ debug("[0x%08x] mrctrl1 = 0x%08x\n", -+ (u32)&priv->ctl->mrctrl1, readl(&priv->ctl->mrctrl1)); -+ -+ /* 3. In a separate APB transaction, write the MRCTRL0.mr_wr to 1. This -+ * bit is self-clearing, and triggers the MR transaction. -+ * The uMCTL2 then asserts the MRSTAT.mr_wr_busy while it performs -+ * the MR transaction to SDRAM, and no further accesses can be -+ * initiated until it is deasserted -+ */ -+ mrctrl0 |= DDRCTRL_MRCTRL0_MR_WR; -+ writel(mrctrl0, &priv->ctl->mrctrl0); -+ -+ while (readl(&priv->ctl->mrstat) & DDRCTRL_MRSTAT_MR_WR_BUSY) -+ ; -+ debug("[0x%08x] mrctrl0 = 0x%08x\n", -+ (u32)&priv->ctl->mrctrl0, mrctrl0); -+} -+ -+/* switch DDR3 from DLL-on to DLL-off */ -+static void ddr3_dll_off(struct ddr_info *priv) -+{ -+ u32 mr1 = readl(&priv->phy->mr1); -+ u32 mr2 = readl(&priv->phy->mr2); -+ u32 dbgcam; -+ -+ debug("%s: entry\n", __func__); -+ debug("mr1: 0x%08x\n", mr1); -+ debug("mr2: 0x%08x\n", mr2); -+ /* 1. Set the DBG1.dis_hif = 1. -+ * This prevents further reads/writes being received on the HIF. -+ */ -+ setbits_le32(&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF); -+ debug("[0x%08x] dbg1 = 0x%08x\n", -+ (u32)&priv->ctl->dbg1, readl(&priv->ctl->dbg1)); -+ -+ /* 2. Ensure all commands have been flushed from the uMCTL2 by polling -+ * DBGCAM.wr_data_pipeline_empty = 1, -+ * DBGCAM.rd_data_pipeline_empty = 1, -+ * DBGCAM.dbg_wr_q_depth = 0 , -+ * DBGCAM.dbg_lpr_q_depth = 0, and -+ * DBGCAM.dbg_hpr_q_depth = 0. -+ */ -+ do { -+ dbgcam = readl(&priv->ctl->dbgcam); -+ debug("[0x%08x] dbgcam = 0x%08x\n", -+ (u32)&priv->ctl->dbgcam, dbgcam); -+ } while (((dbgcam & DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY) == -+ DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY) && -+ !(dbgcam & DDRCTRL_DBGCAM_DBG_Q_DEPTH)); -+ -+ /* 3. Perform an MRS command (using MRCTRL0 and MRCTRL1 registers) -+ * to disable RTT_NOM: -+ * a. DDR3: Write to MR1[9], MR1[6] and MR1[2] -+ * b. DDR4: Write to MR1[10:8] -+ */ -+ mr1 &= ~(BIT(9) | BIT(6) | BIT(2)); -+ mode_register_write(priv, 1, mr1); -+ -+ /* 4. For DDR4 only: Perform an MRS command -+ * (using MRCTRL0 and MRCTRL1 registers) to write to MR5[8:6] -+ * to disable RTT_PARK -+ */ -+ -+ /* 5. Perform an MRS command (using MRCTRL0 and MRCTRL1 registers) -+ * to write to MR2[10:9], to disable RTT_WR -+ * (and therefore disable dynamic ODT). -+ * This applies for both DDR3 and DDR4. -+ */ -+ mr2 &= ~GENMASK(10, 9); -+ mode_register_write(priv, 2, mr2); -+ -+ /* 6. Perform an MRS command (using MRCTRL0 and MRCTRL1 registers) -+ * to disable the DLL. The timing of this MRS is automatically -+ * handled by the uMCTL2. -+ * a. DDR3: Write to MR1[0] -+ * b. DDR4: Write to MR1[0] -+ */ -+ mr1 |= BIT(0); -+ mode_register_write(priv, 1, mr1); -+ -+ /* 7. Put the SDRAM into self-refresh mode by setting -+ * PWRCTL.selfref_sw = 1, and polling STAT.operating_mode to ensure -+ * the DDRC has entered self-refresh. -+ */ -+ setbits_le32(&priv->ctl->pwrctl, -+ DDRCTRL_PWRCTL_SELFREF_SW); -+ debug("[0x%08x] pwrctl = 0x%08x\n", -+ (u32)&priv->ctl->pwrctl, -+ readl(&priv->ctl->pwrctl)); -+ -+ /* 8. Wait until STAT.operating_mode[1:0]==11 indicating that the -+ * DWC_ddr_umctl2 core is in self-refresh mode. -+ * Ensure transition to self-refresh was due to software -+ * by checking that STAT.selfref_type[1:0]=2. -+ */ -+ wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_SR); -+ -+ /* 9. Set the MSTR.dll_off_mode = 1. -+ * warning: MSTR.dll_off_mode is a quasi-dynamic type 2 field -+ */ -+ start_sw_done(priv->ctl); -+ -+ setbits_le32(&priv->ctl->mstr, DDRCTRL_MSTR_DLL_OFF_MODE); -+ debug("[0x%08x] mstr = 0x%08x\n", -+ (u32)&priv->ctl->mstr, -+ readl(&priv->ctl->mstr)); -+ -+ wait_sw_done_ack(priv->ctl); -+ -+ /* 10. Change the clock frequency to the desired value. */ -+ -+ /* 11. Update any registers which may be required to change for the new -+ * frequency. This includes static and dynamic registers. -+ * This includes both uMCTL2 registers and PHY registers. -+ */ -+ /* change Bypass Mode Frequency Range */ -+ if (clk_get_rate(&priv->clk) < 100000000) -+ clrbits_le32(&priv->phy->dllgcr, DDRPHYC_DLLGCR_BPS200); -+ else -+ setbits_le32(&priv->phy->dllgcr, DDRPHYC_DLLGCR_BPS200); -+ -+ setbits_le32(&priv->phy->acdllcr, DDRPHYC_ACDLLCR_DLLDIS); -+ -+ setbits_le32(&priv->phy->dx0dllcr, DDRPHYC_DXNDLLCR_DLLDIS); -+ setbits_le32(&priv->phy->dx1dllcr, DDRPHYC_DXNDLLCR_DLLDIS); -+ setbits_le32(&priv->phy->dx2dllcr, DDRPHYC_DXNDLLCR_DLLDIS); -+ setbits_le32(&priv->phy->dx3dllcr, DDRPHYC_DXNDLLCR_DLLDIS); -+ -+ /* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */ -+ clrbits_le32(&priv->ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_SW); -+ wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL); -+ -+ /* 13. If ZQCTL0.dis_srx_zqcl = 0, the uMCTL2 performs a ZQCL command -+ * at this point. -+ */ -+ -+ /* 14. Perform MRS commands as required to re-program timing registers -+ * in the SDRAM for the new frequency -+ * (in particular, CL, CWL and WR may need to be changed). -+ */ -+ -+ /* 15. Write DBG1.dis_hif = 0 to re-enable reads and writes.*/ -+ clrbits_le32(&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF); -+ debug("[0x%08x] dbg1 = 0x%08x\n", -+ (u32)&priv->ctl->dbg1, readl(&priv->ctl->dbg1)); -+ -+ debug("%s: exit\n", __func__); -+} -+ - void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl) - { - start_sw_done(ctl); -@@ -355,7 +803,7 @@ void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl, - } - - /* board-specific DDR power initializations. */ --__weak int board_ddr_power_init(void) -+__weak int board_ddr_power_init(enum ddr_type ddr_type) - { - return 0; - } -@@ -365,16 +813,25 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - const struct stm32mp1_ddr_config *config) - { - u32 pir; -- int ret; -+ int ret = -EINVAL; - -- ret = board_ddr_power_init(); -+ if (config->c_reg.mstr & DDRCTRL_MSTR_DDR3) -+ ret = board_ddr_power_init(STM32MP_DDR3); -+ else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2) -+ ret = board_ddr_power_init(STM32MP_LPDDR2); -+ else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3) -+ ret = board_ddr_power_init(STM32MP_LPDDR3); - - if (ret) - panic("ddr power init failed\n"); - -+start: -+ debug("%s entry\n", __func__); -+ - debug("name = %s\n", config->info.name); -- debug("speed = %d MHz\n", config->info.speed); -+ debug("speed = %d kHz\n", config->info.speed); - debug("size = 0x%x\n", config->info.size); -+ - /* - * 1. Program the DWC_ddr_umctl2 registers - * 1.1 RESETS: presetn, core_ddrc_rstn, aresetn -@@ -389,7 +846,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - - /* 1.2. start CLOCK */ - if (stm32mp1_ddr_clk_enable(priv, config->info.speed)) -- panic("invalid DRAM clock : %d MHz\n", -+ panic("invalid DRAM clock : %d kHz\n", - config->info.speed); - - /* 1.3. deassert reset */ -@@ -401,11 +858,12 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - */ - clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAPBRST); - --/* 1.4. wait 4 cycles for synchronization */ -- asm(" nop"); -- asm(" nop"); -- asm(" nop"); -- asm(" nop"); -+/* 1.4. wait 128 cycles to permit initialization of end logic */ -+ udelay(2); -+ /* for PCLK = 133MHz => 1 us is enough, 2 to allow lower frequency */ -+ -+ if (INTERACTIVE(STEP_DDR_RESET)) -+ goto start; - - /* 1.5. initialize registers ddr_umctl2 */ - /* Stop uMCTL2 before PHY is ready */ -@@ -414,6 +872,17 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - (u32)&priv->ctl->dfimisc, readl(&priv->ctl->dfimisc)); - - set_reg(priv, REG_REG, &config->c_reg); -+ -+ /* DDR3 = don't set DLLOFF for init mode */ -+ if ((config->c_reg.mstr & -+ (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) -+ == (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) { -+ debug("deactivate DLL OFF in mstr\n"); -+ clrbits_le32(&priv->ctl->mstr, DDRCTRL_MSTR_DLL_OFF_MODE); -+ debug("[0x%08x] mstr = 0x%08x\n", -+ (u32)&priv->ctl->mstr, readl(&priv->ctl->mstr)); -+ } -+ - set_reg(priv, REG_TIMING, &config->c_timing); - set_reg(priv, REG_MAP, &config->c_map); - -@@ -421,9 +890,14 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - clrsetbits_le32(&priv->ctl->init0, - DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK, - DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL); -+ debug("[0x%08x] init0 = 0x%08x\n", -+ (u32)&priv->ctl->init0, readl(&priv->ctl->init0)); - - set_reg(priv, REG_PERF, &config->c_perf); - -+ if (INTERACTIVE(STEP_CTL_INIT)) -+ goto start; -+ - /* 2. deassert reset signal core_ddrc_rstn, aresetn and presetn */ - clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCORERST); - clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAXIRST); -@@ -436,6 +910,19 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - set_reg(priv, REGPHY_TIMING, &config->p_timing); - set_reg(priv, REGPHY_CAL, &config->p_cal); - -+ /* DDR3 = don't set DLLOFF for init mode */ -+ if ((config->c_reg.mstr & -+ (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) -+ == (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) { -+ debug("deactivate DLL OFF in mr1\n"); -+ clrbits_le32(&priv->phy->mr1, BIT(0)); -+ debug("[0x%08x] mr1 = 0x%08x\n", -+ (u32)&priv->phy->mr1, readl(&priv->phy->mr1)); -+ } -+ -+ if (INTERACTIVE(STEP_PHY_INIT)) -+ goto start; -+ - /* 4. Monitor PHY init status by polling PUBL register PGSR.IDONE - * Perform DDR PHY DRAM initialization and Gate Training Evaluation - */ -@@ -445,6 +932,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - * by setting PIR.INIT and PIR CTLDINIT and pool PGSR.IDONE - * DRAM init is done by PHY, init0.skip_dram.init = 1 - */ -+ - pir = DDRPHYC_PIR_DLLSRST | DDRPHYC_PIR_DLLLOCK | DDRPHYC_PIR_ZCAL | - DDRPHYC_PIR_ITMSRST | DDRPHYC_PIR_DRAMINIT | DDRPHYC_PIR_ICPC; - -@@ -456,7 +944,12 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - /* 6. SET DFIMISC.dfi_init_complete_en to 1 */ - /* Enable quasi-dynamic register programming*/ - start_sw_done(priv->ctl); -+ - setbits_le32(&priv->ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); -+ debug("[0x%08x] dfimisc = 0x%08x\n", -+ (u32)&priv->ctl->dfimisc, -+ readl(&priv->ctl->dfimisc)); -+ - wait_sw_done_ack(priv->ctl); - - /* 7. Wait for DWC_ddr_umctl2 to move to normal operation mode -@@ -466,6 +959,10 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - - wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL); - -+ /* switch to DLL OFF mode */ -+ if (config->c_reg.mstr & DDRCTRL_MSTR_DLL_OFF_MODE) -+ ddr3_dll_off(priv); -+ - debug("DDR DQS training : "); - /* 8. Disable Auto refresh and power down by setting - * - RFSHCTL3.dis_au_refresh = 1 -@@ -492,4 +989,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - /* enable uMCTL2 AXI port 0 and 1 */ - setbits_le32(&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN); - setbits_le32(&priv->ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN); -+ -+ if (INTERACTIVE(STEP_DDR_READY)) -+ goto start; - } -diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.h b/drivers/ram/stm32mp1/stm32mp1_ddr.h -index 3cd0161..90b4a4b 100644 ---- a/drivers/ram/stm32mp1/stm32mp1_ddr.h -+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.h -@@ -26,6 +26,7 @@ struct stm32mp1_ddrphy; - * @ctl: DDR controleur base address - * @clk: DDR clock - * @phy: DDR PHY base address -+ * @pwr: pwr base address - * @rcc: rcc base address - */ - struct ddr_info { -@@ -34,6 +35,7 @@ struct ddr_info { - struct clk clk; - struct stm32mp1_ddrctl *ctl; - struct stm32mp1_ddrphy *phy; -+ void *pwr; - u32 rcc; - }; - -@@ -157,7 +159,7 @@ struct stm32mp1_ddrphy_cal { - - struct stm32mp1_ddr_info { - const char *name; -- u16 speed; /* in MHZ */ -+ u32 speed; /* in kHZ */ - u32 size; /* memory size in byte = col * row * width */ - }; - -@@ -172,7 +174,7 @@ struct stm32mp1_ddr_config { - struct stm32mp1_ddrphy_cal p_cal; - }; - --int stm32mp1_ddr_clk_enable(struct ddr_info *priv, u16 mem_speed); -+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, -@@ -197,10 +199,6 @@ void stm32mp1_edit_param(const struct stm32mp1_ddr_config *config, - char *name, - char *string); - --void stm32mp1_dump_info( -- const struct ddr_info *priv, -- const struct stm32mp1_ddr_config *config); -- - bool stm32mp1_ddr_interactive( - void *priv, - enum stm32mp1_ddr_interact_step step, -diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h -index a606b2b..9d33186 100644 ---- a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h -+++ b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h -@@ -234,6 +234,8 @@ struct stm32mp1_ddrphy { - - /* DDRCTRL REGISTERS */ - #define DDRCTRL_MSTR_DDR3 BIT(0) -+#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_FULL (0 << 12) - #define DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF (1 << 12) -@@ -330,6 +332,7 @@ struct stm32mp1_ddrphy { - - #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 -diff --git a/drivers/ram/stm32mp1/stm32mp1_interactive.c b/drivers/ram/stm32mp1/stm32mp1_interactive.c -new file mode 100644 -index 0000000..3840af5 ---- /dev/null -+++ b/drivers/ram/stm32mp1/stm32mp1_interactive.c -@@ -0,0 +1,467 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "stm32mp1_ddr.h" -+#include "stm32mp1_tests.h" -+ -+DECLARE_GLOBAL_DATA_PTR; -+ -+enum ddr_command { -+ DDR_CMD_HELP, -+ DDR_CMD_INFO, -+ DDR_CMD_FREQ, -+ DDR_CMD_RESET, -+ DDR_CMD_PARAM, -+ DDR_CMD_PRINT, -+ DDR_CMD_EDIT, -+ DDR_CMD_STEP, -+ DDR_CMD_NEXT, -+ DDR_CMD_GO, -+ DDR_CMD_TEST, -+ DDR_CMD_TUNING, -+ DDR_CMD_UNKNOWN, -+}; -+ -+const char *step_str[] = { -+ [STEP_DDR_RESET] = "DDR_RESET", -+ [STEP_CTL_INIT] = "DDR_CTRL_INIT_DONE", -+ [STEP_PHY_INIT] = "DDR PHY_INIT_DONE", -+ [STEP_DDR_READY] = "DDR_READY", -+ [STEP_RUN] = "RUN" -+}; -+ -+enum ddr_command stm32mp1_get_command(char *cmd, int argc) -+{ -+ const char *cmd_string[DDR_CMD_UNKNOWN] = { -+ [DDR_CMD_HELP] = "help", -+ [DDR_CMD_INFO] = "info", -+ [DDR_CMD_FREQ] = "freq", -+ [DDR_CMD_RESET] = "reset", -+ [DDR_CMD_PARAM] = "param", -+ [DDR_CMD_PRINT] = "print", -+ [DDR_CMD_EDIT] = "edit", -+ [DDR_CMD_STEP] = "step", -+ [DDR_CMD_NEXT] = "next", -+ [DDR_CMD_GO] = "go", -+ [DDR_CMD_TEST] = "test", -+#ifdef CONFIG_STM32MP1_DDR_TUNING -+ [DDR_CMD_TUNING] = "tuning", -+#endif -+ }; -+ /* min and max number of argument */ -+ const char cmd_arg[DDR_CMD_UNKNOWN][2] = { -+ [DDR_CMD_HELP] = { 0, 0 }, -+ [DDR_CMD_INFO] = { 0, 255 }, -+ [DDR_CMD_FREQ] = { 0, 1 }, -+ [DDR_CMD_RESET] = { 0, 0 }, -+ [DDR_CMD_PARAM] = { 0, 2 }, -+ [DDR_CMD_PRINT] = { 0, 1 }, -+ [DDR_CMD_EDIT] = { 2, 2 }, -+ [DDR_CMD_STEP] = { 0, 1 }, -+ [DDR_CMD_NEXT] = { 0, 0 }, -+ [DDR_CMD_GO] = { 0, 0 }, -+ [DDR_CMD_TEST] = { 0, 255 }, -+#ifdef CONFIG_STM32MP1_DDR_TUNING -+ [DDR_CMD_TUNING] = { 0, 255 }, -+#endif -+ }; -+ int i; -+ -+ for (i = 0; i < DDR_CMD_UNKNOWN; i++) -+ if (!strcmp(cmd, cmd_string[i])) { -+ if (argc - 1 < cmd_arg[i][0]) { -+ printf("no enought argument (min=%d)\n", -+ cmd_arg[i][0]); -+ return DDR_CMD_UNKNOWN; -+ } else if (argc - 1 > cmd_arg[i][1]) { -+ printf("too many argument (max=%d)\n", -+ cmd_arg[i][1]); -+ return DDR_CMD_UNKNOWN; -+ } else { -+ return i; -+ } -+ } -+ -+ printf("unknown command %s\n", cmd); -+ return DDR_CMD_UNKNOWN; -+} -+ -+static void stm32mp1_do_usage(void) -+{ -+ const char *usage = { -+ "commands:\n\n" -+ "help this message\n" -+ "info [ ] display/change DDR information\n" -+ "freq [freq] display/change the DDR frequency\n" -+ "param [type|reg] print input parameters\n" -+ "param edit parameters in step 0\n" -+ "print [type|reg] dump register\n" -+ "edit modify register\n" -+ " all registers if [type|reg] is absent\n" -+ " = ctl, phy\n" -+ " or one category (static, timing, map, perf, cal, dyn)\n" -+ " = name of the register\n" -+ "step [n] list the step / go to the step \n" -+ "next go to the next step\n" -+ "go continue SPL execution\n" -+ "reset reboot machine\n" -+ "test [help] | [...] list (with help) or execute test \n" -+#ifdef CONFIG_STM32MP1_DDR_TUNING -+ "tuning [help] | [...] list (with help) or execute test \n" -+#endif -+ }; -+ -+ puts(usage); -+} -+ -+static bool stm32mp1_check_step(enum stm32mp1_ddr_interact_step step, -+ enum stm32mp1_ddr_interact_step expected) -+{ -+ if (step != expected) { -+ printf("invalid step %d:%s expecting %d:%s\n", -+ step, step_str[step], -+ expected, -+ step_str[expected]); -+ return false; -+ } -+ return true; -+} -+ -+static void stm32mp1_do_info(struct ddr_info *priv, -+ struct stm32mp1_ddr_config *config, -+ enum stm32mp1_ddr_interact_step step, -+ int argc, char * const argv[]) -+{ -+ unsigned long value; -+ static char *ddr_name; -+ -+ if (argc == 1) { -+ printf("step = %d : %s\n", step, step_str[step]); -+ printf("name = %s\n", config->info.name); -+ printf("size = 0x%x\n", config->info.size); -+ printf("speed = %d kHz\n", config->info.speed); -+ return; -+ } -+ -+ if (argc < 3) { -+ printf("no enought parameter\n"); -+ return; -+ } -+ if (!strcmp(argv[1], "name")) { -+ u32 i, name_len = 0; -+ -+ for (i = 2; i < argc; i++) -+ name_len += strlen(argv[i]) + 1; -+ if (ddr_name) -+ free(ddr_name); -+ ddr_name = malloc(name_len); -+ config->info.name = ddr_name; -+ if (!ddr_name) { -+ printf("alloc error, length %d\n", name_len); -+ return; -+ } -+ strcpy(ddr_name, argv[2]); -+ for (i = 3; i < argc; i++) { -+ strcat(ddr_name, " "); -+ strcat(ddr_name, argv[i]); -+ } -+ printf("name = %s\n", ddr_name); -+ return; -+ } -+ if (!strcmp(argv[1], "size")) { -+ if (strict_strtoul(argv[2], 16, &value) < 0) { -+ printf("invalid value %s\n", argv[2]); -+ } else { -+ config->info.size = value; -+ printf("size = 0x%x\n", config->info.size); -+ } -+ return; -+ } -+ if (!strcmp(argv[1], "speed")) { -+ if (strict_strtoul(argv[2], 10, &value) < 0) { -+ printf("invalid value %s\n", argv[2]); -+ } else { -+ config->info.speed = value; -+ printf("speed = %d kHz\n", config->info.speed); -+ value = clk_get_rate(&priv->clk); -+ printf("DDRPHY = %ld kHz\n", value / 1000); -+ } -+ return; -+ } -+ printf("argument %s invalid\n", argv[1]); -+} -+ -+static bool stm32mp1_do_freq(struct ddr_info *priv, -+ int argc, char * const argv[]) -+{ -+ unsigned long ddrphy_clk; -+ -+ if (argc == 2) { -+ if (strict_strtoul(argv[1], 0, &ddrphy_clk) < 0) { -+ printf("invalid argument %s", argv[1]); -+ return false; -+ } -+ if (clk_set_rate(&priv->clk, ddrphy_clk * 1000)) { -+ printf("ERROR: update failed!\n"); -+ return false; -+ } -+ } -+ ddrphy_clk = clk_get_rate(&priv->clk); -+ printf("DDRPHY = %ld kHz\n", ddrphy_clk / 1000); -+ if (argc == 2) -+ return true; -+ return false; -+} -+ -+static void stm32mp1_do_param(enum stm32mp1_ddr_interact_step step, -+ const struct stm32mp1_ddr_config *config, -+ int argc, char * const argv[]) -+{ -+ switch (argc) { -+ case 1: -+ stm32mp1_dump_param(config, NULL); -+ break; -+ case 2: -+ if (stm32mp1_dump_param(config, argv[1])) -+ printf("invalid argument %s\n", -+ argv[1]); -+ break; -+ case 3: -+ if (!stm32mp1_check_step(step, STEP_DDR_RESET)) -+ return; -+ stm32mp1_edit_param(config, argv[1], argv[2]); -+ break; -+ } -+} -+ -+static void stm32mp1_do_print(struct ddr_info *priv, -+ int argc, char * const argv[]) -+{ -+ switch (argc) { -+ case 1: -+ stm32mp1_dump_reg(priv, NULL); -+ break; -+ case 2: -+ if (stm32mp1_dump_reg(priv, argv[1])) -+ printf("invalid argument %s\n", -+ argv[1]); -+ break; -+ } -+} -+ -+static int stm32mp1_do_step(enum stm32mp1_ddr_interact_step step, -+ int argc, char * const argv[]) -+{ -+ int i; -+ unsigned long value; -+ -+ switch (argc) { -+ case 1: -+ for (i = 0; i < ARRAY_SIZE(step_str); i++) -+ printf("%d:%s\n", i, step_str[i]); -+ break; -+ -+ case 2: -+ if ((strict_strtoul(argv[1], 0, -+ &value) < 0) || -+ value >= ARRAY_SIZE(step_str)) { -+ printf("invalid argument %s\n", -+ argv[1]); -+ goto end; -+ } -+ -+ if (value != STEP_DDR_RESET && -+ value <= step) { -+ printf("invalid target %d:%s, current step is %d:%s\n", -+ (int)value, step_str[value], -+ step, step_str[step]); -+ goto end; -+ } -+ printf("step to %d:%s\n", -+ (int)value, step_str[value]); -+ return (int)value; -+ }; -+ -+end: -+ return step; -+} -+ -+static const char * const s_result[] = { -+ [TEST_PASSED] = "Pass", -+ [TEST_FAILED] = "Failed", -+ [TEST_ERROR] = "Error" -+}; -+ -+static void stm32mp1_ddr_subcmd(struct ddr_info *priv, -+ int argc, char *argv[], -+ const struct test_desc array[], -+ const int array_nb) -+{ -+ int i; -+ unsigned long value; -+ int result; -+ char string[50] = ""; -+ -+ if (argc == 1) { -+ printf("%s:%d\n", argv[0], array_nb); -+ for (i = 0; i < array_nb; i++) -+ printf("%d:%s:%s\n", -+ i, array[i].name, array[i].usage); -+ return; -+ } -+ if (argc > 1 && !strcmp(argv[1], "help")) { -+ printf("%s:%d\n", argv[0], array_nb); -+ for (i = 0; i < array_nb; i++) -+ printf("%d:%s:%s:%s\n", i, -+ array[i].name, array[i].usage, array[i].help); -+ return; -+ } -+ -+ if ((strict_strtoul(argv[1], 0, &value) < 0) || -+ value >= array_nb) { -+ sprintf(string, "invalid argument %s", -+ argv[1]); -+ result = TEST_FAILED; -+ goto end; -+ } -+ -+ if (argc > (array[value].max_args + 2)) { -+ sprintf(string, "invalid nb of args %d, max %d", -+ argc - 2, array[value].max_args); -+ result = TEST_FAILED; -+ goto end; -+ } -+ -+ printf("execute %d:%s\n", (int)value, array[value].name); -+ clear_ctrlc(); -+ result = array[value].fct(priv->ctl, priv->phy, -+ string, argc - 2, &argv[2]); -+ -+end: -+ printf("Result: %s [%s]\n", s_result[result], string); -+} -+ -+bool stm32mp1_ddr_interactive(void *priv, -+ enum stm32mp1_ddr_interact_step step, -+ const struct stm32mp1_ddr_config *config) -+{ -+ const char *prompt = "DDR>"; -+ char buffer[CONFIG_SYS_CBSIZE]; -+ char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ -+ int argc; -+ static int next_step = -1; -+ -+ if (next_step < 0 && step == STEP_DDR_RESET) { -+#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE_FORCE -+ gd->flags &= ~(GD_FLG_SILENT | -+ GD_FLG_DISABLE_CONSOLE); -+ next_step = STEP_DDR_RESET; -+#else -+ unsigned long start = get_timer(0); -+ -+ while (1) { -+ if (tstc() && (getc() == 'd')) { -+ next_step = STEP_DDR_RESET; -+ break; -+ } -+ if (get_timer(start) > 100) -+ break; -+ } -+#endif -+ } -+ -+ debug("** step %d ** %s / %d\n", step, step_str[step], next_step); -+ -+ if (next_step < 0) -+ return false; -+ -+ if (step < 0 || step > ARRAY_SIZE(step_str)) { -+ printf("** step %d ** INVALID\n", step); -+ return false; -+ } -+ -+ printf("%d:%s\n", step, step_str[step]); -+ printf("%s\n", prompt); -+ -+ if (next_step > step) -+ return false; -+ -+ while (next_step == step) { -+ cli_readline_into_buffer(prompt, buffer, 0); -+ argc = cli_simple_parse_line(buffer, argv); -+ if (!argc) -+ continue; -+ -+ switch (stm32mp1_get_command(argv[0], argc)) { -+ case DDR_CMD_HELP: -+ stm32mp1_do_usage(); -+ break; -+ -+ case DDR_CMD_INFO: -+ stm32mp1_do_info(priv, -+ (struct stm32mp1_ddr_config *)config, -+ step, argc, argv); -+ break; -+ -+ case DDR_CMD_FREQ: -+ if (stm32mp1_do_freq(priv, argc, argv)) -+ next_step = STEP_DDR_RESET; -+ break; -+ -+ case DDR_CMD_RESET: -+ do_reset(NULL, 0, 0, NULL); -+ break; -+ -+ case DDR_CMD_PARAM: -+ stm32mp1_do_param(step, config, argc, argv); -+ break; -+ -+ case DDR_CMD_PRINT: -+ stm32mp1_do_print(priv, argc, argv); -+ break; -+ -+ case DDR_CMD_EDIT: -+ stm32mp1_edit_reg(priv, argv[1], argv[2]); -+ break; -+ -+ case DDR_CMD_GO: -+ next_step = STEP_RUN; -+ break; -+ -+ case DDR_CMD_NEXT: -+ next_step = step + 1; -+ break; -+ -+ case DDR_CMD_STEP: -+ next_step = stm32mp1_do_step(step, argc, argv); -+ break; -+ -+ case DDR_CMD_TEST: -+ if (!stm32mp1_check_step(step, STEP_DDR_READY)) -+ continue; -+ stm32mp1_ddr_subcmd(priv, argc, argv, test, test_nb); -+ break; -+ -+#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; -+ } -+ } -+ return next_step == STEP_DDR_RESET; -+} -diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c b/drivers/ram/stm32mp1/stm32mp1_ram.c -index bd497a3..6245cb4 100644 ---- a/drivers/ram/stm32mp1/stm32mp1_ram.c -+++ b/drivers/ram/stm32mp1/stm32mp1_ram.c -@@ -12,6 +12,8 @@ - #include - #include "stm32mp1_ddr.h" - -+DECLARE_GLOBAL_DATA_PTR; -+ - static const char *const clkname[] = { - "ddrc1", - "ddrc2", -@@ -20,7 +22,7 @@ static const char *const clkname[] = { - "ddrphyc" /* LAST clock => used for get_rate() */ - }; - --int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed) -+int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) - { - unsigned long ddrphy_clk; - unsigned long ddr_clk; -@@ -43,16 +45,15 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed) - priv->clk = clk; - ddrphy_clk = clk_get_rate(&priv->clk); - -- debug("DDR: mem_speed (%d MHz), RCC %d MHz\n", -- mem_speed, (u32)(ddrphy_clk / 1000 / 1000)); -+ debug("DDR: mem_speed (%d kHz), RCC %d kHz\n", -+ mem_speed, (u32)(ddrphy_clk / 1000)); - /* max 10% frequency delta */ -- ddr_clk = abs(ddrphy_clk - mem_speed * 1000 * 1000); -- if (ddr_clk > (mem_speed * 1000 * 100)) { -- pr_err("DDR expected freq %d MHz, current is %d MHz\n", -- mem_speed, (u32)(ddrphy_clk / 1000 / 1000)); -- return -EINVAL; -+ ddr_clk = abs(ddrphy_clk - mem_speed * 1000); -+ if (ddr_clk > (mem_speed * 100)) { -+ pr_err("DDR expected freq %d kHz, current is %d kHz\n", -+ mem_speed, (u32)(ddrphy_clk / 1000)); -+ return -1; - } -- - return 0; - } - -@@ -108,6 +109,7 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) - } - } - -+ - ret = clk_get_by_name(dev, "axidcg", &axidcg); - if (ret) { - debug("%s: Cannot found axidcg\n", __func__); -@@ -141,7 +143,7 @@ static int stm32mp1_ddr_probe(struct udevice *dev) - { - struct ddr_info *priv = dev_get_priv(dev); - struct regmap *map; -- int ret; -+ int ret = 0; - - debug("STM32MP1 DDR probe\n"); - priv->dev = dev; -@@ -153,11 +155,17 @@ static int stm32mp1_ddr_probe(struct udevice *dev) - priv->ctl = regmap_get_range(map, 0); - priv->phy = regmap_get_range(map, 1); - -+ map = syscon_get_regmap_by_driver_data(STM32MP_SYSCON_PWR); -+ if (IS_ERR(map)) -+ return PTR_ERR(map); -+ priv->pwr = regmap_get_range(map, 0); -+ - priv->rcc = STM32_RCC_BASE; - - priv->info.base = STM32_DDR_BASE; - --#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) -+#if !defined(CONFIG_STM32MP1_TRUSTED) && \ -+ (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) - priv->info.size = 0; - return stm32mp1_ddr_setup(dev); - #else -diff --git a/drivers/ram/stm32mp1/stm32mp1_tests.c b/drivers/ram/stm32mp1/stm32mp1_tests.c -new file mode 100644 -index 0000000..5f2af4e ---- /dev/null -+++ b/drivers/ram/stm32mp1/stm32mp1_tests.c -@@ -0,0 +1,1360 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+#include -+#include -+#include -+#include -+#include "stm32mp1_tests.h" -+ -+#define ADDR_INVALID 0xFFFFFFFF -+ -+DECLARE_GLOBAL_DATA_PTR; -+ -+static int get_bufsize(char *string, int argc, char *argv[], int arg_nb, -+ size_t *bufsize, size_t default_size) -+{ -+ unsigned long value; -+ -+ if (argc > arg_nb) { -+ if (strict_strtoul(argv[arg_nb], 0, &value) < 0) { -+ sprintf(string, "invalid %d parameter %s", -+ arg_nb, argv[arg_nb]); -+ return -1; -+ } -+ if (value > STM32_DDR_SIZE || value == 0) { -+ sprintf(string, "invalid size %s", argv[arg_nb]); -+ return -1; -+ } -+ if (value & 0x3) { -+ sprintf(string, "unaligned size %s", -+ argv[arg_nb]); -+ return -1; -+ } -+ *bufsize = value; -+ } else { -+ if (default_size != STM32_DDR_SIZE) -+ *bufsize = default_size; -+ else -+ *bufsize = get_ram_size((long *)STM32_DDR_BASE, -+ STM32_DDR_SIZE); -+ } -+ return 0; -+} -+ -+static int get_nb_loop(char *string, int argc, char *argv[], int arg_nb, -+ u32 *nb_loop, u32 default_nb_loop) -+{ -+ unsigned long value; -+ -+ if (argc > arg_nb) { -+ if (strict_strtoul(argv[arg_nb], 0, &value) < 0) { -+ sprintf(string, "invalid %d parameter %s", -+ arg_nb, argv[arg_nb]); -+ return -1; -+ } -+ if (value == 0) -+ printf("WARNING: infinite loop requested\n"); -+ *nb_loop = value; -+ } else { -+ *nb_loop = default_nb_loop; -+ } -+ -+ return 0; -+} -+ -+static int get_addr(char *string, int argc, char *argv[], int arg_nb, -+ u32 *addr) -+{ -+ unsigned long value; -+ -+ if (argc > arg_nb) { -+ if (strict_strtoul(argv[arg_nb], 16, &value) < 0) { -+ sprintf(string, "invalid %d parameter %s", -+ arg_nb, argv[arg_nb]); -+ return -1; -+ } -+ if (value < STM32_DDR_BASE) { -+ sprintf(string, "too low address %s", argv[arg_nb]); -+ return -1; -+ } -+ if (value & 0x3 && value != ADDR_INVALID) { -+ sprintf(string, "unaligned address %s", -+ argv[arg_nb]); -+ return -1; -+ } -+ *addr = value; -+ } else { -+ *addr = STM32_DDR_BASE; -+ } -+ -+ return 0; -+} -+ -+static int get_pattern(char *string, int argc, char *argv[], int arg_nb, -+ u32 *pattern, u32 default_pattern) -+{ -+ unsigned long value; -+ -+ if (argc > arg_nb) { -+ if (strict_strtoul(argv[arg_nb], 16, &value) < 0) { -+ sprintf(string, "invalid %d parameter %s", -+ arg_nb, argv[arg_nb]); -+ return -1; -+ } -+ *pattern = value; -+ } else { -+ *pattern = default_pattern; -+ } -+ -+ return 0; -+} -+ -+static u32 check_addr(u32 addr, u32 value) -+{ -+ u32 data = readl(addr); -+ -+ if (value != data) { -+ printf("0x%08x: 0x%08x <=> 0x%08x", addr, data, value); -+ data = readl(addr); -+ printf("(2nd read: 0x%08x)", data); -+ if (value == data) -+ printf("- read error"); -+ else -+ printf("- write error"); -+ printf("\n"); -+ return -1; -+ } -+ return 0; -+} -+ -+static int progress(u32 offset) -+{ -+ if (!(offset & 0xFFFFFF)) { -+ putc('.'); -+ if (ctrlc()) { -+ printf("\ntest interrupted!\n"); -+ return 1; -+ } -+ } -+ return 0; -+} -+ -+static int test_loop_end(u32 *loop, u32 nb_loop, u32 progress) -+{ -+ (*loop)++; -+ if (nb_loop && *loop >= nb_loop) -+ return 1; -+ if ((*loop) % progress) -+ return 0; -+ /* allow to interrupt the test only for progress step */ -+ if (ctrlc()) { -+ printf("test interrupted!\n"); -+ return 1; -+ } -+ printf("loop #%d\n", *loop); -+ return 0; -+} -+ -+/********************************************************************** -+ * -+ * Function: memTestDataBus() -+ * -+ * Description: Test the data bus wiring in a memory region by -+ * performing a walking 1's test at a fixed address -+ * within that region. The address is selected -+ * by the caller. -+ * -+ * Notes: -+ * -+ * Returns: 0 if the test succeeds. -+ * A non-zero result is the first pattern that failed. -+ * -+ **********************************************************************/ -+static u32 databus(u32 *address) -+{ -+ u32 pattern; -+ u32 read_value; -+ -+ /* Perform a walking 1's test at the given address. */ -+ for (pattern = 1; pattern != 0; pattern <<= 1) { -+ /* Write the test pattern. */ -+ writel(pattern, address); -+ -+ /* Read it back (immediately is okay for this test). */ -+ read_value = readl(address); -+ debug("%x: %x <=> %x\n", -+ (u32)address, read_value, pattern); -+ -+ if (read_value != pattern) -+ return pattern; -+ } -+ -+ return 0; -+} -+ -+/********************************************************************** -+ * -+ * Function: memTestAddressBus() -+ * -+ * Description: Test the address bus wiring in a memory region by -+ * performing a walking 1's test on the relevant bits -+ * of the address and checking for aliasing. This test -+ * will find single-bit address failures such as stuck -+ * -high, stuck-low, and shorted pins. The base address -+ * and size of the region are selected by the caller. -+ * -+ * Notes: For best results, the selected base address should -+ * have enough LSB 0's to guarantee single address bit -+ * changes. For example, to test a 64-Kbyte region, -+ * select a base address on a 64-Kbyte boundary. Also, -+ * select the region size as a power-of-two--if at all -+ * possible. -+ * -+ * Returns: NULL if the test succeeds. -+ * A non-zero result is the first address at which an -+ * aliasing problem was uncovered. By examining the -+ * contents of memory, it may be possible to gather -+ * additional information about the problem. -+ * -+ **********************************************************************/ -+static u32 *addressbus(u32 *address, u32 nb_bytes) -+{ -+ u32 mask = (nb_bytes / sizeof(u32) - 1); -+ u32 offset; -+ u32 test_offset; -+ u32 read_value; -+ -+ u32 pattern = 0xAAAAAAAA; -+ u32 antipattern = 0x55555555; -+ -+ /* Write the default pattern at each of the power-of-two offsets. */ -+ for (offset = 1; (offset & mask) != 0; offset <<= 1) -+ writel(pattern, &address[offset]); -+ -+ /* Check for address bits stuck high. */ -+ test_offset = 0; -+ writel(antipattern, &address[test_offset]); -+ -+ for (offset = 1; (offset & mask) != 0; offset <<= 1) { -+ read_value = readl(&address[offset]); -+ debug("%x: %x <=> %x\n", -+ (u32)&address[offset], read_value, pattern); -+ if (read_value != pattern) -+ return &address[offset]; -+ } -+ -+ writel(pattern, &address[test_offset]); -+ -+ /* Check for address bits stuck low or shorted. */ -+ for (test_offset = 1; (test_offset & mask) != 0; test_offset <<= 1) { -+ writel(antipattern, &address[test_offset]); -+ if (readl(&address[0]) != pattern) -+ return &address[test_offset]; -+ -+ for (offset = 1; (offset & mask) != 0; offset <<= 1) { -+ if (readl(&address[offset]) != pattern && -+ offset != test_offset) -+ return &address[test_offset]; -+ } -+ writel(pattern, &address[test_offset]); -+ } -+ -+ return NULL; -+} -+ -+/********************************************************************** -+ * -+ * Function: memTestDevice() -+ * -+ * Description: Test the integrity of a physical memory device by -+ * performing an increment/decrement test over the -+ * entire region. In the process every storage bit -+ * in the device is tested as a zero and a one. The -+ * base address and the size of the region are -+ * selected by the caller. -+ * -+ * Notes: -+ * -+ * Returns: NULL if the test succeeds. -+ * -+ * A non-zero result is the first address at which an -+ * incorrect value was read back. By examining the -+ * contents of memory, it may be possible to gather -+ * additional information about the problem. -+ * -+ **********************************************************************/ -+static u32 *memdevice(u32 *address, u32 nb_bytes) -+{ -+ u32 offset; -+ u32 nb_words = nb_bytes / sizeof(u32); -+ -+ u32 pattern; -+ u32 antipattern; -+ -+ puts("Fill with pattern"); -+ /* Fill memory with a known pattern. */ -+ for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) { -+ writel(pattern, &address[offset]); -+ if (progress(offset)) -+ return NULL; -+ } -+ -+ puts("\nCheck and invert pattern"); -+ /* Check each location and invert it for the second pass. */ -+ for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) { -+ if (readl(&address[offset]) != pattern) -+ return &address[offset]; -+ -+ antipattern = ~pattern; -+ writel(antipattern, &address[offset]); -+ if (progress(offset)) -+ return NULL; -+ } -+ -+ puts("\nCheck inverted pattern"); -+ /* Check each location for the inverted pattern and zero it. */ -+ for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) { -+ antipattern = ~pattern; -+ if (readl(&address[offset]) != antipattern) -+ return &address[offset]; -+ if (progress(offset)) -+ return NULL; -+ } -+ printf("\n"); -+ -+ return NULL; -+} -+ -+static enum test_result databuswalk0(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ int i; -+ u32 loop = 0, nb_loop; -+ u32 addr; -+ u32 error = 0; -+ u32 data; -+ -+ if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100)) -+ return TEST_ERROR; -+ if (get_addr(string, argc, argv, 1, &addr)) -+ return TEST_ERROR; -+ -+ printf("running %d loops at 0x%x\n", nb_loop, addr); -+ while (!error) { -+ for (i = 0; i < 32; i++) -+ writel(~(1 << i), addr + 4 * i); -+ for (i = 0; i < 32; i++) { -+ data = readl(addr + 4 * i); -+ if (~(1 << i) != data) { -+ error |= 1 << i; -+ debug("%x: error %x expected %x => error:%x\n", -+ addr + 4 * i, data, ~(1 << i), error); -+ } -+ } -+ if (test_loop_end(&loop, nb_loop, 1000)) -+ break; -+ for (i = 0; i < 32; i++) -+ writel(0, addr + 4 * i); -+ } -+ if (error) { -+ sprintf(string, "loop %d: error for bits 0x%x", -+ loop, error); -+ return TEST_FAILED; -+ } -+ sprintf(string, "no error for %d loops", loop); -+ return TEST_PASSED; -+} -+ -+static enum test_result databuswalk1(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ int i; -+ u32 loop = 0, nb_loop; -+ u32 addr; -+ u32 error = 0; -+ u32 data; -+ -+ if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100)) -+ return TEST_ERROR; -+ if (get_addr(string, argc, argv, 1, &addr)) -+ return TEST_ERROR; -+ printf("running %d loops at 0x%x\n", nb_loop, addr); -+ while (!error) { -+ for (i = 0; i < 32; i++) -+ writel(1 << i, addr + 4 * i); -+ for (i = 0; i < 32; i++) { -+ data = readl(addr + 4 * i); -+ if ((1 << i) != data) { -+ error |= 1 << i; -+ debug("%x: error %x expected %x => error:%x\n", -+ addr + 4 * i, data, (1 << i), error); -+ } -+ } -+ if (test_loop_end(&loop, nb_loop, 1000)) -+ break; -+ for (i = 0; i < 32; i++) -+ writel(0, addr + 4 * i); -+ } -+ if (error) { -+ sprintf(string, "loop %d: error for bits 0x%x", -+ loop, error); -+ return TEST_FAILED; -+ } -+ sprintf(string, "no error for %d loops", loop); -+ return TEST_PASSED; -+} -+ -+static enum test_result test_databus(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ u32 addr; -+ u32 error; -+ -+ if (get_addr(string, argc, argv, 0, &addr)) -+ return TEST_ERROR; -+ error = databus((u32 *)addr); -+ if (error) { -+ sprintf(string, "0x%x: error for bits 0x%x", -+ addr, error); -+ return TEST_FAILED; -+ } -+ sprintf(string, "address 0x%x", addr); -+ return TEST_PASSED; -+} -+ -+static enum test_result test_addressbus(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ u32 addr; -+ u32 bufsize; -+ u32 error; -+ -+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) -+ return TEST_ERROR; -+ if (!is_power_of_2(bufsize)) { -+ sprintf(string, "size 0x%x is not a power of 2", -+ (u32)bufsize); -+ return TEST_ERROR; -+ } -+ if (get_addr(string, argc, argv, 1, &addr)) -+ return TEST_ERROR; -+ -+ error = (u32)addressbus((u32 *)addr, bufsize); -+ if (error) { -+ sprintf(string, "0x%x: error for address 0x%x", -+ addr, error); -+ return TEST_FAILED; -+ } -+ sprintf(string, "address 0x%x, size 0x%x", -+ addr, bufsize); -+ return TEST_PASSED; -+} -+ -+static enum test_result test_memdevice(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ u32 addr; -+ size_t bufsize; -+ u32 error; -+ -+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) -+ return TEST_ERROR; -+ if (get_addr(string, argc, argv, 1, &addr)) -+ return TEST_ERROR; -+ error = (u32)memdevice((u32 *)addr, (unsigned long)bufsize); -+ if (error) { -+ sprintf(string, "0x%x: error for address 0x%x", -+ addr, error); -+ return TEST_FAILED; -+ } -+ sprintf(string, "address 0x%x, size 0x%x", -+ addr, bufsize); -+ return TEST_PASSED; -+} -+ -+/********************************************************************** -+ * -+ * Function: sso -+ * -+ * Description: Test the Simultaneous Switching Output. -+ * Verifies succes sive reads and writes to the same memory word, -+ * holding one bit constant while toggling all other data bits -+ * simultaneously -+ * => stress the data bus over an address range -+ * -+ * The CPU writes to each address in the given range. -+ * For each bit, first the CPU holds the bit at 1 while -+ * toggling the other bits, and then the CPU holds the bit at 0 -+ * while toggling the other bits. -+ * After each write, the CPU reads the address that was written -+ * to verify that it contains the correct data -+ * -+ **********************************************************************/ -+static enum test_result test_sso(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ int i, j; -+ u32 addr, bufsize, remaining, offset; -+ u32 error = 0; -+ u32 data; -+ -+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4)) -+ return TEST_ERROR; -+ if (get_addr(string, argc, argv, 1, &addr)) -+ return TEST_ERROR; -+ -+ printf("running sso at 0x%x length 0x%x", addr, bufsize); -+ offset = addr; -+ remaining = bufsize; -+ while (remaining) { -+ for (i = 0; i < 32; i++) { -+ /* write pattern. */ -+ for (j = 0; j < 6; j++) { -+ switch (j) { -+ case 0: -+ case 2: -+ data = 1 << i; -+ break; -+ case 3: -+ case 5: -+ data = ~(1 << i); -+ break; -+ case 1: -+ data = ~0x0; -+ break; -+ case 4: -+ data = 0x0; -+ break; -+ } -+ -+ writel(data, offset); -+ error = check_addr(offset, data); -+ if (error) -+ goto end; -+ } -+ } -+ offset += 4; -+ remaining -= 4; -+ if (progress(offset << 7)) -+ goto end; -+ } -+ puts("\n"); -+ -+end: -+ if (error) { -+ sprintf(string, "error for pattern 0x%x @0x%x", -+ data, offset); -+ return TEST_FAILED; -+ } -+ sprintf(string, "no error for sso at 0x%x length 0x%x", addr, bufsize); -+ return TEST_PASSED; -+} -+ -+/********************************************************************** -+ * -+ * Function: Random -+ * -+ * Description: Verifies r/w with pseudo-ramdom value on one region -+ * + write the region (individual access) -+ * + memcopy to the 2nd region (try to use burst) -+ * + verify the 2 regions -+ * -+ **********************************************************************/ -+static enum test_result test_random(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ u32 addr, offset, value = 0; -+ size_t bufsize; -+ u32 loop = 0, nb_loop; -+ u32 error = 0; -+ unsigned int seed; -+ -+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) -+ return TEST_ERROR; -+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) -+ return TEST_ERROR; -+ if (get_addr(string, argc, argv, 2, &addr)) -+ return TEST_ERROR; -+ -+ printf("running %d loops at 0x%x\n", nb_loop, addr); -+ while (!error) { -+ seed = rand(); -+ for (offset = addr; offset < addr + bufsize; offset += 4) -+ writel(rand(), offset); -+ -+ memcpy((void *)addr + bufsize, (void *)addr, bufsize); -+ -+ srand(seed); -+ for (offset = addr; offset < addr + 2 * bufsize; offset += 4) { -+ if (offset == (addr + bufsize)) -+ srand(seed); -+ value = rand(); -+ error = check_addr(offset, value); -+ if (error) -+ break; -+ if (progress(offset)) -+ return TEST_FAILED; -+ } -+ if (test_loop_end(&loop, nb_loop, 100)) -+ break; -+ } -+ -+ if (error) { -+ sprintf(string, -+ "loop %d: error for address 0x%x: 0x%x expected 0x%x", -+ loop, offset, readl(offset), value); -+ return TEST_FAILED; -+ } -+ sprintf(string, "no error for %d loops, size 0x%x", -+ loop, bufsize); -+ return TEST_PASSED; -+} -+ -+/********************************************************************** -+ * -+ * Function: noise -+ * -+ * Description: Verifies r/w while forcing switching of all data bus lines. -+ * optimised 4 iteration write/read/write/read cycles... -+ * for pattern and inversed pattern -+ * -+ **********************************************************************/ -+void do_noise(u32 addr, u32 pattern, u32 *result) -+{ -+ __asm__("push {R0-R11}"); -+ __asm__("mov r0, %0" : : "r" (addr)); -+ __asm__("mov r1, %0" : : "r" (pattern)); -+ __asm__("mov r11, %0" : : "r" (result)); -+ -+ __asm__("mvn r2, r1"); -+ -+ __asm__("str r1, [r0]"); -+ __asm__("ldr r3, [r0]"); -+ __asm__("str r2, [r0]"); -+ __asm__("ldr r4, [r0]"); -+ -+ __asm__("str r1, [r0]"); -+ __asm__("ldr r5, [r0]"); -+ __asm__("str r2, [r0]"); -+ __asm__("ldr r6, [r0]"); -+ -+ __asm__("str r1, [r0]"); -+ __asm__("ldr r7, [r0]"); -+ __asm__("str r2, [r0]"); -+ __asm__("ldr r8, [r0]"); -+ -+ __asm__("str r1, [r0]"); -+ __asm__("ldr r9, [r0]"); -+ __asm__("str r2, [r0]"); -+ __asm__("ldr r10, [r0]"); -+ -+ __asm__("stmia R11!, {R3-R10}"); -+ -+ __asm__("pop {R0-R11}"); -+} -+ -+static enum test_result test_noise(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ u32 addr, pattern; -+ u32 result[8]; -+ int i; -+ enum test_result res = TEST_PASSED; -+ -+ if (get_pattern(string, argc, argv, 0, &pattern, 0xFFFFFFFF)) -+ return TEST_ERROR; -+ if (get_addr(string, argc, argv, 1, &addr)) -+ return TEST_ERROR; -+ -+ printf("running noise for 0x%x at 0x%x\n", pattern, addr); -+ -+ do_noise(addr, pattern, result); -+ -+ for (i = 0; i < 0x8;) { -+ if (check_addr((u32)&result[i++], pattern)) -+ res = TEST_FAILED; -+ if (check_addr((u32)&result[i++], ~pattern)) -+ res = TEST_FAILED; -+ } -+ -+ return res; -+} -+ -+/********************************************************************** -+ * -+ * Function: noise_burst -+ * -+ * Description: Verifies r/w while forcing switching of all data bus lines. -+ * optimised write loop witrh store multiple to use burst -+ * for pattern and inversed pattern -+ * -+ **********************************************************************/ -+void do_noise_burst(u32 addr, u32 pattern, size_t bufsize) -+{ -+ __asm__("push {R0-R9}"); -+ __asm__("mov r0, %0" : : "r" (addr)); -+ __asm__("mov r1, %0" : : "r" (pattern)); -+ __asm__("mov r9, %0" : : "r" (bufsize)); -+ -+ __asm__("mvn r2, r1"); -+ __asm__("mov r3, r1"); -+ __asm__("mov r4, r2"); -+ __asm__("mov r5, r1"); -+ __asm__("mov r6, r2"); -+ __asm__("mov r7, r1"); -+ __asm__("mov r8, r2"); -+ -+ __asm__("loop1:"); -+ __asm__("stmia R0!, {R1-R8}"); -+ __asm__("stmia R0!, {R1-R8}"); -+ __asm__("stmia R0!, {R1-R8}"); -+ __asm__("stmia R0!, {R1-R8}"); -+ __asm__("subs r9, r9, #128"); -+ __asm__("bge loop1"); -+ __asm__("pop {R0-R9}"); -+} -+ -+/* chunk size enough to allow interruption with Ctrl-C*/ -+#define CHUNK_SIZE 0x8000000 -+static enum test_result test_noise_burst(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ u32 addr, offset, pattern; -+ size_t bufsize, remaining, size; -+ int i; -+ enum test_result res = TEST_PASSED; -+ -+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) -+ return TEST_ERROR; -+ if (get_pattern(string, argc, argv, 1, &pattern, 0xFFFFFFFF)) -+ return TEST_ERROR; -+ if (get_addr(string, argc, argv, 2, &addr)) -+ return TEST_ERROR; -+ -+ printf("running noise burst for 0x%x at 0x%x + 0x%x", -+ pattern, addr, bufsize); -+ -+ offset = addr; -+ remaining = bufsize; -+ size = CHUNK_SIZE; -+ while (remaining) { -+ if (remaining < size) -+ size = remaining; -+ do_noise_burst(offset, pattern, size); -+ remaining -= size; -+ offset += size; -+ if (progress(offset)) { -+ res = TEST_FAILED; -+ goto end; -+ } -+ } -+ puts("\ncheck buffer"); -+ for (i = 0; i < bufsize;) { -+ if (check_addr(addr + i, pattern)) -+ res = TEST_FAILED; -+ i += 4; -+ if (check_addr(addr + i, ~pattern)) -+ res = TEST_FAILED; -+ i += 4; -+ if (progress(i)) { -+ res = TEST_FAILED; -+ goto end; -+ } -+ } -+end: -+ puts("\n"); -+ return res; -+} -+ -+/********************************************************************** -+ * -+ * Function: pattern test -+ * -+ * Description: optimized loop for read/write pattern (array of 8 u32) -+ * -+ **********************************************************************/ -+#define PATTERN_SIZE 8 -+static enum test_result test_loop(const u32 *pattern, u32 *address, -+ const u32 bufsize) -+{ -+ int i; -+ int j; -+ enum test_result res = TEST_PASSED; -+ u32 *offset, testsize, remaining; -+ -+ offset = address; -+ remaining = bufsize; -+ while (remaining) { -+ testsize = bufsize > 0x1000000 ? 0x1000000 : bufsize; -+ -+ __asm__("push {R0-R10}"); -+ __asm__("mov r0, %0" : : "r" (pattern)); -+ __asm__("mov r1, %0" : : "r" (offset)); -+ __asm__("mov r2, %0" : : "r" (testsize)); -+ __asm__("ldmia r0!, {R3-R10}"); -+ -+ __asm__("loop2:"); -+ __asm__("stmia r1!, {R3-R10}"); -+ __asm__("stmia r1!, {R3-R10}"); -+ __asm__("stmia r1!, {R3-R10}"); -+ __asm__("stmia r1!, {R3-R10}"); -+ __asm__("subs r2, r2, #8"); -+ __asm__("bge loop2"); -+ __asm__("pop {R0-R10}"); -+ -+ offset += testsize; -+ remaining -= testsize; -+ if (progress((u32)offset)) { -+ res = TEST_FAILED; -+ goto end; -+ } -+ } -+ -+ puts("\ncheck buffer"); -+ for (i = 0; i < bufsize; i += PATTERN_SIZE * 4) { -+ for (j = 0; j < PATTERN_SIZE; j++, address++) -+ if (check_addr((u32)address, pattern[j])) { -+ res = TEST_FAILED; -+ goto end; -+ } -+ if (progress(i)) { -+ res = TEST_FAILED; -+ goto end; -+ } -+ } -+ -+end: -+ puts("\n"); -+ return res; -+} -+ -+const u32 pattern_div1_x16[PATTERN_SIZE] = { -+ 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, -+ 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF -+}; -+ -+const u32 pattern_div2_x16[PATTERN_SIZE] = { -+ 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, -+ 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000 -+}; -+ -+const u32 pattern_div4_x16[PATTERN_SIZE] = { -+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, -+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 -+}; -+ -+const u32 pattern_div4_x32[PATTERN_SIZE] = { -+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000 -+}; -+ -+const u32 pattern_mostly_zero_x16[PATTERN_SIZE] = { -+ 0x00000000, 0x00000000, 0x00000000, 0x0000FFFF, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000 -+}; -+ -+const u32 pattern_mostly_zero_x32[PATTERN_SIZE] = { -+ 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000 -+}; -+ -+const u32 pattern_mostly_one_x16[PATTERN_SIZE] = { -+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF, -+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF -+}; -+ -+const u32 pattern_mostly_one_x32[PATTERN_SIZE] = { -+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, -+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF -+}; -+ -+#define NB_PATTERN 5 -+static enum test_result test_freq_pattern(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ const u32 * const patterns_x16[NB_PATTERN] = { -+ pattern_div1_x16, -+ pattern_div2_x16, -+ pattern_div4_x16, -+ pattern_mostly_zero_x16, -+ pattern_mostly_one_x16, -+ }; -+ const u32 * const patterns_x32[NB_PATTERN] = { -+ pattern_div2_x16, -+ pattern_div4_x16, -+ pattern_div4_x32, -+ pattern_mostly_zero_x32, -+ pattern_mostly_one_x32 -+ }; -+ const char *patterns_comments[NB_PATTERN] = { -+ "switching at frequency F/1", -+ "switching at frequency F/2", -+ "switching at frequency F/4", -+ "mostly zero", -+ "mostly one" -+ }; -+ -+ enum test_result res = TEST_PASSED, pattern_res; -+ int i, bus_width; -+ const u32 **patterns; -+ u32 bufsize; -+ -+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) -+ return TEST_ERROR; -+ -+ switch (readl(&ctl->mstr) & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) { -+ case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF: -+ case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER: -+ bus_width = 16; -+ break; -+ default: -+ bus_width = 32; -+ break; -+ } -+ -+ printf("running test pattern at 0x%08x length 0x%x width = %d\n", -+ STM32_DDR_BASE, bufsize, bus_width); -+ -+ patterns = -+ (const u32 **)(bus_width == 16 ? patterns_x16 : patterns_x32); -+ -+ for (i = 0; i < NB_PATTERN; i++) { -+ printf("test data pattern %s:", patterns_comments[i]); -+ pattern_res = test_loop(patterns[i], (u32 *)STM32_DDR_BASE, -+ bufsize); -+ if (pattern_res != TEST_PASSED) { -+ printf("Failed\n"); -+ return pattern_res; -+ } -+ printf("Passed\n"); -+ } -+ -+ return res; -+} -+ -+/********************************************************************** -+ * -+ * Function: pattern test with size -+ * -+ * Description: loop for write pattern -+ * -+ **********************************************************************/ -+ -+static enum test_result test_loop_size(const u32 *pattern, u32 size, -+ u32 *address, -+ const u32 bufsize) -+{ -+ int i, j; -+ enum test_result res = TEST_PASSED; -+ u32 *p = address; -+ -+ for (i = 0; i < bufsize; i += size * 4) { -+ for (j = 0; j < size ; j++, p++) -+ *p = pattern[j]; -+ if (progress(i)) { -+ res = TEST_FAILED; -+ goto end; -+ } -+ } -+ -+ puts("\ncheck buffer"); -+ p = address; -+ for (i = 0; i < bufsize; i += size * 4) { -+ for (j = 0; j < size; j++, p++) -+ if (check_addr((u32)p, pattern[j])) { -+ res = TEST_FAILED; -+ goto end; -+ } -+ if (progress(i)) { -+ res = TEST_FAILED; -+ goto end; -+ } -+ } -+ -+end: -+ puts("\n"); -+ return res; -+} -+ -+static enum test_result test_checkboard(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ enum test_result res = TEST_PASSED; -+ u32 bufsize; -+ -+ u32 checkboard[2] = {0x55555555, 0xAAAAAAAA}; -+ -+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) -+ return TEST_ERROR; -+ -+ printf("running test checkboard at 0x%08x length 0x%x\n", -+ STM32_DDR_BASE, bufsize); -+ -+ res = test_loop_size(checkboard, 2, (u32 *)STM32_DDR_BASE, -+ bufsize); -+ -+ checkboard[0] = ~checkboard[0]; -+ checkboard[1] = ~checkboard[1]; -+ -+ res = test_loop_size(checkboard, 2, (u32 *)STM32_DDR_BASE, -+ bufsize); -+ -+ return res; -+} -+ -+static enum test_result test_blockseq(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ enum test_result res = TEST_PASSED; -+ u32 bufsize; -+ int i; -+ -+ u32 value; -+ -+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) -+ return TEST_ERROR; -+ -+ printf("running at 0x%08x length 0x%x\n", STM32_DDR_BASE, bufsize); -+ for (i = 0; i < 256; i++) { -+ value = i | i << 8 | i << 16 | i << 24; -+ printf("pattern = %08x", value); -+ res = test_loop_size(&value, 1, (u32 *)STM32_DDR_BASE, -+ bufsize); -+ if (res != TEST_PASSED) -+ return res; -+ } -+ -+ return res; -+} -+ -+static enum test_result test_walkbit0(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ enum test_result res = TEST_PASSED; -+ u32 bufsize; -+ int i; -+ -+ u32 value; -+ -+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) -+ return TEST_ERROR; -+ -+ printf("running at 0x%08x length 0x%x\n", STM32_DDR_BASE, bufsize); -+ for (i = 0; i < 64; i++) { -+ if (i < 32) -+ value = 1 << i; -+ else -+ value = 1 << (63 - i); -+ -+ printf("pattern = %08x", value); -+ res = test_loop_size(&value, 1, (u32 *)STM32_DDR_BASE, -+ bufsize); -+ if (res != TEST_PASSED) -+ return res; -+ } -+ -+ return res; -+} -+ -+static enum test_result test_walkbit1(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ enum test_result res = TEST_PASSED; -+ u32 bufsize; -+ int i; -+ -+ u32 value; -+ -+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) -+ return TEST_ERROR; -+ -+ printf("running at 0x%08x length 0x%x\n", STM32_DDR_BASE, bufsize); -+ for (i = 0; i < 64; i++) { -+ if (i < 32) -+ value = ~(1 << i); -+ else -+ value = ~(1 << (63 - i)); -+ -+ printf("pattern = %08x", value); -+ res = test_loop_size(&value, 1, (u32 *)STM32_DDR_BASE, -+ bufsize); -+ if (res != TEST_PASSED) -+ return res; -+ } -+ -+ return res; -+} -+ -+/* -+ * try to catch bad bits which are dependent on the current values of -+ * surrounding bits in either the same word32 -+ */ -+static enum test_result test_bitspread(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ enum test_result res = TEST_PASSED; -+ u32 bufsize; -+ int i, j; -+ -+ u32 bitspread[4]; -+ -+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) -+ return TEST_ERROR; -+ -+ printf("running at 0x%08x length 0x%x\n", STM32_DDR_BASE, bufsize); -+ for (i = 1; i < 32; i++) { -+ for (j = 0; j < i; j++) { -+ if (i < 32) -+ bitspread[0] = (1 << i) | (1 << j); -+ else -+ bitspread[0] = (1 << (63 - i)) | -+ (1 << (63 - j)); -+ bitspread[1] = bitspread[0]; -+ bitspread[2] = ~bitspread[0]; -+ bitspread[3] = ~bitspread[0]; -+ printf("pattern = %08x", bitspread[0]); -+ -+ res = test_loop_size(bitspread, 4, -+ (u32 *)STM32_DDR_BASE, -+ bufsize); -+ if (res != TEST_PASSED) -+ return res; -+ } -+ } -+ -+ return res; -+} -+ -+static enum test_result test_bitflip(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ enum test_result res = TEST_PASSED; -+ u32 bufsize; -+ int i; -+ -+ u32 bitflip[4]; -+ -+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) -+ return TEST_ERROR; -+ -+ printf("running at 0x%08x length 0x%x\n", STM32_DDR_BASE, bufsize); -+ for (i = 0; i < 32; i++) { -+ bitflip[0] = 1 << i; -+ bitflip[1] = bitflip[0]; -+ bitflip[2] = ~bitflip[0]; -+ bitflip[3] = bitflip[2]; -+ printf("pattern = %08x", bitflip[0]); -+ -+ res = test_loop_size(bitflip, 4, (u32 *)STM32_DDR_BASE, -+ bufsize); -+ if (res != TEST_PASSED) -+ return res; -+ } -+ -+ return res; -+} -+ -+/********************************************************************** -+ * -+ * Function: infinite read access to DDR -+ * -+ * Description: continuous read the same pattern at the same address -+ * -+ **********************************************************************/ -+static enum test_result test_read(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ u32 *addr; -+ u32 data; -+ u32 loop = 0; -+ bool random = false; -+ -+ if (get_addr(string, argc, argv, 0, (u32 *)&addr)) -+ return TEST_ERROR; -+ -+ if ((u32)addr == ADDR_INVALID) { -+ printf("random "); -+ random = true; -+ } -+ -+ printf("running at 0x%08x\n", (u32)addr); -+ -+ while (1) { -+ if (random) -+ addr = (u32 *)(STM32_DDR_BASE + -+ (rand() & (STM32_DDR_SIZE - 1) & ~0x3)); -+ data = readl(addr); -+ if (test_loop_end(&loop, 0, 1000)) -+ break; -+ } -+ sprintf(string, "0x%x: %x", (u32)addr, data); -+ -+ return TEST_PASSED; -+} -+ -+/********************************************************************** -+ * -+ * Function: infinite write access to DDR -+ * -+ * Description: continuous write the same pattern at the same address -+ * -+ **********************************************************************/ -+static enum test_result test_write(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ u32 *addr; -+ u32 data = 0xA5A5AA55; -+ u32 loop = 0; -+ bool random = false; -+ -+ if (get_addr(string, argc, argv, 0, (u32 *)&addr)) -+ return TEST_ERROR; -+ -+ if ((u32)addr == ADDR_INVALID) { -+ printf("random "); -+ random = true; -+ } -+ -+ printf("running at 0x%08x\n", (u32)addr); -+ -+ while (1) { -+ if (random) { -+ addr = (u32 *)(STM32_DDR_BASE + -+ (rand() & (STM32_DDR_SIZE - 1) & ~0x3)); -+ data = rand(); -+ } -+ writel(data, addr); -+ if (test_loop_end(&loop, 0, 1000)) -+ break; -+ } -+ sprintf(string, "0x%x: %x", (u32)addr, data); -+ -+ return TEST_PASSED; -+} -+ -+#define NB_TEST_INFINITE 2 -+static enum test_result test_all(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, int argc, char *argv[]) -+{ -+ enum test_result res = TEST_PASSED, result; -+ int i, nb_error = 0; -+ -+ /* execute all the test except the lasts which are infinite */ -+ for (i = 1; i < test_nb - NB_TEST_INFINITE; i++) { -+ printf("execute %d:%s\n", (int)i, test[i].name); -+ result = test[i].fct(ctl, phy, string, 0, NULL); -+ printf("result %d:%s = ", (int)i, test[i].name); -+ if (result != TEST_PASSED) { -+ nb_error++; -+ res = TEST_FAILED; -+ puts("Failed"); -+ } else { -+ puts("Passed"); -+ } -+ puts("\n\n"); -+ } -+ sprintf(string, "%d/%d test failed", nb_error, -+ test_nb - NB_TEST_INFINITE); -+ -+ return res; -+} -+ -+/**************************************************************** -+ * TEST Description -+ ****************************************************************/ -+ -+const struct test_desc test[] = { -+ {test_all, "All", "", "Execute all tests", 0 }, -+ {test_databus, "Simple DataBus", "[addr]", -+ "Verifies each data line by walking 1 on fixed address", -+ 1 -+ }, -+ {databuswalk0, "DataBusWalking0", "[loop] [addr]", -+ "Verifies each data bus signal can be driven low (32 word burst)", -+ 2 -+ }, -+ {databuswalk1, "DataBusWalking1", "[loop] [addr]", -+ "Verifies each data bus signal can be driven high (32 word burst)", -+ 2 -+ }, -+ {test_addressbus, "AddressBus", "[size] [addr]", -+ "Verifies each relevant bits of the address and checking for aliasing", -+ 2 -+ }, -+ {test_memdevice, "MemDevice", "[size] [addr]", -+ "Test the integrity of a physical memory (test every storage bit in the region)", -+ 2 -+ }, -+ {test_sso, "SimultaneousSwitchingOutput", "[size] [addr] ", -+ "Stress the data bus over an address range", -+ 2 -+ }, -+ {test_noise, "Noise", "[pattern] [addr]", -+ "Verifies r/w while forcing switching of all data bus lines.", -+ 3 -+ }, -+ {test_noise_burst, "NoiseBurst", "[size] [pattern] [addr]", -+ "burst transfers while forcing switching of the data bus lines", -+ 3 -+ }, -+ {test_random, "Random", "[size] [loop] [addr]", -+ "Verifies r/w and memcopy(burst for pseudo random value.", -+ 3 -+ }, -+ {test_freq_pattern, "FrequencySelectivePattern ", "[size]", -+ "write & test patterns: Mostly Zero, Mostly One and F/n", -+ 1 -+ }, -+ {test_blockseq, "BlockSequential", "[size]", -+ "test incremental pattern", -+ 1 -+ }, -+ {test_checkboard, "Checkerboard", "[size]", -+ "test checker pattern", -+ 1 -+ }, -+ {test_bitspread, "BitSpread", "[size]", -+ "test Bit Spread pattern", -+ 1 -+ }, -+ {test_bitflip, "BitFlip", "[size]", -+ "test Bit Flip pattern", -+ 1 -+ }, -+ {test_walkbit0, "WalkingOnes", "[size]", -+ "test Walking Ones pattern", -+ 1 -+ }, -+ {test_walkbit1, "WalkingZeroes", "[size]", -+ "test Walking Zeroes pattern", -+ 1 -+ }, -+ /* need to the the 2 last one (infinite) : skipped for test all */ -+ {test_read, "infinite read", "[addr]", -+ "basic test : infinite read access", 1}, -+ {test_write, "infinite write", "[addr]", -+ "basic test : infinite write access", 1}, -+}; -+ -+const int test_nb = ARRAY_SIZE(test); -diff --git a/drivers/ram/stm32mp1/stm32mp1_tests.h b/drivers/ram/stm32mp1/stm32mp1_tests.h -new file mode 100644 -index 0000000..a69fc0a ---- /dev/null -+++ b/drivers/ram/stm32mp1/stm32mp1_tests.h -@@ -0,0 +1,34 @@ -+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#ifndef _RAM_STM32MP1_TESTS_H_ -+#define _RAM_STM32MP1_TESTS_H_ -+ -+#include "stm32mp1_ddr_regs.h" -+ -+enum test_result { -+ TEST_PASSED, -+ TEST_FAILED, -+ TEST_ERROR -+}; -+ -+struct test_desc { -+ enum test_result (*fct)(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string, -+ int argc, char *argv[]); -+ const char *name; -+ const char *usage; -+ const char *help; -+ u8 max_args; -+}; -+ -+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 -new file mode 100644 -index 0000000..0778921 ---- /dev/null -+++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c -@@ -0,0 +1,1504 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#if defined(DEBUG) -+#define DEBUG_BIST -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "stm32mp1_ddr_regs.h" -+#include "stm32mp1_ddr.h" -+#include "stm32mp1_tests.h" -+#include "stm32mp1_tuning.h" -+ -+/* TODO make enum for nominal_delay_m_1.... (for all arrays) */ -+ -+/* 36deg, 54deg, 72deg, 90deg, 108deg, 126deg, 144deg */ -+const u8 dx_dll_phase[7] = {3, 2, 1, 0, 14, 13, 12}; -+ -+/* New DQ delay value (index). These values are 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]; -+ -+/*Stores the DQS trim values (PHASE index, unit index) */ -+u8 eye_training_val[NUM_BYTES][2]; -+ -+/* stores the log of pass/fail */ -+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]; -+ -+static void itm_soft_reset(struct stm32mp1_ddrphy *phy); -+static u8 set_midpoint_read_dqs_gating(struct stm32mp1_ddrphy *phy, u8 byte); -+ -+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; -+} -+ -+/* Read DQS PHASE delay register and provides the index of the retrieved -+ * value in dx_dll_phase array. -+ */ -+u8 DQS_phase_index(struct stm32mp1_ddrphy *phy, u8 byte) -+{ -+ u32 addr = DXNDLLCR(phy, byte); -+ u32 sdphase = 0; -+ u8 index = 0; -+ -+ sdphase = (readl(addr) & DDRPHYC_DXNDLLCR_SDPHASE_MASK) -+ >> DDRPHYC_DXNDLLCR_SDPHASE_SHIFT; -+ -+ switch (sdphase) { -+ case 0x0: /* 90deg */ -+ case 0x5: -+ case 0xA: -+ case 0xF: -+ index = 3; /* The index of 90deg in dx_dll_phase */ -+ break; -+ -+ case 0x2: /* 54deg */ -+ case 0x7: -+ index = 1; -+ break; -+ -+ case 0x1: /* 72deg */ -+ case 0x6: -+ case 0xB: -+ index = 2; -+ break; -+ -+ case 0x3: /* 36deg */ -+ index = 0; -+ break; -+ -+ case 0x4: /* 108deg */ -+ case 0x9: -+ case 0xe: -+ index = 4; -+ break; -+ -+ case 0x8: /* 126deg */ -+ case 0xd: -+ index = 5; -+ break; -+ -+ case 0xc: /* 144deg */ -+ index = 6; -+ break; -+ -+ default: -+ index = 3; /* 90deg */ -+ } -+ -+ pr_debug("%s: [%x]: %x => phase = %x -> DQS phase index = %d\n", -+ __func__, addr, readl(addr), sdphase, index); -+ -+ return index; -+} -+ -+/* Read DQS unit delay register and provides the index of the retrieved value -+ * We are assuming that the delay on DQS and DQSN are equal -+ */ -+u8 DQS_unit_index(struct stm32mp1_ddrphy *phy, u8 byte) -+{ -+ u32 addr = DXNDQSTR(phy, byte); -+ u32 index; -+ -+ /* We are assuming that the delay on DQS and DQSN are equal */ -+ index = (readl(addr) & DDRPHYC_DXNDQSTR_DQSDLY_MASK) -+ >> DDRPHYC_DXNDQSTR_DQSDLY_SHIFT; -+ -+ pr_debug("%s: [%x]: %x => DQS unit index = %x\n", -+ __func__, addr, readl(addr), index); -+ -+ return index; -+} -+ -+/* 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 -+ */ -+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; -+ -+ pr_debug("%s: [%x]: %x => DQ unit index = %x\n", -+ __func__, addr, readl(addr), index); -+ -+ return index; -+} -+ -+/* read r0dgsl value */ -+u8 get_r0dgsl_index(struct stm32mp1_ddrphy *phy, u8 byte) -+{ -+ u32 addr = DXNDQSTR(phy, byte); -+ -+ return (readl(addr) & DDRPHYC_DXNDQSTR_R0DGSL_MASK) -+ >> DDRPHYC_DXNDQSTR_R0DGSL_SHIFT; -+} -+ -+/*read r0dgsl value */ -+u8 get_r0dgps_index(struct stm32mp1_ddrphy *phy, u8 byte) -+{ -+ u32 addr = DXNDQSTR(phy, byte); -+ -+ return (readl(addr) & DDRPHYC_DXNDQSTR_R0DGPS_MASK) -+ >> DDRPHYC_DXNDQSTR_R0DGPS_SHIFT; -+} -+ -+/* 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. -+ */ -+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). -+ */ -+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 -+ */ -+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)); -+} -+ -+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); -+} -+ -+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. */ -+void config_BIST(struct stm32mp1_ddrphy *phy) -+{ -+ /* 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; -+ /* Specifies the maximum SDRAM row address to be used during -+ * BIST before the address & increments to the next bank. -+ */ -+ u32 bmrow = 0x7FFF; /* To check */ -+ /* Specifies the maximum SDRAM column address to be used during -+ * BIST before the address & increments to the next row. -+ */ -+ u32 bmcol = 0x3FF; /* To check */ -+ 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); -+ -+ /* To check this line : */ -+ writel(bmcol | (bmrow << 12) | (bmbank << 28), &phy->bistar2); -+} -+ -+/* Select the Byte lane to be tested by BIST. */ -+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. */ -+void BIST_test(struct stm32mp1_ddrphy *phy, u8 byte, -+ struct BIST_result *bist) -+{ -+ bool result = true; /* BIST_SUCCESS */ -+ u32 cnt = 0; -+ u32 error = 0; -+ -+ 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 */ -+ mdelay(1); -+ -+ /*Perform BIST Run*/ -+ clrsetbits_le32(&phy->bistrr, -+ 0x00000007, -+ 0x00000001); -+ /* Write BISTRR.BINST = 3?b001; */ -+ -+ /* Wait for a number of CTL clocks before reading BIST register*/ -+ /* Wait 300 ctl_clk cycles; ... IS it really needed?? */ -+ /* Perform BIST Instruction Stop*/ -+ /* Write BISTRR.BINST = 3?b010;*/ -+ -+ /* poll on BISTGSR.BDONE. If 0, wait. ++TODO Add timeout */ -+ while (!(readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDDONE)) -+ ; -+ -+ /*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++; -+#ifdef DEBUG_BIST -+ if (error < 5) -+ printf(" %d: %d, bistwcsr=0x%x, bistgsr=0x%x\n", -+ error, cnt, readl(&phy->bistwcsr), -+ readl(&phy->bistgsr)); -+#endif -+ } -+ if (error < BIST_error_max) { -+ if (cnt != 1000) -+ goto run; -+ bist->test_result = true; -+ } else { -+ bist->test_result = false; -+ } -+#ifdef DEBUG_BIST -+ if (cnt != 1000) -+ goto run; -+ printf(" - BIST result = %d, error=%d\n", bist->test_result, error); -+#endif -+} -+ -+/* Init the Write_Read result struct. */ -+void init_result_struct(struct BIST_result *result) -+{ -+ u8 i = 0; -+ -+ /* Init with an overall "true" (success) condition. -+ * Any fail at any bit will set this to false -+ */ -+ result->test_result = true; -+ result->all_bits_fail = false; -+ -+ /* Init with an "true" (success) condition for bit_i. -+ * A fail at this bit will set this to false -+ */ -+ for (i = 0; i < 8; i++) -+ result->bit_i_test_result[i] = true; -+} -+ -+/* 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. -+ */ -+void apply_deskew_results(struct stm32mp1_ddrphy *phy, u8 byte) -+{ -+ 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); -+ pr_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) -+ pr_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) -+{ -+ 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(phy); -+ pr_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; -+ } -+ pr_debug("\n======================\n"); -+ pr_debug("Start deskew byte %d .\n", datx8); -+ pr_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) { -+ pr_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 */ -+ pr_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 -+ */ -+ pr_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; -+ } -+ -+ pr_debug("there is a pass region for phase idx %d\n", -+ phase_idx); -+ pr_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) { -+ pr_debug("Fail region (PHASE) found phase idx %d\n", -+ phase_idx); -+ pr_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; -+ pr_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; -+ pr_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++; -+ pr_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; -+ pr_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; -+ pr_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); -+ pr_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; -+ } -+#ifdef DEBUG_BIST -+ printf("deskewing bit %d:\n", bit_i); -+#else -+ pr_debug("deskewing bit %d:\n", bit_i); -+#endif -+ 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); -+#ifdef DEBUG_BIST -+ printf(" delay_index %d:\n", bit_i_delay_index); -+#endif -+ BIST_test(phy, datx8, &result); -+ success = result.test_result; -+ bit_i_delay_index--; -+ } -+#ifdef DEBUG_BIST -+ { /* check next error */ -+ int delay_index = bit_i_delay_index; -+ -+ while (delay_index >= 0) { -+ set_DQ_unit_delay(phy, datx8, bit_i, -+ delay_index); -+ printf(" delay_index %d:\n", -+ delay_index); -+ BIST_test(phy, datx8, &result); -+ delay_index--; -+ } -+ } -+#endif -+ -+ /* 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; -+ pr_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; -+ pr_debug("Fail not found on bit %d => deskew[%d][%d] = %d\n", -+ bit_i, datx8, bit_i, -+ deskew_delay[datx8][bit_i]); -+ } -+ } -+ pr_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; -+ pr_debug("The Deskew algorithm can't converge, there is too much margin in your design. Good job!\n"); -+ } -+ -+ apply_deskew_results(phy, datx8); -+ /* 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 */ -+ -+/* TODO: Check if how delay blocks work. Maybe I have a wrong assumption!! -+ * Can check with Tuning App note. -+ */ -+ -+/* 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) -+{ -+ 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(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; -+ -+ pr_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; -+ } -+ pr_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; -+ } -+ pr_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; -+ } -+ pr_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; -+ } -+ pr_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]++; -+ pr_debug("** found phase : %d - %d & unit %d - %d\n", -+ right_bound.phase, left_bound.phase, -+ right_bound.unit, left_bound.unit); -+ pr_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; -+} -+ -+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))); -+} -+ -+static enum test_result read_dqs_gating(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string) -+{ -+ 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(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); -+ /* dummy reads */ -+ readl(0xc0000000); -+ readl(0xc0000000); -+ } -+ -+ /* re-enable drift compensation */ -+ /* setbits_le32(&phy->pgcr, DDRPHYC_PGCR_DFTCMP); */ -+ return TEST_PASSED; -+} -+ -+/* analyse the dgs gating log table, and determine the midpoint.*/ -+static u8 set_midpoint_read_dqs_gating(struct stm32mp1_ddrphy *phy, u8 byte) -+{ -+ 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) { -+ pr_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]; -+ } -+ } -+ pr_debug("*******calculating mid region: system latency: %d phase: %d********\n", -+ dqs_gate_values[byte][0], -+ dqs_gate_values[byte][1]); -+ pr_debug("*******the nominal values were system latency: 0 phase: 2*******\n"); -+ set_r0dgsl_delay(phy, byte, dqs_gate_values[byte][0]); -+ set_r0dgps_delay(phy, byte, dqs_gate_values[byte][1]); -+ } -+ } else { -+ /* if intermitant, restore defaut values */ -+ pr_debug("dqs gating:no regular fail/pass/fail found. defaults values restored.\n"); -+ set_r0dgsl_delay(phy, byte, 0); -+ set_r0dgps_delay(phy, byte, 2); -+ } -+ -+ /* return 0 if intermittent or if both left_bound -+ * and right_bound are not found -+ */ -+ return !(intermittent || (left_bound_found && right_bound_found)); -+} -+ -+static void itm_soft_reset(struct stm32mp1_ddrphy *phy) -+{ -+ stm32mp1_ddrphy_init(phy, DDRPHYC_PIR_ITMSRST); -+} -+ -+/**************************************************************** -+ * 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); -+ enum test_result res; -+ -+ stm32mp1_refresh_disable(ctl); -+ res = read_dqs_gating(ctl, phy, string); -+ stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl); -+ -+ 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); -+ enum test_result res; -+ -+ stm32mp1_refresh_disable(ctl); -+ res = bit_deskew(ctl, phy, string); -+ stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl); -+ -+ 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); -+ enum test_result res; -+ -+ stm32mp1_refresh_disable(ctl); -+ res = eye_training(ctl, phy, string); -+ stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl); -+ -+ 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/ram/stm32mp1/stm32mp1_tuning.h b/drivers/ram/stm32mp1/stm32mp1_tuning.h -new file mode 100644 -index 0000000..964a050 ---- /dev/null -+++ b/drivers/ram/stm32mp1/stm32mp1_tuning.h -@@ -0,0 +1,54 @@ -+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#ifndef _RAM_STM32MP1_TUNING_H_ -+#define _RAM_STM32MP1_TUNING_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 */ -+}; -+ -+u8 DQS_phase_index(struct stm32mp1_ddrphy *phy, u8 byte); -+u8 DQS_unit_index(struct stm32mp1_ddrphy *phy, u8 byte); -+u8 DQ_unit_index(struct stm32mp1_ddrphy *phy, u8 byte, u8 bit); -+ -+void apply_deskew_results(struct stm32mp1_ddrphy *phy, u8 byte); -+void init_result_struct(struct BIST_result *result); -+void BIST_test(struct stm32mp1_ddrphy *phy, u8 byte, -+ struct BIST_result *result); -+ -+/* 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 */ -+}; -+#endif -diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig -index 9eb532b..b1cae58 100644 ---- a/drivers/remoteproc/Kconfig -+++ b/drivers/remoteproc/Kconfig -@@ -49,4 +49,13 @@ config REMOTEPROC_TI_POWER - help - Say 'y' here to add support for TI power processors such as those - found on certain TI keystone and OMAP generation SoCs. -+ -+config REMOTEPROC_STM32_COPRO -+ bool "Support for STM32 Co-processor" -+ select REMOTEPROC -+ depends on DM -+ depends on ARCH_STM32MP -+ depends on OF_CONTROL -+ help -+ Say 'y' here to add support for STM32 Cortex-M4 co-processors. - endmenu -diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile -index 77eb708..5b120c1 100644 ---- a/drivers/remoteproc/Makefile -+++ b/drivers/remoteproc/Makefile -@@ -10,4 +10,5 @@ obj-$(CONFIG_$(SPL_)REMOTEPROC) += rproc-uclass.o - obj-$(CONFIG_K3_SYSTEM_CONTROLLER) += k3_system_controller.o - obj-$(CONFIG_REMOTEPROC_K3) += k3_rproc.o - obj-$(CONFIG_REMOTEPROC_SANDBOX) += sandbox_testproc.o -+obj-$(CONFIG_REMOTEPROC_STM32_COPRO) += stm32_copro.o - obj-$(CONFIG_REMOTEPROC_TI_POWER) += ti_power_proc.o -diff --git a/drivers/remoteproc/rproc-uclass.c b/drivers/remoteproc/rproc-uclass.c -index c8a41a6..8ea92f7 100644 ---- a/drivers/remoteproc/rproc-uclass.c -+++ b/drivers/remoteproc/rproc-uclass.c -@@ -5,6 +5,7 @@ - */ - #define pr_fmt(fmt) "%s: " fmt, __func__ - #include -+#include - #include - #include - #include -@@ -18,6 +19,40 @@ - DECLARE_GLOBAL_DATA_PTR; - - /** -+ * struct resource_table - firmware resource table header -+ * @ver: version number -+ * @num: number of resource entries -+ * @reserved: reserved (must be zero) -+ * @offset: array of offsets pointing at the various resource entries -+ * -+ * A resource table is essentially a list of system resources required -+ * by the remote processor. It may also include configuration entries. -+ * If needed, the remote processor firmware should contain this table -+ * as a dedicated ".resource_table" ELF section. -+ * -+ * Some resources entries are mere announcements, where the host is informed -+ * of specific remoteproc configuration. Other entries require the host to -+ * do something (e.g. allocate a system resource). Sometimes a negotiation -+ * is expected, where the firmware requests a resource, and once allocated, -+ * the host should provide back its details (e.g. address of an allocated -+ * memory region). -+ * -+ * The header of the resource table, as expressed by this structure, -+ * contains a version number (should we need to change this format in the -+ * future), the number of available resource entries, and their offsets -+ * in the table. -+ * -+ * Immediately following this header are the resource entries themselves, -+ * each of which begins with a resource entry header (as described below). -+ */ -+struct resource_table { -+ u32 ver; -+ u32 num; -+ u32 reserved[2]; -+ u32 offset[0]; -+} __packed; -+ -+/** - * for_each_remoteproc_device() - iterate through the list of rproc devices - * @fn: check function to call per match, if this function returns fail, - * iteration is aborted with the resultant error value -@@ -291,11 +326,252 @@ int rproc_dev_init(int id) - return ret; - } - -+/* -+ * Determine if a valid ELF image exists at the given memory location. -+ * First look at the ELF header magic field, then make sure that it is -+ * executable. -+ */ -+static bool is_valid_elf_image(unsigned long addr, int size) -+{ -+ Elf32_Ehdr *ehdr; /* Elf header structure pointer */ -+ -+ ehdr = (Elf32_Ehdr *)addr; -+ -+ if (!IS_ELF(*ehdr) || size <= sizeof(Elf32_Ehdr)) { -+ pr_err("No elf image at address 0x%08lx\n", addr); -+ return false; -+ } -+ -+ if (ehdr->e_type != ET_EXEC) { -+ pr_err("Not a 32-bit elf image at address 0x%08lx\n", addr); -+ return false; -+ } -+ -+ return true; -+} -+ -+ -+/* Basic function to verify ELF image format */ -+static int -+rproc_elf_sanity_check(struct udevice *dev, ulong addr, ulong size) -+{ -+ Elf32_Ehdr *ehdr; -+ char class; -+ -+ if (!addr) { -+ dev_err(dev, "Invalid fw address?\n"); -+ return -EINVAL; -+ } -+ -+ if (size < sizeof(Elf32_Ehdr)) { -+ dev_err(dev, "Image is too small\n"); -+ return -EINVAL; -+ } -+ -+ ehdr = (Elf32_Ehdr *)addr; -+ -+ /* We only support ELF32 at this point */ -+ class = ehdr->e_ident[EI_CLASS]; -+ if (class != ELFCLASS32) { -+ dev_err(dev, "Unsupported class: %d\n", class); -+ return -EINVAL; -+ } -+ -+ /* We assume the firmware has the same endianness as the host */ -+# ifdef __LITTLE_ENDIAN -+ if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) { -+# else /* BIG ENDIAN */ -+ if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) { -+# endif -+ dev_err(dev, "Unsupported firmware endianness\n"); -+ return -EINVAL; -+ } -+ -+ if (size < ehdr->e_shoff + sizeof(Elf32_Shdr)) { -+ dev_err(dev, "Image is too small\n"); -+ return -EINVAL; -+ } -+ -+ if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) { -+ dev_err(dev, "Image is corrupted (bad magic)\n"); -+ return -EINVAL; -+ } -+ -+ if (ehdr->e_phnum == 0) { -+ dev_err(dev, "No loadable segments\n"); -+ return -EINVAL; -+ } -+ -+ if (ehdr->e_phoff > size) { -+ dev_err(dev, "Firmware size is too small\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* -+ * A very simple elf loader, assumes the image is valid, returns the -+ * entry point address. -+ */ -+static int rproc_load_elf_image(struct udevice *dev, unsigned long addr, -+ unsigned long *entry) -+{ -+ Elf32_Ehdr *ehdr; /* Elf header structure pointer */ -+ Elf32_Phdr *phdr; /* Program header structure pointer */ -+ const struct dm_rproc_ops *ops; -+ unsigned int i; -+ -+ ehdr = (Elf32_Ehdr *)addr; -+ phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff); -+ -+ ops = rproc_get_ops(dev); -+ if (!ops) { -+ dev_dbg(dev, "Driver has no ops?\n"); -+ return -EINVAL; -+ } -+ -+ /* Load each program header */ -+ for (i = 0; i < ehdr->e_phnum; ++i) { -+ void *dst = (void *)(uintptr_t)phdr->p_paddr; -+ void *src = (void *)addr + phdr->p_offset; -+ -+ if (phdr->p_type != PT_LOAD) -+ continue; -+ -+ if (ops->da_to_pa) -+ dst = (void *)ops->da_to_pa(dev, (ulong)dst); -+ -+ dev_dbg(dev, "Loading phdr %i to 0x%p (%i bytes)\n", -+ i, dst, phdr->p_filesz); -+ if (phdr->p_filesz) -+ memcpy(dst, src, phdr->p_filesz); -+ if (phdr->p_filesz != phdr->p_memsz) -+ memset(dst + phdr->p_filesz, 0x00, -+ phdr->p_memsz - phdr->p_filesz); -+ flush_cache((unsigned long)dst, phdr->p_filesz); -+ ++phdr; -+ } -+ -+ *entry = ehdr->e_entry; -+ -+ return 0; -+} -+ -+/* Helper to find resource table in an ELF image */ -+static Elf32_Shdr *find_rsc_table(struct udevice *dev, Elf32_Ehdr *ehdr, -+ size_t fw_size) -+{ -+ Elf32_Shdr *shdr; -+ int i; -+ const char *name_table; -+ struct resource_table *table = NULL; -+ const u8 *elf_data = (void *)ehdr; -+ -+ /* look for the resource table and handle it */ -+ shdr = (Elf32_Shdr *)(elf_data + ehdr->e_shoff); -+ name_table = (const char *)(elf_data + -+ shdr[ehdr->e_shstrndx].sh_offset); -+ -+ for (i = 0; i < ehdr->e_shnum; i++, shdr++) { -+ u32 size = shdr->sh_size; -+ u32 offset = shdr->sh_offset; -+ -+ if (strcmp(name_table + shdr->sh_name, ".resource_table")) -+ continue; -+ -+ table = (struct resource_table *)(elf_data + offset); -+ -+ /* make sure we have the entire table */ -+ if (offset + size > fw_size || offset + size < size) { -+ dev_err(dev, "resource table truncated\n"); -+ return NULL; -+ } -+ -+ /* make sure table has at least the header */ -+ if (sizeof(struct resource_table) > size) { -+ dev_err(dev, "header-less resource table\n"); -+ return NULL; -+ } -+ -+ /* we don't support any version beyond the first */ -+ if (table->ver != 1) { -+ dev_err(dev, "unsupported fw ver: %d\n", table->ver); -+ return NULL; -+ } -+ -+ /* make sure reserved bytes are zeroes */ -+ if (table->reserved[0] || table->reserved[1]) { -+ dev_err(dev, "non zero reserved bytes\n"); -+ return NULL; -+ } -+ -+ /* make sure the offsets array isn't truncated */ -+ if (table->num * sizeof(table->offset[0]) + -+ sizeof(struct resource_table) > size) { -+ dev_err(dev, "resource table incomplete\n"); -+ return NULL; -+ } -+ -+ return shdr; -+ } -+ -+ return NULL; -+} -+ -+/** -+ * rproc_elf_find_load_rsc_table() - find the loaded resource table -+ * @dev: the rproc device -+ * @fw_addr: the ELF firmware image address -+ * @fw_size: the ELF firmware image size -+ * @rsc_addr: resource table address -+ * @rsc_size: resource table size -+ * -+ * This function finds the resource table, load it and return its address. -+ * -+ * Return: 0 if all ok, else appropriate error value. -+ */ -+static int rproc_elf_find_load_rsc_table(struct udevice *dev, -+ ulong fw_addr, ulong fw_size, -+ ulong *rsc_addr, -+ unsigned int *rsc_size) -+{ -+ const struct dm_rproc_ops *ops; -+ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)fw_addr; -+ Elf32_Shdr *shdr; -+ void *src; -+ void *dst; -+ -+ shdr = find_rsc_table(dev, ehdr, fw_size); -+ if (!shdr) -+ return -ENODATA; -+ -+ *rsc_addr = (ulong)shdr->sh_addr; -+ *rsc_size = (unsigned int)shdr->sh_size; -+ -+ ops = rproc_get_ops(dev); -+ if (ops->da_to_pa) -+ dst = (void *)ops->da_to_pa(dev, (ulong)shdr->sh_addr); -+ else -+ dst = (void *)shdr->sh_addr; -+ -+ dev_dbg(dev, "Loading resource table to 0x%8lx (%i bytes)\n", -+ (ulong)dst, shdr->sh_size); -+ -+ src = (void *)fw_addr + shdr->sh_offset; -+ -+ memcpy(dst, src, shdr->sh_size); -+ flush_cache((unsigned long)dst, shdr->sh_size); -+ -+ return 0; -+} -+ - int rproc_load(int id, ulong addr, ulong size) - { - struct udevice *dev = NULL; - struct dm_rproc_uclass_pdata *uc_pdata; - const struct dm_rproc_ops *ops; -+ unsigned long entry; - int ret; - - ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev); -@@ -315,8 +591,22 @@ int rproc_load(int id, ulong addr, ulong size) - - debug("Loading to '%s' from address 0x%08lX size of %lu bytes\n", - uc_pdata->name, addr, size); -- if (ops->load) -- return ops->load(dev, addr, size); -+ -+ if (is_valid_elf_image(addr, size)) { -+ if (rproc_elf_sanity_check(dev, addr, size)) -+ return -EINVAL; -+ -+ /* Elf file load */ -+ if (ops->reset) -+ ops->reset(dev); -+ -+ return rproc_load_elf_image(dev, addr, &entry); -+ -+ } else { -+ /* Binary file load */ -+ if (ops->load) -+ return ops->load(dev, addr, size); -+ } - - debug("%s: data corruption?? mandatory function is missing!\n", - dev->name); -@@ -324,6 +614,45 @@ int rproc_load(int id, ulong addr, ulong size) - return -EINVAL; - }; - -+int rproc_load_rsc_table(int id, ulong addr, ulong size, ulong *rsc_addr, -+ unsigned int *rsc_size) -+{ -+ struct udevice *dev = NULL; -+ const struct dm_rproc_ops *ops; -+ int ret; -+ -+ ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev); -+ if (ret) { -+ debug("Unknown remote processor id '%d' requested(%d)\n", -+ id, ret); -+ return -EINVAL; -+ } -+ -+ ops = rproc_get_ops(dev); -+ if (!ops) { -+ dev_dbg(dev, "Driver has no ops?\n"); -+ return -EINVAL; -+ } -+ -+ dev_dbg(dev, "Loocking for resource table from address 0x%08lX size of %lu bytes\n", -+ addr, size); -+ -+ if (!rproc_elf_sanity_check(dev, addr, size)) { -+ /* load elf image */ -+ ret = rproc_elf_find_load_rsc_table(dev, addr, size, rsc_addr, -+ rsc_size); -+ if (ret) { -+ dev_dbg(dev, "No resource table found\n"); -+ return -ENODATA; -+ } -+ dev_dbg(dev, "Resource table at 0x%08lx, size 0x%x!\n", -+ *rsc_addr, *rsc_size); -+ return 0; -+ } -+ -+ return -ENODATA; -+}; -+ - /* - * Completely internal helper enums.. - * Keeping this isolated helps this code evolve independent of other -diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c -new file mode 100644 -index 0000000..310d077 ---- /dev/null -+++ b/drivers/remoteproc/stm32_copro.c -@@ -0,0 +1,272 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+#define pr_fmt(fmt) "%s: " fmt, __func__ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define RCC_GCR_HOLD_BOOT 0 -+#define RCC_GCR_RELEASE_BOOT 1 -+ -+/** -+ * struct stm32_copro_privdata - power processor private data -+ * @loadaddr: base address for loading the power processor -+ * @reset_ctl: reset controller handle -+ * @hold_boot_regmap -+ * @hold_boot_offset -+ * @hold_boot_mask -+ * @secured_soc: TZEN flag (register protection) -+ */ -+struct stm32_copro_privdata { -+ phys_addr_t loadaddr; -+ struct reset_ctl reset_ctl; -+ struct regmap *hold_boot_regmap; -+ uint hold_boot_offset; -+ uint hold_boot_mask; -+ bool secured_soc; -+ }; -+ -+/** -+ * st_of_to_priv() - generate private data from device tree -+ * @dev: corresponding ti remote processor device -+ * @priv: pointer to driver specific private data -+ * -+ * Return: 0 if all went ok, else corresponding -ve error -+ */ -+static int st_of_to_priv(struct udevice *dev, -+ struct stm32_copro_privdata *priv) -+{ -+ struct regmap *regmap; -+ const fdt32_t *cell; -+ const void *blob = gd->fdt_blob; -+ uint tz_offset, tz_mask, tzen; -+ int len, ret; -+ -+ if (!blob) { -+ dev_dbg(dev, "no dt?\n"); -+ return -EINVAL; -+ } -+ -+ priv->loadaddr = dev_read_addr(dev); -+ if (priv->loadaddr == FDT_ADDR_T_NONE) { -+ dev_dbg(dev, "no 'reg' property\n"); -+ return -EINVAL; -+ } -+ -+ regmap = syscon_phandle_to_regmap(dev, "st,syscfg-holdboot"); -+ if (IS_ERR(regmap)) { -+ dev_dbg(dev, "unable to find holdboot regmap (%ld)\n", -+ PTR_ERR(regmap)); -+ return -EINVAL; -+ } -+ -+ priv->hold_boot_regmap = regmap; -+ -+ cell = dev_read_prop(dev, "st,syscfg-holdboot", &len); -+ if (len < 3 * sizeof(fdt32_t)) { -+ dev_dbg(dev, "holdboot offset and mask not available\n"); -+ return -EINVAL; -+ } -+ -+ priv->hold_boot_offset = fdtdec_get_number(cell + 1, 1); -+ -+ priv->hold_boot_mask = fdtdec_get_number(cell + 2, 1); -+ -+ regmap = syscon_phandle_to_regmap(dev, "st,syscfg-tz"); -+ if (IS_ERR(regmap)) { -+ dev_dbg(dev, "unable to find tz regmap (%ld)\n", -+ PTR_ERR(regmap)); -+ return -EINVAL; -+ } -+ -+ cell = dev_read_prop(dev, "st,syscfg-tz", &len); -+ if (len < 3 * sizeof(fdt32_t)) { -+ dev_dbg(dev, "tz offset and mask not available\n"); -+ return -EINVAL; -+ } -+ -+ tz_offset = fdtdec_get_number(cell + 1, 1); -+ -+ tz_mask = fdtdec_get_number(cell + 2, 1); -+ -+ ret = regmap_read(regmap, tz_offset, &tzen); -+ if (ret) { -+ dev_dbg(dev, "failed to read soc secure state\n"); -+ return ret; -+ } -+ -+ priv->secured_soc = !!(tzen & tz_mask); -+ -+ return reset_get_by_index(dev, 0, &priv->reset_ctl); -+} -+ -+/** -+ * stm32_copro_probe() - Basic probe -+ * @dev: corresponding STM32 remote processor device -+ * -+ * Return: 0 if all went ok, else corresponding -ve error -+ */ -+static int stm32_copro_probe(struct udevice *dev) -+{ -+ struct stm32_copro_privdata *priv; -+ int ret; -+ -+ priv = dev_get_priv(dev); -+ -+ ret = st_of_to_priv(dev, priv); -+ -+ dev_dbg(dev, "probed with slave_addr=0x%08lX (%d)\n", -+ priv->loadaddr, ret); -+ -+ return ret; -+} -+ -+/* Hold boot bit management */ -+static int stm32_copro_set_hold_boot(struct udevice *dev, bool hold) -+{ -+ struct stm32_copro_privdata *priv; -+ uint status, val; -+ int ret; -+ -+ priv = dev_get_priv(dev); -+ -+ val = hold ? RCC_GCR_HOLD_BOOT : RCC_GCR_RELEASE_BOOT; -+ -+ if (priv->secured_soc) { -+ return stm32_smc_exec(STM32_SMC_RCC, STM32_SMC_REG_WRITE, -+ priv->hold_boot_offset, val); -+ } -+ -+ ret = regmap_read(priv->hold_boot_regmap, priv->hold_boot_offset, -+ &status); -+ if (ret) { -+ dev_err(dev, "failed to read status of mcu\n"); -+ return ret; -+ } -+ -+ status &= ~priv->hold_boot_mask; -+ status |= val; -+ -+ ret = regmap_write(priv->hold_boot_regmap, priv->hold_boot_offset, -+ status); -+ if (ret) -+ dev_err(dev, "failed to set hold boot\n"); -+ -+ return ret; -+} -+ -+/** -+ * stm32_copro_load() - Loadup the STM32 Cortex-M4 remote processor -+ * @dev: corresponding STM32 remote processor device -+ * @addr: Address in memory where image binary is stored -+ * @size: Size in bytes of the image binary -+ * -+ * Return: 0 if all went ok, else corresponding -ve error -+ */ -+static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size) -+{ -+ struct stm32_copro_privdata *priv; -+ int ret; -+ -+ priv = dev_get_priv(dev); -+ -+ stm32_copro_set_hold_boot(dev, true); -+ -+ ret = reset_assert(&priv->reset_ctl); -+ if (ret) { -+ dev_dbg(dev, "Unable assert reset line (ret=%d)\n", ret); -+ return ret; -+ } -+ -+ dev_dbg(dev, "Loading binary from 0x%08lX, size 0x%08lX to 0x%08lX\n", -+ addr, size, priv->loadaddr); -+ -+ memcpy((void *)priv->loadaddr, (void *)addr, size); -+ -+ dev_dbg(dev, "Complete!\n"); -+ return 0; -+} -+ -+/** -+ * stm32_copro_start() - Start Cortex-M4 coprocessor -+ * @dev: corresponding st remote processor device -+ * -+ * Return: 0 if all went ok, else corresponding -ve error -+ */ -+static int stm32_copro_start(struct udevice *dev) -+{ -+ int ret; -+ -+ /* move hold boot from true to false start the copro */ -+ ret = stm32_copro_set_hold_boot(dev, false); -+ if (ret) -+ return ret; -+ -+ /* -+ * Once copro running, reset hold boot flag to avoid copro -+ * rebooting autonomously -+ */ -+ return stm32_copro_set_hold_boot(dev, true); -+} -+ -+/** -+ * stm32_copro_reset() - Reset Cortex-M4 coprocessor -+ * @dev: corresponding st remote processor device -+ * -+ * Return: 0 if all went ok, else corresponding -ve error -+ */ -+static int stm32_copro_reset(struct udevice *dev) -+{ -+ struct stm32_copro_privdata *priv; -+ int ret; -+ -+ priv = dev_get_priv(dev); -+ -+ stm32_copro_set_hold_boot(dev, true); -+ -+ ret = reset_assert(&priv->reset_ctl); -+ if (ret) { -+ dev_dbg(dev, "Unable assert reset line (ret=%d)\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+ulong stm32_copro_da_to_pa(struct udevice *dev, ulong da) -+{ -+ /* to update according to lastest DT */ -+ if (da >= 0 && da < 0x10000) -+ return (da + 0x38000000); -+ -+ return da; -+} -+ -+static const struct dm_rproc_ops stm32_copro_ops = { -+ .load = stm32_copro_load, -+ .start = stm32_copro_start, -+ .reset = stm32_copro_reset, -+ .da_to_pa = stm32_copro_da_to_pa, -+}; -+ -+static const struct udevice_id stm32_copro_ids[] = { -+ {.compatible = "st,stm32mp1-rproc"}, -+ {} -+}; -+ -+U_BOOT_DRIVER(stm32_copro) = { -+ .name = "stm32_m4_proc", -+ .of_match = stm32_copro_ids, -+ .id = UCLASS_REMOTEPROC, -+ .ops = &stm32_copro_ops, -+ .probe = stm32_copro_probe, -+ .priv_auto_alloc_size = sizeof(struct stm32_copro_privdata), -+}; -diff --git a/drivers/reset/stm32-reset.c b/drivers/reset/stm32-reset.c -index 16d3dba..1d00e17 100644 ---- a/drivers/reset/stm32-reset.c -+++ b/drivers/reset/stm32-reset.c -@@ -11,6 +11,13 @@ - #include - #include - -+#ifdef CONFIG_STM32MP1_TRUSTED -+#include -+ -+#define RCC_APB5RST_BANK 0x62 -+#define RCC_AHB5RST_BANK 0x64 -+#endif /* CONFIG_STM32MP1_TRUSTED */ -+ - /* reset clear offset for STM32MP RCC */ - #define RCC_CL 0x4 - -@@ -33,12 +40,23 @@ static int stm32_reset_assert(struct reset_ctl *reset_ctl) - struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev); - int bank = (reset_ctl->id / BITS_PER_LONG) * 4; - int offset = reset_ctl->id % BITS_PER_LONG; -+#ifdef CONFIG_STM32MP1_TRUSTED -+ int rcc_bank = reset_ctl->id / BITS_PER_LONG; -+#endif /* CONFIG_STM32MP1_TRUSTED */ -+ - debug("%s: reset id = %ld bank = %d offset = %d)\n", __func__, - 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); -+#ifdef CONFIG_STM32MP1_TRUSTED -+ if (rcc_bank == RCC_APB5RST_BANK || -+ rcc_bank == RCC_AHB5RST_BANK) -+ stm32_smc_exec(STM32_SMC_RCC, STM32_SMC_REG_WRITE, -+ bank, BIT(offset)); -+ else -+#endif /* CONFIG_STM32MP1_TRUSTED */ -+ writel(BIT(offset), priv->base + bank); - else - setbits_le32(priv->base + bank, BIT(offset)); - -@@ -50,12 +68,23 @@ static int stm32_reset_deassert(struct reset_ctl *reset_ctl) - struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev); - int bank = (reset_ctl->id / BITS_PER_LONG) * 4; - int offset = reset_ctl->id % BITS_PER_LONG; -+#ifdef CONFIG_STM32MP1_TRUSTED -+ int rcc_bank = reset_ctl->id / BITS_PER_LONG; -+#endif /* CONFIG_STM32MP1_TRUSTED */ -+ - debug("%s: reset id = %ld bank = %d offset = %d)\n", __func__, - 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); -+#ifdef CONFIG_STM32MP1_TRUSTED -+ if (rcc_bank == RCC_APB5RST_BANK || -+ rcc_bank == RCC_AHB5RST_BANK) -+ stm32_smc_exec(STM32_SMC_RCC, STM32_SMC_REG_WRITE, -+ bank + RCC_CL, BIT(offset)); -+ else -+#endif /* CONFIG_STM32MP1_TRUSTED */ -+ writel(BIT(offset), priv->base + bank + RCC_CL); - else - clrbits_le32(priv->base + bank, BIT(offset)); - -diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c -index 66e02d5..d806057 100644 ---- a/drivers/serial/serial_stm32.c -+++ b/drivers/serial/serial_stm32.c -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -66,6 +67,14 @@ static int stm32_serial_setconfig(struct udevice *dev, uint serial_config) - if (bits != SERIAL_8_BITS || stop != SERIAL_ONE_STOP || stm32f4) - return -ENOTSUPP; /* not supported in driver*/ - -+ /* -+ * only parity config is implemented, check if other serial settings -+ * are the default one. -+ * (STM32F4 serial IP didn't support parity setting) -+ */ -+ if (bits != SERIAL_8_BITS || stop != SERIAL_ONE_STOP || stm32f4) -+ return -ENOTSUPP; /* not supported in driver*/ -+ - clrbits_le32(cr1, USART_CR1_RE | USART_CR1_TE | BIT(uart_enable_bit)); - /* update usart configuration (uart need to be disable) - * PCE: parity check enable -@@ -171,6 +180,7 @@ static int stm32_serial_probe(struct udevice *dev) - { - struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); - struct clk clk; -+ struct reset_ctl reset; - int ret; - - plat->uart_info = (struct stm32_uart_info *)dev_get_driver_data(dev); -@@ -185,6 +195,13 @@ static int stm32_serial_probe(struct udevice *dev) - return ret; - } - -+ ret = reset_get_by_index(dev, 0, &reset); -+ if (!ret) { -+ reset_assert(&reset); -+ udelay(2); -+ reset_deassert(&reset); -+ } -+ - plat->clock_rate = clk_get_rate(&clk); - if (plat->clock_rate < 0) { - clk_disable(&clk); -@@ -258,7 +275,6 @@ static inline void _debug_uart_init(void) - _stm32_serial_setbrg(base, uart_info, - CONFIG_DEBUG_UART_CLOCK, - CONFIG_BAUDRATE); -- printf("DEBUG done\n"); - } - - static inline void _debug_uart_putc(int c) -diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index 516188e..da96754 100644 ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -191,7 +191,7 @@ config SANDBOX_SPI - - config STM32_QSPI - bool "STM32F7 QSPI driver" -- depends on STM32F7 -+ depends on STM32F7 || ARCH_STM32MP - help - Enable the STM32F7 Quad-SPI (QSPI) driver. This driver can be - used to access the SPI NOR flash chips on platforms embedding -diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c -index b06883f..b80f810 100644 ---- a/drivers/spi/soft_spi.c -+++ b/drivers/spi/soft_spi.c -@@ -215,8 +215,8 @@ static int soft_spi_probe(struct udevice *dev) - int cs_flags, clk_flags; - int ret; - -- cs_flags = (slave->mode & SPI_CS_HIGH) ? 0 : GPIOD_ACTIVE_LOW; -- clk_flags = (slave->mode & SPI_CPOL) ? GPIOD_ACTIVE_LOW : 0; -+ cs_flags = (slave && slave->mode & SPI_CS_HIGH) ? 0 : GPIOD_ACTIVE_LOW; -+ clk_flags = (slave && slave->mode & SPI_CPOL) ? GPIOD_ACTIVE_LOW : 0; - - if (gpio_request_by_name(dev, "cs-gpios", 0, &plat->cs, - GPIOD_IS_OUT | cs_flags) || -diff --git a/drivers/sysreset/sysreset_syscon.c b/drivers/sysreset/sysreset_syscon.c -index 3450640..9d02aaf 100644 ---- a/drivers/sysreset/sysreset_syscon.c -+++ b/drivers/sysreset/sysreset_syscon.c -@@ -24,6 +24,9 @@ static int syscon_reboot_request(struct udevice *dev, enum sysreset_t type) - { - struct syscon_reboot_priv *priv = dev_get_priv(dev); - -+ if (type == SYSRESET_POWER) -+ return -EPROTONOSUPPORT; -+ - regmap_write(priv->regmap, priv->offset, priv->mask); - - return -EINPROGRESS; -@@ -36,20 +39,9 @@ static struct sysreset_ops syscon_reboot_ops = { - int syscon_reboot_probe(struct udevice *dev) - { - struct syscon_reboot_priv *priv = dev_get_priv(dev); -- int err; -- u32 phandle; -- ofnode node; -- -- err = ofnode_read_u32(dev_ofnode(dev), "regmap", &phandle); -- if (err) -- return err; -- -- node = ofnode_get_by_phandle(phandle); -- if (!ofnode_valid(node)) -- return -EINVAL; - -- priv->regmap = syscon_node_to_regmap(node); -- if (!priv->regmap) { -+ priv->regmap = syscon_phandle_to_regmap(dev, "regmap"); -+ if (IS_ERR(priv->regmap)) { - pr_err("unable to find regmap\n"); - return -ENODEV; - } -diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig -index 26b4d12..fa1cdc4 100644 ---- a/drivers/usb/gadget/Kconfig -+++ b/drivers/usb/gadget/Kconfig -@@ -72,6 +72,15 @@ config USB_GADGET_BCM_UDC_OTG_PHY - help - Enable the Broadcom UDC OTG physical device interface. - -+config USB_GADGET_GEN_UDC_OTG_PHY -+ bool "Generic UDC OTG PHY" -+ depends on PHY && USB_GADGET_DWC2_OTG -+ default y if ARCH_STM32MP -+ help -+ Enable the generic UDC OTG physical device interface. -+ it is based on the generic phy driver API on the phy -+ u-class and on the device tree information -+ - config USB_GADGET_DWC2_OTG - bool "DesignWare USB2.0 HS OTG controller (gadget mode)" - select USB_GADGET_DUALSPEED -diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile -index b74c1fd..abb3c20 100644 ---- a/drivers/usb/gadget/Makefile -+++ b/drivers/usb/gadget/Makefile -@@ -20,6 +20,7 @@ obj-$(CONFIG_USB_GADGET_BCM_UDC_OTG_PHY) += bcm_udc_otg_phy.o - obj-$(CONFIG_USB_GADGET_DWC2_OTG) += dwc2_udc_otg.o - obj-$(CONFIG_USB_GADGET_DWC2_OTG_PHY) += dwc2_udc_otg_phy.o - obj-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o -+obj-$(CONFIG_USB_GADGET_GEN_UDC_OTG_PHY) += gen_udc_otg_phy.o - obj-$(CONFIG_CI_UDC) += ci_udc.o - ifndef CONFIG_SPL_BUILD - obj-$(CONFIG_USB_GADGET_DOWNLOAD) += g_dnl.o -diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c -index e3edd10..6552a5b 100644 ---- a/drivers/usb/gadget/dwc2_udc_otg.c -+++ b/drivers/usb/gadget/dwc2_udc_otg.c -@@ -425,6 +425,9 @@ static void reconfig_usbd(struct dwc2_udc *dev) - - writel(dflt_gusbcfg, ®->gusbcfg); - -+ if (dev->pdata->usb_gotgctl) -+ setbits_le32(®->gotgctl, dev->pdata->usb_gotgctl); -+ - /* 3. Put the OTG device core in the disconnected state.*/ - uTemp = readl(®->dctl); - uTemp |= SOFT_DISCONNECT; -diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c -index e9e1600..43d0516 100644 ---- a/drivers/usb/gadget/g_dnl.c -+++ b/drivers/usb/gadget/g_dnl.c -@@ -89,6 +89,11 @@ static struct usb_gadget_strings *g_dnl_composite_strings[] = { - NULL, - }; - -+void g_dnl_set_product(const char *s) -+{ -+ g_dnl_string_defs[1].s = s; -+} -+ - static int g_dnl_unbind(struct usb_composite_dev *cdev) - { - struct usb_gadget *gadget = cdev->gadget; -diff --git a/drivers/usb/gadget/gen_udc_otg_phy.c b/drivers/usb/gadget/gen_udc_otg_phy.c -new file mode 100644 -index 0000000..36c31cd ---- /dev/null -+++ b/drivers/usb/gadget/gen_udc_otg_phy.c -@@ -0,0 +1,66 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+ -+#include "dwc2_udc_otg_priv.h" -+ -+void otg_phy_init(struct dwc2_udc *dev) -+{ -+ struct dwc2_plat_otg_data *pdata = dev->pdata; -+ struct udevice *phy_dev; -+ struct phy phy; -+ -+ if (uclass_get_device_by_of_offset(UCLASS_PHY, -+ pdata->phy_of_node, &phy_dev)) { -+ pr_err("failed to found usb phy\n"); -+ hang(); -+ return; -+ } -+ -+ phy.dev = phy_dev; -+ phy.id = pdata->regs_phy; -+ -+ if (generic_phy_init(&phy)) { -+ pr_err("failed to init usb phy\n"); -+ generic_phy_power_off(&phy); -+ return; -+ } -+ -+ if (generic_phy_power_on(&phy)) { -+ pr_err("unable to power on the phy\n"); -+ return; -+ } -+ -+ pr_debug("USB Generic PHY Enable\n"); -+} -+ -+void otg_phy_off(struct dwc2_udc *dev) -+{ -+ struct dwc2_plat_otg_data *pdata = dev->pdata; -+ struct udevice *phy_dev; -+ struct phy phy; -+ int ret; -+ -+ uclass_get_device_by_of_offset(UCLASS_PHY, -+ pdata->phy_of_node, &phy_dev); -+ phy.dev = phy_dev; -+ phy.id = pdata->regs_phy; -+ -+ ret = generic_phy_power_off(&phy); -+ if (ret) { -+ pr_err("failed to power off usb phy\n"); -+ return; -+ } -+ ret = generic_phy_exit(&phy); -+ if (ret) { -+ pr_err("failed to power off usb phy\n"); -+ return; -+ } -+ -+ pr_debug("USB Generic PHY Disable\n"); -+} -diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c -index b6f008a..f96da8e 100644 ---- a/drivers/usb/host/dwc2.c -+++ b/drivers/usb/host/dwc2.c -@@ -5,12 +5,15 @@ - */ - - #include -+#include - #include - #include --#include -+#include - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -35,6 +38,7 @@ struct dwc2_priv { - #ifdef CONFIG_DM_REGULATOR - struct udevice *vbus_supply; - #endif -+ struct phy phy; - #else - uint8_t *aligned_buffer; - uint8_t *status_buffer; -@@ -811,7 +815,7 @@ int wait_for_chhltd(struct dwc2_hc_regs *hc_regs, uint32_t *sub, u8 *toggle) - uint32_t hcint, hctsiz; - - ret = wait_for_bit_le32(&hc_regs->hcint, DWC2_HCINT_CHHLTD, true, -- 2000, false); -+ 2000, false); - if (ret) - return ret; - -@@ -1210,6 +1214,8 @@ static int dwc2_init_common(struct udevice *dev, struct dwc2_priv *priv) - if (readl(®s->gintsts) & DWC2_GINTSTS_CURMODE_HOST) - mdelay(1000); - -+ printf("USB DWC2\n"); -+ - return 0; - } - -@@ -1317,13 +1323,119 @@ static int dwc2_usb_ofdata_to_platdata(struct udevice *dev) - return 0; - } - -+static int dwc2_setup_phy(struct udevice *dev) -+{ -+ struct dwc2_priv *priv = dev_get_priv(dev); -+ int ret; -+ -+ ret = generic_phy_get_by_index(dev, 0, &priv->phy); -+ if (ret) { -+ if (ret != -ENOENT) { -+ dev_err(dev, "failed to get usb phy\n"); -+ return ret; -+ } -+ return 0; -+ } -+ -+ ret = generic_phy_init(&priv->phy); -+ if (ret) { -+ dev_err(dev, "failed to init usb phy\n"); -+ return ret; -+ } -+ -+ ret = generic_phy_power_on(&priv->phy); -+ if (ret) { -+ dev_err(dev, "failed to power on usb phy\n"); -+ return generic_phy_exit(&priv->phy); -+ } -+ -+ return 0; -+} -+ -+static int dwc2_shutdown_phy(struct udevice *dev) -+{ -+ struct dwc2_priv *priv = dev_get_priv(dev); -+ int ret; -+ -+ if (!generic_phy_valid(&priv->phy)) -+ return 0; -+ -+ ret = generic_phy_power_off(&priv->phy); -+ if (ret) { -+ dev_err(dev, "failed to power off usb phy\n"); -+ return ret; -+ } -+ -+ ret = generic_phy_exit(&priv->phy); -+ if (ret) { -+ dev_err(dev, "failed to power off usb phy\n"); -+ return ret; -+ } -+ return 0; -+} -+ -+static int dwc2_reset_init(struct udevice *dev) -+{ -+ struct reset_ctl_bulk resets; -+ int ret; -+ -+ ret = reset_get_bulk(dev, &resets); -+ if (ret == -ENOTSUPP || ret == -ENOENT) -+ return 0; -+ else if (ret) -+ return ret; -+ -+ reset_assert_bulk(&resets); -+ udelay(2); -+ ret = reset_deassert_bulk(&resets); -+ if (ret) { -+ reset_release_bulk(&resets); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int dwc2_clk_init(struct udevice *dev) -+{ -+ struct clk_bulk clks; -+ int ret; -+ -+ ret = clk_get_bulk(dev, &clks); -+ if (ret == -ENOSYS || ret == -ENOENT) -+ return 0; -+ if (ret) -+ return ret; -+ -+ ret = clk_enable_bulk(&clks); -+ if (ret) { -+ clk_release_bulk(&clks); -+ return ret; -+ } -+ -+ return 0; -+} -+ - static int dwc2_usb_probe(struct udevice *dev) - { - struct dwc2_priv *priv = dev_get_priv(dev); - struct usb_bus_priv *bus_priv = dev_get_uclass_priv(dev); -+ int ret; - - bus_priv->desc_before_addr = true; - -+ ret = dwc2_reset_init(dev); -+ if (ret) -+ return ret; -+ -+ ret = dwc2_clk_init(dev); -+ if (ret) -+ return ret; -+ -+ ret = dwc2_setup_phy(dev); -+ if (ret) -+ return ret; -+ - return dwc2_init_common(dev, priv); - } - -@@ -1336,6 +1448,8 @@ static int dwc2_usb_remove(struct udevice *dev) - if (ret) - return ret; - -+ dwc2_shutdown_phy(dev); -+ - dwc2_uninit_common(priv->regs); - - reset_release_bulk(&priv->resets); -diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig -index 25c94f4..8809552 100644 ---- a/drivers/video/Kconfig -+++ b/drivers/video/Kconfig -@@ -73,6 +73,13 @@ config VIDEO_ANSI - Enable ANSI escape sequence decoding for a more fully functional - console. - -+config VIDEO_MIPI_DSI -+ bool -+ help -+ Support MIPI DSI interface for driving a MIPI compatible device. -+ The MIPI Display Serial Interface (MIPI DSI) defines a high-speed -+ serial interface between a host processor and a display module. -+ - config CONSOLE_NORMAL - bool "Support a simple text console" - depends on DM_VIDEO -@@ -320,6 +327,22 @@ config VIDEO_LCD_ANX9804 - from a parallel LCD interface and translate it on the fy into a DP - interface for driving eDP TFT displays. It uses I2C for configuration. - -+config VIDEO_LCD_ORISETECH_OTM8009A -+ bool "OTM8009A DSI LCD panel support" -+ depends on DM_VIDEO -+ select VIDEO_MIPI_DSI -+ default n -+ ---help--- -+ Support for Orise Tech otm8009a 480p dsi 2dl video mode panel. -+ -+config VIDEO_LCD_RAYDIUM_RM68200 -+ bool "RM68200 DSI LCD panel support" -+ depends on DM_VIDEO -+ select VIDEO_MIPI_DSI -+ default n -+ ---help--- -+ Support for Raydium rm68200 720x1280 dsi 2dl video mode panel. -+ - config VIDEO_LCD_SSD2828 - bool "SSD2828 bridge chip" - default n -@@ -681,6 +704,16 @@ config VIDEO_DW_HDMI - rather requires a SoC-specific glue driver to call it), it - can not be enabled from the configuration menu. - -+config VIDEO_DW_MIPI_DSI -+ bool -+ select VIDEO_MIPI_DSI -+ help -+ Enables the common driver code for the Synopsis Designware -+ block found in SoCs from various vendors. -+ As this does not provide any functionality by itself (but -+ rather requires a SoC-specific glue driver to call it), it -+ can not be enabled from the configuration menu. -+ - config VIDEO_SIMPLE - bool "Simple display driver for preconfigured display" - help -diff --git a/drivers/video/Makefile b/drivers/video/Makefile -index 80e1e82..c3d39ed 100644 ---- a/drivers/video/Makefile -+++ b/drivers/video/Makefile -@@ -50,6 +50,8 @@ obj-$(CONFIG_VIDEO_IPUV3) += mxc_ipuv3_fb.o ipu_common.o ipu_disp.o - obj-$(CONFIG_VIDEO_IVYBRIDGE_IGD) += ivybridge_igd.o - 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_SSD2828) += ssd2828.o - obj-$(CONFIG_VIDEO_MB862xx) += mb862xx.o videomodes.o - obj-$(CONFIG_VIDEO_MVEBU) += mvebu_lcd.o -@@ -61,6 +63,8 @@ obj-$(CONFIG_VIDEO_SIMPLE) += simplefb.o - obj-$(CONFIG_VIDEO_TEGRA20) += tegra.o - obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o - obj-$(CONFIG_VIDEO_VESA) += vesa.o -+obj-$(CONFIG_VIDEO_DW_MIPI_DSI) += dw_mipi_dsi.o -+obj-${CONFIG_VIDEO_MIPI_DSI} += mipi_display.o - - obj-y += bridge/ - obj-y += sunxi/ -diff --git a/drivers/video/dw_mipi_dsi.c b/drivers/video/dw_mipi_dsi.c -new file mode 100644 -index 0000000..fe1e25a ---- /dev/null -+++ b/drivers/video/dw_mipi_dsi.c -@@ -0,0 +1,826 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2016, Fuzhou Rockchip Electronics Co., Ltd -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ * Author(s): Philippe Cornu for STMicroelectronics. -+ * Yannick Fertre for STMicroelectronics. -+ * -+ * This generic Synopsys DesignWare MIPI DSI host driver is based on the -+ * Linux Kernel driver from drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define HWVER_131 0x31333100 /* IP version 1.31 */ -+ -+#define DSI_VERSION 0x00 -+#define VERSION GENMASK(31, 8) -+ -+#define DSI_PWR_UP 0x04 -+#define RESET 0 -+#define POWERUP BIT(0) -+ -+#define DSI_CLKMGR_CFG 0x08 -+#define TO_CLK_DIVISION(div) (((div) & 0xff) << 8) -+#define TX_ESC_CLK_DIVISION(div) ((div) & 0xff) -+ -+#define DSI_DPI_VCID 0x0c -+#define DPI_VCID(vcid) ((vcid) & 0x3) -+ -+#define DSI_DPI_COLOR_CODING 0x10 -+#define LOOSELY18_EN BIT(8) -+#define DPI_COLOR_CODING_16BIT_1 0x0 -+#define DPI_COLOR_CODING_16BIT_2 0x1 -+#define DPI_COLOR_CODING_16BIT_3 0x2 -+#define DPI_COLOR_CODING_18BIT_1 0x3 -+#define DPI_COLOR_CODING_18BIT_2 0x4 -+#define DPI_COLOR_CODING_24BIT 0x5 -+ -+#define DSI_DPI_CFG_POL 0x14 -+#define COLORM_ACTIVE_LOW BIT(4) -+#define SHUTD_ACTIVE_LOW BIT(3) -+#define HSYNC_ACTIVE_LOW BIT(2) -+#define VSYNC_ACTIVE_LOW BIT(1) -+#define DATAEN_ACTIVE_LOW BIT(0) -+ -+#define DSI_DPI_LP_CMD_TIM 0x18 -+#define OUTVACT_LPCMD_TIME(p) (((p) & 0xff) << 16) -+#define INVACT_LPCMD_TIME(p) ((p) & 0xff) -+ -+#define DSI_DBI_VCID 0x1c -+#define DSI_DBI_CFG 0x20 -+#define DSI_DBI_PARTITIONING_EN 0x24 -+#define DSI_DBI_CMDSIZE 0x28 -+ -+#define DSI_PCKHDL_CFG 0x2c -+#define CRC_RX_EN BIT(4) -+#define ECC_RX_EN BIT(3) -+#define BTA_EN BIT(2) -+#define EOTP_RX_EN BIT(1) -+#define EOTP_TX_EN BIT(0) -+ -+#define DSI_GEN_VCID 0x30 -+ -+#define DSI_MODE_CFG 0x34 -+#define ENABLE_VIDEO_MODE 0 -+#define ENABLE_CMD_MODE BIT(0) -+ -+#define DSI_VID_MODE_CFG 0x38 -+#define ENABLE_LOW_POWER (0x3f << 8) -+#define ENABLE_LOW_POWER_MASK (0x3f << 8) -+#define VID_MODE_TYPE_NON_BURST_SYNC_PULSES 0x0 -+#define VID_MODE_TYPE_NON_BURST_SYNC_EVENTS 0x1 -+#define VID_MODE_TYPE_BURST 0x2 -+#define VID_MODE_TYPE_MASK 0x3 -+ -+#define DSI_VID_PKT_SIZE 0x3c -+#define VID_PKT_SIZE(p) ((p) & 0x3fff) -+ -+#define DSI_VID_NUM_CHUNKS 0x40 -+#define VID_NUM_CHUNKS(c) ((c) & 0x1fff) -+ -+#define DSI_VID_NULL_SIZE 0x44 -+#define VID_NULL_SIZE(b) ((b) & 0x1fff) -+ -+#define DSI_VID_HSA_TIME 0x48 -+#define DSI_VID_HBP_TIME 0x4c -+#define DSI_VID_HLINE_TIME 0x50 -+#define DSI_VID_VSA_LINES 0x54 -+#define DSI_VID_VBP_LINES 0x58 -+#define DSI_VID_VFP_LINES 0x5c -+#define DSI_VID_VACTIVE_LINES 0x60 -+#define DSI_EDPI_CMD_SIZE 0x64 -+ -+#define DSI_CMD_MODE_CFG 0x68 -+#define MAX_RD_PKT_SIZE_LP BIT(24) -+#define DCS_LW_TX_LP BIT(19) -+#define DCS_SR_0P_TX_LP BIT(18) -+#define DCS_SW_1P_TX_LP BIT(17) -+#define DCS_SW_0P_TX_LP BIT(16) -+#define GEN_LW_TX_LP BIT(14) -+#define GEN_SR_2P_TX_LP BIT(13) -+#define GEN_SR_1P_TX_LP BIT(12) -+#define GEN_SR_0P_TX_LP BIT(11) -+#define GEN_SW_2P_TX_LP BIT(10) -+#define GEN_SW_1P_TX_LP BIT(9) -+#define GEN_SW_0P_TX_LP BIT(8) -+#define ACK_RQST_EN BIT(1) -+#define TEAR_FX_EN BIT(0) -+ -+#define CMD_MODE_ALL_LP (MAX_RD_PKT_SIZE_LP | \ -+ DCS_LW_TX_LP | \ -+ DCS_SR_0P_TX_LP | \ -+ DCS_SW_1P_TX_LP | \ -+ DCS_SW_0P_TX_LP | \ -+ GEN_LW_TX_LP | \ -+ GEN_SR_2P_TX_LP | \ -+ GEN_SR_1P_TX_LP | \ -+ GEN_SR_0P_TX_LP | \ -+ GEN_SW_2P_TX_LP | \ -+ GEN_SW_1P_TX_LP | \ -+ GEN_SW_0P_TX_LP) -+ -+#define DSI_GEN_HDR 0x6c -+#define DSI_GEN_PLD_DATA 0x70 -+ -+#define DSI_CMD_PKT_STATUS 0x74 -+#define GEN_RD_CMD_BUSY BIT(6) -+#define GEN_PLD_R_FULL BIT(5) -+#define GEN_PLD_R_EMPTY BIT(4) -+#define GEN_PLD_W_FULL BIT(3) -+#define GEN_PLD_W_EMPTY BIT(2) -+#define GEN_CMD_FULL BIT(1) -+#define GEN_CMD_EMPTY BIT(0) -+ -+#define DSI_TO_CNT_CFG 0x78 -+#define HSTX_TO_CNT(p) (((p) & 0xffff) << 16) -+#define LPRX_TO_CNT(p) ((p) & 0xffff) -+ -+#define DSI_HS_RD_TO_CNT 0x7c -+#define DSI_LP_RD_TO_CNT 0x80 -+#define DSI_HS_WR_TO_CNT 0x84 -+#define DSI_LP_WR_TO_CNT 0x88 -+#define DSI_BTA_TO_CNT 0x8c -+ -+#define DSI_LPCLK_CTRL 0x94 -+#define AUTO_CLKLANE_CTRL BIT(1) -+#define PHY_TXREQUESTCLKHS BIT(0) -+ -+#define DSI_PHY_TMR_LPCLK_CFG 0x98 -+#define PHY_CLKHS2LP_TIME(lbcc) (((lbcc) & 0x3ff) << 16) -+#define PHY_CLKLP2HS_TIME(lbcc) ((lbcc) & 0x3ff) -+ -+#define DSI_PHY_TMR_CFG 0x9c -+#define PHY_HS2LP_TIME(lbcc) (((lbcc) & 0xff) << 24) -+#define PHY_LP2HS_TIME(lbcc) (((lbcc) & 0xff) << 16) -+#define MAX_RD_TIME(lbcc) ((lbcc) & 0x7fff) -+#define PHY_HS2LP_TIME_V131(lbcc) (((lbcc) & 0x3ff) << 16) -+#define PHY_LP2HS_TIME_V131(lbcc) ((lbcc) & 0x3ff) -+ -+#define DSI_PHY_RSTZ 0xa0 -+#define PHY_DISFORCEPLL 0 -+#define PHY_ENFORCEPLL BIT(3) -+#define PHY_DISABLECLK 0 -+#define PHY_ENABLECLK BIT(2) -+#define PHY_RSTZ 0 -+#define PHY_UNRSTZ BIT(1) -+#define PHY_SHUTDOWNZ 0 -+#define PHY_UNSHUTDOWNZ BIT(0) -+ -+#define DSI_PHY_IF_CFG 0xa4 -+#define PHY_STOP_WAIT_TIME(cycle) (((cycle) & 0xff) << 8) -+#define N_LANES(n) (((n) - 1) & 0x3) -+ -+#define DSI_PHY_ULPS_CTRL 0xa8 -+#define DSI_PHY_TX_TRIGGERS 0xac -+ -+#define DSI_PHY_STATUS 0xb0 -+#define PHY_STOP_STATE_CLK_LANE BIT(2) -+#define PHY_LOCK BIT(0) -+ -+#define DSI_PHY_TST_CTRL0 0xb4 -+#define PHY_TESTCLK BIT(1) -+#define PHY_UNTESTCLK 0 -+#define PHY_TESTCLR BIT(0) -+#define PHY_UNTESTCLR 0 -+ -+#define DSI_PHY_TST_CTRL1 0xb8 -+#define PHY_TESTEN BIT(16) -+#define PHY_UNTESTEN 0 -+#define PHY_TESTDOUT(n) (((n) & 0xff) << 8) -+#define PHY_TESTDIN(n) ((n) & 0xff) -+ -+#define DSI_INT_ST0 0xbc -+#define DSI_INT_ST1 0xc0 -+#define DSI_INT_MSK0 0xc4 -+#define DSI_INT_MSK1 0xc8 -+ -+#define DSI_PHY_TMR_RD_CFG 0xf4 -+#define MAX_RD_TIME_V131(lbcc) ((lbcc) & 0x7fff) -+ -+#define PHY_STATUS_TIMEOUT_US 10000 -+#define CMD_PKT_STATUS_TIMEOUT_US 20000 -+ -+#define MSEC_PER_SEC 1000 -+ -+struct dw_mipi_dsi { -+ struct mipi_dsi_host dsi_host; -+ struct mipi_dsi_device *device; -+ void __iomem *base; -+ unsigned int lane_mbps; /* per lane */ -+ u32 channel; -+ u32 lanes; -+ u32 format; -+ unsigned long mode_flags; -+ unsigned int max_data_lanes; -+ const struct dw_mipi_dsi_phy_ops *phy_ops; -+}; -+ -+static int dsi_mode_vrefresh(struct display_timing *timings) -+{ -+ int refresh = 0; -+ unsigned int calc_val; -+ u32 htotal = timings->hactive.typ + timings->hfront_porch.typ + -+ timings->hback_porch.typ + timings->hsync_len.typ; -+ u32 vtotal = timings->vactive.typ + timings->vfront_porch.typ + -+ timings->vback_porch.typ + timings->vsync_len.typ; -+ -+ if (htotal > 0 && vtotal > 0) { -+ calc_val = timings->pixelclock.typ; -+ calc_val /= htotal; -+ refresh = (calc_val + vtotal / 2) / vtotal; -+ } -+ -+ return refresh; -+} -+ -+/* -+ * The controller should generate 2 frames before -+ * preparing the peripheral. -+ */ -+static void dw_mipi_dsi_wait_for_two_frames(struct display_timing *timings) -+{ -+ int refresh, two_frames; -+ -+ refresh = dsi_mode_vrefresh(timings); -+ two_frames = DIV_ROUND_UP(MSEC_PER_SEC, refresh) * 2; -+ mdelay(two_frames); -+} -+ -+static inline struct dw_mipi_dsi *host_to_dsi(struct mipi_dsi_host *host) -+{ -+ return container_of(host, struct dw_mipi_dsi, dsi_host); -+} -+ -+static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, u32 val) -+{ -+ writel(val, dsi->base + reg); -+} -+ -+static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg) -+{ -+ return readl(dsi->base + reg); -+} -+ -+static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host, -+ struct mipi_dsi_device *device) -+{ -+ struct dw_mipi_dsi *dsi = host_to_dsi(host); -+ -+ if (device->lanes > dsi->max_data_lanes) { -+ dev_err(device->dev, -+ "the number of data lanes(%u) is too many\n", -+ device->lanes); -+ return -EINVAL; -+ } -+ -+ dsi->lanes = device->lanes; -+ dsi->channel = device->channel; -+ dsi->format = device->format; -+ dsi->mode_flags = device->mode_flags; -+ -+ return 0; -+} -+ -+static void dw_mipi_message_config(struct dw_mipi_dsi *dsi, -+ const struct mipi_dsi_msg *msg) -+{ -+ bool lpm = msg->flags & MIPI_DSI_MSG_USE_LPM; -+ u32 val = 0; -+ -+ if (msg->flags & MIPI_DSI_MSG_REQ_ACK) -+ val |= ACK_RQST_EN; -+ if (lpm) -+ val |= CMD_MODE_ALL_LP; -+ -+ dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS); -+ dsi_write(dsi, DSI_CMD_MODE_CFG, val); -+} -+ -+static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val) -+{ -+ int ret; -+ u32 val, mask; -+ -+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, -+ val, !(val & GEN_CMD_FULL), -+ CMD_PKT_STATUS_TIMEOUT_US); -+ if (ret) { -+ dev_err(dsi->dev, "failed to get available command FIFO\n"); -+ return ret; -+ } -+ -+ dsi_write(dsi, DSI_GEN_HDR, hdr_val); -+ -+ mask = GEN_CMD_EMPTY | GEN_PLD_W_EMPTY; -+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, -+ val, (val & mask) == mask, -+ CMD_PKT_STATUS_TIMEOUT_US); -+ if (ret) { -+ dev_err(dsi->dev, "failed to write command FIFO\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi, -+ const struct mipi_dsi_packet *packet) -+{ -+ const u8 *tx_buf = packet->payload; -+ int len = packet->payload_length, pld_data_bytes = sizeof(u32), ret; -+ __le32 word; -+ u32 val; -+ -+ while (len) { -+ if (len < pld_data_bytes) { -+ word = 0; -+ memcpy(&word, tx_buf, len); -+ dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word)); -+ len = 0; -+ } else { -+ memcpy(&word, tx_buf, pld_data_bytes); -+ dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word)); -+ tx_buf += pld_data_bytes; -+ len -= pld_data_bytes; -+ } -+ -+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, -+ val, !(val & GEN_PLD_W_FULL), -+ CMD_PKT_STATUS_TIMEOUT_US); -+ if (ret) { -+ dev_err(dsi->dev, -+ "failed to get available write payload FIFO\n"); -+ return ret; -+ } -+ } -+ -+ word = 0; -+ memcpy(&word, packet->header, sizeof(packet->header)); -+ return dw_mipi_dsi_gen_pkt_hdr_write(dsi, le32_to_cpu(word)); -+} -+ -+static int dw_mipi_dsi_read(struct dw_mipi_dsi *dsi, -+ const struct mipi_dsi_msg *msg) -+{ -+ int i, j, ret, len = msg->rx_len; -+ u8 *buf = msg->rx_buf; -+ u32 val; -+ -+ /* Wait end of the read operation */ -+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, -+ val, !(val & GEN_RD_CMD_BUSY), -+ CMD_PKT_STATUS_TIMEOUT_US); -+ if (ret) { -+ dev_err(dsi->dev, "Timeout during read operation\n"); -+ return ret; -+ } -+ -+ for (i = 0; i < len; i += 4) { -+ /* Read fifo must not be empty before all bytes are read */ -+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, -+ val, !(val & GEN_PLD_R_EMPTY), -+ CMD_PKT_STATUS_TIMEOUT_US); -+ if (ret) { -+ dev_err(dsi->dev, "Read payload FIFO is empty\n"); -+ return ret; -+ } -+ -+ val = dsi_read(dsi, DSI_GEN_PLD_DATA); -+ for (j = 0; j < 4 && j + i < len; j++) -+ buf[i + j] = val >> (8 * j); -+ } -+ -+ return ret; -+} -+ -+static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host, -+ const struct mipi_dsi_msg *msg) -+{ -+ struct dw_mipi_dsi *dsi = host_to_dsi(host); -+ struct mipi_dsi_packet packet; -+ int ret, nb_bytes; -+ -+ ret = mipi_dsi_create_packet(&packet, msg); -+ if (ret) { -+ dev_err(dsi->dev, "failed to create packet: %d\n", ret); -+ return ret; -+ } -+ -+ dw_mipi_message_config(dsi, msg); -+ -+ ret = dw_mipi_dsi_write(dsi, &packet); -+ if (ret) -+ return ret; -+ -+ if (msg->rx_buf && msg->rx_len) { -+ ret = dw_mipi_dsi_read(dsi, msg); -+ if (ret) -+ return ret; -+ nb_bytes = msg->rx_len; -+ } else { -+ nb_bytes = packet.size; -+ } -+ -+ return nb_bytes; -+} -+ -+static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = { -+ .attach = dw_mipi_dsi_host_attach, -+ .transfer = dw_mipi_dsi_host_transfer, -+}; -+ -+static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) -+{ -+ u32 val; -+ -+ /* -+ * TODO dw drv improvements -+ * enabling low power is panel-dependent, we should use the -+ * panel configuration here... -+ */ -+ val = ENABLE_LOW_POWER; -+ -+ if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) -+ val |= VID_MODE_TYPE_BURST; -+ else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) -+ val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES; -+ else -+ val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS; -+ -+ dsi_write(dsi, DSI_VID_MODE_CFG, val); -+} -+ -+static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi, -+ unsigned long mode_flags) -+{ -+ dsi_write(dsi, DSI_PWR_UP, RESET); -+ -+ if (mode_flags & MIPI_DSI_MODE_VIDEO) { -+ dsi_write(dsi, DSI_MODE_CFG, ENABLE_VIDEO_MODE); -+ dw_mipi_dsi_video_mode_config(dsi); -+ dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS); -+ } else { -+ dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE); -+ } -+ -+ dsi_write(dsi, DSI_PWR_UP, POWERUP); -+} -+ -+static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi) -+{ -+ /* -+ * The maximum permitted escape clock is 20MHz and it is derived from -+ * lanebyteclk, which is running at "lane_mbps / 8". Thus we want: -+ * -+ * (lane_mbps >> 3) / esc_clk_division < 20 -+ * which is: -+ * (lane_mbps >> 3) / 20 > esc_clk_division -+ */ -+ u32 esc_clk_division = (dsi->lane_mbps >> 3) / 20 + 1; -+ -+ dsi_write(dsi, DSI_PWR_UP, RESET); -+ -+ /* -+ * TODO dw drv improvements -+ * timeout clock division should be computed with the -+ * high speed transmission counter timeout and byte lane... -+ */ -+ dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) | -+ TX_ESC_CLK_DIVISION(esc_clk_division)); -+} -+ -+static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi, -+ struct display_timing *timings) -+{ -+ u32 val = 0, color = 0; -+ -+ switch (dsi->format) { -+ case MIPI_DSI_FMT_RGB888: -+ color = DPI_COLOR_CODING_24BIT; -+ break; -+ case MIPI_DSI_FMT_RGB666: -+ color = DPI_COLOR_CODING_18BIT_2 | LOOSELY18_EN; -+ break; -+ case MIPI_DSI_FMT_RGB666_PACKED: -+ color = DPI_COLOR_CODING_18BIT_1; -+ break; -+ case MIPI_DSI_FMT_RGB565: -+ color = DPI_COLOR_CODING_16BIT_1; -+ break; -+ } -+ -+ if (dsi->mode_flags & DISPLAY_FLAGS_VSYNC_HIGH) -+ val |= VSYNC_ACTIVE_LOW; -+ if (dsi->mode_flags & DISPLAY_FLAGS_HSYNC_HIGH) -+ val |= HSYNC_ACTIVE_LOW; -+ -+ dsi_write(dsi, DSI_DPI_VCID, DPI_VCID(dsi->channel)); -+ dsi_write(dsi, DSI_DPI_COLOR_CODING, color); -+ dsi_write(dsi, DSI_DPI_CFG_POL, val); -+ /* -+ * TODO dw drv improvements -+ * largest packet sizes during hfp or during vsa/vpb/vfp -+ * should be computed according to byte lane, lane number and only -+ * if sending lp cmds in high speed is enable (PHY_TXREQUESTCLKHS) -+ */ -+ dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4) -+ | INVACT_LPCMD_TIME(4)); -+} -+ -+static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi) -+{ -+ dsi_write(dsi, DSI_PCKHDL_CFG, CRC_RX_EN | ECC_RX_EN | BTA_EN); -+} -+ -+static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi, -+ struct display_timing *timings) -+{ -+ /* -+ * TODO dw drv improvements -+ * only burst mode is supported here. For non-burst video modes, -+ * we should compute DSI_VID_PKT_SIZE, DSI_VCCR.NUMC & -+ * DSI_VNPCR.NPSIZE... especially because this driver supports -+ * non-burst video modes, see dw_mipi_dsi_video_mode_config()... -+ */ -+ dsi_write(dsi, DSI_VID_PKT_SIZE, VID_PKT_SIZE(timings->hactive.typ)); -+} -+ -+static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi) -+{ -+ /* -+ * TODO dw drv improvements -+ * compute high speed transmission counter timeout according -+ * to the timeout clock division (TO_CLK_DIVISION) and byte lane... -+ */ -+ dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000)); -+ /* -+ * TODO dw drv improvements -+ * the Bus-Turn-Around Timeout Counter should be computed -+ * according to byte lane... -+ */ -+ dsi_write(dsi, DSI_BTA_TO_CNT, 0xd00); -+ dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE); -+} -+ -+/* Get lane byte clock cycles. */ -+static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi, -+ struct display_timing *timings, -+ u32 hcomponent) -+{ -+ u32 frac, lbcc; -+ -+ lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8; -+ -+ frac = lbcc % (timings->pixelclock.typ / 1000); -+ lbcc = lbcc / (timings->pixelclock.typ / 1000); -+ if (frac) -+ lbcc++; -+ -+ return lbcc; -+} -+ -+static void dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi *dsi, -+ struct display_timing *timings) -+{ -+ u32 htotal, hsa, hbp, lbcc; -+ -+ htotal = timings->hactive.typ + timings->hfront_porch.typ + -+ timings->hback_porch.typ + timings->hsync_len.typ; -+ -+ hsa = timings->hback_porch.typ; -+ hbp = timings->hsync_len.typ; -+ -+ /* -+ * TODO dw drv improvements -+ * computations below may be improved... -+ */ -+ lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, timings, htotal); -+ dsi_write(dsi, DSI_VID_HLINE_TIME, lbcc); -+ -+ lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, timings, hsa); -+ dsi_write(dsi, DSI_VID_HSA_TIME, lbcc); -+ -+ lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, timings, hbp); -+ dsi_write(dsi, DSI_VID_HBP_TIME, lbcc); -+} -+ -+static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi, -+ struct display_timing *timings) -+{ -+ u32 vactive, vsa, vfp, vbp; -+ -+ vactive = timings->vactive.typ; -+ vsa = timings->vback_porch.typ; -+ vfp = timings->vfront_porch.typ; -+ vbp = timings->vsync_len.typ; -+ -+ dsi_write(dsi, DSI_VID_VACTIVE_LINES, vactive); -+ dsi_write(dsi, DSI_VID_VSA_LINES, vsa); -+ dsi_write(dsi, DSI_VID_VFP_LINES, vfp); -+ dsi_write(dsi, DSI_VID_VBP_LINES, vbp); -+} -+ -+static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi) -+{ -+ u32 hw_version; -+ -+ /* -+ * TODO dw drv improvements -+ * data & clock lane timers should be computed according to panel -+ * blankings and to the automatic clock lane control mode... -+ * note: DSI_PHY_TMR_CFG.MAX_RD_TIME should be in line with -+ * DSI_CMD_MODE_CFG.MAX_RD_PKT_SIZE_LP (see CMD_MODE_ALL_LP) -+ */ -+ -+ 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_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_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40) -+ | PHY_CLKLP2HS_TIME(0x40)); -+} -+ -+static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi) -+{ -+ /* -+ * TODO dw drv improvements -+ * stop wait time should be the maximum between host dsi -+ * and panel stop wait times -+ */ -+ dsi_write(dsi, DSI_PHY_IF_CFG, PHY_STOP_WAIT_TIME(0x20) | -+ N_LANES(dsi->lanes)); -+} -+ -+static void dw_mipi_dsi_dphy_init(struct dw_mipi_dsi *dsi) -+{ -+ /* Clear PHY state */ -+ dsi_write(dsi, DSI_PHY_RSTZ, PHY_DISFORCEPLL | PHY_DISABLECLK -+ | PHY_RSTZ | PHY_SHUTDOWNZ); -+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR); -+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR); -+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR); -+} -+ -+static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi) -+{ -+ u32 val; -+ int ret; -+ -+ dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK | -+ PHY_UNRSTZ | PHY_UNSHUTDOWNZ); -+ -+ 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"); -+ -+ 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"); -+} -+ -+static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi) -+{ -+ dsi_read(dsi, DSI_INT_ST0); -+ dsi_read(dsi, DSI_INT_ST1); -+ dsi_write(dsi, DSI_INT_MSK0, 0); -+ dsi_write(dsi, DSI_INT_MSK1, 0); -+} -+ -+static void dw_mipi_dsi_bridge_set(struct dw_mipi_dsi *dsi, -+ struct display_timing *timings) -+{ -+ const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->phy_ops; -+ int ret; -+ -+ ret = phy_ops->get_lane_mbps(dsi->device, timings, dsi->lanes, -+ dsi->format, &dsi->lane_mbps); -+ if (ret) -+ dev_warn(dsi->dev, "Phy get_lane_mbps() failed\n"); -+ -+ dw_mipi_dsi_init(dsi); -+ dw_mipi_dsi_dpi_config(dsi, timings); -+ dw_mipi_dsi_packet_handler_config(dsi); -+ dw_mipi_dsi_video_mode_config(dsi); -+ dw_mipi_dsi_video_packet_config(dsi, timings); -+ dw_mipi_dsi_command_mode_config(dsi); -+ dw_mipi_dsi_line_timer_config(dsi, timings); -+ dw_mipi_dsi_vertical_timing_config(dsi, timings); -+ -+ dw_mipi_dsi_dphy_init(dsi); -+ dw_mipi_dsi_dphy_timing_config(dsi); -+ dw_mipi_dsi_dphy_interface_config(dsi); -+ -+ dw_mipi_dsi_clear_err(dsi); -+ -+ ret = phy_ops->init(dsi->device); -+ if (ret) -+ dev_warn(dsi->dev, "Phy init() failed\n"); -+ -+ dw_mipi_dsi_dphy_enable(dsi); -+ -+ dw_mipi_dsi_wait_for_two_frames(timings); -+ -+ /* Switch to cmd mode for panel-bridge pre_enable & panel prepare */ -+ dw_mipi_dsi_set_mode(dsi, 0); -+} -+ -+void dw_mipi_dsi_bridge_enable(struct mipi_dsi_device *device) -+{ -+ struct mipi_dsi_host *host = device->host; -+ struct dw_mipi_dsi *dsi = host_to_dsi(host); -+ -+ /* Switch to video mode for panel-bridge enable & panel enable */ -+ dw_mipi_dsi_set_mode(dsi, MIPI_DSI_MODE_VIDEO); -+} -+EXPORT_SYMBOL_GPL(dw_mipi_dsi_bridge_enable); -+ -+int dw_mipi_dsi_init_bridge(struct mipi_dsi_device *device) -+{ -+ struct dw_mipi_dsi_plat_data *platdata = dev_get_platdata(device->dev); -+ struct udevice *panel = platdata->panel; -+ struct display_timing timings; -+ struct dw_mipi_dsi *dsi; -+ struct clk clk; -+ int ret; -+ -+ dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); -+ -+ dsi->phy_ops = platdata->phy_ops; -+ dsi->max_data_lanes = platdata->max_data_lanes; -+ dsi->device = device; -+ dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; -+ device->host = &dsi->dsi_host; -+ -+ /* TODO Get these settings from panel */ -+ dsi->lanes = 2; -+ dsi->format = MIPI_DSI_FMT_RGB888; -+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | -+ MIPI_DSI_MODE_VIDEO_BURST | -+ MIPI_DSI_MODE_LPM; -+ -+ dsi->base = (void *)dev_read_addr(device->dev); -+ if ((fdt_addr_t)dsi->base == FDT_ADDR_T_NONE) { -+ dev_err(device->dev, "dsi dt register address error\n"); -+ return -EINVAL; -+ } -+ -+ ret = panel_get_display_timing(panel, &timings); -+ if (ret) { -+ ret = fdtdec_decode_display_timing(gd->fdt_blob, -+ dev_of_offset(panel), -+ 0, &timings); -+ if (ret) { -+ dev_err(dev, "decode display timing error %d\n", ret); -+ return ret; -+ } -+ } -+ -+ if (!dsi->phy_ops->init || !dsi->phy_ops->get_lane_mbps) { -+ dev_err(device->dev, "Phy not properly configured\n"); -+ return -ENODEV; -+ } -+ -+ ret = clk_get_by_name(device->dev, "px_clk", &clk); -+ if (ret) { -+ dev_err(device->dev, "peripheral clock get error %d\n", ret); -+ return ret; -+ } -+ -+ /* get the pixel clock set by the clock framework */ -+ timings.pixelclock.typ = clk_get_rate(&clk); -+ -+ dw_mipi_dsi_bridge_set(dsi, &timings); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(dw_mipi_dsi_init_bridge); -+ -+MODULE_AUTHOR("Chris Zhong "); -+MODULE_AUTHOR("Philippe Cornu "); -+MODULE_AUTHOR("Yannick Fertré "); -+MODULE_DESCRIPTION("DW MIPI DSI host controller driver"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:dw-mipi-dsi"); -diff --git a/drivers/video/mipi_display.c b/drivers/video/mipi_display.c -new file mode 100644 -index 0000000..611ee53 ---- /dev/null -+++ b/drivers/video/mipi_display.c -@@ -0,0 +1,817 @@ -+/* -+ * MIPI DSI Bus -+ * -+ * Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd. -+ * Copyright (C) 2018 STMicroelectronics - All Rights Reserved -+ * Andrzej Hajda -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sub license, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the -+ * next paragraph) shall be included in all copies or substantial portions -+ * of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, -+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -+ * USE OR OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Mipi_display.c contains a set of dsi helpers. -+ * This file is based on the drm helper file drivers/gpu/drm/drm_mipi_dsi.c -+ * (kernel linux). -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+/** -+ * DOC: dsi helpers -+ * -+ * These functions contain some common logic and helpers to deal with MIPI DSI -+ * peripherals. -+ * -+ * Helpers are provided for a number of standard MIPI DSI command as well as a -+ * subset of the MIPI DCS command set. -+ */ -+ -+/** -+ * mipi_dsi_attach - attach a DSI device to its DSI host -+ * @dsi: DSI peripheral -+ */ -+int mipi_dsi_attach(struct mipi_dsi_device *dsi) -+{ -+ const struct mipi_dsi_host_ops *ops = dsi->host->ops; -+ -+ if (!ops || !ops->attach) -+ return -ENOSYS; -+ -+ return ops->attach(dsi->host, dsi); -+} -+EXPORT_SYMBOL(mipi_dsi_attach); -+ -+/** -+ * mipi_dsi_detach - detach a DSI device from its DSI host -+ * @dsi: DSI peripheral -+ */ -+int mipi_dsi_detach(struct mipi_dsi_device *dsi) -+{ -+ const struct mipi_dsi_host_ops *ops = dsi->host->ops; -+ -+ if (!ops || !ops->detach) -+ return -ENOSYS; -+ -+ return ops->detach(dsi->host, dsi); -+} -+EXPORT_SYMBOL(mipi_dsi_detach); -+ -+/** -+ * mipi_dsi_device_transfer - transfer message to a DSI device -+ * @dsi: DSI peripheral -+ * @msg: message -+ */ -+static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi, -+ struct mipi_dsi_msg *msg) -+{ -+ const struct mipi_dsi_host_ops *ops = dsi->host->ops; -+ -+ if (!ops || !ops->transfer) -+ return -ENOSYS; -+ -+ if (dsi->mode_flags & MIPI_DSI_MODE_LPM) -+ msg->flags |= MIPI_DSI_MSG_USE_LPM; -+ -+ return ops->transfer(dsi->host, msg); -+} -+ -+/** -+ * mipi_dsi_packet_format_is_short - check if a packet is of the short format -+ * @type: MIPI DSI data type of the packet -+ * -+ * Return: true if the packet for the given data type is a short packet, false -+ * otherwise. -+ */ -+bool mipi_dsi_packet_format_is_short(u8 type) -+{ -+ switch (type) { -+ case MIPI_DSI_V_SYNC_START: -+ case MIPI_DSI_V_SYNC_END: -+ case MIPI_DSI_H_SYNC_START: -+ case MIPI_DSI_H_SYNC_END: -+ case MIPI_DSI_END_OF_TRANSMISSION: -+ case MIPI_DSI_COLOR_MODE_OFF: -+ case MIPI_DSI_COLOR_MODE_ON: -+ case MIPI_DSI_SHUTDOWN_PERIPHERAL: -+ case MIPI_DSI_TURN_ON_PERIPHERAL: -+ case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: -+ case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM: -+ case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: -+ case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM: -+ case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM: -+ case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM: -+ case MIPI_DSI_DCS_SHORT_WRITE: -+ case MIPI_DSI_DCS_SHORT_WRITE_PARAM: -+ case MIPI_DSI_DCS_READ: -+ case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE: -+ return true; -+ } -+ -+ return false; -+} -+EXPORT_SYMBOL(mipi_dsi_packet_format_is_short); -+ -+/** -+ * mipi_dsi_packet_format_is_long - check if a packet is of the long format -+ * @type: MIPI DSI data type of the packet -+ * -+ * Return: true if the packet for the given data type is a long packet, false -+ * otherwise. -+ */ -+bool mipi_dsi_packet_format_is_long(u8 type) -+{ -+ switch (type) { -+ case MIPI_DSI_NULL_PACKET: -+ case MIPI_DSI_BLANKING_PACKET: -+ case MIPI_DSI_GENERIC_LONG_WRITE: -+ case MIPI_DSI_DCS_LONG_WRITE: -+ case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_30: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_36: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_16: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_18: -+ case MIPI_DSI_PIXEL_STREAM_3BYTE_18: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_24: -+ return true; -+ } -+ -+ return false; -+} -+EXPORT_SYMBOL(mipi_dsi_packet_format_is_long); -+ -+/** -+ * mipi_dsi_create_packet - create a packet from a message according to the -+ * DSI protocol -+ * @packet: pointer to a DSI packet structure -+ * @msg: message to translate into a packet -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, -+ const struct mipi_dsi_msg *msg) -+{ -+ if (!packet || !msg) -+ return -EINVAL; -+ -+ /* do some minimum sanity checking */ -+ if (!mipi_dsi_packet_format_is_short(msg->type) && -+ !mipi_dsi_packet_format_is_long(msg->type)) -+ return -EINVAL; -+ -+ if (msg->channel > 3) -+ return -EINVAL; -+ -+ memset(packet, 0, sizeof(*packet)); -+ packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f); -+ -+ /* TODO: compute ECC if hardware support is not available */ -+ -+ /* -+ * Long write packets contain the word count in header bytes 1 and 2. -+ * The payload follows the header and is word count bytes long. -+ * -+ * Short write packets encode up to two parameters in header bytes 1 -+ * and 2. -+ */ -+ if (mipi_dsi_packet_format_is_long(msg->type)) { -+ packet->header[1] = (msg->tx_len >> 0) & 0xff; -+ packet->header[2] = (msg->tx_len >> 8) & 0xff; -+ -+ packet->payload_length = msg->tx_len; -+ packet->payload = msg->tx_buf; -+ } else { -+ const u8 *tx = msg->tx_buf; -+ -+ packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0; -+ packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0; -+ } -+ -+ packet->size = sizeof(packet->header) + packet->payload_length; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_create_packet); -+ -+/* -+ * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the -+ * the payload in a long packet transmitted from the peripheral back to the -+ * host processor -+ * @dsi: DSI peripheral device -+ * @value: the maximum size of the payload -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, -+ u16 value) -+{ -+ u8 tx[2] = { value & 0xff, value >> 8 }; -+ struct mipi_dsi_msg msg = { -+ .channel = dsi->channel, -+ .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, -+ .tx_len = sizeof(tx), -+ .tx_buf = tx, -+ }; -+ int ret = mipi_dsi_device_transfer(dsi, &msg); -+ -+ return (ret < 0) ? ret : 0; -+} -+EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); -+ -+/** -+ * mipi_dsi_generic_write() - transmit data using a generic write packet -+ * @dsi: DSI peripheral device -+ * @payload: buffer containing the payload -+ * @size: size of payload buffer -+ * -+ * This function will automatically choose the right data type depending on -+ * the payload length. -+ * -+ * Return: The number of bytes transmitted on success or a negative error code -+ * on failure. -+ */ -+ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, -+ size_t size) -+{ -+ struct mipi_dsi_msg msg = { -+ .channel = dsi->channel, -+ .tx_buf = payload, -+ .tx_len = size -+ }; -+ -+ switch (size) { -+ case 0: -+ msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM; -+ break; -+ -+ case 1: -+ msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM; -+ break; -+ -+ case 2: -+ msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM; -+ break; -+ -+ default: -+ msg.type = MIPI_DSI_GENERIC_LONG_WRITE; -+ break; -+ } -+ -+ return mipi_dsi_device_transfer(dsi, &msg); -+} -+EXPORT_SYMBOL(mipi_dsi_generic_write); -+ -+/** -+ * mipi_dsi_generic_read() - receive data using a generic read packet -+ * @dsi: DSI peripheral device -+ * @params: buffer containing the request parameters -+ * @num_params: number of request parameters -+ * @data: buffer in which to return the received data -+ * @size: size of receive buffer -+ * -+ * This function will automatically choose the right data type depending on -+ * the number of parameters passed in. -+ * -+ * Return: The number of bytes successfully read or a negative error code on -+ * failure. -+ */ -+ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, -+ size_t num_params, void *data, size_t size) -+{ -+ struct mipi_dsi_msg msg = { -+ .channel = dsi->channel, -+ .tx_len = num_params, -+ .tx_buf = params, -+ .rx_len = size, -+ .rx_buf = data -+ }; -+ -+ switch (num_params) { -+ case 0: -+ msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM; -+ break; -+ -+ case 1: -+ msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM; -+ break; -+ -+ case 2: -+ msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM; -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ return mipi_dsi_device_transfer(dsi, &msg); -+} -+EXPORT_SYMBOL(mipi_dsi_generic_read); -+ -+/** -+ * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload -+ * @dsi: DSI peripheral device -+ * @data: buffer containing data to be transmitted -+ * @len: size of transmission buffer -+ * -+ * This function will automatically choose the right data type depending on -+ * the command payload length. -+ * -+ * Return: The number of bytes successfully transmitted or a negative error -+ * code on failure. -+ */ -+ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, -+ const void *data, size_t len) -+{ -+ struct mipi_dsi_msg msg = { -+ .channel = dsi->channel, -+ .tx_buf = data, -+ .tx_len = len -+ }; -+ -+ switch (len) { -+ case 0: -+ return -EINVAL; -+ -+ case 1: -+ msg.type = MIPI_DSI_DCS_SHORT_WRITE; -+ break; -+ -+ case 2: -+ msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; -+ break; -+ -+ default: -+ msg.type = MIPI_DSI_DCS_LONG_WRITE; -+ break; -+ } -+ -+ return mipi_dsi_device_transfer(dsi, &msg); -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer); -+ -+/** -+ * mipi_dsi_dcs_write() - send DCS write command -+ * @dsi: DSI peripheral device -+ * @cmd: DCS command -+ * @data: buffer containing the command payload -+ * @len: command payload length -+ * -+ * This function will automatically choose the right data type depending on -+ * the command payload length. -+ * -+ * Return: The number of bytes successfully transmitted or a negative error -+ * code on failure. -+ */ -+ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, -+ const void *data, size_t len) -+{ -+ ssize_t err; -+ size_t size; -+ u8 *tx; -+ -+ if (len > 0) { -+ size = 1 + len; -+ -+ tx = kmalloc(size, GFP_KERNEL); -+ if (!tx) -+ return -ENOMEM; -+ -+ /* concatenate the DCS command byte and the payload */ -+ tx[0] = cmd; -+ memcpy(&tx[1], data, len); -+ } else { -+ tx = &cmd; -+ size = 1; -+ } -+ -+ err = mipi_dsi_dcs_write_buffer(dsi, tx, size); -+ -+ if (len > 0) -+ kfree(tx); -+ -+ return err; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_write); -+ -+/** -+ * mipi_dsi_dcs_read() - send DCS read request command -+ * @dsi: DSI peripheral device -+ * @cmd: DCS command -+ * @data: buffer in which to receive data -+ * @len: size of receive buffer -+ * -+ * Return: The number of bytes read or a negative error code on failure. -+ */ -+ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, -+ size_t len) -+{ -+ struct mipi_dsi_msg msg = { -+ .channel = dsi->channel, -+ .type = MIPI_DSI_DCS_READ, -+ .tx_buf = &cmd, -+ .tx_len = 1, -+ .rx_buf = data, -+ .rx_len = len -+ }; -+ -+ return mipi_dsi_device_transfer(dsi, &msg); -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_read); -+ -+/** -+ * mipi_dsi_pixel_format_to_bpp - obtain the number of bits per pixel for any -+ * given pixel format defined by the MIPI DSI -+ * specification -+ * @fmt: MIPI DSI pixel format -+ * -+ * Returns: The number of bits per pixel of the given pixel format. -+ */ -+int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt) -+{ -+ switch (fmt) { -+ case MIPI_DSI_FMT_RGB888: -+ case MIPI_DSI_FMT_RGB666: -+ return 24; -+ -+ case MIPI_DSI_FMT_RGB666_PACKED: -+ return 18; -+ -+ case MIPI_DSI_FMT_RGB565: -+ return 16; -+ } -+ -+ return -EINVAL; -+} -+EXPORT_SYMBOL(mipi_dsi_pixel_format_to_bpp); -+ -+/** -+ * mipi_dsi_dcs_nop() - send DCS nop packet -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_nop); -+ -+/** -+ * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset); -+ -+/** -+ * mipi_dsi_dcs_get_power_mode() - query the display module's current power -+ * mode -+ * @dsi: DSI peripheral device -+ * @mode: return location for the current power mode -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode, -+ sizeof(*mode)); -+ if (err <= 0) { -+ if (err == 0) -+ err = -ENODATA; -+ -+ return err; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode); -+ -+/** -+ * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image -+ * data used by the interface -+ * @dsi: DSI peripheral device -+ * @format: return location for the pixel format -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format, -+ sizeof(*format)); -+ if (err <= 0) { -+ if (err == 0) -+ err = -ENODATA; -+ -+ return err; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format); -+ -+/** -+ * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the -+ * display module except interface communication -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode); -+ -+/** -+ * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display -+ * module -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode); -+ -+/** -+ * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the -+ * display device -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off); -+ -+/** -+ * mipi_dsi_dcs_set_display_on() - start displaying the image data on the -+ * display device -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure -+ */ -+int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on); -+ -+/** -+ * mipi_dsi_dcs_set_column_address() - define the column extent of the frame -+ * memory accessed by the host processor -+ * @dsi: DSI peripheral device -+ * @start: first column of frame memory -+ * @end: last column of frame memory -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, -+ u16 end) -+{ -+ u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload, -+ sizeof(payload)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address); -+ -+/** -+ * mipi_dsi_dcs_set_page_address() - define the page extent of the frame -+ * memory accessed by the host processor -+ * @dsi: DSI peripheral device -+ * @start: first page of frame memory -+ * @end: last page of frame memory -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, -+ u16 end) -+{ -+ u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload, -+ sizeof(payload)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address); -+ -+/** -+ * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect -+ * output signal on the TE signal line -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure -+ */ -+int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off); -+ -+/** -+ * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect -+ * output signal on the TE signal line. -+ * @dsi: DSI peripheral device -+ * @mode: the Tearing Effect Output Line mode -+ * -+ * Return: 0 on success or a negative error code on failure -+ */ -+int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, -+ enum mipi_dsi_dcs_tear_mode mode) -+{ -+ u8 value = mode; -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value, -+ sizeof(value)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on); -+ -+/** -+ * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image -+ * data used by the interface -+ * @dsi: DSI peripheral device -+ * @format: pixel format -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format, -+ sizeof(format)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format); -+ -+/** -+ * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for -+ * the Tearing Effect output signal of the display module -+ * @dsi: DSI peripheral device -+ * @scanline: scanline to use as trigger -+ * -+ * Return: 0 on success or a negative error code on failure -+ */ -+int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline) -+{ -+ u8 payload[3] = { MIPI_DCS_SET_TEAR_SCANLINE, scanline >> 8, -+ scanline & 0xff }; -+ ssize_t err; -+ -+ err = mipi_dsi_generic_write(dsi, payload, sizeof(payload)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline); -+ -+/** -+ * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the -+ * display -+ * @dsi: DSI peripheral device -+ * @brightness: brightness value -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, -+ u16 brightness) -+{ -+ u8 payload[2] = { brightness & 0xff, brightness >> 8 }; -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, -+ payload, sizeof(payload)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness); -+ -+/** -+ * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value -+ * of the display -+ * @dsi: DSI peripheral device -+ * @brightness: brightness value -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, -+ u16 *brightness) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, -+ brightness, sizeof(*brightness)); -+ if (err <= 0) { -+ if (err == 0) -+ err = -ENODATA; -+ -+ return err; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness); -+ -+MODULE_AUTHOR("Andrzej Hajda "); -+MODULE_AUTHOR("Yannick Fertre "); -+MODULE_DESCRIPTION("MIPI DSI Bus"); -+MODULE_LICENSE("GPL and additional rights"); -diff --git a/drivers/video/orisetech_otm8009a.c b/drivers/video/orisetech_otm8009a.c -new file mode 100644 -index 0000000..ad1d6f0 ---- /dev/null -+++ b/drivers/video/orisetech_otm8009a.c -@@ -0,0 +1,339 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2018 STMicroelectronics - All Rights Reserved -+ * Author(s): Yannick Fertre for STMicroelectronics. -+ * Philippe Cornu for STMicroelectronics. -+ * -+ * This otm8009a panel driver is based on the Linux Kernel driver from -+ * drivers/gpu/drm/panel/panel-orisetech-otm8009a.c. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define OTM8009A_BACKLIGHT_DEFAULT 240 -+#define OTM8009A_BACKLIGHT_MAX 255 -+ -+/* Manufacturer Command Set */ -+#define MCS_ADRSFT 0x0000 /* Address Shift Function */ -+#define MCS_PANSET 0xB3A6 /* Panel Type Setting */ -+#define MCS_SD_CTRL 0xC0A2 /* Source Driver Timing Setting */ -+#define MCS_P_DRV_M 0xC0B4 /* Panel Driving Mode */ -+#define MCS_OSC_ADJ 0xC181 /* Oscillator Adjustment for Idle/Normal mode */ -+#define MCS_RGB_VID_SET 0xC1A1 /* RGB Video Mode Setting */ -+#define MCS_SD_PCH_CTRL 0xC480 /* Source Driver Precharge Control */ -+#define MCS_NO_DOC1 0xC48A /* Command not documented */ -+#define MCS_PWR_CTRL1 0xC580 /* Power Control Setting 1 */ -+#define MCS_PWR_CTRL2 0xC590 /* Power Control Setting 2 for Normal Mode */ -+#define MCS_PWR_CTRL4 0xC5B0 /* Power Control Setting 4 for DC Voltage */ -+#define MCS_PANCTRLSET1 0xCB80 /* Panel Control Setting 1 */ -+#define MCS_PANCTRLSET2 0xCB90 /* Panel Control Setting 2 */ -+#define MCS_PANCTRLSET3 0xCBA0 /* Panel Control Setting 3 */ -+#define MCS_PANCTRLSET4 0xCBB0 /* Panel Control Setting 4 */ -+#define MCS_PANCTRLSET5 0xCBC0 /* Panel Control Setting 5 */ -+#define MCS_PANCTRLSET6 0xCBD0 /* Panel Control Setting 6 */ -+#define MCS_PANCTRLSET7 0xCBE0 /* Panel Control Setting 7 */ -+#define MCS_PANCTRLSET8 0xCBF0 /* Panel Control Setting 8 */ -+#define MCS_PANU2D1 0xCC80 /* Panel U2D Setting 1 */ -+#define MCS_PANU2D2 0xCC90 /* Panel U2D Setting 2 */ -+#define MCS_PANU2D3 0xCCA0 /* Panel U2D Setting 3 */ -+#define MCS_PAND2U1 0xCCB0 /* Panel D2U Setting 1 */ -+#define MCS_PAND2U2 0xCCC0 /* Panel D2U Setting 2 */ -+#define MCS_PAND2U3 0xCCD0 /* Panel D2U Setting 3 */ -+#define MCS_GOAVST 0xCE80 /* GOA VST Setting */ -+#define MCS_GOACLKA1 0xCEA0 /* GOA CLKA1 Setting */ -+#define MCS_GOACLKA3 0xCEB0 /* GOA CLKA3 Setting */ -+#define MCS_GOAECLK 0xCFC0 /* GOA ECLK Setting */ -+#define MCS_NO_DOC2 0xCFD0 /* Command not documented */ -+#define MCS_GVDDSET 0xD800 /* GVDD/NGVDD */ -+#define MCS_VCOMDC 0xD900 /* VCOM Voltage Setting */ -+#define MCS_GMCT2_2P 0xE100 /* Gamma Correction 2.2+ Setting */ -+#define MCS_GMCT2_2N 0xE200 /* Gamma Correction 2.2- Setting */ -+#define MCS_NO_DOC3 0xF5B6 /* Command not documented */ -+#define MCS_CMD2_ENA1 0xFF00 /* Enable Access Command2 "CMD2" */ -+#define MCS_CMD2_ENA2 0xFF80 /* Enable Access Orise Command2 */ -+ -+struct otm8009a_panel_priv { -+ struct udevice *reg; -+ struct gpio_desc reset; -+}; -+ -+static const struct display_timing default_timing = { -+ .pixelclock = {.min = 32729000, .typ = 32729000, .max = 32729000,}, -+ .hactive = {.min = 480, .typ = 480, .max = 480,}, -+ .hfront_porch = {.min = 120, .typ = 120, .max = 120,}, -+ .hback_porch = {.min = 120, .typ = 120, .max = 120,}, -+ .hsync_len = {.min = 63, .typ = 63, .max = 63,}, -+ .vactive = {.min = 800, .typ = 800, .max = 800,}, -+ .vfront_porch = {.min = 12, .typ = 12, .max = 12,}, -+ .vback_porch = {.min = 12, .typ = 12, .max = 12,}, -+ .vsync_len = {.min = 12, .typ = 12, .max = 12,}, -+}; -+ -+static void otm8009a_dcs_write_buf(struct udevice *dev, const void *data, -+ size_t len) -+{ -+ struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); -+ struct mipi_dsi_device *device = plat->device; -+ -+ if (mipi_dsi_dcs_write_buffer(device, data, len) < 0) -+ dev_err(dev, "mipi dsi dcs write buffer failed\n"); -+} -+ -+#define dcs_write_seq(dev, seq...) \ -+({ \ -+ static const u8 d[] = { seq }; \ -+ otm8009a_dcs_write_buf(dev, d, ARRAY_SIZE(d)); \ -+}) -+ -+#define dcs_write_cmd_at(dev, cmd, seq...) \ -+({ \ -+ static const u16 c = cmd; \ -+ struct udevice *device = dev; \ -+ dcs_write_seq(device, MCS_ADRSFT, (c) & 0xFF); \ -+ dcs_write_seq(device, (c) >> 8, seq); \ -+}) -+ -+static int otm8009a_init_sequence(struct udevice *dev) -+{ -+ struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); -+ struct mipi_dsi_device *device = plat->device; -+ int ret; -+ -+ /* Enter CMD2 */ -+ dcs_write_cmd_at(dev, MCS_CMD2_ENA1, 0x80, 0x09, 0x01); -+ -+ /* Enter Orise Command2 */ -+ dcs_write_cmd_at(dev, MCS_CMD2_ENA2, 0x80, 0x09); -+ -+ dcs_write_cmd_at(dev, MCS_SD_PCH_CTRL, 0x30); -+ mdelay(10); -+ -+ dcs_write_cmd_at(dev, MCS_NO_DOC1, 0x40); -+ mdelay(10); -+ -+ dcs_write_cmd_at(dev, MCS_PWR_CTRL4 + 1, 0xA9); -+ dcs_write_cmd_at(dev, MCS_PWR_CTRL2 + 1, 0x34); -+ dcs_write_cmd_at(dev, MCS_P_DRV_M, 0x50); -+ dcs_write_cmd_at(dev, MCS_VCOMDC, 0x4E); -+ dcs_write_cmd_at(dev, MCS_OSC_ADJ, 0x66); /* 65Hz */ -+ dcs_write_cmd_at(dev, MCS_PWR_CTRL2 + 2, 0x01); -+ dcs_write_cmd_at(dev, MCS_PWR_CTRL2 + 5, 0x34); -+ dcs_write_cmd_at(dev, MCS_PWR_CTRL2 + 4, 0x33); -+ dcs_write_cmd_at(dev, MCS_GVDDSET, 0x79, 0x79); -+ dcs_write_cmd_at(dev, MCS_SD_CTRL + 1, 0x1B); -+ dcs_write_cmd_at(dev, MCS_PWR_CTRL1 + 2, 0x83); -+ dcs_write_cmd_at(dev, MCS_SD_PCH_CTRL + 1, 0x83); -+ dcs_write_cmd_at(dev, MCS_RGB_VID_SET, 0x0E); -+ dcs_write_cmd_at(dev, MCS_PANSET, 0x00, 0x01); -+ -+ dcs_write_cmd_at(dev, MCS_GOAVST, 0x85, 0x01, 0x00, 0x84, 0x01, 0x00); -+ dcs_write_cmd_at(dev, MCS_GOACLKA1, 0x18, 0x04, 0x03, 0x39, 0x00, 0x00, -+ 0x00, 0x18, 0x03, 0x03, 0x3A, 0x00, 0x00, 0x00); -+ dcs_write_cmd_at(dev, MCS_GOACLKA3, 0x18, 0x02, 0x03, 0x3B, 0x00, 0x00, -+ 0x00, 0x18, 0x01, 0x03, 0x3C, 0x00, 0x00, 0x00); -+ dcs_write_cmd_at(dev, MCS_GOAECLK, 0x01, 0x01, 0x20, 0x20, 0x00, 0x00, -+ 0x01, 0x02, 0x00, 0x00); -+ -+ dcs_write_cmd_at(dev, MCS_NO_DOC2, 0x00); -+ -+ dcs_write_cmd_at(dev, MCS_PANCTRLSET1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); -+ dcs_write_cmd_at(dev, MCS_PANCTRLSET2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0); -+ dcs_write_cmd_at(dev, MCS_PANCTRLSET3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0); -+ dcs_write_cmd_at(dev, MCS_PANCTRLSET4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); -+ dcs_write_cmd_at(dev, MCS_PANCTRLSET5, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0); -+ dcs_write_cmd_at(dev, MCS_PANCTRLSET6, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, -+ 4, 0, 0, 0, 0); -+ dcs_write_cmd_at(dev, MCS_PANCTRLSET7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); -+ dcs_write_cmd_at(dev, MCS_PANCTRLSET8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); -+ -+ dcs_write_cmd_at(dev, MCS_PANU2D1, 0x00, 0x26, 0x09, 0x0B, 0x01, 0x25, -+ 0x00, 0x00, 0x00, 0x00); -+ dcs_write_cmd_at(dev, MCS_PANU2D2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x0A, 0x0C, 0x02); -+ dcs_write_cmd_at(dev, MCS_PANU2D3, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); -+ dcs_write_cmd_at(dev, MCS_PAND2U1, 0x00, 0x25, 0x0C, 0x0A, 0x02, 0x26, -+ 0x00, 0x00, 0x00, 0x00); -+ dcs_write_cmd_at(dev, MCS_PAND2U2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x0B, 0x09, 0x01); -+ dcs_write_cmd_at(dev, MCS_PAND2U3, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); -+ -+ dcs_write_cmd_at(dev, MCS_PWR_CTRL1 + 1, 0x66); -+ -+ dcs_write_cmd_at(dev, MCS_NO_DOC3, 0x06); -+ -+ dcs_write_cmd_at(dev, MCS_GMCT2_2P, 0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10, -+ 0x0B, 0x0A, 0x04, 0x07, 0x0B, 0x08, 0x0F, 0x10, 0x0A, -+ 0x01); -+ dcs_write_cmd_at(dev, MCS_GMCT2_2N, 0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10, -+ 0x0B, 0x0A, 0x04, 0x07, 0x0B, 0x08, 0x0F, 0x10, 0x0A, -+ 0x01); -+ -+ /* Exit CMD2 */ -+ dcs_write_cmd_at(dev, MCS_CMD2_ENA1, 0xFF, 0xFF, 0xFF); -+ -+ ret = mipi_dsi_dcs_nop(device); -+ if (ret) -+ return ret; -+ -+ ret = mipi_dsi_dcs_exit_sleep_mode(device); -+ if (ret) -+ return ret; -+ -+ /* Wait for sleep out exit */ -+ mdelay(120); -+ -+ /* Default portrait 480x800 rgb24 */ -+ dcs_write_seq(dev, MIPI_DCS_SET_ADDRESS_MODE, 0x00); -+ -+ ret = mipi_dsi_dcs_set_column_address(device, 0, 479); -+ if (ret) -+ return ret; -+ -+ ret = mipi_dsi_dcs_set_page_address(device, 0, 799); -+ if (ret) -+ return ret; -+ -+ /* See otm8009a driver documentation for pixel format descriptions */ -+ ret = mipi_dsi_dcs_set_pixel_format(device, MIPI_DCS_PIXEL_FMT_24BIT | -+ MIPI_DCS_PIXEL_FMT_24BIT << 4); -+ if (ret) -+ return ret; -+ -+ /* Disable CABC feature */ -+ dcs_write_seq(dev, MIPI_DCS_WRITE_POWER_SAVE, 0x00); -+ -+ return 0; -+} -+ -+static int otm8009a_panel_enable_backlight(struct udevice *dev) -+{ -+ struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); -+ struct mipi_dsi_device *device = plat->device; -+ int ret; -+ -+ device->lanes = 2; -+ device->format = MIPI_DSI_FMT_RGB888; -+ device->mode_flags = MIPI_DSI_MODE_VIDEO | -+ MIPI_DSI_MODE_VIDEO_BURST | -+ MIPI_DSI_MODE_LPM; -+ -+ ret = mipi_dsi_attach(device); -+ if (ret < 0) -+ return ret; -+ -+ ret = otm8009a_init_sequence(dev); -+ if (ret) -+ return ret; -+ -+ /* -+ * Power on the backlight with the requested brightness -+ * Note We can not use mipi_dsi_dcs_set_display_brightness() -+ * as otm8009a driver support only 8-bit brightness (1 param). -+ */ -+ dcs_write_seq(dev, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, -+ OTM8009A_BACKLIGHT_DEFAULT); -+ -+ /* Update Brightness Control & Backlight */ -+ dcs_write_seq(dev, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x24); -+ -+ ret = mipi_dsi_dcs_set_display_on(device); -+ if (ret) -+ return ret; -+ -+ ret = mipi_dsi_dcs_nop(device); -+ if (ret) -+ return ret; -+ -+ /* Send Command GRAM memory write (no parameters) */ -+ dcs_write_seq(dev, MIPI_DCS_WRITE_MEMORY_START); -+ -+ /* need to wait a few time before set the DSI bridge in video mode */ -+ mdelay(10); -+ -+ return 0; -+} -+ -+static int otm8009a_panel_get_display_timing(struct udevice *dev, -+ struct display_timing *timings) -+{ -+ memcpy(timings, &default_timing, sizeof(*timings)); -+ return 0; -+} -+ -+static int otm8009a_panel_ofdata_to_platdata(struct udevice *dev) -+{ -+ struct otm8009a_panel_priv *priv = dev_get_priv(dev); -+ int ret; -+ -+ if (IS_ENABLED(CONFIG_DM_REGULATOR)) { -+ ret = device_get_supply_regulator(dev, "power-supply", -+ &priv->reg); -+ if (ret && ret != -ENOENT) { -+ 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; -+ } -+ -+ return 0; -+} -+ -+static int otm8009a_panel_probe(struct udevice *dev) -+{ -+ struct otm8009a_panel_priv *priv = dev_get_priv(dev); -+ int ret; -+ -+ if (IS_ENABLED(CONFIG_DM_REGULATOR) && priv->reg) { -+ dev_err(dev, "enable regulator '%s'\n", priv->reg->name); -+ 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(10); -+ -+ return 0; -+} -+ -+static const struct panel_ops otm8009a_panel_ops = { -+ .enable_backlight = otm8009a_panel_enable_backlight, -+ .get_display_timing = otm8009a_panel_get_display_timing, -+}; -+ -+static const struct udevice_id otm8009a_panel_ids[] = { -+ { .compatible = "orisetech,otm8009a" }, -+ { } -+}; -+ -+U_BOOT_DRIVER(otm8009a_panel) = { -+ .name = "otm8009a_panel", -+ .id = UCLASS_PANEL, -+ .of_match = otm8009a_panel_ids, -+ .ops = &otm8009a_panel_ops, -+ .ofdata_to_platdata = otm8009a_panel_ofdata_to_platdata, -+ .probe = otm8009a_panel_probe, -+ .platdata_auto_alloc_size = sizeof(struct mipi_dsi_panel_plat), -+ .priv_auto_alloc_size = sizeof(struct otm8009a_panel_priv), -+}; -diff --git a/drivers/video/raydium-rm68200.c b/drivers/video/raydium-rm68200.c -new file mode 100644 -index 0000000..3347f12 ---- /dev/null -+++ b/drivers/video/raydium-rm68200.c -@@ -0,0 +1,338 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2018 STMicroelectronics - All Rights Reserved -+ * Author(s): Yannick Fertre for STMicroelectronics. -+ * Philippe Cornu for STMicroelectronics. -+ * -+ * This rm68200 panel driver is based on the Linux Kernel driver from -+ * drivers/gpu/drm/panel/panel-raydium-rm68200.c. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/*** Manufacturer Command Set ***/ -+#define MCS_CMD_MODE_SW 0xFE /* CMD Mode Switch */ -+#define MCS_CMD1_UCS 0x00 /* User Command Set (UCS = CMD1) */ -+#define MCS_CMD2_P0 0x01 /* Manufacture Command Set Page0 (CMD2 P0) */ -+#define MCS_CMD2_P1 0x02 /* Manufacture Command Set Page1 (CMD2 P1) */ -+#define MCS_CMD2_P2 0x03 /* Manufacture Command Set Page2 (CMD2 P2) */ -+#define MCS_CMD2_P3 0x04 /* Manufacture Command Set Page3 (CMD2 P3) */ -+ -+/* CMD2 P0 commands (Display Options and Power) */ -+#define MCS_STBCTR 0x12 /* TE1 Output Setting Zig-Zag Connection */ -+#define MCS_SGOPCTR 0x16 /* Source Bias Current */ -+#define MCS_SDCTR 0x1A /* Source Output Delay Time */ -+#define MCS_INVCTR 0x1B /* Inversion Type */ -+#define MCS_EXT_PWR_IC 0x24 /* External PWR IC Control */ -+#define MCS_SETAVDD 0x27 /* PFM Control for AVDD Output */ -+#define MCS_SETAVEE 0x29 /* PFM Control for AVEE Output */ -+#define MCS_BT2CTR 0x2B /* DDVDL Charge Pump Control */ -+#define MCS_BT3CTR 0x2F /* VGH Charge Pump Control */ -+#define MCS_BT4CTR 0x34 /* VGL Charge Pump Control */ -+#define MCS_VCMCTR 0x46 /* VCOM Output Level Control */ -+#define MCS_SETVGN 0x52 /* VG M/S N Control */ -+#define MCS_SETVGP 0x54 /* VG M/S P Control */ -+#define MCS_SW_CTRL 0x5F /* Interface Control for PFM and MIPI */ -+ -+/* CMD2 P2 commands (GOA Timing Control) - no description in datasheet */ -+#define GOA_VSTV1 0x00 -+#define GOA_VSTV2 0x07 -+#define GOA_VCLK1 0x0E -+#define GOA_VCLK2 0x17 -+#define GOA_VCLK_OPT1 0x20 -+#define GOA_BICLK1 0x2A -+#define GOA_BICLK2 0x37 -+#define GOA_BICLK3 0x44 -+#define GOA_BICLK4 0x4F -+#define GOA_BICLK_OPT1 0x5B -+#define GOA_BICLK_OPT2 0x60 -+#define MCS_GOA_GPO1 0x6D -+#define MCS_GOA_GPO2 0x71 -+#define MCS_GOA_EQ 0x74 -+#define MCS_GOA_CLK_GALLON 0x7C -+#define MCS_GOA_FS_SEL0 0x7E -+#define MCS_GOA_FS_SEL1 0x87 -+#define MCS_GOA_FS_SEL2 0x91 -+#define MCS_GOA_FS_SEL3 0x9B -+#define MCS_GOA_BS_SEL0 0xAC -+#define MCS_GOA_BS_SEL1 0xB5 -+#define MCS_GOA_BS_SEL2 0xBF -+#define MCS_GOA_BS_SEL3 0xC9 -+#define MCS_GOA_BS_SEL4 0xD3 -+ -+/* CMD2 P3 commands (Gamma) */ -+#define MCS_GAMMA_VP 0x60 /* Gamma VP1~VP16 */ -+#define MCS_GAMMA_VN 0x70 /* Gamma VN1~VN16 */ -+ -+struct rm68200_panel_priv { -+ struct udevice *reg; -+ struct udevice *backlight; -+ struct gpio_desc reset; -+}; -+ -+static const struct display_timing default_timing = { -+ .pixelclock = {.min = 52582000, .typ = 52582000, .max = 52582000,}, -+ .hactive = {.min = 720, .typ = 720, .max = 720,}, -+ .hfront_porch = {.min = 38, .typ = 38, .max = 38,}, -+ .hback_porch = {.min = 8, .typ = 8, .max = 8,}, -+ .hsync_len = {.min = 38, .typ = 38, .max = 38,}, -+ .vactive = {.min = 1280, .typ = 1280, .max = 1280,}, -+ .vfront_porch = {.min = 12, .typ = 12, .max = 12,}, -+ .vback_porch = {.min = 4, .typ = 4, .max = 4,}, -+ .vsync_len = {.min = 12, .typ = 12, .max = 12,}, -+}; -+ -+static void rm68200_dcs_write_buf(struct udevice *dev, const void *data, -+ size_t len) -+{ -+ struct mipi_dsi_panel_plat *plat = dev_get_platdata(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); -+} -+ -+static void rm68200_dcs_write_cmd(struct udevice *dev, u8 cmd, u8 value) -+{ -+ struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); -+ struct mipi_dsi_device *device = plat->device; -+ int err; -+ -+ err = mipi_dsi_dcs_write(device, cmd, &value, 1); -+ if (err < 0) -+ dev_err(dev, "MIPI DSI DCS write failed: %d\n", err); -+} -+ -+#define dcs_write_seq(ctx, seq...) \ -+({ \ -+ static const u8 d[] = { seq }; \ -+ \ -+ rm68200_dcs_write_buf(ctx, d, ARRAY_SIZE(d)); \ -+}) -+ -+/* -+ * This panel is not able to auto-increment all cmd addresses so for some of -+ * them, we need to send them one by one... -+ */ -+#define dcs_write_cmd_seq(ctx, cmd, seq...) \ -+({ \ -+ static const u8 d[] = { seq }; \ -+ unsigned int i; \ -+ \ -+ for (i = 0; i < ARRAY_SIZE(d) ; i++) \ -+ rm68200_dcs_write_cmd(ctx, cmd + i, d[i]); \ -+}) -+ -+static void rm68200_init_sequence(struct udevice *dev) -+{ -+ /* Enter CMD2 with page 0 */ -+ dcs_write_seq(dev, MCS_CMD_MODE_SW, MCS_CMD2_P0); -+ dcs_write_cmd_seq(dev, MCS_EXT_PWR_IC, 0xC0, 0x53, 0x00); -+ dcs_write_seq(dev, MCS_BT2CTR, 0xE5); -+ dcs_write_seq(dev, MCS_SETAVDD, 0x0A); -+ dcs_write_seq(dev, MCS_SETAVEE, 0x0A); -+ dcs_write_seq(dev, MCS_SGOPCTR, 0x52); -+ dcs_write_seq(dev, MCS_BT3CTR, 0x53); -+ dcs_write_seq(dev, MCS_BT4CTR, 0x5A); -+ dcs_write_seq(dev, MCS_INVCTR, 0x00); -+ dcs_write_seq(dev, MCS_STBCTR, 0x0A); -+ dcs_write_seq(dev, MCS_SDCTR, 0x06); -+ dcs_write_seq(dev, MCS_VCMCTR, 0x56); -+ dcs_write_seq(dev, MCS_SETVGN, 0xA0, 0x00); -+ dcs_write_seq(dev, MCS_SETVGP, 0xA0, 0x00); -+ dcs_write_seq(dev, MCS_SW_CTRL, 0x11); /* 2 data lanes, see doc */ -+ -+ dcs_write_seq(dev, MCS_CMD_MODE_SW, MCS_CMD2_P2); -+ dcs_write_seq(dev, GOA_VSTV1, 0x05); -+ dcs_write_seq(dev, 0x02, 0x0B); -+ dcs_write_seq(dev, 0x03, 0x0F); -+ dcs_write_seq(dev, 0x04, 0x7D, 0x00, 0x50); -+ dcs_write_cmd_seq(dev, GOA_VSTV2, 0x05, 0x16, 0x0D, 0x11, 0x7D, 0x00, -+ 0x50); -+ dcs_write_cmd_seq(dev, GOA_VCLK1, 0x07, 0x08, 0x01, 0x02, 0x00, 0x7D, -+ 0x00, 0x85, 0x08); -+ dcs_write_cmd_seq(dev, GOA_VCLK2, 0x03, 0x04, 0x05, 0x06, 0x00, 0x7D, -+ 0x00, 0x85, 0x08); -+ dcs_write_seq(dev, GOA_VCLK_OPT1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00); -+ dcs_write_cmd_seq(dev, GOA_BICLK1, 0x07, 0x08); -+ dcs_write_seq(dev, 0x2D, 0x01); -+ dcs_write_seq(dev, 0x2F, 0x02, 0x00, 0x40, 0x05, 0x08, 0x54, 0x7D, -+ 0x00); -+ dcs_write_cmd_seq(dev, GOA_BICLK2, 0x03, 0x04, 0x05, 0x06, 0x00); -+ dcs_write_seq(dev, 0x3D, 0x40); -+ dcs_write_seq(dev, 0x3F, 0x05, 0x08, 0x54, 0x7D, 0x00); -+ dcs_write_seq(dev, GOA_BICLK3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00); -+ dcs_write_seq(dev, GOA_BICLK4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00); -+ dcs_write_seq(dev, 0x58, 0x00, 0x00, 0x00); -+ dcs_write_seq(dev, GOA_BICLK_OPT1, 0x00, 0x00, 0x00, 0x00, 0x00); -+ dcs_write_seq(dev, GOA_BICLK_OPT2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); -+ dcs_write_seq(dev, MCS_GOA_GPO1, 0x00, 0x00, 0x00, 0x00); -+ dcs_write_seq(dev, MCS_GOA_GPO2, 0x00, 0x20, 0x00); -+ dcs_write_seq(dev, MCS_GOA_EQ, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -+ 0x00, 0x00); -+ dcs_write_seq(dev, MCS_GOA_CLK_GALLON, 0x00, 0x00); -+ dcs_write_cmd_seq(dev, MCS_GOA_FS_SEL0, 0xBF, 0x02, 0x06, 0x14, 0x10, -+ 0x16, 0x12, 0x08, 0x3F); -+ dcs_write_cmd_seq(dev, MCS_GOA_FS_SEL1, 0x3F, 0x3F, 0x3F, 0x3F, 0x0C, -+ 0x0A, 0x0E, 0x3F, 0x3F, 0x00); -+ dcs_write_cmd_seq(dev, MCS_GOA_FS_SEL2, 0x04, 0x3F, 0x3F, 0x3F, 0x3F, -+ 0x05, 0x01, 0x3F, 0x3F, 0x0F); -+ dcs_write_cmd_seq(dev, MCS_GOA_FS_SEL3, 0x0B, 0x0D, 0x3F, 0x3F, 0x3F, -+ 0x3F); -+ dcs_write_cmd_seq(dev, 0xA2, 0x3F, 0x09, 0x13, 0x17, 0x11, 0x15); -+ dcs_write_cmd_seq(dev, 0xA9, 0x07, 0x03, 0x3F); -+ dcs_write_cmd_seq(dev, MCS_GOA_BS_SEL0, 0x3F, 0x05, 0x01, 0x17, 0x13, -+ 0x15, 0x11, 0x0F, 0x3F); -+ dcs_write_cmd_seq(dev, MCS_GOA_BS_SEL1, 0x3F, 0x3F, 0x3F, 0x3F, 0x0B, -+ 0x0D, 0x09, 0x3F, 0x3F, 0x07); -+ dcs_write_cmd_seq(dev, MCS_GOA_BS_SEL2, 0x03, 0x3F, 0x3F, 0x3F, 0x3F, -+ 0x02, 0x06, 0x3F, 0x3F, 0x08); -+ dcs_write_cmd_seq(dev, MCS_GOA_BS_SEL3, 0x0C, 0x0A, 0x3F, 0x3F, 0x3F, -+ 0x3F, 0x3F, 0x0E, 0x10, 0x14); -+ dcs_write_cmd_seq(dev, MCS_GOA_BS_SEL4, 0x12, 0x16, 0x00, 0x04, 0x3F); -+ dcs_write_seq(dev, 0xDC, 0x02); -+ dcs_write_seq(dev, 0xDE, 0x12); -+ -+ dcs_write_seq(dev, MCS_CMD_MODE_SW, 0x0E); /* No documentation */ -+ dcs_write_seq(dev, 0x01, 0x75); -+ -+ dcs_write_seq(dev, MCS_CMD_MODE_SW, MCS_CMD2_P3); -+ dcs_write_cmd_seq(dev, MCS_GAMMA_VP, 0x00, 0x0C, 0x12, 0x0E, 0x06, -+ 0x12, 0x0E, 0x0B, 0x15, 0x0B, 0x10, 0x07, 0x0F, -+ 0x12, 0x0C, 0x00); -+ dcs_write_cmd_seq(dev, MCS_GAMMA_VN, 0x00, 0x0C, 0x12, 0x0E, 0x06, -+ 0x12, 0x0E, 0x0B, 0x15, 0x0B, 0x10, 0x07, 0x0F, -+ 0x12, 0x0C, 0x00); -+ -+ /* Exit CMD2 */ -+ dcs_write_seq(dev, MCS_CMD_MODE_SW, MCS_CMD1_UCS); -+} -+ -+static int rm68200_panel_enable_backlight(struct udevice *dev) -+{ -+ struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); -+ struct mipi_dsi_device *device = plat->device; -+ struct rm68200_panel_priv *priv = dev_get_priv(dev); -+ int ret; -+ -+ device->lanes = 2; -+ device->format = MIPI_DSI_FMT_RGB888; -+ device->mode_flags = MIPI_DSI_MODE_VIDEO | -+ MIPI_DSI_MODE_VIDEO_BURST | -+ MIPI_DSI_MODE_LPM; -+ -+ ret = mipi_dsi_attach(device); -+ if (ret < 0) -+ return ret; -+ -+ rm68200_init_sequence(dev); -+ -+ ret = mipi_dsi_dcs_exit_sleep_mode(device); -+ if (ret) -+ return ret; -+ -+ mdelay(125); -+ -+ ret = mipi_dsi_dcs_set_display_on(device); -+ if (ret) -+ return ret; -+ -+ mdelay(20); -+ -+ ret = backlight_enable(priv->backlight); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static int rm68200_panel_get_display_timing(struct udevice *dev, -+ struct display_timing *timings) -+{ -+ memcpy(timings, &default_timing, sizeof(*timings)); -+ return 0; -+} -+ -+static int rm68200_panel_ofdata_to_platdata(struct udevice *dev) -+{ -+ struct rm68200_panel_priv *priv = dev_get_priv(dev); -+ int ret; -+ -+ if (IS_ENABLED(CONFIG_DM_REGULATOR)) { -+ ret = device_get_supply_regulator(dev, "power-supply", -+ &priv->reg); -+ if (ret && ret != -ENOENT) { -+ 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; -+ } -+ -+ return 0; -+} -+ -+static int rm68200_panel_probe(struct udevice *dev) -+{ -+ struct rm68200_panel_priv *priv = dev_get_priv(dev); -+ int ret; -+ -+ if (IS_ENABLED(CONFIG_DM_REGULATOR) && priv->reg) { -+ 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(10); -+ -+ return 0; -+} -+ -+static const struct panel_ops rm68200_panel_ops = { -+ .enable_backlight = rm68200_panel_enable_backlight, -+ .get_display_timing = rm68200_panel_get_display_timing, -+}; -+ -+static const struct udevice_id rm68200_panel_ids[] = { -+ { .compatible = "raydium,rm68200" }, -+ { } -+}; -+ -+U_BOOT_DRIVER(rm68200_panel) = { -+ .name = "rm68200_panel", -+ .id = UCLASS_PANEL, -+ .of_match = rm68200_panel_ids, -+ .ops = &rm68200_panel_ops, -+ .ofdata_to_platdata = rm68200_panel_ofdata_to_platdata, -+ .probe = rm68200_panel_probe, -+ .platdata_auto_alloc_size = sizeof(struct mipi_dsi_panel_plat), -+ .priv_auto_alloc_size = sizeof(struct rm68200_panel_priv), -+}; -diff --git a/drivers/video/stm32/Kconfig b/drivers/video/stm32/Kconfig -index 78b1fac..95d51bb 100644 ---- a/drivers/video/stm32/Kconfig -+++ b/drivers/video/stm32/Kconfig -@@ -13,6 +13,15 @@ menuconfig VIDEO_STM32 - DSI. This option enables these supports which can be used on - devices which have RGB TFT or DSI display connected. - -+config VIDEO_STM32_DSI -+ bool "Enable STM32 DSI video support" -+ depends on VIDEO_STM32 -+ select VIDEO_BRIDGE -+ select VIDEO_DW_MIPI_DSI -+ help -+ This option enables support DSI internal bridge which can be used on -+ devices which have DSI devices connected. -+ - config VIDEO_STM32_MAX_XRES - int "Maximum horizontal resolution (for memory allocation purposes)" - depends on VIDEO_STM32 -diff --git a/drivers/video/stm32/Makefile b/drivers/video/stm32/Makefile -index 7297e5f..f8b42d1 100644 ---- a/drivers/video/stm32/Makefile -+++ b/drivers/video/stm32/Makefile -@@ -6,3 +6,4 @@ - # Yannick Fertre - - obj-${CONFIG_VIDEO_STM32} = stm32_ltdc.o -+obj-${CONFIG_VIDEO_STM32_DSI} += stm32_dsi.o -diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c -new file mode 100644 -index 0000000..09266fe ---- /dev/null -+++ b/drivers/video/stm32/stm32_dsi.c -@@ -0,0 +1,446 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2018 STMicroelectronics - All Rights Reserved -+ * Author(s): Philippe Cornu for STMicroelectronics. -+ * Yannick Fertre for STMicroelectronics. -+ * -+ * This MIPI DSI controller driver is based on the Linux Kernel driver from -+ * drivers/gpu/drm/stm/dw_mipi_dsi-stm.c. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define HWVER_130 0x31333000 /* IP version 1.30 */ -+#define HWVER_131 0x31333100 /* IP version 1.31 */ -+ -+/* DSI digital registers & bit definitions */ -+#define DSI_VERSION 0x00 -+#define VERSION GENMASK(31, 8) -+ -+/* -+ * DSI wrapper registers & bit definitions -+ * Note: registers are named as in the Reference Manual -+ */ -+#define DSI_WCFGR 0x0400 /* Wrapper ConFiGuration Reg */ -+#define WCFGR_DSIM BIT(0) /* DSI Mode */ -+#define WCFGR_COLMUX GENMASK(3, 1) /* COLor MUltipleXing */ -+ -+#define DSI_WCR 0x0404 /* Wrapper Control Reg */ -+#define WCR_DSIEN BIT(3) /* DSI ENable */ -+ -+#define DSI_WISR 0x040C /* Wrapper Interrupt and Status Reg */ -+#define WISR_PLLLS BIT(8) /* PLL Lock Status */ -+#define WISR_RRS BIT(12) /* Regulator Ready Status */ -+ -+#define DSI_WPCR0 0x0418 /* Wrapper Phy Conf Reg 0 */ -+#define WPCR0_UIX4 GENMASK(5, 0) /* Unit Interval X 4 */ -+#define WPCR0_TDDL BIT(16) /* Turn Disable Data Lanes */ -+ -+#define DSI_WRPCR 0x0430 /* Wrapper Regulator & Pll Ctrl Reg */ -+#define WRPCR_PLLEN BIT(0) /* PLL ENable */ -+#define WRPCR_NDIV GENMASK(8, 2) /* pll loop DIVision Factor */ -+#define WRPCR_IDF GENMASK(14, 11) /* pll Input Division Factor */ -+#define WRPCR_ODF GENMASK(17, 16) /* pll Output Division Factor */ -+#define WRPCR_REGEN BIT(24) /* REGulator ENable */ -+#define WRPCR_BGREN BIT(28) /* BandGap Reference ENable */ -+#define IDF_MIN 1 -+#define IDF_MAX 7 -+#define NDIV_MIN 10 -+#define NDIV_MAX 125 -+#define ODF_MIN 1 -+#define ODF_MAX 8 -+ -+/* dsi color format coding according to the datasheet */ -+enum dsi_color { -+ DSI_RGB565_CONF1, -+ DSI_RGB565_CONF2, -+ DSI_RGB565_CONF3, -+ DSI_RGB666_CONF1, -+ DSI_RGB666_CONF2, -+ DSI_RGB888, -+}; -+ -+#define LANE_MIN_KBPS 31250 -+#define LANE_MAX_KBPS 500000 -+ -+/* Timeout for regulator on/off, pll lock/unlock & fifo empty */ -+#define TIMEOUT_US 200000 -+ -+struct stm32_dsi_priv { -+ struct mipi_dsi_device device; -+ void __iomem *base; -+ struct udevice *panel; -+ u32 pllref_clk; -+ u32 hw_version; -+ int lane_min_kbps; -+ int lane_max_kbps; -+ struct udevice *vdd_reg; -+}; -+ -+static inline void dsi_write(struct stm32_dsi_priv *dsi, u32 reg, u32 val) -+{ -+ writel(val, dsi->base + reg); -+} -+ -+static inline u32 dsi_read(struct stm32_dsi_priv *dsi, u32 reg) -+{ -+ return readl(dsi->base + reg); -+} -+ -+static inline void dsi_set(struct stm32_dsi_priv *dsi, u32 reg, u32 mask) -+{ -+ dsi_write(dsi, reg, dsi_read(dsi, reg) | mask); -+} -+ -+static inline void dsi_clear(struct stm32_dsi_priv *dsi, u32 reg, u32 mask) -+{ -+ dsi_write(dsi, reg, dsi_read(dsi, reg) & ~mask); -+} -+ -+static inline void dsi_update_bits(struct stm32_dsi_priv *dsi, u32 reg, -+ u32 mask, u32 val) -+{ -+ dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val); -+} -+ -+static enum dsi_color dsi_color_from_mipi(u32 fmt) -+{ -+ switch (fmt) { -+ case MIPI_DSI_FMT_RGB888: -+ return DSI_RGB888; -+ case MIPI_DSI_FMT_RGB666: -+ return DSI_RGB666_CONF2; -+ case MIPI_DSI_FMT_RGB666_PACKED: -+ return DSI_RGB666_CONF1; -+ case MIPI_DSI_FMT_RGB565: -+ return DSI_RGB565_CONF1; -+ default: -+ pr_err("MIPI color invalid, so we use rgb888\n"); -+ } -+ return DSI_RGB888; -+} -+ -+static int dsi_pll_get_clkout_khz(int clkin_khz, int idf, int ndiv, int odf) -+{ -+ int divisor = idf * odf; -+ -+ /* prevent from division by 0 */ -+ if (!divisor) -+ return 0; -+ -+ return DIV_ROUND_CLOSEST(clkin_khz * ndiv, divisor); -+} -+ -+static int dsi_pll_get_params(struct stm32_dsi_priv *dsi, -+ int clkin_khz, int clkout_khz, -+ int *idf, int *ndiv, int *odf) -+{ -+ int i, o, n, n_min, n_max; -+ int fvco_min, fvco_max, delta, best_delta; /* all in khz */ -+ -+ /* Early checks preventing division by 0 & odd results */ -+ if (clkin_khz <= 0 || clkout_khz <= 0) -+ return -EINVAL; -+ -+ fvco_min = dsi->lane_min_kbps * 2 * ODF_MAX; -+ fvco_max = dsi->lane_max_kbps * 2 * ODF_MIN; -+ -+ best_delta = 1000000; /* big started value (1000000khz) */ -+ -+ for (i = IDF_MIN; i <= IDF_MAX; i++) { -+ /* Compute ndiv range according to Fvco */ -+ n_min = ((fvco_min * i) / (2 * clkin_khz)) + 1; -+ n_max = (fvco_max * i) / (2 * clkin_khz); -+ -+ /* No need to continue idf loop if we reach ndiv max */ -+ if (n_min >= NDIV_MAX) -+ break; -+ -+ /* Clamp ndiv to valid values */ -+ if (n_min < NDIV_MIN) -+ n_min = NDIV_MIN; -+ if (n_max > NDIV_MAX) -+ n_max = NDIV_MAX; -+ -+ for (o = ODF_MIN; o <= ODF_MAX; o *= 2) { -+ n = DIV_ROUND_CLOSEST(i * o * clkout_khz, clkin_khz); -+ /* Check ndiv according to vco range */ -+ if (n < n_min || n > n_max) -+ continue; -+ /* Check if new delta is better & saves parameters */ -+ delta = dsi_pll_get_clkout_khz(clkin_khz, i, n, o) - -+ clkout_khz; -+ if (delta < 0) -+ delta = -delta; -+ if (delta < best_delta) { -+ *idf = i; -+ *ndiv = n; -+ *odf = o; -+ best_delta = delta; -+ } -+ /* fast return in case of "perfect result" */ -+ if (!delta) -+ return 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static int dsi_phy_init(void *priv_data) -+{ -+ struct mipi_dsi_device *device = priv_data; -+ struct udevice *dev = device->dev; -+ struct stm32_dsi_priv *dsi = dev_get_priv(dev); -+ u32 val; -+ int ret; -+ -+ /* Enable the regulator */ -+ dsi_set(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN); -+ ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS, -+ TIMEOUT_US); -+ if (ret) { -+ dev_err(dev, "!TIMEOUT! waiting REGU\n"); -+ return ret; -+ } -+ -+ /* Enable the DSI PLL & wait for its lock */ -+ dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN); -+ ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS, -+ TIMEOUT_US); -+ if (ret) { -+ dev_err(dev, "!TIMEOUT! waiting PLL\n"); -+ return ret; -+ } -+ -+ /* Enable the DSI wrapper */ -+ dsi_set(dsi, DSI_WCR, WCR_DSIEN); -+ -+ return 0; -+} -+ -+static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings, -+ u32 lanes, u32 format, unsigned int *lane_mbps) -+{ -+ struct mipi_dsi_device *device = priv_data; -+ struct udevice *dev = device->dev; -+ struct stm32_dsi_priv *dsi = dev_get_priv(dev); -+ int idf, ndiv, odf, pll_in_khz, pll_out_khz; -+ int ret, bpp; -+ u32 val; -+ -+ /* Update lane capabilities according to hw version */ -+ dsi->hw_version = dsi_read(dsi, DSI_VERSION) & VERSION; -+ dsi->lane_min_kbps = LANE_MIN_KBPS; -+ dsi->lane_max_kbps = LANE_MAX_KBPS; -+ if (dsi->hw_version == HWVER_131) { -+ dsi->lane_min_kbps *= 2; -+ dsi->lane_max_kbps *= 2; -+ } -+ -+ pll_in_khz = dsi->pllref_clk / 1000; -+ -+ /* Compute requested pll out */ -+ bpp = mipi_dsi_pixel_format_to_bpp(format); -+ pll_out_khz = (timings->pixelclock.typ / 1000) * bpp / lanes; -+ /* Add 20% to pll out to be higher than pixel bw (burst mode only) */ -+ pll_out_khz = (pll_out_khz * 12) / 10; -+ if (pll_out_khz > dsi->lane_max_kbps) { -+ pll_out_khz = dsi->lane_max_kbps; -+ dev_warn(dev, "Warning max phy mbps is used\n"); -+ } -+ if (pll_out_khz < dsi->lane_min_kbps) { -+ pll_out_khz = dsi->lane_min_kbps; -+ dev_warn(dev, "Warning min phy mbps is used\n"); -+ } -+ -+ /* Compute best pll parameters */ -+ idf = 0; -+ ndiv = 0; -+ odf = 0; -+ ret = dsi_pll_get_params(dsi, pll_in_khz, pll_out_khz, -+ &idf, &ndiv, &odf); -+ if (ret) { -+ dev_err(dev, "Warning dsi_pll_get_params(): bad params\n"); -+ return ret; -+ } -+ -+ /* Get the adjusted pll out value */ -+ pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf); -+ -+ /* Set the PLL division factors */ -+ dsi_update_bits(dsi, DSI_WRPCR, WRPCR_NDIV | WRPCR_IDF | WRPCR_ODF, -+ (ndiv << 2) | (idf << 11) | ((ffs(odf) - 1) << 16)); -+ -+ /* Compute uix4 & set the bit period in high-speed mode */ -+ val = 4000000 / pll_out_khz; -+ dsi_update_bits(dsi, DSI_WPCR0, WPCR0_UIX4, val); -+ -+ /* Select video mode by resetting DSIM bit */ -+ dsi_clear(dsi, DSI_WCFGR, WCFGR_DSIM); -+ -+ /* Select the color coding */ -+ dsi_update_bits(dsi, DSI_WCFGR, WCFGR_COLMUX, -+ dsi_color_from_mipi(format) << 1); -+ -+ *lane_mbps = pll_out_khz / 1000; -+ -+ debug("pll_in %ukHz pll_out %ukHz lane_mbps %uMHz\n", -+ pll_in_khz, pll_out_khz, *lane_mbps); -+ -+ return 0; -+} -+ -+static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_stm_phy_ops = { -+ .init = dsi_phy_init, -+ .get_lane_mbps = dsi_get_lane_mbps, -+}; -+ -+static int stm32_dsi_attach(struct udevice *dev) -+{ -+ struct stm32_dsi_priv *priv = dev_get_priv(dev); -+ struct dw_mipi_dsi_plat_data *platdata = dev_get_platdata(dev); -+ struct mipi_dsi_device *device = &priv->device; -+ int ret; -+ -+ platdata->max_data_lanes = 2; -+ platdata->phy_ops = &dw_mipi_dsi_stm_phy_ops; -+ -+ ret = uclass_first_device(UCLASS_PANEL, &platdata->panel); -+ if (ret) { -+ dev_err(dev, "panel device error %d\n", ret); -+ return ret; -+ } -+ -+ ret = dw_mipi_dsi_init_bridge(device); -+ if (ret) { -+ dev_err(dev, "failed to initialize mipi dsi host\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int stm32_dsi_set_backlight(struct udevice *dev, int percent) -+{ -+ struct dw_mipi_dsi_plat_data *dplat = dev_get_platdata(dev); -+ struct stm32_dsi_priv *priv = dev_get_priv(dev); -+ struct mipi_dsi_device *device = &priv->device; -+ struct udevice *panel = dplat->panel; -+ struct mipi_dsi_panel_plat *mplat; -+ int ret; -+ -+ mplat = dev_get_platdata(panel); -+ mplat->device = device; -+ -+ ret = panel_enable_backlight(panel); -+ if (ret) { -+ dev_err(dev, "panel %s enable backlight error %d\n", -+ panel->name, ret); -+ return ret; -+ } -+ -+ dw_mipi_dsi_bridge_enable(device); -+ -+ return 0; -+} -+ -+static int stm32_dsi_probe(struct udevice *dev) -+{ -+ struct stm32_dsi_priv *priv = dev_get_priv(dev); -+ struct mipi_dsi_device *device = &priv->device; -+ struct reset_ctl rst; -+ struct clk clk; -+ int ret; -+ -+ device->dev = dev; -+ -+ priv->base = (void *)dev_read_addr(dev); -+ if ((fdt_addr_t)priv->base == FDT_ADDR_T_NONE) { -+ dev_err(dev, "dsi dt register address error\n"); -+ return -EINVAL; -+ } -+ -+ if (IS_ENABLED(CONFIG_DM_REGULATOR)) { -+ ret = device_get_supply_regulator(dev, "phy-dsi-supply", -+ &priv->vdd_reg); -+ if (ret && ret != -ENOENT) { -+ dev_err(dev, "Warning: cannot get phy dsi supply\n"); -+ return -ENODEV; -+ } -+ -+ ret = regulator_set_enable(priv->vdd_reg, true); -+ if (ret) -+ return -ENODEV; -+ } -+ -+ ret = clk_get_by_name(device->dev, "pclk", &clk); -+ if (ret) { -+ dev_err(dev, "peripheral clock get error %d\n", ret); -+ regulator_set_enable(priv->vdd_reg, false); -+ return -ENODEV; -+ } -+ -+ ret = clk_enable(&clk); -+ if (ret) { -+ dev_err(dev, "peripheral clock enable error %d\n", ret); -+ regulator_set_enable(priv->vdd_reg, false); -+ return -ENODEV; -+ } -+ -+ ret = clk_get_by_name(dev, "ref", &clk); -+ if (ret) { -+ dev_err(dev, "pll reference clock get error %d\n", ret); -+ clk_disable(&clk); -+ regulator_set_enable(priv->vdd_reg, false); -+ return ret; -+ } -+ -+ priv->pllref_clk = (unsigned int)clk_get_rate(&clk); -+ -+ ret = reset_get_by_index(device->dev, 0, &rst); -+ if (ret) { -+ dev_err(dev, "missing dsi hardware reset\n"); -+ clk_disable(&clk); -+ regulator_set_enable(priv->vdd_reg, false); -+ return -ENODEV; -+ } -+ -+ /* Reset */ -+ reset_deassert(&rst); -+ -+ return 0; -+} -+ -+struct video_bridge_ops stm32_dsi_ops = { -+ .attach = stm32_dsi_attach, -+ .set_backlight = stm32_dsi_set_backlight, -+}; -+ -+static const struct udevice_id stm32_dsi_ids[] = { -+ { .compatible = "st,stm32-dsi"}, -+ { } -+}; -+ -+U_BOOT_DRIVER(stm32_dsi) = { -+ .name = "stm32-display-dsi", -+ .id = UCLASS_VIDEO_BRIDGE, -+ .of_match = stm32_dsi_ids, -+ .bind = dm_scan_fdt_dev, -+ .probe = stm32_dsi_probe, -+ .ops = &stm32_dsi_ops, -+ .priv_auto_alloc_size = sizeof(struct stm32_dsi_priv), -+ .platdata_auto_alloc_size = sizeof(struct dw_mipi_dsi_plat_data), -+}; -diff --git a/drivers/video/stm32/stm32_ltdc.c b/drivers/video/stm32/stm32_ltdc.c -index dc6c889..8c996b8 100644 ---- a/drivers/video/stm32/stm32_ltdc.c -+++ b/drivers/video/stm32/stm32_ltdc.c -@@ -4,22 +4,20 @@ - * Author(s): Philippe Cornu for STMicroelectronics. - * Yannick Fertre for STMicroelectronics. - */ -- - #include - #include -+#include - #include - #include - #include - #include -+#include - #include - #include - #include - --DECLARE_GLOBAL_DATA_PTR; -- - struct stm32_ltdc_priv { - void __iomem *regs; -- struct display_timing timing; - enum video_log2_bpp l2bpp; - u32 bg_col_argb; - u32 crop_x, crop_y, crop_w, crop_h; -@@ -174,8 +172,8 @@ static u32 stm32_ltdc_get_pixel_format(enum video_log2_bpp l2bpp) - case VIDEO_BPP2: - case VIDEO_BPP4: - default: -- debug("%s: warning %dbpp not supported yet, %dbpp instead\n", -- __func__, VNBITS(l2bpp), VNBITS(VIDEO_BPP16)); -+ pr_warn("%s: warning %dbpp not supported yet, %dbpp instead\n", -+ __func__, VNBITS(l2bpp), VNBITS(VIDEO_BPP16)); - pf = PF_RGB565; - break; - } -@@ -209,23 +207,23 @@ static void stm32_ltdc_enable(struct stm32_ltdc_priv *priv) - setbits_le32(priv->regs + LTDC_GCR, GCR_LTDCEN); - } - --static void stm32_ltdc_set_mode(struct stm32_ltdc_priv *priv) -+static void stm32_ltdc_set_mode(struct stm32_ltdc_priv *priv, -+ struct display_timing *timings) - { - void __iomem *regs = priv->regs; -- struct display_timing *timing = &priv->timing; - u32 hsync, vsync, acc_hbp, acc_vbp, acc_act_w, acc_act_h; - u32 total_w, total_h; - u32 val; - - /* Convert video timings to ltdc timings */ -- hsync = timing->hsync_len.typ - 1; -- vsync = timing->vsync_len.typ - 1; -- acc_hbp = hsync + timing->hback_porch.typ; -- acc_vbp = vsync + timing->vback_porch.typ; -- acc_act_w = acc_hbp + timing->hactive.typ; -- acc_act_h = acc_vbp + timing->vactive.typ; -- total_w = acc_act_w + timing->hfront_porch.typ; -- total_h = acc_act_h + timing->vfront_porch.typ; -+ hsync = timings->hsync_len.typ - 1; -+ vsync = timings->vsync_len.typ - 1; -+ acc_hbp = hsync + timings->hback_porch.typ; -+ acc_vbp = vsync + timings->vback_porch.typ; -+ acc_act_w = acc_hbp + timings->hactive.typ; -+ acc_act_h = acc_vbp + timings->vactive.typ; -+ total_w = acc_act_w + timings->hfront_porch.typ; -+ total_h = acc_act_h + timings->vfront_porch.typ; - - /* Synchronization sizes */ - val = (hsync << 16) | vsync; -@@ -247,14 +245,14 @@ static void stm32_ltdc_set_mode(struct stm32_ltdc_priv *priv) - - /* Signal polarities */ - val = 0; -- debug("%s: timing->flags 0x%08x\n", __func__, timing->flags); -- if (timing->flags & DISPLAY_FLAGS_HSYNC_HIGH) -+ debug("%s: timing->flags 0x%08x\n", __func__, timings->flags); -+ if (timings->flags & DISPLAY_FLAGS_HSYNC_HIGH) - val |= GCR_HSPOL; -- if (timing->flags & DISPLAY_FLAGS_VSYNC_HIGH) -+ if (timings->flags & DISPLAY_FLAGS_VSYNC_HIGH) - val |= GCR_VSPOL; -- if (timing->flags & DISPLAY_FLAGS_DE_HIGH) -+ if (timings->flags & DISPLAY_FLAGS_DE_HIGH) - val |= GCR_DEPOL; -- if (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) -+ if (timings->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) - val |= GCR_PCPOL; - clrsetbits_le32(regs + LTDC_GCR, - GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val); -@@ -330,96 +328,129 @@ static int stm32_ltdc_probe(struct udevice *dev) - struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev); - struct video_priv *uc_priv = dev_get_uclass_priv(dev); - struct stm32_ltdc_priv *priv = dev_get_priv(dev); -- struct udevice *panel; -+#ifdef CONFIG_VIDEO_BRIDGE -+ struct udevice *bridge = NULL; -+#endif -+ struct udevice *panel = NULL; -+ struct display_timing timings; - struct clk pclk; - struct reset_ctl rst; -- int rate, ret; -+ int ret; - - priv->regs = (void *)dev_read_addr(dev); - if ((fdt_addr_t)priv->regs == FDT_ADDR_T_NONE) { -- debug("%s: ltdc dt register address error\n", __func__); -+ dev_err(dev, "ltdc dt register address error\n"); - return -EINVAL; - } - - ret = clk_get_by_index(dev, 0, &pclk); - if (ret) { -- debug("%s: peripheral clock get error %d\n", __func__, ret); -+ dev_err(dev, "peripheral clock get error %d\n", ret); - return ret; - } - - ret = clk_enable(&pclk); - if (ret) { -- debug("%s: peripheral clock enable error %d\n", -- __func__, ret); -+ dev_err(dev, "peripheral clock enable error %d\n", ret); - return ret; - } - -- ret = reset_get_by_index(dev, 0, &rst); -+ ret = uclass_first_device_err(UCLASS_PANEL, &panel); - if (ret) { -- debug("%s: missing ltdc hardware reset\n", __func__); -- return -ENODEV; -+ if (ret != -ENODEV) -+ dev_err(dev, "panel device error %d\n", ret); -+ return ret; - } - -- /* Reset */ -- reset_deassert(&rst); -- -- ret = uclass_first_device(UCLASS_PANEL, &panel); -+ ret = panel_get_display_timing(panel, &timings); - if (ret) { -- debug("%s: panel device error %d\n", __func__, ret); -- return ret; -+ ret = fdtdec_decode_display_timing(gd->fdt_blob, -+ dev_of_offset(panel), -+ 0, &timings); -+ if (ret) { -+ dev_err(dev, "decode display timing error %d\n", ret); -+ return ret; -+ } - } - -- ret = panel_enable_backlight(panel); -+ ret = clk_set_rate(&pclk, timings.pixelclock.typ); -+ if (ret) -+ dev_warn(dev, "fail to set pixel clock %d hz\n", -+ timings.pixelclock.typ); -+ -+ debug("%s: Set pixel clock req %d hz get %ld hz\n", __func__, -+ timings.pixelclock.typ, clk_get_rate(&pclk)); -+ -+ ret = reset_get_by_index(dev, 0, &rst); - if (ret) { -- debug("%s: panel %s enable backlight error %d\n", -- __func__, panel->name, ret); -+ dev_err(dev, "missing ltdc hardware reset\n"); - return ret; - } - -- ret = fdtdec_decode_display_timing(gd->fdt_blob, -- dev_of_offset(dev), 0, -- &priv->timing); -- if (ret) { -- debug("%s: decode display timing error %d\n", -- __func__, ret); -- return -EINVAL; -- } -+ /* Reset */ -+ reset_deassert(&rst); - -- rate = clk_set_rate(&pclk, priv->timing.pixelclock.typ); -- if (rate < 0) { -- debug("%s: fail to set pixel clock %d hz %d hz\n", -- __func__, priv->timing.pixelclock.typ, rate); -- return rate; -+#ifdef CONFIG_VIDEO_BRIDGE -+ ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &bridge); -+ if (ret) -+ debug("No video bridge, or no backlight on bridge\n"); -+ -+ if (bridge) { -+ ret = video_bridge_attach(bridge); -+ if (ret) { -+ dev_err(dev, "fail to attach bridge\n"); -+ return ret; -+ } - } -- -- debug("%s: Set pixel clock req %d hz get %d hz\n", __func__, -- priv->timing.pixelclock.typ, rate); -- -+#endif - /* TODO Below parameters are hard-coded for the moment... */ - priv->l2bpp = VIDEO_BPP16; - priv->bg_col_argb = 0xFFFFFFFF; /* white no transparency */ - priv->crop_x = 0; - priv->crop_y = 0; -- priv->crop_w = priv->timing.hactive.typ; -- priv->crop_h = priv->timing.vactive.typ; -+ priv->crop_w = timings.hactive.typ; -+ priv->crop_h = timings.vactive.typ; - priv->alpha = 0xFF; - - debug("%s: %dx%d %dbpp frame buffer at 0x%lx\n", __func__, -- priv->timing.hactive.typ, priv->timing.vactive.typ, -+ timings.hactive.typ, timings.vactive.typ, - VNBITS(priv->l2bpp), uc_plat->base); - debug("%s: crop %d,%d %dx%d bg 0x%08x alpha %d\n", __func__, - priv->crop_x, priv->crop_y, priv->crop_w, priv->crop_h, - priv->bg_col_argb, priv->alpha); - - /* Configure & start LTDC */ -- stm32_ltdc_set_mode(priv); -+ stm32_ltdc_set_mode(priv, &timings); - stm32_ltdc_set_layer1(priv, uc_plat->base); - stm32_ltdc_enable(priv); - -- uc_priv->xsize = priv->timing.hactive.typ; -- uc_priv->ysize = priv->timing.vactive.typ; -+ uc_priv->xsize = timings.hactive.typ; -+ uc_priv->ysize = timings.vactive.typ; - uc_priv->bpix = priv->l2bpp; - -+#ifdef CONFIG_VIDEO_BRIDGE -+ if (bridge) { -+ ret = video_bridge_set_backlight(bridge, 80); -+ if (ret) { -+ dev_err(dev, "fail to set backlight\n"); -+ return ret; -+ } -+ } else { -+ ret = panel_enable_backlight(panel); -+ if (ret) { -+ dev_err(dev, "panel %s enable backlight error %d\n", -+ panel->name, ret); -+ return ret; -+ } -+ } -+#else -+ ret = panel_enable_backlight(panel); -+ if (ret) { -+ dev_err(dev, "panel %s enable backlight error %d\n", -+ panel->name, ret); -+ return ret; -+ } -+#endif - video_set_flush_dcache(dev, true); - - return 0; -diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c -index 44dfa71..5fe49a5 100644 ---- a/drivers/video/video-uclass.c -+++ b/drivers/video/video-uclass.c -@@ -300,3 +300,17 @@ UCLASS_DRIVER(video) = { - .per_device_auto_alloc_size = sizeof(struct video_priv), - .per_device_platdata_auto_alloc_size = sizeof(struct video_uc_platdata), - }; -+ -+static int do_video_clear(cmd_tbl_t *cmdtp, int flag, int argc, -+ char *const argv[]) -+{ -+ struct udevice *dev; -+ -+ if (uclass_first_device_err(UCLASS_VIDEO, &dev)) -+ return CMD_RET_FAILURE; -+ video_clear(dev); -+ -+ return 0; -+} -+ -+U_BOOT_CMD(cls, 1, 1, do_video_clear, "clear screen", ""); -diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig -index 02f4e1e..705fc7d 100644 ---- a/drivers/watchdog/Kconfig -+++ b/drivers/watchdog/Kconfig -@@ -103,6 +103,21 @@ config WDT_CDNS - Select this to enable Cadence watchdog timer, which can be found on some - Xilinx Microzed Platform. - -+config STM32MP_WATCHDOG -+ bool "Enable IWDG watchdog driver for STM32 MP's family" -+ depends on ARCH_STM32MP -+ select HW_WATCHDOG -+ help -+ Enable the STM32 watchdog (IWDG) driver. Enable support to -+ configure STM32's on-SoC watchdog. -+ -+config STM32MP_WATCHDOG_TIMEOUT_SECS -+ int "IWDG watchdog timeout" -+ depends on STM32MP_WATCHDOG -+ default 32 -+ help -+ Configure the timeout for IWDG (default: 32s). -+ - config XILINX_TB_WATCHDOG - bool "Xilinx Axi watchdog timer support" - depends on WDT -diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile -index 08406ca..25491cf 100644 ---- a/drivers/watchdog/Makefile -+++ b/drivers/watchdog/Makefile -@@ -23,3 +23,4 @@ obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o - obj-$(CONFIG_WDT_ORION) += orion_wdt.o - obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o - obj-$(CONFIG_MPC8xx_WATCHDOG) += mpc8xx_wdt.o -+obj-$(CONFIG_STM32MP_WATCHDOG) += stm32mp_wdt.o -\ No newline at end of file -diff --git a/drivers/watchdog/stm32mp_wdt.c b/drivers/watchdog/stm32mp_wdt.c -new file mode 100644 -index 0000000..696be1b ---- /dev/null -+++ b/drivers/watchdog/stm32mp_wdt.c -@@ -0,0 +1,119 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* IWDG registers */ -+#define IWDG_KR 0x00 /* Key register */ -+#define IWDG_PR 0x04 /* Prescaler Register */ -+#define IWDG_RLR 0x08 /* ReLoad Register */ -+#define IWDG_SR 0x0C /* Status Register */ -+ -+/* IWDG_KR register bit mask */ -+#define KR_KEY_RELOAD 0xAAAA /* Reload counter enable */ -+#define KR_KEY_ENABLE 0xCCCC /* Peripheral enable */ -+#define KR_KEY_EWA 0x5555 /* Write access enable */ -+ -+/* IWDG_PR register bit values */ -+#define PR_256 0x06 /* Prescaler set to 256 */ -+ -+/* IWDG_RLR register values */ -+#define RLR_MAX 0xFFF /* Max value supported by reload register */ -+ -+static fdt_addr_t stm32mp_wdt_base -+ __attribute__((section(".data"))) = FDT_ADDR_T_NONE; -+ -+void hw_watchdog_reset(void) -+{ -+ if (stm32mp_wdt_base != FDT_ADDR_T_NONE) -+ writel(KR_KEY_RELOAD, stm32mp_wdt_base + IWDG_KR); -+} -+ -+void hw_watchdog_init(void) -+{ -+ struct regmap *map; -+ -+ map = syscon_get_regmap_by_driver_data(STM32MP_SYSCON_IWDG); -+ if (!IS_ERR(map)) -+ stm32mp_wdt_base = map->ranges[0].start; -+ else -+ printf("%s: iwdg init error", __func__); -+} -+ -+static int stm32mp_wdt_probe(struct udevice *dev) -+{ -+ struct regmap *map = syscon_get_regmap(dev); -+ struct clk clk; -+ int ret, reload; -+ u32 time_start; -+ ulong regmap_base = map->ranges[0].start; -+ -+ debug("IWDG init\n"); -+ -+ /* Enable clock */ -+ ret = clk_get_by_name(dev, "pclk", &clk); -+ if (ret) -+ return ret; -+ -+ ret = clk_enable(&clk); -+ if (ret) -+ return ret; -+ -+ /* Get LSI clock */ -+ ret = clk_get_by_name(dev, "lsi", &clk); -+ if (ret) -+ return ret; -+ -+ /* Prescaler fixed to 256 */ -+ reload = CONFIG_STM32MP_WATCHDOG_TIMEOUT_SECS * -+ clk_get_rate(&clk) / 256; -+ if (reload > RLR_MAX + 1) -+ /* Force to max watchdog counter reload value */ -+ reload = RLR_MAX + 1; -+ else if (!reload) -+ /* Force to min watchdog counter reload value */ -+ reload = clk_get_rate(&clk) / 256; -+ -+ /* Enable watchdog */ -+ writel(KR_KEY_ENABLE, regmap_base + IWDG_KR); -+ -+ /* Set prescaler & reload registers */ -+ writel(KR_KEY_EWA, regmap_base + IWDG_KR); -+ writel(PR_256, regmap_base + IWDG_PR); -+ writel(reload - 1, regmap_base + IWDG_RLR); -+ -+ /* Wait for the registers to be updated */ -+ time_start = get_timer(0); -+ while (readl(regmap_base + IWDG_SR)) { -+ if (get_timer(time_start) > CONFIG_SYS_HZ) { -+ pr_err("Updating IWDG registers timeout"); -+ return -ETIMEDOUT; -+ } -+ } -+ -+ debug("IWDG init done\n"); -+ -+ return 0; -+} -+ -+static const struct udevice_id stm32mp_wdt_match[] = { -+ { .compatible = "st,stm32mp1-iwdg", -+ .data = STM32MP_SYSCON_IWDG }, -+ { /* sentinel */ } -+}; -+ -+U_BOOT_DRIVER(stm32mp_wdt) = { -+ .name = "stm32mp-wdt", -+ .id = UCLASS_SYSCON, -+ .of_match = stm32mp_wdt_match, -+ .probe = stm32mp_wdt_probe, -+}; -diff --git a/include/adc.h b/include/adc.h -index d04c9c4..5841dfb 100644 ---- a/include/adc.h -+++ b/include/adc.h -@@ -219,6 +219,17 @@ int adc_channels_data(struct udevice *dev, unsigned int channel_mask, - int adc_data_mask(struct udevice *dev, unsigned int *data_mask); - - /** -+ * adc_channel_mask() - get channel mask for given ADC device -+ * -+ * This can be used if adc uclass platform data is filled. -+ * -+ * @dev: ADC device to check -+ * @channel_mask: pointer to the returned channel bitmask -+ * @return: 0 if OK, -ve on error -+ */ -+int adc_channel_mask(struct udevice *dev, unsigned int *channel_mask); -+ -+/** - * adc_channel_single_shot() - get output data of conversion for the ADC - * device's channel. This function searches for the device with the given name, - * starts the given channel conversion and returns the output data. -@@ -284,4 +295,14 @@ int adc_vss_value(struct udevice *dev, int *uV); - */ - int adc_stop(struct udevice *dev); - -+/** -+ * adc_raw_to_uV() - converts raw value to microvolts for given ADC device. -+ * -+ * @dev: ADC device used from conversion -+ * @raw: raw value to convert -+ * @uV: converted value in microvolts -+ * @return: 0 on success or -ve on error -+ */ -+int adc_raw_to_uV(struct udevice *dev, unsigned int raw, int *uV); -+ - #endif -diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h -index 701298c..b4beaa7 100644 ---- a/include/configs/stm32mp1.h -+++ b/include/configs/stm32mp1.h -@@ -10,17 +10,17 @@ - #include - #include - --#define CONFIG_PREBOOT -- - /* - * Number of clock ticks in 1 sec - */ - #define CONFIG_SYS_HZ 1000 - -+#ifndef CONFIG_STM32MP1_TRUSTED - /* PSCI support */ - #define CONFIG_ARMV7_PSCI_1_0 - #define CONFIG_ARMV7_SECURE_BASE STM32_SYSRAM_BASE - #define CONFIG_ARMV7_SECURE_MAX_SIZE STM32_SYSRAM_SIZE -+#endif - - /* - * malloc() pool size -@@ -33,6 +33,8 @@ - #define CONFIG_SYS_SDRAM_BASE STM32_DDR_BASE - #define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_TEXT_BASE - -+#define CONFIG_DISABLE_CONSOLE -+ - /* - * Console I/O buffer size - */ -@@ -53,6 +55,9 @@ - #define CONFIG_SETUP_MEMORY_TAGS - #define CONFIG_INITRD_TAG - -+/* Extend size of kernel image for uncompression */ -+#define CONFIG_SYS_BOOTM_LEN SZ_32M -+ - /* SPL support */ - #ifdef CONFIG_SPL - /* BOOTROM load address */ -@@ -69,36 +74,118 @@ - STM32_SYSRAM_SIZE) - #endif /* #ifdef CONFIG_SPL */ - -+#define CONFIG_SYS_MEMTEST_START STM32_DDR_BASE -+#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + SZ_64M) -+#define CONFIG_SYS_MEMTEST_SCRATCH (CONFIG_SYS_MEMTEST_END + 4) -+ - /*MMC SD*/ - #define CONFIG_SYS_MMC_MAX_DEVICE 3 - #define CONFIG_SUPPORT_EMMC_BOOT - --#if !defined(CONFIG_SPL) || !defined(CONFIG_SPL_BUILD) -+/*****************************************************************************/ -+#ifdef CONFIG_DISTRO_DEFAULTS -+/*****************************************************************************/ -+ -+/* NAND support */ -+#define CONFIG_SYS_NAND_ONFI_DETECTION -+#define CONFIG_SYS_MAX_NAND_DEVICE 1 -+ -+/* SPI nand */ -+#define CONFIG_SYS_MAX_NAND_DEVICE 1 -+ -+/* SPI FLASH support */ -+#if defined(CONFIG_SPL_BUILD) -+#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x80000 -+#endif - -+/* FILE SYSTEM */ -+ -+#if defined(CONFIG_STM32_QSPI) || defined(CONFIG_NAND_STM32_FMC2) -+/* Dynamic MTD partition support */ -+#define CONFIG_SYS_MTDPARTS_RUNTIME -+#endif -+ -+/* Ethernet need */ -+#ifdef CONFIG_DWC_ETH_QOS -+#define CONFIG_SYS_NONCACHED_MEMORY (1 * SZ_1M) /* 1M */ -+#define CONFIG_SERVERIP 192.168.1.1 -+#define CONFIG_BOOTP_SERVERIP -+#define CONFIG_SYS_AUTOLOAD "no" -+#endif -+ -+#ifdef CONFIG_DM_VIDEO -+#define CONFIG_VIDEO_BMP_RLE8 -+#define CONFIG_BMP_16BPP -+#define CONFIG_BMP_24BPP -+#define CONFIG_BMP_32BPP -+#endif -+ -+#if !defined(CONFIG_SPL_BUILD) -+ -+/* default order is eMMC (SDMMC 1)/ NAND / SDCARD (SDMMC 0) / SDMMC2 */ - #define BOOT_TARGET_DEVICES(func) \ - func(MMC, mmc, 1) \ -+ func(UBIFS, ubifs, 0) \ - func(MMC, mmc, 0) \ -- func(MMC, mmc, 2) -+ func(MMC, mmc, 2) \ -+ func(PXE, pxe, na) - - #include - --#define STM32MP_PREBOOT \ -+#define CONFIG_PREBOOT \ - "echo \"Boot over ${boot_device}${boot_instance}!\"; " \ -- "if test \"${boot_device}\" = \"mmc\"; then " \ -- "env set boot_targets \"mmc${boot_instance}\"; "\ -- "fi;" -+ "if test ${boot_device} = serial; then " \ -+ "stm32prog serial ${boot_instance}; " \ -+ "else if test ${boot_device} = usb; then " \ -+ "stm32prog usb ${boot_instance}; " \ -+ "else " \ -+ "if test ${boot_device} = mmc; then " \ -+ "env set boot_targets \"mmc${boot_instance}\"; "\ -+ "else if test ${boot_device} = nand; then " \ -+ "env set boot_targets \"ubifs0\"; "\ -+ "fi; fi; fi; fi;" -+ -+#ifdef CONFIG_STM32MP1_OPTEE -+#define CONFIG_SYS_MEM_TOP_HIDE SZ_32M -+/* with OPTEE: define specific MTD partitions = teeh, teed, teex */ -+#define STM32MP_MTDPARTS \ -+ "mtdparts_nor0=256k(fsbl1),256k(fsbl2),2m(ssbl),256k(logo),256k(teeh),256k(teed),256k(teex),-(nor_user)\0" \ -+ "mtdparts_nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),512k(teeh),512k(teed),512k(teex),-(UBI);\0" -+ -+#else /* CONFIG_STM32MP1_OPTEE */ -+ -+#define STM32MP_MTDPARTS \ -+ "mtdparts_nor0=256k(fsbl1),256k(fsbl2),2m(ssbl),256k(logo),-(nor_user)\0" \ -+ "mtdparts_nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),-(UBI)\0" -+ -+#endif /* CONFIG_STM32MP1_OPTEE */ - -+/* -+ * memory layout for 32M uncompressed/compressed kernel, -+ * 1M fdt, 1M script, 1M pxe and 1M for splashimage -+ * and the ramdisk at the end. -+ */ - #define CONFIG_EXTRA_ENV_SETTINGS \ -- "scriptaddr=0xC0000000\0" \ -- "pxefile_addr_r=0xC0000000\0" \ -- "kernel_addr_r=0xC1000000\0" \ -- "fdt_addr_r=0xC4000000\0" \ -- "ramdisk_addr_r=0xC4100000\0" \ -+ "stdin=serial\0" \ -+ "stdout=serial\0" \ -+ "stderr=serial\0" \ -+ "bootdelay=1\0" \ -+ "kernel_addr_r=0xc2000000\0" \ -+ "fdt_addr_r=0xc4000000\0" \ -+ "scriptaddr=0xc4100000\0" \ -+ "pxefile_addr_r=0xc4200000\0" \ -+ "splashimage=0xc4300000\0" \ -+ "ramdisk_addr_r=0xc4400000\0" \ - "fdt_high=0xffffffff\0" \ - "initrd_high=0xffffffff\0" \ -- "preboot=" STM32MP_PREBOOT "\0" \ -- BOOTENV -+ "bootlimit=0\0" \ -+ "altbootcmd=run bootcmd\0" \ -+ "usb_pgood_delay=2000\0" \ -+ STM32MP_MTDPARTS \ -+ BOOTENV \ -+ "boot_net_usb_start=true\0" - - #endif /* ifndef CONFIG_SPL_BUILD */ -+#endif /* ifdef CONFIG_DISTRO_DEFAULTS*/ - - #endif /* __CONFIG_H */ -diff --git a/include/dfu.h b/include/dfu.h -index fbe978a..36304c7 100644 ---- a/include/dfu.h -+++ b/include/dfu.h -@@ -22,6 +22,7 @@ enum dfu_device_type { - DFU_DEV_NAND, - DFU_DEV_RAM, - DFU_DEV_SF, -+ DFU_DEV_VIRT, - }; - - enum dfu_layout { -@@ -77,6 +78,12 @@ struct sf_internal_data { - /* RAW programming */ - u64 start; - u64 size; -+ /* for sf/ubi use */ -+ unsigned int ubi; -+}; -+ -+struct virt_internal_data { -+ int dev_num; - }; - - #define DFU_NAME_SIZE 32 -@@ -107,6 +114,7 @@ struct dfu_entity { - struct nand_internal_data nand; - struct ram_internal_data ram; - struct sf_internal_data sf; -+ struct virt_internal_data virt; - } data; - - int (*get_medium_size)(struct dfu_entity *dfu, u64 *size); -@@ -142,6 +150,8 @@ struct dfu_entity { - #ifdef CONFIG_SET_DFU_ALT_INFO - void set_dfu_alt_info(char *interface, char *devstr); - #endif -+int dfu_alt_init(int num, struct dfu_entity **dfu); -+int dfu_alt_add(struct dfu_entity *dfu, char *interface, char *devstr, char *s); - int dfu_config_entities(char *s, char *interface, char *devstr); - void dfu_free_entities(void); - void dfu_show_entities(void); -@@ -161,6 +171,9 @@ bool dfu_usb_get_reset(void); - int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num); - int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num); - int dfu_flush(struct dfu_entity *de, void *buf, int size, int blk_seq_num); -+void dfu_flush_callback(struct dfu_entity *dfu); -+void dfu_transaction_cleanup(struct dfu_entity *dfu); -+int dfu_transaction_initiate(struct dfu_entity *dfu, bool read); - - /* - * dfu_defer_flush - pointer to store dfu_entity for deferred flashing. -@@ -246,6 +259,22 @@ static inline int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, - } - #endif - -+#ifdef CONFIG_DFU_VIRT -+int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr, char *s); -+int dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset, -+ void *buf, long *len); -+int dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size); -+int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset, -+ void *buf, long *len); -+#else -+static inline int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr, -+ char *s) -+{ -+ puts("VIRT support not available!\n"); -+ return -1; -+} -+#endif -+ - /** - * dfu_tftp_write - Write TFTP data to DFU medium - * -diff --git a/include/dm/pinctrl.h b/include/dm/pinctrl.h -index 80de3f3..63a7d55 100644 ---- a/include/dm/pinctrl.h -+++ b/include/dm/pinctrl.h -@@ -6,6 +6,9 @@ - #ifndef __PINCTRL_H - #define __PINCTRL_H - -+#define PINNAME_SIZE 10 -+#define PINMUX_SIZE 40 -+ - /** - * struct pinconf_param - pin config parameters - * -@@ -66,6 +69,7 @@ struct pinconf_param { - * pointing a config node. (necessary for pinctrl_full) - * @set_state_simple: do needed pinctrl operations for a peripherl @periph. - * (necessary for pinctrl_simple) -+ * @get_pin_muxing: display the muxing of a given pin. - */ - struct pinctrl_ops { - int (*get_pins_count)(struct udevice *dev); -@@ -129,6 +133,24 @@ struct pinctrl_ops { - * @return mux value (SoC-specific, e.g. 0 for input, 1 for output) - */ - int (*get_gpio_mux)(struct udevice *dev, int banknum, int index); -+ -+ /** -+ * get_pin_muxing() - show pin muxing -+ * -+ * This allows to display the muxing of a given pin. It's useful for -+ * debug purpose to know if a pin is configured as GPIO or as an -+ * alternate function and which one. -+ * Typically it is used by a PINCTRL driver with knowledge of the SoC -+ * pinctrl setup. -+ * -+ * @dev: Pinctrl device to use -+ * @selector: Pin selector -+ * @buf Pin's muxing description -+ * @size Pin's muxing description length -+ * return 0 if OK, -ve on error -+ */ -+ int (*get_pin_muxing)(struct udevice *dev, unsigned int selector, -+ char *buf, int size); - }; - - #define pinctrl_get_ops(dev) ((struct pinctrl_ops *)(dev)->driver->ops) -@@ -348,4 +370,41 @@ int pinctrl_decode_pin_config(const void *blob, int node); - */ - int pinctrl_get_gpio_mux(struct udevice *dev, int banknum, int index); - -+/** -+ * pinctrl_get_pin_muxing() - Returns the muxing description -+ * -+ * This allows to display the muxing description of the given pin for -+ * debug purpose -+ * -+ * @dev: Pinctrl device to use -+ * @selector Pin index within pin-controller -+ * @buf Pin's muxing description -+ * @size Pin's muxing description length -+ * @return 0 if OK, -ve on error -+ */ -+int pinctrl_get_pin_muxing(struct udevice *dev, int selector, char *buf, -+ int size); -+ -+/** -+ * pinctrl_get_pins_count() - display pin-controller pins number -+ * -+ * This allows to know the number of pins owned by a given pin-controller -+ * -+ * @dev: Pinctrl device to use -+ * @return pins number if OK, -ve on error -+ */ -+int pinctrl_get_pins_count(struct udevice *dev); -+ -+/** -+ * pinctrl_get_pin_name() - Returns the pin's name -+ * -+ * This allows to display the pin's name for debug purpose -+ * -+ * @dev: Pinctrl device to use -+ * @selector Pin index within pin-controller -+ * @buf Pin's name -+ * @return 0 if OK, -ve on error -+ */ -+int pinctrl_get_pin_name(struct udevice *dev, int selector, char *buf, -+ int size); - #endif /* __PINCTRL_H */ -diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h -index 269a2c6..6193017 100644 ---- a/include/dm/uclass-id.h -+++ b/include/dm/uclass-id.h -@@ -40,6 +40,7 @@ enum uclass_id { - UCLASS_ETH, /* Ethernet device */ - UCLASS_FS_FIRMWARE_LOADER, /* Generic loader */ - UCLASS_GPIO, /* Bank of general-purpose I/O pins */ -+ UCLASS_HWSPINLOCK, /* Hardware semaphores */ - UCLASS_FIRMWARE, /* Firmware */ - UCLASS_I2C, /* I2C bus */ - UCLASS_I2C_EEPROM, /* I2C EEPROM device */ -diff --git a/include/dm/uclass.h b/include/dm/uclass.h -index eebf2d5..11e6df3 100644 ---- a/include/dm/uclass.h -+++ b/include/dm/uclass.h -@@ -306,6 +306,18 @@ int uclass_first_device_err(enum uclass_id id, struct udevice **devp); - int uclass_next_device(struct udevice **devp); - - /** -+ * uclass_next_device_err() - Get the next device in a uclass -+ * -+ * The device returned is probed if necessary, and ready for use -+ * -+ * @devp: On entry, pointer to device to lookup. On exit, returns pointer -+ * to the next device in the uclass if no error occurred, or -ENODEV if -+ * there is no next device. -+ * @return 0 if found, -ENODEV if not found, other -ve on error -+ */ -+int uclass_next_device_err(struct udevice **devp); -+ -+/** - * uclass_first_device_check() - Get the first device in a uclass - * - * The device returned is probed if necessary, and ready for use -@@ -379,4 +391,20 @@ int uclass_resolve_seq(struct udevice *dev); - #define uclass_foreach_dev_safe(pos, next, uc) \ - list_for_each_entry_safe(pos, next, &uc->dev_head, uclass_node) - -+/** -+ * uclass_foreach_dev_probe() - Helper function to iteration through devices -+ * of given uclass -+ * -+ * This creates a for() loop which works through the available devices in -+ * a uclass in order from start to end. Devices are probed if necessary, -+ * and ready for use. -+ * -+ * @id: Uclass ID -+ * @dev: struct udevice * to hold the current device. Set to NULL when there -+ * are no more devices. -+ */ -+#define uclass_foreach_dev_probe(id, dev) \ -+ for (int _ret = uclass_first_device_err(id, &dev); !_ret && dev; \ -+ _ret = uclass_next_device_err(&dev)) -+ - #endif -diff --git a/include/dw_mipi_dsi.h b/include/dw_mipi_dsi.h -new file mode 100644 -index 0000000..ebf4713 ---- /dev/null -+++ b/include/dw_mipi_dsi.h -@@ -0,0 +1,32 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ -+/* -+ * Copyright (C) 2017-2018, STMicroelectronics - All Rights Reserved -+ * -+ * Authors: Yannick Fertre -+ * Philippe Cornu -+ * -+ * This generic Synopsys DesignWare MIPI DSI host include is based on -+ * the Linux Kernel include from include/drm/bridge/dw_mipi_dsi.h. -+ */ -+ -+#ifndef __DW_MIPI_DSI__ -+#define __DW_MIPI_DSI__ -+ -+#include -+ -+struct dw_mipi_dsi_phy_ops { -+ int (*init)(void *priv_data); -+ int (*get_lane_mbps)(void *priv_data, struct display_timing *timings, -+ u32 lanes, u32 format, unsigned int *lane_mbps); -+}; -+ -+struct dw_mipi_dsi_plat_data { -+ unsigned int max_data_lanes; -+ const struct dw_mipi_dsi_phy_ops *phy_ops; -+ struct udevice *panel; -+}; -+ -+int dw_mipi_dsi_init_bridge(struct mipi_dsi_device *device); -+void dw_mipi_dsi_bridge_enable(struct mipi_dsi_device *device); -+ -+#endif /* __DW_MIPI_DSI__ */ -diff --git a/include/g_dnl.h b/include/g_dnl.h -index 6d461c7..836ee60 100644 ---- a/include/g_dnl.h -+++ b/include/g_dnl.h -@@ -38,6 +38,7 @@ int g_dnl_board_usb_cable_connected(void); - int g_dnl_register(const char *s); - void g_dnl_unregister(void); - void g_dnl_set_serialnumber(char *); -+void g_dnl_set_product(const char *s); - - bool g_dnl_detach(void); - void g_dnl_trigger_detach(void); -diff --git a/include/hwspinlock.h b/include/hwspinlock.h -new file mode 100644 -index 0000000..99389c1 ---- /dev/null -+++ b/include/hwspinlock.h -@@ -0,0 +1,140 @@ -+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#ifndef _HWSPINLOCK_H_ -+#define _HWSPINLOCK_H_ -+ -+/** -+ * Implement a hwspinlock uclass. -+ * Hardware spinlocks are used to perform hardware protection of -+ * critical sections and synchronisation between multiprocessors. -+ */ -+ -+struct udevice; -+ -+/** -+ * struct hwspinlock - A handle to (allowing control of) a single hardware -+ * spinlock. -+ * -+ * @dev: The device which implements the hardware spinlock. -+ * @id: The hardware spinlock ID within the provider. -+ */ -+struct hwspinlock { -+ struct udevice *dev; -+ unsigned long id; -+}; -+ -+#if CONFIG_IS_ENABLED(DM_HWSPINLOCK) -+ -+/** -+ * hwspinlock_get_by_index - Get a hardware spinlock by integer index -+ * -+ * This looks up and request a hardware spinlock. The index is relative to the -+ * client device; each device is assumed to have n hardware spinlock associated -+ * with it somehow, and this function finds and requests one of them. -+ * -+ * @dev: The client device. -+ * @index: The index of the hardware spinlock to request, within the -+ * client's list of hardware spinlock. -+ * @hws: A pointer to a hardware spinlock struct to initialize. -+ * @return 0 if OK, or a negative error code. -+ */ -+int hwspinlock_get_by_index(struct udevice *dev, -+ int index, struct hwspinlock *hws); -+ -+/** -+ * Lock the hardware spinlock -+ * -+ * @hws: A hardware spinlock struct that previously requested by -+ * hwspinlock_get_by_index -+ * @timeout: Timeout value in msecs -+ * @return: 0 if OK, -ETIMEDOUT if timeout, -ve on other errors -+ */ -+int hwspinlock_lock_timeout(struct hwspinlock *hws, unsigned int timeout); -+ -+/** -+ * Unlock the hardware spinlock -+ * -+ * @hws: A hardware spinlock struct that previously requested by -+ * hwspinlock_get_by_index -+ * @return: 0 if OK, -ve on error -+ */ -+int hwspinlock_unlock(struct hwspinlock *hws); -+ -+#else -+ -+static inline int hwspinlock_get_by_index(struct udevice *dev, -+ int index, -+ struct hwspinlock *hws) -+{ -+ return -ENOSYS; -+} -+ -+static inline int hwspinlock_lock_timeout(struct hwspinlock *hws, -+ int timeout) -+{ -+ return -ENOSYS; -+} -+ -+static inline int hwspinlock_unlock(struct hwspinlock *hws) -+{ -+ return -ENOSYS; -+} -+ -+#endif /* CONFIG_DM_HWSPINLOCK */ -+ -+struct ofnode_phandle_args; -+ -+/** -+ * struct hwspinlock_ops - Driver model hwspinlock operations -+ * -+ * The uclass interface is implemented by all hwspinlock devices which use -+ * driver model. -+ */ -+struct hwspinlock_ops { -+ /** -+ * of_xlate - Translate a client's device-tree (OF) hardware specifier. -+ * -+ * The hardware core calls this function as the first step in -+ * implementing a client's hwspinlock_get_by_*() call. -+ * -+ * @hws: The hardware spinlock struct to hold the translation -+ * result. -+ * @args: The hardware spinlock specifier values from device tree. -+ * @return 0 if OK, or a negative error code. -+ */ -+ int (*of_xlate)(struct hwspinlock *hws, -+ struct ofnode_phandle_args *args); -+ -+ /** -+ * Lock the hardware spinlock -+ * -+ * @dev: hwspinlock Device -+ * @index: index of the lock to be used -+ * @return 0 if OK, -ve on error -+ */ -+ int (*lock)(struct udevice *dev, int index); -+ -+ /** -+ * Unlock the hardware spinlock -+ * -+ * @dev: hwspinlock Device -+ * @index: index of the lock to be unlocked -+ * @return 0 if OK, -ve on error -+ */ -+ int (*unlock)(struct udevice *dev, int index); -+ -+ /** -+ * Relax - optional -+ * Platform-specific relax method, called by hwspinlock core -+ * while spinning on a lock, between two successive call to -+ * lock -+ * -+ * @dev: hwspinlock Device -+ */ -+ void (*relax)(struct udevice *dev); -+}; -+ -+#endif /* _HWSPINLOCK_H_ */ -diff --git a/include/image.h b/include/image.h -index 031c355..610da44 100644 ---- a/include/image.h -+++ b/include/image.h -@@ -278,6 +278,7 @@ enum { - IH_TYPE_PMMC, /* TI Power Management Micro-Controller Firmware */ - IH_TYPE_STM32IMAGE, /* STMicroelectronics STM32 Image */ - IH_TYPE_SOCFPGAIMAGE_V1, /* Altera SOCFPGA A10 Preloader */ -+ IH_TYPE_STM32COPRO, /* STMicroelectronics STM32 Coprocessor Image */ - - IH_TYPE_COUNT, /* Number of image types */ - }; -diff --git a/include/mipi_display.h b/include/mipi_display.h -index ddcc8ca..5c3dbbe 100644 ---- a/include/mipi_display.h -+++ b/include/mipi_display.h -@@ -4,12 +4,16 @@ - * - * Copyright (C) 2010 Guennadi Liakhovetski - * Copyright (C) 2006 Nokia Corporation -- * Author: Imre Deak -+ * Copyright (C) 2018 STMicroelectronics - All Rights Reserved -+ * Author(s): Imre Deak -+ * Yannick Fertre -+ * Philippe Cornu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -+ - #ifndef MIPI_DISPLAY_H - #define MIPI_DISPLAY_H - -@@ -115,6 +119,14 @@ enum { - MIPI_DCS_READ_MEMORY_CONTINUE = 0x3E, - MIPI_DCS_SET_TEAR_SCANLINE = 0x44, - MIPI_DCS_GET_SCANLINE = 0x45, -+ MIPI_DCS_SET_DISPLAY_BRIGHTNESS = 0x51, /* MIPI DCS 1.3 */ -+ MIPI_DCS_GET_DISPLAY_BRIGHTNESS = 0x52, /* MIPI DCS 1.3 */ -+ MIPI_DCS_WRITE_CONTROL_DISPLAY = 0x53, /* MIPI DCS 1.3 */ -+ MIPI_DCS_GET_CONTROL_DISPLAY = 0x54, /* MIPI DCS 1.3 */ -+ MIPI_DCS_WRITE_POWER_SAVE = 0x55, /* MIPI DCS 1.3 */ -+ MIPI_DCS_GET_POWER_SAVE = 0x56, /* MIPI DCS 1.3 */ -+ MIPI_DCS_SET_CABC_MIN_BRIGHTNESS = 0x5E, /* MIPI DCS 1.3 */ -+ MIPI_DCS_GET_CABC_MIN_BRIGHTNESS = 0x5F, /* MIPI DCS 1.3 */ - MIPI_DCS_READ_DDB_START = 0xA1, - MIPI_DCS_READ_DDB_CONTINUE = 0xA8, - }; -@@ -127,4 +139,247 @@ enum { - #define MIPI_DCS_PIXEL_FMT_8BIT 2 - #define MIPI_DCS_PIXEL_FMT_3BIT 1 - -+struct mipi_dsi_host; -+struct mipi_dsi_device; -+ -+/* request ACK from peripheral */ -+#define MIPI_DSI_MSG_REQ_ACK BIT(0) -+/* use Low Power Mode to transmit message */ -+#define MIPI_DSI_MSG_USE_LPM BIT(1) -+ -+/** -+ * struct mipi_dsi_msg - read/write DSI buffer -+ * @channel: virtual channel id -+ * @type: payload data type -+ * @flags: flags controlling this message transmission -+ * @tx_len: length of @tx_buf -+ * @tx_buf: data to be written -+ * @rx_len: length of @rx_buf -+ * @rx_buf: data to be read, or NULL -+ */ -+struct mipi_dsi_msg { -+ u8 channel; -+ u8 type; -+ u16 flags; -+ -+ size_t tx_len; -+ const void *tx_buf; -+ -+ size_t rx_len; -+ void *rx_buf; -+}; -+ -+bool mipi_dsi_packet_format_is_short(u8 type); -+bool mipi_dsi_packet_format_is_long(u8 type); -+ -+/** -+ * struct mipi_dsi_packet - represents a MIPI DSI packet in protocol format -+ * @size: size (in bytes) of the packet -+ * @header: the four bytes that make up the header (Data ID, Word Count or -+ * Packet Data, and ECC) -+ * @payload_length: number of bytes in the payload -+ * @payload: a pointer to a buffer containing the payload, if any -+ */ -+struct mipi_dsi_packet { -+ size_t size; -+ u8 header[4]; -+ size_t payload_length; -+ const u8 *payload; -+}; -+ -+int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, -+ const struct mipi_dsi_msg *msg); -+ -+/** -+ * struct mipi_dsi_host_ops - DSI bus operations -+ * @attach: attach DSI device to DSI host -+ * @detach: detach DSI device from DSI host -+ * @transfer: transmit a DSI packet -+ * -+ * DSI packets transmitted by .transfer() are passed in as mipi_dsi_msg -+ * structures. This structure contains information about the type of packet -+ * being transmitted as well as the transmit and receive buffers. When an -+ * error is encountered during transmission, this function will return a -+ * negative error code. On success it shall return the number of bytes -+ * transmitted for write packets or the number of bytes received for read -+ * packets. -+ * -+ * Note that typically DSI packet transmission is atomic, so the .transfer() -+ * function will seldomly return anything other than the number of bytes -+ * contained in the transmit buffer on success. -+ */ -+struct mipi_dsi_host_ops { -+ int (*attach)(struct mipi_dsi_host *host, -+ struct mipi_dsi_device *dsi); -+ int (*detach)(struct mipi_dsi_host *host, -+ struct mipi_dsi_device *dsi); -+ ssize_t (*transfer)(struct mipi_dsi_host *host, -+ const struct mipi_dsi_msg *msg); -+}; -+ -+/** -+ * struct mipi_dsi_host - DSI host device -+ * @dev: driver model device node for this DSI host -+ * @ops: DSI host operations -+ * @list: list management -+ */ -+struct mipi_dsi_host { -+ struct device *dev; -+ const struct mipi_dsi_host_ops *ops; -+ struct list_head list; -+}; -+ -+/* DSI mode flags */ -+ -+/* video mode */ -+#define MIPI_DSI_MODE_VIDEO BIT(0) -+/* video burst mode */ -+#define MIPI_DSI_MODE_VIDEO_BURST BIT(1) -+/* video pulse mode */ -+#define MIPI_DSI_MODE_VIDEO_SYNC_PULSE BIT(2) -+/* enable auto vertical count mode */ -+#define MIPI_DSI_MODE_VIDEO_AUTO_VERT BIT(3) -+/* enable hsync-end packets in vsync-pulse and v-porch area */ -+#define MIPI_DSI_MODE_VIDEO_HSE BIT(4) -+/* disable hfront-porch area */ -+#define MIPI_DSI_MODE_VIDEO_HFP BIT(5) -+/* disable hback-porch area */ -+#define MIPI_DSI_MODE_VIDEO_HBP BIT(6) -+/* disable hsync-active area */ -+#define MIPI_DSI_MODE_VIDEO_HSA BIT(7) -+/* flush display FIFO on vsync pulse */ -+#define MIPI_DSI_MODE_VSYNC_FLUSH BIT(8) -+/* disable EoT packets in HS mode */ -+#define MIPI_DSI_MODE_EOT_PACKET BIT(9) -+/* device supports non-continuous clock behavior (DSI spec 5.6.1) */ -+#define MIPI_DSI_CLOCK_NON_CONTINUOUS BIT(10) -+/* transmit data in low power */ -+#define MIPI_DSI_MODE_LPM BIT(11) -+ -+enum mipi_dsi_pixel_format { -+ MIPI_DSI_FMT_RGB888, -+ MIPI_DSI_FMT_RGB666, -+ MIPI_DSI_FMT_RGB666_PACKED, -+ MIPI_DSI_FMT_RGB565, -+}; -+ -+#define DSI_DEV_NAME_SIZE 20 -+ -+/** -+ * struct mipi_dsi_device_info - template for creating a mipi_dsi_device -+ * @type: DSI peripheral chip type -+ * @channel: DSI virtual channel assigned to peripheral -+ * @node: pointer to OF device node or NULL -+ * -+ * This is populated and passed to mipi_dsi_device_new to create a new -+ * DSI device -+ */ -+struct mipi_dsi_device_info { -+ char type[DSI_DEV_NAME_SIZE]; -+ u32 channel; -+ struct device_node *node; -+}; -+ -+/** -+ * struct mipi_dsi_device - DSI peripheral device -+ * @host: DSI host for this peripheral -+ * @dev: driver model device node for this peripheral -+ * @name: DSI peripheral chip type -+ * @channel: virtual channel assigned to the peripheral -+ * @format: pixel format for video mode -+ * @lanes: number of active data lanes -+ * @mode_flags: DSI operation mode related flags -+ */ -+struct mipi_dsi_device { -+ struct mipi_dsi_host *host; -+ struct udevice *dev; -+ -+ char name[DSI_DEV_NAME_SIZE]; -+ unsigned int channel; -+ unsigned int lanes; -+ enum mipi_dsi_pixel_format format; -+ unsigned long mode_flags; -+}; -+ -+/** -+ * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode -+ * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking -+ * information only -+ * @MIPI_DSI_DCS_TEAR_MODE_VHBLANK : the TE output line consists of both -+ * V-Blanking and H-Blanking information -+ */ -+enum mipi_dsi_dcs_tear_mode { -+ MIPI_DSI_DCS_TEAR_MODE_VBLANK, -+ MIPI_DSI_DCS_TEAR_MODE_VHBLANK, -+}; -+ -+/** -+ * struct mipi_dsi_panel_plat - DSI panel platform data -+ * @device: DSI peripheral device -+ */ -+struct mipi_dsi_panel_plat { -+ struct mipi_dsi_device *device; -+}; -+ -+int mipi_dsi_attach(struct mipi_dsi_device *dsi); -+int mipi_dsi_detach(struct mipi_dsi_device *dsi); -+int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt); -+ -+/* bit compatible with the xrandr RR_ definitions (bits 0-13) -+ * -+ * ABI warning: Existing userspace really expects -+ * the mode flags to match the xrandr definitions. Any -+ * changes that don't match the xrandr definitions will -+ * likely need a new client cap or some other mechanism -+ * to avoid breaking existing userspace. This includes -+ * allocating new flags in the previously unused bits! -+ */ -+#define MIPI_DSI_FLAG_PHSYNC BIT(0) -+#define MIPI_DSI_FLAG_NHSYNC BIT(1) -+#define MIPI_DSI_FLAG_PVSYNC BIT(2) -+#define MIPI_DSI_FLAG_NVSYNC BIT(3) -+#define MIPI_DSI_FLAG_INTERLACE BIT(4) -+#define MIPI_DSI_FLAG_DBLSCAN BIT(5) -+#define MIPI_DSI_FLAG_CSYNC BIT(6) -+#define MIPI_DSI_FLAG_PCSYNC BIT(7) -+#define MIPI_DSI_FLAG_NCSYNC BIT(8) -+#define MIPI_DSI_FLAG_HSKEW BIT(9) /* hskew provided */ -+#define MIPI_DSI_FLAG_BCAST BIT(10) -+#define MIPI_DSI_FLAG_PIXMUX BIT(11) -+#define MIPI_DSI_FLAG_DBLCLK BIT(12) -+#define MIPI_DSI_FLAG_CLKDIV2 BIT(13) -+ -+/* request ACK from peripheral */ -+#define MIPI_DSI_MSG_REQ_ACK BIT(0) -+/* use Low Power Mode to transmit message */ -+#define MIPI_DSI_MSG_USE_LPM BIT(1) -+ -+ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, -+ const void *data, size_t len); -+ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, -+ const void *data, size_t len); -+ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, -+ size_t len); -+int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi); -+int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi); -+int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode); -+int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format); -+int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi); -+int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi); -+int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi); -+int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi); -+int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, -+ u16 end); -+int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, -+ u16 end); -+int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi); -+int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, -+ enum mipi_dsi_dcs_tear_mode mode); -+int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format); -+int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline); -+int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, -+ u16 brightness); -+int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, -+ u16 *brightness); -+ - #endif -diff --git a/include/power/stpmic1.h b/include/power/stpmic1.h -new file mode 100644 -index 0000000..d90a1a9 ---- /dev/null -+++ b/include/power/stpmic1.h -@@ -0,0 +1,118 @@ -+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#ifndef __PMIC_STPMIC1_H_ -+#define __PMIC_STPMIC1_H_ -+ -+#define STPMIC1_MAIN_CR 0x10 -+#define STPMIC1_BUCKS_MRST_CR 0x18 -+#define STPMIC1_LDOS_MRST_CR 0x1a -+#define STPMIC1_BUCKX_MAIN_CR(buck) (0x20 + (buck)) -+#define STPMIC1_REFDDR_MAIN_CR 0x24 -+#define STPMIC1_LDOX_MAIN_CR(ldo) (0x25 + (ldo)) -+#define STPMIC1_BST_SW_CR 0x40 -+#define STPMIC1_NVM_SR 0xb8 -+#define STPMIC1_NVM_CR 0xb9 -+ -+/* Main PMIC Control Register (MAIN_CR) */ -+#define STPMIC1_SWOFF BIT(0) -+#define STPMIC1_RREQ_EN BIT(1) -+ -+/* BUCKS_MRST_CR */ -+#define STPMIC1_MRST_BUCK(buck) BIT(buck) -+#define STPMIC1_MRST_BUCK_DEBUG (STPMIC1_MRST_BUCK(STPMIC1_BUCK1) | \ -+ STPMIC1_MRST_BUCK(STPMIC1_BUCK3)) -+ -+/* LDOS_MRST_CR */ -+#define STPMIC1_MRST_LDO(ldo) BIT(ldo) -+#define STPMIC1_MRST_LDO_DEBUG 0 -+ -+/* BUCKx_MAIN_CR (x=1...4) */ -+#define STPMIC1_BUCK_ENA BIT(0) -+#define STPMIC1_BUCK_PREG_MODE BIT(1) -+#define STPMIC1_BUCK_VOUT_MASK GENMASK(7, 2) -+#define STPMIC1_BUCK_VOUT_SHIFT 2 -+#define STPMIC1_BUCK_VOUT(sel) (sel << STPMIC1_BUCK_VOUT_SHIFT) -+ -+#define STPMIC1_BUCK2_1200000V STPMIC1_BUCK_VOUT(24) -+#define STPMIC1_BUCK2_1350000V STPMIC1_BUCK_VOUT(30) -+ -+#define STPMIC1_BUCK3_1800000V STPMIC1_BUCK_VOUT(39) -+ -+/* REFDDR_MAIN_CR */ -+#define STPMIC1_VREF_ENA BIT(0) -+ -+/* LDOX_MAIN_CR */ -+#define STPMIC1_LDO_ENA BIT(0) -+#define STPMIC1_LDO12356_VOUT_MASK GENMASK(6, 2) -+#define STPMIC1_LDO12356_VOUT_SHIFT 2 -+#define STPMIC1_LDO_VOUT(sel) (sel << STPMIC1_LDO12356_VOUT_SHIFT) -+ -+#define STPMIC1_LDO3_MODE BIT(7) -+#define STPMIC1_LDO3_DDR_SEL 31 -+#define STPMIC1_LDO3_1800000 STPMIC1_LDO_VOUT(9) -+ -+#define STPMIC1_LDO4_UV 3300000 -+ -+/* BST_SW_CR */ -+#define STPMIC1_BST_ON BIT(0) -+#define STPMIC1_VBUSOTG_ON BIT(1) -+#define STPMIC1_SWOUT_ON BIT(2) -+#define STPMIC1_PWR_SW_ON (STPMIC1_VBUSOTG_ON | STPMIC1_SWOUT_ON) -+ -+/* NVM_SR */ -+#define STPMIC1_NVM_BUSY BIT(0) -+ -+/* NVM_CR */ -+#define STPMIC1_NVM_CMD_PROGRAM 1 -+#define STPMIC1_NVM_CMD_READ 2 -+ -+/* Timeout */ -+#define STPMIC1_DEFAULT_START_UP_DELAY_MS 1 -+#define STPMIC1_DEFAULT_STOP_DELAY_MS 5 -+#define STPMIC1_USB_BOOST_START_UP_DELAY_MS 10 -+ -+enum { -+ STPMIC1_BUCK1, -+ STPMIC1_BUCK2, -+ STPMIC1_BUCK3, -+ STPMIC1_BUCK4, -+ STPMIC1_MAX_BUCK, -+}; -+ -+enum { -+ STPMIC1_PREG_MODE_HP, -+ STPMIC1_PREG_MODE_LP, -+}; -+ -+enum { -+ STPMIC1_LDO1, -+ STPMIC1_LDO2, -+ STPMIC1_LDO3, -+ STPMIC1_LDO4, -+ STPMIC1_LDO5, -+ STPMIC1_LDO6, -+ STPMIC1_MAX_LDO, -+}; -+ -+enum { -+ STPMIC1_LDO_MODE_NORMAL, -+ STPMIC1_LDO_MODE_BYPASS, -+ STPMIC1_LDO_MODE_SINK_SOURCE, -+}; -+ -+enum { -+ STPMIC1_PWR_SW1, -+ STPMIC1_PWR_SW2, -+ STPMIC1_MAX_PWR_SW, -+}; -+ -+int stpmic1_shadow_read_byte(u8 addr, u8 *buf); -+int stpmic1_shadow_write_byte(u8 addr, u8 *buf); -+int stpmic1_nvm_read_byte(u8 addr, u8 *buf); -+int stpmic1_nvm_write_byte(u8 addr, u8 *buf); -+int stpmic1_nvm_read_all(u8 *buf, int buf_len); -+int stpmic1_nvm_write_all(u8 *buf, int buf_len); -+#endif -diff --git a/include/power/stpmu1.h b/include/power/stpmu1.h -deleted file mode 100644 -index 5906fbf..0000000 ---- a/include/power/stpmu1.h -+++ /dev/null -@@ -1,85 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ --/* -- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -- */ -- --#ifndef __PMIC_STPMU1_H_ --#define __PMIC_STPMU1_H_ -- --#define STPMU1_MASK_RESET_BUCK 0x18 --#define STPMU1_BUCKX_CTRL_REG(buck) (0x20 + (buck)) --#define STPMU1_VREF_CTRL_REG 0x24 --#define STPMU1_LDOX_CTRL_REG(ldo) (0x25 + (ldo)) --#define STPMU1_USB_CTRL_REG 0x40 --#define STPMU1_NVM_USER_STATUS_REG 0xb8 --#define STPMU1_NVM_USER_CONTROL_REG 0xb9 -- --#define STPMU1_MASK_RESET_BUCK3 BIT(2) -- --#define STPMU1_BUCK_EN BIT(0) --#define STPMU1_BUCK_MODE BIT(1) --#define STPMU1_BUCK_OUTPUT_MASK GENMASK(7, 2) --#define STPMU1_BUCK_OUTPUT_SHIFT 2 --#define STPMU1_BUCK2_1200000V (24 << STPMU1_BUCK_OUTPUT_SHIFT) --#define STPMU1_BUCK2_1350000V (30 << STPMU1_BUCK_OUTPUT_SHIFT) --#define STPMU1_BUCK3_1800000V (39 << STPMU1_BUCK_OUTPUT_SHIFT) -- --#define STPMU1_VREF_EN BIT(0) -- --#define STPMU1_LDO_EN BIT(0) --#define STPMU1_LDO12356_OUTPUT_MASK GENMASK(6, 2) --#define STPMU1_LDO12356_OUTPUT_SHIFT 2 --#define STPMU1_LDO3_MODE BIT(7) --#define STPMU1_LDO3_DDR_SEL 31 --#define STPMU1_LDO3_1800000 (9 << STPMU1_LDO12356_OUTPUT_SHIFT) --#define STPMU1_LDO4_UV 3300000 -- --#define STPMU1_USB_BOOST_EN BIT(0) --#define STPMU1_USB_PWR_SW_EN GENMASK(2, 1) -- --#define STPMU1_NVM_USER_CONTROL_PROGRAM BIT(0) --#define STPMU1_NVM_USER_CONTROL_READ BIT(1) -- --#define STPMU1_NVM_USER_STATUS_BUSY BIT(0) --#define STPMU1_NVM_USER_STATUS_ERROR BIT(1) -- --#define STPMU1_DEFAULT_START_UP_DELAY_MS 1 --#define STPMU1_DEFAULT_STOP_DELAY_MS 5 --#define STPMU1_USB_BOOST_START_UP_DELAY_MS 10 -- --enum { -- STPMU1_BUCK1, -- STPMU1_BUCK2, -- STPMU1_BUCK3, -- STPMU1_BUCK4, -- STPMU1_MAX_BUCK, --}; -- --enum { -- STPMU1_BUCK_MODE_HP, -- STPMU1_BUCK_MODE_LP, --}; -- --enum { -- STPMU1_LDO1, -- STPMU1_LDO2, -- STPMU1_LDO3, -- STPMU1_LDO4, -- STPMU1_LDO5, -- STPMU1_LDO6, -- STPMU1_MAX_LDO, --}; -- --enum { -- STPMU1_LDO_MODE_NORMAL, -- STPMU1_LDO_MODE_BYPASS, -- STPMU1_LDO_MODE_SINK_SOURCE, --}; -- --enum { -- STPMU1_PWR_SW1, -- STPMU1_PWR_SW2, -- STPMU1_MAX_PWR_SW, --}; -- --#endif -diff --git a/include/remoteproc.h b/include/remoteproc.h -index a59dba8..fa82531 100644 ---- a/include/remoteproc.h -+++ b/include/remoteproc.h -@@ -63,6 +63,8 @@ struct dm_rproc_uclass_pdata { - * Return 0 on success, 1 if not running, -ve on others errors - * @ping: Ping the remote device for basic communication check(optional) - * Return 0 on success, 1 if not responding, -ve on other errors -+ * @da_to_pa: Return translated physical address (device address different -+ * from physical address) - */ - struct dm_rproc_ops { - int (*init)(struct udevice *dev); -@@ -72,6 +74,7 @@ struct dm_rproc_ops { - int (*reset)(struct udevice *dev); - int (*is_running)(struct udevice *dev); - int (*ping)(struct udevice *dev); -+ ulong (*da_to_pa)(struct udevice *dev, ulong da); - }; - - /* Accessor */ -@@ -101,7 +104,7 @@ int rproc_dev_init(int id); - bool rproc_is_initialized(void); - - /** -- * rproc_load() - load binary to a remote processor -+ * rproc_load() - load binary or elf to a remote processor - * @id: id of the remote processor - * @addr: address in memory where the binary image is located - * @size: size of the binary image -@@ -111,6 +114,19 @@ bool rproc_is_initialized(void); - int rproc_load(int id, ulong addr, ulong size); - - /** -+ * rproc_get_rsc_table() - get resource table address from elf image -+ * @id: id of the remote processor -+ * @addr: address in memory where the image is located -+ * @size: size of the image -+ * @rsc_addr: resource table address (device address) -+ * @rsc_size: resource table size -+ * -+ * Return: 0 if all ok, else appropriate error value. -+ */ -+int rproc_load_rsc_table(int id, ulong addr, ulong size, ulong *rsc_addr, -+ unsigned int *rsc_size); -+ -+/** - * rproc_start() - Start a remote processor - * @id: id of the remote processor - * -@@ -166,6 +182,8 @@ static inline int rproc_stop(int id) { return -ENOSYS; } - static inline int rproc_reset(int id) { return -ENOSYS; } - static inline int rproc_ping(int id) { return -ENOSYS; } - static inline int rproc_is_running(int id) { return -ENOSYS; } -+static int rproc_load_rsc_table(int id, ulong addr, ulong size, ulong *rsc_addr, -+ unsigned int *rsc_size) { return -ENOSYS; } - #endif - - #endif /* _RPROC_H_ */ -diff --git a/include/syscon.h b/include/syscon.h -index 2aa73e5..1b99751 100644 ---- a/include/syscon.h -+++ b/include/syscon.h -@@ -89,4 +89,13 @@ void *syscon_get_first_range(ulong driver_data); - */ - struct regmap *syscon_node_to_regmap(ofnode node); - -+/** -+ * syscon_phandle_to_regmap - get regmap from syscon phandle -+ * -+ * @parent: Parent device containing the phandle pointer -+ * @name: Name of property in the parent device node -+ */ -+struct regmap *syscon_phandle_to_regmap(struct udevice *parent, -+ const char *name); -+ - #endif -diff --git a/include/usb/dwc2_udc.h b/include/usb/dwc2_udc.h -index 62e3236..3bd05fa 100644 ---- a/include/usb/dwc2_udc.h -+++ b/include/usb/dwc2_udc.h -@@ -19,6 +19,7 @@ struct dwc2_plat_otg_data { - unsigned int usb_phy_ctrl; - unsigned int usb_flags; - unsigned int usb_gusbcfg; -+ unsigned int usb_gotgctl; - unsigned int rx_fifo_sz; - unsigned int np_tx_fifo_sz; - unsigned int tx_fifo_sz; -diff --git a/test/dm/Makefile b/test/dm/Makefile -index b490cf2..9b3b0bf 100644 ---- a/test/dm/Makefile -+++ b/test/dm/Makefile -@@ -19,6 +19,7 @@ obj-$(CONFIG_CLK) += clk.o - obj-$(CONFIG_DM_ETH) += eth.o - obj-$(CONFIG_FIRMWARE) += firmware.o - obj-$(CONFIG_DM_GPIO) += gpio.o -+obj-$(CONFIG_DM_HWSPINLOCK) += hwspinlock.o - obj-$(CONFIG_DM_I2C) += i2c.o - obj-$(CONFIG_LED) += led.o - obj-$(CONFIG_DM_MAILBOX) += mailbox.o -diff --git a/test/dm/hwspinlock.c b/test/dm/hwspinlock.c -new file mode 100644 -index 0000000..09ec38b ---- /dev/null -+++ b/test/dm/hwspinlock.c -@@ -0,0 +1,40 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Test that hwspinlock driver functions are called */ -+static int dm_test_hwspinlock_base(struct unit_test_state *uts) -+{ -+ struct sandbox_state *state = state_get_current(); -+ struct hwspinlock hws; -+ -+ ut_assertok(uclass_get_device(UCLASS_HWSPINLOCK, 0, &hws.dev)); -+ ut_assertnonnull(hws.dev); -+ ut_asserteq(false, state->hwspinlock); -+ -+ hws.id = 0; -+ ut_assertok(hwspinlock_lock_timeout(&hws, 1)); -+ ut_asserteq(true, state->hwspinlock); -+ -+ ut_assertok(hwspinlock_unlock(&hws)); -+ ut_asserteq(false, state->hwspinlock); -+ -+ ut_assertok(hwspinlock_lock_timeout(&hws, 1)); -+ ut_assertok(!hwspinlock_lock_timeout(&hws, 1)); -+ -+ ut_assertok(hwspinlock_unlock(&hws)); -+ ut_assertok(!hwspinlock_unlock(&hws)); -+ -+ return 0; -+} -+ -+DM_TEST(dm_test_hwspinlock_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -diff --git a/test/py/tests/test_pinmux.py b/test/py/tests/test_pinmux.py -new file mode 100644 -index 0000000..f04a279 ---- /dev/null -+++ b/test/py/tests/test_pinmux.py -@@ -0,0 +1,62 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+import pytest -+import u_boot_utils -+ -+@pytest.mark.buildconfigspec('cmd_pinmux') -+def test_pinmux_usage_1(u_boot_console): -+ """Test that 'pinmux' command without parameters displays -+ pinmux usage.""" -+ output = u_boot_console.run_command('pinmux') -+ assert 'Usage:' in output -+ -+@pytest.mark.buildconfigspec('cmd_pinmux') -+def test_pinmux_usage_2(u_boot_console): -+ """Test that 'pinmux status' executed without previous "pinmux dev" -+ command displays pinmux usage.""" -+ output = u_boot_console.run_command('pinmux status') -+ assert 'Usage:' in output -+ -+@pytest.mark.buildconfigspec('cmd_pinmux') -+def test_pinmux_status_all(u_boot_console): -+ """Test that 'pinmux status -a' displays pin's muxing.""" -+ output = u_boot_console.run_command('pinmux status -a') -+ assert ('SCL : I2C SCL' in output) -+ assert ('SDA : I2C SDA' in output) -+ assert ('TX : Uart TX' in output) -+ assert ('RX : Uart RX' in output) -+ assert ('W1 : 1-wire gpio' in output) -+ -+@pytest.mark.buildconfigspec('cmd_pinmux') -+def test_pinmux_list(u_boot_console): -+ """Test that 'pinmux list' returns the pin-controller list.""" -+ output = u_boot_console.run_command('pinmux list') -+ assert 'sandbox_pinctrl' in output -+ -+@pytest.mark.buildconfigspec('cmd_pinmux') -+def test_pinmux_dev_bad(u_boot_console): -+ """Test that 'pinmux dev' returns an error when trying to select a -+ wrong pin controller.""" -+ pincontroller = 'bad_pin_controller_name' -+ output = u_boot_console.run_command('pinmux dev ' + pincontroller) -+ expected_output = 'Can\'t get the pin-controller: ' + pincontroller + '!' -+ assert (expected_output in output) -+ -+@pytest.mark.buildconfigspec('cmd_pinmux') -+def test_pinmux_dev(u_boot_console): -+ """Test that 'pinmux dev' select the wanted pin controller.""" -+ pincontroller = 'pinctrl' -+ output = u_boot_console.run_command('pinmux dev ' + pincontroller) -+ expected_output = 'dev: ' + pincontroller -+ assert (expected_output in output) -+ -+@pytest.mark.buildconfigspec('cmd_pinmux') -+def test_pinmux_status(u_boot_console): -+ """Test that 'pinmux status' displays selected pincontroller's pin -+ muxing descriptions.""" -+ output = u_boot_console.run_command('pinmux status') -+ assert ('SCL : I2C SCL' in output) -+ assert ('SDA : I2C SDA' in output) -+ assert ('TX : Uart TX' in output) -+ assert ('RX : Uart RX' in output) -+ assert ('W1 : 1-wire gpio' in output) -diff --git a/tools/stm32image.c b/tools/stm32image.c -index 08b32ba..ff3ec5f 100644 ---- a/tools/stm32image.c -+++ b/tools/stm32image.c -@@ -14,6 +14,8 @@ - #define HEADER_VERSION_V1 0x1 - /* default option : bit0 => no signature */ - #define HEADER_DEFAULT_OPTION (cpu_to_le32(0x00000001)) -+/* default binary type for U-Boot */ -+#define HEADER_TYPE_UBOOT (cpu_to_le32(0x00000000)) - - struct stm32_header { - uint32_t magic_number; -@@ -29,7 +31,8 @@ struct stm32_header { - uint32_t option_flags; - uint32_t ecdsa_algorithm; - uint32_t ecdsa_public_key[64 / 4]; -- uint32_t padding[84 / 4]; -+ uint32_t padding[83 / 4]; -+ uint32_t binary_type; - }; - - static struct stm32_header stm32image_header; -@@ -43,6 +46,7 @@ static void stm32image_default_header(struct stm32_header *ptr) - ptr->header_version[VER_MAJOR_IDX] = HEADER_VERSION_V1; - ptr->option_flags = HEADER_DEFAULT_OPTION; - ptr->ecdsa_algorithm = 1; -+ ptr->binary_type = HEADER_TYPE_UBOOT; - } - - static uint32_t stm32image_checksum(void *start, uint32_t len) -@@ -112,6 +116,8 @@ static void stm32image_print_header(const void *ptr) - le32_to_cpu(stm32hdr->image_checksum)); - printf("Option : 0x%08x\n", - le32_to_cpu(stm32hdr->option_flags)); -+ printf("BinaryType : 0x%08x\n", -+ le32_to_cpu(stm32hdr->binary_type)); - } - - static void stm32image_set_header(void *ptr, struct stat *sbuf, int ifd, --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0005-ARM-v2020.01-stm32mp-r1-CONFIG.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0005-ARM-v2020.01-stm32mp-r1-CONFIG.patch new file mode 100644 index 0000000..110d82b --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0005-ARM-v2020.01-stm32mp-r1-CONFIG.patch @@ -0,0 +1,545 @@ +From 5731d9684c509e5d8920ad4b94391fd6aa310323 Mon Sep 17 00:00:00 2001 +From: Romuald JEANNE +Date: Fri, 5 Jun 2020 13:46:04 +0200 +Subject: [PATCH 5/5] ARM v2020.01-stm32mp-r1 CONFIG + +--- + configs/stm32mp15_basic_defconfig | 36 +++++--- + configs/stm32mp15_dhcom_basic_defconfig | 141 ++++++++++++++++++++++++++++++++ + configs/stm32mp15_optee_defconfig | 129 ----------------------------- + configs/stm32mp15_trusted_defconfig | 41 +++++++--- + 4 files changed, 194 insertions(+), 153 deletions(-) + create mode 100644 configs/stm32mp15_dhcom_basic_defconfig + delete mode 100644 configs/stm32mp15_optee_defconfig + +diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig +index 713a7e6..cf28217 100644 +--- a/configs/stm32mp15_basic_defconfig ++++ b/configs/stm32mp15_basic_defconfig +@@ -2,8 +2,12 @@ CONFIG_ARM=y + CONFIG_ARCH_STM32MP=y + CONFIG_SYS_MALLOC_F_LEN=0x3000 + CONFIG_SPL_MMC_SUPPORT=y ++CONFIG_ENV_OFFSET=0x280000 + CONFIG_SPL=y +-CONFIG_TARGET_STM32MP1=y ++CONFIG_TARGET_ST_STM32MP15x=y ++CONFIG_CMD_STM32PROG=y ++CONFIG_ENV_SECT_SIZE=0x40000 ++CONFIG_ENV_OFFSET_REDUND=0x2C0000 + CONFIG_SPL_SPI_FLASH_SUPPORT=y + CONFIG_SPL_SPI_SUPPORT=y + # CONFIG_ARMV7_VIRT is not set +@@ -19,11 +23,13 @@ CONFIG_SPL_POWER_SUPPORT=y + CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000 + CONFIG_SYS_PROMPT="STM32MP> " + # CONFIG_CMD_BOOTD is not set ++CONFIG_CMD_DTIMG=y + # CONFIG_CMD_ELF is not set + # CONFIG_CMD_IMI is not set + # CONFIG_CMD_XIMG 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 + CONFIG_CMD_ADC=y +@@ -31,10 +37,8 @@ CONFIG_CMD_CLK=y + CONFIG_CMD_DFU=y + CONFIG_CMD_FUSE=y + CONFIG_CMD_GPIO=y +-CONFIG_CMD_GPT=y + CONFIG_CMD_I2C=y + CONFIG_CMD_MMC=y +-CONFIG_CMD_MTD=y + CONFIG_CMD_REMOTEPROC=y + CONFIG_CMD_SPI=y + CONFIG_CMD_USB=y +@@ -52,29 +56,31 @@ CONFIG_CMD_UBI=y + CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" + 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_NOWHERE=y +-CONFIG_ENV_IS_IN_EXT4=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_EXT4_INTERFACE="mmc" +-CONFIG_ENV_EXT4_DEVICE_AND_PART="0:auto" +-CONFIG_ENV_EXT4_FILE="/uboot.env" +-CONFIG_ENV_OFFSET_REDUND=0x2C0000 + 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_STM32_ADC=y +-CONFIG_DFU_MMC=y +-CONFIG_DFU_RAM=y +-CONFIG_DFU_MTD=y +-CONFIG_DFU_VIRT=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_FASTBOOT_MMC_BOOT_SUPPORT=y ++CONFIG_FASTBOOT_MMC_BOOT1_NAME="mmc1boot0" ++CONFIG_FASTBOOT_MMC_BOOT2_NAME="mmc1boot1" ++CONFIG_FASTBOOT_MMC_USER_SUPPORT=y ++CONFIG_FASTBOOT_MMC_USER_NAME="mmc1" ++CONFIG_FASTBOOT_CMD_OEM_FORMAT=y ++CONFIG_FASTBOOT_CMD_OEM_PARTCONF=y ++CONFIG_FASTBOOT_CMD_OEM_BOOTBUS=y ++CONFIG_GPIO_HOG=y + CONFIG_DM_HWSPINLOCK=y + CONFIG_HWSPINLOCK_STM32=y + CONFIG_DM_I2C=y +@@ -88,6 +94,7 @@ 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 +@@ -99,6 +106,7 @@ CONFIG_SPI_FLASH_WINBOND=y + # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set + CONFIG_SPI_FLASH_MTD=y + CONFIG_SPL_SPI_FLASH_MTD=y ++CONFIG_PHY_REALTEK=y + CONFIG_DM_ETH=y + CONFIG_DWC_ETH_QOS=y + CONFIG_PHY=y +@@ -113,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_RTC=y + CONFIG_RTC_STM32=y +@@ -142,4 +151,7 @@ CONFIG_VIDEO_STM32=y + CONFIG_VIDEO_STM32_DSI=y + CONFIG_VIDEO_STM32_MAX_XRES=1280 + CONFIG_VIDEO_STM32_MAX_YRES=800 ++CONFIG_WDT=y ++CONFIG_WDT_STM32MP=y ++CONFIG_ERRNO_STR=y + CONFIG_FDT_FIXUP_PARTITIONS=y +diff --git a/configs/stm32mp15_dhcom_basic_defconfig b/configs/stm32mp15_dhcom_basic_defconfig +new file mode 100644 +index 0000000..ed3504d +--- /dev/null ++++ b/configs/stm32mp15_dhcom_basic_defconfig +@@ -0,0 +1,141 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_STM32MP=y ++CONFIG_SYS_MALLOC_F_LEN=0x3000 ++CONFIG_SPL_MMC_SUPPORT=y ++CONFIG_ENV_SIZE=0x4000 ++CONFIG_SPL=y ++CONFIG_TARGET_DH_STM32MP1_PDK2=y ++CONFIG_SPL_SPI_FLASH_SUPPORT=y ++CONFIG_SPL_SPI_SUPPORT=y ++# CONFIG_ARMV7_VIRT is not set ++CONFIG_SPL_TEXT_BASE=0x2FFC2500 ++CONFIG_DISTRO_DEFAULTS=y ++CONFIG_FIT=y ++CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" ++CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y ++CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=3 ++CONFIG_SPL_I2C_SUPPORT=y ++CONFIG_SPL_MTD_SUPPORT=y ++CONFIG_SPL_POWER_SUPPORT=y ++CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000 ++CONFIG_SYS_PROMPT="STM32MP> " ++# CONFIG_CMD_BOOTD is not set ++# CONFIG_CMD_ELF is not set ++# CONFIG_CMD_IMI is not set ++# CONFIG_CMD_XIMG is not set ++# CONFIG_CMD_EXPORTENV is not set ++CONFIG_CMD_EEPROM=y ++CONFIG_CMD_MEMINFO=y ++CONFIG_CMD_MEMTEST=y ++CONFIG_CMD_ADC=y ++CONFIG_CMD_CLK=y ++CONFIG_CMD_DFU=y ++CONFIG_CMD_FUSE=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_I2C=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_MTD=y ++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 ++CONFIG_CMD_PMIC=y ++CONFIG_CMD_REGULATOR=y ++CONFIG_CMD_EXT4_WRITE=y ++CONFIG_CMD_MTDPARTS=y ++# CONFIG_SPL_DOS_PARTITION is not set ++CONFIG_DEFAULT_DEVICE_TREE="stm32mp15xx-dhcom-pdk2" ++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 ++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_USE_ENV_SPI_MODE=y ++CONFIG_ENV_SPI_MODE=0x0 ++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_IP_DEFRAG=y ++CONFIG_TFTP_BLOCKSIZE=1536 ++CONFIG_STM32_ADC=y ++CONFIG_SPL_BLOCK_CACHE=y ++CONFIG_DFU_MMC=y ++CONFIG_DFU_RAM=y ++CONFIG_DFU_VIRT=y ++CONFIG_SET_DFU_ALT_INFO=y ++CONFIG_GPIO_HOG=y ++CONFIG_DM_HWSPINLOCK=y ++CONFIG_HWSPINLOCK_STM32=y ++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_DM_MMC=y ++CONFIG_SUPPORT_EMMC_BOOT=y ++CONFIG_STM32_SDMMC2=y ++CONFIG_MTD=y ++CONFIG_SYS_MTDPARTS_RUNTIME=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_SPL_SPI_FLASH_MTD=y ++CONFIG_DM_ETH=y ++CONFIG_DWC_ETH_QOS=y ++CONFIG_PHY=y ++CONFIG_PHY_STM32_USBPHYC=y ++CONFIG_PINCONF=y ++# CONFIG_SPL_PINCTRL_FULL is not set ++CONFIG_PINCTRL_STMFX=y ++CONFIG_DM_PMIC=y ++# CONFIG_SPL_PMIC_CHILDREN is not set ++CONFIG_PMIC_STPMIC1=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_DM_REGULATOR_STM32_VREFBUF=y ++CONFIG_DM_REGULATOR_STPMIC1=y ++CONFIG_REMOTEPROC_STM32_COPRO=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_USB=y ++CONFIG_DM_USB=y ++CONFIG_DM_USB_GADGET=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_MANUFACTURER="dh" ++CONFIG_USB_GADGET_VENDOR_NUM=0x0483 ++CONFIG_USB_GADGET_PRODUCT_NUM=0x5720 ++CONFIG_USB_GADGET_DWC2_OTG=y ++CONFIG_USB_GADGET_DOWNLOAD=y ++CONFIG_USB_HOST_ETHER=y ++CONFIG_USB_ETHER_ASIX=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_LZO=y ++CONFIG_FDT_FIXUP_PARTITIONS=y +diff --git a/configs/stm32mp15_optee_defconfig b/configs/stm32mp15_optee_defconfig +deleted file mode 100644 +index f9161fd..0000000 +--- a/configs/stm32mp15_optee_defconfig ++++ /dev/null +@@ -1,129 +0,0 @@ +-CONFIG_ARM=y +-CONFIG_ARCH_STM32MP=y +-CONFIG_SYS_MALLOC_F_LEN=0x3000 +-CONFIG_TARGET_STM32MP1=y +-CONFIG_STM32MP1_OPTEE=y +-CONFIG_DISTRO_DEFAULTS=y +-CONFIG_FIT=y +-CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" +-CONFIG_SYS_PROMPT="STM32MP> " +-# CONFIG_CMD_BOOTD is not set +-# CONFIG_CMD_ELF is not set +-# CONFIG_CMD_IMI is not set +-# CONFIG_CMD_XIMG is not set +-# CONFIG_CMD_EXPORTENV is not set +-# CONFIG_CMD_IMPORTENV is not set +-CONFIG_CMD_MEMINFO=y +-CONFIG_CMD_MEMTEST=y +-CONFIG_CMD_ADC=y +-CONFIG_CMD_CLK=y +-CONFIG_CMD_DFU=y +-CONFIG_CMD_FUSE=y +-CONFIG_CMD_GPIO=y +-CONFIG_CMD_GPT=y +-CONFIG_CMD_I2C=y +-CONFIG_CMD_MMC=y +-CONFIG_CMD_MTD=y +-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 +-CONFIG_CMD_PMIC=y +-CONFIG_CMD_REGULATOR=y +-CONFIG_CMD_EXT4_WRITE=y +-CONFIG_CMD_MTDPARTS=y +-CONFIG_CMD_UBI=y +-CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" +-CONFIG_ENV_IS_NOWHERE=y +-CONFIG_ENV_IS_IN_EXT4=y +-CONFIG_ENV_IS_IN_SPI_FLASH=y +-CONFIG_ENV_IS_IN_UBI=y +-CONFIG_SYS_REDUNDAND_ENVIRONMENT=y +-CONFIG_ENV_EXT4_INTERFACE="mmc" +-CONFIG_ENV_EXT4_DEVICE_AND_PART="0:auto" +-CONFIG_ENV_EXT4_FILE="/uboot.env" +-CONFIG_ENV_OFFSET_REDUND=0x2C0000 +-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_STM32_ADC=y +-CONFIG_DFU_MMC=y +-CONFIG_DFU_RAM=y +-CONFIG_DFU_MTD=y +-CONFIG_DFU_VIRT=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_DM_HWSPINLOCK=y +-CONFIG_HWSPINLOCK_STM32=y +-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_DM_MMC=y +-CONFIG_SUPPORT_EMMC_BOOT=y +-CONFIG_STM32_SDMMC2=y +-CONFIG_MTD=y +-CONFIG_DM_MTD=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_DM_ETH=y +-CONFIG_DWC_ETH_QOS=y +-CONFIG_PHY=y +-CONFIG_PHY_STM32_USBPHYC=y +-CONFIG_PINCONF=y +-CONFIG_PINCTRL_STMFX=y +-CONFIG_DM_PMIC=y +-CONFIG_PMIC_STPMIC1=y +-CONFIG_DM_REGULATOR_FIXED=y +-CONFIG_DM_REGULATOR_GPIO=y +-CONFIG_DM_REGULATOR_STM32_VREFBUF=y +-CONFIG_DM_REGULATOR_STPMIC1=y +-CONFIG_REMOTEPROC_STM32_COPRO=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_USB=y +-CONFIG_DM_USB=y +-CONFIG_DM_USB_GADGET=y +-CONFIG_USB_EHCI_HCD=y +-CONFIG_USB_EHCI_GENERIC=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_BPP8=y +-CONFIG_VIDEO_BPP16=y +-CONFIG_VIDEO_BPP32=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_FDT_FIXUP_PARTITIONS=y +diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig +index a5ea528..e248b7d 100644 +--- a/configs/stm32mp15_trusted_defconfig ++++ b/configs/stm32mp15_trusted_defconfig +@@ -1,17 +1,23 @@ + CONFIG_ARM=y + CONFIG_ARCH_STM32MP=y + CONFIG_SYS_MALLOC_F_LEN=0x3000 +-CONFIG_TARGET_STM32MP1=y ++CONFIG_ENV_OFFSET=0x280000 ++CONFIG_TARGET_ST_STM32MP15x=y ++CONFIG_CMD_STM32PROG=y ++CONFIG_ENV_SECT_SIZE=0x40000 ++CONFIG_ENV_OFFSET_REDUND=0x2C0000 + CONFIG_DISTRO_DEFAULTS=y + CONFIG_FIT=y + CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" + CONFIG_SYS_PROMPT="STM32MP> " + # CONFIG_CMD_BOOTD is not set ++CONFIG_CMD_DTIMG=y + # CONFIG_CMD_ELF is not set + # CONFIG_CMD_IMI is not set + # CONFIG_CMD_XIMG 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 + CONFIG_CMD_ADC=y +@@ -19,10 +25,8 @@ CONFIG_CMD_CLK=y + CONFIG_CMD_DFU=y + CONFIG_CMD_FUSE=y + CONFIG_CMD_GPIO=y +-CONFIG_CMD_GPT=y + CONFIG_CMD_I2C=y + CONFIG_CMD_MMC=y +-CONFIG_CMD_MTD=y + CONFIG_CMD_REMOTEPROC=y + CONFIG_CMD_SPI=y + CONFIG_CMD_USB=y +@@ -38,29 +42,32 @@ CONFIG_CMD_MTDPARTS=y + CONFIG_CMD_UBI=y + CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" + CONFIG_ENV_IS_NOWHERE=y +-CONFIG_ENV_IS_IN_EXT4=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_EXT4_INTERFACE="mmc" +-CONFIG_ENV_EXT4_DEVICE_AND_PART="0:auto" +-CONFIG_ENV_EXT4_FILE="/uboot.env" +-CONFIG_ENV_OFFSET_REDUND=0x2C0000 + 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_STM32_ADC=y +-CONFIG_DFU_MMC=y +-CONFIG_DFU_RAM=y +-CONFIG_DFU_MTD=y +-CONFIG_DFU_VIRT=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_FASTBOOT_MMC_BOOT_SUPPORT=y ++CONFIG_FASTBOOT_MMC_BOOT1_NAME="mmc1boot0" ++CONFIG_FASTBOOT_MMC_BOOT2_NAME="mmc1boot1" ++CONFIG_FASTBOOT_MMC_USER_SUPPORT=y ++CONFIG_FASTBOOT_MMC_USER_NAME="mmc1" ++CONFIG_FASTBOOT_CMD_OEM_FORMAT=y ++CONFIG_FASTBOOT_CMD_OEM_PARTCONF=y ++CONFIG_FASTBOOT_CMD_OEM_BOOTBUS=y ++CONFIG_GPIO_HOG=y + CONFIG_DM_HWSPINLOCK=y + CONFIG_HWSPINLOCK_STM32=y + CONFIG_DM_I2C=y +@@ -69,11 +76,13 @@ CONFIG_LED=y + CONFIG_LED_GPIO=y + CONFIG_DM_MAILBOX=y + CONFIG_STM32_IPCC=y ++CONFIG_ARM_SMC_MAILBOX=y + CONFIG_DM_MMC=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 +@@ -84,6 +93,7 @@ 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 +@@ -97,6 +107,7 @@ CONFIG_DM_REGULATOR_GPIO=y + CONFIG_DM_REGULATOR_STM32_VREFBUF=y + CONFIG_DM_REGULATOR_STPMIC1=y + CONFIG_REMOTEPROC_STM32_COPRO=y ++CONFIG_RESET_SCMI=y + CONFIG_DM_RTC=y + CONFIG_RTC_STM32=y + CONFIG_SERIAL_RX_BUFFER=y +@@ -104,6 +115,9 @@ CONFIG_SPI=y + CONFIG_DM_SPI=y + CONFIG_STM32_QSPI=y + CONFIG_STM32_SPI=y ++CONFIG_TEE=y ++CONFIG_OPTEE=y ++# CONFIG_OPTEE_TA_AVB is not set + CONFIG_USB=y + CONFIG_DM_USB=y + CONFIG_DM_USB_GADGET=y +@@ -125,4 +139,7 @@ CONFIG_VIDEO_STM32=y + CONFIG_VIDEO_STM32_DSI=y + CONFIG_VIDEO_STM32_MAX_XRES=1280 + CONFIG_VIDEO_STM32_MAX_YRES=800 ++CONFIG_WDT=y ++CONFIG_WDT_STM32MP=y ++CONFIG_ERRNO_STR=y + CONFIG_FDT_FIXUP_PARTITIONS=y +-- +2.7.4 + diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0006-ARM-v2018.11-stm32mp-r2-MACHINE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0006-ARM-v2018.11-stm32mp-r2-MACHINE.patch deleted file mode 100644 index f6bb762..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0006-ARM-v2018.11-stm32mp-r2-MACHINE.patch +++ /dev/null @@ -1,237 +0,0 @@ -From 761f1ccf48cd083baa2bf3a120f8f1da993af217 Mon Sep 17 00:00:00 2001 -From: christophe montaud -Date: Mon, 28 Jan 2019 11:04:22 +0100 -Subject: [PATCH 6/8] ARM v2018.11 stm32mp r2 MACHINE - ---- - arch/arm/mach-stm32mp/Kconfig | 13 +++ - arch/arm/mach-stm32mp/Makefile | 1 + - .../arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c | 22 ++++ - arch/arm/mach-stm32mp/include/mach/stm32.h | 3 + - arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S | 124 +++++++++++++++++++++ - 5 files changed, 163 insertions(+) - create mode 100644 arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S - -diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig -index 0c68c24..fbc8195 100644 ---- a/arch/arm/mach-stm32mp/Kconfig -+++ b/arch/arm/mach-stm32mp/Kconfig -@@ -47,6 +47,19 @@ config TARGET_STM32MP1 - STMicroelectronics MPU with core ARMv7 - dual core A7 for STM32MP153, monocore for STM32MP151 - -+config STM32MP1_RESET_HALT_WORKAROUND -+ bool "workaround for reset halt deubg on stm32mp15x" -+ depends on TARGET_STM32MP1 -+ default y -+ help -+ Activate a workaround for current STM32MP15x revision B -+ limitation on debug reset halt not handle by ROM code: -+ add a delay loop early in the SPL boot process to wait for -+ the debugger to attach -+ it can be removed when using the Soc revision -+ that fixes the limitation. -+ -+ - config STM32MP1_TRUSTED - bool "Support trusted boot with TF-A" - default y if !SPL -diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile -index 09636db..c67bcce 100644 ---- a/arch/arm/mach-stm32mp/Makefile -+++ b/arch/arm/mach-stm32mp/Makefile -@@ -9,6 +9,7 @@ obj-y += syscon.o - - ifdef CONFIG_SPL_BUILD - obj-y += spl.o -+obj-$(CONFIG_STM32MP1_RESET_HALT_WORKAROUND) += stm32mp1_helper_dgb.o - else - obj-$(CONFIG_CMD_STM32PROG) += cmd_stm32prog/ - obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o -diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c -index d1c07dc..a6ee0f2 100644 ---- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c -+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c -@@ -10,6 +10,26 @@ - - DECLARE_GLOBAL_DATA_PTR; - -+static void enable_vidconsole(void) -+{ -+#ifdef CONFIG_DM_VIDEO -+ char *stdname; -+ char buf[64]; -+ -+ stdname = env_get("stdout"); -+ if (!strstr(stdname, "vidconsole")) { -+ snprintf(buf, sizeof(buf), "%s,vidconsole", stdname); -+ env_set("stdout", buf); -+ } -+ -+ stdname = env_get("stderr"); -+ if (!strstr(stdname, "vidconsole")) { -+ snprintf(buf, sizeof(buf), "%s,vidconsole", stdname); -+ env_set("stderr", buf); -+ } -+#endif -+} -+ - static int do_stm32prog(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) - { -@@ -44,6 +64,8 @@ static int do_stm32prog(cmd_tbl_t *cmdtp, int flag, int argc, - if (argc > 4) - size = simple_strtoul(argv[4], NULL, 16); - -+ enable_vidconsole(); -+ - data = stm32prog_init(link, dev, addr, size); - if (!data) - return CMD_RET_FAILURE; -diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h -index 4147873..36b885b 100644 ---- a/arch/arm/mach-stm32mp/include/mach/stm32.h -+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h -@@ -35,6 +35,9 @@ - #define STM32_DDR_BASE 0xC0000000 - #define STM32_DDR_SIZE SZ_1G - -+#define STM32_RETRAM_BASE 0x38000000 -+#define STM32_RETRAM_SIZE 0x00010000 -+ - #ifndef __ASSEMBLY__ - #include - -diff --git a/arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S b/arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S -new file mode 100644 -index 0000000..29f8e1f ---- /dev/null -+++ b/arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S -@@ -0,0 +1,124 @@ -+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ -+/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ */ -+ -+/***************************************************************************** -+ * This file is only needed for current Soc revision which has a limitation on -+ * debug reset halt. This can be removed when using the Soc revision that -+ * fixes the limitation. Anyway, this source code identifies the Soc revision -+ * and is only executed if it corresponds, so it can be kept on other -+ * revisions without any consequence. -+ ****************************************************************************/ -+ -+#include -+#include -+ -+#define BIT(nr) (1 << (nr)) -+ -+#define DBG_DSCR_ADDR 0x500D0088 -+#define DBG_DSCR_HDBGEN BIT(14) -+ -+#define RCC_DBGCFGR_ADDR 0x5000080C -+#define RCC_DBGCFGR_DBGCKEN BIT(8) -+ -+#define PWR_CR1_ADDR 0x50001000 -+#define PWR_CR1_DBP BIT(8) -+ -+#define DBGMCU_IDC_ADDR 0x50081000 -+#define DBGMCU_IDC_MASK 0xFFFF0FFF -+#define DBGMCU_IDC_VALUE 0x20000500 -+ -+#define TAMP_BKP_REGISTER_20 (0x5C00A100 + (20 << 2)) -+ -+ -+ .globl save_boot_params -+ -+ENTRY(save_boot_params) -+ /* -+ * This function is the first call after reset. -+ * Boot rom parameters are stored in r0..r3, so we mustn't use them -+ * here. And because they are saved in r9..r12 just after the -+ * execution of this function, we should firstly use these registers. -+ * And then, if more registers needed, we have to start by using -+ * r8, and then r7 and so on. By this way, debug will be done in -+ * conditions closed to the initial context. -+ */ -+ -+ /* Check Soc revision */ -+ ldr r12, =RCC_DBGCFGR_ADDR -+ ldr r11, [r12] /* read RCC_DBGCFGR (r11) */ -+ orr r10, r11, #RCC_DBGCFGR_DBGCKEN -+ str r10, [r12] /* update RCC_DBGCFGR */ -+ ldr r10, =DBGMCU_IDC_ADDR -+ ldr r10, [r10] /* read DBGMCU_IDC (r10) */ -+ str r11, [r12] /* restore RCC_DBGCFGR (r11) */ -+ ldr r12, =DBGMCU_IDC_MASK -+ and r10, r12 /* mask reserved bits */ -+ ldr r11, =DBGMCU_IDC_VALUE -+ teq r10, r11 /* test DBGMCU_IDC */ -+ bne func_exit -+ -+ /* Disable the backup domain write protection */ -+ ldr r12, =PWR_CR1_ADDR -+ ldr r11, [r12] -+ orr r11, r11, #PWR_CR1_DBP -+ str r11, [r12] -+poll_dbp: -+ ldr r11, [r12] -+ tst r11, #PWR_CR1_DBP -+ beq poll_dbp -+ -+ /* Clear tamper 20 bit 16 if set */ -+ ldr r12, =TAMP_BKP_REGISTER_20 -+ ldr r11, [r12] -+ tst r11, #(BIT(16)) -+ beq func_exit -+ bic r11, #(BIT(16)) -+ str r11, [r12] -+ -+ /* Re-enable the backup domain write protection */ -+ ldr r12, =PWR_CR1_ADDR -+ ldr r11, [r12] -+ bic r11, #PWR_CR1_DBP -+ str r11, [r12] -+poll_dbp_2: -+ ldr r11, [r12] -+ tst r11, #PWR_CR1_DBP -+ bne poll_dbp_2 -+ -+ /* Get current time + 1 second */ -+ /* CNTFRQ */ -+ mrc p15, 0, r12, c14, c0, 0 -+ /* CNTPCT_64 */ -+ mrrc p15, 0, r11, r10, c14 -+ add r12, r12, r11 -+ -+loop: -+ /* Check A7 DBG_DSCR HDBGEN bit value */ -+ ldr r10, =DBG_DSCR_ADDR -+ ldr r10, [r10] -+ tst r10, #DBG_DSCR_HDBGEN -+ beq loop_continue -+ /* Sw break */ -+ bkpt 5 -+ /* Jump entrypoint */ -+ b reset -+loop_continue: -+ /* Check 1 second expiration */ -+ mrrc p15, 0, r10, r9, c14 -+ /* Check if MSB 64-bit increment needed */ -+ cmp r12, r11 -+ bmi msb_incr -+ cmp r12, r10 -+ bmi func_exit -+ b loop -+msb_incr: -+ cmp r12, r10 -+ bpl loop -+ cmp r11, r10 -+ bmi loop -+func_exit: -+ b save_boot_params_ret -+ENDPROC(save_boot_params) --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0007-ARM-v2018.11-stm32mp-r2-DEVICETREE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0007-ARM-v2018.11-stm32mp-r2-DEVICETREE.patch deleted file mode 100644 index 564e041..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0007-ARM-v2018.11-stm32mp-r2-DEVICETREE.patch +++ /dev/null @@ -1,1004 +0,0 @@ -From c8d598d448c6a49bcfd5383053a226db1f883ef7 Mon Sep 17 00:00:00 2001 -From: christophe montaud -Date: Mon, 28 Jan 2019 11:06:23 +0100 -Subject: [PATCH 7/8] ARM v2018.11 stm32mp r2 DEVICETREE - ---- - arch/arm/dts/stm32mp157a-dk1.dts | 3 +- - arch/arm/dts/stm32mp157c-ed1.dts | 3 +- - arch/arm/dts/stm32mp157c-m4-srm.dtsi | 436 +++++++++++++++++++++++++ - doc/device-tree-bindings/clock/st,stm32mp1.txt | 427 ++++++++++++++++-------- - 4 files changed, 727 insertions(+), 142 deletions(-) - create mode 100644 arch/arm/dts/stm32mp157c-m4-srm.dtsi - -diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts -index e3d305a..8e09447 100644 ---- a/arch/arm/dts/stm32mp157a-dk1.dts -+++ b/arch/arm/dts/stm32mp157a-dk1.dts -@@ -7,6 +7,7 @@ - /dts-v1/; - - #include "stm32mp157c.dtsi" -+#include "stm32mp157c-m4-srm.dtsi" - #include "stm32mp157cac-pinctrl.dtsi" - #include - #include -@@ -309,7 +310,7 @@ - - vddcore: buck1 { - regulator-name = "vddcore"; -- regulator-min-microvolt = <800000>; -+ regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1350000>; - regulator-always-on; - regulator-initial-mode = <0>; -diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts -index 37edf87..0f70bb7 100644 ---- a/arch/arm/dts/stm32mp157c-ed1.dts -+++ b/arch/arm/dts/stm32mp157c-ed1.dts -@@ -6,6 +6,7 @@ - /dts-v1/; - - #include "stm32mp157c.dtsi" -+#include "stm32mp157c-m4-srm.dtsi" - #include "stm32mp157caa-pinctrl.dtsi" - #include - #include -@@ -202,7 +203,7 @@ - - vddcore: buck1 { - regulator-name = "vddcore"; -- regulator-min-microvolt = <800000>; -+ regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1350000>; - regulator-always-on; - regulator-initial-mode = <0>; -diff --git a/arch/arm/dts/stm32mp157c-m4-srm.dtsi b/arch/arm/dts/stm32mp157c-m4-srm.dtsi -new file mode 100644 -index 0000000..5ebe24b ---- /dev/null -+++ b/arch/arm/dts/stm32mp157c-m4-srm.dtsi -@@ -0,0 +1,436 @@ -+&m4_rproc { -+ m4_system_resources { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ m4_timers2: timer@40000000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40000000>; -+ clocks = <&rcc TIM2_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_timers3: timer@40001000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40001000>; -+ clocks = <&rcc TIM3_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_timers4: timer@40002000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40002000>; -+ clocks = <&rcc TIM4_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_timers5: timer@40003000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40003000>; -+ clocks = <&rcc TIM5_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_timers6: timer@40004000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40004000>; -+ clocks = <&rcc TIM6_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_timers7: timer@40005000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40005000>; -+ clocks = <&rcc TIM7_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_timers12: timer@40006000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40006000>; -+ clocks = <&rcc TIM12_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_timers13: timer@40007000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40007000>; -+ clocks = <&rcc TIM13_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_timers14: timer@40008000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40008000>; -+ clocks = <&rcc TIM14_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_lptimer1: timer@40009000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40009000>; -+ clocks = <&rcc LPTIM1_K>; -+ clock-names = "mux"; -+ status = "disabled"; -+ }; -+ m4_spi2: spi@4000b000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4000b000>; -+ clocks = <&rcc SPI2_K>; -+ status = "disabled"; -+ }; -+ m4_i2s2: audio-controller@4000b000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4000b000>; -+ status = "disabled"; -+ }; -+ m4_spi3: spi@4000c000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4000c000>; -+ clocks = <&rcc SPI3_K>; -+ status = "disabled"; -+ }; -+ m4_i2s3: audio-controller@4000c000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4000c000>; -+ status = "disabled"; -+ }; -+ m4_spdifrx: audio-controller@4000d000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4000d000>; -+ clocks = <&rcc SPDIF_K>; -+ clock-names = "kclk"; -+ status = "disabled"; -+ }; -+ m4_usart2: serial@4000e000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4000e000>; -+ interrupt-parent = <&exti>; -+ interrupts = <27 1>; -+ clocks = <&rcc USART2_K>; -+ status = "disabled"; -+ }; -+ m4_usart3: serial@4000f000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4000f000>; -+ interrupt-parent = <&exti>; -+ interrupts = <28 1>; -+ clocks = <&rcc USART3_K>; -+ status = "disabled"; -+ }; -+ m4_uart4: serial@40010000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40010000>; -+ interrupt-parent = <&exti>; -+ interrupts = <30 1>; -+ clocks = <&rcc UART4_K>; -+ status = "disabled"; -+ }; -+ m4_uart5: serial@40011000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40011000>; -+ interrupt-parent = <&exti>; -+ interrupts = <31 1>; -+ clocks = <&rcc UART5_K>; -+ status = "disabled"; -+ }; -+ m4_i2c1: i2c@40012000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40012000>; -+ interrupt-parent = <&exti>; -+ interrupts = <21 1>; -+ clocks = <&rcc I2C1_K>; -+ status = "disabled"; -+ }; -+ m4_i2c2: i2c@40013000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40013000>; -+ interrupt-parent = <&exti>; -+ interrupts = <22 1>; -+ clocks = <&rcc I2C2_K>; -+ status = "disabled"; -+ }; -+ m4_i2c3: i2c@40014000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40014000>; -+ interrupt-parent = <&exti>; -+ interrupts = <23 1>; -+ clocks = <&rcc I2C3_K>; -+ status = "disabled"; -+ }; -+ m4_i2c5: i2c@40015000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40015000>; -+ interrupt-parent = <&exti>; -+ interrupts = <25 1>; -+ clocks = <&rcc I2C5_K>; -+ status = "disabled"; -+ }; -+ m4_cec: cec@40016000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40016000>; -+ interrupt-parent = <&exti>; -+ interrupts = <69 1>; -+ clocks = <&rcc CEC_K>, <&rcc CK_LSE>; -+ clock-names = "cec", "hdmi-cec"; -+ status = "disabled"; -+ }; -+ m4_dac: dac@40017000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40017000>; -+ clocks = <&rcc DAC12>; -+ clock-names = "pclk"; -+ status = "disabled"; -+ }; -+ m4_uart7: serial@40018000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40018000>; -+ interrupt-parent = <&exti>; -+ interrupts = <32 1>; -+ clocks = <&rcc UART7_K>; -+ status = "disabled"; -+ }; -+ m4_uart8: serial@40019000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x40019000>; -+ interrupt-parent = <&exti>; -+ interrupts = <33 1>; -+ clocks = <&rcc UART8_K>; -+ status = "disabled"; -+ }; -+ m4_timers1: timer@44000000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x44000000>; -+ clocks = <&rcc TIM1_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_timers8: timer@44001000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x44001000>; -+ clocks = <&rcc TIM8_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_usart6: serial@44003000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x44003000>; -+ interrupt-parent = <&exti>; -+ interrupts = <29 1>; -+ clocks = <&rcc USART6_K>; -+ status = "disabled"; -+ }; -+ m4_spi1: spi@44004000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x44004000>; -+ clocks = <&rcc SPI1_K>; -+ status = "disabled"; -+ }; -+ m4_i2s1: audio-controller@44004000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x44004000>; -+ status = "disabled"; -+ }; -+ m4_spi4: spi@44005000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x44005000>; -+ clocks = <&rcc SPI4_K>; -+ status = "disabled"; -+ }; -+ m4_timers15: timer@44006000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x44006000>; -+ clocks = <&rcc TIM15_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_timers16: timer@44007000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x44007000>; -+ clocks = <&rcc TIM16_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_timers17: timer@44008000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x44008000>; -+ clocks = <&rcc TIM17_K>; -+ clock-names = "int"; -+ status = "disabled"; -+ }; -+ m4_spi5: spi@44009000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x44009000>; -+ clocks = <&rcc SPI5_K>; -+ status = "disabled"; -+ }; -+ m4_sai1: sai@4400a000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4400a000>; -+ clocks = <&rcc SAI1_K>; -+ clock-names = "sai_ck"; -+ status = "disabled"; -+ }; -+ m4_sai2: sai@4400b000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4400b000>; -+ clocks = <&rcc SAI2_K>; -+ clock-names = "sai_ck"; -+ status = "disabled"; -+ }; -+ m4_sai3: sai@4400c000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4400c000>; -+ clocks = <&rcc SAI3_K>; -+ clock-names = "sai_ck"; -+ status = "disabled"; -+ }; -+ m4_dfsdm: dfsdm@4400d000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4400d000>; -+ clocks = <&rcc DFSDM_K>; -+ clock-names = "dfsdm"; -+ status = "disabled"; -+ }; -+ m4_m_can1: can@4400e000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4400e000>, <0x44011000>; -+ clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; -+ clock-names = "hclk", "cclk"; -+ status = "disabled"; -+ }; -+ m4_m_can2: can@4400f000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4400f000>, <0x44011000>; -+ clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; -+ clock-names = "hclk", "cclk"; -+ status = "disabled"; -+ }; -+ m4_dma1: dma@48000000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x48000000>; -+ clocks = <&rcc DMA1>; -+ status = "disabled"; -+ }; -+ m4_dma2: dma@48001000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x48001000>; -+ clocks = <&rcc DMA2>; -+ status = "disabled"; -+ }; -+ m4_dmamux1: dma-router@48002000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x48002000>; -+ clocks = <&rcc DMAMUX>; -+ status = "disabled"; -+ }; -+ m4_adc: adc@48003000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x48003000>; -+ clocks = <&rcc ADC12>, <&rcc ADC12_K>; -+ clock-names = "bus", "adc"; -+ status = "disabled"; -+ }; -+ m4_sdmmc3: sdmmc@48004000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x48004000>, <0x48005000>; -+ clocks = <&rcc SDMMC3_K>; -+ status = "disabled"; -+ }; -+ m4_usbotg_hs: usb-otg@49000000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x49000000>; -+ clocks = <&rcc USBO_K>; -+ clock-names = "otg"; -+ status = "disabled"; -+ }; -+ m4_hash2: hash@4c002000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4c002000>; -+ clocks = <&rcc HASH2>; -+ status = "disabled"; -+ }; -+ m4_rng2: rng@4c003000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4c003000>; -+ clocks = <&rcc RNG2_K>; -+ status = "disabled"; -+ }; -+ m4_crc2: crc@4c004000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4c004000>; -+ clocks = <&rcc CRC2>; -+ status = "disabled"; -+ }; -+ m4_cryp2: cryp@4c005000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4c005000>; -+ clocks = <&rcc CRYP2>; -+ status = "disabled"; -+ }; -+ m4_dcmi: dcmi@4c006000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x4c006000>; -+ clocks = <&rcc DCMI>; -+ clock-names = "mclk"; -+ status = "disabled"; -+ }; -+ m4_lptimer2: timer@50021000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x50021000>; -+ clocks = <&rcc LPTIM2_K>; -+ clock-names = "mux"; -+ status = "disabled"; -+ }; -+ m4_lptimer3: timer@50022000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x50022000>; -+ clocks = <&rcc LPTIM3_K>; -+ clock-names = "mux"; -+ status = "disabled"; -+ }; -+ m4_lptimer4: timer@50023000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x50023000>; -+ clocks = <&rcc LPTIM4_K>; -+ clock-names = "mux"; -+ status = "disabled"; -+ }; -+ m4_lptimer5: timer@50024000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x50024000>; -+ clocks = <&rcc LPTIM5_K>; -+ clock-names = "mux"; -+ status = "disabled"; -+ }; -+ m4_sai4: sai@50027000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x50027000>; -+ clocks = <&rcc SAI4_K>; -+ clock-names = "sai_ck"; -+ status = "disabled"; -+ }; -+ m4_qspi: qspi@58003000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x58003000>, <0x70000000>; -+ clocks = <&rcc QSPI_K>; -+ status = "disabled"; -+ }; -+ m4_ethernet0: ethernet@5800a000 { -+ compatible = "rproc-srm-dev"; -+ reg = <0x5800a000>; -+ clock-names = "stmmaceth", -+ "mac-clk-tx", -+ "mac-clk-rx", -+ "ethstp", -+ "syscfg-clk"; -+ clocks = <&rcc ETHMAC>, -+ <&rcc ETHTX>, -+ <&rcc ETHRX>, -+ <&rcc ETHSTP>, -+ <&rcc SYSCFG>; -+ status = "disabled"; -+ }; -+ }; -+}; -+ -diff --git a/doc/device-tree-bindings/clock/st,stm32mp1.txt b/doc/device-tree-bindings/clock/st,stm32mp1.txt -index 6a9397e..02e1460 100644 ---- a/doc/device-tree-bindings/clock/st,stm32mp1.txt -+++ b/doc/device-tree-bindings/clock/st,stm32mp1.txt -@@ -1,185 +1,186 @@ - STMicroelectronics STM32MP1 clock tree initialization - ===================================================== - --The STM32MP clock tree initialization is based on device tree information --for RCC IP and on fixed clocks. -+The STM32MP1 clock tree initialization is based on device tree information -+for RCC IP node (st,stm32mp1-rcc) and on fixed-clock nodes. - --------------------------------- --RCC CLOCK = st,stm32mp1-rcc-clk --------------------------------- -+RCC IP = st,stm32mp1-rcc -+======================== - - The RCC IP is both a reset and a clock controller but this documentation only - describes the fields added for clock tree initialization which are not present --in Linux binding. -+in Linux binding for compatible "st,stm32mp1-rcc" defined in st,stm32mp1-rcc.txt -+file. - --Please refer to ../mfd/st,stm32-rcc.txt for all the other properties common --with Linux. -+The added properties for clock tree initialization are: - - Required properties: -+- st,clksrc : The clock sources configuration array in a platform specific -+ order. - --- compatible: Should be "st,stm32mp1-rcc-clk" -+ For the STM32MP15x family there are 9 clock sources selector which are -+ configured in the following order: -+ MPU AXI MCU PLL12 PLL3 PLL4 RTC MCO1 MCO2 - --- st,clksrc : The clock source in this order -+ Clock source configuration values are defined by macros CLK__ -+ from dt-bindings/clock/stm32mp1-clksrc.h. - -- for STM32MP15x: 9 clock sources are requested -- MPU AXI MCU PLL12 PLL3 PLL4 RTC MCO1 MCO2 -- -- with value equals to RCC clock specifier as defined in -- dt-bindings/clock/stm32mp1-clksrc.h: CLK__ -- --- st,clkdiv : The div parameters in this order -- for STM32MP15x: 11 dividers value are requested -+ Example: -+ st,clksrc = < -+ CLK_MPU_PLL1P -+ CLK_AXI_PLL2P -+ CLK_MCU_PLL3P -+ CLK_PLL12_HSE -+ CLK_PLL3_HSE -+ CLK_PLL4_HSE -+ CLK_RTC_LSE -+ CLK_MCO1_DISABLED -+ CLK_MCO2_DISABLED -+ >; -+ -+- st,clkdiv : The clock main dividers value specified in an array -+ in a platform specific order. -+ -+ When used, it shall describe the whole clock dividers tree. -+ -+ For the STM32MP15x family there are 11 dividers values expected. -+ They shall be configured in the following order: - MPU AXI MCU APB1 APB2 APB3 APB4 APB5 RTC MCO1 MCO2 - -- with DIV coding defined in RCC associated register RCC_xxxDIVR -- -- most the case, it is: -+ The each divider value uses the DIV coding defined in RCC associated -+ register RCC_xxxDIVR. In most the case, it is: - 0x0: not divided - 0x1: division by 2 - 0x2: division by 4 - 0x3: division by 8 - ... - -- but for RTC MCO1 MCO2, the coding is different: -+ Note that for RTC MCO1 MCO2, the coding is different: - 0x0: not divided - 0x1: division by 2 - 0x2: division by 3 - 0x3: division by 4 - ... - --Optional Properties: --- st,pll -- PLL children node for PLL1 to PLL4 : (see ref manual for details) -- with associated index 0 to 3 (st,pll@0 to st,pll@4) -- PLLx is off when the associated node is absent -+ Example: -+ st,clkdiv = < -+ 1 /*MPU*/ -+ 0 /*AXI*/ -+ 0 /*MCU*/ -+ 1 /*APB1*/ -+ 1 /*APB2*/ -+ 1 /*APB3*/ -+ 1 /*APB4*/ -+ 2 /*APB5*/ -+ 23 /*RTC*/ -+ 0 /*MCO1*/ -+ 0 /*MCO2*/ -+ >; - -- - Sub-nodes: -+Optional Properties: -+- st,pll : A specific PLL configuration, including frequency. - -- - cfg: The parameters for PLL configuration in this order: -- DIVM DIVN DIVP DIVQ DIVR Output -+ PLL children nodes for PLL1 to PLL4 (see ref manual for details) -+ are listed with associated index 0 to 3 (st,pll@0 to st,pll@3). -+ PLLx is off when the associated node is absent. - -- with DIV value as defined in RCC spec: -- 0x0: bypass (division by 1) -- 0x1: division by 2 -- 0x2: division by 3 -- 0x3: division by 4 -- ... -+ Here are the available properties for each PLL node: - -- and Output = bitfield for each output value = 1:ON/0:OFF -- BIT(0) => output P : DIVPEN -- BIT(1) => output Q : DIVQEN -- BIT(2) => output R : DIVREN -- NB : macro PQR(p,q,r) can be used to build this value -- with p,p,r = 0 or 1 -+ - cfg: The parameters for PLL configuration in the following order: -+ DIVM DIVN DIVP DIVQ DIVR Output. - -- - frac : Fractional part of the multiplication factor -- (optional, PLL is in integer mode when absent) -+ DIVx values are defined as in RCC spec: -+ 0x0: bypass (division by 1) -+ 0x1: division by 2 -+ 0x2: division by 3 -+ 0x3: division by 4 -+ ... - -- - csg : Clock Spreading Generator (optional) -- with parameters in this order: -- MOD_PER INC_STEP SSCG_MODE -+ Output contains a bitfield for each output value (1:ON/0:OFF) -+ BIT(0) => output P : DIVPEN -+ BIT(1) => output Q : DIVQEN -+ BIT(2) => output R : DIVREN -+ NB: macro PQR(p,q,r) can be used to build this value -+ with p,q,r = 0 or 1. -+ -+ - frac : Fractional part of the multiplication factor -+ (optional, PLL is in integer mode when absent). -+ -+ - csg : Clock Spreading Generator (optional) with parameters in the -+ following order: MOD_PER INC_STEP SSCG_MODE. -+ -+ MOD_PER: Modulation Period Adjustment -+ INC_STEP: Modulation Depth Adjustment -+ SSCG_MODE: Spread spectrum clock generator mode, with associated -+ defined from stm32mp1-clksrc.h: -+ - SSCG_MODE_CENTER_SPREAD = 0 -+ - SSCG_MODE_DOWN_SPREAD = 1 -+ -+ Example: -+ st,pll@0 { -+ cfg = < 1 53 0 0 0 1 >; -+ frac = < 0x810 >; -+ }; -+ st,pll@1 { -+ cfg = < 1 43 1 0 0 PQR(0,1,1) >; -+ csg = < 10 20 1 >; -+ }; -+ st,pll@2 { -+ cfg = < 2 85 3 13 3 0 >; -+ csg = < 10 20 SSCG_MODE_CENTER_SPREAD >; -+ }; -+ st,pll@3 { -+ cfg = < 2 78 4 7 9 3 >; -+ }; - -- * MOD_PER: Modulation Period Adjustment -- * INC_STEP: Modulation Depth Adjustment -- * SSCG_MODE: Spread spectrum clock generator mode -- you can use associated defines from stm32mp1-clksrc.h -- * SSCG_MODE_CENTER_SPREAD = 0 -- * SSCG_MODE_DOWN_SPREAD = 1 -+- st,pkcs : used to configure the peripherals kernel clock selection. - -+ The property is a list of peripheral kernel clock source identifiers defined -+ by macros CLK__ as defined by header file -+ dt-bindings/clock/stm32mp1-clksrc.h. - --- st,pkcs : used to configure the peripherals kernel clock selection -- containing a list of peripheral kernel clock source identifier as defined -- in the file dt-bindings/clock/stm32mp1-clksrc.h -+ st,pkcs may not list all the kernel clocks and has no ordering requirements. - - Example: -+ st,pkcs = < -+ CLK_STGEN_HSE -+ CLK_CKPER_HSI -+ CLK_USBPHY_PLL2P -+ CLK_DSI_PLL2Q -+ CLK_I2C46_HSI -+ CLK_UART1_HSI -+ CLK_UART24_HSI -+ >; - -- rcc: rcc@50000000 { -- compatible = "syscon", "simple-mfd"; -- -- reg = <0x50000000 0x1000>; -- -- rcc_clk: rcc-clk@50000000 { -- #clock-cells = <1>; -- compatible = "st,stm32mp1-rcc-clk"; -- -- st,clksrc = < CLK_MPU_PLL1P -- CLK_AXI_PLL2P -- CLK_MCU_HSI -- CLK_PLL12_HSE -- CLK_PLL3_HSE -- CLK_PLL4_HSE -- CLK_RTC_HSE -- CLK_MCO1_DISABLED -- CLK_MCO2_DISABLED -- >; -- -- st,clkdiv = < -- 1 /*MPU*/ -- 0 /*AXI*/ -- 0 /*MCU*/ -- 1 /*APB1*/ -- 1 /*APB2*/ -- 1 /*APB3*/ -- 1 /*APB4*/ -- 5 /*APB5*/ -- 23 /*RTC*/ -- 0 /*MCO1*/ -- 0 /*MCO2*/ -- >; -- -- st,pll@0 { -- cfg = < 1 53 0 0 0 1 >; -- frac = < 0x810 >; -- }; -- st,pll@1 { -- cfg = < 1 43 1 0 0 PQR(0,1,1)>; -- csg = <10 20 1>; -- }; -- st,pll@2 { -- cfg = < 2 85 3 13 3 0>; -- csg = <10 20 SSCG_MODE_CENTER_SPREAD>; -- }; -- st,pll@3 { -- cfg = < 2 78 4 7 9 3>; -- }; -- st,pkcs = < -- CLK_STGEN_HSE -- CLK_CKPER_HSI -- CLK_USBPHY_PLL2P -- CLK_DSI_PLL2Q -- >; -- }; -- }; -- ---------------------------- - other clocks = fixed-clock ---------------------------- -+========================== -+ - The clock tree is also based on 5 fixed-clock in clocks node - used to define the state of associated ST32MP1 oscillators: --- clk-lsi --- clk-lse --- clk-hsi --- clk-hse --- clk-csi -+ - clk-lsi -+ - clk-lse -+ - clk-hsi -+ - clk-hse -+ - clk-csi - - At boot the clock tree initialization will --- enable the oscillator present in device tree --- disable HSI oscillator if the node is absent (always activated by bootrom) -+ - enable oscillators present in device tree -+ - disable HSI oscillator if the node is absent (always activated by bootrom) - - Optional properties : - - a) for external oscillator: "clk-lse", "clk-hse" - -- 4 optional fields are managed -- - "st,bypass" Configure the oscillator bypass mode (HSEBYP, LSEBYP) -- - "st,digbypass" Configure the bypass mode as full-swing digital signal -- (DIGBYP) -- - "st,css" Activate the clock security system (HSECSSON, LSECSSON) -- - "st,drive" (only for LSE) value of the drive for the oscillator -- (see LSEDRV_ define in the file dt-bindings/clock/stm32mp1-clksrc.h) -- -- Example board file: -+ 4 optional fields are managed -+ - "st,bypass" configures the oscillator bypass mode (HSEBYP, LSEBYP) -+ - "st,digbypass" configures the bypass mode as full-swing digital -+ signal (DIGBYP) -+ - "st,css" activates the clock security system (HSECSSON, LSECSSON) -+ - "st,drive" (only for LSE) contains the value of the drive for the -+ oscillator (see LSEDRV_ defined in the file -+ dt-bindings/clock/stm32mp1-clksrc.h) - -+ Example board file: - / { - clocks { - clk_hse: clk-hse { -@@ -200,13 +201,12 @@ a) for external oscillator: "clk-lse", "clk-hse" - - b) for internal oscillator: "clk-hsi" - -- internally HSI clock is fixed to 64MHz for STM32MP157 soc -- in device tree clk-hsi is the clock after HSIDIV (ck_hsi in RCC doc) -- So this clock frequency is used to compute the expected HSI_DIV -- for the clock tree initialisation -- -- ex: for HSIDIV = /1 -+ Internally HSI clock is fixed to 64MHz for STM32MP157 SoC. -+ In device tree, clk-hsi is the clock after HSIDIV (clk_hsi in RCC -+ doc). So this clock frequency is used to compute the expected HSI_DIV -+ for the clock tree initialization. - -+ Example with HSIDIV = /1: - / { - clocks { - clk_hsi: clk-hsi { -@@ -216,8 +216,7 @@ b) for internal oscillator: "clk-hsi" - }; - }; - -- ex: for HSIDIV = /2 -- -+ Example with HSIDIV = /2 - / { - clocks { - clk_hsi: clk-hsi { -@@ -226,3 +225,151 @@ b) for internal oscillator: "clk-hsi" - clock-frequency = <32000000>; - }; - }; -+ -+Example of clock tree initialization -+==================================== -+ -+/ { -+ clocks { -+ u-boot,dm-pre-reloc; -+ clk_hse: clk-hse { -+ u-boot,dm-pre-reloc; -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <24000000>; -+ st,digbypass; -+ }; -+ -+ clk_hsi: clk-hsi { -+ u-boot,dm-pre-reloc; -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <64000000>; -+ }; -+ -+ clk_lse: clk-lse { -+ u-boot,dm-pre-reloc; -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+ }; -+ -+ clk_lsi: clk-lsi { -+ u-boot,dm-pre-reloc; -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32000>; -+ }; -+ -+ clk_csi: clk-csi { -+ u-boot,dm-pre-reloc; -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <4000000>; -+ }; -+ }; -+ -+ soc { -+ -+ rcc: rcc@50000000 { -+ u-boot,dm-pre-reloc; -+ compatible = "st,stm32mp1-rcc", "syscon"; -+ reg = <0x50000000 0x1000>; -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ interrupts = ; -+ -+ st,clksrc = < -+ CLK_MPU_PLL1P -+ CLK_AXI_PLL2P -+ CLK_MCU_PLL3P -+ CLK_PLL12_HSE -+ CLK_PLL3_HSE -+ CLK_PLL4_HSE -+ CLK_RTC_LSE -+ CLK_MCO1_DISABLED -+ CLK_MCO2_DISABLED -+ >; -+ -+ st,clkdiv = < -+ 1 /*MPU*/ -+ 0 /*AXI*/ -+ 0 /*MCU*/ -+ 1 /*APB1*/ -+ 1 /*APB2*/ -+ 1 /*APB3*/ -+ 1 /*APB4*/ -+ 2 /*APB5*/ -+ 23 /*RTC*/ -+ 0 /*MCO1*/ -+ 0 /*MCO2*/ -+ >; -+ -+ st,pkcs = < -+ CLK_CKPER_HSE -+ CLK_FMC_ACLK -+ CLK_QSPI_ACLK -+ CLK_ETH_DISABLED -+ CLK_SDMMC12_PLL4P -+ CLK_DSI_DSIPLL -+ CLK_STGEN_HSE -+ CLK_USBPHY_HSE -+ CLK_SPI2S1_PLL3Q -+ CLK_SPI2S23_PLL3Q -+ CLK_SPI45_HSI -+ CLK_SPI6_HSI -+ CLK_I2C46_HSI -+ CLK_SDMMC3_PLL4P -+ CLK_USBO_USBPHY -+ CLK_ADC_CKPER -+ CLK_CEC_LSE -+ CLK_I2C12_HSI -+ CLK_I2C35_HSI -+ CLK_UART1_HSI -+ CLK_UART24_HSI -+ CLK_UART35_HSI -+ CLK_UART6_HSI -+ CLK_UART78_HSI -+ CLK_SPDIF_PLL4P -+ CLK_FDCAN_PLL4Q -+ CLK_SAI1_PLL3Q -+ CLK_SAI2_PLL3Q -+ CLK_SAI3_PLL3Q -+ CLK_SAI4_PLL3Q -+ CLK_RNG1_LSI -+ CLK_RNG2_LSI -+ CLK_LPTIM1_PCLK1 -+ CLK_LPTIM23_PCLK3 -+ CLK_LPTIM45_LSE -+ >; -+ -+ /* VCO = 1300.0 MHz => P = 650 (CPU) */ -+ pll1: st,pll@0 { -+ cfg = < 2 80 0 0 0 PQR(1,0,0) >; -+ frac = < 0x800 >; -+ u-boot,dm-pre-reloc; -+ }; -+ -+ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), -+ R = 533 (DDR) */ -+ pll2: st,pll@1 { -+ cfg = < 2 65 1 0 0 PQR(1,1,1) >; -+ frac = < 0x1400 >; -+ u-boot,dm-pre-reloc; -+ }; -+ -+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ -+ pll3: st,pll@2 { -+ cfg = < 1 33 1 16 36 PQR(1,1,1) >; -+ frac = < 0x1a04 >; -+ u-boot,dm-pre-reloc; -+ }; -+ -+ /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ -+ pll4: st,pll@3 { -+ cfg = < 3 98 5 7 7 PQR(1,1,1) >; -+ u-boot,dm-pre-reloc; -+ }; -+ }; -+ }; -+}; --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0008-ARM-v2018.11-stm32mp-r2-MISC.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0008-ARM-v2018.11-stm32mp-r2-MISC.patch deleted file mode 100644 index 14945ec..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0008-ARM-v2018.11-stm32mp-r2-MISC.patch +++ /dev/null @@ -1,290 +0,0 @@ -From 8db9dfe442ded4ec2d320d61a5b92d9bc1c771d4 Mon Sep 17 00:00:00 2001 -From: christophe montaud -Date: Mon, 28 Jan 2019 11:07:22 +0100 -Subject: [PATCH 8/8] ARM v2018.11 stm32mp r2 MISC - ---- - Makefile | 2 +- - drivers/remoteproc/rproc-uclass.c | 10 +++++++-- - drivers/remoteproc/stm32_copro.c | 44 +++++++++++++++------------------------ - drivers/video/stm32/stm32_dsi.c | 41 ++++++++++++++++++++++-------------- - 4 files changed, 51 insertions(+), 46 deletions(-) - -diff --git a/Makefile b/Makefile -index 84cb372..693ffae 100644 ---- a/Makefile -+++ b/Makefile -@@ -3,7 +3,7 @@ - VERSION = 2018 - PATCHLEVEL = 11 - SUBLEVEL = --EXTRAVERSION = -stm32mp-r1 -+EXTRAVERSION = -stm32mp-r2 - NAME = - - # *DOCUMENTATION* -diff --git a/drivers/remoteproc/rproc-uclass.c b/drivers/remoteproc/rproc-uclass.c -index 8ea92f7..204e6e8 100644 ---- a/drivers/remoteproc/rproc-uclass.c -+++ b/drivers/remoteproc/rproc-uclass.c -@@ -449,7 +449,10 @@ static int rproc_load_elf_image(struct udevice *dev, unsigned long addr, - if (phdr->p_filesz != phdr->p_memsz) - memset(dst + phdr->p_filesz, 0x00, - phdr->p_memsz - phdr->p_filesz); -- flush_cache((unsigned long)dst, phdr->p_filesz); -+ flush_cache(rounddown((int)dst, ARCH_DMA_MINALIGN), -+ roundup((int)dst + phdr->p_filesz, -+ ARCH_DMA_MINALIGN) - -+ rounddown((int)dst, ARCH_DMA_MINALIGN)); - ++phdr; - } - -@@ -561,7 +564,10 @@ static int rproc_elf_find_load_rsc_table(struct udevice *dev, - src = (void *)fw_addr + shdr->sh_offset; - - memcpy(dst, src, shdr->sh_size); -- flush_cache((unsigned long)dst, shdr->sh_size); -+ flush_cache(rounddown((int)dst, ARCH_DMA_MINALIGN), -+ roundup((int)dst + shdr->sh_size, -+ ARCH_DMA_MINALIGN) - -+ rounddown((int)dst, ARCH_DMA_MINALIGN)); - - return 0; - } -diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c -index 310d077..44230ff 100644 ---- a/drivers/remoteproc/stm32_copro.c -+++ b/drivers/remoteproc/stm32_copro.c -@@ -18,7 +18,6 @@ - - /** - * struct stm32_copro_privdata - power processor private data -- * @loadaddr: base address for loading the power processor - * @reset_ctl: reset controller handle - * @hold_boot_regmap - * @hold_boot_offset -@@ -26,7 +25,6 @@ - * @secured_soc: TZEN flag (register protection) - */ - struct stm32_copro_privdata { -- phys_addr_t loadaddr; - struct reset_ctl reset_ctl; - struct regmap *hold_boot_regmap; - uint hold_boot_offset; -@@ -46,21 +44,9 @@ static int st_of_to_priv(struct udevice *dev, - { - struct regmap *regmap; - const fdt32_t *cell; -- const void *blob = gd->fdt_blob; - uint tz_offset, tz_mask, tzen; - int len, ret; - -- if (!blob) { -- dev_dbg(dev, "no dt?\n"); -- return -EINVAL; -- } -- -- priv->loadaddr = dev_read_addr(dev); -- if (priv->loadaddr == FDT_ADDR_T_NONE) { -- dev_dbg(dev, "no 'reg' property\n"); -- return -EINVAL; -- } -- - regmap = syscon_phandle_to_regmap(dev, "st,syscfg-holdboot"); - if (IS_ERR(regmap)) { - dev_dbg(dev, "unable to find holdboot regmap (%ld)\n", -@@ -123,8 +109,7 @@ static int stm32_copro_probe(struct udevice *dev) - - ret = st_of_to_priv(dev, priv); - -- dev_dbg(dev, "probed with slave_addr=0x%08lX (%d)\n", -- priv->loadaddr, ret); -+ dev_dbg(dev, "probed (%d)\n", ret); - - return ret; - } -@@ -163,6 +148,17 @@ static int stm32_copro_set_hold_boot(struct udevice *dev, bool hold) - return ret; - } - -+static ulong stm32_copro_da_to_pa(struct udevice *dev, ulong da) -+{ -+ /* to update with address translate by DT range */ -+ -+ /* CM4 boot at address 0x0 = RETRAM alias, not available for CA7 load */ -+ if (da >= 0 && da < STM32_RETRAM_SIZE) -+ return (da + STM32_RETRAM_BASE); -+ -+ return da; -+} -+ - /** - * stm32_copro_load() - Loadup the STM32 Cortex-M4 remote processor - * @dev: corresponding STM32 remote processor device -@@ -174,6 +170,7 @@ static int stm32_copro_set_hold_boot(struct udevice *dev, bool hold) - static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size) - { - struct stm32_copro_privdata *priv; -+ phys_addr_t loadaddr; - int ret; - - priv = dev_get_priv(dev); -@@ -186,10 +183,12 @@ static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size) - return ret; - } - -+ /* by default load for copro BOOT address = 0x0 */ -+ loadaddr = stm32_copro_da_to_pa(dev, 0x0); - dev_dbg(dev, "Loading binary from 0x%08lX, size 0x%08lX to 0x%08lX\n", -- addr, size, priv->loadaddr); -+ addr, size, loadaddr); - -- memcpy((void *)priv->loadaddr, (void *)addr, size); -+ memcpy((void *)loadaddr, (void *)addr, size); - - dev_dbg(dev, "Complete!\n"); - return 0; -@@ -241,15 +240,6 @@ static int stm32_copro_reset(struct udevice *dev) - return 0; - } - --ulong stm32_copro_da_to_pa(struct udevice *dev, ulong da) --{ -- /* to update according to lastest DT */ -- if (da >= 0 && da < 0x10000) -- return (da + 0x38000000); -- -- return da; --} -- - static const struct dm_rproc_ops stm32_copro_ops = { - .load = stm32_copro_load, - .start = stm32_copro_start, -diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c -index 09266fe..f8f7c83 100644 ---- a/drivers/video/stm32/stm32_dsi.c -+++ b/drivers/video/stm32/stm32_dsi.c -@@ -242,7 +242,6 @@ static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings, - u32 val; - - /* Update lane capabilities according to hw version */ -- dsi->hw_version = dsi_read(dsi, DSI_VERSION) & VERSION; - dsi->lane_min_kbps = LANE_MIN_KBPS; - dsi->lane_max_kbps = LANE_MAX_KBPS; - if (dsi->hw_version == HWVER_131) { -@@ -310,9 +309,9 @@ static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_stm_phy_ops = { - - static int stm32_dsi_attach(struct udevice *dev) - { -- struct stm32_dsi_priv *priv = dev_get_priv(dev); -+ struct stm32_dsi_priv *dsi = dev_get_priv(dev); - struct dw_mipi_dsi_plat_data *platdata = dev_get_platdata(dev); -- struct mipi_dsi_device *device = &priv->device; -+ struct mipi_dsi_device *device = &dsi->device; - int ret; - - platdata->max_data_lanes = 2; -@@ -336,8 +335,8 @@ static int stm32_dsi_attach(struct udevice *dev) - static int stm32_dsi_set_backlight(struct udevice *dev, int percent) - { - struct dw_mipi_dsi_plat_data *dplat = dev_get_platdata(dev); -- struct stm32_dsi_priv *priv = dev_get_priv(dev); -- struct mipi_dsi_device *device = &priv->device; -+ struct stm32_dsi_priv *dsi = dev_get_priv(dev); -+ struct mipi_dsi_device *device = &dsi->device; - struct udevice *panel = dplat->panel; - struct mipi_dsi_panel_plat *mplat; - int ret; -@@ -359,29 +358,29 @@ static int stm32_dsi_set_backlight(struct udevice *dev, int percent) - - static int stm32_dsi_probe(struct udevice *dev) - { -- struct stm32_dsi_priv *priv = dev_get_priv(dev); -- struct mipi_dsi_device *device = &priv->device; -+ struct stm32_dsi_priv *dsi = dev_get_priv(dev); -+ struct mipi_dsi_device *device = &dsi->device; - struct reset_ctl rst; - struct clk clk; - int ret; - - device->dev = dev; - -- priv->base = (void *)dev_read_addr(dev); -- if ((fdt_addr_t)priv->base == FDT_ADDR_T_NONE) { -+ dsi->base = (void *)dev_read_addr(dev); -+ if ((fdt_addr_t)dsi->base == FDT_ADDR_T_NONE) { - dev_err(dev, "dsi dt register address error\n"); - return -EINVAL; - } - - if (IS_ENABLED(CONFIG_DM_REGULATOR)) { - ret = device_get_supply_regulator(dev, "phy-dsi-supply", -- &priv->vdd_reg); -+ &dsi->vdd_reg); - if (ret && ret != -ENOENT) { - dev_err(dev, "Warning: cannot get phy dsi supply\n"); - return -ENODEV; - } - -- ret = regulator_set_enable(priv->vdd_reg, true); -+ ret = regulator_set_enable(dsi->vdd_reg, true); - if (ret) - return -ENODEV; - } -@@ -389,14 +388,14 @@ static int stm32_dsi_probe(struct udevice *dev) - ret = clk_get_by_name(device->dev, "pclk", &clk); - if (ret) { - dev_err(dev, "peripheral clock get error %d\n", ret); -- regulator_set_enable(priv->vdd_reg, false); -+ regulator_set_enable(dsi->vdd_reg, false); - return -ENODEV; - } - - ret = clk_enable(&clk); - if (ret) { - dev_err(dev, "peripheral clock enable error %d\n", ret); -- regulator_set_enable(priv->vdd_reg, false); -+ regulator_set_enable(dsi->vdd_reg, false); - return -ENODEV; - } - -@@ -404,23 +403,33 @@ static int stm32_dsi_probe(struct udevice *dev) - if (ret) { - dev_err(dev, "pll reference clock get error %d\n", ret); - clk_disable(&clk); -- regulator_set_enable(priv->vdd_reg, false); -+ regulator_set_enable(dsi->vdd_reg, false); - return ret; - } - -- priv->pllref_clk = (unsigned int)clk_get_rate(&clk); -+ dsi->pllref_clk = (unsigned int)clk_get_rate(&clk); - - ret = reset_get_by_index(device->dev, 0, &rst); - if (ret) { - dev_err(dev, "missing dsi hardware reset\n"); - clk_disable(&clk); -- regulator_set_enable(priv->vdd_reg, false); -+ regulator_set_enable(dsi->vdd_reg, false); - return -ENODEV; - } - - /* Reset */ - reset_deassert(&rst); - -+ /* check hardware version */ -+ dsi->hw_version = dsi_read(dsi, DSI_VERSION) & VERSION; -+ if (dsi->hw_version != HWVER_130 && -+ dsi->hw_version != HWVER_131) { -+ dev_err(dev, "bad dsi hardware version\n"); -+ clk_disable(&clk); -+ regulator_set_enable(dsi->vdd_reg, false); -+ return -ENODEV; -+ } -+ - return 0; - } - --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0009-ARM-v2018.11-stm32mp-r3-MACHINE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0009-ARM-v2018.11-stm32mp-r3-MACHINE.patch deleted file mode 100644 index f906d27..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0009-ARM-v2018.11-stm32mp-r3-MACHINE.patch +++ /dev/null @@ -1,1721 +0,0 @@ -From 3aac802adabb5ef4d55d2bfda97d264725aa25ad Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Tue, 17 Sep 2019 13:54:46 +0200 -Subject: [PATCH 09/13] ARM v2018.11 stm32mp r3 MACHINE - ---- - arch/arm/mach-stm32mp/Kconfig | 30 +-- - arch/arm/mach-stm32mp/Makefile | 8 +- - arch/arm/mach-stm32mp/bsec.c | 16 +- - arch/arm/mach-stm32mp/cmd_poweroff.c | 2 +- - arch/arm/mach-stm32mp/cmd_stm32key.c | 3 +- - arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 25 ++- - arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h | 2 +- - .../mach-stm32mp/cmd_stm32prog/stm32prog_serial.c | 44 ++-- - .../arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c | 11 +- - arch/arm/mach-stm32mp/config.mk | 5 +- - arch/arm/mach-stm32mp/cpu.c | 165 ++++++++------- - arch/arm/mach-stm32mp/fdt.c | 224 +++++++++++++++++++++ - arch/arm/mach-stm32mp/include/mach/stm32.h | 6 - - arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h | 2 +- - arch/arm/mach-stm32mp/include/mach/sys_proto.h | 13 ++ - arch/arm/mach-stm32mp/psci.c | 23 ++- - arch/arm/mach-stm32mp/spl.c | 6 +- - arch/arm/mach-stm32mp/stm32-etzpc.c | 199 ------------------ - arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S | 136 +++++++++++++ - arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S | 124 ------------ - arch/arm/mach-stm32mp/syscon.c | 1 - - 21 files changed, 581 insertions(+), 464 deletions(-) - create mode 100644 arch/arm/mach-stm32mp/fdt.c - delete mode 100644 arch/arm/mach-stm32mp/stm32-etzpc.c - create mode 100644 arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S - delete mode 100644 arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S - -diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig -index fbc8195..470b51f 100644 ---- a/arch/arm/mach-stm32mp/Kconfig -+++ b/arch/arm/mach-stm32mp/Kconfig -@@ -39,16 +39,18 @@ config TARGET_STM32MP1 - select STM32_RESET - select STM32_SERIAL - imply BOOTCOUNT_LIMIT -+ imply PRE_CONSOLE_BUFFER -+ imply SILENT_CONSOLE - imply SYSRESET_PSCI if STM32MP1_TRUSTED - imply SYSRESET_SYSCON if !STM32MP1_TRUSTED - help - target STMicroelectronics SOC STM32MP1 family -- STM32MP153 or STM32MP151 -+ STM32MP157, STM32MP153 or STM32MP151 - STMicroelectronics MPU with core ARMv7 -- dual core A7 for STM32MP153, monocore for STM32MP151 -+ dual core A7 for STM32MP157/3, monocore for STM32MP151 - - config STM32MP1_RESET_HALT_WORKAROUND -- bool "workaround for reset halt deubg on stm32mp15x" -+ bool "workaround for reset halt debug on stm32mp15x" - depends on TARGET_STM32MP1 - default y - help -@@ -59,7 +61,6 @@ config STM32MP1_RESET_HALT_WORKAROUND - it can be removed when using the Soc revision - that fixes the limitation. - -- - config STM32MP1_TRUSTED - bool "Support trusted boot with TF-A" - default y if !SPL -@@ -68,7 +69,7 @@ config STM32MP1_TRUSTED - Say Y here to enable boot with TF-A - Trusted boot chain is : - BootRom => TF-A.stm32 (clock & DDR) => U-Boot.stm32 -- TF-A monitor provide ST smc to manage secure devices -+ TF-A monitor provides proprietary smc to manage secure devices - - config STM32MP1_OPTEE - bool "Support trusted boot with TF-A and OPTEE" -@@ -96,8 +97,6 @@ config STM32_ETZPC - Say y to enable STM32 Extended TrustZone Protection - Controller (ETZPC) - --source "board/st/stm32mp1/Kconfig" -- - config CMD_STM32PROG - bool "command stm32prog for STM32CudeProgrammer" - default y -@@ -132,13 +131,18 @@ config SYS_TEXT_BASE - when DDR driver is used: - DDR + 1MB (0xC0100000) - -+config PRE_CON_BUF_ADDR -+ default 0xC02FF000 -+ -+config PRE_CON_BUF_SZ -+ default 4096 -+ - config NR_DRAM_BANKS - default 1 - - config BOOTSTAGE_STASH_ADDR - default 0xC3000000 - -- - if BOOTCOUNT_LIMIT - config SYS_BOOTCOUNT_SINGLEWORD - default y -@@ -149,6 +153,10 @@ config SYS_BOOTCOUNT_ADDR - endif - - if DEBUG_UART -+ -+config DEBUG_UART_BOARD_INIT -+ default y -+ - # debug on UART4 by default - config DEBUG_UART_BASE - default 0x40010000 -@@ -156,10 +164,8 @@ config DEBUG_UART_BASE - # clock source is HSI on reset - config DEBUG_UART_CLOCK - default 64000000 -- --# currently activated for debug / should be deactivated for real product --config DEBUG_UART_BOARD_INIT -- default y - endif - -+source "board/st/stm32mp1/Kconfig" -+ - endif -diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile -index c67bcce..9158a20 100644 ---- a/arch/arm/mach-stm32mp/Makefile -+++ b/arch/arm/mach-stm32mp/Makefile -@@ -9,15 +9,15 @@ obj-y += syscon.o - - ifdef CONFIG_SPL_BUILD - obj-y += spl.o --obj-$(CONFIG_STM32MP1_RESET_HALT_WORKAROUND) += stm32mp1_helper_dgb.o -+obj-$(CONFIG_STM32MP1_RESET_HALT_WORKAROUND) += stm32mp1_helper_dbg.o - else - obj-$(CONFIG_CMD_STM32PROG) += cmd_stm32prog/ - obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o - --obj-$(CONFIG_ARMV7_PSCI) += psci.o - obj-y += bsec.o --obj-y += cmd_poweroff.o -+obj-$(CONFIG_SYSRESET) += cmd_poweroff.o -+obj-$(CONFIG_ARMV7_PSCI) += psci.o - endif - - obj-$(CONFIG_$(SPL_)DM_REGULATOR) += pwr_regulator.o --obj-$(CONFIG_STM32_ETZPC) += stm32-etzpc.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 913dbef..5256378 100644 ---- a/arch/arm/mach-stm32mp/bsec.c -+++ b/arch/arm/mach-stm32mp/bsec.c -@@ -1,4 +1,4 @@ --// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+// SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved - */ -@@ -359,12 +359,13 @@ static int stm32mp_bsec_read(struct udevice *dev, int offset, - bool shadow = true; - int nb_otp = size / sizeof(u32); - int otp; -+ unsigned int offs = offset; - -- if (offset >= STM32_BSEC_OTP_OFFSET) { -- offset -= STM32_BSEC_OTP_OFFSET; -+ if (offs >= STM32_BSEC_OTP_OFFSET) { -+ offs -= STM32_BSEC_OTP_OFFSET; - shadow = false; - } -- otp = offset / sizeof(u32); -+ otp = offs / sizeof(u32); - - if (otp < 0 || (otp + nb_otp - 1) > BSEC_OTP_MAX_VALUE) { - dev_err(dev, "wrong value for otp, max value : %i\n", -@@ -394,12 +395,13 @@ static int stm32mp_bsec_write(struct udevice *dev, int offset, - bool shadow = true; - int nb_otp = size / sizeof(u32); - int otp; -+ unsigned int offs = offset; - -- if (offset >= STM32_BSEC_OTP_OFFSET) { -- offset -= STM32_BSEC_OTP_OFFSET; -+ if (offs >= STM32_BSEC_OTP_OFFSET) { -+ offs -= STM32_BSEC_OTP_OFFSET; - shadow = false; - } -- otp = offset / sizeof(u32); -+ otp = offs / sizeof(u32); - - if (otp < 0 || (otp + nb_otp - 1) > BSEC_OTP_MAX_VALUE) { - dev_err(dev, "wrong value for otp, max value : %d\n", -diff --git a/arch/arm/mach-stm32mp/cmd_poweroff.c b/arch/arm/mach-stm32mp/cmd_poweroff.c -index a6fdc79..f54dd1d 100644 ---- a/arch/arm/mach-stm32mp/cmd_poweroff.c -+++ b/arch/arm/mach-stm32mp/cmd_poweroff.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause - /* -- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved - */ - - #include -diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c -index 4245e6f..6b1e4db 100644 ---- a/arch/arm/mach-stm32mp/cmd_stm32key.c -+++ b/arch/arm/mach-stm32mp/cmd_stm32key.c -@@ -66,7 +66,8 @@ static int confirm_prog(void) - return 0; - } - --int do_stm32key(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -+static int do_stm32key(cmd_tbl_t *cmdtp, int flag, int argc, -+ char * const argv[]) - { - u32 addr; - const char *op = argc >= 2 ? argv[1] : NULL; -diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c -index d263b38..8325b56 100644 ---- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c -+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c -@@ -46,12 +46,17 @@ - EFI_GUID(0xFD58F1C7, 0xBE0D, 0x4338, \ - 0x88, 0xE9, 0xAD, 0x8F, 0x05, 0x0A, 0xEB, 0x18) - -+/* RAW parttion (binary / bootloader) used Linux - reserved UUID */ -+#define LINUX_RESERVED_UUID "8DA63339-0007-60C0-C436-083AC8230908" -+ -+#define DFU_DEV_UNDEFINED 0xFFFF -+ - /* - * unique partition guid (uuid) for partition named "rootfs" - * on each MMC instance = SD Card or eMMC - * allow fixed kernel bootcmd: "rootf=PARTUID=e91c4e10-..." - */ --const static efi_guid_t uuid_mmc[3] = { -+static const efi_guid_t uuid_mmc[3] = { - ROOTFS_MMC0_UUID, - ROOTFS_MMC1_UUID, - ROOTFS_MMC2_UUID -@@ -89,7 +94,7 @@ char *stm32prog_get_error(struct stm32prog_data *data) - u8 stm32prog_header_check(struct raw_header_s *raw_header, - struct image_header_s *header) - { -- int i; -+ unsigned int i; - - header->present = 0; - header->image_checksum = 0x0; -@@ -261,7 +266,7 @@ static int parse_ip(struct stm32prog_data *data, - char *p, struct stm32prog_part_t *part) - { - int result = 0; -- int len = 0; -+ unsigned int len = 0; - - part->dev_id = 0; - if (!strcmp(p, "none")) { -@@ -431,7 +436,7 @@ static int parse_flash_layout(struct stm32prog_data *data, - eof = true; - continue; - } -- /* no break */ -+ /* fall through */ - /* by default continue with the next character */ - default: - p++; -@@ -769,7 +774,7 @@ static int treat_partition_list(struct stm32prog_data *data) - struct stm32prog_part_t *part; - - for (j = 0; j < STM32PROG_MAX_DEV; j++) { -- data->dev[j].dev_type = -1; -+ data->dev[j].dev_type = DFU_DEV_UNDEFINED; - INIT_LIST_HEAD(&data->dev[j].part_list); - } - -@@ -812,7 +817,7 @@ static int treat_partition_list(struct stm32prog_data *data) - } - } - for (j = 0; j < STM32PROG_MAX_DEV; j++) { -- if (data->dev[j].dev_type == -1) { -+ if (data->dev[j].dev_type == DFU_DEV_UNDEFINED) { - /* new device found */ - data->dev[j].dev_type = part->dev_type; - data->dev[j].dev_id = part->dev_id; -@@ -841,7 +846,8 @@ static int create_partitions(struct stm32prog_data *data) - char buf[ENV_BUF_LEN]; - char uuid[UUID_STR_LEN + 1]; - unsigned char *uuid_bin; -- int i, mmc_id; -+ unsigned int mmc_id; -+ int i; - bool rootfs_found; - struct stm32prog_part_t *part; - -@@ -874,7 +880,8 @@ static int create_partitions(struct stm32prog_data *data) - if (part->part_type == PART_BINARY) - offset += snprintf(buf + offset, - ENV_BUF_LEN - offset, -- ",type=data"); -+ ",type=" -+ LINUX_RESERVED_UUID); - else - offset += snprintf(buf + offset, - ENV_BUF_LEN - offset, -@@ -1517,7 +1524,7 @@ static int part_delete(struct stm32prog_data *data, - return ret; - } - --void stm32prog_devices_init(struct stm32prog_data *data) -+static void stm32prog_devices_init(struct stm32prog_data *data) - { - int i; - int ret; -diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h -index 51541bc..08d6e5e 100644 ---- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h -+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h -@@ -139,7 +139,7 @@ struct stm32prog_data { - int full_update; - - /* command internal information */ -- int phase; -+ unsigned int phase; - u32 offset; - char error[255]; - struct stm32prog_part_t *cur_part; -diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c -index 36f9393..f9dee73 100644 ---- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c -+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c -@@ -29,7 +29,7 @@ const u8 cmd_id[] = { - #define NB_CMD sizeof(cmd_id) - - /* DFU support for serial *********************************************/ --struct dfu_entity *stm32prog_get_entity(struct stm32prog_data *data) -+static struct dfu_entity *stm32prog_get_entity(struct stm32prog_data *data) - { - int alt_id; - -@@ -76,6 +76,7 @@ static int stm32prog_read(struct stm32prog_data *data, u8 phase, u32 offset, - u8 *buffer, u32 buffer_size) - { - struct dfu_entity *dfu_entity; -+ u32 size; - int ret; - - /* pr_debug("%s entry\n", __func__); */ -@@ -128,12 +129,15 @@ static int stm32prog_read(struct stm32prog_data *data, u8 phase, u32 offset, - ret, phase, offset); - return ret; - } -- if (ret < buffer_size) { -+ -+ size = ret; -+ -+ if (size < buffer_size) { - data->offset = 0; - data->read_phase = PHASE_END; -- memset(buffer + ret, 0, buffer_size - ret); -+ memset(buffer + size, 0, buffer_size - size); - } else { -- data->offset += ret; -+ data->offset += size; - } - /*pr_debug("%s exit ret=%d\n", __func__, ret);*/ - return ret; -@@ -215,8 +219,10 @@ static int stm32prog_serial_getc_err(void) - - do { - err = ops->getc(down_serial_dev); -- if (err == -EAGAIN) -+ if (err == -EAGAIN) { - ctrlc(); -+ WATCHDOG_RESET(); -+ } - } while ((err == -EAGAIN) && (!had_ctrlc())); - - return err; -@@ -243,6 +249,7 @@ static bool stm32prog_serial_get_buffer(u8 *buffer, u32 *count) - *count -= 1; - } else if (err == -EAGAIN) { - ctrlc(); -+ WATCHDOG_RESET(); - } else { - break; - } -@@ -626,7 +633,7 @@ static void download_command(struct stm32prog_data *data) - u32 packet_number; - u32 result = ACK_BYTE; - u8 ret; -- int i; -+ unsigned int i; - bool error; - int rcv; - -@@ -729,6 +736,10 @@ static void download_command(struct stm32prog_data *data) - if (rcv_xor != my_xor) { - printf("checksum error on packet %d\n", - packet_number); -+ /* wait to be sure that all data are received -+ * in the FIFO before flush -+ */ -+ mdelay(30); - data->packet_number--; - result = NACK_BYTE; - goto end; -@@ -785,7 +796,7 @@ static void download_command(struct stm32prog_data *data) - if (data->cursor <= BL_HEADER_SIZE) - goto end; - /* compute checksum on payload */ -- for (i = size; i < codesize; i++) -+ for (i = (unsigned long)size; i < codesize; i++) - data->checksum += data->buffer[i]; - - if (data->cursor > -@@ -822,10 +833,10 @@ end: - */ - static void read_partition_command(struct stm32prog_data *data) - { -- u32 part_id, codesize, offset = 0, rcv_data; -+ u32 i, part_id, codesize, offset = 0, rcv_data; - long size; - u8 tmp_xor; -- int i, res; -+ int res; - u8 buffer[256]; - - part_id = stm32prog_serial_getc(); -@@ -854,28 +865,29 @@ static void read_partition_command(struct stm32prog_data *data) - } - - pr_debug("%s : %x\n", __func__, part_id); -+ rcv_data = 0; - switch (part_id) { - case PHASE_OTP: -- res = 0; - size = codesize; - if (!stm32prog_otp_read(data, offset, buffer, &size)) -- res = size; -+ rcv_data = size; - break; - case PHASE_PMIC: -- res = 0; - size = codesize; - if (!stm32prog_pmic_read(data, offset, buffer, &size)) -- res = size; -+ rcv_data = size; - break; - default: - res = stm32prog_read(data, part_id, offset, - buffer, codesize); -+ if (res > 0) -+ rcv_data = res; - break; - } -- if (res > 0) { -+ if (rcv_data > 0) { - stm32prog_serial_putc(ACK_BYTE); - /*----------- Send data to the host -----------*/ -- for (i = 0; i < res; i++) -+ for (i = 0; i < rcv_data; i++) - stm32prog_serial_putc(buffer[i]); - /*----------- Send filler to the host -----------*/ - for (; i < codesize; i++) -@@ -951,7 +963,7 @@ bool stm32prog_serial_loop(struct stm32prog_data *data) - /* wait to be sure that all data are received - * in the FIFO before flush (CMD and XOR) - */ -- mdelay(2); -+ mdelay(3); - stm32prog_serial_result(NACK_BYTE); - } else { - /*pr_debug("+ cmd %x\n", counter);*/ -diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c -index c7dd678..f795a9c 100644 ---- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c -+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c -@@ -254,6 +254,7 @@ static const char product[] = - bool stm32prog_usb_loop(struct stm32prog_data *data, int dev) - { - int ret; -+ bool result; - - stm32prog_data = data; - g_dnl_set_product(product); -@@ -267,8 +268,14 @@ bool stm32prog_usb_loop(struct stm32prog_data *data, int dev) - /* found next selected partition */ - stm32prog_next_phase(data); - } -- return (run_usb_dnl_gadget(dev, "usb_dnl_dfu") || -- (stm32prog_data->phase == PHASE_DO_RESET)); -+ -+ ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu") ; -+ -+ result = !!(ret) || (stm32prog_data->phase == PHASE_DO_RESET); -+ -+ stm32prog_data = NULL; -+ -+ return result; - } - - int g_dnl_get_board_bcd_device_number(int gcnum) -diff --git a/arch/arm/mach-stm32mp/config.mk b/arch/arm/mach-stm32mp/config.mk -index bd8944a..d9d39fd 100644 ---- a/arch/arm/mach-stm32mp/config.mk -+++ b/arch/arm/mach-stm32mp/config.mk -@@ -7,7 +7,7 @@ ifndef CONFIG_SPL - ALL-y += u-boot.stm32 - else - ifdef CONFIG_SPL_BUILD --ALL-y += spl/u-boot-spl.stm32 -+ALL-y += u-boot-spl.stm32 - endif - endif - -@@ -25,3 +25,6 @@ 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 5d5ce4a..efe8b79 100644 ---- a/arch/arm/mach-stm32mp/cpu.c -+++ b/arch/arm/mach-stm32mp/cpu.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -15,13 +16,13 @@ - #include - #include - #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) -@@ -49,6 +50,9 @@ - #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 -@@ -79,11 +83,6 @@ - #define PKG_SHIFT 27 - #define PKG_MASK GENMASK(2, 0) - --#define PKG_AA_LBGA448 4 --#define PKG_AB_LBGA354 3 --#define PKG_AC_TFBGA361 2 --#define PKG_AD_TFBGA257 1 -- - DECLARE_GLOBAL_DATA_PTR; - - #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) -@@ -142,6 +141,10 @@ static void security_init(void) - * 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_STM32MP1_TRUSTED */ - -@@ -157,14 +160,18 @@ static void dbgmcu_init(void) - } - #endif /* !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) */ - --static u32 get_bootmode(void) --{ -- u32 boot_mode; - #if !defined(CONFIG_STM32MP1_TRUSTED) && \ - (!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; -@@ -179,12 +186,14 @@ static u32 get_bootmode(void) - clrsetbits_le32(TAMP_BOOT_CONTEXT, - TAMP_BOOT_MODE_MASK, - boot_mode << TAMP_BOOT_MODE_SHIFT); --#else -- /* read TAMP backup register */ -- boot_mode = (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >> -- TAMP_BOOT_MODE_SHIFT; -+} - #endif -- return boot_mode; -+ -+u32 get_bootmode(void) -+{ -+ /* read bootmode from TAMP backup register */ -+ return (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >> -+ TAMP_BOOT_MODE_SHIFT; - } - - /* -@@ -201,15 +210,15 @@ int arch_cpu_init(void) - dbgmcu_init(); - #ifndef CONFIG_STM32MP1_TRUSTED - security_init(); -+ update_bootmode(); - #endif - #endif - -- /* get bootmode from BootRom context: saved in TAMP register */ - boot_mode = get_bootmode(); - - if ((boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART) - gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; --#if defined(CONFIG_DEBUG_UART) &&\ -+#if defined(CONFIG_DEBUG_UART) && \ - !defined(CONFIG_STM32MP1_TRUSTED) && \ - (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) - else -@@ -270,7 +279,7 @@ u32 get_cpu_type(void) - } - - /* Get Package options from OTP */ --static u32 get_cpu_package(void) -+u32 get_cpu_package(void) - { - return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK); - } -@@ -359,7 +368,7 @@ static void setup_boot_mode(void) - u32 boot_ctx = readl(TAMP_BOOT_CONTEXT); - u32 boot_mode = - (boot_ctx & TAMP_BOOT_MODE_MASK) >> TAMP_BOOT_MODE_SHIFT; -- int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1; -+ unsigned int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1; - u32 forced_mode = (boot_ctx & TAMP_BOOT_FORCED_MASK); - struct udevice *dev; - int alias; -@@ -399,14 +408,16 @@ static void setup_boot_mode(void) - env_set("boot_instance", cmd); - break; - case BOOT_FLASH_NAND: -- sprintf(cmd, "%d", instance); - env_set("boot_device", "nand"); -- env_set("boot_instance", cmd); -+ env_set("boot_instance", "0"); - break; - case BOOT_FLASH_NOR: - env_set("boot_device", "nor"); - env_set("boot_instance", "0"); - break; -+ default: -+ pr_debug("unexpected boot mode = %x\n", boot_mode); -+ break; - } - - switch (forced_mode) { -@@ -415,8 +426,8 @@ static void setup_boot_mode(void) - env_set("preboot", "env set preboot; fastboot 0"); - break; - case BOOT_STM32PROG: -- printf("Enter STM32CubeProgrammer mode!\n"); -- env_set("preboot", "env set preboot; stm32prog usb 0"); -+ env_set("boot_device", "usb"); -+ env_set("boot_instance", "0"); - break; - case BOOT_UMS_MMC0: - case BOOT_UMS_MMC1: -@@ -430,8 +441,9 @@ static void setup_boot_mode(void) - env_set("preboot", "env set preboot; run altbootcmd"); - break; - case BOOT_NORMAL: -+ break; - default: -- pr_debug("unexpected boot mode = %x\n", boot_mode); -+ pr_debug("unexpected forced boot mode = %x\n", forced_mode); - break; - } - -@@ -450,12 +462,9 @@ static int setup_mac_address(void) - int i; - u32 otp[2]; - uchar enetaddr[6]; -+ char buf[ARP_HLEN_ASCII + 1]; - struct udevice *dev; - -- /* MAC already in environment */ -- if (eth_env_get_enetaddr("ethaddr", enetaddr)) -- return 0; -- - ret = uclass_get_device_by_driver(UCLASS_MISC, - DM_GET_DRIVER(stm32mp_bsec), - &dev); -@@ -474,9 +483,11 @@ static int setup_mac_address(void) - pr_err("invalid MAC address in OTP %pM", enetaddr); - return -EINVAL; - } -+ - pr_debug("OTP MAC address = %pM\n", enetaddr); -- ret = !eth_env_set_enetaddr("ethaddr", enetaddr); -- if (!ret) -+ sprintf(buf, "%pM", enetaddr); -+ ret = env_set("ethaddr", buf); -+ if (ret) - pr_err("Failed to set mac address %pM from OTP: %d\n", - enetaddr, ret); - #endif -@@ -491,9 +502,6 @@ static int setup_serial_number(void) - struct udevice *dev; - int ret; - -- if (env_get("serial#")) -- return 0; -- - ret = uclass_get_device_by_driver(UCLASS_MISC, - DM_GET_DRIVER(stm32mp_bsec), - &dev); -@@ -511,53 +519,64 @@ static int setup_serial_number(void) - return 0; - } - --int arch_misc_init(void) --{ -- setup_boot_mode(); -- setup_mac_address(); -- setup_serial_number(); - -- return 0; -+#if defined(CONFIG_WDT) && \ -+(defined(CONFIG_SPL_WATCHDOG_SUPPORT) || !defined(CONFIG_SPL_BUILD)) -+/* Called by macro WATCHDOG_RESET */ -+void watchdog_reset(void) -+{ -+ static ulong next_reset; -+ struct udevice *watchdog_dev; -+ ulong now; -+ -+ now = timer_get_us(); -+ -+ /* Do not reset the watchdog too often, only every 1 sec */ -+ if (now > next_reset) { -+ /* -+ * Watchdog has been enabled at SPL stage, to avoid -+ * watchdog_dev bad reference after relocation, we don't save -+ * it in a static variable, we retrieve it each time using -+ * uclass_get_device() call. -+ */ -+ if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) -+ return; -+ -+ wdt_reset(watchdog_dev); -+ next_reset = now + 1000000; -+ } - } - --/* -- * 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, bd_t *bd) -+int watchdog_start(void) - { -- int ret = 0; -- u32 pkg; -+ struct udevice *watchdog_dev; - --#if CONFIG_STM32_ETZPC -- ret = stm32_fdt_fixup_etzpc(blob); -- if (ret) -- return ret; -+ if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { -+ debug("Watchdog: Not found by seq!\n"); -+ if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { -+ puts("Watchdog: Not found!\n"); -+ return 0; -+ } -+ } -+ -+ wdt_start(watchdog_dev, 0, 0); -+ printf("Watchdog: Started\n"); -+ -+ return 0; -+} -+#else -+int watchdog_start(void) -+{ -+ return 0; -+} - #endif - -- switch (get_cpu_package()) { -- case PKG_AA_LBGA448: -- pkg = STM32MP157CAA; -- break; -- case PKG_AB_LBGA354: -- pkg = STM32MP157CAB; -- break; -- case PKG_AC_TFBGA361: -- pkg = STM32MP157CAC; -- break; -- case PKG_AD_TFBGA257: -- pkg = STM32MP157CAD; -- break; -- default: -- pkg = 0; -- break; -- } -- if (pkg) { -- do_fixup_by_compat_u32(blob, "st,stm32mp157-pinctrl", -- "st,package", pkg, false); -- do_fixup_by_compat_u32(blob, "st,stm32mp157-z-pinctrl", -- "st,package", pkg, false); -- } -+int arch_misc_init(void) -+{ -+ watchdog_start(); -+ setup_boot_mode(); -+ setup_mac_address(); -+ setup_serial_number(); - -- return ret; -+ return 0; - } -diff --git a/arch/arm/mach-stm32mp/fdt.c b/arch/arm/mach-stm32mp/fdt.c -new file mode 100644 -index 0000000..259b99a ---- /dev/null -+++ b/arch/arm/mach-stm32mp/fdt.c -@@ -0,0 +1,224 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define ETZPC_DECPROT(n) (STM32_ETZPC_BASE + 0x10 + 4 * (n)) -+#define ETZPC_DECPROT_NB 6 -+ -+#define DECPROT_MASK 0x03 -+#define NB_PROT_PER_REG 0x10 -+#define DECPROT_NB_BITS 2 -+ -+#define DECPROT_SECURED 0x00 -+#define DECPROT_WRITE_SECURE 0x01 -+#define DECPROT_MCU_ISOLATION 0x02 -+#define DECPROT_NON_SECURED 0x03 -+ -+#define ETZPC_RESERVED 0xffffffff -+ -+static const u32 stm32mp1_ip_addr[] = { -+ 0x5c008000, /* 00 stgenc */ -+ 0x54000000, /* 01 bkpsram */ -+ 0x5c003000, /* 02 iwdg1 */ -+ 0x5c000000, /* 03 usart1 */ -+ 0x5c001000, /* 04 spi6 */ -+ 0x5c002000, /* 05 i2c4 */ -+ ETZPC_RESERVED, /* 06 reserved */ -+ 0x54003000, /* 07 rng1 */ -+ 0x54002000, /* 08 hash1 */ -+ 0x54001000, /* 09 cryp1 */ -+ 0x5a003000, /* 0A ddrctrl */ -+ 0x5a004000, /* 0B ddrphyc */ -+ 0x5c009000, /* 0C i2c6 */ -+ ETZPC_RESERVED, /* 0D reserved */ -+ ETZPC_RESERVED, /* 0E reserved */ -+ ETZPC_RESERVED, /* 0F reserved */ -+ 0x40000000, /* 10 tim2 */ -+ 0x40001000, /* 11 tim3 */ -+ 0x40002000, /* 12 tim4 */ -+ 0x40003000, /* 13 tim5 */ -+ 0x40004000, /* 14 tim6 */ -+ 0x40005000, /* 15 tim7 */ -+ 0x40006000, /* 16 tim12 */ -+ 0x40007000, /* 17 tim13 */ -+ 0x40008000, /* 18 tim14 */ -+ 0x40009000, /* 19 lptim1 */ -+ 0x4000a000, /* 1A wwdg1 */ -+ 0x4000b000, /* 1B spi2 */ -+ 0x4000c000, /* 1C spi3 */ -+ 0x4000d000, /* 1D spdifrx */ -+ 0x4000e000, /* 1E usart2 */ -+ 0x4000f000, /* 1F usart3 */ -+ 0x40010000, /* 20 uart4 */ -+ 0x40011000, /* 21 uart5 */ -+ 0x40012000, /* 22 i2c1 */ -+ 0x40013000, /* 23 i2c2 */ -+ 0x40014000, /* 24 i2c3 */ -+ 0x40015000, /* 25 i2c5 */ -+ 0x40016000, /* 26 cec */ -+ 0x40017000, /* 27 dac */ -+ 0x40018000, /* 28 uart7 */ -+ 0x40019000, /* 29 uart8 */ -+ ETZPC_RESERVED, /* 2A reserved */ -+ ETZPC_RESERVED, /* 2B reserved */ -+ 0x4001c000, /* 2C mdios */ -+ ETZPC_RESERVED, /* 2D reserved */ -+ ETZPC_RESERVED, /* 2E reserved */ -+ ETZPC_RESERVED, /* 2F reserved */ -+ 0x44000000, /* 30 tim1 */ -+ 0x44001000, /* 31 tim8 */ -+ ETZPC_RESERVED, /* 32 reserved */ -+ 0x44003000, /* 33 usart6 */ -+ 0x44004000, /* 34 spi1 */ -+ 0x44005000, /* 35 spi4 */ -+ 0x44006000, /* 36 tim15 */ -+ 0x44007000, /* 37 tim16 */ -+ 0x44008000, /* 38 tim17 */ -+ 0x44009000, /* 39 spi5 */ -+ 0x4400a000, /* 3A sai1 */ -+ 0x4400b000, /* 3B sai2 */ -+ 0x4400c000, /* 3C sai3 */ -+ 0x4400d000, /* 3D dfsdm */ -+ 0x4400e000, /* 3E tt_fdcan */ -+ ETZPC_RESERVED, /* 3F reserved */ -+ 0x50021000, /* 40 lptim2 */ -+ 0x50022000, /* 41 lptim3 */ -+ 0x50023000, /* 42 lptim4 */ -+ 0x50024000, /* 43 lptim5 */ -+ 0x50027000, /* 44 sai4 */ -+ 0x50025000, /* 45 vrefbuf */ -+ 0x4c006000, /* 46 dcmi */ -+ 0x4c004000, /* 47 crc2 */ -+ 0x48003000, /* 48 adc */ -+ 0x4c002000, /* 49 hash2 */ -+ 0x4c003000, /* 4A rng2 */ -+ 0x4c005000, /* 4B cryp2 */ -+ ETZPC_RESERVED, /* 4C reserved */ -+ ETZPC_RESERVED, /* 4D reserved */ -+ ETZPC_RESERVED, /* 4E reserved */ -+ ETZPC_RESERVED, /* 4F reserved */ -+ ETZPC_RESERVED, /* 50 sram1 */ -+ ETZPC_RESERVED, /* 51 sram2 */ -+ ETZPC_RESERVED, /* 52 sram3 */ -+ ETZPC_RESERVED, /* 53 sram4 */ -+ ETZPC_RESERVED, /* 54 retram */ -+ 0x49000000, /* 55 otg */ -+ 0x48004000, /* 56 sdmmc3 */ -+ 0x48005000, /* 57 dlybsd3 */ -+ 0x48000000, /* 58 dma1 */ -+ 0x48001000, /* 59 dma2 */ -+ 0x48002000, /* 5A dmamux */ -+ 0x58002000, /* 5B fmc */ -+ 0x58003000, /* 5C qspi */ -+ 0x58004000, /* 5D dlybq */ -+ 0x5800a000, /* 5E eth */ -+ ETZPC_RESERVED, /* 5F reserved */ -+}; -+ -+/* fdt helper */ -+static bool fdt_disable_subnode_by_address(void *fdt, int offset, u32 addr) -+{ -+ int node; -+ -+ for (node = fdt_first_subnode(fdt, offset); -+ node >= 0; -+ node = fdt_next_subnode(fdt, node)) { -+ if (addr == (u32)fdt_getprop(fdt, node, "reg", 0)) { -+ if (fdtdec_get_is_enabled(fdt, node)) { -+ fdt_status_disabled(fdt, node); -+ -+ return true; -+ } -+ return false; -+ } -+ } -+ -+ return false; -+} -+ -+static int stm32_fdt_fixup_etzpc(void *fdt) -+{ -+ const u32 *array; -+ int array_size, i; -+ int soc_node, offset, shift; -+ u32 addr, status, decprot[ETZPC_DECPROT_NB]; -+ -+ array = stm32mp1_ip_addr; -+ array_size = ARRAY_SIZE(stm32mp1_ip_addr); -+ -+ for (i = 0; i < ETZPC_DECPROT_NB; i++) -+ decprot[i] = readl(ETZPC_DECPROT(i)); -+ -+ soc_node = fdt_path_offset(fdt, "/soc"); -+ if (soc_node < 0) -+ return soc_node; -+ -+ for (i = 0; i < array_size; i++) { -+ offset = i / NB_PROT_PER_REG; -+ shift = (i % NB_PROT_PER_REG) * DECPROT_NB_BITS; -+ status = (decprot[offset] >> shift) & DECPROT_MASK; -+ addr = array[i]; -+ -+ debug("ETZPC: 0x%08x decprot %d=%d\n", addr, i, status); -+ -+ if (addr == ETZPC_RESERVED || -+ status == DECPROT_NON_SECURED) -+ continue; -+ -+ if (fdt_disable_subnode_by_address(fdt, soc_node, addr)) -+ printf("ETZPC: 0x%08x node disabled, decprot %d=%d\n", -+ addr, i, status); -+ } -+ -+ return 0; -+} -+ -+/* -+ * 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, bd_t *bd) -+{ -+ int ret = 0; -+ u32 pkg; -+ -+ if (CONFIG_IS_ENABLED(STM32_ETZPC)) { -+ ret = stm32_fdt_fixup_etzpc(blob); -+ if (ret) -+ return ret; -+ } -+ -+ switch (get_cpu_package()) { -+ case PKG_AA_LBGA448: -+ pkg = STM32MP157CAA; -+ break; -+ case PKG_AB_LBGA354: -+ pkg = STM32MP157CAB; -+ break; -+ case PKG_AC_TFBGA361: -+ pkg = STM32MP157CAC; -+ break; -+ case PKG_AD_TFBGA257: -+ pkg = STM32MP157CAD; -+ break; -+ default: -+ pkg = 0; -+ break; -+ } -+ if (pkg) { -+ do_fixup_by_compat_u32(blob, "st,stm32mp157-pinctrl", -+ "st,package", pkg, false); -+ do_fixup_by_compat_u32(blob, "st,stm32mp157-z-pinctrl", -+ "st,package", pkg, false); -+ } -+ -+ return ret; -+} -diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h -index 36b885b..5283e90 100644 ---- a/arch/arm/mach-stm32mp/include/mach/stm32.h -+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h -@@ -44,8 +44,6 @@ - /* enumerated used to identify the SYSCON driver instance */ - enum { - STM32MP_SYSCON_UNKNOWN, -- STM32MP_SYSCON_ETZPC, -- STM32MP_SYSCON_IWDG, - STM32MP_SYSCON_PWR, - STM32MP_SYSCON_STGEN, - STM32MP_SYSCON_SYSCFG, -@@ -126,9 +124,5 @@ enum forced_boot_mode { - - #define BSEC_OTP_BOARD 59 - --#if CONFIG_STM32_ETZPC --int stm32_fdt_fixup_etzpc(void *fdt); --#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 538958f..9ee7fb7 100644 ---- a/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h -+++ b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h -@@ -1,6 +1,6 @@ - /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ - /* -- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved - */ - - #ifndef __STM32MP1_SMC_H__ -diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h -index c565748..871324b 100644 ---- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h -+++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h -@@ -19,3 +19,16 @@ u32 get_cpu_type(void); - - /* return CPU_REV constants */ - 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 -+ -+/* return boot mode */ -+u32 get_bootmode(void); -+/* start IWDG watchdog */ -+int watchdog_start(void); -diff --git a/arch/arm/mach-stm32mp/psci.c b/arch/arm/mach-stm32mp/psci.c -index c2dff38..708a699 100644 ---- a/arch/arm/mach-stm32mp/psci.c -+++ b/arch/arm/mach-stm32mp/psci.c -@@ -47,14 +47,14 @@ static u32 __secure stm32mp_get_gicd_base_address(void) - return (periphbase & CBAR_MASK) + GIC_DIST_OFFSET; - } - --static void __secure stm32mp_smp_kick_all_cpus(void) -+static void __secure stm32mp_raise_sgi0(int cpu) - { - u32 gic_dist_addr; - - gic_dist_addr = stm32mp_get_gicd_base_address(); - -- /* kick all CPUs (except this one) by writing to GICD_SGIR */ -- writel(1U << 24, gic_dist_addr + GICD_SGIR); -+ /* ask cpu with SGI0 */ -+ writel((BIT(cpu) << 16), gic_dist_addr + GICD_SGIR); - } - - void __secure psci_arch_cpu_entry(void) -@@ -62,6 +62,9 @@ void __secure psci_arch_cpu_entry(void) - u32 cpu = psci_get_cpu_id(); - - psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON); -+ -+ /* reset magic in TAMP register */ -+ writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER); - } - - int __secure psci_features(u32 function_id, u32 psci_fid) -@@ -127,6 +130,17 @@ int __secure psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc, - if (psci_state[cpu] == PSCI_AFFINITY_LEVEL_ON) - return ARM_PSCI_RET_ALREADY_ON; - -+ /* reset magic in TAMP register */ -+ if (readl(TAMP_BACKUP_MAGIC_NUMBER)) -+ writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER); -+ -+ /* -+ * ROM code need a first SGI0 after core reset -+ * core is ready when magic is set to 0 in ROM code -+ */ -+ while (readl(TAMP_BACKUP_MAGIC_NUMBER)) -+ stm32mp_raise_sgi0(cpu); -+ - /* store target PC and context id*/ - psci_save(cpu, pc, context_id); - -@@ -142,7 +156,8 @@ int __secure psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc, - writel(BOOT_API_A7_CORE0_MAGIC_NUMBER, - TAMP_BACKUP_MAGIC_NUMBER); - -- stm32mp_smp_kick_all_cpus(); -+ /* Generate an IT to start the core */ -+ stm32mp_raise_sgi0(cpu); - - return ARM_PSCI_RET_SUCCESS; - } -diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c -index fa393cc..6c8744f 100644 ---- a/arch/arm/mach-stm32mp/spl.c -+++ b/arch/arm/mach-stm32mp/spl.c -@@ -24,8 +24,7 @@ u32 spl_boot_device(void) - { - u32 boot_mode; - -- boot_mode = (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >> -- TAMP_BOOT_MODE_SHIFT; -+ boot_mode = get_bootmode(); - - switch (boot_mode) { - case BOOT_FLASH_SD_1: -@@ -50,6 +49,7 @@ u32 spl_boot_device(void) - case BOOT_FLASH_NOR_QSPI: - return BOOT_DEVICE_SPI; - } -+ - return BOOT_DEVICE_MMC1; - } - -@@ -119,6 +119,8 @@ void board_init_f(ulong dummy) - /* enable console uart printing */ - preloader_console_init(); - -+ watchdog_start(); -+ - ret = uclass_get_device(UCLASS_RAM, 0, &dev); - if (ret) { - printf("DRAM init failed: %d\n", ret); -diff --git a/arch/arm/mach-stm32mp/stm32-etzpc.c b/arch/arm/mach-stm32mp/stm32-etzpc.c -deleted file mode 100644 -index ea6dcca..0000000 ---- a/arch/arm/mach-stm32mp/stm32-etzpc.c -+++ /dev/null -@@ -1,199 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause --/* -- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -- */ -- --#include --#include --#include --#include --#include -- --#define ETZPC_DECPROT(n) (0x10 + 4 * (n)) --#define ETZPC_DECPROT_NB 6 -- --#define ETZPC_IP_VER 0x3F4 -- --#define IP_VER_STM32MP1 0x00000020 -- --#define DECPROT_MASK 0x03 --#define NB_PROT_PER_REG 0x10 --#define DECPROT_NB_BITS 2 -- --#define DECPROT_SECURED 0x00 --#define DECPROT_WRITE_SECURE 0x01 --#define DECPROT_MCU_ISOLATION 0x02 --#define DECPROT_NON_SECURED 0x03 -- --#define ETZPC_RESERVED 0xffffffff -- --static const u32 stm32mp1_ip_addr[] = { -- 0x5c008000, /* 00 stgenc */ -- 0x54000000, /* 01 bkpsram */ -- 0x5c003000, /* 02 iwdg1 */ -- 0x5c000000, /* 03 usart1 */ -- 0x5c001000, /* 04 spi6 */ -- 0x5c002000, /* 05 i2c4 */ -- ETZPC_RESERVED, /* 06 reserved */ -- 0x54003000, /* 07 rng1 */ -- 0x54002000, /* 08 hash1 */ -- 0x54001000, /* 09 cryp1 */ -- 0x5a003000, /* 0A ddrctrl */ -- 0x5a004000, /* 0B ddrphyc */ -- 0x5c009000, /* 0C i2c6 */ -- ETZPC_RESERVED, /* 0D reserved */ -- ETZPC_RESERVED, /* 0E reserved */ -- ETZPC_RESERVED, /* 0F reserved */ -- 0x40000000, /* 10 tim2 */ -- 0x40001000, /* 11 tim3 */ -- 0x40002000, /* 12 tim4 */ -- 0x40003000, /* 13 tim5 */ -- 0x40004000, /* 14 tim6 */ -- 0x40005000, /* 15 tim7 */ -- 0x40006000, /* 16 tim12 */ -- 0x40007000, /* 17 tim13 */ -- 0x40008000, /* 18 tim14 */ -- 0x40009000, /* 19 lptim1 */ -- 0x4000a000, /* 1A wwdg1 */ -- 0x4000b000, /* 1B spi2 */ -- 0x4000c000, /* 1C spi3 */ -- 0x4000d000, /* 1D spdifrx */ -- 0x4000e000, /* 1E usart2 */ -- 0x4000f000, /* 1F usart3 */ -- 0x40010000, /* 20 uart4 */ -- 0x40011000, /* 21 uart5 */ -- 0x40012000, /* 22 i2c1 */ -- 0x40013000, /* 23 i2c2 */ -- 0x40014000, /* 24 i2c3 */ -- 0x40015000, /* 25 i2c5 */ -- 0x40016000, /* 26 cec */ -- 0x40017000, /* 27 dac */ -- 0x40018000, /* 28 uart7 */ -- 0x40019000, /* 29 uart8 */ -- ETZPC_RESERVED, /* 2A reserved */ -- ETZPC_RESERVED, /* 2B reserved */ -- 0x4001c000, /* 2C mdios */ -- ETZPC_RESERVED, /* 2D reserved */ -- ETZPC_RESERVED, /* 2E reserved */ -- ETZPC_RESERVED, /* 2F reserved */ -- 0x44000000, /* 30 tim1 */ -- 0x44001000, /* 31 tim8 */ -- ETZPC_RESERVED, /* 32 reserved */ -- 0x44003000, /* 33 usart6 */ -- 0x44004000, /* 34 spi1 */ -- 0x44005000, /* 35 spi4 */ -- 0x44006000, /* 36 tim15 */ -- 0x44007000, /* 37 tim16 */ -- 0x44008000, /* 38 tim17 */ -- 0x44009000, /* 39 spi5 */ -- 0x4400a000, /* 3A sai1 */ -- 0x4400b000, /* 3B sai2 */ -- 0x4400c000, /* 3C sai3 */ -- 0x4400d000, /* 3D dfsdm */ -- 0x4400e000, /* 3E tt_fdcan */ -- ETZPC_RESERVED, /* 3F reserved */ -- 0x50021000, /* 40 lptim2 */ -- 0x50022000, /* 41 lptim3 */ -- 0x50023000, /* 42 lptim4 */ -- 0x50024000, /* 43 lptim5 */ -- 0x50027000, /* 44 sai4 */ -- 0x50025000, /* 45 vrefbuf */ -- 0x4c006000, /* 46 dcmi */ -- 0x4c004000, /* 47 crc2 */ -- 0x48003000, /* 48 adc */ -- 0x4c002000, /* 49 hash2 */ -- 0x4c003000, /* 4A rng2 */ -- 0x4c005000, /* 4B cryp2 */ -- ETZPC_RESERVED, /* 4C reserved */ -- ETZPC_RESERVED, /* 4D reserved */ -- ETZPC_RESERVED, /* 4E reserved */ -- ETZPC_RESERVED, /* 4F reserved */ -- ETZPC_RESERVED, /* 50 sram1 */ -- ETZPC_RESERVED, /* 51 sram2 */ -- ETZPC_RESERVED, /* 52 sram3 */ -- ETZPC_RESERVED, /* 53 sram4 */ -- ETZPC_RESERVED, /* 54 retram */ -- 0x49000000, /* 55 otg */ -- 0x48004000, /* 56 sdmmc3 */ -- 0x48005000, /* 57 dlybsd3 */ -- 0x48000000, /* 58 dma1 */ -- 0x48001000, /* 59 dma2 */ -- 0x48002000, /* 5A dmamux */ -- 0x58002000, /* 5B fmc */ -- 0x58003000, /* 5C qspi */ -- 0x58004000, /* 5D dlybq */ -- 0x5800a000, /* 5E eth */ -- ETZPC_RESERVED, /* 5F reserved */ --}; -- --/* fdt helper */ --static bool fdt_disable_subnode_by_address(void *fdt, int offset, u32 addr) --{ -- int node; -- -- for (node = fdt_first_subnode(fdt, offset); -- node >= 0; -- node = fdt_next_subnode(fdt, node)) { -- if (addr == (u32)fdt_getprop(fdt, node, "reg", 0)) { -- if (fdtdec_get_is_enabled(fdt, node)) { -- fdt_status_disabled(fdt, node); -- -- return true; -- } -- return false; -- } -- } -- -- return false; --} -- --int stm32_fdt_fixup_etzpc(void *fdt) --{ -- void *base; -- u32 version; -- const u32 *array; -- int array_size, i; -- int soc_node, offset, shift; -- u32 addr, status, decprot[ETZPC_DECPROT_NB]; -- -- base = syscon_get_first_range(STM32MP_SYSCON_ETZPC); -- if (IS_ERR(base)) -- return PTR_ERR(base); -- -- version = readl(base + ETZPC_IP_VER); -- -- switch (version) { -- case IP_VER_STM32MP1: -- array = stm32mp1_ip_addr; -- array_size = ARRAY_SIZE(stm32mp1_ip_addr); -- break; -- default: -- return 0; -- } -- -- for (i = 0; i < ETZPC_DECPROT_NB; i++) -- decprot[i] = readl(base + ETZPC_DECPROT(i)); -- -- soc_node = fdt_path_offset(fdt, "/soc"); -- if (soc_node < 0) -- return soc_node; -- -- for (i = 0; i < array_size; i++) { -- offset = i / NB_PROT_PER_REG; -- shift = (i % NB_PROT_PER_REG) * DECPROT_NB_BITS; -- status = (decprot[offset] >> shift) & DECPROT_MASK; -- addr = array[i]; -- -- debug("ETZPC: 0x%08x decprot %d=%d\n", addr, i, status); -- -- if (addr == ETZPC_RESERVED || -- status == DECPROT_NON_SECURED) -- continue; -- -- if (fdt_disable_subnode_by_address(fdt, soc_node, addr)) -- printf("ETZPC: 0x%08x node disabled, decprot %d=%d\n", -- addr, i, status); -- } -- -- return 0; --} -diff --git a/arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S b/arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S -new file mode 100644 -index 0000000..37a1b06 ---- /dev/null -+++ b/arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S -@@ -0,0 +1,136 @@ -+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ -+/* -+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -+ * -+ */ -+ -+/***************************************************************************** -+ * This file is only needed for current Soc revision which has a limitation on -+ * debug reset halt. This can be removed when using the Soc revision that -+ * fixes the limitation. Anyway, this source code identifies the Soc revision -+ * and is only executed if it corresponds, so it can be kept on other -+ * revisions without any consequence. -+ ****************************************************************************/ -+ -+#include -+#include -+ -+#define BIT(nr) (1 << (nr)) -+ -+#define BSEC_OTP_DATA0_ADDR 0x5C005200 -+#define BSEC_OTP_DATA0_CLOSED BIT(6) -+ -+#define DBG_DSCR_ADDR 0x500D0088 -+#define DBG_DSCR_HDBGEN BIT(14) -+ -+#define RCC_DBGCFGR_ADDR 0x5000080C -+#define RCC_DBGCFGR_DBGCKEN BIT(8) -+ -+#define PWR_CR1_ADDR 0x50001000 -+#define PWR_CR1_DBP BIT(8) -+ -+#define DBGMCU_IDC_ADDR 0x50081000 -+#define DBGMCU_IDC_MASK 0xFFFF0FFF -+#define DBGMCU_IDC_VALUE 0x20000500 -+ -+#define TAMP_BKP_REGISTER_20 (0x5C00A100 + (20 << 2)) -+ -+ -+ .globl save_boot_params -+ -+ENTRY(save_boot_params) -+ /* -+ * This function is the first call after reset. -+ * Boot rom parameters are stored in r0..r3, so we mustn't use them -+ * here. And because they are saved in r9..r12 just after the -+ * execution of this function, we should firstly use these registers. -+ * And then, if more registers needed, we have to start by using -+ * r8, and then r7 and so on. By this way, debug will be done in -+ * conditions closed to the initial context. -+ */ -+ -+ /* -+ * Check Sec Close bit in OTP (word 0 bit 6). If enabled, do not allow -+ * debug session and exit function. -+ */ -+ ldr r12, =BSEC_OTP_DATA0_ADDR -+ ldr r12, [r12] -+ ands r11, r12, #BSEC_OTP_DATA0_CLOSED -+ bne func_exit -+ -+ /* Check Soc revision */ -+ ldr r12, =RCC_DBGCFGR_ADDR -+ ldr r11, [r12] /* read RCC_DBGCFGR (r11) */ -+ orr r10, r11, #RCC_DBGCFGR_DBGCKEN -+ str r10, [r12] /* update RCC_DBGCFGR */ -+ ldr r10, =DBGMCU_IDC_ADDR -+ ldr r10, [r10] /* read DBGMCU_IDC (r10) */ -+ str r11, [r12] /* restore RCC_DBGCFGR (r11) */ -+ ldr r12, =DBGMCU_IDC_MASK -+ and r10, r12 /* mask reserved bits */ -+ ldr r11, =DBGMCU_IDC_VALUE -+ teq r10, r11 /* test DBGMCU_IDC */ -+ bne func_exit -+ -+ /* Disable the backup domain write protection */ -+ ldr r12, =PWR_CR1_ADDR -+ ldr r11, [r12] -+ orr r11, r11, #PWR_CR1_DBP -+ str r11, [r12] -+poll_dbp: -+ ldr r11, [r12] -+ tst r11, #PWR_CR1_DBP -+ beq poll_dbp -+ -+ /* Clear tamper 20 bit 16 if set */ -+ ldr r12, =TAMP_BKP_REGISTER_20 -+ ldr r11, [r12] -+ tst r11, #(BIT(16)) -+ beq func_exit -+ bic r11, #(BIT(16)) -+ str r11, [r12] -+ -+ /* Re-enable the backup domain write protection */ -+ ldr r12, =PWR_CR1_ADDR -+ ldr r11, [r12] -+ bic r11, #PWR_CR1_DBP -+ str r11, [r12] -+poll_dbp_2: -+ ldr r11, [r12] -+ tst r11, #PWR_CR1_DBP -+ bne poll_dbp_2 -+ -+ /* Get current time + 1 second */ -+ /* CNTFRQ */ -+ mrc p15, 0, r12, c14, c0, 0 -+ /* CNTPCT_64 */ -+ mrrc p15, 0, r11, r10, c14 -+ add r12, r12, r11 -+ -+loop: -+ /* Check A7 DBG_DSCR HDBGEN bit value */ -+ ldr r10, =DBG_DSCR_ADDR -+ ldr r10, [r10] -+ tst r10, #DBG_DSCR_HDBGEN -+ beq loop_continue -+ /* Sw break */ -+ bkpt 5 -+ /* Jump entrypoint */ -+ b reset -+loop_continue: -+ /* Check 1 second expiration */ -+ mrrc p15, 0, r10, r9, c14 -+ /* Check if MSB 64-bit increment needed */ -+ cmp r12, r11 -+ bmi msb_incr -+ cmp r12, r10 -+ bmi func_exit -+ b loop -+msb_incr: -+ cmp r12, r10 -+ bpl loop -+ cmp r11, r10 -+ bmi loop -+func_exit: -+ b save_boot_params_ret -+ENDPROC(save_boot_params) -diff --git a/arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S b/arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S -deleted file mode 100644 -index 29f8e1f..0000000 ---- a/arch/arm/mach-stm32mp/stm32mp1_helper_dgb.S -+++ /dev/null -@@ -1,124 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ --/* -- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved -- * -- */ -- --/***************************************************************************** -- * This file is only needed for current Soc revision which has a limitation on -- * debug reset halt. This can be removed when using the Soc revision that -- * fixes the limitation. Anyway, this source code identifies the Soc revision -- * and is only executed if it corresponds, so it can be kept on other -- * revisions without any consequence. -- ****************************************************************************/ -- --#include --#include -- --#define BIT(nr) (1 << (nr)) -- --#define DBG_DSCR_ADDR 0x500D0088 --#define DBG_DSCR_HDBGEN BIT(14) -- --#define RCC_DBGCFGR_ADDR 0x5000080C --#define RCC_DBGCFGR_DBGCKEN BIT(8) -- --#define PWR_CR1_ADDR 0x50001000 --#define PWR_CR1_DBP BIT(8) -- --#define DBGMCU_IDC_ADDR 0x50081000 --#define DBGMCU_IDC_MASK 0xFFFF0FFF --#define DBGMCU_IDC_VALUE 0x20000500 -- --#define TAMP_BKP_REGISTER_20 (0x5C00A100 + (20 << 2)) -- -- -- .globl save_boot_params -- --ENTRY(save_boot_params) -- /* -- * This function is the first call after reset. -- * Boot rom parameters are stored in r0..r3, so we mustn't use them -- * here. And because they are saved in r9..r12 just after the -- * execution of this function, we should firstly use these registers. -- * And then, if more registers needed, we have to start by using -- * r8, and then r7 and so on. By this way, debug will be done in -- * conditions closed to the initial context. -- */ -- -- /* Check Soc revision */ -- ldr r12, =RCC_DBGCFGR_ADDR -- ldr r11, [r12] /* read RCC_DBGCFGR (r11) */ -- orr r10, r11, #RCC_DBGCFGR_DBGCKEN -- str r10, [r12] /* update RCC_DBGCFGR */ -- ldr r10, =DBGMCU_IDC_ADDR -- ldr r10, [r10] /* read DBGMCU_IDC (r10) */ -- str r11, [r12] /* restore RCC_DBGCFGR (r11) */ -- ldr r12, =DBGMCU_IDC_MASK -- and r10, r12 /* mask reserved bits */ -- ldr r11, =DBGMCU_IDC_VALUE -- teq r10, r11 /* test DBGMCU_IDC */ -- bne func_exit -- -- /* Disable the backup domain write protection */ -- ldr r12, =PWR_CR1_ADDR -- ldr r11, [r12] -- orr r11, r11, #PWR_CR1_DBP -- str r11, [r12] --poll_dbp: -- ldr r11, [r12] -- tst r11, #PWR_CR1_DBP -- beq poll_dbp -- -- /* Clear tamper 20 bit 16 if set */ -- ldr r12, =TAMP_BKP_REGISTER_20 -- ldr r11, [r12] -- tst r11, #(BIT(16)) -- beq func_exit -- bic r11, #(BIT(16)) -- str r11, [r12] -- -- /* Re-enable the backup domain write protection */ -- ldr r12, =PWR_CR1_ADDR -- ldr r11, [r12] -- bic r11, #PWR_CR1_DBP -- str r11, [r12] --poll_dbp_2: -- ldr r11, [r12] -- tst r11, #PWR_CR1_DBP -- bne poll_dbp_2 -- -- /* Get current time + 1 second */ -- /* CNTFRQ */ -- mrc p15, 0, r12, c14, c0, 0 -- /* CNTPCT_64 */ -- mrrc p15, 0, r11, r10, c14 -- add r12, r12, r11 -- --loop: -- /* Check A7 DBG_DSCR HDBGEN bit value */ -- ldr r10, =DBG_DSCR_ADDR -- ldr r10, [r10] -- tst r10, #DBG_DSCR_HDBGEN -- beq loop_continue -- /* Sw break */ -- bkpt 5 -- /* Jump entrypoint */ -- b reset --loop_continue: -- /* Check 1 second expiration */ -- mrrc p15, 0, r10, r9, c14 -- /* Check if MSB 64-bit increment needed */ -- cmp r12, r11 -- bmi msb_incr -- cmp r12, r10 -- bmi func_exit -- b loop --msb_incr: -- cmp r12, r10 -- bpl loop -- cmp r11, r10 -- bmi loop --func_exit: -- b save_boot_params_ret --ENDPROC(save_boot_params) -diff --git a/arch/arm/mach-stm32mp/syscon.c b/arch/arm/mach-stm32mp/syscon.c -index 242f834..e10c42e 100644 ---- a/arch/arm/mach-stm32mp/syscon.c -+++ b/arch/arm/mach-stm32mp/syscon.c -@@ -9,7 +9,6 @@ - #include - - static const struct udevice_id stm32mp_syscon_ids[] = { -- { .compatible = "st,stm32mp1-etzpc", .data = STM32MP_SYSCON_ETZPC }, - { .compatible = "st,stm32mp1-pwr", .data = STM32MP_SYSCON_PWR }, - { .compatible = "st,stm32-stgen", .data = STM32MP_SYSCON_STGEN }, - { .compatible = "st,stm32mp157-syscfg", --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0010-ARM-v2018.11-stm32mp-r3-BOARD.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0010-ARM-v2018.11-stm32mp-r3-BOARD.patch deleted file mode 100644 index 455b591..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0010-ARM-v2018.11-stm32mp-r3-BOARD.patch +++ /dev/null @@ -1,1012 +0,0 @@ -From 1a87553f3934c4be22e3713945b0e0f8a2580c75 Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Tue, 17 Sep 2019 13:55:06 +0200 -Subject: [PATCH 10/13] ARM v2018.11 stm32mp r3 BOARD - ---- - board/st/stm32mp1/MAINTAINERS | 5 +- - board/st/stm32mp1/README | 51 ++-- - board/st/stm32mp1/board.c | 4 +- - board/st/stm32mp1/cmd_stboard.c | 2 +- - board/st/stm32mp1/stm32mp1.c | 621 ++++++++++++++++++++++++++-------------- - 5 files changed, 449 insertions(+), 234 deletions(-) - -diff --git a/board/st/stm32mp1/MAINTAINERS b/board/st/stm32mp1/MAINTAINERS -index 6c9710a..3bf4c21 100644 ---- a/board/st/stm32mp1/MAINTAINERS -+++ b/board/st/stm32mp1/MAINTAINERS -@@ -1,11 +1,10 @@ - STM32MP1 BOARD - M: Patrick Delaunay --M: Christophe Kerello - L: uboot-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers) - S: Maintained - F: arch/arm/dts/stm32mp157* - F: board/st/stm32mp1 --F: configs/stm32mp15_trusted_defconfig --F: configs/stm32mp15_optee_defconfig - F: configs/stm32mp15_basic_defconfig -+F: configs/stm32mp15_optee_defconfig -+F: configs/stm32mp15_trusted_defconfig - F: include/configs/stm32mp1.h -diff --git a/board/st/stm32mp1/README b/board/st/stm32mp1/README -index 4ebcfb4..b710602 100644 ---- a/board/st/stm32mp1/README -+++ b/board/st/stm32mp1/README -@@ -49,20 +49,26 @@ BootRom => FSBL in SYSRAM => SSBL in DDR => OS (Linux Kernel) - with FSBL = First Stage Bootloader - SSBL = Second Stage Bootloader - --2 boot configurations are supported: -+3 boot configurations are supported: - - 1) The "Trusted" boot chain (defconfig_file : stm32mp15_trusted_defconfig) - BootRom => FSBL = Trusted Firmware-A (TF-A) => SSBL = U-Boot - TF-A performs a full initialization of Secure peripherals and installs a - secure monitor. - U-Boot is running in normal world and uses TF-A monitor -- to access to secure resources -+ to access to secure resources. - --2) The "Basic" boot chain (defconfig_file : stm32mp15_basic_defconfig) -+2) The "Trusted & OP-TEE" boot chain (defconfig_file : stm32mp15_optee_defconfig) -+ BootRom => FSBL = Trusted Firmware-A (TF-A) => SSBL = U-Boot -+ TF-A performs a full initialization of Secure peripherals and installs OP-TEE -+ from specific partitions (teeh, teed, teex). -+ U-Boot is running in normal world and uses OP-TEE monitor to access. -+ -+3) The "Basic" boot chain (defconfig_file : stm32mp15_basic_defconfig) - BootRom => FSBL = U-Boot SPL => SSBL = U-Boot - SPL has limited security initialisation - 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) -+ with only PSCI support (Power State Coordination Interface defined by ARM). - - All the STM32MP1 boards supported by U-Boot use the same generic board - stm32mp1 which support all the bootable devices. -@@ -108,13 +114,18 @@ the supported device trees for stm32mp157 are: - - for example: use one output directory for each configuration - # export KBUILD_OUTPUT=stm32mp15_trusted -+ # export KBUILD_OUTPUT=stm32mp15_optee - # export KBUILD_OUTPUT=stm32mp15_basic - -+ you can build outside of code directory: -+ # export KBUILD_OUTPUT=../build/stm32mp15_trusted -+ - 4. Configure U-Boot: - - # make - - - For trusted boot mode : "stm32mp15_trusted_defconfig" -+ - For trusted & optee boot mode : "stm32mp15_optee_defconfig" - - For basic boot mode: "stm32mp15_basic_defconfig" - - 5. Configure the device-tree and build the U-Boot image: -@@ -127,7 +138,12 @@ the supported device trees for stm32mp157 are: - # make stm32mp15_trusted_defconfig - # make DEVICE_TREE=stm32mp157c-ev1 all - -- b) basic boot on dk2 -+ b) trusted & OP-TEE boot on dk1 -+ # export KBUILD_OUTPUT=stm32mp15_optee -+ # make stm32mp15_optee_defconfig -+ # make DEVICE_TREE=stm32mp157a-dk1 all -+ -+ c) basic boot on dk2 - # export KBUILD_OUTPUT=stm32mp15_basic - # make stm32mp15_basic_defconfig - # make DEVICE_TREE=stm32mp157c-dk2 all -@@ -140,7 +156,7 @@ the supported device trees for stm32mp157 are: - So in the output directory (selected by KBUILD_OUTPUT), - you can found the needed files: - -- a) For Trusted boot -+ a) For Trusted boot (with or without OP-TEE) - + FSBL = tf-a.stm32 (provided by TF-A compilation) - + SSBL = u-boot.stm32 - -@@ -160,7 +176,6 @@ You can select the boot mode, - ----------------------------------- - Reserved 0 0 0 - NOR 0 0 1 -- SD-Card 1 1 1 - SD-Card 1 0 1 - eMMC 0 1 0 - NAND 0 1 1 -@@ -193,14 +208,14 @@ The minimal requirements for STMP32MP1 boot up to U-Boot are: - - one ssbl partition for U-Boot - - 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 | -- | * | - | - | Boot/Rootfs | -- ----- ------- --------- --------------- -+ ----- ------- --------- -------------- -+ | 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 | -+ | * | - | - | Boot/Rootfs | -+ ----- ------- --------- -------------- - - (*) add bootable partition for extlinux.conf - following Generic Distribution -@@ -224,7 +239,7 @@ for example: with gpt table with 128 entries - - you can add other partitions for kernel - one partition rootfs for example: -- -n 3:5154: -c 4:rootfs \ -+ -n 4:5154: -c 4:rootfs \ - - c) copy the FSBL (2 times) and SSBL file on the correct partition. - in this example in partition 1 to 3 -@@ -239,7 +254,7 @@ for example: with gpt table with 128 entries - # dd if=tf-a.stm32 of=/dev/mmcblk0p2 - # dd if=u-boot.stm32 of=/dev/mmcblk0p3 - --To boot from SDCard, select BootPinMode = 1 1 1 and reset. -+To boot from SDCard, select BootPinMode = 1 0 1 and reset. - - 8. Prepare eMMC - =============== -@@ -248,7 +263,7 @@ You can use U-Boot to copy binary in eMMC. - In the next example, you need to boot from SDCARD and the images (u-boot-spl.stm32, u-boot.img) - are presents on SDCARD (mmc 0) in ext4 partition 4 (bootfs). - --To boot from SDCard, select BootPinMode = 1 1 1 and reset. -+To boot from SDCard, select BootPinMode = 1 0 1 and reset. - - Then you update the eMMC with the next U-Boot command : - -diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c -index b6e5288..c3d832f 100644 ---- a/board/st/stm32mp1/board.c -+++ b/board/st/stm32mp1/board.c -@@ -47,7 +47,7 @@ int board_ddr_power_init(enum ddr_type ddr_type) - ret = uclass_get_device_by_driver(UCLASS_PMIC, - DM_GET_DRIVER(pmic_stpmic1), &dev); - if (ret) -- /* No PMIC on power discrete board */ -+ /* No PMIC on board */ - return 0; - - switch (ddr_type) { -@@ -149,7 +149,7 @@ int board_ddr_power_init(enum ddr_type ddr_type) - - mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); - -- /* Enable VDD_DDR22 =BUCK2 */ -+ /* Enable VDD_DDR2 =BUCK2 */ - ret = pmic_clrsetbits(dev, - STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), - STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA); -diff --git a/board/st/stm32mp1/cmd_stboard.c b/board/st/stm32mp1/cmd_stboard.c -index 38b1c1b..03d4b52 100644 ---- a/board/st/stm32mp1/cmd_stboard.c -+++ b/board/st/stm32mp1/cmd_stboard.c -@@ -11,7 +11,7 @@ - - static bool check_stboard(u16 board) - { -- int i; -+ unsigned int i; - const u16 st_board_id[] = { - 0x1272, - 0x1263, -diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c -index 5dc6296..f852b1e 100644 ---- a/board/st/stm32mp1/stm32mp1.c -+++ b/board/st/stm32mp1/stm32mp1.c -@@ -2,28 +2,34 @@ - /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved - */ -- - #include - #include - #include -+#include - #include - #include - #include -+#include - #include - #include -+#include - #include - #include - #include -+#include - #include -+#include - #include - #include - #include - #include - #include -+#include - #include - #include - #include - #include -+#include - #include - #include - #include -@@ -37,6 +43,9 @@ - #define SYSCFG_CMPENSETR 0x24 - #define SYSCFG_PMCCLRR 0x44 - -+#define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0) -+#define SYSCFG_BOOTR_BOOTPD_SHIFT 4 -+ - #define SYSCFG_IOCTRLSETR_HSLVEN_TRACE BIT(0) - #define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI BIT(1) - #define SYSCFG_IOCTRLSETR_HSLVEN_ETH BIT(2) -@@ -63,9 +72,10 @@ - */ - DECLARE_GLOBAL_DATA_PTR; - -+#define USB_LOW_THRESHOLD_UV 200000 - #define USB_WARNING_LOW_THRESHOLD_UV 660000 - #define USB_START_LOW_THRESHOLD_UV 1230000 --#define USB_START_HIGH_THRESHOLD_UV 2100000 -+#define USB_START_HIGH_THRESHOLD_UV 2150000 - - int checkboard(void) - { -@@ -76,7 +86,9 @@ int checkboard(void) - const char *fdt_compat; - int fdt_compat_len; - -- if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED)) -+ if (IS_ENABLED(CONFIG_STM32MP1_OPTEE)) -+ mode = "op-tee"; -+ else if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED)) - mode = "trusted"; - else - mode = "basic"; -@@ -155,47 +167,6 @@ static void board_key_check(void) - #endif - } - --bool board_is_dk2(void) --{ -- if (of_machine_is_compatible("st,stm32mp157c-dk2")) -- return true; -- -- return false; --} -- --int board_late_init(void) --{ --#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG -- const void *fdt_compat; -- int fdt_compat_len; -- -- fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible", -- &fdt_compat_len); -- if (fdt_compat && fdt_compat_len) { -- if (strncmp(fdt_compat, "st,", 3) != 0) -- env_set("board_name", fdt_compat); -- else -- env_set("board_name", fdt_compat + 3); -- } --#endif -- -- return 0; --} -- --#ifdef CONFIG_STM32_SDMMC2 --/* this is a weak define that we are overriding */ --int board_mmc_init(void) --{ -- return 0; --} --#endif -- --#ifdef CONFIG_STM32_QSPI --void board_qspi_init(void) --{ --} --#endif /* CONFIG_STM32_QSPI */ -- - #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) - - /* -@@ -230,19 +201,12 @@ static struct reset_ctl usbotg_reset; - /* STUSB1600_CC_CONNECTION_STATUS bitfields */ - #define STUSB1600_CC_ATTACH BIT(0) - --static int stusb1600_init(void) -+static int stusb1600_init(ofnode node) - { - struct udevice *dev, *bus; -- ofnode node; - int ret; - u32 chip_addr; - -- node = ofnode_by_compatible(ofnode_null(), "st,stusb1600"); -- if (!ofnode_valid(node)) { -- printf("stusb1600 not found\n"); -- return -ENODEV; -- } -- - ret = ofnode_read_u32(node, "reg", &chip_addr); - if (ret) - return -EINVAL; -@@ -274,9 +238,11 @@ static int stusb1600_cable_connected(void) - return status & STUSB1600_CC_ATTACH; - } - --void board_usbotg_init(void) -+static void board_usbotg_init(void) - { -+ ofnode usb1600_node; - int node; -+ int count; - struct fdtdec_phandle_args args; - struct udevice *dev; - const void *blob = gd->fdt_blob; -@@ -353,11 +319,18 @@ void board_usbotg_init(void) - "g-rx-fifo-size", 0); - stm32mp_otg_data.np_tx_fifo_sz = fdtdec_get_int(blob, node, - "g-np-tx-fifo-size", 0); -- stm32mp_otg_data.tx_fifo_sz = fdtdec_get_int(blob, node, -- "g-tx-fifo-size", 0); - -- if (fdtdec_get_bool(blob, node, "usb1600")) { -- stusb1600_init(); -+ count = fdtdec_get_int_array_count(blob, node, "g-tx-fifo-size", -+ &stm32mp_otg_data.tx_fifo_sz_array[DWC2_SIZE_OFFS], -+ ARRAY_SIZE(stm32mp_otg_data.tx_fifo_sz_array)); -+ -+ if (count != -FDT_ERR_NOTFOUND) -+ stm32mp_otg_data.tx_fifo_sz_array[DWC2_SIZE_NB_OFFS] = count; -+ -+ /* if node stusb1600 is present, means DK1 or DK2 board */ -+ usb1600_node = ofnode_by_compatible(ofnode_null(), "st,stusb1600"); -+ if (ofnode_valid(usb1600_node)) { -+ stusb1600_init(usb1600_node); - return; - } - -@@ -426,107 +399,6 @@ int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name) - } - #endif /* CONFIG_USB_GADGET */ - --static void sysconf_init(void) --{ -- u8 *syscfg; --#ifdef CONFIG_DM_REGULATOR -- struct udevice *pwr_dev; -- struct udevice *pwr_reg; -- struct udevice *dev; -- int ret; -- u32 otp = 0; --#endif -- u32 bootr; -- -- syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); -- debug("SYSCFG: init @0x%p\n", syscfg); -- -- /* interconnect update : select master using the port 1 */ -- /* LTDC = AXI_M9 */ -- /* GPU = AXI_M8 */ -- /* today information is hardcoded in U-Boot */ -- writel(BIT(9), syscfg + SYSCFG_ICNR); -- debug("[0x%x] SYSCFG.icnr = 0x%08x (LTDC and GPU)\n", -- (u32)syscfg + SYSCFG_ICNR, readl(syscfg + SYSCFG_ICNR)); -- -- /* disable Pull-Down for boot pin connected to VDD */ -- bootr = readl(syscfg + SYSCFG_BOOTR); -- bootr |= (bootr & 0x7 << 4); -- writel(bootr, syscfg + SYSCFG_BOOTR); -- debug("[0x%x] SYSCFG.bootr = 0x%08x\n", -- (u32)syscfg + SYSCFG_BOOTR, readl(syscfg + SYSCFG_BOOTR)); -- --#ifdef CONFIG_DM_REGULATOR -- /* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI -- * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection. -- * The customer will have to disable this for low frequencies -- * or if AFMUX is selected but the function not used, typically for -- * TRACE. Otherwise, impact on power consumption. -- * -- * WARNING: -- * enabling High Speed mode while VDD>2.7V -- * with the OTP product_below_2v5 (OTP 18, BIT 13) -- * erroneously set to 1 can damage the IC! -- * => U-Boot set the register only if VDD < 2.7V (in DT) -- * but this value need to be consistent with board design -- */ -- ret = syscon_get_by_driver_data(STM32MP_SYSCON_PWR, &pwr_dev); -- if (!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 = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4); -- if (!ret) -- otp = otp & BIT(13); -- -- /* get VDD = pwr-supply */ -- ret = device_get_supply_regulator(pwr_dev, "pwr-supply", -- &pwr_reg); -- -- /* check if VDD is Low Voltage */ -- if (!ret) { -- if (regulator_get_value(pwr_reg) < 2700000) { -- writel(SYSCFG_IOCTRLSETR_HSLVEN_TRACE | -- SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI | -- SYSCFG_IOCTRLSETR_HSLVEN_ETH | -- SYSCFG_IOCTRLSETR_HSLVEN_SDMMC | -- SYSCFG_IOCTRLSETR_HSLVEN_SPI, -- syscfg + SYSCFG_IOCTRLSETR); -- -- if (!otp) -- pr_err("product_below_2v5=0: HSLVEN protected by HW\n"); -- } else { -- if (otp) -- pr_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n"); -- } -- } else { -- debug("VDD unknown"); -- } -- } --#endif -- debug("[0x%x] SYSCFG.IOCTRLSETR = 0x%08x\n", -- (u32)syscfg + SYSCFG_IOCTRLSETR, -- readl(syscfg + SYSCFG_IOCTRLSETR)); -- -- /* activate automatic I/O compensation -- * warning: need to ensure CSI enabled and ready in clock driver -- */ -- writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR); -- -- while (!(readl(syscfg + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY)) -- ; -- clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); -- -- debug("[0x%x] SYSCFG.cmpcr = 0x%08x\n", -- (u32)syscfg + SYSCFG_CMPCR, readl(syscfg + SYSCFG_CMPCR)); --} -- - /* board interface eth init */ - /* this is a weak define that we are overriding */ - int board_interface_eth_init(int interface_type, bool eth_clk_sel_reg, -@@ -563,6 +435,9 @@ int board_interface_eth_init(int interface_type, bool eth_clk_sel_reg, - debug("%s: PHY_INTERFACE_MODE_RMII\n", __func__); - 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; -@@ -621,18 +496,47 @@ static int setup_led(enum led_state_t cmd) - } - #endif /* CONFIG_LED */ - -+static void __maybe_unused led_error_blink(u32 nb_blink) -+{ -+#ifdef CONFIG_LED -+ int ret; -+ struct udevice *led; -+ u32 i; -+#endif -+ -+ if (!nb_blink) -+ return; -+ -+#ifdef CONFIG_LED -+ ret = get_led(&led, "u-boot,error-led"); -+ if (!ret) { -+ /* make u-boot,error-led blinking */ -+ /* if U32_MAX and 125ms interval, for 17.02 years */ -+ for (i = 0; i < 2 * nb_blink; i++) { -+ led_set_state(led, LEDST_TOGGLE); -+ mdelay(125); -+ WATCHDOG_RESET(); -+ } -+ } -+#endif -+ -+ /* infinite: the boot process must be stopped */ -+ if (nb_blink == U32_MAX) -+ hang(); -+} -+ - #ifdef CONFIG_ADC - static int board_check_usb_power(void) - { - struct ofnode_phandle_args adc_args; - struct udevice *adc; -- struct udevice *led; - ofnode node; - unsigned int raw; - int max_uV = 0; -+ int min_uV = USB_START_HIGH_THRESHOLD_UV; - int ret, uV, adc_count; -- u8 i, nb_blink; -- -+ u32 nb_blink; -+ u8 i; - node = ofnode_path("/config"); - if (!ofnode_valid(node)) { - debug("%s: no /config node?\n", __func__); -@@ -684,6 +588,8 @@ static int board_check_usb_power(void) - if (!adc_raw_to_uV(adc, raw, &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 { -@@ -698,37 +604,169 @@ static int board_check_usb_power(void) - * continue. - */ - if (max_uV > USB_START_LOW_THRESHOLD_UV && -- max_uV < USB_START_HIGH_THRESHOLD_UV) -+ max_uV <= USB_START_HIGH_THRESHOLD_UV && -+ min_uV <= USB_LOW_THRESHOLD_UV) - return 0; - -- /* Stop boot process and make u-boot,error-led blinking */ -- pr_err("\n*******************************************\n"); -+ pr_err("****************************************************\n"); - -- if (max_uV < USB_WARNING_LOW_THRESHOLD_UV) { -- pr_err("* WARNING 500mA power supply detected *\n"); -- nb_blink = 2; -- } else { -- pr_err("* WARNING 1.5A power supply detected *\n"); -- nb_blink = 3; -+ /* -+ * If highest and lowest value are either both below -+ * USB_LOW_THRESHOLD_UV or both above USB_LOW_THRESHOLD_UV, that -+ * means USB TYPE-C is in unattached mode, this is an issue, make -+ * u-boot,error-led blinking and stop boot process. -+ */ -+ if ((max_uV > USB_LOW_THRESHOLD_UV && -+ min_uV > USB_LOW_THRESHOLD_UV) || -+ (max_uV <= USB_LOW_THRESHOLD_UV && -+ min_uV <= USB_LOW_THRESHOLD_UV)) { -+ pr_err("* ERROR USB TYPE-C connection in unattached mode *\n"); -+ pr_err("* Check that USB TYPE-C cable is correctly plugged *\n"); -+ /* with 125ms interval, led will blink for 17.02 years ....*/ -+ nb_blink = U32_MAX; - } - -- pr_err("* Current too low, use a 3A power supply! *\n"); -- pr_err("*******************************************\n\n"); -+ if (max_uV > USB_LOW_THRESHOLD_UV && -+ max_uV <= USB_WARNING_LOW_THRESHOLD_UV && -+ min_uV <= USB_LOW_THRESHOLD_UV) { -+ pr_err("* WARNING 500mA power supply detected *\n"); -+ nb_blink = 2; -+ } - -- ret = get_led(&led, "u-boot,error-led"); -- if (ret) -- return ret; -+ if (max_uV > USB_WARNING_LOW_THRESHOLD_UV && -+ max_uV <= USB_START_LOW_THRESHOLD_UV && -+ min_uV <= USB_LOW_THRESHOLD_UV) { -+ pr_err("* WARNING 1.5mA power supply detected *\n"); -+ nb_blink = 3; -+ } - -- for (i = 0; i < nb_blink * 2; i++) { -- led_set_state(led, LEDST_TOGGLE); -- mdelay(125); -+ /* -+ * If highest value is above 2.15 Volts that means that the USB TypeC -+ * supplies more than 3 Amp, this is not compliant with TypeC specification -+ */ -+ if (max_uV > USB_START_HIGH_THRESHOLD_UV) { -+ pr_err("* USB TYPE-C charger not compliant with *\n"); -+ pr_err("* specification *\n"); -+ pr_err("****************************************************\n\n"); -+ /* with 125ms interval, led will blink for 17.02 years ....*/ -+ nb_blink = U32_MAX; -+ } else { -+ pr_err("* Current too low, use a 3A power supply! *\n"); -+ pr_err("****************************************************\n\n"); - } -- led_set_state(led, LEDST_ON); -+ -+ led_error_blink(nb_blink); - - return 0; - } - #endif /* CONFIG_ADC */ - -+static void sysconf_init(void) -+{ -+#ifndef CONFIG_STM32MP1_TRUSTED -+ u8 *syscfg; -+#ifdef CONFIG_DM_REGULATOR -+ struct udevice *pwr_dev; -+ struct udevice *pwr_reg; -+ struct udevice *dev; -+ int ret; -+ u32 otp = 0; -+#endif -+ u32 bootr; -+ -+ syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); -+ debug("SYSCFG: init @0x%p\n", syscfg); -+ -+ /* interconnect update : select master using the port 1 */ -+ /* LTDC = AXI_M9 */ -+ /* GPU = AXI_M8 */ -+ /* today information is hardcoded in U-Boot */ -+ writel(BIT(9), syscfg + SYSCFG_ICNR); -+ debug("[0x%x] SYSCFG.icnr = 0x%08x (LTDC and GPU)\n", -+ (u32)syscfg + SYSCFG_ICNR, readl(syscfg + SYSCFG_ICNR)); -+ -+ /* disable Pull-Down for boot pin connected to VDD */ -+ bootr = readl(syscfg + SYSCFG_BOOTR); -+ bootr &= ~(SYSCFG_BOOTR_BOOT_MASK << SYSCFG_BOOTR_BOOTPD_SHIFT); -+ bootr |= (bootr & SYSCFG_BOOTR_BOOT_MASK) << SYSCFG_BOOTR_BOOTPD_SHIFT; -+ writel(bootr, syscfg + SYSCFG_BOOTR); -+ debug("[0x%x] SYSCFG.bootr = 0x%08x\n", -+ (u32)syscfg + SYSCFG_BOOTR, readl(syscfg + SYSCFG_BOOTR)); -+ -+#ifdef CONFIG_DM_REGULATOR -+ /* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI -+ * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection. -+ * The customer will have to disable this for low frequencies -+ * or if AFMUX is selected but the function not used, typically for -+ * TRACE. Otherwise, impact on power consumption. -+ * -+ * WARNING: -+ * enabling High Speed mode while VDD>2.7V -+ * with the OTP product_below_2v5 (OTP 18, BIT 13) -+ * erroneously set to 1 can damage the IC! -+ * => U-Boot set the register only if VDD < 2.7V (in DT) -+ * but this value need to be consistent with board design -+ */ -+ ret = syscon_get_by_driver_data(STM32MP_SYSCON_PWR, &pwr_dev); -+ if (!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 = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4); -+ if (!ret) -+ otp = otp & BIT(13); -+ -+ ret = uclass_get_device_by_driver(UCLASS_PMIC, -+ DM_GET_DRIVER(stm32mp_pwr_pmic), -+ &dev); -+ -+ /* get VDD = vdd-supply */ -+ ret = device_get_supply_regulator(dev, "vdd-supply", &pwr_reg); -+ -+ /* check if VDD is Low Voltage */ -+ if (!ret) { -+ if (regulator_get_value(pwr_reg) < 2700000) { -+ writel(SYSCFG_IOCTRLSETR_HSLVEN_TRACE | -+ SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI | -+ SYSCFG_IOCTRLSETR_HSLVEN_ETH | -+ SYSCFG_IOCTRLSETR_HSLVEN_SDMMC | -+ SYSCFG_IOCTRLSETR_HSLVEN_SPI, -+ syscfg + SYSCFG_IOCTRLSETR); -+ -+ if (!otp) -+ pr_err("product_below_2v5=0: HSLVEN protected by HW\n"); -+ } else { -+ if (otp) -+ pr_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n"); -+ } -+ } else { -+ debug("VDD unknown"); -+ } -+ } -+#endif -+ debug("[0x%x] SYSCFG.IOCTRLSETR = 0x%08x\n", -+ (u32)syscfg + SYSCFG_IOCTRLSETR, -+ readl(syscfg + SYSCFG_IOCTRLSETR)); -+ -+ /* activate automatic I/O compensation -+ * warning: need to ensure CSI enabled and ready in clock driver -+ */ -+ writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR); -+ -+ while (!(readl(syscfg + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY)) -+ ; -+ clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); -+ -+ debug("[0x%x] SYSCFG.cmpcr = 0x%08x\n", -+ (u32)syscfg + SYSCFG_CMPCR, readl(syscfg + SYSCFG_CMPCR)); -+#endif -+} -+ - #ifdef CONFIG_DM_REGULATOR - /* Fix to make I2C1 usable on DK2 for touchscreen usage in kernel */ - static int dk2_i2c1_fix(void) -@@ -787,6 +825,63 @@ error: - } - #endif - -+enum env_location env_get_location(enum env_operation op, int prio) -+{ -+ u32 bootmode = get_bootmode(); -+ -+ if (prio) -+ return ENVL_UNKNOWN; -+ -+ switch (bootmode & TAMP_BOOT_DEVICE_MASK) { -+#ifdef CONFIG_ENV_IS_IN_EXT4 -+ case BOOT_FLASH_SD: -+ case BOOT_FLASH_EMMC: -+ return ENVL_EXT4; -+#endif -+#ifdef CONFIG_ENV_IS_IN_UBI -+ case BOOT_FLASH_NAND: -+ return ENVL_UBI; -+#endif -+#ifdef CONFIG_ENV_IS_IN_SPI_FLASH -+ case BOOT_FLASH_NOR: -+ return ENVL_SPI_FLASH; -+#endif -+ default: -+ return ENVL_NOWHERE; -+ } -+} -+ -+#if defined(CONFIG_ENV_IS_IN_EXT4) -+const char *env_ext4_get_intf(void) -+{ -+ u32 bootmode = get_bootmode(); -+ -+ switch (bootmode & TAMP_BOOT_DEVICE_MASK) { -+ case BOOT_FLASH_SD: -+ case BOOT_FLASH_EMMC: -+ return "mmc"; -+ default: -+ return ""; -+ } -+} -+ -+const char *env_ext4_get_dev_part(void) -+{ -+ static char *const dev_part[] = {"0:auto", "1:auto", "2:auto"}; -+ u32 bootmode = get_bootmode(); -+ -+ return dev_part[(bootmode & TAMP_BOOT_INSTANCE_MASK) - 1]; -+} -+#endif -+ -+static __maybe_unused bool board_is_dk2(void) -+{ -+ if (of_machine_is_compatible("st,stm32mp157c-dk2")) -+ return true; -+ -+ return false; -+} -+ - /* board dependent setup after realloc */ - int board_init(void) - { -@@ -820,14 +915,6 @@ int board_init(void) - - sysconf_init(); - --#ifdef CONFIG_STM32_SDMMC2 -- board_mmc_init(); --#endif /* CONFIG_STM32_SDMMC2 */ -- --#ifdef CONFIG_STM32_QSPI -- board_qspi_init(); --#endif /* CONFIG_STM32_QSPI */ -- - #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) - board_usbotg_init(); - #endif -@@ -835,6 +922,51 @@ int board_init(void) - return 0; - } - -+int board_late_init(void) -+{ -+ -+ char *boot_device; -+#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG -+ const void *fdt_compat; -+ int fdt_compat_len; -+ int ret; -+ u32 otp; -+ struct udevice *dev; -+ char buf[10]; -+ -+ fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible", -+ &fdt_compat_len); -+ if (fdt_compat && fdt_compat_len) { -+ if (strncmp(fdt_compat, "st,", 3) != 0) -+ env_set("board_name", fdt_compat); -+ else -+ env_set("board_name", fdt_compat + 3); -+ } -+ ret = uclass_get_device_by_driver(UCLASS_MISC, -+ DM_GET_DRIVER(stm32mp_bsec), -+ &dev); -+ -+ if (!ret) -+ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), -+ &otp, sizeof(otp)); -+ if (!ret && otp) { -+ snprintf(buf, sizeof(buf), "0x%04x", otp >> 16); -+ env_set("board_id", buf); -+ -+ snprintf(buf, sizeof(buf), "0x%04x", -+ ((otp >> 8) & 0xF) - 1 + 0xA); -+ env_set("board_rev", buf); -+ } -+#endif -+ -+ /* Check the boot-source to disable bootdelay */ -+ boot_device = env_get("boot_device"); -+ if (!strcmp(boot_device, "serial") || !strcmp(boot_device, "usb")) -+ env_set("bootdelay", "0"); -+ -+ return 0; -+} -+ - void board_quiesce_devices(void) - { - #ifdef CONFIG_LED -@@ -843,32 +975,101 @@ void board_quiesce_devices(void) - } - - #ifdef CONFIG_SYS_MTDPARTS_RUNTIME -+ -+#define MTDPARTS_LEN 256 -+#define MTDIDS_LEN 128 -+ -+/** -+ * The mtdparts_nand0 and mtdparts_nor0 variable tends to be long. -+ * If we need to access it before the env is relocated, then we need -+ * to use our own stack buffer. gd->env_buf will be too small. -+ * -+ * @param buf temporary buffer pointer MTDPARTS_LEN long -+ * @return mtdparts variable string, NULL if not found -+ */ -+static const char *env_get_mtdparts(const char *str, char *buf) -+{ -+ if (gd->flags & GD_FLG_ENV_READY) -+ return env_get(str); -+ if (env_get_f(str, buf, MTDPARTS_LEN) != -1) -+ return buf; -+ return NULL; -+} -+ -+/** -+ * update the variables "mtdids" and "mtdparts" with content of mtdparts_ -+ */ -+static void board_get_mtdparts(const char *dev, -+ char *mtdids, -+ char *mtdparts) -+{ -+ char env_name[32] = "mtdparts_"; -+ char tmp_mtdparts[MTDPARTS_LEN]; -+ const char *tmp; -+ -+ /* name of env variable to read = mtdparts_ */ -+ strcat(env_name, dev); -+ tmp = env_get_mtdparts(env_name, tmp_mtdparts); -+ if (tmp) { -+ /* mtdids: "=, ...." */ -+ if (mtdids[0] != '\0') -+ strcat(mtdids, ","); -+ strcat(mtdids, dev); -+ strcat(mtdids, "="); -+ strcat(mtdids, dev); -+ -+ /* mtdparts: "mtdparts=:>;..." */ -+ if (mtdparts[0] != '\0') -+ strncat(mtdparts, ";", MTDPARTS_LEN); -+ else -+ strcat(mtdparts, "mtdparts="); -+ strncat(mtdparts, dev, MTDPARTS_LEN); -+ strncat(mtdparts, ":", MTDPARTS_LEN); -+ strncat(mtdparts, tmp, MTDPARTS_LEN); -+ } -+} -+ - void board_mtdparts_default(const char **mtdids, const char **mtdparts) - { -+ struct mtd_info *mtd; - struct udevice *dev; -- char *s_nand0 = NULL, *s_nor0 = NULL; -- static char parts[256]; -- static char ids[22]; -- -- if (!uclass_get_device(UCLASS_MTD, 0, &dev)) -- s_nand0 = env_get("mtdparts_nand0"); -- -- if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) -- s_nor0 = env_get("mtdparts_nor0"); -- -- strcpy(ids, ""); -- strcpy(parts, ""); -- if (s_nand0 && s_nor0) { -- snprintf(ids, sizeof(ids), "nor0=nor0,nand0=nand0"); -- snprintf(parts, sizeof(parts), -- "mtdparts=nor0:%s;nand0:%s", s_nor0, s_nand0); -- } else if (s_nand0) { -- snprintf(ids, sizeof(ids), "nand0=nand0"); -- snprintf(parts, sizeof(parts), "mtdparts=nand0:%s", s_nand0); -- } else if (s_nor0) { -- snprintf(ids, sizeof(ids), "nor0=nor0"); -- snprintf(parts, sizeof(parts), "mtdparts=nor0:%s", s_nor0); -+ static char parts[3 * MTDPARTS_LEN + 1]; -+ static char ids[MTDIDS_LEN + 1]; -+ static bool mtd_initialized; -+ -+ if (mtd_initialized) { -+ *mtdids = ids; -+ *mtdparts = parts; -+ return; -+ } -+ -+ memset(parts, 0, sizeof(parts)); -+ memset(ids, 0, sizeof(ids)); -+ -+ /* probe all MTD devices */ -+ for (uclass_first_device(UCLASS_MTD, &dev); -+ dev; -+ uclass_next_device(&dev)) { -+ pr_debug("mtd device = %s\n", dev->name); -+ } -+ -+ mtd = get_mtd_device_nm("nand0"); -+ if (!IS_ERR_OR_NULL(mtd)) { -+ board_get_mtdparts("nand0", ids, parts); -+ put_mtd_device(mtd); - } -+ -+ mtd = get_mtd_device_nm("spi-nand0"); -+ if (!IS_ERR_OR_NULL(mtd)) { -+ board_get_mtdparts("spi-nand0", ids, parts); -+ put_mtd_device(mtd); -+ } -+ -+ if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) { -+ board_get_mtdparts("nor0", ids, parts); -+ } -+ -+ mtd_initialized = true; - *mtdids = ids; - *mtdparts = parts; - debug("%s:mtdids=%s & mtdparts=%s\n", __func__, ids, parts); -@@ -913,7 +1114,7 @@ int ft_board_setup(void *blob, bd_t *bd) - } - #endif - --void board_stm32copro_image_process(ulong fw_image, size_t fw_size) -+static void board_stm32copro_image_process(ulong fw_image, size_t fw_size) - { - int ret, id = 0; /* Copro id fixed to 0 as only one coproc on mp1 */ - unsigned int rsc_size; --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0011-ARM-v2018.11-stm32mp-r3-DEVICETREE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0011-ARM-v2018.11-stm32mp-r3-DEVICETREE.patch deleted file mode 100644 index 7a369f9..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0011-ARM-v2018.11-stm32mp-r3-DEVICETREE.patch +++ /dev/null @@ -1,1987 +0,0 @@ -From 0317a782b980c961af443f46c185f57bbebc941f Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Tue, 17 Sep 2019 13:55:43 +0200 -Subject: [PATCH 11/13] ARM v2018.11 stm32mp r3 DEVICETREE - ---- - arch/arm/dts/stm32429i-eval-u-boot.dtsi | 11 - - arch/arm/dts/stm32f429-disco-u-boot.dtsi | 11 - - arch/arm/dts/stm32f469-disco-u-boot.dtsi | 11 - - arch/arm/dts/stm32f746.dtsi | 11 - - arch/arm/dts/stm32h743-pinctrl.dtsi | 11 - - arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binF.dtsi | 12 +- - arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi | 13 +- - arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binF.dtsi | 8 +- - arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi | 10 +- - arch/arm/dts/stm32mp157-pinctrl.dtsi | 294 +++++++---------------- - arch/arm/dts/stm32mp157-u-boot.dtsi | 35 +-- - arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi | 24 +- - arch/arm/dts/stm32mp157a-dk1.dts | 83 +++++-- - arch/arm/dts/stm32mp157c-dk2.dts | 11 +- - arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi | 12 +- - arch/arm/dts/stm32mp157c-ed1.dts | 13 +- - arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi | 4 - - arch/arm/dts/stm32mp157c-ev1.dts | 19 +- - arch/arm/dts/stm32mp157c-m4-srm.dtsi | 4 +- - arch/arm/dts/stm32mp157c.dtsi | 90 +++++-- - 20 files changed, 291 insertions(+), 396 deletions(-) - -diff --git a/arch/arm/dts/stm32429i-eval-u-boot.dtsi b/arch/arm/dts/stm32429i-eval-u-boot.dtsi -index 6da0a63..fe437bb 100644 ---- a/arch/arm/dts/stm32429i-eval-u-boot.dtsi -+++ b/arch/arm/dts/stm32429i-eval-u-boot.dtsi -@@ -92,57 +92,46 @@ - }; - - &gpioa { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiob { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioc { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiod { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioe { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiof { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiog { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioh { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioi { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioj { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiok { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - -diff --git a/arch/arm/dts/stm32f429-disco-u-boot.dtsi b/arch/arm/dts/stm32f429-disco-u-boot.dtsi -index 10e0950..399d4c9 100644 ---- a/arch/arm/dts/stm32f429-disco-u-boot.dtsi -+++ b/arch/arm/dts/stm32f429-disco-u-boot.dtsi -@@ -87,57 +87,46 @@ - }; - - &gpioa { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiob { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioc { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiod { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioe { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiof { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiog { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioh { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioi { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioj { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiok { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - -diff --git a/arch/arm/dts/stm32f469-disco-u-boot.dtsi b/arch/arm/dts/stm32f469-disco-u-boot.dtsi -index 774f1b5..d370ca7 100644 ---- a/arch/arm/dts/stm32f469-disco-u-boot.dtsi -+++ b/arch/arm/dts/stm32f469-disco-u-boot.dtsi -@@ -92,57 +92,46 @@ - }; - - &gpioa { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiob { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioc { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiod { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioe { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiof { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiog { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioh { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioi { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioj { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiok { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - -diff --git a/arch/arm/dts/stm32f746.dtsi b/arch/arm/dts/stm32f746.dtsi -index afa7832..4bae1a1 100644 ---- a/arch/arm/dts/stm32f746.dtsi -+++ b/arch/arm/dts/stm32f746.dtsi -@@ -130,7 +130,6 @@ - gpioa: gpio@40020000 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x0 0x400>; - clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOA)>; - st,bank-name = "GPIOA"; -@@ -140,7 +139,6 @@ - gpiob: gpio@40020400 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x400 0x400>; - clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOB)>; - st,bank-name = "GPIOB"; -@@ -151,7 +149,6 @@ - gpioc: gpio@40020800 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x800 0x400>; - clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOC)>; - st,bank-name = "GPIOC"; -@@ -161,7 +158,6 @@ - gpiod: gpio@40020c00 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0xc00 0x400>; - clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOD)>; - st,bank-name = "GPIOD"; -@@ -171,7 +167,6 @@ - gpioe: gpio@40021000 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x1000 0x400>; - clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOE)>; - st,bank-name = "GPIOE"; -@@ -181,7 +176,6 @@ - gpiof: gpio@40021400 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x1400 0x400>; - clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOF)>; - st,bank-name = "GPIOF"; -@@ -191,7 +185,6 @@ - gpiog: gpio@40021800 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x1800 0x400>; - clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOG)>; - st,bank-name = "GPIOG"; -@@ -201,7 +194,6 @@ - gpioh: gpio@40021c00 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x1c00 0x400>; - clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOH)>; - st,bank-name = "GPIOH"; -@@ -211,7 +203,6 @@ - gpioi: gpio@40022000 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x2000 0x400>; - clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOI)>; - st,bank-name = "GPIOI"; -@@ -221,7 +212,6 @@ - gpioj: gpio@40022400 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x2400 0x400>; - clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOJ)>; - st,bank-name = "GPIOJ"; -@@ -231,7 +221,6 @@ - gpiok: gpio@40022800 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x2800 0x400>; - clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOK)>; - st,bank-name = "GPIOK"; -diff --git a/arch/arm/dts/stm32h743-pinctrl.dtsi b/arch/arm/dts/stm32h743-pinctrl.dtsi -index e4f4aa5..65d6ca2 100644 ---- a/arch/arm/dts/stm32h743-pinctrl.dtsi -+++ b/arch/arm/dts/stm32h743-pinctrl.dtsi -@@ -54,7 +54,6 @@ - gpioa: gpio@58020000 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x0 0x400>; - clocks = <&rcc GPIOA_CK>; - st,bank-name = "GPIOA"; -@@ -63,7 +62,6 @@ - gpiob: gpio@58020400 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x400 0x400>; - clocks = <&rcc GPIOB_CK>; - st,bank-name = "GPIOB"; -@@ -72,7 +70,6 @@ - gpioc: gpio@58020800 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x800 0x400>; - clocks = <&rcc GPIOC_CK>; - st,bank-name = "GPIOC"; -@@ -81,7 +78,6 @@ - gpiod: gpio@58020c00 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0xc00 0x400>; - clocks = <&rcc GPIOD_CK>; - st,bank-name = "GPIOD"; -@@ -90,7 +86,6 @@ - gpioe: gpio@58021000 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x1000 0x400>; - clocks = <&rcc GPIOE_CK>; - st,bank-name = "GPIOE"; -@@ -99,7 +94,6 @@ - gpiof: gpio@58021400 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x1400 0x400>; - clocks = <&rcc GPIOF_CK>; - st,bank-name = "GPIOF"; -@@ -108,7 +102,6 @@ - gpiog: gpio@58021800 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x1800 0x400>; - clocks = <&rcc GPIOG_CK>; - st,bank-name = "GPIOG"; -@@ -117,7 +110,6 @@ - gpioh: gpio@58021c00 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x1c00 0x400>; - clocks = <&rcc GPIOH_CK>; - st,bank-name = "GPIOH"; -@@ -126,7 +118,6 @@ - gpioi: gpio@58022000 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x2000 0x400>; - clocks = <&rcc GPIOI_CK>; - st,bank-name = "GPIOI"; -@@ -135,7 +126,6 @@ - gpioj: gpio@58022400 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x2400 0x400>; - clocks = <&rcc GPIOJ_CK>; - st,bank-name = "GPIOJ"; -@@ -144,7 +134,6 @@ - gpiok: gpio@58022800 { - gpio-controller; - #gpio-cells = <2>; -- compatible = "st,stm32-gpio"; - reg = <0x2800 0x400>; - clocks = <&rcc GPIOK_CK>; - st,bank-name = "GPIOK"; -diff --git a/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binF.dtsi b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binF.dtsi -index da83310..43edbfe 100644 ---- a/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binF.dtsi -+++ b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binF.dtsi -@@ -1,8 +1,8 @@ - // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause - /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -- */ --/* STM32MP157C DK1/DK2 BOARD configuration -+ * -+ * STM32MP157C DK1/DK2 BOARD configuration - * 1x DDR3L 4Gb, 16-bit, 533MHz. - * Reference used NT5CC256M16DP-DI from NANYA - * -@@ -16,7 +16,7 @@ - * address mapping : RBC - * Tc > + 85C : N - */ --#define DDR_MEM_NAME "DDR3-1066/777 bin F 1x4Gb 533MHz v1.41" -+#define DDR_MEM_NAME "DDR3-1066/777 bin F 1x4Gb 533MHz v1.45" - #define DDR_MEM_SPEED 533000 - #define DDR_MEM_SIZE 0x20000000 - -@@ -89,7 +89,7 @@ - #define DDR_PTR2 0x042DA068 - #define DDR_ACIOCR 0x10400812 - #define DDR_DXCCR 0x00000C40 --#define DDR_DSGCR 0xF200001F -+#define DDR_DSGCR 0xF200011F - #define DDR_DCR 0x0000000B - #define DDR_DTPR0 0x36D477D0 - #define DDR_DTPR1 0x098B00D8 -@@ -108,11 +108,11 @@ - #define DDR_DX1DLLCR 0x40000000 - #define DDR_DX1DQTR 0xFFFFFFFF - #define DDR_DX1DQSTR 0x3DB02000 --#define DDR_DX2GCR 0x0000CE81 -+#define DDR_DX2GCR 0x0000CE80 - #define DDR_DX2DLLCR 0x40000000 - #define DDR_DX2DQTR 0xFFFFFFFF - #define DDR_DX2DQSTR 0x3DB02000 --#define DDR_DX3GCR 0x0000CE81 -+#define DDR_DX3GCR 0x0000CE80 - #define DDR_DX3DLLCR 0x40000000 - #define DDR_DX3DQTR 0xFFFFFFFF - #define DDR_DX3DQSTR 0x3DB02000 -diff --git a/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi -index 16b8cf6..11e8f2b 100644 ---- a/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi -+++ b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi -@@ -1,8 +1,8 @@ - // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause - /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -- */ --/* STM32MP157C DK1/DK2 BOARD configuration -+ * -+ * STM32MP157C DK1/DK2 BOARD configuration - * 1x DDR3L 4Gb, 16-bit, 533MHz. - * Reference used NT5CC256M16DP-DI from NANYA - * -@@ -16,8 +16,7 @@ - * address mapping : RBC - * Tc > + 85C : N - */ -- --#define DDR_MEM_NAME "DDR3-1066/888 bin G 1x4Gb 533MHz v1.41" -+#define DDR_MEM_NAME "DDR3-1066/888 bin G 1x4Gb 533MHz v1.45" - #define DDR_MEM_SPEED 533000 - #define DDR_MEM_SIZE 0x20000000 - -@@ -90,7 +89,7 @@ - #define DDR_PTR2 0x042DA068 - #define DDR_ACIOCR 0x10400812 - #define DDR_DXCCR 0x00000C40 --#define DDR_DSGCR 0xF200001F -+#define DDR_DSGCR 0xF200011F - #define DDR_DCR 0x0000000B - #define DDR_DTPR0 0x38D488D0 - #define DDR_DTPR1 0x098B00D8 -@@ -109,11 +108,11 @@ - #define DDR_DX1DLLCR 0x40000000 - #define DDR_DX1DQTR 0xFFFFFFFF - #define DDR_DX1DQSTR 0x3DB02000 --#define DDR_DX2GCR 0x0000CE81 -+#define DDR_DX2GCR 0x0000CE80 - #define DDR_DX2DLLCR 0x40000000 - #define DDR_DX2DQTR 0xFFFFFFFF - #define DDR_DX2DQSTR 0x3DB02000 --#define DDR_DX3GCR 0x0000CE81 -+#define DDR_DX3GCR 0x0000CE80 - #define DDR_DX3DLLCR 0x40000000 - #define DDR_DX3DQTR 0xFFFFFFFF - #define DDR_DX3DQSTR 0x3DB02000 -diff --git a/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binF.dtsi b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binF.dtsi -index 82781e7..e0644a3 100644 ---- a/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binF.dtsi -+++ b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binF.dtsi -@@ -1,8 +1,8 @@ - // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause - /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -- */ --/* STM32MP157C ED1 BOARD configuration -+ * -+ * STM32MP157C ED1 BOARD configuration - * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology. - * Reference used NT5CC256M16DP-DI from NANYA - * -@@ -16,7 +16,7 @@ - * address mapping : RBC - * Tc > + 85C : N - */ --#define DDR_MEM_NAME "DDR3-1066/777 bin F 2x4Gb 533MHz v1.41" -+#define DDR_MEM_NAME "DDR3-1066/777 bin F 2x4Gb 533MHz v1.45" - #define DDR_MEM_SPEED 533000 - #define DDR_MEM_SIZE 0x40000000 - -@@ -89,7 +89,7 @@ - #define DDR_PTR2 0x042DA068 - #define DDR_ACIOCR 0x10400812 - #define DDR_DXCCR 0x00000C40 --#define DDR_DSGCR 0xF200001F -+#define DDR_DSGCR 0xF200011F - #define DDR_DCR 0x0000000B - #define DDR_DTPR0 0x36D477D0 - #define DDR_DTPR1 0x098B00D8 -diff --git a/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi -index 82e7104..4b70b60 100644 ---- a/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi -+++ b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi -@@ -1,9 +1,8 @@ - // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause - /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -- */ -- --/* STM32MP157C ED1 BOARD configuration -+ * -+ * STM32MP157C ED1 BOARD configuration - * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology. - * Reference used NT5CC256M16DP-DI from NANYA - * -@@ -17,8 +16,7 @@ - * address mapping : RBC - * Tc > + 85C : N - */ -- --#define DDR_MEM_NAME "DDR3-1066/888 bin G 2x4Gb 533MHz v1.41" -+#define DDR_MEM_NAME "DDR3-1066/888 bin G 2x4Gb 533MHz v1.45" - #define DDR_MEM_SPEED 533000 - #define DDR_MEM_SIZE 0x40000000 - -@@ -91,7 +89,7 @@ - #define DDR_PTR2 0x042DA068 - #define DDR_ACIOCR 0x10400812 - #define DDR_DXCCR 0x00000C40 --#define DDR_DSGCR 0xF200001F -+#define DDR_DSGCR 0xF200011F - #define DDR_DCR 0x0000000B - #define DDR_DTPR0 0x38D488D0 - #define DDR_DTPR1 0x098B00D8 -diff --git a/arch/arm/dts/stm32mp157-pinctrl.dtsi b/arch/arm/dts/stm32mp157-pinctrl.dtsi -index 183d7ba..dd796ec 100644 ---- a/arch/arm/dts/stm32mp157-pinctrl.dtsi -+++ b/arch/arm/dts/stm32mp157-pinctrl.dtsi -@@ -248,7 +248,7 @@ - pinmux = ; /* DFSDM_CKOUT */ - bias-disable; - drive-push-pull; -- slew-rate = <1>; -+ slew-rate = <0>; - }; - }; - -@@ -291,13 +291,18 @@ - , /* ETH_RGMII_TXD2 */ - , /* ETH_RGMII_TXD3 */ - , /* ETH_RGMII_TX_CTL */ -- , /* ETH_MDIO */ - ; /* ETH_MDC */ - bias-disable; - drive-push-pull; - slew-rate = <2>; - }; - pins2 { -+ pinmux = ; /* ETH_MDIO */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ pins3 { - pinmux = , /* ETH_RGMII_RXD0 */ - , /* ETH_RGMII_RXD1 */ - , /* ETH_RGMII_RXD2 */ -@@ -387,171 +392,6 @@ - }; - }; - -- hdp0_pins_b: hdp0-1 { -- pins { -- pinmux = ; /* HDP0 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <2>; -- }; -- }; -- -- hdp0_pins_sleep_b: hdp0-sleep-1 { -- pins { -- pinmux = ; /* HDP0 */ -- }; -- }; -- -- hdp1_pins_a: hdp1-0 { -- pins { -- pinmux = ; /* HDP1 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <2>; -- }; -- }; -- -- hdp1_pins_sleep_a: hdp1-sleep-0 { -- pins { -- pinmux = ; /* HDP1 */ -- }; -- }; -- -- hdp1_pins_b: hdp1-1 { -- pins { -- pinmux = ; /* HDP1 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <2>; -- }; -- }; -- -- hdp1_pins_sleep_b: hdp1-sleep-1 { -- pins { -- pinmux = ; /* HDP1 */ -- }; -- }; -- -- hdp2_pins_a: hdp2-0 { -- pins { -- pinmux = ; /* HDP2 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <2>; -- }; -- }; -- -- hdp2_pins_sleep_a: hdp2-sleep-0 { -- pins { -- pinmux = ; /* HDP2 */ -- }; -- }; -- -- hdp2_pins_b: hdp2-1 { -- pins { -- pinmux = ; /* HDP2 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <2>; -- }; -- }; -- -- hdp2_pins_sleep_b: hdp2-sleep-1 { -- pins { -- pinmux = ; /* HDP2 */ -- }; -- }; -- -- hdp3_pins_a: hdp3-0 { -- pins { -- pinmux = ; /* HDP3 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <2>; -- }; -- }; -- -- hdp3_pins_sleep_a: hdp3-sleep-0 { -- pins { -- pinmux = ; /* HDP3 */ -- }; -- }; -- -- hdp3_pins_b: hdp3-1 { -- pins { -- pinmux = ; /* HDP3 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <2>; -- }; -- }; -- -- hdp3_pins_sleep_b: hdp3-sleep-1 { -- pins { -- pinmux = ; /* HDP3 */ -- }; -- }; -- -- hdp4_pins_a: hdp4-0 { -- pins { -- pinmux = ; /* HDP4 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <2>; -- }; -- }; -- -- hdp4_pins_sleep_a: hdp4-sleep-0 { -- pins { -- pinmux = ; /* HDP4 */ -- }; -- }; -- -- hdp4_pins_b: hdp4-1 { -- pins { -- pinmux = ; /* HDP4 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <2>; -- }; -- }; -- -- hdp4_pins_sleep_b: hdp4-sleep-1 { -- pins { -- pinmux = ; /* HDP4 */ -- }; -- }; -- -- hdp5_pins_a: hdp5-0 { -- pins { -- pinmux = ; /* HDP5 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <2>; -- }; -- }; -- -- hdp5_pins_sleep_a: hdp5-sleep-0 { -- pins { -- pinmux = ; /* HDP5 */ -- }; -- }; -- -- hdp5_pins_b: hdp5-1 { -- pins { -- pinmux = ; /* HDP5 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <2>; -- }; -- }; -- -- hdp5_pins_sleep_b: hdp5-sleep-1 { -- pins { -- pinmux = ; /* HDP5 */ -- }; -- }; -- - hdp6_pins_a: hdp6-0 { - pins { - pinmux = ; /* HDP6 */ -@@ -567,21 +407,6 @@ - }; - }; - -- hdp6_pins_b: hdp6-1 { -- pins { -- pinmux = ; /* HDP6 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <2>; -- }; -- }; -- -- hdp6_pins_sleep_b: hdp6-sleep-1 { -- pins { -- pinmux = ; /* HDP6 */ -- }; -- }; -- - hdp7_pins_a: hdp7-0 { - pins { - pinmux = ; /* HDP7 */ -@@ -597,21 +422,6 @@ - }; - }; - -- hdp7_pins_b: hdp7-1 { -- pins { -- pinmux = ; /* HDP7 */ -- bias-disable; -- drive-push-pull; -- slew-rate = <2>; -- }; -- }; -- -- hdp7_pins_sleep_b: hdp7-sleep-1 { -- pins { -- pinmux = ; /* HDP7 */ -- }; -- }; -- - i2c1_pins_a: i2c1-0 { - pins { - pinmux = , /* I2C1_SCL */ -@@ -1249,6 +1059,49 @@ - }; - }; - -+ sdmmc2_b4_pins_b: sdmmc2-b4-1 { -+ pins1 { -+ pinmux = , /* SDMMC2_D0 */ -+ , /* SDMMC2_D1 */ -+ , /* SDMMC2_D2 */ -+ , /* SDMMC2_D3 */ -+ ; /* SDMMC2_CMD */ -+ slew-rate = <1>; -+ drive-push-pull; -+ bias-disable; -+ }; -+ pins2 { -+ pinmux = ; /* SDMMC2_CK */ -+ slew-rate = <2>; -+ drive-push-pull; -+ bias-disable; -+ }; -+ }; -+ -+ sdmmc2_b4_od_pins_b: sdmmc2-b4-od-1 { -+ pins1 { -+ pinmux = , /* SDMMC2_D0 */ -+ , /* SDMMC2_D1 */ -+ , /* SDMMC2_D2 */ -+ ; /* SDMMC2_D3 */ -+ slew-rate = <1>; -+ drive-push-pull; -+ bias-disable; -+ }; -+ pins2 { -+ pinmux = ; /* SDMMC2_CK */ -+ slew-rate = <2>; -+ drive-push-pull; -+ bias-disable; -+ }; -+ pins3 { -+ pinmux = ; /* SDMMC2_CMD */ -+ slew-rate = <1>; -+ drive-open-drain; -+ bias-disable; -+ }; -+ }; -+ - sdmmc2_d47_pins_a: sdmmc2-d47-0 { - pins { - pinmux = , /* SDMMC2_D4 */ -@@ -1383,6 +1236,13 @@ - }; - }; - -+ stusb1600_pins_a: stusb1600-0 { -+ pins { -+ pinmux = ; -+ bias-pull-up; -+ }; -+ }; -+ - uart4_pins_a: uart4-0 { - pins1 { - pinmux = ; /* UART4_TX */ -@@ -1413,6 +1273,36 @@ - }; - }; - -+ uart7_pins_a: uart7-0 { -+ pins1 { -+ pinmux = ; /* USART7_TX */ -+ bias-disable; -+ drive-push-pull; -+ slew-rate = <0>; -+ }; -+ pins2 { -+ pinmux = ; /* USART7_RX */ -+ bias-disable; -+ }; -+ }; -+ -+ uart7_idle_pins_a: uart7-idle-0 { -+ pins1 { -+ pinmux = ; /* USART7_TX */ -+ }; -+ pins2 { -+ pinmux = ; /* USART7_RX */ -+ bias-disable; -+ }; -+ }; -+ -+ uart7_sleep_pins_a: uart7-sleep-0 { -+ pins { -+ pinmux = , /* USART7_TX */ -+ ; /* USART7_RX */ -+ }; -+ }; -+ - usart2_pins_a: usart2-0 { - pins1 { - pinmux = , /* USART2_TX */ -@@ -1557,16 +1447,6 @@ - status = "disabled"; - }; - -- btreg: bt_reg_on-0 { -- pins { -- pinmux = ; -- drive-push-pull; -- bias-pull-up; -- output-high; -- slew-rate = <0>; -- }; -- }; -- - i2c4_pins_a: i2c4-0 { - pins { - pinmux = , /* I2C4_SCL */ -diff --git a/arch/arm/dts/stm32mp157-u-boot.dtsi b/arch/arm/dts/stm32mp157-u-boot.dtsi -index 035b1c6..98cf1aa 100644 ---- a/arch/arm/dts/stm32mp157-u-boot.dtsi -+++ b/arch/arm/dts/stm32mp157-u-boot.dtsi -@@ -21,11 +21,12 @@ - pinctrl1 = &pinctrl_z; - }; - -- clocks { -- u-boot,dm-pre-reloc; -+ /* need PSCI for sysreset during board_f */ -+ psci { -+ u-boot,dm-pre-proper; - }; - -- config { -+ clocks { - u-boot,dm-pre-reloc; - }; - -@@ -36,12 +37,6 @@ - soc { - u-boot,dm-pre-reloc; - -- etzpc: etzpc@5C007000 { -- compatible = "st,stm32mp1-etzpc"; -- reg = <0x5C007000 0x400>; -- status = "okay"; -- }; -- - stgen: stgen@5C008000 { - compatible = "st,stm32-stgen"; - reg = <0x5C008000 0x1000>; -@@ -52,7 +47,7 @@ - }; - - &bsec { -- u-boot,dm-pre-reloc; -+ u-boot,dm-pre-proper; - }; - - &clk_csi { -@@ -76,62 +71,50 @@ - }; - - &gpioa { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiob { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioc { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiod { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioe { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiof { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiog { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioh { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioi { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioj { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpiok { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - - &gpioz { -- compatible = "st,stm32-gpio"; - u-boot,dm-pre-reloc; - }; - -@@ -141,7 +124,7 @@ - - /* pre-reloc probe = reserve video frame buffer in video_reserve() */ - <dc { -- u-boot,dm-pre-reloc; -+ u-boot,dm-pre-proper; - }; - - &pinctrl { -@@ -161,13 +144,13 @@ - }; - - &sdmmc1 { -- compatible = "st,stm32-sdmmc2"; -+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; - }; - - &sdmmc2 { -- compatible = "st,stm32-sdmmc2"; -+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; - }; - - &sdmmc3 { -- compatible = "st,stm32-sdmmc2"; -+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; - }; -diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi -index 0f9ed9f..757df24 100644 ---- a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi -+++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi -@@ -33,19 +33,16 @@ - }; - }; - -+&adc { -+ status = "okay"; -+}; -+ - &clk_hse { - st,digbypass; - }; - - &i2c4 { - u-boot,dm-pre-reloc; -- -- stusb1600: typec@28 { -- #extcon-cells = <0>; -- compatible = "st,stusb1600"; -- reg = <0x28>; -- status = "okay"; -- }; - }; - - &i2c4_pins_a { -@@ -112,7 +109,7 @@ - CLK_UART6_HSI - CLK_UART78_HSI - CLK_SPDIF_PLL4P -- CLK_FDCAN_PLL4Q -+ CLK_FDCAN_PLL4R - CLK_SAI1_PLL3Q - CLK_SAI2_PLL3Q - CLK_SAI3_PLL3Q -@@ -177,14 +174,7 @@ - }; - pins2 { - u-boot,dm-pre-reloc; -+ /* pull-up on rx to avoid floating level */ -+ bias-pull-up; - }; - }; -- --&usbotg_hs { -- usb1600; -- hnp-srp-disable; --}; -- --&v3v3 { -- regulator-always-on; --}; -diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts -index 8e09447..2b01a01 100644 ---- a/arch/arm/dts/stm32mp157a-dk1.dts -+++ b/arch/arm/dts/stm32mp157a-dk1.dts -@@ -9,7 +9,6 @@ - #include "stm32mp157c.dtsi" - #include "stm32mp157c-m4-srm.dtsi" - #include "stm32mp157cac-pinctrl.dtsi" --#include - #include - #include - -@@ -20,6 +19,8 @@ - aliases { - ethernet0 = ðernet0; - serial0 = &uart4; -+ serial1 = &usart3; -+ serial2 = &uart7; - }; - - chosen { -@@ -71,8 +72,8 @@ - no-map; - }; - -- gpu_reserved: gpu@dc000000 { -- reg = <0xdc000000 0x4000000>; -+ gpu_reserved: gpu@d4000000 { -+ reg = <0xd4000000 0x4000000>; - no-map; - }; - }; -@@ -125,11 +126,11 @@ - - &adc { - pinctrl-names = "default"; -- pinctrl-0 = <&adc12_usb_pwr_pins_a>; -+ pinctrl-0 = <&adc12_ain_pins_a>, <&adc12_usb_pwr_pins_a>; - vdd-supply = <&vdd>; - vdda-supply = <&vdd>; - vref-supply = <&vrefbuf>; -- status = "okay"; -+ status = "disabled"; - adc1: adc@0 { - /* - * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in18 & in19. -@@ -138,13 +139,13 @@ - * Use arbitrary margin here (e.g. 5µs). - */ - st,min-sample-time-nsecs = <5000>; -- /* ANA0, ANA1, USB Type-C CC1 & CC2 */ -- st,adc-channels = <0 1 18 19>; -+ /* AIN connector, USB Type-C CC1 & CC2 */ -+ st,adc-channels = <0 1 6 13 18 19>; - status = "okay"; - }; - adc2: adc@100 { -- /* ANA0, ANA1, temp sensor, USB Type-C CC1 & CC2 */ -- st,adc-channels = <0 1 12 18 19>; -+ /* AIN connector, temp sensor, USB Type-C CC1 & CC2 */ -+ st,adc-channels = <0 1 2 6 12 18 19>; - /* temperature sensor min sample time */ - st,min-sample-time-nsecs = <10000>; - status = "okay"; -@@ -178,7 +179,7 @@ - pinctrl-0 = <ðernet0_rgmii_pins_a>; - pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; - pinctrl-names = "default", "sleep"; -- phy-mode = "rgmii"; -+ phy-mode = "rgmii-id"; - max-speed = <1000>; - phy-handle = <&phy0>; - -@@ -287,6 +288,23 @@ - /delete-property/dmas; - /delete-property/dma-names; - -+ typec: stusb1600@28 { -+ compatible = "st,stusb1600"; -+ reg = <0x28>; -+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>; -+ interrupt-parent = <&gpioi>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&stusb1600_pins_a>; -+ status = "okay"; -+ -+ typec_con: connector { -+ compatible = "usb-c-connector"; -+ label = "USB-C"; -+ power-role = "dual"; -+ power-opmode = "default"; -+ }; -+ }; -+ - pmic: stpmic@33 { - compatible = "st,stpmic1"; - reg = <0x33>; -@@ -297,7 +315,7 @@ - - st,main-control-register = <0x04>; - st,vin-control-register = <0xc0>; -- st,usb-control-register = <0x30>; -+ st,usb-control-register = <0x20>; - - regulators { - compatible = "st,stpmic1-regulators"; -@@ -433,6 +451,15 @@ - }; - }; - -+&i2c5 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&i2c5_pins_a>; -+ pinctrl-1 = <&i2c5_pins_sleep_a>; -+ /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"; -@@ -481,12 +508,16 @@ - interrupt-parent = <&exti>; - interrupts = <68 1>; - interrupt-names = "wdg"; -+ wakeup-source; - recovery; - status = "okay"; - }; - - &pwr { -- pwr-supply = <&vdd>; -+ pwr-regulators { -+ vdd-supply = <&vdd>; -+ vdd_3v3_usbfs-supply = <&vdd_usb>; -+ }; - }; - - &rng1 { -@@ -554,6 +585,18 @@ - status = "okay"; - }; - -+&sdmmc3 { -+ pinctrl-names = "default", "opendrain", "sleep"; -+ pinctrl-0 = <&sdmmc3_b4_pins_a>; -+ pinctrl-1 = <&sdmmc3_b4_od_pins_a>; -+ pinctrl-2 = <&sdmmc3_b4_sleep_pins_a>; -+ broken-cd; -+ st,neg-edge; -+ bus-width = <4>; -+ vmmc-supply = <&v3v3>; -+ status = "disabled"; -+}; -+ - &spi4 { - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&spi4_pins_a>; -@@ -572,6 +615,7 @@ - /* spare dmas for other usage */ - /delete-property/dmas; - /delete-property/dma-names; -+ status = "disabled"; - pwm { - pinctrl-0 = <&pwm1_pins_a>; - pinctrl-1 = <&pwm1_sleep_pins_a>; -@@ -586,6 +630,7 @@ - &timers3 { - /delete-property/dmas; - /delete-property/dma-names; -+ status = "disabled"; - pwm { - pinctrl-0 = <&pwm3_pins_a>; - pinctrl-1 = <&pwm3_sleep_pins_a>; -@@ -600,6 +645,7 @@ - &timers4 { - /delete-property/dmas; - /delete-property/dma-names; -+ status = "disabled"; - pwm { - pinctrl-0 = <&pwm4_pins_a &pwm4_pins_b>; - pinctrl-1 = <&pwm4_sleep_pins_a &pwm4_sleep_pins_b>; -@@ -614,6 +660,7 @@ - &timers5 { - /delete-property/dmas; - /delete-property/dma-names; -+ status = "disabled"; - pwm { - pinctrl-0 = <&pwm5_pins_a>; - pinctrl-1 = <&pwm5_sleep_pins_a>; -@@ -638,6 +685,7 @@ - &timers12 { - /delete-property/dmas; - /delete-property/dma-names; -+ status = "disabled"; - pwm { - pinctrl-0 = <&pwm12_pins_a>; - pinctrl-1 = <&pwm12_sleep_pins_a>; -@@ -658,6 +706,14 @@ - status = "okay"; - }; - -+&uart7 { -+ pinctrl-names = "default", "sleep", "idle"; -+ pinctrl-0 = <&uart7_pins_a>; -+ pinctrl-1 = <&uart7_sleep_pins_a>; -+ pinctrl-2 = <&uart7_idle_pins_a>; -+ status = "disabled"; -+}; -+ - &usart3 { - pinctrl-names = "default", "sleep", "idle"; - pinctrl-0 = <&usart3_pins_b>; -@@ -673,8 +729,7 @@ - }; - - &usbotg_hs { -- dr_mode = "peripheral"; -- force-b-session-valid; -+ extcon = <&typec>; - phys = <&usbphyc_port1 0>; - phy-names = "usb2-phy"; - status = "okay"; -diff --git a/arch/arm/dts/stm32mp157c-dk2.dts b/arch/arm/dts/stm32mp157c-dk2.dts -index c276c59..d11fbb8 100644 ---- a/arch/arm/dts/stm32mp157c-dk2.dts -+++ b/arch/arm/dts/stm32mp157c-dk2.dts -@@ -14,7 +14,7 @@ - compatible = "st,stm32mp157c-dk2", "st,stm32mp157"; - - aliases { -- serial1 = &usart2; -+ serial3 = &usart2; - }; - - wifi_pwrseq: wifi-pwrseq { -@@ -51,6 +51,7 @@ - compatible = "orisetech,otm8009a"; - reg = <0>; - reset-gpios = <&gpioe 4 GPIO_ACTIVE_LOW>; -+ power-supply = <&v3v3>; - status = "okay"; - - port { -@@ -106,9 +107,10 @@ - - /* Wifi */ - &sdmmc2 { -+ arm,primecell-periphid = <0x10153180>; - pinctrl-names = "default", "opendrain", "sleep"; -- pinctrl-0 = <&sdmmc2_b4_pins_a>; -- pinctrl-1 = <&sdmmc2_b4_od_pins_a>; -+ pinctrl-0 = <&sdmmc2_b4_pins_b>; -+ pinctrl-1 = <&sdmmc2_b4_od_pins_b>; - pinctrl-2 = <&sdmmc2_b4_sleep_pins_a>; - non-removable; - st,neg-edge; -@@ -136,8 +138,7 @@ - status = "okay"; - - bluetooth { -- pinctrl-names = "default"; -- pinctrl-0 = <&btreg>; -+ shutdown-gpios = <&gpioz 6 GPIO_ACTIVE_HIGH>; - compatible = "brcm,bcm43438-bt"; - max-speed = <3000000>; - }; -diff --git a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi -index b6bf6f1..5ab4eeb 100644 ---- a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi -+++ b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi -@@ -16,11 +16,19 @@ - - config { - u-boot,boot-led = "heartbeat"; -+ u-boot,error-led = "error"; - st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; - st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; - }; - - led { -+ red { -+ label = "error"; -+ gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; -+ default-state = "off"; -+ status = "okay"; -+ }; -+ - blue { - default-state = "on"; - }; -@@ -99,7 +107,7 @@ - CLK_UART6_HSI - CLK_UART78_HSI - CLK_SPDIF_PLL4P -- CLK_FDCAN_PLL4Q -+ CLK_FDCAN_PLL4R - CLK_SAI1_PLL3Q - CLK_SAI2_PLL3Q - CLK_SAI3_PLL3Q -@@ -195,5 +203,7 @@ - }; - pins2 { - u-boot,dm-pre-reloc; -+ /* pull-up on rx to avoid floating level */ -+ bias-pull-up; - }; - }; -diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts -index 0f70bb7..c9eabc1 100644 ---- a/arch/arm/dts/stm32mp157c-ed1.dts -+++ b/arch/arm/dts/stm32mp157c-ed1.dts -@@ -8,7 +8,6 @@ - #include "stm32mp157c.dtsi" - #include "stm32mp157c-m4-srm.dtsi" - #include "stm32mp157caa-pinctrl.dtsi" --#include - #include - - / { -@@ -64,8 +63,8 @@ - no-map; - }; - -- gpu_reserved: gpu@f8000000 { -- reg = <0xf8000000 0x8000000>; -+ gpu_reserved: gpu@e8000000 { -+ reg = <0xe8000000 0x8000000>; - no-map; - }; - }; -@@ -188,7 +187,7 @@ - - st,main-control-register = <0x04>; - st,vin-control-register = <0xc0>; -- st,usb-control-register = <0x30>; -+ st,usb-control-register = <0x20>; - - regulators { - compatible = "st,stpmic1-regulators"; -@@ -337,12 +336,16 @@ - interrupt-parent = <&exti>; - interrupts = <68 1>; - interrupt-names = "wdg"; -+ wakeup-source; - recovery; - status = "okay"; - }; - - &pwr { -- pwr-supply = <&vdd>; -+ pwr-regulators { -+ vdd-supply = <&vdd>; -+ vdd_3v3_usbfs-supply = <&vdd_usb>; -+ }; - }; - - &rng1 { -diff --git a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi -index ec08813..86039d6 100644 ---- a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi -+++ b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi -@@ -54,7 +54,3 @@ - u-boot,dm-spl; - }; - }; -- --&usbotg_hs { -- g-tx-fifo-size = <576>; --}; -diff --git a/arch/arm/dts/stm32mp157c-ev1.dts b/arch/arm/dts/stm32mp157c-ev1.dts -index 18742e8..559b9b9 100644 ---- a/arch/arm/dts/stm32mp157c-ev1.dts -+++ b/arch/arm/dts/stm32mp157c-ev1.dts -@@ -7,7 +7,6 @@ - - #include "stm32mp157c-ed1.dts" - #include --#include - #include - - / { -@@ -330,7 +329,7 @@ - compatible = "raydium,rm68200"; - reg = <0>; - reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>; -- power-supply = <&v1v8>; -+ power-supply = <&v3v3>; - backlight = <&panel_backlight>; - status = "okay"; - -@@ -347,7 +346,7 @@ - pinctrl-0 = <ðernet0_rgmii_pins_a>; - pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; - pinctrl-names = "default", "sleep"; -- phy-mode = "rgmii"; -+ phy-mode = "rgmii-id"; - max-speed = <1000>; - phy-handle = <&phy0>; - -@@ -442,14 +441,12 @@ - - ov5640: camera@3c { - compatible = "ovti,ov5640"; -- pinctrl-names = "default"; -- pinctrl-0 = <&ov5640_pins>; - reg = <0x3c>; - clocks = <&clk_ext_camera>; - clock-names = "xclk"; - DOVDD-supply = <&v2v8>; -- powerdown-gpios = <&stmfx_pinctrl 18 GPIO_ACTIVE_HIGH>; -- reset-gpios = <&stmfx_pinctrl 19 GPIO_ACTIVE_LOW>; -+ 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"; - -@@ -485,21 +482,13 @@ - - hog_pins: hog { - pins = "gpio14"; -- drive-push-pull; - bias-pull-down; - }; - - joystick_pins: joystick { - pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4"; -- drive-push-pull; - bias-pull-down; - }; -- -- ov5640_pins: camera { -- pins = "agpio2", "agpio3"; /* stmfx pins 18 & 19 */ -- drive-push-pull; -- output-low; -- }; - }; - }; - -diff --git a/arch/arm/dts/stm32mp157c-m4-srm.dtsi b/arch/arm/dts/stm32mp157c-m4-srm.dtsi -index 5ebe24b..9ea9736 100644 ---- a/arch/arm/dts/stm32mp157c-m4-srm.dtsi -+++ b/arch/arm/dts/stm32mp157c-m4-srm.dtsi -@@ -295,14 +295,14 @@ - m4_m_can1: can@4400e000 { - compatible = "rproc-srm-dev"; - reg = <0x4400e000>, <0x44011000>; -- clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; -+ clocks = <&rcc FDCAN>, <&rcc FDCAN_K>; - clock-names = "hclk", "cclk"; - status = "disabled"; - }; - m4_m_can2: can@4400f000 { - compatible = "rproc-srm-dev"; - reg = <0x4400f000>, <0x44011000>; -- clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; -+ clocks = <&rcc FDCAN>, <&rcc FDCAN_K>; - clock-names = "hclk", "cclk"; - status = "disabled"; - }; -diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp157c.dtsi -index 4de499e..c94a1f25 100644 ---- a/arch/arm/dts/stm32mp157c.dtsi -+++ b/arch/arm/dts/stm32mp157c.dtsi -@@ -5,6 +5,7 @@ - */ - #include - #include -+#include - #include - - / { -@@ -58,6 +59,7 @@ - , - ; - interrupt-parent = <&intc>; -+ always-on; - }; - - clocks { -@@ -131,12 +133,6 @@ - thermal-sensors = <&dts>; - - trips { -- cpu_alert1: cpu-alert1 { -- temperature = <85000>; -- hysteresis = <0>; -- type = "passive"; -- }; -- - cpu-crit { - temperature = <120000>; - hysteresis = <0>; -@@ -203,6 +199,7 @@ - - pwm { - compatible = "st,stm32-pwm"; -+ #pwm-cells = <3>; - status = "disabled"; - }; - -@@ -231,6 +228,7 @@ - - pwm { - compatible = "st,stm32-pwm"; -+ #pwm-cells = <3>; - status = "disabled"; - }; - -@@ -257,6 +255,7 @@ - - pwm { - compatible = "st,stm32-pwm"; -+ #pwm-cells = <3>; - status = "disabled"; - }; - -@@ -285,6 +284,7 @@ - - pwm { - compatible = "st,stm32-pwm"; -+ #pwm-cells = <3>; - status = "disabled"; - }; - -@@ -342,6 +342,7 @@ - - pwm { - compatible = "st,stm32-pwm"; -+ #pwm-cells = <3>; - status = "disabled"; - }; - -@@ -363,6 +364,7 @@ - - pwm { - compatible = "st,stm32-pwm"; -+ #pwm-cells = <3>; - status = "disabled"; - }; - -@@ -384,6 +386,7 @@ - - pwm { - compatible = "st,stm32-pwm"; -+ #pwm-cells = <3>; - status = "disabled"; - }; - -@@ -430,8 +433,8 @@ - interrupts = ; - clocks = <&rcc SPI2_K>; - resets = <&rcc SPI2_R>; -- dmas = <&dmamux1 39 0x400 0x05>, -- <&dmamux1 40 0x400 0x05>; -+ dmas = <&dmamux1 39 0x400 0x01>, -+ <&dmamux1 40 0x400 0x01>; - dma-names = "rx", "tx"; - power-domains = <&pd_core>; - status = "disabled"; -@@ -456,8 +459,8 @@ - interrupts = ; - clocks = <&rcc SPI3_K>; - resets = <&rcc SPI3_R>; -- dmas = <&dmamux1 61 0x400 0x05>, -- <&dmamux1 62 0x400 0x05>; -+ dmas = <&dmamux1 61 0x400 0x01>, -+ <&dmamux1 62 0x400 0x01>; - dma-names = "rx", "tx"; - power-domains = <&pd_core>; - status = "disabled"; -@@ -555,6 +558,7 @@ - dma-names = "rx", "tx"; - power-domains = <&pd_core>; - st,syscfg-fmp = <&syscfg 0x4 0x1>; -+ st,syscfg-fmp-clr = <&syscfg 0x44 0x1>; - status = "disabled"; - }; - -@@ -574,6 +578,7 @@ - dma-names = "rx", "tx"; - power-domains = <&pd_core>; - st,syscfg-fmp = <&syscfg 0x4 0x2>; -+ st,syscfg-fmp-clr = <&syscfg 0x44 0x2>; - status = "disabled"; - }; - -@@ -593,6 +598,7 @@ - dma-names = "rx", "tx"; - power-domains = <&pd_core>; - st,syscfg-fmp = <&syscfg 0x4 0x4>; -+ st,syscfg-fmp-clr = <&syscfg 0x44 0x4>; - status = "disabled"; - }; - -@@ -612,6 +618,7 @@ - dma-names = "rx", "tx"; - power-domains = <&pd_core>; - st,syscfg-fmp = <&syscfg 0x4 0x10>; -+ st,syscfg-fmp-clr = <&syscfg 0x44 0x10>; - status = "disabled"; - }; - -@@ -619,7 +626,7 @@ - compatible = "st,stm32-cec"; - reg = <0x40016000 0x400>; - interrupts = ; -- clocks = <&rcc CEC_K>, <&clk_lse>; -+ clocks = <&rcc CEC_K>, <&rcc CEC>; - clock-names = "cec", "hdmi-cec"; - power-domains = <&pd_core>; - status = "disabled"; -@@ -695,6 +702,7 @@ - - pwm { - compatible = "st,stm32-pwm"; -+ #pwm-cells = <3>; - status = "disabled"; - }; - -@@ -725,6 +733,7 @@ - - pwm { - compatible = "st,stm32-pwm"; -+ #pwm-cells = <3>; - status = "disabled"; - }; - -@@ -756,8 +765,8 @@ - interrupts = ; - clocks = <&rcc SPI1_K>; - resets = <&rcc SPI1_R>; -- dmas = <&dmamux1 37 0x400 0x05>, -- <&dmamux1 38 0x400 0x05>; -+ dmas = <&dmamux1 37 0x400 0x01>, -+ <&dmamux1 38 0x400 0x01>; - dma-names = "rx", "tx"; - power-domains = <&pd_core>; - status = "disabled"; -@@ -782,8 +791,8 @@ - interrupts = ; - clocks = <&rcc SPI4_K>; - resets = <&rcc SPI4_R>; -- dmas = <&dmamux1 83 0x400 0x05>, -- <&dmamux1 84 0x400 0x05>; -+ dmas = <&dmamux1 83 0x400 0x01>, -+ <&dmamux1 84 0x400 0x01>; - dma-names = "rx", "tx"; - power-domains = <&pd_core>; - status = "disabled"; -@@ -805,6 +814,7 @@ - - pwm { - compatible = "st,stm32-pwm"; -+ #pwm-cells = <3>; - status = "disabled"; - }; - -@@ -829,6 +839,7 @@ - - pwm { - compatible = "st,stm32-pwm"; -+ #pwm-cells = <3>; - status = "disabled"; - }; - timer@15 { -@@ -852,6 +863,7 @@ - - pwm { - compatible = "st,stm32-pwm"; -+ #pwm-cells = <3>; - status = "disabled"; - }; - -@@ -870,8 +882,8 @@ - interrupts = ; - clocks = <&rcc SPI5_K>; - resets = <&rcc SPI5_R>; -- dmas = <&dmamux1 85 0x400 0x05>, -- <&dmamux1 86 0x400 0x05>; -+ dmas = <&dmamux1 85 0x400 0x01>, -+ <&dmamux1 86 0x400 0x01>; - dma-names = "rx", "tx"; - power-domains = <&pd_core>; - status = "disabled"; -@@ -892,6 +904,8 @@ - - compatible = "st,stm32-sai-sub-a"; - reg = <0x4 0x1c>; -+ clocks = <&rcc SAI1_K>; -+ clock-names = "sai_ck"; - dmas = <&dmamux1 87 0x400 0x01>; - status = "disabled"; - }; -@@ -900,6 +914,8 @@ - #sound-dai-cells = <0>; - compatible = "st,stm32-sai-sub-b"; - reg = <0x24 0x1c>; -+ clocks = <&rcc SAI1_K>; -+ clock-names = "sai_ck"; - dmas = <&dmamux1 88 0x400 0x01>; - status = "disabled"; - }; -@@ -919,6 +935,8 @@ - #sound-dai-cells = <0>; - compatible = "st,stm32-sai-sub-a"; - reg = <0x4 0x1c>; -+ clocks = <&rcc SAI2_K>; -+ clock-names = "sai_ck"; - dmas = <&dmamux1 89 0x400 0x01>; - status = "disabled"; - }; -@@ -927,6 +945,8 @@ - #sound-dai-cells = <0>; - compatible = "st,stm32-sai-sub-b"; - reg = <0x24 0x1c>; -+ clocks = <&rcc SAI2_K>; -+ clock-names = "sai_ck"; - dmas = <&dmamux1 90 0x400 0x01>; - status = "disabled"; - }; -@@ -946,6 +966,8 @@ - #sound-dai-cells = <0>; - compatible = "st,stm32-sai-sub-a"; - reg = <0x04 0x1c>; -+ clocks = <&rcc SAI3_K>; -+ clock-names = "sai_ck"; - dmas = <&dmamux1 113 0x400 0x01>; - status = "disabled"; - }; -@@ -954,6 +976,8 @@ - #sound-dai-cells = <0>; - compatible = "st,stm32-sai-sub-b"; - reg = <0x24 0x1c>; -+ clocks = <&rcc SAI3_K>; -+ clock-names = "sai_ck"; - dmas = <&dmamux1 114 0x400 0x01>; - status = "disabled"; - }; -@@ -1067,6 +1091,7 @@ - , - ; - clocks = <&rcc DMA1>; -+ resets = <&rcc DMA1_R>; - #dma-cells = <4>; - st,mem2mem; - dma-requests = <8>; -@@ -1093,6 +1118,7 @@ - , - ; - clocks = <&rcc DMA2>; -+ resets = <&rcc DMA2_R>; - #dma-cells = <4>; - st,mem2mem; - dma-requests = <8>; -@@ -1115,6 +1141,7 @@ - dma-masters = <&dma1 &dma2>; - dma-channels = <16>; - clocks = <&rcc DMAMUX>; -+ resets = <&rcc DMAMUX_R>; - }; - - adc: adc@48003000 { -@@ -1215,13 +1242,16 @@ - clock-names = "otg"; - resets = <&rcc USBO_R>; - reset-names = "dwc2"; -- interrupts = ; -+ interrupts-extended = <&intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 44 1>; -+ interrupt-names = "event", "wakeup"; - g-rx-fifo-size = <256>; - g-np-tx-fifo-size = <32>; - g-tx-fifo-size = <128 128 64 64 64 64 32 32>; - dr_mode = "otg"; - usb33d-supply = <&usb33>; - power-domains = <&pd_core>; -+ wakeup-source; - status = "disabled"; - }; - -@@ -1257,7 +1287,7 @@ - resets = <&rcc CAMITF_R>; - clocks = <&rcc DCMI>; - clock-names = "mclk"; -- dmas = <&dmamux1 75 0x400 0xd>; -+ dmas = <&dmamux1 75 0x400 0x1d>; - dma-names = "tx"; - status = "disabled"; - }; -@@ -1442,6 +1472,8 @@ - #sound-dai-cells = <0>; - compatible = "st,stm32-sai-sub-b"; - reg = <0x24 0x1c>; -+ clocks = <&rcc SAI4_K>; -+ clock-names = "sai_ck"; - dmas = <&dmamux1 100 0x400 0x01>; - status = "disabled"; - }; -@@ -1623,7 +1655,7 @@ - interrupts = ; - clocks = <&rcc HASH1>; - resets = <&rcc HASH1_R>; -- dmas = <&mdma1 31 0x10 0x1000A02 0x0 0x0 0x0 0x0>; -+ dmas = <&mdma1 31 0x10 0x1000A02 0x0 0x0 0x0>; - dma-names = "in"; - dma-maxburst = <2>; - status = "disabled"; -@@ -1642,6 +1674,7 @@ - reg = <0x58000000 0x1000>; - interrupts = ; - clocks = <&rcc MDMA>; -+ resets = <&rcc MDMA_R>; - #dma-cells = <6>; - dma-channels = <32>; - dma-requests = <48>; -@@ -1756,7 +1789,6 @@ - clocks = <&rcc USBH>; - resets = <&rcc USBH_R>; - interrupts = ; -- power-domains = <&pd_core>; - status = "disabled"; - }; - -@@ -1765,9 +1797,12 @@ - reg = <0x5800d000 0x1000>; - clocks = <&rcc USBH>; - resets = <&rcc USBH_R>; -- interrupts = ; -+ interrupts-extended = <&intc GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 43 1>; -+ interrupt-names = "event", "wakeup"; - companion = <&usbh_ohci>; - power-domains = <&pd_core>; -+ wakeup-source; - status = "disabled"; - }; - -@@ -1834,6 +1869,15 @@ - }; - }; - -+ ddrperfm: perf@5a007000 { -+ compatible = "st,stm32-ddr-pmu"; -+ reg = <0x5a007000 0x400>; -+ clocks = <&rcc DDRPERFM>, <&rcc PLL2_R>; -+ clock-names = "bus", "ddr"; -+ resets = <&rcc DDRPERFM_R>; -+ status = "okay"; -+ }; -+ - usart1: serial@5c000000 { - compatible = "st,stm32h7-uart"; - reg = <0x5c000000 0x400>; -@@ -1878,6 +1922,7 @@ - dma-names = "rx", "tx"; - power-domains = <&pd_core>; - st,syscfg-fmp = <&syscfg 0x4 0x8>; -+ st,syscfg-fmp-clr = <&syscfg 0x44 0x8>; - status = "disabled"; - }; - -@@ -1920,6 +1965,7 @@ - dma-names = "rx", "tx"; - power-domains = <&pd_core>; - st,syscfg-fmp = <&syscfg 0x4 0x20>; -+ st,syscfg-fmp-clr = <&syscfg 0x44 0x20>; - status = "disabled"; - }; - --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0012-ARM-v2018.11-stm32mp-r3-CONFIG.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0012-ARM-v2018.11-stm32mp-r3-CONFIG.patch deleted file mode 100644 index ab08250..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0012-ARM-v2018.11-stm32mp-r3-CONFIG.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 4407a960368fbc08654cc08ea18856565ec562fb Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Tue, 17 Sep 2019 13:55:59 +0200 -Subject: [PATCH 12/13] ARM v2018.11 stm32mp r3 CONFIG - ---- - configs/stm32mp15_basic_defconfig | 17 ++++++++++++++--- - configs/stm32mp15_optee_defconfig | 16 +++++++++++++--- - configs/stm32mp15_trusted_defconfig | 16 +++++++++++++--- - 3 files changed, 40 insertions(+), 9 deletions(-) - -diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig -index ad3424e..3eff6b5 100644 ---- a/configs/stm32mp15_basic_defconfig -+++ b/configs/stm32mp15_basic_defconfig -@@ -9,6 +9,7 @@ CONFIG_SPL_SPI_SUPPORT=y - # CONFIG_ARMV7_VIRT is not set - CONFIG_DISTRO_DEFAULTS=y - CONFIG_FIT=y -+CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=3 - CONFIG_SPL_I2C_SUPPORT=y -@@ -16,6 +17,7 @@ CONFIG_SPL_MTD_SUPPORT=y - CONFIG_SPL_POWER_SUPPORT=y - CONFIG_SYS_PROMPT="STM32MP> " - # CONFIG_CMD_BOOTD is not set -+CONFIG_CMD_DTIMG=y - # CONFIG_CMD_ELF is not set - # CONFIG_CMD_IMI is not set - # CONFIG_CMD_XIMG is not set -@@ -32,6 +34,7 @@ CONFIG_CMD_I2C=y - CONFIG_CMD_MMC=y - CONFIG_CMD_REMOTEPROC=y - CONFIG_CMD_SF=y -+CONFIG_CMD_SPI=y - CONFIG_CMD_USB=y - CONFIG_CMD_USB_MASS_STORAGE=y - CONFIG_CMD_BMP=y -@@ -45,6 +48,14 @@ CONFIG_CMD_MTDPARTS=y - CONFIG_CMD_UBI=y - # CONFIG_SPL_DOS_PARTITION is not set - CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" -+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_NOWHERE=y -+CONFIG_ENV_IS_IN_EXT4=y -+CONFIG_ENV_IS_IN_SPI_FLASH=y -+CONFIG_ENV_IS_IN_UBI=y -+CONFIG_ENV_EXT4_INTERFACE="mmc" -+CONFIG_ENV_EXT4_DEVICE_AND_PART="0:auto" -+CONFIG_ENV_EXT4_FILE="/uboot.env" - CONFIG_STM32_ADC=y - CONFIG_USB_FUNCTION_FASTBOOT=y - CONFIG_FASTBOOT_BUF_ADDR=0xC0000000 -@@ -74,7 +85,6 @@ 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_FIXED=y - CONFIG_DM_ETH=y - CONFIG_DWC_ETH_QOS=y - CONFIG_PHY=y -@@ -91,10 +101,13 @@ CONFIG_DM_REGULATOR_STM32_VREFBUF=y - CONFIG_DM_REGULATOR_STPMIC1=y - CONFIG_STM32MP1_DDR_INTERACTIVE=y - CONFIG_REMOTEPROC_STM32_COPRO=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_USB=y - CONFIG_DM_USB=y - CONFIG_USB_EHCI_HCD=y -@@ -113,6 +126,4 @@ CONFIG_VIDEO_STM32=y - CONFIG_VIDEO_STM32_DSI=y - CONFIG_VIDEO_STM32_MAX_XRES=1280 - CONFIG_VIDEO_STM32_MAX_YRES=800 --CONFIG_STM32MP_WATCHDOG=y - CONFIG_FDT_FIXUP_PARTITIONS=y --# CONFIG_EFI_LOADER is not set -diff --git a/configs/stm32mp15_optee_defconfig b/configs/stm32mp15_optee_defconfig -index a24727c..9ef8f62 100644 ---- a/configs/stm32mp15_optee_defconfig -+++ b/configs/stm32mp15_optee_defconfig -@@ -5,8 +5,10 @@ CONFIG_TARGET_STM32MP1=y - CONFIG_STM32MP1_OPTEE=y - CONFIG_DISTRO_DEFAULTS=y - CONFIG_FIT=y -+CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" - CONFIG_SYS_PROMPT="STM32MP> " - # CONFIG_CMD_BOOTD is not set -+CONFIG_CMD_DTIMG=y - # CONFIG_CMD_ELF is not set - # CONFIG_CMD_IMI is not set - # CONFIG_CMD_XIMG is not set -@@ -23,6 +25,7 @@ CONFIG_CMD_I2C=y - CONFIG_CMD_MMC=y - CONFIG_CMD_REMOTEPROC=y - CONFIG_CMD_SF=y -+CONFIG_CMD_SPI=y - CONFIG_CMD_USB=y - CONFIG_CMD_USB_MASS_STORAGE=y - CONFIG_CMD_BMP=y -@@ -35,6 +38,13 @@ CONFIG_CMD_EXT4_WRITE=y - CONFIG_CMD_MTDPARTS=y - CONFIG_CMD_UBI=y - CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" -+CONFIG_ENV_IS_NOWHERE=y -+CONFIG_ENV_IS_IN_EXT4=y -+CONFIG_ENV_IS_IN_SPI_FLASH=y -+CONFIG_ENV_IS_IN_UBI=y -+CONFIG_ENV_EXT4_INTERFACE="mmc" -+CONFIG_ENV_EXT4_DEVICE_AND_PART="0:auto" -+CONFIG_ENV_EXT4_FILE="/uboot.env" - CONFIG_STM32_ADC=y - CONFIG_USB_FUNCTION_FASTBOOT=y - CONFIG_FASTBOOT_BUF_ADDR=0xC0000000 -@@ -64,7 +74,6 @@ 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_FIXED=y - CONFIG_DM_ETH=y - CONFIG_DWC_ETH_QOS=y - CONFIG_PHY=y -@@ -78,10 +87,13 @@ CONFIG_DM_REGULATOR_GPIO=y - CONFIG_DM_REGULATOR_STM32_VREFBUF=y - CONFIG_DM_REGULATOR_STPMIC1=y - CONFIG_REMOTEPROC_STM32_COPRO=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_USB=y - CONFIG_DM_USB=y - CONFIG_USB_EHCI_HCD=y -@@ -100,6 +112,4 @@ CONFIG_VIDEO_STM32=y - CONFIG_VIDEO_STM32_DSI=y - CONFIG_VIDEO_STM32_MAX_XRES=1280 - CONFIG_VIDEO_STM32_MAX_YRES=800 --CONFIG_STM32MP_WATCHDOG=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 e41506b..7635d7f 100644 ---- a/configs/stm32mp15_trusted_defconfig -+++ b/configs/stm32mp15_trusted_defconfig -@@ -4,8 +4,10 @@ CONFIG_SYS_MALLOC_F_LEN=0x3000 - CONFIG_TARGET_STM32MP1=y - CONFIG_DISTRO_DEFAULTS=y - CONFIG_FIT=y -+CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" - CONFIG_SYS_PROMPT="STM32MP> " - # CONFIG_CMD_BOOTD is not set -+CONFIG_CMD_DTIMG=y - # CONFIG_CMD_ELF is not set - # CONFIG_CMD_IMI is not set - # CONFIG_CMD_XIMG is not set -@@ -22,6 +24,7 @@ CONFIG_CMD_I2C=y - CONFIG_CMD_MMC=y - CONFIG_CMD_REMOTEPROC=y - CONFIG_CMD_SF=y -+CONFIG_CMD_SPI=y - CONFIG_CMD_USB=y - CONFIG_CMD_USB_MASS_STORAGE=y - CONFIG_CMD_BMP=y -@@ -34,6 +37,13 @@ CONFIG_CMD_EXT4_WRITE=y - CONFIG_CMD_MTDPARTS=y - CONFIG_CMD_UBI=y - CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" -+CONFIG_ENV_IS_NOWHERE=y -+CONFIG_ENV_IS_IN_EXT4=y -+CONFIG_ENV_IS_IN_SPI_FLASH=y -+CONFIG_ENV_IS_IN_UBI=y -+CONFIG_ENV_EXT4_INTERFACE="mmc" -+CONFIG_ENV_EXT4_DEVICE_AND_PART="0:auto" -+CONFIG_ENV_EXT4_FILE="/uboot.env" - CONFIG_STM32_ADC=y - CONFIG_USB_FUNCTION_FASTBOOT=y - CONFIG_FASTBOOT_BUF_ADDR=0xC0000000 -@@ -63,7 +73,6 @@ 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_FIXED=y - CONFIG_DM_ETH=y - CONFIG_DWC_ETH_QOS=y - CONFIG_PHY=y -@@ -77,10 +86,13 @@ CONFIG_DM_REGULATOR_GPIO=y - CONFIG_DM_REGULATOR_STM32_VREFBUF=y - CONFIG_DM_REGULATOR_STPMIC1=y - CONFIG_REMOTEPROC_STM32_COPRO=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_USB=y - CONFIG_DM_USB=y - CONFIG_USB_EHCI_HCD=y -@@ -99,6 +111,4 @@ CONFIG_VIDEO_STM32=y - CONFIG_VIDEO_STM32_DSI=y - CONFIG_VIDEO_STM32_MAX_XRES=1280 - CONFIG_VIDEO_STM32_MAX_YRES=800 --CONFIG_STM32MP_WATCHDOG=y - CONFIG_FDT_FIXUP_PARTITIONS=y --# CONFIG_EFI_LOADER is not set --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0013-ARM-v2018.11-stm32mp-r3-MISC.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0013-ARM-v2018.11-stm32mp-r3-MISC.patch deleted file mode 100644 index 9f74a76..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0013-ARM-v2018.11-stm32mp-r3-MISC.patch +++ /dev/null @@ -1,6902 +0,0 @@ -From a827cb0a8ffbd388b225f0b523e08f19dbcfd614 Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Tue, 17 Sep 2019 13:56:28 +0200 -Subject: [PATCH 13/13] ARM v2018.11 stm32mp r3 MISC - ---- - Makefile | 2 +- - README | 3 + - cmd/bootefi.c | 6 +- - cmd/dtimg.c | 50 +- - cmd/fastboot.c | 2 + - cmd/nvedit.c | 36 +- - cmd/part.c | 16 +- - cmd/pinmux.c | 1 + - cmd/sf.c | 3 +- - common/board_f.c | 2 +- - common/cli_readline.c | 6 + - common/console.c | 47 +- - common/image-android-dt.c | 42 ++ - common/spl/spl_spi.c | 2 + - doc/device-tree-bindings/clock/st,stm32mp1.txt | 4 +- - doc/device-tree-bindings/i2c/i2c-stm32.txt | 61 +- - doc/device-tree-bindings/net/stm32-dwmac.txt | 6 +- - doc/device-tree-bindings/ram/st,stm32mp1-ddr.txt | 2 +- - .../regulator/st,stm32mp1-pwr-reg.txt | 11 + - doc/device-tree-bindings/spi/spi-stm32-qspi.txt | 69 +-- - drivers/adc/adc-uclass.c | 17 +- - drivers/adc/stm32-adc-core.c | 3 +- - drivers/adc/stm32-adc.c | 13 +- - drivers/clk/clk_stm32mp1.c | 53 +- - drivers/core/root.c | 3 +- - drivers/core/util.c | 2 + - drivers/firmware/psci.c | 2 +- - drivers/gpio/Kconfig | 4 +- - drivers/gpio/Makefile | 2 +- - drivers/gpio/stm32_gpio.c | 210 +++++++ - drivers/gpio/stm32f7_gpio.c | 216 -------- - drivers/hwspinlock/stm32_hwspinlock.c | 26 +- - drivers/i2c/stm32f7_i2c.c | 12 +- - drivers/mailbox/stm32-ipcc.c | 2 +- - drivers/misc/stm32mp_fuse.c | 1 + - drivers/mmc/mmc_write.c | 2 +- - drivers/mmc/stm32_sdmmc2.c | 8 +- - drivers/mtd/mtd_uboot.c | 5 +- - drivers/mtd/nand/raw/stm32_fmc2_nand.c | 95 ++-- - drivers/net/dwc_eth_qos.c | 85 +-- - drivers/phy/phy-stm32-usbphyc.c | 3 +- - drivers/pinctrl/pinctrl-stmfx.c | 38 +- - drivers/pinctrl/pinctrl_stm32.c | 62 ++- - drivers/power/regulator/regulator-uclass.c | 2 +- - drivers/power/regulator/stm32-vrefbuf.c | 2 +- - drivers/ram/stm32mp1/Kconfig | 10 +- - drivers/ram/stm32mp1/Makefile | 3 +- - drivers/ram/stm32mp1/stm32mp1_ddr.c | 157 ++++-- - drivers/ram/stm32mp1/stm32mp1_ddr.h | 2 - - drivers/ram/stm32mp1/stm32mp1_interactive.c | 51 +- - drivers/ram/stm32mp1/stm32mp1_ram.c | 18 +- - drivers/ram/stm32mp1/stm32mp1_tests.c | 388 ++++++++----- - drivers/ram/stm32mp1/stm32mp1_tuning.c | 276 +++++---- - drivers/ram/stm32mp1/stm32mp1_tuning.h | 54 -- - drivers/remoteproc/rproc-uclass.c | 12 +- - drivers/remoteproc/stm32_copro.c | 6 +- - drivers/rtc/Kconfig | 7 + - drivers/rtc/Makefile | 1 + - drivers/rtc/stm32_rtc.c | 308 +++++++++++ - drivers/serial/serial_stm32.c | 11 +- - drivers/serial/serial_stm32.h | 2 + - drivers/spi/Kconfig | 8 + - drivers/spi/Makefile | 1 + - drivers/spi/spi-mem.c | 41 +- - drivers/spi/spi-uclass.c | 4 +- - drivers/spi/stm32_qspi.c | 375 +++++++++---- - drivers/spi/stm32_spi.c | 616 +++++++++++++++++++++ - drivers/usb/gadget/dwc2_udc_otg.c | 18 +- - drivers/usb/gadget/dwc2_udc_otg_priv.h | 1 - - drivers/usb/gadget/dwc2_udc_otg_regs.h | 23 +- - drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c | 14 +- - drivers/video/orisetech_otm8009a.c | 7 +- - drivers/video/video-uclass.c | 4 +- - drivers/watchdog/Kconfig | 59 +- - drivers/watchdog/Makefile | 2 +- - drivers/watchdog/stm32mp_wdt.c | 120 ++-- - env/Kconfig | 18 +- - env/ext4.c | 34 +- - fs/ext4/ext4_write.c | 6 + - include/configs/stm32mp1.h | 123 +++- - include/dfu.h | 1 + - include/environment.h | 9 + - include/ext4fs.h | 1 + - include/image-android-dt.h | 2 + - include/linux/mtd/mtd.h | 1 + - include/netdev.h | 2 + - include/spi.h | 9 +- - include/usb/dwc2_udc.h | 6 + - test/py/tests/test_pinmux.py | 4 + - 89 files changed, 2850 insertions(+), 1204 deletions(-) - create mode 100644 drivers/gpio/stm32_gpio.c - delete mode 100644 drivers/gpio/stm32f7_gpio.c - delete mode 100644 drivers/ram/stm32mp1/stm32mp1_tuning.h - create mode 100644 drivers/rtc/stm32_rtc.c - create mode 100644 drivers/spi/stm32_spi.c - -diff --git a/Makefile b/Makefile -index 693ffae..b9579b2 100644 ---- a/Makefile -+++ b/Makefile -@@ -3,7 +3,7 @@ - VERSION = 2018 - PATCHLEVEL = 11 - SUBLEVEL = --EXTRAVERSION = -stm32mp-r2 -+EXTRAVERSION = -stm32mp-r3 - NAME = - - # *DOCUMENTATION* -diff --git a/README b/README -index a46c7c6..788858c 100644 ---- a/README -+++ b/README -@@ -2192,6 +2192,9 @@ The following options need to be configured: - CONFIG_SF_DEFAULT_MODE (see include/spi.h) - CONFIG_SF_DEFAULT_SPEED in Hz - -+ In case of DT boot, SPI don't read default speed and mode -+ from CONFIG_*, but from platdata values computed from available -+ DT node - - - TFTP Fixed UDP Port: - CONFIG_TFTP_PORT -diff --git a/cmd/bootefi.c b/cmd/bootefi.c -index 4d68d80..595dbdd 100644 ---- a/cmd/bootefi.c -+++ b/cmd/bootefi.c -@@ -190,13 +190,13 @@ static efi_status_t copy_fdt(ulong *fdt_addrp, ulong *fdt_sizep) - /* Safe fdt location is at 127MB */ - new_fdt_addr = fdt_ram_start + (127 * 1024 * 1024) + fdt_size; - ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, -- EFI_RUNTIME_SERVICES_DATA, fdt_pages, -+ EFI_BOOT_SERVICES_DATA, fdt_pages, - &new_fdt_addr); - if (ret != EFI_SUCCESS) { - /* If we can't put it there, put it somewhere */ - new_fdt_addr = (ulong)memalign(EFI_PAGE_SIZE, fdt_size); - ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, -- EFI_RUNTIME_SERVICES_DATA, fdt_pages, -+ EFI_BOOT_SERVICES_DATA, fdt_pages, - &new_fdt_addr); - if (ret != EFI_SUCCESS) { - printf("ERROR: Failed to reserve space for FDT\n"); -@@ -625,7 +625,7 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path) - - part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition, - 1); -- if (part < 0) -+ if (part < 0 || !desc) - return; - - bootefi_device_path = efi_dp_from_part(desc, part); -diff --git a/cmd/dtimg.c b/cmd/dtimg.c -index 65c8d10..eca6a23 100644 ---- a/cmd/dtimg.c -+++ b/cmd/dtimg.c -@@ -98,10 +98,52 @@ static int do_dtimg_size(cmd_tbl_t *cmdtp, int flag, int argc, - return dtimg_get_fdt(argc, argv, CMD_DTIMG_SIZE); - } - -+static int do_dtimg_getindex(cmd_tbl_t *cmdtp, int flag, int argc, -+ char * const argv[]) -+{ -+ char *endp; -+ ulong hdr_addr; -+ int index; -+ char buf[512] = { 0 }; -+ -+ if (argc < 4) -+ return CMD_RET_USAGE; -+ -+ hdr_addr = simple_strtoul(argv[1], &endp, 16); -+ if (*endp != '\0') { -+ printf("Error: Wrong image address\n"); -+ return CMD_RET_FAILURE; -+ } -+ -+ if (!android_dt_check_header(hdr_addr)) { -+ printf("Error: DT image header is incorrect\n"); -+ return CMD_RET_FAILURE; -+ } -+ -+ index = android_dt_get_index(hdr_addr, strtoul(argv[2], NULL, 0), -+ strtoul(argv[3], NULL, 0)); -+ -+ if (index < 0) { -+ printf("Error: board id %04lx not found in DT table\n", -+ strtoul(argv[2], NULL, 0)); -+ return CMD_RET_FAILURE; -+ } -+ -+ snprintf(buf, sizeof(buf), "%i", index); -+ -+ if (argc == 5) -+ env_set(argv[4], buf); -+ else -+ printf("%s\n", buf); -+ -+ return CMD_RET_SUCCESS; -+} -+ - static cmd_tbl_t cmd_dtimg_sub[] = { - U_BOOT_CMD_MKENT(dump, 2, 0, do_dtimg_dump, "", ""), - U_BOOT_CMD_MKENT(start, 4, 0, do_dtimg_start, "", ""), - U_BOOT_CMD_MKENT(size, 4, 0, do_dtimg_size, "", ""), -+ U_BOOT_CMD_MKENT(getindex, 5, 0, do_dtimg_getindex, "", ""), - }; - - static int do_dtimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -@@ -137,5 +179,11 @@ U_BOOT_CMD( - " - get size (hex, bytes) of FDT in the image, by index\n" - " : image address in RAM, in hex\n" - " : index of desired FDT in the image\n" -- " : name of variable where to store size of FDT" -+ " : name of variable where to store size of FDT\n" -+ "dtimg getindex [varname]\n" -+ " - get index of FDT in the image, by board identifier and revision\n" -+ " : image address in RAM, in hex\n" -+ " : board identifier\n" -+ " : board revision (0 if not used)\n" -+ " [varname]: name of variable where to store index of FDT" - ); -diff --git a/cmd/fastboot.c b/cmd/fastboot.c -index ae3a5f6..e3d67b2 100644 ---- a/cmd/fastboot.c -+++ b/cmd/fastboot.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - - static int do_fastboot_udp(int argc, char *const argv[], - uintptr_t buf_addr, size_t buf_size) -@@ -74,6 +75,7 @@ static int do_fastboot_usb(int argc, char *const argv[], - break; - if (ctrlc()) - break; -+ WATCHDOG_RESET(); - usb_gadget_handle_interrupts(controller_index); - } - -diff --git a/cmd/nvedit.c b/cmd/nvedit.c -index de16c72..767e824 100644 ---- a/cmd/nvedit.c -+++ b/cmd/nvedit.c -@@ -39,18 +39,24 @@ - - DECLARE_GLOBAL_DATA_PTR; - --#if !defined(CONFIG_ENV_IS_IN_EEPROM) && \ -- !defined(CONFIG_ENV_IS_IN_FLASH) && \ -- !defined(CONFIG_ENV_IS_IN_MMC) && \ -- !defined(CONFIG_ENV_IS_IN_FAT) && \ -- !defined(CONFIG_ENV_IS_IN_EXT4) && \ -- !defined(CONFIG_ENV_IS_IN_NAND) && \ -- !defined(CONFIG_ENV_IS_IN_NVRAM) && \ -- !defined(CONFIG_ENV_IS_IN_ONENAND) && \ -- !defined(CONFIG_ENV_IS_IN_SATA) && \ -- !defined(CONFIG_ENV_IS_IN_SPI_FLASH) && \ -- !defined(CONFIG_ENV_IS_IN_REMOTE) && \ -- !defined(CONFIG_ENV_IS_IN_UBI) && \ -+#if defined(CONFIG_ENV_IS_IN_EEPROM) || \ -+ defined(CONFIG_ENV_IS_IN_FLASH) || \ -+ defined(CONFIG_ENV_IS_IN_MMC) || \ -+ defined(CONFIG_ENV_IS_IN_FAT) || \ -+ defined(CONFIG_ENV_IS_IN_EXT4) || \ -+ defined(CONFIG_ENV_IS_IN_NAND) || \ -+ defined(CONFIG_ENV_IS_IN_NVRAM) || \ -+ defined(CONFIG_ENV_IS_IN_ONENAND) || \ -+ defined(CONFIG_ENV_IS_IN_SATA) || \ -+ defined(CONFIG_ENV_IS_IN_SPI_FLASH) || \ -+ defined(CONFIG_ENV_IS_IN_REMOTE) || \ -+ defined(CONFIG_ENV_IS_IN_UBI) -+ -+#define ENV_IS_IN_DEVICE -+ -+#endif -+ -+#if !defined(ENV_IS_IN_DEVICE) && \ - !defined(CONFIG_ENV_IS_NOWHERE) - # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|MMC|FAT|EXT4|\ - NAND|NVRAM|ONENAND|SATA|SPI_FLASH|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE -@@ -738,7 +744,7 @@ ulong env_get_ulong(const char *name, int base, ulong default_val) - } - - #ifndef CONFIG_SPL_BUILD --#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) -+#if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE) - static int do_env_save(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) - { -@@ -1194,7 +1200,7 @@ static cmd_tbl_t cmd_env_sub[] = { - #if defined(CONFIG_CMD_RUN) - U_BOOT_CMD_MKENT(run, CONFIG_SYS_MAXARGS, 1, do_run, "", ""), - #endif --#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) -+#if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE) - U_BOOT_CMD_MKENT(save, 1, 0, do_env_save, "", ""), - #endif - U_BOOT_CMD_MKENT(set, CONFIG_SYS_MAXARGS, 0, do_env_set, "", ""), -@@ -1266,7 +1272,7 @@ static char env_help_text[] = - #if defined(CONFIG_CMD_RUN) - "env run var [...] - run commands in an environment variable\n" - #endif --#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) -+#if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE) - "env save - save environment\n" - #endif - "env set [-f] name [arg ...]\n"; -diff --git a/cmd/part.c b/cmd/part.c -index bfb6488..6a75856 100644 ---- a/cmd/part.c -+++ b/cmd/part.c -@@ -24,6 +24,7 @@ - enum cmd_part_info { - CMD_PART_INFO_START = 0, - CMD_PART_INFO_SIZE, -+ CMD_PART_INFO_NB, - }; - - static int do_part_uuid(int argc, char * const argv[]) -@@ -149,6 +150,9 @@ static int do_part_info(int argc, char * const argv[], enum cmd_part_info param) - case CMD_PART_INFO_SIZE: - snprintf(buf, sizeof(buf), LBAF, info.size); - break; -+ case CMD_PART_INFO_NB: -+ snprintf(buf, sizeof(buf), "%i", part); -+ break; - default: - printf("** Unknown cmd_part_info value: %d\n", param); - return 1; -@@ -172,6 +176,11 @@ static int do_part_size(int argc, char * const argv[]) - return do_part_info(argc, argv, CMD_PART_INFO_SIZE); - } - -+static int do_part_nb(int argc, char * const argv[]) -+{ -+ return do_part_info(argc, argv, CMD_PART_INFO_NB); -+} -+ - static int do_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) - { - if (argc < 2) -@@ -185,6 +194,8 @@ static int do_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) - return do_part_start(argc - 2, argv + 2); - else if (!strcmp(argv[1], "size")) - return do_part_size(argc - 2, argv + 2); -+ else if (!strcmp(argv[1], "nb")) -+ return do_part_nb(argc - 2, argv + 2); - - return CMD_RET_USAGE; - } -@@ -206,5 +217,8 @@ U_BOOT_CMD( - " part can be either partition number or partition name\n" - "part size \n" - " - set environment variable to the size of the partition (in blocks)\n" -- " part can be either partition number or partition name" -+ " part can be either partition number or partition name\n" -+ "part nb \n" -+ " - set environment variable to the number of the partition\n" -+ " part shall be the partition name" - ); -diff --git a/cmd/pinmux.c b/cmd/pinmux.c -index 6c8ec51..de909a1 100644 ---- a/cmd/pinmux.c -+++ b/cmd/pinmux.c -@@ -27,6 +27,7 @@ static int do_dev(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) - printf("Can't get the pin-controller: %s!\n", name); - return CMD_RET_FAILURE; - } -+ /* fall through */ - case 1: - if (!currdev) { - printf("Pin-controller device is not set!\n"); -diff --git a/cmd/sf.c b/cmd/sf.c -index 84bb057..f1811d2 100644 ---- a/cmd/sf.c -+++ b/cmd/sf.c -@@ -81,14 +81,13 @@ static int do_spi_flash_probe(int argc, char * const argv[]) - { - unsigned int bus = CONFIG_SF_DEFAULT_BUS; - unsigned int cs = CONFIG_SF_DEFAULT_CS; -+ /* In DM mode, defaults speed and mode will be taken from DT */ - unsigned int speed = CONFIG_SF_DEFAULT_SPEED; - unsigned int mode = CONFIG_SF_DEFAULT_MODE; - char *endp; - #ifdef CONFIG_DM_SPI_FLASH - struct udevice *new, *bus_dev; - int ret; -- /* In DM mode defaults will be taken from DT */ -- speed = 0, mode = 0; - #else - struct spi_flash *new; - #endif -diff --git a/common/board_f.c b/common/board_f.c -index 59745d5..1a3b1c7 100644 ---- a/common/board_f.c -+++ b/common/board_f.c -@@ -92,7 +92,7 @@ static int init_func_watchdog_init(void) - (defined(CONFIG_M68K) || defined(CONFIG_MICROBLAZE) || \ - defined(CONFIG_SH) || defined(CONFIG_AT91SAM9_WATCHDOG) || \ - defined(CONFIG_DESIGNWARE_WATCHDOG) || \ -- defined(CONFIG_IMX_WATCHDOG) || defined(CONFIG_STM32MP_WATCHDOG)) -+ defined(CONFIG_IMX_WATCHDOG)) - hw_watchdog_init(); - puts(" Watchdog enabled\n"); - # endif -diff --git a/common/cli_readline.c b/common/cli_readline.c -index 99b6317..a6dc79b 100644 ---- a/common/cli_readline.c -+++ b/common/cli_readline.c -@@ -13,6 +13,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/console.c b/common/console.c -index 9a94f32..d0f2793 100644 ---- a/common/console.c -+++ b/common/console.c -@@ -463,6 +463,11 @@ static void print_pre_console_buffer(int flushpoint) - char buf_out[CONFIG_PRE_CON_BUF_SZ + 1]; - char *buf_in; - -+#ifdef CONFIG_SILENT_CONSOLE -+ if (gd->flags & GD_FLG_SILENT) -+ return; -+#endif -+ - buf_in = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ); - if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ) - in = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ; -@@ -511,8 +516,11 @@ void putc(const char c) - membuff_putbyte(&gd->console_out, c); - #endif - #ifdef CONFIG_SILENT_CONSOLE -- if (gd->flags & GD_FLG_SILENT) -+ if (gd->flags & GD_FLG_SILENT) { -+ if (!(gd->flags & GD_FLG_DEVINIT)) -+ pre_console_putc(c); - return; -+ } - #endif - - #ifdef CONFIG_DISABLE_CONSOLE -@@ -552,8 +560,11 @@ void puts(const char *s) - membuff_put(&gd->console_out, s, strlen(s)); - #endif - #ifdef CONFIG_SILENT_CONSOLE -- if (gd->flags & GD_FLG_SILENT) -+ if (gd->flags & GD_FLG_SILENT) { -+ if (!(gd->flags & GD_FLG_DEVINIT)) -+ pre_console_puts(s); - return; -+ } - #endif - - #ifdef CONFIG_DISABLE_CONSOLE -@@ -713,14 +724,22 @@ int console_assign(int file, const char *devname) - return -1; - } - --static void console_update_silent(void) -+/* return true if the 'silent' flag is removed */ -+static bool console_update_silent(void) - { - #ifdef CONFIG_SILENT_CONSOLE -- if (env_get("silent") != NULL) -+ if (env_get("silent") != NULL) { - gd->flags |= GD_FLG_SILENT; -- else -+ } else { -+ unsigned long flags = gd->flags; -+ - gd->flags &= ~GD_FLG_SILENT; -+ -+ return !!(flags & GD_FLG_SILENT); -+ } - #endif -+ -+ return false; - } - - int console_announce_r(void) -@@ -785,6 +804,13 @@ int console_init_r(void) - #if CONFIG_IS_ENABLED(CONSOLE_MUX) - int iomux_err = 0; - #endif -+ int flushpoint; -+ -+ /* update silent for env loaded from flash (initr_env) */ -+ if (console_update_silent()) -+ flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL; -+ else -+ flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL; - - /* set default handlers at first */ - gd->jt->getc = serial_getc; -@@ -862,7 +888,7 @@ done: - if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) - return 0; - #endif -- print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL); -+ print_pre_console_buffer(flushpoint); - return 0; - } - -@@ -876,8 +902,13 @@ int console_init_r(void) - struct list_head *list = stdio_get_list(); - struct list_head *pos; - struct stdio_dev *dev; -+ int flushpoint; - -- console_update_silent(); -+ /* update silent for env loaded from flash (initr_env) */ -+ if (console_update_silent()) -+ flushpoint = PRE_CONSOLE_FLUSHPOINT1_SERIAL; -+ else -+ flushpoint = PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL; - - #ifdef CONFIG_SPLASH_SCREEN - /* -@@ -940,7 +971,7 @@ int console_init_r(void) - if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) - return 0; - #endif -- print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL); -+ print_pre_console_buffer(flushpoint); - return 0; - } - -diff --git a/common/image-android-dt.c b/common/image-android-dt.c -index c0683ee..90499d7 100644 ---- a/common/image-android-dt.c -+++ b/common/image-android-dt.c -@@ -153,4 +153,46 @@ void android_dt_print_contents(ulong hdr_addr) - unmap_sysmem(fdt); - } - } -+ - #endif -+ -+/** -+ * Get dtb index based on board identifier and revision. -+ * -+ * @param hdr_addr Start address of DT image -+ * @param board_id board identifier -+ * @param board_rev board revision (0 if not used) -+ * -+ * @return index in dt table -+ */ -+int android_dt_get_index(ulong hdr_addr, u32 board_id, u32 board_rev) -+{ -+ const struct dt_table_header *hdr; -+ u32 entry_count, entries_offset, entry_size; -+ u32 i; -+ int ret = -1; -+ -+ hdr = map_sysmem(hdr_addr, sizeof(*hdr)); -+ entry_count = fdt32_to_cpu(hdr->dt_entry_count); -+ entries_offset = fdt32_to_cpu(hdr->dt_entries_offset); -+ entry_size = fdt32_to_cpu(hdr->dt_entry_size); -+ unmap_sysmem(hdr); -+ -+ for (i = 0; i < entry_count; ++i) { -+ const ulong e_addr = hdr_addr + entries_offset + i * entry_size; -+ const struct dt_table_entry *e; -+ -+ e = map_sysmem(e_addr, sizeof(*e)); -+ -+ if ((fdt32_to_cpu(e->id) == board_id) && -+ (board_rev == 0 || fdt32_to_cpu(e->rev) == board_rev)) { -+ ret = i; -+ unmap_sysmem(e); -+ break; -+ } -+ -+ unmap_sysmem(e); -+ } -+ -+ return ret; -+} -diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c -index 3cefc9a..3d21110 100644 ---- a/common/spl/spl_spi.c -+++ b/common/spl/spl_spi.c -@@ -77,6 +77,8 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, - - /* - * Load U-Boot image from SPI flash into RAM -+ * In DM mode: defaults speed and mode will be -+ * taken from DT when available - */ - #ifdef CONFIG_DM_SPI_FLASH - /* In DM mode defaults will be taken from DT */ -diff --git a/doc/device-tree-bindings/clock/st,stm32mp1.txt b/doc/device-tree-bindings/clock/st,stm32mp1.txt -index 02e1460..ec1d703 100644 ---- a/doc/device-tree-bindings/clock/st,stm32mp1.txt -+++ b/doc/device-tree-bindings/clock/st,stm32mp1.txt -@@ -164,8 +164,10 @@ used to define the state of associated ST32MP1 oscillators: - - clk-csi - - At boot the clock tree initialization will -- - enable oscillators present in device tree -+ - enable oscillators present in device tree and not disabled -+ (node with status="disabled"), - - disable HSI oscillator if the node is absent (always activated by bootrom) -+ and not disabled (node with status="disabled"). - - Optional properties : - -diff --git a/doc/device-tree-bindings/i2c/i2c-stm32.txt b/doc/device-tree-bindings/i2c/i2c-stm32.txt -index 352dba5..7f7686e 100644 ---- a/doc/device-tree-bindings/i2c/i2c-stm32.txt -+++ b/doc/device-tree-bindings/i2c/i2c-stm32.txt -@@ -7,6 +7,7 @@ Required properties : - - reg : Offset and length of the register set for the device - - interrupts : Must contain the interrupt id for I2C event and then the - interrupt id for I2C error. -+ Optionnaly a wakeup interrupt may be specified. - - resets: Must contain the phandle to the reset controller. - - clocks: Must contain the input clock of the I2C instance. - - A pinctrl state named "default" must be defined to set pins in mode of -@@ -20,18 +21,25 @@ Optional properties : - the default 100 kHz frequency will be used. - For STM32F4 SoC Standard-mode and Fast-mode are supported, possible values are - 100000 and 400000. -- For STM32F7 SoC, Standard-mode, Fast-mode and Fast-mode Plus are supported, -- possible values are 100000, 400000 and 1000000. --- i2c-scl-rising-time-ns : Only for STM32F7, I2C SCL Rising time for the board -- (default: 25) --- i2c-scl-falling-time-ns : Only for STM32F7, I2C SCL Falling time for the board -- (default: 10) -+ For STM32F7, STM32H7 and STM32MP1 SoCs, Standard-mode, Fast-mode and Fast-mode -+ Plus are supported, possible values are 100000, 400000 and 1000000. -+- i2c-scl-rising-time-ns: I2C SCL Rising time for the board (default: 25) -+ For STM32F7, STM32H7 and STM32MP1 only. -+- i2c-scl-falling-time-ns: I2C SCL Falling time for the board (default: 10) -+ For STM32F7, STM32H7 and STM32MP1 only. - I2C Timings are derived from these 2 values --- st,syscfg-fmp: Only for STM32F7, use to set Fast Mode Plus bit within SYSCFG -- whether Fast Mode Plus speed is selected by slave. -+- st,syscfg-fmp: Use to set Fast Mode Plus bit within SYSCFG when Fast Mode -+ Plus speed is selected by slave. - 1st cell : phandle to syscfg - 2nd cell : register offset within SYSCFG - 3rd cell : register bitmask for FMP bit -+ For STM32F7, STM32H7 and STM32MP1 only. -+- st,syscfg-fmp-clr: Use to clear Fast Mode Plus bit within SYSCFG when Fast -+ Mode Plus speed is selected by slave. -+ 1st cell: phandle to syscfg -+ 2nd cell: clear register offset within SYSCFG -+ 3rd cell: register bitmask for FMP clear bit -+ For STM32MP1 family only. - - Example : - -@@ -61,8 +69,25 @@ Example : - pinctrl-1 = <&i2c1_sda_pin_sleep>, <&i2c1_scl_pin_sleep>; - pinctrl-names = "default", "sleep"; - st,syscfg-fmp = <&syscfg 0x4 0x1>; -+ st,syscfg-fmp-clr = <&syscfg 0x44 0x1>; - }; - -+ i2c@40013000 { -+ compatible = "st,stm32f7-i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x40013000 0x400>; -+ interrupt-names = "event", "error", "wakeup"; -+ interrupts-extended = <&intc GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>, -+ <&intc GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>, -+ <&exti 22 1>; -+ clocks = <&rcc I2C2_K>; -+ resets = <&rcc I2C2_R>; -+ st,syscfg-fmp = <&syscfg 0x4 0x2>; -+ st,syscfg-fmp-clr = <&syscfg 0x44 0x2>; -+ }; -+ -+ - * I2C Devices - - An I2C device connected onto STM32 I2C controller must use a format described by -@@ -75,28 +100,10 @@ Required properties : - I2C slave addresses (see i2c.txt for more details) - - Optional properties : --- wakeup-source -- device can be used as a wakeup source. Valid only if device is a -- master. --- interrupt-names -- should be set as "wakeup" if a dedicated wakeup source is used. -- Imply "wakeup-source" property --- interrupts -- defined dedicated IRQ wakeup source from controller. - -- i2c@40005400 { -+ i2c@40013000 { - camera@3c { - compatible = "ovti,ov5640"; - reg = <0x3c>; - }; - }; -- -- i2c@40005400 { -- eeprom@64 { -- compatible = "linux,slave-24c02"; -- reg = <0x40000064>; -- wakeup-source; -- interrupt-names = "wakeup"; -- interrupts-extended = <&exti 25 1>; -- }; -- }; -diff --git a/doc/device-tree-bindings/net/stm32-dwmac.txt b/doc/device-tree-bindings/net/stm32-dwmac.txt -index 73773ec..e675803 100644 ---- a/doc/device-tree-bindings/net/stm32-dwmac.txt -+++ b/doc/device-tree-bindings/net/stm32-dwmac.txt -@@ -14,8 +14,7 @@ Required properties: - - clock-names: Should be "stmmaceth" for the host clock. - Should be "mac-clk-tx" for the MAC TX clock. - Should be "mac-clk-rx" for the MAC RX clock. -- For MPU family need to add also "ethstp" for power mode clock and, -- "syscfg-clk" for SYSCFG clock. -+ For MPU family need to add also "ethstp" for power mode clock. - - interrupt-names: Should contain a list of interrupt names corresponding to - the interrupts in the interrupts property, if available. - Should be "macirq" for the main MAC IRQ -@@ -24,7 +23,8 @@ Required properties: - encompases the glue register, and the offset of the control register. - - Optional properties: --- clock-names: For MPU family "mac-clk-ck" for PHY without quartz -+- clock-names: For MPU family "eth-ck" for PHY without quartz -+ "syscfg-clk" for SYSCFG clock. - - st,eth_clk_sel (boolean) : set this property in RGMII PHY when you do not want use 125Mhz - - st,eth_ref_clk_sel (boolean) : set this property in RMII mode when you have PHY without crystal 50MHz - -diff --git a/doc/device-tree-bindings/ram/st,stm32mp1-ddr.txt b/doc/device-tree-bindings/ram/st,stm32mp1-ddr.txt -index e5b1bb5..ee708ce 100644 ---- a/doc/device-tree-bindings/ram/st,stm32mp1-ddr.txt -+++ b/doc/device-tree-bindings/ram/st,stm32mp1-ddr.txt -@@ -102,7 +102,7 @@ controlleur attributes: - phyc attributes: - ---------------- - - st,phy-reg : phy values depending of the DDR type (DDR3/LPDDR2/LPDDR3) -- for STM32MP15x: 10 values are requested in this order -+ for STM32MP15x: 11 values are requested in this order - PGCR - ACIOCR - DXCCR -diff --git a/doc/device-tree-bindings/regulator/st,stm32mp1-pwr-reg.txt b/doc/device-tree-bindings/regulator/st,stm32mp1-pwr-reg.txt -index cee27d5..12acf9d 100644 ---- a/doc/device-tree-bindings/regulator/st,stm32mp1-pwr-reg.txt -+++ b/doc/device-tree-bindings/regulator/st,stm32mp1-pwr-reg.txt -@@ -10,12 +10,17 @@ Required properties: - - st,tzcr: syscon of Trust Zone Configuration Register. Usefull to know if we - are in secure mode. - st,tzcr = & ; -+Optional properties: -+- vdd-supply: phandle to the parent supply/regulator node for vdd input -+- vdd_3v3_usbfs-supply: phandle to the parent supply/regulator node for usb33 - - Example: - - pwr-regulators@c { - compatible = "st,stm32mp1,pwr-reg"; - st,tzcr = <&rcc 0x0 0x1>; -+ vdd-supply = <&vdd>; -+ vdd_3v3_usbfs-supply = <&vdd_usb>; - - reg11: reg11 { - regulator-name = "reg11"; -@@ -28,4 +33,10 @@ Example: - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; -+ -+ usb33: usb33 { -+ regulator-name = "usb33"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; - }; -diff --git a/doc/device-tree-bindings/spi/spi-stm32-qspi.txt b/doc/device-tree-bindings/spi/spi-stm32-qspi.txt -index 6c7da1d..551a8d6 100644 ---- a/doc/device-tree-bindings/spi/spi-stm32-qspi.txt -+++ b/doc/device-tree-bindings/spi/spi-stm32-qspi.txt -@@ -1,39 +1,44 @@ --STM32 QSPI controller device tree bindings ---------------------------------------------- -+* STMicroelectronics Quad Serial Peripheral Interface(QSPI) - - Required properties: --- compatible : should be "st,stm32-qspi". --- reg : 1. Physical base address and size of SPI registers map. -- 2. Physical base address & size of mapped NOR Flash. --- spi-max-frequency : Max supported spi frequency. --- status : enable in requried dts. -- --Connected flash properties ---------------------------- --- spi-max-frequency : Max supported spi frequency. --- spi-tx-bus-width : Bus width (number of lines) for writing (1-4) --- spi-rx-bus-width : Bus width (number of lines) for reading (1-4) --- memory-map : Address and size for memory-mapping the flash -+- compatible: should be "st,stm32f469-qspi" -+- reg: the first contains the register location and length. -+ the second contains the memory mapping address and length -+- reg-names: should contain the reg names "qspi" "qspi_mm" -+- interrupts: should contain the interrupt for the device -+- clocks: the phandle of the clock needed by the QSPI controller -+- A pinctrl must be defined to set pins in mode of operation for QSPI transfer -+ -+Optional properties: -+- resets: must contain the phandle to the reset controller. -+ -+A spi flash (NOR/NAND) must be a child of spi node and could have some -+properties. Also see jedec,spi-nor.txt. -+ -+Required properties: -+- reg: chip-Select number (QSPI controller may connect 2 flashes) -+- spi-max-frequency: max frequency of spi bus -+ -+Optional property: -+- spi-rx-bus-width: see ./spi-bus.txt for the description - - Example: -- qspi: quadspi@A0001000 { -- compatible = "st,stm32-qspi"; -- #address-cells = <1>; -- #size-cells = <0>; -- reg = <0xA0001000 0x1000>, <0x90000000 0x10000000>; -- reg-names = "QuadSPI", "QuadSPI-memory"; -- interrupts = <92>; -- spi-max-frequency = <108000000>; -- status = "okay"; -- -- qflash0: n25q128a { -- #address-cells = <1>; -- #size-cells = <1>; -- compatible = "micron,n25q128a13", "spi-flash"; -- spi-max-frequency = <108000000>; -- spi-tx-bus-width = <4>; -- spi-rx-bus-width = <4>; -- memory-map = <0x90000000 0x1000000>; -+ -+qspi: spi@a0001000 { -+ compatible = "st,stm32f469-qspi"; -+ reg = <0xa0001000 0x1000>, <0x90000000 0x10000000>; -+ reg-names = "qspi", "qspi_mm"; -+ interrupts = <91>; -+ resets = <&rcc STM32F4_AHB3_RESET(QSPI)>; -+ clocks = <&rcc 0 STM32F4_AHB3_CLOCK(QSPI)>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_qspi0>; -+ -+ flash@0 { -+ compatible = "jedec,spi-nor"; - reg = <0>; -+ spi-rx-bus-width = <4>; -+ spi-max-frequency = <108000000>; -+ ... - }; - }; -diff --git a/drivers/adc/adc-uclass.c b/drivers/adc/adc-uclass.c -index 27b2654..0a492eb 100644 ---- a/drivers/adc/adc-uclass.c -+++ b/drivers/adc/adc-uclass.c -@@ -277,13 +277,8 @@ static int adc_vdd_platdata_update(struct udevice *dev) - * will bind before its supply regulator device, then the below 'get' - * will return an error. - */ -- if (!uc_pdata->vdd_supply) { -- /* Only get vdd_supply once */ -- ret = device_get_supply_regulator(dev, "vdd-supply", -- &uc_pdata->vdd_supply); -- if (ret) -- return ret; -- } -+ if (!uc_pdata->vdd_supply) -+ return 0; - - ret = regulator_get_value(uc_pdata->vdd_supply); - if (ret < 0) -@@ -299,12 +294,8 @@ static int adc_vss_platdata_update(struct udevice *dev) - struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); - int ret; - -- if (!uc_pdata->vss_supply) { -- ret = device_get_supply_regulator(dev, "vss-supply", -- &uc_pdata->vss_supply); -- if (ret) -- return ret; -- } -+ if (!uc_pdata->vss_supply) -+ return 0; - - ret = regulator_get_value(uc_pdata->vss_supply); - if (ret < 0) -diff --git a/drivers/adc/stm32-adc-core.c b/drivers/adc/stm32-adc-core.c -index a9aa143..04b6a8a 100644 ---- a/drivers/adc/stm32-adc-core.c -+++ b/drivers/adc/stm32-adc-core.c -@@ -60,7 +60,8 @@ static int stm32h7_adc_clk_sel(struct udevice *dev, - { - u32 ckmode, presc; - unsigned long rate; -- int i, div; -+ unsigned int i; -+ int div; - - /* stm32h7 bus clock is common for all ADC instances (mandatory) */ - if (!clk_valid(&common->bclk)) { -diff --git a/drivers/adc/stm32-adc.c b/drivers/adc/stm32-adc.c -index e108062..029338e 100644 ---- a/drivers/adc/stm32-adc.c -+++ b/drivers/adc/stm32-adc.c -@@ -163,15 +163,16 @@ static int stm32_adc_chan_of_init(struct udevice *dev) - struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); - struct stm32_adc *adc = dev_get_priv(dev); - u32 chans[STM32_ADC_CH_MAX]; -- int i, num_channels, ret; -+ unsigned int i, num_channels; -+ int ret; - - /* Retrieve single ended channels listed in device tree */ -- num_channels = dev_read_size(dev, "st,adc-channels"); -- if (num_channels < 0) { -- dev_err(dev, "can't get st,adc-channels: %d\n", num_channels); -- return num_channels; -+ ret = dev_read_size(dev, "st,adc-channels"); -+ if (ret < 0) { -+ dev_err(dev, "can't get st,adc-channels: %d\n", ret); -+ return ret; - } -- num_channels /= sizeof(u32); -+ num_channels = ret / sizeof(u32); - - if (num_channels > adc->cfg->max_channels) { - dev_err(dev, "too many st,adc-channels: %d\n", num_channels); -diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c -index 79f834b..2d7b185 100644 ---- a/drivers/clk/clk_stm32mp1.c -+++ b/drivers/clk/clk_stm32mp1.c -@@ -94,6 +94,7 @@ DECLARE_GLOBAL_DATA_PTR; - #define RCC_PLL4CSGR 0x8A4 - #define RCC_I2C12CKSELR 0x8C0 - #define RCC_I2C35CKSELR 0x8C4 -+#define RCC_SPI2S1CKSELR 0x8D8 - #define RCC_UART6CKSELR 0x8E4 - #define RCC_UART24CKSELR 0x8E8 - #define RCC_UART35CKSELR 0x8EC -@@ -171,6 +172,7 @@ DECLARE_GLOBAL_DATA_PTR; - /* used for ALL PLLNCR registers */ - #define RCC_PLLNCR_PLLON BIT(0) - #define RCC_PLLNCR_PLLRDY BIT(1) -+#define RCC_PLLNCR_SSCG_CTRL BIT(2) - #define RCC_PLLNCR_DIVPEN BIT(4) - #define RCC_PLLNCR_DIVQEN BIT(5) - #define RCC_PLLNCR_DIVREN BIT(6) -@@ -301,6 +303,8 @@ enum stm32mp1_parent_sel { - _STGEN_SEL, - _DSI_SEL, - _ADC12_SEL, -+ _SPI1_SEL, -+ _RTC_SEL, - _PARENT_SEL_NB, - _UNKNOWN_SEL = 0xff, - }; -@@ -538,6 +542,7 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { - STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 23, I2C3_K, _I2C35_SEL), - 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, 13, USART6_K, _UART6_SEL), - - STM32MP1_CLK_SET_CLR_F(RCC_MP_APB3ENSETR, 13, VREF, _PCLK3), -@@ -550,6 +555,7 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { - STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 16, USBPHY_K, _USBPHY_SEL), - - STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 2, I2C4_K, _I2C46_SEL), -+ STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 8, RTCAPB, _PCLK5), - STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 20, STGEN_K, _STGEN_SEL), - - STM32MP1_CLK_SET_CLR_F(RCC_MP_AHB2ENSETR, 5, ADC12, _HCLK2), -@@ -574,7 +580,7 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { - - STM32MP1_CLK_SEC_SET_CLR(RCC_MP_AHB5ENSETR, 0, GPIOZ, _UNKNOWN_SEL), - -- STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 7, ETHCK, _ETH_SEL), -+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 7, ETHCK_K, _ETH_SEL), - STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 8, ETHTX, _UNKNOWN_SEL), - STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 9, ETHRX, _UNKNOWN_SEL), - STM32MP1_CLK_SET_CLR_F(RCC_MP_AHB6ENSETR, 10, ETHMAC, _ACLK), -@@ -585,6 +591,8 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { - STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 24, USBH, _UNKNOWN_SEL), - - STM32MP1_CLK(RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL), -+ -+ STM32MP1_CLK(RCC_BDCR, 20, RTC, _RTC_SEL), - }; - - static const u8 i2c12_parents[] = {_PCLK1, _PLL4_R, _HSI_KER, _CSI_KER}; -@@ -608,6 +616,9 @@ 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}; -+static const u8 spi_parents[] = {_PLL4_P, _PLL3_Q, _I2S_CKIN, _CK_PER, -+ _PLL3_R}; -+static const u8 rtc_parents[] = {_UNKNOWN_ID, _LSE, _LSI, _HSE}; - - static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { - STM32MP1_CLK_PARENT(_I2C12_SEL, RCC_I2C12CKSELR, 0, 0x7, i2c12_parents), -@@ -625,13 +636,17 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { - STM32MP1_CLK_PARENT(_SDMMC3_SEL, RCC_SDMMC3CKSELR, 0, 0x7, - sdmmc3_parents), - STM32MP1_CLK_PARENT(_ETH_SEL, RCC_ETHCKSELR, 0, 0x3, eth_parents), -- STM32MP1_CLK_PARENT(_QSPI_SEL, RCC_QSPICKSELR, 0, 0xf, qspi_parents), -- STM32MP1_CLK_PARENT(_FMC_SEL, RCC_FMCCKSELR, 0, 0xf, fmc_parents), -+ STM32MP1_CLK_PARENT(_QSPI_SEL, RCC_QSPICKSELR, 0, 0x3, qspi_parents), -+ STM32MP1_CLK_PARENT(_FMC_SEL, RCC_FMCCKSELR, 0, 0x3, fmc_parents), - STM32MP1_CLK_PARENT(_USBPHY_SEL, RCC_USBCKSELR, 0, 0x3, usbphy_parents), - STM32MP1_CLK_PARENT(_USBO_SEL, RCC_USBCKSELR, 4, 0x1, usbo_parents), - STM32MP1_CLK_PARENT(_STGEN_SEL, RCC_STGENCKSELR, 0, 0x3, stgen_parents), - STM32MP1_CLK_PARENT(_DSI_SEL, RCC_DSICKSELR, 0, 0x1, dsi_parents), -- STM32MP1_CLK_PARENT(_ADC12_SEL, RCC_ADCCKSELR, 0, 0x1, adc_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(_RTC_SEL, RCC_BDCR, RCC_BDCR_RTCSRC_SHIFT, -+ (RCC_BDCR_RTCSRC_MASK >> RCC_BDCR_RTCSRC_SHIFT), -+ rtc_parents), - }; - - #ifdef STM32MP1_CLOCK_TREE_INIT -@@ -746,6 +761,8 @@ char * const stm32mp1_clk_parent_sel_name[_PARENT_SEL_NB] = { - [_STGEN_SEL] = "STGEN", - [_DSI_SEL] = "DSI", - [_ADC12_SEL] = "ADC12", -+ [_SPI1_SEL] = "SPI1", -+ [_RTC_SEL] = "RTC", - }; - - static const struct stm32mp1_clk_data stm32mp1_data = { -@@ -814,10 +831,11 @@ static int stm32mp1_clk_get_parent(struct stm32mp1_clk_priv *priv, - const struct stm32mp1_clk_sel *sel = priv->data->sel; - int i; - int s, p; -+ unsigned int idx; - -- for (i = 0; i < ARRAY_SIZE(stm32mp1_clks); i++) -- if (stm32mp1_clks[i][0] == id) -- return stm32mp1_clks[i][1]; -+ for (idx = 0; idx < ARRAY_SIZE(stm32mp1_clks); idx++) -+ if (stm32mp1_clks[idx][0] == id) -+ return stm32mp1_clks[idx][1]; - - i = stm32mp1_clk_get_id(priv, id); - if (i < 0) -@@ -1340,7 +1358,10 @@ static void pll_start(struct stm32mp1_clk_priv *priv, int pll_id) - { - const struct stm32mp1_clk_pll *pll = priv->data->pll; - -- writel(RCC_PLLNCR_PLLON, priv->base + pll[pll_id].pllxcr); -+ clrsetbits_le32(priv->base + pll[pll_id].pllxcr, -+ RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | -+ RCC_PLLNCR_DIVREN, -+ RCC_PLLNCR_PLLON); - } - - static int pll_output(struct stm32mp1_clk_priv *priv, int pll_id, int output) -@@ -1459,6 +1480,8 @@ static void pll_csg(struct stm32mp1_clk_priv *priv, int pll_id, u32 *csg) - RCC_PLLNCSGR_SSCG_MODE_MASK); - - writel(pllxcsg, priv->base + pll[pll_id].pllxcsgr); -+ -+ setbits_le32(priv->base + pll[pll_id].pllxcr, RCC_PLLNCR_SSCG_CTRL); - } - - static __maybe_unused int pll_set_rate(struct udevice *dev, -@@ -2052,22 +2075,22 @@ static int stm32mp1_clk_probe(struct udevice *dev) - stm32mp1_clk_dump(priv); - #endif - -+ gd->cpu_clk = stm32mp1_clk_get(priv, _CK_MPU); -+ gd->bus_clk = stm32mp1_clk_get(priv, _ACLK); -+ /* DDRPHYC father */ -+ gd->mem_clk = stm32mp1_clk_get(priv, _PLL2_R); - #if defined(CONFIG_DISPLAY_CPUINFO) - if (gd->flags & GD_FLG_RELOC) { - char buf[32]; - - printf("Clocks:\n"); -- printf("- MPU : %s MHz\n", -- strmhz(buf, stm32mp1_clk_get(priv, _CK_MPU))); -+ printf("- MPU : %s MHz\n", strmhz(buf, gd->cpu_clk)); - printf("- MCU : %s MHz\n", - strmhz(buf, stm32mp1_clk_get(priv, _CK_MCU))); -- printf("- AXI : %s MHz\n", -- strmhz(buf, stm32mp1_clk_get(priv, _ACLK))); -+ printf("- AXI : %s MHz\n", strmhz(buf, gd->bus_clk)); - printf("- PER : %s MHz\n", - strmhz(buf, stm32mp1_clk_get(priv, _CK_PER))); -- /* DDRPHYC father */ -- printf("- DDR : %s MHz\n", -- strmhz(buf, stm32mp1_clk_get(priv, _PLL2_R))); -+ printf("- DDR : %s MHz\n", strmhz(buf, gd->mem_clk)); - } - #endif /* CONFIG_DISPLAY_CPUINFO */ - #endif -diff --git a/drivers/core/root.c b/drivers/core/root.c -index b54bf5b..ab63bc0 100644 ---- a/drivers/core/root.c -+++ b/drivers/core/root.c -@@ -223,7 +223,8 @@ static int dm_scan_fdt_live(struct udevice *parent, - - for (np = node_parent->child; np; np = np->sibling) { - if (pre_reloc_only && -- !of_find_property(np, "u-boot,dm-pre-reloc", NULL)) -+ !of_find_property(np, "u-boot,dm-pre-reloc", NULL) && -+ !of_find_property(np, "u-boot,dm-pre-proper", NULL)) - continue; - if (!of_device_is_available(np)) { - pr_debug(" - ignoring disabled device\n"); -diff --git a/drivers/core/util.c b/drivers/core/util.c -index 451d476..0db01eb 100644 ---- a/drivers/core/util.c -+++ b/drivers/core/util.c -@@ -34,6 +34,8 @@ bool dm_fdt_pre_reloc(const void *blob, int offset) - { - if (fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL)) - return true; -+ if (fdt_getprop(blob, offset, "u-boot,dm-pre-proper", NULL)) -+ return true; - - #ifdef CONFIG_TPL_BUILD - if (fdt_getprop(blob, offset, "u-boot,dm-tpl", NULL)) -diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c -index 2cb35f3..5609b69 100644 ---- a/drivers/firmware/psci.c -+++ b/drivers/firmware/psci.c -@@ -15,7 +15,7 @@ - #include - #include - --psci_fn *invoke_psci_fn; -+psci_fn *invoke_psci_fn __attribute__((section(".data"))); - - static unsigned long __invoke_psci_fn_hvc(unsigned long function_id, - unsigned long arg0, unsigned long arg1, -diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig -index 5cd8b34..9e9cfd6 100644 ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -238,13 +238,13 @@ config PIC32_GPIO - help - Say yes here to support Microchip PIC32 GPIOs. - --config STM32F7_GPIO -+config STM32_GPIO - bool "ST STM32 GPIO driver" - depends on DM_GPIO && (STM32 || ARCH_STM32MP) - default y - help - Device model driver support for STM32 GPIO controller. It should be -- usable on many stm32 families like stm32f4 & stm32H7. -+ usable on many stm32 families like stm32f4/f7/h7 and stm32mp1. - Tested on STM32F7. - - config MVEBU_GPIO -diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile -index f186120..c7cab28 100644 ---- a/drivers/gpio/Makefile -+++ b/drivers/gpio/Makefile -@@ -46,7 +46,7 @@ obj-$(CONFIG_ADI_GPIO2) += adi_gpio2.o - obj-$(CONFIG_TCA642X) += tca642x.o - obj-$(CONFIG_SUNXI_GPIO) += sunxi_gpio.o - obj-$(CONFIG_LPC32XX_GPIO) += lpc32xx_gpio.o --obj-$(CONFIG_STM32F7_GPIO) += stm32f7_gpio.o -+obj-$(CONFIG_STM32_GPIO) += stm32_gpio.o - obj-$(CONFIG_GPIO_UNIPHIER) += gpio-uniphier.o - obj-$(CONFIG_ZYNQ_GPIO) += zynq_gpio.o - obj-$(CONFIG_VYBRID_GPIO) += vybrid_gpio.o -diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c -new file mode 100644 -index 0000000..4eea8ae ---- /dev/null -+++ b/drivers/gpio/stm32_gpio.c -@@ -0,0 +1,210 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2017, STMicroelectronics - All Rights Reserved -+ * Author(s): Vikas Manocha, for STMicroelectronics. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MODE_BITS(gpio_pin) (gpio_pin * 2) -+#define MODE_BITS_MASK 3 -+#define BSRR_BIT(gpio_pin, value) BIT(gpio_pin + (value ? 0 : 16)) -+ -+/* -+ * convert gpio offset to gpio index due to potential gpio -+ * holes into gpio bank -+ */ -+int stm32_offset_to_index(struct udevice *dev, unsigned int offset) -+{ -+ 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++; -+ } -+ } -+ /* shouldn't happen */ -+ return -EINVAL; -+} -+ -+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 bits_index; -+ int mask; -+ int idx; -+ -+ idx = stm32_offset_to_index(dev, offset); -+ if (idx < 0) -+ return idx; -+ -+ bits_index = MODE_BITS(idx); -+ mask = MODE_BITS_MASK << bits_index; -+ -+ clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_IN << bits_index); -+ -+ return 0; -+} -+ -+static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset, -+ int value) -+{ -+ struct stm32_gpio_priv *priv = dev_get_priv(dev); -+ struct stm32_gpio_regs *regs = priv->regs; -+ int bits_index; -+ int mask; -+ int idx; -+ -+ idx = stm32_offset_to_index(dev, offset); -+ if (idx < 0) -+ return idx; -+ -+ bits_index = MODE_BITS(idx); -+ mask = MODE_BITS_MASK << bits_index; -+ -+ clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_OUT << bits_index); -+ -+ writel(BSRR_BIT(idx, value), ®s->bsrr); -+ -+ return 0; -+} -+ -+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; -+ -+ return readl(®s->idr) & BIT(idx) ? 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; -+ -+ writel(BSRR_BIT(idx, value), ®s->bsrr); -+ -+ return 0; -+} -+ -+static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset) -+{ -+ struct stm32_gpio_priv *priv = dev_get_priv(dev); -+ 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; -+ -+ bits_index = MODE_BITS(idx); -+ mask = MODE_BITS_MASK << bits_index; -+ -+ mode = (readl(®s->moder) & mask) >> bits_index; -+ if (mode == STM32_GPIO_MODE_OUT) -+ return GPIOF_OUTPUT; -+ if (mode == STM32_GPIO_MODE_IN) -+ return GPIOF_INPUT; -+ if (mode == STM32_GPIO_MODE_AN) -+ return GPIOF_UNUSED; -+ -+ return GPIOF_FUNC; -+} -+ -+static const struct dm_gpio_ops gpio_stm32_ops = { -+ .direction_input = stm32_gpio_direction_input, -+ .direction_output = stm32_gpio_direction_output, -+ .get_value = stm32_gpio_get_value, -+ .set_value = stm32_gpio_set_value, -+ .get_function = stm32_gpio_get_function, -+}; -+ -+static int gpio_stm32_probe(struct udevice *dev) -+{ -+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); -+ struct stm32_gpio_priv *priv = dev_get_priv(dev); -+ struct ofnode_phandle_args args; -+ struct clk clk; -+ fdt_addr_t addr; -+ const char *name; -+ int ret; -+ int i; -+ -+ addr = dev_read_addr(dev); -+ if (addr == FDT_ADDR_T_NONE) -+ return -EINVAL; -+ -+ priv->regs = (struct stm32_gpio_regs *)addr; -+ name = dev_read_string(dev, "st,bank-name"); -+ if (!name) -+ return -EINVAL; -+ uc_priv->bank_name = name; -+ -+ i = 0; -+ ret = dev_read_phandle_with_args(dev, "gpio-ranges", -+ NULL, 3, i, &args); -+ -+ 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); -+ } -+ -+ dev_dbg(dev, "addr = 0x%p bank_name = %s gpio_count = %d gpio_range = 0x%x\n", -+ (u32 *)priv->regs, uc_priv->bank_name, uc_priv->gpio_count, -+ priv->gpio_range); -+ -+ ret = clk_get_by_index(dev, 0, &clk); -+ if (ret < 0) -+ return ret; -+ -+ ret = clk_enable(&clk); -+ -+ if (ret) { -+ dev_err(dev, "failed to enable clock\n"); -+ return ret; -+ } -+ debug("clock enabled for device %s\n", dev->name); -+ -+ return 0; -+} -+ -+U_BOOT_DRIVER(gpio_stm32) = { -+ .name = "gpio_stm32", -+ .id = UCLASS_GPIO, -+ .probe = gpio_stm32_probe, -+ .ops = &gpio_stm32_ops, -+ .flags = DM_FLAG_PRE_RELOC | DM_UC_FLAG_SEQ_ALIAS, -+ .priv_auto_alloc_size = sizeof(struct stm32_gpio_priv), -+}; -diff --git a/drivers/gpio/stm32f7_gpio.c b/drivers/gpio/stm32f7_gpio.c -deleted file mode 100644 -index 7fff64e..0000000 ---- a/drivers/gpio/stm32f7_gpio.c -+++ /dev/null -@@ -1,216 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0+ --/* -- * Copyright (C) 2017, STMicroelectronics - All Rights Reserved -- * Author(s): Vikas Manocha, for STMicroelectronics. -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define MODE_BITS(gpio_pin) (gpio_pin * 2) --#define MODE_BITS_MASK 3 --#define BSRR_BIT(gpio_pin, value) BIT(gpio_pin + (value ? 0 : 16)) -- --/* -- * convert gpio offset to gpio index due to potential gpio -- * holes into gpio bank -- */ --int stm32_offset_to_index(struct udevice *dev, unsigned int offset) --{ -- struct stm32_gpio_priv *priv = dev_get_priv(dev); -- 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++; -- } -- } -- /* shouldn't happen */ -- return -EINVAL; --} -- --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 bits_index; -- int mask; -- int idx; -- -- idx = stm32_offset_to_index(dev, offset); -- if (idx < 0) -- return idx; -- -- bits_index = MODE_BITS(idx); -- mask = MODE_BITS_MASK << bits_index; -- -- clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_IN << bits_index); -- -- return 0; --} -- --static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset, -- int value) --{ -- struct stm32_gpio_priv *priv = dev_get_priv(dev); -- struct stm32_gpio_regs *regs = priv->regs; -- int bits_index; -- int mask; -- int idx; -- -- idx = stm32_offset_to_index(dev, offset); -- if (idx < 0) -- return idx; -- -- bits_index = MODE_BITS(idx); -- mask = MODE_BITS_MASK << bits_index; -- -- clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_OUT << bits_index); -- -- writel(BSRR_BIT(idx, value), ®s->bsrr); -- -- return 0; --} -- --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; -- -- return readl(®s->idr) & BIT(idx) ? 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; -- -- writel(BSRR_BIT(idx, value), ®s->bsrr); -- -- return 0; --} -- --static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset) --{ -- struct stm32_gpio_priv *priv = dev_get_priv(dev); -- 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; -- -- bits_index = MODE_BITS(idx); -- mask = MODE_BITS_MASK << bits_index; -- -- mode = (readl(®s->moder) & mask) >> bits_index; -- if (mode == STM32_GPIO_MODE_OUT) -- return GPIOF_OUTPUT; -- if (mode == STM32_GPIO_MODE_IN) -- return GPIOF_INPUT; -- if (mode == STM32_GPIO_MODE_AN) -- return GPIOF_UNUSED; -- -- return GPIOF_FUNC; --} -- --static const struct dm_gpio_ops gpio_stm32_ops = { -- .direction_input = stm32_gpio_direction_input, -- .direction_output = stm32_gpio_direction_output, -- .get_value = stm32_gpio_get_value, -- .set_value = stm32_gpio_set_value, -- .get_function = stm32_gpio_get_function, --}; -- --static int gpio_stm32_probe(struct udevice *dev) --{ -- struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); -- struct stm32_gpio_priv *priv = dev_get_priv(dev); -- struct ofnode_phandle_args args; -- struct clk clk; -- fdt_addr_t addr; -- const char *name; -- int ret; -- int i; -- -- addr = dev_read_addr(dev); -- if (addr == FDT_ADDR_T_NONE) -- return -EINVAL; -- -- priv->regs = (struct stm32_gpio_regs *)addr; -- name = dev_read_string(dev, "st,bank-name"); -- if (!name) -- return -EINVAL; -- uc_priv->bank_name = name; -- -- i = 0; -- ret = dev_read_phandle_with_args(dev, "gpio-ranges", -- NULL, 3, i, &args); -- -- 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); -- } -- -- dev_dbg(dev, "addr = 0x%p bank_name = %s gpio_count = %d gpio_range = 0x%x\n", -- (u32 *)priv->regs, uc_priv->bank_name, uc_priv->gpio_count, -- priv->gpio_range); -- -- ret = clk_get_by_index(dev, 0, &clk); -- if (ret < 0) -- return ret; -- -- ret = clk_enable(&clk); -- -- if (ret) { -- dev_err(dev, "failed to enable clock\n"); -- return ret; -- } -- debug("clock enabled for device %s\n", dev->name); -- -- return 0; --} -- --static const struct udevice_id stm32_gpio_ids[] = { -- { .compatible = "st,stm32-gpio" }, -- { } --}; -- --U_BOOT_DRIVER(gpio_stm32) = { -- .name = "gpio_stm32", -- .id = UCLASS_GPIO, -- .of_match = stm32_gpio_ids, -- .probe = gpio_stm32_probe, -- .ops = &gpio_stm32_ops, -- .flags = DM_FLAG_PRE_RELOC | DM_UC_FLAG_SEQ_ALIAS, -- .priv_auto_alloc_size = sizeof(struct stm32_gpio_priv), --}; -diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c -index b8f3b16..a32bde4 100644 ---- a/drivers/hwspinlock/stm32_hwspinlock.c -+++ b/drivers/hwspinlock/stm32_hwspinlock.c -@@ -6,8 +6,6 @@ - #include - #include - #include --#include --#include - #include - #include - -@@ -15,22 +13,26 @@ - #define STM32_MUTEX_LOCK_BIT BIT(31) - #define STM32_MUTEX_NUM_LOCKS 32 - -+struct stm32mp1_hws_priv { -+ fdt_addr_t base; -+}; -+ - static int stm32mp1_lock(struct udevice *dev, int index) - { -- fdt_addr_t *base = dev_get_priv(dev); -+ struct stm32mp1_hws_priv *priv = dev_get_priv(dev); - u32 status; - - if (index >= STM32_MUTEX_NUM_LOCKS) - return -EINVAL; - -- status = readl(*base + index * sizeof(u32)); -+ status = readl(priv->base + index * sizeof(u32)); - if (status == (STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID)) - return -EBUSY; - - writel(STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID, -- *base + index * sizeof(u32)); -+ priv->base + index * sizeof(u32)); - -- status = readl(*base + index * sizeof(u32)); -+ status = readl(priv->base + index * sizeof(u32)); - if (status != (STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID)) - return -EINVAL; - -@@ -39,24 +41,24 @@ static int stm32mp1_lock(struct udevice *dev, int index) - - static int stm32mp1_unlock(struct udevice *dev, int index) - { -- fdt_addr_t *base = dev_get_priv(dev); -+ struct stm32mp1_hws_priv *priv = dev_get_priv(dev); - - if (index >= STM32_MUTEX_NUM_LOCKS) - return -EINVAL; - -- writel(STM32_MUTEX_COREID, *base + index * sizeof(u32)); -+ writel(STM32_MUTEX_COREID, priv->base + index * sizeof(u32)); - - return 0; - } - - static int stm32mp1_hwspinlock_probe(struct udevice *dev) - { -- fdt_addr_t *base = dev_get_priv(dev); -+ struct stm32mp1_hws_priv *priv = dev_get_priv(dev); - struct clk clk; - int ret; - -- *base = dev_read_addr(dev); -- if (*base == FDT_ADDR_T_NONE) -+ priv->base = dev_read_addr(dev); -+ if (priv->base == FDT_ADDR_T_NONE) - return -EINVAL; - - ret = clk_get_by_index(dev, 0, &clk); -@@ -86,5 +88,5 @@ U_BOOT_DRIVER(hwspinlock_stm32mp1) = { - .of_match = stm32mp1_hwspinlock_ids, - .ops = &stm32mp1_hwspinlock_ops, - .probe = stm32mp1_hwspinlock_probe, -- .priv_auto_alloc_size = sizeof(fdt_addr_t), -+ .priv_auto_alloc_size = sizeof(struct stm32mp1_hws_priv), - }; -diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c -index 50c4fd0..2b18735 100644 ---- a/drivers/i2c/stm32f7_i2c.c -+++ b/drivers/i2c/stm32f7_i2c.c -@@ -519,13 +519,13 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, - /* Compute possible values for PRESC, SCLDEL and SDADEL */ - for (p = 0; p < STM32_PRESC_MAX; p++) { - for (l = 0; l < STM32_SCLDEL_MAX; l++) { -- u32 scldel = (l + 1) * (p + 1) * i2cclk; -+ int scldel = (l + 1) * (p + 1) * i2cclk; - - if (scldel < scldel_min) - continue; - - for (a = 0; a < STM32_SDADEL_MAX; a++) { -- u32 sdadel = (a * (p + 1) + 1) * i2cclk; -+ int sdadel = (a * (p + 1) + 1) * i2cclk; - - if (((sdadel >= sdadel_min) && - (sdadel <= sdadel_max)) && -@@ -613,10 +613,12 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, - if ((tscl >= clk_min) && (tscl <= clk_max) && - (tscl_h >= i2c_specs[setup->speed].h_min) && - (i2cclk < tscl_h)) { -- int clk_error = tscl - i2cbus; -+ u32 clk_error; - -- if (clk_error < 0) -- clk_error = -clk_error; -+ if (tscl > i2cbus) -+ clk_error = tscl - i2cbus; -+ else -+ clk_error = i2cbus - tscl; - - if (clk_error < clk_error_prev) { - clk_error_prev = clk_error; -diff --git a/drivers/mailbox/stm32-ipcc.c b/drivers/mailbox/stm32-ipcc.c -index dfcea91..4ebec15 100644 ---- a/drivers/mailbox/stm32-ipcc.c -+++ b/drivers/mailbox/stm32-ipcc.c -@@ -127,7 +127,7 @@ static int stm32_ipcc_probe(struct udevice *dev) - - /* proc_id */ - cell = dev_read_prop(dev, "st,proc_id", &len); -- if (len < sizeof(fdt32_t)) { -+ if (sizeof(fdt32_t) - len > 0) { - dev_dbg(dev, "Missing st,proc_id\n"); - return -EINVAL; - } -diff --git a/drivers/misc/stm32mp_fuse.c b/drivers/misc/stm32mp_fuse.c -index 842871f..e199abe 100644 ---- a/drivers/misc/stm32mp_fuse.c -+++ b/drivers/misc/stm32mp_fuse.c -@@ -5,6 +5,7 @@ - - #include - #include -+#include - #include - #include - #include -diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c -index 1a3f561..b8acc33 100644 ---- a/drivers/mmc/mmc_write.c -+++ b/drivers/mmc/mmc_write.c -@@ -79,7 +79,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) - u32 start_rem, blkcnt_rem; - struct mmc *mmc = find_mmc_device(dev_num); - lbaint_t blk = 0, blk_r = 0; -- int timeout = 2000; -+ int timeout = 1000; - - if (!mmc) - return -1; -diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c -index ed31ca1..32434a4 100644 ---- a/drivers/mmc/stm32_sdmmc2.c -+++ b/drivers/mmc/stm32_sdmmc2.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - - struct stm32_sdmmc2_plat { - struct mmc_config cfg; -@@ -190,7 +191,7 @@ struct stm32_sdmmc2_ctx { - #define SDMMC_IDMACTRL_IDMAEN BIT(0) - - #define SDMMC_CMD_TIMEOUT 0xFFFFFFFF --#define SDMMC_BUSYD0END_TIMEOUT_US 1000000 -+#define SDMMC_BUSYD0END_TIMEOUT_US 2000000 - - static void stm32_sdmmc2_start_data(struct stm32_sdmmc2_priv *priv, - struct mmc_data *data, -@@ -432,6 +433,8 @@ static int stm32_sdmmc2_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, - u32 cmdat = data ? SDMMC_CMD_CMDTRANS : 0; - int ret, retry = 3; - -+ WATCHDOG_RESET(); -+ - retry_cmd: - ctx.data_length = 0; - ctx.dpsm_abort = false; -@@ -669,6 +672,7 @@ static int stm32_sdmmc2_probe(struct udevice *dev) - switch (dev_read_u32_default(dev, "bus-width", 1)) { - case 8: - cfg->host_caps |= MMC_MODE_8BIT; -+ /* fall through */ - case 4: - cfg->host_caps |= MMC_MODE_4BIT; - break; -@@ -692,7 +696,7 @@ clk_free: - return ret; - } - --int stm32_sdmmc_bind(struct udevice *dev) -+static int stm32_sdmmc_bind(struct udevice *dev) - { - struct stm32_sdmmc2_plat *plat = dev_get_platdata(dev); - -diff --git a/drivers/mtd/mtd_uboot.c b/drivers/mtd/mtd_uboot.c -index 5ca560c..6c11810 100644 ---- a/drivers/mtd/mtd_uboot.c -+++ b/drivers/mtd/mtd_uboot.c -@@ -123,7 +123,6 @@ static const char *get_mtdparts(void) - { - __maybe_unused const char *mtdids = NULL; - static char tmp_parts[MTDPARTS_MAXLEN]; -- static bool use_defaults = true; - const char *mtdparts = NULL; - - if (gd->flags & GD_FLG_ENV_READY) -@@ -131,7 +130,7 @@ static const char *get_mtdparts(void) - else if (env_get_f("mtdparts", tmp_parts, sizeof(tmp_parts)) != -1) - mtdparts = tmp_parts; - -- if (mtdparts || !use_defaults) -+ if (mtdparts) - return mtdparts; - - #if defined(CONFIG_SYS_MTDPARTS_RUNTIME) -@@ -145,8 +144,6 @@ static const char *get_mtdparts(void) - if (mtdparts) - env_set("mtdparts", mtdparts); - -- use_defaults = false; -- - return mtdparts; - } - -diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c -index 6f6f5e6..a54af94 100644 ---- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c -+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c -@@ -627,21 +627,16 @@ static void stm32_fmc2_calc_timings(struct nand_chip *chip, - struct stm32_fmc2_timings *tims = &nand->timings; - unsigned long hclk = clk_get_rate(&fmc2->clk); - unsigned long hclkp = FMC2_NSEC_PER_SEC / (hclk / 1000); -- int tar, tclr, thiz, twait, tset_mem, tset_att, thold_mem, thold_att; -- -- tar = hclkp; -- if (tar < sdrt->tAR_min) -- tar = sdrt->tAR_min; -- tims->tar = DIV_ROUND_UP(tar, hclkp) - 1; -- if (tims->tar > FMC2_PCR_TIMING_MASK) -- tims->tar = FMC2_PCR_TIMING_MASK; -- -- tclr = hclkp; -- if (tclr < sdrt->tCLR_min) -- tclr = sdrt->tCLR_min; -- tims->tclr = DIV_ROUND_UP(tclr, hclkp) - 1; -- if (tims->tclr > FMC2_PCR_TIMING_MASK) -- tims->tclr = FMC2_PCR_TIMING_MASK; -+ unsigned long timing, tar, tclr, thiz, twait; -+ unsigned long tset_mem, tset_att, thold_mem, thold_att; -+ -+ tar = max_t(unsigned long, hclkp, sdrt->tAR_min); -+ timing = DIV_ROUND_UP(tar, hclkp) - 1; -+ tims->tar = min_t(unsigned long, timing, FMC2_PCR_TIMING_MASK); -+ -+ tclr = max_t(unsigned long, hclkp, sdrt->tCLR_min); -+ timing = DIV_ROUND_UP(tclr, hclkp) - 1; -+ tims->tclr = min_t(unsigned long, timing, FMC2_PCR_TIMING_MASK); - - tims->thiz = FMC2_THIZ; - thiz = (tims->thiz + 1) * hclkp; -@@ -651,18 +646,11 @@ static void stm32_fmc2_calc_timings(struct nand_chip *chip, - * tWAIT > tWP - * tWAIT > tREA + tIO - */ -- twait = hclkp; -- if (twait < sdrt->tRP_min) -- twait = sdrt->tRP_min; -- if (twait < sdrt->tWP_min) -- twait = sdrt->tWP_min; -- if (twait < sdrt->tREA_max + FMC2_TIO) -- twait = sdrt->tREA_max + FMC2_TIO; -- tims->twait = DIV_ROUND_UP(twait, hclkp); -- if (tims->twait == 0) -- tims->twait = 1; -- else if (tims->twait > FMC2_PMEM_PATT_TIMING_MASK) -- tims->twait = FMC2_PMEM_PATT_TIMING_MASK; -+ twait = max_t(unsigned long, hclkp, sdrt->tRP_min); -+ twait = max_t(unsigned long, twait, sdrt->tWP_min); -+ twait = max_t(unsigned long, twait, sdrt->tREA_max + FMC2_TIO); -+ timing = DIV_ROUND_UP(twait, hclkp); -+ tims->twait = clamp_val(timing, 1, FMC2_PMEM_PATT_TIMING_MASK); - - /* - * tSETUP_MEM > tCS - tWAIT -@@ -677,20 +665,15 @@ static void stm32_fmc2_calc_timings(struct nand_chip *chip, - if (twait > thiz && (sdrt->tDS_min > twait - thiz) && - (tset_mem < sdrt->tDS_min - (twait - thiz))) - tset_mem = sdrt->tDS_min - (twait - thiz); -- tims->tset_mem = DIV_ROUND_UP(tset_mem, hclkp); -- if (tims->tset_mem == 0) -- tims->tset_mem = 1; -- else if (tims->tset_mem > FMC2_PMEM_PATT_TIMING_MASK) -- tims->tset_mem = FMC2_PMEM_PATT_TIMING_MASK; -+ timing = DIV_ROUND_UP(tset_mem, hclkp); -+ tims->tset_mem = clamp_val(timing, 1, FMC2_PMEM_PATT_TIMING_MASK); - - /* - * tHOLD_MEM > tCH - * tHOLD_MEM > tREH - tSETUP_MEM - * tHOLD_MEM > max(tRC, tWC) - (tSETUP_MEM + tWAIT) - */ -- thold_mem = hclkp; -- if (thold_mem < sdrt->tCH_min) -- thold_mem = sdrt->tCH_min; -+ thold_mem = max_t(unsigned long, hclkp, sdrt->tCH_min); - if (sdrt->tREH_min > tset_mem && - (thold_mem < sdrt->tREH_min - tset_mem)) - thold_mem = sdrt->tREH_min - tset_mem; -@@ -700,11 +683,8 @@ static void stm32_fmc2_calc_timings(struct nand_chip *chip, - if ((sdrt->tWC_min > tset_mem + twait) && - (thold_mem < sdrt->tWC_min - (tset_mem + twait))) - thold_mem = sdrt->tWC_min - (tset_mem + twait); -- tims->thold_mem = DIV_ROUND_UP(thold_mem, hclkp); -- if (tims->thold_mem == 0) -- tims->thold_mem = 1; -- else if (tims->thold_mem > FMC2_PMEM_PATT_TIMING_MASK) -- tims->thold_mem = FMC2_PMEM_PATT_TIMING_MASK; -+ timing = DIV_ROUND_UP(thold_mem, hclkp); -+ tims->thold_mem = clamp_val(timing, 1, FMC2_PMEM_PATT_TIMING_MASK); - - /* - * tSETUP_ATT > tCS - tWAIT -@@ -726,11 +706,8 @@ static void stm32_fmc2_calc_timings(struct nand_chip *chip, - if (twait > thiz && (sdrt->tDS_min > twait - thiz) && - (tset_att < sdrt->tDS_min - (twait - thiz))) - tset_att = sdrt->tDS_min - (twait - thiz); -- tims->tset_att = DIV_ROUND_UP(tset_att, hclkp); -- if (tims->tset_att == 0) -- tims->tset_att = 1; -- else if (tims->tset_att > FMC2_PMEM_PATT_TIMING_MASK) -- tims->tset_att = FMC2_PMEM_PATT_TIMING_MASK; -+ timing = DIV_ROUND_UP(tset_att, hclkp); -+ tims->tset_att = clamp_val(timing, 1, FMC2_PMEM_PATT_TIMING_MASK); - - /* - * tHOLD_ATT > tALH -@@ -745,17 +722,11 @@ static void stm32_fmc2_calc_timings(struct nand_chip *chip, - * tHOLD_ATT > tRC - (tSETUP_ATT + tWAIT) - * tHOLD_ATT > tWC - (tSETUP_ATT + tWAIT) - */ -- thold_att = hclkp; -- if (thold_att < sdrt->tALH_min) -- thold_att = sdrt->tALH_min; -- if (thold_att < sdrt->tCH_min) -- thold_att = sdrt->tCH_min; -- if (thold_att < sdrt->tCLH_min) -- thold_att = sdrt->tCLH_min; -- if (thold_att < sdrt->tCOH_min) -- thold_att = sdrt->tCOH_min; -- if (thold_att < sdrt->tDH_min) -- thold_att = sdrt->tDH_min; -+ thold_att = max_t(unsigned long, hclkp, sdrt->tALH_min); -+ thold_att = max_t(unsigned long, thold_att, sdrt->tCH_min); -+ thold_att = max_t(unsigned long, thold_att, sdrt->tCLH_min); -+ thold_att = max_t(unsigned long, thold_att, sdrt->tCOH_min); -+ thold_att = max_t(unsigned long, thold_att, sdrt->tDH_min); - if ((sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC > tset_mem) && - (thold_att < sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC - tset_mem)) - thold_att = sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC - tset_mem; -@@ -774,11 +745,8 @@ static void stm32_fmc2_calc_timings(struct nand_chip *chip, - if ((sdrt->tWC_min > tset_att + twait) && - (thold_att < sdrt->tWC_min - (tset_att + twait))) - thold_att = sdrt->tWC_min - (tset_att + twait); -- tims->thold_att = DIV_ROUND_UP(thold_att, hclkp); -- if (tims->thold_att == 0) -- tims->thold_att = 1; -- else if (tims->thold_att > FMC2_PMEM_PATT_TIMING_MASK) -- tims->thold_att = FMC2_PMEM_PATT_TIMING_MASK; -+ timing = DIV_ROUND_UP(thold_att, hclkp); -+ tims->thold_att = clamp_val(timing, 1, FMC2_PMEM_PATT_TIMING_MASK); - } - - static int stm32_fmc2_setup_interface(struct mtd_info *mtd, int chipnr, -@@ -932,7 +900,8 @@ static int stm32_fmc2_probe(struct udevice *dev) - struct nand_ecclayout *ecclayout; - struct resource resource; - struct reset_ctl reset; -- int oob_index, chip_cs, mem_region, ret, i; -+ int oob_index, chip_cs, mem_region, ret; -+ unsigned int i; - - spin_lock_init(&fmc2->controller.lock); - init_waitqueue_head(&fmc2->controller.wq); -@@ -1049,7 +1018,7 @@ static int stm32_fmc2_probe(struct udevice *dev) - oob_index = FMC2_BBM_LEN; - for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) - ecclayout->eccpos[i] = oob_index; -- ecclayout->oobfree->offset = oob_index + 1; -+ ecclayout->oobfree->offset = oob_index; - ecclayout->oobfree->length = mtd->oobsize - ecclayout->oobfree->offset; - chip->ecc.layout = ecclayout; - -diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c -index 072b8c8..5b933fb 100644 ---- a/drivers/net/dwc_eth_qos.c -+++ b/drivers/net/dwc_eth_qos.c -@@ -262,6 +262,7 @@ struct eqos_desc { - struct eqos_config { - bool reg_access_always_ok; - int mdio_wait; -+ int swr_wait; - int config_mac; - int config_mac_mdio; - int (*interface)(struct udevice *); -@@ -620,7 +621,7 @@ err: - return ret; - } - --void eqos_stop_clks_tegra186(struct udevice *dev) -+static void eqos_stop_clks_tegra186(struct udevice *dev) - { - struct eqos_priv *eqos = dev_get_priv(dev); - -@@ -635,7 +636,7 @@ void eqos_stop_clks_tegra186(struct udevice *dev) - debug("%s: OK\n", __func__); - } - --void eqos_stop_clks_stm32(struct udevice *dev) -+static void eqos_stop_clks_stm32(struct udevice *dev) - { - struct eqos_priv *eqos = dev_get_priv(dev); - -@@ -1004,10 +1005,16 @@ static int eqos_start(struct udevice *dev) - eqos->tx_desc_idx = 0; - eqos->rx_desc_idx = 0; - -+ ret = eqos->config->ops->eqos_start_clks(dev); -+ if (ret < 0) { -+ pr_err("eqos_start_clks() failed: %d", ret); -+ goto err; -+ } -+ - ret = eqos->config->ops->eqos_start_resets(dev); - if (ret < 0) { - pr_err("eqos_start_resets() failed: %d", ret); -- goto err; -+ goto err_stop_clks; - } - - udelay(10); -@@ -1015,7 +1022,8 @@ static int eqos_start(struct udevice *dev) - eqos->reg_access_ok = true; - - ret = wait_for_bit_le32(&eqos->dma_regs->mode, -- EQOS_DMA_MODE_SWR, false, 10, false); -+ EQOS_DMA_MODE_SWR, false, -+ eqos->config->swr_wait, false); - if (ret) { - pr_err("EQOS_DMA_MODE_SWR stuck"); - goto err_stop_resets; -@@ -1031,6 +1039,24 @@ static int eqos_start(struct udevice *dev) - val = (rate / 1000000) - 1; - writel(val, &eqos->mac_regs->us_tic_counter); - -+ /* -+ * if PHY was already connected and configured, -+ * don't need to reconnect/reconfigure again -+ */ -+ if (!eqos->phy) { -+ eqos->phy = phy_connect(eqos->mii, 0, dev, -+ eqos->config->interface(dev)); -+ if (!eqos->phy) { -+ pr_err("phy_connect() failed"); -+ goto err_stop_resets; -+ } -+ ret = phy_config(eqos->phy); -+ if (ret < 0) { -+ pr_err("phy_config() failed: %d", ret); -+ goto err_shutdown_phy; -+ } -+ } -+ - ret = phy_startup(eqos->phy); - if (ret < 0) { - pr_err("phy_startup() failed: %d", ret); -@@ -1255,15 +1281,16 @@ static int eqos_start(struct udevice *dev) - - err_shutdown_phy: - phy_shutdown(eqos->phy); -- eqos->phy = NULL; - err_stop_resets: - eqos->config->ops->eqos_stop_resets(dev); -+err_stop_clks: -+ eqos->config->ops->eqos_stop_clks(dev); - err: - pr_err("FAILED: %d", ret); - return ret; - } - --void eqos_stop(struct udevice *dev) -+static void eqos_stop(struct udevice *dev) - { - struct eqos_priv *eqos = dev_get_priv(dev); - int i; -@@ -1308,12 +1335,16 @@ void eqos_stop(struct udevice *dev) - clrbits_le32(&eqos->dma_regs->ch0_rx_control, - EQOS_DMA_CH0_RX_CONTROL_SR); - -+ if (eqos->phy) { -+ phy_shutdown(eqos->phy); -+ } - eqos->config->ops->eqos_stop_resets(dev); -+ eqos->config->ops->eqos_stop_clks(dev); - - debug("%s: OK\n", __func__); - } - --int eqos_send(struct udevice *dev, void *packet, int length) -+static int eqos_send(struct udevice *dev, void *packet, int length) - { - struct eqos_priv *eqos = dev_get_priv(dev); - struct eqos_desc *tx_desc; -@@ -1354,7 +1385,7 @@ int eqos_send(struct udevice *dev, void *packet, int length) - return -ETIMEDOUT; - } - --int eqos_recv(struct udevice *dev, int flags, uchar **packetp) -+static int eqos_recv(struct udevice *dev, int flags, uchar **packetp) - { - struct eqos_priv *eqos = dev_get_priv(dev); - struct eqos_desc *rx_desc; -@@ -1378,7 +1409,7 @@ int eqos_recv(struct udevice *dev, int flags, uchar **packetp) - return length; - } - --int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) -+static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) - { - struct eqos_priv *eqos = dev_get_priv(dev); - uchar *packet_expected; -@@ -1721,6 +1752,7 @@ static int eqos_probe(struct udevice *dev) - eqos->mii = mdio_alloc(); - if (!eqos->mii) { - pr_err("mdio_alloc() failed"); -+ ret = -ENOMEM; - goto err_remove_resources_tegra; - } - eqos->mii->read = eqos_mdio_read; -@@ -1734,34 +1766,9 @@ static int eqos_probe(struct udevice *dev) - goto err_free_mdio; - } - -- // Bring up PHY -- ret = eqos->config->ops->eqos_start_clks(dev); -- if (ret < 0) { -- pr_err("eqos_start_clks() failed: %d", ret); -- goto err_free_mdio; -- } -- -- eqos->phy = phy_connect(eqos->mii, 0, dev, -- eqos->config->interface(dev)); -- if (!eqos->phy) { -- pr_err("phy_connect() failed"); -- goto err_stop_resets; -- } -- ret = phy_config(eqos->phy); -- if (ret < 0) { -- pr_err("phy_config() failed: %d", ret); -- goto err_shutdown_phy; -- } -- - debug("%s: OK\n", __func__); - return 0; - --err_shutdown_phy: -- phy_shutdown(eqos->phy); -- eqos->phy = NULL; --err_stop_resets: -- eqos->config->ops->eqos_stop_resets(dev); -- eqos->config->ops->eqos_stop_clks(dev); - err_free_mdio: - mdio_free(eqos->mii); - err_remove_resources_tegra: -@@ -1781,14 +1788,6 @@ static int eqos_remove(struct udevice *dev) - - mdio_unregister(eqos->mii); - mdio_free(eqos->mii); -- -- if (eqos->phy) { -- phy_shutdown(eqos->phy); -- eqos->phy = NULL; -- } -- -- eqos->config->ops->eqos_stop_resets(dev); -- eqos->config->ops->eqos_stop_clks(dev); - eqos->config->ops->eqos_remove_resources(dev); - - eqos_probe_resources_core(dev); -@@ -1826,6 +1825,7 @@ static struct eqos_ops eqos_tegra186_ops = { - static const struct eqos_config eqos_tegra186_config = { - .reg_access_always_ok = false, - .mdio_wait = 10, -+ .swr_wait = 10, - .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, - .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_20_35, - .interface = eqos_get_interface_tegra186, -@@ -1852,6 +1852,7 @@ static struct eqos_ops eqos_stm32_ops = { - static const struct eqos_config eqos_stm32_config = { - .reg_access_always_ok = false, - .mdio_wait = 10000, -+ .swr_wait = 50, - .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV, - .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, - .interface = eqos_get_interface_stm32, -diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c -index 22937d8..b6d3144 100644 ---- a/drivers/phy/phy-stm32-usbphyc.c -+++ b/drivers/phy/phy-stm32-usbphyc.c -@@ -60,7 +60,8 @@ struct stm32_usbphyc { - } phys[MAX_PHYS]; - }; - --void stm32_usbphyc_get_pll_params(u32 clk_rate, struct pll_params *pll_params) -+static void stm32_usbphyc_get_pll_params(u32 clk_rate, -+ struct pll_params *pll_params) - { - unsigned long long fvco, ndiv, frac; - -diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c -index 9b5009a..8bb215f 100644 ---- a/drivers/pinctrl/pinctrl-stmfx.c -+++ b/drivers/pinctrl/pinctrl-stmfx.c -@@ -231,23 +231,23 @@ static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin, - switch (param) { - case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: - case PIN_CONFIG_BIAS_DISABLE: -+ case PIN_CONFIG_DRIVE_PUSH_PULL: -+ ret = stmfx_pinctrl_set_type(dev, pin, 0); -+ break; - case PIN_CONFIG_BIAS_PULL_DOWN: -+ ret = stmfx_pinctrl_set_type(dev, pin, 1); -+ if (ret) -+ return ret; - ret = stmfx_pinctrl_set_pupd(dev, pin, 0); - break; - case PIN_CONFIG_BIAS_PULL_UP: -+ ret = stmfx_pinctrl_set_type(dev, pin, 1); -+ if (ret) -+ return ret; - ret = stmfx_pinctrl_set_pupd(dev, pin, 1); - break; - case PIN_CONFIG_DRIVE_OPEN_DRAIN: -- if (dir == GPIOF_OUTPUT) -- ret = stmfx_pinctrl_set_type(dev, pin, 1); -- else -- ret = stmfx_pinctrl_set_type(dev, pin, 0); -- break; -- case PIN_CONFIG_DRIVE_PUSH_PULL: -- if (dir == GPIOF_OUTPUT) -- ret = stmfx_pinctrl_set_type(dev, pin, 0); -- else -- ret = stmfx_pinctrl_set_type(dev, pin, 1); -+ ret = stmfx_pinctrl_set_type(dev, pin, 1); - break; - case PIN_CONFIG_OUTPUT: - ret = stmfx_gpio_direction_output(plat->gpio, pin, arg); -@@ -286,6 +286,23 @@ static const char *stmfx_pinctrl_get_pin_name(struct udevice *dev, - return pin_name; - } - -+static int stmfx_pinctrl_get_pin_muxing(struct udevice *dev, -+ unsigned int selector, -+ char *buf, int size) -+{ -+ struct stmfx_pinctrl *plat = dev_get_platdata(dev); -+ int func; -+ -+ func = stmfx_gpio_get_function(plat->gpio, selector); -+ if (func < 0) -+ return func; -+ -+ snprintf(buf, size, "%s", func == GPIOF_INPUT ? "input" : "output"); -+ -+ return 0; -+} -+ -+ - static int stmfx_pinctrl_bind(struct udevice *dev) - { - struct stmfx_pinctrl *plat = dev_get_platdata(dev); -@@ -306,6 +323,7 @@ const struct pinctrl_ops stmfx_pinctrl_ops = { - .get_pins_count = stmfx_pinctrl_get_pins_count, - .get_pin_name = stmfx_pinctrl_get_pin_name, - .set_state = pinctrl_generic_set_state, -+ .get_pin_muxing = stmfx_pinctrl_get_pin_muxing, - #if CONFIG_IS_ENABLED(PINCONF) - .pinconf_set = stmfx_pinctrl_conf_set, - .pinconf_num_params = ARRAY_SIZE(stmfx_pinctrl_conf_params), -diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c -index eb7799d..e74139e 100644 ---- a/drivers/pinctrl/pinctrl_stm32.c -+++ b/drivers/pinctrl/pinctrl_stm32.c -@@ -4,6 +4,7 @@ - #include - #include - #include -+#include - #include - - DECLARE_GLOBAL_DATA_PTR; -@@ -135,7 +136,7 @@ static struct udevice *stm32_pinctrl_get_gpio_dev(struct udevice *dev, - */ - *idx = stm32_offset_to_index(gpio_bank->gpio_dev, - selector - pin_count); -- if (*idx < 0) -+ if (IS_ERR_VALUE(*idx)) - return NULL; - - return gpio_bank->gpio_dev; -@@ -211,20 +212,21 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, - - return 0; - } -+ - #endif - --int stm32_pinctrl_probe(struct udevice *dev) -+static int stm32_pinctrl_probe(struct udevice *dev) - { - struct stm32_pinctrl_priv *priv = dev_get_priv(dev); -- int err; -+ int ret; -+ -+ INIT_LIST_HEAD(&priv->gpio_dev); - - /* hwspinlock property is optional, just log the error */ -- err = hwspinlock_get_by_index(dev, 0, &priv->hws); -- if (err) -+ ret = hwspinlock_get_by_index(dev, 0, &priv->hws); -+ if (ret) - debug("%s: hwspinlock_get_by_index may have failed (%d)\n", -- __func__, err); -- -- INIT_LIST_HEAD(&priv->gpio_dev); -+ __func__, ret); - - return 0; - } -@@ -234,7 +236,7 @@ static int stm32_gpio_config(struct gpio_desc *desc, - { - struct stm32_gpio_priv *priv = dev_get_priv(desc->dev); - struct stm32_gpio_regs *regs = priv->regs; -- struct stm32_pinctrl_priv *pinctrl_priv; -+ struct stm32_pinctrl_priv *ctrl_priv; - int ret; - u32 index; - -@@ -242,9 +244,8 @@ static int stm32_gpio_config(struct gpio_desc *desc, - ctl->pupd > 2 || ctl->speed > 3) - return -EINVAL; - -- pinctrl_priv = dev_get_priv(dev_get_parent(desc->dev)); -- -- ret = hwspinlock_lock_timeout(&pinctrl_priv->hws, 10); -+ ctrl_priv = dev_get_priv(dev_get_parent(desc->dev)); -+ ret = hwspinlock_lock_timeout(&ctrl_priv->hws, 10); - if (ret == -ETIME) { - dev_err(desc->dev, "HWSpinlock timeout\n"); - return ret; -@@ -264,7 +265,7 @@ static int stm32_gpio_config(struct gpio_desc *desc, - index = desc->offset; - clrsetbits_le32(®s->otyper, OTYPE_MSK << index, ctl->otype << index); - -- hwspinlock_unlock(&pinctrl_priv->hws); -+ hwspinlock_unlock(&ctrl_priv->hws); - - return 0; - } -@@ -327,8 +328,8 @@ static int stm32_pinctrl_config(int offset) - int rv, len; - - /* -- * check for "pinmux" property in each subnode of pin controller -- * phandle "pinctrl-0" (e.g. pins1 and pins2 for usart1) -+ * check for "pinmux" property in each subnode (e.g. pins1 and pins2 for -+ * usart1) of pin controller phandle "pinctrl-0" - */ - fdt_for_each_subnode(offset, gd->fdt_blob, offset) { - struct stm32_gpio_dsc gpio_dsc; -@@ -363,6 +364,35 @@ static int stm32_pinctrl_config(int offset) - return 0; - } - -+static int stm32_pinctrl_bind(struct udevice *dev) -+{ -+ ofnode node; -+ const char *name; -+ int ret; -+ -+ dev_for_each_subnode(node, dev) { -+ debug("%s: bind %s\n", __func__, ofnode_get_name(node)); -+ -+ ofnode_get_property(node, "gpio-controller", &ret); -+ if (ret < 0) -+ continue; -+ /* Get the name of each gpio node */ -+ name = ofnode_get_name(node); -+ if (!name) -+ return -EINVAL; -+ -+ /* Bind each gpio node */ -+ ret = device_bind_driver_to_node(dev, "gpio_stm32", -+ name, node, NULL); -+ if (ret) -+ return ret; -+ -+ debug("%s: bind %s\n", __func__, name); -+ } -+ -+ return 0; -+} -+ - #if CONFIG_IS_ENABLED(PINCTRL_FULL) - static int stm32_pinctrl_set_state(struct udevice *dev, struct udevice *config) - { -@@ -431,7 +461,7 @@ U_BOOT_DRIVER(pinctrl_stm32) = { - .id = UCLASS_PINCTRL, - .of_match = stm32_pinctrl_ids, - .ops = &stm32_pinctrl_ops, -- .bind = dm_scan_fdt_dev, -+ .bind = stm32_pinctrl_bind, - .probe = stm32_pinctrl_probe, - .priv_auto_alloc_size = sizeof(struct stm32_pinctrl_priv), - }; -diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c -index 4511625..39e4627 100644 ---- a/drivers/power/regulator/regulator-uclass.c -+++ b/drivers/power/regulator/regulator-uclass.c -@@ -113,7 +113,7 @@ int regulator_set_enable(struct udevice *dev, bool enable) - - uc_pdata = dev_get_uclass_platdata(dev); - if (!enable && uc_pdata->always_on) -- return -EACCES; -+ return 0; - - return ops->set_enable(dev, enable); - } -diff --git a/drivers/power/regulator/stm32-vrefbuf.c b/drivers/power/regulator/stm32-vrefbuf.c -index 0ad6833..645528e 100644 ---- a/drivers/power/regulator/stm32-vrefbuf.c -+++ b/drivers/power/regulator/stm32-vrefbuf.c -@@ -30,7 +30,7 @@ struct stm32_vrefbuf { - struct udevice *vdda_supply; - }; - --static const unsigned int stm32_vrefbuf_voltages[] = { -+static const int stm32_vrefbuf_voltages[] = { - /* Matches resp. VRS = 000b, 001b, 010b, 011b */ - 2500000, 2048000, 1800000, 1500000, - }; -diff --git a/drivers/ram/stm32mp1/Kconfig b/drivers/ram/stm32mp1/Kconfig -index 761de09..2fd8c7b 100644 ---- a/drivers/ram/stm32mp1/Kconfig -+++ b/drivers/ram/stm32mp1/Kconfig -@@ -30,9 +30,17 @@ config STM32MP1_DDR_INTERACTIVE_FORCE - useful when SPL is loaded in sysram - directly by programmer - -+config STM32MP1_DDR_TESTS -+ bool "STM32MP1 DDR driver : tests support" -+ depends on STM32MP1_DDR_INTERACTIVE -+ default y -+ help -+ activate test support for interactive support in -+ STM32MP1 DDR controller driver: command test -+ - config STM32MP1_DDR_TUNING - bool "STM32MP1 DDR driver : support of tuning" -- depends on SPL && STM32MP1_DDR_INTERACTIVE -+ depends on STM32MP1_DDR_INTERACTIVE - default y - help - activate tuning command in STM32MP1 DDR interactive mode -diff --git a/drivers/ram/stm32mp1/Makefile b/drivers/ram/stm32mp1/Makefile -index bc292d1..e1e9135 100644 ---- a/drivers/ram/stm32mp1/Makefile -+++ b/drivers/ram/stm32mp1/Makefile -@@ -6,7 +6,8 @@ - obj-y += stm32mp1_ram.o - obj-y += stm32mp1_ddr.o - --obj-$(CONFIG_STM32MP1_DDR_INTERACTIVE) += stm32mp1_interactive.o stm32mp1_tests.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),) -diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c -index a83ea39..f6484da 100644 ---- a/drivers/ram/stm32mp1/stm32mp1_ddr.c -+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c -@@ -41,8 +41,32 @@ struct reg_desc { - offsetof(struct stm32mp1_ddrphy, x),\ - offsetof(struct y, x)} - -+#define DDR_REG_DYN(x) \ -+ {#x,\ -+ offsetof(struct stm32mp1_ddrctl, x),\ -+ INVALID_OFFSET} -+ -+#define DDRPHY_REG_DYN(x) \ -+ {#x,\ -+ offsetof(struct stm32mp1_ddrphy, x),\ -+ INVALID_OFFSET} -+ -+/*********************************************************** -+ * PARAMETERS: value get from device tree : -+ * size / order need to be aligned with binding -+ * modification NOT ALLOWED !!! -+ ***********************************************************/ -+#define DDRCTL_REG_REG_SIZE 25 /* st,ctl-reg */ -+#define DDRCTL_REG_TIMING_SIZE 12 /* st,ctl-timing */ -+#define DDRCTL_REG_MAP_SIZE 9 /* st,ctl-map */ -+#define DDRCTL_REG_PERF_SIZE 17 /* st,ctl-perf */ -+ -+#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[] = { -+static const struct reg_desc ddr_reg[DDRCTL_REG_REG_SIZE] = { - DDRCTL_REG_REG(mstr), - DDRCTL_REG_REG(mrctrl0), - DDRCTL_REG_REG(mrctrl1), -@@ -71,7 +95,7 @@ static const struct reg_desc ddr_reg[] = { - }; - - #define DDRCTL_REG_TIMING(x) DDRCTL_REG(x, stm32mp1_ddrctrl_timing) --static const struct reg_desc ddr_timing[] = { -+static const struct reg_desc ddr_timing[DDRCTL_REG_TIMING_SIZE] = { - DDRCTL_REG_TIMING(rfshtmg), - DDRCTL_REG_TIMING(dramtmg0), - DDRCTL_REG_TIMING(dramtmg1), -@@ -87,7 +111,7 @@ static const struct reg_desc ddr_timing[] = { - }; - - #define DDRCTL_REG_MAP(x) DDRCTL_REG(x, stm32mp1_ddrctrl_map) --static const struct reg_desc ddr_map[] = { -+static const struct reg_desc ddr_map[DDRCTL_REG_MAP_SIZE] = { - DDRCTL_REG_MAP(addrmap1), - DDRCTL_REG_MAP(addrmap2), - DDRCTL_REG_MAP(addrmap3), -@@ -100,7 +124,7 @@ static const struct reg_desc ddr_map[] = { - }; - - #define DDRCTL_REG_PERF(x) DDRCTL_REG(x, stm32mp1_ddrctrl_perf) --static const struct reg_desc ddr_perf[] = { -+static const struct reg_desc ddr_perf[DDRCTL_REG_PERF_SIZE] = { - DDRCTL_REG_PERF(sched), - DDRCTL_REG_PERF(sched1), - DDRCTL_REG_PERF(perfhpr1), -@@ -121,7 +145,7 @@ static const struct reg_desc ddr_perf[] = { - }; - - #define DDRPHY_REG_REG(x) DDRPHY_REG(x, stm32mp1_ddrphy_reg) --static const struct reg_desc ddrphy_reg[] = { -+static const struct reg_desc ddrphy_reg[DDRPHY_REG_REG_SIZE] = { - DDRPHY_REG_REG(pgcr), - DDRPHY_REG_REG(aciocr), - DDRPHY_REG_REG(dxccr), -@@ -136,7 +160,7 @@ static const struct reg_desc ddrphy_reg[] = { - }; - - #define DDRPHY_REG_TIMING(x) DDRPHY_REG(x, stm32mp1_ddrphy_timing) --static const struct reg_desc ddrphy_timing[] = { -+static const struct reg_desc ddrphy_timing[DDRPHY_REG_TIMING_SIZE] = { - DDRPHY_REG_TIMING(ptr0), - DDRPHY_REG_TIMING(ptr1), - DDRPHY_REG_TIMING(ptr2), -@@ -150,7 +174,7 @@ static const struct reg_desc ddrphy_timing[] = { - }; - - #define DDRPHY_REG_CAL(x) DDRPHY_REG(x, stm32mp1_ddrphy_cal) --static const struct reg_desc 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), -@@ -165,11 +189,10 @@ static const struct reg_desc ddrphy_cal[] = { - DDRPHY_REG_CAL(dx3dqstr), - }; - --#define DDR_REG_DYN(x) \ -- {#x,\ -- offsetof(struct stm32mp1_ddrctl, x),\ -- INVALID_OFFSET} -- -+/************************************************************** -+ * DYNAMIC REGISTERS: only used for debug purpose (read/modify) -+ **************************************************************/ -+#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE - static const struct reg_desc ddr_dyn[] = { - DDR_REG_DYN(stat), - DDR_REG_DYN(init0), -@@ -181,16 +204,30 @@ static const struct reg_desc ddr_dyn[] = { - DDR_REG_DYN(pctrl_1), - }; - --#define DDRPHY_REG_DYN(x) \ -- {#x,\ -- offsetof(struct stm32mp1_ddrphy, x),\ -- INVALID_OFFSET} -+#define DDR_REG_DYN_SIZE ARRAY_SIZE(ddr_dyn) - - static const struct reg_desc ddrphy_dyn[] = { - DDRPHY_REG_DYN(pir), - DDRPHY_REG_DYN(pgsr), -+ DDRPHY_REG_DYN(zq0sr0), -+ DDRPHY_REG_DYN(zq0sr1), -+ DDRPHY_REG_DYN(dx0gsr0), -+ DDRPHY_REG_DYN(dx0gsr1), -+ DDRPHY_REG_DYN(dx1gsr0), -+ DDRPHY_REG_DYN(dx1gsr1), -+ DDRPHY_REG_DYN(dx2gsr0), -+ DDRPHY_REG_DYN(dx2gsr1), -+ DDRPHY_REG_DYN(dx3gsr0), -+ DDRPHY_REG_DYN(dx3gsr1), - }; - -+#define DDRPHY_REG_DYN_SIZE ARRAY_SIZE(ddrphy_dyn) -+ -+#endif -+ -+/***************************************************************** -+ * REGISTERS ARRAY: used to parse device tree and interactive mode -+ *****************************************************************/ - enum reg_type { - REG_REG, - REG_TIMING, -@@ -199,11 +236,13 @@ enum reg_type { - 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 - */ - REG_DYN, - REGPHY_DYN, -+#endif - REG_TYPE_NB - }; - -@@ -224,23 +263,25 @@ struct ddr_reg_info { - - const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = { - [REG_REG] = { -- "static", ddr_reg, ARRAY_SIZE(ddr_reg), DDR_BASE}, -+ "static", ddr_reg, DDRCTL_REG_REG_SIZE, DDR_BASE}, - [REG_TIMING] = { -- "timing", ddr_timing, ARRAY_SIZE(ddr_timing), DDR_BASE}, -+ "timing", ddr_timing, DDRCTL_REG_TIMING_SIZE, DDR_BASE}, - [REG_PERF] = { -- "perf", ddr_perf, ARRAY_SIZE(ddr_perf), DDR_BASE}, -+ "perf", ddr_perf, DDRCTL_REG_PERF_SIZE, DDR_BASE}, - [REG_MAP] = { -- "map", ddr_map, ARRAY_SIZE(ddr_map), DDR_BASE}, -+ "map", ddr_map, DDRCTL_REG_MAP_SIZE, DDR_BASE}, - [REGPHY_REG] = { -- "static", ddrphy_reg, ARRAY_SIZE(ddrphy_reg), DDRPHY_BASE}, -+ "static", ddrphy_reg, DDRPHY_REG_REG_SIZE, DDRPHY_BASE}, - [REGPHY_TIMING] = { -- "timing", ddrphy_timing, ARRAY_SIZE(ddrphy_timing), DDRPHY_BASE}, -+ "timing", ddrphy_timing, DDRPHY_REG_TIMING_SIZE, DDRPHY_BASE}, - [REGPHY_CAL] = { -- "cal", ddrphy_cal, ARRAY_SIZE(ddrphy_cal), DDRPHY_BASE}, -+ "cal", ddrphy_cal, DDRPHY_REG_CAL_SIZE, DDRPHY_BASE}, -+#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE - [REG_DYN] = { -- "dyn", ddr_dyn, ARRAY_SIZE(ddr_dyn), DDR_BASE}, -+ "dyn", ddr_dyn, DDR_REG_DYN_SIZE, DDR_BASE}, - [REGPHY_DYN] = { -- "dyn", ddrphy_dyn, ARRAY_SIZE(ddrphy_dyn), DDRPHY_BASE}, -+ "dyn", ddrphy_dyn, DDRPHY_REG_DYN_SIZE, DDRPHY_BASE}, -+#endif - }; - - const char *base_name[] = { -@@ -281,37 +322,6 @@ static void set_reg(const struct ddr_info *priv, - } - } - --static void ddrphy_idone_wait(struct stm32mp1_ddrphy *phy) --{ -- u32 pgsr; -- int ret; -- -- ret = readl_poll_timeout(&phy->pgsr, pgsr, -- pgsr & (DDRPHYC_PGSR_IDONE | -- DDRPHYC_PGSR_DTERR | -- DDRPHYC_PGSR_DTIERR | -- DDRPHYC_PGSR_DFTERR | -- DDRPHYC_PGSR_RVERR | -- DDRPHYC_PGSR_RVEIRR), -- 1000000); -- debug("\n[0x%08x] pgsr = 0x%08x ret=%d\n", -- (u32)&phy->pgsr, pgsr, ret); --} -- --void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, u32 pir) --{ -- pir |= DDRPHYC_PIR_INIT; -- writel(pir, &phy->pir); -- debug("[0x%08x] pir = 0x%08x -> 0x%08x\n", -- (u32)&phy->pir, pir, readl(&phy->pir)); -- -- /* need to wait 10 configuration clock before start polling */ -- udelay(10); -- -- /* Wait DRAM initialization and Gate Training Evaluation complete */ -- ddrphy_idone_wait(phy); --} -- - #ifdef CONFIG_STM32MP1_DDR_INTERACTIVE - static void stm32mp1_dump_reg_desc(u32 base_addr, const struct reg_desc *desc) - { -@@ -410,7 +420,7 @@ void stm32mp1_edit_reg(const struct ddr_info *priv, - printf("%s not found\n", name); - return; - } -- if (strict_strtoul(string, 16, &value) < 0) { -+ if (strict_strtoul(string, 16, &value) < 0) { - printf("invalid value %s\n", string); - return; - } -@@ -605,7 +615,7 @@ static void wait_operating_mode(struct ddr_info *priv, int mode) - } - - /* Mode Register Writes (MRW or MRS) */ --void mode_register_write(struct ddr_info *priv, u8 addr, u16 data) -+static void mode_register_write(struct ddr_info *priv, u8 addr, u16 data) - { - u32 mrctrl0; - -@@ -780,6 +790,37 @@ static void ddr3_dll_off(struct ddr_info *priv) - debug("%s: exit\n", __func__); - } - -+static void ddrphy_idone_wait(struct stm32mp1_ddrphy *phy) -+{ -+ u32 pgsr; -+ int ret; -+ -+ ret = readl_poll_timeout(&phy->pgsr, pgsr, -+ pgsr & (DDRPHYC_PGSR_IDONE | -+ DDRPHYC_PGSR_DTERR | -+ DDRPHYC_PGSR_DTIERR | -+ DDRPHYC_PGSR_DFTERR | -+ DDRPHYC_PGSR_RVERR | -+ DDRPHYC_PGSR_RVEIRR), -+ 1000000); -+ debug("\n[0x%08x] pgsr = 0x%08x ret=%d\n", -+ (u32)&phy->pgsr, pgsr, ret); -+} -+ -+void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, u32 pir) -+{ -+ pir |= DDRPHYC_PIR_INIT; -+ writel(pir, &phy->pir); -+ debug("[0x%08x] pir = 0x%08x -> 0x%08x\n", -+ (u32)&phy->pir, pir, readl(&phy->pir)); -+ -+ /* need to wait 10 configuration clock before start polling */ -+ udelay(10); -+ -+ /* Wait DRAM initialization and Gate Training Evaluation complete */ -+ ddrphy_idone_wait(phy); -+} -+ - void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl) - { - start_sw_done(ctl); -diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.h b/drivers/ram/stm32mp1/stm32mp1_ddr.h -index 90b4a4b..52b748f 100644 ---- a/drivers/ram/stm32mp1/stm32mp1_ddr.h -+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.h -@@ -26,7 +26,6 @@ struct stm32mp1_ddrphy; - * @ctl: DDR controleur base address - * @clk: DDR clock - * @phy: DDR PHY base address -- * @pwr: pwr base address - * @rcc: rcc base address - */ - struct ddr_info { -@@ -35,7 +34,6 @@ struct ddr_info { - struct clk clk; - struct stm32mp1_ddrctl *ctl; - struct stm32mp1_ddrphy *phy; -- void *pwr; - u32 rcc; - }; - -diff --git a/drivers/ram/stm32mp1/stm32mp1_interactive.c b/drivers/ram/stm32mp1/stm32mp1_interactive.c -index 3840af5..8df6a39 100644 ---- a/drivers/ram/stm32mp1/stm32mp1_interactive.c -+++ b/drivers/ram/stm32mp1/stm32mp1_interactive.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause - /* -- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved - */ - - #include -@@ -52,7 +52,9 @@ enum ddr_command stm32mp1_get_command(char *cmd, int argc) - [DDR_CMD_STEP] = "step", - [DDR_CMD_NEXT] = "next", - [DDR_CMD_GO] = "go", -+#ifdef CONFIG_STM32MP1_DDR_TESTS - [DDR_CMD_TEST] = "test", -+#endif - #ifdef CONFIG_STM32MP1_DDR_TUNING - [DDR_CMD_TUNING] = "tuning", - #endif -@@ -69,7 +71,9 @@ enum ddr_command stm32mp1_get_command(char *cmd, int argc) - [DDR_CMD_STEP] = { 0, 1 }, - [DDR_CMD_NEXT] = { 0, 0 }, - [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 -@@ -99,25 +103,32 @@ static void stm32mp1_do_usage(void) - { - const char *usage = { - "commands:\n\n" -- "help this message\n" -- "info [ ] display/change DDR information\n" -- "freq [freq] display/change the DDR frequency\n" -- "param [type|reg] print input parameters\n" -- "param edit parameters in step 0\n" -- "print [type|reg] dump register\n" -- "edit modify register\n" -- " all registers if [type|reg] is absent\n" -- " = ctl, phy\n" -- " or one category (static, timing, map, perf, cal, dyn)\n" -- " = name of the register\n" -- "step [n] list the step / go to the step \n" -- "next go to the next step\n" -- "go continue SPL execution\n" -- "reset reboot machine\n" -- "test [help] | [...] list (with help) or execute test \n" -+ "help displays help\n" -+ "info displays DDR information\n" -+ "info changes DDR information\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" -+ "param edits parameters in step 0\n" -+ "print [type|reg] dumps registers\n" -+ "edit modifies one register\n" -+ "step lists the available step\n" -+ "step go to the step \n" -+ "next goes to the next step\n" -+ "go continues the U-Boot SPL execution\n" -+ "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] | [...] list (with help) or execute test \n" -+ "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" -+ " = name of the register\n" - }; - - puts(usage); -@@ -295,6 +306,7 @@ end: - return step; - } - -+#if defined(CONFIG_STM32MP1_DDR_TESTS) || defined(CONFIG_STM32MP1_DDR_TUNING) - static const char * const s_result[] = { - [TEST_PASSED] = "Pass", - [TEST_FAILED] = "Failed", -@@ -349,6 +361,7 @@ static void stm32mp1_ddr_subcmd(struct ddr_info *priv, - end: - printf("Result: %s [%s]\n", s_result[result], string); - } -+#endif - - bool stm32mp1_ddr_interactive(void *priv, - enum stm32mp1_ddr_interact_step step, -@@ -445,11 +458,13 @@ bool stm32mp1_ddr_interactive(void *priv, - next_step = stm32mp1_do_step(step, argc, argv); - break; - -+#ifdef CONFIG_STM32MP1_DDR_TESTS - case DDR_CMD_TEST: - if (!stm32mp1_check_step(step, STEP_DDR_READY)) - continue; - stm32mp1_ddr_subcmd(priv, argc, argv, test, test_nb); - break; -+#endif - - #ifdef CONFIG_STM32MP1_DDR_TUNING - case DDR_CMD_TUNING: -diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c b/drivers/ram/stm32mp1/stm32mp1_ram.c -index 6245cb4..1da57ce 100644 ---- a/drivers/ram/stm32mp1/stm32mp1_ram.c -+++ b/drivers/ram/stm32mp1/stm32mp1_ram.c -@@ -12,8 +12,6 @@ - #include - #include "stm32mp1_ddr.h" - --DECLARE_GLOBAL_DATA_PTR; -- - static const char *const clkname[] = { - "ddrc1", - "ddrc2", -@@ -28,7 +26,7 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) - unsigned long ddr_clk; - struct clk clk; - int ret; -- int idx; -+ unsigned int idx; - - for (idx = 0; idx < ARRAY_SIZE(clkname); idx++) { - ret = clk_get_by_name(priv->dev, clkname[idx], &clk); -@@ -52,7 +50,7 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) - if (ddr_clk > (mem_speed * 100)) { - pr_err("DDR expected freq %d kHz, current is %d kHz\n", - mem_speed, (u32)(ddrphy_clk / 1000)); -- return -1; -+ return -EINVAL; - } - return 0; - } -@@ -60,7 +58,8 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) - static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) - { - struct ddr_info *priv = dev_get_priv(dev); -- int ret, idx; -+ int ret; -+ unsigned int idx; - struct clk axidcg; - struct stm32mp1_ddr_config config; - -@@ -103,8 +102,8 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev) - debug("%s: %s[0x%x] = %d\n", __func__, - param[idx].name, param[idx].size, ret); - if (ret) { -- pr_err("%s: Cannot read %s\n", -- __func__, param[idx].name); -+ pr_err("%s: Cannot read %s, error=%d\n", -+ __func__, param[idx].name, ret); - return -EINVAL; - } - } -@@ -155,11 +154,6 @@ static int stm32mp1_ddr_probe(struct udevice *dev) - priv->ctl = regmap_get_range(map, 0); - priv->phy = regmap_get_range(map, 1); - -- map = syscon_get_regmap_by_driver_data(STM32MP_SYSCON_PWR); -- if (IS_ERR(map)) -- return PTR_ERR(map); -- priv->pwr = regmap_get_range(map, 0); -- - priv->rcc = STM32_RCC_BASE; - - priv->info.base = STM32_DDR_BASE; -diff --git a/drivers/ram/stm32mp1/stm32mp1_tests.c b/drivers/ram/stm32mp1/stm32mp1_tests.c -index 5f2af4e..e09ca31 100644 ---- a/drivers/ram/stm32mp1/stm32mp1_tests.c -+++ b/drivers/ram/stm32mp1/stm32mp1_tests.c -@@ -4,6 +4,7 @@ - */ - #include - #include -+#include - #include - #include - #include "stm32mp1_tests.h" -@@ -154,6 +155,7 @@ static int test_loop_end(u32 *loop, u32 nb_loop, u32 progress) - return 1; - } - printf("loop #%d\n", *loop); -+ WATCHDOG_RESET(); - return 0; - } - -@@ -578,27 +580,29 @@ static enum test_result test_random(struct stm32mp1_ddrctl *ctl, - u32 error = 0; - unsigned int seed; - -- if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) -+ if (get_bufsize(string, argc, argv, 0, &bufsize, 8 * 1024)) - return TEST_ERROR; - if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) - return TEST_ERROR; - if (get_addr(string, argc, argv, 2, &addr)) - return TEST_ERROR; - -- printf("running %d loops at 0x%x\n", nb_loop, addr); -+ bufsize /= 2; -+ printf("running %d loops copy from 0x%x to 0x%x (buffer size=0x%x)\n", -+ nb_loop, addr, addr + bufsize, bufsize); - while (!error) { - seed = rand(); -- for (offset = addr; offset < addr + bufsize; offset += 4) -- writel(rand(), offset); -+ for (offset = 0; offset < bufsize; offset += 4) -+ writel(rand(), addr + offset); - - memcpy((void *)addr + bufsize, (void *)addr, bufsize); - - srand(seed); -- for (offset = addr; offset < addr + 2 * bufsize; offset += 4) { -- if (offset == (addr + bufsize)) -+ for (offset = 0; offset < 2 * bufsize; offset += 4) { -+ if (offset == bufsize) - srand(seed); - value = rand(); -- error = check_addr(offset, value); -+ error = check_addr(addr + offset, value); - if (error) - break; - if (progress(offset)) -@@ -607,6 +611,7 @@ static enum test_result test_random(struct stm32mp1_ddrctl *ctl, - if (test_loop_end(&loop, nb_loop, 100)) - break; - } -+ putc('\n'); - - if (error) { - sprintf(string, -@@ -791,9 +796,9 @@ static enum test_result test_loop(const u32 *pattern, u32 *address, - int i; - int j; - enum test_result res = TEST_PASSED; -- u32 *offset, testsize, remaining; -+ u32 offset, testsize, remaining; - -- offset = address; -+ offset = (u32)address; - remaining = bufsize; - while (remaining) { - testsize = bufsize > 0x1000000 ? 0x1000000 : bufsize; -@@ -809,7 +814,7 @@ static enum test_result test_loop(const u32 *pattern, u32 *address, - __asm__("stmia r1!, {R3-R10}"); - __asm__("stmia r1!, {R3-R10}"); - __asm__("stmia r1!, {R3-R10}"); -- __asm__("subs r2, r2, #8"); -+ __asm__("subs r2, r2, #128"); - __asm__("bge loop2"); - __asm__("pop {R0-R10}"); - -@@ -993,24 +998,34 @@ static enum test_result test_checkboard(struct stm32mp1_ddrctl *ctl, - char *string, int argc, char *argv[]) - { - enum test_result res = TEST_PASSED; -- u32 bufsize; -+ u32 bufsize, nb_loop, loop = 0, addr; -+ int i; - - u32 checkboard[2] = {0x55555555, 0xAAAAAAAA}; - - if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) - return TEST_ERROR; -+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) -+ return TEST_ERROR; -+ if (get_addr(string, argc, argv, 2, &addr)) -+ return TEST_ERROR; - -- printf("running test checkboard at 0x%08x length 0x%x\n", -- STM32_DDR_BASE, bufsize); -- -- res = test_loop_size(checkboard, 2, (u32 *)STM32_DDR_BASE, -- bufsize); -- -- checkboard[0] = ~checkboard[0]; -- checkboard[1] = ~checkboard[1]; -- -- res = test_loop_size(checkboard, 2, (u32 *)STM32_DDR_BASE, -- bufsize); -+ printf("running %d loops at 0x%08x length 0x%x\n", -+ nb_loop, addr, bufsize); -+ while (1) { -+ for (i = 0; i < 2; i++) { -+ res = test_loop_size(checkboard, 2, (u32 *)addr, -+ bufsize); -+ if (res) -+ return res; -+ checkboard[0] = ~checkboard[0]; -+ checkboard[1] = ~checkboard[1]; -+ } -+ if (test_loop_end(&loop, nb_loop, 1)) -+ break; -+ } -+ sprintf(string, "no error for %d loops at 0x%08x length 0x%x", -+ loop, addr, bufsize); - - return res; - } -@@ -1020,23 +1035,31 @@ static enum test_result test_blockseq(struct stm32mp1_ddrctl *ctl, - char *string, int argc, char *argv[]) - { - enum test_result res = TEST_PASSED; -- u32 bufsize; -+ u32 bufsize, nb_loop, loop = 0, addr, value; - int i; - -- u32 value; -- - if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) - return TEST_ERROR; -+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) -+ return TEST_ERROR; -+ if (get_addr(string, argc, argv, 2, &addr)) -+ return TEST_ERROR; - -- printf("running at 0x%08x length 0x%x\n", STM32_DDR_BASE, bufsize); -- for (i = 0; i < 256; i++) { -- value = i | i << 8 | i << 16 | i << 24; -- printf("pattern = %08x", value); -- res = test_loop_size(&value, 1, (u32 *)STM32_DDR_BASE, -- bufsize); -- if (res != TEST_PASSED) -- return res; -+ printf("running %d loops at 0x%08x length 0x%x\n", -+ nb_loop, addr, bufsize); -+ while (1) { -+ for (i = 0; i < 256; i++) { -+ value = i | i << 8 | i << 16 | i << 24; -+ printf("pattern = %08x", value); -+ res = test_loop_size(&value, 1, (u32 *)addr, bufsize); -+ if (res != TEST_PASSED) -+ return res; -+ } -+ if (test_loop_end(&loop, nb_loop, 1)) -+ break; - } -+ sprintf(string, "no error for %d loops at 0x%08x length 0x%x", -+ loop, addr, bufsize); - - return res; - } -@@ -1046,27 +1069,35 @@ static enum test_result test_walkbit0(struct stm32mp1_ddrctl *ctl, - char *string, int argc, char *argv[]) - { - enum test_result res = TEST_PASSED; -- u32 bufsize; -+ u32 bufsize, nb_loop, loop = 0, addr, value; - int i; - -- u32 value; -- - if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) - return TEST_ERROR; -+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) -+ return TEST_ERROR; -+ if (get_addr(string, argc, argv, 2, &addr)) -+ return TEST_ERROR; - -- printf("running at 0x%08x length 0x%x\n", STM32_DDR_BASE, bufsize); -- for (i = 0; i < 64; i++) { -- if (i < 32) -- value = 1 << i; -- else -- value = 1 << (63 - i); -+ printf("running %d loops at 0x%08x length 0x%x\n", -+ nb_loop, addr, bufsize); -+ while (1) { -+ for (i = 0; i < 64; i++) { -+ if (i < 32) -+ value = 1 << i; -+ else -+ value = 1 << (63 - i); - -- printf("pattern = %08x", value); -- res = test_loop_size(&value, 1, (u32 *)STM32_DDR_BASE, -- bufsize); -- if (res != TEST_PASSED) -- return res; -+ printf("pattern = %08x", value); -+ res = test_loop_size(&value, 1, (u32 *)addr, bufsize); -+ if (res != TEST_PASSED) -+ return res; -+ } -+ if (test_loop_end(&loop, nb_loop, 1)) -+ break; - } -+ sprintf(string, "no error for %d loops at 0x%08x length 0x%x", -+ loop, addr, bufsize); - - return res; - } -@@ -1076,27 +1107,35 @@ static enum test_result test_walkbit1(struct stm32mp1_ddrctl *ctl, - char *string, int argc, char *argv[]) - { - enum test_result res = TEST_PASSED; -- u32 bufsize; -+ u32 bufsize, nb_loop, loop = 0, addr, value; - int i; - -- u32 value; -- - if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) - return TEST_ERROR; -+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) -+ return TEST_ERROR; -+ if (get_addr(string, argc, argv, 2, &addr)) -+ return TEST_ERROR; - -- printf("running at 0x%08x length 0x%x\n", STM32_DDR_BASE, bufsize); -- for (i = 0; i < 64; i++) { -- if (i < 32) -- value = ~(1 << i); -- else -- value = ~(1 << (63 - i)); -+ printf("running %d loops at 0x%08x length 0x%x\n", -+ nb_loop, addr, bufsize); -+ while (1) { -+ for (i = 0; i < 64; i++) { -+ if (i < 32) -+ value = ~(1 << i); -+ else -+ value = ~(1 << (63 - i)); - -- printf("pattern = %08x", value); -- res = test_loop_size(&value, 1, (u32 *)STM32_DDR_BASE, -- bufsize); -- if (res != TEST_PASSED) -- return res; -+ printf("pattern = %08x", value); -+ res = test_loop_size(&value, 1, (u32 *)addr, bufsize); -+ if (res != TEST_PASSED) -+ return res; -+ } -+ if (test_loop_end(&loop, nb_loop, 1)) -+ break; - } -+ sprintf(string, "no error for %d loops at 0x%08x length 0x%x", -+ loop, addr, bufsize); - - return res; - } -@@ -1110,34 +1149,42 @@ static enum test_result test_bitspread(struct stm32mp1_ddrctl *ctl, - char *string, int argc, char *argv[]) - { - enum test_result res = TEST_PASSED; -- u32 bufsize; -+ u32 bufsize, nb_loop, loop = 0, addr, bitspread[4]; - int i, j; - -- u32 bitspread[4]; -- - if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) - return TEST_ERROR; -+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) -+ return TEST_ERROR; -+ if (get_addr(string, argc, argv, 2, &addr)) -+ return TEST_ERROR; - -- printf("running at 0x%08x length 0x%x\n", STM32_DDR_BASE, bufsize); -- for (i = 1; i < 32; i++) { -- for (j = 0; j < i; j++) { -- if (i < 32) -- bitspread[0] = (1 << i) | (1 << j); -- else -- bitspread[0] = (1 << (63 - i)) | -- (1 << (63 - j)); -- bitspread[1] = bitspread[0]; -- bitspread[2] = ~bitspread[0]; -- bitspread[3] = ~bitspread[0]; -- printf("pattern = %08x", bitspread[0]); -- -- res = test_loop_size(bitspread, 4, -- (u32 *)STM32_DDR_BASE, -- bufsize); -- if (res != TEST_PASSED) -- return res; -+ printf("running %d loops at 0x%08x length 0x%x\n", -+ nb_loop, addr, bufsize); -+ while (1) { -+ for (i = 1; i < 32; i++) { -+ for (j = 0; j < i; j++) { -+ if (i < 32) -+ bitspread[0] = (1 << i) | (1 << j); -+ else -+ bitspread[0] = (1 << (63 - i)) | -+ (1 << (63 - j)); -+ bitspread[1] = bitspread[0]; -+ bitspread[2] = ~bitspread[0]; -+ bitspread[3] = ~bitspread[0]; -+ printf("pattern = %08x", bitspread[0]); -+ -+ res = test_loop_size(bitspread, 4, (u32 *)addr, -+ bufsize); -+ if (res != TEST_PASSED) -+ return res; -+ } - } -+ if (test_loop_end(&loop, nb_loop, 1)) -+ break; - } -+ sprintf(string, "no error for %d loops at 0x%08x length 0x%x", -+ loop, addr, bufsize); - - return res; - } -@@ -1147,27 +1194,37 @@ static enum test_result test_bitflip(struct stm32mp1_ddrctl *ctl, - char *string, int argc, char *argv[]) - { - enum test_result res = TEST_PASSED; -- u32 bufsize; -+ u32 bufsize, nb_loop, loop = 0, addr; - int i; - - u32 bitflip[4]; - - if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024)) - return TEST_ERROR; -+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) -+ return TEST_ERROR; -+ if (get_addr(string, argc, argv, 2, &addr)) -+ return TEST_ERROR; -+ -+ printf("running %d loops at 0x%08x length 0x%x\n", -+ nb_loop, addr, bufsize); -+ while (1) { -+ for (i = 0; i < 32; i++) { -+ bitflip[0] = 1 << i; -+ bitflip[1] = bitflip[0]; -+ bitflip[2] = ~bitflip[0]; -+ bitflip[3] = bitflip[2]; -+ printf("pattern = %08x", bitflip[0]); - -- printf("running at 0x%08x length 0x%x\n", STM32_DDR_BASE, bufsize); -- for (i = 0; i < 32; i++) { -- bitflip[0] = 1 << i; -- bitflip[1] = bitflip[0]; -- bitflip[2] = ~bitflip[0]; -- bitflip[3] = bitflip[2]; -- printf("pattern = %08x", bitflip[0]); -- -- res = test_loop_size(bitflip, 4, (u32 *)STM32_DDR_BASE, -- bufsize); -- if (res != TEST_PASSED) -- return res; -+ res = test_loop_size(bitflip, 4, (u32 *)addr, bufsize); -+ if (res != TEST_PASSED) -+ return res; -+ } -+ if (test_loop_end(&loop, nb_loop, 1)) -+ break; - } -+ sprintf(string, "no error for %d loops at 0x%08x length 0x%x", -+ loop, addr, bufsize); - - return res; - } -@@ -1186,27 +1243,38 @@ static enum test_result test_read(struct stm32mp1_ddrctl *ctl, - u32 *addr; - u32 data; - u32 loop = 0; -+ int i, size = 1024 * 1024; - bool random = false; - - if (get_addr(string, argc, argv, 0, (u32 *)&addr)) - return TEST_ERROR; - -+ if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55)) -+ return TEST_ERROR; -+ - if ((u32)addr == ADDR_INVALID) { -- printf("random "); -+ printf("running random\n"); - random = true; -+ } else { -+ printf("running at 0x%08x with pattern=0x%08x\n", -+ (u32)addr, data); -+ writel(data, addr); - } - -- printf("running at 0x%08x\n", (u32)addr); -- - while (1) { -- if (random) -- addr = (u32 *)(STM32_DDR_BASE + -- (rand() & (STM32_DDR_SIZE - 1) & ~0x3)); -- data = readl(addr); -- if (test_loop_end(&loop, 0, 1000)) -+ for (i = 0; i < size; i++) { -+ if (random) -+ addr = (u32 *)(STM32_DDR_BASE + -+ (rand() & (STM32_DDR_SIZE - 1) & ~0x3)); -+ data = readl(addr); -+ } -+ if (test_loop_end(&loop, 0, 1)) - break; - } -- sprintf(string, "0x%x: %x", (u32)addr, data); -+ if (random) -+ sprintf(string, "%d loops random", loop); -+ else -+ sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data); - - return TEST_PASSED; - } -@@ -1223,31 +1291,41 @@ static enum test_result test_write(struct stm32mp1_ddrctl *ctl, - char *string, int argc, char *argv[]) - { - u32 *addr; -- u32 data = 0xA5A5AA55; -+ u32 data; - u32 loop = 0; -+ int i, size = 1024 * 1024; - bool random = false; - - if (get_addr(string, argc, argv, 0, (u32 *)&addr)) - return TEST_ERROR; - -+ if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55)) -+ return TEST_ERROR; -+ - if ((u32)addr == ADDR_INVALID) { -- printf("random "); -+ printf("running random\n"); - random = true; -+ } else { -+ printf("running at 0x%08x with pattern 0x%08x\n", -+ (u32)addr, data); - } - -- printf("running at 0x%08x\n", (u32)addr); -- - while (1) { -- if (random) { -- addr = (u32 *)(STM32_DDR_BASE + -- (rand() & (STM32_DDR_SIZE - 1) & ~0x3)); -- data = rand(); -+ for (i = 0; i < size; i++) { -+ if (random) { -+ addr = (u32 *)(STM32_DDR_BASE + -+ (rand() & (STM32_DDR_SIZE - 1) & ~0x3)); -+ data = rand(); -+ } -+ writel(data, addr); - } -- writel(data, addr); -- if (test_loop_end(&loop, 0, 1000)) -+ if (test_loop_end(&loop, 0, 1)) - break; - } -- sprintf(string, "0x%x: %x", (u32)addr, data); -+ if (random) -+ sprintf(string, "%d loops random", loop); -+ else -+ sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data); - - return TEST_PASSED; - } -@@ -1259,24 +1337,38 @@ static enum test_result test_all(struct stm32mp1_ddrctl *ctl, - { - enum test_result res = TEST_PASSED, result; - int i, nb_error = 0; -+ u32 loop = 0, nb_loop; - -- /* execute all the test except the lasts which are infinite */ -- for (i = 1; i < test_nb - NB_TEST_INFINITE; i++) { -- printf("execute %d:%s\n", (int)i, test[i].name); -- result = test[i].fct(ctl, phy, string, 0, NULL); -- printf("result %d:%s = ", (int)i, test[i].name); -- if (result != TEST_PASSED) { -- nb_error++; -- res = TEST_FAILED; -- puts("Failed"); -- } else { -- puts("Passed"); -+ if (get_nb_loop(string, argc, argv, 0, &nb_loop, 1)) -+ return TEST_ERROR; -+ -+ while (!nb_error) { -+ /* execute all the test except the lasts which are infinite */ -+ for (i = 1; i < test_nb - NB_TEST_INFINITE; i++) { -+ printf("execute %d:%s\n", (int)i, test[i].name); -+ result = test[i].fct(ctl, phy, string, 0, NULL); -+ printf("result %d:%s = ", (int)i, test[i].name); -+ if (result != TEST_PASSED) { -+ nb_error++; -+ res = TEST_FAILED; -+ puts("Failed"); -+ } else { -+ puts("Passed"); -+ } -+ puts("\n\n"); - } -- puts("\n\n"); -+ printf("loop %d: %d/%d test failed\n\n\n", -+ loop + 1, nb_error, test_nb - NB_TEST_INFINITE); -+ if (test_loop_end(&loop, nb_loop, 1)) -+ break; -+ } -+ if (res != TEST_PASSED) { -+ sprintf(string, "loop %d: %d/%d test failed", loop, nb_error, -+ test_nb - NB_TEST_INFINITE); -+ } else { -+ sprintf(string, "loop %d: %d tests passed", loop, -+ test_nb - NB_TEST_INFINITE); - } -- sprintf(string, "%d/%d test failed", nb_error, -- test_nb - NB_TEST_INFINITE); -- - return res; - } - -@@ -1285,7 +1377,7 @@ static enum test_result test_all(struct stm32mp1_ddrctl *ctl, - ****************************************************************/ - - const struct test_desc test[] = { -- {test_all, "All", "", "Execute all tests", 0 }, -+ {test_all, "All", "[loop]", "Execute all tests", 1 }, - {test_databus, "Simple DataBus", "[addr]", - "Verifies each data line by walking 1 on fixed address", - 1 -@@ -1322,39 +1414,39 @@ const struct test_desc test[] = { - "Verifies r/w and memcopy(burst for pseudo random value.", - 3 - }, -- {test_freq_pattern, "FrequencySelectivePattern ", "[size]", -+ {test_freq_pattern, "FrequencySelectivePattern", "[size]", - "write & test patterns: Mostly Zero, Mostly One and F/n", - 1 - }, -- {test_blockseq, "BlockSequential", "[size]", -+ {test_blockseq, "BlockSequential", "[size] [loop] [addr]", - "test incremental pattern", -- 1 -+ 3 - }, -- {test_checkboard, "Checkerboard", "[size]", -+ {test_checkboard, "Checkerboard", "[size] [loop] [addr]", - "test checker pattern", -- 1 -+ 3 - }, -- {test_bitspread, "BitSpread", "[size]", -+ {test_bitspread, "BitSpread", "[size] [loop] [addr]", - "test Bit Spread pattern", -- 1 -+ 3 - }, -- {test_bitflip, "BitFlip", "[size]", -+ {test_bitflip, "BitFlip", "[size] [loop] [addr]", - "test Bit Flip pattern", -- 1 -+ 3 - }, -- {test_walkbit0, "WalkingOnes", "[size]", -+ {test_walkbit0, "WalkingOnes", "[size] [loop] [addr]", - "test Walking Ones pattern", -- 1 -+ 3 - }, -- {test_walkbit1, "WalkingZeroes", "[size]", -+ {test_walkbit1, "WalkingZeroes", "[size] [loop] [addr]", - "test Walking Zeroes pattern", -- 1 -+ 3 - }, - /* need to the the 2 last one (infinite) : skipped for test all */ -- {test_read, "infinite read", "[addr]", -- "basic test : infinite read access", 1}, -- {test_write, "infinite write", "[addr]", -- "basic test : infinite write access", 1}, -+ {test_read, "infinite read", "[addr] [pattern]", -+ "basic test : infinite read access (random: addr=0xFFFFFFFF)", 2}, -+ {test_write, "infinite write", "[addr] [pattern]", -+ "basic test : infinite write access (random: addr=0xFFFFFFFF)", 2}, - }; - - const int test_nb = ARRAY_SIZE(test); -diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c -index 0778921..b928ac2 100644 ---- a/drivers/ram/stm32mp1/stm32mp1_tuning.c -+++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause - /* -- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved - */ - - #if defined(DEBUG) -@@ -17,30 +17,46 @@ - #include "stm32mp1_ddr_regs.h" - #include "stm32mp1_ddr.h" - #include "stm32mp1_tests.h" --#include "stm32mp1_tuning.h" - --/* TODO make enum for nominal_delay_m_1.... (for all arrays) */ -- --/* 36deg, 54deg, 72deg, 90deg, 108deg, 126deg, 144deg */ --const u8 dx_dll_phase[7] = {3, 2, 1, 0, 14, 13, 12}; -- --/* New DQ delay value (index). These values are 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]; -- --/*Stores the DQS trim values (PHASE index, unit index) */ --u8 eye_training_val[NUM_BYTES][2]; -+#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 -+}; - --/* stores the log of pass/fail */ --u8 dqs_gating[NUM_BYTES][MAX_GSL_IDX + 1][MAX_GPS_IDX + 1]; -+/* 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 */ -+}; - --/* stores the dqs gate values (gsl index, gps index) */ --u8 dqs_gate_values[NUM_BYTES][2]; -+/* 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 */ -+}; - --static void itm_soft_reset(struct stm32mp1_ddrphy *phy); --static u8 set_midpoint_read_dqs_gating(struct stm32mp1_ddrphy *phy, u8 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; -@@ -64,10 +80,16 @@ static u8 get_nb_bytes(struct stm32mp1_ddrctl *ctl) - return nb_bytes; - } - -+static void itm_soft_reset(struct stm32mp1_ddrphy *phy) -+{ -+ stm32mp1_ddrphy_init(phy, DDRPHYC_PIR_ITMSRST); -+} -+ -+#ifdef UNUSED - /* Read DQS PHASE delay register and provides the index of the retrieved - * value in dx_dll_phase array. - */ --u8 DQS_phase_index(struct stm32mp1_ddrphy *phy, u8 byte) -+static u8 DQS_phase_index(struct stm32mp1_ddrphy *phy, u8 byte) - { - u32 addr = DXNDLLCR(phy, byte); - u32 sdphase = 0; -@@ -123,11 +145,13 @@ u8 DQS_phase_index(struct stm32mp1_ddrphy *phy, u8 byte) - - return index; - } -+#endif - -+#ifdef UNUSED - /* Read DQS unit delay register and provides the index of the retrieved value - * We are assuming that the delay on DQS and DQSN are equal - */ --u8 DQS_unit_index(struct stm32mp1_ddrphy *phy, u8 byte) -+static u8 DQS_unit_index(struct stm32mp1_ddrphy *phy, u8 byte) - { - u32 addr = DXNDQSTR(phy, byte); - u32 index; -@@ -141,12 +165,13 @@ u8 DQS_unit_index(struct stm32mp1_ddrphy *phy, u8 byte) - - return index; - } -+#endif - - /* 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 - */ --u8 DQ_unit_index(struct stm32mp1_ddrphy *phy, u8 byte, u8 bit) -+static u8 DQ_unit_index(struct stm32mp1_ddrphy *phy, u8 byte, u8 bit) - { - u32 index; - u32 addr = DXNDQTR(phy, byte); -@@ -163,29 +188,33 @@ u8 DQ_unit_index(struct stm32mp1_ddrphy *phy, u8 byte, u8 bit) - return index; - } - -+#ifdef UNUSED - /* read r0dgsl value */ --u8 get_r0dgsl_index(struct stm32mp1_ddrphy *phy, u8 byte) -+static u8 get_r0dgsl_index(struct stm32mp1_ddrphy *phy, u8 byte) - { - u32 addr = DXNDQSTR(phy, byte); - - return (readl(addr) & DDRPHYC_DXNDQSTR_R0DGSL_MASK) - >> DDRPHYC_DXNDQSTR_R0DGSL_SHIFT; - } -+#endif - -+#ifdef UNUSED - /*read r0dgsl value */ --u8 get_r0dgps_index(struct stm32mp1_ddrphy *phy, u8 byte) -+static u8 get_r0dgps_index(struct stm32mp1_ddrphy *phy, u8 byte) - { - u32 addr = DXNDQSTR(phy, byte); - - return (readl(addr) & DDRPHYC_DXNDQSTR_R0DGPS_MASK) - >> DDRPHYC_DXNDQSTR_R0DGPS_SHIFT; - } -+#endif - - /* 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. - */ --void DQS_phase_delay(struct stm32mp1_ddrphy *phy, u8 byte, u8 phase_idx) -+static void DQS_phase_delay(struct stm32mp1_ddrphy *phy, u8 byte, u8 phase_idx) - { - u8 sdphase_val = 0; - -@@ -200,8 +229,8 @@ void DQS_phase_delay(struct stm32mp1_ddrphy *phy, u8 byte, u8 phase_idx) - * unit delay is specified by giving the index of the desired delay - * for dgsdly and dqsndly (same value). - */ --void DQS_unit_delay(struct stm32mp1_ddrphy *phy, -- u8 byte, u8 unit_dly_idx) -+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), -@@ -219,9 +248,9 @@ void DQS_unit_delay(struct stm32mp1_ddrphy *phy, - /* Sets the DQ unit delay for a bit line in particular byte lane. - * unit delay is specified by giving the desired delay - */ --void set_DQ_unit_delay(struct stm32mp1_ddrphy *phy, -- u8 byte, u8 bit, -- u8 dq_delay_index) -+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); - -@@ -232,16 +261,16 @@ void set_DQ_unit_delay(struct stm32mp1_ddrphy *phy, - dq_bit_delay_val << DDRPHYC_DXNDQTR_DQDLY_SHIFT(bit)); - } - --void set_r0dgsl_delay(struct stm32mp1_ddrphy *phy, -- u8 byte, u8 r0dgsl_idx) -+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); - } - --void set_r0dgps_delay(struct stm32mp1_ddrphy *phy, -- u8 byte, u8 r0dgps_idx) -+static void set_r0dgps_delay(struct stm32mp1_ddrphy *phy, -+ u8 byte, u8 r0dgps_idx) - { - clrsetbits_le32(DXNDQSTR(phy, byte), - DDRPHYC_DXNDQSTR_R0DGPS_MASK, -@@ -249,7 +278,7 @@ void set_r0dgps_delay(struct stm32mp1_ddrphy *phy, - } - - /* Basic BIST configuration for data lane tests. */ --void config_BIST(struct stm32mp1_ddrphy *phy) -+static void config_BIST(struct stm32mp1_ddrphy *phy) - { - /* Selects the SDRAM bank address to be used during BIST. */ - u32 bbank = 0; -@@ -309,7 +338,7 @@ void config_BIST(struct stm32mp1_ddrphy *phy) - } - - /* Select the Byte lane to be tested by BIST. */ --void BIST_datx8_sel(struct stm32mp1_ddrphy *phy, u8 datx8) -+static void BIST_datx8_sel(struct stm32mp1_ddrphy *phy, u8 datx8) - { - clrsetbits_le32(&phy->bistrr, - DDRPHYC_BISTRR_BDXSEL_MASK, -@@ -320,8 +349,8 @@ void BIST_datx8_sel(struct stm32mp1_ddrphy *phy, u8 datx8) - } - - /* Perform BIST Write_Read test on a byte lane and return test result. */ --void BIST_test(struct stm32mp1_ddrphy *phy, u8 byte, -- struct BIST_result *bist) -+static void BIST_test(struct stm32mp1_ddrphy *phy, u8 byte, -+ struct BIST_result *bist) - { - bool result = true; /* BIST_SUCCESS */ - u32 cnt = 0; -@@ -405,8 +434,9 @@ run: - #endif - } - -+#ifdef UNUSED - /* Init the Write_Read result struct. */ --void init_result_struct(struct BIST_result *result) -+static void init_result_struct(struct BIST_result *result) - { - u8 i = 0; - -@@ -422,13 +452,16 @@ void init_result_struct(struct BIST_result *result) - for (i = 0; i < 8; i++) - result->bit_i_test_result[i] = true; - } -+#endif - - /* 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. - */ --void apply_deskew_results(struct stm32mp1_ddrphy *phy, u8 byte) -+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; -@@ -464,6 +497,10 @@ void apply_deskew_results(struct stm32mp1_ddrphy *phy, u8 byte) - 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; -@@ -869,7 +906,8 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, - pr_debug("The Deskew algorithm can't converge, there is too much margin in your design. Good job!\n"); - } - -- apply_deskew_results(phy, datx8); -+ 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); -@@ -903,6 +941,8 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl, - 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; -@@ -1189,7 +1229,7 @@ static enum test_result eye_training(struct stm32mp1_ddrctl *ctl, - return TEST_PASSED; - } - --void display_reg_results(struct stm32mp1_ddrphy *phy, u8 byte) -+static void display_reg_results(struct stm32mp1_ddrphy *phy, u8 byte) - { - u8 i = 0; - -@@ -1211,79 +1251,14 @@ void display_reg_results(struct stm32mp1_ddrphy *phy, u8 byte) - readl(DXNDQTR(phy, byte))); - } - --static enum test_result read_dqs_gating(struct stm32mp1_ddrctl *ctl, -- struct stm32mp1_ddrphy *phy, -- char *string) --{ -- 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(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); -- /* dummy reads */ -- readl(0xc0000000); -- readl(0xc0000000); -- } -- -- /* re-enable drift compensation */ -- /* setbits_le32(&phy->pgcr, DDRPHYC_PGCR_DFTCMP); */ -- return TEST_PASSED; --} -- - /* analyse the dgs gating log table, and determine the midpoint.*/ --static u8 set_midpoint_read_dqs_gating(struct stm32mp1_ddrphy *phy, u8 byte) -+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}; -@@ -1389,9 +1364,76 @@ static u8 set_midpoint_read_dqs_gating(struct stm32mp1_ddrphy *phy, u8 byte) - return !(intermittent || (left_bound_found && right_bound_found)); - } - --static void itm_soft_reset(struct stm32mp1_ddrphy *phy) -+static enum test_result read_dqs_gating(struct stm32mp1_ddrctl *ctl, -+ struct stm32mp1_ddrphy *phy, -+ char *string) - { -- stm32mp1_ddrphy_init(phy, DDRPHYC_PIR_ITMSRST); -+ /* 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(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; - } - - /**************************************************************** -diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.h b/drivers/ram/stm32mp1/stm32mp1_tuning.h -deleted file mode 100644 -index 964a050..0000000 ---- a/drivers/ram/stm32mp1/stm32mp1_tuning.h -+++ /dev/null -@@ -1,54 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ --/* -- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -- */ -- --#ifndef _RAM_STM32MP1_TUNING_H_ --#define _RAM_STM32MP1_TUNING_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 */ --}; -- --u8 DQS_phase_index(struct stm32mp1_ddrphy *phy, u8 byte); --u8 DQS_unit_index(struct stm32mp1_ddrphy *phy, u8 byte); --u8 DQ_unit_index(struct stm32mp1_ddrphy *phy, u8 byte, u8 bit); -- --void apply_deskew_results(struct stm32mp1_ddrphy *phy, u8 byte); --void init_result_struct(struct BIST_result *result); --void BIST_test(struct stm32mp1_ddrphy *phy, u8 byte, -- struct BIST_result *result); -- --/* 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 */ --}; --#endif -diff --git a/drivers/remoteproc/rproc-uclass.c b/drivers/remoteproc/rproc-uclass.c -index 204e6e8..36f1e97 100644 ---- a/drivers/remoteproc/rproc-uclass.c -+++ b/drivers/remoteproc/rproc-uclass.c -@@ -449,10 +449,10 @@ static int rproc_load_elf_image(struct udevice *dev, unsigned long addr, - if (phdr->p_filesz != phdr->p_memsz) - memset(dst + phdr->p_filesz, 0x00, - phdr->p_memsz - phdr->p_filesz); -- flush_cache(rounddown((int)dst, ARCH_DMA_MINALIGN), -- roundup((int)dst + phdr->p_filesz, -+ flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN), -+ roundup((unsigned long)dst + phdr->p_filesz, - ARCH_DMA_MINALIGN) - -- rounddown((int)dst, ARCH_DMA_MINALIGN)); -+ rounddown((unsigned long)dst, ARCH_DMA_MINALIGN)); - ++phdr; - } - -@@ -564,10 +564,10 @@ static int rproc_elf_find_load_rsc_table(struct udevice *dev, - src = (void *)fw_addr + shdr->sh_offset; - - memcpy(dst, src, shdr->sh_size); -- flush_cache(rounddown((int)dst, ARCH_DMA_MINALIGN), -- roundup((int)dst + shdr->sh_size, -+ flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN), -+ roundup((unsigned long)dst + shdr->sh_size, - ARCH_DMA_MINALIGN) - -- rounddown((int)dst, ARCH_DMA_MINALIGN)); -+ rounddown((unsigned long)dst, ARCH_DMA_MINALIGN)); - - return 0; - } -diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c -index 44230ff..0a8b900 100644 ---- a/drivers/remoteproc/stm32_copro.c -+++ b/drivers/remoteproc/stm32_copro.c -@@ -57,7 +57,7 @@ static int st_of_to_priv(struct udevice *dev, - priv->hold_boot_regmap = regmap; - - cell = dev_read_prop(dev, "st,syscfg-holdboot", &len); -- if (len < 3 * sizeof(fdt32_t)) { -+ if ((3 * sizeof(fdt32_t) - len) > 0) { - dev_dbg(dev, "holdboot offset and mask not available\n"); - return -EINVAL; - } -@@ -74,7 +74,7 @@ static int st_of_to_priv(struct udevice *dev, - } - - cell = dev_read_prop(dev, "st,syscfg-tz", &len); -- if (len < 3 * sizeof(fdt32_t)) { -+ if (3 * sizeof(fdt32_t) - len > 0) { - dev_dbg(dev, "tz offset and mask not available\n"); - return -EINVAL; - } -@@ -153,7 +153,7 @@ static ulong stm32_copro_da_to_pa(struct udevice *dev, ulong da) - /* to update with address translate by DT range */ - - /* CM4 boot at address 0x0 = RETRAM alias, not available for CA7 load */ -- if (da >= 0 && da < STM32_RETRAM_SIZE) -+ if (da < STM32_RETRAM_SIZE) - return (da + STM32_RETRAM_BASE); - - return da; -diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig -index bcc01b1..e6167c1 100644 ---- a/drivers/rtc/Kconfig -+++ b/drivers/rtc/Kconfig -@@ -94,4 +94,11 @@ config RTC_MC146818 - clock with a wide array of features and 50 bytes of general-purpose, - battery-backed RAM. The driver supports access to the clock and RAM. - -+config RTC_STM32 -+ bool "Enable STM32 RTC driver" -+ depends on DM_RTC -+ help -+ Enable STM32 RTC driver. This driver supports the rtc that is present -+ on some STM32 SoCs. -+ - endmenu -diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile -index 1724602..90e79fb 100644 ---- a/drivers/rtc/Makefile -+++ b/drivers/rtc/Makefile -@@ -50,5 +50,6 @@ obj-$(CONFIG_RTC_RX8025) += rx8025.o - obj-$(CONFIG_RTC_RX8010SJ) += rx8010sj.o - obj-$(CONFIG_RTC_S3C24X0) += s3c24x0_rtc.o - obj-$(CONFIG_RTC_S35392A) += s35392a.o -+obj-$(CONFIG_RTC_STM32) += stm32_rtc.o - obj-$(CONFIG_SANDBOX) += sandbox_rtc.o - obj-$(CONFIG_RTC_X1205) += x1205.o -diff --git a/drivers/rtc/stm32_rtc.c b/drivers/rtc/stm32_rtc.c -new file mode 100644 -index 0000000..c2c74ce ---- /dev/null -+++ b/drivers/rtc/stm32_rtc.c -@@ -0,0 +1,308 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define STM32_RTC_TR 0x00 -+#define STM32_RTC_DR 0x04 -+#define STM32_RTC_ISR 0x0C -+#define STM32_RTC_PRER 0x10 -+#define STM32_RTC_CR 0x18 -+#define STM32_RTC_WPR 0x24 -+ -+/* STM32_RTC_TR bit fields */ -+#define STM32_RTC_SEC_SHIFT 0 -+#define STM32_RTC_SEC GENMASK(6, 0) -+#define STM32_RTC_MIN_SHIFT 8 -+#define STM32_RTC_MIN GENMASK(14, 8) -+#define STM32_RTC_HOUR_SHIFT 16 -+#define STM32_RTC_HOUR GENMASK(21, 16) -+ -+/* STM32_RTC_DR bit fields */ -+#define STM32_RTC_DATE_SHIFT 0 -+#define STM32_RTC_DATE GENMASK(5, 0) -+#define STM32_RTC_MONTH_SHIFT 8 -+#define STM32_RTC_MONTH GENMASK(12, 8) -+#define STM32_RTC_WDAY_SHIFT 13 -+#define STM32_RTC_WDAY GENMASK(15, 13) -+#define STM32_RTC_YEAR_SHIFT 16 -+#define STM32_RTC_YEAR GENMASK(23, 16) -+ -+/* STM32_RTC_CR bit fields */ -+#define STM32_RTC_CR_FMT BIT(6) -+ -+/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */ -+#define STM32_RTC_ISR_INITS BIT(4) -+#define STM32_RTC_ISR_RSF BIT(5) -+#define STM32_RTC_ISR_INITF BIT(6) -+#define STM32_RTC_ISR_INIT BIT(7) -+ -+/* STM32_RTC_PRER bit fields */ -+#define STM32_RTC_PRER_PRED_S_SHIFT 0 -+#define STM32_RTC_PRER_PRED_S GENMASK(14, 0) -+#define STM32_RTC_PRER_PRED_A_SHIFT 16 -+#define STM32_RTC_PRER_PRED_A GENMASK(22, 16) -+ -+/* STM32_RTC_WPR key constants */ -+#define RTC_WPR_1ST_KEY 0xCA -+#define RTC_WPR_2ND_KEY 0x53 -+#define RTC_WPR_WRONG_KEY 0xFF -+ -+struct stm32_rtc_priv { -+ fdt_addr_t base; -+}; -+ -+static int stm32_rtc_get(struct udevice *dev, struct rtc_time *tm) -+{ -+ struct stm32_rtc_priv *priv = dev_get_priv(dev); -+ u32 tr, dr; -+ -+ tr = readl(priv->base + STM32_RTC_TR); -+ dr = readl(priv->base + STM32_RTC_DR); -+ -+ tm->tm_sec = bcd2bin((tr & STM32_RTC_SEC) >> STM32_RTC_SEC_SHIFT); -+ tm->tm_min = bcd2bin((tr & STM32_RTC_MIN) >> STM32_RTC_MIN_SHIFT); -+ tm->tm_hour = bcd2bin((tr & STM32_RTC_HOUR) >> STM32_RTC_HOUR_SHIFT); -+ -+ tm->tm_mday = bcd2bin((dr & STM32_RTC_DATE) >> STM32_RTC_DATE_SHIFT); -+ tm->tm_mon = bcd2bin((dr & STM32_RTC_MONTH) >> STM32_RTC_MONTH_SHIFT); -+ tm->tm_year = bcd2bin((dr & STM32_RTC_YEAR) >> STM32_RTC_YEAR_SHIFT); -+ tm->tm_wday = bcd2bin((dr & STM32_RTC_WDAY) >> STM32_RTC_WDAY_SHIFT); -+ tm->tm_yday = 0; -+ tm->tm_isdst = 0; -+ -+ dev_dbg(dev, "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", -+ tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, -+ tm->tm_hour, tm->tm_min, tm->tm_sec); -+ -+ return 0; -+} -+ -+static void stm32_rtc_unlock(struct udevice *dev) -+{ -+ struct stm32_rtc_priv *priv = dev_get_priv(dev); -+ -+ writel(RTC_WPR_1ST_KEY, priv->base + STM32_RTC_WPR); -+ writel(RTC_WPR_2ND_KEY, priv->base + STM32_RTC_WPR); -+} -+ -+static void stm32_rtc_lock(struct udevice *dev) -+{ -+ struct stm32_rtc_priv *priv = dev_get_priv(dev); -+ -+ writel(RTC_WPR_WRONG_KEY, priv->base + STM32_RTC_WPR); -+} -+ -+static int stm32_rtc_enter_init_mode(struct udevice *dev) -+{ -+ struct stm32_rtc_priv *priv = dev_get_priv(dev); -+ u32 isr = readl(priv->base + STM32_RTC_ISR); -+ -+ if (!(isr & STM32_RTC_ISR_INITF)) { -+ isr |= STM32_RTC_ISR_INIT; -+ writel(isr, priv->base + STM32_RTC_ISR); -+ -+ return readl_poll_timeout(priv->base + STM32_RTC_ISR, -+ isr, -+ (isr & STM32_RTC_ISR_INITF), -+ 100000); -+ } -+ -+ return 0; -+} -+ -+static int stm32_rtc_wait_sync(struct udevice *dev) -+{ -+ struct stm32_rtc_priv *priv = dev_get_priv(dev); -+ u32 isr = readl(priv->base + STM32_RTC_ISR); -+ -+ isr &= ~STM32_RTC_ISR_RSF; -+ writel(isr, priv->base + STM32_RTC_ISR); -+ -+ /* -+ * Wait for RSF to be set to ensure the calendar registers are -+ * synchronised, it takes around 2 rtc_ck clock cycles -+ */ -+ return readl_poll_timeout(priv->base + STM32_RTC_ISR, -+ isr, (isr & STM32_RTC_ISR_RSF), -+ 100000); -+} -+ -+static void stm32_rtc_exit_init_mode(struct udevice *dev) -+{ -+ struct stm32_rtc_priv *priv = dev_get_priv(dev); -+ u32 isr = readl(priv->base + STM32_RTC_ISR); -+ -+ isr &= ~STM32_RTC_ISR_INIT; -+ writel(isr, priv->base + STM32_RTC_ISR); -+} -+ -+static int stm32_rtc_set_time(struct udevice *dev, u32 time, u32 date) -+{ -+ struct stm32_rtc_priv *priv = dev_get_priv(dev); -+ int ret; -+ -+ stm32_rtc_unlock(dev); -+ -+ ret = stm32_rtc_enter_init_mode(dev); -+ if (ret) -+ goto lock; -+ -+ writel(time, priv->base + STM32_RTC_TR); -+ writel(date, priv->base + STM32_RTC_DR); -+ -+ stm32_rtc_exit_init_mode(dev); -+ -+ ret = stm32_rtc_wait_sync(dev); -+ -+lock: -+ stm32_rtc_lock(dev); -+ return ret; -+} -+ -+static int stm32_rtc_set(struct udevice *dev, const struct rtc_time *tm) -+{ -+ u32 t, d; -+ -+ dev_dbg(dev, "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", -+ tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, -+ tm->tm_hour, tm->tm_min, tm->tm_sec); -+ -+ /* Time in BCD format */ -+ t = (bin2bcd(tm->tm_sec) << STM32_RTC_SEC_SHIFT) & STM32_RTC_SEC; -+ t |= (bin2bcd(tm->tm_min) << STM32_RTC_MIN_SHIFT) & STM32_RTC_MIN; -+ t |= (bin2bcd(tm->tm_hour) << STM32_RTC_HOUR_SHIFT) & STM32_RTC_HOUR; -+ -+ /* Date in BCD format */ -+ d = (bin2bcd(tm->tm_mday) << STM32_RTC_DATE_SHIFT) & STM32_RTC_DATE; -+ d |= (bin2bcd(tm->tm_mon) << STM32_RTC_MONTH_SHIFT) & STM32_RTC_MONTH; -+ d |= (bin2bcd(tm->tm_year) << STM32_RTC_YEAR_SHIFT) & STM32_RTC_YEAR; -+ d |= (bin2bcd(tm->tm_wday) << STM32_RTC_WDAY_SHIFT) & STM32_RTC_WDAY; -+ -+ return stm32_rtc_set_time(dev, t, d); -+} -+ -+static int stm32_rtc_reset(struct udevice *dev) -+{ -+ dev_dbg(dev, "Reset DATE\n"); -+ -+ return stm32_rtc_set_time(dev, 0, 0); -+} -+ -+static int stm32_rtc_init(struct udevice *dev) -+{ -+ struct stm32_rtc_priv *priv = dev_get_priv(dev); -+ unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr; -+ unsigned int rate; -+ struct clk clk; -+ int ret; -+ u32 isr = readl(priv->base + STM32_RTC_ISR); -+ -+ if (isr & STM32_RTC_ISR_INITS) -+ return 0; -+ -+ ret = clk_get_by_index(dev, 1, &clk); -+ if (ret) -+ return ret; -+ -+ ret = clk_enable(&clk); -+ if (ret) -+ clk_free(&clk); -+ -+ rate = clk_get_rate(&clk); -+ -+ /* Find prediv_a and prediv_s to obtain the 1Hz calendar clock */ -+ pred_a_max = STM32_RTC_PRER_PRED_A >> STM32_RTC_PRER_PRED_A_SHIFT; -+ pred_s_max = STM32_RTC_PRER_PRED_S >> STM32_RTC_PRER_PRED_S_SHIFT; -+ -+ for (pred_a = pred_a_max; pred_a + 1 > 0; pred_a--) { -+ pred_s = (rate / (pred_a + 1)) - 1; -+ -+ if (((pred_s + 1) * (pred_a + 1)) == rate) -+ break; -+ } -+ -+ /* -+ * Can't find a 1Hz, so give priority to RTC power consumption -+ * by choosing the higher possible value for prediv_a -+ */ -+ if (pred_s > pred_s_max || pred_a > pred_a_max) { -+ pred_a = pred_a_max; -+ pred_s = (rate / (pred_a + 1)) - 1; -+ } -+ -+ stm32_rtc_unlock(dev); -+ -+ ret = stm32_rtc_enter_init_mode(dev); -+ if (ret) { -+ dev_err(dev, -+ "Can't enter in init mode. Prescaler config failed.\n"); -+ goto unlock; -+ } -+ -+ prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S; -+ prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A; -+ writel(prer, priv->base + STM32_RTC_PRER); -+ -+ /* Force 24h time format */ -+ cr = readl(priv->base + STM32_RTC_CR); -+ cr &= ~STM32_RTC_CR_FMT; -+ writel(cr, priv->base + STM32_RTC_CR); -+ -+ stm32_rtc_exit_init_mode(dev); -+ -+ ret = stm32_rtc_wait_sync(dev); -+unlock: -+ stm32_rtc_lock(dev); -+ -+ return ret; -+} -+ -+static int stm32_rtc_probe(struct udevice *dev) -+{ -+ struct stm32_rtc_priv *priv = dev_get_priv(dev); -+ struct clk clk; -+ int ret; -+ -+ priv->base = dev_read_addr(dev); -+ if (priv->base == FDT_ADDR_T_NONE) -+ return -EINVAL; -+ -+ ret = clk_get_by_index(dev, 0, &clk); -+ if (ret) -+ return ret; -+ -+ ret = clk_enable(&clk); -+ if (ret) -+ clk_free(&clk); -+ -+ ret = stm32_rtc_init(dev); -+ -+ return ret; -+} -+ -+static const struct rtc_ops stm32_rtc_ops = { -+ .get = stm32_rtc_get, -+ .set = stm32_rtc_set, -+ .reset = stm32_rtc_reset, -+}; -+ -+static const struct udevice_id stm32_rtc_ids[] = { -+ { .compatible = "st,stm32mp1-rtc" }, -+ { } -+}; -+ -+U_BOOT_DRIVER(rtc_stm32) = { -+ .name = "rtc-stm32", -+ .id = UCLASS_RTC, -+ .probe = stm32_rtc_probe, -+ .of_match = stm32_rtc_ids, -+ .ops = &stm32_rtc_ops, -+ .priv_auto_alloc_size = sizeof(struct stm32_rtc_priv), -+}; -diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c -index d806057..0bde839 100644 ---- a/drivers/serial/serial_stm32.c -+++ b/drivers/serial/serial_stm32.c -@@ -114,10 +114,11 @@ static int stm32_serial_getc(struct udevice *dev) - if ((isr & USART_ISR_RXNE) == 0) - return -EAGAIN; - -- if (isr & (USART_ISR_PE | USART_ISR_ORE)) { -+ if (isr & (USART_ISR_PE | USART_ISR_ORE | USART_ISR_FE)) { - if (!stm32f4) - setbits_le32(base + ICR_OFFSET, -- USART_ICR_PCECF | USART_ICR_ORECF); -+ USART_ICR_PCECF | USART_ICR_ORECF | -+ USART_ICR_FECF); - else - readl(base + RDR_OFFSET(stm32f4)); - return -EIO; -@@ -203,9 +204,9 @@ static int stm32_serial_probe(struct udevice *dev) - } - - plat->clock_rate = clk_get_rate(&clk); -- if (plat->clock_rate < 0) { -+ if (!plat->clock_rate) { - clk_disable(&clk); -- return plat->clock_rate; -+ return -EINVAL; - }; - - _stm32_serial_init(plat->base, plat->uart_info); -@@ -283,7 +284,7 @@ static inline void _debug_uart_putc(int c) - struct stm32_uart_info *uart_info = _debug_uart_info(); - - while (_stm32_serial_putc(base, uart_info, c) == -EAGAIN) -- WATCHDOG_RESET(); -+ ; - } - - DEBUG_UART_FUNCS -diff --git a/drivers/serial/serial_stm32.h b/drivers/serial/serial_stm32.h -index 5549f8c..7b0c531 100644 ---- a/drivers/serial/serial_stm32.h -+++ b/drivers/serial/serial_stm32.h -@@ -67,6 +67,7 @@ struct stm32x7_serial_platdata { - #define USART_ISR_TXE BIT(7) - #define USART_ISR_RXNE BIT(5) - #define USART_ISR_ORE BIT(3) -+#define USART_ISR_FE BIT(1) - #define USART_ISR_PE BIT(0) - - #define USART_BRR_F_MASK GENMASK(7, 0) -@@ -74,6 +75,7 @@ struct stm32x7_serial_platdata { - #define USART_BRR_M_MASK GENMASK(15, 4) - - #define USART_ICR_ORECF BIT(3) -+#define USART_ICR_FECF BIT(1) - #define USART_ICR_PCECF BIT(0) - - #endif -diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index da96754..62d6245 100644 ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -197,6 +197,14 @@ config STM32_QSPI - used to access the SPI NOR flash chips on platforms embedding - this ST IP core. - -+config STM32_SPI -+ bool "STM32 SPI driver" -+ depends on ARCH_STM32MP -+ help -+ Enable the STM32 Serial Peripheral Interface (SPI) driver for STM32MP -+ SoCs. This uses driver model and requires a device tree binding to -+ operate. -+ - config SUN4I_SPI - bool "Allwinner A10 SoCs SPI controller" - help -diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile -index 7242ea7..2f984d9 100644 ---- a/drivers/spi/Makefile -+++ b/drivers/spi/Makefile -@@ -47,6 +47,7 @@ obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o - obj-$(CONFIG_SH_SPI) += sh_spi.o - obj-$(CONFIG_SH_QSPI) += sh_qspi.o - obj-$(CONFIG_STM32_QSPI) += stm32_qspi.o -+obj-$(CONFIG_STM32_SPI) += stm32_spi.o - obj-$(CONFIG_SUN4I_SPI) += sun4i_spi.o - obj-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o - obj-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o -diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c -index af9aef0..1bb0987 100644 ---- a/drivers/spi/spi-mem.c -+++ b/drivers/spi/spi-mem.c -@@ -210,6 +210,10 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) - if (!spi_mem_supports_op(slave, op)) - return -ENOTSUPP; - -+ ret = spi_claim_bus(slave); -+ if (ret < 0) -+ return ret; -+ - if (ops->mem_ops) { - #ifndef __UBOOT__ - /* -@@ -232,6 +236,7 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) - mutex_lock(&ctlr->io_mutex); - #endif - ret = ops->mem_ops->exec_op(slave, op); -+ - #ifndef __UBOOT__ - mutex_unlock(&ctlr->io_mutex); - mutex_unlock(&ctlr->bus_lock_mutex); -@@ -245,8 +250,10 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) - * read path) and expect the core to use the regular SPI - * interface in other cases. - */ -- if (!ret || ret != -ENOTSUPP) -+ if (!ret || ret != -ENOTSUPP) { -+ spi_release_bus(slave); - return ret; -+ } - } - - #ifndef __UBOOT__ -@@ -323,15 +330,6 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) - return -EIO; - #else - -- /* U-Boot does not support parallel SPI data lanes */ -- if ((op->cmd.buswidth != 1) || -- (op->addr.nbytes && op->addr.buswidth != 1) || -- (op->dummy.nbytes && op->dummy.buswidth != 1) || -- (op->data.nbytes && op->data.buswidth != 1)) { -- printf("Dual/Quad raw SPI transfers not supported\n"); -- return -ENOTSUPP; -- } -- - if (op->data.nbytes) { - if (op->data.dir == SPI_MEM_DATA_IN) - rx_buf = op->data.buf.in; -@@ -342,10 +340,6 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) - op_len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes; - op_buf = calloc(1, op_len); - -- ret = spi_claim_bus(slave); -- if (ret < 0) -- return ret; -- - op_buf[pos++] = op->cmd.opcode; - - if (op->addr.nbytes) { -@@ -421,6 +415,25 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, struct spi_mem_op *op) - if (ops->mem_ops && ops->mem_ops->adjust_op_size) - return ops->mem_ops->adjust_op_size(slave, op); - -+ if (!ops->mem_ops || !ops->mem_ops->exec_op) { -+ unsigned int len; -+ -+ len = sizeof(op->cmd.opcode) + op->addr.nbytes + -+ op->dummy.nbytes; -+ if (slave->max_write_size && len > slave->max_write_size) -+ return -EINVAL; -+ -+ if (op->data.dir == SPI_MEM_DATA_IN && slave->max_read_size) -+ op->data.nbytes = min(op->data.nbytes, -+ slave->max_read_size); -+ else if (slave->max_write_size) -+ op->data.nbytes = min(op->data.nbytes, -+ slave->max_write_size - len); -+ -+ if (!op->data.nbytes) -+ return -EINVAL; -+ } -+ - return 0; - } - EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size); -diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c -index b84255b..856c533 100644 ---- a/drivers/spi/spi-uclass.c -+++ b/drivers/spi/spi-uclass.c -@@ -320,7 +320,9 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, - } - - plat = dev_get_parent_platdata(dev); -- if (!speed) { -+ -+ /* get speed and mode from platdata when available */ -+ if (plat->max_hz) { - speed = plat->max_hz; - mode = plat->mode; - } -diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c -index 3b92254..39e95c2 100644 ---- a/drivers/spi/stm32_qspi.c -+++ b/drivers/spi/stm32_qspi.c -@@ -15,9 +15,11 @@ - #include - #include - #include -+#include - #include - #include - #include -+#include - - struct stm32_qspi_regs { - u32 cr; /* 0x00 */ -@@ -45,7 +47,6 @@ struct stm32_qspi_regs { - #define STM32_QSPI_CR_SSHIFT BIT(4) - #define STM32_QSPI_CR_DFM BIT(6) - #define STM32_QSPI_CR_FSEL BIT(7) --#define STM32_QSPI_CR_FTHRES_MASK GENMASK(4, 0) - #define STM32_QSPI_CR_FTHRES_SHIFT (8) - #define STM32_QSPI_CR_TEIE BIT(16) - #define STM32_QSPI_CR_TCIE BIT(17) -@@ -155,7 +156,12 @@ enum STM32_QSPI_CCR_FMODE { - /* default SCK frequency, unit: HZ */ - #define STM32_QSPI_DEFAULT_SCK_FREQ 108000000 - --#define STM32_MAX_NORCHIP 2 -+#define STM32_QSPI_MAX_CHIP 2 -+ -+#define STM32_QSPI_FIFO_TIMEOUT_US 30000 -+#define STM32_QSPI_CMD_TIMEOUT_US 1000000 -+#define STM32_BUSY_TIMEOUT_US 100000 -+#define STM32_ABT_TIMEOUT_US 100000 - - struct stm32_qspi_platdata { - u32 base; -@@ -163,11 +169,20 @@ struct stm32_qspi_platdata { - u32 max_hz; - }; - -+struct stm32_qspi_flash { -+ u32 cr; -+ u32 dcr; -+ u32 mode; -+ bool initialized; -+}; -+ - struct stm32_qspi_priv { - struct stm32_qspi_regs *regs; -+ struct stm32_qspi_flash flash[STM32_QSPI_MAX_CHIP]; - ulong clock_rate; - u32 max_hz; - u32 mode; -+ int cs_used; - - u32 command; - u32 address; -@@ -177,47 +192,18 @@ struct stm32_qspi_priv { - #define CMD_HAS_DATA BIT(26) - }; - --static void _stm32_qspi_disable(struct stm32_qspi_priv *priv) --{ -- clrbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN); --} -- --static void _stm32_qspi_enable(struct stm32_qspi_priv *priv) -+static int _stm32_qspi_wait_for_not_busy(struct stm32_qspi_priv *priv) - { -- setbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN); --} -- --static void _stm32_qspi_wait_for_not_busy(struct stm32_qspi_priv *priv) --{ -- while (readl(&priv->regs->sr) & STM32_QSPI_SR_BUSY) -- ; --} -- --static void _stm32_qspi_wait_for_complete(struct stm32_qspi_priv *priv) --{ -- while (!(readl(&priv->regs->sr) & STM32_QSPI_SR_TCF)) -- ; --} -- --static void _stm32_qspi_wait_for_ftf(struct stm32_qspi_priv *priv) --{ -- while (!(readl(&priv->regs->sr) & STM32_QSPI_SR_FTF)) -- ; --} -+ u32 sr; -+ int ret; - --static void _stm32_qspi_set_flash_size(struct stm32_qspi_priv *priv, u32 size) --{ -- u32 fsize = fls(size) - 1; -+ ret = readl_poll_timeout(&priv->regs->sr, sr, -+ !(sr & STM32_QSPI_SR_BUSY), -+ STM32_BUSY_TIMEOUT_US); -+ if (ret) -+ pr_err("busy timeout (stat:%#x)\n", sr); - -- clrsetbits_le32(&priv->regs->dcr, -- STM32_QSPI_DCR_FSIZE_MASK << STM32_QSPI_DCR_FSIZE_SHIFT, -- fsize << STM32_QSPI_DCR_FSIZE_SHIFT); --} -- --static void _stm32_qspi_set_cs(struct stm32_qspi_priv *priv, unsigned int cs) --{ -- clrsetbits_le32(&priv->regs->cr, STM32_QSPI_CR_FSEL, -- cs ? STM32_QSPI_CR_FSEL : 0); -+ return ret; - } - - static unsigned int _stm32_qspi_gen_ccr(struct stm32_qspi_priv *priv, u8 fmode) -@@ -303,13 +289,79 @@ static void _stm32_qspi_start_xfer(struct stm32_qspi_priv *priv, u32 cr_reg) - writel(priv->address, &priv->regs->ar); - } - -+static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv *priv, bool wait_nobusy) -+{ -+ u32 sr; -+ int ret; -+ -+ if (wait_nobusy) -+ return _stm32_qspi_wait_for_not_busy(priv); -+ -+ 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); -+ -+ return ret; -+} -+ -+static void _stm32_qspi_read_fifo(u8 *val, void __iomem *addr) -+{ -+ *val = readb(addr); -+} -+ -+static void _stm32_qspi_write_fifo(u8 *val, void __iomem *addr) -+{ -+ writeb(*val, addr); -+} -+ -+static int _stm32_qspi_poll(struct stm32_qspi_priv *priv, -+ const u8 *dout, u8 *din, u32 len) -+{ -+ void (*fifo)(u8 *val, void __iomem *addr); -+ u32 sr; -+ u8 *buf; -+ int ret; -+ -+ if (din) { -+ fifo = _stm32_qspi_read_fifo; -+ buf = din; -+ -+ } else { -+ fifo = _stm32_qspi_write_fifo; -+ buf = (u8 *)dout; -+ } -+ -+ while (len--) { -+ ret = readl_poll_timeout(&priv->regs->sr, sr, -+ sr & STM32_QSPI_SR_FTF, -+ STM32_QSPI_FIFO_TIMEOUT_US); -+ if (ret) { -+ pr_err("fifo timeout (len:%d stat:%#x)\n", len, sr); -+ return ret; -+ } -+ -+ fifo(buf++, &priv->regs->dr); -+ } -+ -+ return 0; -+} -+ - static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv, - struct spi_flash *flash, unsigned int bitlen, - const u8 *dout, u8 *din, unsigned long flags) - { - unsigned int words = bitlen / 8; - u32 ccr_reg; -- int i; -+ int ret; - - if (flags & SPI_XFER_MMAP) { - _stm32_qspi_enable_mmap(priv, flash); -@@ -361,12 +413,16 @@ static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv, - } - - if (flags & SPI_XFER_END) { -+ bool cmd_has_data = priv->command & CMD_HAS_DATA; -+ - ccr_reg = _stm32_qspi_gen_ccr(priv, - STM32_QSPI_CCR_IND_WRITE); - -- _stm32_qspi_wait_for_not_busy(priv); -+ ret = _stm32_qspi_wait_for_not_busy(priv); -+ if (ret) -+ return ret; - -- if (priv->command & CMD_HAS_DATA) -+ if (cmd_has_data) - _stm32_qspi_set_xfer_length(priv, words); - - _stm32_qspi_start_xfer(priv, ccr_reg); -@@ -374,28 +430,22 @@ static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv, - debug("%s: write: ccr:0x%08x adr:0x%08x\n", - __func__, priv->regs->ccr, priv->regs->ar); - -- if (priv->command & CMD_HAS_DATA) { -- _stm32_qspi_wait_for_ftf(priv); -- -- debug("%s: words:%d data:", __func__, words); -- -- i = 0; -- while (words > i) { -- writeb(dout[i], &priv->regs->dr); -- debug("%02x ", dout[i]); -- i++; -- } -- debug("\n"); -- -- _stm32_qspi_wait_for_complete(priv); -- } else { -- _stm32_qspi_wait_for_not_busy(priv); -+ if (cmd_has_data) { -+ ret = _stm32_qspi_poll(priv, dout, NULL, words); -+ if (ret) -+ return ret; - } -+ -+ ret = _stm32_qspi_wait_cmd(priv, !cmd_has_data); -+ if (ret) -+ return ret; - } - } else if (din) { - ccr_reg = _stm32_qspi_gen_ccr(priv, STM32_QSPI_CCR_IND_READ); - -- _stm32_qspi_wait_for_not_busy(priv); -+ ret = _stm32_qspi_wait_for_not_busy(priv); -+ if (ret) -+ return ret; - - _stm32_qspi_set_xfer_length(priv, words); - -@@ -404,20 +454,112 @@ static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv, - debug("%s: read: ccr:0x%08x adr:0x%08x len:%d\n", __func__, - priv->regs->ccr, priv->regs->ar, priv->regs->dlr); - -- debug("%s: data:", __func__); -+ ret = _stm32_qspi_poll(priv, NULL, din, words); -+ if (ret) -+ return ret; - -- i = 0; -- while (words > i) { -- din[i] = readb(&priv->regs->dr); -- debug("%02x ", din[i]); -- i++; -- } -- debug("\n"); -+ ret = _stm32_qspi_wait_cmd(priv, false); -+ if (ret) -+ return ret; - } - - return 0; - } - -+static int _stm32_qspi_tx(struct stm32_qspi_priv *priv, -+ const struct spi_mem_op *op) -+{ -+ if (!op->data.nbytes) -+ return 0; -+ -+ if (op->data.dir == SPI_MEM_DATA_IN) -+ return _stm32_qspi_poll(priv, NULL, op->data.buf.in, -+ op->data.nbytes); -+ -+ return _stm32_qspi_poll(priv, op->data.buf.out, NULL, op->data.nbytes); -+} -+ -+static int _stm32_qspi_get_mode(u8 buswidth) -+{ -+ if (buswidth == 4) -+ return 3; -+ -+ return buswidth; -+} -+ -+static int stm32_qspi_exec_op(struct spi_slave *slave, -+ const struct spi_mem_op *op) -+{ -+ struct stm32_qspi_priv *priv = dev_get_priv(slave->dev->parent); -+ u32 cr, ccr; -+ int timeout, ret; -+ -+ debug("%s: cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n", -+ __func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, -+ op->dummy.buswidth, op->data.buswidth, -+ op->addr.val, op->data.nbytes); -+ -+ ret = _stm32_qspi_wait_for_not_busy(priv); -+ if (ret) -+ return ret; -+ -+ ccr = (STM32_QSPI_CCR_IND_WRITE << STM32_QSPI_CCR_FMODE_SHIFT); -+ if (op->data.dir == SPI_MEM_DATA_IN && op->data.nbytes) -+ ccr = (STM32_QSPI_CCR_IND_READ << STM32_QSPI_CCR_FMODE_SHIFT); -+ -+ if (op->data.nbytes) -+ _stm32_qspi_set_xfer_length(priv, op->data.nbytes); -+ -+ ccr |= op->cmd.opcode; -+ ccr |= (_stm32_qspi_get_mode(op->cmd.buswidth) -+ << STM32_QSPI_CCR_IMODE_SHIFT); -+ -+ if (op->addr.nbytes) { -+ ccr |= ((op->addr.nbytes - 1) << STM32_QSPI_CCR_ADSIZE_SHIFT); -+ ccr |= (_stm32_qspi_get_mode(op->addr.buswidth) -+ << STM32_QSPI_CCR_ADMODE_SHIFT); -+ } -+ -+ if (op->dummy.buswidth && op->dummy.nbytes) -+ ccr |= (op->dummy.nbytes * 8 / op->dummy.buswidth -+ << STM32_QSPI_CCR_DCYC_SHIFT); -+ -+ if (op->data.nbytes) -+ ccr |= (_stm32_qspi_get_mode(op->data.buswidth) -+ << STM32_QSPI_CCR_DMODE_SHIFT); -+ -+ writel(ccr, &priv->regs->ccr); -+ -+ if (op->addr.nbytes) -+ writel(op->addr.val, &priv->regs->ar); -+ -+ ret = _stm32_qspi_tx(priv, op); -+ if (ret) -+ goto abort; -+ -+ /* wait end of tx in indirect mode */ -+ ret = _stm32_qspi_wait_cmd(priv, !op->data.nbytes); -+ if (ret) -+ goto abort; -+ -+ return 0; -+ -+abort: -+ setbits_le32(&priv->regs->cr, STM32_QSPI_CR_ABORT); -+ -+ /* wait clear of abort bit by hw */ -+ timeout = readl_poll_timeout(&priv->regs->cr, cr, -+ !(cr & STM32_QSPI_CR_ABORT), -+ STM32_ABT_TIMEOUT_US); -+ -+ writel(STM32_QSPI_FCR_CTCF, &priv->regs->fcr); -+ -+ if (ret || timeout) -+ debug("%s ret:%d abort timeout:%d\n", __func__, ret, timeout); -+ -+ return ret; -+} -+ - static int stm32_qspi_ofdata_to_platdata(struct udevice *bus) - { - struct resource res_regs, res_mem; -@@ -455,17 +597,15 @@ static int stm32_qspi_probe(struct udevice *bus) - { - struct stm32_qspi_platdata *plat = dev_get_platdata(bus); - struct stm32_qspi_priv *priv = dev_get_priv(bus); -- struct dm_spi_bus *dm_spi_bus; -+ struct dm_spi_bus *dm_spi_bus = bus->uclass_priv; - struct clk clk; - struct reset_ctl reset_ctl; - int ret; - -- dm_spi_bus = bus->uclass_priv; -- - dm_spi_bus->max_hz = plat->max_hz; - - priv->regs = (struct stm32_qspi_regs *)(uintptr_t)plat->base; -- -+ priv->cs_used = -1; - priv->max_hz = plat->max_hz; - - ret = clk_get_by_index(bus, 0, &clk); -@@ -480,9 +620,9 @@ static int stm32_qspi_probe(struct udevice *bus) - } - - priv->clock_rate = clk_get_rate(&clk); -- if (priv->clock_rate < 0) { -+ if (!priv->clock_rate) { - clk_disable(&clk); -- return priv->clock_rate; -+ return -EINVAL; - } - - ret = reset_get_by_index(bus, 0, &reset_ctl); -@@ -501,6 +641,10 @@ static int stm32_qspi_probe(struct udevice *bus) - - setbits_le32(&priv->regs->cr, STM32_QSPI_CR_SSHIFT); - -+ /* Set dcr fsize to max address */ -+ setbits_le32(&priv->regs->dcr, -+ STM32_QSPI_DCR_FSIZE_MASK << STM32_QSPI_DCR_FSIZE_SHIFT); -+ - return 0; - } - -@@ -511,37 +655,47 @@ static int stm32_qspi_remove(struct udevice *bus) - - static int stm32_qspi_claim_bus(struct udevice *dev) - { -- struct stm32_qspi_priv *priv; -- struct udevice *bus; -- struct spi_flash *flash; -- struct dm_spi_slave_platdata *slave_plat; -- -- bus = dev->parent; -- priv = dev_get_priv(bus); -- flash = dev_get_uclass_priv(dev); -- slave_plat = dev_get_parent_platdata(dev); -+ struct stm32_qspi_priv *priv = dev_get_priv(dev->parent); -+ struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); -+ int slave_cs = slave_plat->cs; - -- if (slave_plat->cs >= STM32_MAX_NORCHIP) -+ if (slave_cs >= STM32_QSPI_MAX_CHIP) - return -ENODEV; - -- _stm32_qspi_set_cs(priv, slave_plat->cs); -+ if (priv->cs_used != slave_cs) { -+ struct stm32_qspi_flash *flash = &priv->flash[slave_cs]; -+ -+ priv->cs_used = slave_cs; -+ -+ if (flash->initialized) { -+ /* Set the configuration: speed + mode + cs */ -+ writel(flash->cr, &priv->regs->cr); -+ writel(flash->dcr, &priv->regs->dcr); -+ priv->mode = flash->mode; -+ } else { -+ /* Set chip select */ -+ clrsetbits_le32(&priv->regs->cr, STM32_QSPI_CR_FSEL, -+ priv->cs_used ? STM32_QSPI_CR_FSEL : 0); -+ -+ /* Save the configuration: speed + mode + cs */ -+ flash->cr = readl(&priv->regs->cr); -+ flash->dcr = readl(&priv->regs->dcr); -+ flash->mode = priv->mode; - -- _stm32_qspi_set_flash_size(priv, flash->size); -+ flash->initialized = true; -+ } -+ } - -- _stm32_qspi_enable(priv); -+ setbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN); - - return 0; - } - - static int stm32_qspi_release_bus(struct udevice *dev) - { -- struct stm32_qspi_priv *priv; -- struct udevice *bus; -- -- bus = dev->parent; -- priv = dev_get_priv(bus); -+ struct stm32_qspi_priv *priv = dev_get_priv(dev->parent); - -- _stm32_qspi_disable(priv); -+ clrbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN); - - return 0; - } -@@ -549,13 +703,8 @@ static int stm32_qspi_release_bus(struct udevice *dev) - static int stm32_qspi_xfer(struct udevice *dev, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) - { -- struct stm32_qspi_priv *priv; -- struct udevice *bus; -- struct spi_flash *flash; -- -- bus = dev->parent; -- priv = dev_get_priv(bus); -- flash = dev_get_uclass_priv(dev); -+ struct stm32_qspi_priv *priv = dev_get_priv(dev->parent); -+ struct spi_flash *flash = dev_get_uclass_priv(dev); - - return _stm32_qspi_xfer(priv, flash, bitlen, (const u8 *)dout, - (u8 *)din, flags); -@@ -568,22 +717,26 @@ static int stm32_qspi_set_speed(struct udevice *bus, uint speed) - u32 qspi_clk = priv->clock_rate; - u32 prescaler = 255; - u32 csht; -+ int ret; - - if (speed > plat->max_hz) - speed = plat->max_hz; - - if (speed > 0) { -- prescaler = DIV_ROUND_UP(qspi_clk, speed) - 1; -- if (prescaler > 255) -- prescaler = 255; -- else if (prescaler < 0) -- prescaler = 0; -+ prescaler = 0; -+ if (qspi_clk) { -+ prescaler = DIV_ROUND_UP(qspi_clk, speed) - 1; -+ if (prescaler > 255) -+ prescaler = 255; -+ } - } - - csht = DIV_ROUND_UP((5 * qspi_clk) / (prescaler + 1), 100000000); - csht = (csht - 1) & STM32_QSPI_DCR_CSHT_MASK; - -- _stm32_qspi_wait_for_not_busy(priv); -+ ret = _stm32_qspi_wait_for_not_busy(priv); -+ if (ret) -+ return ret; - - clrsetbits_le32(&priv->regs->cr, - STM32_QSPI_CR_PRESCALER_MASK << -@@ -603,8 +756,11 @@ static int stm32_qspi_set_speed(struct udevice *bus, uint speed) - static int stm32_qspi_set_mode(struct udevice *bus, uint mode) - { - struct stm32_qspi_priv *priv = dev_get_priv(bus); -+ int ret; - -- _stm32_qspi_wait_for_not_busy(priv); -+ ret = _stm32_qspi_wait_for_not_busy(priv); -+ if (ret) -+ return ret; - - if ((mode & SPI_CPHA) && (mode & SPI_CPOL)) - setbits_le32(&priv->regs->dcr, STM32_QSPI_DCR_CKMODE); -@@ -649,12 +805,17 @@ static int stm32_qspi_set_mode(struct udevice *bus, uint mode) - return 0; - } - -+static const struct spi_controller_mem_ops stm32_qspi_mem_ops = { -+ .exec_op = stm32_qspi_exec_op, -+}; -+ - static const struct dm_spi_ops stm32_qspi_ops = { - .claim_bus = stm32_qspi_claim_bus, - .release_bus = stm32_qspi_release_bus, - .xfer = stm32_qspi_xfer, - .set_speed = stm32_qspi_set_speed, - .set_mode = stm32_qspi_set_mode, -+ .mem_ops = &stm32_qspi_mem_ops, - }; - - static const struct udevice_id stm32_qspi_ids[] = { -diff --git a/drivers/spi/stm32_spi.c b/drivers/spi/stm32_spi.c -new file mode 100644 -index 0000000..75b6006 ---- /dev/null -+++ b/drivers/spi/stm32_spi.c -@@ -0,0 +1,616 @@ -+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -+/* -+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved -+ * -+ * Driver for STMicroelectronics Serial peripheral interface (SPI) -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+/* STM32 SPI registers */ -+#define STM32_SPI_CR1 0x00 -+#define STM32_SPI_CR2 0x04 -+#define STM32_SPI_CFG1 0x08 -+#define STM32_SPI_CFG2 0x0C -+#define STM32_SPI_SR 0x14 -+#define STM32_SPI_IFCR 0x18 -+#define STM32_SPI_TXDR 0x20 -+#define STM32_SPI_RXDR 0x30 -+#define STM32_SPI_I2SCFGR 0x50 -+ -+/* STM32_SPI_CR1 bit fields */ -+#define SPI_CR1_SPE BIT(0) -+#define SPI_CR1_MASRX BIT(8) -+#define SPI_CR1_CSTART BIT(9) -+#define SPI_CR1_CSUSP BIT(10) -+#define SPI_CR1_HDDIR BIT(11) -+#define SPI_CR1_SSI BIT(12) -+ -+/* STM32_SPI_CR2 bit fields */ -+#define SPI_CR2_TSIZE GENMASK(15, 0) -+ -+/* STM32_SPI_CFG1 bit fields */ -+#define SPI_CFG1_DSIZE GENMASK(4, 0) -+#define SPI_CFG1_DSIZE_MIN 3 -+#define SPI_CFG1_FTHLV_SHIFT 5 -+#define SPI_CFG1_FTHLV GENMASK(8, 5) -+#define SPI_CFG1_MBR_SHIFT 28 -+#define SPI_CFG1_MBR GENMASK(30, 28) -+#define SPI_CFG1_MBR_MIN 0 -+#define SPI_CFG1_MBR_MAX FIELD_GET(SPI_CFG1_MBR, SPI_CFG1_MBR) -+ -+/* STM32_SPI_CFG2 bit fields */ -+#define SPI_CFG2_COMM_SHIFT 17 -+#define SPI_CFG2_COMM GENMASK(18, 17) -+#define SPI_CFG2_MASTER BIT(22) -+#define SPI_CFG2_LSBFRST BIT(23) -+#define SPI_CFG2_CPHA BIT(24) -+#define SPI_CFG2_CPOL BIT(25) -+#define SPI_CFG2_SSM BIT(26) -+#define SPI_CFG2_AFCNTR BIT(31) -+ -+/* STM32_SPI_SR bit fields */ -+#define SPI_SR_RXP BIT(0) -+#define SPI_SR_TXP BIT(1) -+#define SPI_SR_EOT BIT(3) -+#define SPI_SR_TXTF BIT(4) -+#define SPI_SR_OVR BIT(6) -+#define SPI_SR_SUSP BIT(11) -+#define SPI_SR_RXPLVL_SHIFT 13 -+#define SPI_SR_RXPLVL GENMASK(14, 13) -+#define SPI_SR_RXWNE BIT(15) -+ -+/* STM32_SPI_IFCR bit fields */ -+#define SPI_IFCR_ALL GENMASK(11, 3) -+ -+/* STM32_SPI_I2SCFGR bit fields */ -+#define SPI_I2SCFGR_I2SMOD BIT(0) -+ -+#define MAX_CS_COUNT 4 -+ -+/* SPI Master Baud Rate min/max divisor */ -+#define STM32_MBR_DIV_MIN (2 << SPI_CFG1_MBR_MIN) -+#define STM32_MBR_DIV_MAX (2 << SPI_CFG1_MBR_MAX) -+ -+#define STM32_SPI_TIMEOUT_US 100000 -+ -+/* SPI Communication mode */ -+#define SPI_FULL_DUPLEX 0 -+#define SPI_SIMPLEX_TX 1 -+#define SPI_SIMPLEX_RX 2 -+#define SPI_HALF_DUPLEX 3 -+ -+struct stm32_spi_priv { -+ void __iomem *base; -+ struct clk clk; -+ struct reset_ctl rst_ctl; -+ struct gpio_desc cs_gpios[MAX_CS_COUNT]; -+ ulong bus_clk_rate; -+ unsigned int fifo_size; -+ unsigned int cur_bpw; -+ unsigned int cur_hz; -+ unsigned int cur_xferlen; /* current transfer length in bytes */ -+ unsigned int tx_len; /* number of data to be written in bytes */ -+ unsigned int rx_len; /* number of data to be read in bytes */ -+ const void *tx_buf; /* data to be written, or NULL */ -+ void *rx_buf; /* data to be read, or NULL */ -+ u32 cur_mode; -+ bool cs_high; -+}; -+ -+static void stm32_spi_write_txfifo(struct stm32_spi_priv *priv) -+{ -+ while ((priv->tx_len > 0) && -+ (readl(priv->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); -+ 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); -+ priv->tx_len -= sizeof(u16); -+ } else { -+ const u8 *tx_buf8 = (const u8 *)(priv->tx_buf + offs); -+ -+ writeb(*tx_buf8, priv->base + STM32_SPI_TXDR); -+ priv->tx_len -= sizeof(u8); -+ } -+ } -+ -+ debug("%s: %d bytes left\n", __func__, priv->tx_len); -+} -+ -+static void stm32_spi_read_rxfifo(struct stm32_spi_priv *priv) -+{ -+ u32 sr = readl(priv->base + STM32_SPI_SR); -+ u32 rxplvl = (sr & SPI_SR_RXPLVL) >> SPI_SR_RXPLVL_SHIFT; -+ -+ while ((priv->rx_len > 0) && -+ ((sr & SPI_SR_RXP) || -+ ((sr & SPI_SR_EOT) && ((sr & SPI_SR_RXWNE) || (rxplvl > 0))))) { -+ u32 offs = priv->cur_xferlen - priv->rx_len; -+ -+ if (IS_ALIGNED((uintptr_t)(priv->rx_buf + offs), sizeof(u32)) && -+ (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); -+ priv->rx_len -= sizeof(u32); -+ } else if (IS_ALIGNED((uintptr_t)(priv->rx_buf + offs), sizeof(u16)) && -+ (priv->rx_len >= sizeof(u16) || -+ (!(sr & SPI_SR_RXWNE) && -+ (rxplvl >= 2 || priv->cur_bpw > 8)))) { -+ u16 *rx_buf16 = (u16 *)(priv->rx_buf + offs); -+ -+ *rx_buf16 = readw(priv->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); -+ priv->rx_len -= sizeof(u8); -+ } -+ -+ sr = readl(priv->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) -+{ -+ debug("%s\n", __func__); -+ -+ /* Enable the SPI hardware */ -+ setbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_SPE); -+ -+ return 0; -+} -+ -+static int stm32_spi_disable(struct stm32_spi_priv *priv) -+{ -+ debug("%s\n", __func__); -+ -+ /* Disable the SPI hardware */ -+ clrbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_SPE); -+ -+ return 0; -+} -+ -+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); -+ -+ debug("%s\n", __func__); -+ -+ /* Enable the SPI hardware */ -+ return stm32_spi_enable(priv); -+} -+ -+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); -+ -+ debug("%s\n", __func__); -+ -+ /* Disable the SPI hardware */ -+ return stm32_spi_disable(priv); -+} -+ -+static void stm32_spi_stopxfer(struct udevice *dev) -+{ -+ struct stm32_spi_priv *priv = dev_get_priv(dev); -+ u32 cr1, sr; -+ int ret; -+ -+ debug("%s\n", __func__); -+ -+ cr1 = readl(priv->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, -+ !(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, -+ sr, !(sr & SPI_SR_SUSP), -+ 100000) < 0) -+ dev_err(dev, "Suspend request timeout\n"); -+ } -+ } -+ -+ /* clear status flags */ -+ setbits_le32(priv->base + STM32_SPI_IFCR, SPI_IFCR_ALL); -+} -+ -+static int stm32_spi_set_cs(struct udevice *dev, unsigned int cs, bool enable) -+{ -+ struct stm32_spi_priv *priv = dev_get_priv(dev); -+ -+ debug("%s: cs=%d enable=%d\n", __func__, cs, enable); -+ -+ if (cs >= MAX_CS_COUNT) -+ return -ENODEV; -+ -+ if (!dm_gpio_is_valid(&priv->cs_gpios[cs])) -+ return -EINVAL; -+ -+ if (priv->cs_high) -+ enable = !enable; -+ -+ return dm_gpio_set_value(&priv->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); -+ u32 cfg2_clrb = 0, cfg2_setb = 0; -+ -+ debug("%s: mode=%d\n", __func__, mode); -+ -+ if (mode & SPI_CPOL) -+ cfg2_setb |= SPI_CFG2_CPOL; -+ else -+ cfg2_clrb |= SPI_CFG2_CPOL; -+ -+ if (mode & SPI_CPHA) -+ cfg2_setb |= SPI_CFG2_CPHA; -+ else -+ cfg2_clrb |= SPI_CFG2_CPHA; -+ -+ if (mode & SPI_LSB_FIRST) -+ cfg2_setb |= SPI_CFG2_LSBFRST; -+ else -+ cfg2_clrb |= SPI_CFG2_LSBFRST; -+ -+ if (cfg2_clrb || cfg2_setb) -+ clrsetbits_le32(priv->base + STM32_SPI_CFG2, -+ cfg2_clrb, cfg2_setb); -+ -+ if (mode & SPI_CS_HIGH) -+ priv->cs_high = true; -+ else -+ priv->cs_high = false; -+ return 0; -+} -+ -+static int stm32_spi_set_fthlv(struct udevice *dev, u32 xfer_len) -+{ -+ struct stm32_spi_priv *priv = dev_get_priv(dev); -+ u32 fthlv, half_fifo; -+ -+ /* data packet should not exceed 1/2 of fifo space */ -+ half_fifo = (priv->fifo_size / 2); -+ -+ /* data_packet should not exceed transfer length */ -+ fthlv = (half_fifo > xfer_len) ? xfer_len : half_fifo; -+ -+ /* align packet size with data registers access */ -+ fthlv -= (fthlv % 4); -+ -+ if (!fthlv) -+ fthlv = 1; -+ clrsetbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_FTHLV, -+ (fthlv - 1) << SPI_CFG1_FTHLV_SHIFT); -+ -+ return 0; -+} -+ -+static int stm32_spi_set_speed(struct udevice *bus, uint hz) -+{ -+ struct stm32_spi_priv *priv = dev_get_priv(bus); -+ u32 mbrdiv; -+ long div; -+ -+ debug("%s: hz=%d\n", __func__, hz); -+ -+ if (priv->cur_hz == hz) -+ return 0; -+ -+ div = DIV_ROUND_UP(priv->bus_clk_rate, hz); -+ -+ if (div < STM32_MBR_DIV_MIN || -+ div > STM32_MBR_DIV_MAX) -+ return -EINVAL; -+ -+ /* Determine the first power of 2 greater than or equal to div */ -+ if (div & (div - 1)) -+ mbrdiv = fls(div); -+ else -+ mbrdiv = fls(div) - 1; -+ -+ if (!mbrdiv) -+ return -EINVAL; -+ -+ clrsetbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_MBR, -+ (mbrdiv - 1) << SPI_CFG1_MBR_SHIFT); -+ -+ priv->cur_hz = hz; -+ -+ return 0; -+} -+ -+static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen, -+ const void *dout, void *din, unsigned long flags) -+{ -+ struct udevice *bus = dev_get_parent(slave); -+ struct dm_spi_slave_platdata *slave_plat; -+ struct stm32_spi_priv *priv = dev_get_priv(bus); -+ u32 sr; -+ u32 ifcr = 0; -+ u32 xferlen; -+ u32 mode; -+ int xfer_status = 0; -+ -+ xferlen = bitlen / 8; -+ -+ if (xferlen <= SPI_CR2_TSIZE) -+ writel(xferlen, priv->base + STM32_SPI_CR2); -+ else -+ return -EMSGSIZE; -+ -+ priv->tx_buf = dout; -+ priv->rx_buf = din; -+ priv->tx_len = priv->tx_buf ? bitlen / 8 : 0; -+ priv->rx_len = priv->rx_buf ? bitlen / 8 : 0; -+ -+ mode = SPI_FULL_DUPLEX; -+ if (!priv->tx_buf) -+ mode = SPI_SIMPLEX_RX; -+ else if (!priv->rx_buf) -+ mode = SPI_SIMPLEX_TX; -+ -+ if (priv->cur_xferlen != xferlen || priv->cur_mode != mode) { -+ priv->cur_mode = mode; -+ priv->cur_xferlen = xferlen; -+ -+ /* Disable the SPI hardware to unlock CFG1/CFG2 registers */ -+ stm32_spi_disable(priv); -+ -+ clrsetbits_le32(priv->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); -+ } -+ -+ debug("%s: priv->tx_len=%d priv->rx_len=%d\n", __func__, -+ priv->tx_len, priv->rx_len); -+ -+ slave_plat = dev_get_parent_platdata(slave); -+ if (flags & SPI_XFER_BEGIN) -+ stm32_spi_set_cs(bus, slave_plat->cs, false); -+ -+ /* Be sure to have data in fifo before starting data transfer */ -+ if (priv->tx_buf) -+ stm32_spi_write_txfifo(priv); -+ -+ setbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_CSTART); -+ -+ while (1) { -+ sr = readl(priv->base + STM32_SPI_SR); -+ -+ if (sr & SPI_SR_OVR) { -+ dev_err(bus, "Overrun: RX data lost\n"); -+ xfer_status = -EIO; -+ break; -+ } -+ -+ if (sr & SPI_SR_SUSP) { -+ dev_warn(bus, "System too slow is limiting data throughput\n"); -+ -+ if (priv->rx_buf && priv->rx_len > 0) -+ stm32_spi_read_rxfifo(priv); -+ -+ ifcr |= SPI_SR_SUSP; -+ } -+ -+ if (sr & SPI_SR_TXTF) -+ ifcr |= SPI_SR_TXTF; -+ -+ if (sr & SPI_SR_TXP) -+ if (priv->tx_buf && priv->tx_len > 0) -+ stm32_spi_write_txfifo(priv); -+ -+ if (sr & SPI_SR_RXP) -+ if (priv->rx_buf && priv->rx_len > 0) -+ stm32_spi_read_rxfifo(priv); -+ -+ if (sr & SPI_SR_EOT) { -+ if (priv->rx_buf && priv->rx_len > 0) -+ stm32_spi_read_rxfifo(priv); -+ break; -+ } -+ -+ writel(ifcr, priv->base + STM32_SPI_IFCR); -+ } -+ -+ /* clear status flags */ -+ setbits_le32(priv->base + STM32_SPI_IFCR, SPI_IFCR_ALL); -+ stm32_spi_stopxfer(bus); -+ -+ if (flags & SPI_XFER_END) -+ stm32_spi_set_cs(bus, slave_plat->cs, true); -+ -+ return xfer_status; -+} -+ -+static int stm32_spi_get_fifo_size(struct udevice *dev) -+{ -+ struct stm32_spi_priv *priv = dev_get_priv(dev); -+ u32 count = 0; -+ -+ stm32_spi_enable(priv); -+ -+ while (readl(priv->base + STM32_SPI_SR) & SPI_SR_TXP) -+ writeb(++count, priv->base + STM32_SPI_TXDR); -+ -+ stm32_spi_disable(priv); -+ -+ debug("%s %d x 8-bit fifo size\n", __func__, count); -+ -+ return count; -+} -+ -+static int stm32_spi_probe(struct udevice *dev) -+{ -+ struct stm32_spi_priv *priv = dev_get_priv(dev); -+ 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); -+ if (ret < 0) -+ return ret; -+ -+ ret = clk_enable(&priv->clk); -+ if (ret < 0) -+ return ret; -+ -+ clk_rate = clk_get_rate(&priv->clk); -+ if (!clk_rate) { -+ ret = -EINVAL; -+ goto clk_err; -+ } -+ -+ 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); -+ 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; -+ } -+ -+ 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, -+ priv->cur_bpw - 1); -+ -+ for (i = 0; i < ARRAY_SIZE(priv->cs_gpios); i++) { -+ if (!dm_gpio_is_valid(&priv->cs_gpios[i])) -+ continue; -+ -+ dm_gpio_set_dir_flags(&priv->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); -+ -+ /* -+ * - SS input value high -+ * - transmitter half duplex direction -+ * - automatic communication suspend when RX-Fifo is full -+ */ -+ setbits_le32(priv->base + STM32_SPI_CR1, -+ SPI_CR1_SSI | SPI_CR1_HDDIR | SPI_CR1_MASRX); -+ -+ /* -+ * - Set the master mode (default Motorola mode) -+ * - Consider 1 master/n slaves configuration and -+ * SS input value is determined by the SSI bit -+ * - keep control of all associated GPIOs -+ */ -+ setbits_le32(priv->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); -+ -+ return ret; -+}; -+ -+static int stm32_spi_remove(struct udevice *dev) -+{ -+ struct stm32_spi_priv *priv = dev_get_priv(dev); -+ int ret; -+ -+ stm32_spi_stopxfer(dev); -+ stm32_spi_disable(priv); -+ -+ ret = reset_assert(&priv->rst_ctl); -+ if (ret < 0) -+ return ret; -+ -+ reset_free(&priv->rst_ctl); -+ -+ ret = clk_disable(&priv->clk); -+ if (ret < 0) -+ return ret; -+ -+ clk_free(&priv->clk); -+ -+ return ret; -+}; -+ -+static const struct dm_spi_ops stm32_spi_ops = { -+ .claim_bus = stm32_spi_claim_bus, -+ .release_bus = stm32_spi_release_bus, -+ .set_mode = stm32_spi_set_mode, -+ .set_speed = stm32_spi_set_speed, -+ .xfer = stm32_spi_xfer, -+}; -+ -+static const struct udevice_id stm32_spi_ids[] = { -+ { .compatible = "st,stm32h7-spi", }, -+ { } -+}; -+ -+U_BOOT_DRIVER(stm32_spi) = { -+ .name = "stm32_spi", -+ .id = UCLASS_SPI, -+ .of_match = stm32_spi_ids, -+ .ops = &stm32_spi_ops, -+ .priv_auto_alloc_size = sizeof(struct stm32_spi_priv), -+ .probe = stm32_spi_probe, -+ .remove = stm32_spi_remove, -+}; -diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c -index 6552a5b..520eb65 100644 ---- a/drivers/usb/gadget/dwc2_udc_otg.c -+++ b/drivers/usb/gadget/dwc2_udc_otg.c -@@ -401,6 +401,8 @@ static void reconfig_usbd(struct dwc2_udc *dev) - unsigned int uTemp = writel(CORE_SOFT_RESET, ®->grstctl); - uint32_t dflt_gusbcfg; - uint32_t rx_fifo_sz, tx_fifo_sz, np_tx_fifo_sz; -+ u32 max_hw_ep; -+ int pdata_hw_ep; - - debug("Reseting OTG controller\n"); - -@@ -486,10 +488,22 @@ static void reconfig_usbd(struct dwc2_udc *dev) - writel((np_tx_fifo_sz << 16) | rx_fifo_sz, - ®->gnptxfsiz); - -- for (i = 1; i < DWC2_MAX_HW_ENDPOINTS; i++) -+ /* retrieve the number of TX fifo */ -+ max_hw_ep = (readl(®->ghwcfg4) & GHWCFG4_NUM_IN_EPS_MASK) >> -+ GHWCFG4_NUM_IN_EPS_SHIFT; -+ pdata_hw_ep = dev->pdata->tx_fifo_sz_array[DWC2_SIZE_NB_OFFS]; -+ -+ if (pdata_hw_ep && max_hw_ep != pdata_hw_ep) -+ pr_err("Got %d hw endpoint and %d tx-fifo-size in array !!\n", -+ max_hw_ep, pdata_hw_ep); -+ -+ for (i = 1; i <= max_hw_ep; i++) { -+ if (pdata_hw_ep) -+ tx_fifo_sz = dev->pdata->tx_fifo_sz_array[(i - 1) + -+ DWC2_SIZE_OFFS]; - writel((rx_fifo_sz + np_tx_fifo_sz + tx_fifo_sz*(i-1)) | - tx_fifo_sz << 16, ®->dieptxf[i-1]); -- -+ } - /* Flush the RX FIFO */ - writel(RX_FIFO_FLUSH, ®->grstctl); - while (readl(®->grstctl) & RX_FIFO_FLUSH) -diff --git a/drivers/usb/gadget/dwc2_udc_otg_priv.h b/drivers/usb/gadget/dwc2_udc_otg_priv.h -index b64e222..a092f43 100644 ---- a/drivers/usb/gadget/dwc2_udc_otg_priv.h -+++ b/drivers/usb/gadget/dwc2_udc_otg_priv.h -@@ -24,7 +24,6 @@ - #define EP_FIFO_SIZE2 1024 - /* ep0-control, ep1in-bulk, ep2out-bulk, ep3in-int */ - #define DWC2_MAX_ENDPOINTS 4 --#define DWC2_MAX_HW_ENDPOINTS 16 - - #define WAIT_FOR_SETUP 0 - #define DATA_STATE_XMIT 1 -diff --git a/drivers/usb/gadget/dwc2_udc_otg_regs.h b/drivers/usb/gadget/dwc2_udc_otg_regs.h -index a1829b3..449b208 100644 ---- a/drivers/usb/gadget/dwc2_udc_otg_regs.h -+++ b/drivers/usb/gadget/dwc2_udc_otg_regs.h -@@ -60,22 +60,24 @@ struct dwc2_usbotg_reg { - u32 grxstsp; /* Receive Status Debug Pop/Status Pop */ - u32 grxfsiz; /* Receive FIFO Size */ - u32 gnptxfsiz; /* Non-Periodic Transmit FIFO Size */ -- u8 res1[216]; -+ u8 res1[36]; -+ u32 ghwcfg4; /* User HW Config4 */ -+ u8 res2[176]; - u32 dieptxf[15]; /* Device Periodic Transmit FIFO size register */ -- u8 res2[1728]; -+ u8 res3[1728]; - /* Device Configuration */ - u32 dcfg; /* Device Configuration Register */ - u32 dctl; /* Device Control */ - u32 dsts; /* Device Status */ -- u8 res3[4]; -+ u8 res4[4]; - u32 diepmsk; /* Device IN Endpoint Common Interrupt Mask */ - u32 doepmsk; /* Device OUT Endpoint Common Interrupt Mask */ - u32 daint; /* Device All Endpoints Interrupt */ - u32 daintmsk; /* Device All Endpoints Interrupt Mask */ -- u8 res4[224]; -+ u8 res5[224]; - struct dwc2_dev_in_endp in_endp[16]; - struct dwc2_dev_out_endp out_endp[16]; -- u8 res5[768]; -+ u8 res6[768]; - struct ep_fifo ep[16]; - }; - -@@ -86,6 +88,9 @@ struct dwc2_usbotg_reg { - #define B_SESSION_VALID (0x1<<19) - #define A_SESSION_VALID (0x1<<18) - -+/* DWC2_UDC_OTG_GOTINT */ -+#define GOTGINT_SES_END_DET (1<<2) -+ - /* DWC2_UDC_OTG_GAHBCFG */ - #define PTXFE_HALF (0<<8) - #define PTXFE_ZERO (1<<8) -@@ -118,6 +123,7 @@ struct dwc2_usbotg_reg { - #define INT_NP_TX_FIFO_EMPTY (0x1<<5) - #define INT_RX_FIFO_NOT_EMPTY (0x1<<4) - #define INT_SOF (0x1<<3) -+#define INT_OTG (0x1<<2) - #define INT_DEV_MODE (0x0<<0) - #define INT_HOST_MODE (0x1<<1) - #define INT_GOUTNakEff (0x01<<7) -@@ -246,7 +252,7 @@ struct dwc2_usbotg_reg { - - /* Masks definitions */ - #define GINTMSK_INIT (INT_OUT_EP | INT_IN_EP | INT_RESUME | INT_ENUMDONE\ -- | INT_RESET | INT_SUSPEND) -+ | INT_RESET | INT_SUSPEND | INT_OTG) - #define DOEPMSK_INIT (CTRL_OUT_EP_SETUP_PHASE_DONE | AHB_ERROR|TRANSFER_DONE) - #define DIEPMSK_INIT (NON_ISO_IN_EP_TIMEOUT|AHB_ERROR|TRANSFER_DONE) - #define GAHBCFG_INIT (PTXFE_HALF | NPTXFE_HALF | MODE_DMA | BURST_INCR4\ -@@ -269,4 +275,9 @@ struct dwc2_usbotg_reg { - /* Device ALL Endpoints Interrupt Register (DAINT) */ - #define DAINT_IN_EP_INT(x) (x << 0) - #define DAINT_OUT_EP_INT(x) (x << 16) -+ -+/* User HW Config4 */ -+#define GHWCFG4_NUM_IN_EPS_MASK (0xf << 26) -+#define GHWCFG4_NUM_IN_EPS_SHIFT 26 -+ - #endif -diff --git a/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c b/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c -index a75af49..7eb632d 100644 ---- a/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c -+++ b/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c -@@ -467,7 +467,7 @@ static void process_ep_out_intr(struct dwc2_udc *dev) - static int dwc2_udc_irq(int irq, void *_dev) - { - struct dwc2_udc *dev = _dev; -- u32 intr_status; -+ u32 intr_status, gotgint; - u32 usb_status, gintmsk; - unsigned long flags = 0; - -@@ -521,14 +521,24 @@ static int dwc2_udc_irq(int irq, void *_dev) - && dev->driver) { - if (dev->driver->suspend) - dev->driver->suspend(&dev->gadget); -+ } -+ } -+ -+ if (intr_status & INT_OTG) { -+ gotgint = readl(®->gotgint); -+ debug_cond(DEBUG_ISR, -+ "\tOTG interrupt: (GOTGINT):0x%x\n", gotgint); - -- /* HACK to let gadget detect disconnected state */ -+ if (gotgint & GOTGINT_SES_END_DET) { -+ debug_cond(DEBUG_ISR, "\t\tSession End Detected\n"); -+ /* Let gadget detect disconnected state */ - if (dev->driver->disconnect) { - spin_unlock_irqrestore(&dev->lock, flags); - dev->driver->disconnect(&dev->gadget); - spin_lock_irqsave(&dev->lock, flags); - } - } -+ writel(gotgint, ®->gotgint); - } - - if (intr_status & INT_RESUME) { -diff --git a/drivers/video/orisetech_otm8009a.c b/drivers/video/orisetech_otm8009a.c -index ad1d6f0..41c4bef 100644 ---- a/drivers/video/orisetech_otm8009a.c -+++ b/drivers/video/orisetech_otm8009a.c -@@ -302,10 +302,13 @@ static int otm8009a_panel_probe(struct udevice *dev) - int ret; - - if (IS_ENABLED(CONFIG_DM_REGULATOR) && priv->reg) { -- dev_err(dev, "enable regulator '%s'\n", priv->reg->name); -+ dev_dbg(dev, "enable regulator '%s'\n", priv->reg->name); - ret = regulator_set_enable(priv->reg, true); -- if (ret) -+ if (ret) { -+ dev_err(dev, "Regulator : '%s' - can't enable\n", -+ priv->reg->name); - return ret; -+ } - } - - /* reset panel */ -diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c -index 5fe49a5..367d811 100644 ---- a/drivers/video/video-uclass.c -+++ b/drivers/video/video-uclass.c -@@ -277,7 +277,9 @@ static int video_post_bind(struct udevice *dev) - return 0; - size = alloc_fb(dev, &addr); - if (addr < gd->video_bottom) { -- /* Device tree node may need the 'u-boot,dm-pre-reloc' tag */ -+ /* Device tree node may need the 'u-boot,dm-pre-reloc' or -+ * 'u-boot,dm-pre-proper' tag -+ */ - printf("Video device '%s' cannot allocate frame buffer memory -ensure the device is set up before relocation\n", - dev->name); - return -ENOSPC; -diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig -index 705fc7d..5bae563 100644 ---- a/drivers/watchdog/Kconfig -+++ b/drivers/watchdog/Kconfig -@@ -20,6 +20,13 @@ config BCM2835_WDT - This provides basic infrastructure to support BCM2835/2836 watchdog - hardware, with a max timeout of ~15secs. - -+config IMX_WATCHDOG -+ bool "Enable Watchdog Timer support for IMX and LSCH2 of NXP" -+ select HW_WATCHDOG -+ help -+ Select this to enable the IMX and LSCH2 of Layerscape watchdog -+ driver. -+ - config OMAP_WATCHDOG - bool "TI OMAP watchdog driver" - depends on ARCH_OMAP2PLUS -@@ -52,14 +59,6 @@ config WDT - What exactly happens when the timer expires is up to a particular - device/driver. - --config WDT_SANDBOX -- bool "Enable Watchdog Timer support for Sandbox" -- depends on SANDBOX && WDT -- help -- Enable Watchdog Timer support in Sandbox. This is a dummy device that -- can be probed and supports all of the methods of WDT, but does not -- really do anything. -- - config WDT_ARMADA_37XX - bool "Marvell Armada 37xx watchdog timer support" - depends on WDT && ARMADA_3700 -@@ -88,13 +87,6 @@ config WDT_BCM6345 - The watchdog timer is stopped when initialized. - It performs full SoC reset. - --config WDT_ORION -- bool "Orion watchdog timer support" -- depends on WDT -- help -- Select this to enable Orion watchdog timer, which can be found on some -- Marvell Armada chips. -- - config WDT_CDNS - bool "Cadence watchdog timer support" - depends on WDT -@@ -103,20 +95,28 @@ config WDT_CDNS - Select this to enable Cadence watchdog timer, which can be found on some - Xilinx Microzed Platform. - --config STM32MP_WATCHDOG -- bool "Enable IWDG watchdog driver for STM32 MP's family" -- depends on ARCH_STM32MP -- select HW_WATCHDOG -+config WDT_ORION -+ bool "Orion watchdog timer support" -+ depends on WDT - help -- Enable the STM32 watchdog (IWDG) driver. Enable support to -- configure STM32's on-SoC watchdog. -+ Select this to enable Orion watchdog timer, which can be found on some -+ Marvell Armada chips. -+ -+config WDT_SANDBOX -+ bool "Enable Watchdog Timer support for Sandbox" -+ depends on SANDBOX && WDT -+ help -+ Enable Watchdog Timer support in Sandbox. This is a dummy device that -+ can be probed and supports all of the methods of WDT, but does not -+ really do anything. - --config STM32MP_WATCHDOG_TIMEOUT_SECS -- int "IWDG watchdog timeout" -- depends on STM32MP_WATCHDOG -- default 32 -+config WDT_STM32MP -+ bool "IWDG watchdog driver for STM32 MP's family" -+ depends on WDT -+ imply WATCHDOG - help -- Configure the timeout for IWDG (default: 32s). -+ Enable the STM32 watchdog (IWDG) driver. Enable support to -+ configure STM32's on-SoC watchdog. - - config XILINX_TB_WATCHDOG - bool "Xilinx Axi watchdog timer support" -@@ -126,11 +126,4 @@ config XILINX_TB_WATCHDOG - Select this to enable Xilinx Axi watchdog timer, which can be found on some - Xilinx Microblaze Platforms. - --config IMX_WATCHDOG -- bool "Enable Watchdog Timer support for IMX and LSCH2 of NXP" -- select HW_WATCHDOG -- help -- Select this to enable the IMX and LSCH2 of Layerscape watchdog -- driver. -- - endmenu -diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile -index 25491cf..6374b5b 100644 ---- a/drivers/watchdog/Makefile -+++ b/drivers/watchdog/Makefile -@@ -23,4 +23,4 @@ obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o - obj-$(CONFIG_WDT_ORION) += orion_wdt.o - obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o - obj-$(CONFIG_MPC8xx_WATCHDOG) += mpc8xx_wdt.o --obj-$(CONFIG_STM32MP_WATCHDOG) += stm32mp_wdt.o -\ No newline at end of file -+obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o -diff --git a/drivers/watchdog/stm32mp_wdt.c b/drivers/watchdog/stm32mp_wdt.c -index 696be1b..ea85e41 100644 ---- a/drivers/watchdog/stm32mp_wdt.c -+++ b/drivers/watchdog/stm32mp_wdt.c -@@ -1,16 +1,15 @@ - // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause - /* -- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved - */ - - #include - #include - #include --#include - #include --#include -+#include - #include --#include -+#include - - /* IWDG registers */ - #define IWDG_KR 0x00 /* Key register */ -@@ -29,36 +28,78 @@ - /* IWDG_RLR register values */ - #define RLR_MAX 0xFFF /* Max value supported by reload register */ - --static fdt_addr_t stm32mp_wdt_base -- __attribute__((section(".data"))) = FDT_ADDR_T_NONE; -+/* IWDG_SR register bit values */ -+#define SR_PVU BIT(0) /* Watchdog prescaler value update */ -+#define SR_RVU BIT(1) /* Watchdog counter reload value update */ - --void hw_watchdog_reset(void) -+#define DEFAULT_TIMEOUT_SECS 32 /* default timeout */ -+ -+struct stm32mp_wdt_priv { -+ fdt_addr_t base; /* registers addr in physical memory */ -+ u32 timeout; /* timeout in seconds */ -+ unsigned long wdt_clk_rate; /* Watchdog dedicated clock rate */ -+}; -+ -+static int stm32mp_wdt_reset(struct udevice *dev) - { -- if (stm32mp_wdt_base != FDT_ADDR_T_NONE) -- writel(KR_KEY_RELOAD, stm32mp_wdt_base + IWDG_KR); -+ struct stm32mp_wdt_priv *priv = dev_get_priv(dev); -+ -+ writel(KR_KEY_RELOAD, priv->base + IWDG_KR); -+ -+ return 0; - } - --void hw_watchdog_init(void) -+static int stm32mp_wdt_start(struct udevice *dev, u64 timeout, ulong flags) - { -- struct regmap *map; -+ struct stm32mp_wdt_priv *priv = dev_get_priv(dev); -+ int reload; -+ u32 val; -+ int ret; -+ -+ /* Prescaler fixed to 256 */ -+ reload = (priv->timeout * 1000) * priv->wdt_clk_rate / 256; -+ if (reload > RLR_MAX + 1) -+ /* Force to max watchdog counter reload value */ -+ reload = RLR_MAX + 1; -+ else if (!reload) -+ /* Force to min watchdog counter reload value */ -+ reload = priv->wdt_clk_rate / 256; -+ -+ /* Set prescaler & reload registers */ -+ writel(KR_KEY_EWA, priv->base + IWDG_KR); -+ writel(PR_256, priv->base + IWDG_PR); -+ writel(reload - 1, priv->base + IWDG_RLR); - -- map = syscon_get_regmap_by_driver_data(STM32MP_SYSCON_IWDG); -- if (!IS_ERR(map)) -- stm32mp_wdt_base = map->ranges[0].start; -- else -- printf("%s: iwdg init error", __func__); -+ /* Enable watchdog */ -+ writel(KR_KEY_ENABLE, priv->base + IWDG_KR); -+ -+ /* Wait for the registers to be updated */ -+ ret = readl_poll_timeout(priv->base + IWDG_SR, val, -+ val & (SR_PVU | SR_RVU), CONFIG_SYS_HZ); -+ -+ if (ret < 0) { -+ pr_err("Updating IWDG registers timeout"); -+ return -ETIMEDOUT; -+ } -+ -+ return 0; - } - - static int stm32mp_wdt_probe(struct udevice *dev) - { -- struct regmap *map = syscon_get_regmap(dev); -+ struct stm32mp_wdt_priv *priv = dev_get_priv(dev); - struct clk clk; -- int ret, reload; -- u32 time_start; -- ulong regmap_base = map->ranges[0].start; -+ int ret; - - debug("IWDG init\n"); - -+ priv->base = devfdt_get_addr(dev); -+ if (priv->base == FDT_ADDR_T_NONE) -+ return -EINVAL; -+ -+ priv->timeout = dev_read_u32_default(dev, "timeout-sec", -+ DEFAULT_TIMEOUT_SECS); -+ - /* Enable clock */ - ret = clk_get_by_name(dev, "pclk", &clk); - if (ret) -@@ -73,47 +114,28 @@ static int stm32mp_wdt_probe(struct udevice *dev) - if (ret) - return ret; - -- /* Prescaler fixed to 256 */ -- reload = CONFIG_STM32MP_WATCHDOG_TIMEOUT_SECS * -- clk_get_rate(&clk) / 256; -- if (reload > RLR_MAX + 1) -- /* Force to max watchdog counter reload value */ -- reload = RLR_MAX + 1; -- else if (!reload) -- /* Force to min watchdog counter reload value */ -- reload = clk_get_rate(&clk) / 256; -- -- /* Enable watchdog */ -- writel(KR_KEY_ENABLE, regmap_base + IWDG_KR); -- -- /* Set prescaler & reload registers */ -- writel(KR_KEY_EWA, regmap_base + IWDG_KR); -- writel(PR_256, regmap_base + IWDG_PR); -- writel(reload - 1, regmap_base + IWDG_RLR); -- -- /* Wait for the registers to be updated */ -- time_start = get_timer(0); -- while (readl(regmap_base + IWDG_SR)) { -- if (get_timer(time_start) > CONFIG_SYS_HZ) { -- pr_err("Updating IWDG registers timeout"); -- return -ETIMEDOUT; -- } -- } -+ priv->wdt_clk_rate = clk_get_rate(&clk); - - debug("IWDG init done\n"); - - return 0; - } - -+static const struct wdt_ops stm32mp_wdt_ops = { -+ .start = stm32mp_wdt_start, -+ .reset = stm32mp_wdt_reset, -+}; -+ - static const struct udevice_id stm32mp_wdt_match[] = { -- { .compatible = "st,stm32mp1-iwdg", -- .data = STM32MP_SYSCON_IWDG }, -+ { .compatible = "st,stm32mp1-iwdg" }, - { /* sentinel */ } - }; - - U_BOOT_DRIVER(stm32mp_wdt) = { - .name = "stm32mp-wdt", -- .id = UCLASS_SYSCON, -+ .id = UCLASS_WDT, - .of_match = stm32mp_wdt_match, -+ .priv_auto_alloc_size = sizeof(struct stm32mp_wdt_priv), - .probe = stm32mp_wdt_probe, -+ .ops = &stm32mp_wdt_ops, - }; -diff --git a/env/Kconfig b/env/Kconfig -index 9011109..b304451 100644 ---- a/env/Kconfig -+++ b/env/Kconfig -@@ -2,18 +2,12 @@ menu "Environment" - - config ENV_IS_NOWHERE - bool "Environment is not stored" -- depends on !ENV_IS_IN_EEPROM -- depends on !ENV_IS_IN_EXT4 -- depends on !ENV_IS_IN_FAT -- depends on !ENV_IS_IN_FLASH -- depends on !ENV_IS_IN_MMC -- depends on !ENV_IS_IN_NAND -- depends on !ENV_IS_IN_NVRAM -- depends on !ENV_IS_IN_ONENAND -- depends on !ENV_IS_IN_REMOTE -- depends on !ENV_IS_IN_SPI_FLASH -- depends on !ENV_IS_IN_UBI -- default y -+ default y if !ENV_IS_IN_EEPROM && !ENV_IS_IN_EXT4 && \ -+ !ENV_IS_IN_FAT && !ENV_IS_IN_FLASH && \ -+ !ENV_IS_IN_MMC && !ENV_IS_IN_NAND && \ -+ !ENV_IS_IN_NVRAM && !ENV_IS_IN_ONENAND && \ -+ !ENV_IS_IN_REMOTE && !ENV_IS_IN_SPI_FLASH && \ -+ !ENV_IS_IN_UBI - help - Define this if you don't want to or can't have an environment stored - on a storage medium. In this case the environment will still exist -diff --git a/env/ext4.c b/env/ext4.c -index 09c5e4a..d027a70 100644 ---- a/env/ext4.c -+++ b/env/ext4.c -@@ -30,6 +30,16 @@ - #include - #include - -+__weak const char *env_ext4_get_intf(void) -+{ -+ return (const char *)CONFIG_ENV_EXT4_INTERFACE; -+} -+ -+__weak const char *env_ext4_get_dev_part(void) -+{ -+ return (const char *)CONFIG_ENV_EXT4_DEVICE_AND_PART; -+} -+ - #ifdef CONFIG_CMD_SAVEENV - static int env_ext4_save(void) - { -@@ -38,13 +48,14 @@ static int env_ext4_save(void) - disk_partition_t info; - int dev, part; - int err; -+ const char *ifname = env_ext4_get_intf(); -+ const char *dev_and_part = env_ext4_get_dev_part(); - - err = env_export(&env_new); - if (err) - return err; - -- part = blk_get_device_part_str(CONFIG_ENV_EXT4_INTERFACE, -- CONFIG_ENV_EXT4_DEVICE_AND_PART, -+ part = blk_get_device_part_str(ifname, dev_and_part, - &dev_desc, &info, 1); - if (part < 0) - return 1; -@@ -54,8 +65,7 @@ static int env_ext4_save(void) - - if (!ext4fs_mount(info.size)) { - printf("\n** Unable to use %s %s for saveenv **\n", -- CONFIG_ENV_EXT4_INTERFACE, -- CONFIG_ENV_EXT4_DEVICE_AND_PART); -+ ifname, dev_and_part); - return 1; - } - -@@ -65,8 +75,7 @@ static int env_ext4_save(void) - - if (err == -1) { - printf("\n** Unable to write \"%s\" from %s%d:%d **\n", -- CONFIG_ENV_EXT4_FILE, CONFIG_ENV_EXT4_INTERFACE, dev, -- part); -+ CONFIG_ENV_EXT4_FILE, ifname, dev, part); - return 1; - } - -@@ -83,14 +92,15 @@ static int env_ext4_load(void) - int dev, part; - int err; - loff_t off; -+ const char *ifname = env_ext4_get_intf(); -+ const char *dev_and_part = env_ext4_get_dev_part(); - - #ifdef CONFIG_MMC -- if (!strcmp(CONFIG_ENV_EXT4_INTERFACE, "mmc")) -+ if (!strcmp(ifname, "mmc")) - mmc_initialize(NULL); - #endif - -- part = blk_get_device_part_str(CONFIG_ENV_EXT4_INTERFACE, -- CONFIG_ENV_EXT4_DEVICE_AND_PART, -+ part = blk_get_device_part_str(ifname, dev_and_part, - &dev_desc, &info, 1); - if (part < 0) - goto err_env_relocate; -@@ -100,8 +110,7 @@ static int env_ext4_load(void) - - if (!ext4fs_mount(info.size)) { - printf("\n** Unable to use %s %s for loading the env **\n", -- CONFIG_ENV_EXT4_INTERFACE, -- CONFIG_ENV_EXT4_DEVICE_AND_PART); -+ ifname, dev_and_part); - goto err_env_relocate; - } - -@@ -111,8 +120,7 @@ static int env_ext4_load(void) - - if (err == -1) { - printf("\n** Unable to read \"%s\" from %s%d:%d **\n", -- CONFIG_ENV_EXT4_FILE, CONFIG_ENV_EXT4_INTERFACE, dev, -- part); -+ CONFIG_ENV_EXT4_FILE, ifname, dev, part); - goto err_env_relocate; - } - -diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c -index a7f543f..4eb77c3 100644 ---- a/fs/ext4/ext4_write.c -+++ b/fs/ext4/ext4_write.c -@@ -864,6 +864,12 @@ int ext4fs_write(const char *fname, unsigned char *buffer, - printf("error in File System init\n"); - return -1; - } -+ -+ if (le32_to_cpu(fs->sb->feature_ro_compat) & EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) { -+ printf("Unsupported feature metadata_csum found, not writing.\n"); -+ return -1; -+ } -+ - inodes_per_block = fs->blksz / fs->inodesz; - parent_inodeno = ext4fs_get_parent_inode_num(fname, filename, F_FILE); - if (parent_inodeno == -1) -diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h -index b4beaa7..1501845 100644 ---- a/include/configs/stm32mp1.h -+++ b/include/configs/stm32mp1.h -@@ -48,7 +48,19 @@ - /* - * Env parameters - */ --#define CONFIG_ENV_SIZE SZ_4K -+#define CONFIG_ENV_OVERWRITE -+#define CONFIG_ENV_SIZE SZ_8K -+ -+#if defined(CONFIG_ENV_IS_IN_UBI) -+#define CONFIG_ENV_UBI_PART "UBI" -+#define CONFIG_ENV_UBI_VOLUME "uboot_config" -+#define CONFIG_ENV_UBI_VOLUME_REDUND "uboot_config_r" -+#endif -+ -+#if defined(CONFIG_ENV_IS_IN_SPI_FLASH) -+#define CONFIG_ENV_SECT_SIZE SZ_256K -+#define CONFIG_ENV_OFFSET 0x00280000 -+#endif - - /* ATAGs */ - #define CONFIG_CMDLINE_TAG -@@ -90,9 +102,6 @@ - #define CONFIG_SYS_NAND_ONFI_DETECTION - #define CONFIG_SYS_MAX_NAND_DEVICE 1 - --/* SPI nand */ --#define CONFIG_SYS_MAX_NAND_DEVICE 1 -- - /* SPI FLASH support */ - #if defined(CONFIG_SPL_BUILD) - #define CONFIG_SYS_SPI_U_BOOT_OFFS 0x80000 -@@ -130,33 +139,102 @@ - func(MMC, mmc, 2) \ - func(PXE, pxe, na) - --#include -+/* -+ * bootcmd for stm32mp1: -+ * CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" -+ * for serial/usb: execute the stm32prog command -+ * for mmc boot (eMMC, SD card), boot only on the same device -+ * for nand boot, boot with on ubifs partition on nand -+ * for nor boot, use the default order -+ */ -+#define CONFIG_PREBOOT - --#define CONFIG_PREBOOT \ -- "echo \"Boot over ${boot_device}${boot_instance}!\"; " \ -- "if test ${boot_device} = serial; then " \ -- "stm32prog serial ${boot_instance}; " \ -- "else if test ${boot_device} = usb; then " \ -- "stm32prog usb ${boot_instance}; " \ -+#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 " \ -- "if test ${boot_device} = mmc; then " \ -- "env set boot_targets \"mmc${boot_instance}\"; "\ -- "else if test ${boot_device} = nand; then " \ -- "env set boot_targets \"ubifs0\"; "\ -- "fi; fi; fi; fi;" -+ "run env_check;" \ -+ "if test ${boot_device} = mmc;" \ -+ "then env set boot_targets \"mmc${boot_instance}\"; fi;" \ -+ "if test ${boot_device} = nand;" \ -+ "then env set boot_targets ubifs0; fi;" \ -+ "run distro_bootcmd;" \ -+ "fi;\0" -+ -+/* DTIMG command added only for Android distribution */ -+#ifdef CONFIG_CMD_DTIMG -+/* -+ * bootcmd for android on MMC: -+ * CONFIG_BOOTCOMMAND="run bootcmd_android" -+ * overidde DISTRO script "mmc_boot" to boot android on mmc -+ * using system_${suffix} partition (with "_a") by default -+ * - display splash screen -+ * - load device tree form dtimg -+ * - load kernel and set bootargs -+ * - start kernel -+ */ -+ -+#define STM32MP_ANDROID \ -+ "suffix=a\0" \ -+ "dtimg_addr=0xc4500000\0" \ -+ "android_mmc_splash="\ -+ "if part start mmc ${devnum} splash splash_start && " \ -+ "part size mmc ${devnum} splash splash_size;"\ -+ "then " \ -+ "mmc read ${splashimage} ${splash_start} ${splash_size};" \ -+ "cls; bmp display ${splashimage} m m;" \ -+ "fi\0" \ -+ "android_mmc_fdt="\ -+ "if part start mmc ${devnum} dt_${suffix} dt_start &&" \ -+ "part size mmc ${devnum} dt_${suffix} dt_size;"\ -+ "then " \ -+ "mmc read ${dtimg_addr} ${dt_start} ${dt_size};" \ -+ "dtimg getindex ${dtimg_addr} ${board_id} ${board_rev}" \ -+ " dt_index;" \ -+ "dtimg start ${dtimg_addr} ${dt_index} fdt_addr_r;"\ -+ "fi\0" \ -+ "android_mmc_kernel="\ -+ "if part start mmc ${devnum} boot_${suffix} boot_start &&" \ -+ "part size mmc ${devnum} boot_${suffix} boot_size;"\ -+ "then " \ -+ "mmc read ${kernel_addr_r} ${boot_start} ${boot_size};" \ -+ "part nb mmc ${devnum} system_${suffix} rootpart_nb;" \ -+ "env set bootargs" \ -+ "root=/dev/mmcblk${devnum}p${rootpart_nb} " \ -+ "androidboot.serialno=${serial#} " \ -+ "androidboot.slot_suffix=_${suffix};"\ -+ "fi\0" \ -+ "android_mmc_boot="\ -+ "mmc dev ${devnum};"\ -+ "run android_mmc_splash;" \ -+ "run android_mmc_fdt;" \ -+ "run android_mmc_kernel;" \ -+ "bootm ${kernel_addr_r} - ${fdt_addr_r};\0" \ -+ "bootcmd_android=" \ -+ "env set mmc_boot run android_mmc_boot;" \ -+ "run bootcmd_stm32mp\0" -+ -+#else -+#define STM32MP_ANDROID -+#endif/* CONFIG_CMD_DTIMG */ -+ -+#include - - #ifdef CONFIG_STM32MP1_OPTEE - #define CONFIG_SYS_MEM_TOP_HIDE SZ_32M - /* with OPTEE: define specific MTD partitions = teeh, teed, teex */ - #define STM32MP_MTDPARTS \ -- "mtdparts_nor0=256k(fsbl1),256k(fsbl2),2m(ssbl),256k(logo),256k(teeh),256k(teed),256k(teex),-(nor_user)\0" \ -- "mtdparts_nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),512k(teeh),512k(teed),512k(teex),-(UBI);\0" -+ "mtdparts_nor0=256k(fsbl1),256k(fsbl2),2m(ssbl),256k(u-boot-env),256k(teeh),256k(teed),256k(teex),-(nor_user)\0" \ -+ "mtdparts_nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),512k(teeh),512k(teed),512k(teex),-(UBI)\0" \ -+ "mtdparts_spi-nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),512k(teeh),512k(teed),512k(teex),-(UBI)\0" \ - - #else /* CONFIG_STM32MP1_OPTEE */ - - #define STM32MP_MTDPARTS \ -- "mtdparts_nor0=256k(fsbl1),256k(fsbl2),2m(ssbl),256k(logo),-(nor_user)\0" \ -- "mtdparts_nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),-(UBI)\0" -+ "mtdparts_nor0=256k(fsbl1),256k(fsbl2),2m(ssbl),256k(u-boot-env),-(nor_user)\0" \ -+ "mtdparts_nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),-(UBI)\0" \ -+ "mtdparts_spi-nand0=2m(fsbl),2m(ssbl1),2m(ssbl2),-(UBI)\0" - - #endif /* CONFIG_STM32MP1_OPTEE */ - -@@ -181,7 +259,12 @@ - "bootlimit=0\0" \ - "altbootcmd=run bootcmd\0" \ - "usb_pgood_delay=2000\0" \ -+ "env_default=1\0" \ -+ "env_check=if test $env_default -eq 1;"\ -+ " then env set env_default 0;env save;fi\0" \ -+ STM32MP_BOOTCMD \ - STM32MP_MTDPARTS \ -+ STM32MP_ANDROID \ - BOOTENV \ - "boot_net_usb_start=true\0" - -diff --git a/include/dfu.h b/include/dfu.h -index 36304c7..64fdba3 100644 ---- a/include/dfu.h -+++ b/include/dfu.h -@@ -167,6 +167,7 @@ unsigned char *dfu_get_buf(struct dfu_entity *dfu); - unsigned char *dfu_free_buf(void); - unsigned long dfu_get_buf_size(void); - bool dfu_usb_get_reset(void); -+void dfu_initiated_callback(struct dfu_entity *dfu); - - int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num); - int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num); -diff --git a/include/environment.h b/include/environment.h -index 5e90f15..e5d4811 100644 ---- a/include/environment.h -+++ b/include/environment.h -@@ -268,9 +268,18 @@ extern struct hsearch_data env_htab; - /* Function that updates CRC of the enironment */ - void env_crc_update(void); - -+/* allows to set ext4 interface */ -+const char *env_ext4_get_intf(void); -+ -+/* allows to set ext4 device and partition */ -+const char *env_ext4_get_dev_part(void); -+ - /* Look up the variable from the default environment */ - char *env_get_default(const char *name); - -+/* Returns the best env location for a board */ -+enum env_location env_get_location(enum env_operation op, int prio); -+ - /* [re]set to the default environment */ - void set_default_env(const char *s, int flags); - -diff --git a/include/ext4fs.h b/include/ext4fs.h -index bb55639..2421011 100644 ---- a/include/ext4fs.h -+++ b/include/ext4fs.h -@@ -32,6 +32,7 @@ - #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ - #define EXT4_EXT_MAGIC 0xf30a - #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 -+#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400 - #define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 - #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 - #define EXT4_INDIRECT_BLOCKS 12 -diff --git a/include/image-android-dt.h b/include/image-android-dt.h -index 9a3aa8f..f9abe85 100644 ---- a/include/image-android-dt.h -+++ b/include/image-android-dt.h -@@ -17,4 +17,6 @@ bool android_dt_get_fdt_by_index(ulong hdr_addr, u32 index, ulong *addr, - void android_dt_print_contents(ulong hdr_addr); - #endif - -+int android_dt_get_index(ulong hdr_addr, u32 board_id, u32 board_rev); -+ - #endif /* IMAGE_ANDROID_DT_H */ -diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h -index 68e5915..9cb0e43 100644 ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -586,5 +586,6 @@ void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset, - int mtd_search_alternate_name(const char *mtdname, char *altname, - unsigned int max_len); - -+void board_mtdparts_default(const char **mtdids, const char **mtdparts); - #endif - #endif /* __MTD_MTD_H__ */ -diff --git a/include/netdev.h b/include/netdev.h -index 5500162..2b1028c 100644 ---- a/include/netdev.h -+++ b/include/netdev.h -@@ -21,6 +21,8 @@ - */ - - int board_eth_init(bd_t *bis); -+int board_interface_eth_init(int interface_type, bool eth_clk_sel_reg, -+ bool eth_ref_clk_sel_reg); - int cpu_eth_init(bd_t *bis); - - /* Driver initialization prototypes */ -diff --git a/include/spi.h b/include/spi.h -index 938627b..7c8abc0 100644 ---- a/include/spi.h -+++ b/include/spi.h -@@ -503,14 +503,15 @@ int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp, - * device and slave device. - * - * If no such slave exists, and drv_name is not NULL, then a new slave device -- * is automatically bound on this chip select. -+ * is automatically bound on this chip select with requested speed and mode. - * -- * Ths new slave device is probed ready for use with the given speed and mode. -+ * Ths new slave device is probed ready for use with the speed and mode -+ * from platdata, when available, or the requested value. - * - * @busnum: SPI bus number - * @cs: Chip select to look for -- * @speed: SPI speed to use for this slave -- * @mode: SPI mode to use for this slave -+ * @speed: SPI speed to use for this slave when not available in platdata -+ * @mode: SPI mode to use for this slave when not available in platdata - * @drv_name: Name of driver to attach to this chip select - * @dev_name: Name of the new device thus created - * @busp: Returns bus device -diff --git a/include/usb/dwc2_udc.h b/include/usb/dwc2_udc.h -index 3bd05fa..a0f7103 100644 ---- a/include/usb/dwc2_udc.h -+++ b/include/usb/dwc2_udc.h -@@ -10,6 +10,10 @@ - - #define PHY0_SLEEP (1 << 5) - -+#define DWC2_MAX_HW_ENDPOINTS 16 -+#define DWC2_SIZE_NB_OFFS 0 -+#define DWC2_SIZE_OFFS 1 -+ - struct dwc2_plat_otg_data { - void *priv; - int phy_of_node; -@@ -23,6 +27,8 @@ struct dwc2_plat_otg_data { - unsigned int rx_fifo_sz; - unsigned int np_tx_fifo_sz; - unsigned int tx_fifo_sz; -+ /* [0] number of element, [1..17] tx_fifo_sz (max 16 endpoints)*/ -+ unsigned int tx_fifo_sz_array[DWC2_MAX_HW_ENDPOINTS + 1]; - }; - - int dwc2_udc_probe(struct dwc2_plat_otg_data *pdata); -diff --git a/test/py/tests/test_pinmux.py b/test/py/tests/test_pinmux.py -index f04a279..25394f1 100644 ---- a/test/py/tests/test_pinmux.py -+++ b/test/py/tests/test_pinmux.py -@@ -18,6 +18,7 @@ def test_pinmux_usage_2(u_boot_console): - assert 'Usage:' in output - - @pytest.mark.buildconfigspec('cmd_pinmux') -+@pytest.mark.boardspec('sandbox') - def test_pinmux_status_all(u_boot_console): - """Test that 'pinmux status -a' displays pin's muxing.""" - output = u_boot_console.run_command('pinmux status -a') -@@ -28,6 +29,7 @@ def test_pinmux_status_all(u_boot_console): - assert ('W1 : 1-wire gpio' in output) - - @pytest.mark.buildconfigspec('cmd_pinmux') -+@pytest.mark.boardspec('sandbox') - def test_pinmux_list(u_boot_console): - """Test that 'pinmux list' returns the pin-controller list.""" - output = u_boot_console.run_command('pinmux list') -@@ -43,6 +45,7 @@ def test_pinmux_dev_bad(u_boot_console): - assert (expected_output in output) - - @pytest.mark.buildconfigspec('cmd_pinmux') -+@pytest.mark.boardspec('sandbox') - def test_pinmux_dev(u_boot_console): - """Test that 'pinmux dev' select the wanted pin controller.""" - pincontroller = 'pinctrl' -@@ -51,6 +54,7 @@ def test_pinmux_dev(u_boot_console): - assert (expected_output in output) - - @pytest.mark.buildconfigspec('cmd_pinmux') -+@pytest.mark.boardspec('sandbox') - def test_pinmux_status(u_boot_console): - """Test that 'pinmux status' displays selected pincontroller's pin - muxing descriptions.""" --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0014-ARM-v2018.11-stm32mp-r4-MACHINE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0014-ARM-v2018.11-stm32mp-r4-MACHINE.patch deleted file mode 100644 index 3fe26e6..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0014-ARM-v2018.11-stm32mp-r4-MACHINE.patch +++ /dev/null @@ -1,494 +0,0 @@ -From 19120ee9047a8e592c8a82d12a8482ef944f0dda Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Thu, 30 Jan 2020 14:55:56 +0100 -Subject: [PATCH 14/17] ARM v2018.11 stm32mp r4 MACHINE - ---- - arch/arm/mach-stm32mp/Makefile | 3 +- - arch/arm/mach-stm32mp/bsec.c | 4 +- - arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 82 ++++++++++++++----------- - arch/arm/mach-stm32mp/cpu.c | 21 +++++++ - arch/arm/mach-stm32mp/include/mach/ddr.h | 6 +- - arch/arm/mach-stm32mp/include/mach/stm32.h | 1 + - arch/arm/mach-stm32mp/include/mach/sys_proto.h | 13 +++- - arch/arm/mach-stm32mp/spl.c | 41 ++++++++----- - arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S | 5 +- - 9 files changed, 116 insertions(+), 60 deletions(-) - -diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile -index 9158a20..13e7773 100644 ---- a/arch/arm/mach-stm32mp/Makefile -+++ b/arch/arm/mach-stm32mp/Makefile -@@ -6,6 +6,7 @@ - obj-y += cpu.o - obj-y += dram_init.o - obj-y += syscon.o -+obj-y += bsec.o - - ifdef CONFIG_SPL_BUILD - obj-y += spl.o -@@ -13,8 +14,6 @@ obj-$(CONFIG_STM32MP1_RESET_HALT_WORKAROUND) += stm32mp1_helper_dbg.o - else - obj-$(CONFIG_CMD_STM32PROG) += cmd_stm32prog/ - obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o -- --obj-y += bsec.o - obj-$(CONFIG_SYSRESET) += cmd_poweroff.o - obj-$(CONFIG_ARMV7_PSCI) += psci.o - endif -diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c -index 5256378..fa7f39f 100644 ---- a/arch/arm/mach-stm32mp/bsec.c -+++ b/arch/arm/mach-stm32mp/bsec.c -@@ -436,7 +436,7 @@ static int stm32mp_bsec_ofdata_to_platdata(struct udevice *dev) - return 0; - } - --#ifndef CONFIG_STM32MP1_TRUSTED -+#if !defined(CONFIG_STM32MP1_TRUSTED) && !defined(CONFIG_SPL_BUILD) - static int stm32mp_bsec_probe(struct udevice *dev) - { - int otp; -@@ -463,7 +463,7 @@ U_BOOT_DRIVER(stm32mp_bsec) = { - .ofdata_to_platdata = stm32mp_bsec_ofdata_to_platdata, - .platdata_auto_alloc_size = sizeof(struct stm32mp_bsec_platdata), - .ops = &stm32mp_bsec_ops, --#ifndef CONFIG_STM32MP1_TRUSTED -+#if !defined(CONFIG_STM32MP1_TRUSTED) && !defined(CONFIG_SPL_BUILD) - .probe = stm32mp_bsec_probe, - #endif - }; -diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c -index 8325b56..c6d8f14 100644 ---- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c -+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c -@@ -63,7 +63,7 @@ static const efi_guid_t uuid_mmc[3] = { - }; - - DECLARE_GLOBAL_DATA_PTR; --#define ENV_BUF_LEN SZ_1K -+#define ALT_BUF_LEN SZ_1K - - /* order of column in flash layout file */ - enum stm32prog_col_t { -@@ -842,8 +842,8 @@ static int treat_partition_list(struct stm32prog_data *data) - static int create_partitions(struct stm32prog_data *data) - { - int offset = 0; -- char cmdbuf[32]; -- char buf[ENV_BUF_LEN]; -+ const int buflen = SZ_8K; -+ char *buf; - char uuid[UUID_STR_LEN + 1]; - unsigned char *uuid_bin; - unsigned int mmc_id; -@@ -851,6 +851,10 @@ static int create_partitions(struct stm32prog_data *data) - bool rootfs_found; - struct stm32prog_part_t *part; - -+ buf = malloc(buflen); -+ if (!buf) -+ return -ENOMEM; -+ - puts("partitions : "); - /* initialize the selected device */ - for (i = 0; i < data->dev_nb; i++) { -@@ -860,7 +864,7 @@ static int create_partitions(struct stm32prog_data *data) - - offset = 0; - rootfs_found = false; -- memset(buf, 0, sizeof(buf)); -+ memset(buf, 0, buflen); - - list_for_each_entry(part, &data->dev[i].part_list, list) { - /* skip eMMC boot partitions */ -@@ -871,7 +875,17 @@ static int create_partitions(struct stm32prog_data *data) - if (part->part_type == RAW_IMAGE) - continue; - -- offset += snprintf(buf + offset, ENV_BUF_LEN - offset, -+ if (offset + 100 > buflen) { -+ pr_debug("\n%s: buffer too small, %s skippped", -+ __func__, part->name); -+ continue; -+ } -+ -+ if (!offset) -+ offset += sprintf(buf, "gpt write mmc %d \"", -+ data->dev[i].dev_id); -+ -+ offset += snprintf(buf + offset, buflen - offset, - "name=%s,start=0x%llx,size=0x%llx", - part->name, - part->addr, -@@ -879,17 +893,17 @@ static int create_partitions(struct stm32prog_data *data) - - if (part->part_type == PART_BINARY) - offset += snprintf(buf + offset, -- ENV_BUF_LEN - offset, -+ buflen - offset, - ",type=" - LINUX_RESERVED_UUID); - else - offset += snprintf(buf + offset, -- ENV_BUF_LEN - offset, -+ buflen - offset, - ",type=linux"); - - if (part->part_type == PART_SYSTEM) - offset += snprintf(buf + offset, -- ENV_BUF_LEN - offset, -+ buflen - offset, - ",bootable"); - - if (!rootfs_found && !strcmp(part->name, "rootfs")) { -@@ -901,23 +915,21 @@ static int create_partitions(struct stm32prog_data *data) - uuid_bin_to_str(uuid_bin, uuid, - UUID_STR_FORMAT_GUID); - offset += snprintf(buf + offset, -- ENV_BUF_LEN - offset, -+ buflen - offset, - ",uuid=%s", uuid); - } - } - -- offset += snprintf(buf + offset, -- ENV_BUF_LEN - offset, -- ";"); -+ offset += snprintf(buf + offset, buflen - offset, ";"); - } - - if (offset) { -- sprintf(cmdbuf, "gpt write mmc %d \"%s\"", -- data->dev[i].dev_id, buf); -- pr_debug("cmd: %s\n", cmdbuf); -- if (run_command(cmdbuf, 0)) { -- stm32prog_err("partitionning fail : %s", -- cmdbuf); -+ offset += snprintf(buf + offset, buflen - offset, "\""); -+ pr_debug("\ncmd: %s\n", buf); -+ if (run_command(buf, 0)) { -+ stm32prog_err("partitionning fail : %s", buf); -+ free(buf); -+ - return -1; - } - } -@@ -926,21 +938,21 @@ static int create_partitions(struct stm32prog_data *data) - part_init(data->dev[i].block_dev); - - #ifdef DEBUG -- sprintf(cmdbuf, "gpt verify mmc %d", -- data->dev[i].dev_id); -- pr_debug("cmd: %s ", cmdbuf); -- if (run_command(cmdbuf, 0)) -+ sprintf(buf, "gpt verify mmc %d", data->dev[i].dev_id); -+ pr_debug("\ncmd: %s", buf); -+ if (run_command(buf, 0)) - printf("fail !\n"); - else - printf("OK\n"); - - /* TEMP : for debug, display partition */ -- sprintf(cmdbuf, "part list mmc %d", -- data->dev[i].dev_id); -- run_command(cmdbuf, 0); -+ sprintf(buf, "part list mmc %d", data->dev[i].dev_id); -+ run_command(buf, 0); - #endif - } - puts("done\n"); -+ free(buf); -+ - return 0; - } - -@@ -952,7 +964,7 @@ static int stm32prog_alt_add(struct stm32prog_data *data, - int offset = 0; - char devstr[4]; - char dfustr[10]; -- char buf[ENV_BUF_LEN]; -+ char buf[ALT_BUF_LEN]; - u32 size; - char multiplier, type; - -@@ -973,7 +985,7 @@ static int stm32prog_alt_add(struct stm32prog_data *data, - type = 'a';/*Readable*/ - - memset(buf, 0, sizeof(buf)); -- offset = snprintf(buf, ENV_BUF_LEN - offset, -+ offset = snprintf(buf, ALT_BUF_LEN - offset, - "@%s/0x%02x/1*%d%c%c ", - part->name, part->id, - size, multiplier, type); -@@ -985,29 +997,29 @@ static int stm32prog_alt_add(struct stm32prog_data *data, - dfu_size = part->size / part->dev->lba_blk_size; - else - dfu_size = part->size; -- offset += snprintf(buf + offset, ENV_BUF_LEN - offset, -+ offset += snprintf(buf + offset, ALT_BUF_LEN - offset, - "raw 0x0 0x%llx", dfu_size); - } else if (part->part_id < 0) { - u64 nb_blk = part->size / part->dev->lba_blk_size; - - /* lba_blk_size, mmc->read_bl_len */ -- offset += snprintf(buf + offset, ENV_BUF_LEN - offset, -+ offset += snprintf(buf + offset, ALT_BUF_LEN - offset, - "raw 0x%llx 0x%llx", - part->addr, nb_blk); -- offset += snprintf(buf + offset, ENV_BUF_LEN - offset, -+ offset += snprintf(buf + offset, ALT_BUF_LEN - offset, - " mmcpart %d;", -(part->part_id)); - } else { - if (part->part_type == PART_SYSTEM && - (part->dev_type == DFU_DEV_NAND || - part->dev_type == DFU_DEV_SF)) - offset += snprintf(buf + offset, -- ENV_BUF_LEN - offset, -+ ALT_BUF_LEN - offset, - "partubi"); - else - offset += snprintf(buf + offset, -- ENV_BUF_LEN - offset, -+ ALT_BUF_LEN - offset, - "part"); -- offset += snprintf(buf + offset, ENV_BUF_LEN - offset, -+ offset += snprintf(buf + offset, ALT_BUF_LEN - offset, - " %d %d;", - part->dev_id, - part->part_id); -@@ -1041,7 +1053,7 @@ static int stm32prog_alt_add_virt(struct dfu_entity *dfu, - { - int ret = 0; - char devstr[4]; -- char buf[ENV_BUF_LEN]; -+ char buf[ALT_BUF_LEN]; - - sprintf(devstr, "%d", phase); - sprintf(buf, "@%s/0x%02x/1*%dBe", name, phase, size); -@@ -1100,7 +1112,7 @@ static int dfu_init_entities(struct stm32prog_data *data) - ret = stm32prog_alt_add(data, dfu, part); - } - } else { -- char buf[ENV_BUF_LEN]; -+ char buf[ALT_BUF_LEN]; - - sprintf(buf, "@FlashLayout/0x%02x/1*256Ke ram %x 40000", - PHASE_FLASHLAYOUT, STM32_DDR_BASE); -diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c -index efe8b79..5d43f0b 100644 ---- a/arch/arm/mach-stm32mp/cpu.c -+++ b/arch/arm/mach-stm32mp/cpu.c -@@ -291,18 +291,36 @@ int print_cpuinfo(void) - - /* MPUs Part Numbers */ - switch (get_cpu_type()) { -+ case CPU_STM32MP157Fxx: -+ cpu_s = "157F"; -+ break; -+ case CPU_STM32MP157Dxx: -+ cpu_s = "157D"; -+ break; - case CPU_STM32MP157Cxx: - cpu_s = "157C"; - break; - case CPU_STM32MP157Axx: - cpu_s = "157A"; - break; -+ case CPU_STM32MP153Fxx: -+ cpu_s = "153F"; -+ break; -+ case CPU_STM32MP153Dxx: -+ cpu_s = "153D"; -+ break; - case CPU_STM32MP153Cxx: - cpu_s = "153C"; - break; - case CPU_STM32MP153Axx: - cpu_s = "153A"; - break; -+ case CPU_STM32MP151Fxx: -+ cpu_s = "151F"; -+ break; -+ case CPU_STM32MP151Dxx: -+ cpu_s = "151D"; -+ break; - case CPU_STM32MP151Cxx: - cpu_s = "151C"; - break; -@@ -341,6 +359,9 @@ int print_cpuinfo(void) - case CPU_REVB: - cpu_r = "B"; - break; -+ case CPU_REVZ: -+ cpu_r = "Z"; -+ break; - default: - cpu_r = "?"; - break; -diff --git a/arch/arm/mach-stm32mp/include/mach/ddr.h b/arch/arm/mach-stm32mp/include/mach/ddr.h -index b8a17cf..bfc42a7 100644 ---- a/arch/arm/mach-stm32mp/include/mach/ddr.h -+++ b/arch/arm/mach-stm32mp/include/mach/ddr.h -@@ -9,8 +9,10 @@ - /* DDR power initializations */ - enum ddr_type { - STM32MP_DDR3, -- STM32MP_LPDDR2, -- STM32MP_LPDDR3, -+ STM32MP_LPDDR2_16, -+ STM32MP_LPDDR2_32, -+ STM32MP_LPDDR3_16, -+ STM32MP_LPDDR3_32, - }; - - int board_ddr_power_init(enum ddr_type ddr_type); -diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h -index 5283e90..70fb235 100644 ---- a/arch/arm/mach-stm32mp/include/mach/stm32.h -+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h -@@ -96,6 +96,7 @@ enum boot_device { - #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_BOOT_CONTEXT TAMP_BACKUP_REGISTER(20) - #define TAMP_BOOTCOUNT TAMP_BACKUP_REGISTER(21) - -diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h -index 871324b..0ede1e7 100644 ---- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h -+++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h -@@ -3,19 +3,26 @@ - * Copyright (C) 2015-2017, STMicroelectronics - All Rights Reserved - */ - --/* ID = Device Version (bit31:16) + Device Part Number (RPN) (bit15:0)*/ -+/* ID = Device Version (bit31:16) + Device Part Number (RPN) (bit7:0) */ - #define CPU_STM32MP157Cxx 0x05000000 - #define CPU_STM32MP157Axx 0x05000001 - #define CPU_STM32MP153Cxx 0x05000024 - #define CPU_STM32MP153Axx 0x05000025 - #define CPU_STM32MP151Cxx 0x0500002E - #define CPU_STM32MP151Axx 0x0500002F -+#define CPU_STM32MP157Fxx 0x05000080 -+#define CPU_STM32MP157Dxx 0x05000081 -+#define CPU_STM32MP153Fxx 0x050000A4 -+#define CPU_STM32MP153Dxx 0x050000A5 -+#define CPU_STM32MP151Fxx 0x050000AE -+#define CPU_STM32MP151Dxx 0x050000AF - - /* return CPU_STMP32MP...Xxx constants */ - u32 get_cpu_type(void); - - #define CPU_REVA 0x1000 - #define CPU_REVB 0x2000 -+#define CPU_REVZ 0x2001 - - /* return CPU_REV constants */ - u32 get_cpu_rev(void); -@@ -32,3 +39,7 @@ u32 get_cpu_package(void); - u32 get_bootmode(void); - /* start IWDG watchdog */ - int watchdog_start(void); -+ -+/* board power management : configure vddcore according OPP */ -+void board_vddcore_init(u32 voltage_mv); -+int board_vddcore_set(void); -diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c -index 6c8744f..74b56f9 100644 ---- a/arch/arm/mach-stm32mp/spl.c -+++ b/arch/arm/mach-stm32mp/spl.c -@@ -85,42 +85,49 @@ void spl_display_print(void) - } - #endif - -+__weak int board_vddcore_set(void) -+{ -+ return 0; -+} -+ - void board_init_f(ulong dummy) - { - struct udevice *dev; -- int ret; -+ int ret, clk, reset, pinctrl, power; - - arch_cpu_init(); - - ret = spl_early_init(); - if (ret) { -- debug("spl_early_init() failed: %d\n", ret); -+ debug("%s: spl_early_init() failed: %d\n", __func__, ret); - hang(); - } - -- ret = uclass_get_device(UCLASS_CLK, 0, &dev); -- if (ret) { -- debug("Clock init failed: %d\n", ret); -- return; -- } -+ clk = uclass_get_device(UCLASS_CLK, 0, &dev); -+ if (clk) -+ debug("%s: Clock init failed: %d\n", __func__, clk); - -- ret = uclass_get_device(UCLASS_RESET, 0, &dev); -- if (ret) { -- debug("Reset init failed: %d\n", ret); -- return; -- } -+ reset = uclass_get_device(UCLASS_RESET, 0, &dev); -+ if (reset) -+ debug("%s: Reset init failed: %d\n", __func__, reset); - -- ret = uclass_get_device(UCLASS_PINCTRL, 0, &dev); -- if (ret) { -- debug("%s: Cannot find pinctrl device\n", __func__); -- return; -- } -+ pinctrl = uclass_get_device(UCLASS_PINCTRL, 0, &dev); -+ if (pinctrl) -+ debug("%s: Cannot find pinctrl device: %d\n", -+ __func__, pinctrl); - - /* enable console uart printing */ - preloader_console_init(); - - watchdog_start(); - -+ /* change vddcore if needed after clock tree init */ -+ power = board_vddcore_set(); -+ -+ if (clk || reset || pinctrl || power) -+ printf("%s: probe failed clk=%d reset=%d pinctrl=%d power=%d\n", -+ __func__, clk, reset, pinctrl, power); -+ - ret = uclass_get_device(UCLASS_RAM, 0, &dev); - if (ret) { - printf("DRAM init failed: %d\n", ret); -diff --git a/arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S b/arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S -index 37a1b06..d17a37a 100644 ---- a/arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S -+++ b/arch/arm/mach-stm32mp/stm32mp1_helper_dbg.S -@@ -10,6 +10,9 @@ - * fixes the limitation. Anyway, this source code identifies the Soc revision - * and is only executed if it corresponds, so it can be kept on other - * revisions without any consequence. -+ * The revisions that need the workaround have ID values: -+ * - 0x2000X500 -+ * - 0x2001X500 - ****************************************************************************/ - - #include -@@ -30,7 +33,7 @@ - #define PWR_CR1_DBP BIT(8) - - #define DBGMCU_IDC_ADDR 0x50081000 --#define DBGMCU_IDC_MASK 0xFFFF0FFF -+#define DBGMCU_IDC_MASK 0xFFFE0FFF - #define DBGMCU_IDC_VALUE 0x20000500 - - #define TAMP_BKP_REGISTER_20 (0x5C00A100 + (20 << 2)) --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0015-ARM-v2018.11-stm32mp-r4-BOARD.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0015-ARM-v2018.11-stm32mp-r4-BOARD.patch deleted file mode 100644 index 5f8eb7b..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0015-ARM-v2018.11-stm32mp-r4-BOARD.patch +++ /dev/null @@ -1,255 +0,0 @@ -From 74c58d9ed7af723b31a4f9d3725afcce9fde1ca4 Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Thu, 30 Jan 2020 14:56:24 +0100 -Subject: [PATCH 15/17] ARM v2018.11 stm32mp r4 BOARD - ---- - board/st/stm32mp1/Kconfig | 4 ++++ - board/st/stm32mp1/README | 21 ++++++++++++++-- - board/st/stm32mp1/board.c | 57 ++++++++++++++++++++++++++++++++++++++++---- - board/st/stm32mp1/stm32mp1.c | 36 +++++++++++++--------------- - 4 files changed, 92 insertions(+), 26 deletions(-) - -diff --git a/board/st/stm32mp1/Kconfig b/board/st/stm32mp1/Kconfig -index 92d8f90..6a06e5b 100644 ---- a/board/st/stm32mp1/Kconfig -+++ b/board/st/stm32mp1/Kconfig -@@ -16,4 +16,8 @@ config CMD_STBOARD - This compile the stboard command to - read and write the board in the OTP. - -+config TARGET_STM32MP157C_DK2 -+ bool "support of STMicroelectronics STM32MP157C-DK2 Discovery Board" -+ default y -+ - endif -diff --git a/board/st/stm32mp1/README b/board/st/stm32mp1/README -index b710602..782b9d18 100644 ---- a/board/st/stm32mp1/README -+++ b/board/st/stm32mp1/README -@@ -305,7 +305,20 @@ Mac id storage and retrieval in stm32mp otp : - To program a MAC address on virgin OTP words above, you can use the fuse command - on bank 0 to access to internal OTP: - -- example to set mac address "12:34:56:78:9a:bc" -+ Prerequisite: check if a MAC address isn't yet programmed in OTP -+ -+ 1- check OTP: their value must be equal to 0 -+ -+ STM32MP> fuse sense 0 57 2 -+ Sensing bank 0: -+ Word 0x00000039: 00000000 00000000 -+ -+ 2- check environment variable -+ -+ STM32MP> env print ethaddr -+ ## Error: "ethaddr" not defined -+ -+ Example to set mac address "12:34:56:78:9a:bc" - - 1- Write OTP - STM32MP> fuse prog -y 0 57 0x78563412 0x0000bc9a -@@ -319,9 +332,13 @@ on bank 0 to access to internal OTP: - ### Setting environment from OTP MAC address = "12:34:56:78:9a:bc" - - 4 check env update -- STM32MP> print ethaddr -+ STM32MP> env print ethaddr - ethaddr=12:34:56:78:9a:bc - -+warning:: This MAC address provisioning can't be executed twice on the same -+ board as the OTP are protected. It is already done for the board -+ provided by STMicroelectronics. -+ - 10. Coprocessor firmware - ======================== - -diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c -index c3d832f..3e38aef 100644 ---- a/board/st/stm32mp1/board.c -+++ b/board/st/stm32mp1/board.c -@@ -38,11 +38,46 @@ void board_debug_uart_init(void) - #endif - - #ifdef CONFIG_PMIC_STPMIC1 -+u32 opp_voltage_mv; -+ -+void board_vddcore_init(u32 voltage_mv) -+{ -+ opp_voltage_mv = voltage_mv; -+} -+ -+int board_vddcore_set(void) -+{ -+ struct udevice *dev; -+ int ret; -+ u32 value; -+ -+ if (!opp_voltage_mv) -+ return 0; -+ -+ ret = uclass_get_device_by_driver(UCLASS_PMIC, -+ DM_GET_DRIVER(pmic_stpmic1), &dev); -+ if (ret) -+ return ret; -+ -+ /* VDDCORE= STMPCI1 BUCK1 ramp=+25mV, 5 => 725mV, 36 => 1500mV */ -+ value = ((opp_voltage_mv - 725) / 25) + 5; -+ if (value < 5) -+ value = 5; -+ if (value > 36) -+ value = 36; -+ -+ return pmic_clrsetbits(dev, -+ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK1), -+ STPMIC1_BUCK_VOUT_MASK, -+ STPMIC1_BUCK_VOUT(value)); -+} -+ - int board_ddr_power_init(enum ddr_type ddr_type) - { - struct udevice *dev; - bool buck3_at_1800000v = false; - int ret; -+ u32 buck2; - - ret = uclass_get_device_by_driver(UCLASS_PMIC, - DM_GET_DRIVER(pmic_stpmic1), &dev); -@@ -102,8 +137,10 @@ int board_ddr_power_init(enum ddr_type ddr_type) - - break; - -- case STM32MP_LPDDR2: -- case STM32MP_LPDDR3: -+ case STM32MP_LPDDR2_16: -+ case STM32MP_LPDDR2_32: -+ case STM32MP_LPDDR3_16: -+ case STM32MP_LPDDR3_32: - /* - * configure VDD_DDR1 = LDO3 - * Set LDO3 to 1.8V -@@ -133,11 +170,23 @@ int board_ddr_power_init(enum ddr_type ddr_type) - if (ret < 0) - return ret; - -- /* VDD_DDR2 : Set BUCK2 to 1.2V */ -+ /* VDD_DDR2 : Set BUCK2 to 1.2V (16bits) or 1.25V (32 bits)*/ -+ switch (ddr_type) { -+ case STM32MP_LPDDR2_32: -+ case STM32MP_LPDDR3_32: -+ buck2 = STPMIC1_BUCK2_1250000V; -+ break; -+ default: -+ case STM32MP_LPDDR2_16: -+ case STM32MP_LPDDR3_16: -+ buck2 = STPMIC1_BUCK2_1200000V; -+ break; -+ } -+ - ret = pmic_clrsetbits(dev, - STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), - STPMIC1_BUCK_VOUT_MASK, -- STPMIC1_BUCK2_1200000V); -+ buck2); - if (ret < 0) - return ret; - -diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c -index f852b1e..822b6d7 100644 ---- a/board/st/stm32mp1/stm32mp1.c -+++ b/board/st/stm32mp1/stm32mp1.c -@@ -388,10 +388,15 @@ int g_dnl_board_usb_cable_connected(void) - } - - #define STM32MP1_G_DNL_DFU_PRODUCT_NUM 0xdf11 -+#define STM32MP1_G_DNL_FASTBOOT_PRODUCT_NUM 0x0afb -+ - int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name) - { - if (!strcmp(name, "usb_dnl_dfu")) - put_unaligned(STM32MP1_G_DNL_DFU_PRODUCT_NUM, &dev->idProduct); -+ else if (!strcmp(name, "usb_dnl_fastboot")) -+ put_unaligned(STM32MP1_G_DNL_FASTBOOT_PRODUCT_NUM, -+ &dev->idProduct); - else - put_unaligned(CONFIG_USB_GADGET_PRODUCT_NUM, &dev->idProduct); - -@@ -517,6 +522,7 @@ static void __maybe_unused led_error_blink(u32 nb_blink) - mdelay(125); - WATCHDOG_RESET(); - } -+ led_set_state(led, LEDST_ON); - } - #endif - -@@ -876,7 +882,8 @@ const char *env_ext4_get_dev_part(void) - - static __maybe_unused bool board_is_dk2(void) - { -- if (of_machine_is_compatible("st,stm32mp157c-dk2")) -+ if (CONFIG_IS_ENABLED(TARGET_STM32MP157C_DK2) && -+ of_machine_is_compatible("st,stm32mp157c-dk2")) - return true; - - return false; -@@ -1079,9 +1086,7 @@ void board_mtdparts_default(const char **mtdids, const char **mtdparts) - #if defined(CONFIG_OF_BOARD_SETUP) - int ft_board_setup(void *blob, bd_t *bd) - { -- ulong copro_rsc_addr, copro_rsc_size; - int off; -- char *s_copro = NULL; - #ifdef CONFIG_FDT_FIXUP_PARTITIONS - struct node_info nodes[] = { - { "st,stm32f469-qspi", MTD_DEV_TYPE_NOR, }, -@@ -1093,20 +1098,11 @@ int ft_board_setup(void *blob, bd_t *bd) - /* Update DT if coprocessor started */ - off = fdt_path_offset(blob, "/m4"); - if (off > 0) { -- s_copro = env_get("copro_state"); -- copro_rsc_addr = env_get_hex("copro_rsc_addr", 0); -- copro_rsc_size = env_get_hex("copro_rsc_size", 0); -- -- if (s_copro) { -+ if (env_get("copro_state")) { - fdt_setprop_empty(blob, off, "early-booted"); -- if (copro_rsc_addr) -- fdt_setprop_u32(blob, off, "rsc-address", -- copro_rsc_addr); -- if (copro_rsc_size) -- fdt_setprop_u32(blob, off, "rsc-size", -- copro_rsc_size); - } else { - fdt_delprop(blob, off, "early-booted"); -+ writel(0, TAMP_COPRO_RSC_TBL_ADDRESS); - } - } - -@@ -1128,18 +1124,18 @@ static void board_stm32copro_image_process(ulong fw_image, size_t fw_size) - } - - ret = rproc_load_rsc_table(id, fw_image, fw_size, &rsc_addr, &rsc_size); -- if (!ret) { -- env_set_hex("copro_rsc_addr", rsc_addr); -- env_set_hex("copro_rsc_size", rsc_size); -- } -+ if (ret && ret != -ENODATA) -+ return; - - ret = rproc_load(id, fw_image, fw_size); - printf("Load Remote Processor %d with data@addr=0x%08lx %u bytes:%s\n", - id, fw_image, fw_size, ret ? " Failed!" : " Success!"); - - if (!ret) { -- rproc_start(id); -- env_set("copro_state", "booted"); -+ ret = rproc_start(id); -+ printf("Start firmware:%s\n", ret ? " Failed!" : " Success!"); -+ if (!ret) -+ env_set("copro_state", "booted"); - } - } - --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0016-ARM-v2018.11-stm32mp-r4-DEVICETREE.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0016-ARM-v2018.11-stm32mp-r4-DEVICETREE.patch deleted file mode 100644 index bc0c041..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0016-ARM-v2018.11-stm32mp-r4-DEVICETREE.patch +++ /dev/null @@ -1,1191 +0,0 @@ -From 6220cbc776b6bfb9d88646eb98dc4f928e05374b Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Thu, 30 Jan 2020 14:57:26 +0100 -Subject: [PATCH 16/17] ARM v2018.11 stm32mp r4 DEVICETREE - ---- - arch/arm/dts/stm32mp157-u-boot.dtsi | 12 +- - arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi | 7 - - arch/arm/dts/stm32mp157a-dk1.dts | 33 +- - arch/arm/dts/stm32mp157c-dk2.dts | 4 +- - arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi | 7 - - arch/arm/dts/stm32mp157c-ed1.dts | 25 +- - arch/arm/dts/stm32mp157c-ev1.dts | 8 +- - arch/arm/dts/stm32mp157c-m4-srm.dtsi | 525 +++++++++++++++++++++++++ - arch/arm/dts/stm32mp157c.dtsi | 109 +++-- - doc/device-tree-bindings/clock/st,stm32mp1.txt | 4 + - include/dt-bindings/mfd/st,stpmic1.h | 4 + - include/dt-bindings/pinctrl/stm32-pinfunc.h | 1 + - 12 files changed, 673 insertions(+), 66 deletions(-) - -diff --git a/arch/arm/dts/stm32mp157-u-boot.dtsi b/arch/arm/dts/stm32mp157-u-boot.dtsi -index 98cf1aa..1c1a7cc 100644 ---- a/arch/arm/dts/stm32mp157-u-boot.dtsi -+++ b/arch/arm/dts/stm32mp157-u-boot.dtsi -@@ -47,7 +47,7 @@ - }; - - &bsec { -- u-boot,dm-pre-proper; -+ u-boot,dm-pre-reloc; - }; - - &clk_csi { -@@ -70,6 +70,16 @@ - u-boot,dm-pre-reloc; - }; - -+&cpu0_opp_table { -+ u-boot,dm-spl; -+ opp-650000000 { -+ u-boot,dm-spl; -+ }; -+ opp-800000000 { -+ u-boot,dm-spl; -+ }; -+}; -+ - &gpioa { - u-boot,dm-pre-reloc; - }; -diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi -index 757df24..7bc2b7f 100644 ---- a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi -+++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi -@@ -121,13 +121,6 @@ - CLK_LPTIM45_LSE - >; - -- /* VCO = 1300.0 MHz => P = 650 (CPU) */ -- pll1: st,pll@0 { -- cfg = < 2 80 0 0 0 PQR(1,0,0) >; -- frac = < 0x800 >; -- u-boot,dm-pre-reloc; -- }; -- - /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ - pll2: st,pll@1 { - cfg = < 2 65 1 0 0 PQR(1,1,1) >; -diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts -index 2b01a01..9ec45de 100644 ---- a/arch/arm/dts/stm32mp157a-dk1.dts -+++ b/arch/arm/dts/stm32mp157a-dk1.dts -@@ -7,8 +7,8 @@ - /dts-v1/; - - #include "stm32mp157c.dtsi" --#include "stm32mp157c-m4-srm.dtsi" - #include "stm32mp157cac-pinctrl.dtsi" -+#include "stm32mp157c-m4-srm.dtsi" - #include - #include - -@@ -162,6 +162,14 @@ - status = "okay"; - }; - -+&cpu0{ -+ cpu-supply = <&vddcore>; -+}; -+ -+&cpu1{ -+ cpu-supply = <&vddcore>; -+}; -+ - &dma1 { - sram = <&dma_pool>; - }; -@@ -252,9 +260,6 @@ - reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>; - interrupts = <1 IRQ_TYPE_EDGE_FALLING>; - interrupt-parent = <&gpiog>; -- pinctrl-names = "default", "sleep"; -- pinctrl-0 = <<dc_pins_a>; -- pinctrl-1 = <<dc_pins_sleep_a>; - status = "okay"; - - ports { -@@ -284,6 +289,7 @@ - pinctrl-1 = <&i2c4_pins_sleep_a>; - i2c-scl-rising-time-ns = <185>; - i2c-scl-falling-time-ns = <20>; -+ clock-frequency = <400000>; - status = "okay"; - /delete-property/dmas; - /delete-property/dma-names; -@@ -312,10 +318,7 @@ - interrupt-controller; - #interrupt-cells = <2>; - status = "okay"; -- -- st,main-control-register = <0x04>; -- st,vin-control-register = <0xc0>; -- st,usb-control-register = <0x20>; -+ wakeup-source; - - regulators { - compatible = "st,stpmic1-regulators"; -@@ -427,20 +430,20 @@ - vbus_otg: pwr_sw1 { - regulator-name = "vbus_otg"; - interrupts = ; -- regulator-active-discharge; - }; - - vbus_sw: pwr_sw2 { - regulator-name = "vbus_sw"; - interrupts = ; -- regulator-active-discharge; -+ regulator-active-discharge = <1>; - }; - }; - - onkey { - compatible = "st,stpmic1-onkey"; -- interrupts = , ; -+ interrupts = , ; - interrupt-names = "onkey-falling", "onkey-rising"; -+ power-off-time-sec = <10>; - status = "okay"; - }; - -@@ -487,6 +490,9 @@ - }; - - <dc { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <<dc_pins_a>; -+ pinctrl-1 = <<dc_pins_sleep_a>; - status = "okay"; - - port { -@@ -703,6 +709,8 @@ - pinctrl-1 = <&uart4_sleep_pins_a>; - pinctrl-2 = <&uart4_idle_pins_a>; - pinctrl-3 = <&uart4_pins_a>; -+ /delete-property/dmas; -+ /delete-property/dma-names; - status = "okay"; - }; - -@@ -711,6 +719,8 @@ - pinctrl-0 = <&uart7_pins_a>; - pinctrl-1 = <&uart7_sleep_pins_a>; - pinctrl-2 = <&uart7_idle_pins_a>; -+ /delete-property/dmas; -+ /delete-property/dma-names; - status = "disabled"; - }; - -@@ -719,6 +729,7 @@ - pinctrl-0 = <&usart3_pins_b>; - pinctrl-1 = <&usart3_sleep_pins_b>; - pinctrl-2 = <&usart3_idle_pins_b>; -+ st,hw-flow-ctrl; - status = "disabled"; - }; - -diff --git a/arch/arm/dts/stm32mp157c-dk2.dts b/arch/arm/dts/stm32mp157c-dk2.dts -index d11fbb8..5523dc3 100644 ---- a/arch/arm/dts/stm32mp157c-dk2.dts -+++ b/arch/arm/dts/stm32mp157c-dk2.dts -@@ -47,7 +47,7 @@ - }; - }; - -- panel@0 { -+ panel: panel@0 { - compatible = "orisetech,otm8009a"; - reg = <0>; - reset-gpios = <&gpioe 4 GPIO_ACTIVE_LOW>; -@@ -71,6 +71,7 @@ - interrupt-controller; - touchscreen-size-x = <480>; - touchscreen-size-y = <800>; -+ panel = <&panel>; - status = "okay"; - }; - touchscreen@38 { -@@ -81,6 +82,7 @@ - interrupt-controller; - touchscreen-size-x = <480>; - touchscreen-size-y = <800>; -+ panel = <&panel>; - status = "okay"; - }; - }; -diff --git a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi -index 5ab4eeb..898155f 100644 ---- a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi -+++ b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi -@@ -119,13 +119,6 @@ - CLK_LPTIM45_LSE - >; - -- /* VCO = 1300.0 MHz => P = 650 (CPU) */ -- pll1: st,pll@0 { -- cfg = < 2 80 0 0 0 PQR(1,0,0) >; -- frac = < 0x800 >; -- u-boot,dm-pre-reloc; -- }; -- - /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ - pll2: st,pll@1 { - cfg = < 2 65 1 0 0 PQR(1,1,1) >; -diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts -index c9eabc1..f5e685d 100644 ---- a/arch/arm/dts/stm32mp157c-ed1.dts -+++ b/arch/arm/dts/stm32mp157c-ed1.dts -@@ -6,8 +6,8 @@ - /dts-v1/; - - #include "stm32mp157c.dtsi" --#include "stm32mp157c-m4-srm.dtsi" - #include "stm32mp157caa-pinctrl.dtsi" -+#include "stm32mp157c-m4-srm.dtsi" - #include - - / { -@@ -137,6 +137,14 @@ - }; - }; - -+&cpu0{ -+ cpu-supply = <&vddcore>; -+}; -+ -+&cpu1{ -+ cpu-supply = <&vddcore>; -+}; -+ - &dac { - pinctrl-names = "default"; - pinctrl-0 = <&dac_ch1_pins_a &dac_ch2_pins_a>; -@@ -173,6 +181,7 @@ - pinctrl-1 = <&i2c4_pins_sleep_a>; - i2c-scl-rising-time-ns = <185>; - i2c-scl-falling-time-ns = <20>; -+ clock-frequency = <400000>; - status = "okay"; - /delete-property/dmas; - /delete-property/dma-names; -@@ -184,14 +193,10 @@ - interrupt-controller; - #interrupt-cells = <2>; - status = "okay"; -- -- st,main-control-register = <0x04>; -- st,vin-control-register = <0xc0>; -- st,usb-control-register = <0x20>; -+ wakeup-source; - - regulators { - compatible = "st,stpmic1-regulators"; -- - ldo1-supply = <&v3v3>; - ldo2-supply = <&v3v3>; - ldo3-supply = <&vdd_ddr>; -@@ -295,20 +300,20 @@ - vbus_otg: pwr_sw1 { - regulator-name = "vbus_otg"; - interrupts = ; -- regulator-active-discharge; - }; - - vbus_sw: pwr_sw2 { - regulator-name = "vbus_sw"; - interrupts = ; -- regulator-active-discharge; -+ regulator-active-discharge = <1>; - }; - }; - - onkey { - compatible = "st,stpmic1-onkey"; -- interrupts = , ; -+ interrupts = , ; - interrupt-names = "onkey-falling", "onkey-rising"; -+ power-off-time-sec = <10>; - status = "okay"; - }; - -@@ -408,6 +413,8 @@ - pinctrl-1 = <&uart4_sleep_pins_a>; - pinctrl-2 = <&uart4_idle_pins_a>; - pinctrl-3 = <&uart4_pins_a>; -+ /delete-property/dmas; -+ /delete-property/dma-names; - status = "okay"; - }; - -diff --git a/arch/arm/dts/stm32mp157c-ev1.dts b/arch/arm/dts/stm32mp157c-ev1.dts -index 559b9b9..7323f40 100644 ---- a/arch/arm/dts/stm32mp157c-ev1.dts -+++ b/arch/arm/dts/stm32mp157c-ev1.dts -@@ -98,7 +98,7 @@ - }; - }; - -- sound { -+ sound: sound { - compatible = "audio-graph-card"; - label = "STM32MP1-EV"; - routing = -@@ -325,7 +325,7 @@ - }; - }; - -- panel-dsi@0 { -+ panel_dsi: panel-dsi@0 { - compatible = "raydium,rm68200"; - reg = <0>; - reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>; -@@ -495,6 +495,7 @@ - gt9147: goodix_ts@5d { - compatible = "goodix,gt9147"; - reg = <0x5d>; -+ panel = <&panel_dsi>; - status = "okay"; - - irq-gpios = <&stmfx_pinctrl 14 GPIO_ACTIVE_HIGH>; -@@ -649,7 +650,7 @@ - &spdifrx { - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&spdifrx_pins_a>; -- pinctrl-1 = <&spdifrx_sleep_pins_a>; -+ pinctrl-1 = <&spdifrx_pins_a>; - status = "okay"; - - spdifrx_port: port { -@@ -717,6 +718,7 @@ - pinctrl-0 = <&usart3_pins_a>; - pinctrl-1 = <&usart3_sleep_pins_a>; - pinctrl-2 = <&usart3_idle_pins_a>; -+ st,hw-flow-ctrl; - status = "disabled"; - }; - -diff --git a/arch/arm/dts/stm32mp157c-m4-srm.dtsi b/arch/arm/dts/stm32mp157c-m4-srm.dtsi -index 9ea9736..4d641a9 100644 ---- a/arch/arm/dts/stm32mp157c-m4-srm.dtsi -+++ b/arch/arm/dts/stm32mp157c-m4-srm.dtsi -@@ -1,3 +1,528 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -+ * Author: Fabien Dessenne for STMicroelectronics. -+ */ -+ -+&pinctrl { -+ m4_adc1_in6_pins_a: m4-adc1-in6 { -+ pins { -+ pinmux = ; -+ }; -+ }; -+ -+ m4_adc12_ain_pins_a: m4-adc12-ain-0 { -+ pins { -+ pinmux = , /* ADC1 in13 */ -+ , /* ADC1 in6 */ -+ , /* ADC2 in2 */ -+ ; /* ADC2 in6 */ -+ }; -+ }; -+ -+ m4_adc12_usb_pwr_pins_a: m4-adc12-usb-pwr-pins-0 { -+ pins { -+ pinmux = , /* ADC12 in18 */ -+ ; /* ADC12 in19 */ -+ }; -+ }; -+ -+ m4_cec_pins_a: m4-cec-0 { -+ pins { -+ pinmux = ; -+ }; -+ }; -+ -+ m4_cec_pins_b: m4-cec-1 { -+ pins { -+ pinmux = ; -+ }; -+ }; -+ -+ m4_dac_ch1_pins_a: m4-dac-ch1 { -+ pins { -+ pinmux = ; -+ }; -+ }; -+ -+ m4_dac_ch2_pins_a: m4-dac-ch2 { -+ pins { -+ pinmux = ; -+ }; -+ }; -+ -+ m4_dcmi_pins_a: m4-dcmi-0 { -+ pins { -+ pinmux = ,/* DCMI_HSYNC */ -+ ,/* DCMI_VSYNC */ -+ ,/* DCMI_PIXCLK */ -+ ,/* DCMI_D0 */ -+ ,/* DCMI_D1 */ -+ ,/* DCMI_D2 */ -+ ,/* DCMI_D3 */ -+ ,/* DCMI_D4 */ -+ ,/* DCMI_D5 */ -+ ,/* DCMI_D6 */ -+ ,/* DCMI_D7 */ -+ ,/* DCMI_D8 */ -+ ,/* DCMI_D9 */ -+ ,/* DCMI_D10 */ -+ ;/* DCMI_D11 */ -+ }; -+ }; -+ -+ m4_dfsdm_clkout_pins_a: m4-dfsdm-clkout-pins-0 { -+ pins { -+ pinmux = ; /* DFSDM_CKOUT */ -+ }; -+ }; -+ -+ m4_dfsdm_data1_pins_a: m4-dfsdm-data1-pins-0 { -+ pins { -+ pinmux = ; /* DFSDM_DATA1 */ -+ }; -+ }; -+ -+ m4_dfsdm_data3_pins_a: m4-dfsdm-data3-pins-0 { -+ pins { -+ pinmux = ; /* DFSDM_DATA3 */ -+ }; -+ }; -+ -+ m4_ethernet0_rgmii_pins_a: m4-rgmii-0 { -+ pins { -+ pinmux = , /* ETH_RGMII_CLK125 */ -+ , /* ETH_RGMII_GTX_CLK */ -+ , /* ETH_RGMII_TXD0 */ -+ , /* ETH_RGMII_TXD1 */ -+ , /* ETH_RGMII_TXD2 */ -+ , /* ETH_RGMII_TXD3 */ -+ , /* ETH_RGMII_TX_CTL */ -+ , /* ETH_MDC */ -+ , /* ETH_MDIO */ -+ , /* ETH_RGMII_RXD0 */ -+ , /* ETH_RGMII_RXD1 */ -+ , /* ETH_RGMII_RXD2 */ -+ , /* ETH_RGMII_RXD3 */ -+ , /* ETH_RGMII_RX_CLK */ -+ ; /* ETH_RGMII_RX_CTL */ -+ }; -+ }; -+ -+ m4_fmc_pins_a: m4-fmc-0 { -+ pins { -+ pinmux = , /* FMC_NOE */ -+ , /* FMC_NWE */ -+ , /* FMC_A16_FMC_CLE */ -+ , /* FMC_A17_FMC_ALE */ -+ , /* FMC_D0 */ -+ , /* FMC_D1 */ -+ , /* FMC_D2 */ -+ , /* FMC_D3 */ -+ , /* FMC_D4 */ -+ , /* FMC_D5 */ -+ , /* FMC_D6 */ -+ , /* FMC_D7 */ -+ , /* FMC_NE2_FMC_NCE */ -+ ; /* FMC_NWAIT */ -+ }; -+ }; -+ -+ m4_hdp0_pins_a: m4-hdp0-0 { -+ pins { -+ pinmux = ; /* HDP0 */ -+ }; -+ }; -+ -+ m4_hdp6_pins_a: m4-hdp6-0 { -+ pins { -+ pinmux = ; /* HDP6 */ -+ }; -+ }; -+ -+ m4_hdp7_pins_a: m4-hdp7-0 { -+ pins { -+ pinmux = ; /* HDP7 */ -+ }; -+ }; -+ -+ m4_i2c1_pins_a: m4-i2c1-0 { -+ pins { -+ pinmux = , /* I2C1_SCL */ -+ ; /* I2C1_SDA */ -+ }; -+ }; -+ -+ m4_i2c2_pins_a: m4-i2c2-0 { -+ pins { -+ pinmux = , /* I2C2_SCL */ -+ ; /* I2C2_SDA */ -+ }; -+ }; -+ -+ m4_i2c5_pins_a: m4-i2c5-0 { -+ pins { -+ pinmux = , /* I2C5_SCL */ -+ ; /* I2C5_SDA */ -+ }; -+ }; -+ -+ m4_i2s2_pins_a: m4-i2s2-0 { -+ pins { -+ pinmux = , /* I2S2_SDO */ -+ , /* I2S2_WS */ -+ ; /* I2S2_CK */ -+ }; -+ }; -+ -+ m4_ltdc_pins_a: m4-ltdc-a-0 { -+ pins { -+ pinmux = , /* LCD_CLK */ -+ , /* LCD_HSYNC */ -+ , /* LCD_VSYNC */ -+ , /* LCD_DE */ -+ , /* LCD_R0 */ -+ , /* LCD_R1 */ -+ , /* LCD_R2 */ -+ , /* LCD_R3 */ -+ , /* LCD_R4 */ -+ , /* LCD_R5 */ -+ , /* LCD_R6 */ -+ , /* LCD_R7 */ -+ , /* LCD_G0 */ -+ , /* LCD_G1 */ -+ , /* LCD_G2 */ -+ , /* LCD_G3 */ -+ , /* LCD_G4 */ -+ , /* LCD_G5 */ -+ , /* LCD_G6 */ -+ , /* LCD_G7 */ -+ , /* LCD_B0 */ -+ , /* LCD_B1 */ -+ , /* LCD_B2 */ -+ , /* LCD_B3 */ -+ , /* LCD_B4 */ -+ , /* LCD_B5 */ -+ , /* LCD_B6 */ -+ ; /* LCD_B7 */ -+ }; -+ }; -+ -+ m4_ltdc_pins_b: m4-ltdc-b-0 { -+ pins { -+ pinmux = , /* LCD_CLK */ -+ , /* LCD_HSYNC */ -+ , /* LCD_VSYNC */ -+ , /* LCD_DE */ -+ , /* LCD_R0 */ -+ , /* LCD_R1 */ -+ , /* LCD_R2 */ -+ , /* LCD_R3 */ -+ , /* LCD_R4 */ -+ , /* LCD_R5 */ -+ , /* LCD_R6 */ -+ , /* LCD_R7 */ -+ , /* LCD_G0 */ -+ , /* LCD_G1 */ -+ , /* LCD_G2 */ -+ , /* LCD_G3 */ -+ , /* LCD_G4 */ -+ , /* LCD_G5 */ -+ , /* LCD_G6 */ -+ , /* LCD_G7 */ -+ , /* LCD_B0 */ -+ , /* LCD_B1 */ -+ , /* LCD_B2 */ -+ , /* LCD_B3 */ -+ , /* LCD_B4 */ -+ , /* LCD_B5 */ -+ , /* LCD_B6 */ -+ ; /* LCD_B7 */ -+ }; -+ }; -+ -+ m4_m_can1_pins_a: m4-m-can1-0 { -+ pins { -+ pinmux = , /* CAN1_TX */ -+ ; /* CAN1_RX */ -+ }; -+ }; -+ -+ m4_pwm1_pins_a: m4-pwm1-0 { -+ pins { -+ pinmux = , /* TIM1_CH1 */ -+ , /* TIM1_CH2 */ -+ ; /* TIM1_CH4 */ -+ }; -+ }; -+ -+ m4_pwm2_pins_a: m4-pwm2-0 { -+ pins { -+ pinmux = ; /* TIM2_CH4 */ -+ }; -+ }; -+ -+ m4_pwm3_pins_a: m4-pwm3-0 { -+ pins { -+ pinmux = ; /* TIM3_CH2 */ -+ }; -+ }; -+ -+ m4_pwm4_pins_a: m4-pwm4-0 { -+ pins { -+ pinmux = , /* TIM4_CH3 */ -+ ; /* TIM4_CH4 */ -+ }; -+ }; -+ -+ m4_pwm4_pins_b: m4-pwm4-1 { -+ pins { -+ pinmux = ; /* TIM4_CH2 */ -+ }; -+ }; -+ -+ m4_pwm5_pins_a: m4-pwm5-0 { -+ pins { -+ pinmux = ; /* TIM5_CH2 */ -+ }; -+ }; -+ -+ m4_pwm8_pins_a: m4-pwm8-0 { -+ pins { -+ pinmux = ; /* TIM8_CH4 */ -+ }; -+ }; -+ -+ m4_pwm12_pins_a: m4-pwm12-0 { -+ pins { -+ pinmux = ; /* TIM12_CH1 */ -+ }; -+ }; -+ -+ m4_qspi_bk1_pins_a: m4-qspi-bk1-0 { -+ pins { -+ pinmux = , /* QSPI_BK1_IO0 */ -+ , /* QSPI_BK1_IO1 */ -+ , /* QSPI_BK1_IO2 */ -+ , /* QSPI_BK1_IO3 */ -+ ; /* QSPI_BK1_NCS */ -+ }; -+ }; -+ -+ m4_qspi_bk2_pins_a: m4-qspi-bk2-0 { -+ pins { -+ pinmux = , /* QSPI_BK2_IO0 */ -+ , /* QSPI_BK2_IO1 */ -+ , /* QSPI_BK2_IO2 */ -+ , /* QSPI_BK2_IO3 */ -+ ; /* QSPI_BK2_NCS */ -+ }; -+ }; -+ -+ m4_qspi_clk_pins_a: m4-qspi-clk-0 { -+ pins { -+ pinmux = ; /* QSPI_CLK */ -+ }; -+ }; -+ -+ m4_rtc_out2_rmp_pins_a: m4-rtc-out2-rmp-pins-0 { -+ pins { -+ pinmux = ; /* RTC_OUT2_RMP */ -+ }; -+ }; -+ -+ m4_sai2a_pins_a: m4-sai2a-0 { -+ pins { -+ pinmux = , /* SAI2_SCK_A */ -+ , /* SAI2_SD_A */ -+ , /* SAI2_FS_A */ -+ ; /* SAI2_MCLK_A */ -+ }; -+ }; -+ -+ m4_sai2b_pins_a: m4-sai2b-0 { -+ pins { -+ pinmux = , /* SAI2_SCK_B */ -+ , /* SAI2_FS_B */ -+ , /* SAI2_MCLK_B */ -+ ; /* SAI2_SD_B */ -+ }; -+ }; -+ -+ m4_sai2b_pins_b: m4-sai2b-2 { -+ pins { -+ pinmux = ; /* SAI2_SD_B */ -+ }; -+ }; -+ -+ m4_sai4a_pins_a: m4-sai4a-0 { -+ pins { -+ pinmux = ; /* SAI4_SD_A */ -+ }; -+ }; -+ -+ m4_sdmmc1_b4_pins_a: m4-sdmmc1-b4-0 { -+ pins { -+ pinmux = , /* SDMMC1_D0 */ -+ , /* SDMMC1_D1 */ -+ , /* SDMMC1_D2 */ -+ , /* SDMMC1_D3 */ -+ , /* SDMMC1_CMD */ -+ ; /* SDMMC1_CK */ -+ }; -+ }; -+ -+ m4_sdmmc1_dir_pins_a: m4-sdmmc1-dir-0 { -+ pins { -+ pinmux = , /* SDMMC1_D0DIR */ -+ , /* SDMMC1_D123DIR */ -+ , /* SDMMC1_CDIR */ -+ ; /* SDMMC1_CKIN */ -+ }; -+ }; -+ -+ m4_sdmmc2_b4_pins_a: m4-sdmmc2-b4-0 { -+ pins { -+ pinmux = , /* SDMMC2_D0 */ -+ , /* SDMMC2_D1 */ -+ , /* SDMMC2_D2 */ -+ , /* SDMMC2_D3 */ -+ , /* SDMMC2_CMD */ -+ ; /* SDMMC2_CK */ -+ }; -+ }; -+ -+ m4_sdmmc2_b4_pins_b: m4-sdmmc2-b4-1 { -+ pins { -+ pinmux = , /* SDMMC2_D0 */ -+ , /* SDMMC2_D1 */ -+ , /* SDMMC2_D2 */ -+ , /* SDMMC2_D3 */ -+ , /* SDMMC2_CMD */ -+ ; /* SDMMC2_CK */ -+ }; -+ }; -+ -+ m4_sdmmc2_d47_pins_a: m4-sdmmc2-d47-0 { -+ pins { -+ pinmux = , /* SDMMC2_D4 */ -+ , /* SDMMC2_D5 */ -+ , /* SDMMC2_D6 */ -+ ; /* SDMMC2_D7 */ -+ }; -+ }; -+ -+ m4_sdmmc3_b4_pins_a: m4-sdmmc3-b4-0 { -+ pins { -+ pinmux = , /* SDMMC3_D0 */ -+ , /* SDMMC3_D1 */ -+ , /* SDMMC3_D2 */ -+ , /* SDMMC3_D3 */ -+ , /* SDMMC3_CMD */ -+ ; /* SDMMC3_CK */ -+ }; -+ }; -+ -+ m4_spdifrx_pins_a: m4-spdifrx-0 { -+ pins { -+ pinmux = ; /* SPDIF_IN1 */ -+ }; -+ }; -+ -+ m4_spi4_pins_a: m4-spi4-0 { -+ pins { -+ pinmux = , /* SPI4_SCK */ -+ , /* SPI4_MOSI */ -+ ; /* SPI4_MISO */ -+ }; -+ }; -+ -+ m4_spi5_pins_a: m4-spi5-0 { -+ pins { -+ pinmux = , /* SPI5_SCK */ -+ , /* SPI5_MOSI */ -+ ; /* SPI5_MISO */ -+ }; -+ }; -+ -+ m4_stusb1600_pins_a: m4-stusb1600-0 { -+ pins { -+ pinmux = ; -+ }; -+ }; -+ -+ m4_uart4_pins_a: m4-uart4-0 { -+ pins { -+ pinmux = , /* UART4_TX */ -+ ; /* UART4_RX */ -+ }; -+ }; -+ -+ m4_uart7_pins_a: m4-uart7-0 { -+ pins { -+ pinmux = , /* USART7_TX */ -+ ; /* USART7_RX */ -+ }; -+ }; -+ -+ m4_usart2_pins_a: m4-usart2-0 { -+ pins { -+ pinmux = , /* USART2_TX */ -+ , /* USART2_RTS */ -+ , /* USART2_RX */ -+ ; /* USART2_CTS_NSS */ -+ }; -+ }; -+ -+ m4_usart3_pins_a: m4-usart3-0 { -+ pins { -+ pinmux = , /* USART3_TX */ -+ , /* USART3_RTS */ -+ , /* USART3_RX */ -+ ; /* USART3_CTS_NSS */ -+ }; -+ }; -+ -+ m4_usart3_pins_b: m4-usart3-1 { -+ pins { -+ pinmux = , /* USART3_TX */ -+ , /* USART3_RTS */ -+ , /* USART3_RX */ -+ ; /* USART3_CTS_NSS */ -+ }; -+ }; -+ -+ m4_usbotg_hs_pins_a: m4-usbotg_hs-0 { -+ pins { -+ pinmux = ; /* OTG_ID */ -+ }; -+ }; -+ -+ m4_usbotg_fs_dp_dm_pins_a: m4-usbotg-fs-dp-dm-0 { -+ pins { -+ pinmux = , /* OTG_FS_DM */ -+ ; /* OTG_FS_DP */ -+ }; -+ }; -+}; -+ -+&pinctrl_z { -+ m4_i2c4_pins_a: m4-i2c4-0 { -+ pins { -+ pinmux = , /* I2C4_SCL */ -+ ; /* I2C4_SDA */ -+ }; -+ }; -+ -+ m4_spi1_pins_a: m4-spi1-0 { -+ pins { -+ pinmux = , /* SPI1_SCK */ -+ , /* SPI1_MOSI */ -+ ; /* SPI1_MISO */ -+ }; -+ }; -+}; -+ - &m4_rproc { - m4_system_resources { - #address-cells = <1>; -diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp157c.dtsi -index c94a1f25..d56e0f9 100644 ---- a/arch/arm/dts/stm32mp157c.dtsi -+++ b/arch/arm/dts/stm32mp157c.dtsi -@@ -20,14 +20,36 @@ - compatible = "arm,cortex-a7"; - device_type = "cpu"; - reg = <0>; -- clock-frequency = <650000000>; -+ clocks = <&rcc CK_MPU>; -+ clock-names = "cpu"; -+ operating-points-v2 = <&cpu0_opp_table>; -+ nvmem-cells = <&part_number_otp>; -+ nvmem-cell-names = "part_number"; - }; - - cpu1: cpu@1 { - compatible = "arm,cortex-a7"; - device_type = "cpu"; - reg = <1>; -- clock-frequency = <650000000>; -+ clocks = <&rcc CK_MPU>; -+ clock-names = "cpu"; -+ operating-points-v2 = <&cpu0_opp_table>; -+ }; -+ }; -+ -+ cpu0_opp_table: cpu0-opp-table { -+ compatible = "operating-points-v2"; -+ opp-shared; -+ -+ opp-650000000 { -+ 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>; - }; - }; - -@@ -500,6 +522,9 @@ - resets = <&rcc USART2_R>; - wakeup-source; - power-domains = <&pd_core>; -+ dmas = <&dmamux1 43 0x400 0x21>, -+ <&dmamux1 44 0x400 0x1>; -+ dma-names = "rx", "tx"; - status = "disabled"; - }; - -@@ -513,6 +538,9 @@ - resets = <&rcc USART3_R>; - wakeup-source; - power-domains = <&pd_core>; -+ dmas = <&dmamux1 45 0x400 0x21>, -+ <&dmamux1 46 0x400 0x1>; -+ dma-names = "rx", "tx"; - status = "disabled"; - }; - -@@ -526,6 +554,9 @@ - resets = <&rcc UART4_R>; - wakeup-source; - power-domains = <&pd_core>; -+ dmas = <&dmamux1 63 0x400 0x21>, -+ <&dmamux1 64 0x400 0x1>; -+ dma-names = "rx", "tx"; - status = "disabled"; - }; - -@@ -539,6 +570,9 @@ - resets = <&rcc UART5_R>; - wakeup-source; - power-domains = <&pd_core>; -+ dmas = <&dmamux1 65 0x400 0x21>, -+ <&dmamux1 66 0x400 0x1>; -+ dma-names = "rx", "tx"; - status = "disabled"; - }; - -@@ -666,6 +700,9 @@ - resets = <&rcc UART7_R>; - wakeup-source; - power-domains = <&pd_core>; -+ dmas = <&dmamux1 79 0x400 0x21>, -+ <&dmamux1 80 0x400 0x1>; -+ dma-names = "rx", "tx"; - status = "disabled"; - }; - -@@ -679,6 +716,9 @@ - resets = <&rcc UART8_R>; - wakeup-source; - power-domains = <&pd_core>; -+ dmas = <&dmamux1 81 0x400 0x21>, -+ <&dmamux1 82 0x400 0x1>; -+ dma-names = "rx", "tx"; - status = "disabled"; - }; - -@@ -754,6 +794,9 @@ - resets = <&rcc USART6_R>; - wakeup-source; - power-domains = <&pd_core>; -+ dmas = <&dmamux1 71 0x400 0x21>, -+ <&dmamux1 72 0x400 0x1>; -+ dma-names = "rx", "tx"; - status = "disabled"; - }; - -@@ -1060,7 +1103,7 @@ - interrupts = , - ; - interrupt-names = "int0", "int1"; -- clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; -+ clocks = <&rcc FDCAN>, <&rcc FDCAN_K>; - clock-names = "hclk", "cclk"; - bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>; - status = "disabled"; -@@ -1073,7 +1116,7 @@ - interrupts = , - ; - interrupt-names = "int0", "int1"; -- clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; -+ clocks = <&rcc FDCAN>, <&rcc FDCAN_K>; - clock-names = "hclk", "cclk"; - bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>; - status = "disabled"; -@@ -1095,14 +1138,14 @@ - #dma-cells = <4>; - st,mem2mem; - dma-requests = <8>; -- dmas = <&mdma1 0 0x11 0x1200000a 0x48000008 0x00000020 1>, -- <&mdma1 1 0x11 0x1200000a 0x48000008 0x00000800 1>, -- <&mdma1 2 0x11 0x1200000a 0x48000008 0x00200000 1>, -- <&mdma1 3 0x11 0x1200000a 0x48000008 0x08000000 1>, -- <&mdma1 4 0x11 0x1200000a 0x4800000C 0x00000020 1>, -- <&mdma1 5 0x11 0x1200000a 0x4800000C 0x00000800 1>, -- <&mdma1 6 0x11 0x1200000a 0x4800000C 0x00200000 1>, -- <&mdma1 7 0x11 0x1200000a 0x4800000C 0x08000000 1>; -+ dmas = <&mdma1 0 0x3 0x1200000a 0x48000008 0x00000020 1>, -+ <&mdma1 1 0x3 0x1200000a 0x48000008 0x00000800 1>, -+ <&mdma1 2 0x3 0x1200000a 0x48000008 0x00200000 1>, -+ <&mdma1 3 0x3 0x1200000a 0x48000008 0x08000000 1>, -+ <&mdma1 4 0x3 0x1200000a 0x4800000C 0x00000020 1>, -+ <&mdma1 5 0x3 0x1200000a 0x4800000C 0x00000800 1>, -+ <&mdma1 6 0x3 0x1200000a 0x4800000C 0x00200000 1>, -+ <&mdma1 7 0x3 0x1200000a 0x4800000C 0x08000000 1>; - dma-names = "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7"; - }; - -@@ -1122,14 +1165,14 @@ - #dma-cells = <4>; - st,mem2mem; - dma-requests = <8>; -- dmas = <&mdma1 8 0x11 0x1200000a 0x48001008 0x00000020 1>, -- <&mdma1 9 0x11 0x1200000a 0x48001008 0x00000800 1>, -- <&mdma1 10 0x11 0x1200000a 0x48001008 0x00200000 1>, -- <&mdma1 11 0x11 0x1200000a 0x48001008 0x08000000 1>, -- <&mdma1 12 0x11 0x1200000a 0x4800100C 0x00000020 1>, -- <&mdma1 13 0x11 0x1200000a 0x4800100C 0x00000800 1>, -- <&mdma1 14 0x11 0x1200000a 0x4800100C 0x00200000 1>, -- <&mdma1 15 0x11 0x1200000a 0x4800100C 0x08000000 1>; -+ dmas = <&mdma1 8 0x3 0x1200000a 0x48001008 0x00000020 1>, -+ <&mdma1 9 0x3 0x1200000a 0x48001008 0x00000800 1>, -+ <&mdma1 10 0x3 0x1200000a 0x48001008 0x00200000 1>, -+ <&mdma1 11 0x3 0x1200000a 0x48001008 0x08000000 1>, -+ <&mdma1 12 0x3 0x1200000a 0x4800100C 0x00000020 1>, -+ <&mdma1 13 0x3 0x1200000a 0x4800100C 0x00000800 1>, -+ <&mdma1 14 0x3 0x1200000a 0x4800100C 0x00200000 1>, -+ <&mdma1 15 0x3 0x1200000a 0x4800100C 0x08000000 1>; - dma-names = "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7"; - }; - -@@ -1309,6 +1352,13 @@ - 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>; -+ - pwr-regulators { - compatible = "st,stm32mp1,pwr-reg"; - st,tzcr = <&rcc 0x0 0x1>; -@@ -1655,7 +1705,7 @@ - interrupts = ; - clocks = <&rcc HASH1>; - resets = <&rcc HASH1_R>; -- dmas = <&mdma1 31 0x10 0x1000A02 0x0 0x0 0x0>; -+ dmas = <&mdma1 31 0x2 0x1000A02 0x0 0x0 0x0>; - dma-names = "in"; - dma-maxburst = <2>; - status = "disabled"; -@@ -1690,22 +1740,22 @@ - <0x89010000 0x1000>, - <0x89020000 0x1000>; - interrupts = ; -- dmas = <&mdma1 20 0x10 0x12000A02 0x0 0x0 0>, -- <&mdma1 20 0x10 0x12000A08 0x0 0x0 0>, -- <&mdma1 21 0x10 0x12000A0A 0x0 0x0 0>; -+ dmas = <&mdma1 20 0x2 0x12000A02 0x0 0x0 0>, -+ <&mdma1 20 0x2 0x12000A08 0x0 0x0 0>, -+ <&mdma1 21 0x2 0x12000A0A 0x0 0x0 0>; - dma-names = "tx", "rx", "ecc"; - clocks = <&rcc FMC_K>; - resets = <&rcc FMC_R>; - status = "disabled"; - }; - -- qspi: qspi@58003000 { -+ qspi: spi@58003000 { - compatible = "st,stm32f469-qspi"; - reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; - reg-names = "qspi", "qspi_mm"; - interrupts = ; -- dmas = <&mdma1 22 0x10 0x100002 0x0 0x0 0x0>, -- <&mdma1 22 0x10 0x100008 0x0 0x0 0x0>; -+ dmas = <&mdma1 22 0x2 0x100002 0x0 0x0 0x0>, -+ <&mdma1 22 0x2 0x100008 0x0 0x0 0x0>; - dma-names = "tx", "rx"; - clocks = <&rcc QSPI_K>; - resets = <&rcc QSPI_R>; -@@ -1941,6 +1991,10 @@ - reg = <0x5c005000 0x400>; - #address-cells = <1>; - #size-cells = <1>; -+ -+ part_number_otp: part_number_otp@4 { -+ reg = <0x4 0x1>; -+ }; - ts_cal1: calib@5c { - reg = <0x5c 0x2>; - }; -@@ -2001,6 +2055,7 @@ - st,syscfg-pdds = <&pwr 0x014 0x1>; - st,syscfg-holdboot = <&rcc 0x10C 0x1>; - st,syscfg-tz = <&rcc 0x000 0x1>; -+ st,syscfg-rsc-tbl = <&tamp 0x144 0xFFFFFFFF>; - status = "disabled"; - - m4_system_resources { -diff --git a/doc/device-tree-bindings/clock/st,stm32mp1.txt b/doc/device-tree-bindings/clock/st,stm32mp1.txt -index ec1d703..a703318 100644 ---- a/doc/device-tree-bindings/clock/st,stm32mp1.txt -+++ b/doc/device-tree-bindings/clock/st,stm32mp1.txt -@@ -84,6 +84,10 @@ Optional Properties: - are listed with associated index 0 to 3 (st,pll@0 to st,pll@3). - PLLx is off when the associated node is absent. - -+ For PLL1, when the node is absent, the frequency of the OPP node is used -+ to compute the PLL setting (see compatible "operating-points-v2" in -+ opp/opp.txt for details). -+ - Here are the available properties for each PLL node: - - - cfg: The parameters for PLL configuration in the following order: -diff --git a/include/dt-bindings/mfd/st,stpmic1.h b/include/dt-bindings/mfd/st,stpmic1.h -index b2d6c83..321cd08 100644 ---- a/include/dt-bindings/mfd/st,stpmic1.h -+++ b/include/dt-bindings/mfd/st,stpmic1.h -@@ -43,4 +43,8 @@ - #define IT_SWIN_F 30 - #define IT_SWIN_R 31 - -+/* BUCK MODES definitions */ -+#define STPMIC1_BUCK_MODE_NORMAL 0 -+#define STPMIC1_BUCK_MODE_LP 2 -+ - #endif /* __DT_BINDINGS_STPMIC1_H__ */ -diff --git a/include/dt-bindings/pinctrl/stm32-pinfunc.h b/include/dt-bindings/pinctrl/stm32-pinfunc.h -index e928aea..e3b45a8 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)) --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0017-ARM-v2018.11-stm32mp-r4-MISC.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0017-ARM-v2018.11-stm32mp-r4-MISC.patch deleted file mode 100644 index e360167..0000000 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0017-ARM-v2018.11-stm32mp-r4-MISC.patch +++ /dev/null @@ -1,4739 +0,0 @@ -From a962515cc6270639e7ec645409a0dd1b0c848829 Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Thu, 30 Jan 2020 14:57:55 +0100 -Subject: [PATCH 17/17] ARM v2018.11 stm32mp r4 MISC - ---- - Makefile | 2 +- - cmd/remoteproc.c | 4 - - drivers/clk/clk_stm32mp1.c | 284 +++++++++- - drivers/i2c/stm32f7_i2c.c | 116 ++-- - drivers/mmc/mmc-uclass.c | 14 + - drivers/mmc/mmc.c | 15 + - drivers/mmc/stm32_sdmmc2.c | 13 +- - drivers/net/dwc_eth_qos.c | 47 +- - drivers/ram/stm32mp1/stm32mp1_ddr.c | 30 +- - drivers/ram/stm32mp1/stm32mp1_interactive.c | 4 +- - drivers/remoteproc/rproc-uclass.c | 35 +- - drivers/remoteproc/stm32_copro.c | 9 +- - drivers/video/Kconfig | 13 +- - drivers/video/Makefile | 5 +- - drivers/video/dsi-host-uclass.c | 39 ++ - drivers/video/dw_mipi_dsi.c | 140 ++--- - drivers/video/mipi_display.c | 817 --------------------------- - drivers/video/mipi_dsi.c | 828 ++++++++++++++++++++++++++++ - drivers/video/orisetech_otm8009a.c | 101 ++-- - drivers/video/raydium-rm68200.c | 39 +- - drivers/video/stm32/stm32_dsi.c | 167 ++++-- - drivers/video/stm32/stm32_ltdc.c | 50 +- - include/dm/uclass-id.h | 1 + - include/dsi_host.h | 57 ++ - include/mipi_display.h | 249 +-------- - include/mipi_dsi.h | 473 ++++++++++++++++ - include/mmc.h | 13 + - include/power/stpmic1.h | 1 + - include/remoteproc.h | 11 + - 29 files changed, 2188 insertions(+), 1389 deletions(-) - create mode 100644 drivers/video/dsi-host-uclass.c - delete mode 100644 drivers/video/mipi_display.c - create mode 100644 drivers/video/mipi_dsi.c - create mode 100644 include/dsi_host.h - create mode 100644 include/mipi_dsi.h - -diff --git a/Makefile b/Makefile -index b9579b2..4c72fc1 100644 ---- a/Makefile -+++ b/Makefile -@@ -3,7 +3,7 @@ - VERSION = 2018 - PATCHLEVEL = 11 - SUBLEVEL = --EXTRAVERSION = -stm32mp-r3 -+EXTRAVERSION = -stm32mp-r4 - NAME = - - # *DOCUMENTATION* -diff --git a/cmd/remoteproc.c b/cmd/remoteproc.c -index 755e933..5665032 100644 ---- a/cmd/remoteproc.c -+++ b/cmd/remoteproc.c -@@ -177,10 +177,6 @@ static int do_remoteproc_load_rsc_table(cmd_tbl_t *cmdtp, int flag, int argc, - } - - ret = rproc_load_rsc_table(id, addr, size, &rsc_addr, &rsc_size); -- if (!ret) { -- env_set_hex("copro_rsc_addr", rsc_addr); -- env_set_hex("copro_rsc_size", rsc_size); -- } - - printf("Remote Processor %d resource table %s : 0x%08lx-0x%x\n", - id, ret ? "Not found" : "Found", ret ? 0 : rsc_addr, -diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c -index 2d7b185..a6503e4 100644 ---- a/drivers/clk/clk_stm32mp1.c -+++ b/drivers/clk/clk_stm32mp1.c -@@ -650,8 +650,18 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { - }; - - #ifdef STM32MP1_CLOCK_TREE_INIT -+ - /* define characteristic of PLL according type */ -+#define DIVM_MIN 0 -+#define DIVM_MAX 63 - #define DIVN_MIN 24 -+#define DIVP_MIN 0 -+#define DIVP_MAX 127 -+#define FRAC_MAX 8192 -+ -+#define PLL1600_VCO_MIN 800000000 -+#define PLL1600_VCO_MAX 1600000000 -+ - static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = { - [PLL_800] = { - .refclk_min = 4, -@@ -1206,6 +1216,211 @@ static ulong stm32mp1_clk_get_rate(struct clk *clk) - } - - #ifdef STM32MP1_CLOCK_TREE_INIT -+ -+bool stm32mp1_supports_opp(u32 opp_id, u32 cpu_type) -+{ -+ unsigned int id; -+ -+ switch (opp_id) { -+ case 1: -+ case 2: -+ id = opp_id; -+ break; -+ default: -+ id = 1; /* default value */ -+ break; -+ } -+ -+ switch (cpu_type) { -+ case CPU_STM32MP157Fxx: -+ case CPU_STM32MP157Dxx: -+ case CPU_STM32MP153Fxx: -+ case CPU_STM32MP153Dxx: -+ case CPU_STM32MP151Fxx: -+ case CPU_STM32MP151Dxx: -+ return true; -+ default: -+ return id == 1; -+ } -+} -+ -+__weak void board_vddcore_init(u32 voltage_mv) -+{ -+} -+ -+/* -+ * gets OPP parameters (frequency in KHz and voltage in mV) from -+ * an OPP table subnode. Platform HW support capabilities are also checked. -+ * Returns 0 on success and a negative FDT error code on failure. -+ */ -+static int stm32mp1_get_opp(u32 cpu_type, ofnode subnode, -+ u32 *freq_khz, u32 *voltage_mv) -+{ -+ u32 opp_hw; -+ u64 read_freq_64; -+ u32 read_voltage_32; -+ -+ *freq_khz = 0; -+ *voltage_mv = 0; -+ -+ opp_hw = ofnode_read_u32_default(subnode, "opp-supported-hw", 0); -+ if (opp_hw) -+ if (!stm32mp1_supports_opp(opp_hw, cpu_type)) -+ return -FDT_ERR_BADVALUE; -+ -+ read_freq_64 = ofnode_read_u64_default(subnode, "opp-hz", 0) / -+ 1000ULL; -+ read_voltage_32 = ofnode_read_u32_default(subnode, "opp-microvolt", 0) / -+ 1000U; -+ -+ if (!read_voltage_32 || !read_freq_64) -+ return -FDT_ERR_NOTFOUND; -+ -+ /* Frequency value expressed in KHz must fit on 32 bits */ -+ if (read_freq_64 > U32_MAX) -+ return -FDT_ERR_BADVALUE; -+ -+ /* Millivolt value must fit on 16 bits */ -+ if (read_voltage_32 > U16_MAX) -+ return -FDT_ERR_BADVALUE; -+ -+ *freq_khz = (u32)read_freq_64; -+ *voltage_mv = read_voltage_32; -+ -+ return 0; -+} -+ -+/* -+ * parses OPP table in DT and finds the parameters for the -+ * highest frequency supported by the HW platform. -+ * Returns 0 on success and a negative FDT error code on failure. -+ */ -+int stm32mp1_get_max_opp_freq(struct stm32mp1_clk_priv *priv, u64 *freq_hz) -+{ -+ ofnode node, subnode; -+ int ret; -+ u32 freq = 0U, voltage = 0U; -+ u32 cpu_type = get_cpu_type(); -+ -+ node = ofnode_by_compatible(ofnode_null(), "operating-points-v2"); -+ if (!ofnode_valid(node)) -+ return -FDT_ERR_NOTFOUND; -+ -+ ofnode_for_each_subnode(subnode, node) { -+ unsigned int read_freq; -+ unsigned int read_voltage; -+ -+ ret = stm32mp1_get_opp(cpu_type, subnode, -+ &read_freq, &read_voltage); -+ if (ret) -+ continue; -+ -+ if (read_freq > freq) { -+ freq = read_freq; -+ voltage = read_voltage; -+ } -+ } -+ -+ if (!freq || !voltage) -+ return -FDT_ERR_NOTFOUND; -+ -+ *freq_hz = (u64)1000U * freq; -+ board_vddcore_init(voltage); -+ -+ return 0; -+} -+ -+static int stm32mp1_pll1_opp(struct stm32mp1_clk_priv *priv, int clksrc, -+ u32 *pllcfg, u32 *fracv) -+{ -+ u32 post_divm; -+ u32 input_freq; -+ u64 output_freq; -+ u64 freq; -+ u64 vco; -+ u32 divm, divn, divp, frac; -+ int i, ret; -+ u32 diff; -+ u32 best_diff = U32_MAX; -+ -+ /* PLL1 is 1600 */ -+ const u32 DIVN_MAX = stm32mp1_pll[PLL_1600].divn_max; -+ const u32 POST_DIVM_MIN = stm32mp1_pll[PLL_1600].refclk_min * 1000000U; -+ const u32 POST_DIVM_MAX = stm32mp1_pll[PLL_1600].refclk_max * 1000000U; -+ -+ ret = stm32mp1_get_max_opp_freq(priv, &output_freq); -+ if (ret) -+ return ret; -+ -+ switch (clksrc) { -+ case CLK_PLL12_HSI: -+ input_freq = stm32mp1_clk_get_fixed(priv, _HSI); -+ break; -+ case CLK_PLL12_HSE: -+ input_freq = stm32mp1_clk_get_fixed(priv, _HSE); -+ break; -+ default: -+ return -EINTR; -+ } -+ -+ /* Following parameters have always the same value */ -+ pllcfg[PLLCFG_Q] = 0; -+ pllcfg[PLLCFG_R] = 0; -+ pllcfg[PLLCFG_O] = PQR(1, 0, 0); -+ -+ for (divm = DIVM_MAX; divm >= DIVM_MIN; divm--) { -+ post_divm = (u32)(input_freq / (divm + 1)); -+ if (post_divm < POST_DIVM_MIN || post_divm > POST_DIVM_MAX) -+ continue; -+ -+ for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) { -+ freq = output_freq * (divm + 1) * (divp + 1); -+ divn = (u32)((freq / input_freq) - 1); -+ if (divn < DIVN_MIN || divn > DIVN_MAX) -+ continue; -+ -+ frac = (u32)(((freq * FRAC_MAX) / input_freq) - -+ ((divn + 1) * FRAC_MAX)); -+ /* 2 loops to refine the fractional part */ -+ for (i = 2; i != 0; i--) { -+ if (frac > FRAC_MAX) -+ break; -+ -+ vco = (post_divm * (divn + 1)) + -+ ((post_divm * (u64)frac) / -+ FRAC_MAX); -+ if (vco < (PLL1600_VCO_MIN / 2) || -+ vco > (PLL1600_VCO_MAX / 2)) { -+ frac++; -+ continue; -+ } -+ freq = vco / (divp + 1); -+ if (output_freq < freq) -+ diff = (u32)(freq - output_freq); -+ else -+ diff = (u32)(output_freq - freq); -+ if (diff < best_diff) { -+ pllcfg[PLLCFG_M] = divm; -+ pllcfg[PLLCFG_N] = divn; -+ pllcfg[PLLCFG_P] = divp; -+ *fracv = frac; -+ -+ if (diff == 0) -+ return 0; -+ -+ best_diff = diff; -+ } -+ frac++; -+ } -+ } -+ } -+ -+ if (best_diff == U32_MAX) -+ return -1; -+ -+ return 0; -+} -+ - static void stm32mp1_ls_osc_set(int enable, fdt_addr_t rcc, u32 offset, - u32 mask_on) - { -@@ -1678,7 +1893,10 @@ static int stm32mp1_clktree(struct udevice *dev) - unsigned int clksrc[CLKSRC_NB]; - unsigned int clkdiv[CLKDIV_NB]; - unsigned int pllcfg[_PLL_NB][PLLCFG_NB]; -- ofnode plloff[_PLL_NB]; -+ unsigned int pllfracv[_PLL_NB]; -+ unsigned int pllcsg[_PLL_NB][PLLCSG_NB]; -+ bool pllcfg_valid[_PLL_NB]; -+ bool pllcsg_set[_PLL_NB]; - int ret; - int i, len; - int lse_css = 0; -@@ -1700,16 +1918,41 @@ static int stm32mp1_clktree(struct udevice *dev) - /* check mandatory field in each pll */ - for (i = 0; i < _PLL_NB; i++) { - char name[12]; -+ ofnode node; - - sprintf(name, "st,pll@%d", i); -- plloff[i] = dev_read_subnode(dev, name); -- if (!ofnode_valid(plloff[i])) -- continue; -- ret = ofnode_read_u32_array(plloff[i], "cfg", -- pllcfg[i], PLLCFG_NB); -- if (ret < 0) { -- debug("field cfg invalid: error %d\n", ret); -- return -FDT_ERR_NOTFOUND; -+ node = dev_read_subnode(dev, name); -+ pllcfg_valid[i] = ofnode_valid(node); -+ pllcsg_set[i] = false; -+ if (pllcfg_valid[i]) { -+ debug("DT for PLL %d @ %s\n", i, name); -+ ret = ofnode_read_u32_array(node, "cfg", -+ pllcfg[i], PLLCFG_NB); -+ if (ret < 0) { -+ debug("field cfg invalid: error %d\n", ret); -+ return -FDT_ERR_NOTFOUND; -+ } -+ pllfracv[i] = ofnode_read_u32_default(node, "frac", 0); -+ -+ ret = ofnode_read_u32_array(node, "csg", pllcsg[i], -+ PLLCSG_NB); -+ if (!ret) { -+ pllcsg_set[i] = true; -+ } else if (ret != -FDT_ERR_NOTFOUND) { -+ debug("invalid csg node for pll@%d res=%d\n", -+ i, ret); -+ return ret; -+ } -+ } else if (i == _PLL1) { -+ /* use OPP for PLL1 for A7 CPU */ -+ debug("DT for PLL %d with OPP\n", i); -+ ret = stm32mp1_pll1_opp(priv, -+ clksrc[CLKSRC_PLL12], -+ pllcfg[i], -+ &pllfracv[i]); -+ if (ret) -+ return ret; -+ pllcfg_valid[i] = true; - } - } - -@@ -1794,29 +2037,18 @@ static int stm32mp1_clktree(struct udevice *dev) - /* configure and start PLLs */ - debug("configure PLLs\n"); - for (i = 0; i < _PLL_NB; i++) { -- u32 fracv; -- u32 csg[PLLCSG_NB]; -- -- debug("configure PLL %d @ %d\n", i, -- ofnode_to_offset(plloff[i])); -- if (!ofnode_valid(plloff[i])) -+ if (!pllcfg_valid[i]) - continue; -- -- fracv = ofnode_read_u32_default(plloff[i], "frac", 0); -- pll_config(priv, i, pllcfg[i], fracv); -- ret = ofnode_read_u32_array(plloff[i], "csg", csg, PLLCSG_NB); -- if (!ret) { -- pll_csg(priv, i, csg); -- } else if (ret != -FDT_ERR_NOTFOUND) { -- debug("invalid csg node for pll@%d res=%d\n", i, ret); -- return ret; -- } -+ debug("configure PLL %d\n", i); -+ pll_config(priv, i, pllcfg[i], pllfracv[i]); -+ if (pllcsg_set[i]) -+ pll_csg(priv, i, pllcsg[i]); - pll_start(priv, i); - } - - /* wait and start PLLs ouptut when ready */ - for (i = 0; i < _PLL_NB; i++) { -- if (!ofnode_valid(plloff[i])) -+ if (!pllcfg_valid[i]) - continue; - debug("output PLL %d\n", i); - pll_output(priv, i, pllcfg[i][PLLCFG_O]); -diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c -index 2b18735..db363a2 100644 ---- a/drivers/i2c/stm32f7_i2c.c -+++ b/drivers/i2c/stm32f7_i2c.c -@@ -119,13 +119,6 @@ struct stm32_i2c_regs { - #define FAST_RATE 400000 - #define FAST_PLUS_RATE 1000000 - --enum stm32_i2c_speed { -- STM32_I2C_SPEED_STANDARD, /* 100 kHz */ -- STM32_I2C_SPEED_FAST, /* 400 kHz */ -- STM32_I2C_SPEED_FAST_PLUS, /* 1 MHz */ -- STM32_I2C_SPEED_END, --}; -- - /** - * struct stm32_i2c_spec - private i2c specification timing - * @rate: I2C bus speed (Hz) -@@ -155,7 +148,6 @@ struct stm32_i2c_spec { - - /** - * struct stm32_i2c_setup - private I2C timing setup parameters -- * @speed: I2C speed mode (standard, Fast Plus) - * @speed_freq: I2C speed frequency (Hz) - * @clock_src: I2C clock source frequency (Hz) - * @rise_time: Rise time (ns) -@@ -164,7 +156,6 @@ struct stm32_i2c_spec { - * @analog_filter: Analog filter delay (On/Off) - */ - struct stm32_i2c_setup { -- enum stm32_i2c_speed speed; - u32 speed_freq; - u32 clock_src; - u32 rise_time; -@@ -194,11 +185,12 @@ struct stm32_i2c_priv { - struct stm32_i2c_regs *regs; - struct clk clk; - struct stm32_i2c_setup *setup; -- int speed; -+ u32 speed; - }; - - static const struct stm32_i2c_spec i2c_specs[] = { -- [STM32_I2C_SPEED_STANDARD] = { -+ /* Standard speed - 100 KHz */ -+ { - .rate = STANDARD_RATE, - .rate_min = 8000, - .rate_max = 120000, -@@ -210,7 +202,8 @@ static const struct stm32_i2c_spec i2c_specs[] = { - .l_min = 4700, - .h_min = 4000, - }, -- [STM32_I2C_SPEED_FAST] = { -+ /* Fast speed - 400 KHz */ -+ { - .rate = FAST_RATE, - .rate_min = 320000, - .rate_max = 480000, -@@ -222,7 +215,8 @@ static const struct stm32_i2c_spec i2c_specs[] = { - .l_min = 1300, - .h_min = 600, - }, -- [STM32_I2C_SPEED_FAST_PLUS] = { -+ /* Fast Plus Speed - 1 MHz */ -+ { - .rate = FAST_PLUS_RATE, - .rate_min = 800000, - .rate_max = 1200000, -@@ -484,6 +478,7 @@ static int stm32_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, - } - - static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, -+ const struct stm32_i2c_spec *specs, - struct list_head *solutions) - { - struct stm32_i2c_timings *v; -@@ -500,13 +495,13 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, - af_delay_max = setup->analog_filter ? - STM32_I2C_ANALOG_FILTER_DELAY_MAX : 0; - -- sdadel_min = i2c_specs[setup->speed].hddat_min + setup->fall_time - -+ sdadel_min = specs->hddat_min + setup->fall_time - - af_delay_min - (setup->dnf + 3) * i2cclk; - -- sdadel_max = i2c_specs[setup->speed].vddat_max - setup->rise_time - -+ sdadel_max = specs->vddat_max - setup->rise_time - - af_delay_max - (setup->dnf + 4) * i2cclk; - -- scldel_min = setup->rise_time + i2c_specs[setup->speed].sudat_min; -+ scldel_min = setup->rise_time + specs->sudat_min; - - if (sdadel_min < 0) - sdadel_min = 0; -@@ -558,6 +553,7 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, - } - - static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, -+ const struct stm32_i2c_spec *specs, - struct list_head *solutions, - struct stm32_i2c_timings *s) - { -@@ -580,8 +576,8 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, - dnf_delay = setup->dnf * i2cclk; - - tsync = af_delay_min + dnf_delay + (2 * i2cclk); -- clk_max = STM32_NSEC_PER_SEC / i2c_specs[setup->speed].rate_min; -- clk_min = STM32_NSEC_PER_SEC / i2c_specs[setup->speed].rate_max; -+ clk_max = STM32_NSEC_PER_SEC / specs->rate_min; -+ clk_min = STM32_NSEC_PER_SEC / specs->rate_max; - - /* - * Among Prescaler possibilities discovered above figures out SCL Low -@@ -599,7 +595,7 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, - for (l = 0; l < STM32_SCLL_MAX; l++) { - u32 tscl_l = (l + 1) * prescaler + tsync; - -- if ((tscl_l < i2c_specs[setup->speed].l_min) || -+ if (tscl_l < specs->l_min || - (i2cclk >= - ((tscl_l - af_delay_min - dnf_delay) / 4))) { - continue; -@@ -611,7 +607,7 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, - setup->rise_time + setup->fall_time; - - if ((tscl >= clk_min) && (tscl <= clk_max) && -- (tscl_h >= i2c_specs[setup->speed].h_min) && -+ (tscl_h >= specs->h_min) && - (i2cclk < tscl_h)) { - u32 clk_error; - -@@ -640,26 +636,40 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, - return ret; - } - -+static const struct stm32_i2c_spec *get_specs(u32 rate) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(i2c_specs); i++) -+ if (rate <= i2c_specs[i].rate) -+ return &i2c_specs[i]; -+ -+ /* NOT REACHED */ -+ return ERR_PTR(-EINVAL); -+} -+ - static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, - struct stm32_i2c_setup *setup, - struct stm32_i2c_timings *output) - { -+ const struct stm32_i2c_spec *specs; - struct stm32_i2c_timings *v, *_v; - struct list_head solutions; - int ret; - -- if (setup->speed >= STM32_I2C_SPEED_END) { -- pr_err("%s: speed out of bound {%d/%d}\n", __func__, -- setup->speed, STM32_I2C_SPEED_END - 1); -+ specs = get_specs(setup->speed_freq); -+ if (specs == ERR_PTR(-EINVAL)) { -+ pr_err("%s: speed out of bound {%d}\n", __func__, -+ setup->speed_freq); - return -EINVAL; - } - -- if ((setup->rise_time > i2c_specs[setup->speed].rise_max) || -- (setup->fall_time > i2c_specs[setup->speed].fall_max)) { -+ if (setup->rise_time > specs->rise_max || -+ setup->fall_time > specs->fall_max) { - pr_err("%s :timings out of bound Rise{%d>%d}/Fall{%d>%d}\n", - __func__, -- setup->rise_time, i2c_specs[setup->speed].rise_max, -- setup->fall_time, i2c_specs[setup->speed].fall_max); -+ setup->rise_time, specs->rise_max, -+ setup->fall_time, specs->fall_max); - return -EINVAL; - } - -@@ -669,18 +679,12 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, - return -EINVAL; - } - -- if (setup->speed_freq > i2c_specs[setup->speed].rate) { -- pr_err("%s: Freq {%d/%d}\n", __func__, -- setup->speed_freq, i2c_specs[setup->speed].rate); -- return -EINVAL; -- } -- - INIT_LIST_HEAD(&solutions); -- ret = stm32_i2c_compute_solutions(setup, &solutions); -+ ret = stm32_i2c_compute_solutions(setup, specs, &solutions); - if (ret) - goto exit; - -- ret = stm32_i2c_choose_solution(setup, &solutions, output); -+ ret = stm32_i2c_choose_solution(setup, specs, &solutions, output); - if (ret) - goto exit; - -@@ -699,14 +703,24 @@ exit: - return ret; - } - -+static u32 get_lower_rate(u32 rate) -+{ -+ int i; -+ -+ for (i = ARRAY_SIZE(i2c_specs) - 1; i >= 0; i--) -+ if (rate > i2c_specs[i].rate) -+ return i2c_specs[i].rate; -+ -+ return i2c_specs[0].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; - int ret = 0; - -- setup->speed = i2c_priv->speed; -- setup->speed_freq = i2c_specs[setup->speed].rate; -+ setup->speed_freq = i2c_priv->speed; - setup->clock_src = clk_get_rate(&i2c_priv->clk); - - if (!setup->clock_src) { -@@ -719,13 +733,11 @@ static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv, - if (ret) { - debug("%s: failed to compute I2C timings.\n", - __func__); -- if (i2c_priv->speed > STM32_I2C_SPEED_STANDARD) { -- i2c_priv->speed--; -- setup->speed = i2c_priv->speed; -+ if (setup->speed_freq > STANDARD_RATE) { - setup->speed_freq = -- i2c_specs[setup->speed].rate; -+ get_lower_rate(setup->speed_freq); - debug("%s: downgrade I2C Speed Freq to (%i)\n", -- __func__, i2c_specs[setup->speed].rate); -+ __func__, setup->speed_freq); - } else { - break; - } -@@ -737,13 +749,15 @@ static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv, - return ret; - } - -- debug("%s: I2C Speed(%i), Freq(%i), Clk Source(%i)\n", __func__, -- setup->speed, setup->speed_freq, setup->clock_src); -+ debug("%s: I2C Freq(%i), Clk Source(%i)\n", __func__, -+ setup->speed_freq, setup->clock_src); - debug("%s: I2C Rise(%i) and Fall(%i) Time\n", __func__, - setup->rise_time, setup->fall_time); - debug("%s: I2C Analog Filter(%s), DNF(%i)\n", __func__, - setup->analog_filter ? "On" : "Off", setup->dnf); - -+ i2c_priv->speed = setup->speed_freq; -+ - return 0; - } - -@@ -783,21 +797,13 @@ static int stm32_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) - { - struct stm32_i2c_priv *i2c_priv = dev_get_priv(bus); - -- switch (speed) { -- case STANDARD_RATE: -- i2c_priv->speed = STM32_I2C_SPEED_STANDARD; -- break; -- case FAST_RATE: -- i2c_priv->speed = STM32_I2C_SPEED_FAST; -- break; -- case FAST_PLUS_RATE: -- i2c_priv->speed = STM32_I2C_SPEED_FAST_PLUS; -- break; -- default: -+ if (speed > FAST_PLUS_RATE) { - debug("%s: Speed %d not supported\n", __func__, speed); - return -EINVAL; - } - -+ i2c_priv->speed = speed; -+ - return stm32_i2c_hw_config(i2c_priv); - } - -diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c -index f73f072..79ced50 100644 ---- a/drivers/mmc/mmc-uclass.c -+++ b/drivers/mmc/mmc-uclass.c -@@ -120,6 +120,20 @@ int mmc_execute_tuning(struct mmc *mmc, uint opcode) - } - #endif - -+int dm_mmc_host_power_cycle(struct udevice *dev) -+{ -+ struct dm_mmc_ops *ops = mmc_get_ops(dev); -+ -+ if (ops->host_power_cycle) -+ return ops->host_power_cycle(dev); -+ return 0; -+} -+ -+int mmc_host_power_cycle(struct mmc *mmc) -+{ -+ return dm_mmc_host_power_cycle(mmc->dev); -+} -+ - int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg) - { - int val; -diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c -index 585951c..826565f 100644 ---- a/drivers/mmc/mmc.c -+++ b/drivers/mmc/mmc.c -@@ -1486,6 +1486,16 @@ static int mmc_set_ios(struct mmc *mmc) - - return ret; - } -+ -+static int mmc_host_power_cycle(struct mmc *mmc) -+{ -+ int ret = 0; -+ -+ if (mmc->cfg->ops->host_power_cycle) -+ ret = mmc->cfg->ops->host_power_cycle(mmc); -+ -+ return ret; -+} - #endif - - int mmc_set_clock(struct mmc *mmc, uint clock, bool disable) -@@ -2566,6 +2576,11 @@ static int mmc_power_cycle(struct mmc *mmc) - ret = mmc_power_off(mmc); - if (ret) - return ret; -+ -+ ret = mmc_host_power_cycle(mmc); -+ if (ret) -+ return ret; -+ - /* - * SD spec recommends at least 1ms of delay. Let's wait for 2ms - * to be on the safer side. -diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c -index 32434a4..1726ed7 100644 ---- a/drivers/mmc/stm32_sdmmc2.c -+++ b/drivers/mmc/stm32_sdmmc2.c -@@ -524,8 +524,6 @@ static void stm32_sdmmc2_pwrcycle(struct stm32_sdmmc2_priv *priv) - return; - - stm32_sdmmc2_reset(priv); -- writel(SDMMC_POWER_PWRCTRL_CYCLE | priv->pwr_reg_msk, -- priv->base + SDMMC_POWER); - } - - /* -@@ -619,10 +617,21 @@ static int stm32_sdmmc2_getcd(struct udevice *dev) - return 1; - } - -+static int stm32_sdmmc2_host_power_cycle(struct udevice *dev) -+{ -+ struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); -+ -+ writel(SDMMC_POWER_PWRCTRL_CYCLE | priv->pwr_reg_msk, -+ priv->base + SDMMC_POWER); -+ -+ return 0; -+} -+ - static const struct dm_mmc_ops stm32_sdmmc2_ops = { - .send_cmd = stm32_sdmmc2_send_cmd, - .set_ios = stm32_sdmmc2_set_ios, - .get_cd = stm32_sdmmc2_getcd, -+ .host_power_cycle = stm32_sdmmc2_host_power_cycle, - }; - - static int stm32_sdmmc2_probe(struct udevice *dev) -diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c -index 5b933fb..d8887c1 100644 ---- a/drivers/net/dwc_eth_qos.c -+++ b/drivers/net/dwc_eth_qos.c -@@ -692,6 +692,30 @@ static int eqos_start_resets_tegra186(struct udevice *dev) - - 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; - } - -@@ -707,6 +731,11 @@ static int eqos_stop_resets_tegra186(struct udevice *dev) - - static int eqos_stop_resets_stm32(struct udevice *dev) - { -+ struct eqos_priv *eqos = dev_get_priv(dev); -+ -+ if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) -+ dm_gpio_set_value(&eqos->phy_reset_gpio, 1); -+ - return 0; - } - -@@ -1604,7 +1633,7 @@ static int eqos_probe_resources_stm32(struct udevice *dev) - int interface; - bool eth_clk_sel_reg = false; - bool eth_ref_clk_sel_reg = false; -- -+ struct ofnode_phandle_args phandle_args; - - debug("%s(dev=%p):\n", __func__, dev); - -@@ -1650,6 +1679,19 @@ static int eqos_probe_resources_stm32(struct udevice *dev) - if (ret) - pr_warn("No phy clock provided %d", ret); - -+ /* search "reset-gpios" in phy node */ -+ ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, -+ &phandle_args); -+ if (!ret) { -+ 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); -+ - debug("%s: OK\n", __func__); - return 0; - -@@ -1713,6 +1755,9 @@ static int eqos_remove_resources_stm32(struct udevice *dev) - if (clk_valid(&eqos->clk_ck)) - clk_free(&eqos->clk_ck); - -+ if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) -+ dm_gpio_free(dev, &eqos->phy_reset_gpio); -+ - debug("%s: OK\n", __func__); - return 0; - } -diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c -index f6484da..c87882d 100644 ---- a/drivers/ram/stm32mp1/stm32mp1_ddr.c -+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c -@@ -855,14 +855,34 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - { - u32 pir; - int ret = -EINVAL; -+ char bus_width; -+ -+ switch (config->c_reg.mstr & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) { -+ case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER: -+ bus_width = 8; -+ break; -+ case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF: -+ bus_width = 16; -+ break; -+ default: -+ bus_width = 32; -+ break; -+ } -+ - - if (config->c_reg.mstr & DDRCTRL_MSTR_DDR3) - ret = board_ddr_power_init(STM32MP_DDR3); -- else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2) -- ret = board_ddr_power_init(STM32MP_LPDDR2); -- else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3) -- ret = board_ddr_power_init(STM32MP_LPDDR3); -- -+ else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2) { -+ if (bus_width == 32) -+ ret = board_ddr_power_init(STM32MP_LPDDR2_32); -+ else -+ ret = board_ddr_power_init(STM32MP_LPDDR2_16); -+ } else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3) { -+ if (bus_width == 32) -+ ret = board_ddr_power_init(STM32MP_LPDDR3_32); -+ else -+ ret = board_ddr_power_init(STM32MP_LPDDR3_16); -+ } - if (ret) - panic("ddr power init failed\n"); - -diff --git a/drivers/ram/stm32mp1/stm32mp1_interactive.c b/drivers/ram/stm32mp1/stm32mp1_interactive.c -index 8df6a39..62da596 100644 ---- a/drivers/ram/stm32mp1/stm32mp1_interactive.c -+++ b/drivers/ram/stm32mp1/stm32mp1_interactive.c -@@ -367,7 +367,6 @@ bool stm32mp1_ddr_interactive(void *priv, - enum stm32mp1_ddr_interact_step step, - const struct stm32mp1_ddr_config *config) - { -- const char *prompt = "DDR>"; - char buffer[CONFIG_SYS_CBSIZE]; - char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ - int argc; -@@ -403,13 +402,12 @@ bool stm32mp1_ddr_interactive(void *priv, - } - - printf("%d:%s\n", step, step_str[step]); -- printf("%s\n", prompt); - - if (next_step > step) - return false; - - while (next_step == step) { -- cli_readline_into_buffer(prompt, buffer, 0); -+ cli_readline_into_buffer("DDR>", buffer, 0); - argc = cli_simple_parse_line(buffer, argv); - if (!argc) - continue; -diff --git a/drivers/remoteproc/rproc-uclass.c b/drivers/remoteproc/rproc-uclass.c -index 36f1e97..89eed8c 100644 ---- a/drivers/remoteproc/rproc-uclass.c -+++ b/drivers/remoteproc/rproc-uclass.c -@@ -244,6 +244,7 @@ UCLASS_DRIVER(rproc) = { - .flags = DM_UC_FLAG_SEQ_ALIAS, - .pre_probe = rproc_pre_probe, - .post_probe = rproc_post_probe, -+ .per_device_auto_alloc_size = sizeof(struct rproc_priv), - .per_device_platdata_auto_alloc_size = - sizeof(struct dm_rproc_uclass_pdata), - }; -@@ -432,7 +433,7 @@ static int rproc_load_elf_image(struct udevice *dev, unsigned long addr, - } - - /* Load each program header */ -- for (i = 0; i < ehdr->e_phnum; ++i) { -+ for (i = 0; i < ehdr->e_phnum; ++i, phdr++) { - void *dst = (void *)(uintptr_t)phdr->p_paddr; - void *src = (void *)addr + phdr->p_offset; - -@@ -453,7 +454,6 @@ static int rproc_load_elf_image(struct udevice *dev, unsigned long addr, - roundup((unsigned long)dst + phdr->p_filesz, - ARCH_DMA_MINALIGN) - - rounddown((unsigned long)dst, ARCH_DMA_MINALIGN)); -- ++phdr; - } - - *entry = ehdr->e_entry; -@@ -625,6 +625,7 @@ int rproc_load_rsc_table(int id, ulong addr, ulong size, ulong *rsc_addr, - { - struct udevice *dev = NULL; - const struct dm_rproc_ops *ops; -+ struct rproc_priv *priv; - int ret; - - ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev); -@@ -640,23 +641,27 @@ int rproc_load_rsc_table(int id, ulong addr, ulong size, ulong *rsc_addr, - return -EINVAL; - } - -- dev_dbg(dev, "Loocking for resource table from address 0x%08lX size of %lu bytes\n", -+ dev_dbg(dev, "Looking for resource table from address 0x%08lX size of %lu bytes\n", - addr, size); - -- if (!rproc_elf_sanity_check(dev, addr, size)) { -- /* load elf image */ -- ret = rproc_elf_find_load_rsc_table(dev, addr, size, rsc_addr, -- rsc_size); -- if (ret) { -- dev_dbg(dev, "No resource table found\n"); -- return -ENODATA; -- } -- dev_dbg(dev, "Resource table at 0x%08lx, size 0x%x!\n", -- *rsc_addr, *rsc_size); -- return 0; -+ ret = rproc_elf_sanity_check(dev, addr, size); -+ if (ret) -+ return ret; -+ -+ ret = rproc_elf_find_load_rsc_table(dev, addr, size, rsc_addr, -+ rsc_size); -+ if (ret) { -+ dev_dbg(dev, "No resource table found\n"); -+ return -ENODATA; - } - -- return -ENODATA; -+ priv = dev_get_uclass_priv(dev); -+ priv->rsc_table_addr = *rsc_addr; -+ priv->rsc_table_size = *rsc_size; -+ dev_dbg(dev, "Resource table at 0x%08lx, size 0x%x!\n", -+ priv->rsc_table_addr, priv->rsc_table_size); -+ -+ return 0; - }; - - /* -diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c -index 0a8b900..9fed8c8 100644 ---- a/drivers/remoteproc/stm32_copro.c -+++ b/drivers/remoteproc/stm32_copro.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - - #define RCC_GCR_HOLD_BOOT 0 - #define RCC_GCR_RELEASE_BOOT 1 -@@ -202,6 +203,7 @@ static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size) - */ - static int stm32_copro_start(struct udevice *dev) - { -+ struct rproc_priv *uc_priv = dev_get_uclass_priv(dev); - int ret; - - /* move hold boot from true to false start the copro */ -@@ -213,7 +215,12 @@ static int stm32_copro_start(struct udevice *dev) - * Once copro running, reset hold boot flag to avoid copro - * rebooting autonomously - */ -- return stm32_copro_set_hold_boot(dev, true); -+ ret = stm32_copro_set_hold_boot(dev, true); -+ if (!ret) -+ /* Store rsc_address in bkp register */ -+ writel(uc_priv->rsc_table_addr, TAMP_COPRO_RSC_TBL_ADDRESS); -+ -+ return ret; - } - - /** -diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig -index 8809552..890212de 100644 ---- a/drivers/video/Kconfig -+++ b/drivers/video/Kconfig -@@ -74,7 +74,8 @@ config VIDEO_ANSI - console. - - config VIDEO_MIPI_DSI -- bool -+ bool "Support MIPI DSI interface" -+ depends on DM_VIDEO - help - Support MIPI DSI interface for driving a MIPI compatible device. - The MIPI Display Serial Interface (MIPI DSI) defines a high-speed -@@ -332,16 +333,18 @@ config VIDEO_LCD_ORISETECH_OTM8009A - depends on DM_VIDEO - select VIDEO_MIPI_DSI - default n -- ---help--- -- Support for Orise Tech otm8009a 480p dsi 2dl video mode panel. -+ help -+ Say Y here if you want to enable support for Orise Technology -+ otm8009a 480x800 dsi 2dl panel. - - config VIDEO_LCD_RAYDIUM_RM68200 - bool "RM68200 DSI LCD panel support" - depends on DM_VIDEO - select VIDEO_MIPI_DSI - default n -- ---help--- -- Support for Raydium rm68200 720x1280 dsi 2dl video mode panel. -+ help -+ Say Y here if you want to enable support for Raydium RM68200 -+ 720x1280 DSI video mode panel. - - config VIDEO_LCD_SSD2828 - bool "SSD2828 bridge chip" -diff --git a/drivers/video/Makefile b/drivers/video/Makefile -index c3d39ed..796eb6c 100644 ---- a/drivers/video/Makefile -+++ b/drivers/video/Makefile -@@ -11,6 +11,7 @@ obj-$(CONFIG_CONSOLE_ROTATION) += console_rotate.o - obj-$(CONFIG_CONSOLE_TRUETYPE) += console_truetype.o fonts/ - obj-$(CONFIG_DISPLAY) += display-uclass.o - obj-$(CONFIG_DM_VIDEO) += backlight-uclass.o -+obj-$(CONFIG_DM_VIDEO) += dsi-host-uclass.o - obj-$(CONFIG_DM_VIDEO) += panel-uclass.o simple_panel.o - obj-$(CONFIG_DM_VIDEO) += video-uclass.o vidconsole-uclass.o - obj-$(CONFIG_DM_VIDEO) += video_bmp.o -@@ -44,6 +45,7 @@ obj-$(CONFIG_VIDEO_BROADWELL_IGD) += broadwell_igd.o - obj-$(CONFIG_VIDEO_COREBOOT) += coreboot.o - obj-$(CONFIG_VIDEO_DA8XX) += da8xx-fb.o videomodes.o - obj-$(CONFIG_VIDEO_DW_HDMI) += dw_hdmi.o -+obj-$(CONFIG_VIDEO_DW_MIPI_DSI) += dw_mipi_dsi.o - obj-$(CONFIG_VIDEO_EFI) += efi.o - obj-$(CONFIG_VIDEO_FSL_DCU_FB) += fsl_dcu_fb.o videomodes.o - obj-$(CONFIG_VIDEO_IPUV3) += mxc_ipuv3_fb.o ipu_common.o ipu_disp.o -@@ -54,6 +56,7 @@ obj-$(CONFIG_VIDEO_LCD_ORISETECH_OTM8009A) += orisetech_otm8009a.o - obj-$(CONFIG_VIDEO_LCD_RAYDIUM_RM68200) += raydium-rm68200.o - obj-$(CONFIG_VIDEO_LCD_SSD2828) += ssd2828.o - obj-$(CONFIG_VIDEO_MB862xx) += mb862xx.o videomodes.o -+obj-${CONFIG_VIDEO_MIPI_DSI} += mipi_dsi.o - obj-$(CONFIG_VIDEO_MVEBU) += mvebu_lcd.o - obj-$(CONFIG_VIDEO_MX3) += mx3fb.o videomodes.o - obj-$(CONFIG_VIDEO_MXS) += mxsfb.o videomodes.o -@@ -63,8 +66,6 @@ obj-$(CONFIG_VIDEO_SIMPLE) += simplefb.o - obj-$(CONFIG_VIDEO_TEGRA20) += tegra.o - obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o - obj-$(CONFIG_VIDEO_VESA) += vesa.o --obj-$(CONFIG_VIDEO_DW_MIPI_DSI) += dw_mipi_dsi.o --obj-${CONFIG_VIDEO_MIPI_DSI} += mipi_display.o - - obj-y += bridge/ - obj-y += sunxi/ -diff --git a/drivers/video/dsi-host-uclass.c b/drivers/video/dsi-host-uclass.c -new file mode 100644 -index 0000000..1db1f88 ---- /dev/null -+++ b/drivers/video/dsi-host-uclass.c -@@ -0,0 +1,39 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2019 STMicroelectronics - All Rights Reserved -+ * Author(s): Yannick Fertre for STMicroelectronics. -+ * -+ */ -+ -+#include -+#include -+#include -+ -+int dsi_host_init(struct udevice *dev, -+ struct mipi_dsi_device *device, -+ struct display_timing *timings, -+ unsigned int max_data_lanes, -+ const struct mipi_dsi_phy_ops *phy_ops) -+{ -+ struct dsi_host_ops *ops = dsi_host_get_ops(dev); -+ -+ if (!ops->init) -+ return -ENOSYS; -+ -+ return ops->init(dev, device, timings, max_data_lanes, phy_ops); -+} -+ -+int dsi_host_enable(struct udevice *dev) -+{ -+ struct dsi_host_ops *ops = dsi_host_get_ops(dev); -+ -+ if (!ops->enable) -+ return -ENOSYS; -+ -+ return ops->enable(dev); -+} -+ -+UCLASS_DRIVER(dsi_host) = { -+ .id = UCLASS_DSI_HOST, -+ .name = "dsi_host", -+}; -diff --git a/drivers/video/dw_mipi_dsi.c b/drivers/video/dw_mipi_dsi.c -index fe1e25a..83d7c7b 100644 ---- a/drivers/video/dw_mipi_dsi.c -+++ b/drivers/video/dw_mipi_dsi.c -@@ -1,25 +1,24 @@ - // SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright (C) 2016, Fuzhou Rockchip Electronics Co., Ltd -- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved - * Author(s): Philippe Cornu for STMicroelectronics. - * Yannick Fertre for STMicroelectronics. - * -- * This generic Synopsys DesignWare MIPI DSI host driver is based on the -- * Linux Kernel driver from drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c. -+ * This generic Synopsys DesignWare MIPI DSI host driver is inspired from -+ * the Linux Kernel driver drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c. - */ - - #include - #include -+#include - #include - #include --#include - #include - #include - #include - #include - #include --#include - #include - #include - -@@ -221,11 +220,8 @@ struct dw_mipi_dsi { - void __iomem *base; - unsigned int lane_mbps; /* per lane */ - u32 channel; -- u32 lanes; -- u32 format; -- unsigned long mode_flags; - unsigned int max_data_lanes; -- const struct dw_mipi_dsi_phy_ops *phy_ops; -+ const struct mipi_dsi_phy_ops *phy_ops; - }; - - static int dsi_mode_vrefresh(struct display_timing *timings) -@@ -286,10 +282,7 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host, - return -EINVAL; - } - -- dsi->lanes = device->lanes; - dsi->channel = device->channel; -- dsi->format = device->format; -- dsi->mode_flags = device->mode_flags; - - return 0; - } -@@ -444,6 +437,7 @@ static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = { - - static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) - { -+ struct mipi_dsi_device *device = dsi->device; - u32 val; - - /* -@@ -453,9 +447,9 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) - */ - val = ENABLE_LOW_POWER; - -- if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) -+ if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) - val |= VID_MODE_TYPE_BURST; -- else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) -+ else if (device->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) - val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES; - else - val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS; -@@ -466,6 +460,8 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) - static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi, - unsigned long mode_flags) - { -+ const struct mipi_dsi_phy_ops *phy_ops = dsi->phy_ops; -+ - dsi_write(dsi, DSI_PWR_UP, RESET); - - if (mode_flags & MIPI_DSI_MODE_VIDEO) { -@@ -476,10 +472,13 @@ static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi, - dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE); - } - -+ if (phy_ops->post_set_mode) -+ phy_ops->post_set_mode(dsi->device, mode_flags); -+ - dsi_write(dsi, DSI_PWR_UP, POWERUP); - } - --static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi) -+static void dw_mipi_dsi_init_pll(struct dw_mipi_dsi *dsi) - { - /* - * The maximum permitted escape clock is 20MHz and it is derived from -@@ -505,9 +504,10 @@ static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi) - static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi, - struct display_timing *timings) - { -+ struct mipi_dsi_device *device = dsi->device; - u32 val = 0, color = 0; - -- switch (dsi->format) { -+ switch (device->format) { - case MIPI_DSI_FMT_RGB888: - color = DPI_COLOR_CODING_24BIT; - break; -@@ -522,9 +522,9 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi, - break; - } - -- if (dsi->mode_flags & DISPLAY_FLAGS_VSYNC_HIGH) -+ if (device->mode_flags & DISPLAY_FLAGS_VSYNC_HIGH) - val |= VSYNC_ACTIVE_LOW; -- if (dsi->mode_flags & DISPLAY_FLAGS_HSYNC_HIGH) -+ if (device->mode_flags & DISPLAY_FLAGS_HSYNC_HIGH) - val |= HSYNC_ACTIVE_LOW; - - dsi_write(dsi, DSI_DPI_VCID, DPI_VCID(dsi->channel)); -@@ -560,6 +560,8 @@ static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi, - - static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi) - { -+ const struct mipi_dsi_phy_ops *phy_ops = dsi->phy_ops; -+ - /* - * TODO dw drv improvements - * compute high speed transmission counter timeout according -@@ -573,6 +575,9 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi) - */ - dsi_write(dsi, DSI_BTA_TO_CNT, 0xd00); - dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE); -+ -+ if (phy_ops->post_set_mode) -+ phy_ops->post_set_mode(dsi->device, 0); - } - - /* Get lane byte clock cycles. */ -@@ -662,13 +667,15 @@ static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi) - - static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi) - { -+ struct mipi_dsi_device *device = dsi->device; -+ - /* - * TODO dw drv improvements - * stop wait time should be the maximum between host dsi - * and panel stop wait times - */ - dsi_write(dsi, DSI_PHY_IF_CFG, PHY_STOP_WAIT_TIME(0x20) | -- N_LANES(dsi->lanes)); -+ N_LANES(device->lanes)); - } - - static void dw_mipi_dsi_dphy_init(struct dw_mipi_dsi *dsi) -@@ -712,15 +719,16 @@ static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi) - static void dw_mipi_dsi_bridge_set(struct dw_mipi_dsi *dsi, - struct display_timing *timings) - { -- const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->phy_ops; -+ const struct mipi_dsi_phy_ops *phy_ops = dsi->phy_ops; -+ struct mipi_dsi_device *device = dsi->device; - int ret; - -- ret = phy_ops->get_lane_mbps(dsi->device, timings, dsi->lanes, -- dsi->format, &dsi->lane_mbps); -+ 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"); - -- dw_mipi_dsi_init(dsi); -+ dw_mipi_dsi_init_pll(dsi); - dw_mipi_dsi_dpi_config(dsi, timings); - dw_mipi_dsi_packet_handler_config(dsi); - dw_mipi_dsi_video_mode_config(dsi); -@@ -747,62 +755,33 @@ static void dw_mipi_dsi_bridge_set(struct dw_mipi_dsi *dsi, - dw_mipi_dsi_set_mode(dsi, 0); - } - --void dw_mipi_dsi_bridge_enable(struct mipi_dsi_device *device) -+static int dw_mipi_dsi_init(struct udevice *dev, -+ struct mipi_dsi_device *device, -+ struct display_timing *timings, -+ unsigned int max_data_lanes, -+ const struct mipi_dsi_phy_ops *phy_ops) - { -- struct mipi_dsi_host *host = device->host; -- struct dw_mipi_dsi *dsi = host_to_dsi(host); -- -- /* Switch to video mode for panel-bridge enable & panel enable */ -- dw_mipi_dsi_set_mode(dsi, MIPI_DSI_MODE_VIDEO); --} --EXPORT_SYMBOL_GPL(dw_mipi_dsi_bridge_enable); -- --int dw_mipi_dsi_init_bridge(struct mipi_dsi_device *device) --{ -- struct dw_mipi_dsi_plat_data *platdata = dev_get_platdata(device->dev); -- struct udevice *panel = platdata->panel; -- struct display_timing timings; -- struct dw_mipi_dsi *dsi; -+ struct dw_mipi_dsi *dsi = dev_get_priv(dev); - struct clk clk; - int ret; - -- dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); -+ if (!phy_ops->init || !phy_ops->get_lane_mbps) { -+ dev_err(device->dev, "Phy not properly configured\n"); -+ return -ENODEV; -+ } - -- dsi->phy_ops = platdata->phy_ops; -- dsi->max_data_lanes = platdata->max_data_lanes; -+ dsi->phy_ops = phy_ops; -+ dsi->max_data_lanes = max_data_lanes; - dsi->device = device; - dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; - device->host = &dsi->dsi_host; - -- /* TODO Get these settings from panel */ -- dsi->lanes = 2; -- dsi->format = MIPI_DSI_FMT_RGB888; -- dsi->mode_flags = MIPI_DSI_MODE_VIDEO | -- MIPI_DSI_MODE_VIDEO_BURST | -- MIPI_DSI_MODE_LPM; -- - dsi->base = (void *)dev_read_addr(device->dev); - if ((fdt_addr_t)dsi->base == FDT_ADDR_T_NONE) { - dev_err(device->dev, "dsi dt register address error\n"); - return -EINVAL; - } - -- ret = panel_get_display_timing(panel, &timings); -- if (ret) { -- ret = fdtdec_decode_display_timing(gd->fdt_blob, -- dev_of_offset(panel), -- 0, &timings); -- if (ret) { -- dev_err(dev, "decode display timing error %d\n", ret); -- return ret; -- } -- } -- -- if (!dsi->phy_ops->init || !dsi->phy_ops->get_lane_mbps) { -- dev_err(device->dev, "Phy not properly configured\n"); -- return -ENODEV; -- } -- - ret = clk_get_by_name(device->dev, "px_clk", &clk); - if (ret) { - dev_err(device->dev, "peripheral clock get error %d\n", ret); -@@ -810,13 +789,40 @@ int dw_mipi_dsi_init_bridge(struct mipi_dsi_device *device) - } - - /* get the pixel clock set by the clock framework */ -- timings.pixelclock.typ = clk_get_rate(&clk); -+ timings->pixelclock.typ = clk_get_rate(&clk); - -- dw_mipi_dsi_bridge_set(dsi, &timings); -+ dw_mipi_dsi_bridge_set(dsi, timings); - - return 0; - } --EXPORT_SYMBOL_GPL(dw_mipi_dsi_init_bridge); -+ -+static int dw_mipi_dsi_enable(struct udevice *dev) -+{ -+ struct dw_mipi_dsi *dsi = dev_get_priv(dev); -+ -+ /* Switch to video mode for panel-bridge enable & panel enable */ -+ dw_mipi_dsi_set_mode(dsi, MIPI_DSI_MODE_VIDEO); -+ -+ return 0; -+} -+ -+struct dsi_host_ops dw_mipi_dsi_ops = { -+ .init = dw_mipi_dsi_init, -+ .enable = dw_mipi_dsi_enable, -+}; -+ -+static int dw_mipi_dsi_probe(struct udevice *dev) -+{ -+ return 0; -+} -+ -+U_BOOT_DRIVER(dw_mipi_dsi) = { -+ .name = "dw_mipi_dsi", -+ .id = UCLASS_DSI_HOST, -+ .probe = dw_mipi_dsi_probe, -+ .ops = &dw_mipi_dsi_ops, -+ .priv_auto_alloc_size = sizeof(struct dw_mipi_dsi), -+}; - - MODULE_AUTHOR("Chris Zhong "); - MODULE_AUTHOR("Philippe Cornu "); -diff --git a/drivers/video/mipi_display.c b/drivers/video/mipi_display.c -deleted file mode 100644 -index 611ee53..0000000 ---- a/drivers/video/mipi_display.c -+++ /dev/null -@@ -1,817 +0,0 @@ --/* -- * MIPI DSI Bus -- * -- * Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd. -- * Copyright (C) 2018 STMicroelectronics - All Rights Reserved -- * Andrzej Hajda -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the -- * "Software"), to deal in the Software without restriction, including -- * without limitation the rights to use, copy, modify, merge, publish, -- * distribute, sub license, and/or sell copies of the Software, and to -- * permit persons to whom the Software is furnished to do so, subject to -- * the following conditions: -- * -- * The above copyright notice and this permission notice (including the -- * next paragraph) shall be included in all copies or substantial portions -- * of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, -- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -- * USE OR OTHER DEALINGS IN THE SOFTWARE. -- * -- * Mipi_display.c contains a set of dsi helpers. -- * This file is based on the drm helper file drivers/gpu/drm/drm_mipi_dsi.c -- * (kernel linux). -- * -- */ -- --#include --#include --#include --#include --#include -- --/** -- * DOC: dsi helpers -- * -- * These functions contain some common logic and helpers to deal with MIPI DSI -- * peripherals. -- * -- * Helpers are provided for a number of standard MIPI DSI command as well as a -- * subset of the MIPI DCS command set. -- */ -- --/** -- * mipi_dsi_attach - attach a DSI device to its DSI host -- * @dsi: DSI peripheral -- */ --int mipi_dsi_attach(struct mipi_dsi_device *dsi) --{ -- const struct mipi_dsi_host_ops *ops = dsi->host->ops; -- -- if (!ops || !ops->attach) -- return -ENOSYS; -- -- return ops->attach(dsi->host, dsi); --} --EXPORT_SYMBOL(mipi_dsi_attach); -- --/** -- * mipi_dsi_detach - detach a DSI device from its DSI host -- * @dsi: DSI peripheral -- */ --int mipi_dsi_detach(struct mipi_dsi_device *dsi) --{ -- const struct mipi_dsi_host_ops *ops = dsi->host->ops; -- -- if (!ops || !ops->detach) -- return -ENOSYS; -- -- return ops->detach(dsi->host, dsi); --} --EXPORT_SYMBOL(mipi_dsi_detach); -- --/** -- * mipi_dsi_device_transfer - transfer message to a DSI device -- * @dsi: DSI peripheral -- * @msg: message -- */ --static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi, -- struct mipi_dsi_msg *msg) --{ -- const struct mipi_dsi_host_ops *ops = dsi->host->ops; -- -- if (!ops || !ops->transfer) -- return -ENOSYS; -- -- if (dsi->mode_flags & MIPI_DSI_MODE_LPM) -- msg->flags |= MIPI_DSI_MSG_USE_LPM; -- -- return ops->transfer(dsi->host, msg); --} -- --/** -- * mipi_dsi_packet_format_is_short - check if a packet is of the short format -- * @type: MIPI DSI data type of the packet -- * -- * Return: true if the packet for the given data type is a short packet, false -- * otherwise. -- */ --bool mipi_dsi_packet_format_is_short(u8 type) --{ -- switch (type) { -- case MIPI_DSI_V_SYNC_START: -- case MIPI_DSI_V_SYNC_END: -- case MIPI_DSI_H_SYNC_START: -- case MIPI_DSI_H_SYNC_END: -- case MIPI_DSI_END_OF_TRANSMISSION: -- case MIPI_DSI_COLOR_MODE_OFF: -- case MIPI_DSI_COLOR_MODE_ON: -- case MIPI_DSI_SHUTDOWN_PERIPHERAL: -- case MIPI_DSI_TURN_ON_PERIPHERAL: -- case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: -- case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM: -- case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: -- case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM: -- case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM: -- case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM: -- case MIPI_DSI_DCS_SHORT_WRITE: -- case MIPI_DSI_DCS_SHORT_WRITE_PARAM: -- case MIPI_DSI_DCS_READ: -- case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE: -- return true; -- } -- -- return false; --} --EXPORT_SYMBOL(mipi_dsi_packet_format_is_short); -- --/** -- * mipi_dsi_packet_format_is_long - check if a packet is of the long format -- * @type: MIPI DSI data type of the packet -- * -- * Return: true if the packet for the given data type is a long packet, false -- * otherwise. -- */ --bool mipi_dsi_packet_format_is_long(u8 type) --{ -- switch (type) { -- case MIPI_DSI_NULL_PACKET: -- case MIPI_DSI_BLANKING_PACKET: -- case MIPI_DSI_GENERIC_LONG_WRITE: -- case MIPI_DSI_DCS_LONG_WRITE: -- case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20: -- case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24: -- case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16: -- case MIPI_DSI_PACKED_PIXEL_STREAM_30: -- case MIPI_DSI_PACKED_PIXEL_STREAM_36: -- case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12: -- case MIPI_DSI_PACKED_PIXEL_STREAM_16: -- case MIPI_DSI_PACKED_PIXEL_STREAM_18: -- case MIPI_DSI_PIXEL_STREAM_3BYTE_18: -- case MIPI_DSI_PACKED_PIXEL_STREAM_24: -- return true; -- } -- -- return false; --} --EXPORT_SYMBOL(mipi_dsi_packet_format_is_long); -- --/** -- * mipi_dsi_create_packet - create a packet from a message according to the -- * DSI protocol -- * @packet: pointer to a DSI packet structure -- * @msg: message to translate into a packet -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, -- const struct mipi_dsi_msg *msg) --{ -- if (!packet || !msg) -- return -EINVAL; -- -- /* do some minimum sanity checking */ -- if (!mipi_dsi_packet_format_is_short(msg->type) && -- !mipi_dsi_packet_format_is_long(msg->type)) -- return -EINVAL; -- -- if (msg->channel > 3) -- return -EINVAL; -- -- memset(packet, 0, sizeof(*packet)); -- packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f); -- -- /* TODO: compute ECC if hardware support is not available */ -- -- /* -- * Long write packets contain the word count in header bytes 1 and 2. -- * The payload follows the header and is word count bytes long. -- * -- * Short write packets encode up to two parameters in header bytes 1 -- * and 2. -- */ -- if (mipi_dsi_packet_format_is_long(msg->type)) { -- packet->header[1] = (msg->tx_len >> 0) & 0xff; -- packet->header[2] = (msg->tx_len >> 8) & 0xff; -- -- packet->payload_length = msg->tx_len; -- packet->payload = msg->tx_buf; -- } else { -- const u8 *tx = msg->tx_buf; -- -- packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0; -- packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0; -- } -- -- packet->size = sizeof(packet->header) + packet->payload_length; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_create_packet); -- --/* -- * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the -- * the payload in a long packet transmitted from the peripheral back to the -- * host processor -- * @dsi: DSI peripheral device -- * @value: the maximum size of the payload -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, -- u16 value) --{ -- u8 tx[2] = { value & 0xff, value >> 8 }; -- struct mipi_dsi_msg msg = { -- .channel = dsi->channel, -- .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, -- .tx_len = sizeof(tx), -- .tx_buf = tx, -- }; -- int ret = mipi_dsi_device_transfer(dsi, &msg); -- -- return (ret < 0) ? ret : 0; --} --EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); -- --/** -- * mipi_dsi_generic_write() - transmit data using a generic write packet -- * @dsi: DSI peripheral device -- * @payload: buffer containing the payload -- * @size: size of payload buffer -- * -- * This function will automatically choose the right data type depending on -- * the payload length. -- * -- * Return: The number of bytes transmitted on success or a negative error code -- * on failure. -- */ --ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, -- size_t size) --{ -- struct mipi_dsi_msg msg = { -- .channel = dsi->channel, -- .tx_buf = payload, -- .tx_len = size -- }; -- -- switch (size) { -- case 0: -- msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM; -- break; -- -- case 1: -- msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM; -- break; -- -- case 2: -- msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM; -- break; -- -- default: -- msg.type = MIPI_DSI_GENERIC_LONG_WRITE; -- break; -- } -- -- return mipi_dsi_device_transfer(dsi, &msg); --} --EXPORT_SYMBOL(mipi_dsi_generic_write); -- --/** -- * mipi_dsi_generic_read() - receive data using a generic read packet -- * @dsi: DSI peripheral device -- * @params: buffer containing the request parameters -- * @num_params: number of request parameters -- * @data: buffer in which to return the received data -- * @size: size of receive buffer -- * -- * This function will automatically choose the right data type depending on -- * the number of parameters passed in. -- * -- * Return: The number of bytes successfully read or a negative error code on -- * failure. -- */ --ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, -- size_t num_params, void *data, size_t size) --{ -- struct mipi_dsi_msg msg = { -- .channel = dsi->channel, -- .tx_len = num_params, -- .tx_buf = params, -- .rx_len = size, -- .rx_buf = data -- }; -- -- switch (num_params) { -- case 0: -- msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM; -- break; -- -- case 1: -- msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM; -- break; -- -- case 2: -- msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM; -- break; -- -- default: -- return -EINVAL; -- } -- -- return mipi_dsi_device_transfer(dsi, &msg); --} --EXPORT_SYMBOL(mipi_dsi_generic_read); -- --/** -- * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload -- * @dsi: DSI peripheral device -- * @data: buffer containing data to be transmitted -- * @len: size of transmission buffer -- * -- * This function will automatically choose the right data type depending on -- * the command payload length. -- * -- * Return: The number of bytes successfully transmitted or a negative error -- * code on failure. -- */ --ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, -- const void *data, size_t len) --{ -- struct mipi_dsi_msg msg = { -- .channel = dsi->channel, -- .tx_buf = data, -- .tx_len = len -- }; -- -- switch (len) { -- case 0: -- return -EINVAL; -- -- case 1: -- msg.type = MIPI_DSI_DCS_SHORT_WRITE; -- break; -- -- case 2: -- msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; -- break; -- -- default: -- msg.type = MIPI_DSI_DCS_LONG_WRITE; -- break; -- } -- -- return mipi_dsi_device_transfer(dsi, &msg); --} --EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer); -- --/** -- * mipi_dsi_dcs_write() - send DCS write command -- * @dsi: DSI peripheral device -- * @cmd: DCS command -- * @data: buffer containing the command payload -- * @len: command payload length -- * -- * This function will automatically choose the right data type depending on -- * the command payload length. -- * -- * Return: The number of bytes successfully transmitted or a negative error -- * code on failure. -- */ --ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, -- const void *data, size_t len) --{ -- ssize_t err; -- size_t size; -- u8 *tx; -- -- if (len > 0) { -- size = 1 + len; -- -- tx = kmalloc(size, GFP_KERNEL); -- if (!tx) -- return -ENOMEM; -- -- /* concatenate the DCS command byte and the payload */ -- tx[0] = cmd; -- memcpy(&tx[1], data, len); -- } else { -- tx = &cmd; -- size = 1; -- } -- -- err = mipi_dsi_dcs_write_buffer(dsi, tx, size); -- -- if (len > 0) -- kfree(tx); -- -- return err; --} --EXPORT_SYMBOL(mipi_dsi_dcs_write); -- --/** -- * mipi_dsi_dcs_read() - send DCS read request command -- * @dsi: DSI peripheral device -- * @cmd: DCS command -- * @data: buffer in which to receive data -- * @len: size of receive buffer -- * -- * Return: The number of bytes read or a negative error code on failure. -- */ --ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, -- size_t len) --{ -- struct mipi_dsi_msg msg = { -- .channel = dsi->channel, -- .type = MIPI_DSI_DCS_READ, -- .tx_buf = &cmd, -- .tx_len = 1, -- .rx_buf = data, -- .rx_len = len -- }; -- -- return mipi_dsi_device_transfer(dsi, &msg); --} --EXPORT_SYMBOL(mipi_dsi_dcs_read); -- --/** -- * mipi_dsi_pixel_format_to_bpp - obtain the number of bits per pixel for any -- * given pixel format defined by the MIPI DSI -- * specification -- * @fmt: MIPI DSI pixel format -- * -- * Returns: The number of bits per pixel of the given pixel format. -- */ --int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt) --{ -- switch (fmt) { -- case MIPI_DSI_FMT_RGB888: -- case MIPI_DSI_FMT_RGB666: -- return 24; -- -- case MIPI_DSI_FMT_RGB666_PACKED: -- return 18; -- -- case MIPI_DSI_FMT_RGB565: -- return 16; -- } -- -- return -EINVAL; --} --EXPORT_SYMBOL(mipi_dsi_pixel_format_to_bpp); -- --/** -- * mipi_dsi_dcs_nop() - send DCS nop packet -- * @dsi: DSI peripheral device -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi) --{ -- ssize_t err; -- -- err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0); -- if (err < 0) -- return err; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_nop); -- --/** -- * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module -- * @dsi: DSI peripheral device -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi) --{ -- ssize_t err; -- -- err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0); -- if (err < 0) -- return err; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset); -- --/** -- * mipi_dsi_dcs_get_power_mode() - query the display module's current power -- * mode -- * @dsi: DSI peripheral device -- * @mode: return location for the current power mode -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode) --{ -- ssize_t err; -- -- err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode, -- sizeof(*mode)); -- if (err <= 0) { -- if (err == 0) -- err = -ENODATA; -- -- return err; -- } -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode); -- --/** -- * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image -- * data used by the interface -- * @dsi: DSI peripheral device -- * @format: return location for the pixel format -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format) --{ -- ssize_t err; -- -- err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format, -- sizeof(*format)); -- if (err <= 0) { -- if (err == 0) -- err = -ENODATA; -- -- return err; -- } -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format); -- --/** -- * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the -- * display module except interface communication -- * @dsi: DSI peripheral device -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi) --{ -- ssize_t err; -- -- err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0); -- if (err < 0) -- return err; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode); -- --/** -- * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display -- * module -- * @dsi: DSI peripheral device -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi) --{ -- ssize_t err; -- -- err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); -- if (err < 0) -- return err; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode); -- --/** -- * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the -- * display device -- * @dsi: DSI peripheral device -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi) --{ -- ssize_t err; -- -- err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); -- if (err < 0) -- return err; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off); -- --/** -- * mipi_dsi_dcs_set_display_on() - start displaying the image data on the -- * display device -- * @dsi: DSI peripheral device -- * -- * Return: 0 on success or a negative error code on failure -- */ --int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi) --{ -- ssize_t err; -- -- err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); -- if (err < 0) -- return err; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on); -- --/** -- * mipi_dsi_dcs_set_column_address() - define the column extent of the frame -- * memory accessed by the host processor -- * @dsi: DSI peripheral device -- * @start: first column of frame memory -- * @end: last column of frame memory -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, -- u16 end) --{ -- u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; -- ssize_t err; -- -- err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload, -- sizeof(payload)); -- if (err < 0) -- return err; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address); -- --/** -- * mipi_dsi_dcs_set_page_address() - define the page extent of the frame -- * memory accessed by the host processor -- * @dsi: DSI peripheral device -- * @start: first page of frame memory -- * @end: last page of frame memory -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, -- u16 end) --{ -- u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; -- ssize_t err; -- -- err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload, -- sizeof(payload)); -- if (err < 0) -- return err; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address); -- --/** -- * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect -- * output signal on the TE signal line -- * @dsi: DSI peripheral device -- * -- * Return: 0 on success or a negative error code on failure -- */ --int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi) --{ -- ssize_t err; -- -- err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0); -- if (err < 0) -- return err; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off); -- --/** -- * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect -- * output signal on the TE signal line. -- * @dsi: DSI peripheral device -- * @mode: the Tearing Effect Output Line mode -- * -- * Return: 0 on success or a negative error code on failure -- */ --int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, -- enum mipi_dsi_dcs_tear_mode mode) --{ -- u8 value = mode; -- ssize_t err; -- -- err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value, -- sizeof(value)); -- if (err < 0) -- return err; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on); -- --/** -- * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image -- * data used by the interface -- * @dsi: DSI peripheral device -- * @format: pixel format -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format) --{ -- ssize_t err; -- -- err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format, -- sizeof(format)); -- if (err < 0) -- return err; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format); -- --/** -- * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for -- * the Tearing Effect output signal of the display module -- * @dsi: DSI peripheral device -- * @scanline: scanline to use as trigger -- * -- * Return: 0 on success or a negative error code on failure -- */ --int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline) --{ -- u8 payload[3] = { MIPI_DCS_SET_TEAR_SCANLINE, scanline >> 8, -- scanline & 0xff }; -- ssize_t err; -- -- err = mipi_dsi_generic_write(dsi, payload, sizeof(payload)); -- if (err < 0) -- return err; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline); -- --/** -- * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the -- * display -- * @dsi: DSI peripheral device -- * @brightness: brightness value -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, -- u16 brightness) --{ -- u8 payload[2] = { brightness & 0xff, brightness >> 8 }; -- ssize_t err; -- -- err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, -- payload, sizeof(payload)); -- if (err < 0) -- return err; -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness); -- --/** -- * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value -- * of the display -- * @dsi: DSI peripheral device -- * @brightness: brightness value -- * -- * Return: 0 on success or a negative error code on failure. -- */ --int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, -- u16 *brightness) --{ -- ssize_t err; -- -- err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, -- brightness, sizeof(*brightness)); -- if (err <= 0) { -- if (err == 0) -- err = -ENODATA; -- -- return err; -- } -- -- return 0; --} --EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness); -- --MODULE_AUTHOR("Andrzej Hajda "); --MODULE_AUTHOR("Yannick Fertre "); --MODULE_DESCRIPTION("MIPI DSI Bus"); --MODULE_LICENSE("GPL and additional rights"); -diff --git a/drivers/video/mipi_dsi.c b/drivers/video/mipi_dsi.c -new file mode 100644 -index 0000000..cdc3ef5 ---- /dev/null -+++ b/drivers/video/mipi_dsi.c -@@ -0,0 +1,828 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * MIPI DSI Bus -+ * -+ * Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd. -+ * Copyright (C) 2019 STMicroelectronics - All Rights Reserved -+ * Andrzej Hajda -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sub license, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the -+ * next paragraph) shall be included in all copies or substantial portions -+ * of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, -+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -+ * USE OR OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Mipi_dsi.c contains a set of dsi helpers. -+ * This file is inspired from the drm helper file drivers/gpu/drm/drm_mipi_dsi.c -+ * (kernel linux). -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/** -+ * DOC: dsi helpers -+ * -+ * These functions contain some common logic and helpers to deal with MIPI DSI -+ * peripherals. -+ * -+ * Helpers are provided for a number of standard MIPI DSI command as well as a -+ * subset of the MIPI DCS command set. -+ */ -+ -+/** -+ * mipi_dsi_attach - attach a DSI device to its DSI host -+ * @dsi: DSI peripheral -+ */ -+int mipi_dsi_attach(struct mipi_dsi_device *dsi) -+{ -+ const struct mipi_dsi_host_ops *ops = dsi->host->ops; -+ -+ if (!ops || !ops->attach) -+ return -ENOSYS; -+ -+ return ops->attach(dsi->host, dsi); -+} -+EXPORT_SYMBOL(mipi_dsi_attach); -+ -+/** -+ * mipi_dsi_detach - detach a DSI device from its DSI host -+ * @dsi: DSI peripheral -+ */ -+int mipi_dsi_detach(struct mipi_dsi_device *dsi) -+{ -+ const struct mipi_dsi_host_ops *ops = dsi->host->ops; -+ -+ if (!ops || !ops->detach) -+ return -ENOSYS; -+ -+ return ops->detach(dsi->host, dsi); -+} -+EXPORT_SYMBOL(mipi_dsi_detach); -+ -+/** -+ * mipi_dsi_device_transfer - transfer message to a DSI device -+ * @dsi: DSI peripheral -+ * @msg: message -+ */ -+static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi, -+ struct mipi_dsi_msg *msg) -+{ -+ const struct mipi_dsi_host_ops *ops = dsi->host->ops; -+ -+ if (!ops || !ops->transfer) -+ return -ENOSYS; -+ -+ if (dsi->mode_flags & MIPI_DSI_MODE_LPM) -+ msg->flags |= MIPI_DSI_MSG_USE_LPM; -+ -+ return ops->transfer(dsi->host, msg); -+} -+ -+/** -+ * mipi_dsi_packet_format_is_short - check if a packet is of the short format -+ * @type: MIPI DSI data type of the packet -+ * -+ * Return: true if the packet for the given data type is a short packet, false -+ * otherwise. -+ */ -+bool mipi_dsi_packet_format_is_short(u8 type) -+{ -+ switch (type) { -+ case MIPI_DSI_V_SYNC_START: -+ case MIPI_DSI_V_SYNC_END: -+ case MIPI_DSI_H_SYNC_START: -+ case MIPI_DSI_H_SYNC_END: -+ case MIPI_DSI_END_OF_TRANSMISSION: -+ case MIPI_DSI_COLOR_MODE_OFF: -+ case MIPI_DSI_COLOR_MODE_ON: -+ case MIPI_DSI_SHUTDOWN_PERIPHERAL: -+ case MIPI_DSI_TURN_ON_PERIPHERAL: -+ case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: -+ case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM: -+ case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: -+ case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM: -+ case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM: -+ case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM: -+ case MIPI_DSI_DCS_SHORT_WRITE: -+ case MIPI_DSI_DCS_SHORT_WRITE_PARAM: -+ case MIPI_DSI_DCS_READ: -+ case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE: -+ return true; -+ } -+ -+ return false; -+} -+EXPORT_SYMBOL(mipi_dsi_packet_format_is_short); -+ -+/** -+ * mipi_dsi_packet_format_is_long - check if a packet is of the long format -+ * @type: MIPI DSI data type of the packet -+ * -+ * Return: true if the packet for the given data type is a long packet, false -+ * otherwise. -+ */ -+bool mipi_dsi_packet_format_is_long(u8 type) -+{ -+ switch (type) { -+ case MIPI_DSI_NULL_PACKET: -+ case MIPI_DSI_BLANKING_PACKET: -+ case MIPI_DSI_GENERIC_LONG_WRITE: -+ case MIPI_DSI_DCS_LONG_WRITE: -+ case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_30: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_36: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_16: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_18: -+ case MIPI_DSI_PIXEL_STREAM_3BYTE_18: -+ case MIPI_DSI_PACKED_PIXEL_STREAM_24: -+ return true; -+ } -+ -+ return false; -+} -+EXPORT_SYMBOL(mipi_dsi_packet_format_is_long); -+ -+/** -+ * mipi_dsi_create_packet - create a packet from a message according to the -+ * DSI protocol -+ * @packet: pointer to a DSI packet structure -+ * @msg: message to translate into a packet -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, -+ const struct mipi_dsi_msg *msg) -+{ -+ if (!packet || !msg) -+ return -EINVAL; -+ -+ /* do some minimum sanity checking */ -+ if (!mipi_dsi_packet_format_is_short(msg->type) && -+ !mipi_dsi_packet_format_is_long(msg->type)) -+ return -EINVAL; -+ -+ if (msg->channel > 3) -+ return -EINVAL; -+ -+ memset(packet, 0, sizeof(*packet)); -+ packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f); -+ -+ /* TODO: compute ECC if hardware support is not available */ -+ -+ /* -+ * Long write packets contain the word count in header bytes 1 and 2. -+ * The payload follows the header and is word count bytes long. -+ * -+ * Short write packets encode up to two parameters in header bytes 1 -+ * and 2. -+ */ -+ if (mipi_dsi_packet_format_is_long(msg->type)) { -+ packet->header[1] = (msg->tx_len >> 0) & 0xff; -+ packet->header[2] = (msg->tx_len >> 8) & 0xff; -+ -+ packet->payload_length = msg->tx_len; -+ packet->payload = msg->tx_buf; -+ } else { -+ const u8 *tx = msg->tx_buf; -+ -+ packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0; -+ packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0; -+ } -+ -+ packet->size = sizeof(packet->header) + packet->payload_length; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_create_packet); -+ -+/** -+ * mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi) -+{ -+ struct mipi_dsi_msg msg = { -+ .channel = dsi->channel, -+ .type = MIPI_DSI_SHUTDOWN_PERIPHERAL, -+ .tx_buf = (u8 [2]) { 0, 0 }, -+ .tx_len = 2, -+ }; -+ int ret = mipi_dsi_device_transfer(dsi, &msg); -+ -+ return (ret < 0) ? ret : 0; -+} -+EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral); -+ -+/** -+ * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi) -+{ -+ struct mipi_dsi_msg msg = { -+ .channel = dsi->channel, -+ .type = MIPI_DSI_TURN_ON_PERIPHERAL, -+ .tx_buf = (u8 [2]) { 0, 0 }, -+ .tx_len = 2, -+ }; -+ int ret = mipi_dsi_device_transfer(dsi, &msg); -+ -+ return (ret < 0) ? ret : 0; -+} -+EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral); -+ -+/* -+ * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the -+ * the payload in a long packet transmitted from the peripheral back to the -+ * host processor -+ * @dsi: DSI peripheral device -+ * @value: the maximum size of the payload -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, -+ u16 value) -+{ -+ u8 tx[2] = { value & 0xff, value >> 8 }; -+ struct mipi_dsi_msg msg = { -+ .channel = dsi->channel, -+ .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, -+ .tx_len = sizeof(tx), -+ .tx_buf = tx, -+ }; -+ int ret = mipi_dsi_device_transfer(dsi, &msg); -+ -+ return (ret < 0) ? ret : 0; -+} -+EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); -+ -+/** -+ * mipi_dsi_generic_write() - transmit data using a generic write packet -+ * @dsi: DSI peripheral device -+ * @payload: buffer containing the payload -+ * @size: size of payload buffer -+ * -+ * This function will automatically choose the right data type depending on -+ * the payload length. -+ * -+ * Return: The number of bytes transmitted on success or a negative error code -+ * on failure. -+ */ -+ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, -+ size_t size) -+{ -+ struct mipi_dsi_msg msg = { -+ .channel = dsi->channel, -+ .tx_buf = payload, -+ .tx_len = size -+ }; -+ -+ switch (size) { -+ case 0: -+ msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM; -+ break; -+ -+ case 1: -+ msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM; -+ break; -+ -+ case 2: -+ msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM; -+ break; -+ -+ default: -+ msg.type = MIPI_DSI_GENERIC_LONG_WRITE; -+ break; -+ } -+ -+ return mipi_dsi_device_transfer(dsi, &msg); -+} -+EXPORT_SYMBOL(mipi_dsi_generic_write); -+ -+/** -+ * mipi_dsi_generic_read() - receive data using a generic read packet -+ * @dsi: DSI peripheral device -+ * @params: buffer containing the request parameters -+ * @num_params: number of request parameters -+ * @data: buffer in which to return the received data -+ * @size: size of receive buffer -+ * -+ * This function will automatically choose the right data type depending on -+ * the number of parameters passed in. -+ * -+ * Return: The number of bytes successfully read or a negative error code on -+ * failure. -+ */ -+ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, -+ size_t num_params, void *data, size_t size) -+{ -+ struct mipi_dsi_msg msg = { -+ .channel = dsi->channel, -+ .tx_len = num_params, -+ .tx_buf = params, -+ .rx_len = size, -+ .rx_buf = data -+ }; -+ -+ switch (num_params) { -+ case 0: -+ msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM; -+ break; -+ -+ case 1: -+ msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM; -+ break; -+ -+ case 2: -+ msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM; -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ return mipi_dsi_device_transfer(dsi, &msg); -+} -+EXPORT_SYMBOL(mipi_dsi_generic_read); -+ -+/** -+ * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload -+ * @dsi: DSI peripheral device -+ * @data: buffer containing data to be transmitted -+ * @len: size of transmission buffer -+ * -+ * This function will automatically choose the right data type depending on -+ * the command payload length. -+ * -+ * Return: The number of bytes successfully transmitted or a negative error -+ * code on failure. -+ */ -+ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, -+ const void *data, size_t len) -+{ -+ struct mipi_dsi_msg msg = { -+ .channel = dsi->channel, -+ .tx_buf = data, -+ .tx_len = len -+ }; -+ -+ switch (len) { -+ case 0: -+ return -EINVAL; -+ -+ case 1: -+ msg.type = MIPI_DSI_DCS_SHORT_WRITE; -+ break; -+ -+ case 2: -+ msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; -+ break; -+ -+ default: -+ msg.type = MIPI_DSI_DCS_LONG_WRITE; -+ break; -+ } -+ -+ return mipi_dsi_device_transfer(dsi, &msg); -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer); -+ -+/** -+ * mipi_dsi_dcs_write() - send DCS write command -+ * @dsi: DSI peripheral device -+ * @cmd: DCS command -+ * @data: buffer containing the command payload -+ * @len: command payload length -+ * -+ * This function will automatically choose the right data type depending on -+ * the command payload length. -+ * -+ * Return: The number of bytes successfully transmitted or a negative error -+ * code on failure. -+ */ -+ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, -+ const void *data, size_t len) -+{ -+ ssize_t err; -+ size_t size; -+ u8 *tx; -+ -+ if (len > 0) { -+ size = 1 + len; -+ -+ tx = kmalloc(size, GFP_KERNEL); -+ if (!tx) -+ return -ENOMEM; -+ -+ /* concatenate the DCS command byte and the payload */ -+ tx[0] = cmd; -+ memcpy(&tx[1], data, len); -+ } else { -+ tx = &cmd; -+ size = 1; -+ } -+ -+ err = mipi_dsi_dcs_write_buffer(dsi, tx, size); -+ -+ if (len > 0) -+ kfree(tx); -+ -+ return err; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_write); -+ -+/** -+ * mipi_dsi_dcs_read() - send DCS read request command -+ * @dsi: DSI peripheral device -+ * @cmd: DCS command -+ * @data: buffer in which to receive data -+ * @len: size of receive buffer -+ * -+ * Return: The number of bytes read or a negative error code on failure. -+ */ -+ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, -+ size_t len) -+{ -+ struct mipi_dsi_msg msg = { -+ .channel = dsi->channel, -+ .type = MIPI_DSI_DCS_READ, -+ .tx_buf = &cmd, -+ .tx_len = 1, -+ .rx_buf = data, -+ .rx_len = len -+ }; -+ -+ return mipi_dsi_device_transfer(dsi, &msg); -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_read); -+ -+/** -+ * mipi_dsi_dcs_nop() - send DCS nop packet -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_nop); -+ -+/** -+ * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset); -+ -+/** -+ * mipi_dsi_dcs_get_power_mode() - query the display module's current power -+ * mode -+ * @dsi: DSI peripheral device -+ * @mode: return location for the current power mode -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode, -+ sizeof(*mode)); -+ if (err <= 0) { -+ if (err == 0) -+ err = -ENODATA; -+ -+ return err; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode); -+ -+/** -+ * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image -+ * data used by the interface -+ * @dsi: DSI peripheral device -+ * @format: return location for the pixel format -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format, -+ sizeof(*format)); -+ if (err <= 0) { -+ if (err == 0) -+ err = -ENODATA; -+ -+ return err; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format); -+ -+/** -+ * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the -+ * display module except interface communication -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode); -+ -+/** -+ * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display -+ * module -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode); -+ -+/** -+ * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the -+ * display device -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off); -+ -+/** -+ * mipi_dsi_dcs_set_display_on() - start displaying the image data on the -+ * display device -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure -+ */ -+int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on); -+ -+/** -+ * mipi_dsi_dcs_set_column_address() - define the column extent of the frame -+ * memory accessed by the host processor -+ * @dsi: DSI peripheral device -+ * @start: first column of frame memory -+ * @end: last column of frame memory -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, -+ u16 end) -+{ -+ u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload, -+ sizeof(payload)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address); -+ -+/** -+ * mipi_dsi_dcs_set_page_address() - define the page extent of the frame -+ * memory accessed by the host processor -+ * @dsi: DSI peripheral device -+ * @start: first page of frame memory -+ * @end: last page of frame memory -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, -+ u16 end) -+{ -+ u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload, -+ sizeof(payload)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address); -+ -+/** -+ * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect -+ * output signal on the TE signal line -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure -+ */ -+int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off); -+ -+/** -+ * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect -+ * output signal on the TE signal line. -+ * @dsi: DSI peripheral device -+ * @mode: the Tearing Effect Output Line mode -+ * -+ * Return: 0 on success or a negative error code on failure -+ */ -+int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, -+ enum mipi_dsi_dcs_tear_mode mode) -+{ -+ u8 value = mode; -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value, -+ sizeof(value)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on); -+ -+/** -+ * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image -+ * data used by the interface -+ * @dsi: DSI peripheral device -+ * @format: pixel format -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format, -+ sizeof(format)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format); -+ -+/** -+ * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for -+ * the Tearing Effect output signal of the display module -+ * @dsi: DSI peripheral device -+ * @scanline: scanline to use as trigger -+ * -+ * Return: 0 on success or a negative error code on failure -+ */ -+int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline) -+{ -+ u8 payload[3] = { MIPI_DCS_SET_TEAR_SCANLINE, scanline >> 8, -+ scanline & 0xff }; -+ ssize_t err; -+ -+ err = mipi_dsi_generic_write(dsi, payload, sizeof(payload)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline); -+ -+/** -+ * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the -+ * display -+ * @dsi: DSI peripheral device -+ * @brightness: brightness value -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, -+ u16 brightness) -+{ -+ u8 payload[2] = { brightness & 0xff, brightness >> 8 }; -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, -+ payload, sizeof(payload)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness); -+ -+/** -+ * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value -+ * of the display -+ * @dsi: DSI peripheral device -+ * @brightness: brightness value -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, -+ u16 *brightness) -+{ -+ ssize_t err; -+ -+ err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, -+ brightness, sizeof(*brightness)); -+ if (err <= 0) { -+ if (err == 0) -+ err = -ENODATA; -+ -+ return err; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness); -diff --git a/drivers/video/orisetech_otm8009a.c b/drivers/video/orisetech_otm8009a.c -index 41c4bef..629bf76 100644 ---- a/drivers/video/orisetech_otm8009a.c -+++ b/drivers/video/orisetech_otm8009a.c -@@ -1,16 +1,16 @@ - // SPDX-License-Identifier: GPL-2.0+ - /* -- * Copyright (C) 2018 STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2019 STMicroelectronics - All Rights Reserved - * Author(s): Yannick Fertre for STMicroelectronics. - * Philippe Cornu for STMicroelectronics. - * -- * This otm8009a panel driver is based on the Linux Kernel driver from -+ * This otm8009a panel driver is inspired from the Linux Kernel driver - * drivers/gpu/drm/panel/panel-orisetech-otm8009a.c. - */ - #include - #include - #include --#include -+#include - #include - #include - #include -@@ -63,15 +63,15 @@ struct otm8009a_panel_priv { - }; - - static const struct display_timing default_timing = { -- .pixelclock = {.min = 32729000, .typ = 32729000, .max = 32729000,}, -- .hactive = {.min = 480, .typ = 480, .max = 480,}, -- .hfront_porch = {.min = 120, .typ = 120, .max = 120,}, -- .hback_porch = {.min = 120, .typ = 120, .max = 120,}, -- .hsync_len = {.min = 63, .typ = 63, .max = 63,}, -- .vactive = {.min = 800, .typ = 800, .max = 800,}, -- .vfront_porch = {.min = 12, .typ = 12, .max = 12,}, -- .vback_porch = {.min = 12, .typ = 12, .max = 12,}, -- .vsync_len = {.min = 12, .typ = 12, .max = 12,}, -+ .pixelclock.typ = 29700000, -+ .hactive.typ = 480, -+ .hfront_porch.typ = 98, -+ .hback_porch.typ = 98, -+ .hsync_len.typ = 32, -+ .vactive.typ = 800, -+ .vfront_porch.typ = 15, -+ .vback_porch.typ = 14, -+ .vsync_len.typ = 10, - }; - - static void otm8009a_dcs_write_buf(struct udevice *dev, const void *data, -@@ -84,12 +84,34 @@ static void otm8009a_dcs_write_buf(struct udevice *dev, const void *data, - dev_err(dev, "mipi dsi dcs write buffer failed\n"); - } - -+static void otm8009a_dcs_write_buf_hs(struct udevice *dev, const void *data, -+ size_t len) -+{ -+ struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); -+ struct mipi_dsi_device *device = plat->device; -+ -+ /* data will be sent in dsi hs mode (ie. no lpm) */ -+ device->mode_flags &= ~MIPI_DSI_MODE_LPM; -+ -+ if (mipi_dsi_dcs_write_buffer(device, data, len) < 0) -+ dev_err(dev, "mipi dsi dcs write buffer failed\n"); -+ -+ /* restore back the dsi lpm mode */ -+ device->mode_flags |= MIPI_DSI_MODE_LPM; -+} -+ - #define dcs_write_seq(dev, seq...) \ - ({ \ - static const u8 d[] = { seq }; \ - otm8009a_dcs_write_buf(dev, d, ARRAY_SIZE(d)); \ - }) - -+#define dcs_write_seq_hs(dev, seq...) \ -+({ \ -+ static const u8 d[] = { seq }; \ -+ otm8009a_dcs_write_buf_hs(dev, d, ARRAY_SIZE(d)); \ -+}) -+ - #define dcs_write_cmd_at(dev, cmd, seq...) \ - ({ \ - static const u16 c = cmd; \ -@@ -196,11 +218,13 @@ static int otm8009a_init_sequence(struct udevice *dev) - /* Default portrait 480x800 rgb24 */ - dcs_write_seq(dev, MIPI_DCS_SET_ADDRESS_MODE, 0x00); - -- ret = mipi_dsi_dcs_set_column_address(device, 0, 479); -+ ret = mipi_dsi_dcs_set_column_address(device, 0, -+ default_timing.hactive.typ - 1); - if (ret) - return ret; - -- ret = mipi_dsi_dcs_set_page_address(device, 0, 799); -+ ret = mipi_dsi_dcs_set_page_address(device, 0, -+ default_timing.vactive.typ - 1); - if (ret) - return ret; - -@@ -213,6 +237,17 @@ static int otm8009a_init_sequence(struct udevice *dev) - /* Disable CABC feature */ - dcs_write_seq(dev, MIPI_DCS_WRITE_POWER_SAVE, 0x00); - -+ ret = mipi_dsi_dcs_set_display_on(device); -+ if (ret) -+ return ret; -+ -+ ret = mipi_dsi_dcs_nop(device); -+ if (ret) -+ return ret; -+ -+ /* Send Command GRAM memory write (no parameters) */ -+ dcs_write_seq(dev, MIPI_DCS_WRITE_MEMORY_START); -+ - return 0; - } - -@@ -222,12 +257,6 @@ static int otm8009a_panel_enable_backlight(struct udevice *dev) - struct mipi_dsi_device *device = plat->device; - int ret; - -- device->lanes = 2; -- device->format = MIPI_DSI_FMT_RGB888; -- device->mode_flags = MIPI_DSI_MODE_VIDEO | -- MIPI_DSI_MODE_VIDEO_BURST | -- MIPI_DSI_MODE_LPM; -- - ret = mipi_dsi_attach(device); - if (ret < 0) - return ret; -@@ -247,18 +276,10 @@ static int otm8009a_panel_enable_backlight(struct udevice *dev) - /* Update Brightness Control & Backlight */ - dcs_write_seq(dev, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x24); - -- ret = mipi_dsi_dcs_set_display_on(device); -- if (ret) -- return ret; -- -- ret = mipi_dsi_dcs_nop(device); -- if (ret) -- return ret; -- -- /* Send Command GRAM memory write (no parameters) */ -- dcs_write_seq(dev, MIPI_DCS_WRITE_MEMORY_START); -+ /* Update Brightness Control & Backlight */ -+ dcs_write_seq_hs(dev, MIPI_DCS_WRITE_CONTROL_DISPLAY); - -- /* need to wait a few time before set the DSI bridge in video mode */ -+ /* Need to wait a few time before sending the first image */ - mdelay(10); - - return 0; -@@ -268,6 +289,7 @@ static int otm8009a_panel_get_display_timing(struct udevice *dev, - struct display_timing *timings) - { - memcpy(timings, &default_timing, sizeof(*timings)); -+ - return 0; - } - -@@ -299,23 +321,28 @@ static int otm8009a_panel_ofdata_to_platdata(struct udevice *dev) - static int otm8009a_panel_probe(struct udevice *dev) - { - struct otm8009a_panel_priv *priv = dev_get_priv(dev); -+ struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); - int ret; - - if (IS_ENABLED(CONFIG_DM_REGULATOR) && priv->reg) { - dev_dbg(dev, "enable regulator '%s'\n", priv->reg->name); - ret = regulator_set_enable(priv->reg, true); -- if (ret) { -- dev_err(dev, "Regulator : '%s' - can't enable\n", -- priv->reg->name); -+ if (ret) - return ret; -- } - } - - /* reset panel */ - dm_gpio_set_value(&priv->reset, true); -- mdelay(1); -+ mdelay(1); /* >50us */ - dm_gpio_set_value(&priv->reset, false); -- mdelay(10); -+ mdelay(10); /* >5ms */ -+ -+ /* 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; - } -diff --git a/drivers/video/raydium-rm68200.c b/drivers/video/raydium-rm68200.c -index 3347f12..76b0ed2 100644 ---- a/drivers/video/raydium-rm68200.c -+++ b/drivers/video/raydium-rm68200.c -@@ -1,16 +1,16 @@ - // SPDX-License-Identifier: GPL-2.0+ - /* -- * Copyright (C) 2018 STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2019 STMicroelectronics - All Rights Reserved - * Author(s): Yannick Fertre for STMicroelectronics. - * Philippe Cornu for STMicroelectronics. - * -- * This rm68200 panel driver is based on the Linux Kernel driver from -+ * This rm68200 panel driver is inspired from the Linux Kernel driver - * drivers/gpu/drm/panel/panel-raydium-rm68200.c. - */ - #include - #include - #include --#include -+#include - #include - #include - #include -@@ -76,15 +76,15 @@ struct rm68200_panel_priv { - }; - - static const struct display_timing default_timing = { -- .pixelclock = {.min = 52582000, .typ = 52582000, .max = 52582000,}, -- .hactive = {.min = 720, .typ = 720, .max = 720,}, -- .hfront_porch = {.min = 38, .typ = 38, .max = 38,}, -- .hback_porch = {.min = 8, .typ = 8, .max = 8,}, -- .hsync_len = {.min = 38, .typ = 38, .max = 38,}, -- .vactive = {.min = 1280, .typ = 1280, .max = 1280,}, -- .vfront_porch = {.min = 12, .typ = 12, .max = 12,}, -- .vback_porch = {.min = 4, .typ = 4, .max = 4,}, -- .vsync_len = {.min = 12, .typ = 12, .max = 12,}, -+ .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 rm68200_dcs_write_buf(struct udevice *dev, const void *data, -@@ -226,12 +226,6 @@ static int rm68200_panel_enable_backlight(struct udevice *dev) - struct rm68200_panel_priv *priv = dev_get_priv(dev); - int ret; - -- device->lanes = 2; -- device->format = MIPI_DSI_FMT_RGB888; -- device->mode_flags = MIPI_DSI_MODE_VIDEO | -- MIPI_DSI_MODE_VIDEO_BURST | -- MIPI_DSI_MODE_LPM; -- - ret = mipi_dsi_attach(device); - if (ret < 0) - return ret; -@@ -261,6 +255,7 @@ static int rm68200_panel_get_display_timing(struct udevice *dev, - struct display_timing *timings) - { - memcpy(timings, &default_timing, sizeof(*timings)); -+ - return 0; - } - -@@ -299,6 +294,7 @@ static int rm68200_panel_ofdata_to_platdata(struct udevice *dev) - static int rm68200_panel_probe(struct udevice *dev) - { - struct rm68200_panel_priv *priv = dev_get_priv(dev); -+ struct mipi_dsi_panel_plat *plat = dev_get_platdata(dev); - int ret; - - if (IS_ENABLED(CONFIG_DM_REGULATOR) && priv->reg) { -@@ -313,6 +309,13 @@ static int rm68200_panel_probe(struct udevice *dev) - dm_gpio_set_value(&priv->reset, false); - mdelay(10); - -+ /* 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; - } - -diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c -index f8f7c83..022ae96 100644 ---- a/drivers/video/stm32/stm32_dsi.c -+++ b/drivers/video/stm32/stm32_dsi.c -@@ -1,17 +1,18 @@ - // SPDX-License-Identifier: GPL-2.0+ - /* -- * Copyright (C) 2018 STMicroelectronics - All Rights Reserved -+ * Copyright (C) 2019 STMicroelectronics - All Rights Reserved - * Author(s): Philippe Cornu for STMicroelectronics. - * Yannick Fertre for STMicroelectronics. - * - * This MIPI DSI controller driver is based on the Linux Kernel driver from - * drivers/gpu/drm/stm/dw_mipi_dsi-stm.c. - */ -+ - #include - #include - #include --#include --#include -+#include -+#include - #include - #include - #include -@@ -19,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -87,6 +89,7 @@ struct stm32_dsi_priv { - int lane_min_kbps; - int lane_max_kbps; - struct udevice *vdd_reg; -+ struct udevice *dsi_host; - }; - - static inline void dsi_write(struct stm32_dsi_priv *dsi, u32 reg, u32 val) -@@ -207,12 +210,14 @@ static int dsi_phy_init(void *priv_data) - u32 val; - int ret; - -+ debug("Initialize DSI physical layer\n"); -+ - /* Enable the regulator */ - dsi_set(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN); - ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS, - TIMEOUT_US); - if (ret) { -- dev_err(dev, "!TIMEOUT! waiting REGU\n"); -+ debug("!TIMEOUT! waiting REGU\n"); - return ret; - } - -@@ -221,16 +226,37 @@ static int dsi_phy_init(void *priv_data) - ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS, - TIMEOUT_US); - if (ret) { -- dev_err(dev, "!TIMEOUT! waiting PLL\n"); -+ debug("!TIMEOUT! waiting PLL\n"); - return ret; - } - -- /* Enable the DSI wrapper */ -- dsi_set(dsi, DSI_WCR, WCR_DSIEN); -- - return 0; - } - -+static void dsi_phy_post_set_mode(void *priv_data, unsigned long mode_flags) -+{ -+ struct mipi_dsi_device *device = priv_data; -+ struct udevice *dev = device->dev; -+ struct stm32_dsi_priv *dsi = dev_get_priv(dev); -+ -+ debug("Set mode %p enable %ld\n", dsi, -+ mode_flags & MIPI_DSI_MODE_VIDEO); -+ -+ if (!dsi) -+ return; -+ -+ /* -+ * DSI wrapper must be enabled in video mode & disabled in command mode. -+ * If wrapper is enabled in command mode, the display controller -+ * register access will hang. -+ */ -+ -+ if (mode_flags & MIPI_DSI_MODE_VIDEO) -+ dsi_set(dsi, DSI_WCR, WCR_DSIEN); -+ else -+ dsi_clear(dsi, DSI_WCR, WCR_DSIEN); -+} -+ - static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings, - u32 lanes, u32 format, unsigned int *lane_mbps) - { -@@ -302,28 +328,51 @@ static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings, - return 0; - } - --static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_stm_phy_ops = { -+static const struct mipi_dsi_phy_ops dsi_stm_phy_ops = { - .init = dsi_phy_init, - .get_lane_mbps = dsi_get_lane_mbps, -+ .post_set_mode = dsi_phy_post_set_mode, - }; - - static int stm32_dsi_attach(struct udevice *dev) - { -- struct stm32_dsi_priv *dsi = dev_get_priv(dev); -- struct dw_mipi_dsi_plat_data *platdata = dev_get_platdata(dev); -- struct mipi_dsi_device *device = &dsi->device; -+ struct stm32_dsi_priv *priv = dev_get_priv(dev); -+ struct mipi_dsi_device *device = &priv->device; -+ struct mipi_dsi_panel_plat *mplat; -+ struct display_timing timings; - int ret; - -- platdata->max_data_lanes = 2; -- platdata->phy_ops = &dw_mipi_dsi_stm_phy_ops; -- -- ret = uclass_first_device(UCLASS_PANEL, &platdata->panel); -+ ret = uclass_first_device(UCLASS_PANEL, &priv->panel); - if (ret) { - dev_err(dev, "panel device error %d\n", ret); - return ret; - } - -- ret = dw_mipi_dsi_init_bridge(device); -+ mplat = dev_get_platdata(priv->panel); -+ mplat->device = &priv->device; -+ device->lanes = mplat->lanes; -+ device->format = mplat->format; -+ device->mode_flags = mplat->mode_flags; -+ -+ ret = panel_get_display_timing(priv->panel, &timings); -+ if (ret) { -+ ret = fdtdec_decode_display_timing(gd->fdt_blob, -+ dev_of_offset(priv->panel), -+ 0, &timings); -+ if (ret) { -+ dev_err(dev, "decode display timing error %d\n", ret); -+ return ret; -+ } -+ } -+ -+ ret = uclass_get_device(UCLASS_DSI_HOST, 0, &priv->dsi_host); -+ if (ret) { -+ dev_err(dev, "No video dsi host detected %d\n", ret); -+ return ret; -+ } -+ -+ ret = dsi_host_init(priv->dsi_host, device, &timings, 2, -+ &dsi_stm_phy_ops); - if (ret) { - dev_err(dev, "failed to initialize mipi dsi host\n"); - return ret; -@@ -334,103 +383,116 @@ static int stm32_dsi_attach(struct udevice *dev) - - static int stm32_dsi_set_backlight(struct udevice *dev, int percent) - { -- struct dw_mipi_dsi_plat_data *dplat = dev_get_platdata(dev); -- struct stm32_dsi_priv *dsi = dev_get_priv(dev); -- struct mipi_dsi_device *device = &dsi->device; -- struct udevice *panel = dplat->panel; -- struct mipi_dsi_panel_plat *mplat; -+ struct stm32_dsi_priv *priv = dev_get_priv(dev); - int ret; - -- mplat = dev_get_platdata(panel); -- mplat->device = device; -- -- ret = panel_enable_backlight(panel); -+ ret = panel_enable_backlight(priv->panel); - if (ret) { - dev_err(dev, "panel %s enable backlight error %d\n", -- panel->name, ret); -+ priv->panel->name, ret); - return ret; - } - -- dw_mipi_dsi_bridge_enable(device); -+ ret = dsi_host_enable(priv->dsi_host); -+ if (ret) { -+ dev_err(dev, "failed to enable mipi dsi host\n"); -+ return ret; -+ } - - return 0; - } - -+static int stm32_dsi_bind(struct udevice *dev) -+{ -+ int ret; -+ -+ ret = device_bind_driver_to_node(dev, "dw_mipi_dsi", "dsihost", -+ dev_ofnode(dev), NULL); -+ if (ret) -+ return ret; -+ -+ return dm_scan_fdt_dev(dev); -+} -+ - static int stm32_dsi_probe(struct udevice *dev) - { -- struct stm32_dsi_priv *dsi = dev_get_priv(dev); -- struct mipi_dsi_device *device = &dsi->device; -+ struct stm32_dsi_priv *priv = dev_get_priv(dev); -+ struct mipi_dsi_device *device = &priv->device; - struct reset_ctl rst; - struct clk clk; - int ret; - - device->dev = dev; - -- dsi->base = (void *)dev_read_addr(dev); -- if ((fdt_addr_t)dsi->base == FDT_ADDR_T_NONE) { -+ priv->base = (void *)dev_read_addr(dev); -+ if ((fdt_addr_t)priv->base == FDT_ADDR_T_NONE) { - dev_err(dev, "dsi dt register address error\n"); - return -EINVAL; - } - - if (IS_ENABLED(CONFIG_DM_REGULATOR)) { - ret = device_get_supply_regulator(dev, "phy-dsi-supply", -- &dsi->vdd_reg); -+ &priv->vdd_reg); - if (ret && ret != -ENOENT) { - dev_err(dev, "Warning: cannot get phy dsi supply\n"); - return -ENODEV; - } - -- ret = regulator_set_enable(dsi->vdd_reg, true); -- if (ret) -- return -ENODEV; -+ if (ret != -ENOENT) { -+ ret = regulator_set_enable(priv->vdd_reg, true); -+ if (ret) -+ return ret; -+ } - } - - ret = clk_get_by_name(device->dev, "pclk", &clk); - if (ret) { - dev_err(dev, "peripheral clock get error %d\n", ret); -- regulator_set_enable(dsi->vdd_reg, false); -- return -ENODEV; -+ goto err_reg; - } - - ret = clk_enable(&clk); - if (ret) { - dev_err(dev, "peripheral clock enable error %d\n", ret); -- regulator_set_enable(dsi->vdd_reg, false); -- return -ENODEV; -+ goto err_reg; - } - - ret = clk_get_by_name(dev, "ref", &clk); - if (ret) { - dev_err(dev, "pll reference clock get error %d\n", ret); -- clk_disable(&clk); -- regulator_set_enable(dsi->vdd_reg, false); -- return ret; -+ goto err_clk; - } - -- dsi->pllref_clk = (unsigned int)clk_get_rate(&clk); -+ priv->pllref_clk = (unsigned int)clk_get_rate(&clk); - - ret = reset_get_by_index(device->dev, 0, &rst); - if (ret) { - dev_err(dev, "missing dsi hardware reset\n"); -- clk_disable(&clk); -- regulator_set_enable(dsi->vdd_reg, false); -- return -ENODEV; -+ goto err_clk; - } - - /* Reset */ - reset_deassert(&rst); - - /* check hardware version */ -- dsi->hw_version = dsi_read(dsi, DSI_VERSION) & VERSION; -- if (dsi->hw_version != HWVER_130 && -- dsi->hw_version != HWVER_131) { -+ priv->hw_version = dsi_read(priv, DSI_VERSION) & VERSION; -+ if (priv->hw_version != HWVER_130 && -+ priv->hw_version != HWVER_131) { - dev_err(dev, "bad dsi hardware version\n"); - clk_disable(&clk); -- regulator_set_enable(dsi->vdd_reg, false); -+ if (IS_ENABLED(CONFIG_DM_REGULATOR)) -+ regulator_set_enable(priv->vdd_reg, false); - return -ENODEV; - } - - return 0; -+err_clk: -+ clk_disable(&clk); -+err_reg: -+ if (IS_ENABLED(CONFIG_DM_REGULATOR)) -+ regulator_set_enable(priv->vdd_reg, false); -+ -+ return ret; - } - - struct video_bridge_ops stm32_dsi_ops = { -@@ -447,9 +509,8 @@ U_BOOT_DRIVER(stm32_dsi) = { - .name = "stm32-display-dsi", - .id = UCLASS_VIDEO_BRIDGE, - .of_match = stm32_dsi_ids, -- .bind = dm_scan_fdt_dev, -+ .bind = stm32_dsi_bind, - .probe = stm32_dsi_probe, - .ops = &stm32_dsi_ops, - .priv_auto_alloc_size = sizeof(struct stm32_dsi_priv), -- .platdata_auto_alloc_size = sizeof(struct dw_mipi_dsi_plat_data), - }; -diff --git a/drivers/video/stm32/stm32_ltdc.c b/drivers/video/stm32/stm32_ltdc.c -index 8c996b8..59ff692 100644 ---- a/drivers/video/stm32/stm32_ltdc.c -+++ b/drivers/video/stm32/stm32_ltdc.c -@@ -4,6 +4,7 @@ - * Author(s): Philippe Cornu for STMicroelectronics. - * Yannick Fertre for STMicroelectronics. - */ -+ - #include - #include - #include -@@ -328,9 +329,7 @@ static int stm32_ltdc_probe(struct udevice *dev) - struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev); - struct video_priv *uc_priv = dev_get_uclass_priv(dev); - struct stm32_ltdc_priv *priv = dev_get_priv(dev); --#ifdef CONFIG_VIDEO_BRIDGE - struct udevice *bridge = NULL; --#endif - struct udevice *panel = NULL; - struct display_timing timings; - struct clk pclk; -@@ -390,19 +389,20 @@ static int stm32_ltdc_probe(struct udevice *dev) - /* Reset */ - reset_deassert(&rst); - --#ifdef CONFIG_VIDEO_BRIDGE -- ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &bridge); -- if (ret) -- debug("No video bridge, or no backlight on bridge\n"); -- -- if (bridge) { -- ret = video_bridge_attach(bridge); -- if (ret) { -- dev_err(dev, "fail to attach bridge\n"); -- return ret; -+ if (IS_ENABLED(CONFIG_VIDEO_BRIDGE)) { -+ ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &bridge); -+ if (ret) -+ debug("No video bridge, or no backlight on bridge\n"); -+ -+ if (bridge) { -+ ret = video_bridge_attach(bridge); -+ if (ret) { -+ dev_err(dev, "fail to attach bridge\n"); -+ return ret; -+ } - } - } --#endif -+ - /* TODO Below parameters are hard-coded for the moment... */ - priv->l2bpp = VIDEO_BPP16; - priv->bg_col_argb = 0xFFFFFFFF; /* white no transparency */ -@@ -428,29 +428,21 @@ static int stm32_ltdc_probe(struct udevice *dev) - uc_priv->ysize = timings.vactive.typ; - uc_priv->bpix = priv->l2bpp; - --#ifdef CONFIG_VIDEO_BRIDGE -- if (bridge) { -- ret = video_bridge_set_backlight(bridge, 80); -- if (ret) { -- dev_err(dev, "fail to set backlight\n"); -- return ret; -- } -- } else { -+ if (!bridge) { - ret = panel_enable_backlight(panel); - if (ret) { - dev_err(dev, "panel %s enable backlight error %d\n", - panel->name, ret); - return ret; - } -+ } else if (IS_ENABLED(CONFIG_VIDEO_BRIDGE)) { -+ ret = video_bridge_set_backlight(bridge, 80); -+ if (ret) { -+ dev_err(dev, "fail to set backlight\n"); -+ return ret; -+ } - } --#else -- ret = panel_enable_backlight(panel); -- if (ret) { -- dev_err(dev, "panel %s enable backlight error %d\n", -- panel->name, ret); -- return ret; -- } --#endif -+ - video_set_flush_dcache(dev, true); - - return 0; -diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h -index 6193017..5f62167 100644 ---- a/include/dm/uclass-id.h -+++ b/include/dm/uclass-id.h -@@ -35,6 +35,7 @@ enum uclass_id { - UCLASS_CPU, /* CPU, typically part of an SoC */ - UCLASS_CROS_EC, /* Chrome OS EC */ - UCLASS_DISPLAY, /* Display (e.g. DisplayPort, HDMI) */ -+ UCLASS_DSI_HOST, /* Dsi host device */ - UCLASS_DMA, /* Direct Memory Access */ - UCLASS_EFI, /* EFI managed devices */ - UCLASS_ETH, /* Ethernet device */ -diff --git a/include/dsi_host.h b/include/dsi_host.h -new file mode 100644 -index 0000000..9ff226f ---- /dev/null -+++ b/include/dsi_host.h -@@ -0,0 +1,57 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ -+/* -+ * Copyright (C) 2019 STMicroelectronics - All Rights Reserved -+ * Author(s): Yannick Fertre for STMicroelectronics. -+ * -+ */ -+ -+#ifndef _DSI_HOST_H -+#define _DSI_HOST_H -+ -+#include -+ -+struct dsi_host_ops { -+ /** -+ * init() - Enable the dsi_host -+ * -+ * @dev: dsi host device -+ * @return 0 if OK, -ve on error -+ */ -+ int (*init)(struct udevice *dev, -+ struct mipi_dsi_device *device, -+ struct display_timing *timings, -+ unsigned int max_data_lanes, -+ const struct mipi_dsi_phy_ops *phy_ops); -+ -+ /** -+ * enable() - Enable the dsi_host -+ * -+ * @dev: dsi host device -+ * @return 0 if OK, -ve on error -+ */ -+ int (*enable)(struct udevice *dev); -+}; -+ -+#define dsi_host_get_ops(dev) ((struct dsi_host_ops *)(dev)->driver->ops) -+ -+/** -+ * dsi_host_init -+ * -+ * @dev: dsi host device -+ * @return 0 if OK, -ve on error -+ */ -+int dsi_host_init(struct udevice *dev, -+ struct mipi_dsi_device *device, -+ struct display_timing *timings, -+ unsigned int max_data_lanes, -+ const struct mipi_dsi_phy_ops *phy_ops); -+ -+/** -+ * dsi_host_enable -+ * -+ * @dev: dsi host device -+ * @return 0 if OK, -ve on error -+ */ -+int dsi_host_enable(struct udevice *dev); -+ -+#endif -diff --git a/include/mipi_display.h b/include/mipi_display.h -index 5c3dbbe..19aa65a 100644 ---- a/include/mipi_display.h -+++ b/include/mipi_display.h -@@ -4,16 +4,12 @@ - * - * Copyright (C) 2010 Guennadi Liakhovetski - * Copyright (C) 2006 Nokia Corporation -- * Copyright (C) 2018 STMicroelectronics - All Rights Reserved -- * Author(s): Imre Deak -- * Yannick Fertre -- * Philippe Cornu -+ * Author: Imre Deak - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -- - #ifndef MIPI_DISPLAY_H - #define MIPI_DISPLAY_H - -@@ -139,247 +135,4 @@ enum { - #define MIPI_DCS_PIXEL_FMT_8BIT 2 - #define MIPI_DCS_PIXEL_FMT_3BIT 1 - --struct mipi_dsi_host; --struct mipi_dsi_device; -- --/* request ACK from peripheral */ --#define MIPI_DSI_MSG_REQ_ACK BIT(0) --/* use Low Power Mode to transmit message */ --#define MIPI_DSI_MSG_USE_LPM BIT(1) -- --/** -- * struct mipi_dsi_msg - read/write DSI buffer -- * @channel: virtual channel id -- * @type: payload data type -- * @flags: flags controlling this message transmission -- * @tx_len: length of @tx_buf -- * @tx_buf: data to be written -- * @rx_len: length of @rx_buf -- * @rx_buf: data to be read, or NULL -- */ --struct mipi_dsi_msg { -- u8 channel; -- u8 type; -- u16 flags; -- -- size_t tx_len; -- const void *tx_buf; -- -- size_t rx_len; -- void *rx_buf; --}; -- --bool mipi_dsi_packet_format_is_short(u8 type); --bool mipi_dsi_packet_format_is_long(u8 type); -- --/** -- * struct mipi_dsi_packet - represents a MIPI DSI packet in protocol format -- * @size: size (in bytes) of the packet -- * @header: the four bytes that make up the header (Data ID, Word Count or -- * Packet Data, and ECC) -- * @payload_length: number of bytes in the payload -- * @payload: a pointer to a buffer containing the payload, if any -- */ --struct mipi_dsi_packet { -- size_t size; -- u8 header[4]; -- size_t payload_length; -- const u8 *payload; --}; -- --int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, -- const struct mipi_dsi_msg *msg); -- --/** -- * struct mipi_dsi_host_ops - DSI bus operations -- * @attach: attach DSI device to DSI host -- * @detach: detach DSI device from DSI host -- * @transfer: transmit a DSI packet -- * -- * DSI packets transmitted by .transfer() are passed in as mipi_dsi_msg -- * structures. This structure contains information about the type of packet -- * being transmitted as well as the transmit and receive buffers. When an -- * error is encountered during transmission, this function will return a -- * negative error code. On success it shall return the number of bytes -- * transmitted for write packets or the number of bytes received for read -- * packets. -- * -- * Note that typically DSI packet transmission is atomic, so the .transfer() -- * function will seldomly return anything other than the number of bytes -- * contained in the transmit buffer on success. -- */ --struct mipi_dsi_host_ops { -- int (*attach)(struct mipi_dsi_host *host, -- struct mipi_dsi_device *dsi); -- int (*detach)(struct mipi_dsi_host *host, -- struct mipi_dsi_device *dsi); -- ssize_t (*transfer)(struct mipi_dsi_host *host, -- const struct mipi_dsi_msg *msg); --}; -- --/** -- * struct mipi_dsi_host - DSI host device -- * @dev: driver model device node for this DSI host -- * @ops: DSI host operations -- * @list: list management -- */ --struct mipi_dsi_host { -- struct device *dev; -- const struct mipi_dsi_host_ops *ops; -- struct list_head list; --}; -- --/* DSI mode flags */ -- --/* video mode */ --#define MIPI_DSI_MODE_VIDEO BIT(0) --/* video burst mode */ --#define MIPI_DSI_MODE_VIDEO_BURST BIT(1) --/* video pulse mode */ --#define MIPI_DSI_MODE_VIDEO_SYNC_PULSE BIT(2) --/* enable auto vertical count mode */ --#define MIPI_DSI_MODE_VIDEO_AUTO_VERT BIT(3) --/* enable hsync-end packets in vsync-pulse and v-porch area */ --#define MIPI_DSI_MODE_VIDEO_HSE BIT(4) --/* disable hfront-porch area */ --#define MIPI_DSI_MODE_VIDEO_HFP BIT(5) --/* disable hback-porch area */ --#define MIPI_DSI_MODE_VIDEO_HBP BIT(6) --/* disable hsync-active area */ --#define MIPI_DSI_MODE_VIDEO_HSA BIT(7) --/* flush display FIFO on vsync pulse */ --#define MIPI_DSI_MODE_VSYNC_FLUSH BIT(8) --/* disable EoT packets in HS mode */ --#define MIPI_DSI_MODE_EOT_PACKET BIT(9) --/* device supports non-continuous clock behavior (DSI spec 5.6.1) */ --#define MIPI_DSI_CLOCK_NON_CONTINUOUS BIT(10) --/* transmit data in low power */ --#define MIPI_DSI_MODE_LPM BIT(11) -- --enum mipi_dsi_pixel_format { -- MIPI_DSI_FMT_RGB888, -- MIPI_DSI_FMT_RGB666, -- MIPI_DSI_FMT_RGB666_PACKED, -- MIPI_DSI_FMT_RGB565, --}; -- --#define DSI_DEV_NAME_SIZE 20 -- --/** -- * struct mipi_dsi_device_info - template for creating a mipi_dsi_device -- * @type: DSI peripheral chip type -- * @channel: DSI virtual channel assigned to peripheral -- * @node: pointer to OF device node or NULL -- * -- * This is populated and passed to mipi_dsi_device_new to create a new -- * DSI device -- */ --struct mipi_dsi_device_info { -- char type[DSI_DEV_NAME_SIZE]; -- u32 channel; -- struct device_node *node; --}; -- --/** -- * struct mipi_dsi_device - DSI peripheral device -- * @host: DSI host for this peripheral -- * @dev: driver model device node for this peripheral -- * @name: DSI peripheral chip type -- * @channel: virtual channel assigned to the peripheral -- * @format: pixel format for video mode -- * @lanes: number of active data lanes -- * @mode_flags: DSI operation mode related flags -- */ --struct mipi_dsi_device { -- struct mipi_dsi_host *host; -- struct udevice *dev; -- -- char name[DSI_DEV_NAME_SIZE]; -- unsigned int channel; -- unsigned int lanes; -- enum mipi_dsi_pixel_format format; -- unsigned long mode_flags; --}; -- --/** -- * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode -- * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking -- * information only -- * @MIPI_DSI_DCS_TEAR_MODE_VHBLANK : the TE output line consists of both -- * V-Blanking and H-Blanking information -- */ --enum mipi_dsi_dcs_tear_mode { -- MIPI_DSI_DCS_TEAR_MODE_VBLANK, -- MIPI_DSI_DCS_TEAR_MODE_VHBLANK, --}; -- --/** -- * struct mipi_dsi_panel_plat - DSI panel platform data -- * @device: DSI peripheral device -- */ --struct mipi_dsi_panel_plat { -- struct mipi_dsi_device *device; --}; -- --int mipi_dsi_attach(struct mipi_dsi_device *dsi); --int mipi_dsi_detach(struct mipi_dsi_device *dsi); --int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt); -- --/* bit compatible with the xrandr RR_ definitions (bits 0-13) -- * -- * ABI warning: Existing userspace really expects -- * the mode flags to match the xrandr definitions. Any -- * changes that don't match the xrandr definitions will -- * likely need a new client cap or some other mechanism -- * to avoid breaking existing userspace. This includes -- * allocating new flags in the previously unused bits! -- */ --#define MIPI_DSI_FLAG_PHSYNC BIT(0) --#define MIPI_DSI_FLAG_NHSYNC BIT(1) --#define MIPI_DSI_FLAG_PVSYNC BIT(2) --#define MIPI_DSI_FLAG_NVSYNC BIT(3) --#define MIPI_DSI_FLAG_INTERLACE BIT(4) --#define MIPI_DSI_FLAG_DBLSCAN BIT(5) --#define MIPI_DSI_FLAG_CSYNC BIT(6) --#define MIPI_DSI_FLAG_PCSYNC BIT(7) --#define MIPI_DSI_FLAG_NCSYNC BIT(8) --#define MIPI_DSI_FLAG_HSKEW BIT(9) /* hskew provided */ --#define MIPI_DSI_FLAG_BCAST BIT(10) --#define MIPI_DSI_FLAG_PIXMUX BIT(11) --#define MIPI_DSI_FLAG_DBLCLK BIT(12) --#define MIPI_DSI_FLAG_CLKDIV2 BIT(13) -- --/* request ACK from peripheral */ --#define MIPI_DSI_MSG_REQ_ACK BIT(0) --/* use Low Power Mode to transmit message */ --#define MIPI_DSI_MSG_USE_LPM BIT(1) -- --ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, -- const void *data, size_t len); --ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, -- const void *data, size_t len); --ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, -- size_t len); --int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi); --int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi); --int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode); --int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format); --int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi); --int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi); --int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi); --int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi); --int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, -- u16 end); --int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, -- u16 end); --int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi); --int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, -- enum mipi_dsi_dcs_tear_mode mode); --int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format); --int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline); --int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, -- u16 brightness); --int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, -- u16 *brightness); -- - #endif -diff --git a/include/mipi_dsi.h b/include/mipi_dsi.h -new file mode 100644 -index 0000000..f76e8d7 ---- /dev/null -+++ b/include/mipi_dsi.h -@@ -0,0 +1,473 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * MIPI DSI Bus -+ * -+ * Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd. -+ * Copyright (C) 2018 STMicroelectronics - All Rights Reserved -+ * Author(s): Andrzej Hajda -+ * Yannick Fertre -+ * Philippe Cornu -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef MIPI_DSI_H -+#define MIPI_DSI_H -+ -+#include -+#include -+ -+struct mipi_dsi_host; -+struct mipi_dsi_device; -+ -+/* request ACK from peripheral */ -+#define MIPI_DSI_MSG_REQ_ACK BIT(0) -+/* use Low Power Mode to transmit message */ -+#define MIPI_DSI_MSG_USE_LPM BIT(1) -+ -+/** -+ * struct mipi_dsi_msg - read/write DSI buffer -+ * @channel: virtual channel id -+ * @type: payload data type -+ * @flags: flags controlling this message transmission -+ * @tx_len: length of @tx_buf -+ * @tx_buf: data to be written -+ * @rx_len: length of @rx_buf -+ * @rx_buf: data to be read, or NULL -+ */ -+struct mipi_dsi_msg { -+ u8 channel; -+ u8 type; -+ u16 flags; -+ -+ size_t tx_len; -+ const void *tx_buf; -+ -+ size_t rx_len; -+ void *rx_buf; -+}; -+ -+bool mipi_dsi_packet_format_is_short(u8 type); -+bool mipi_dsi_packet_format_is_long(u8 type); -+ -+/** -+ * struct mipi_dsi_packet - represents a MIPI DSI packet in protocol format -+ * @size: size (in bytes) of the packet -+ * @header: the four bytes that make up the header (Data ID, Word Count or -+ * Packet Data, and ECC) -+ * @payload_length: number of bytes in the payload -+ * @payload: a pointer to a buffer containing the payload, if any -+ */ -+struct mipi_dsi_packet { -+ size_t size; -+ u8 header[4]; -+ size_t payload_length; -+ const u8 *payload; -+}; -+ -+int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, -+ const struct mipi_dsi_msg *msg); -+ -+/** -+ * struct mipi_dsi_host_ops - DSI bus operations -+ * @attach: attach DSI device to DSI host -+ * @detach: detach DSI device from DSI host -+ * @transfer: transmit a DSI packet -+ * -+ * DSI packets transmitted by .transfer() are passed in as mipi_dsi_msg -+ * structures. This structure contains information about the type of packet -+ * being transmitted as well as the transmit and receive buffers. When an -+ * error is encountered during transmission, this function will return a -+ * negative error code. On success it shall return the number of bytes -+ * transmitted for write packets or the number of bytes received for read -+ * packets. -+ * -+ * Note that typically DSI packet transmission is atomic, so the .transfer() -+ * function will seldomly return anything other than the number of bytes -+ * contained in the transmit buffer on success. -+ */ -+struct mipi_dsi_host_ops { -+ int (*attach)(struct mipi_dsi_host *host, -+ struct mipi_dsi_device *dsi); -+ int (*detach)(struct mipi_dsi_host *host, -+ struct mipi_dsi_device *dsi); -+ ssize_t (*transfer)(struct mipi_dsi_host *host, -+ const struct mipi_dsi_msg *msg); -+}; -+ -+/** -+ * struct mipi_dsi_phy_ops - DSI host physical operations -+ * @init: initialized host physical part -+ * @get_lane_mbps: get lane bitrate per lane (mbps) -+ * @post_set_mode: operation that should after set mode -+ */ -+struct mipi_dsi_phy_ops { -+ int (*init)(void *priv_data); -+ 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); -+}; -+ -+/** -+ * struct mipi_dsi_host - DSI host device -+ * @dev: driver model device node for this DSI host -+ * @ops: DSI host operations -+ * @list: list management -+ */ -+struct mipi_dsi_host { -+ struct device *dev; -+ const struct mipi_dsi_host_ops *ops; -+ struct list_head list; -+}; -+ -+/* DSI mode flags */ -+ -+/* video mode */ -+#define MIPI_DSI_MODE_VIDEO BIT(0) -+/* video burst mode */ -+#define MIPI_DSI_MODE_VIDEO_BURST BIT(1) -+/* video pulse mode */ -+#define MIPI_DSI_MODE_VIDEO_SYNC_PULSE BIT(2) -+/* enable auto vertical count mode */ -+#define MIPI_DSI_MODE_VIDEO_AUTO_VERT BIT(3) -+/* enable hsync-end packets in vsync-pulse and v-porch area */ -+#define MIPI_DSI_MODE_VIDEO_HSE BIT(4) -+/* disable hfront-porch area */ -+#define MIPI_DSI_MODE_VIDEO_HFP BIT(5) -+/* disable hback-porch area */ -+#define MIPI_DSI_MODE_VIDEO_HBP BIT(6) -+/* disable hsync-active area */ -+#define MIPI_DSI_MODE_VIDEO_HSA BIT(7) -+/* flush display FIFO on vsync pulse */ -+#define MIPI_DSI_MODE_VSYNC_FLUSH BIT(8) -+/* disable EoT packets in HS mode */ -+#define MIPI_DSI_MODE_EOT_PACKET BIT(9) -+/* device supports non-continuous clock behavior (DSI spec 5.6.1) */ -+#define MIPI_DSI_CLOCK_NON_CONTINUOUS BIT(10) -+/* transmit data in low power */ -+#define MIPI_DSI_MODE_LPM BIT(11) -+ -+enum mipi_dsi_pixel_format { -+ MIPI_DSI_FMT_RGB888, -+ MIPI_DSI_FMT_RGB666, -+ MIPI_DSI_FMT_RGB666_PACKED, -+ MIPI_DSI_FMT_RGB565, -+}; -+ -+#define DSI_DEV_NAME_SIZE 20 -+ -+/** -+ * struct mipi_dsi_device_info - template for creating a mipi_dsi_device -+ * @type: DSI peripheral chip type -+ * @channel: DSI virtual channel assigned to peripheral -+ * @node: pointer to OF device node or NULL -+ * -+ * This is populated and passed to mipi_dsi_device_new to create a new -+ * DSI device -+ */ -+struct mipi_dsi_device_info { -+ char type[DSI_DEV_NAME_SIZE]; -+ u32 channel; -+ struct device_node *node; -+}; -+ -+/** -+ * struct mipi_dsi_device - DSI peripheral device -+ * @host: DSI host for this peripheral -+ * @dev: driver model device node for this peripheral -+ * @name: DSI peripheral chip type -+ * @channel: virtual channel assigned to the peripheral -+ * @format: pixel format for video mode -+ * @lanes: number of active data lanes -+ * @mode_flags: DSI operation mode related flags -+ */ -+struct mipi_dsi_device { -+ struct mipi_dsi_host *host; -+ struct udevice *dev; -+ -+ char name[DSI_DEV_NAME_SIZE]; -+ unsigned int channel; -+ unsigned int lanes; -+ enum mipi_dsi_pixel_format format; -+ unsigned long mode_flags; -+}; -+ -+/** -+ * mipi_dsi_pixel_format_to_bpp - obtain the number of bits per pixel for any -+ * given pixel format defined by the MIPI DSI -+ * specification -+ * @fmt: MIPI DSI pixel format -+ * -+ * Returns: The number of bits per pixel of the given pixel format. -+ */ -+static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt) -+{ -+ switch (fmt) { -+ case MIPI_DSI_FMT_RGB888: -+ case MIPI_DSI_FMT_RGB666: -+ return 24; -+ -+ case MIPI_DSI_FMT_RGB666_PACKED: -+ return 18; -+ -+ case MIPI_DSI_FMT_RGB565: -+ return 16; -+ } -+ -+ return -EINVAL; -+} -+ -+/** -+ * struct mipi_dsi_panel_plat - DSI panel platform data -+ * @device: DSI peripheral device -+ * @lanes: number of active data lanes -+ * @format: pixel format for video mode -+ * @mode_flags: DSI operation mode related flags -+ */ -+struct mipi_dsi_panel_plat { -+ struct mipi_dsi_device *device; -+ unsigned int lanes; -+ enum mipi_dsi_pixel_format format; -+ unsigned long mode_flags; -+}; -+ -+/** -+ * mipi_dsi_attach - attach a DSI device to its DSI host -+ * @dsi: DSI peripheral -+ */ -+int mipi_dsi_attach(struct mipi_dsi_device *dsi); -+ -+/** -+ * mipi_dsi_detach - detach a DSI device from its DSI host -+ * @dsi: DSI peripheral -+ */ -+int mipi_dsi_detach(struct mipi_dsi_device *dsi); -+int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi); -+int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi); -+int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, -+ u16 value); -+ -+ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, -+ size_t size); -+ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, -+ size_t num_params, void *data, size_t size); -+ -+/** -+ * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode -+ * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking -+ * information only -+ * @MIPI_DSI_DCS_TEAR_MODE_VHBLANK : the TE output line consists of both -+ * V-Blanking and H-Blanking information -+ */ -+enum mipi_dsi_dcs_tear_mode { -+ MIPI_DSI_DCS_TEAR_MODE_VBLANK, -+ MIPI_DSI_DCS_TEAR_MODE_VHBLANK, -+}; -+ -+#define MIPI_DSI_DCS_POWER_MODE_DISPLAY BIT(2) -+#define MIPI_DSI_DCS_POWER_MODE_NORMAL BIT(3) -+#define MIPI_DSI_DCS_POWER_MODE_SLEEP BIT(4) -+#define MIPI_DSI_DCS_POWER_MODE_PARTIAL BIT(5) -+#define MIPI_DSI_DCS_POWER_MODE_IDLE BIT(6) -+ -+/** -+ * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload -+ * @dsi: DSI peripheral device -+ * @data: buffer containing data to be transmitted -+ * @len: size of transmission buffer -+ * -+ * This function will automatically choose the right data type depending on -+ * the command payload length. -+ * -+ * Return: The number of bytes successfully transmitted or a negative error -+ * code on failure. -+ */ -+ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, -+ const void *data, size_t len); -+ -+/** -+ * mipi_dsi_dcs_write() - send DCS write command -+ * @dsi: DSI peripheral device -+ * @cmd: DCS command -+ * @data: buffer containing the command payload -+ * @len: command payload length -+ * -+ * This function will automatically choose the right data type depending on -+ * the command payload length. -+ -+ * code on failure. -+ */ -+ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, -+ const void *data, size_t len); -+ -+/** -+ * mipi_dsi_dcs_read() - send DCS read request command -+ * @dsi: DSI peripheral device -+ * @cmd: DCS command -+ * @data: buffer in which to receive data -+ * @len: size of receive buffer -+ * -+ * Return: The number of bytes read or a negative error code on failure. -+ */ -+ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, -+ size_t len); -+ -+/** -+ * mipi_dsi_dcs_nop() - send DCS nop packet -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi); -+ -+/** -+ * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi); -+ -+/** -+ * mipi_dsi_dcs_get_power_mode() - query the display module's current power -+ * mode -+ * @dsi: DSI peripheral device -+ * @mode: return location for the current power mode -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode); -+ -+/** -+ * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image -+ * data used by the interface -+ * @dsi: DSI peripheral device -+ * @format: return location for the pixel format -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format); -+ -+/** -+ * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the -+ * display module except interface communication -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi); -+ -+/** -+ * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display -+ * module -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi); -+ -+/** -+ * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the -+ * display device -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi); -+ -+/** -+ * mipi_dsi_dcs_set_display_on() - start displaying the image data on the -+ * display device -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure -+ */ -+int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi); -+ -+/** -+ * mipi_dsi_dcs_set_column_address() - define the column extent of the frame -+ * memory accessed by the host processor -+ * @dsi: DSI peripheral device -+ * @start: first column of frame memory -+ * @end: last column of frame memory -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, -+ u16 end); -+/** -+ * mipi_dsi_dcs_set_page_address() - define the page extent of the frame -+ * memory accessed by the host processor -+ * @dsi: DSI peripheral device -+ * @start: first page of frame memory -+ * @end: last page of frame memory -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, -+ u16 end); -+ -+/** -+ * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect -+ * output signal on the TE signal line -+ * @dsi: DSI peripheral device -+ * -+ * Return: 0 on success or a negative error code on failure -+ */ -+int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi); -+ -+/** -+ * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect -+ * output signal on the TE signal line. -+ * @dsi: DSI peripheral device -+ * @mode: the Tearing Effect Output Line mode -+ * -+ * Return: 0 on success or a negative error code on failure -+ */ -+int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, -+ enum mipi_dsi_dcs_tear_mode mode); -+ -+/** -+ * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image -+ * data used by the interface -+ * @dsi: DSI peripheral device -+ * @format: pixel format -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format); -+ -+/** -+ * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for -+ * the Tearing Effect output signal of the display module -+ * @dsi: DSI peripheral device -+ * @scanline: scanline to use as trigger -+ * -+ * Return: 0 on success or a negative error code on failure -+ */ -+int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline); -+ -+/** -+ * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the -+ * display -+ * @dsi: DSI peripheral device -+ * @brightness: brightness value -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, -+ u16 brightness); -+ -+/** -+ * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value -+ * of the display -+ * @dsi: DSI peripheral device -+ * @brightness: brightness value -+ * -+ * Return: 0 on success or a negative error code on failure. -+ */ -+int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, -+ u16 *brightness); -+ -+#endif /* MIPI_DSI_H */ -diff --git a/include/mmc.h b/include/mmc.h -index 95548e9..a3974a8 100644 ---- a/include/mmc.h -+++ b/include/mmc.h -@@ -461,6 +461,16 @@ struct dm_mmc_ops { - */ - int (*wait_dat0)(struct udevice *dev, int state, int timeout); - #endif -+ -+ /** -+ * host_power_cycle - host specific tasks in power cycle sequence -+ * Called between mmc_power_off() and -+ * mmc_power_on() -+ * -+ * @dev: Device to check -+ * @return 0 if not present, 1 if present, -ve on error -+ */ -+ int (*host_power_cycle)(struct udevice *dev); - }; - - #define mmc_get_ops(dev) ((struct dm_mmc_ops *)(dev)->driver->ops) -@@ -473,6 +483,7 @@ int dm_mmc_get_cd(struct udevice *dev); - int dm_mmc_get_wp(struct udevice *dev); - int dm_mmc_execute_tuning(struct udevice *dev, uint opcode); - int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout); -+int dm_mmc_host_power_cycle(struct udevice *dev); - - /* Transition functions for compatibility */ - int mmc_set_ios(struct mmc *mmc); -@@ -481,6 +492,7 @@ int mmc_getcd(struct mmc *mmc); - int mmc_getwp(struct mmc *mmc); - int mmc_execute_tuning(struct mmc *mmc, uint opcode); - int mmc_wait_dat0(struct mmc *mmc, int state, int timeout); -+int mmc_host_power_cycle(struct mmc *mmc); - - #else - struct mmc_ops { -@@ -490,6 +502,7 @@ struct mmc_ops { - int (*init)(struct mmc *mmc); - int (*getcd)(struct mmc *mmc); - int (*getwp)(struct mmc *mmc); -+ int (*host_power_cycle)(struct mmc *mmc); - }; - #endif - -diff --git a/include/power/stpmic1.h b/include/power/stpmic1.h -index d90a1a9..b5a6d52 100644 ---- a/include/power/stpmic1.h -+++ b/include/power/stpmic1.h -@@ -37,6 +37,7 @@ - #define STPMIC1_BUCK_VOUT(sel) (sel << STPMIC1_BUCK_VOUT_SHIFT) - - #define STPMIC1_BUCK2_1200000V STPMIC1_BUCK_VOUT(24) -+#define STPMIC1_BUCK2_1250000V STPMIC1_BUCK_VOUT(26) - #define STPMIC1_BUCK2_1350000V STPMIC1_BUCK_VOUT(30) - - #define STPMIC1_BUCK3_1800000V STPMIC1_BUCK_VOUT(39) -diff --git a/include/remoteproc.h b/include/remoteproc.h -index fa82531..e25702b 100644 ---- a/include/remoteproc.h -+++ b/include/remoteproc.h -@@ -45,6 +45,17 @@ struct dm_rproc_uclass_pdata { - }; - - /** -+ * struct rproc_priv - Device information used by the rproc uclass -+ * -+ * @rsc_table_addr: Resource Table address (if any) -+ * @rsc_table_size: Resource Table size -+ */ -+struct rproc_priv { -+ ulong rsc_table_addr; -+ unsigned int rsc_table_size; -+}; -+ -+/** - * struct dm_rproc_ops - Operations that are provided by remote proc driver - * @init: Initialize the remoteproc device invoked after probe (optional) - * Return 0 on success, -ve error on fail --- -2.7.4 - diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0099-Add-external-var-to-allow-build-of-new-devicetree-fi.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0099-Add-external-var-to-allow-build-of-new-devicetree-fi.patch new file mode 100644 index 0000000..d049dfe --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0099-Add-external-var-to-allow-build-of-new-devicetree-fi.patch @@ -0,0 +1,29 @@ +From 641d3282b8df04bf1a23c9ded96d01e2381d4e38 Mon Sep 17 00:00:00 2001 +From: Romuald JEANNE +Date: Tue, 26 May 2020 15:03:11 +0200 +Subject: [PATCH] Add external var to allow build of new devicetree file + +Signed-off-by: Romuald JEANNE +--- + arch/arm/dts/Makefile | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index 29eb949..718e454 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -1,5 +1,11 @@ + # SPDX-License-Identifier: GPL-2.0+ + ++DEVICE_TREE_EXT ?= ++ ++ifneq ($(DEVICE_TREE_EXT),) ++dtb-y += $(DEVICE_TREE_EXT) ++endif ++ + dtb-$(CONFIG_TARGET_SMARTWEB) += at91sam9260-smartweb.dtb + dtb-$(CONFIG_TARGET_TAURUS) += at91sam9g20-taurus.dtb + dtb-$(CONFIG_TARGET_CORVUS) += at91sam9g45-corvus.dtb +-- +2.7.4 + 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 952971c..c1fcafc 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 @@ -19,17 +19,17 @@ For U-Boot build you need to install: - Fedora: sudo yum install git If you have never configured you git configuration: - $> git config --global user.name "your_name" - $> git config --global user.email "your_email@example.com" + $ git config --global user.name "your_name" + $ git config --global user.email "your_email@example.com" 2. Initialize cross-compilation via SDK: --------------------------------------- * Source SDK environment: - $> source /environment-setup-cortexa7t2hf-neon-vfpv4-openstlinux_weston-linux-gnueabi + $ source /environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi * To verify if you cross-compilation environment are put in place: - $> set | grep CROSS - CROSS_COMPILE=arm-openstlinux_weston-linux-gnueabi- + $ set | grep CROSS + CROSS_COMPILE=arm-ostl-linux-gnueabi- Warning: the environment are valid only on the shell session where you have sourced the sdk environment. @@ -38,11 +38,11 @@ Warning: the environment are valid only on the shell session where you have ------------------------ Extract the sources from tarball, for example: -$> tar xfJ SOURCES-st-image-weston-openstlinux-weston-stm32mp1-*.tar.xz +$ tar xfJ SOURCES-st-image-weston-openstlinux-weston-stm32mp1-*.tar.xz -In the U-Boot source directory (sources/*/u-boot-stm32mp-2018.11-r0), +In the U-Boot source directory (sources/*/##BP##-##PR##), you have one U-Boot source tarball, the patches and one Makefile: - - v2018.11.tar.gz + - ##BP##-##PR##.tar.gz - 000*.patch - Makefile.sdk @@ -51,8 +51,8 @@ NB: if you would like to have a git management on the code see Then you must extract the tarball and apply the patch: - $> tar xfz v2018.11.tar.gz - $> cd u-boot-2018.11 + $> tar xfz ##BP##-##PR##.tar.gz + $> cd ##BP## $> for p in `ls -1 ../*.patch`; do patch -p1 < $p; done 4. Management of U-Boot source code with GIT @@ -63,57 +63,57 @@ 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: v2018.11-stm32mp - Revision: v2018.11-stm32mp-r2 + Branch: v##PV##-stm32mp + Revision: v##PV##-stm32mp-##PR## - $> git clone https://github.com/STMicroelectronics/u-boot.git - $> git checkout -b WORKING v2018.11-stm32mp-r2 + $ git clone https://github.com/STMicroelectronics/u-boot.git + $ git checkout -b WORKING v##PV##-stm32mp-##PR## 4.2 Create Git from tarball - $> tar xvf v2018.11.tar.gz - $> cd u-boot-2018.11 - $> 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 + $ tar xfz ##BP##-##PR##.tar.gz + $ 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 URL: git://git.denx.de/u-boot.git Branch: master - Revision: v2018.11 + Revision: v##PV## - $> git clone git://git.denx.de/u-boot.git + $ git clone git://git.denx.de/u-boot.git or - $> git clone http://git.denx.de/u-boot.git + $ git clone http://git.denx.de/u-boot.git - $> cd u-boot - $> git checkout -b WORKING v2018.11 - $> for p in `ls -1 ../*.patch`; do git am $p; done + $ cd u-boot + $ git checkout -b WORKING v##PV## + $ for p in `ls -1 ../*.patch`; do git am $p; done 5. Compilation U-Boot source code: ---------------------------------- To compile U-Boot source code, first move to U-Boot source: - $> cd u-boot-2018.11 + $ cd ##BP## or - $> cd u-boot + $ cd u-boot 5.1 Compilation for one target (one defconfig, one device tree) see /board/st/stm32mp1/README for details - # make stm32mp15__defconfig - # make DEVICE_TREE= all + $ make stm32mp15__defconfig + $ make DEVICE_TREE= all example: a) trusted boot on ev1 - # make stm32mp15_trusted_defconfig - # make DEVICE_TREE=stm32mp157c-ev1 all + $ make stm32mp15_trusted_defconfig + $ make DEVICE_TREE=stm32mp157c-ev1 all b) basic boot on dk2 - # make stm32mp15_basic_defconfig - # make DEVICE_TREE=stm32mp157c-dk2 all + $ make stm32mp15_basic_defconfig + $ make DEVICE_TREE=stm32mp157c-dk2 all 5.2 Compilation for several targets: use Makefile.sdk @@ -135,36 +135,21 @@ variables 'DEVICE_TREE' and 'UBOOT_CONFIGS': The generated binary files are available in ../build-${config}. -by default we define 3 configs: basic, trusted, optee -for the 4 board : stm32mp157a-dk1 stm32mp157c-dk2 stm32mp157c-ed1 stm32mp157c-ev1 - -The generated files are: - -../build-trusted - u-boot-stm32mp157a-dk1-trusted.stm32 - u-boot-stm32mp157c-dk2-trusted.stm32 - u-boot-stm32mp157c-ed1-trusted.stm32 - u-boot-stm32mp157c-ev1-trusted.stm32 - -../build-optee - u-boot-stm32mp157a-dk1-optee.stm32 - u-boot-stm32mp157c-dk2-optee.stm32 - u-boot-stm32mp157c-ed1-optee.stm32 - u-boot-stm32mp157c-ev1-optee.stm32 - -../build-basic - u-boot-stm32mp157a-dk1-basic.img & u-boot-spl.stm32-stm32mp157a-dk1-basic - u-boot-stm32mp157c-dk2-basic.img & u-boot-spl.stm32-stm32mp157c-dk2-basic - u-boot-stm32mp157c-ed1-basic.img & u-boot-spl.stm32-stm32mp157c-ed1-basic - u-boot-stm32mp157c-ev1-basic.img & u-boot-spl.stm32-stm32mp157c-ev1-basic +by default we define 3 configs: basic, trusted, optee for the several boards +The generated files are : + for trusted and optee configs: + #> ../build-{trusted,optee}/*.stm32 + for basic config + #> ../build-basic/u-boot-spl.elf-*-basic + #> ../build-basic/u-boot-*-basic.img You can override the default U-Boot configuration if you specify these variables: - Compile default U-Boot configuration but applying specific devicetree(s): - $> make -f $PWD/../Makefile.sdk all DEVICE_TREE=" " + $ make -f $PWD/../Makefile.sdk all DEVICE_TREE=" " - Compile for a specific U-Boot configuration: - $> make -f $PWD/../Makefile.sdk all UBOOT_CONFIGS=,, + $ make -f $PWD/../Makefile.sdk all UBOOT_CONFIGS=,, - Compile for a specific U-Boot configuration and applying specific devicetree(s): - $> make -f $PWD/../Makefile.sdk all UBOOT_CONFIGS=,, DEVICE_TREE=" " + $ make -f $PWD/../Makefile.sdk all UBOOT_CONFIGS=,, DEVICE_TREE=" " 6. Update software on board: ---------------------------- @@ -203,14 +188,14 @@ U-boot binary (u-boot*.stm32) MUST be copied on a dedicated partition named "ssb "fsbl1" is the partition 1: - SDCARD: /dev/mmcblkXp1 (where X is the instance number) - SDCARD via USB reader: /dev/sdX1 (where X is the instance number) - dd if= of=/dev/ bs=1M conv=fdatasync + $ dd if= of=/dev/ bs=1M conv=fdatasync * u-boot*.img Copy the binary on the dedicated partition, on SDCARD/USB disk the partition "ssbl" is the partition 4: - SDCARD: /dev/mmcblkXp3 (where X is the instance number) - SDCARD via USB reader: /dev/sdX3 (where X is the instance number) - dd if= of=/dev/ bs=1M conv=fdatasync + $ dd if= of=/dev/ bs=1M conv=fdatasync 6.2.2. Trusted boot chain * tf-a-*.stm32 @@ -218,19 +203,19 @@ U-boot binary (u-boot*.stm32) MUST be copied on a dedicated partition named "ssb "fsbl1" is the partition 1: - SDCARD: /dev/mmcblkXp1 (where X is the instance number) - SDCARD via USB reader: /dev/sdX1 (where X is the instance number) - dd if= of=/dev/ bs=1M conv=fdatasync + $ dd if= of=/dev/ bs=1M conv=fdatasync * u-boot*.stm32 Copy the binary on the dedicated partition, on SDCARD/USB disk the partition "ssbl" is the partition 4: - SDCARD: /dev/mmcblkXp3 (where X is the instance number) - SDCARD via USB reader: /dev/sdX3 (where X is the instance number) - dd if= of=/dev/ bs=1M conv=fdatasync + $ dd if= of=/dev/ bs=1M conv=fdatasync 6.2.3. FAQ to found the partition associated to a specific label, just plug the SDCARD/USB disk on your PC and call the following command: - $> ls -l /dev/disk/by-partlabel/ + $ ls -l /dev/disk/by-partlabel/ total 0 lrwxrwxrwx 1 root root 10 Jan 17 17:38 bootfs -> ../../mmcblk0p4 lrwxrwxrwx 1 root root 10 Jan 17 17:38 fsbl1 -> ../../mmcblk0p1 ➔ FSBL (TF-A) @@ -265,4 +250,4 @@ By default on STMicroelectronics board, "mmc 0" is SD card on SDMMC1. * Follow section 6.2 to put U-Boot SPL binary and U-Boot binary (*.img or *.stm32) on SDCARD/USB disk. -PS: A Ctrl-C is needed to stop the command. +PS: A Ctrl-C is needed to stop the command. \ No newline at end of file diff --git a/recipes-bsp/u-boot/u-boot-stm32mp_2018.11.bb b/recipes-bsp/u-boot/u-boot-stm32mp_2020.01.bb similarity index 87% rename from recipes-bsp/u-boot/u-boot-stm32mp_2018.11.bb rename to recipes-bsp/u-boot/u-boot-stm32mp_2020.01.bb index b4eae6a..3a30d12 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp_2018.11.bb +++ b/recipes-bsp/u-boot/u-boot-stm32mp_2020.01.bb @@ -4,6 +4,9 @@ require u-boot-stm32mp.inc SUMMARY = "Universal Boot Loader for embedded devices for stm32mp" LICENSE = "GPLv2+" +PROVIDES += "u-boot" +RPROVIDES_${PN} += "u-boot" + # --------------------------------- # Configure archiver use # ---------------------------------