From 8efdfc6932fe7aa521ad77fb72a7c2e2c1e5a8f0 Mon Sep 17 00:00:00 2001 From: Christophe Priouzeau Date: Wed, 9 Oct 2019 11:25:40 +0200 Subject: [PATCH] U-BOOT-STM32MP: v1.1.0 update Signed-off-by: Christophe Priouzeau --- .../u-boot/u-boot-stm32mp-archiver.inc | 130 + .../u-boot/u-boot-stm32mp-common_2018.11.inc | 7 +- recipes-bsp/u-boot/u-boot-stm32mp.inc | 130 - ...0009-ARM-v2018.11-stm32mp-r3-MACHINE.patch | 1721 ++++ .../0010-ARM-v2018.11-stm32mp-r3-BOARD.patch | 1012 +++ ...1-ARM-v2018.11-stm32mp-r3-DEVICETREE.patch | 1987 +++++ .../0012-ARM-v2018.11-stm32mp-r3-CONFIG.patch | 218 + .../0013-ARM-v2018.11-stm32mp-r3-MISC.patch | 6902 +++++++++++++++++ recipes-bsp/u-boot/u-boot-stm32mp_2018.11.bb | 5 + 9 files changed, 11981 insertions(+), 131 deletions(-) create mode 100644 recipes-bsp/u-boot/u-boot-stm32mp-archiver.inc create mode 100644 recipes-bsp/u-boot/u-boot-stm32mp/0009-ARM-v2018.11-stm32mp-r3-MACHINE.patch create mode 100644 recipes-bsp/u-boot/u-boot-stm32mp/0010-ARM-v2018.11-stm32mp-r3-BOARD.patch create mode 100644 recipes-bsp/u-boot/u-boot-stm32mp/0011-ARM-v2018.11-stm32mp-r3-DEVICETREE.patch create mode 100644 recipes-bsp/u-boot/u-boot-stm32mp/0012-ARM-v2018.11-stm32mp-r3-CONFIG.patch create mode 100644 recipes-bsp/u-boot/u-boot-stm32mp/0013-ARM-v2018.11-stm32mp-r3-MISC.patch diff --git a/recipes-bsp/u-boot/u-boot-stm32mp-archiver.inc b/recipes-bsp/u-boot/u-boot-stm32mp-archiver.inc new file mode 100644 index 0000000..cc301a2 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp-archiver.inc @@ -0,0 +1,130 @@ +# +# Archiver Configuration +# +SRC_URI_append = " file://README.HOW_TO.txt " + +inherit archiver +ARCHIVER_MODE[src] = "original" + +inherit archiver_stm32mp_clean + +archiver_create_makefile_for_sdk() { + # Init internal var for uboot_configs: should be 'defconfig,type,binary' + if [ -n "${UBOOT_CONFIG}" ]; then + unset i j k + for config in ${UBOOT_MACHINE}; do + i=$(expr $i + 1); + for type in ${UBOOT_CONFIG}; do + j=$(expr $j + 1); + if [ $j -eq $i ]; then + for binary in ${UBOOT_BINARIES}; do + k=$(expr $k + 1); + if [ $k -eq $i ]; then + uboot_configs="${uboot_configs} ${config},${type},${binary}" + fi + done + unset k + fi + done + unset j + done + unset i + else + uboot_configs="${UBOOT_MACHINE},,${UBOOT_BINARY}" + fi + + mkdir -p ${ARCHIVER_OUTDIR} + + # Remove default variable + echo "LDFLAGS=" > ${ARCHIVER_OUTDIR}/Makefile.sdk + echo "CFLAGS=" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo "CPPFLAGS=" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo "" >> ${ARCHIVER_OUTDIR}/Makefile.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 + + # Configure default U-Boot configs + echo "UBOOT_CONFIGS ?= ${uboot_configs}" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo "DEVICE_TREE ?= ${UBOOT_DEVICETREE}" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + + echo "help:" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " @echo" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " @echo \"Configured U-Boot config(s):\"" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " @for config in \$(UBOOT_CONFIGS); do \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " defconfig=\$\$(echo \$\$config | cut -d',' -f1) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " type=\$\$(echo \$\$config | cut -d',' -f2) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " binary=\$\$(echo \$\$config | cut -d',' -f3) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " echo \" \$\$defconfig config (\$\$type type) for \$\$binary binary\" ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " for devicetree in \$(DEVICE_TREE); do \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " echo \" with device tree: \$\$devicetree\" ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " done ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " done" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " @echo" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " @echo \"Available targets:\"" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " @echo \" all : build U-Boot binaries for defined config(s)\"" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " @echo \" clean : clean build directories from generated files\"" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + + echo "version:" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " @if test ! -e .scmversion ; then echo \$(UBOOT_LOCALVERSION) > \$(LOCAL_PATH)/.scmversion; fi" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + + echo "all: version" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " for config in \$(UBOOT_CONFIGS); do \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " uboot_config=\$\$(echo \$\$config | cut -d',' -f1) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " uboot_type=-\$\$(echo \$\$config | cut -d',' -f2) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " uboot_binary=\$\$(echo \$\$config | cut -d',' -f3) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " uboot_suffix=\$\$(echo \$\$uboot_binary | cut -d'.' -f2) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + # Make sure about configuration set + echo " if test -z \"\$\$uboot_config\" -o -z \"\$\$uboot_type\" -o -z \"\$\$uboot_binary\"; then \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " echo ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " echo \"[ERROR] UBOOT_CONFIGS wrongly configured. It should be space separated list of element ,,\" ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " echo ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " exit 1 ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " fi ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + # Init folder and defconfig selected + 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 " 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 + # 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 + echo " if [ -f \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_BINARY_STM32} ]; then \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " cp -f \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_BINARY_STM32} \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_BINARYNAME}\$\$uboot_type ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " cp -f \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_ELF} \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_ELF_NAME}\$\$uboot_type ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.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 + # 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 + echo " if [ -f \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_BINARY_STM32} ]; then \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " cp -f \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_BINARY_STM32} \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_BINARYNAME}-\$\$devicetree\$\$uboot_type ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " cp -f \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_ELF} \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_ELF_NAME}-\$\$devicetree\$\$uboot_type ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " fi ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " done ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " fi ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " done" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + + echo "clean:" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " @for config in \$(UBOOT_CONFIGS); do \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " uboot_type=-\$\$(echo \$\$config | cut -d',' -f2) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " echo \"Removing \$(LOCAL_PATH)/../build\$\$uboot_type ...\" ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " rm -rf \$(LOCAL_PATH)/../build\$\$uboot_type ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " done" >> ${ARCHIVER_OUTDIR}/Makefile.sdk +} +do_ar_original[prefuncs] += "archiver_create_makefile_for_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 index ab0627a..9923789 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp-common_2018.11.inc +++ b/recipes-bsp/u-boot/u-boot-stm32mp-common_2018.11.inc @@ -24,6 +24,11 @@ SRC_URI += " \ 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 \ " U_BOOT_VERSION = "2018.11" @@ -37,7 +42,7 @@ S = "${WORKDIR}/u-boot-${PV}" 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_class-devupstream = "22eea618b3295cfae777aa80789eb1b46824db12" SRCREV_FORMAT_class-devupstream = "uboot" PV_class-devupstream = "${U_BOOT_VERSION}+github+${SRCPV}" diff --git a/recipes-bsp/u-boot/u-boot-stm32mp.inc b/recipes-bsp/u-boot/u-boot-stm32mp.inc index 1dd1269..23193df 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp.inc +++ b/recipes-bsp/u-boot/u-boot-stm32mp.inc @@ -154,136 +154,6 @@ do_deploy_append() { fi } -# ----------------------------------------------------------------------------- -# ARCHIVER -# -inherit archiver -ARCHIVER_MODE[src] = "${@'original' if d.getVar('ST_ARCHIVER_ENABLE') == '1' else ''}" -SRC_URI += " file://README.HOW_TO.txt " - -inherit archiver_stm32mp_clean - -archiver_create_makefile_for_sdk() { - # Init internal var for uboot_configs: should be 'defconfig,type,binary' - if [ -n "${UBOOT_CONFIG}" ]; then - unset i j k - for config in ${UBOOT_MACHINE}; do - i=$(expr $i + 1); - for type in ${UBOOT_CONFIG}; do - j=$(expr $j + 1); - if [ $j -eq $i ]; then - for binary in ${UBOOT_BINARIES}; do - k=$(expr $k + 1); - if [ $k -eq $i ]; then - uboot_configs="${uboot_configs} ${config},${type},${binary}" - fi - done - unset k - fi - done - unset j - done - unset i - else - uboot_configs="${UBOOT_MACHINE},,${UBOOT_BINARY}" - fi - - mkdir -p ${ARCHIVER_OUTDIR} - - # Remove default variable - echo "LDFLAGS=" > ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "CFLAGS=" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "CPPFLAGS=" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "" >> ${ARCHIVER_OUTDIR}/Makefile.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 - - # Configure default U-Boot configs - echo "UBOOT_CONFIGS ?= ${uboot_configs}" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "DEVICE_TREE ?= ${UBOOT_DEVICETREE}" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - - echo "help:" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " @echo" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " @echo \"Configured U-Boot config(s):\"" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " @for config in \$(UBOOT_CONFIGS); do \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " defconfig=\$\$(echo \$\$config | cut -d',' -f1) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " type=\$\$(echo \$\$config | cut -d',' -f2) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " binary=\$\$(echo \$\$config | cut -d',' -f3) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " echo \" \$\$defconfig config (\$\$type type) for \$\$binary binary\" ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " for devicetree in \$(DEVICE_TREE); do \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " echo \" with device tree: \$\$devicetree\" ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " done ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " done" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " @echo" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " @echo \"Available targets:\"" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " @echo \" all : build U-Boot binaries for defined config(s)\"" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " @echo \" clean : clean build directories from generated files\"" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - - echo "version:" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " @if test ! -e .scmversion ; then echo \$(UBOOT_LOCALVERSION) > \$(LOCAL_PATH)/.scmversion; fi" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - - echo "all: version" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " for config in \$(UBOOT_CONFIGS); do \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " uboot_config=\$\$(echo \$\$config | cut -d',' -f1) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " uboot_type=-\$\$(echo \$\$config | cut -d',' -f2) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " uboot_binary=\$\$(echo \$\$config | cut -d',' -f3) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " uboot_suffix=\$\$(echo \$\$uboot_binary | cut -d'.' -f2) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - # Make sure about configuration set - echo " if test -z \"\$\$uboot_config\" -o -z \"\$\$uboot_type\" -o -z \"\$\$uboot_binary\"; then \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " echo ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " echo \"[ERROR] UBOOT_CONFIGS wrongly configured. It should be space separated list of element ,,\" ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " echo ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " exit 1 ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " fi ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - # Init folder and defconfig selected - 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 " 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 - # 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 - echo " if [ -f \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_BINARY_STM32} ]; then \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " cp -f \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_BINARY_STM32} \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_BINARYNAME}\$\$uboot_type ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " cp -f \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_ELF} \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_ELF_NAME}\$\$uboot_type ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.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 - # 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 - echo " if [ -f \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_BINARY_STM32} ]; then \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " cp -f \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_BINARY_STM32} \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_BINARYNAME}-\$\$devicetree\$\$uboot_type ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " cp -f \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_ELF} \$(LOCAL_PATH)/../build\$\$uboot_type/${SPL_ELF_NAME}-\$\$devicetree\$\$uboot_type ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " fi ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " done ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " fi ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " done" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - - echo "clean:" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " @for config in \$(UBOOT_CONFIGS); do \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " uboot_type=-\$\$(echo \$\$config | cut -d',' -f2) ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " echo \"Removing \$(LOCAL_PATH)/../build\$\$uboot_type ...\" ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " rm -rf \$(LOCAL_PATH)/../build\$\$uboot_type ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " done" >> ${ARCHIVER_OUTDIR}/Makefile.sdk -} -do_ar_original[prefuncs] += "archiver_create_makefile_for_sdk" - # --------------------------------------------------------------------- # Avoid QA Issue: No GNU_HASH in the elf binary INSANE_SKIP_${PN} += "ldflags" 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 new file mode 100644 index 0000000..f906d27 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0009-ARM-v2018.11-stm32mp-r3-MACHINE.patch @@ -0,0 +1,1721 @@ +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 new file mode 100644 index 0000000..455b591 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0010-ARM-v2018.11-stm32mp-r3-BOARD.patch @@ -0,0 +1,1012 @@ +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 new file mode 100644 index 0000000..7a369f9 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0011-ARM-v2018.11-stm32mp-r3-DEVICETREE.patch @@ -0,0 +1,1987 @@ +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 new file mode 100644 index 0000000..ab08250 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0012-ARM-v2018.11-stm32mp-r3-CONFIG.patch @@ -0,0 +1,218 @@ +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 new file mode 100644 index 0000000..9f74a76 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0013-ARM-v2018.11-stm32mp-r3-MISC.patch @@ -0,0 +1,6902 @@ +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_2018.11.bb b/recipes-bsp/u-boot/u-boot-stm32mp_2018.11.bb index 49da32d..b4eae6a 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp_2018.11.bb +++ b/recipes-bsp/u-boot/u-boot-stm32mp_2018.11.bb @@ -3,3 +3,8 @@ require u-boot-stm32mp.inc SUMMARY = "Universal Boot Loader for embedded devices for stm32mp" LICENSE = "GPLv2+" + +# --------------------------------- +# Configure archiver use +# --------------------------------- +include ${@oe.utils.ifelse(d.getVar('ST_ARCHIVER_ENABLE') == '1', 'u-boot-stm32mp-archiver.inc','')}